Skip to content

Commit 9661808

Browse files
authored
Add maxIteration argument for eigenValuesQR (#726)
1 parent a1618ed commit 9661808

File tree

2 files changed

+22
-14
lines changed

2 files changed

+22
-14
lines changed

lib/util/matrix.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4220,17 +4220,18 @@ export default class Matrix {
42204220
/**
42214221
* Returns eigenvalues by LU decomposition.
42224222
*
4223+
* @param {number} [maxIteration=1.0e5] Maximum iteration
42234224
* @returns {number[]} Eigenvalues
42244225
*/
4225-
eigenValuesLR() {
4226+
eigenValuesLR(maxIteration = 1.0e5) {
42264227
if (!this.isSquare()) {
42274228
throw new MatrixException('Eigen values only define square matrix.', this)
42284229
}
42294230

42304231
let a = this
42314232
const n = a.rows
42324233
const tol = 1.0e-15
4233-
let maxCount = 1.0e5
4234+
let maxCount = maxIteration
42344235
while (maxCount-- > 0) {
42354236
const [l, u] = a.lu()
42364237
a = u.dot(l)
@@ -4253,9 +4254,10 @@ export default class Matrix {
42534254
/**
42544255
* Returns eigenvalues by QR decomposition.
42554256
*
4257+
* @param {number} [maxIteration=1.0e6] Maximum iteration
42564258
* @returns {number[]} Eigenvalues
42574259
*/
4258-
eigenValuesQR() {
4260+
eigenValuesQR(maxIteration = 1.0e6) {
42594261
if (!this.isSquare()) {
42604262
throw new MatrixException('Eigen values only define square matrix.', this)
42614263
}
@@ -4264,7 +4266,7 @@ export default class Matrix {
42644266
const ev = []
42654267
const tol = 1.0e-8
42664268
for (let n = a.rows; n > 2; n--) {
4267-
let maxCount = 1.0e6
4269+
let maxCount = maxIteration
42684270
while (1) {
42694271
const am = a.block(n - 2, n - 2).eigenValues()
42704272
if (isNaN(am[0])) {
@@ -4383,9 +4385,10 @@ export default class Matrix {
43834385
/**
43844386
* Returns the maximum eigenvalue and its eigenvector.
43854387
*
4388+
* @param {number} [maxIteration=1.0e4] Maximum iteration
43864389
* @returns {[number, Matrix]} Maximum eigenvalue and its eigenvector
43874390
*/
4388-
eigenPowerIteration() {
4391+
eigenPowerIteration(maxIteration = 1.0e4) {
43894392
if (!this.isSquare()) {
43904393
throw new MatrixException('Eigen vectors only define square matrix.', this)
43914394
}
@@ -4395,7 +4398,7 @@ export default class Matrix {
43954398
let px = Matrix.randn(n, 1)
43964399
px.div(px.norm())
43974400
let pl = Infinity
4398-
let maxCount = 1.0e4
4401+
let maxCount = maxIteration
43994402
while (maxCount-- > 0) {
44004403
const x = this.dot(px)
44014404
let lnum = 0,
@@ -4420,9 +4423,10 @@ export default class Matrix {
44204423
* Returns the nearest eigenvalue and its eigenvector to the specified value.
44214424
*
44224425
* @param {number} [ev=0.0] Target value
4426+
* @param {number} [maxIteration=1.0e4] Maximum iteration
44234427
* @returns {[number, Matrix]} Eigenvalue and eigenvector
44244428
*/
4425-
eigenInverseIteration(ev = 0.0) {
4429+
eigenInverseIteration(ev = 0.0, maxIteration = 1.0e4) {
44264430
if (!this.isSquare()) {
44274431
throw new MatrixException('Eigen vectors only define square matrix.', this)
44284432
}
@@ -4437,7 +4441,7 @@ export default class Matrix {
44374441
let py = Matrix.randn(n, 1)
44384442
py.div(py.norm())
44394443
let pl = Infinity
4440-
let maxCount = 1.0e4
4444+
let maxCount = maxIteration
44414445
while (maxCount-- > 0) {
44424446
const y = a.dot(py)
44434447
let lnum = 0,

tests/lib/util/matrix.test.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5469,15 +5469,19 @@ describe('Matrix', () => {
54695469
test('fail neg value', () => {
54705470
const mat = Matrix.randn(3, 3)
54715471
mat.set(0, 0, -0.1)
5472-
expect(() => mat.balancingSinkhornKnopp()).toThrow('Doubly stochastic matrix only calculate for non negative matrix.')
5472+
expect(() => mat.balancingSinkhornKnopp()).toThrow(
5473+
'Doubly stochastic matrix only calculate for non negative matrix.'
5474+
)
54735475
})
54745476

54755477
test.each([
54765478
[2, 3],
54775479
[3, 2],
54785480
])('fail(%i, %i)', (r, c) => {
54795481
const mat = Matrix.randn(r, c)
5480-
expect(() => mat.balancingSinkhornKnopp()).toThrow('Doubly stochastic matrix only defined for square matrix.')
5482+
expect(() => mat.balancingSinkhornKnopp()).toThrow(
5483+
'Doubly stochastic matrix only defined for square matrix.'
5484+
)
54815485
})
54825486
})
54835487

@@ -6653,13 +6657,13 @@ describe('Matrix', () => {
66536657
expect(() => mat.eigenValuesQR()).toThrow('Eigen values only define square matrix.')
66546658
})
66556659

6656-
test.only('iteration not converged', () => {
6660+
test('iteration not converged', () => {
66576661
const mat = new Matrix(3, 3, [
66586662
[-0.3, -0.4, 1.7],
66596663
[-0.2, -1.8, -0.8],
66606664
[-0.9, 0.5, -0.5],
66616665
])
6662-
expect(() => mat.eigenValuesQR()).toThrow('eigenValuesQR not converged.')
6666+
expect(() => mat.eigenValuesQR(1)).toThrow('eigenValuesQR not converged.')
66636667
})
66646668
})
66656669

@@ -6782,7 +6786,7 @@ describe('Matrix', () => {
67826786
[-1, -2],
67836787
[2, -2],
67846788
])
6785-
expect(() => mat.eigenPowerIteration()).toThrow('eigenPowerIteration not converged.')
6789+
expect(() => mat.eigenPowerIteration(1)).toThrow('eigenPowerIteration not converged.')
67866790
})
67876791
})
67886792

@@ -6856,7 +6860,7 @@ describe('Matrix', () => {
68566860
[-1, -2],
68576861
[2, -2],
68586862
])
6859-
expect(() => mat.eigenInverseIteration()).toThrow('eigenInverseIteration not converged.')
6863+
expect(() => mat.eigenInverseIteration(0, 1)).toThrow('eigenInverseIteration not converged.')
68606864
})
68616865
})
68626866
})

0 commit comments

Comments
 (0)