# Linear algebra using numpy in Python

The Numpy library in Python has a lot of built-in functions to implement linear algebra over any Numpy array or vector. These functions help to perform complex algebraic operations such as finding the rank or eigenvalues of a matrix in a very simplified manner, for any defined array or vector. To use this library, we first need to import it and that can be done using the import statement as shown:

`import numpy as np`

## Different functions and operations using the Numpy library are as follows:

### Matrix/Vector Product:

```import numpy as np
a=[1, 3, 4]
b=[5, 6, 8]
c=[2+1j,4+5j]
d=[4+5j,3+8j]
e = np.array([[2, 4, 1],
[0, 2, 6],
[4, -8, 1]])
#dot is used to find the dot product of two vector or matrices
print("Dot product for the two given arrays is ",np.dot(a,b))
#vdot is used to find the dot product of two vector or matrices with complex numbers
print("Dot product for the two given arrays with complex numbers is ",np.vdot(c,d))
#matrix_power is used to find the matrix raised to a power i
print("Matrix e raised to power 3:\n",np.linalg.matrix_power(e, 3))```

Output:

```Dot product for the two given arrays is 55
Dot product for the two given arrays with complex numbers is (65+23j)
Matrix e raised to power 3:
[[124 -168 83]
[120 -136 -222]
[-148 376 -79]]```

In the above code, we have used three different functions. The first two functions dot and vdot find the dot product of two array or matrices. They take the two arrays as input. The third function matrix_power is used to find the power of a matrix. It takes the matrix ‘e’ and the integer ‘i=3’ as input and returns the matrix e raised to power 3.

There are many more functions like:

• linalg.multi_dot(arrays): It computes the dot product of two or more arrays within a single function call and also selects the fastest evaluation order automatically.
• inner(a,b): It gives the inner product for two arrays.
• outer(a,b): It gives the outer product for the two vectors a and b.
• kron(a,b): It gives the Kronecker product for two arrays.
• tensordot(a, b[, axes]): It gives the tensor dot product along specified axes as mentioned in the argument.
• einsum(subscripts, *operands[, out, dtype, …]: It is used to evaluate the Einstein summation convention on the given operands.
• einsum_path(subscripts, *operands[, optimize]): It considers the creation of intermediate arrays and is used to evaluate the lowest cost contraction order for an einsum.

### Matrix eigenvalues:

```import numpy as np
from numpy import linalg as la
a, b = la.eig(np.diag((1, 7, 5)))
print("printing eigen values and eigen vectors of a square array.")
print(a)
print(b)
p = np.array([[5, -7j], [3j, 4]])
r, s = la.eigh(p)
print("The eigen values and eigen vectors of a complex Hermitian/a real symmetric matrix are.")
print(r)
print(s)```

Output:

```printing eigen values and eigen vectors of a square array.
[1. 7. 5.]
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
The eigen values and eigen vectors of a complex Hermitian/a real symmetric matrix are.
[1.45861873 7.54138127]
[[-0.6463749 +0.j         -0.76301998+0.j        ]
[ 0.        +0.76301998j  0.        -0.6463749j ]]```

In the above code, we have used two functions to calculate the eigenvalues and eigenvector for a matrix. The first function, ‘eig’ determines the eigenvalue and eigenvector for a square matrix whereas the ‘eigh’ function determines the eigenvalues and eigenvectors of a real symmetric matrix.

Some more related functions are:

• linalg.eigvals(a): It computes the eigenvalues of a general matrix.
• linalg.eigvalsh(a[, UPLO]): It gives the eigenvalues for a real symmetric or a complex Hermitian matrix.

### Other matrix operations:

```import numpy as np

a = np.array([[6, 0, 4],
[3, 2, 2],
[2, -8, 3]])

# Rank of a matrix
print("Rank of a:", np.linalg.matrix_rank(a))

# Determinant of a matrix
print("Determinant of a:", np.linalg.det(a))

# Inverse of matrix
print("Inverse of a:\n", np.linalg.inv(a))

#condition of a matrix
print("Condition of a:\n", np.linalg.cond(a))

#norm of a matrix
print("Norm of a: ", np.linalg.norm(a))

(sign, logdet) = np.linalg.slogdet(a)
print('sign',sign)
print('logdet', logdet)

#trace of a matrix
print("Trace of a: ", np.trace(a))```

Output:

```Rank of a: 3
Determinant of a: 19.999999999999996
Inverse of a:
[[ 1.10000000e+00 -1.60000000e+00 -4.00000000e-01]
[-2.50000000e-01  5.00000000e-01 -2.77555756e-17]
[-1.40000000e+00  2.40000000e+00  6.00000000e-01]]
Condition of a:
33.83119025058056
Norm of a:  12.083045973594572
sign 1.0
logdet 2.995732273553991
Trace of a:  11```

### Decomposition matrix

Decomposition functions in Numpy are:

• linalg.cholesky: It gives the Cholesky decomposition.
• linalg.svd(a[, full_matrices, compute_uv, …]): It gives the Singular Value Decomposition.
• linalg.qr(a[, mode]): It computes the qr factorization for a given matrix.