nerdamer 1.1.13 → 2.0.0-rc.1
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/LICENSE.md +184 -0
- package/README.md +293 -312
- package/dist/bundle.js +2 -0
- package/dist/bundle.js.LICENSE.txt +7 -0
- package/dist/parser.js +2 -0
- package/dist/parser.js.LICENSE.txt +7 -0
- package/docs-data/parser-functions.json +1960 -0
- package/index.d.ts +10 -426
- package/output/algebra/adapters.d.ts +33 -0
- package/output/algebra/adapters.js +109 -0
- package/output/algebra/algorithms/arith.d.ts +84 -0
- package/output/algebra/algorithms/arith.js +323 -0
- package/output/algebra/algorithms/factor.d.ts +3 -0
- package/output/algebra/algorithms/factor.js +5 -0
- package/output/algebra/algorithms/factorMultivariate.d.ts +23 -0
- package/output/algebra/algorithms/factorMultivariate.js +2393 -0
- package/output/algebra/algorithms/factorUnivariate.d.ts +72 -0
- package/output/algebra/algorithms/factorUnivariate.js +1072 -0
- package/output/algebra/algorithms/gcd.d.ts +22 -0
- package/output/algebra/algorithms/gcd.js +690 -0
- package/output/algebra/algorithms/groebnerBase.d.ts +157 -0
- package/output/algebra/algorithms/groebnerBase.js +1166 -0
- package/output/algebra/algorithms/multiPoly/MultiPoly.d.ts +137 -0
- package/output/algebra/algorithms/multiPoly/MultiPoly.js +346 -0
- package/output/algebra/algorithms/poly.d.ts +228 -0
- package/output/algebra/algorithms/poly.js +1299 -0
- package/output/algebra/algorithms/rational.d.ts +17 -0
- package/output/algebra/algorithms/rational.js +115 -0
- package/output/algebra/factor/factor.d.ts +62 -0
- package/output/algebra/factor/factor.js +158 -0
- package/output/algebra/gcd/gcd.d.ts +29 -0
- package/output/algebra/gcd/gcd.js +141 -0
- package/output/algebra/groebner.d.ts +21 -0
- package/output/algebra/groebner.js +42 -0
- package/output/algebra/partfrac.d.ts +19 -0
- package/output/algebra/partfrac.js +398 -0
- package/output/algebra/polynomialize.d.ts +20 -0
- package/output/algebra/polynomialize.js +24 -0
- package/output/algebra/simplify/complexsimp.d.ts +7 -0
- package/output/algebra/simplify/complexsimp.js +24 -0
- package/output/algebra/simplify/factorCommon.d.ts +13 -0
- package/output/algebra/simplify/factorCommon.js +136 -0
- package/output/algebra/simplify/funcsimp.d.ts +26 -0
- package/output/algebra/simplify/funcsimp.js +633 -0
- package/output/algebra/simplify/invtrigrewrite.d.ts +10 -0
- package/output/algebra/simplify/invtrigrewrite.js +96 -0
- package/output/algebra/simplify/ratsimp.d.ts +21 -0
- package/output/algebra/simplify/ratsimp.js +140 -0
- package/output/algebra/simplify/simplify.d.ts +25 -0
- package/output/algebra/simplify/simplify.js +228 -0
- package/output/algebra/simplify/trigreduce.d.ts +38 -0
- package/output/algebra/simplify/trigreduce.js +424 -0
- package/output/algebra/simplify/trigrewrite.d.ts +17 -0
- package/output/algebra/simplify/trigrewrite.js +156 -0
- package/output/algebra/simplify/trigsimp.d.ts +11 -0
- package/output/algebra/simplify/trigsimp.js +369 -0
- package/output/algebra/simplify/utils.d.ts +32 -0
- package/output/algebra/simplify/utils.js +56 -0
- package/output/algebra/utils.d.ts +32 -0
- package/output/algebra/utils.js +48 -0
- package/output/api/advanced.d.ts +7 -0
- package/output/api/advanced.js +18 -0
- package/output/api/algebra.d.ts +17 -0
- package/output/api/algebra.js +32 -0
- package/output/api/assumptions.d.ts +4 -0
- package/output/api/assumptions.js +11 -0
- package/output/api/calculus.d.ts +9 -0
- package/output/api/calculus.js +21 -0
- package/output/api/core.d.ts +17 -0
- package/output/api/core.js +41 -0
- package/output/api/debug.d.ts +16 -0
- package/output/api/debug.js +23 -0
- package/output/api/parser.d.ts +85 -0
- package/output/api/parser.js +16 -0
- package/output/api/solve.d.ts +10 -0
- package/output/api/solve.js +16 -0
- package/output/api/structures.d.ts +10 -0
- package/output/api/structures.js +22 -0
- package/output/calculus/derivative/diff.d.ts +30 -0
- package/output/calculus/derivative/diff.js +238 -0
- package/output/calculus/fresnel.d.ts +16 -0
- package/output/calculus/fresnel.js +39 -0
- package/output/calculus/integrate/byParts.d.ts +18 -0
- package/output/calculus/integrate/byParts.js +339 -0
- package/output/calculus/integrate/bySubstitution.d.ts +135 -0
- package/output/calculus/integrate/bySubstitution.js +411 -0
- package/output/calculus/integrate/integrate.d.ts +38 -0
- package/output/calculus/integrate/integrate.js +652 -0
- package/output/calculus/integrate/integrationTable.d.ts +2 -0
- package/output/calculus/integrate/integrationTable.js +914 -0
- package/output/calculus/integrate/utils.d.ts +28 -0
- package/output/calculus/integrate/utils.js +96 -0
- package/output/calculus/laplace/ilaplace.d.ts +31 -0
- package/output/calculus/laplace/ilaplace.js +192 -0
- package/output/calculus/laplace/ilaplaceTable.d.ts +2 -0
- package/output/calculus/laplace/ilaplaceTable.js +200 -0
- package/output/calculus/laplace/laplace.d.ts +22 -0
- package/output/calculus/laplace/laplace.js +109 -0
- package/output/calculus/laplace/laplaceTable.d.ts +2 -0
- package/output/calculus/laplace/laplaceTable.js +187 -0
- package/output/calculus/limit/limit.d.ts +35 -0
- package/output/calculus/limit/limit.js +1183 -0
- package/output/calculus/limit/limitsTable.d.ts +2 -0
- package/output/calculus/limit/limitsTable.js +7 -0
- package/output/core/Settings.d.ts +32 -0
- package/output/core/Settings.js +68 -0
- package/output/core/adapters.d.ts +18 -0
- package/output/core/adapters.js +40 -0
- package/output/core/classes/assumption/Assumption.d.ts +218 -0
- package/output/core/classes/assumption/Assumption.js +605 -0
- package/output/core/classes/assumption/assertiveFunctions.d.ts +6 -0
- package/output/core/classes/assumption/assertiveFunctions.js +64 -0
- package/output/core/classes/assumption/assume.d.ts +90 -0
- package/output/core/classes/assumption/assume.js +145 -0
- package/output/core/classes/collection/Collection.d.ts +107 -0
- package/output/core/classes/collection/Collection.js +231 -0
- package/output/core/classes/complex/Complex.d.ts +99 -0
- package/output/core/classes/complex/Complex.js +135 -0
- package/output/core/classes/decimalSet/DecimalSet.d.ts +226 -0
- package/output/core/classes/decimalSet/DecimalSet.js +453 -0
- package/output/core/classes/dictionary/Dictionary.d.ts +102 -0
- package/output/core/classes/dictionary/Dictionary.js +213 -0
- package/output/core/classes/equation/Equation.d.ts +256 -0
- package/output/core/classes/equation/Equation.js +350 -0
- package/output/core/classes/expression/CoeffObject.d.ts +100 -0
- package/output/core/classes/expression/CoeffObject.js +198 -0
- package/output/core/classes/expression/Expression.d.ts +1674 -0
- package/output/core/classes/expression/Expression.js +2332 -0
- package/output/core/classes/expression/analysis.d.ts +25 -0
- package/output/core/classes/expression/analysis.js +218 -0
- package/output/core/classes/expression/collect.d.ts +9 -0
- package/output/core/classes/expression/collect.js +49 -0
- package/output/core/classes/expression/format.d.ts +45 -0
- package/output/core/classes/expression/format.js +217 -0
- package/output/core/classes/expression/products.d.ts +23 -0
- package/output/core/classes/expression/products.js +115 -0
- package/output/core/classes/expression/shortcuts.d.ts +35 -0
- package/output/core/classes/expression/shortcuts.js +129 -0
- package/output/core/classes/expression/traversal.d.ts +31 -0
- package/output/core/classes/expression/traversal.js +216 -0
- package/output/core/classes/expression/trig.d.ts +25 -0
- package/output/core/classes/expression/trig.js +40 -0
- package/output/core/classes/expression/utils.d.ts +52 -0
- package/output/core/classes/expression/utils.js +189 -0
- package/output/core/classes/lookupTable/LookupTable.d.ts +12 -0
- package/output/core/classes/lookupTable/LookupTable.js +55 -0
- package/output/core/classes/matrix/Matrix.d.ts +227 -0
- package/output/core/classes/matrix/Matrix.js +889 -0
- package/output/core/classes/matrix/Sylvester.d.ts +11 -0
- package/output/core/classes/matrix/Sylvester.js +54 -0
- package/output/core/classes/matrix/functions.d.ts +26 -0
- package/output/core/classes/matrix/functions.js +52 -0
- package/output/core/classes/matrix/utils.d.ts +9 -0
- package/output/core/classes/matrix/utils.js +22 -0
- package/output/core/classes/parser/Parser.d.ts +480 -0
- package/output/core/classes/parser/Parser.js +1812 -0
- package/output/core/classes/parser/Token.d.ts +58 -0
- package/output/core/classes/parser/Token.js +137 -0
- package/output/core/classes/parser/constants.d.ts +160 -0
- package/output/core/classes/parser/constants.js +227 -0
- package/output/core/classes/parser/helpers.d.ts +21 -0
- package/output/core/classes/parser/helpers.js +42 -0
- package/output/core/classes/parser/operations/add.d.ts +15 -0
- package/output/core/classes/parser/operations/add.js +238 -0
- package/output/core/classes/parser/operations/comma.d.ts +7 -0
- package/output/core/classes/parser/operations/comma.js +11 -0
- package/output/core/classes/parser/operations/compare.d.ts +21 -0
- package/output/core/classes/parser/operations/compare.js +461 -0
- package/output/core/classes/parser/operations/divide.d.ts +2 -0
- package/output/core/classes/parser/operations/divide.js +72 -0
- package/output/core/classes/parser/operations/functions.d.ts +46 -0
- package/output/core/classes/parser/operations/functions.js +430 -0
- package/output/core/classes/parser/operations/multiply.d.ts +11 -0
- package/output/core/classes/parser/operations/multiply.js +321 -0
- package/output/core/classes/parser/operations/power.d.ts +48 -0
- package/output/core/classes/parser/operations/power.js +673 -0
- package/output/core/classes/parser/operations/subtract.d.ts +3 -0
- package/output/core/classes/parser/operations/subtract.js +35 -0
- package/output/core/classes/parser/preprocess.d.ts +14 -0
- package/output/core/classes/parser/preprocess.js +259 -0
- package/output/core/classes/parser/scripting/controlFlow.d.ts +121 -0
- package/output/core/classes/parser/scripting/controlFlow.js +355 -0
- package/output/core/classes/parser/scripting/evaluate.d.ts +10 -0
- package/output/core/classes/parser/scripting/evaluate.js +112 -0
- package/output/core/classes/parser/scripting/functions.d.ts +14 -0
- package/output/core/classes/parser/scripting/functions.js +59 -0
- package/output/core/classes/parser/scripting/scope.d.ts +35 -0
- package/output/core/classes/parser/scripting/scope.js +155 -0
- package/output/core/classes/parser/types.d.ts +125 -0
- package/output/core/classes/parser/types.js +2 -0
- package/output/core/classes/parser/wrappers/IndexedReference.d.ts +31 -0
- package/output/core/classes/parser/wrappers/IndexedReference.js +68 -0
- package/output/core/classes/parser/wrappers/KeyValuePair.d.ts +24 -0
- package/output/core/classes/parser/wrappers/KeyValuePair.js +51 -0
- package/output/core/classes/polynomial/Polynomial.d.ts +500 -0
- package/output/core/classes/polynomial/Polynomial.js +1149 -0
- package/output/core/classes/polynomial/Term.d.ts +222 -0
- package/output/core/classes/polynomial/Term.js +430 -0
- package/output/core/classes/polynomial/functions.d.ts +69 -0
- package/output/core/classes/polynomial/functions.js +126 -0
- package/output/core/classes/polynomial/utils.d.ts +62 -0
- package/output/core/classes/polynomial/utils.js +206 -0
- package/output/core/classes/rational/Rational.d.ts +504 -0
- package/output/core/classes/rational/Rational.js +779 -0
- package/output/core/classes/seq/SEQ.d.ts +13 -0
- package/output/core/classes/seq/SEQ.js +137 -0
- package/output/core/classes/valuesSet/ValuesSet.d.ts +179 -0
- package/output/core/classes/valuesSet/ValuesSet.js +381 -0
- package/output/core/classes/vector/Vector.d.ts +222 -0
- package/output/core/classes/vector/Vector.js +497 -0
- package/output/core/classes/vector/functions.d.ts +28 -0
- package/output/core/classes/vector/functions.js +47 -0
- package/output/core/common/classes/MathematicalAggregate.d.ts +53 -0
- package/output/core/common/classes/MathematicalAggregate.js +140 -0
- package/output/core/common/classes/Scope.d.ts +62 -0
- package/output/core/common/classes/Scope.js +122 -0
- package/output/core/common/classes/StructuredEntity.d.ts +55 -0
- package/output/core/common/classes/StructuredEntity.js +151 -0
- package/output/core/common/common.d.ts +63 -0
- package/output/core/common/common.js +279 -0
- package/output/core/common/functions/functions.d.ts +14 -0
- package/output/core/common/functions/functions.js +33 -0
- package/output/core/common/functions/structuredEntityUtils.d.ts +27 -0
- package/output/core/common/functions/structuredEntityUtils.js +40 -0
- package/output/core/converters/BaseConverter.d.ts +97 -0
- package/output/core/converters/BaseConverter.js +405 -0
- package/output/core/converters/Converter.d.ts +111 -0
- package/output/core/converters/Converter.js +802 -0
- package/output/core/converters/Pattern.d.ts +71 -0
- package/output/core/converters/Pattern.js +302 -0
- package/output/core/dispatch.d.ts +34 -0
- package/output/core/dispatch.js +304 -0
- package/output/core/errors.d.ts +531 -0
- package/output/core/errors.js +621 -0
- package/output/core/functions/bigint/bigint.d.ts +121 -0
- package/output/core/functions/bigint/bigint.js +392 -0
- package/output/core/functions/bigint/primeFactor.d.ts +49 -0
- package/output/core/functions/bigint/primeFactor.js +267 -0
- package/output/core/functions/bigint/primes.d.ts +1 -0
- package/output/core/functions/bigint/primes.js +11 -0
- package/output/core/functions/build/definitions.d.ts +12 -0
- package/output/core/functions/build/definitions.js +133 -0
- package/output/core/functions/build/index.d.ts +32 -0
- package/output/core/functions/build/index.js +136 -0
- package/output/core/functions/complex.d.ts +90 -0
- package/output/core/functions/complex.js +482 -0
- package/output/core/functions/decimal.d.ts +24 -0
- package/output/core/functions/decimal.js +664 -0
- package/output/core/functions/expand/expand.d.ts +42 -0
- package/output/core/functions/expand/expand.js +376 -0
- package/output/core/functions/fresnelNumeric.d.ts +12 -0
- package/output/core/functions/fresnelNumeric.js +123 -0
- package/output/core/functions/numeric.d.ts +140 -0
- package/output/core/functions/numeric.js +790 -0
- package/output/core/functions/rationalNormalization.d.ts +11 -0
- package/output/core/functions/rationalNormalization.js +117 -0
- package/output/core/functions/setFunction.d.ts +19 -0
- package/output/core/functions/setFunction.js +75 -0
- package/output/core/functions/string.d.ts +26 -0
- package/output/core/functions/string.js +101 -0
- package/output/core/functions/subst.d.ts +90 -0
- package/output/core/functions/subst.js +498 -0
- package/output/core/functions/utils.d.ts +24 -0
- package/output/core/functions/utils.js +51 -0
- package/output/core/types.d.ts +48 -0
- package/output/core/types.js +2 -0
- package/output/index.d.ts +339 -0
- package/output/index.js +715 -0
- package/output/math/defint/defintDecimal.d.ts +37 -0
- package/output/math/defint/defintDecimal.js +320 -0
- package/output/math/defint/defintNative.d.ts +57 -0
- package/output/math/defint/defintNative.js +292 -0
- package/output/math/geometry.d.ts +8 -0
- package/output/math/geometry.js +32 -0
- package/output/math/math.d.ts +655 -0
- package/output/math/math.js +1811 -0
- package/output/math/trig.d.ts +518 -0
- package/output/math/trig.js +1444 -0
- package/output/math/trunc.d.ts +19 -0
- package/output/math/trunc.js +36 -0
- package/output/math/utils.d.ts +60 -0
- package/output/math/utils.js +180 -0
- package/output/solve/classes/DecimalMatrix.d.ts +17 -0
- package/output/solve/classes/DecimalMatrix.js +86 -0
- package/output/solve/classes/FunctionSolver.d.ts +135 -0
- package/output/solve/classes/FunctionSolver.js +433 -0
- package/output/solve/classes/MultivariateSolver.d.ts +84 -0
- package/output/solve/classes/MultivariateSolver.js +240 -0
- package/output/solve/classes/PolynomialSolver.d.ts +85 -0
- package/output/solve/classes/PolynomialSolver.js +292 -0
- package/output/solve/classes/SolutionSet.d.ts +153 -0
- package/output/solve/classes/SolutionSet.js +357 -0
- package/output/solve/classes/Solver.d.ts +17 -0
- package/output/solve/classes/Solver.js +132 -0
- package/output/solve/classes/SymbolicSolver.d.ts +74 -0
- package/output/solve/classes/SymbolicSolver.js +601 -0
- package/output/solve/linsolve.d.ts +51 -0
- package/output/solve/linsolve.js +225 -0
- package/output/solve/solve.d.ts +34 -0
- package/output/solve/solve.js +260 -0
- package/output/solve/solveSystem.d.ts +31 -0
- package/output/solve/solveSystem.js +290 -0
- package/output/solve/utils.d.ts +9 -0
- package/output/solve/utils.js +62 -0
- package/output/utils/array.d.ts +42 -0
- package/output/utils/array.js +98 -0
- package/output/utils/debug.d.ts +131 -0
- package/output/utils/debug.js +295 -0
- package/output/utils/decimal.d.ts +3 -0
- package/output/utils/decimal.js +16 -0
- package/output/utils/numeric.d.ts +14 -0
- package/output/utils/numeric.js +51 -0
- package/output/utils/object.d.ts +26 -0
- package/output/utils/object.js +56 -0
- package/package.json +213 -57
- package/.travis.yml +0 -3
- package/Algebra.js +0 -4568
- package/BREAKING_CHANGES.md +0 -5
- package/CODE_OF_CONDUCT.md +0 -46
- package/CONTRIBUTING.md +0 -14
- package/Calculus.js +0 -2675
- package/Extra.js +0 -622
- package/Solve.js +0 -1783
- package/all.js +0 -16
- package/all.min.js +0 -1
- package/gulpfile.js +0 -16
- package/index.html +0 -158
- package/license.txt +0 -19
- package/nerdamer.core.js +0 -12510
- package/spec/LaTeX.spec.js +0 -302
- package/spec/TeXConvert.spec.js +0 -8
- package/spec/algebra.spec.js +0 -287
- package/spec/basic_parser.spec.js +0 -134
- package/spec/build.spec.js +0 -131
- package/spec/calculus.spec.js +0 -183
- package/spec/core.spec.js +0 -2970
- package/spec/extra.spec.js +0 -54
- package/spec/solve.spec.js +0 -126
- package/spec/support/jasmine.json +0 -11
- package/spec/support/utils.js +0 -42
- package/spec/text.spec.js +0 -132
|
@@ -0,0 +1,889 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Matrix = void 0;
|
|
4
|
+
const math_1 = require("../../../math/math");
|
|
5
|
+
const StructuredEntity_1 = require("../../common/classes/StructuredEntity");
|
|
6
|
+
const common_1 = require("../../common/common");
|
|
7
|
+
const structuredEntityUtils_1 = require("../../common/functions/structuredEntityUtils");
|
|
8
|
+
const errors_1 = require("../../errors");
|
|
9
|
+
const Expression_1 = require("../expression/Expression");
|
|
10
|
+
const shortcuts_1 = require("../expression/shortcuts");
|
|
11
|
+
const constants_1 = require("../parser/constants");
|
|
12
|
+
const Vector_1 = require("../vector/Vector");
|
|
13
|
+
/**
|
|
14
|
+
* A rectangular two-dimensional matrix of scalar {@link Expression} elements.
|
|
15
|
+
*
|
|
16
|
+
* @remarks
|
|
17
|
+
* Construction validates that all nonempty rows have the same length and
|
|
18
|
+
* converts every entry to an Expression; nested parser aggregates are not
|
|
19
|
+
* matrix elements. Existing Expression entries are retained, so use
|
|
20
|
+
* {@link copy} when independent element objects are required. `copy`,
|
|
21
|
+
* {@link evaluate}, and {@link expand} return deep independent matrices.
|
|
22
|
+
*
|
|
23
|
+
* Addition, subtraction, and division remain element-wise. {@link times}
|
|
24
|
+
* implements scalar scaling, matrix multiplication, and matrix-vector multiplication,
|
|
25
|
+
* while {@link pow} implements integer matrix powers. Scalar and matrix products return
|
|
26
|
+
* new Matrices; a matrix-vector product returns a new Vector. {@link each}, {@link set},
|
|
27
|
+
* and parser assignment mutate this matrix. `each` may also be used for observation by
|
|
28
|
+
* returning nothing; use {@link forEach} when no transformation is intended.
|
|
29
|
+
*
|
|
30
|
+
* Direct `get`/`set` indices are zero-based. The compatibility accessor
|
|
31
|
+
* {@link e} and the {@link row}/{@link col} helpers are one-based. Matrix
|
|
32
|
+
* comparisons are component-wise predicates, not a total or lexicographic
|
|
33
|
+
* ordering; a type or dimension mismatch compares false.
|
|
34
|
+
*/
|
|
35
|
+
class Matrix extends StructuredEntity_1.StructuredEntity {
|
|
36
|
+
/**
|
|
37
|
+
* Number of row swaps performed during the last toRightTriangular call.
|
|
38
|
+
* Used internally by determinant() to correct the sign.
|
|
39
|
+
*/
|
|
40
|
+
_rowSwaps = 0;
|
|
41
|
+
dataType = constants_1.MATRIX;
|
|
42
|
+
elements;
|
|
43
|
+
isEnumerable = true;
|
|
44
|
+
precision;
|
|
45
|
+
/**
|
|
46
|
+
* Creates a matrix from array or Vector rows.
|
|
47
|
+
*
|
|
48
|
+
* @param elements - Rows containing values convertible to scalar Expressions.
|
|
49
|
+
* @throws {@link core!MathError} If nonempty rows have different lengths.
|
|
50
|
+
* @throws {@link core!UnexpectedDataType} If an entry cannot be converted to an
|
|
51
|
+
* Expression.
|
|
52
|
+
*/
|
|
53
|
+
constructor(...elements) {
|
|
54
|
+
super();
|
|
55
|
+
this.elements = [];
|
|
56
|
+
let previousRowLength;
|
|
57
|
+
for (let i = 0; i < elements.length; i++) {
|
|
58
|
+
const rowInput = elements[i];
|
|
59
|
+
const row = Vector_1.Vector.isVector(rowInput) ? rowInput.elements : (0, structuredEntityUtils_1.toParserEntities)(rowInput);
|
|
60
|
+
// Matrices are numeric/algebraic objects; elements must be expressions.
|
|
61
|
+
const exprRow = row.map((v) => {
|
|
62
|
+
// Reject aggregate types inside a matrix (Vector/Matrix/Collection/ValuesSet/Equation).
|
|
63
|
+
return Expression_1.Expression.create(v);
|
|
64
|
+
});
|
|
65
|
+
if (exprRow.length > 0) {
|
|
66
|
+
if (previousRowLength !== undefined && previousRowLength !== exprRow.length) {
|
|
67
|
+
throw new errors_1.MathError((0, errors_1.message)('cannotCreateMatrix'));
|
|
68
|
+
}
|
|
69
|
+
this.elements.push(exprRow);
|
|
70
|
+
previousRowLength = exprRow.length;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/** Creates a matrix whose cells are independent copies of `value`. */
|
|
75
|
+
static fill(rows, cols, value) {
|
|
76
|
+
const M = new Matrix([]);
|
|
77
|
+
for (let i = 0; i < rows; i++) {
|
|
78
|
+
const row = [];
|
|
79
|
+
for (let j = 0; j < cols; j++) {
|
|
80
|
+
row.push(value.copy());
|
|
81
|
+
}
|
|
82
|
+
M.elements.push(row);
|
|
83
|
+
}
|
|
84
|
+
return M;
|
|
85
|
+
}
|
|
86
|
+
/** Creates the `n` by `n` identity matrix. */
|
|
87
|
+
static identity(n) {
|
|
88
|
+
const M = new Matrix([]);
|
|
89
|
+
for (let i = 0; i < n; i++) {
|
|
90
|
+
const row = [];
|
|
91
|
+
for (let j = 0; j < n; j++) {
|
|
92
|
+
row.push(i === j ? (0, shortcuts_1.one)() : (0, shortcuts_1.zero)());
|
|
93
|
+
}
|
|
94
|
+
M.elements.push(row);
|
|
95
|
+
}
|
|
96
|
+
return M;
|
|
97
|
+
}
|
|
98
|
+
static isMatrix(obj) {
|
|
99
|
+
return (0, common_1.isNerdamerNativeType)(obj, constants_1.MATRIX);
|
|
100
|
+
}
|
|
101
|
+
/** Creates a matrix filled with symbolic zeros. */
|
|
102
|
+
static zeroMatrix(rows, cols) {
|
|
103
|
+
return Matrix.fill(rows, cols, (0, shortcuts_1.zero)());
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Returns a row at the given zero-based index as a Vector.
|
|
107
|
+
* Used by the parser for bracket indexing, e.g. matrix[0] returns the first row.
|
|
108
|
+
* This enables chained indexing: matrix[0][1] returns the element at row 0, col 1.
|
|
109
|
+
*
|
|
110
|
+
* @param indices Zero-based indices (after INDEX_BASE adjustment).
|
|
111
|
+
* Single index [i] returns row i as a Vector.
|
|
112
|
+
* Two indices [i, j] returns the element at row i, col j.
|
|
113
|
+
* @returns A copied row Vector for one index, or the stored Expression for two.
|
|
114
|
+
* @throws {@link core!MathError} If either index is out of bounds.
|
|
115
|
+
*/
|
|
116
|
+
__get__(indices) {
|
|
117
|
+
const row = indices[0];
|
|
118
|
+
if (row < 0 || row >= this.elements.length) {
|
|
119
|
+
throw new errors_1.MathError(`Row index ${row} out of bounds for Matrix with ${this.elements.length} rows`);
|
|
120
|
+
}
|
|
121
|
+
if (indices.length > 1) {
|
|
122
|
+
const col = indices[1];
|
|
123
|
+
if (col < 0 || col >= this.elements[row].length) {
|
|
124
|
+
throw new errors_1.MathError(`Column index ${col} out of bounds for Matrix with ${this.elements[row].length} columns`);
|
|
125
|
+
}
|
|
126
|
+
return this.elements[row][col];
|
|
127
|
+
}
|
|
128
|
+
return new Vector_1.Vector(this.elements[row]);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Sets a zero-based cell or replaces an entire row.
|
|
132
|
+
* [i, j] sets the element at row i, col j.
|
|
133
|
+
* [i] requires a Vector whose length matches the matrix column count.
|
|
134
|
+
*
|
|
135
|
+
* @param indices Zero-based indices
|
|
136
|
+
* @param value The value to set
|
|
137
|
+
* @throws {@link core!UnexpectedDataType} If a full-row assignment does not receive a Vector.
|
|
138
|
+
* @throws {@link core!MathError} If an index is out of bounds or a replacement row has the wrong length.
|
|
139
|
+
*/
|
|
140
|
+
__set__(indices, value) {
|
|
141
|
+
if (typeof indices === 'string') {
|
|
142
|
+
throw new errors_1.MathError('Matrix does not support string key access');
|
|
143
|
+
}
|
|
144
|
+
const row = indices[0];
|
|
145
|
+
const col = indices.length > 1 ? indices[1] : undefined;
|
|
146
|
+
if (row < 0 || row >= this.elements.length) {
|
|
147
|
+
throw new errors_1.MathError(`Row index ${row} out of bounds for Matrix with ${this.elements.length} rows`);
|
|
148
|
+
}
|
|
149
|
+
if (col !== undefined) {
|
|
150
|
+
if (col < 0 || col >= this.elements[row].length) {
|
|
151
|
+
throw new errors_1.MathError(`Column index ${col} out of bounds for Matrix with ${this.elements[row].length} columns`);
|
|
152
|
+
}
|
|
153
|
+
this.elements[row][col] = Expression_1.Expression.create(value);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
if (!Vector_1.Vector.isVector(value)) {
|
|
157
|
+
throw new errors_1.UnexpectedDataType((0, errors_1.message)('vectorExpected', { type: constants_1.dataTypes[value.dataType] }));
|
|
158
|
+
}
|
|
159
|
+
if (value.elements.length !== this.cols()) {
|
|
160
|
+
throw new errors_1.MathError((0, errors_1.message)('mismatchedDimensions', { function: 'Matrix.__set__' }));
|
|
161
|
+
}
|
|
162
|
+
// Build the replacement before mutating so conversion errors leave the matrix unchanged.
|
|
163
|
+
const replacement = value.elements.map(e => Expression_1.Expression.create(e));
|
|
164
|
+
this.elements[row] = replacement;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Returns the horizontal augmentation `[this | matrix]` without mutating either input.
|
|
169
|
+
*
|
|
170
|
+
* @throws {@link core!MathError} If the row counts differ.
|
|
171
|
+
*/
|
|
172
|
+
augment(matrix) {
|
|
173
|
+
const rows = this.rows();
|
|
174
|
+
if (rows !== matrix.rows()) {
|
|
175
|
+
throw new errors_1.MathError((0, errors_1.message)('rowsMustMatch'));
|
|
176
|
+
}
|
|
177
|
+
if (rows === 0) {
|
|
178
|
+
return this.copy();
|
|
179
|
+
}
|
|
180
|
+
const M = matrix.copy();
|
|
181
|
+
const T = this.copy();
|
|
182
|
+
const cols = T.cols();
|
|
183
|
+
let i = rows;
|
|
184
|
+
const nj = M.cols();
|
|
185
|
+
let j;
|
|
186
|
+
while (i--) {
|
|
187
|
+
j = nj;
|
|
188
|
+
while (j--) {
|
|
189
|
+
T.elements[i][cols + j] = M.elements[i][j];
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return T;
|
|
193
|
+
}
|
|
194
|
+
canMultiplyFromLeft(M) {
|
|
195
|
+
return this.cols() === M.rows();
|
|
196
|
+
}
|
|
197
|
+
col(n) {
|
|
198
|
+
const col = [];
|
|
199
|
+
const rows = this.rows();
|
|
200
|
+
if (n > 0 && n <= this.cols()) {
|
|
201
|
+
for (let i = 0; i < rows; i++) {
|
|
202
|
+
col.push([this.elements[i][n - 1]]);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return new Matrix(...col);
|
|
206
|
+
}
|
|
207
|
+
cols() {
|
|
208
|
+
return this.elements.length === 0 ? 0 : this.elements[0].length;
|
|
209
|
+
}
|
|
210
|
+
/** Copies the matrix and every Expression element. */
|
|
211
|
+
copy() {
|
|
212
|
+
const copy = this.map(e => e.copy());
|
|
213
|
+
return this.copySymbolicAccessTo(copy);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Computes the determinant by triangular elimination.
|
|
217
|
+
*
|
|
218
|
+
* The determinant of the empty matrix is one.
|
|
219
|
+
*
|
|
220
|
+
* @throws {@link core!UnsupportedOperationError} If the matrix is not square.
|
|
221
|
+
*/
|
|
222
|
+
determinant() {
|
|
223
|
+
if (this.rows() === 0) {
|
|
224
|
+
return (0, shortcuts_1.one)();
|
|
225
|
+
}
|
|
226
|
+
if (!this.isSquare()) {
|
|
227
|
+
throw new errors_1.UnsupportedOperationError((0, errors_1.message)('squareMatrixRequired'));
|
|
228
|
+
}
|
|
229
|
+
const M = this.toRightTriangular();
|
|
230
|
+
const n = this.rows();
|
|
231
|
+
let det = M.elements[0][0];
|
|
232
|
+
for (let i = 1; i < n; i++) {
|
|
233
|
+
det = det.times(M.get(i, i));
|
|
234
|
+
}
|
|
235
|
+
// Each row swap negates the determinant
|
|
236
|
+
if (M._rowSwaps % 2 !== 0) {
|
|
237
|
+
det = det.neg();
|
|
238
|
+
}
|
|
239
|
+
return det;
|
|
240
|
+
}
|
|
241
|
+
dimensions() {
|
|
242
|
+
return [this.rows(), this.cols()];
|
|
243
|
+
}
|
|
244
|
+
dimensionsMatch(M) {
|
|
245
|
+
return Matrix.isMatrix(M) && this.cols() === M.cols() && this.rows() === M.rows();
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Divides corresponding entries, or broadcasts a scalar divisor.
|
|
249
|
+
*
|
|
250
|
+
* @throws {@link core!DimensionError} If a Matrix divisor has different dimensions.
|
|
251
|
+
*/
|
|
252
|
+
div(x) {
|
|
253
|
+
if (Matrix.isMatrix(x) && !this.dimensionsMatch(x)) {
|
|
254
|
+
throw new errors_1.DimensionError((0, errors_1.message)('mismatchedDimensions', { function: 'Matrix.div' }));
|
|
255
|
+
}
|
|
256
|
+
return super.div(x);
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Returns a one-based matrix element for compatibility with the legacy accessor.
|
|
260
|
+
*
|
|
261
|
+
* @throws {@link core!MathError} If either index is out of bounds.
|
|
262
|
+
*/
|
|
263
|
+
e(i, j) {
|
|
264
|
+
return this.get(i - 1, j - 1);
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Visits or replaces every element in row-major order.
|
|
268
|
+
* Returning `void` leaves the current cell unchanged. Callback row and column
|
|
269
|
+
* indices are zero-based.
|
|
270
|
+
*/
|
|
271
|
+
each(fn) {
|
|
272
|
+
for (let i = 0; i < this.elements.length; i++) {
|
|
273
|
+
const row = this.elements[i];
|
|
274
|
+
for (let j = 0; j < row.length; j++) {
|
|
275
|
+
const result = fn(row[j], i, j);
|
|
276
|
+
if (result !== undefined) {
|
|
277
|
+
row[j] = result;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return this;
|
|
282
|
+
}
|
|
283
|
+
eq(M) {
|
|
284
|
+
if (!Matrix.isMatrix(M) || !this.dimensionsMatch(M)) {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
const rows = this.rows();
|
|
288
|
+
const cols = this.cols();
|
|
289
|
+
for (let i = 0; i < rows; i++) {
|
|
290
|
+
for (let j = 0; j < cols; j++) {
|
|
291
|
+
if (!this.elements[i][j].eq(M.elements[i][j])) {
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
evaluate(values) {
|
|
299
|
+
let retval;
|
|
300
|
+
const symbolicAccess = Expression_1.Expression.fromSymbolicAccess(this);
|
|
301
|
+
if (symbolicAccess && values) {
|
|
302
|
+
retval = symbolicAccess.evaluate(values);
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
const copy = this.copy();
|
|
306
|
+
copy.each(e => e.evaluate(values));
|
|
307
|
+
retval = copy;
|
|
308
|
+
}
|
|
309
|
+
return retval;
|
|
310
|
+
}
|
|
311
|
+
/** Expands a copied matrix, leaving this one unchanged. */
|
|
312
|
+
expand() {
|
|
313
|
+
const copy = this.copy();
|
|
314
|
+
copy.each(e => e.expand());
|
|
315
|
+
return copy;
|
|
316
|
+
}
|
|
317
|
+
/** Visits every cell without changing the matrix. */
|
|
318
|
+
forEach(callback) {
|
|
319
|
+
for (let i = 0; i < this.elements.length; i++) {
|
|
320
|
+
for (let j = 0; j < this.elements[i].length; j++) {
|
|
321
|
+
callback(this.elements[i][j], i, j);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Returns the stored Expression at a zero-based row and column.
|
|
327
|
+
*
|
|
328
|
+
* @throws {@link core!MathError} If either index is out of bounds.
|
|
329
|
+
*/
|
|
330
|
+
get(row, col) {
|
|
331
|
+
return this.__get__([row, col]);
|
|
332
|
+
}
|
|
333
|
+
gt(M) {
|
|
334
|
+
if (!Matrix.isMatrix(M) || !this.dimensionsMatch(M)) {
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
const rows = this.rows();
|
|
338
|
+
const cols = this.cols();
|
|
339
|
+
for (let i = 0; i < rows; i++) {
|
|
340
|
+
for (let j = 0; j < cols; j++) {
|
|
341
|
+
if (!this.elements[i][j].gt(M.elements[i][j])) {
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return true;
|
|
347
|
+
}
|
|
348
|
+
gte(M) {
|
|
349
|
+
if (!Matrix.isMatrix(M) || !this.dimensionsMatch(M)) {
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
const rows = this.rows();
|
|
353
|
+
const cols = this.cols();
|
|
354
|
+
for (let i = 0; i < rows; i++) {
|
|
355
|
+
for (let j = 0; j < cols; j++) {
|
|
356
|
+
if (!this.elements[i][j].gte(M.elements[i][j])) {
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return true;
|
|
362
|
+
}
|
|
363
|
+
inspect() {
|
|
364
|
+
let text = '';
|
|
365
|
+
for (let i = 0; i < this.elements.length; i++) {
|
|
366
|
+
const row = this.elements[i];
|
|
367
|
+
text += `[${row.map(x => x.text()).join(', ')}]\n`;
|
|
368
|
+
}
|
|
369
|
+
return text;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Computes an inverse by augmenting with the identity and eliminating rows.
|
|
373
|
+
*
|
|
374
|
+
* @returns A new inverse matrix; this matrix is unchanged.
|
|
375
|
+
* @throws {@link core!UnsupportedOperationError} If the matrix is not square.
|
|
376
|
+
* @throws {@link core!MathError} If the matrix is singular.
|
|
377
|
+
*/
|
|
378
|
+
inverse() {
|
|
379
|
+
if (!this.isSquare()) {
|
|
380
|
+
throw new errors_1.UnsupportedOperationError((0, errors_1.message)('squareMatrixRequired'));
|
|
381
|
+
}
|
|
382
|
+
if (this.rows() === 0) {
|
|
383
|
+
return this.copy();
|
|
384
|
+
}
|
|
385
|
+
if (this.isSingular()) {
|
|
386
|
+
throw new errors_1.MathError((0, errors_1.message)('singularMatrix'));
|
|
387
|
+
}
|
|
388
|
+
const n = this.elements.length;
|
|
389
|
+
let i = n;
|
|
390
|
+
const M = this.augment(Matrix.identity(n)).toRightTriangular();
|
|
391
|
+
const inverseElements = [];
|
|
392
|
+
let j;
|
|
393
|
+
let p;
|
|
394
|
+
let els;
|
|
395
|
+
let divisor;
|
|
396
|
+
let newElement;
|
|
397
|
+
const np = M.elements[0].length;
|
|
398
|
+
const z = (0, shortcuts_1.zero)();
|
|
399
|
+
while (i--) {
|
|
400
|
+
els = [];
|
|
401
|
+
inverseElements[i] = [];
|
|
402
|
+
divisor = M.elements[i][i];
|
|
403
|
+
// Safety check: if the pivot is zero after triangularization,
|
|
404
|
+
// the matrix is singular (shouldn't reach here due to isSingular check above)
|
|
405
|
+
if (divisor.eq(z)) {
|
|
406
|
+
throw new errors_1.MathError((0, errors_1.message)('singularMatrix'));
|
|
407
|
+
}
|
|
408
|
+
for (p = 0; p < np; p++) {
|
|
409
|
+
newElement = M.elements[i][p].div(divisor);
|
|
410
|
+
els.push(newElement);
|
|
411
|
+
if (p >= n) {
|
|
412
|
+
inverseElements[i].push(newElement);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
M.elements[i] = els;
|
|
416
|
+
j = i;
|
|
417
|
+
while (j--) {
|
|
418
|
+
els = [];
|
|
419
|
+
for (p = 0; p < np; p++) {
|
|
420
|
+
els.push(M.elements[j][p].minus(M.elements[i][p].times(M.elements[j][i])));
|
|
421
|
+
}
|
|
422
|
+
M.elements[j] = els;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return new Matrix(...inverseElements);
|
|
426
|
+
}
|
|
427
|
+
isSingular() {
|
|
428
|
+
return this.isSquare() && this.determinant().eq('0');
|
|
429
|
+
}
|
|
430
|
+
isSquare() {
|
|
431
|
+
return this.rows() === this.cols();
|
|
432
|
+
}
|
|
433
|
+
lt(M) {
|
|
434
|
+
if (!Matrix.isMatrix(M) || !this.dimensionsMatch(M)) {
|
|
435
|
+
return false;
|
|
436
|
+
}
|
|
437
|
+
const rows = this.rows();
|
|
438
|
+
const cols = this.cols();
|
|
439
|
+
for (let i = 0; i < rows; i++) {
|
|
440
|
+
for (let j = 0; j < cols; j++) {
|
|
441
|
+
if (!this.elements[i][j].lt(M.elements[i][j])) {
|
|
442
|
+
return false;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return true;
|
|
447
|
+
}
|
|
448
|
+
lte(M) {
|
|
449
|
+
if (!Matrix.isMatrix(M) || !this.dimensionsMatch(M)) {
|
|
450
|
+
return false;
|
|
451
|
+
}
|
|
452
|
+
const rows = this.rows();
|
|
453
|
+
const cols = this.cols();
|
|
454
|
+
for (let i = 0; i < rows; i++) {
|
|
455
|
+
for (let j = 0; j < cols; j++) {
|
|
456
|
+
if (!this.elements[i][j].lte(M.elements[i][j])) {
|
|
457
|
+
return false;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
return true;
|
|
462
|
+
}
|
|
463
|
+
/** Returns a new matrix populated by callback results without mutating this matrix. */
|
|
464
|
+
map(callback) {
|
|
465
|
+
const M = new Matrix([]);
|
|
466
|
+
for (let i = 0; i < this.elements.length; i++) {
|
|
467
|
+
M.elements[i] = [];
|
|
468
|
+
for (let j = 0; j < this.elements[i].length; j++) {
|
|
469
|
+
M.elements[i][j] = callback(this.elements[i][j], i, j);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
return M;
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Subtracts corresponding entries, or broadcasts a scalar subtrahend.
|
|
476
|
+
*
|
|
477
|
+
* @throws {@link core!DimensionError} If a Matrix operand has different dimensions.
|
|
478
|
+
*/
|
|
479
|
+
minus(x) {
|
|
480
|
+
if (Matrix.isMatrix(x) && !this.dimensionsMatch(x)) {
|
|
481
|
+
throw new errors_1.DimensionError((0, errors_1.message)('mismatchedDimensions', { function: 'Matrix.minus' }));
|
|
482
|
+
}
|
|
483
|
+
return super.minus(x);
|
|
484
|
+
}
|
|
485
|
+
multiply(x) {
|
|
486
|
+
return this.times(x);
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Computes a basis for the nullspace using the same reduced row-echelon form as {@link rref}.
|
|
490
|
+
*
|
|
491
|
+
* @remarks
|
|
492
|
+
* Without `prime`, the basis is computed with exact symbolic Expression arithmetic. When
|
|
493
|
+
* `prime` is supplied, the existing modular arithmetic path is preserved and basis entries
|
|
494
|
+
* are reduced modulo that value. Each free column contributes one basis vector, ordered by
|
|
495
|
+
* increasing free-column index. A full-column-rank matrix therefore returns an empty basis.
|
|
496
|
+
*
|
|
497
|
+
* @param prime - Optional modulus for finite-field nullspace arithmetic.
|
|
498
|
+
* @returns Basis vectors as independent Expression arrays ordered by matrix column.
|
|
499
|
+
*/
|
|
500
|
+
nullspace(prime) {
|
|
501
|
+
const p = prime === undefined ? undefined : Expression_1.Expression.create(prime);
|
|
502
|
+
const A = this.rref(prime);
|
|
503
|
+
const rows = A.rows();
|
|
504
|
+
const cols = A.cols();
|
|
505
|
+
const z = (0, shortcuts_1.zero)();
|
|
506
|
+
// Find pivot columns: for each row, the first nonzero entry is the pivot.
|
|
507
|
+
const pivotCols = new Set();
|
|
508
|
+
const rowPivot = new Array(rows).fill(-1);
|
|
509
|
+
for (let i = 0; i < rows; i++) {
|
|
510
|
+
for (let j = 0; j < cols; j++) {
|
|
511
|
+
if (!A.elements[i][j].eq(z)) {
|
|
512
|
+
pivotCols.add(j);
|
|
513
|
+
rowPivot[i] = j;
|
|
514
|
+
break;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
const freeCols = [];
|
|
519
|
+
for (let j = 0; j < cols; j++) {
|
|
520
|
+
if (!pivotCols.has(j)) {
|
|
521
|
+
freeCols.push(j);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
const basis = [];
|
|
525
|
+
for (const free of freeCols) {
|
|
526
|
+
const vec = Array.from({ length: cols }, () => (0, shortcuts_1.zero)());
|
|
527
|
+
vec[free] = (0, shortcuts_1.one)();
|
|
528
|
+
for (let i = 0; i < rows; i++) {
|
|
529
|
+
const pivot = rowPivot[i];
|
|
530
|
+
if (pivot !== -1) {
|
|
531
|
+
const value = (0, shortcuts_1.zero)().minus(A.elements[i][free]);
|
|
532
|
+
vec[pivot] = p ? (0, math_1.mod)(value, p) : value;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
basis.push(vec);
|
|
536
|
+
}
|
|
537
|
+
return basis;
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Adds corresponding entries, or broadcasts a scalar addend.
|
|
541
|
+
*
|
|
542
|
+
* @throws {@link core!DimensionError} If a Matrix operand has different dimensions.
|
|
543
|
+
*/
|
|
544
|
+
plus(x) {
|
|
545
|
+
if (Matrix.isMatrix(x) && !this.dimensionsMatch(x)) {
|
|
546
|
+
throw new errors_1.DimensionError((0, errors_1.message)('mismatchedDimensions', { function: 'Matrix.plus' }));
|
|
547
|
+
}
|
|
548
|
+
return super.plus(x);
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Raises this matrix to an integer power without mutating it.
|
|
552
|
+
*
|
|
553
|
+
* Positive powers use matrix multiplication, zero returns the identity, and
|
|
554
|
+
* negative powers use the matrix inverse. A rectangular matrix is accepted only
|
|
555
|
+
* for the identity power `1`; all other matrix powers require a square matrix.
|
|
556
|
+
*
|
|
557
|
+
* @throws {@link core!UnsupportedOperationError} If the exponent is not an integer,
|
|
558
|
+
* or if a nontrivial power is requested for a rectangular matrix.
|
|
559
|
+
* @throws {@link core!MathError} If a negative power requires the inverse of a singular matrix.
|
|
560
|
+
*/
|
|
561
|
+
pow(x) {
|
|
562
|
+
const exponent = Expression_1.Expression.create(x);
|
|
563
|
+
if (!exponent.isNUM() || !exponent.isInteger()) {
|
|
564
|
+
throw new errors_1.UnsupportedOperationError((0, errors_1.message)('unsupportedOperation'));
|
|
565
|
+
}
|
|
566
|
+
const n = exponent.getMultiplier().numerator;
|
|
567
|
+
let retval;
|
|
568
|
+
if (n === 1n) {
|
|
569
|
+
retval = this.copy();
|
|
570
|
+
}
|
|
571
|
+
else {
|
|
572
|
+
if (!this.isSquare()) {
|
|
573
|
+
throw new errors_1.UnsupportedOperationError((0, errors_1.message)('squareMatrixRequired'));
|
|
574
|
+
}
|
|
575
|
+
if (n === 0n) {
|
|
576
|
+
retval = Matrix.identity(this.rows());
|
|
577
|
+
}
|
|
578
|
+
else {
|
|
579
|
+
let remaining = n < 0n ? -n : n;
|
|
580
|
+
let base = n < 0n ? this.inverse() : this.copy();
|
|
581
|
+
retval = Matrix.identity(this.rows());
|
|
582
|
+
while (remaining > 0n) {
|
|
583
|
+
if (remaining % 2n === 1n) {
|
|
584
|
+
retval = retval.times(base);
|
|
585
|
+
}
|
|
586
|
+
remaining /= 2n;
|
|
587
|
+
if (remaining > 0n) {
|
|
588
|
+
base = base.times(base);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
return retval;
|
|
594
|
+
}
|
|
595
|
+
rank() {
|
|
596
|
+
const M = this.toRightTriangular();
|
|
597
|
+
let rank = 0;
|
|
598
|
+
let i = M.rows();
|
|
599
|
+
const cols = M.cols();
|
|
600
|
+
const z = (0, shortcuts_1.zero)();
|
|
601
|
+
let j;
|
|
602
|
+
while (i--) {
|
|
603
|
+
j = cols;
|
|
604
|
+
while (j--) {
|
|
605
|
+
if (!M.elements[i][j].eq(z)) {
|
|
606
|
+
rank++;
|
|
607
|
+
break;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
return rank;
|
|
612
|
+
}
|
|
613
|
+
row(n) {
|
|
614
|
+
let retval;
|
|
615
|
+
if (n < 1 || n > this.rows()) {
|
|
616
|
+
retval = new Matrix([]);
|
|
617
|
+
}
|
|
618
|
+
else if (this.cols() === 0) {
|
|
619
|
+
retval = Matrix.zeroMatrix(1, 0);
|
|
620
|
+
}
|
|
621
|
+
else {
|
|
622
|
+
retval = new Matrix(this.elements[n - 1]);
|
|
623
|
+
}
|
|
624
|
+
return retval;
|
|
625
|
+
}
|
|
626
|
+
rows() {
|
|
627
|
+
return this.elements.length;
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Returns reduced row-echelon form without mutating this matrix.
|
|
631
|
+
*
|
|
632
|
+
* When `prime` is supplied, pivot arithmetic is performed modulo that value.
|
|
633
|
+
* Otherwise pivots and zero rows are determined by exact Expression equality.
|
|
634
|
+
*/
|
|
635
|
+
rref(prime) {
|
|
636
|
+
const rows = this.rows();
|
|
637
|
+
const cols = this.cols();
|
|
638
|
+
let lead = 0;
|
|
639
|
+
const M = this.copy();
|
|
640
|
+
const z = (0, shortcuts_1.zero)();
|
|
641
|
+
const p = prime ? Expression_1.Expression.create(prime) : undefined;
|
|
642
|
+
// Pivot selection must use field representatives, so normalize before zero testing.
|
|
643
|
+
if (p) {
|
|
644
|
+
M.each(e => (0, math_1.mod)(e, p));
|
|
645
|
+
}
|
|
646
|
+
for (let r = 0; r < rows; r++) {
|
|
647
|
+
if (cols <= lead) {
|
|
648
|
+
break;
|
|
649
|
+
}
|
|
650
|
+
// Find a row with a nonzero entry in the lead column
|
|
651
|
+
let i = r;
|
|
652
|
+
while (M.elements[i][lead].eq(z)) {
|
|
653
|
+
i++;
|
|
654
|
+
if (rows === i) {
|
|
655
|
+
i = r;
|
|
656
|
+
lead++;
|
|
657
|
+
if (cols === lead) {
|
|
658
|
+
return M;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
// Swap rows i and r
|
|
663
|
+
[M.elements[i], M.elements[r]] = [M.elements[r], M.elements[i]];
|
|
664
|
+
if (p) {
|
|
665
|
+
const inv = (0, math_1.modInv)(M.elements[r][lead], p);
|
|
666
|
+
for (let j = 0; j < cols; j++) {
|
|
667
|
+
M.elements[r][j] = (0, math_1.mod)(M.elements[r][j].times(inv), p);
|
|
668
|
+
}
|
|
669
|
+
for (let k = 0; k < rows; k++) {
|
|
670
|
+
if (k !== r) {
|
|
671
|
+
const factor = M.elements[k][lead];
|
|
672
|
+
for (let j = 0; j < cols; j++) {
|
|
673
|
+
M.elements[k][j] = (0, math_1.mod)(M.elements[k][j].minus(factor.times(M.elements[r][j])), p);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
else {
|
|
679
|
+
const pivot = M.elements[r][lead];
|
|
680
|
+
// The pivot search has already established that this expression is nonzero,
|
|
681
|
+
// so RREF requires normalization regardless of its numeric magnitude.
|
|
682
|
+
for (let j = 0; j < cols; j++) {
|
|
683
|
+
M.elements[r][j] = M.elements[r][j].div(pivot);
|
|
684
|
+
}
|
|
685
|
+
for (let k = 0; k < rows; k++) {
|
|
686
|
+
if (k !== r) {
|
|
687
|
+
const factor = M.elements[k][lead];
|
|
688
|
+
// A zero factor means this row is already clear in the pivot column.
|
|
689
|
+
// Skipping the no-op also avoids propagating numeric metadata through
|
|
690
|
+
// multiplication by zero.
|
|
691
|
+
if (factor.eq(z)) {
|
|
692
|
+
continue;
|
|
693
|
+
}
|
|
694
|
+
for (let j = 0; j < cols; j++) {
|
|
695
|
+
M.elements[k][j] = M.elements[k][j].minus(factor.times(M.elements[r][j]));
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
lead++;
|
|
701
|
+
}
|
|
702
|
+
M.elements.sort((rowA, rowB) => {
|
|
703
|
+
const isZeroA = rowA.every(val => val.eq(z));
|
|
704
|
+
const isZeroB = rowB.every(val => val.eq(z));
|
|
705
|
+
if (isZeroA && !isZeroB) {
|
|
706
|
+
return 1;
|
|
707
|
+
}
|
|
708
|
+
if (!isZeroA && isZeroB) {
|
|
709
|
+
return -1;
|
|
710
|
+
}
|
|
711
|
+
return 0;
|
|
712
|
+
});
|
|
713
|
+
return M;
|
|
714
|
+
}
|
|
715
|
+
/** Sets a zero-based cell after converting `value` to an Expression. */
|
|
716
|
+
set(row, col, value) {
|
|
717
|
+
this.__set__([row, col], value);
|
|
718
|
+
return this;
|
|
719
|
+
}
|
|
720
|
+
text() {
|
|
721
|
+
const textArray = [];
|
|
722
|
+
for (let i = 0; i < this.elements.length; i++) {
|
|
723
|
+
const row = this.elements[i];
|
|
724
|
+
const rowTextArray = [];
|
|
725
|
+
for (let j = 0; j < row.length; j++) {
|
|
726
|
+
rowTextArray.push(row[j].text());
|
|
727
|
+
}
|
|
728
|
+
textArray.push(`[${rowTextArray.join(', ')}]`);
|
|
729
|
+
}
|
|
730
|
+
const text = `matrix(${textArray.join(', ')})`;
|
|
731
|
+
return this.formatSymbolicAccess(text);
|
|
732
|
+
}
|
|
733
|
+
times(M) {
|
|
734
|
+
let retval;
|
|
735
|
+
// Scalar multiplication: scale every element.
|
|
736
|
+
if (Expression_1.Expression.isExpression(M)) {
|
|
737
|
+
retval = this.map(e => e.times(M));
|
|
738
|
+
}
|
|
739
|
+
else if (Vector_1.Vector.isVector(M)) {
|
|
740
|
+
if (this.cols() !== M.count()) {
|
|
741
|
+
throw new errors_1.MathError((0, errors_1.message)('mismatchedDimensions', { function: 'Matrix.times' }));
|
|
742
|
+
}
|
|
743
|
+
const elements = [];
|
|
744
|
+
for (let i = 0; i < this.rows(); i++) {
|
|
745
|
+
elements.push(new Vector_1.Vector(this.elements[i]).dot(M));
|
|
746
|
+
}
|
|
747
|
+
retval = new Vector_1.Vector(elements);
|
|
748
|
+
}
|
|
749
|
+
else {
|
|
750
|
+
if (!Matrix.isMatrix(M)) {
|
|
751
|
+
throw new errors_1.UnsupportedOperationError((0, errors_1.message)('unsupportedType', { type: constants_1.dataTypes[M.dataType] }));
|
|
752
|
+
}
|
|
753
|
+
if (!this.canMultiplyFromLeft(M)) {
|
|
754
|
+
throw new errors_1.MathError((0, errors_1.message)('mismatchedDimensions', { function: 'Matrix.times' }));
|
|
755
|
+
}
|
|
756
|
+
if (this.rows() === 0) {
|
|
757
|
+
retval = new Matrix([]);
|
|
758
|
+
}
|
|
759
|
+
else if (M.cols() === 0) {
|
|
760
|
+
retval = Matrix.zeroMatrix(this.rows(), 0);
|
|
761
|
+
}
|
|
762
|
+
else {
|
|
763
|
+
const e = this.elements;
|
|
764
|
+
const m = e.length;
|
|
765
|
+
const o = e[0].length;
|
|
766
|
+
const elements = [];
|
|
767
|
+
let i = m;
|
|
768
|
+
const n = M.cols();
|
|
769
|
+
let j;
|
|
770
|
+
let k;
|
|
771
|
+
let rowThis;
|
|
772
|
+
let rowElem;
|
|
773
|
+
let sum;
|
|
774
|
+
while (i--) {
|
|
775
|
+
rowElem = [];
|
|
776
|
+
rowThis = e[i];
|
|
777
|
+
j = n;
|
|
778
|
+
while (j--) {
|
|
779
|
+
sum = (0, shortcuts_1.zero)();
|
|
780
|
+
k = o;
|
|
781
|
+
while (k--) {
|
|
782
|
+
const x = rowThis[k];
|
|
783
|
+
const y = M.elements[k][j];
|
|
784
|
+
sum = sum.plus(x.times(y));
|
|
785
|
+
}
|
|
786
|
+
rowElem[j] = sum;
|
|
787
|
+
}
|
|
788
|
+
elements[i] = rowElem;
|
|
789
|
+
}
|
|
790
|
+
retval = new Matrix(...elements);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
return retval;
|
|
794
|
+
}
|
|
795
|
+
/** Returns a row-echelon copy produced by forward elimination and row swaps. */
|
|
796
|
+
toRightTriangular() {
|
|
797
|
+
const M = this.copy();
|
|
798
|
+
const rows = M.rows();
|
|
799
|
+
const cols = M.cols();
|
|
800
|
+
const z = (0, shortcuts_1.zero)();
|
|
801
|
+
let pivotRow = 0;
|
|
802
|
+
// Track the number of row swaps for determinant sign correction.
|
|
803
|
+
M._rowSwaps = 0;
|
|
804
|
+
for (let lead = 0; lead < cols && pivotRow < rows; lead++) {
|
|
805
|
+
let pivot = pivotRow;
|
|
806
|
+
while (pivot < rows && M.elements[pivot][lead].eq(z)) {
|
|
807
|
+
pivot++;
|
|
808
|
+
}
|
|
809
|
+
// A column without a pivot does not consume a row.
|
|
810
|
+
if (pivot === rows) {
|
|
811
|
+
continue;
|
|
812
|
+
}
|
|
813
|
+
if (pivot !== pivotRow) {
|
|
814
|
+
[M.elements[pivot], M.elements[pivotRow]] = [
|
|
815
|
+
M.elements[pivotRow],
|
|
816
|
+
M.elements[pivot],
|
|
817
|
+
];
|
|
818
|
+
M._rowSwaps++;
|
|
819
|
+
}
|
|
820
|
+
const pivotValue = M.elements[pivotRow][lead];
|
|
821
|
+
// Eliminate below the pivot.
|
|
822
|
+
for (let row = pivotRow + 1; row < rows; row++) {
|
|
823
|
+
if (!M.elements[row][lead].eq(z)) {
|
|
824
|
+
const multiplier = M.elements[row][lead].div(pivotValue);
|
|
825
|
+
const els = [];
|
|
826
|
+
for (let col = 0; col < cols; col++) {
|
|
827
|
+
els.push(col <= lead
|
|
828
|
+
? (0, shortcuts_1.zero)()
|
|
829
|
+
: M.elements[row][col].minus(M.elements[pivotRow][col].times(multiplier)));
|
|
830
|
+
}
|
|
831
|
+
M.elements[row] = els;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
pivotRow++;
|
|
835
|
+
}
|
|
836
|
+
return M;
|
|
837
|
+
}
|
|
838
|
+
toUpperTriangular() {
|
|
839
|
+
return this.toRightTriangular();
|
|
840
|
+
}
|
|
841
|
+
/**
|
|
842
|
+
* Returns the sum of the main diagonal. The empty matrix has trace zero.
|
|
843
|
+
* @throws {@link core!MathError} If the matrix is not square.
|
|
844
|
+
*/
|
|
845
|
+
trace() {
|
|
846
|
+
if (!this.isSquare()) {
|
|
847
|
+
throw new errors_1.MathError('Unable to calculate trace for the matrix');
|
|
848
|
+
}
|
|
849
|
+
let tr = (0, shortcuts_1.zero)();
|
|
850
|
+
const n = this.elements.length;
|
|
851
|
+
for (let i = 0; i < n; i++) {
|
|
852
|
+
const e = this.elements[i][i];
|
|
853
|
+
if (!Expression_1.Expression.isExpression(e)) {
|
|
854
|
+
throw new errors_1.MathError('Unable to calculate trace for the matrix');
|
|
855
|
+
}
|
|
856
|
+
tr = tr.plus(e);
|
|
857
|
+
}
|
|
858
|
+
return tr;
|
|
859
|
+
}
|
|
860
|
+
/** Returns a transposed matrix. Existing elements are normalized by the constructor. */
|
|
861
|
+
transpose() {
|
|
862
|
+
const rows = this.rows();
|
|
863
|
+
const cols = this.cols();
|
|
864
|
+
if (rows > 0 && cols === 0) {
|
|
865
|
+
throw new errors_1.UnsupportedOperationError((0, errors_1.message)('unsupportedOperation'));
|
|
866
|
+
}
|
|
867
|
+
const elements = [];
|
|
868
|
+
let i = cols;
|
|
869
|
+
while (i--) {
|
|
870
|
+
let j = rows;
|
|
871
|
+
elements[i] = [];
|
|
872
|
+
while (j--) {
|
|
873
|
+
elements[i][j] = this.elements[j][i];
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
return new Matrix(...elements);
|
|
877
|
+
}
|
|
878
|
+
/** Returns elements as a column-major Vector. */
|
|
879
|
+
unroll() {
|
|
880
|
+
const v = [];
|
|
881
|
+
for (let i = 1; i <= this.cols(); i++) {
|
|
882
|
+
for (let j = 1; j <= this.rows(); j++) {
|
|
883
|
+
v.push(this.e(j, i));
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
return new Vector_1.Vector(v);
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
exports.Matrix = Matrix;
|