<jupyter_start><jupyter_text>Linear Algebra for CheAssignment 3 : Matrices  ObjectivesAt the end of this activity you will be able to:1. Be familiar with matrices and their relation to linear equations.2. Perform basic matrix operations.3. Program and translate matrix equations and operations using Python.  Discussion<jupyter_code>import numpy as np
import matplotlib.pyplot as plt
import scipy.linalg as la
%matplotlib inline<jupyter_output><empty_output><jupyter_text>MatricesThe notation and use of matrices is probably one of the fundamentals of modern computing. Matrices are also handy representations of complex equations or multiple inter-related equations from 2-dimensional equations to even hundreds and thousands of them.Let's say for example you have  and  as system of equation. $$A = \left\{    \begin{array}\        4x + 20y \\         10x - 10y    \end{array}\right. \\B = \left\{    \begin{array}\        11x+12y+13z \\         5x -8y -9z \\        -55x + 44y +22z    \end{array}\right. \\C = \left\{  \begin{array}\  w - 21x + 35y - 45z \\  3w - 21x - 22y + 20z \\  2w - 9x + 10y - 11z  \end{array}\right. $$ $$A=\begin{bmatrix} 1 & 1 \\ 4 & {-10}\end{bmatrix} \\B=\begin{bmatrix} 1 & 1 & 1 \\ 3 & -2 & -1 \\ -1 & 4 & 2\end{bmatrix}\\C=\begin{bmatrix} 1 & -2 & 3 & -4 \\ 3 & -1 & -2 & 1 \\ 2 & -1 & 3 & -2 \end{bmatrix}$$ So assuming that you already discused the fundamental representation of matrices, their types, and operations. we'll proceed in doing them in here in Python We could see that A is a system of 2 equations with 2 parameters   Declaring MatricesJust like our previous laboratory activity, we'll represent system of linear equations as a matrix. The entities or numbers in matrices are called the elements of a matrix. These elements are arranged and ordered in rows and columns which form the list/array-like structure of matrices. And just like arrays, these elements are indexed according to their position with respect to their rows and columns. This can be reprsented just like the equation below. Whereas A is a matrix consisting of elements denoted by . Denoted by  is the number of rows in the matrix while  stands for the number of columns.Do note that the  of a matrix is i x j . $$A=\begin{bmatrix}a_{(0,0)}&a_{(0,1)}&\dots&a_{(0,j-1)}\\a_{(1,0)}&a_{(1,1)}&\dots&a_{(1,j-1)}\\\vdots&\vdots&\ddots&\vdots&\\a_{(i-1,0)}&a_{(i-1,1)}&\dots&a_{(i-1,j-1)}\end{bmatrix}$$ We already gone over some of the types of matrices as vectors but we'll further discuss them in this laboratory activity. Since you already know how to describe vectors using shape, dimensions and size attributes, we'll use them to analyze these matrices.<jupyter_code>## Since we'll keep on describing matrices. Lets make a function.
def describe_mat(matrix):
    print(f'Matrix:\n{matrix}\n\nShape:\t{matrix.shape}\nRank:\t{matrix.ndim}\n')

## Declaring a 2 x 2 matrix
A = np.array ([
    [1, 2],
    [3, 1]
])
describe_mat(A)
##Declaring a 2 x 3 matrix
G = np.array([
    [1,1,3],
    [2,2,4]
])
describe_mat(G)

##Declaring a 3 x 2 matrix
B = np.array([
    [8, 2],
    [5, 4],
    [1, 1]
])
describe_mat(B)

H = np.array([1,2,3,4])
describe_mat(H)<jupyter_output>Matrix:
[1 2 3 4]

Shape:	(4,)
Rank:	1<jupyter_text>Categorizing Matrices There are several ways of classifying matrices. Once could be according to their shape and another is according to their element values. We'll try to go through them  According to shape  Row and Column Matrices Row and column are common in vector and matrix computations. They can also represent row and column spaces of a bigger vector space. Row and column spaces of a bigger vector space. Row and column matrices are represented by a single column or single row. So with that being, the shape of row matrices would be 1 x j  and column matrices would be i x 1 .<jupyter_code>## Declaring a Row Matrix

