Как найти ранг матрицы в питоне

linalg.matrix_rank(A, tol=None, hermitian=False)[source]#

Return matrix rank of array using SVD method

Rank of the array is the number of singular values of the array that are
greater than tol.

Changed in version 1.14: Can now operate on stacks of matrices

Parameters:
A{(M,), (…, M, N)} array_like

Input vector or stack of matrices.

tol(…) array_like, float, optional

Threshold below which SVD values are considered zero. If tol is
None, and S is an array with singular values for M, and
eps is the epsilon value for datatype of S, then tol is
set to S.max() * max(M, N) * eps.

Changed in version 1.14: Broadcasted against the stack of matrices

hermitianbool, optional

If True, A is assumed to be Hermitian (symmetric if real-valued),
enabling a more efficient method for finding singular values.
Defaults to False.

New in version 1.14.

Returns:
rank(…) array_like

Rank of A.

Notes

The default threshold to detect rank deficiency is a test on the magnitude
of the singular values of A. By default, we identify singular values less
than S.max() * max(M, N) * eps as indicating rank deficiency (with
the symbols defined above). This is the algorithm MATLAB uses [1]. It also
appears in Numerical recipes in the discussion of SVD solutions for linear
least squares [2].

This default threshold is designed to detect rank deficiency accounting for
the numerical errors of the SVD computation. Imagine that there is a column
in A that is an exact (in floating point) linear combination of other
columns in A. Computing the SVD on A will not produce a singular value
exactly equal to 0 in general: any difference of the smallest SVD value from
0 will be caused by numerical imprecision in the calculation of the SVD.
Our threshold for small SVD values takes this numerical imprecision into
account, and the default threshold will detect such numerical rank
deficiency. The threshold may declare a matrix A rank deficient even if
the linear combination of some columns of A is not exactly equal to
another column of A but only numerically very close to another column of
A.

We chose our default threshold because it is in wide use. Other thresholds
are possible. For example, elsewhere in the 2007 edition of Numerical
recipes
there is an alternative threshold of S.max() *
np.finfo(A.dtype).eps / 2. * np.sqrt(m + n + 1.)
. The authors describe
this threshold as being based on “expected roundoff error” (p 71).

The thresholds above deal with floating point roundoff error in the
calculation of the SVD. However, you may have more information about the
sources of error in A that would make you consider other tolerance values
to detect effective rank deficiency. The most useful measure of the
tolerance depends on the operations you intend to use on your matrix. For
example, if your data come from uncertain measurements with uncertainties
greater than floating point epsilon, choosing a tolerance near that
uncertainty may be preferable. The tolerance may be absolute if the
uncertainties are absolute rather than relative.

References

[2]

W. H. Press, S. A. Teukolsky, W. T. Vetterling and B. P. Flannery,
“Numerical Recipes (3rd edition)”, Cambridge University Press, 2007,
page 795.

Examples

>>> from numpy.linalg import matrix_rank
>>> matrix_rank(np.eye(4)) # Full rank matrix
4
>>> I=np.eye(4); I[-1,-1] = 0. # rank deficient matrix
>>> matrix_rank(I)
3
>>> matrix_rank(np.ones((4,))) # 1 dimension - rank 1 unless all 0
1
>>> matrix_rank(np.zeros((4,)))
0

Содержание

  • NumPy: матрицы и операции над ними
  • 1. Создание матриц
  • 2. Индексирование
  • 3. Векторы, вектор-строки и вектор-столбцы
  • 4. Datatypes
  • 5. Математические операции
  • 6. Умножение матриц и столбцов
  • 7. Объединение массивов
    • Задания: (Блок 1)
      • Задание 1:
      • Задание 2:
  • 8. Транспонирование матриц
  • 9. Определитель матрицы
  • 10. Ранг матрицы
  • 11. Системы линейных уравнений
  • 12. Обращение матриц
  • 13. Собственные числа и собственные вектора матрицы
  • 14. Расстояния между векторами
    • p-норма
    • 1 норма
    • 2 норма
  • 15. Расстояния между векторами
  • 16. Скалярное произведение и угол между векторами
  • 17. Комплексные числа в питоне
    • Задания: (Блок 2)
      • Задание 3:

NumPy: матрицы и операции над ними

Ссылка на jupyter notebook

В этом ноутбуке из сторонних библиотек нам понадобится только NumPy.
Для удобства импортируем ее под более коротким именем:

import numpy as np

1. Создание матриц

Приведем несколько способов создания матриц в NumPy.

Самый простой способ — с помощью функции
numpy.array(list, dtype=None, …).

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

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

Например, матрицу из списка списков целых чисел можно создать следующим
образом:

a = np.array([1, 2, 3])   # Создаем одномерный массив
print(type(a))            # Prints "<class 'numpy.ndarray'>"
print(a.shape)            # Prints "(3,)" - кортеж с размерностями
print(a[0], a[1], a[2])   # Prints "1 2 3"
a[0] = 5                  # Изменяем значение элемента массива
print(a)                  # Prints "[5, 2, 3]"

b = np.array([[1,2,3],[4,5,6]])    # Создаем двухмерный массив
print(b.shape)                     # Prints "(2, 3)"
print(b[0, 0], b[0, 1], b[1, 0])   # Prints "1 2 4"
print(np.arange(1, 5)) #Cоздает вектор с эелементами от 1 до 4
<class 'numpy.ndarray'>
(3,)
1 2 3
[5 2 3]
(2, 3)
1 2 4
[1 2 3 4]
matrix = np.array([[1, 2, 3], [2, 5, 6], [6, 7, 4]])
print ("Матрица:n", matrix)
Матрица:
 [[1 2 3]
 [2 5 6]
 [6 7 4]]

Второй способ создания — с помощью встроенных функций
numpy.eye(N, M=None, …), numpy.zeros(shape, …),
numpy.ones(shape, …).

