Returns solution to the linear system np.dot(spd_matrix, x) = b. Input: spd_matrix is an NxN Symmetric Positive Definite (SPD) matrix. load_vector is an Nx1 vector. Output: x is an Nx1 vector that is the solution vector. >>> import numpy as np >>> spd_matrix = np.
(
spd_matrix: np.ndarray,
load_vector: np.ndarray,
max_iterations: int = 1000,
tol: float = 1e-8,
)
| 69 | |
| 70 | |
| 71 | def conjugate_gradient( |
| 72 | spd_matrix: np.ndarray, |
| 73 | load_vector: np.ndarray, |
| 74 | max_iterations: int = 1000, |
| 75 | tol: float = 1e-8, |
| 76 | ) -> Any: |
| 77 | """ |
| 78 | Returns solution to the linear system np.dot(spd_matrix, x) = b. |
| 79 | |
| 80 | Input: |
| 81 | spd_matrix is an NxN Symmetric Positive Definite (SPD) matrix. |
| 82 | load_vector is an Nx1 vector. |
| 83 | |
| 84 | Output: |
| 85 | x is an Nx1 vector that is the solution vector. |
| 86 | |
| 87 | >>> import numpy as np |
| 88 | >>> spd_matrix = np.array([ |
| 89 | ... [8.73256573, -5.02034289, -2.68709226], |
| 90 | ... [-5.02034289, 3.78188322, 0.91980451], |
| 91 | ... [-2.68709226, 0.91980451, 1.94746467]]) |
| 92 | >>> b = np.array([ |
| 93 | ... [-5.80872761], |
| 94 | ... [ 3.23807431], |
| 95 | ... [ 1.95381422]]) |
| 96 | >>> conjugate_gradient(spd_matrix, b) |
| 97 | array([[-0.63114139], |
| 98 | [-0.01561498], |
| 99 | [ 0.13979294]]) |
| 100 | """ |
| 101 | # Ensure proper dimensionality. |
| 102 | assert np.shape(spd_matrix)[0] == np.shape(spd_matrix)[1] |
| 103 | assert np.shape(load_vector)[0] == np.shape(spd_matrix)[0] |
| 104 | assert _is_matrix_spd(spd_matrix) |
| 105 | |
| 106 | # Initialize solution guess, residual, search direction. |
| 107 | x0 = np.zeros((np.shape(load_vector)[0], 1)) |
| 108 | r0 = np.copy(load_vector) |
| 109 | p0 = np.copy(r0) |
| 110 | |
| 111 | # Set initial errors in solution guess and residual. |
| 112 | error_residual = 1e9 |
| 113 | error_x_solution = 1e9 |
| 114 | error = 1e9 |
| 115 | |
| 116 | # Set iteration counter to threshold number of iterations. |
| 117 | iterations = 0 |
| 118 | |
| 119 | while error > tol: |
| 120 | # Save this value so we only calculate the matrix-vector product once. |
| 121 | w = np.dot(spd_matrix, p0) |
| 122 | |
| 123 | # The main algorithm. |
| 124 | |
| 125 | # Update search direction magnitude. |
| 126 | alpha = np.dot(r0.T, r0) / np.dot(p0.T, w) |
| 127 | # Update solution guess. |
| 128 | x = x0 + alpha * p0 |