Spec-Zone.ru › NumPy 1.21

NumPy для пользователей MATLAB

Введение

MATLAB® и NumPy имеют много общего, но NumPy создан для работы с Python, а не для того, чтобы быть клоном MATLAB. Это руководство поможет пользователям MATLAB начать работу с NumPy.

Некоторые ключевые различия

В MATLAB базовый тип, даже для скаляров, является многомерным массивом. Присваивания массивов в MATLAB хранятся как двумерные массивы с двойной точностью с плавающей запятой, если вы не укажете количество измерений и тип. Операции над двумерными экземплярами этих массивов моделируются по операциям над матрицами в линейной алгебре.

В NumPy базовый тип — многомерный array. Присваивания массивов в NumPy обычно хранятся как n-мерные массивы с минимальным типом, необходимым для хранения объектов в последовательности, если вы не укажете количество измерений и тип. NumPy выполняет операции поэлементно, поэтому умножение двумерных массивов с * не является матричным умножением — это поэлементное умножение. (Оператор @, доступный с Python 3.5, может быть использован для обычного матричного умножения.)

В MATLAB индексы нумеруются с 1; a(1) — первый элемент. См. примечание ИНДЕКС

NumPy, как и Python, нумерует индексы с 0; a[0] — первый элемент.

Язык сценариев MATLAB был создан для линейной алгебры, поэтому синтаксис для некоторых операций с массивами более компактен, чем в NumPy. С другой стороны, API для добавления графических интерфейсов и создания полноценных приложений — это скорее дополнительный элемент.

NumPy основан на Python, универсальном языке программирования. Преимущество NumPy заключается в доступе к библиотекам Python, включая: SciPy, Matplotlib, Pandas, OpenCV и многое другое. Кроме того, Python часто используется как язык сценариев в других программных продуктах, что позволяет использовать NumPy и там.

Фрагментация массивов в MATLAB использует семантику передачи по значению, с ленивой схемой копирования при записи, чтобы предотвратить создание копий до тех пор, пока они не потребуются. Операции фрагментации копируют части массива.

Фрагментация массивов в NumPy использует передачу по ссылке, которая не копирует аргументы. Операции фрагментации представляют собой представления массива.

Приблизительные эквиваленты

В таблице ниже приведены приблизительные эквиваленты некоторых распространенных выражений MATLAB. Это аналогичные, а не эквивалентные выражения. Подробности см. в документации.

В таблице ниже предполагается, что вы выполнили следующие команды в Python:

import numpy as np
from scipy import io, integrate, linalg, signal
from scipy.sparse.linalg import eigs

Также предполагается ниже, что если в Примечаниях говорится о «матрице», то аргументы являются двумерными сущностями.

Эквиваленты общего назначения

MATLAB

NumPy

Примечания

help func

info(func) или help(func) или func? (в IPython)

получение справки по функции func

which func

см. примечание ПОМОЩЬ

выяснение места определения func

type func

np.source(func) или func?? (в IPython)

вывод исходного кода func (если это не встроенная функция)

% comment

# comment

комментирование строки кода с текстом comment

for i=1:3
    fprintf('%i\n',i)
end
for i in range(1, 4):
   print(i)

использование цикла for для вывода чисел 1, 2 и 3 с помощью range

a && b

a and b

короткое логическое И (с сокращением вычислений) (встроенный оператор Python); только скалярные аргументы

a || b

a or b

короткое логическое ИЛИ (с сокращением вычислений) (встроенный оператор Python); только скалярные аргументы

>> 4 == 4
ans = 1
>> 4 == 5
ans = 0
>>> 4 == 4
True
>>> 4 == 5
False

Объекты boolean в Python — True и False, в отличие от логических типов MATLAB 1 и 0

a=4
if a==4
    fprintf('a = 4\n')
elseif a==5
    fprintf('a = 5\n')
end
a = 4
if a == 4:
    print('a = 4')
elif a == 5:
    print('a = 5')

создание оператора if-else для проверки, равен ли a 4 или 5, и вывод результата

1*i, 1*j, 1i, 1j

1j

комплексные числа

eps

np.finfo(float).eps или np.spacing(1)

Верхняя граница относительной погрешности из-за округления в 64-битной арифметике с плавающей запятой.

load data.mat

io.loadmat('data.mat')