rowmatrix1D = np.array([
    1, 3, 2, -4
]) ## this is a 1-D Matrix with a shape of (3,), it's not really considered as a row matrix.
row_mat_2D = np.array([
    [1,2,3, -4]
]) ## this is a 2-D Matrix with a shape of (1,3)
describe_mat(rowmatrix1D)
describe_mat(row_mat_2D)

##Declaring a Column Matrix
col_mat = np.array([
    [1],
    [2],
    [5]
]) ## this is a 2-D Matrix with a shape of (3,1)
describe_mat(col_mat)<jupyter_output>Matrix:
[[1]
 [2]
 [5]]

Shape:	(3, 1)
Rank:	2<jupyter_text>Square MatricesSquare matrices are matrices that have the same row and column sizes. We could say a matrix is square if i = j . We can tweak our matrix descriptor function to determine square matrices.<jupyter_code>def describe_mat(matrix):
    is_square = True if matrix.shape[0] == matrix.shape[1] else False 
    print(f'Matrix:\n{matrix}\n\nShape:\t{matrix.shape}\nRank:\t{matrix.ndim}\nIs Square: {is_square}\n')

square_mat = np.array([
    [1,2,5],
    [3,3,8],
    [6,1,2]
])

non_square_mat = np.array([
    [1,2,5],
    [3,3,8]
])
describe_mat(square_mat)
describe_mat(non_square_mat)<jupyter_output>Matrix:
[[1 2 5]
 [3 3 8]
 [6 1 2]]

Shape:	(3, 3)
Rank:	2
Is Square: True

Matrix:
[[1 2 5]
 [3 3 8]]

Shape:	(2, 3)
Rank:	2
Is Square: False<jupyter_text>According to element values  Null matrixA Null Matrix is a matrix that has no elements. It is always a subspace of any vector or matrix.<jupyter_code>def describe_mat(matrix):
    if matrix.size > 1:
        is_square = False if matrix.shape[0] < matrix.shape[1] else False 
        print(f'Matrix:\n{matrix}\n\nShape:\t{matrix.shape}\nRank:\t{matrix.ndim}\nIs Square: {is_square}\n')
    else:
        print('Matrix is Null')

null_mat = np.array([])
describe_mat(null_mat)<jupyter_output>Matrix is Null<jupyter_text>Zero MatrixA zero matrix can be any rectangular matrix but with all elements having a value of 0.<jupyter_code>zero_mat_row = np.zeros((1,1))
zero_mat_sqr = np.zeros((3,3))
zero_mat_rct = np.zeros((4,4))

print(f'Zero Row Matrix: \n{zero_mat_row}')
print(f'Zero Square Matrix: \n{zero_mat_sqr}')
print(f'Zero Rectangular Matrix: \n{zero_mat_rct}')<jupyter_output>Zero Row Matrix: 
[[0.]]
Zero Square Matrix: 
[[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]
Zero Rectangular Matrix: 
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]<jupyter_text>Ones MatrixA ones matrix, just like the zero matrix, can be any rectangular matrix but all of its elements are 1s instead of 0s.<jupyter_code>ones_mat_row = np.ones((1,3))
ones_mat_sqr = np.ones((2,3))
ones_mat_rct = np.ones((4,4))

print(f'Ones Row Matrix: \n{ones_mat_row}')
print(f'Ones Square Matrix: \n{ones_mat_sqr}')
print(f'Ones Rectangular Matrix: \n{ones_mat_rct}')<jupyter_output>Ones Row Matrix: 
[[1. 1. 1.]]
Ones Square Matrix: 
[[1. 1. 1.]
 [1. 1. 1.]]
