@cortex-js/compute-engine 0.53.0 → 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 +1684 -333
- package/dist/compute-engine.min.esm.js +527 -55
- package/dist/compute-engine.min.umd.cjs +1035 -0
- package/dist/{compute-engine.umd.js → compute-engine.umd.cjs} +1684 -333
- package/dist/math-json.esm.js +2 -2
- package/dist/math-json.min.esm.js +2 -2
- package/dist/{math-json.min.umd.js → math-json.min.umd.cjs} +2 -2
- package/dist/{math-json.umd.js → 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 +68 -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 +9 -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 +2 -2
- 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 +3 -3
- package/dist/compute-engine.min.umd.js +0 -563
|
@@ -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) {
|
|
@@ -11083,7 +11083,7 @@ function parseWhereExpression(parser, lhs, until) {
|
|
|
11083
11083
|
condition: (p) => {
|
|
11084
11084
|
if (until?.condition?.(p)) return true;
|
|
11085
11085
|
const saved = p.index;
|
|
11086
|
-
p.
|
|
11086
|
+
p.skipVisualSpace();
|
|
11087
11087
|
const isComma = p.peek === ",";
|
|
11088
11088
|
p.index = saved;
|
|
11089
11089
|
return isComma;
|
|
@@ -11091,11 +11091,11 @@ function parseWhereExpression(parser, lhs, until) {
|
|
|
11091
11091
|
};
|
|
11092
11092
|
const bindings = [];
|
|
11093
11093
|
do {
|
|
11094
|
-
parser.
|
|
11094
|
+
parser.skipVisualSpace();
|
|
11095
11095
|
const binding = parser.parseExpression(bindingTerminator);
|
|
11096
11096
|
if (!binding) break;
|
|
11097
11097
|
bindings.push(binding);
|
|
11098
|
-
parser.
|
|
11098
|
+
parser.skipVisualSpace();
|
|
11099
11099
|
} while (parser.match(","));
|
|
11100
11100
|
if (bindings.length === 0) return null;
|
|
11101
11101
|
const block = [];
|
|
@@ -11594,14 +11594,11 @@ function* factorial3(n) {
|
|
|
11594
11594
|
let loop = n;
|
|
11595
11595
|
let sum2 = n;
|
|
11596
11596
|
let val = n;
|
|
11597
|
-
let counter = 0;
|
|
11598
11597
|
while (loop > 2) {
|
|
11599
11598
|
loop -= BigInt(2);
|
|
11600
11599
|
sum2 += loop;
|
|
11601
11600
|
val *= sum2;
|
|
11602
|
-
|
|
11603
|
-
if (counter % 5e4 === 0 || counter > 1e4 && counter % 500 === 0)
|
|
11604
|
-
yield val;
|
|
11601
|
+
yield val;
|
|
11605
11602
|
}
|
|
11606
11603
|
return val;
|
|
11607
11604
|
}
|
|
@@ -12293,6 +12290,18 @@ var _expandForIs;
|
|
|
12293
12290
|
function _setExpandForIs(fn) {
|
|
12294
12291
|
_expandForIs = fn;
|
|
12295
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
|
+
}
|
|
12296
12305
|
var EXPANDABLE_OPS = ["Multiply", "Power", "Negate", "Divide"];
|
|
12297
12306
|
function _couldBenefitFromExpand(a, b) {
|
|
12298
12307
|
if (a.has(EXPANDABLE_OPS)) return true;
|
|
@@ -12608,6 +12617,34 @@ var _BoxedExpression = class __BoxedExpression {
|
|
|
12608
12617
|
factors() {
|
|
12609
12618
|
return [this];
|
|
12610
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
|
+
}
|
|
12611
12648
|
is(other, tolerance) {
|
|
12612
12649
|
if (this.isSame(other)) return true;
|
|
12613
12650
|
if (_expandForIs && _couldBenefitFromExpand(this, other)) {
|
|
@@ -16067,10 +16104,14 @@ function isSqrt(expr) {
|
|
|
16067
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;
|
|
16068
16105
|
}
|
|
16069
16106
|
function asRadical(expr) {
|
|
16070
|
-
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
|
+
}
|
|
16071
16112
|
if (isFunction2(expr, "Divide") && expr.op1.isSame(1) && isSqrt(expr.op2)) {
|
|
16072
16113
|
const n = expr.op2.re;
|
|
16073
|
-
if (!Number.isInteger(n)) return null;
|
|
16114
|
+
if (!Number.isInteger(n) || n <= 0) return null;
|
|
16074
16115
|
return [1, n];
|
|
16075
16116
|
}
|
|
16076
16117
|
return null;
|
|
@@ -16670,13 +16711,14 @@ function gcd3(a, b) {
|
|
|
16670
16711
|
function lcm3(a, b) {
|
|
16671
16712
|
return a.mul(b).div(gcd3(a, b));
|
|
16672
16713
|
}
|
|
16673
|
-
function factorial23(ce, n) {
|
|
16714
|
+
function* factorial23(ce, n) {
|
|
16674
16715
|
if (!n.isInteger() || n.isNegative()) return ce._BIGNUM_NAN;
|
|
16675
16716
|
if (n.lessThan(1)) return ce._BIGNUM_ONE;
|
|
16676
16717
|
let result = n;
|
|
16677
16718
|
while (n.greaterThan(2)) {
|
|
16678
16719
|
n = n.minus(2);
|
|
16679
16720
|
result = result.mul(n);
|
|
16721
|
+
yield result;
|
|
16680
16722
|
}
|
|
16681
16723
|
return result;
|
|
16682
16724
|
}
|
|
@@ -20193,24 +20235,30 @@ var COLLECTIONS_LIBRARY = {
|
|
|
20193
20235
|
if (initial.type.matches("real") && collection.type.matches(ce.type("collection<real>"))) {
|
|
20194
20236
|
const compiled = ce._compile(fn);
|
|
20195
20237
|
if (compiled.calling !== "lambda" || !compiled.run) return void 0;
|
|
20196
|
-
|
|
20197
|
-
|
|
20198
|
-
|
|
20199
|
-
|
|
20200
|
-
|
|
20201
|
-
|
|
20202
|
-
|
|
20203
|
-
|
|
20238
|
+
return run(
|
|
20239
|
+
(function* () {
|
|
20240
|
+
let accumulator = initial.re;
|
|
20241
|
+
let first = true;
|
|
20242
|
+
for (const item of collection.each()) {
|
|
20243
|
+
if (first) accumulator = item.re;
|
|
20244
|
+
else accumulator = compiled.run(accumulator, item.re);
|
|
20245
|
+
first = false;
|
|
20246
|
+
yield;
|
|
20247
|
+
}
|
|
20248
|
+
return ce.box(accumulator);
|
|
20249
|
+
})(),
|
|
20250
|
+
ce._timeRemaining
|
|
20251
|
+
);
|
|
20204
20252
|
}
|
|
20205
20253
|
const f = applicable(fn);
|
|
20206
|
-
|
|
20207
|
-
|
|
20208
|
-
|
|
20209
|
-
|
|
20210
|
-
|
|
20211
|
-
|
|
20212
|
-
|
|
20213
|
-
|
|
20254
|
+
return run(
|
|
20255
|
+
reduceCollection(
|
|
20256
|
+
collection,
|
|
20257
|
+
(acc, x) => f([acc, x]) ?? ce.Nothing,
|
|
20258
|
+
initial
|
|
20259
|
+
),
|
|
20260
|
+
ce._timeRemaining
|
|
20261
|
+
);
|
|
20214
20262
|
}
|
|
20215
20263
|
},
|
|
20216
20264
|
Join: {
|
|
@@ -21435,12 +21483,10 @@ function tally(collection) {
|
|
|
21435
21483
|
}
|
|
21436
21484
|
function* reduceCollection(collection, fn, initial) {
|
|
21437
21485
|
let acc = initial;
|
|
21438
|
-
let counter = 0;
|
|
21439
21486
|
for (const x of collection.each()) {
|
|
21440
21487
|
const result = fn(acc, x);
|
|
21441
21488
|
if (result === null) return void 0;
|
|
21442
|
-
|
|
21443
|
-
if (counter % 1e3 === 0) yield acc;
|
|
21489
|
+
yield acc;
|
|
21444
21490
|
acc = result;
|
|
21445
21491
|
}
|
|
21446
21492
|
return acc;
|
|
@@ -22859,12 +22905,10 @@ function* reduceBigOp(body, indexes, fn, initial) {
|
|
|
22859
22905
|
const indexingSets = normalizeIndexingSets(indexes);
|
|
22860
22906
|
const cartesianArray = indexingSetCartesianProduct(indexingSets);
|
|
22861
22907
|
let result = initial;
|
|
22862
|
-
let counter = 0;
|
|
22863
22908
|
for (const element of cartesianArray) {
|
|
22864
22909
|
indexingSets.forEach((x, i) => ce.assign(x.index, element[i]));
|
|
22865
22910
|
result = fn(result, body) ?? void 0;
|
|
22866
|
-
|
|
22867
|
-
if (counter % 1e3 === 0) yield result;
|
|
22911
|
+
yield result;
|
|
22868
22912
|
if (result === void 0) break;
|
|
22869
22913
|
}
|
|
22870
22914
|
return result ?? void 0;
|
|
@@ -22931,7 +22975,6 @@ function* reduceElementIndexingSets(body, indexes, fn, initial, returnReason = f
|
|
|
22931
22975
|
return initial;
|
|
22932
22976
|
}
|
|
22933
22977
|
let result = initial;
|
|
22934
|
-
let counter = 0;
|
|
22935
22978
|
while (true) {
|
|
22936
22979
|
for (let i = 0; i < elementDomains.length; i++) {
|
|
22937
22980
|
ce.assign(
|
|
@@ -22940,8 +22983,7 @@ function* reduceElementIndexingSets(body, indexes, fn, initial, returnReason = f
|
|
|
22940
22983
|
);
|
|
22941
22984
|
}
|
|
22942
22985
|
result = fn(result, body) ?? void 0;
|
|
22943
|
-
|
|
22944
|
-
if (counter % 1e3 === 0) yield result;
|
|
22986
|
+
yield result;
|
|
22945
22987
|
if (result === void 0) break;
|
|
22946
22988
|
let dim = elementDomains.length - 1;
|
|
22947
22989
|
while (dim >= 0) {
|
|
@@ -23911,7 +23953,8 @@ var ARITHMETIC_LIBRARY = [
|
|
|
23911
23953
|
ce._timeRemaining
|
|
23912
23954
|
)
|
|
23913
23955
|
);
|
|
23914
|
-
} catch {
|
|
23956
|
+
} catch (e) {
|
|
23957
|
+
if (e instanceof CancellationError) throw e;
|
|
23915
23958
|
return void 0;
|
|
23916
23959
|
}
|
|
23917
23960
|
},
|
|
@@ -23930,7 +23973,8 @@ var ARITHMETIC_LIBRARY = [
|
|
|
23930
23973
|
signal
|
|
23931
23974
|
)
|
|
23932
23975
|
);
|
|
23933
|
-
} catch {
|
|
23976
|
+
} catch (e) {
|
|
23977
|
+
if (e instanceof CancellationError) throw e;
|
|
23934
23978
|
return void 0;
|
|
23935
23979
|
}
|
|
23936
23980
|
}
|
|
@@ -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
|
-
}
|
|
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);
|
|
27505
27669
|
}
|
|
27506
|
-
|
|
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;
|
|
27572
|
-
}
|
|
27573
|
-
return newNumerator.div(newDenominator);
|
|
27670
|
+
return roots;
|
|
27574
27671
|
}
|
|
27575
27672
|
|
|
27576
27673
|
// src/compute-engine/symbolic/antiderivative.ts
|
|
@@ -33539,7 +33636,7 @@ function* runLoop(body, collection, ce) {
|
|
|
33539
33636
|
if (isFunction2(result, "Break")) return result.op1;
|
|
33540
33637
|
if (result.operator === "Return") return result;
|
|
33541
33638
|
i2 += 1;
|
|
33542
|
-
|
|
33639
|
+
yield result;
|
|
33543
33640
|
if (i2 > ce.iterationLimit)
|
|
33544
33641
|
throw new CancellationError({ cause: "iteration-limit-exceeded" });
|
|
33545
33642
|
}
|
|
@@ -33551,7 +33648,7 @@ function* runLoop(body, collection, ce) {
|
|
|
33551
33648
|
if (isFunction2(result, "Break")) return result.op1;
|
|
33552
33649
|
if (result.operator === "Return") return result;
|
|
33553
33650
|
i += 1;
|
|
33554
|
-
|
|
33651
|
+
yield result;
|
|
33555
33652
|
if (i > ce.iterationLimit)
|
|
33556
33653
|
throw new CancellationError({ cause: "iteration-limit-exceeded" });
|
|
33557
33654
|
}
|
|
@@ -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;
|
|
@@ -48911,9 +49572,11 @@ function withDeadline(engine, fn) {
|
|
|
48911
49572
|
return () => {
|
|
48912
49573
|
if (engine._deadline === void 0) {
|
|
48913
49574
|
engine._deadline = Date.now() + engine.timeLimit;
|
|
48914
|
-
|
|
48915
|
-
|
|
48916
|
-
|
|
49575
|
+
try {
|
|
49576
|
+
return fn();
|
|
49577
|
+
} finally {
|
|
49578
|
+
engine._deadline = void 0;
|
|
49579
|
+
}
|
|
48917
49580
|
}
|
|
48918
49581
|
return fn();
|
|
48919
49582
|
};
|
|
@@ -48922,9 +49585,11 @@ function withDeadlineAsync(engine, fn) {
|
|
|
48922
49585
|
return async () => {
|
|
48923
49586
|
if (engine._deadline === void 0) {
|
|
48924
49587
|
engine._deadline = Date.now() + engine.timeLimit;
|
|
48925
|
-
|
|
48926
|
-
|
|
48927
|
-
|
|
49588
|
+
try {
|
|
49589
|
+
return await fn();
|
|
49590
|
+
} finally {
|
|
49591
|
+
engine._deadline = void 0;
|
|
49592
|
+
}
|
|
48928
49593
|
}
|
|
48929
49594
|
return fn();
|
|
48930
49595
|
};
|
|
@@ -50422,6 +51087,9 @@ var BaseCompiler = class _BaseCompiler {
|
|
|
50422
51087
|
}
|
|
50423
51088
|
}
|
|
50424
51089
|
if (h === "Function") {
|
|
51090
|
+
const fnFn = target.functions?.(h);
|
|
51091
|
+
if (typeof fnFn === "function")
|
|
51092
|
+
return fnFn(args, (expr) => _BaseCompiler.compile(expr, target), target);
|
|
50425
51093
|
const params = args.slice(1).map((x) => isSymbol2(x) ? x.symbol : "_");
|
|
50426
51094
|
return `((${params.join(", ")}) => ${_BaseCompiler.compile(
|
|
50427
51095
|
args[0].canonical,
|
|
@@ -50431,15 +51099,26 @@ var BaseCompiler = class _BaseCompiler {
|
|
|
50431
51099
|
}
|
|
50432
51100
|
)})`;
|
|
50433
51101
|
}
|
|
50434
|
-
if (h === "Declare")
|
|
50435
|
-
|
|
51102
|
+
if (h === "Declare") {
|
|
51103
|
+
const name = isSymbol2(args[0]) ? args[0].symbol : "_";
|
|
51104
|
+
return target.declare ? target.declare(name) : `let ${name}`;
|
|
51105
|
+
}
|
|
50436
51106
|
if (h === "Assign")
|
|
50437
51107
|
return `${isSymbol2(args[0]) ? args[0].symbol : "_"} = ${_BaseCompiler.compile(args[1], target)}`;
|
|
50438
51108
|
if (h === "Return")
|
|
50439
51109
|
return `return ${_BaseCompiler.compile(args[0], target)}`;
|
|
50440
51110
|
if (h === "Break") return "break";
|
|
50441
51111
|
if (h === "Continue") return "continue";
|
|
50442
|
-
if (h === "Loop")
|
|
51112
|
+
if (h === "Loop") {
|
|
51113
|
+
const loopFn = target.functions?.(h);
|
|
51114
|
+
if (typeof loopFn === "function")
|
|
51115
|
+
return loopFn(
|
|
51116
|
+
args,
|
|
51117
|
+
(expr) => _BaseCompiler.compile(expr, target),
|
|
51118
|
+
target
|
|
51119
|
+
);
|
|
51120
|
+
return _BaseCompiler.compileForLoop(args, target);
|
|
51121
|
+
}
|
|
50443
51122
|
if (h === "If") {
|
|
50444
51123
|
if (args.length !== 3) throw new Error("If: wrong number of arguments");
|
|
50445
51124
|
const fn2 = target.functions?.(h);
|
|
@@ -50516,16 +51195,38 @@ var BaseCompiler = class _BaseCompiler {
|
|
|
50516
51195
|
if (args.length === 1 && locals.length === 0) {
|
|
50517
51196
|
return _BaseCompiler.compile(args[0], target);
|
|
50518
51197
|
}
|
|
50519
|
-
const
|
|
50520
|
-
|
|
50521
|
-
|
|
50522
|
-
|
|
50523
|
-
|
|
50524
|
-
|
|
51198
|
+
const typeHints = {};
|
|
51199
|
+
if (target.declare && target.language) {
|
|
51200
|
+
const isWGSL = target.language === "wgsl";
|
|
51201
|
+
for (const local of locals) {
|
|
51202
|
+
for (const arg of args) {
|
|
51203
|
+
if (isFunction2(arg, "Assign") && isSymbol2(arg.ops[0], local)) {
|
|
51204
|
+
if (_BaseCompiler.isComplexValued(arg.ops[1])) {
|
|
51205
|
+
typeHints[local] = isWGSL ? "vec2f" : "vec2";
|
|
51206
|
+
}
|
|
51207
|
+
break;
|
|
51208
|
+
}
|
|
50525
51209
|
}
|
|
50526
|
-
}
|
|
50527
|
-
|
|
51210
|
+
}
|
|
51211
|
+
}
|
|
51212
|
+
const localTarget = {
|
|
51213
|
+
...target,
|
|
51214
|
+
var: (id) => {
|
|
51215
|
+
if (locals.includes(id)) return id;
|
|
51216
|
+
return target.var(id);
|
|
51217
|
+
}
|
|
51218
|
+
};
|
|
51219
|
+
const result = args.filter((a) => !isSymbol2(a, "Nothing")).map((arg) => {
|
|
51220
|
+
if (isFunction2(arg, "Declare") && isSymbol2(arg.ops[0]) && target.declare) {
|
|
51221
|
+
return target.declare(
|
|
51222
|
+
arg.ops[0].symbol,
|
|
51223
|
+
typeHints[arg.ops[0].symbol]
|
|
51224
|
+
);
|
|
51225
|
+
}
|
|
51226
|
+
return _BaseCompiler.compile(arg, localTarget);
|
|
51227
|
+
}).filter((s) => s !== "");
|
|
50528
51228
|
if (result.length === 0) return "";
|
|
51229
|
+
if (target.block) return target.block(result);
|
|
50529
51230
|
result[result.length - 1] = `return ${result[result.length - 1]}`;
|
|
50530
51231
|
return `(() => {${target.ws("\n")}${result.join(
|
|
50531
51232
|
`;${target.ws("\n")}`
|
|
@@ -51011,6 +51712,9 @@ _setExpandForIs(expand2);
|
|
|
51011
51712
|
_setSerializeJson(serializeJson);
|
|
51012
51713
|
_setProduct(Product);
|
|
51013
51714
|
_setCompile(compile);
|
|
51715
|
+
_setGetPolynomialCoefficients(getPolynomialCoefficients);
|
|
51716
|
+
_setGetPolynomialDegree(polynomialDegree);
|
|
51717
|
+
_setFindUnivariateRoots(findUnivariateRoots);
|
|
51014
51718
|
|
|
51015
51719
|
// src/compute-engine/symbolic/simplify-logic.ts
|
|
51016
51720
|
function simplifyLogicFunction(x) {
|
|
@@ -53949,6 +54653,27 @@ var SIMPLIFY_RULES = [
|
|
|
53949
54653
|
if (result.isSame(x)) return void 0;
|
|
53950
54654
|
return { value: result, because: "cancel common polynomial factors" };
|
|
53951
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
|
+
},
|
|
53952
54677
|
// Quick a/a -> 1 check for identical numerator/denominator
|
|
53953
54678
|
// Must run before expand to avoid decomposing the fraction first
|
|
53954
54679
|
(x) => {
|
|
@@ -57291,6 +58016,62 @@ var GPU_OPERATORS = {
|
|
|
57291
58016
|
function gpuVec2(target) {
|
|
57292
58017
|
return target?.language === "wgsl" ? "vec2f" : "vec2";
|
|
57293
58018
|
}
|
|
58019
|
+
var GPU_UNROLL_LIMIT = 100;
|
|
58020
|
+
function compileGPUSumProduct(kind, args, _compile2, target) {
|
|
58021
|
+
if (!args[0]) throw new Error(`${kind}: no body`);
|
|
58022
|
+
if (!args[1]) throw new Error(`${kind}: no indexing set`);
|
|
58023
|
+
if (BaseCompiler.isComplexValued(args[0]))
|
|
58024
|
+
throw new Error(
|
|
58025
|
+
`${kind}: complex-valued body not supported in GPU targets`
|
|
58026
|
+
);
|
|
58027
|
+
const limitsExpr = args[1];
|
|
58028
|
+
if (!isFunction2(limitsExpr, "Limits"))
|
|
58029
|
+
throw new Error(`${kind}: expected Limits indexing set`);
|
|
58030
|
+
const limitsOps = limitsExpr.ops;
|
|
58031
|
+
const index = isSymbol2(limitsOps[0]) ? limitsOps[0].symbol : "_";
|
|
58032
|
+
const lowerRe = limitsOps[1].re;
|
|
58033
|
+
const upperRe = limitsOps[2].re;
|
|
58034
|
+
const lowerNum = !isNaN(lowerRe) && Number.isFinite(lowerRe) ? Math.floor(lowerRe) : void 0;
|
|
58035
|
+
const upperNum = !isNaN(upperRe) && Number.isFinite(upperRe) ? Math.floor(upperRe) : void 0;
|
|
58036
|
+
const isSum = kind === "Sum";
|
|
58037
|
+
const op = isSum ? "+" : "*";
|
|
58038
|
+
const identity = isSum ? "0.0" : "1.0";
|
|
58039
|
+
const isWGSL = target.language === "wgsl";
|
|
58040
|
+
const bothConstant = lowerNum !== void 0 && upperNum !== void 0;
|
|
58041
|
+
if (bothConstant && lowerNum > upperNum) return identity;
|
|
58042
|
+
if (bothConstant && upperNum - lowerNum + 1 <= GPU_UNROLL_LIMIT) {
|
|
58043
|
+
const terms = [];
|
|
58044
|
+
for (let k = lowerNum; k <= upperNum; k++) {
|
|
58045
|
+
const kStr = formatGPUNumber(k);
|
|
58046
|
+
const innerTarget = {
|
|
58047
|
+
...target,
|
|
58048
|
+
var: (id) => id === index ? kStr : target.var(id)
|
|
58049
|
+
};
|
|
58050
|
+
terms.push(`(${BaseCompiler.compile(args[0], innerTarget)})`);
|
|
58051
|
+
}
|
|
58052
|
+
return `(${terms.join(` ${op} `)})`;
|
|
58053
|
+
}
|
|
58054
|
+
const acc = BaseCompiler.tempVar();
|
|
58055
|
+
const floatType = isWGSL ? "f32" : "float";
|
|
58056
|
+
const intType = isWGSL ? "i32" : "int";
|
|
58057
|
+
const bodyTarget = {
|
|
58058
|
+
...target,
|
|
58059
|
+
var: (id) => id === index ? isWGSL ? `f32(${index})` : `float(${index})` : target.var(id)
|
|
58060
|
+
};
|
|
58061
|
+
const body = BaseCompiler.compile(args[0], bodyTarget);
|
|
58062
|
+
const lowerStr = lowerNum !== void 0 ? String(lowerNum) : BaseCompiler.compile(limitsOps[1], target);
|
|
58063
|
+
const upperStr = upperNum !== void 0 ? String(upperNum) : BaseCompiler.compile(limitsOps[2], target);
|
|
58064
|
+
const accDecl = isWGSL ? `var ${acc}: ${floatType}` : `${floatType} ${acc}`;
|
|
58065
|
+
const indexDecl = isWGSL ? `var ${index}: ${intType}` : `${intType} ${index}`;
|
|
58066
|
+
const lines = [
|
|
58067
|
+
`${accDecl} = ${identity};`,
|
|
58068
|
+
`for (${indexDecl} = ${lowerStr}; ${index} <= ${upperStr}; ${index}++) {`,
|
|
58069
|
+
` ${acc} ${op}= ${body};`,
|
|
58070
|
+
`}`,
|
|
58071
|
+
`return ${acc}`
|
|
58072
|
+
];
|
|
58073
|
+
return lines.join("\n");
|
|
58074
|
+
}
|
|
57294
58075
|
var GPU_FUNCTIONS = {
|
|
57295
58076
|
// Variadic arithmetic (for function-call form, e.g., with vectors)
|
|
57296
58077
|
Add: (args, compile3, target) => {
|
|
@@ -57640,6 +58421,28 @@ var GPU_FUNCTIONS = {
|
|
|
57640
58421
|
if (x === null) throw new Error("ErfInv: no argument");
|
|
57641
58422
|
return `_gpu_erfinv(${compile3(x)})`;
|
|
57642
58423
|
},
|
|
58424
|
+
Heaviside: ([x], compile3) => {
|
|
58425
|
+
if (x === null) throw new Error("Heaviside: no argument");
|
|
58426
|
+
return `_gpu_heaviside(${compile3(x)})`;
|
|
58427
|
+
},
|
|
58428
|
+
Sinc: ([x], compile3) => {
|
|
58429
|
+
if (x === null) throw new Error("Sinc: no argument");
|
|
58430
|
+
return `_gpu_sinc(${compile3(x)})`;
|
|
58431
|
+
},
|
|
58432
|
+
FresnelC: ([x], compile3) => {
|
|
58433
|
+
if (x === null) throw new Error("FresnelC: no argument");
|
|
58434
|
+
return `_gpu_fresnelC(${compile3(x)})`;
|
|
58435
|
+
},
|
|
58436
|
+
FresnelS: ([x], compile3) => {
|
|
58437
|
+
if (x === null) throw new Error("FresnelS: no argument");
|
|
58438
|
+
return `_gpu_fresnelS(${compile3(x)})`;
|
|
58439
|
+
},
|
|
58440
|
+
BesselJ: ([n, x], compile3, target) => {
|
|
58441
|
+
if (n === null || x === null)
|
|
58442
|
+
throw new Error("BesselJ: need two arguments");
|
|
58443
|
+
const intCast = target?.language === "wgsl" ? "i32" : "int";
|
|
58444
|
+
return `_gpu_besselJ(${intCast}(${compile3(n)}), ${compile3(x)})`;
|
|
58445
|
+
},
|
|
57643
58446
|
// Additional math functions
|
|
57644
58447
|
Lb: "log2",
|
|
57645
58448
|
Log: (args, compile3) => {
|
|
@@ -57725,7 +58528,44 @@ var GPU_FUNCTIONS = {
|
|
|
57725
58528
|
Length: "length",
|
|
57726
58529
|
Normalize: "normalize",
|
|
57727
58530
|
Reflect: "reflect",
|
|
57728
|
-
Refract: "refract"
|
|
58531
|
+
Refract: "refract",
|
|
58532
|
+
// Sum/Product — unrolled or for-loop
|
|
58533
|
+
Sum: (args, compile3, target) => compileGPUSumProduct("Sum", args, compile3, target),
|
|
58534
|
+
Product: (args, compile3, target) => compileGPUSumProduct("Product", args, compile3, target),
|
|
58535
|
+
// Loop — GPU for-loop (no IIFE, no let)
|
|
58536
|
+
Loop: (args, _compile2, target) => {
|
|
58537
|
+
if (!args[0]) throw new Error("Loop: no body");
|
|
58538
|
+
if (!args[1]) throw new Error("Loop: no indexing set");
|
|
58539
|
+
const indexing = args[1];
|
|
58540
|
+
if (!isFunction2(indexing, "Element"))
|
|
58541
|
+
throw new Error("Loop: expected Element(index, Range(lo, hi))");
|
|
58542
|
+
const indexExpr = indexing.ops[0];
|
|
58543
|
+
const rangeExpr = indexing.ops[1];
|
|
58544
|
+
if (!isSymbol2(indexExpr)) throw new Error("Loop: index must be a symbol");
|
|
58545
|
+
if (!isFunction2(rangeExpr, "Range"))
|
|
58546
|
+
throw new Error("Loop: expected Range(lo, hi)");
|
|
58547
|
+
const index = indexExpr.symbol;
|
|
58548
|
+
const lower = Math.floor(rangeExpr.ops[0].re);
|
|
58549
|
+
const upper = Math.floor(rangeExpr.ops[1].re);
|
|
58550
|
+
if (!Number.isFinite(lower) || !Number.isFinite(upper))
|
|
58551
|
+
throw new Error("Loop: bounds must be finite numbers");
|
|
58552
|
+
const isWGSL = target.language === "wgsl";
|
|
58553
|
+
const intType = isWGSL ? "i32" : "int";
|
|
58554
|
+
const bodyCode = BaseCompiler.compile(args[0], {
|
|
58555
|
+
...target,
|
|
58556
|
+
var: (id) => id === index ? index : target.var(id)
|
|
58557
|
+
});
|
|
58558
|
+
const indexDecl = isWGSL ? `var ${index}: ${intType}` : `${intType} ${index}`;
|
|
58559
|
+
return `for (${indexDecl} = ${lower}; ${index} <= ${upper}; ${index}++) {
|
|
58560
|
+
${bodyCode};
|
|
58561
|
+
}`;
|
|
58562
|
+
},
|
|
58563
|
+
// Function (lambda) — not supported in GPU
|
|
58564
|
+
Function: () => {
|
|
58565
|
+
throw new Error(
|
|
58566
|
+
"Anonymous functions (Function) are not supported in GPU targets"
|
|
58567
|
+
);
|
|
58568
|
+
}
|
|
57729
58569
|
};
|
|
57730
58570
|
function compileGPUMatrix(args, compile3, vecFn, matFn, arrayFn) {
|
|
57731
58571
|
const body = args[0];
|
|
@@ -57806,6 +58646,476 @@ float _gpu_erfinv(float x) {
|
|
|
57806
58646
|
return sqrt(pi) * 0.5 * (x + (pi / 12.0) * x3 + (7.0 * pi * pi / 480.0) * x5 + (127.0 * pi * pi * pi / 40320.0) * x7 + (4369.0 * pi * pi * pi * pi / 5806080.0) * x9);
|
|
57807
58647
|
}
|
|
57808
58648
|
`;
|
|
58649
|
+
var GPU_HEAVISIDE_PREAMBLE_GLSL = `
|
|
58650
|
+
float _gpu_heaviside(float x) {
|
|
58651
|
+
if (x < 0.0) return 0.0;
|
|
58652
|
+
if (x > 0.0) return 1.0;
|
|
58653
|
+
return 0.5;
|
|
58654
|
+
}
|
|
58655
|
+
`;
|
|
58656
|
+
var GPU_HEAVISIDE_PREAMBLE_WGSL = `
|
|
58657
|
+
fn _gpu_heaviside(x: f32) -> f32 {
|
|
58658
|
+
if (x < 0.0) { return 0.0; }
|
|
58659
|
+
if (x > 0.0) { return 1.0; }
|
|
58660
|
+
return 0.5;
|
|
58661
|
+
}
|
|
58662
|
+
`;
|
|
58663
|
+
var GPU_SINC_PREAMBLE_GLSL = `
|
|
58664
|
+
float _gpu_sinc(float x) {
|
|
58665
|
+
if (abs(x) < 1e-10) return 1.0;
|
|
58666
|
+
return sin(x) / x;
|
|
58667
|
+
}
|
|
58668
|
+
`;
|
|
58669
|
+
var GPU_SINC_PREAMBLE_WGSL = `
|
|
58670
|
+
fn _gpu_sinc(x: f32) -> f32 {
|
|
58671
|
+
if (abs(x) < 1e-10) { return 1.0; }
|
|
58672
|
+
return sin(x) / x;
|
|
58673
|
+
}
|
|
58674
|
+
`;
|
|
58675
|
+
var GPU_POLEVL_PREAMBLE_GLSL = `
|
|
58676
|
+
float _gpu_polevl(float x, float c[12], int n) {
|
|
58677
|
+
float ans = c[0];
|
|
58678
|
+
for (int i = 1; i < n; i++) ans = ans * x + c[i];
|
|
58679
|
+
return ans;
|
|
58680
|
+
}
|
|
58681
|
+
`;
|
|
58682
|
+
var GPU_POLEVL_PREAMBLE_WGSL = `
|
|
58683
|
+
fn _gpu_polevl(x: f32, c: array<f32, 12>, n: i32) -> f32 {
|
|
58684
|
+
var ans = c[0];
|
|
58685
|
+
for (var i: i32 = 1; i < n; i++) { ans = ans * x + c[i]; }
|
|
58686
|
+
return ans;
|
|
58687
|
+
}
|
|
58688
|
+
`;
|
|
58689
|
+
var GPU_FRESNELC_PREAMBLE_GLSL = `
|
|
58690
|
+
float _gpu_fresnelC(float x_in) {
|
|
58691
|
+
float sgn = x_in < 0.0 ? -1.0 : 1.0;
|
|
58692
|
+
float x = abs(x_in);
|
|
58693
|
+
|
|
58694
|
+
if (x < 1.6) {
|
|
58695
|
+
float x2 = x * x;
|
|
58696
|
+
float t = x2 * x2;
|
|
58697
|
+
float cn[6] = float[6](
|
|
58698
|
+
-4.98843114573573548651e-8, 9.50428062829859605134e-6,
|
|
58699
|
+
-6.45191435683965050962e-4, 1.88843319396703850064e-2,
|
|
58700
|
+
-2.05525900955013891793e-1, 9.99999999999999998822e-1
|
|
58701
|
+
);
|
|
58702
|
+
float cd[7] = float[7](
|
|
58703
|
+
3.99982968972495980367e-12, 9.15439215774657478799e-10,
|
|
58704
|
+
1.25001862479598821474e-7, 1.22262789024179030997e-5,
|
|
58705
|
+
8.68029542941784300606e-4, 4.12142090722199792936e-2, 1.0
|
|
58706
|
+
);
|
|
58707
|
+
return sgn * x * _gpu_polevl(t, cn, 6) / _gpu_polevl(t, cd, 7);
|
|
58708
|
+
}
|
|
58709
|
+
|
|
58710
|
+
if (x < 36.0) {
|
|
58711
|
+
float x2 = x * x;
|
|
58712
|
+
float t = 3.14159265358979 * x2;
|
|
58713
|
+
float u = 1.0 / (t * t);
|
|
58714
|
+
float fn[10] = float[10](
|
|
58715
|
+
4.21543555043677546506e-1, 1.43407919780758885261e-1,
|
|
58716
|
+
1.15220955073585758835e-2, 3.450179397825740279e-4,
|
|
58717
|
+
4.63613749287867322088e-6, 3.05568983790257605827e-8,
|
|
58718
|
+
1.02304514164907233465e-10, 1.72010743268161828879e-13,
|
|
58719
|
+
1.34283276233062758925e-16, 3.76329711269987889006e-20
|
|
58720
|
+
);
|
|
58721
|
+
float fd[11] = float[11](
|
|
58722
|
+
1.0, 7.51586398353378947175e-1,
|
|
58723
|
+
1.16888925859191382142e-1, 6.44051526508858611005e-3,
|
|
58724
|
+
1.55934409164153020873e-4, 1.8462756734893054587e-6,
|
|
58725
|
+
1.12699224763999035261e-8, 3.60140029589371370404e-11,
|
|
58726
|
+
5.8875453362157841001e-14, 4.52001434074129701496e-17,
|
|
58727
|
+
1.25443237090011264384e-20
|
|
58728
|
+
);
|
|
58729
|
+
float gn[11] = float[11](
|
|
58730
|
+
5.04442073643383265887e-1, 1.97102833525523411709e-1,
|
|
58731
|
+
1.87648584092575249293e-2, 6.84079380915393090172e-4,
|
|
58732
|
+
1.15138826111884280931e-5, 9.82852443688422223854e-8,
|
|
58733
|
+
4.45344415861750144738e-10, 1.08268041139020870318e-12,
|
|
58734
|
+
1.37555460633261799868e-15, 8.36354435630677421531e-19,
|
|
58735
|
+
1.86958710162783235106e-22
|
|
58736
|
+
);
|
|
58737
|
+
float gd[12] = float[12](
|
|
58738
|
+
1.0, 1.47495759925128324529,
|
|
58739
|
+
3.37748989120019970451e-1, 2.53603741420338795122e-2,
|
|
58740
|
+
8.14679107184306179049e-4, 1.27545075667729118702e-5,
|
|
58741
|
+
1.04314589657571990585e-7, 4.60680728515232032307e-10,
|
|
58742
|
+
1.10273215066240270757e-12, 1.38796531259578871258e-15,
|
|
58743
|
+
8.39158816283118707363e-19, 1.86958710162783236342e-22
|
|
58744
|
+
);
|
|
58745
|
+
float f = 1.0 - u * _gpu_polevl(u, fn, 10) / _gpu_polevl(u, fd, 11);
|
|
58746
|
+
float g = (1.0 / t) * _gpu_polevl(u, gn, 11) / _gpu_polevl(u, gd, 12);
|
|
58747
|
+
float z = 1.5707963267948966 * x2;
|
|
58748
|
+
float c = cos(z);
|
|
58749
|
+
float s = sin(z);
|
|
58750
|
+
return sgn * (0.5 + (f * s - g * c) / (3.14159265358979 * x));
|
|
58751
|
+
}
|
|
58752
|
+
|
|
58753
|
+
return sgn * 0.5;
|
|
58754
|
+
}
|
|
58755
|
+
`;
|
|
58756
|
+
var GPU_FRESNELC_PREAMBLE_WGSL = `
|
|
58757
|
+
fn _gpu_fresnelC(x_in: f32) -> f32 {
|
|
58758
|
+
let sgn: f32 = select(1.0, -1.0, x_in < 0.0);
|
|
58759
|
+
let x = abs(x_in);
|
|
58760
|
+
|
|
58761
|
+
if (x < 1.6) {
|
|
58762
|
+
let x2 = x * x;
|
|
58763
|
+
let t = x2 * x2;
|
|
58764
|
+
var cn = array<f32, 12>(
|
|
58765
|
+
-4.98843114573573548651e-8, 9.50428062829859605134e-6,
|
|
58766
|
+
-6.45191435683965050962e-4, 1.88843319396703850064e-2,
|
|
58767
|
+
-2.05525900955013891793e-1, 9.99999999999999998822e-1,
|
|
58768
|
+
0.0, 0.0, 0.0, 0.0, 0.0, 0.0
|
|
58769
|
+
);
|
|
58770
|
+
var cd = array<f32, 12>(
|
|
58771
|
+
3.99982968972495980367e-12, 9.15439215774657478799e-10,
|
|
58772
|
+
1.25001862479598821474e-7, 1.22262789024179030997e-5,
|
|
58773
|
+
8.68029542941784300606e-4, 4.12142090722199792936e-2, 1.0,
|
|
58774
|
+
0.0, 0.0, 0.0, 0.0, 0.0
|
|
58775
|
+
);
|
|
58776
|
+
return sgn * x * _gpu_polevl(t, cn, 6) / _gpu_polevl(t, cd, 7);
|
|
58777
|
+
}
|
|
58778
|
+
|
|
58779
|
+
if (x < 36.0) {
|
|
58780
|
+
let x2 = x * x;
|
|
58781
|
+
let t = 3.14159265358979 * x2;
|
|
58782
|
+
let u = 1.0 / (t * t);
|
|
58783
|
+
var fn = array<f32, 12>(
|
|
58784
|
+
4.21543555043677546506e-1, 1.43407919780758885261e-1,
|
|
58785
|
+
1.15220955073585758835e-2, 3.450179397825740279e-4,
|
|
58786
|
+
4.63613749287867322088e-6, 3.05568983790257605827e-8,
|
|
58787
|
+
1.02304514164907233465e-10, 1.72010743268161828879e-13,
|
|
58788
|
+
1.34283276233062758925e-16, 3.76329711269987889006e-20,
|
|
58789
|
+
0.0, 0.0
|
|
58790
|
+
);
|
|
58791
|
+
var fd = array<f32, 12>(
|
|
58792
|
+
1.0, 7.51586398353378947175e-1,
|
|
58793
|
+
1.16888925859191382142e-1, 6.44051526508858611005e-3,
|
|
58794
|
+
1.55934409164153020873e-4, 1.8462756734893054587e-6,
|
|
58795
|
+
1.12699224763999035261e-8, 3.60140029589371370404e-11,
|
|
58796
|
+
5.8875453362157841001e-14, 4.52001434074129701496e-17,
|
|
58797
|
+
1.25443237090011264384e-20, 0.0
|
|
58798
|
+
);
|
|
58799
|
+
var gn = array<f32, 12>(
|
|
58800
|
+
5.04442073643383265887e-1, 1.97102833525523411709e-1,
|
|
58801
|
+
1.87648584092575249293e-2, 6.84079380915393090172e-4,
|
|
58802
|
+
1.15138826111884280931e-5, 9.82852443688422223854e-8,
|
|
58803
|
+
4.45344415861750144738e-10, 1.08268041139020870318e-12,
|
|
58804
|
+
1.37555460633261799868e-15, 8.36354435630677421531e-19,
|
|
58805
|
+
1.86958710162783235106e-22, 0.0
|
|
58806
|
+
);
|
|
58807
|
+
var gd = array<f32, 12>(
|
|
58808
|
+
1.0, 1.47495759925128324529,
|
|
58809
|
+
3.37748989120019970451e-1, 2.53603741420338795122e-2,
|
|
58810
|
+
8.14679107184306179049e-4, 1.27545075667729118702e-5,
|
|
58811
|
+
1.04314589657571990585e-7, 4.60680728515232032307e-10,
|
|
58812
|
+
1.10273215066240270757e-12, 1.38796531259578871258e-15,
|
|
58813
|
+
8.39158816283118707363e-19, 1.86958710162783236342e-22
|
|
58814
|
+
);
|
|
58815
|
+
let f = 1.0 - u * _gpu_polevl(u, fn, 10) / _gpu_polevl(u, fd, 11);
|
|
58816
|
+
let g = (1.0 / t) * _gpu_polevl(u, gn, 11) / _gpu_polevl(u, gd, 12);
|
|
58817
|
+
let z = 1.5707963267948966 * x2;
|
|
58818
|
+
let c = cos(z);
|
|
58819
|
+
let s = sin(z);
|
|
58820
|
+
return sgn * (0.5 + (f * s - g * c) / (3.14159265358979 * x));
|
|
58821
|
+
}
|
|
58822
|
+
|
|
58823
|
+
return sgn * 0.5;
|
|
58824
|
+
}
|
|
58825
|
+
`;
|
|
58826
|
+
var GPU_FRESNELS_PREAMBLE_GLSL = `
|
|
58827
|
+
float _gpu_fresnelS(float x_in) {
|
|
58828
|
+
float sgn = x_in < 0.0 ? -1.0 : 1.0;
|
|
58829
|
+
float x = abs(x_in);
|
|
58830
|
+
|
|
58831
|
+
if (x < 1.6) {
|
|
58832
|
+
float x2 = x * x;
|
|
58833
|
+
float t = x2 * x2;
|
|
58834
|
+
float sn[6] = float[6](
|
|
58835
|
+
-2.99181919401019853726e3, 7.08840045257738576863e5,
|
|
58836
|
+
-6.29741486205862506537e7, 2.54890880573376359104e9,
|
|
58837
|
+
-4.42979518059697779103e10, 3.18016297876567817986e11
|
|
58838
|
+
);
|
|
58839
|
+
float sd[7] = float[7](
|
|
58840
|
+
1.0, 2.81376268889994315696e2, 4.55847810806532581675e4,
|
|
58841
|
+
5.1734388877009640073e6, 4.19320245898111231129e8, 2.2441179564534092094e10,
|
|
58842
|
+
6.07366389490084914091e11
|
|
58843
|
+
);
|
|
58844
|
+
return sgn * x * x2 * _gpu_polevl(t, sn, 6) / _gpu_polevl(t, sd, 7);
|
|
58845
|
+
}
|
|
58846
|
+
|
|
58847
|
+
if (x < 36.0) {
|
|
58848
|
+
float x2 = x * x;
|
|
58849
|
+
float t = 3.14159265358979 * x2;
|
|
58850
|
+
float u = 1.0 / (t * t);
|
|
58851
|
+
float fn[10] = float[10](
|
|
58852
|
+
4.21543555043677546506e-1, 1.43407919780758885261e-1,
|
|
58853
|
+
1.15220955073585758835e-2, 3.450179397825740279e-4,
|
|
58854
|
+
4.63613749287867322088e-6, 3.05568983790257605827e-8,
|
|
58855
|
+
1.02304514164907233465e-10, 1.72010743268161828879e-13,
|
|
58856
|
+
1.34283276233062758925e-16, 3.76329711269987889006e-20
|
|
58857
|
+
);
|
|
58858
|
+
float fd[11] = float[11](
|
|
58859
|
+
1.0, 7.51586398353378947175e-1,
|
|
58860
|
+
1.16888925859191382142e-1, 6.44051526508858611005e-3,
|
|
58861
|
+
1.55934409164153020873e-4, 1.8462756734893054587e-6,
|
|
58862
|
+
1.12699224763999035261e-8, 3.60140029589371370404e-11,
|
|
58863
|
+
5.8875453362157841001e-14, 4.52001434074129701496e-17,
|
|
58864
|
+
1.25443237090011264384e-20
|
|
58865
|
+
);
|
|
58866
|
+
float gn[11] = float[11](
|
|
58867
|
+
5.04442073643383265887e-1, 1.97102833525523411709e-1,
|
|
58868
|
+
1.87648584092575249293e-2, 6.84079380915393090172e-4,
|
|
58869
|
+
1.15138826111884280931e-5, 9.82852443688422223854e-8,
|
|
58870
|
+
4.45344415861750144738e-10, 1.08268041139020870318e-12,
|
|
58871
|
+
1.37555460633261799868e-15, 8.36354435630677421531e-19,
|
|
58872
|
+
1.86958710162783235106e-22
|
|
58873
|
+
);
|
|
58874
|
+
float gd[12] = float[12](
|
|
58875
|
+
1.0, 1.47495759925128324529,
|
|
58876
|
+
3.37748989120019970451e-1, 2.53603741420338795122e-2,
|
|
58877
|
+
8.14679107184306179049e-4, 1.27545075667729118702e-5,
|
|
58878
|
+
1.04314589657571990585e-7, 4.60680728515232032307e-10,
|
|
58879
|
+
1.10273215066240270757e-12, 1.38796531259578871258e-15,
|
|
58880
|
+
8.39158816283118707363e-19, 1.86958710162783236342e-22
|
|
58881
|
+
);
|
|
58882
|
+
float f = 1.0 - u * _gpu_polevl(u, fn, 10) / _gpu_polevl(u, fd, 11);
|
|
58883
|
+
float g = (1.0 / t) * _gpu_polevl(u, gn, 11) / _gpu_polevl(u, gd, 12);
|
|
58884
|
+
float z = 1.5707963267948966 * x2;
|
|
58885
|
+
float c = cos(z);
|
|
58886
|
+
float s = sin(z);
|
|
58887
|
+
return sgn * (0.5 - (f * c + g * s) / (3.14159265358979 * x));
|
|
58888
|
+
}
|
|
58889
|
+
|
|
58890
|
+
return sgn * 0.5;
|
|
58891
|
+
}
|
|
58892
|
+
`;
|
|
58893
|
+
var GPU_FRESNELS_PREAMBLE_WGSL = `
|
|
58894
|
+
fn _gpu_fresnelS(x_in: f32) -> f32 {
|
|
58895
|
+
let sgn: f32 = select(1.0, -1.0, x_in < 0.0);
|
|
58896
|
+
let x = abs(x_in);
|
|
58897
|
+
|
|
58898
|
+
if (x < 1.6) {
|
|
58899
|
+
let x2 = x * x;
|
|
58900
|
+
let t = x2 * x2;
|
|
58901
|
+
var sn = array<f32, 12>(
|
|
58902
|
+
-2.99181919401019853726e3, 7.08840045257738576863e5,
|
|
58903
|
+
-6.29741486205862506537e7, 2.54890880573376359104e9,
|
|
58904
|
+
-4.42979518059697779103e10, 3.18016297876567817986e11,
|
|
58905
|
+
0.0, 0.0, 0.0, 0.0, 0.0, 0.0
|
|
58906
|
+
);
|
|
58907
|
+
var sd = array<f32, 12>(
|
|
58908
|
+
1.0, 2.81376268889994315696e2, 4.55847810806532581675e4,
|
|
58909
|
+
5.1734388877009640073e6, 4.19320245898111231129e8, 2.2441179564534092094e10,
|
|
58910
|
+
6.07366389490084914091e11,
|
|
58911
|
+
0.0, 0.0, 0.0, 0.0, 0.0
|
|
58912
|
+
);
|
|
58913
|
+
return sgn * x * x2 * _gpu_polevl(t, sn, 6) / _gpu_polevl(t, sd, 7);
|
|
58914
|
+
}
|
|
58915
|
+
|
|
58916
|
+
if (x < 36.0) {
|
|
58917
|
+
let x2 = x * x;
|
|
58918
|
+
let t = 3.14159265358979 * x2;
|
|
58919
|
+
let u = 1.0 / (t * t);
|
|
58920
|
+
var fn = array<f32, 12>(
|
|
58921
|
+
4.21543555043677546506e-1, 1.43407919780758885261e-1,
|
|
58922
|
+
1.15220955073585758835e-2, 3.450179397825740279e-4,
|
|
58923
|
+
4.63613749287867322088e-6, 3.05568983790257605827e-8,
|
|
58924
|
+
1.02304514164907233465e-10, 1.72010743268161828879e-13,
|
|
58925
|
+
1.34283276233062758925e-16, 3.76329711269987889006e-20,
|
|
58926
|
+
0.0, 0.0
|
|
58927
|
+
);
|
|
58928
|
+
var fd = array<f32, 12>(
|
|
58929
|
+
1.0, 7.51586398353378947175e-1,
|
|
58930
|
+
1.16888925859191382142e-1, 6.44051526508858611005e-3,
|
|
58931
|
+
1.55934409164153020873e-4, 1.8462756734893054587e-6,
|
|
58932
|
+
1.12699224763999035261e-8, 3.60140029589371370404e-11,
|
|
58933
|
+
5.8875453362157841001e-14, 4.52001434074129701496e-17,
|
|
58934
|
+
1.25443237090011264384e-20, 0.0
|
|
58935
|
+
);
|
|
58936
|
+
var gn = array<f32, 12>(
|
|
58937
|
+
5.04442073643383265887e-1, 1.97102833525523411709e-1,
|
|
58938
|
+
1.87648584092575249293e-2, 6.84079380915393090172e-4,
|
|
58939
|
+
1.15138826111884280931e-5, 9.82852443688422223854e-8,
|
|
58940
|
+
4.45344415861750144738e-10, 1.08268041139020870318e-12,
|
|
58941
|
+
1.37555460633261799868e-15, 8.36354435630677421531e-19,
|
|
58942
|
+
1.86958710162783235106e-22, 0.0
|
|
58943
|
+
);
|
|
58944
|
+
var gd = array<f32, 12>(
|
|
58945
|
+
1.0, 1.47495759925128324529,
|
|
58946
|
+
3.37748989120019970451e-1, 2.53603741420338795122e-2,
|
|
58947
|
+
8.14679107184306179049e-4, 1.27545075667729118702e-5,
|
|
58948
|
+
1.04314589657571990585e-7, 4.60680728515232032307e-10,
|
|
58949
|
+
1.10273215066240270757e-12, 1.38796531259578871258e-15,
|
|
58950
|
+
8.39158816283118707363e-19, 1.86958710162783236342e-22
|
|
58951
|
+
);
|
|
58952
|
+
let f = 1.0 - u * _gpu_polevl(u, fn, 10) / _gpu_polevl(u, fd, 11);
|
|
58953
|
+
let g = (1.0 / t) * _gpu_polevl(u, gn, 11) / _gpu_polevl(u, gd, 12);
|
|
58954
|
+
let z = 1.5707963267948966 * x2;
|
|
58955
|
+
let c = cos(z);
|
|
58956
|
+
let s = sin(z);
|
|
58957
|
+
return sgn * (0.5 - (f * c + g * s) / (3.14159265358979 * x));
|
|
58958
|
+
}
|
|
58959
|
+
|
|
58960
|
+
return sgn * 0.5;
|
|
58961
|
+
}
|
|
58962
|
+
`;
|
|
58963
|
+
var GPU_BESSELJ_PREAMBLE_GLSL = `
|
|
58964
|
+
float _gpu_factorial(int n) {
|
|
58965
|
+
float f = 1.0;
|
|
58966
|
+
for (int i = 2; i <= n; i++) f *= float(i);
|
|
58967
|
+
return f;
|
|
58968
|
+
}
|
|
58969
|
+
|
|
58970
|
+
float _gpu_besselJ_series(int n, float x) {
|
|
58971
|
+
float halfX = x / 2.0;
|
|
58972
|
+
float negQ = -(x * x) / 4.0;
|
|
58973
|
+
float term = 1.0;
|
|
58974
|
+
for (int i = 1; i <= n; i++) term /= float(i);
|
|
58975
|
+
float s = term;
|
|
58976
|
+
for (int k = 1; k <= 60; k++) {
|
|
58977
|
+
term *= negQ / (float(k) * float(n + k));
|
|
58978
|
+
s += term;
|
|
58979
|
+
if (abs(term) < abs(s) * 1e-7) break;
|
|
58980
|
+
}
|
|
58981
|
+
return s * pow(halfX, float(n));
|
|
58982
|
+
}
|
|
58983
|
+
|
|
58984
|
+
float _gpu_besselJ_asymptotic(int n, float x) {
|
|
58985
|
+
float mu = 4.0 * float(n) * float(n);
|
|
58986
|
+
float P = 1.0;
|
|
58987
|
+
float Q = 0.0;
|
|
58988
|
+
float ak = 1.0;
|
|
58989
|
+
float e8x = 8.0 * x;
|
|
58990
|
+
for (int k = 1; k <= 12; k++) {
|
|
58991
|
+
float twokm1 = float(2 * k - 1);
|
|
58992
|
+
ak *= mu - twokm1 * twokm1;
|
|
58993
|
+
float denom = _gpu_factorial(k) * pow(e8x, float(k));
|
|
58994
|
+
float contrib = ak / denom;
|
|
58995
|
+
if (k == 1 || k == 3 || k == 5 || k == 7 || k == 9 || k == 11) {
|
|
58996
|
+
// odd k: contributes to Q
|
|
58997
|
+
if (((k - 1) / 2) % 2 == 0) Q += contrib;
|
|
58998
|
+
else Q -= contrib;
|
|
58999
|
+
} else {
|
|
59000
|
+
// even k: contributes to P
|
|
59001
|
+
if ((k / 2) % 2 == 1) P -= contrib;
|
|
59002
|
+
else P += contrib;
|
|
59003
|
+
}
|
|
59004
|
+
if (abs(contrib) < 1e-7) break;
|
|
59005
|
+
}
|
|
59006
|
+
float chi = x - (float(n) / 2.0 + 0.25) * 3.14159265358979;
|
|
59007
|
+
return sqrt(2.0 / (3.14159265358979 * x)) * (P * cos(chi) - Q * sin(chi));
|
|
59008
|
+
}
|
|
59009
|
+
|
|
59010
|
+
float _gpu_besselJ(int n, float x) {
|
|
59011
|
+
if (x == 0.0) return n == 0 ? 1.0 : 0.0;
|
|
59012
|
+
float sgn = 1.0;
|
|
59013
|
+
if (n < 0) {
|
|
59014
|
+
n = -n;
|
|
59015
|
+
if (n % 2 != 0) sgn = -1.0;
|
|
59016
|
+
}
|
|
59017
|
+
if (x < 0.0) {
|
|
59018
|
+
x = -x;
|
|
59019
|
+
if (n % 2 != 0) sgn *= -1.0;
|
|
59020
|
+
}
|
|
59021
|
+
if (x > 25.0 + float(n * n) / 2.0) return sgn * _gpu_besselJ_asymptotic(n, x);
|
|
59022
|
+
if (x < 5.0 + float(n)) return sgn * _gpu_besselJ_series(n, x);
|
|
59023
|
+
// Miller's backward recurrence
|
|
59024
|
+
int M = max(n + 20, int(ceil(x)) + 30);
|
|
59025
|
+
if (M > 200) return sgn * _gpu_besselJ_series(n, x);
|
|
59026
|
+
float vals[201];
|
|
59027
|
+
float jp1 = 0.0;
|
|
59028
|
+
float jk = 1.0;
|
|
59029
|
+
vals[M] = jk;
|
|
59030
|
+
for (int k = M; k >= 1; k--) {
|
|
59031
|
+
float jm1 = (2.0 * float(k) / x) * jk - jp1;
|
|
59032
|
+
jp1 = jk;
|
|
59033
|
+
jk = jm1;
|
|
59034
|
+
vals[k - 1] = jk;
|
|
59035
|
+
}
|
|
59036
|
+
float norm = vals[0];
|
|
59037
|
+
for (int k = 2; k <= M; k += 2) norm += 2.0 * vals[k];
|
|
59038
|
+
return sgn * vals[n] / norm;
|
|
59039
|
+
}
|
|
59040
|
+
`;
|
|
59041
|
+
var GPU_BESSELJ_PREAMBLE_WGSL = `
|
|
59042
|
+
fn _gpu_factorial(n: i32) -> f32 {
|
|
59043
|
+
var f: f32 = 1.0;
|
|
59044
|
+
for (var i: i32 = 2; i <= n; i++) { f *= f32(i); }
|
|
59045
|
+
return f;
|
|
59046
|
+
}
|
|
59047
|
+
|
|
59048
|
+
fn _gpu_besselJ_series(n_in: i32, x: f32) -> f32 {
|
|
59049
|
+
let halfX = x / 2.0;
|
|
59050
|
+
let negQ = -(x * x) / 4.0;
|
|
59051
|
+
var term: f32 = 1.0;
|
|
59052
|
+
for (var i: i32 = 1; i <= n_in; i++) { term /= f32(i); }
|
|
59053
|
+
var s = term;
|
|
59054
|
+
for (var k: i32 = 1; k <= 60; k++) {
|
|
59055
|
+
term *= negQ / (f32(k) * f32(n_in + k));
|
|
59056
|
+
s += term;
|
|
59057
|
+
if (abs(term) < abs(s) * 1e-7) { break; }
|
|
59058
|
+
}
|
|
59059
|
+
return s * pow(halfX, f32(n_in));
|
|
59060
|
+
}
|
|
59061
|
+
|
|
59062
|
+
fn _gpu_besselJ_asymptotic(n_in: i32, x: f32) -> f32 {
|
|
59063
|
+
let mu = 4.0 * f32(n_in) * f32(n_in);
|
|
59064
|
+
var P: f32 = 1.0;
|
|
59065
|
+
var Q: f32 = 0.0;
|
|
59066
|
+
var ak: f32 = 1.0;
|
|
59067
|
+
let e8x = 8.0 * x;
|
|
59068
|
+
for (var k: i32 = 1; k <= 12; k++) {
|
|
59069
|
+
let twokm1 = f32(2 * k - 1);
|
|
59070
|
+
ak *= mu - twokm1 * twokm1;
|
|
59071
|
+
let denom = _gpu_factorial(k) * pow(e8x, f32(k));
|
|
59072
|
+
let contrib = ak / denom;
|
|
59073
|
+
if (k == 1 || k == 3 || k == 5 || k == 7 || k == 9 || k == 11) {
|
|
59074
|
+
if (((k - 1) / 2) % 2 == 0) { Q += contrib; }
|
|
59075
|
+
else { Q -= contrib; }
|
|
59076
|
+
} else {
|
|
59077
|
+
if ((k / 2) % 2 == 1) { P -= contrib; }
|
|
59078
|
+
else { P += contrib; }
|
|
59079
|
+
}
|
|
59080
|
+
if (abs(contrib) < 1e-7) { break; }
|
|
59081
|
+
}
|
|
59082
|
+
let chi = x - (f32(n_in) / 2.0 + 0.25) * 3.14159265358979;
|
|
59083
|
+
return sqrt(2.0 / (3.14159265358979 * x)) * (P * cos(chi) - Q * sin(chi));
|
|
59084
|
+
}
|
|
59085
|
+
|
|
59086
|
+
fn _gpu_besselJ(n_in: i32, x_in: f32) -> f32 {
|
|
59087
|
+
var n = n_in;
|
|
59088
|
+
var x = x_in;
|
|
59089
|
+
if (x == 0.0) { return select(0.0, 1.0, n == 0); }
|
|
59090
|
+
var sgn: f32 = 1.0;
|
|
59091
|
+
if (n < 0) {
|
|
59092
|
+
n = -n;
|
|
59093
|
+
if (n % 2 != 0) { sgn = -1.0; }
|
|
59094
|
+
}
|
|
59095
|
+
if (x < 0.0) {
|
|
59096
|
+
x = -x;
|
|
59097
|
+
if (n % 2 != 0) { sgn *= -1.0; }
|
|
59098
|
+
}
|
|
59099
|
+
if (x > 25.0 + f32(n * n) / 2.0) { return sgn * _gpu_besselJ_asymptotic(n, x); }
|
|
59100
|
+
if (x < 5.0 + f32(n)) { return sgn * _gpu_besselJ_series(n, x); }
|
|
59101
|
+
// Miller's backward recurrence
|
|
59102
|
+
var M = max(n + 20, i32(ceil(x)) + 30);
|
|
59103
|
+
if (M > 200) { return sgn * _gpu_besselJ_series(n, x); }
|
|
59104
|
+
var vals: array<f32, 201>;
|
|
59105
|
+
var jp1: f32 = 0.0;
|
|
59106
|
+
var jk: f32 = 1.0;
|
|
59107
|
+
vals[M] = jk;
|
|
59108
|
+
for (var k: i32 = M; k >= 1; k--) {
|
|
59109
|
+
let jm1 = (2.0 * f32(k) / x) * jk - jp1;
|
|
59110
|
+
jp1 = jk;
|
|
59111
|
+
jk = jm1;
|
|
59112
|
+
vals[k - 1] = jk;
|
|
59113
|
+
}
|
|
59114
|
+
var norm = vals[0];
|
|
59115
|
+
for (var k2: i32 = 2; k2 <= M; k2 += 2) { norm += 2.0 * vals[k2]; }
|
|
59116
|
+
return sgn * vals[n] / norm;
|
|
59117
|
+
}
|
|
59118
|
+
`;
|
|
57809
59119
|
var GPU_FRACTAL_PREAMBLE_GLSL = `
|
|
57810
59120
|
float _fractal_mandelbrot(vec2 c, int maxIter) {
|
|
57811
59121
|
vec2 z = vec2(0.0, 0.0);
|
|
@@ -58268,6 +59578,16 @@ var GPUShaderTarget = class {
|
|
|
58268
59578
|
indent: 0,
|
|
58269
59579
|
ws: (s) => s ?? "",
|
|
58270
59580
|
preamble: "",
|
|
59581
|
+
declare: (name, typeHint) => {
|
|
59582
|
+
const type2 = typeHint ?? (this.languageId === "wgsl" ? "f32" : "float");
|
|
59583
|
+
return this.languageId === "wgsl" ? `var ${name}: ${type2}` : `${type2} ${name}`;
|
|
59584
|
+
},
|
|
59585
|
+
block: (stmts) => {
|
|
59586
|
+
if (stmts.length === 0) return "";
|
|
59587
|
+
const last = stmts.length - 1;
|
|
59588
|
+
stmts[last] = `return ${stmts[last]}`;
|
|
59589
|
+
return stmts.join(";\n");
|
|
59590
|
+
},
|
|
58271
59591
|
...options
|
|
58272
59592
|
};
|
|
58273
59593
|
}
|
|
@@ -58302,6 +59622,18 @@ var GPUShaderTarget = class {
|
|
|
58302
59622
|
preamble += buildComplexPreamble(code, this.languageId);
|
|
58303
59623
|
if (code.includes("_gpu_gamma")) preamble += GPU_GAMMA_PREAMBLE;
|
|
58304
59624
|
if (code.includes("_gpu_erf")) preamble += GPU_ERF_PREAMBLE;
|
|
59625
|
+
if (code.includes("_gpu_heaviside"))
|
|
59626
|
+
preamble += this.languageId === "wgsl" ? GPU_HEAVISIDE_PREAMBLE_WGSL : GPU_HEAVISIDE_PREAMBLE_GLSL;
|
|
59627
|
+
if (code.includes("_gpu_sinc"))
|
|
59628
|
+
preamble += this.languageId === "wgsl" ? GPU_SINC_PREAMBLE_WGSL : GPU_SINC_PREAMBLE_GLSL;
|
|
59629
|
+
if (code.includes("_gpu_fresnel"))
|
|
59630
|
+
preamble += this.languageId === "wgsl" ? GPU_POLEVL_PREAMBLE_WGSL : GPU_POLEVL_PREAMBLE_GLSL;
|
|
59631
|
+
if (code.includes("_gpu_fresnelC"))
|
|
59632
|
+
preamble += this.languageId === "wgsl" ? GPU_FRESNELC_PREAMBLE_WGSL : GPU_FRESNELC_PREAMBLE_GLSL;
|
|
59633
|
+
if (code.includes("_gpu_fresnelS"))
|
|
59634
|
+
preamble += this.languageId === "wgsl" ? GPU_FRESNELS_PREAMBLE_WGSL : GPU_FRESNELS_PREAMBLE_GLSL;
|
|
59635
|
+
if (code.includes("_gpu_besselJ"))
|
|
59636
|
+
preamble += this.languageId === "wgsl" ? GPU_BESSELJ_PREAMBLE_WGSL : GPU_BESSELJ_PREAMBLE_GLSL;
|
|
58305
59637
|
if (code.includes("_fractal_")) {
|
|
58306
59638
|
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PREAMBLE_WGSL : GPU_FRACTAL_PREAMBLE_GLSL;
|
|
58307
59639
|
}
|
|
@@ -58350,6 +59682,12 @@ var GLSLTarget = class extends GPUShaderTarget {
|
|
|
58350
59682
|
const target = this.createTarget();
|
|
58351
59683
|
const body = BaseCompiler.compile(expr, target);
|
|
58352
59684
|
const params = parameters.map(([name, type2]) => `${type2} ${name}`).join(", ");
|
|
59685
|
+
if (body.includes("\n")) {
|
|
59686
|
+
const indented = body.split("\n").map((l) => ` ${l}`).join("\n");
|
|
59687
|
+
return `${returnType} ${functionName}(${params}) {
|
|
59688
|
+
${indented};
|
|
59689
|
+
}`;
|
|
59690
|
+
}
|
|
58353
59691
|
return `${returnType} ${functionName}(${params}) {
|
|
58354
59692
|
return ${body};
|
|
58355
59693
|
}`;
|
|
@@ -58453,6 +59791,14 @@ var WGSLTarget = class extends GPUShaderTarget {
|
|
|
58453
59791
|
const target = this.createTarget();
|
|
58454
59792
|
const body = BaseCompiler.compile(expr, target);
|
|
58455
59793
|
const params = parameters.map(([name, type2]) => `${name}: ${toWGSLType(type2)}`).join(", ");
|
|
59794
|
+
if (body.includes("\n")) {
|
|
59795
|
+
const indented = body.split("\n").map((l) => ` ${l}`).join("\n");
|
|
59796
|
+
return `fn ${functionName}(${params}) -> ${toWGSLType(
|
|
59797
|
+
returnType
|
|
59798
|
+
)} {
|
|
59799
|
+
${indented};
|
|
59800
|
+
}`;
|
|
59801
|
+
}
|
|
58456
59802
|
return `fn ${functionName}(${params}) -> ${toWGSLType(returnType)} {
|
|
58457
59803
|
return ${body};
|
|
58458
59804
|
}`;
|
|
@@ -59097,7 +60443,7 @@ function binomial2(n, k) {
|
|
|
59097
60443
|
];
|
|
59098
60444
|
return ok({ lo: Math.min(...vals), hi: Math.max(...vals) });
|
|
59099
60445
|
}
|
|
59100
|
-
function
|
|
60446
|
+
function gcd5(a, b) {
|
|
59101
60447
|
const uA = unwrapOrPropagate(a);
|
|
59102
60448
|
if (!Array.isArray(uA)) return uA;
|
|
59103
60449
|
const uB = unwrapOrPropagate(b);
|
|
@@ -59749,7 +61095,7 @@ var IntervalArithmetic = {
|
|
|
59749
61095
|
factorial: factorial5,
|
|
59750
61096
|
factorial2: factorial24,
|
|
59751
61097
|
binomial: binomial2,
|
|
59752
|
-
gcd:
|
|
61098
|
+
gcd: gcd5,
|
|
59753
61099
|
lcm: lcm4,
|
|
59754
61100
|
chop: chop4,
|
|
59755
61101
|
erf: erf2,
|
|
@@ -63528,6 +64874,11 @@ var _Parser = class __Parser {
|
|
|
63528
64874
|
if (this.atEnd) return lhs;
|
|
63529
64875
|
console.assert(lhs !== null);
|
|
63530
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
|
+
}
|
|
63531
64882
|
this.skipSpace();
|
|
63532
64883
|
const superscripts = [];
|
|
63533
64884
|
const subscripts = [];
|
|
@@ -65632,9 +66983,9 @@ function TR12i(expr) {
|
|
|
65632
66983
|
return ce._fn("Tan", [tanCArg]).neg();
|
|
65633
66984
|
}
|
|
65634
66985
|
function lcm5(a, b) {
|
|
65635
|
-
return Math.abs(a * b) /
|
|
66986
|
+
return Math.abs(a * b) / gcd6(a, b);
|
|
65636
66987
|
}
|
|
65637
|
-
function
|
|
66988
|
+
function gcd6(a, b) {
|
|
65638
66989
|
a = Math.abs(a);
|
|
65639
66990
|
b = Math.abs(b);
|
|
65640
66991
|
while (b) {
|
|
@@ -67320,10 +68671,10 @@ var ComputeEngine = class _ComputeEngine {
|
|
|
67320
68671
|
_setComputeEngineClass(ComputeEngine);
|
|
67321
68672
|
|
|
67322
68673
|
// src/compute-engine.ts
|
|
67323
|
-
var version = "0.
|
|
68674
|
+
var version = "0.54.0";
|
|
67324
68675
|
globalThis[/* @__PURE__ */ Symbol.for("io.cortexjs.compute-engine")] = {
|
|
67325
68676
|
ComputeEngine: ComputeEngine.prototype.constructor,
|
|
67326
|
-
version: "0.
|
|
68677
|
+
version: "0.54.0"
|
|
67327
68678
|
};
|
|
67328
68679
|
export {
|
|
67329
68680
|
BaseCompiler,
|