-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnull_space_solver.py
More file actions
36 lines (31 loc) · 1.1 KB
/
Copy pathnull_space_solver.py
File metadata and controls
36 lines (31 loc) · 1.1 KB
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
from scipy.linalg import null_space
from scipy.sparse import csr_matrix
from scipy.sparse.linalg import spsolve, lsqr
import numpy as np
class NullSpaceSolver:
def __init__(self, P, A):
self.P = csr_matrix(P)
self.A = csr_matrix(A)
self.AT = csr_matrix(A.T)
self.Z = self.calc_null_space(A)
self.P_ = csr_matrix(self.Z.T @ self.P @ self.Z)
print("max: ", np.max(self.A @ self.Z))
def calc_null_space(self, A):
return null_space(A)
def solve(
self,
f,
g,
):
# Solve A x_hat = g to find a particular solution for constraint
x_hat = lsqr(self.A, g, atol=1e-12, btol=1e-12, iter_lim=10000)[0]
# Right-hand side for reduced system
rhs = self.Z.T @ (f - self.P @ x_hat)
# Solve Z^T P Z z = rhs
z = spsolve(self.P_, rhs)
# Full x
x = x_hat + self.Z @ z
# Solve for y from A.T y = f - P x
y = lsqr(self.AT, f - self.P @ x, atol=1e-12, btol=1e-12, iter_lim=10000)[0]
print(f"error: {np.max(self.A.T @ y - (f - self.P @ x))}")
return x, y