Первая функция создает единичную матрицу размера N×M;
если M не задан, то M = N.

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

Примеры:

b = np.eye(5)
print ("Единичная матрица:n", b)
Единичная матрица:
 [[1. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0.]
 [0. 0. 1. 0. 0.]
 [0. 0. 0. 1. 0.]
 [0. 0. 0. 0. 1.]]
c = np.ones((7, 5))
print ("Матрица, состоящая из одних единиц:n", c)
Матрица, состоящая из одних единиц:
 [[1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1.]]
d = np.full((2,2), 7)  # Создает матрицу (1, 2) заполненую заданным значением
print(d)               # Prints "[[ 7.  7.]
                       #          [ 7.  7.]]"

e = np.random.random((2,2))  # Создает еденичную матрицу (2, 2) заполненую случаными числами (0, 1)
print(e)                     # Might print "[[ 0.91940167  0.08143941]
                             #               [ 0.68744134  0.87236687]]"
[[7 7]
 [7 7]]
[[0.25744383 0.48056466]
 [0.13767881 0.40578168]]

Обратите внимание: размерность массива задается не двумя аргументами
функции, а одним — кортежем!

Вот так — np.ones(7, 5) — создать массив не получится, так как
функции в качестве параметра shape передается 7, а не кортеж
(7, 5).

И, наконец, третий способ — с помощью функции
numpy.arange([start, ]stop, [step, ], …), которая создает
одномерный массив последовательных чисел из промежутка
[start, stop) с заданным шагом step, и метода
array.reshape(shape).

Параметр shape, как и в предыдущем примере, задает размерность
матрицы (кортеж чисел). Логика работы метода ясна из следующего примера:

v = np.arange(0, 24, 2)
print ("Вектор-столбец:n", v)
Вектор-столбец:
 [ 0  2  4  6  8 10 12 14 16 18 20 22]
d = v.reshape((3, 4))
print ("Матрица:n", d)
Матрица:
 [[ 0  2  4  6]
 [ 8 10 12 14]
 [16 18 20 22]]

Более подробно о том, как создавать массивы в NumPy, см.
документацию.

2. Индексирование

Для получения элементов матрицы можно использовать несколько способов.
Рассмотрим самые простые из них.

Для удобства напомним, как выглядит матрица d:

print ("Матрица:n", d)
Матрица:
 [[ 0  2  4  6]
 [ 8 10 12 14]
 [16 18 20 22]]

Элемент на пересечении строки i и столбца j можно
получить с помощью выражения array[i, j].

Обратите внимание: строки и столбцы нумеруются с нуля!

print ("Второй элемент третьей строки матрицы:", d[2, 1])
Второй элемент третьей строки матрицы: 18

Из матрицы можно получать целые строки или столбцы с помощью выражений
array[i, :] или array[:, j] соответственно:

print ("Вторая строка матрицы d:n", d[1, :])
print ("Четвертый столбец матрицы d:n", d[:, 3])
Вторая строка матрицы d:
 [ 8 10 12 14]
Четвертый столбец матрицы d:
 [ 6 14 22]

Еще один способ получения элементов — с помощью выражения
array[list1, list2], где list1, list2
некоторые списки целых чисел. При такой адресации одновременно
просматриваются оба списка и возвращаются элементы матрицы с
соответствующими координатами. Следующий пример более понятно объясняет
механизм работы такого индексирования:

print ("Элементы матрицы d с координатами (1, 2) и (0, 3):n", d[[1, 0], [2, 3]])
Элементы матрицы d с координатами (1, 2) и (0, 3):
 [12  6]
# Slicing

# Создадим матрицу (3, 4)
# [[ 1  2  3  4]
#  [ 5  6  7  8]
#  [ 9 10 11 12]]
a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])

# Используя слайсинг, созадим матрицу b из элементов матрицы а
# будем использовать 0 и 1 строку, а так же 1 и 2 столебц
# [[2 3]
#  [6 7]]
b = a[:2, 1:3]
print(b)

# ОБРАТИТЕ ВНИМАНИЕ НА ИЗМЕНЕНИЕ ИСХОДОЙ МАТРИЦЫ
print(a[0, 1])   # Prints "2"
b[0, 0] = 77     # b[0, 0] is the same piece of data as a[0, 1]
print(a[0, 1])   # Prints "77"
[[2 3]
 [6 7]]
2
77
# Integer array indexing

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

# Пример Integer array indexing
# В результате получится массив размерности (3,)
# Обратите внимание, что до запятой идут индексы строк, после - столбцов
print(a[[0, 1, 2], [0, 1, 0]])  # Prints "[1 4 5]"
print()

# По-другому пример можно записать так
print(np.array([a[0, 0], a[1, 1], a[2, 0]]))  # Prints "[1 4 5]"
[[1 2]
 [3 4]
 [5 6]]

[1 4 5]

[1 4 5]

Примеры использования слайсинга:

# Создадим новый маассив, из которого будем выбирать эллементы
a = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])

print(a)  # prints "array([[ 1,  2,  3],
          #                [ 4,  5,  6],
          #                [ 7,  8,  9],
          #                [10, 11, 12]])"

# Создадим массив индексов
b = np.array([0, 2, 0, 1])

# Выберем из каждой строки элемент с индексом из b (индекс столбца берется из b)
print(a[np.arange(4), b])  # Prints "[ 1  6  7 11]"
print()

# Добавим к этим элементам 10
a[np.arange(4), b] += 10

print(a)  # prints "array([[11,  2,  3],
          #                [ 4,  5, 16],
          #                [17,  8,  9],
          #                [10, 21, 12]])
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]
[ 1  6  7 11]

[[11  2  3]
 [ 4  5 16]
 [17  8  9]
 [10 21 12]]
a = np.array([[1,2], [3, 4], [5, 6]])