Загрузка переменных MATLAB, сохраненных в файле data.mat. (Примечание: при сохранении массивов в data.mat в MATLAB/Octave используйте недавний двоичный формат. scipy.io.loadmat создаст словарь с сохраненными массивами и дополнительной информацией.)

ode45

integrate.solve_ivp(f)

интегрирование ОДУ методом Рунге-Кутты 4,5

ode15s

integrate.solve_ivp(f, method='BDF')

интегрирование ОДУ методом BDF

Эквиваленты линейной алгебры

MATLAB

NumPy

Примечания

ndims(a)

np.ndim(a) или a.ndim

количество измерений массива a

numel(a)

np.size(a) или a.size

количество элементов массива a

size(a)

np.shape(a) или a.shape

«размер» массива a

size(a,n)

a.shape[n-1]

получение количества элементов n-го измерения массива a. (Обратите внимание, что MATLAB использует нумерацию с 1, а Python — с 0. См. примечание ИНДЕКСИРОВАНИЕ)

[ 1 2 3; 4 5 6 ]

np.array([[1. ,2. ,3.], [4. ,5. ,6.]])

определение двумерного массива 2x3

[ a b; c d ]

np.block([[a, b], [c, d]])

создание матрицы из блоков a, b, c, и d

a(end)

a[-1]

доступ к последнему элементу в векторе MATLAB (1xn или nx1) или одномерном массиве NumPy a (длина n)

a(2,5)

a[1, 4]

доступ к элементу во второй строке, пятом столбце двумерного массива a

a(2,:)

a[1] или a[1, :]

вся вторая строка двумерного массива a

a(1:5,:)

a[0:5] или a[:5] или a[0:5, :]

первые 5 строк двумерного массива a

a(end-4:end,:)

a[-5:]

последние 5 строк двумерного массива a

a(1:3,5:9)

a[0:3, 4:9]

Первые три строки и пятый по девятый столбцы двумерного массива a.

a([2,4,5],[1,3])

a[np.ix_([1, 3, 4], [0, 2])]

строки 2, 4 и 5 и столбцы 1 и 3. Это позволяет изменить матрицу и не требует обычного среза.

a(3:2:21,:)

a[2:21:2,:]

каждая вторая строка a, начиная с третьей и заканчивая двадцать первой

a(1:2:end,:)

a[ ::2,:]

каждая вторая строка a, начиная с первой

a(end:-1:1,:) или flipud(a)

a[::-1,:]

a со строками в обратном порядке

a([1:end 1],:)

a[np.r_[:len(a),0]]

a с копией первой строки, добавленной в конец

a.'

a.transpose() или a.T

транспонирование a

a'

a.conj().transpose() или a.conj().T

сопряжённое транспонирование a

a * b

a @ b

умножение матриц

a .* b

a * b

элементное умножение

a./b

a/b

элементное деление

a.^3

a**3

возведение в степень по элементам

(a > 0.5)

(a > 0.5)

матрица, где i,j-й элемент равен (a_ij > 0.5). Результат MATLAB — массив логических значений 0 и 1. Результат NumPy — массив с логическими значениями False и True.

find(a > 0.5)

np.nonzero(a > 0.5)

найти индексы, где (a > 0.5)

a(:,find(v > 0.5))

a[:,np.nonzero(v > 0.5)[0]]

извлечь столбцы a где вектор v > 0.5

a(:,find(v>0.5))

a[:, v.T > 0.5]

извлечь столбцы a где столбец-вектор v > 0.5

a(a<0.5)=0

a[a < 0.5]=0

a с элементами, меньшими 0.5, обнулёнными

a .* (a>0.5)

a * (a > 0.5)

a с элементами, меньшими 0.5, обнулёнными

a(:) = 3

a[:] = 3

установить все значения на одно скалярное значение

y=x

y = x.copy()

NumPy присваивает по ссылке

y=x(2,:)

y = x[1, :].copy()

Срезы NumPy — по ссылке

y=x(:)

y = x.flatten()

преобразование массива в вектор (обратите внимание, что это принудительно создаёт копию). Чтобы получить тот же порядок данных, что и в MATLAB, используйте x.flatten('F').

1:10

np.arange(1., 11.) или np.r_[1.:11.] или np.r_[1:10:10j]

создание возрастающего вектора (см. примечание ДИАПАЗОНЫ)

0:9

