first commit
This commit is contained in:
107
project1/Project1_Q1.py
Normal file
107
project1/Project1_Q1.py
Normal file
@@ -0,0 +1,107 @@
|
||||
import numpy as np
|
||||
|
||||
def proj(A:np.ndarray, b:np.ndarray) -> np.ndarray:
|
||||
"""
|
||||
Project vector b onto the column space of matrix A using the formula:
|
||||
proj_A(b) = A(A^* A)^(-1) A^* b
|
||||
|
||||
Parameters:
|
||||
A (np.ndarray): The matrix whose column space we are projecting onto.
|
||||
b (np.ndarray): The vector to be projected.
|
||||
|
||||
Returns:
|
||||
np.ndarray: The projection of b onto the column space of A.
|
||||
"""
|
||||
# Check if A is full rank
|
||||
if np.linalg.matrix_rank(A) < min(A.shape):
|
||||
raise ValueError("Matrix A must be full rank.")
|
||||
# Compute the projection
|
||||
AhA_inv = np.linalg.inv(A.conj().T @ A)
|
||||
projection = A @ AhA_inv @ A.conj().T @ b
|
||||
return projection
|
||||
|
||||
def proj_SVD(A:np.ndarray, b:np.ndarray) -> np.ndarray:
|
||||
"""
|
||||
Project vector b onto the column space of matrix A using SVD.
|
||||
|
||||
Parameters:
|
||||
A (np.ndarray): The matrix whose column space we are projecting onto.
|
||||
b (np.ndarray): The vector to be projected.
|
||||
|
||||
Returns:
|
||||
np.ndarray: The projection of b onto the column space of A.
|
||||
"""
|
||||
# A = U S V^*
|
||||
U, S, Vh = np.linalg.svd(A, full_matrices=False)
|
||||
"""
|
||||
proj_A(b) = A(A^* A)^(-1) A^* b
|
||||
= U S V^* (V S^2 V^*)^(-1) V S U^* b
|
||||
= U S V^* V S^(-2) V^* V S U^* b
|
||||
= U U^* b
|
||||
"""
|
||||
# Compute the projection using the SVD components
|
||||
projection = U @ U.conj().T @ b
|
||||
return projection
|
||||
|
||||
def build_A(eps: float) -> np.ndarray:
|
||||
"""
|
||||
Build the matrix A(ε) as specified in the problem statement.
|
||||
"""
|
||||
A = np.array([
|
||||
[1.0, 1.0, 0.0, (1.0 - eps)],
|
||||
[1.0, 0.0, 1.0, (eps + (1.0 - eps))],
|
||||
[0.0, 1.0, 0.0, eps],
|
||||
[1.0, 0.0, 0.0, (1.0 - eps)],
|
||||
[1.0, 0.0, 0.0, (eps + (1.0 - eps))]
|
||||
], dtype=float)
|
||||
return A
|
||||
|
||||
def build_b() -> np.ndarray:
|
||||
"""
|
||||
Build the vector b as specified in the problem statement.
|
||||
"""
|
||||
b = np.array([2.0, 1.0, 3.0, 1.0, 4.0])
|
||||
return b
|
||||
|
||||
def question_1a(A: np.ndarray, b: np.ndarray):
|
||||
# Question 1(a)
|
||||
print("Question 1(a):")
|
||||
projection = proj(A, b)
|
||||
print("Projection of b onto the column space of A(1): (Using proj function)")
|
||||
print(projection)
|
||||
projection_svd = proj_SVD(A, b)
|
||||
print("Projection of b onto the column space of A(1): (Using proj_SVD function)")
|
||||
print(projection_svd)
|
||||
print("Difference between the two methods:")
|
||||
print(projection - projection_svd)
|
||||
|
||||
def question_1b(A: np.ndarray, b: np.ndarray):
|
||||
# Question 1(b)
|
||||
print("\nQuestion 1(b):")
|
||||
for eps in [1.0, 1e-1, 1e-2, 1e-4, 1e-8, 1e-16, 1e-32]:
|
||||
print(f"\nFor ε = {eps}:")
|
||||
A_eps = build_A(eps)
|
||||
try:
|
||||
projection_eps = proj(A_eps, b)
|
||||
print(f"Projection of b onto the column space of A({eps}):")
|
||||
print(projection_eps)
|
||||
except np.linalg.LinAlgError as e:
|
||||
print(f"LinAlgError for eps={eps}: {e}")
|
||||
except ValueError as ve:
|
||||
print(f"ValueError for eps={eps}: {ve}")
|
||||
projection_svd_eps = proj_SVD(A_eps, b)
|
||||
print(f"Projection of b onto the column space of A({eps}) using SVD:")
|
||||
print(projection_svd_eps)
|
||||
print("Difference between the two methods:")
|
||||
try:
|
||||
print(projection_eps - projection_svd_eps)
|
||||
except:
|
||||
print("Could not compute difference due to previous error.")
|
||||
projection_eps = None # Reset for next iteration
|
||||
|
||||
if __name__ == "__main__":
|
||||
A = build_A(eps=1.0)
|
||||
b = build_b()
|
||||
question_1a(A, b)
|
||||
question_1b(A, b)
|
||||
|
||||
Reference in New Issue
Block a user