bool_idx = (a > 2)   # Найдем эллементы матрицы a, которые больше 2
                     # В результате получим матрицу b, такой же размерности, как и a

print(bool_idx)      # Prints "[[False False]
print()              #          [ True  True]
                     #          [ True  True]]"

# Воспользуемся полученным массивом для создания нового массива, ранга 1
print(a[bool_idx])  # Prints "[3 4 5 6]"

# Аналогично
print(a[a > 2])     # Prints "[3 4 5 6]"
[[False False]
 [ True  True]
 [ True  True]]

[3 4 5 6]
[3 4 5 6]
#Помните, что вы можете пользоваться сразу несколькими типами индексирования
a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])

row_r1 = a[1, :]
row_r2 = a[1:2, :]
print(row_r1, row_r1.shape)  # Prints "[5 6 7 8] (4,)"
print(row_r2, row_r2.shape)  # Prints "[[5 6 7 8]] (1, 4)"
[5 6 7 8] (4,)
[[5 6 7 8]] (1, 4)

Более подробно о различных способах индексирования в массивах см.
документацию.

3. Векторы, вектор-строки и вектор-столбцы

Следующие два способа задания массива кажутся одинаковыми:

a = np.array([1, 2, 3])
b = np.array([[1], [2], [3]])

Однако, на самом деле, это задание одномерного массива (то есть
вектора) и двумерного массива:

print ("Вектор:n", a)
print ("Его размерность:n", a.shape)
print ("Двумерный массив:n", b)
print ("Его размерность:n", b.shape)
Вектор:
 [1 2 3]
Его размерность:
 (3,)
Двумерный массив:
 [[1]
 [2]
 [3]]
Его размерность:
 (3, 1)

Обратите внимание: вектор (одномерный массив) и вектор-столбец
или вектор-строка (двумерные массивы) являются различными объектами в
NumPy, хотя математически задают один и тот же объект. В случае
одномерного массива кортеж shape состоит из одного числа и имеет
вид (n,), где n — длина вектора. В случае двумерных
векторов в shape присутствует еще одна размерность, равная
единице.

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

a = a.T
b = b.T
print ("Вектор не изменился:n", a)
print ("Его размерность также не изменилась:n", a.shape)
print ("Транспонированный двумерный массив:n", b)
print ("Его размерность изменилась:n", b.shape)
Вектор не изменился:
 [1 2 3]
Его размерность также не изменилась:
 (3,)
Транспонированный двумерный массив:
 [[1 2 3]]
Его размерность изменилась:
 (1, 3)

4. Datatypes

Все элементы в массиве numpy принадлежат одному типу. В этом плане
массивы ближе к C, чем к привычным вам листам питона. Numpy имеет
множество встренных типов, подходящих для решения большинства задач.

x = np.array([1, 2])   # Автоматический выбор типа
print(x.dtype)         # Prints "int64"

x = np.array([1.0, 2.0])   # Автоматический выбор типа
print(x.dtype)             # Prints "float64"

x = np.array([1, 2], dtype=np.int64)   # Принудительное выставление типа
print(x.dtype)                         # Prints "int64"
int32
float64
int64

5. Математические операции

К массивам (матрицам) можно применять известные вам математические
операции. Следут понимать, что при этом у элементов должны быть схожие
размерности. Поведение в случае не совпадения размерностей хорошо
описанно в документации numpy.

x = np.array([[1,2],[3,4]], dtype=np.float64)
y = np.array([[5,6],[7,8]], dtype=np.float64)
arr = np.array([1, 2])
# Сложение происходит поэлеметно

# [[ 6.0  8.0]
#  [10.0 12.0]]
print(x + y)
print()
print(np.add(x, y))
print('С числом')
print(x + 1)
print('C массивом другой размерности')
print(x + arr)
[[ 6.  8.]
 [10. 12.]]

[[ 6.  8.]
 [10. 12.]]
С числом
[[2. 3.]
 [4. 5.]]
C массивом другой размерности
[[2. 4.]
 [4. 6.]]
# Вычитание
print(x - y)
print(np.subtract(x, y))
[[-4. -4.]
 [-4. -4.]]
[[-4. -4.]
 [-4. -4.]]
# Деление
# [[ 0.2         0.33333333]
#  [ 0.42857143  0.5       ]]
print(x / y)
print(np.divide(x, y))
[[0.2        0.33333333]
 [0.42857143 0.5       ]]
[[0.2        0.33333333]
 [0.42857143 0.5       ]]
# Другие функции
# [[ 1.          1.41421356]
#  [ 1.73205081  2.        ]]
print(np.sqrt(x))
[[1.         1.41421356]
 [1.73205081 2.        ]]

6. Умножение матриц и столбцов

Напоминание теории. Операция умножения определена для двух
матриц, таких что число столбцов первой равно числу строк второй.

Пусть матрицы A и B таковы, что
A ∈ ℝn×k и
B ∈ ℝk×m. Произведением матриц
A и B называется матрица C, такая что
cij = kr = 1airbrj, где cij
элемент матрицы C, стоящий на пересечении строки с номером
i и столбца с номером j.

В NumPy произведение матриц вычисляется с помощью функции
numpy.dot(a, b, …) или с помощью метода
array1.dot(array2), где array1 и array2
перемножаемые матрицы.

a = np.array([[1, 0], [0, 1]])
b = np.array([[4, 1], [2, 2]])
r1 = np.dot(a, b)
r2 = a.dot(b)
print ("Матрица A:n", a)
print ("Матрица B:n", b)
print ("Результат умножения функцией:n", r1)
print ("Результат умножения методом:n", r2)
Матрица A:
 [[1 0]
 [0 1]]
Матрица B:
 [[4 1]
 [2 2]]
Результат умножения функцией:
 [[4 1]
 [2 2]]
Результат умножения методом:
 [[4 1]
 [2 2]]

