-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcondition_number.py
66 lines (54 loc) · 3.34 KB
/
condition_number.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import matrix_helpers as mh
import numpy as np
class ConditionNumber:
def __init__(self, matrixAB=None, matrixA=None, vectorB=None, print_result=False):
self.whole_matrix = matrixAB
if matrixAB is None:
self.matrixA = matrixA
self.vectorB = vectorB
else:
self.matrixA = mh.get_matrixA(matrixAB)
self.vectorB = mh.get_vectorB_unpacked(matrixAB)
# Get the condition number of the matrix
if matrixAB is None:
self.cond = mh.get_matrix_cond(matrixA)
else:
self.cond = mh.get_matrix_cond(mh.get_matrixA(matrixAB))
if print_result:
print("Condition number of matrix Cond(A) =", self.cond)
def experimental(self, vectorX, delta_vectorX, printall=False):
print("\n--- Experimental condition number check")
# Get the norms of the vectorB and delta_vectorB
vectorB_norm = mh.get_vector_norm_euc(self.vectorB)
delta_vectorB = mh.get_deltaB_from_vectorB(self.vectorB)
deltaB_norm = mh.get_vector_norm_euc(delta_vectorB)
# Get the norms of the vectorX and delta_vectorX
vectorX_norm = mh.get_vector_norm_euc(vectorX)
deltaX_norm = mh.get_vector_norm_euc(delta_vectorX)
if printall:
print(f'\n --- Norms:\n{"||B||":<12} {"=":>4} {vectorB_norm}')
print(f'{"||deltaB||":<12} {"=":>4} {deltaB_norm}')
print(f'{"||X||":<12} {"=":>4} {vectorX_norm}')
print(f'{"||deltaX||":<12} {"=":>4} {deltaX_norm}')
print("\nMatrix determinant =", mh.get_matrix_determinant(self.matrixA))
print("\nChecking Cond(A) for matrix (1):")
print("Cond(A) >= ( ||deltaX|| / ||X|| ) * ( ||B|| / ||deltaB|| )")
print(self.cond, ">= (", deltaX_norm, "/", vectorX_norm, ") * (", vectorB_norm, "/", deltaB_norm, ")")
print(self.cond, ">=", (deltaX_norm / vectorX_norm) * (vectorB_norm / deltaB_norm))
print("\nChecking Cond(A) for matrix (2):")
print("||deltaX|| / ||X|| <= cond(A) * ( ||deltaB|| / ||B||)")
print(deltaX_norm, "/", vectorX_norm, "<=", self.cond, "* (", deltaB_norm, "/", vectorB_norm, ")")
print(deltaX_norm / vectorX_norm, "<=", self.cond * (deltaB_norm / vectorB_norm))
condition_1 = self.cond >= (deltaX_norm / vectorX_norm) * (vectorB_norm / deltaB_norm)
condition_2 = (deltaX_norm / vectorX_norm) <= self.cond * (deltaB_norm / vectorB_norm)
if printall:
print("\n --- Condition returned (1)", condition_1, "and (2)", condition_2, "\n")
print("Condition number of matrix Cond(A) =", self.cond)
print("Condition number from np.linalg.cond(..., 1) =", np.linalg.cond(self.matrixA, 1))
if self.cond < 10:
print("Cond(A) of the matrix falls into 1-10 range. This means that the results of this matrix calculation are adequate.")
elif self.cond < 1000:
print("Cond(A) of the matrix falls into 10-1000 range. This means that the results of this matrix calculation CAN BE INADEQUATE.")
elif self.cond > 1000:
print("Cond(A) of the matrix falls into 1000-infinity range. This means that the results of this matrix calculation ARE INADEQUATE.")
return condition_1, condition_2