```python
# linear algebra concerns itself with linear systems, but represents them through vector spaces and matrices.

```


```python
#  vector is an arrow in space with a specific direction and length, often representing a piece of data.
# It is the central building block to linear algebra, including matrices and linear transformations. 


# Declaring a vector in Python using a list

v = [3, 2]
print(v)
```

    [3, 2]



```python
# Declaring a vector in Python using NumPy

import numpy as np
v = np.array([3, 2])
print(v)

```

    [3 2]



```python
# Declaring a 3-dimensional vector in Python using NumPy

v = np.array([4, 1, 2])
print(v)

```

    [4 1 2]



```python
# Adding two vectors in Python using NumPy

from numpy import array
v = array([3,2])
w = array([2,-1])

# sum the vectors
v_plus_w = v + w

# display summed vector
print(v_plus_w)
```

    [5 1]



```python
# Scaling a number in Python using NumPy

v = array([3,1])

# scale the vector
scaled_v = 2.0 * v

# display scaled vector
print(scaled_v)
```

    [6. 2.]



```python
# A matrix is a collection of vectors 
# , can have multiple rows and columns,
# and is a convenient way to package data. 
```


```python
# Matrix vector multiplication in NumPy

# compose basis matrix with i-hat and j-hat
basis = array(
    [[3, 0],
     [0, 2]]
 )

# declare vector v
v = array([1,1])

# create new vector
# by transforming v with dot product
new_v = basis.dot(v)

print(new_v)
```

    [3 2]



```python
# When thinking in terms of basis vectors,
# I prefer to break out the basis vectors and then compose them together into a matrix.
# Just note you will need to transpose, or swap the columns and rows.
# This is because NumPy’s array() function will do the opposite orientation we want,
# populating each vector as a row rather than a column.

# Declare i-hat and j-hat
i_hat = array([2, 0])
j_hat = array([0, 3])

# compose basis matrix using i-hat and j-hat
# also need to transpose rows into columns
basis = array([i_hat, j_hat]).transpose()

# declare vector v
v = array([1,1])

# create new vector
# by transforming v with dot product
new_v = basis.dot(v)

print(new_v)
```

    [2 3]



```python
# Transforming a vector using NumPy

# Declare i-hat and j-hat
i_hat = array([2, 0])
j_hat = array([0, 3])

# compose basis matrix using i-hat and j-hat
# also need to transpose rows into columns
basis = array([i_hat, j_hat]).transpose()

# declare vector v 0
v = array([2,1])

# create new vector
# by transforming v with dot product
new_v = basis.dot(v)

print(new_v)
```

    [4 3]



```python
# Transformation 1
i_hat1 = array([0, 1])
j_hat1 = array([-1, 0])
transform1 = array([i_hat1, j_hat1]).transpose()

# Transformation 2
i_hat2 = array([1, 0])
j_hat2 = array([1, 1])
transform2 = array([i_hat2, j_hat2]).transpose()

# Combine Transformations
combined = transform2 @ transform1

# Test
print("COMBINED MATRIX:\n {}".format(combined))

v = array([1, 2])
print(combined.dot(v))
```

    COMBINED MATRIX:
     [[ 1 -1]
     [ 1  0]]
    [-1  1]



```python
#  Determinants describe how much a sampled area in a vector space changes in scale with linear transformations,
#     and this can provide helpful information about the transformation

from numpy.linalg import det


i_hat = array([3, 0])
j_hat = array([0, 2])

basis = array([i_hat, j_hat]).transpose()

determinant = det(basis)

print(determinant)
```

    6.0



```python
# testing for a 0 determinant is highly helpful to determine if a transformation has linear dependence.
# When you encounter this you will likely find a difficult or unsolvable problem on your hands.

i_hat = array([-2, 1])
j_hat = array([3, -1.5])

basis = array([i_hat, j_hat]).transpose()

determinant = det(basis)

print(determinant)
```

    0.0



```python
from sympy import *

# 4x + 2y + 4z = 44
# 5x + 3y + 7z = 56
# 9x + 3y + 6z = 72

A = Matrix([
    [4, 2, 4],
    [5, 3, 7],
    [9, 3, 6]
])

# dot product between A and its inverse
# will produce identity function
inverse = A.inv()
identity = inverse * A

# prints Matrix([[-1/2, 0, 1/3], [11/2, -2, -4/3], [-2, 1, 1/3]])
print("INVERSE: {}".format(inverse))

# prints Matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
print("IDENTITY: {}".format(identity))
```

    INVERSE: Matrix([[-1/2, 0, 1/3], [11/2, -2, -4/3], [-2, 1, 1/3]])
    IDENTITY: Matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]])



```python
# 4x + 2y + 4z = 44
# 5x + 3y + 7z = 56
# 9x + 3y + 6z = 72
from numpy import array

from numpy.linalg import inv

A = array([[4, 2, 4],[5, 3, 7],[9, 3, 6]])

B = array([44,56,72])

X = inv(A).dot(B)

print(X)
```

    [ 2. 34. -8.]



```python
# Performing eigendecomposition in NumPy

from numpy import array, diag
from numpy.linalg import eig, inv

A = array([
    [1, 2],
    [4, 5]
])

eigenvals, eigenvecs = eig(A)

print("EIGENVALUES")
print(eigenvals)
print("\nEIGENVECTORS")
print(eigenvecs)
```

    EIGENVALUES
    [-0.46410162  6.46410162]
    
    EIGENVECTORS
    [[-0.80689822 -0.34372377]
     [ 0.59069049 -0.9390708 ]]



```python
# Decomposing and recomposing a matrix in NumPy


```

b1e4756163d12ab6ce11a5c915bfdade7306184d
ipynb
Jupyter Notebook
Maths/Linear Algebra/Linear Algebra.ipynb
rishi9504/Data-Science
10344bf641c601bf16451ddd9eaa28ab4c0fc75b
MIT
Maths/Linear Algebra/Linear Algebra.ipynb
rishi9504/Data-Science
10344bf641c601bf16451ddd9eaa28ab4c0fc75b
MIT
Maths/Linear Algebra/Linear Algebra.ipynb
rishi9504/Data-Science
10344bf641c601bf16451ddd9eaa28ab4c0fc75b
MIT
Qwen/Qwen-72B
1. YES
2. YES