np.arange(10.) или np.r_[:10.] или np.r_[:9:10j]

создание возрастающего вектора (см. примечание ДИАПАЗОНЫ)

[1:10]'

np.arange(1.,11.)[:, np.newaxis]

создание столбец-вектора

zeros(3,4)

np.zeros((3, 4))

двумерный массив 3x4, заполненный нулями с плавающей точкой 64 бита

zeros(3,4,5)

np.zeros((3, 4, 5))

трёхмерный массив 3x4x5, заполненный нулями с плавающей точкой 64 бита

ones(3,4)

np.ones((3, 4))

двумерный массив 3x4, заполненный единицами с плавающей точкой 64 бита

eye(3)

np.eye(3)

единичная матрица 3x3

diag(a)

np.diag(a)

возвращает вектор диагональных элементов двумерного массива, a

diag(v,0)

np.diag(v, 0)

возвращает квадратную диагональную матрицу, ненулевые значения которой — элементы вектора v

rng(42,'twister')
rand(3,4)
from numpy.random import default_rng
rng = default_rng(42)
rng.random(3, 4)

или более старая версия: random.rand((3, 4))

сгенерировать случайный массив 3x4 с генератором случайных чисел по умолчанию и начальным значением 42

linspace(1,3,4)

np.linspace(1,3,4)

4 равномерно распределённых образца между 1 и 3 включительно

[x,y]=meshgrid(0:8,0:5)

