init?
This commit is contained in:
parent
b37d1af801
commit
6ed8b516e3
96
main.py
96
main.py
@ -1,23 +1,30 @@
|
|||||||
from typing import Tuple
|
|
||||||
import numpy as np
|
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
from matplotlib import pyplot as plt
|
||||||
|
from typing import Tuple
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
from scipy.linalg import solve
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Class that performs qr decomposition. Use methods:
|
Class that performs qr decomposition. Use methods:
|
||||||
perform_householder_QR,
|
perform_householder_QR,
|
||||||
perform_givens_QR
|
perform_givens_QR
|
||||||
both accept np.nadarry that fulfils m >= n condtion is 2d, and contains real numbers.
|
both accept np.ndarray that fulfils m >= n condition is 2d, and contains real numbers.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class QR:
|
class QR:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Checks if caulcuated matricies fulfill QR decomposition conditions, that is:
|
Checks if calculated matrices fulfill QR decomposition conditions, that is:
|
||||||
A = QR , where Q -> Q * Qt = I and R is a upper triangular matrix
|
A = QR , where Q -> Q * Qt = I and R is a upper triangular matrix
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __check_condition(self, Q: np.matrix, R: np.matrix) -> bool:
|
def __check_condition(self, Q: np.matrix, R: np.matrix) -> bool:
|
||||||
if not np.allclose(R, np.triu(R)):
|
if not np.allclose(R, np.triu(R)):
|
||||||
print("R matrix is not upper traingle.")
|
print("R matrix is not upper triangle.")
|
||||||
return False
|
return False
|
||||||
I = np.identity(Q.shape[1])
|
I = np.identity(Q.shape[1])
|
||||||
comparison = np.equal(np.matmul(np.transpose(Q), Q), I)
|
comparison = np.equal(np.matmul(np.transpose(Q), Q), I)
|
||||||
@ -25,9 +32,11 @@ class QR:
|
|||||||
print("Q matrix is not orthogonal.")
|
print("Q matrix is not orthogonal.")
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Checks if given matrix is 2d, m >= n and filled with real numbers
|
Checks if given matrix is 2d, m >= n and filled with real numbers
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __check_pre_conditions(self, matrix: np.ndarray) -> bool:
|
def __check_pre_conditions(self, matrix: np.ndarray) -> bool:
|
||||||
if not matrix.shape[0] >= matrix.shape[1]:
|
if not matrix.shape[0] >= matrix.shape[1]:
|
||||||
print("Matrix is m is lesser than n.")
|
print("Matrix is m is lesser than n.")
|
||||||
@ -36,16 +45,17 @@ class QR:
|
|||||||
print("Matrix is not 2D.")
|
print("Matrix is not 2D.")
|
||||||
return False
|
return False
|
||||||
if not np.isreal(matrix).all():
|
if not np.isreal(matrix).all():
|
||||||
print("Matrix doesn't containt all real numbers.")
|
print("Matrix doesn't contain all real numbers.")
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Method that performs Householder Transformation QR, acceptcs 2D, real numbers matrix, that
|
Method that performs Householder Transformation QR, accepts 2D, real numbers matrix, that
|
||||||
fulfills m >= n condition. Return Q and R matrices.
|
fulfills m >= n condition. Return Q and R matrices.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def perform_householder_QR(self, matrix: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
|
def perform_householder_QR(self, matrix: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
|
||||||
if(self.__check_pre_conditions(matrix)):
|
if self.__check_pre_conditions(matrix):
|
||||||
return self.__householder_qr(matrix)
|
return self.__householder_qr(matrix)
|
||||||
else:
|
else:
|
||||||
print("Incorrect type.")
|
print("Incorrect type.")
|
||||||
@ -55,10 +65,10 @@ class QR:
|
|||||||
v = matrix / (matrix[0] + np.copysign(np.linalg.norm(matrix), matrix[0]))
|
v = matrix / (matrix[0] + np.copysign(np.linalg.norm(matrix), matrix[0]))
|
||||||
v[0] = 1
|
v[0] = 1
|
||||||
tau = 2 / (v.T @ v)
|
tau = 2 / (v.T @ v)
|
||||||
return v,tau
|
return v, tau
|
||||||
|
|
||||||
def __householder_qr(self, matrix: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
|
def __householder_qr(self, matrix: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
|
||||||
m,n = matrix.shape
|
m, n = matrix.shape
|
||||||
R = matrix.copy()
|
R = matrix.copy()
|
||||||
Q = np.identity(m)
|
Q = np.identity(m)
|
||||||
|
|
||||||
@ -76,27 +86,40 @@ class QR:
|
|||||||
m, n = matrix.shape
|
m, n = matrix.shape
|
||||||
R = matrix
|
R = matrix
|
||||||
Q = np.eye(m)
|
Q = np.eye(m)
|
||||||
G = np.zeros((2,2))
|
G = np.zeros((2, 2))
|
||||||
for j in range(n):
|
for j in range(n):
|
||||||
for i in reversed(range(j+1, m)):
|
for i in reversed(range(j + 1, m)):
|
||||||
a, b = R[i-1, j], R[i, j]
|
a, b = R[i - 1, j], R[i, j]
|
||||||
G = np.asarray([[a, b], [-b, a]]) / np.sqrt(a**2 + b**2)
|
G = np.asarray([[a, b], [-b, a]]) / np.sqrt(a ** 2 + b ** 2)
|
||||||
R[i-1:i+1, j] = G @ R[i-1:i+1, j]
|
R[i - 1:i + 1, j] = G @ R[i - 1:i + 1, j]
|
||||||
Q[i-1:i+1, :] = G @ Q[i-1:i+1, :]
|
Q[i - 1:i + 1, :] = G @ Q[i - 1:i + 1, :]
|
||||||
|
|
||||||
return Q.T, R
|
return Q.T, R
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Method that performs Givens Rotation QR, acceptcs 2D, real numbers matrix, that
|
Method that performs Givens Rotation QR, accepts 2D, real numbers matrix, that
|
||||||
fulfills m >= n condition. Return Q and R matrices.
|
fulfills m >= n condition. Return Q and R matrices.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def perform_givens_QR(self, matrix: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
|
def perform_givens_QR(self, matrix: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
|
||||||
if(self.__check_pre_conditions(matrix)):
|
if self.__check_pre_conditions(matrix):
|
||||||
return self.__givens_qr(matrix)
|
return self.__givens_qr(matrix)
|
||||||
else:
|
else:
|
||||||
print("Incorrect type.")
|
print("Incorrect type.")
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
|
def solve_least_squares(self, A: np.ndarray, b: np.array):
|
||||||
|
Q, R = self.perform_householder_QR(A)
|
||||||
|
x = solve(R, np.dot(Q.T, b))
|
||||||
|
return x
|
||||||
|
|
||||||
|
def __design_matrix(self, A: np.ndarray):
|
||||||
|
return np.hstack((np.ones(A.shape[0]).reshape(-1, 1), A[:, :-1]))
|
||||||
|
|
||||||
|
def fit_poly(self, A: np.ndarray):
|
||||||
|
return self.solve_least_squares(
|
||||||
|
np.dot(self.__design_matrix(A), self.__design_matrix(A).T),
|
||||||
|
A[:, -1:].reshape(-1, 1))
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -104,7 +127,7 @@ Usage example
|
|||||||
"""
|
"""
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
qr = QR()
|
qr = QR()
|
||||||
matrix = np.matrix('1 2 4; 5 6 7; 8 9 10')
|
matrix = np.matrix('0 0 0; 1 1 2; 1 2 4; 3 3 5; 5 6 7; 8 9 10')
|
||||||
matrix = np.asarray(matrix)
|
matrix = np.asarray(matrix)
|
||||||
print(matrix)
|
print(matrix)
|
||||||
a = deepcopy(matrix)
|
a = deepcopy(matrix)
|
||||||
@ -123,4 +146,39 @@ if __name__ == "__main__":
|
|||||||
Q, R = np.linalg.qr(c)
|
Q, R = np.linalg.qr(c)
|
||||||
print(Q)
|
print(Q)
|
||||||
print(R)
|
print(R)
|
||||||
|
print('solve least squares')
|
||||||
|
b_v = np.asarray([1, 1, ])
|
||||||
|
print(matrix)
|
||||||
|
print(b_v)
|
||||||
|
|
||||||
|
|
||||||
|
def PolyCoefficients(x, coeffs):
|
||||||
|
""" Returns a polynomial for ``x`` values for the ``coeffs`` provided.
|
||||||
|
The coefficients must be in ascending order (``x**0`` to ``x**o``).
|
||||||
|
"""
|
||||||
|
o = len(coeffs)
|
||||||
|
y = 0
|
||||||
|
for i in range(o):
|
||||||
|
y += coeffs[i] * x ** i
|
||||||
|
return y
|
||||||
|
|
||||||
|
|
||||||
|
def f(a, b):
|
||||||
|
return a + 2 * b
|
||||||
|
|
||||||
|
|
||||||
|
x1 = np.asarray(range(0, 6))
|
||||||
|
x2 = np.asarray(range(0, 6))
|
||||||
|
y = f(x1, x2)
|
||||||
|
mat = np.asmatrix([x1, x2, y])
|
||||||
|
|
||||||
|
plt3d = plt.figure().gca(projection='3d')
|
||||||
|
xx, yy = np.meshgrid(range(10), range(10))
|
||||||
|
plt3d.plot_surface(xx, yy, f(xx, yy), alpha=0.2)
|
||||||
|
print(mat.T)
|
||||||
|
print(matrix)
|
||||||
|
print(matrix.shape, mat.T.shape)
|
||||||
|
# plt3d.plot_surface(xx, yy, PolyCoefficients(xx, qr.fit_poly(matrix)), alpha=0.2)
|
||||||
|
plt3d.plot_surface(xx, yy, PolyCoefficients(xx, qr.fit_poly(mat.T)), alpha=0.2)
|
||||||
|
|
||||||
|
plt.show()
|
||||||
|
Loading…
Reference in New Issue
Block a user