Ones Rectangular Matrix: 
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]]<jupyter_text>DIagonal MatrixA diagonal matrix is a square matrix that has values only at the diagonal of the matrix.<jupyter_code>np.diag([
    [2,0,0],
    [0,3,0],
    [0,0,5]
])<jupyter_output><empty_output><jupyter_text>Identity MatrixAn identity matrix is a special diagonal matrix in which the values at the diagonal are ones.<jupyter_code>np.eye(3)
np.identity(4)<jupyter_output><empty_output><jupyter_text>Upper Triangular MatrixAn upper triangular matrix is a matrix that has no values below the diagonal.<jupyter_code>P = np.array([
    [1,2,3,4],
    [1,3,1,-1],
    [1,1,5,2],
    [1,1,1,2]
])
np.triu(P)
F = np.array([
              [2, -3, 4, -5, 6],
              [2, -3, 4, -5, 6],
              [2, -3, 4, -5, 6],
              [2, -3, 4, -5, 6],
              [2, -3, 4, -5, 6],
])
np.triu(F)<jupyter_output><empty_output><jupyter_text>Lower Triangular MatrixA lower triangular matrix is a matrix that has no values above the diagonal.<jupyter_code>E = np.array([
              [2, -3, 4, -5, 6],
              [2, -3, 4, -5, 6],
              [2, -3, 4, -5, 6],
              [2, -3, 4, -5, 6],
              [2, -3, 4, -5, 6],
])
np.tril(E)