np.mgrid[0:9.,0:6.] или np.meshgrid(r_[0:9.],r_[0:6.]

два двумерных массива: один с значениями x, другой с значениями y

ogrid[0:9.,0:6.] или np.ix_(np.r_[0:9.],np.r_[0:6.]

лучший способ вычисления функций на сетке

[x,y]=meshgrid([1,2,4],[2,4,5])

np.meshgrid([1,2,4],[2,4,5])

ix_([1,2,4],[2,4,5])

лучший способ вычисления функций на сетке

repmat(a, m, n)

np.tile(a, (m, n))

создать m на n копий a

[a b]

np.concatenate((a,b),1) или np.hstack((a,b)) или np.column_stack((a,b)) или np.c_[a,b]

склеить столбцы a и b

[a; b]

np.concatenate((a,b)) или np.vstack((a,b)) или np.r_[a,b]

склеить строки a и b

max(max(a))

a.max() или np.nanmax(a)

максимальный элемент a (при ndims(a) <= 2 для MATLAB, если есть NaN, nanmax проигнорирует их и вернёт наибольшее значение)

max(a)

a.max(0)

максимальный элемент каждого столбца массива a

max(a,[],2)

a.max(1)

максимальный элемент каждой строки массива a

max(a,b)

np.maximum(a, b)

сравнивает a и b по элементам и возвращает максимальное значение из каждой пары

norm(v)

np.sqrt(v @ v) или np.linalg.norm(v)

норма L2 вектора v

a & b

logical_and(a,b)

бинарный оператор AND (ufunc NumPy) См. примечание LOGICOPS

a | b

np.logical_or(a,b)

бинарный оператор OR (ufunc NumPy) См. примечание LOGICOPS

bitand(a,b)

a & b

битовый оператор AND (встроенная функция Python и ufunc NumPy)

END_OF_DOCUMENT_MARKER

bitor(a,b)

a | b

битовый оператор OR (родной для Python и NumPy ufunc)

inv(a)

linalg.inv(a)

обратная матрица квадратной 2D-матрицы a

pinv(a)

linalg.pinv(a)

псевдообратная матрица 2D-матрицы a

rank(a)

linalg.matrix_rank(a)

ранг матрицы 2D-матрицы a

a\b

a квадратной; linalg.lstsq(a, b) в противном случае

решение уравнения ax = b для x

b/a

Решить a.T x.T = b.T вместо

решение уравнения xa = b для x

[U,S,V]=svd(a)

U, S, Vh = linalg.svd(a), V = Vh.T

разложение по сингулярным значениям a

c=chol(a) где a==c'*c

c = linalg.cholesky(a) где a == c@c.T

факторизация Холецкого 2D-матрицы (chol(a) в MATLAB возвращает верхнюю треугольную 2D-матрицу, но cholesky возвращает нижнюю треугольную 2D-матрицу)

[V,D]=eig(a)

D,V = linalg.eig(a)

собственные значения \(\lambda\) и собственные векторы \(\bar{v}\) a, где \(\lambda\bar{v}=\mathbf{a}\bar{v}\)

[V,D]=eig(a,b)

D,V = linalg.eig(a, b)

собственные значения \(\lambda\) и собственные векторы \(\bar{v}\) a, b где \(\lambda\mathbf{b}\bar{v}=\mathbf{a}\bar{v}\)

[V,D]=eigs(a,3)

D,V = eigs(a, k = 3)

найти k=3 наибольшие собственные значения и собственные векторы 2D-матрицы, a

[Q,R,P]=qr(a,0)

Q,R = linalg.qr(a)

разложение QR

[L,U,P]=lu(a) где a==P'*L*U

P,L,U = linalg.lu(a) где a == P@L@U

разложение LU (примечание: P(MATLAB) == транспонирование(P(NumPy)))

conjgrad

cg

решение методом сопряжённых градиентов

fft(a)

np.fft(a)

преобразование Фурье a

ifft(a)

np.ifft(a)

обратное преобразование Фурье a

sort(a)

np.sort(a) или a.sort(axis=0)

сортировка каждого столбца 2D-матрицы, a

sort(a, 2)

np.sort(a, axis = 1) или a.sort(axis = 1)

сортировка каждой строки 2D-матрицы, a

[b,I]=sortrows(a,1)

I = np.argsort(a[:, 0]); b = a[I,:]

сохранить массив a как массив b с отсортированными строками по первому столбцу

x = Z\y

x = linalg.lstsq(Z, y)

выполнить линейную регрессию в виде \(\mathbf{Zx}=\mathbf{y}\)

decimate(x, q)

signal.resample(x, np.ceil(len(x)/q))

уменьшение дискретизации с помощью фильтра низких частот

unique(a)

np.unique(a)

вектор уникальных значений в массиве a

squeeze(a)

a.squeeze()

удаление одноэлементных измерений массива a. Обратите внимание, что MATLAB всегда возвращает массивы размерности 2 или выше, а NumPy — размерности 0 или выше

Примечания

Подматрица: Присвоение подматрице может быть выполнено с помощью списков индексов, используя команду ix_. Например, для 2D-матрицы a, можно сделать: ind=[1, 3]; a[np.ix_(ind, ind)] += 100.

Справка: Нет прямого эквивалента команды MATLAB which, но команды help и numpy.source обычно отображают имя файла, где находится функция. Python также имеет модуль inspect (выполните import inspect), который предоставляет getfile инструмент, часто работающий.

ИНДЕКСИРОВАНИЕ: MATLAB использует индексацию, начинающуюся с 1, поэтому начальный элемент последовательности имеет индекс 1. Python использует нулевую индексацию, поэтому начальный элемент последовательности имеет индекс 0. Путаница и споры возникают, потому что у каждого есть преимущества и недостатки. Индексация, начинающаяся с 1, согласуется с обычным использованием естественного языка, где «первый» элемент последовательности имеет индекс 1. Нулевая индексация упрощает индексацию. См. также текст проф.др. Эдсгера В. Дейкстры.

ДИАПАЗОНЫ: В MATLAB 0:5 может использоваться как литерал диапазона, так и индекс «среза» (в скобках); однако в Python конструкции, подобные 0:5, только могут использоваться как индекс среза (в квадратных скобках). Таким образом, создан несколько странный r_ объект, позволяющий NumPy иметь аналогичный лаконичный механизм построения диапазонов. Обратите внимание, что r_ не вызывается как функция или конструктор, а индексируется с помощью квадратных скобок, что позволяет использовать синтаксис среза Python в аргументах.

ЛОГИЧЕСКИЕ ОПЕРАТОРЫ: & или | в NumPy — битовые AND/OR, а в MATLAB & и | — логические AND/OR. Они могут казаться одинаковыми, но есть важные различия. Если бы вы использовали операторы MATLAB & или |, вам следует использовать NumPy ufuncs logical_and/logical_or. Заметные различия между операторами MATLAB и NumPy & и |:

  • Ввод нелогического типа {0,1}: на выходе NumPy — битовое AND ввода. MATLAB рассматривает любое ненулевое значение как 1 и возвращает логическое AND. Например, (3 & 4) в NumPy — 0, а в MATLAB оба 3 и 4 считаются логической истиной, и (3 & 4) возвращает 1.
  • Приоритет: оператор & NumPy имеет более высокий приоритет, чем логические операторы, такие как < и >, в MATLAB — наоборот.

Если вы знаете, что у вас есть булевы аргументы, то можете обойтись операторами NumPy, но будьте осторожны с скобками, как в этом примере: z = (x > 1) & (x < 2). Отсутствие операторных форм NumPy logical_and и logical_or — нежелательный результат проектирования Python.

RESHAPE и ЛИНЕЙНАЯ ИНДЕКСАЦИЯ: MATLAB всегда позволяет обращаться к многомерным массивам с помощью скалярных или линейных индексов, NumPy — нет. Линейные индексы распространены в программах MATLAB, например, find() в матрице возвращает их, тогда как NumPy find ведёт себя по-другому. При конвертации кода MATLAB может потребоваться предварительно преобразовать матрицу в линейную последовательность, выполнить операции индексирования, а затем преобразовать обратно. Поскольку reshape (обычно) создаёт представления того же хранилища, это можно сделать достаточно эффективно. Обратите внимание, что порядок сканирования, используемый reshape в NumPy, по умолчанию — «C», а MATLAB использует порядок Fortran. Если вы просто преобразуете в линейную последовательность и обратно, это не имеет значения. Но если вы конвертируете reshape из кода MATLAB, который зависит от порядка сканирования, то этот код MATLAB: z = reshape(x,3,4); должен стать z = x.reshape(3,4,order='F').copy() в NumPy.

‘массив’ или ‘матрица’? Какой использовать?

Исторически NumPy предоставлял специальный тип матрицы, np.matrix, который является подклассом ndarray, делающим бинарные операции операциями линейной алгебры. Вы можете увидеть его в некоторых существующих кодах вместо np.array. Так какой использовать?

Кратко

Используйте массивы.

  • Они поддерживают многомерную алгебру массивов, которая поддерживается в MATLAB
  • Они являются стандартным типом векторов/матриц/тензоров NumPy. Многие функции NumPy возвращают массивы, а не матрицы.
  • Существует чёткое различие между поэлементными операциями и операциями линейной алгебры.
  • Вы можете иметь стандартные векторы или векторы строк/столбцов, если хотите.

До Python 3.5 единственным недостатком использования типа массива было то, что для умножения (сведения) двух тензоров (скалярное произведение, умножение матрицы на вектор и т. д.) нужно было использовать dot вместо *. С Python 3.5 вы можете использовать оператор матричного умножения @.

Учитывая вышесказанное, мы планируем в конечном итоге устареть matrix.

Подробно

NumPy содержит классы array и matrix. Класс array предназначен для использования в качестве многомерного массива общего назначения для многих видов числовых вычислений, а класс matrix — для облегчения вычислений линейной алгебры.

  • Операторы * и @, функции dot(), и multiply():

    • Для array, ``*`` означает поэлементное умножение, а ``@`` означает матричное умножение; они имеют связанные функции multiply() и dot(). (До Python 3.5, @ не существовало, и для матричного умножения нужно было использовать dot()).
    • Для matrix, ``*`` означает матричное умножение, а для поэлементного умножения нужно использовать функцию multiply().
  • Обработка векторов (одномерных массивов)

    • Для array, формы векторов 1xN, Nx1 и N — это разные вещи. Операции, такие как A[:,1] возвращают одномерный массив формы N, а не двумерный массив формы Nx1. Транспонирование одномерного array ничего не делает.
    • Для matrix, одномерные массивы всегда преобразуются в матрицы 1xN или Nx1 (строчный или столбец вектор). A[:,1] возвращает двумерную матрицу формы Nx1.
  • Обработка многомерных массивов (ndim > 2)

    • array объекты могут иметь число измерений > 2;
    • matrix объекты всегда имеют ровно два измерения.
  • Удобные атрибуты

    • array имеет атрибут .T, который возвращает транспонированную матрицу.
    • matrix также имеет атрибуты .H, .I и .A, которые возвращают сопряжённо-транспонированную, обратную и asarray() матрицы соответственно.
  • Удобный конструктор

    • Конструктор array принимает (вложенные) Python-последовательности в качестве инициализаторов. Как в array([[1,2,3],[4,5,6]]).
    • Конструктор matrix дополнительно принимает удобную строковую инициализацию. Как в matrix("[1 2 3; 4 5 6]").

Использование обоих вариантов имеет свои плюсы и минусы:

  • array

    • :) Поэлементное умножение простое: A*B.
    • :( Нужно помнить, что матричное умножение имеет свой оператор, @.
    • :) Одномерные массивы можно рассматривать как строчные или столбцовые векторы. A @ v рассматривает v как столбцовый вектор, в то время как v @ A рассматривает v как строчный вектор. Это экономит написание транспонирования.
    • :) array — это «стандартный» тип NumPy, поэтому он наиболее протестирован и чаще всего возвращается сторонним кодом, использующим NumPy.
    • :) Хорошо подходит для работы с данными любого числа измерений.
    • :) Более близкое соответствие семантике тензорной алгебры, если вы знакомы с ней.
    • :) Все операции (*, /, +, - и т. д.) выполняются поэлементно.
    • :( Разреженные матрицы из scipy.sparse не взаимодействуют так хорошо с массивами.
  • matrix

    • :\\ Поведение больше похоже на поведение матриц в MATLAB.
    • <:( Максимальное число измерений — два. Для хранения трёхмерных данных необходимо использовать array или, возможно, Python-список из matrix.
    • <:( Минимальное число измерений — два. Векторы недоступны. Их нужно преобразовать в матрицы с одним столбцом или одной строкой.
    • <:( Поскольку array — это стандартный тип NumPy, некоторые функции могут возвращать array даже если вы передадите им matrix в качестве аргумента. Этого не должно происходить с функциями NumPy (если происходит — это ошибка), но сторонний код, основанный на NumPy, может не поддерживать сохранение типа, как NumPy.
    • :) A*B — это матричное умножение, поэтому запись выглядит как в линейной алгебре (для Python >= 3.5 обычные массивы имеют ту же удобную возможность с оператором @).
    • <:( Для поэлементного умножения требуется вызов функции multiply(A,B).
    • <:( Использование перегрузки операторов немного нелогично: * не работает поэлементно, но / работает.
    • Взаимодействие с scipy.sparse немного чище.

Следовательно, гораздо предпочтительнее использовать array. На самом деле, мы намерены в конечном итоге устареть matrix.

Настройка вашей среды

В MATLAB основным инструментом для настройки среды является изменение пути поиска с расположением ваших любимых функций. Вы можете поместить такие настройки в скрипт запуска, который MATLAB будет запускать при старте.

NumPy, или скорее Python, имеют аналогичные возможности.

  • Для изменения пути поиска Python, чтобы включить расположение ваших собственных модулей, определите переменную среды PYTHONPATH.
  • Для запуска определённого скрипта при запуске интерактивного интерпретатора Python, определите переменную среды PYTHONSTARTUP, содержащую имя вашего скрипта запуска.

В отличие от MATLAB, где любой элемент пути можно вызывать сразу, в Python вам сначала нужно выполнить инструкцию «import», чтобы сделать функции в определённом файле доступными.

Например, вы можете создать скрипт запуска, который выглядит так (Примечание: это просто пример, а не «лучшие практики»):

# Make all numpy available via shorter 'np' prefix
import numpy as np
#
# Make the SciPy linear algebra functions available as linalg.func()
# e.g. linalg.lu, linalg.eig (for general l*B@u==A@u solution)
from scipy import linalg
#
# Define a Hermitian function
def hermitian(A, **kwargs):
    return np.conj(A,**kwargs).T
# Make a shortcut for hermitian:
#    hermitian(A) --> H(A)
H = hermitian

Для использования устаревшего matrix и других matlib функций:

# Make all matlib functions accessible at the top level via M.func()
import numpy.matlib as M
# Make some matlib functions accessible directly at the top level via, e.g. rand(3,3)
from numpy.matlib import matrix,rand,zeros,ones,empty,eye

Ссылки

Ещё одна несколько устаревшая справочная таблица MATLAB/NumPy доступна по адресу http://mathesaurus.sf.net/

Подробный список инструментов для научных работ с Python можно найти на странице специализированного программного обеспечения.

Список программного обеспечения, использующего Python в качестве скриптового языка, можно найти в списке программного обеспечения Python

MATLAB® и SimuLink® — зарегистрированные товарные знаки компании The MathWorks, Inc.

© 2005–2022 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.21/user/numpy-for-matlab-users.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API