Tried to fix lanczos implementation
Still solution far from correct.
This commit is contained in:
@@ -4,7 +4,7 @@ Project description
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🚀 Quick Start
|
## Quick Start
|
||||||
|
|
||||||
### Setup
|
### Setup
|
||||||
|
|
||||||
@@ -19,3 +19,13 @@ Project description
|
|||||||
- **Test**: `uv run pytest`
|
- **Test**: `uv run pytest`
|
||||||
- **Format**: `uv run ruff format .`
|
- **Format**: `uv run ruff format .`
|
||||||
- **Lint**: `uv run ruff check . --fix`
|
- **Lint**: `uv run ruff check . --fix`
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
[1] Susnjara et al., Accelerated filtering on graphs using Lanczos method.
|
||||||
|
|
||||||
|
[2] https://epfl-lts2.github.io/gspbox-html/
|
||||||
|
|
||||||
|
## Online guides
|
||||||
|
|
||||||
|
https://every-algorithm.github.io/2024/05/23/lanczos_algorithm.html
|
||||||
|
|||||||
+23
-11
@@ -1,6 +1,12 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
|
import numpy.linalg as LA
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
Arguments
|
||||||
|
L Real valued NxN symmetric matrix
|
||||||
|
s vector of size N
|
||||||
|
M natural number indicating basis size
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
V : ndarray
|
V : ndarray
|
||||||
@@ -13,16 +19,22 @@ beta : ndarray
|
|||||||
|
|
||||||
|
|
||||||
def lanczos(L, s, M):
|
def lanczos(L, s, M):
|
||||||
|
N = len(s)
|
||||||
alp = np.zeros(M)
|
alp = np.zeros(M)
|
||||||
beta = np.zeros(M)
|
beta = np.zeros(M - 1)
|
||||||
V = np.zeros(M)
|
V = np.zeros((N, M))
|
||||||
V[0] = s / np.norm(s)
|
V[:, 0] = s / LA.norm(s)
|
||||||
|
|
||||||
for j in range(0, M):
|
for j in range(M):
|
||||||
w = L * V
|
w = L @ V[:, j]
|
||||||
alp[j] = V[j] @ w
|
alp[j] = np.dot(V[:, j], w)
|
||||||
Vtmp = w - V[j] * alp[j]
|
|
||||||
if j > 1:
|
v_tilde = w - V[:, j] * alp[j]
|
||||||
Vtmp = Vtmp - V[j - 1] * beta[j - 1]
|
if j > 0:
|
||||||
beta[j] = np.norm(Vtmp)
|
v_tilde = v_tilde - V[:, j - 1] * beta[j - 1]
|
||||||
V[j + 1] = Vtmp / beta[j]
|
|
||||||
|
if j < M - 1:
|
||||||
|
beta[j] = LA.norm(v_tilde)
|
||||||
|
V[:, j + 1] = v_tilde / beta[j]
|
||||||
|
|
||||||
|
return [V, alp, beta]
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import numpy as np
|
||||||
|
import numpy.linalg as LA
|
||||||
|
from afgl.lanczos import lanczos
|
||||||
|
|
||||||
|
"""
|
||||||
|
Todo: better test case
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def test_lanczos_return_correct_solution():
|
||||||
|
N = 6
|
||||||
|
M = 4
|
||||||
|
|
||||||
|
A = np.random.randint(1, 10, size=(N, N))
|
||||||
|
L = (A + A.T) / 2
|
||||||
|
s = np.random.randint(1, 10, N)
|
||||||
|
[V, alp, beta] = lanczos(L, s, M)
|
||||||
|
|
||||||
|
T = np.diag(alp) + np.diag(beta, -1) + np.diag(beta, 1)
|
||||||
|
|
||||||
|
x = LA.solve(A, s)
|
||||||
|
e_1 = np.zeros(M)
|
||||||
|
e_1[0] = 1
|
||||||
|
y = (LA.inv(T) @ e_1) * LA.norm(s)
|
||||||
|
x_lanczos = V @ y
|
||||||
|
|
||||||
|
assert LA.norm(x - x_lanczos) < 1e-3
|
||||||
|
|||||||
Reference in New Issue
Block a user