@cortex-js/compute-engine 0.53.1 → 0.54.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/dist/compute-engine.esm.js +979 -288
- package/dist/compute-engine.min.esm.js +70 -70
- package/dist/compute-engine.min.umd.cjs +72 -72
- package/dist/compute-engine.umd.cjs +979 -288
- package/dist/math-json.esm.js +2 -2
- package/dist/math-json.min.esm.js +2 -2
- package/dist/math-json.min.umd.cjs +2 -2
- package/dist/math-json.umd.cjs +2 -2
- package/dist/types/common/ansi-codes.d.ts +1 -1
- package/dist/types/common/configuration-change.d.ts +1 -1
- package/dist/types/common/fuzzy-string-match.d.ts +1 -1
- package/dist/types/common/grapheme-splitter.d.ts +1 -1
- package/dist/types/common/interruptible.d.ts +1 -1
- package/dist/types/common/one-of.d.ts +1 -1
- package/dist/types/common/signals.d.ts +1 -1
- package/dist/types/common/type/ast-nodes.d.ts +1 -1
- package/dist/types/common/type/boxed-type.d.ts +1 -1
- package/dist/types/common/type/lexer.d.ts +1 -1
- package/dist/types/common/type/parse.d.ts +1 -1
- package/dist/types/common/type/parser.d.ts +1 -1
- package/dist/types/common/type/primitive.d.ts +1 -1
- package/dist/types/common/type/reduce.d.ts +1 -1
- package/dist/types/common/type/serialize.d.ts +1 -1
- package/dist/types/common/type/subtype.d.ts +1 -1
- package/dist/types/common/type/type-builder.d.ts +1 -1
- package/dist/types/common/type/types.d.ts +1 -1
- package/dist/types/common/type/utils.d.ts +1 -1
- package/dist/types/common/utils.d.ts +1 -1
- package/dist/types/compute-engine/assume.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +14 -3
- package/dist/types/compute-engine/boxed-expression/apply.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/arithmetic-add.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/arithmetic-mul-div.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/arithmetic-power.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/ascii-math.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/box.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-dictionary.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +3 -3
- package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +3 -3
- package/dist/types/compute-engine/boxed-expression/boxed-operator-definition.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +3 -3
- package/dist/types/compute-engine/boxed-expression/boxed-tensor.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-value-definition.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/cache.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/canonical-utils.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/canonical.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/compare.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/constants.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/expand.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/factor.d.ts +37 -4
- package/dist/types/compute-engine/boxed-expression/flatten.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/hold.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/inequality-bounds.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/init-lazy-refs.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/invisible-operator.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/match.d.ts +2 -2
- package/dist/types/compute-engine/boxed-expression/negate.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/numerics.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/order.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/pattern-utils.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/polynomial-degree.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/polynomials.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/predicates.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/rules.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/serialize.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/sgn.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/simplify.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/solve-linear-system.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/solve.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/stochastic-equal.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/trigonometry.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/type-guards.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/utils.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/validate.d.ts +1 -1
- package/dist/types/compute-engine/collection-utils.d.ts +1 -1
- package/dist/types/compute-engine/compilation/base-compiler.d.ts +1 -1
- package/dist/types/compute-engine/compilation/compile-expression.d.ts +1 -1
- package/dist/types/compute-engine/compilation/glsl-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/gpu-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/interval-javascript-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/javascript-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/python-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/types.d.ts +1 -1
- package/dist/types/compute-engine/compilation/wgsl-target.d.ts +1 -1
- package/dist/types/compute-engine/cost-function.d.ts +1 -1
- package/dist/types/compute-engine/engine-assumptions.d.ts +1 -1
- package/dist/types/compute-engine/engine-cache.d.ts +1 -1
- package/dist/types/compute-engine/engine-common-symbols.d.ts +1 -1
- package/dist/types/compute-engine/engine-compilation-targets.d.ts +1 -1
- package/dist/types/compute-engine/engine-configuration-lifecycle.d.ts +1 -1
- package/dist/types/compute-engine/engine-declarations.d.ts +1 -1
- package/dist/types/compute-engine/engine-expression-entrypoints.d.ts +1 -1
- package/dist/types/compute-engine/engine-extension-contracts.d.ts +1 -1
- package/dist/types/compute-engine/engine-latex-dictionary-state.d.ts +1 -1
- package/dist/types/compute-engine/engine-library-bootstrap.d.ts +1 -1
- package/dist/types/compute-engine/engine-numeric-configuration.d.ts +1 -1
- package/dist/types/compute-engine/engine-parse-entrypoint.d.ts +1 -1
- package/dist/types/compute-engine/engine-runtime-state.d.ts +1 -1
- package/dist/types/compute-engine/engine-scope.d.ts +1 -1
- package/dist/types/compute-engine/engine-sequences.d.ts +1 -1
- package/dist/types/compute-engine/engine-simplification-rules.d.ts +1 -1
- package/dist/types/compute-engine/engine-startup-coordinator.d.ts +1 -1
- package/dist/types/compute-engine/engine-type-resolver.d.ts +1 -1
- package/dist/types/compute-engine/engine-validation-entrypoints.d.ts +1 -1
- package/dist/types/compute-engine/free-functions.d.ts +1 -1
- package/dist/types/compute-engine/function-utils.d.ts +1 -1
- package/dist/types/compute-engine/global-types.d.ts +1 -1
- package/dist/types/compute-engine/index.d.ts +1 -1
- package/dist/types/compute-engine/interval/arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/interval/comparison.d.ts +1 -1
- package/dist/types/compute-engine/interval/elementary.d.ts +1 -1
- package/dist/types/compute-engine/interval/index.d.ts +1 -1
- package/dist/types/compute-engine/interval/trigonometric.d.ts +1 -1
- package/dist/types/compute-engine/interval/types.d.ts +1 -1
- package/dist/types/compute-engine/interval/util.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-complex.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-linear-algebra.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-relational-operators.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-statistics.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-units.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/indexed-types.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/parse-number.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/parse-symbol.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/parse.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serialize-dms.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serialize-number.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serializer-style.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serializer.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/tokenizer.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/types.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/utils.d.ts +1 -1
- package/dist/types/compute-engine/library/arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/library/calculus.d.ts +1 -1
- package/dist/types/compute-engine/library/collections.d.ts +1 -1
- package/dist/types/compute-engine/library/colors.d.ts +1 -1
- package/dist/types/compute-engine/library/combinatorics.d.ts +1 -1
- package/dist/types/compute-engine/library/complex.d.ts +1 -1
- package/dist/types/compute-engine/library/control-structures.d.ts +1 -1
- package/dist/types/compute-engine/library/core.d.ts +1 -1
- package/dist/types/compute-engine/library/fractals.d.ts +1 -1
- package/dist/types/compute-engine/library/library.d.ts +1 -1
- package/dist/types/compute-engine/library/linear-algebra.d.ts +1 -1
- package/dist/types/compute-engine/library/logic-analysis.d.ts +1 -1
- package/dist/types/compute-engine/library/logic.d.ts +1 -1
- package/dist/types/compute-engine/library/number-theory.d.ts +1 -1
- package/dist/types/compute-engine/library/polynomials.d.ts +1 -1
- package/dist/types/compute-engine/library/quantity-arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/library/random-expression.d.ts +1 -1
- package/dist/types/compute-engine/library/relational-operator.d.ts +1 -1
- package/dist/types/compute-engine/library/sets.d.ts +1 -1
- package/dist/types/compute-engine/library/statistics.d.ts +1 -1
- package/dist/types/compute-engine/library/trigonometry.d.ts +1 -1
- package/dist/types/compute-engine/library/type-handlers.d.ts +1 -1
- package/dist/types/compute-engine/library/unit-data.d.ts +1 -1
- package/dist/types/compute-engine/library/units.d.ts +1 -1
- package/dist/types/compute-engine/library/utils.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/big-numeric-value.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/exact-numeric-value.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/machine-numeric-value.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/types.d.ts +1 -1
- package/dist/types/compute-engine/numerics/bigint.d.ts +1 -1
- package/dist/types/compute-engine/numerics/expression.d.ts +1 -1
- package/dist/types/compute-engine/numerics/interval.d.ts +1 -1
- package/dist/types/compute-engine/numerics/monte-carlo.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-bigint.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-bignum.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-complex.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric.d.ts +1 -1
- package/dist/types/compute-engine/numerics/primes.d.ts +1 -1
- package/dist/types/compute-engine/numerics/rationals.d.ts +1 -1
- package/dist/types/compute-engine/numerics/richardson.d.ts +1 -1
- package/dist/types/compute-engine/numerics/special-functions.d.ts +1 -1
- package/dist/types/compute-engine/numerics/statistics.d.ts +1 -1
- package/dist/types/compute-engine/numerics/strings.d.ts +1 -1
- package/dist/types/compute-engine/numerics/types.d.ts +1 -1
- package/dist/types/compute-engine/numerics/unit-data.d.ts +1 -1
- package/dist/types/compute-engine/oeis.d.ts +1 -1
- package/dist/types/compute-engine/sequence.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/antiderivative.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/derivative.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/distribute.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/fu-cost.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/fu-transforms.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/fu.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/logic-utils.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-abs.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-divide.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-factorial.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-hyperbolic.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-infinity.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-log.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-logic.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-power.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-product.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-rules.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-sum.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-trig.d.ts +1 -1
- package/dist/types/compute-engine/tensor/tensor-fields.d.ts +1 -1
- package/dist/types/compute-engine/tensor/tensors.d.ts +1 -1
- package/dist/types/compute-engine/types-definitions.d.ts +1 -1
- package/dist/types/compute-engine/types-engine.d.ts +1 -1
- package/dist/types/compute-engine/types-evaluation.d.ts +1 -1
- package/dist/types/compute-engine/types-expression.d.ts +61 -2
- package/dist/types/compute-engine/types-kernel-evaluation.d.ts +1 -1
- package/dist/types/compute-engine/types-kernel-serialization.d.ts +12 -1
- package/dist/types/compute-engine/types-serialization.d.ts +1 -1
- package/dist/types/compute-engine/types.d.ts +1 -1
- package/dist/types/compute-engine.d.ts +1 -1
- package/dist/types/math-json/symbols.d.ts +1 -1
- package/dist/types/math-json/types.d.ts +1 -1
- package/dist/types/math-json/utils.d.ts +1 -1
- package/dist/types/math-json.d.ts +2 -2
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Compute Engine 0.
|
|
1
|
+
/** Compute Engine 0.54.0 */
|
|
2
2
|
|
|
3
3
|
// node_modules/complex-esm/dist/src/complex.js
|
|
4
4
|
var cosh = Math.cosh || function(x) {
|
|
@@ -12290,6 +12290,18 @@ var _expandForIs;
|
|
|
12290
12290
|
function _setExpandForIs(fn) {
|
|
12291
12291
|
_expandForIs = fn;
|
|
12292
12292
|
}
|
|
12293
|
+
var _getPolynomialCoefficients;
|
|
12294
|
+
function _setGetPolynomialCoefficients(fn) {
|
|
12295
|
+
_getPolynomialCoefficients = fn;
|
|
12296
|
+
}
|
|
12297
|
+
var _getPolynomialDegree;
|
|
12298
|
+
function _setGetPolynomialDegree(fn) {
|
|
12299
|
+
_getPolynomialDegree = fn;
|
|
12300
|
+
}
|
|
12301
|
+
var _findUnivariateRoots;
|
|
12302
|
+
function _setFindUnivariateRoots(fn) {
|
|
12303
|
+
_findUnivariateRoots = fn;
|
|
12304
|
+
}
|
|
12293
12305
|
var EXPANDABLE_OPS = ["Multiply", "Power", "Negate", "Divide"];
|
|
12294
12306
|
function _couldBenefitFromExpand(a, b) {
|
|
12295
12307
|
if (a.has(EXPANDABLE_OPS)) return true;
|
|
@@ -12605,6 +12617,34 @@ var _BoxedExpression = class __BoxedExpression {
|
|
|
12605
12617
|
factors() {
|
|
12606
12618
|
return [this];
|
|
12607
12619
|
}
|
|
12620
|
+
polynomialCoefficients(variable) {
|
|
12621
|
+
let vars;
|
|
12622
|
+
if (variable === void 0) {
|
|
12623
|
+
const unknowns = this.unknowns;
|
|
12624
|
+
if (unknowns.length !== 1) return void 0;
|
|
12625
|
+
vars = [unknowns[0]];
|
|
12626
|
+
} else if (typeof variable === "string") {
|
|
12627
|
+
vars = [variable];
|
|
12628
|
+
} else {
|
|
12629
|
+
if (variable.length === 0) return void 0;
|
|
12630
|
+
vars = variable;
|
|
12631
|
+
}
|
|
12632
|
+
for (const v of vars) {
|
|
12633
|
+
if (_getPolynomialDegree(this, v) < 0) return void 0;
|
|
12634
|
+
}
|
|
12635
|
+
const coeffs = _getPolynomialCoefficients(this, vars[0]);
|
|
12636
|
+
if (coeffs === null) return void 0;
|
|
12637
|
+
return coeffs.reverse();
|
|
12638
|
+
}
|
|
12639
|
+
polynomialRoots(variable) {
|
|
12640
|
+
if (variable === void 0) {
|
|
12641
|
+
const unknowns = this.unknowns;
|
|
12642
|
+
if (unknowns.length !== 1) return void 0;
|
|
12643
|
+
variable = unknowns[0];
|
|
12644
|
+
}
|
|
12645
|
+
if (_getPolynomialDegree(this, variable) < 0) return void 0;
|
|
12646
|
+
return _findUnivariateRoots(this, variable);
|
|
12647
|
+
}
|
|
12608
12648
|
is(other, tolerance) {
|
|
12609
12649
|
if (this.isSame(other)) return true;
|
|
12610
12650
|
if (_expandForIs && _couldBenefitFromExpand(this, other)) {
|
|
@@ -16064,10 +16104,14 @@ function isSqrt(expr) {
|
|
|
16064
16104
|
return expr.operator === "Sqrt" || expr.operator === "Power" && expr.op2.im === 0 && expr.op2.re === 0.5 || expr.operator === "Root" && expr.op2.im === 0 && expr.op2.re === 2;
|
|
16065
16105
|
}
|
|
16066
16106
|
function asRadical(expr) {
|
|
16067
|
-
if (isSqrt(expr) && isFunction2(expr))
|
|
16107
|
+
if (isSqrt(expr) && isFunction2(expr)) {
|
|
16108
|
+
const r = asRational(expr.op1);
|
|
16109
|
+
if (r === void 0 || r[0] < 0 || r[1] < 0) return null;
|
|
16110
|
+
return r;
|
|
16111
|
+
}
|
|
16068
16112
|
if (isFunction2(expr, "Divide") && expr.op1.isSame(1) && isSqrt(expr.op2)) {
|
|
16069
16113
|
const n = expr.op2.re;
|
|
16070
|
-
if (!Number.isInteger(n)) return null;
|
|
16114
|
+
if (!Number.isInteger(n) || n <= 0) return null;
|
|
16071
16115
|
return [1, n];
|
|
16072
16116
|
}
|
|
16073
16117
|
return null;
|
|
@@ -23948,7 +23992,9 @@ var ARITHMETIC_LIBRARY = [
|
|
|
23948
23992
|
if (n === null) return void 0;
|
|
23949
23993
|
const ce = x.engine;
|
|
23950
23994
|
if (bignumPreferred(ce))
|
|
23951
|
-
return ce.number(
|
|
23995
|
+
return ce.number(
|
|
23996
|
+
run(factorial23(ce, ce.bignum(n)), ce._timeRemaining)
|
|
23997
|
+
);
|
|
23952
23998
|
return ce.number(factorial22(n));
|
|
23953
23999
|
}
|
|
23954
24000
|
},
|
|
@@ -26349,6 +26395,268 @@ function expandAll(expr) {
|
|
|
26349
26395
|
return expand2(result);
|
|
26350
26396
|
}
|
|
26351
26397
|
|
|
26398
|
+
// src/compute-engine/boxed-expression/polynomials.ts
|
|
26399
|
+
function polynomialDegree(expr, variable) {
|
|
26400
|
+
if (isNumber(expr)) return 0;
|
|
26401
|
+
if (isSymbol2(expr)) {
|
|
26402
|
+
if (expr.symbol === variable) return 1;
|
|
26403
|
+
return 0;
|
|
26404
|
+
}
|
|
26405
|
+
if (!isFunction2(expr)) {
|
|
26406
|
+
if (expr.has(variable)) return -1;
|
|
26407
|
+
return 0;
|
|
26408
|
+
}
|
|
26409
|
+
const op = expr.operator;
|
|
26410
|
+
if (op === "Negate") return polynomialDegree(expr.op1, variable);
|
|
26411
|
+
if (op === "Add" || op === "Subtract") {
|
|
26412
|
+
let maxDeg = 0;
|
|
26413
|
+
for (const arg of expr.ops) {
|
|
26414
|
+
const deg = polynomialDegree(arg, variable);
|
|
26415
|
+
if (deg < 0) return -1;
|
|
26416
|
+
maxDeg = Math.max(maxDeg, deg);
|
|
26417
|
+
}
|
|
26418
|
+
return maxDeg;
|
|
26419
|
+
}
|
|
26420
|
+
if (op === "Multiply") {
|
|
26421
|
+
let totalDeg = 0;
|
|
26422
|
+
for (const arg of expr.ops) {
|
|
26423
|
+
const deg = polynomialDegree(arg, variable);
|
|
26424
|
+
if (deg < 0) return -1;
|
|
26425
|
+
totalDeg += deg;
|
|
26426
|
+
}
|
|
26427
|
+
return totalDeg;
|
|
26428
|
+
}
|
|
26429
|
+
if (op === "Power") {
|
|
26430
|
+
const baseDeg = polynomialDegree(expr.op1, variable);
|
|
26431
|
+
if (baseDeg < 0) return -1;
|
|
26432
|
+
if (baseDeg === 0) {
|
|
26433
|
+
if (expr.op2.has(variable)) return -1;
|
|
26434
|
+
return 0;
|
|
26435
|
+
}
|
|
26436
|
+
const exp3 = asSmallInteger(expr.op2);
|
|
26437
|
+
if (exp3 === null || exp3 < 0) return -1;
|
|
26438
|
+
return baseDeg * exp3;
|
|
26439
|
+
}
|
|
26440
|
+
if (expr.has(variable)) return -1;
|
|
26441
|
+
return 0;
|
|
26442
|
+
}
|
|
26443
|
+
function getPolynomialCoefficients(expr, variable) {
|
|
26444
|
+
const ce = expr.engine;
|
|
26445
|
+
const degree = polynomialDegree(expr, variable);
|
|
26446
|
+
if (degree < 0) return null;
|
|
26447
|
+
const coeffs = new Array(degree + 1).fill(ce.Zero);
|
|
26448
|
+
const expanded = expand2(expr);
|
|
26449
|
+
const addCoefficient = (coef, deg) => {
|
|
26450
|
+
if (deg > degree) return false;
|
|
26451
|
+
coeffs[deg] = coeffs[deg].add(coef);
|
|
26452
|
+
return true;
|
|
26453
|
+
};
|
|
26454
|
+
const processTerm = (term) => {
|
|
26455
|
+
const termDeg = polynomialDegree(term, variable);
|
|
26456
|
+
if (termDeg < 0) return false;
|
|
26457
|
+
if (termDeg === 0) {
|
|
26458
|
+
return addCoefficient(term, 0);
|
|
26459
|
+
}
|
|
26460
|
+
if (isSymbol2(term, variable)) {
|
|
26461
|
+
return addCoefficient(ce.One, 1);
|
|
26462
|
+
}
|
|
26463
|
+
if (isFunction2(term, "Negate")) {
|
|
26464
|
+
const innerDeg = polynomialDegree(term.op1, variable);
|
|
26465
|
+
if (innerDeg === 0) {
|
|
26466
|
+
return addCoefficient(term, 0);
|
|
26467
|
+
}
|
|
26468
|
+
const innerCoeffs = getPolynomialCoefficients(term.op1, variable);
|
|
26469
|
+
if (!innerCoeffs) return false;
|
|
26470
|
+
for (let i = 0; i < innerCoeffs.length; i++) {
|
|
26471
|
+
if (!innerCoeffs[i].isSame(0)) {
|
|
26472
|
+
addCoefficient(innerCoeffs[i].neg(), i);
|
|
26473
|
+
}
|
|
26474
|
+
}
|
|
26475
|
+
return true;
|
|
26476
|
+
}
|
|
26477
|
+
if (isFunction2(term, "Power")) {
|
|
26478
|
+
if (isSymbol2(term.op1, variable)) {
|
|
26479
|
+
const exp3 = asSmallInteger(term.op2);
|
|
26480
|
+
if (exp3 !== null && exp3 >= 0) {
|
|
26481
|
+
return addCoefficient(ce.One, exp3);
|
|
26482
|
+
}
|
|
26483
|
+
}
|
|
26484
|
+
if (!term.op1.has(variable)) {
|
|
26485
|
+
return addCoefficient(term, 0);
|
|
26486
|
+
}
|
|
26487
|
+
return false;
|
|
26488
|
+
}
|
|
26489
|
+
if (isFunction2(term, "Multiply")) {
|
|
26490
|
+
const factors = term.ops;
|
|
26491
|
+
let coef = ce.One;
|
|
26492
|
+
let varDeg = 0;
|
|
26493
|
+
for (const factor3 of factors) {
|
|
26494
|
+
if (!factor3.has(variable)) {
|
|
26495
|
+
coef = coef.mul(factor3);
|
|
26496
|
+
} else if (isSymbol2(factor3, variable)) {
|
|
26497
|
+
varDeg += 1;
|
|
26498
|
+
} else if (isFunction2(factor3, "Power") && isSymbol2(factor3.op1, variable)) {
|
|
26499
|
+
const exp3 = asSmallInteger(factor3.op2);
|
|
26500
|
+
if (exp3 !== null && exp3 >= 0) {
|
|
26501
|
+
varDeg += exp3;
|
|
26502
|
+
} else {
|
|
26503
|
+
return false;
|
|
26504
|
+
}
|
|
26505
|
+
} else {
|
|
26506
|
+
return false;
|
|
26507
|
+
}
|
|
26508
|
+
}
|
|
26509
|
+
return addCoefficient(coef, varDeg);
|
|
26510
|
+
}
|
|
26511
|
+
return false;
|
|
26512
|
+
};
|
|
26513
|
+
if (isFunction2(expanded, "Add")) {
|
|
26514
|
+
for (const term of expanded.ops) {
|
|
26515
|
+
if (!processTerm(term)) return null;
|
|
26516
|
+
}
|
|
26517
|
+
} else {
|
|
26518
|
+
if (!processTerm(expanded)) return null;
|
|
26519
|
+
}
|
|
26520
|
+
return coeffs;
|
|
26521
|
+
}
|
|
26522
|
+
function fromCoefficients(coeffs, variable) {
|
|
26523
|
+
if (coeffs.length === 0) return coeffs[0]?.engine.Zero ?? null;
|
|
26524
|
+
const ce = coeffs[0].engine;
|
|
26525
|
+
const x = ce.symbol(variable);
|
|
26526
|
+
const terms = [];
|
|
26527
|
+
for (let i = 0; i < coeffs.length; i++) {
|
|
26528
|
+
const coef = coeffs[i];
|
|
26529
|
+
if (coef.isSame(0)) continue;
|
|
26530
|
+
if (i === 0) {
|
|
26531
|
+
terms.push(coef);
|
|
26532
|
+
} else if (i === 1) {
|
|
26533
|
+
if (coef.isSame(1)) {
|
|
26534
|
+
terms.push(x);
|
|
26535
|
+
} else if (coef.isSame(-1)) {
|
|
26536
|
+
terms.push(x.neg());
|
|
26537
|
+
} else {
|
|
26538
|
+
terms.push(coef.mul(x));
|
|
26539
|
+
}
|
|
26540
|
+
} else {
|
|
26541
|
+
const xPow = ce.box(["Power", variable, i]);
|
|
26542
|
+
if (coef.isSame(1)) {
|
|
26543
|
+
terms.push(xPow);
|
|
26544
|
+
} else if (coef.isSame(-1)) {
|
|
26545
|
+
terms.push(xPow.neg());
|
|
26546
|
+
} else {
|
|
26547
|
+
terms.push(coef.mul(xPow));
|
|
26548
|
+
}
|
|
26549
|
+
}
|
|
26550
|
+
}
|
|
26551
|
+
if (terms.length === 0) return ce.Zero;
|
|
26552
|
+
if (terms.length === 1) return terms[0];
|
|
26553
|
+
return add3(...terms);
|
|
26554
|
+
}
|
|
26555
|
+
function polynomialDivide(dividend, divisor, variable) {
|
|
26556
|
+
const ce = dividend.engine;
|
|
26557
|
+
const dividendCoeffs = getPolynomialCoefficients(dividend, variable);
|
|
26558
|
+
const divisorCoeffs = getPolynomialCoefficients(divisor, variable);
|
|
26559
|
+
if (!dividendCoeffs || !divisorCoeffs) return null;
|
|
26560
|
+
if (divisorCoeffs.every((c) => c.isSame(0))) return null;
|
|
26561
|
+
const actualDegree = (coeffs) => {
|
|
26562
|
+
for (let i = coeffs.length - 1; i >= 0; i--) {
|
|
26563
|
+
if (!coeffs[i].isSame(0)) return i;
|
|
26564
|
+
}
|
|
26565
|
+
return -1;
|
|
26566
|
+
};
|
|
26567
|
+
const dividendDeg = actualDegree(dividendCoeffs);
|
|
26568
|
+
const divisorDeg = actualDegree(divisorCoeffs);
|
|
26569
|
+
if (divisorDeg < 0) return null;
|
|
26570
|
+
if (dividendDeg < 0) {
|
|
26571
|
+
return [ce.Zero, ce.Zero];
|
|
26572
|
+
}
|
|
26573
|
+
if (dividendDeg < divisorDeg) {
|
|
26574
|
+
return [ce.Zero, dividend];
|
|
26575
|
+
}
|
|
26576
|
+
const remainder2 = dividendCoeffs.map((c) => c);
|
|
26577
|
+
const quotientCoeffs = new Array(
|
|
26578
|
+
dividendDeg - divisorDeg + 1
|
|
26579
|
+
).fill(ce.Zero);
|
|
26580
|
+
const leadingDivisor = divisorCoeffs[divisorDeg];
|
|
26581
|
+
for (let i = dividendDeg; i >= divisorDeg; i--) {
|
|
26582
|
+
if (remainder2[i].isSame(0)) continue;
|
|
26583
|
+
const quotientCoef = remainder2[i].div(leadingDivisor);
|
|
26584
|
+
quotientCoeffs[i - divisorDeg] = quotientCoef;
|
|
26585
|
+
for (let j = 0; j <= divisorDeg; j++) {
|
|
26586
|
+
const product = quotientCoef.mul(divisorCoeffs[j]);
|
|
26587
|
+
remainder2[i - divisorDeg + j] = remainder2[i - divisorDeg + j].sub(product);
|
|
26588
|
+
}
|
|
26589
|
+
}
|
|
26590
|
+
const quotient = fromCoefficients(quotientCoeffs, variable);
|
|
26591
|
+
const remainderPoly = fromCoefficients(remainder2, variable);
|
|
26592
|
+
return [quotient, remainderPoly];
|
|
26593
|
+
}
|
|
26594
|
+
function polynomialGCD(a, b, variable) {
|
|
26595
|
+
const ce = a.engine;
|
|
26596
|
+
const degA = polynomialDegree(a, variable);
|
|
26597
|
+
const degB = polynomialDegree(b, variable);
|
|
26598
|
+
if (degA < 0 || degB < 0) return ce.One;
|
|
26599
|
+
const aCoeffs = getPolynomialCoefficients(a, variable);
|
|
26600
|
+
const bCoeffs = getPolynomialCoefficients(b, variable);
|
|
26601
|
+
if (!aCoeffs || aCoeffs.every((c) => c.isSame(0))) {
|
|
26602
|
+
return makeMonic(b, variable);
|
|
26603
|
+
}
|
|
26604
|
+
if (!bCoeffs || bCoeffs.every((c) => c.isSame(0))) {
|
|
26605
|
+
return makeMonic(a, variable);
|
|
26606
|
+
}
|
|
26607
|
+
let p = a;
|
|
26608
|
+
let q = b;
|
|
26609
|
+
while (true) {
|
|
26610
|
+
const qCoeffs = getPolynomialCoefficients(q, variable);
|
|
26611
|
+
if (!qCoeffs || qCoeffs.every((c) => c.isSame(0))) {
|
|
26612
|
+
break;
|
|
26613
|
+
}
|
|
26614
|
+
const divResult = polynomialDivide(p, q, variable);
|
|
26615
|
+
if (!divResult) {
|
|
26616
|
+
return ce.One;
|
|
26617
|
+
}
|
|
26618
|
+
const [, remainder2] = divResult;
|
|
26619
|
+
p = q;
|
|
26620
|
+
q = remainder2;
|
|
26621
|
+
}
|
|
26622
|
+
return makeMonic(p, variable);
|
|
26623
|
+
}
|
|
26624
|
+
function makeMonic(poly, variable) {
|
|
26625
|
+
const coeffs = getPolynomialCoefficients(poly, variable);
|
|
26626
|
+
if (!coeffs) return poly;
|
|
26627
|
+
let leadingCoef = null;
|
|
26628
|
+
for (let i = coeffs.length - 1; i >= 0; i--) {
|
|
26629
|
+
if (!coeffs[i].isSame(0)) {
|
|
26630
|
+
leadingCoef = coeffs[i];
|
|
26631
|
+
break;
|
|
26632
|
+
}
|
|
26633
|
+
}
|
|
26634
|
+
if (!leadingCoef || leadingCoef.isSame(1)) return poly;
|
|
26635
|
+
const monicCoeffs = coeffs.map((c) => c.div(leadingCoef));
|
|
26636
|
+
return fromCoefficients(monicCoeffs, variable);
|
|
26637
|
+
}
|
|
26638
|
+
function cancelCommonFactors(expr, variable) {
|
|
26639
|
+
if (!isFunction2(expr, "Divide")) return expr;
|
|
26640
|
+
const numerator = expr.op1;
|
|
26641
|
+
const denominator = expr.op2;
|
|
26642
|
+
const numDeg = polynomialDegree(numerator, variable);
|
|
26643
|
+
const denDeg = polynomialDegree(denominator, variable);
|
|
26644
|
+
if (numDeg < 0 || denDeg < 0) return expr;
|
|
26645
|
+
const gcd7 = polynomialGCD(numerator, denominator, variable);
|
|
26646
|
+
const gcdDeg = polynomialDegree(gcd7, variable);
|
|
26647
|
+
if (gcdDeg <= 0) return expr;
|
|
26648
|
+
const numDivResult = polynomialDivide(numerator, gcd7, variable);
|
|
26649
|
+
const denDivResult = polynomialDivide(denominator, gcd7, variable);
|
|
26650
|
+
if (!numDivResult || !denDivResult) return expr;
|
|
26651
|
+
const [newNumerator] = numDivResult;
|
|
26652
|
+
const [newDenominator] = denDivResult;
|
|
26653
|
+
const denCoeffs = getPolynomialCoefficients(newDenominator, variable);
|
|
26654
|
+
if (denCoeffs && denCoeffs.length === 1 && denCoeffs[0].isSame(1)) {
|
|
26655
|
+
return newNumerator;
|
|
26656
|
+
}
|
|
26657
|
+
return newNumerator.div(newDenominator);
|
|
26658
|
+
}
|
|
26659
|
+
|
|
26352
26660
|
// src/compute-engine/boxed-expression/solve.ts
|
|
26353
26661
|
function numericApproximation(value) {
|
|
26354
26662
|
if (typeof value === "number") return value;
|
|
@@ -27172,6 +27480,13 @@ function findUnivariateRoots(expr, x) {
|
|
|
27172
27480
|
)
|
|
27173
27481
|
);
|
|
27174
27482
|
}
|
|
27483
|
+
if (result.length === 0) {
|
|
27484
|
+
const deg = polynomialDegree(originalExpr, x);
|
|
27485
|
+
if (deg >= 3) {
|
|
27486
|
+
const rationalRoots = findRationalRoots(originalExpr, x, ce);
|
|
27487
|
+
if (rationalRoots.length > 0) result = rationalRoots;
|
|
27488
|
+
}
|
|
27489
|
+
}
|
|
27175
27490
|
} finally {
|
|
27176
27491
|
ce.popScope();
|
|
27177
27492
|
}
|
|
@@ -27310,267 +27625,49 @@ function filterRootsByType(ce, x, roots) {
|
|
|
27310
27625
|
return true;
|
|
27311
27626
|
});
|
|
27312
27627
|
}
|
|
27313
|
-
|
|
27314
|
-
|
|
27315
|
-
|
|
27316
|
-
|
|
27317
|
-
if (
|
|
27318
|
-
|
|
27319
|
-
|
|
27320
|
-
|
|
27321
|
-
if (
|
|
27322
|
-
|
|
27323
|
-
|
|
27324
|
-
|
|
27325
|
-
|
|
27326
|
-
|
|
27327
|
-
|
|
27328
|
-
|
|
27329
|
-
for (const arg of expr.ops) {
|
|
27330
|
-
const deg = polynomialDegree(arg, variable);
|
|
27331
|
-
if (deg < 0) return -1;
|
|
27332
|
-
maxDeg = Math.max(maxDeg, deg);
|
|
27333
|
-
}
|
|
27334
|
-
return maxDeg;
|
|
27335
|
-
}
|
|
27336
|
-
if (op === "Multiply") {
|
|
27337
|
-
let totalDeg = 0;
|
|
27338
|
-
for (const arg of expr.ops) {
|
|
27339
|
-
const deg = polynomialDegree(arg, variable);
|
|
27340
|
-
if (deg < 0) return -1;
|
|
27341
|
-
totalDeg += deg;
|
|
27342
|
-
}
|
|
27343
|
-
return totalDeg;
|
|
27344
|
-
}
|
|
27345
|
-
if (op === "Power") {
|
|
27346
|
-
const baseDeg = polynomialDegree(expr.op1, variable);
|
|
27347
|
-
if (baseDeg < 0) return -1;
|
|
27348
|
-
if (baseDeg === 0) {
|
|
27349
|
-
if (expr.op2.has(variable)) return -1;
|
|
27350
|
-
return 0;
|
|
27351
|
-
}
|
|
27352
|
-
const exp3 = asSmallInteger(expr.op2);
|
|
27353
|
-
if (exp3 === null || exp3 < 0) return -1;
|
|
27354
|
-
return baseDeg * exp3;
|
|
27355
|
-
}
|
|
27356
|
-
if (expr.has(variable)) return -1;
|
|
27357
|
-
return 0;
|
|
27358
|
-
}
|
|
27359
|
-
function getPolynomialCoefficients(expr, variable) {
|
|
27360
|
-
const ce = expr.engine;
|
|
27361
|
-
const degree = polynomialDegree(expr, variable);
|
|
27362
|
-
if (degree < 0) return null;
|
|
27363
|
-
const coeffs = new Array(degree + 1).fill(ce.Zero);
|
|
27364
|
-
const expanded = expand2(expr);
|
|
27365
|
-
const addCoefficient = (coef, deg) => {
|
|
27366
|
-
if (deg > degree) return false;
|
|
27367
|
-
coeffs[deg] = coeffs[deg].add(coef);
|
|
27368
|
-
return true;
|
|
27369
|
-
};
|
|
27370
|
-
const processTerm = (term) => {
|
|
27371
|
-
const termDeg = polynomialDegree(term, variable);
|
|
27372
|
-
if (termDeg < 0) return false;
|
|
27373
|
-
if (termDeg === 0) {
|
|
27374
|
-
return addCoefficient(term, 0);
|
|
27375
|
-
}
|
|
27376
|
-
if (isSymbol2(term, variable)) {
|
|
27377
|
-
return addCoefficient(ce.One, 1);
|
|
27378
|
-
}
|
|
27379
|
-
if (isFunction2(term, "Negate")) {
|
|
27380
|
-
const innerDeg = polynomialDegree(term.op1, variable);
|
|
27381
|
-
if (innerDeg === 0) {
|
|
27382
|
-
return addCoefficient(term, 0);
|
|
27383
|
-
}
|
|
27384
|
-
const innerCoeffs = getPolynomialCoefficients(term.op1, variable);
|
|
27385
|
-
if (!innerCoeffs) return false;
|
|
27386
|
-
for (let i = 0; i < innerCoeffs.length; i++) {
|
|
27387
|
-
if (!innerCoeffs[i].isSame(0)) {
|
|
27388
|
-
addCoefficient(innerCoeffs[i].neg(), i);
|
|
27389
|
-
}
|
|
27390
|
-
}
|
|
27391
|
-
return true;
|
|
27392
|
-
}
|
|
27393
|
-
if (isFunction2(term, "Power")) {
|
|
27394
|
-
if (isSymbol2(term.op1, variable)) {
|
|
27395
|
-
const exp3 = asSmallInteger(term.op2);
|
|
27396
|
-
if (exp3 !== null && exp3 >= 0) {
|
|
27397
|
-
return addCoefficient(ce.One, exp3);
|
|
27398
|
-
}
|
|
27399
|
-
}
|
|
27400
|
-
if (!term.op1.has(variable)) {
|
|
27401
|
-
return addCoefficient(term, 0);
|
|
27402
|
-
}
|
|
27403
|
-
return false;
|
|
27404
|
-
}
|
|
27405
|
-
if (isFunction2(term, "Multiply")) {
|
|
27406
|
-
const factors = term.ops;
|
|
27407
|
-
let coef = ce.One;
|
|
27408
|
-
let varDeg = 0;
|
|
27409
|
-
for (const factor3 of factors) {
|
|
27410
|
-
if (!factor3.has(variable)) {
|
|
27411
|
-
coef = coef.mul(factor3);
|
|
27412
|
-
} else if (isSymbol2(factor3, variable)) {
|
|
27413
|
-
varDeg += 1;
|
|
27414
|
-
} else if (isFunction2(factor3, "Power") && isSymbol2(factor3.op1, variable)) {
|
|
27415
|
-
const exp3 = asSmallInteger(factor3.op2);
|
|
27416
|
-
if (exp3 !== null && exp3 >= 0) {
|
|
27417
|
-
varDeg += exp3;
|
|
27418
|
-
} else {
|
|
27419
|
-
return false;
|
|
27420
|
-
}
|
|
27421
|
-
} else {
|
|
27422
|
-
return false;
|
|
27423
|
-
}
|
|
27628
|
+
function findRationalRoots(expr, variable, ce) {
|
|
27629
|
+
const coeffs = getPolynomialCoefficients(expr, variable);
|
|
27630
|
+
if (!coeffs) return [];
|
|
27631
|
+
const degree = coeffs.length - 1;
|
|
27632
|
+
if (degree < 1) return [];
|
|
27633
|
+
const constantInt = asSmallInteger(coeffs[0]);
|
|
27634
|
+
const leadingInt = asSmallInteger(coeffs[degree]);
|
|
27635
|
+
if (leadingInt === null || constantInt === null) return [];
|
|
27636
|
+
if (leadingInt === 0 || constantInt === 0) return [];
|
|
27637
|
+
const divisors = (n) => {
|
|
27638
|
+
n = Math.abs(n);
|
|
27639
|
+
const result = [];
|
|
27640
|
+
for (let i = 1; i * i <= n; i++) {
|
|
27641
|
+
if (n % i === 0) {
|
|
27642
|
+
result.push(i);
|
|
27643
|
+
if (i !== n / i) result.push(n / i);
|
|
27424
27644
|
}
|
|
27425
|
-
return addCoefficient(coef, varDeg);
|
|
27426
27645
|
}
|
|
27427
|
-
return
|
|
27646
|
+
return result;
|
|
27428
27647
|
};
|
|
27429
|
-
|
|
27430
|
-
|
|
27431
|
-
|
|
27432
|
-
|
|
27433
|
-
|
|
27434
|
-
|
|
27435
|
-
|
|
27436
|
-
|
|
27437
|
-
|
|
27438
|
-
|
|
27439
|
-
|
|
27440
|
-
|
|
27441
|
-
const x = ce.symbol(variable);
|
|
27442
|
-
const terms = [];
|
|
27443
|
-
for (let i = 0; i < coeffs.length; i++) {
|
|
27444
|
-
const coef = coeffs[i];
|
|
27445
|
-
if (coef.isSame(0)) continue;
|
|
27446
|
-
if (i === 0) {
|
|
27447
|
-
terms.push(coef);
|
|
27448
|
-
} else if (i === 1) {
|
|
27449
|
-
if (coef.isSame(1)) {
|
|
27450
|
-
terms.push(x);
|
|
27451
|
-
} else if (coef.isSame(-1)) {
|
|
27452
|
-
terms.push(x.neg());
|
|
27453
|
-
} else {
|
|
27454
|
-
terms.push(coef.mul(x));
|
|
27455
|
-
}
|
|
27456
|
-
} else {
|
|
27457
|
-
const xPow = ce.box(["Power", variable, i]);
|
|
27458
|
-
if (coef.isSame(1)) {
|
|
27459
|
-
terms.push(xPow);
|
|
27460
|
-
} else if (coef.isSame(-1)) {
|
|
27461
|
-
terms.push(xPow.neg());
|
|
27462
|
-
} else {
|
|
27463
|
-
terms.push(coef.mul(xPow));
|
|
27648
|
+
const pDivisors = divisors(constantInt);
|
|
27649
|
+
const qDivisors = divisors(leadingInt);
|
|
27650
|
+
const candidates = [];
|
|
27651
|
+
const seen = /* @__PURE__ */ new Set();
|
|
27652
|
+
for (const p of pDivisors) {
|
|
27653
|
+
for (const q of qDivisors) {
|
|
27654
|
+
for (const sign3 of [1, -1]) {
|
|
27655
|
+
const val = sign3 * p / q;
|
|
27656
|
+
if (!seen.has(val)) {
|
|
27657
|
+
seen.add(val);
|
|
27658
|
+
candidates.push(val);
|
|
27659
|
+
}
|
|
27464
27660
|
}
|
|
27465
27661
|
}
|
|
27466
27662
|
}
|
|
27467
|
-
if (
|
|
27468
|
-
|
|
27469
|
-
|
|
27470
|
-
|
|
27471
|
-
|
|
27472
|
-
|
|
27473
|
-
const dividendCoeffs = getPolynomialCoefficients(dividend, variable);
|
|
27474
|
-
const divisorCoeffs = getPolynomialCoefficients(divisor, variable);
|
|
27475
|
-
if (!dividendCoeffs || !divisorCoeffs) return null;
|
|
27476
|
-
if (divisorCoeffs.every((c) => c.isSame(0))) return null;
|
|
27477
|
-
const actualDegree = (coeffs) => {
|
|
27478
|
-
for (let i = coeffs.length - 1; i >= 0; i--) {
|
|
27479
|
-
if (!coeffs[i].isSame(0)) return i;
|
|
27480
|
-
}
|
|
27481
|
-
return -1;
|
|
27482
|
-
};
|
|
27483
|
-
const dividendDeg = actualDegree(dividendCoeffs);
|
|
27484
|
-
const divisorDeg = actualDegree(divisorCoeffs);
|
|
27485
|
-
if (divisorDeg < 0) return null;
|
|
27486
|
-
if (dividendDeg < 0) {
|
|
27487
|
-
return [ce.Zero, ce.Zero];
|
|
27488
|
-
}
|
|
27489
|
-
if (dividendDeg < divisorDeg) {
|
|
27490
|
-
return [ce.Zero, dividend];
|
|
27491
|
-
}
|
|
27492
|
-
const remainder2 = dividendCoeffs.map((c) => c);
|
|
27493
|
-
const quotientCoeffs = new Array(
|
|
27494
|
-
dividendDeg - divisorDeg + 1
|
|
27495
|
-
).fill(ce.Zero);
|
|
27496
|
-
const leadingDivisor = divisorCoeffs[divisorDeg];
|
|
27497
|
-
for (let i = dividendDeg; i >= divisorDeg; i--) {
|
|
27498
|
-
if (remainder2[i].isSame(0)) continue;
|
|
27499
|
-
const quotientCoef = remainder2[i].div(leadingDivisor);
|
|
27500
|
-
quotientCoeffs[i - divisorDeg] = quotientCoef;
|
|
27501
|
-
for (let j = 0; j <= divisorDeg; j++) {
|
|
27502
|
-
const product = quotientCoef.mul(divisorCoeffs[j]);
|
|
27503
|
-
remainder2[i - divisorDeg + j] = remainder2[i - divisorDeg + j].sub(product);
|
|
27504
|
-
}
|
|
27505
|
-
}
|
|
27506
|
-
const quotient = fromCoefficients(quotientCoeffs, variable);
|
|
27507
|
-
const remainderPoly = fromCoefficients(remainder2, variable);
|
|
27508
|
-
return [quotient, remainderPoly];
|
|
27509
|
-
}
|
|
27510
|
-
function polynomialGCD(a, b, variable) {
|
|
27511
|
-
const ce = a.engine;
|
|
27512
|
-
const degA = polynomialDegree(a, variable);
|
|
27513
|
-
const degB = polynomialDegree(b, variable);
|
|
27514
|
-
if (degA < 0 || degB < 0) return ce.One;
|
|
27515
|
-
const aCoeffs = getPolynomialCoefficients(a, variable);
|
|
27516
|
-
const bCoeffs = getPolynomialCoefficients(b, variable);
|
|
27517
|
-
if (!aCoeffs || aCoeffs.every((c) => c.isSame(0))) {
|
|
27518
|
-
return makeMonic(b, variable);
|
|
27519
|
-
}
|
|
27520
|
-
if (!bCoeffs || bCoeffs.every((c) => c.isSame(0))) {
|
|
27521
|
-
return makeMonic(a, variable);
|
|
27522
|
-
}
|
|
27523
|
-
let p = a;
|
|
27524
|
-
let q = b;
|
|
27525
|
-
while (true) {
|
|
27526
|
-
const qCoeffs = getPolynomialCoefficients(q, variable);
|
|
27527
|
-
if (!qCoeffs || qCoeffs.every((c) => c.isSame(0))) {
|
|
27528
|
-
break;
|
|
27529
|
-
}
|
|
27530
|
-
const divResult = polynomialDivide(p, q, variable);
|
|
27531
|
-
if (!divResult) {
|
|
27532
|
-
return ce.One;
|
|
27533
|
-
}
|
|
27534
|
-
const [, remainder2] = divResult;
|
|
27535
|
-
p = q;
|
|
27536
|
-
q = remainder2;
|
|
27537
|
-
}
|
|
27538
|
-
return makeMonic(p, variable);
|
|
27539
|
-
}
|
|
27540
|
-
function makeMonic(poly, variable) {
|
|
27541
|
-
const coeffs = getPolynomialCoefficients(poly, variable);
|
|
27542
|
-
if (!coeffs) return poly;
|
|
27543
|
-
let leadingCoef = null;
|
|
27544
|
-
for (let i = coeffs.length - 1; i >= 0; i--) {
|
|
27545
|
-
if (!coeffs[i].isSame(0)) {
|
|
27546
|
-
leadingCoef = coeffs[i];
|
|
27547
|
-
break;
|
|
27548
|
-
}
|
|
27549
|
-
}
|
|
27550
|
-
if (!leadingCoef || leadingCoef.isSame(1)) return poly;
|
|
27551
|
-
const monicCoeffs = coeffs.map((c) => c.div(leadingCoef));
|
|
27552
|
-
return fromCoefficients(monicCoeffs, variable);
|
|
27553
|
-
}
|
|
27554
|
-
function cancelCommonFactors(expr, variable) {
|
|
27555
|
-
if (!isFunction2(expr, "Divide")) return expr;
|
|
27556
|
-
const numerator = expr.op1;
|
|
27557
|
-
const denominator = expr.op2;
|
|
27558
|
-
const numDeg = polynomialDegree(numerator, variable);
|
|
27559
|
-
const denDeg = polynomialDegree(denominator, variable);
|
|
27560
|
-
if (numDeg < 0 || denDeg < 0) return expr;
|
|
27561
|
-
const gcd6 = polynomialGCD(numerator, denominator, variable);
|
|
27562
|
-
const gcdDeg = polynomialDegree(gcd6, variable);
|
|
27563
|
-
if (gcdDeg <= 0) return expr;
|
|
27564
|
-
const numDivResult = polynomialDivide(numerator, gcd6, variable);
|
|
27565
|
-
const denDivResult = polynomialDivide(denominator, gcd6, variable);
|
|
27566
|
-
if (!numDivResult || !denDivResult) return expr;
|
|
27567
|
-
const [newNumerator] = numDivResult;
|
|
27568
|
-
const [newDenominator] = denDivResult;
|
|
27569
|
-
const denCoeffs = getPolynomialCoefficients(newDenominator, variable);
|
|
27570
|
-
if (denCoeffs && denCoeffs.length === 1 && denCoeffs[0].isSame(1)) {
|
|
27571
|
-
return newNumerator;
|
|
27663
|
+
if (candidates.length > 100) return [];
|
|
27664
|
+
const roots = [];
|
|
27665
|
+
for (const candidate of candidates) {
|
|
27666
|
+
const root2 = ce.number(candidate);
|
|
27667
|
+
const value = expr.subs({ [variable]: root2 }).N();
|
|
27668
|
+
if (value.isSame(0)) roots.push(root2);
|
|
27572
27669
|
}
|
|
27573
|
-
return
|
|
27670
|
+
return roots;
|
|
27574
27671
|
}
|
|
27575
27672
|
|
|
27576
27673
|
// src/compute-engine/symbolic/antiderivative.ts
|
|
@@ -38214,7 +38311,107 @@ function factorQuadratic(expr, variable) {
|
|
|
38214
38311
|
return ce.box(["Multiply", a.json, factor1.json, factor22.json]);
|
|
38215
38312
|
}
|
|
38216
38313
|
}
|
|
38314
|
+
function factorByRationalRoots(expr, variable) {
|
|
38315
|
+
const ce = expr.engine;
|
|
38316
|
+
const coeffs = getPolynomialCoefficients(expr, variable);
|
|
38317
|
+
if (!coeffs) return null;
|
|
38318
|
+
const degree = coeffs.length - 1;
|
|
38319
|
+
if (degree < 2) return null;
|
|
38320
|
+
const leadingInt = asSmallInteger(coeffs[degree]);
|
|
38321
|
+
const constantInt = asSmallInteger(coeffs[0]);
|
|
38322
|
+
if (leadingInt === null || constantInt === null) return null;
|
|
38323
|
+
if (leadingInt === 0 || constantInt === 0) return null;
|
|
38324
|
+
const divisors = (n) => {
|
|
38325
|
+
n = Math.abs(n);
|
|
38326
|
+
const result = [];
|
|
38327
|
+
for (let i = 1; i * i <= n; i++) {
|
|
38328
|
+
if (n % i === 0) {
|
|
38329
|
+
result.push(i);
|
|
38330
|
+
if (i !== n / i) result.push(n / i);
|
|
38331
|
+
}
|
|
38332
|
+
}
|
|
38333
|
+
return result;
|
|
38334
|
+
};
|
|
38335
|
+
const pDivisors = divisors(constantInt);
|
|
38336
|
+
const qDivisors = divisors(leadingInt);
|
|
38337
|
+
const candidates = [];
|
|
38338
|
+
const seen = /* @__PURE__ */ new Set();
|
|
38339
|
+
for (const p of pDivisors) {
|
|
38340
|
+
for (const q of qDivisors) {
|
|
38341
|
+
const pos = p / q;
|
|
38342
|
+
const neg2 = -p / q;
|
|
38343
|
+
if (!seen.has(pos)) {
|
|
38344
|
+
seen.add(pos);
|
|
38345
|
+
candidates.push([p, q]);
|
|
38346
|
+
}
|
|
38347
|
+
if (!seen.has(neg2)) {
|
|
38348
|
+
seen.add(neg2);
|
|
38349
|
+
candidates.push([-p, q]);
|
|
38350
|
+
}
|
|
38351
|
+
}
|
|
38352
|
+
}
|
|
38353
|
+
if (candidates.length > 100) return null;
|
|
38354
|
+
const x = ce.symbol(variable);
|
|
38355
|
+
const factors = [];
|
|
38356
|
+
let remaining = expr;
|
|
38357
|
+
for (const [p, q] of candidates) {
|
|
38358
|
+
const remDeg2 = polynomialDegree(remaining, variable);
|
|
38359
|
+
if (remDeg2 <= 0) break;
|
|
38360
|
+
const root2 = q === 1 ? ce.number(p) : ce.number(p).div(ce.number(q));
|
|
38361
|
+
const value = remaining.subs({ [variable]: root2 }).N();
|
|
38362
|
+
if (!value.isSame(0)) continue;
|
|
38363
|
+
const linearFactor = q === 1 ? x.sub(ce.number(p)) : ce.number(q).mul(x).sub(ce.number(p));
|
|
38364
|
+
const divResult = polynomialDivide(remaining, linearFactor, variable);
|
|
38365
|
+
if (!divResult) continue;
|
|
38366
|
+
factors.push(linearFactor);
|
|
38367
|
+
remaining = divResult[0];
|
|
38368
|
+
}
|
|
38369
|
+
if (factors.length === 0) return null;
|
|
38370
|
+
const remDeg = polynomialDegree(remaining, variable);
|
|
38371
|
+
if (remDeg === 2) {
|
|
38372
|
+
const quadFactored = factorQuadratic(remaining, variable);
|
|
38373
|
+
if (quadFactored !== null) remaining = quadFactored;
|
|
38374
|
+
}
|
|
38375
|
+
factors.push(remaining);
|
|
38376
|
+
if (factors.length === 1) return factors[0];
|
|
38377
|
+
return ce.box(["Multiply", ...factors.map((f) => f.json)]);
|
|
38378
|
+
}
|
|
38379
|
+
function extractContent(expr, variable) {
|
|
38380
|
+
const ce = expr.engine;
|
|
38381
|
+
const coeffs = getPolynomialCoefficients(expr, variable);
|
|
38382
|
+
if (!coeffs) return null;
|
|
38383
|
+
const intCoeffs = [];
|
|
38384
|
+
for (const c of coeffs) {
|
|
38385
|
+
const n = asSmallInteger(c);
|
|
38386
|
+
if (n === null) return null;
|
|
38387
|
+
intCoeffs.push(n);
|
|
38388
|
+
}
|
|
38389
|
+
const gcd7 = (a, b) => {
|
|
38390
|
+
a = Math.abs(a);
|
|
38391
|
+
b = Math.abs(b);
|
|
38392
|
+
while (b) {
|
|
38393
|
+
[a, b] = [b, a % b];
|
|
38394
|
+
}
|
|
38395
|
+
return a;
|
|
38396
|
+
};
|
|
38397
|
+
let content = 0;
|
|
38398
|
+
for (const c of intCoeffs) {
|
|
38399
|
+
if (c !== 0) content = gcd7(content, c);
|
|
38400
|
+
}
|
|
38401
|
+
if (content <= 1) return null;
|
|
38402
|
+
const primitiveCoeffs = coeffs.map((c) => {
|
|
38403
|
+
const n = asSmallInteger(c);
|
|
38404
|
+
return ce.number(n / content);
|
|
38405
|
+
});
|
|
38406
|
+
const primitive = fromCoefficients(primitiveCoeffs, variable);
|
|
38407
|
+
const factoredPrimitive = factorPolynomial(primitive, variable);
|
|
38408
|
+
return ce.number(content).mul(factoredPrimitive);
|
|
38409
|
+
}
|
|
38217
38410
|
function factorPolynomial(expr, variable) {
|
|
38411
|
+
if (variable !== void 0) {
|
|
38412
|
+
const contentFactored = extractContent(expr, variable);
|
|
38413
|
+
if (contentFactored !== null) return contentFactored;
|
|
38414
|
+
}
|
|
38218
38415
|
const perfectSquare = factorPerfectSquare(expr);
|
|
38219
38416
|
if (perfectSquare !== null) return perfectSquare;
|
|
38220
38417
|
const diffSquares = factorDifferenceOfSquares(expr);
|
|
@@ -38222,6 +38419,8 @@ function factorPolynomial(expr, variable) {
|
|
|
38222
38419
|
if (variable !== void 0) {
|
|
38223
38420
|
const quadratic = factorQuadratic(expr, variable);
|
|
38224
38421
|
if (quadratic !== null) return quadratic;
|
|
38422
|
+
const rationalRoot = factorByRationalRoots(expr, variable);
|
|
38423
|
+
if (rationalRoot !== null) return rationalRoot;
|
|
38225
38424
|
}
|
|
38226
38425
|
return factor(expr);
|
|
38227
38426
|
}
|
|
@@ -38267,6 +38466,257 @@ function factor(expr) {
|
|
|
38267
38466
|
}
|
|
38268
38467
|
return Product.from(together(expr)).asExpression();
|
|
38269
38468
|
}
|
|
38469
|
+
function collectFactors(expr, variable) {
|
|
38470
|
+
const rawFactors = [];
|
|
38471
|
+
collectFactorsRaw(expr, variable, rawFactors);
|
|
38472
|
+
const merged = [];
|
|
38473
|
+
for (const f of rawFactors) {
|
|
38474
|
+
let found = false;
|
|
38475
|
+
for (const m of merged) {
|
|
38476
|
+
if (m.factor.isSame(f.factor)) {
|
|
38477
|
+
m.multiplicity += f.multiplicity;
|
|
38478
|
+
found = true;
|
|
38479
|
+
break;
|
|
38480
|
+
}
|
|
38481
|
+
}
|
|
38482
|
+
if (!found) merged.push({ ...f });
|
|
38483
|
+
}
|
|
38484
|
+
return merged;
|
|
38485
|
+
}
|
|
38486
|
+
function collectFactorsRaw(expr, variable, result) {
|
|
38487
|
+
if (isFunction2(expr, "Multiply")) {
|
|
38488
|
+
for (const op of expr.ops) {
|
|
38489
|
+
collectFactorsRaw(op, variable, result);
|
|
38490
|
+
}
|
|
38491
|
+
return;
|
|
38492
|
+
}
|
|
38493
|
+
if (isFunction2(expr, "Power")) {
|
|
38494
|
+
const base = expr.op1;
|
|
38495
|
+
const exp3 = asSmallInteger(expr.op2);
|
|
38496
|
+
if (exp3 !== null && exp3 > 0 && base.has(variable)) {
|
|
38497
|
+
const deg3 = polynomialDegree(base, variable);
|
|
38498
|
+
result.push({ factor: base, multiplicity: exp3, degree: deg3 });
|
|
38499
|
+
return;
|
|
38500
|
+
}
|
|
38501
|
+
if (!expr.has(variable)) return;
|
|
38502
|
+
const deg2 = polynomialDegree(expr, variable);
|
|
38503
|
+
result.push({ factor: expr, multiplicity: 1, degree: deg2 });
|
|
38504
|
+
return;
|
|
38505
|
+
}
|
|
38506
|
+
if (!expr.has(variable)) return;
|
|
38507
|
+
if (isNumber(expr)) return;
|
|
38508
|
+
const deg = polynomialDegree(expr, variable);
|
|
38509
|
+
result.push({ factor: expr, multiplicity: 1, degree: deg });
|
|
38510
|
+
}
|
|
38511
|
+
function solveLinearSystem(matrix, numVars) {
|
|
38512
|
+
const rows = matrix.length;
|
|
38513
|
+
const cols = numVars + 1;
|
|
38514
|
+
const m = matrix.map((row) => [...row]);
|
|
38515
|
+
const pivotRow = new Array(numVars).fill(-1);
|
|
38516
|
+
let currentRow = 0;
|
|
38517
|
+
for (let col = 0; col < numVars && currentRow < rows; col++) {
|
|
38518
|
+
let maxVal = 0;
|
|
38519
|
+
let maxRow = -1;
|
|
38520
|
+
for (let row = currentRow; row < rows; row++) {
|
|
38521
|
+
const absVal = Math.abs(m[row][col]);
|
|
38522
|
+
if (absVal > maxVal) {
|
|
38523
|
+
maxVal = absVal;
|
|
38524
|
+
maxRow = row;
|
|
38525
|
+
}
|
|
38526
|
+
}
|
|
38527
|
+
if (maxVal === 0) continue;
|
|
38528
|
+
if (maxRow !== currentRow) {
|
|
38529
|
+
[m[currentRow], m[maxRow]] = [m[maxRow], m[currentRow]];
|
|
38530
|
+
}
|
|
38531
|
+
pivotRow[col] = currentRow;
|
|
38532
|
+
for (let row = 0; row < rows; row++) {
|
|
38533
|
+
if (row === currentRow) continue;
|
|
38534
|
+
if (m[row][col] === 0) continue;
|
|
38535
|
+
const factor3 = m[row][col];
|
|
38536
|
+
const pivotVal = m[currentRow][col];
|
|
38537
|
+
for (let j = 0; j < cols; j++) {
|
|
38538
|
+
m[row][j] = m[row][j] * pivotVal - factor3 * m[currentRow][j];
|
|
38539
|
+
}
|
|
38540
|
+
}
|
|
38541
|
+
currentRow++;
|
|
38542
|
+
}
|
|
38543
|
+
const solution = new Array(numVars);
|
|
38544
|
+
for (let col = 0; col < numVars; col++) {
|
|
38545
|
+
const pr = pivotRow[col];
|
|
38546
|
+
if (pr === -1) {
|
|
38547
|
+
solution[col] = [0, 1];
|
|
38548
|
+
continue;
|
|
38549
|
+
}
|
|
38550
|
+
const num = m[pr][cols - 1];
|
|
38551
|
+
const den = m[pr][col];
|
|
38552
|
+
if (den === 0) return null;
|
|
38553
|
+
const g = gcd4(Math.abs(num), Math.abs(den));
|
|
38554
|
+
const sign3 = den < 0 ? -1 : 1;
|
|
38555
|
+
solution[col] = [sign3 * num / g, sign3 * den / g];
|
|
38556
|
+
}
|
|
38557
|
+
return solution;
|
|
38558
|
+
}
|
|
38559
|
+
function gcd4(a, b) {
|
|
38560
|
+
a = Math.abs(a);
|
|
38561
|
+
b = Math.abs(b);
|
|
38562
|
+
while (b) {
|
|
38563
|
+
[a, b] = [b, a % b];
|
|
38564
|
+
}
|
|
38565
|
+
return a || 1;
|
|
38566
|
+
}
|
|
38567
|
+
function partialFraction(expr, variable) {
|
|
38568
|
+
const ce = expr.engine;
|
|
38569
|
+
if (!isFunction2(expr, "Divide")) return expr;
|
|
38570
|
+
const numer = expr.op1;
|
|
38571
|
+
const denom = expr.op2;
|
|
38572
|
+
const numerDeg = polynomialDegree(numer, variable);
|
|
38573
|
+
const denomDeg = polynomialDegree(denom, variable);
|
|
38574
|
+
if (numerDeg < 0 || denomDeg < 0) return expr;
|
|
38575
|
+
if (denomDeg === 0) return expr;
|
|
38576
|
+
let quotient = null;
|
|
38577
|
+
let remainder2;
|
|
38578
|
+
if (numerDeg >= denomDeg) {
|
|
38579
|
+
const divResult = polynomialDivide(numer, denom, variable);
|
|
38580
|
+
if (!divResult) return expr;
|
|
38581
|
+
quotient = divResult[0];
|
|
38582
|
+
remainder2 = divResult[1];
|
|
38583
|
+
const remCoeffs2 = getPolynomialCoefficients(remainder2, variable);
|
|
38584
|
+
if (remCoeffs2 && remCoeffs2.every((c) => c.isSame(0))) {
|
|
38585
|
+
return quotient;
|
|
38586
|
+
}
|
|
38587
|
+
} else {
|
|
38588
|
+
remainder2 = numer;
|
|
38589
|
+
}
|
|
38590
|
+
const factoredDenom = factorPolynomial(denom, variable);
|
|
38591
|
+
const factors = collectFactors(factoredDenom, variable);
|
|
38592
|
+
if (factors.length === 0) return expr;
|
|
38593
|
+
if (factors.length === 1 && factors[0].multiplicity === 1) {
|
|
38594
|
+
if (quotient) return quotient.add(remainder2.div(denom));
|
|
38595
|
+
return expr;
|
|
38596
|
+
}
|
|
38597
|
+
for (const f of factors) {
|
|
38598
|
+
if (f.degree > 2 || f.degree < 0) return expr;
|
|
38599
|
+
}
|
|
38600
|
+
let totalFactorDeg = 0;
|
|
38601
|
+
for (const f of factors) {
|
|
38602
|
+
totalFactorDeg += f.degree * f.multiplicity;
|
|
38603
|
+
}
|
|
38604
|
+
if (totalFactorDeg !== denomDeg) return expr;
|
|
38605
|
+
const templateTerms = [];
|
|
38606
|
+
let unknownCount = 0;
|
|
38607
|
+
for (const f of factors) {
|
|
38608
|
+
for (let k = 1; k <= f.multiplicity; k++) {
|
|
38609
|
+
if (f.degree === 1) {
|
|
38610
|
+
templateTerms.push({
|
|
38611
|
+
isLinear: true,
|
|
38612
|
+
factor: f.factor,
|
|
38613
|
+
power: k,
|
|
38614
|
+
unknownIndex: unknownCount
|
|
38615
|
+
});
|
|
38616
|
+
unknownCount++;
|
|
38617
|
+
} else {
|
|
38618
|
+
templateTerms.push({
|
|
38619
|
+
isLinear: false,
|
|
38620
|
+
factor: f.factor,
|
|
38621
|
+
power: k,
|
|
38622
|
+
unknownIndex: unknownCount
|
|
38623
|
+
});
|
|
38624
|
+
unknownCount += 2;
|
|
38625
|
+
}
|
|
38626
|
+
}
|
|
38627
|
+
}
|
|
38628
|
+
if (unknownCount !== denomDeg) return expr;
|
|
38629
|
+
const expandedDenom = expand2(denom);
|
|
38630
|
+
const denomCoeffs = getPolynomialCoefficients(expandedDenom, variable);
|
|
38631
|
+
if (!denomCoeffs) return expr;
|
|
38632
|
+
const expandedRemainder = expand2(remainder2);
|
|
38633
|
+
const remCoeffs = getPolynomialCoefficients(expandedRemainder, variable);
|
|
38634
|
+
if (!remCoeffs) return expr;
|
|
38635
|
+
const systemRows = denomDeg;
|
|
38636
|
+
const augMatrix = [];
|
|
38637
|
+
for (let i = 0; i < systemRows; i++) {
|
|
38638
|
+
augMatrix.push(new Array(unknownCount + 1).fill(0));
|
|
38639
|
+
}
|
|
38640
|
+
for (let i = 0; i < systemRows; i++) {
|
|
38641
|
+
const coeff = i < remCoeffs.length ? asSmallInteger(remCoeffs[i]) : 0;
|
|
38642
|
+
if (coeff === null) return expr;
|
|
38643
|
+
augMatrix[i][unknownCount] = coeff;
|
|
38644
|
+
}
|
|
38645
|
+
for (const t of templateTerms) {
|
|
38646
|
+
let termDenom;
|
|
38647
|
+
if (t.power === 1) {
|
|
38648
|
+
termDenom = t.factor;
|
|
38649
|
+
} else {
|
|
38650
|
+
termDenom = ce.box(["Power", t.factor.json, t.power]);
|
|
38651
|
+
}
|
|
38652
|
+
const cofactorResult = polynomialDivide(expandedDenom, termDenom, variable);
|
|
38653
|
+
if (!cofactorResult) return expr;
|
|
38654
|
+
const cofactor = cofactorResult[0];
|
|
38655
|
+
const cofRem = cofactorResult[1];
|
|
38656
|
+
const cofRemCoeffs = getPolynomialCoefficients(cofRem, variable);
|
|
38657
|
+
if (!cofRemCoeffs || !cofRemCoeffs.every((c) => c.isSame(0))) return expr;
|
|
38658
|
+
const expandedCofactor = expand2(cofactor);
|
|
38659
|
+
const cofCoeffs = getPolynomialCoefficients(expandedCofactor, variable);
|
|
38660
|
+
if (!cofCoeffs) return expr;
|
|
38661
|
+
const intCofCoeffs = [];
|
|
38662
|
+
for (let i = 0; i < systemRows; i++) {
|
|
38663
|
+
const c = i < cofCoeffs.length ? asSmallInteger(cofCoeffs[i]) : 0;
|
|
38664
|
+
if (c === null) return expr;
|
|
38665
|
+
intCofCoeffs.push(c);
|
|
38666
|
+
}
|
|
38667
|
+
if (t.isLinear) {
|
|
38668
|
+
for (let i = 0; i < systemRows; i++) {
|
|
38669
|
+
augMatrix[i][t.unknownIndex] += intCofCoeffs[i];
|
|
38670
|
+
}
|
|
38671
|
+
} else {
|
|
38672
|
+
const aIdx = t.unknownIndex;
|
|
38673
|
+
const bIdx = t.unknownIndex + 1;
|
|
38674
|
+
for (let i = 0; i < systemRows; i++) {
|
|
38675
|
+
augMatrix[i][bIdx] += intCofCoeffs[i];
|
|
38676
|
+
if (i > 0) {
|
|
38677
|
+
augMatrix[i][aIdx] += intCofCoeffs[i - 1];
|
|
38678
|
+
}
|
|
38679
|
+
}
|
|
38680
|
+
}
|
|
38681
|
+
}
|
|
38682
|
+
const solution = solveLinearSystem(augMatrix, unknownCount);
|
|
38683
|
+
if (!solution) return expr;
|
|
38684
|
+
const x = ce.symbol(variable);
|
|
38685
|
+
const partialTerms = [];
|
|
38686
|
+
if (quotient) partialTerms.push(quotient);
|
|
38687
|
+
for (const t of templateTerms) {
|
|
38688
|
+
let termDenom;
|
|
38689
|
+
if (t.power === 1) {
|
|
38690
|
+
termDenom = t.factor;
|
|
38691
|
+
} else {
|
|
38692
|
+
termDenom = ce.box(["Power", t.factor.json, t.power]);
|
|
38693
|
+
}
|
|
38694
|
+
let termNumer;
|
|
38695
|
+
if (t.isLinear) {
|
|
38696
|
+
const [num, den] = solution[t.unknownIndex];
|
|
38697
|
+
if (num === 0) continue;
|
|
38698
|
+
termNumer = den === 1 ? ce.number(num) : ce.number(num).div(ce.number(den));
|
|
38699
|
+
} else {
|
|
38700
|
+
const [aNum, aDen] = solution[t.unknownIndex];
|
|
38701
|
+
const [bNum, bDen] = solution[t.unknownIndex + 1];
|
|
38702
|
+
if (aNum === 0 && bNum === 0) continue;
|
|
38703
|
+
const terms = [];
|
|
38704
|
+
if (aNum !== 0) {
|
|
38705
|
+
const aCoeff = aDen === 1 ? ce.number(aNum) : ce.number(aNum).div(ce.number(aDen));
|
|
38706
|
+
terms.push(aCoeff.mul(x));
|
|
38707
|
+
}
|
|
38708
|
+
if (bNum !== 0) {
|
|
38709
|
+
const bCoeff = bDen === 1 ? ce.number(bNum) : ce.number(bNum).div(ce.number(bDen));
|
|
38710
|
+
terms.push(bCoeff);
|
|
38711
|
+
}
|
|
38712
|
+
termNumer = terms.length === 1 ? terms[0] : add3(...terms);
|
|
38713
|
+
}
|
|
38714
|
+
partialTerms.push(termNumer.div(termDenom));
|
|
38715
|
+
}
|
|
38716
|
+
if (partialTerms.length === 0) return ce.Zero;
|
|
38717
|
+
if (partialTerms.length === 1) return partialTerms[0];
|
|
38718
|
+
return add3(...partialTerms);
|
|
38719
|
+
}
|
|
38270
38720
|
|
|
38271
38721
|
// src/compute-engine/symbolic/distribute.ts
|
|
38272
38722
|
function distribute2(lhs, rhs, g, f) {
|
|
@@ -38341,7 +38791,7 @@ var POLYNOMIALS_LIBRARY = [
|
|
|
38341
38791
|
}
|
|
38342
38792
|
},
|
|
38343
38793
|
CoefficientList: {
|
|
38344
|
-
description: "Return the list of coefficients of a polynomial, from
|
|
38794
|
+
description: "Return the list of coefficients of a polynomial, from highest to lowest degree. Example: CoefficientList(x\xB3 + 2x + 1, x) \u2192 [1, 0, 2, 1]",
|
|
38345
38795
|
lazy: true,
|
|
38346
38796
|
signature: "(value, symbol) -> list<value>",
|
|
38347
38797
|
evaluate: ([poly, varExpr]) => {
|
|
@@ -38350,7 +38800,7 @@ var POLYNOMIALS_LIBRARY = [
|
|
|
38350
38800
|
if (!variable) return void 0;
|
|
38351
38801
|
const coeffs = getPolynomialCoefficients(poly.canonical, variable);
|
|
38352
38802
|
if (!coeffs) return void 0;
|
|
38353
|
-
return poly.engine.box(["List", ...coeffs]);
|
|
38803
|
+
return poly.engine.box(["List", ...coeffs.reverse()]);
|
|
38354
38804
|
}
|
|
38355
38805
|
},
|
|
38356
38806
|
PolynomialQuotient: {
|
|
@@ -38406,6 +38856,85 @@ var POLYNOMIALS_LIBRARY = [
|
|
|
38406
38856
|
if (!variable) return void 0;
|
|
38407
38857
|
return cancelCommonFactors(expr.canonical, variable);
|
|
38408
38858
|
}
|
|
38859
|
+
},
|
|
38860
|
+
PartialFraction: {
|
|
38861
|
+
description: "Decompose a rational expression into partial fractions. Example: PartialFraction(1/((x+1)(x+2)), x) \u2192 1/(x+1) - 1/(x+2)",
|
|
38862
|
+
lazy: true,
|
|
38863
|
+
signature: "(value, symbol) -> value",
|
|
38864
|
+
evaluate: ([expr, varExpr]) => {
|
|
38865
|
+
if (!expr || !varExpr) return void 0;
|
|
38866
|
+
const variable = sym(varExpr.canonical);
|
|
38867
|
+
if (!variable) return void 0;
|
|
38868
|
+
return partialFraction(expr.canonical, variable);
|
|
38869
|
+
}
|
|
38870
|
+
},
|
|
38871
|
+
Apart: {
|
|
38872
|
+
description: "Alias for PartialFraction. Decompose a rational expression into partial fractions.",
|
|
38873
|
+
lazy: true,
|
|
38874
|
+
signature: "(value, symbol) -> value",
|
|
38875
|
+
evaluate: ([expr, varExpr]) => {
|
|
38876
|
+
if (!expr || !varExpr) return void 0;
|
|
38877
|
+
const variable = sym(varExpr.canonical);
|
|
38878
|
+
if (!variable) return void 0;
|
|
38879
|
+
return partialFraction(expr.canonical, variable);
|
|
38880
|
+
}
|
|
38881
|
+
},
|
|
38882
|
+
PolynomialRoots: {
|
|
38883
|
+
description: "Return the roots of a polynomial expression. Example: PolynomialRoots(x\xB2 - 5x + 6, x) \u2192 {2, 3}",
|
|
38884
|
+
lazy: true,
|
|
38885
|
+
signature: "(value, symbol) -> set<value>",
|
|
38886
|
+
evaluate: ([poly, varExpr]) => {
|
|
38887
|
+
if (!poly || !varExpr) return void 0;
|
|
38888
|
+
const variable = sym(varExpr.canonical);
|
|
38889
|
+
if (!variable) return void 0;
|
|
38890
|
+
const roots = poly.canonical.polynomialRoots(variable);
|
|
38891
|
+
if (!roots || roots.length === 0) return void 0;
|
|
38892
|
+
return poly.engine.box(["Set", ...roots.map((r) => r.json)]);
|
|
38893
|
+
}
|
|
38894
|
+
},
|
|
38895
|
+
Discriminant: {
|
|
38896
|
+
description: "Return the discriminant of a polynomial. Example: Discriminant(x\xB2 - 5x + 6, x) \u2192 1",
|
|
38897
|
+
lazy: true,
|
|
38898
|
+
signature: "(value, symbol) -> value",
|
|
38899
|
+
evaluate: ([poly, varExpr]) => {
|
|
38900
|
+
if (!poly || !varExpr) return void 0;
|
|
38901
|
+
const variable = sym(varExpr.canonical);
|
|
38902
|
+
if (!variable) return void 0;
|
|
38903
|
+
const coeffsAsc = getPolynomialCoefficients(poly.canonical, variable);
|
|
38904
|
+
if (!coeffsAsc) return void 0;
|
|
38905
|
+
const coeffs = [...coeffsAsc].reverse();
|
|
38906
|
+
const degree = coeffs.length - 1;
|
|
38907
|
+
const ce = poly.engine;
|
|
38908
|
+
if (degree === 2) {
|
|
38909
|
+
const [a, b, c] = coeffs;
|
|
38910
|
+
return b.mul(b).sub(ce.number(4).mul(a).mul(c));
|
|
38911
|
+
}
|
|
38912
|
+
if (degree === 3) {
|
|
38913
|
+
const [a, b, c, d] = coeffs;
|
|
38914
|
+
return b.mul(b).mul(c).mul(c).sub(ce.number(4).mul(a).mul(c).mul(c).mul(c)).sub(ce.number(4).mul(b).mul(b).mul(b).mul(d)).add(ce.number(18).mul(a).mul(b).mul(c).mul(d)).sub(ce.number(27).mul(a).mul(a).mul(d).mul(d));
|
|
38915
|
+
}
|
|
38916
|
+
if (degree === 4) {
|
|
38917
|
+
const [a, b, c, d, e] = coeffs;
|
|
38918
|
+
return ce.number(256).mul(a).mul(a).mul(a).mul(e).mul(e).mul(e).sub(ce.number(192).mul(a).mul(a).mul(b).mul(d).mul(e).mul(e)).sub(ce.number(128).mul(a).mul(a).mul(c).mul(c).mul(e).mul(e)).add(ce.number(144).mul(a).mul(a).mul(c).mul(d).mul(d).mul(e)).sub(ce.number(27).mul(a).mul(a).mul(d).mul(d).mul(d).mul(d)).add(ce.number(144).mul(a).mul(b).mul(b).mul(c).mul(e).mul(e)).sub(ce.number(6).mul(a).mul(b).mul(b).mul(d).mul(d).mul(e)).sub(ce.number(80).mul(a).mul(b).mul(c).mul(c).mul(d).mul(e)).add(ce.number(18).mul(a).mul(b).mul(c).mul(d).mul(d).mul(d)).add(ce.number(16).mul(a).mul(c).mul(c).mul(c).mul(c).mul(e)).sub(ce.number(4).mul(a).mul(c).mul(c).mul(c).mul(d).mul(d)).sub(ce.number(27).mul(b).mul(b).mul(b).mul(b).mul(e).mul(e)).add(ce.number(18).mul(b).mul(b).mul(b).mul(c).mul(d).mul(e)).sub(ce.number(4).mul(b).mul(b).mul(b).mul(d).mul(d).mul(d)).sub(ce.number(4).mul(b).mul(b).mul(c).mul(c).mul(c).mul(e)).add(b.mul(b).mul(c).mul(c).mul(d).mul(d));
|
|
38919
|
+
}
|
|
38920
|
+
return void 0;
|
|
38921
|
+
}
|
|
38922
|
+
},
|
|
38923
|
+
Polynomial: {
|
|
38924
|
+
description: "Construct a polynomial from a list of coefficients (highest to lowest degree) and a variable. Example: Polynomial([1, 0, 2, 1], x) \u2192 x\xB3 + 2x + 1",
|
|
38925
|
+
lazy: true,
|
|
38926
|
+
signature: "(list<value>, symbol) -> value",
|
|
38927
|
+
evaluate: ([coeffList, varExpr]) => {
|
|
38928
|
+
if (!coeffList || !varExpr) return void 0;
|
|
38929
|
+
const variable = sym(varExpr.canonical);
|
|
38930
|
+
if (!variable) return void 0;
|
|
38931
|
+
const canonical2 = coeffList.canonical;
|
|
38932
|
+
if (!isFunction2(canonical2, "List")) return void 0;
|
|
38933
|
+
const coeffs = canonical2.ops;
|
|
38934
|
+
if (coeffs.length === 0) return void 0;
|
|
38935
|
+
const ascending = [...coeffs].reverse();
|
|
38936
|
+
return fromCoefficients(ascending, variable);
|
|
38937
|
+
}
|
|
38409
38938
|
}
|
|
38410
38939
|
}
|
|
38411
38940
|
];
|
|
@@ -46404,7 +46933,7 @@ function isLinearInVariables(expr, variables) {
|
|
|
46404
46933
|
};
|
|
46405
46934
|
return checkTerm(expr);
|
|
46406
46935
|
}
|
|
46407
|
-
function
|
|
46936
|
+
function solveLinearSystem2(equations, variables) {
|
|
46408
46937
|
if (equations.length === 0 || variables.length === 0) return null;
|
|
46409
46938
|
const ce = equations[0].engine;
|
|
46410
46939
|
const n = variables.length;
|
|
@@ -47389,6 +47918,15 @@ function matchOnce(expr, pattern, substitution, options) {
|
|
|
47389
47918
|
} else if (operator2 === expr.operator) {
|
|
47390
47919
|
const matchPerms = options.matchPermutations ?? true;
|
|
47391
47920
|
result = pattern.operatorDefinition.commutative && matchPerms ? matchPermutation(expr, pattern, substitution, options) : matchArguments(expr, pattern.ops, substitution, options);
|
|
47921
|
+
if (result === null && options.matchMissingTerms && isFunction2(expr) && isFunction2(pattern) && expr.nops < pattern.nops) {
|
|
47922
|
+
result = matchWithMissingTerms(
|
|
47923
|
+
expr,
|
|
47924
|
+
pattern,
|
|
47925
|
+
substitution,
|
|
47926
|
+
options,
|
|
47927
|
+
ce
|
|
47928
|
+
);
|
|
47929
|
+
}
|
|
47392
47930
|
}
|
|
47393
47931
|
if (result === null && useVariations) {
|
|
47394
47932
|
if (!acceptVariants) return null;
|
|
@@ -47686,8 +48224,8 @@ function matchCommutativeWithAnchors(expr, pattern, substitution, options) {
|
|
|
47686
48224
|
const minCapture = 1;
|
|
47687
48225
|
const maxCapture2 = remaining.length - countMinNeeded(restWildcards);
|
|
47688
48226
|
for (let count = maxCapture2; count >= minCapture; count--) {
|
|
47689
|
-
const
|
|
47690
|
-
for (const indices of
|
|
48227
|
+
const combinations2 = getCombinations(remaining.length, count);
|
|
48228
|
+
for (const indices of combinations2) {
|
|
47691
48229
|
const captured = indices.map((i) => remaining[i]);
|
|
47692
48230
|
const capturedExpr = wrapCaptured(captured);
|
|
47693
48231
|
const newSub = captureWildcard(wcName, capturedExpr, sub3);
|
|
@@ -47716,8 +48254,8 @@ function matchCommutativeWithAnchors(expr, pattern, substitution, options) {
|
|
|
47716
48254
|
if (result !== null) return result;
|
|
47717
48255
|
}
|
|
47718
48256
|
} else {
|
|
47719
|
-
const
|
|
47720
|
-
for (const indices of
|
|
48257
|
+
const combinations2 = getCombinations(remaining.length, count);
|
|
48258
|
+
for (const indices of combinations2) {
|
|
47721
48259
|
const captured = indices.map((i) => remaining[i]);
|
|
47722
48260
|
const capturedExpr = wrapCaptured(captured);
|
|
47723
48261
|
const newSub = captureWildcard(wcName, capturedExpr, sub3);
|
|
@@ -47891,17 +48429,140 @@ function matchArguments(expr, patterns, substitution, options) {
|
|
|
47891
48429
|
}
|
|
47892
48430
|
}
|
|
47893
48431
|
}
|
|
48432
|
+
function matchWithMissingTerms(expr, pattern, substitution, options, ce) {
|
|
48433
|
+
if (!isFunction2(expr) || !isFunction2(pattern)) return null;
|
|
48434
|
+
const operator2 = expr.operator;
|
|
48435
|
+
const identity = operator2 === "Add" ? ce.Zero : operator2 === "Multiply" ? ce.One : null;
|
|
48436
|
+
if (!identity) return null;
|
|
48437
|
+
const patOps = pattern.ops;
|
|
48438
|
+
const missing = patOps.length - expr.nops;
|
|
48439
|
+
if (missing <= 0) return null;
|
|
48440
|
+
const combos = combinations(patOps.length, missing);
|
|
48441
|
+
combos.sort((a, b) => {
|
|
48442
|
+
const scoreA = a.reduce((s, i) => s + patternComplexity(patOps[i]), 0);
|
|
48443
|
+
const scoreB = b.reduce((s, i) => s + patternComplexity(patOps[i]), 0);
|
|
48444
|
+
return scoreA - scoreB;
|
|
48445
|
+
});
|
|
48446
|
+
for (const identityIndices of combos) {
|
|
48447
|
+
const activePatOps = patOps.filter((_, i) => !identityIndices.includes(i));
|
|
48448
|
+
const identityPatOps = identityIndices.map((i) => patOps[i]);
|
|
48449
|
+
const subPattern = ce.function(operator2, activePatOps, { form: "raw" });
|
|
48450
|
+
let sub3 = matchPermutation(expr, subPattern, substitution, options);
|
|
48451
|
+
if (sub3 === null) continue;
|
|
48452
|
+
let failed = false;
|
|
48453
|
+
for (const patOp of identityPatOps) {
|
|
48454
|
+
const result = matchIdentityTerm(patOp, identity, sub3, options, ce);
|
|
48455
|
+
if (result === null) {
|
|
48456
|
+
failed = true;
|
|
48457
|
+
break;
|
|
48458
|
+
}
|
|
48459
|
+
sub3 = result;
|
|
48460
|
+
}
|
|
48461
|
+
if (!failed) return sub3;
|
|
48462
|
+
}
|
|
48463
|
+
return null;
|
|
48464
|
+
}
|
|
48465
|
+
function matchIdentityTerm(patOp, identity, sub3, options, ce) {
|
|
48466
|
+
const result = matchOnce(identity, patOp, sub3, options);
|
|
48467
|
+
if (result !== null) return result;
|
|
48468
|
+
if (identity.isSame(0) && isFunction2(patOp, "Multiply")) {
|
|
48469
|
+
for (const op of patOp.ops) {
|
|
48470
|
+
const wn = wildcardName(op);
|
|
48471
|
+
if (wn && !(wn in sub3)) {
|
|
48472
|
+
return captureWildcard(wn, identity, sub3);
|
|
48473
|
+
}
|
|
48474
|
+
}
|
|
48475
|
+
}
|
|
48476
|
+
if (identity.isSame(1) && isFunction2(patOp, "Power")) {
|
|
48477
|
+
const expOp = patOp.ops[1];
|
|
48478
|
+
if (expOp) {
|
|
48479
|
+
const wn = wildcardName(expOp);
|
|
48480
|
+
if (wn && !(wn in sub3)) {
|
|
48481
|
+
return captureWildcard(wn, ce.Zero, sub3);
|
|
48482
|
+
}
|
|
48483
|
+
}
|
|
48484
|
+
}
|
|
48485
|
+
return null;
|
|
48486
|
+
}
|
|
48487
|
+
function patternComplexity(expr) {
|
|
48488
|
+
if (isWildcard(expr)) return 0;
|
|
48489
|
+
if (isNumber(expr) || isSymbol2(expr) || isString(expr)) return 1;
|
|
48490
|
+
if (isFunction2(expr))
|
|
48491
|
+
return 1 + expr.ops.reduce((s, op) => s + patternComplexity(op), 0);
|
|
48492
|
+
return 1;
|
|
48493
|
+
}
|
|
48494
|
+
function combinations(n, k) {
|
|
48495
|
+
const result = [];
|
|
48496
|
+
const combo = [];
|
|
48497
|
+
function backtrack(start) {
|
|
48498
|
+
if (combo.length === k) {
|
|
48499
|
+
result.push([...combo]);
|
|
48500
|
+
return;
|
|
48501
|
+
}
|
|
48502
|
+
for (let i = start; i < n; i++) {
|
|
48503
|
+
combo.push(i);
|
|
48504
|
+
backtrack(i + 1);
|
|
48505
|
+
combo.pop();
|
|
48506
|
+
}
|
|
48507
|
+
}
|
|
48508
|
+
backtrack(0);
|
|
48509
|
+
return result;
|
|
48510
|
+
}
|
|
47894
48511
|
function match(subject, pattern, options) {
|
|
47895
|
-
|
|
47896
|
-
|
|
48512
|
+
const ce = subject.engine;
|
|
48513
|
+
let autoWildcard = false;
|
|
48514
|
+
let boxedPattern;
|
|
48515
|
+
if (typeof pattern === "string") {
|
|
48516
|
+
autoWildcard = true;
|
|
48517
|
+
boxedPattern = ce.parse(pattern).map(
|
|
48518
|
+
(x) => isSymbol2(x) && x.symbol.length === 1 ? ce.symbol("_" + x.symbol) : x,
|
|
48519
|
+
{ canonical: false }
|
|
48520
|
+
);
|
|
48521
|
+
} else if ("engine" in pattern) {
|
|
48522
|
+
boxedPattern = pattern;
|
|
48523
|
+
} else {
|
|
48524
|
+
boxedPattern = ce.box(pattern);
|
|
48525
|
+
}
|
|
48526
|
+
boxedPattern = boxedPattern.structural;
|
|
48527
|
+
const useVariations = options?.useVariations ?? autoWildcard;
|
|
47897
48528
|
const opts = {
|
|
47898
48529
|
recursive: options?.recursive ?? false,
|
|
47899
48530
|
useVariations,
|
|
47900
48531
|
acceptVariants: useVariations,
|
|
47901
|
-
matchPermutations: options?.matchPermutations ?? true
|
|
48532
|
+
matchPermutations: options?.matchPermutations ?? true,
|
|
48533
|
+
matchMissingTerms: options?.matchMissingTerms ?? autoWildcard
|
|
47902
48534
|
};
|
|
47903
|
-
|
|
47904
|
-
|
|
48535
|
+
let substitution = options?.substitution ?? {};
|
|
48536
|
+
if (autoWildcard && Object.keys(substitution).length > 0) {
|
|
48537
|
+
const prefixed = {};
|
|
48538
|
+
for (const [k, v] of Object.entries(substitution)) {
|
|
48539
|
+
if (k.startsWith("_")) {
|
|
48540
|
+
prefixed[k] = v;
|
|
48541
|
+
} else {
|
|
48542
|
+
if (!(`_${k}` in substitution)) prefixed[`_${k}`] = v;
|
|
48543
|
+
prefixed[k] = v;
|
|
48544
|
+
}
|
|
48545
|
+
}
|
|
48546
|
+
substitution = prefixed;
|
|
48547
|
+
}
|
|
48548
|
+
const result = matchOnce(
|
|
48549
|
+
subject.structural,
|
|
48550
|
+
boxedPattern.structural,
|
|
48551
|
+
substitution,
|
|
48552
|
+
opts
|
|
48553
|
+
);
|
|
48554
|
+
if (!result) return null;
|
|
48555
|
+
if (autoWildcard) {
|
|
48556
|
+
const clean = {};
|
|
48557
|
+
for (const [k, v] of Object.entries(result)) {
|
|
48558
|
+
if (!k.startsWith("_")) continue;
|
|
48559
|
+
const name = k.slice(1);
|
|
48560
|
+
if (isSymbol2(v) && v.symbol === name) continue;
|
|
48561
|
+
clean[name] = v;
|
|
48562
|
+
}
|
|
48563
|
+
return clean;
|
|
48564
|
+
}
|
|
48565
|
+
return result;
|
|
47905
48566
|
}
|
|
47906
48567
|
|
|
47907
48568
|
// src/compute-engine/boxed-expression/sgn.ts
|
|
@@ -48757,7 +49418,7 @@ var BoxedFunction = class extends _BoxedExpression {
|
|
|
48757
49418
|
};
|
|
48758
49419
|
function solveSystem(ce, equations, varNames) {
|
|
48759
49420
|
if (equations && equations.every((eq2) => eq2.operator === "Equal")) {
|
|
48760
|
-
const linearResult =
|
|
49421
|
+
const linearResult = solveLinearSystem2([...equations], varNames);
|
|
48761
49422
|
if (linearResult && filterSolutionByTypes(ce, varNames, linearResult))
|
|
48762
49423
|
return linearResult;
|
|
48763
49424
|
const polyResult = solvePolynomialSystem([...equations], varNames);
|
|
@@ -48787,7 +49448,7 @@ function solveSystem(ce, equations, varNames) {
|
|
|
48787
49448
|
(eq2) => inequalityOps.includes(eq2.operator ?? "")
|
|
48788
49449
|
);
|
|
48789
49450
|
if (equalities.length > 0 && inequalities.length > 0 && equalities.length + inequalities.length === equations.length) {
|
|
48790
|
-
const linearResult =
|
|
49451
|
+
const linearResult = solveLinearSystem2([...equalities], varNames);
|
|
48791
49452
|
if (linearResult) {
|
|
48792
49453
|
if (satisfiesInequalities(linearResult, inequalities))
|
|
48793
49454
|
return filterSolutionByTypes(ce, varNames, linearResult) ? linearResult : null;
|
|
@@ -50428,11 +51089,7 @@ var BaseCompiler = class _BaseCompiler {
|
|
|
50428
51089
|
if (h === "Function") {
|
|
50429
51090
|
const fnFn = target.functions?.(h);
|
|
50430
51091
|
if (typeof fnFn === "function")
|
|
50431
|
-
return fnFn(
|
|
50432
|
-
args,
|
|
50433
|
-
(expr) => _BaseCompiler.compile(expr, target),
|
|
50434
|
-
target
|
|
50435
|
-
);
|
|
51092
|
+
return fnFn(args, (expr) => _BaseCompiler.compile(expr, target), target);
|
|
50436
51093
|
const params = args.slice(1).map((x) => isSymbol2(x) ? x.symbol : "_");
|
|
50437
51094
|
return `((${params.join(", ")}) => ${_BaseCompiler.compile(
|
|
50438
51095
|
args[0].canonical,
|
|
@@ -50561,7 +51218,10 @@ var BaseCompiler = class _BaseCompiler {
|
|
|
50561
51218
|
};
|
|
50562
51219
|
const result = args.filter((a) => !isSymbol2(a, "Nothing")).map((arg) => {
|
|
50563
51220
|
if (isFunction2(arg, "Declare") && isSymbol2(arg.ops[0]) && target.declare) {
|
|
50564
|
-
return target.declare(
|
|
51221
|
+
return target.declare(
|
|
51222
|
+
arg.ops[0].symbol,
|
|
51223
|
+
typeHints[arg.ops[0].symbol]
|
|
51224
|
+
);
|
|
50565
51225
|
}
|
|
50566
51226
|
return _BaseCompiler.compile(arg, localTarget);
|
|
50567
51227
|
}).filter((s) => s !== "");
|
|
@@ -51052,6 +51712,9 @@ _setExpandForIs(expand2);
|
|
|
51052
51712
|
_setSerializeJson(serializeJson);
|
|
51053
51713
|
_setProduct(Product);
|
|
51054
51714
|
_setCompile(compile);
|
|
51715
|
+
_setGetPolynomialCoefficients(getPolynomialCoefficients);
|
|
51716
|
+
_setGetPolynomialDegree(polynomialDegree);
|
|
51717
|
+
_setFindUnivariateRoots(findUnivariateRoots);
|
|
51055
51718
|
|
|
51056
51719
|
// src/compute-engine/symbolic/simplify-logic.ts
|
|
51057
51720
|
function simplifyLogicFunction(x) {
|
|
@@ -53990,6 +54653,27 @@ var SIMPLIFY_RULES = [
|
|
|
53990
54653
|
if (result.isSame(x)) return void 0;
|
|
53991
54654
|
return { value: result, because: "cancel common polynomial factors" };
|
|
53992
54655
|
},
|
|
54656
|
+
//
|
|
54657
|
+
// Auto partial fraction decomposition for Divide with factored denominator
|
|
54658
|
+
// e.g., 1/((x+1)(x+2)) → 1/(x+1) - 1/(x+2)
|
|
54659
|
+
// Only triggers when denominator is already in factored form (Multiply or Power)
|
|
54660
|
+
//
|
|
54661
|
+
// IMPORTANT: partialFraction must not call .simplify() on its result
|
|
54662
|
+
//
|
|
54663
|
+
(x) => {
|
|
54664
|
+
if (!isFunction2(x, "Divide")) return void 0;
|
|
54665
|
+
const denom = x.op2;
|
|
54666
|
+
const denomOp = denom.operator;
|
|
54667
|
+
if (denomOp !== "Multiply" && denomOp !== "Power") return void 0;
|
|
54668
|
+
const unknowns = x.unknowns;
|
|
54669
|
+
if (unknowns.length !== 1) return void 0;
|
|
54670
|
+
const variable = unknowns[0];
|
|
54671
|
+
const result = partialFraction(x, variable);
|
|
54672
|
+
if (result.isSame(x)) return void 0;
|
|
54673
|
+
const ce = x.engine;
|
|
54674
|
+
if (ce.costFunction(result) >= ce.costFunction(x)) return void 0;
|
|
54675
|
+
return { value: result, because: "partial fraction decomposition" };
|
|
54676
|
+
},
|
|
53993
54677
|
// Quick a/a -> 1 check for identical numerator/denominator
|
|
53994
54678
|
// Must run before expand to avoid decomposing the fraction first
|
|
53995
54679
|
(x) => {
|
|
@@ -57754,7 +58438,8 @@ var GPU_FUNCTIONS = {
|
|
|
57754
58438
|
return `_gpu_fresnelS(${compile3(x)})`;
|
|
57755
58439
|
},
|
|
57756
58440
|
BesselJ: ([n, x], compile3, target) => {
|
|
57757
|
-
if (n === null || x === null)
|
|
58441
|
+
if (n === null || x === null)
|
|
58442
|
+
throw new Error("BesselJ: need two arguments");
|
|
57758
58443
|
const intCast = target?.language === "wgsl" ? "i32" : "int";
|
|
57759
58444
|
return `_gpu_besselJ(${intCast}(${compile3(n)}), ${compile3(x)})`;
|
|
57760
58445
|
},
|
|
@@ -57856,8 +58541,7 @@ var GPU_FUNCTIONS = {
|
|
|
57856
58541
|
throw new Error("Loop: expected Element(index, Range(lo, hi))");
|
|
57857
58542
|
const indexExpr = indexing.ops[0];
|
|
57858
58543
|
const rangeExpr = indexing.ops[1];
|
|
57859
|
-
if (!isSymbol2(indexExpr))
|
|
57860
|
-
throw new Error("Loop: index must be a symbol");
|
|
58544
|
+
if (!isSymbol2(indexExpr)) throw new Error("Loop: index must be a symbol");
|
|
57861
58545
|
if (!isFunction2(rangeExpr, "Range"))
|
|
57862
58546
|
throw new Error("Loop: expected Range(lo, hi)");
|
|
57863
58547
|
const index = indexExpr.symbol;
|
|
@@ -59109,7 +59793,9 @@ var WGSLTarget = class extends GPUShaderTarget {
|
|
|
59109
59793
|
const params = parameters.map(([name, type2]) => `${name}: ${toWGSLType(type2)}`).join(", ");
|
|
59110
59794
|
if (body.includes("\n")) {
|
|
59111
59795
|
const indented = body.split("\n").map((l) => ` ${l}`).join("\n");
|
|
59112
|
-
return `fn ${functionName}(${params}) -> ${toWGSLType(
|
|
59796
|
+
return `fn ${functionName}(${params}) -> ${toWGSLType(
|
|
59797
|
+
returnType
|
|
59798
|
+
)} {
|
|
59113
59799
|
${indented};
|
|
59114
59800
|
}`;
|
|
59115
59801
|
}
|
|
@@ -59757,7 +60443,7 @@ function binomial2(n, k) {
|
|
|
59757
60443
|
];
|
|
59758
60444
|
return ok({ lo: Math.min(...vals), hi: Math.max(...vals) });
|
|
59759
60445
|
}
|
|
59760
|
-
function
|
|
60446
|
+
function gcd5(a, b) {
|
|
59761
60447
|
const uA = unwrapOrPropagate(a);
|
|
59762
60448
|
if (!Array.isArray(uA)) return uA;
|
|
59763
60449
|
const uB = unwrapOrPropagate(b);
|
|
@@ -60409,7 +61095,7 @@ var IntervalArithmetic = {
|
|
|
60409
61095
|
factorial: factorial5,
|
|
60410
61096
|
factorial2: factorial24,
|
|
60411
61097
|
binomial: binomial2,
|
|
60412
|
-
gcd:
|
|
61098
|
+
gcd: gcd5,
|
|
60413
61099
|
lcm: lcm4,
|
|
60414
61100
|
chop: chop4,
|
|
60415
61101
|
erf: erf2,
|
|
@@ -64188,6 +64874,11 @@ var _Parser = class __Parser {
|
|
|
64188
64874
|
if (this.atEnd) return lhs;
|
|
64189
64875
|
console.assert(lhs !== null);
|
|
64190
64876
|
const index = this.index;
|
|
64877
|
+
if (this.options.strict === false && typeof lhs === "string" && lhs.length === 1 && /^[a-zA-Z]$/.test(lhs) && /^[2-9]$/.test(this.peek)) {
|
|
64878
|
+
const digit = parseInt(this.peek);
|
|
64879
|
+
this.index++;
|
|
64880
|
+
return this.parseSupsub(["Power", lhs, digit]);
|
|
64881
|
+
}
|
|
64191
64882
|
this.skipSpace();
|
|
64192
64883
|
const superscripts = [];
|
|
64193
64884
|
const subscripts = [];
|
|
@@ -66292,9 +66983,9 @@ function TR12i(expr) {
|
|
|
66292
66983
|
return ce._fn("Tan", [tanCArg]).neg();
|
|
66293
66984
|
}
|
|
66294
66985
|
function lcm5(a, b) {
|
|
66295
|
-
return Math.abs(a * b) /
|
|
66986
|
+
return Math.abs(a * b) / gcd6(a, b);
|
|
66296
66987
|
}
|
|
66297
|
-
function
|
|
66988
|
+
function gcd6(a, b) {
|
|
66298
66989
|
a = Math.abs(a);
|
|
66299
66990
|
b = Math.abs(b);
|
|
66300
66991
|
while (b) {
|
|
@@ -67980,10 +68671,10 @@ var ComputeEngine = class _ComputeEngine {
|
|
|
67980
68671
|
_setComputeEngineClass(ComputeEngine);
|
|
67981
68672
|
|
|
67982
68673
|
// src/compute-engine.ts
|
|
67983
|
-
var version = "0.
|
|
68674
|
+
var version = "0.54.0";
|
|
67984
68675
|
globalThis[/* @__PURE__ */ Symbol.for("io.cortexjs.compute-engine")] = {
|
|
67985
68676
|
ComputeEngine: ComputeEngine.prototype.constructor,
|
|
67986
|
-
version: "0.
|
|
68677
|
+
version: "0.54.0"
|
|
67987
68678
|
};
|
|
67988
68679
|
export {
|
|
67989
68680
|
BaseCompiler,
|