Матрицы в NumPy можно умножать и на векторы:

c = np.array([1, 2])
r3 = b.dot(c)
print ("Матрица:n", b)
print ("Вектор:n", c)
print ("Результат умножения:n", r3)
Матрица:
 [[4 1]
 [2 2]]
Вектор:
 [1 2]
Результат умножения:
 [6 6]

Обратите внимание: операция * производит над матрицами
покоординатное умножение, а не матричное!

r = a * b
print ("Матрица A:n", a)
print ("Матрица B:n", b)
print ("Результат покоординатного умножения через операцию умножения:n", r)
Матрица A:
 [[1 0]
 [0 1]]
Матрица B:
 [[4 1]
 [2 2]]
Результат покоординатного умножения через операцию умножения:
 [[4 0]
 [0 2]]

Более подробно о матричном умножении в NumPy см.
документацию.

7. Объединение массивов

Массивы можно Объединенять. Есть горизонтальное и вертикальное
объединение.

a = np.floor(10*np.random.random((2,2)))
b = np.floor(10*np.random.random((2,2)))

print(a)
print(b)
print()


print(np.vstack((a,b)))
print()

print(np.hstack((a,b)))
[[4. 0.]
 [1. 4.]]
[[9. 7.]
 [2. 6.]]

[[4. 0.]
 [1. 4.]
 [9. 7.]
 [2. 6.]]

[[4. 0. 9. 7.]
 [1. 4. 2. 6.]]

Массивы можно переформировать при помощи метода, который задает новый
многомерный массив. Следуя следующему примеру, мы переформатируем
одномерный массив из десяти элементов во двумерный массив, состоящий из
пяти строк и двух столбцов:

a = np.array(range(10), float)
print(a)
print()

# Превратим в матрицу
a = a.reshape((5, 2))
print(a)
print()

# Вернем обратно
print(a.flatten())

# Другой вариант
print(a.reshape((-1)))
# Превратим в марицу (9, 1)
print(a.reshape((-1, 1)))
# Превратим в марицу (1, 9)
print(a.reshape((1, -1)))
[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]

[[0. 1.]
 [2. 3.]
 [4. 5.]
 [6. 7.]
 [8. 9.]]

