mathjs 9.3.2 → 9.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HISTORY.md +22 -0
- package/README.md +1 -0
- package/bin/cli.js +11 -11
- package/docs/expressions/parsing.md +21 -4
- package/docs/reference/functions/complex.md +5 -49
- package/docs/reference/functions/eigs.md +12 -12
- package/docs/reference/functions/flatten.md +1 -0
- package/docs/reference/functions/matrixFromColumns.md +1 -1
- package/docs/reference/functions/matrixFromFunction.md +12 -0
- package/docs/reference/functions/matrixFromRows.md +1 -1
- package/docs/reference/functions.md +4 -1
- package/examples/advanced/custom_scope_objects.js +115 -0
- package/lib/browser/math.js +10 -10
- package/lib/browser/math.js.map +1 -1
- package/lib/cjs/core/create.js +8 -7
- package/lib/cjs/core/function/import.js +9 -7
- package/lib/cjs/core/function/typed.js +6 -1
- package/lib/cjs/defaultInstance.js +3 -3
- package/lib/cjs/entry/allFactoriesAny.js +3 -3
- package/lib/cjs/entry/allFactoriesNumber.js +3 -3
- package/lib/cjs/entry/configReadonly.js +5 -4
- package/lib/cjs/entry/dependenciesAny/dependenciesEigs.generated.js +51 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesMatrixFromColumns.generated.js +29 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesMatrixFromFunction.generated.js +26 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesMatrixFromRows.generated.js +29 -0
- package/lib/cjs/entry/dependenciesAny.generated.js +24 -0
- package/lib/cjs/entry/impureFunctionsAny.generated.js +22 -17
- package/lib/cjs/entry/impureFunctionsNumber.generated.js +11 -9
- package/lib/cjs/entry/pureFunctionsAny.generated.js +78 -41
- package/lib/cjs/expression/Parser.js +22 -15
- package/lib/cjs/expression/embeddedDocs/embeddedDocs.js +9 -0
- package/lib/cjs/expression/embeddedDocs/function/matrix/column.js +1 -1
- package/lib/cjs/expression/embeddedDocs/function/matrix/matrixFromColumns.js +15 -0
- package/lib/cjs/expression/embeddedDocs/function/matrix/matrixFromFunction.js +15 -0
- package/lib/cjs/expression/embeddedDocs/function/matrix/matrixFromRows.js +15 -0
- package/lib/cjs/expression/embeddedDocs/function/matrix/row.js +1 -1
- package/lib/cjs/expression/function/evaluate.js +6 -4
- package/lib/cjs/expression/keywords.js +1 -3
- package/lib/cjs/expression/node/AccessorNode.js +1 -0
- package/lib/cjs/expression/node/AssignmentNode.js +6 -3
- package/lib/cjs/expression/node/FunctionAssignmentNode.js +2 -4
- package/lib/cjs/expression/node/FunctionNode.js +76 -46
- package/lib/cjs/expression/node/IndexNode.js +5 -13
- package/lib/cjs/expression/node/Node.js +15 -9
- package/lib/cjs/expression/node/ObjectNode.js +5 -3
- package/lib/cjs/expression/node/SymbolNode.js +2 -2
- package/lib/cjs/expression/node/utils/access.js +5 -3
- package/lib/cjs/expression/node/utils/assign.js +5 -3
- package/lib/cjs/expression/parse.js +10 -14
- package/lib/cjs/expression/transform/utils/compileInlineExpression.js +5 -3
- package/lib/cjs/factoriesAny.js +24 -0
- package/lib/cjs/function/algebra/decomposition/qr.js +5 -3
- package/lib/cjs/function/algebra/simplify/resolve.js +7 -1
- package/lib/cjs/function/algebra/simplify.js +20 -14
- package/lib/cjs/function/algebra/solver/lsolveAll.js +6 -16
- package/lib/cjs/function/algebra/solver/usolveAll.js +6 -16
- package/lib/cjs/function/arithmetic/ceil.js +6 -16
- package/lib/cjs/function/arithmetic/floor.js +6 -16
- package/lib/cjs/function/arithmetic/norm.js +2 -2
- package/lib/cjs/function/arithmetic/pow.js +9 -7
- package/lib/cjs/function/arithmetic/round.js +7 -5
- package/lib/cjs/function/complex/im.js +3 -0
- package/lib/cjs/function/complex/re.js +3 -0
- package/lib/cjs/function/matrix/eigs/complexEigs.js +631 -0
- package/lib/cjs/function/matrix/eigs/realSymetric.js +341 -0
- package/lib/cjs/function/matrix/eigs.js +188 -334
- package/lib/cjs/function/matrix/flatten.js +1 -0
- package/lib/cjs/function/matrix/matrixFromColumns.js +118 -0
- package/lib/cjs/function/matrix/matrixFromFunction.js +85 -0
- package/lib/cjs/function/matrix/matrixFromRows.js +108 -0
- package/lib/cjs/function/probability/pickRandom.js +1 -1
- package/lib/cjs/function/probability/util/seededRNG.js +2 -2
- package/lib/cjs/function/relational/compareNatural.js +2 -2
- package/lib/cjs/header.js +2 -2
- package/lib/cjs/plain/bignumber/index.js +2 -2
- package/lib/cjs/type/bignumber/BigNumber.js +2 -2
- package/lib/cjs/type/complex/Complex.js +5 -5
- package/lib/cjs/type/fraction/Fraction.js +2 -2
- package/lib/cjs/type/matrix/DenseMatrix.js +138 -0
- package/lib/cjs/type/matrix/Matrix.js +10 -0
- package/lib/cjs/type/matrix/SparseMatrix.js +77 -3
- package/lib/cjs/type/matrix/function/matrix.js +2 -1
- package/lib/cjs/type/unit/Unit.js +15 -13
- package/lib/cjs/utils/array.js +1 -1
- package/lib/cjs/utils/customs.js +18 -4
- package/lib/cjs/utils/emitter.js +2 -2
- package/lib/cjs/utils/function.js +6 -2
- package/lib/cjs/utils/is.js +7 -5
- package/lib/cjs/utils/latex.js +2 -2
- package/lib/cjs/utils/map.js +197 -0
- package/lib/cjs/utils/object.js +6 -5
- package/lib/cjs/utils/scope.js +33 -0
- package/lib/cjs/utils/snapshot.js +17 -16
- package/lib/cjs/utils/string.js +6 -4
- package/lib/cjs/version.js +1 -1
- package/lib/esm/constants.js +15 -15
- package/lib/esm/core/create.js +1 -2
- package/lib/esm/core/function/typed.js +5 -1
- package/lib/esm/entry/configReadonly.js +1 -2
- package/lib/esm/entry/dependenciesAny/dependenciesEigs.generated.js +34 -0
- package/lib/esm/entry/dependenciesAny/dependenciesMatrixFromColumns.generated.js +16 -0
- package/lib/esm/entry/dependenciesAny/dependenciesMatrixFromFunction.generated.js +14 -0
- package/lib/esm/entry/dependenciesAny/dependenciesMatrixFromRows.generated.js +16 -0
- package/lib/esm/entry/dependenciesAny.generated.js +3 -0
- package/lib/esm/entry/impureFunctionsAny.generated.js +13 -10
- package/lib/esm/entry/impureFunctionsNumber.generated.js +1 -1
- package/lib/esm/entry/pureFunctionsAny.generated.js +66 -32
- package/lib/esm/expression/Help.js +1 -1
- package/lib/esm/expression/Parser.js +23 -15
- package/lib/esm/expression/embeddedDocs/embeddedDocs.js +6 -0
- package/lib/esm/expression/embeddedDocs/function/matrix/column.js +1 -1
- package/lib/esm/expression/embeddedDocs/function/matrix/matrixFromColumns.js +8 -0
- package/lib/esm/expression/embeddedDocs/function/matrix/matrixFromFunction.js +8 -0
- package/lib/esm/expression/embeddedDocs/function/matrix/matrixFromRows.js +8 -0
- package/lib/esm/expression/embeddedDocs/function/matrix/row.js +1 -1
- package/lib/esm/expression/function/compile.js +1 -1
- package/lib/esm/expression/function/evaluate.js +6 -5
- package/lib/esm/expression/function/help.js +1 -1
- package/lib/esm/expression/function/parser.js +1 -1
- package/lib/esm/expression/keywords.js +1 -3
- package/lib/esm/expression/node/AccessorNode.js +2 -1
- package/lib/esm/expression/node/ArrayNode.js +1 -1
- package/lib/esm/expression/node/AssignmentNode.js +7 -4
- package/lib/esm/expression/node/BlockNode.js +1 -1
- package/lib/esm/expression/node/ConditionalNode.js +1 -1
- package/lib/esm/expression/node/ConstantNode.js +1 -1
- package/lib/esm/expression/node/FunctionAssignmentNode.js +3 -4
- package/lib/esm/expression/node/FunctionNode.js +57 -39
- package/lib/esm/expression/node/IndexNode.js +1 -1
- package/lib/esm/expression/node/Node.js +7 -8
- package/lib/esm/expression/node/ObjectNode.js +1 -1
- package/lib/esm/expression/node/OperatorNode.js +1 -1
- package/lib/esm/expression/node/ParenthesisNode.js +1 -1
- package/lib/esm/expression/node/RangeNode.js +1 -1
- package/lib/esm/expression/node/RelationalNode.js +1 -1
- package/lib/esm/expression/node/SymbolNode.js +3 -3
- package/lib/esm/expression/parse.js +2 -3
- package/lib/esm/expression/transform/apply.transform.js +1 -1
- package/lib/esm/expression/transform/column.transform.js +1 -1
- package/lib/esm/expression/transform/concat.transform.js +1 -1
- package/lib/esm/expression/transform/diff.transform.js +1 -1
- package/lib/esm/expression/transform/filter.transform.js +1 -1
- package/lib/esm/expression/transform/forEach.transform.js +1 -1
- package/lib/esm/expression/transform/index.transform.js +1 -1
- package/lib/esm/expression/transform/map.transform.js +1 -1
- package/lib/esm/expression/transform/max.transform.js +1 -1
- package/lib/esm/expression/transform/mean.transform.js +1 -1
- package/lib/esm/expression/transform/min.transform.js +1 -1
- package/lib/esm/expression/transform/range.transform.js +1 -1
- package/lib/esm/expression/transform/row.transform.js +1 -1
- package/lib/esm/expression/transform/std.transform.js +1 -1
- package/lib/esm/expression/transform/subset.transform.js +1 -1
- package/lib/esm/expression/transform/sum.transform.js +1 -1
- package/lib/esm/expression/transform/utils/compileInlineExpression.js +4 -3
- package/lib/esm/expression/transform/variance.transform.js +1 -1
- package/lib/esm/factoriesAny.js +3 -0
- package/lib/esm/factoriesNumber.js +1 -1
- package/lib/esm/function/algebra/decomposition/lup.js +1 -1
- package/lib/esm/function/algebra/decomposition/qr.js +2 -3
- package/lib/esm/function/algebra/decomposition/slu.js +1 -1
- package/lib/esm/function/algebra/derivative.js +1 -1
- package/lib/esm/function/algebra/rationalize.js +1 -1
- package/lib/esm/function/algebra/simplify/resolve.js +7 -2
- package/lib/esm/function/algebra/simplify/simplifyConstant.js +1 -1
- package/lib/esm/function/algebra/simplify/simplifyCore.js +1 -1
- package/lib/esm/function/algebra/simplify/util.js +1 -1
- package/lib/esm/function/algebra/simplify.js +16 -12
- package/lib/esm/function/algebra/solver/lsolve.js +1 -1
- package/lib/esm/function/algebra/solver/lsolveAll.js +1 -1
- package/lib/esm/function/algebra/solver/lusolve.js +1 -1
- package/lib/esm/function/algebra/solver/usolve.js +1 -1
- package/lib/esm/function/algebra/solver/usolveAll.js +1 -1
- package/lib/esm/function/algebra/sparse/csAmd.js +1 -1
- package/lib/esm/function/algebra/sparse/csChol.js +1 -1
- package/lib/esm/function/algebra/sparse/csCounts.js +1 -1
- package/lib/esm/function/algebra/sparse/csLu.js +1 -1
- package/lib/esm/function/algebra/sparse/csSpsolve.js +1 -1
- package/lib/esm/function/algebra/sparse/csSqr.js +1 -1
- package/lib/esm/function/algebra/sparse/csSymperm.js +1 -1
- package/lib/esm/function/arithmetic/abs.js +1 -1
- package/lib/esm/function/arithmetic/add.js +1 -1
- package/lib/esm/function/arithmetic/addScalar.js +1 -1
- package/lib/esm/function/arithmetic/cbrt.js +1 -1
- package/lib/esm/function/arithmetic/ceil.js +1 -1
- package/lib/esm/function/arithmetic/cube.js +1 -1
- package/lib/esm/function/arithmetic/divide.js +1 -1
- package/lib/esm/function/arithmetic/divideScalar.js +1 -1
- package/lib/esm/function/arithmetic/dotDivide.js +1 -1
- package/lib/esm/function/arithmetic/dotMultiply.js +1 -1
- package/lib/esm/function/arithmetic/dotPow.js +1 -1
- package/lib/esm/function/arithmetic/exp.js +1 -1
- package/lib/esm/function/arithmetic/expm1.js +1 -1
- package/lib/esm/function/arithmetic/fix.js +1 -1
- package/lib/esm/function/arithmetic/floor.js +1 -1
- package/lib/esm/function/arithmetic/gcd.js +1 -1
- package/lib/esm/function/arithmetic/hypot.js +1 -1
- package/lib/esm/function/arithmetic/lcm.js +1 -1
- package/lib/esm/function/arithmetic/log.js +1 -1
- package/lib/esm/function/arithmetic/log10.js +1 -1
- package/lib/esm/function/arithmetic/log1p.js +1 -1
- package/lib/esm/function/arithmetic/log2.js +1 -1
- package/lib/esm/function/arithmetic/mod.js +1 -1
- package/lib/esm/function/arithmetic/multiply.js +1 -1
- package/lib/esm/function/arithmetic/multiplyScalar.js +1 -1
- package/lib/esm/function/arithmetic/norm.js +3 -3
- package/lib/esm/function/arithmetic/nthRoot.js +2 -2
- package/lib/esm/function/arithmetic/nthRoots.js +1 -1
- package/lib/esm/function/arithmetic/pow.js +10 -8
- package/lib/esm/function/arithmetic/round.js +6 -6
- package/lib/esm/function/arithmetic/sign.js +1 -1
- package/lib/esm/function/arithmetic/sqrt.js +1 -1
- package/lib/esm/function/arithmetic/square.js +1 -1
- package/lib/esm/function/arithmetic/subtract.js +1 -1
- package/lib/esm/function/arithmetic/unaryMinus.js +1 -1
- package/lib/esm/function/arithmetic/unaryPlus.js +1 -1
- package/lib/esm/function/arithmetic/xgcd.js +1 -1
- package/lib/esm/function/bitwise/bitAnd.js +1 -1
- package/lib/esm/function/bitwise/bitNot.js +1 -1
- package/lib/esm/function/bitwise/bitOr.js +1 -1
- package/lib/esm/function/bitwise/bitXor.js +1 -1
- package/lib/esm/function/bitwise/leftShift.js +1 -1
- package/lib/esm/function/bitwise/rightArithShift.js +1 -1
- package/lib/esm/function/bitwise/rightLogShift.js +1 -1
- package/lib/esm/function/combinatorics/bellNumbers.js +1 -1
- package/lib/esm/function/combinatorics/catalan.js +1 -1
- package/lib/esm/function/combinatorics/composition.js +1 -1
- package/lib/esm/function/combinatorics/stirlingS2.js +1 -1
- package/lib/esm/function/complex/arg.js +1 -1
- package/lib/esm/function/complex/conj.js +1 -1
- package/lib/esm/function/complex/im.js +4 -1
- package/lib/esm/function/complex/re.js +4 -1
- package/lib/esm/function/geometry/distance.js +1 -1
- package/lib/esm/function/geometry/intersect.js +1 -1
- package/lib/esm/function/logical/and.js +1 -1
- package/lib/esm/function/logical/not.js +1 -1
- package/lib/esm/function/logical/or.js +1 -1
- package/lib/esm/function/logical/xor.js +1 -1
- package/lib/esm/function/matrix/apply.js +1 -1
- package/lib/esm/function/matrix/column.js +1 -1
- package/lib/esm/function/matrix/concat.js +1 -1
- package/lib/esm/function/matrix/count.js +1 -1
- package/lib/esm/function/matrix/cross.js +1 -1
- package/lib/esm/function/matrix/ctranspose.js +1 -1
- package/lib/esm/function/matrix/det.js +1 -1
- package/lib/esm/function/matrix/diag.js +1 -1
- package/lib/esm/function/matrix/diff.js +1 -1
- package/lib/esm/function/matrix/dot.js +1 -1
- package/lib/esm/function/matrix/eigs/complexEigs.js +586 -0
- package/lib/esm/function/matrix/eigs/realSymetric.js +335 -0
- package/lib/esm/function/matrix/eigs.js +187 -335
- package/lib/esm/function/matrix/expm.js +1 -1
- package/lib/esm/function/matrix/filter.js +1 -1
- package/lib/esm/function/matrix/flatten.js +2 -1
- package/lib/esm/function/matrix/forEach.js +1 -1
- package/lib/esm/function/matrix/getMatrixDataType.js +1 -1
- package/lib/esm/function/matrix/identity.js +1 -1
- package/lib/esm/function/matrix/inv.js +1 -1
- package/lib/esm/function/matrix/kron.js +1 -1
- package/lib/esm/function/matrix/map.js +1 -1
- package/lib/esm/function/matrix/matrixFromColumns.js +93 -0
- package/lib/esm/function/matrix/matrixFromFunction.js +78 -0
- package/lib/esm/function/matrix/matrixFromRows.js +83 -0
- package/lib/esm/function/matrix/ones.js +1 -1
- package/lib/esm/function/matrix/partitionSelect.js +1 -1
- package/lib/esm/function/matrix/range.js +1 -1
- package/lib/esm/function/matrix/reshape.js +1 -1
- package/lib/esm/function/matrix/resize.js +1 -1
- package/lib/esm/function/matrix/rotate.js +1 -1
- package/lib/esm/function/matrix/rotationMatrix.js +1 -1
- package/lib/esm/function/matrix/row.js +1 -1
- package/lib/esm/function/matrix/size.js +1 -1
- package/lib/esm/function/matrix/sort.js +1 -1
- package/lib/esm/function/matrix/sqrtm.js +1 -1
- package/lib/esm/function/matrix/squeeze.js +1 -1
- package/lib/esm/function/matrix/subset.js +1 -1
- package/lib/esm/function/matrix/trace.js +1 -1
- package/lib/esm/function/matrix/transpose.js +1 -1
- package/lib/esm/function/matrix/zeros.js +1 -1
- package/lib/esm/function/probability/combinations.js +1 -1
- package/lib/esm/function/probability/combinationsWithRep.js +1 -1
- package/lib/esm/function/probability/factorial.js +1 -1
- package/lib/esm/function/probability/gamma.js +1 -1
- package/lib/esm/function/probability/kldivergence.js +1 -1
- package/lib/esm/function/probability/multinomial.js +1 -1
- package/lib/esm/function/probability/permutations.js +1 -1
- package/lib/esm/function/probability/pickRandom.js +2 -2
- package/lib/esm/function/probability/random.js +2 -2
- package/lib/esm/function/probability/randomInt.js +1 -1
- package/lib/esm/function/relational/compare.js +2 -2
- package/lib/esm/function/relational/compareNatural.js +1 -1
- package/lib/esm/function/relational/compareText.js +2 -2
- package/lib/esm/function/relational/deepEqual.js +1 -1
- package/lib/esm/function/relational/equal.js +2 -2
- package/lib/esm/function/relational/equalScalar.js +2 -2
- package/lib/esm/function/relational/equalText.js +1 -1
- package/lib/esm/function/relational/larger.js +2 -2
- package/lib/esm/function/relational/largerEq.js +2 -2
- package/lib/esm/function/relational/smaller.js +2 -2
- package/lib/esm/function/relational/smallerEq.js +2 -2
- package/lib/esm/function/relational/unequal.js +2 -2
- package/lib/esm/function/set/setCartesian.js +1 -1
- package/lib/esm/function/set/setDifference.js +1 -1
- package/lib/esm/function/set/setDistinct.js +1 -1
- package/lib/esm/function/set/setIntersect.js +1 -1
- package/lib/esm/function/set/setIsSubset.js +1 -1
- package/lib/esm/function/set/setMultiplicity.js +1 -1
- package/lib/esm/function/set/setPowerset.js +1 -1
- package/lib/esm/function/set/setSize.js +1 -1
- package/lib/esm/function/set/setSymDifference.js +1 -1
- package/lib/esm/function/set/setUnion.js +1 -1
- package/lib/esm/function/special/erf.js +1 -1
- package/lib/esm/function/statistics/mad.js +1 -1
- package/lib/esm/function/statistics/max.js +1 -1
- package/lib/esm/function/statistics/mean.js +1 -1
- package/lib/esm/function/statistics/median.js +1 -1
- package/lib/esm/function/statistics/min.js +1 -1
- package/lib/esm/function/statistics/mode.js +1 -1
- package/lib/esm/function/statistics/prod.js +1 -1
- package/lib/esm/function/statistics/quantileSeq.js +1 -1
- package/lib/esm/function/statistics/std.js +1 -1
- package/lib/esm/function/statistics/sum.js +1 -1
- package/lib/esm/function/statistics/variance.js +1 -1
- package/lib/esm/function/string/bin.js +1 -1
- package/lib/esm/function/string/format.js +1 -1
- package/lib/esm/function/string/hex.js +1 -1
- package/lib/esm/function/string/oct.js +1 -1
- package/lib/esm/function/string/print.js +1 -1
- package/lib/esm/function/trigonometry/acos.js +1 -1
- package/lib/esm/function/trigonometry/acosh.js +1 -1
- package/lib/esm/function/trigonometry/acot.js +1 -1
- package/lib/esm/function/trigonometry/acoth.js +1 -1
- package/lib/esm/function/trigonometry/acsc.js +1 -1
- package/lib/esm/function/trigonometry/acsch.js +1 -1
- package/lib/esm/function/trigonometry/asec.js +1 -1
- package/lib/esm/function/trigonometry/asech.js +1 -1
- package/lib/esm/function/trigonometry/asin.js +1 -1
- package/lib/esm/function/trigonometry/asinh.js +1 -1
- package/lib/esm/function/trigonometry/atan.js +1 -1
- package/lib/esm/function/trigonometry/atan2.js +1 -1
- package/lib/esm/function/trigonometry/atanh.js +1 -1
- package/lib/esm/function/trigonometry/cos.js +1 -1
- package/lib/esm/function/trigonometry/cosh.js +1 -1
- package/lib/esm/function/trigonometry/cot.js +1 -1
- package/lib/esm/function/trigonometry/coth.js +1 -1
- package/lib/esm/function/trigonometry/csc.js +1 -1
- package/lib/esm/function/trigonometry/csch.js +1 -1
- package/lib/esm/function/trigonometry/sec.js +1 -1
- package/lib/esm/function/trigonometry/sech.js +1 -1
- package/lib/esm/function/trigonometry/sin.js +1 -1
- package/lib/esm/function/trigonometry/sinh.js +1 -1
- package/lib/esm/function/trigonometry/tan.js +1 -1
- package/lib/esm/function/trigonometry/tanh.js +1 -1
- package/lib/esm/function/unit/to.js +1 -1
- package/lib/esm/function/utils/clone.js +1 -1
- package/lib/esm/function/utils/hasNumericValue.js +1 -1
- package/lib/esm/function/utils/isInteger.js +1 -1
- package/lib/esm/function/utils/isNaN.js +1 -1
- package/lib/esm/function/utils/isNegative.js +1 -1
- package/lib/esm/function/utils/isNumeric.js +1 -1
- package/lib/esm/function/utils/isPositive.js +1 -1
- package/lib/esm/function/utils/isPrime.js +1 -1
- package/lib/esm/function/utils/isZero.js +1 -1
- package/lib/esm/function/utils/numeric.js +1 -1
- package/lib/esm/function/utils/typeOf.js +1 -1
- package/lib/esm/json/reviver.js +1 -1
- package/lib/esm/type/bignumber/BigNumber.js +1 -1
- package/lib/esm/type/bignumber/function/bignumber.js +1 -1
- package/lib/esm/type/boolean.js +1 -1
- package/lib/esm/type/chain/Chain.js +1 -1
- package/lib/esm/type/chain/function/chain.js +1 -1
- package/lib/esm/type/complex/function/complex.js +1 -1
- package/lib/esm/type/fraction/function/fraction.js +1 -1
- package/lib/esm/type/matrix/DenseMatrix.js +75 -1
- package/lib/esm/type/matrix/FibonacciHeap.js +1 -1
- package/lib/esm/type/matrix/ImmutableDenseMatrix.js +1 -1
- package/lib/esm/type/matrix/Matrix.js +10 -0
- package/lib/esm/type/matrix/MatrixIndex.js +1 -1
- package/lib/esm/type/matrix/Spa.js +1 -1
- package/lib/esm/type/matrix/SparseMatrix.js +37 -3
- package/lib/esm/type/matrix/function/index.js +1 -1
- package/lib/esm/type/matrix/function/matrix.js +3 -2
- package/lib/esm/type/matrix/function/sparse.js +1 -1
- package/lib/esm/type/matrix/utils/algorithm01.js +1 -1
- package/lib/esm/type/matrix/utils/algorithm02.js +1 -1
- package/lib/esm/type/matrix/utils/algorithm03.js +1 -1
- package/lib/esm/type/matrix/utils/algorithm04.js +1 -1
- package/lib/esm/type/matrix/utils/algorithm05.js +1 -1
- package/lib/esm/type/matrix/utils/algorithm06.js +1 -1
- package/lib/esm/type/matrix/utils/algorithm07.js +1 -1
- package/lib/esm/type/matrix/utils/algorithm08.js +1 -1
- package/lib/esm/type/matrix/utils/algorithm09.js +1 -1
- package/lib/esm/type/matrix/utils/algorithm10.js +1 -1
- package/lib/esm/type/matrix/utils/algorithm11.js +1 -1
- package/lib/esm/type/matrix/utils/algorithm12.js +1 -1
- package/lib/esm/type/matrix/utils/algorithm13.js +1 -1
- package/lib/esm/type/matrix/utils/algorithm14.js +1 -1
- package/lib/esm/type/number.js +1 -1
- package/lib/esm/type/string.js +1 -1
- package/lib/esm/type/unit/Unit.js +4 -5
- package/lib/esm/type/unit/function/createUnit.js +1 -1
- package/lib/esm/type/unit/function/splitUnit.js +1 -1
- package/lib/esm/type/unit/function/unit.js +1 -1
- package/lib/esm/type/unit/physicalConstants.js +2 -2
- package/lib/esm/utils/array.js +1 -1
- package/lib/esm/utils/customs.js +10 -0
- package/lib/esm/utils/map.js +135 -0
- package/lib/esm/utils/scope.js +26 -0
- package/lib/esm/utils/snapshot.js +3 -4
- package/lib/esm/version.js +1 -1
- package/package.json +18 -9
|
@@ -0,0 +1,586 @@
|
|
|
1
|
+
import { clone } from '../../../utils/object.js';
|
|
2
|
+
export function createComplexEigs(_ref) {
|
|
3
|
+
var {
|
|
4
|
+
addScalar,
|
|
5
|
+
subtract,
|
|
6
|
+
flatten,
|
|
7
|
+
multiply,
|
|
8
|
+
multiplyScalar,
|
|
9
|
+
divideScalar,
|
|
10
|
+
sqrt,
|
|
11
|
+
abs,
|
|
12
|
+
bignumber,
|
|
13
|
+
diag,
|
|
14
|
+
inv,
|
|
15
|
+
qr,
|
|
16
|
+
usolveAll,
|
|
17
|
+
equal,
|
|
18
|
+
complex,
|
|
19
|
+
larger,
|
|
20
|
+
smaller,
|
|
21
|
+
round,
|
|
22
|
+
log10,
|
|
23
|
+
transpose,
|
|
24
|
+
matrixFromColumns
|
|
25
|
+
} = _ref;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param {number[][]} arr the matrix to find eigenvalues of
|
|
29
|
+
* @param {number} N size of the matrix
|
|
30
|
+
* @param {number|BigNumber} prec precision, anything lower will be considered zero
|
|
31
|
+
* @param {'number'|'BigNumber'|'Complex'} type
|
|
32
|
+
* @param {boolean} findVectors should we find eigenvectors?
|
|
33
|
+
*
|
|
34
|
+
* @returns {{ values: number[], vectors: number[][] }}
|
|
35
|
+
*/
|
|
36
|
+
function complexEigs(arr, N, prec, type, findVectors) {
|
|
37
|
+
if (findVectors === undefined) {
|
|
38
|
+
findVectors = true;
|
|
39
|
+
} // TODO check if any row/col are zero except the diagonal
|
|
40
|
+
// make sure corresponding rows and columns have similar magnitude
|
|
41
|
+
// important because of numerical stability
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
var R = balance(arr, N, prec, type, findVectors); // R is the row transformation matrix
|
|
45
|
+
// A' = R A R⁻¹, A is the original matrix
|
|
46
|
+
// (if findVectors is false, R is undefined)
|
|
47
|
+
// TODO if magnitudes of elements vary over many orders,
|
|
48
|
+
// move greatest elements to the top left corner
|
|
49
|
+
// using similarity transformations, reduce the matrix
|
|
50
|
+
// to Hessenberg form (upper triangular plus one subdiagonal row)
|
|
51
|
+
// updates the transformation matrix R with new row operationsq
|
|
52
|
+
|
|
53
|
+
reduceToHessenberg(arr, N, prec, type, findVectors, R); // find eigenvalues
|
|
54
|
+
|
|
55
|
+
var {
|
|
56
|
+
values,
|
|
57
|
+
C
|
|
58
|
+
} = iterateUntilTriangular(arr, N, prec, type, findVectors); // values is the list of eigenvalues, C is the column
|
|
59
|
+
// transformation matrix that transforms the hessenberg
|
|
60
|
+
// matrix to upper triangular
|
|
61
|
+
// compose transformations A → hess. and hess. → triang.
|
|
62
|
+
|
|
63
|
+
C = multiply(inv(R), C);
|
|
64
|
+
var vectors;
|
|
65
|
+
|
|
66
|
+
if (findVectors) {
|
|
67
|
+
vectors = findEigenvectors(arr, N, C, values, prec);
|
|
68
|
+
vectors = matrixFromColumns(...vectors);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
values,
|
|
73
|
+
vectors
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* @param {number[][]} arr
|
|
78
|
+
* @param {number} N
|
|
79
|
+
* @param {number} prec
|
|
80
|
+
* @param {'number'|'BigNumber'|'Complex'} type
|
|
81
|
+
* @returns {number[][]}
|
|
82
|
+
*/
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
function balance(arr, N, prec, type, findVectors) {
|
|
86
|
+
var big = type === 'BigNumber';
|
|
87
|
+
var cplx = type === 'Complex';
|
|
88
|
+
var zero = big ? bignumber(0) : cplx ? complex(0) : 0;
|
|
89
|
+
var one = big ? bignumber(1) : cplx ? complex(1) : 1; // base of the floating-point arithmetic
|
|
90
|
+
|
|
91
|
+
var radix = big ? bignumber(10) : 2;
|
|
92
|
+
var radixSq = multiplyScalar(radix, radix); // the diagonal transformation matrix R
|
|
93
|
+
|
|
94
|
+
var Rdiag;
|
|
95
|
+
|
|
96
|
+
if (findVectors) {
|
|
97
|
+
Rdiag = Array(N).fill(one);
|
|
98
|
+
} // this isn't the only time we loop thru the matrix...
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
var last = false;
|
|
102
|
+
|
|
103
|
+
while (!last) {
|
|
104
|
+
// ...haha I'm joking! unless...
|
|
105
|
+
last = true;
|
|
106
|
+
|
|
107
|
+
for (var i = 0; i < N; i++) {
|
|
108
|
+
// compute the taxicab norm of i-th column and row
|
|
109
|
+
// TODO optimize for complex numbers
|
|
110
|
+
var colNorm = zero;
|
|
111
|
+
var rowNorm = zero;
|
|
112
|
+
|
|
113
|
+
for (var j = 0; j < N; j++) {
|
|
114
|
+
if (i === j) continue;
|
|
115
|
+
var c = abs(arr[i][j]);
|
|
116
|
+
colNorm = addScalar(colNorm, c);
|
|
117
|
+
rowNorm = addScalar(rowNorm, c);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (!equal(colNorm, 0) && !equal(rowNorm, 0)) {
|
|
121
|
+
// find integer power closest to balancing the matrix
|
|
122
|
+
// (we want to scale only by integer powers of radix,
|
|
123
|
+
// so that we don't lose any precision due to round-off)
|
|
124
|
+
var f = one;
|
|
125
|
+
var _c = colNorm;
|
|
126
|
+
var rowDivRadix = divideScalar(rowNorm, radix);
|
|
127
|
+
var rowMulRadix = multiplyScalar(rowNorm, radix);
|
|
128
|
+
|
|
129
|
+
while (smaller(_c, rowDivRadix)) {
|
|
130
|
+
_c = multiplyScalar(_c, radixSq);
|
|
131
|
+
f = multiplyScalar(f, radix);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
while (larger(_c, rowMulRadix)) {
|
|
135
|
+
_c = divideScalar(_c, radixSq);
|
|
136
|
+
f = divideScalar(f, radix);
|
|
137
|
+
} // check whether balancing is needed
|
|
138
|
+
// condition = (c + rowNorm) / f < 0.95 * (colNorm + rowNorm)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
var condition = smaller(divideScalar(addScalar(_c, rowNorm), f), multiplyScalar(addScalar(colNorm, rowNorm), 0.95)); // apply balancing similarity transformation
|
|
142
|
+
|
|
143
|
+
if (condition) {
|
|
144
|
+
// we should loop once again to check whether
|
|
145
|
+
// another rebalancing is needed
|
|
146
|
+
last = false;
|
|
147
|
+
var g = divideScalar(1, f);
|
|
148
|
+
|
|
149
|
+
for (var _j = 0; _j < N; _j++) {
|
|
150
|
+
if (i === _j) {
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
arr[i][_j] = multiplyScalar(arr[i][_j], f);
|
|
155
|
+
arr[_j][i] = multiplyScalar(arr[_j][i], g);
|
|
156
|
+
} // keep track of transformations
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
if (findVectors) {
|
|
160
|
+
Rdiag[i] = multiplyScalar(Rdiag[i], f);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
} // return the diagonal row transformation matrix
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
return diag(Rdiag);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* @param {number[][]} arr
|
|
172
|
+
* @param {number} N
|
|
173
|
+
* @param {number} prec
|
|
174
|
+
* @param {'number'|'BigNumber'|'Complex'} type
|
|
175
|
+
* @param {boolean} findVectors
|
|
176
|
+
* @param {number[][]} R the row transformation matrix that will be modified
|
|
177
|
+
*/
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
function reduceToHessenberg(arr, N, prec, type, findVectors, R) {
|
|
181
|
+
var big = type === 'BigNumber';
|
|
182
|
+
var cplx = type === 'Complex';
|
|
183
|
+
var zero = big ? bignumber(0) : cplx ? complex(0) : 0;
|
|
184
|
+
|
|
185
|
+
if (big) {
|
|
186
|
+
prec = bignumber(prec);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
for (var i = 0; i < N - 2; i++) {
|
|
190
|
+
// Find the largest subdiag element in the i-th col
|
|
191
|
+
var maxIndex = 0;
|
|
192
|
+
var max = zero;
|
|
193
|
+
|
|
194
|
+
for (var j = i + 1; j < N; j++) {
|
|
195
|
+
var el = arr[j][i];
|
|
196
|
+
|
|
197
|
+
if (smaller(abs(max), abs(el))) {
|
|
198
|
+
max = el;
|
|
199
|
+
maxIndex = j;
|
|
200
|
+
}
|
|
201
|
+
} // This col is pivoted, no need to do anything
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
if (smaller(abs(max), prec)) {
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (maxIndex !== i + 1) {
|
|
209
|
+
// Interchange maxIndex-th and (i+1)-th row
|
|
210
|
+
var tmp1 = arr[maxIndex];
|
|
211
|
+
arr[maxIndex] = arr[i + 1];
|
|
212
|
+
arr[i + 1] = tmp1; // Interchange maxIndex-th and (i+1)-th column
|
|
213
|
+
|
|
214
|
+
for (var _j2 = 0; _j2 < N; _j2++) {
|
|
215
|
+
var tmp2 = arr[_j2][maxIndex];
|
|
216
|
+
arr[_j2][maxIndex] = arr[_j2][i + 1];
|
|
217
|
+
arr[_j2][i + 1] = tmp2;
|
|
218
|
+
} // keep track of transformations
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
if (findVectors) {
|
|
222
|
+
var tmp3 = R[maxIndex];
|
|
223
|
+
R[maxIndex] = R[i + 1];
|
|
224
|
+
R[i + 1] = tmp3;
|
|
225
|
+
}
|
|
226
|
+
} // Reduce following rows and columns
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
for (var _j3 = i + 2; _j3 < N; _j3++) {
|
|
230
|
+
var n = divideScalar(arr[_j3][i], max);
|
|
231
|
+
|
|
232
|
+
if (n === 0) {
|
|
233
|
+
continue;
|
|
234
|
+
} // from j-th row subtract n-times (i+1)th row
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
for (var k = 0; k < N; k++) {
|
|
238
|
+
arr[_j3][k] = subtract(arr[_j3][k], multiplyScalar(n, arr[i + 1][k]));
|
|
239
|
+
} // to (i+1)th column add n-times j-th column
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
for (var _k = 0; _k < N; _k++) {
|
|
243
|
+
arr[_k][i + 1] = addScalar(arr[_k][i + 1], multiplyScalar(n, arr[_k][_j3]));
|
|
244
|
+
} // keep track of transformations
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
if (findVectors) {
|
|
248
|
+
for (var _k2 = 0; _k2 < N; _k2++) {
|
|
249
|
+
R[_j3][_k2] = subtract(R[_j3][_k2], multiplyScalar(n, R[i + 1][_k2]));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return R;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* @returns {{values: values, C: Matrix}}
|
|
259
|
+
* @see Press, Wiliams: Numerical recipes in Fortran 77
|
|
260
|
+
* @see https://en.wikipedia.org/wiki/QR_algorithm
|
|
261
|
+
*/
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
function iterateUntilTriangular(A, N, prec, type, findVectors) {
|
|
265
|
+
var big = type === 'BigNumber';
|
|
266
|
+
var cplx = type === 'Complex';
|
|
267
|
+
var one = big ? bignumber(1) : cplx ? complex(1) : 1;
|
|
268
|
+
|
|
269
|
+
if (big) {
|
|
270
|
+
prec = bignumber(prec);
|
|
271
|
+
} // The Francis Algorithm
|
|
272
|
+
// The core idea of this algorithm is that doing successive
|
|
273
|
+
// A' = Q⁺AQ transformations will eventually converge to block-
|
|
274
|
+
// upper-triangular with diagonal blocks either 1x1 or 2x2.
|
|
275
|
+
// The Q here is the one from the QR decomposition, A = QR.
|
|
276
|
+
// Since the eigenvalues of a block-upper-triangular matrix are
|
|
277
|
+
// the eigenvalues of its diagonal blocks and we know how to find
|
|
278
|
+
// eigenvalues of a 2x2 matrix, we know the eigenvalues of A.
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
var arr = clone(A); // the list of converged eigenvalues
|
|
282
|
+
|
|
283
|
+
var lambdas = []; // size of arr, which will get smaller as eigenvalues converge
|
|
284
|
+
|
|
285
|
+
var n = N; // the diagonal of the block-diagonal matrix that turns
|
|
286
|
+
// converged 2x2 matrices into upper triangular matrices
|
|
287
|
+
|
|
288
|
+
var Sdiag = []; // N×N matrix describing the overall transformation done during the QR algorithm
|
|
289
|
+
|
|
290
|
+
var Qtotal = findVectors ? diag(Array(N).fill(one)) : undefined; // n×n matrix describing the QR transformations done since last convergence
|
|
291
|
+
|
|
292
|
+
var Qpartial = findVectors ? diag(Array(n).fill(one)) : undefined; // last eigenvalue converged before this many steps
|
|
293
|
+
|
|
294
|
+
var lastConvergenceBefore = 0;
|
|
295
|
+
|
|
296
|
+
while (lastConvergenceBefore <= 100) {
|
|
297
|
+
lastConvergenceBefore += 1; // TODO if the convergence is slow, do something clever
|
|
298
|
+
// Perform the factorization
|
|
299
|
+
|
|
300
|
+
var k = 0; // TODO set close to an eigenvalue
|
|
301
|
+
|
|
302
|
+
for (var i = 0; i < n; i++) {
|
|
303
|
+
arr[i][i] = subtract(arr[i][i], k);
|
|
304
|
+
} // TODO do an implicit QR transformation
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
var {
|
|
308
|
+
Q,
|
|
309
|
+
R
|
|
310
|
+
} = qr(arr);
|
|
311
|
+
arr = multiply(R, Q);
|
|
312
|
+
|
|
313
|
+
for (var _i = 0; _i < n; _i++) {
|
|
314
|
+
arr[_i][_i] = addScalar(arr[_i][_i], k);
|
|
315
|
+
} // keep track of transformations
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
if (findVectors) {
|
|
319
|
+
Qpartial = multiply(Qpartial, Q);
|
|
320
|
+
} // The rightmost diagonal element converged to an eigenvalue
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
if (n === 1 || smaller(abs(arr[n - 1][n - 2]), prec)) {
|
|
324
|
+
lastConvergenceBefore = 0;
|
|
325
|
+
lambdas.push(arr[n - 1][n - 1]); // keep track of transformations
|
|
326
|
+
|
|
327
|
+
if (findVectors) {
|
|
328
|
+
Sdiag.unshift([[1]]);
|
|
329
|
+
inflateMatrix(Qpartial, N);
|
|
330
|
+
Qtotal = multiply(Qtotal, Qpartial);
|
|
331
|
+
|
|
332
|
+
if (n > 1) {
|
|
333
|
+
Qpartial = diag(Array(n - 1).fill(one));
|
|
334
|
+
}
|
|
335
|
+
} // reduce the matrix size
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
n -= 1;
|
|
339
|
+
arr.pop();
|
|
340
|
+
|
|
341
|
+
for (var _i2 = 0; _i2 < n; _i2++) {
|
|
342
|
+
arr[_i2].pop();
|
|
343
|
+
} // The rightmost diagonal 2x2 block converged
|
|
344
|
+
|
|
345
|
+
} else if (n === 2 || smaller(abs(arr[n - 2][n - 3]), prec)) {
|
|
346
|
+
lastConvergenceBefore = 0;
|
|
347
|
+
var ll = eigenvalues2x2(arr[n - 2][n - 2], arr[n - 2][n - 1], arr[n - 1][n - 2], arr[n - 1][n - 1]);
|
|
348
|
+
lambdas.push(...ll); // keep track of transformations
|
|
349
|
+
|
|
350
|
+
if (findVectors) {
|
|
351
|
+
Sdiag.unshift(jordanBase2x2(arr[n - 2][n - 2], arr[n - 2][n - 1], arr[n - 1][n - 2], arr[n - 1][n - 1], ll[0], ll[1], prec, type));
|
|
352
|
+
inflateMatrix(Qpartial, N);
|
|
353
|
+
Qtotal = multiply(Qtotal, Qpartial);
|
|
354
|
+
|
|
355
|
+
if (n > 2) {
|
|
356
|
+
Qpartial = diag(Array(n - 2).fill(one));
|
|
357
|
+
}
|
|
358
|
+
} // reduce the matrix size
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
n -= 2;
|
|
362
|
+
arr.pop();
|
|
363
|
+
arr.pop();
|
|
364
|
+
|
|
365
|
+
for (var _i3 = 0; _i3 < n; _i3++) {
|
|
366
|
+
arr[_i3].pop();
|
|
367
|
+
|
|
368
|
+
arr[_i3].pop();
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (n === 0) {
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
375
|
+
} // standard sorting
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
lambdas.sort((a, b) => +subtract(abs(a), abs(b))); // the algorithm didn't converge
|
|
379
|
+
|
|
380
|
+
if (lastConvergenceBefore > 100) {
|
|
381
|
+
var err = Error('The eigenvalues failed to converge. Only found these eigenvalues: ' + lambdas.join(', '));
|
|
382
|
+
err.values = lambdas;
|
|
383
|
+
err.vectors = [];
|
|
384
|
+
throw err;
|
|
385
|
+
} // combine the overall QR transformation Qtotal with the subsequent
|
|
386
|
+
// transformation S that turns the diagonal 2x2 blocks to upper triangular
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
var C = findVectors ? multiply(Qtotal, blockDiag(Sdiag, N)) : undefined;
|
|
390
|
+
return {
|
|
391
|
+
values: lambdas,
|
|
392
|
+
C
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* @param {Matrix} A original matrix
|
|
397
|
+
* @param {number} N size of A
|
|
398
|
+
* @param {Matrix} C column transformation matrix that turns A into upper triangular
|
|
399
|
+
* @param {number[]} values array of eigenvalues of A
|
|
400
|
+
* @returns {number[][]} eigenvalues
|
|
401
|
+
*/
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
function findEigenvectors(A, N, C, values, prec) {
|
|
405
|
+
var Cinv = inv(C);
|
|
406
|
+
var U = multiply(Cinv, A, C); // turn values into a kind of "multiset"
|
|
407
|
+
// this way it is easier to find eigenvectors
|
|
408
|
+
|
|
409
|
+
var uniqueValues = [];
|
|
410
|
+
var multiplicities = [];
|
|
411
|
+
|
|
412
|
+
for (var λ of values) {
|
|
413
|
+
var i = indexOf(uniqueValues, λ, equal);
|
|
414
|
+
|
|
415
|
+
if (i === -1) {
|
|
416
|
+
// a dirty trick that helps us find more vectors
|
|
417
|
+
// TODO with iterative algorithm this can be removed
|
|
418
|
+
// Note: the round around log10 is needed to prevent rounding off errors in IE
|
|
419
|
+
var rounded = round(λ, subtract(-1, round(log10(prec))));
|
|
420
|
+
uniqueValues.push(rounded);
|
|
421
|
+
multiplicities.push(1);
|
|
422
|
+
} else {
|
|
423
|
+
multiplicities[i] += 1;
|
|
424
|
+
}
|
|
425
|
+
} // find eigenvectors by solving U − λE = 0
|
|
426
|
+
// TODO replace with an iterative eigenvector algorithm
|
|
427
|
+
// (this one might fail for imprecise eigenvalues)
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
var vectors = [];
|
|
431
|
+
var len = uniqueValues.length;
|
|
432
|
+
var b = Array(N).fill(0);
|
|
433
|
+
var E = diag(Array(N).fill(1)); // eigenvalues for which usolve failed (due to numerical error)
|
|
434
|
+
|
|
435
|
+
var failedLambdas = [];
|
|
436
|
+
|
|
437
|
+
for (var _i4 = 0; _i4 < len; _i4++) {
|
|
438
|
+
var _λ = uniqueValues[_i4];
|
|
439
|
+
var solutions = usolveAll(subtract(U, multiply(_λ, E)), b);
|
|
440
|
+
solutions = solutions.map(v => multiply(C, v));
|
|
441
|
+
solutions.shift(); // ignore the null vector
|
|
442
|
+
// looks like we missed something
|
|
443
|
+
|
|
444
|
+
if (solutions.length < multiplicities[_i4]) {
|
|
445
|
+
failedLambdas.push(_λ);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
vectors.push(...solutions.map(v => flatten(v)));
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (failedLambdas.length !== 0) {
|
|
452
|
+
var err = new Error('Failed to find eigenvectors for the following eigenvalues: ' + failedLambdas.join(', '));
|
|
453
|
+
err.values = values;
|
|
454
|
+
err.vectors = vectors;
|
|
455
|
+
throw err;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return vectors;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Compute the eigenvalues of an 2x2 matrix
|
|
462
|
+
* @return {[number,number]}
|
|
463
|
+
*/
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
function eigenvalues2x2(a, b, c, d) {
|
|
467
|
+
// λ± = ½ trA ± ½ √( tr²A - 4 detA )
|
|
468
|
+
var trA = addScalar(a, d);
|
|
469
|
+
var detA = subtract(multiplyScalar(a, d), multiplyScalar(b, c));
|
|
470
|
+
var x = multiplyScalar(trA, 0.5);
|
|
471
|
+
var y = multiplyScalar(sqrt(subtract(multiplyScalar(trA, trA), multiplyScalar(4, detA))), 0.5);
|
|
472
|
+
return [addScalar(x, y), subtract(x, y)];
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* For an 2x2 matrix compute the transformation matrix S,
|
|
476
|
+
* so that SAS⁻¹ is an upper triangular matrix
|
|
477
|
+
* @return {[[number,number],[number,number]]}
|
|
478
|
+
* @see https://math.berkeley.edu/~ogus/old/Math_54-05/webfoils/jordan.pdf
|
|
479
|
+
* @see http://people.math.harvard.edu/~knill/teaching/math21b2004/exhibits/2dmatrices/index.html
|
|
480
|
+
*/
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
function jordanBase2x2(a, b, c, d, l1, l2, prec, type) {
|
|
484
|
+
var big = type === 'BigNumber';
|
|
485
|
+
var cplx = type === 'Complex';
|
|
486
|
+
var zero = big ? bignumber(0) : cplx ? complex(0) : 0;
|
|
487
|
+
var one = big ? bignumber(1) : cplx ? complex(1) : 1; // matrix is already upper triangular
|
|
488
|
+
// return an identity matrix
|
|
489
|
+
|
|
490
|
+
if (smaller(abs(c), prec)) {
|
|
491
|
+
return [[one, zero], [zero, one]];
|
|
492
|
+
} // matrix is diagonalizable
|
|
493
|
+
// return its eigenvectors as columns
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
if (larger(abs(subtract(l1, l2)), prec)) {
|
|
497
|
+
return [[subtract(l1, d), subtract(l2, d)], [c, c]];
|
|
498
|
+
} // matrix is not diagonalizable
|
|
499
|
+
// compute off-diagonal elements of N = A - λI
|
|
500
|
+
// N₁₂ = 0 ⇒ S = ( N⃗₁, I⃗₁ )
|
|
501
|
+
// N₁₂ ≠ 0 ⇒ S = ( N⃗₂, I⃗₂ )
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
var na = subtract(a, l1);
|
|
505
|
+
var nb = subtract(b, l1);
|
|
506
|
+
var nc = subtract(c, l1);
|
|
507
|
+
var nd = subtract(d, l1);
|
|
508
|
+
|
|
509
|
+
if (smaller(abs(nb), prec)) {
|
|
510
|
+
return [[na, one], [nc, zero]];
|
|
511
|
+
} else {
|
|
512
|
+
return [[nb, zero], [nd, one]];
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Enlarge the matrix from n×n to N×N, setting the new
|
|
517
|
+
* elements to 1 on diagonal and 0 elsewhere
|
|
518
|
+
*/
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
function inflateMatrix(arr, N) {
|
|
522
|
+
// add columns
|
|
523
|
+
for (var i = 0; i < arr.length; i++) {
|
|
524
|
+
arr[i].push(...Array(N - arr[i].length).fill(0));
|
|
525
|
+
} // add rows
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
for (var _i5 = arr.length; _i5 < N; _i5++) {
|
|
529
|
+
arr.push(Array(N).fill(0));
|
|
530
|
+
arr[_i5][_i5] = 1;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
return arr;
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Create a block-diagonal matrix with the given square matrices on the diagonal
|
|
537
|
+
* @param {Matrix[] | number[][][]} arr array of matrices to be placed on the diagonal
|
|
538
|
+
* @param {number} N the size of the resulting matrix
|
|
539
|
+
*/
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
function blockDiag(arr, N) {
|
|
543
|
+
var M = [];
|
|
544
|
+
|
|
545
|
+
for (var i = 0; i < N; i++) {
|
|
546
|
+
M[i] = Array(N).fill(0);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
var I = 0;
|
|
550
|
+
|
|
551
|
+
for (var sub of arr) {
|
|
552
|
+
var n = sub.length;
|
|
553
|
+
|
|
554
|
+
for (var _i6 = 0; _i6 < n; _i6++) {
|
|
555
|
+
for (var j = 0; j < n; j++) {
|
|
556
|
+
M[I + _i6][I + j] = sub[_i6][j];
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
I += n;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
return M;
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Finds the index of an element in an array using a custom equality function
|
|
567
|
+
* @template T
|
|
568
|
+
* @param {Array<T>} arr array in which to search
|
|
569
|
+
* @param {T} el the element to find
|
|
570
|
+
* @param {function(T, T): boolean} fn the equality function, first argument is an element of `arr`, the second is always `el`
|
|
571
|
+
* @returns {number} the index of `el`, or -1 when it's not in `arr`
|
|
572
|
+
*/
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
function indexOf(arr, el, fn) {
|
|
576
|
+
for (var i = 0; i < arr.length; i++) {
|
|
577
|
+
if (fn(arr[i], el)) {
|
|
578
|
+
return i;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
return -1;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
return complexEigs;
|
|
586
|
+
}
|