G = np.array([
   [1,0,0],
   [5,3,0],
   [7,8,9]
])
np.tril(G)<jupyter_output><empty_output><jupyter_text>Practice 1. Given the linear combination below, try to create a corresponding matrix representing it. :$$\theta = 10x + 66y - 99z$$ 2. Given the system of linear combinations below, try to encode it as a matrix. Also describe the matrix. $$A = \left\{\begin{array}55x_1 + 4x_2 +2x_3\\6x_2 - 5x_3\\20x_3\end{array}\right.$$ 3. Given the matrix below, express it as a linear combination in a markdown and a LaTeX markdown<jupyter_code>G = np.array([
    [1,7,8],
    [2,2,2],
    [4,6,7]
])
G<jupyter_output><empty_output><jupyter_text>4. Given the matrix below, display the output as a LaTeX markdown also express it as a system of linear combinations.<jupyter_code>H = np.tril(G)
H<jupyter_output><empty_output><jupyter_text>Addition<jupyter_code>A = np.array ([
    [6,2,4],
    [5,3,8],
    [3,6,8] 
])
B = np.array([
    [2,5,3],
    [6,9,6],
    [7,8,9]
])
A+B<jupyter_output><empty_output><jupyter_text>Substraction<jupyter_code>A-B-A

5-B<jupyter_output><empty_output><jupyter_text>Multiplication<jupyter_code>A*B<jupyter_output><empty_output><jupyter_text>Element wise multiplication<jupyter_code>np.multiply(A,B)<jupyter_output><empty_output><jupyter_text>Element wise division<jupyter_code>np.divide(A,B)<jupyter_output><empty_output><jupyter_text>Task 1Create a function named mat_desc() that througouhly describes a matrix, it should:Displays the shape, size, and rank of the matrix.Displays whether the matrix is square or non-square.Displays whether the matrix is an empty matrix.Displays if the matrix is an identity, ones, or zeros matrixUse 5 sample matrices in which their shapes are not lower than . In your methodology, create a flowchart discuss the functions and methods you have done. Present your results in the results section showing the description of each matrix you have declared.<jupyter_code>## Function Area
def mat_desc(mat):
    sq = False
    mat = np.array(mat)
    print(mat)
    print('Shape:', mat.shape)
    print('Size:', mat.size)
    print('Rank:', np.linalg.matrix_rank(mat))
    if(mat.shape[0] == mat.shape[1]):
        sq = True
        print('The matrix is square')
    else:
        print('The matrix is non-square')
    if(mat.shape[0] == 0 and mat.shape[1] == 0):
        print('The matrix is empty')
    else:
        print('The matrix is not empty')
    iden = np.identity(mat.shape[0])
    if(sq and (iden == mat).all()):
        print('The matrix is an identity matrix')
    else:
        print('The matrix is not an identity matrix')
    one = np.ones((mat.shape[0], mat.shape[1]))
    if((one == mat).all()):
        print('The matrix is an ones matrix')
    else:
        print('The matrix is not an ones matrix')
    zero = np.zeros((mat.shape[0], mat.shape[1]))
    if((zero == mat).all()):
        print('The matrix is an zeros matrix')
    else:
        print('The matrix is not a zeros matrix')
## Matrix Declarations

Q = np.array([
    [3,4,6],
    [7,8,9],
    [2,3,1]          
])

G = np.array([
    [4,5,7],
    [8,9,6],
    [2,3,1]        
])


P = np.array([
    [1,1,1],
    [1,1,1],
    [1,1,1]        
])

Z = np.array([
    [3,3,3],
    [3,3,3],
    [3,3,3]           
])

I = np.array([
    [0,0,0],
    [0,0,0],
    [0,0,0],
              
])

T = np.array([
    [1., 0., 0.],
    [0., 1., 0.],
    [0., 0., 1.]
])
##Test Areas

mat_desc(Q)

mat_desc(G)

mat_desc(P)

mat_desc(Z)

mat_desc(I)

mat_desc(T)<jupyter_output>[[3 4 6]
 [7 8 9]
 [2 3 1]]
Shape: (3, 3)
Size: 9
Rank: 3
The matrix is square
The matrix is not empty
The matrix is not an identity matrix
The matrix is not an ones matrix
The matrix is not a zeros matrix
[[4 5 7]
 [8 9 6]
 [2 3 1]]
Shape: (3, 3)
Size: 9
Rank: 3
The matrix is square
The matrix is not empty
The matrix is not an identity matrix
The matrix is not an ones matrix
The matrix is not a zeros matrix
[[1 1 1]
 [1 1 1]
 [1 1 1]]
Shape: (3, 3)
Size: 9
Rank: 1
The matrix is square
The matrix is not empty
The matrix is not an identity matrix
The matrix is an ones matrix
The matrix is not a zeros matrix
[[3 3 3]
 [3 3 3]
 [3 3 3]]
Shape: (3, 3)
Size: 9
Rank: 1
The matrix is square
The matrix is not empty
The matrix is not an identity matrix
The matrix is not an ones matrix
The matrix is not a zeros matrix
[[0 0 0]
 [0 0 0]
 [0 0 0]]
Shape: (3, 3)
Size: 9
Rank: 0
The matrix is square
The matrix is not empty
The matrix is not an identity matrix
The matrix is not an ones matrix
The mat[...]<jupyter_text>Task 2Create a function named mat_operations() that takes in two matrices a input parameters it should:Determines if the matrices are viable for operation and returns your own error message if they are not viable.Returns the sum of the matrices.Returns the difference of the matrices.Returns the element-wise multiplication of the matrices.Returns the element-wise division of the matrices.Use 5 sample matrices in which their shapes are not lower than . In your methodology, create a flowchart discuss the functions and methods you have done. Present your results in the results section showing the description of each matrix you have declared.<jupyter_code>def mat_operations(matrix):
  print (f'{matrix}')
import numpy as np
import matplotlib.pyplot as plt
import scipy.linalg as la
%matplotlib inline
## Matrix 1
row1 = int(input("enter the row number of the first matrix: " ))
col1 = int(input("enter the column number of the first matrix: "))

print('enter', row1*col1, 'elements for matrix 1: ')
matrix1 = list(map(int, input().split()))
r_matrix1 = np.array(matrix1).reshape(row1,col1)
print("matrix 1 is: ")
mat_operations(r_matrix1)

## Matrix 2
row2 = int(input("\nenter the row number of the second matrix: " ))
col2 = int(input("enter the column number of the second matrix: "))

print('enter', row2*col2, 'elements for matrix 2: ')
matrix2 = list(map(int, input().split()))
r_matrix2 = np.array(matrix2).reshape(row2,col2)
print("matrix 2 is: ")
mat_operations(r_matrix2)

## Matrix 3
row3 = int(input("\nenter the row number of the third matrix: " ))
col3 = int(input("enter the column number of the third matrix: "))

print('enter', row3*col3, 'elements for matrix 3: ')
matrix3 = list(map(int, input().split()))
r_matrix3 = np.array(matrix3).reshape(row3,col3)
print("matrix 3 is: ")
mat_operations(r_matrix3)

first = r_matrix1
second = r_matrix2
third = r_matrix3
### ADDITION ----------------------------------------------------------------
print('\nselect two matrices to to add. (Note: use first, second, third, to select the matrices)')
firstadd = str(input("matrix #: "))
print('+') 
secondadd =str(input("matrix #: "))

result = (eval(firstadd).shape == eval(secondadd).shape)
if result:
  print('\nThe sum of the',firstadd,'and',secondadd,'matrix is: ')
  print(eval(firstadd)+eval(secondadd))
else:
  print('\nOperation not viable, check matrix dimensions.') 

###SUBTRACTION--------------------------------------------------------------
print('\nselect two matrices to to subtract')
firstsubb = str(input("matrix #: ")) 
print('-') 
secondsubb =str(input("matrix #: "))

result = (eval(firstsubb).shape == eval(secondsubb).shape)
if result:
  print('\nThe difference of the',firstsubb,'and',secondsubb,'matrix is: ')
  print(eval(firstsubb)-eval(secondsubb))
else:
  print('\nOperation not viable, check matrix dimensions.') 

###ELEMENT-WISE MULTIPLICATION----------------------------------------------
print('\nselect two matrices to multiply')
firstmult = str(input("matrix #: "))
print('x') 
secondmult =str(input("matrix #: "))

result = (eval(firstmult).shape == eval(secondmult).shape)
if result:
  print('\nThe product of the',firstmult,'and',secondmult,'matrix is: ')
  print(eval(firstmult)*eval(secondmult))
else:
  print('\nOperation not viable, check matrix dimensions.') 

### ELEMENT-WISE DIVISION --------------------------------------------------
print('\nselect two matrices to divide')
firstdiv = str(input("matrix #: "))
print('/')
seconddiv =str(input("matrix #: "))

result = (eval(firstdiv).shape == eval(seconddiv).shape)
if result:
  print('\nThe product of the',firstdiv,'and',seconddiv,'matrix is: ')
  print(eval(firstdiv)/eval(seconddiv))
else: 
  print('\nOperation not viable, check matrix dimensions.')<jupyter_output>enter the row number of the first matrix: 2
enter the column number of the first matrix: 2
enter 4 elements for matrix 1: 
2 2 2 2
matrix 1 is: 
[[2 2]
 [2 2]]

enter the row number of the second matrix: 2
enter the column number of the second matrix: 2
enter 4 elements for matrix 2: 
2 2 2 2
matrix 2 is: 
[[2 2]
 [2 2]]

enter the row number of the third matrix: 2
enter the column number of the third matrix: 2
enter 4 elements for matrix 3: 
2 2 2 2
matrix 3 is: 
[[2 2]
 [2 2]]

select two matrices to to add. (Note: use first, second, third, to select the matrices)
matrix #: first + second
+
matrix #: second + third

The sum of the first + second and second + third matrix is: 
[[8 8]
 [8 8]]

select two matrices to to subtract
matrix #: first
-
matrix #: second

The difference of the first and second matrix is: 
[[0 0]
 [0 0]]

select two matrices to multiply
matrix #: first
x
matrix #: second

The product of the first and second matrix is: 
[[4 4]
 [4 4]]

select two matrices to divi[...]
{'fraction_non_alphanumeric': 0.14425981873111782, 'fraction_numerical': 0.03642807343713688, 'mean_word_length': 3.5585275423728815, 'pattern_counts': {'":': 0, '<': 74, '<?xml version=': 0, '>': 74, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '20', 'dir': 'jupyter-structured-clean-dedup', 'id': '568997', 'license': 'Apache-2.0', 'n_tokens_mistral': 6229, 'n_tokens_neox': 5879, 'n_words': 2106, 'path': 'Assignment_3_Matrix_in_Python.ipynb', 'repo_name': 'paulkennethjazul/Linear_Algebra_ChE_2nd_Sem_2021-2022', 'size': '17212'}