-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
71 lines (63 loc) · 1.42 KB
/
index.js
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import { transpose, matrixDot } from './../../utils'
const getR = (c, s, p, q, n) => {
const R = []
for (let i = 0; i < n; i++) {
R[i] = []
for (let j = 0; j < n; j++) {
if (i === p && j === p) {
R[i][j] = c
} else if (i === p && j === q) {
R[i][j] = s
} else if (i === q && j === p) {
R[i][j] = -s
} else if (i === q && j === q) {
R[i][j] = c
} else if (i === j) {
R[i][j] = 1
} else {
R[i][j] = 0
}
}
}
return R
}
const getPQ = M => {
let p = 0
let q = 0
let m = -1
const n = M.length // Size of the matrix
for (let i = 1; i < n; i++) {
for (let j = 0; j < i; j++) {
if (m < Math.abs(M[i][j])) {
m = Math.abs(M[i][j])
p = i
q = j
}
}
}
return [p, q]
}
const getCS = (p, q, M) => {
const µ = (M[q][q] - M[p][p]) / (2 * M[p][q])
const t = -Math.sqrt(µ ** 2 + 1) - µ
const c = 1 / Math.sqrt(1 + t ** 2)
const s = t / Math.sqrt(1 + t ** 2)
return [c, s]
}
export default function jacobi (matrix, epsilon = 0.0001) {
let step = 0
let v = Number.MAX_SAFE_INTEGER
while (Math.abs(v) > epsilon) {
const [p, q] = getPQ(matrix)
v = matrix[p][q]
const [c, s] = getCS(p, q, matrix)
const r = getR(c, s, p, q, matrix.length)
const rt = transpose(r)
matrix = matrixDot(rt, matrixDot(matrix, r))
step++
}
return {
matrix,
step
}
}