[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
[[0.]
 [1.]
 [2.]
 [3.]
 [4.]
 [5.]
 [6.]
 [7.]
 [8.]
 [9.]]
[[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]]

Задания: (Блок 1)

Задание 1:

Решите без использования циклов средставми NumPy (каждый пункт решается
в 1-2 строчки)

  1. Создайте вектор с элементами от 12 до 42
  2. Создайте вектор из нулей длины 12, но его пятый елемент должен быть равен 1
  3. Создайте матрицу (3, 3), заполненую от 0 до 8
  4. Найдите все положительные числа в np.array([1,2,0,0,4,0])
  5. Умножьте матрицу размерности (5, 3) на (3, 2)
  6. Создайте матрицу (10, 10) так, чтобы на границе были 0, а внтури 1
  7. Создайте рандомный вектор и отсортируйте его
  8. Каков эквивалент функции enumerate для numpy массивов?
  9. *Создайте рандомный вектор и выполните нормализацию столбцов (из каждого столбца вычесть среднее этого столбца, из каждого столбца вычесть sd этого столбца)
  10. *Для заданного числа найдите ближайший к нему элемент в векторе
  11. *Найдите N наибольших значений в векторе
# ваш код здесь

Задание 2:

Напишите полностью векторизованный вариант

Дан трёхмерный массив, содержащий изображение, размера (height, width,
numChannels), а также вектор длины numChannels. Сложить каналы
изображения с указанными весами, и вернуть результат в виде матрицы
размера (height, width). Считать реальное изображение можно при помощи
функции

scipy.misc.imread

(если изображение не в формате png,
установите пакет pillow:

conda install pillow

). Преобразуйте
цветное изображение в оттенки серого, использовав коэффициенты
np.array([0.299, 0.587, 0.114]).

# ваш код здесь

8. Транспонирование матриц

Напоминание теории. Транспонированной матрицей AT
называется матрица, полученная из исходной матрицы A заменой
строк на столбцы. Формально: элементы матрицы AT определяются
как aTij = aji, где aTij — элемент
матрицы AT, стоящий на пересечении строки с номером i
и столбца с номером j.

В NumPy транспонированная матрица вычисляется с помощью функции
numpy.transpose() или с помощью метода array.T, где
array — нужный двумерный массив.

a = np.array([[1, 2], [3, 4]])
b = np.transpose(a)
c = a.T
print ("Матрица:n", a)
print ("Транспонирование функцией:n", b)
print ("Транспонирование методом:n",  c)
Матрица:
 [[1 2]
 [3 4]]
Транспонирование функцией:
 [[1 3]
 [2 4]]
Транспонирование методом:
 [[1 3]
 [2 4]]

См. более подробно о
numpy.transpose()
и
array.T
в NumPy.

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

9. Определитель матрицы

Напоминание теории. Для квадратных матриц существует понятие
определителя.

Пусть A — квадратная матрица. Определителем (или
детерминантом) матрицы A ∈ ℝn×n назовем
число

detA = α1, α2, …, αn( − 1)N(α1, α2, …, αn)aα11⋅⋅⋅aαnn, 

где α1, α2, …, αn — перестановка
чисел от 1 до n,
N(α1, α2, …, αn) — число инверсий в
перестановке, суммирование ведется по всем возможным перестановкам длины
n.

Не стоит расстраиваться, если это определение понятно не до конца — в
дальнейшем в таком виде оно не понадобится.

Например, для матрицы размера 2×2 получается:

det

a11


a12











a21


a22


 = a11a22 − a12a21

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

В NumPy определитель матрицы вычисляется с помощью функции
numpy.linalg.det(a), где a — исходная матрица.

a = np.array([[1, 2, 1], [1, 1, 4], [2, 3, 6]], dtype=np.float32)
det = np.linalg.det(a)
print ("Матрица:n", a)
print ("Определитель:n", det)
Матрица:
 [[1. 2. 1.]
 [1. 1. 4.]
 [2. 3. 6.]]
Определитель:
 -1.0

Рассмотрим одно интересное свойство определителя. Пусть у нас есть
параллелограмм с углами в точках
(0, 0), (c, d), (a + c, b + d), (a, b) (углы даны в порядке обхода по
часовой стрелке). Тогда площадь этого параллелограмма можно вычислить
как модуль определителя матрицы


a


c











b


d


.
Похожим образом можно выразить и объем параллелепипеда через
определитель матрицы размера 3×3.

10. Ранг матрицы

Напоминание теории. Рангом матрицы A называется
максимальное число линейно независимых строк (столбцов) этой матрицы.

В NumPy ранг матрицы вычисляется с помощью функции
numpy.linalg.matrix_rank(M, tol=None), где M — матрица,
tol — параметр, отвечающий за некоторую точность вычисления. В
простом случае можно его не задавать, и функция сама определит
подходящее значение этого параметра.

a = np.array([[1, 2, 3], [1, 1, 1], [2, 2, 2]])
r = np.linalg.matrix_rank(a)
print ("Матрица:n", a)
print ("Ранг матрицы:", r)
Матрица:
 [[1 2 3]
 [1 1 1]
 [2 2 2]]
Ранг матрицы: 2

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

Допустим, у нас есть несколько векторов. Составим из них матрицу, где
наши векторы будут являться строками. Понятно, что векторы линейно
независимы тогда и только тогда, когда ранг полученной матрицы совпадает
с числом векторов. Приведем пример:

a = np.array([1, 2, 3])
b = np.array([1, 1, 1])
c = np.array([2, 3, 5])
m = np.array([a, b, c])
print (np.linalg.matrix_rank(m) == m.shape[0])
True

11. Системы линейных уравнений

Напоминание теории. Системой линейных алгебраических уравнений
называется система вида Ax = b, где
A ∈ ℝn×m, x ∈ ℝm×1, b ∈ ℝn×1.
В случае квадратной невырожденной матрицы A решение системы
единственно.

В NumPy решение такой системы можно найти с помощью функции
numpy.linalg.solve(a, b), где первый аргумент — матрица
A, второй — столбец b.

a = np.array([[3, 1], [1, 2]])
b = np.array([9, 8])
x = np.linalg.solve(a, b)
print ("Матрица A:n", a)
print ("Вектор b:n", b)
print ("Решение системы:n", x)
Матрица A:
 [[3 1]
 [1 2]]
Вектор b:
 [9 8]
Решение системы:
 [2. 3.]

Убедимся, что вектор x действительно является решением системы:

print (a.dot(x))
[9. 8.]

Бывают случаи, когда решение системы не существует. Но хотелось бы все
равно “решить” такую систему. Логичным кажется искать такой вектор
x, который минимизирует выражение
Ax − b2 — так мы приблизим выражение
Ax к b.

В NumPy такое псевдорешение можно искать с помощью функции
numpy.linalg.lstsq(a, b, …), где первые два аргумента такие
же, как и для функции numpy.linalg.solve(). Помимо решения
функция возвращает еще три значения, которые нам сейчас не понадобятся.

a = np.array([[0, 1], [1, 1], [2, 1], [3, 1]])
b = np.array([-1, 0.2, 0.9, 2.1])
x, res, r, s = np.linalg.lstsq(a, b, rcond=None)
print ("Матрица A:n", a)
print ("Вектор b:n", b)
print ("Псевдорешение системы:n", x)
Матрица A:
 [[0 1]
 [1 1]
 [2 1]
 [3 1]]
Вектор b:
 [-1.   0.2  0.9  2.1]
Псевдорешение системы:
 [ 1.   -0.95]

12. Обращение матриц

Напоминание теории. Для квадратных невырожденных матриц определено
понятие обратной матрицы.

Пусть A — квадратная невырожденная матрица. Матрица
A − 1 называется обратной матрицей к A, если

AA − 1 = A − 1A = I, 

где I — единичная матрица.

В NumPy обратные матрицы вычисляются с помощью функции
numpy.linalg.inv(a), где a — исходная матрица.

a = np.array([[1, 2, 1], [1, 1, 4], [2, 3, 6]], dtype=np.float32)
b = np.linalg.inv(a)
print ("Матрица A:n", a)
print ("Обратная матрица к A:n", b)
print ("Произведение A на обратную должна быть единичной:n", a.dot(b))
Матрица A:
 [[1. 2. 1.]
 [1. 1. 4.]
 [2. 3. 6.]]
Обратная матрица к A:
 [[ 6.  9. -7.]
 [-2. -4.  3.]
 [-1. -1.  1.]]
Произведение A на обратную должна быть единичной:
 [[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]

13. Собственные числа и собственные вектора матрицы

Напоминание теории. Для квадратных матриц определены понятия
собственного вектора и собственного числа.

Пусть A — квадратная матрица и
A ∈ ℝn×n. Собственным вектором матрицы
A называется такой ненулевой вектор
x ∈ ℝn, что для некоторого
λ ∈ ℝ выполняется равенство
Ax = λx. При этом λ называется
собственным числом матрицы A. Собственные числа и
собственные векторы матрицы играют важную роль в теории линейной алгебры
и ее практических приложениях.

В NumPy собственные числа и собственные векторы матрицы вычисляются
с помощью функции numpy.linalg.eig(a), где a — исходная
матрица. В качестве результата эта функция выдает одномерный массив
w собственных чисел и двумерный массив v, в котором по
столбцам записаны собственные вектора, так что вектор v[:, i]
соотвествует собственному числу w[i].

a = np.array([[-1, -6], [2, 6]])
w, v = np.linalg.eig(a)
print ("Матрица A:n", a)
print ("Собственные числа:n", w)
print ("Собственные векторы:n", v)
Матрица A:
 [[-1 -6]
 [ 2  6]]
Собственные числа:
 [2. 3.]
Собственные векторы:
 [[-0.89442719  0.83205029]
 [ 0.4472136  -0.5547002 ]]

Обратите внимание: у вещественной матрицы собственные значения или
собственные векторы могут быть комплексными.

14. Расстояния между векторами

Вспомним некоторые нормы, которые можно ввести в пространстве
n, и рассмотрим, с помощью каких библиотек и
функций их можно вычислять в NumPy.

p-норма

p-норма (норма Гёльдера) для вектора
x = (x1, …, xn) ∈ ℝn вычисляется по
формуле:

xp = (ni = 1|xi|p)1 ⁄ p,  p ≥ 1.

В частных случаях при: * p = 1 получаем 1 норму
* p = 2 получаем 2 норму

Далее нам понабится модуль numpy.linalg, реализующий некоторые
приложения линейной алгебры. Для вычисления различных норм мы используем
функцию numpy.linalg.norm(x, ord=None, …), где x
исходный вектор, ord — параметр, определяющий норму (мы
рассмотрим два варианта его значений — 1 и 2). Импортируем эту функцию:

from numpy.linalg import norm

1 норма

1 норма (также известная как манхэттенское
расстояние)
для вектора x = (x1, …, xn) ∈ ℝn
вычисляется по формуле:

x1 = ni = 1|xi|.

Ей в функции numpy.linalg.norm(x, ord=None, …) соответствует
параметр ord=1.

a = np.array([1, 2, -3])
print('Вектор a:', a)
Вектор a: [ 1  2 -3]
print('L1 норма вектора a:n', norm(a, ord=1))
L1 норма вектора a:
 6.0

2 норма

2 норма (также известная как евклидова норма) для вектора
x = (x1, …, xn) ∈ ℝn вычисляется по
формуле:

x2 = (ni = 1(xi)2).

Ей в функции numpy.linalg.norm(x, ord=None, …) соответствует
параметр ord=2.

print ('L2 норма вектора a:n', norm(a, ord=2))
L2 норма вектора a:
 3.7416573867739413

Более подробно о том, какие еще нормы (в том числе матричные) можно
вычислить, см.
документацию.

15. Расстояния между векторами

Для двух векторов x = (x1, …, xn) ∈ ℝn и
y = (y1, …, yn) ∈ ℝn 1 и
2 раccтояния вычисляются по следующим формулам
соответственно:

ρ1(x, y) = x − y1 = ni = 1|xi − yi|

ρ2(x, y) = x − y2 = (ni = 1(xi − yi)2).

a = np.array([1, 2, -3])
b = np.array([-4, 3, 8])
print ('Вектор a:', a)
print ('Вектор b:', b)
Вектор a: [ 1  2 -3]
Вектор b: [-4  3  8]
print ('L1 расстояние между векторами a и b:n', norm(a - b, ord=1))
print ('L2 расстояние между векторами a и b:n', norm(a - b, ord=2))
L1 расстояние между векторами a и b:
 17.0
L2 расстояние между векторами a и b:
 12.12435565298214

16. Скалярное произведение и угол между векторами

a = np.array([0, 5, -1])
b = np.array([-4, 9, 3])
print ('Вектор a:', a)
print ('Вектор b:', b)
Вектор a: [ 0  5 -1]
Вектор b: [-4  9  3]

Скалярное произведение в пространстве n для двух
векторов x = (x1, …, xn) и
y = (y1, …, yn) определяется как:

x, y⟩ = ni = 1xiyi.

Длиной вектора x = (x1, …, xn) ∈ ℝn
называется квадратный корень из скалярного произведения, то есть длина
равна евклидовой норме вектора:

|x| = (x, x) = (ni = 1x2i) = x2.

Теперь, когда мы знаем расстояние между двумя ненулевыми векторами и их
длины, мы можем вычислить угол между ними через скалярное произведение:

x, y⟩ = |x||y|cos(α) ⟹ cos(α) = (x, y)/(|x||y|), 

где α ∈ [0, π] — угол между векторами x и
y.

cos_angle = np.dot(a, b) / norm(a) / norm(b)
print ('Косинус угла между a и b:', cos_angle)
print ('Сам угол:', np.arccos(cos_angle))
Косинус угла между a и b: 0.8000362836474323
Сам угол: 0.6434406336093618

17. Комплексные числа в питоне

Напоминание теории. Комплексными числами называются числа вида
x + iy, где x и y — вещественные числа, а
i — мнимая единица (величина, для которой выполняется равенство
i2 =  − 1). Множество всех комплексных чисел обозначается
буквой (подробнее про комплексные числа см.
википедию).

В питоне комплескные числа можно задать следующим образом (j
обозначает мнимую единицу):

a = 3 + 2j
b = 1j
print ("Комплексное число a:n", a)
print ("Комплексное число b:n", b)
Комплексное число a:
 (3+2j)
Комплексное число b:
 1j

С комплексными числами в питоне можно производить базовые арифметические
операции так же, как и с вещественными числами:

c = a * a
d = a / (4 - 5j)
print ("Комплексное число c:n", c)
print ("Комплексное число d:n", d)
Комплексное число c:
 (5+12j)
Комплексное число d:
 (0.0487804878048781+0.5609756097560976j)

Задания: (Блок 2)

Задание 3:

Рассмотрим сложную математическую функцию на отрезке [1, 15]:

f(x) = sin(x / 5) * exp(x / 10) + 5 * exp(-x / 2)

images/lab14/func.png

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

Как известно, многочлен степени n (то есть w0 +
w1x + w2x2 + + wnxn)
однозначно определяется любыми n + 1 различными точками, через которые
он проходит. Это значит, что его коэффициенты w0, … wn
можно определить из следующей системы линейных уравнений:

images/lab14/eqs.png

где через x1, …, xn, xn + 1 обозначены точки, через которые
проходит многочлен, а через f(x1), …, f(xn), f(xn + 1)
значения, которые он должен принимать в этих точках.

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

  1. Сформируйте систему линейных уравнений (то есть задайте матрицу
    коэффициентов A и свободный вектор b) для многочлена первой степени,
    который должен совпадать с функцией f в точках 1 и 15. Решите данную
    систему с помощью функции scipy.linalg.solve. Нарисуйте функцию f и
    полученный многочлен. Хорошо ли он приближает исходную функцию?
  2. Повторите те же шаги для многочлена второй степени, который совпадает
    с функцией f в точках 1, 8 и 15. Улучшилось ли качество
    аппроксимации?
  3. Повторите те же шаги для многочлена третьей степени, который
    совпадает с функцией f в точках 1, 4, 10 и 15. Хорошо ли он
    аппроксимирует функцию? Коэффициенты данного многочлена (четыре числа
    в следующем порядке: w_0, w_1, w_2, w_3) являются ответом на задачу.
    Округлять коэффициенты не обязательно, но при желании можете
    произвести округление до второго знака (т.е. до числа вида 0.42)

Пятый урок посвящен нахождению обратной матрицы, ее свойствам, а также определению ранга матрицы

  • Обратная матрица
  • Ранг матрицы

Обратная матрица

Обратной матрицей A-1 матрицы A называют матрицу, удовлетворяющую следующему равенству:

где – E это единичная матрица.

Для того, чтобы у квадратной матрицы A была обратная матрица необходимо и достаточно чтобы определитель |A| был не равен нулю. Введем понятие союзной матрицы. Союзная матрица A* строится на базе исходной A путем замены всех элементов матрицы A на их алгебраические дополнения.

Исходная матрица:

Союзная ей матрица A*:

Транспонируя матрицу A*, мы получим так называемую присоединенную матрицу A*T:

Теперь, зная как вычислять определитель и присоединенную матрицу, мы можем определить матрицу A-1, обратную матрице A:

➣ Численный пример

Пример вычисления обратной матрицы. Пусть дана исходная матрица A, следующего вида:

Для начала найдем определитель матрицы A:

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

Союзная матрица будет иметь следующий вид:

Присоединенная матрица получается из союзной путем транспонирования:

Находим обратную матрицу:

➤ Пример на Python

Решим задачу определения обратной матрицы на Python. Для получения обратной матрицы будем использовать функцию inv():

>>> A = np.matrix('1 -3; 2 5')
>>> A_inv = np.linalg.inv(A)
>>> print(A_inv)
[[ 0.45454545 0.27272727]
 [-0.18181818 0.09090909]]

Рассмотрим свойства обратной матрицы.

Свойство 1. Обратная матрица обратной матрицы есть исходная матрица:

➤Пример на Python

>>> A = np.matrix('1. -3.; 2. 5.')
>>> A_inv = np.linalg.inv(A)
>>> A_inv_inv = np.linalg.inv(A_inv)

>>> print(A)
[[1. -3.]
 [2. 5.]]
>>> print(A_inv_inv)
[[1. -3.]
 [2. 5.]]

Свойство 2. Обратная матрица транспонированной матрицы равна транспонированной матрице от обратной матрицы:

➤ Пример на Python

>>> A = np.matrix('1. -3.; 2. 5.')
>>> L = np.linalg.inv(A.T)
>>> R = (np.linalg.inv(A)).T

>>> print(L)
[[ 0.45454545 -0.18181818]
 [ 0.27272727 0.09090909]]
>>> print(R)
[[ 0.45454545 -0.18181818]
 [ 0.27272727 0.09090909]]

Свойство 3. Обратная матрица произведения матриц равна произведению обратных матриц:

➤ Пример на Python

>>> A = np.matrix('1. -3.; 2. 5.')
>>> B = np.matrix('7. 6.; 1. 8.')

>>> L = np.linalg.inv(A.dot(B))
>>> R = np.linalg.inv(B).dot(np.linalg.inv(A))

>>> print(L)
[[ 0.09454545 0.03272727]
 [-0.03454545 0.00727273]]
>>> print(R)
[[ 0.09454545 0.03272727]
 [-0.03454545 0.00727273]]

Ранг матрицы

Ранг матрицы является еще одной важной численной характеристикой. Рангом называют максимальное число линейно независимых строк (столбцов) матрицы. Линейная независимость означает, что строки (столбцы) не могут быть линейно выражены через другие строки (столбцы). Ранг матрицы можно найти через ее миноры, он равен наибольшему порядку минора, который не равен нулю. Существование ранга у матрицы не зависит от того квадратная она или нет.

Вычислим ранг матрицы с помощью Python. Создадим единичную матрицу:

>>> m_eye = np.eye(4)
>>> print(m_eye)
[[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]]

Ранг такой матрицы равен количеству ее столбцов (или строк), в нашем случае ранг будет равен четырем, для его вычисления на Python воспользуемся функцией matrix_rank():

>>> rank = np.linalg.matrix_rank(m_eye)
>>> print(rank)
4

Если мы приравняем элемент в нижнем правом углу к нулю, то ранг станет равен трем:

>>> m_eye[3][3] = 0
>>> print(m_eye)
[[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 0.]]

>>> rank = np.linalg.matrix_rank(m_eye)
>>> print(rank)
3

P.S.

Вводные уроки по “Линейной алгебре на Python” вы можете найти соответствующей странице нашего сайта. Все уроки по этой теме собраны в книге “Линейная алгебра на Python”.
Книга: Линейная алгебра на Python
Если вам интересна тема анализа данных, то мы рекомендуем ознакомиться с библиотекой Pandas.  Для начала вы можете познакомиться с вводными уроками. Все уроки по библиотеке Pandas собраны в книге “Pandas. Работа с данными”.
Книга: Pandas. Работа с данными

Recipe Objective

Finding the Rank of a matrix manually isn»t a time taking process. So have you tried to do it in python.

So this is the recipe on how we can find the Rank of a Matrix.

Table of Contents

  • Recipe Objective
    • Step 1 — Loading Library
    • Step 2 — Creating a Matrix
    • Step 3 — Calculating Rank

Step 1 — Loading Library

We have imported numpy which is needed.
import numpy as np

Step 2 — Creating a Matrix

We have created a matrix by using np.array with different values in it.
matrixA = np.array([[1, 2, 3, 23],
[4, 5, 6, 25],
[7, 8, 9, 28],
[10, 11, 12, 41]])

Step 3 — Calculating Rank

We have calculated rank of the matrix by using numpy function np.linalg.matrix_rank and passing the matrix through it.
print("The Rank of a Matrix: ", np.linalg.matrix_rank(matrixA))

So the output comes as

The Rank of a Matrix:  3

Время чтения 3 мин.

Метод Numpy linalg matrix_rank() используется для вычисления ранга данной матрицы с использованием метода SVD.

Содержание

  1. Что такое функция Numpy linalg matrix_rank()?
  2. Синтаксис
  3. Параметры
  4. Примечания
  5. Возвращаемое значение
  6. Расчет ранга одномерной матрицы
  7. Matrix rank  2D-матрицы

Функция Numpy linalg matrix_rank() возвращает ранг матрицы массива с помощью метода SVD. Метод matrix_rank() вычисляется по количеству сингулярных значений Matrix, превышающих tol.

Синтаксис

numpy.linalg.matrix_rank(array, tol)

Параметры

Функция matrix_rank() принимает в основном два параметра:

  1. Array: это массив, ранг которого мы хотим найти.
  2. tol: порог, ниже которого значения SVD считаются нулевыми. Если tol равно None, S — это массив с сингулярными значениями для M, а eps — это значение эпсилон для типа данных S, тогда tol устанавливается равным S.max() * max(M.shape) * eps.

Примечания

Предел по умолчанию для обнаружения ранговых ошибок составляет m. K — это тест на величину отдельных значений. По умолчанию мы нашли значения smasher ниже, чем s.max() * max(mHap) * EPS. .

Этот диапазон по умолчанию предназначен для обнаружения уменьшения ранга с учетом числовых ошибок вычисления SVD. Держите столбец M в M, который является точной комбинацией (с плавающей запятой) других столбцов в M. Вычисление SVD на M обычно не дает единственного значения, равного 0: наименьшее значение SVD.

Любое отличие от 0 из-за численных нарушений в расчете SVD. Наш диапазон для малых значений SVD учитывает это числовое возмущение, а пороговое значение по умолчанию распознает отсутствие такого числового ранга. Хотя линейная комбинация некоторых столбцов М не равна второму столбцу М, хотя численно очень близка ко второму столбцу М, входная матрица М может декларировать понижение ранга.

Мы выбрали ограничение по умолчанию, потому что оно широко используется. Возможны другие ограничения. Например, в версии 2007 года consonant имеет необязательный массив smacks() * np.info(M.dtype) в другом месте .eps/2. * np.sqrt(m + n + 1.). Авторы описывают это ограничение на основе «ошибки округления».

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

Возвращаемое значение

Функция matrix_rank() возвращает целочисленное значение, обозначающее ранг данной Матрицы.

Функция Numpy linalg matrix_rank()

Расчет ранга одномерной матрицы

См. следующий код.

# Programming example to find matrix rank of the 1D matrix

from numpy import linalg as LA

import numpy as np

arr1 = np.array([4, 5, 0, 1])

print(«Matrix rank of the 1st array is: «, LA.matrix_rank(arr1, 0))

arr2 = np.array(np.zeros(4))

print(«The Matrix is: «, arr2)

print(«Matrix rank of the 2nd array is: «, LA.matrix_rank(arr2, 0))

Вывод:

Matrix rank of the 1st array is:  1

The Matrix is:  [0. 0. 0. 0.]

Matrix rank of the 2nd array is:  0

Объяснение.

В этой программе мы сначала импортировали numpy и numpy.linalg для вычисления ранга матрицы.

Мы объявили два одномерных массива, а затем передали значение tol при вызове функции matrix_rank(). Мы получили ранг матрицы в соответствии с заданным значением.

Matrix rank 2D-матрицы

См. следующий код.

# Programming example to find matrix rank of 3D matrix

from numpy import linalg as LA

import numpy as np

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

print(«The arr1 is :n», arr1)

print(«Matrix Rank is:n», LA.matrix_rank(arr1, 1))

arr2 = np.array(np.zeros((4, 4)))

print(«Arr2 is: n: «, arr2)

print(«Matrix Rank is:n», LA.matrix_rank(arr2, 2))

Вывод:

The arr1 is :

[[1 2 3]

[6 5 4]]

Matrix Rank is:

2

Arr2 is:

:  [[0. 0. 0. 0.]

[0. 0. 0. 0.]

[0. 0. 0. 0.]

[0. 0. 0. 0.]]

Matrix Rank is:

0

Объяснение.

В этой программе мы сначала импортировали numpy и numpy.linalg для вычисления ранга матрицы.

Мы объявили два 2D-массива, а затем передали значение tol при вызове функции matrix_rank(). Мы получили ранг матрицы в соответствии с переданным значением.

Понравилась статья? Поделить с друзьями:

Не пропустите также:

  • Как найти свою половинку по своему имени
  • Как правельно составить задачу
  • Как у собаки исправить провисшую спину у собаки
  • Как найти объемную долю жидкости
  • Как найти центр ориентированного графа

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии