@cortex-js/compute-engine 0.55.2 → 0.55.4
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/compile.esm.js +908 -176
- package/dist/compile.min.esm.js +441 -71
- package/dist/compile.min.umd.cjs +442 -72
- package/dist/compile.umd.cjs +908 -176
- package/dist/compute-engine.esm.js +954 -185
- package/dist/compute-engine.min.esm.js +444 -74
- package/dist/compute-engine.min.umd.cjs +444 -74
- package/dist/compute-engine.umd.cjs +954 -185
- package/dist/core.esm.js +951 -174
- package/dist/core.min.esm.js +442 -72
- package/dist/core.min.umd.cjs +442 -72
- package/dist/core.umd.cjs +951 -174
- package/dist/interval.esm.js +2 -2
- package/dist/interval.min.esm.js +2 -2
- package/dist/interval.min.umd.cjs +2 -2
- package/dist/interval.umd.cjs +2 -2
- package/dist/latex-syntax.esm.js +43 -13
- package/dist/latex-syntax.min.esm.js +5 -5
- package/dist/latex-syntax.min.umd.cjs +5 -5
- package/dist/latex-syntax.umd.cjs +43 -13
- package/dist/math-json.esm.js +2 -2
- package/dist/math-json.min.esm.js +2 -2
- package/dist/math-json.min.umd.cjs +2 -2
- package/dist/math-json.umd.cjs +2 -2
- package/dist/numerics.esm.js +2 -2
- package/dist/numerics.min.esm.js +2 -2
- package/dist/numerics.min.umd.cjs +2 -2
- package/dist/numerics.umd.cjs +2 -2
- package/dist/types/big-decimal/big-decimal.d.ts +1 -1
- package/dist/types/big-decimal/index.d.ts +1 -1
- package/dist/types/big-decimal/transcendentals.d.ts +1 -1
- package/dist/types/big-decimal/utils.d.ts +1 -1
- 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/compile.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 +1 -1
- 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 +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +8 -7
- package/dist/types/compute-engine/compilation/compile-expression.d.ts +1 -1
- package/dist/types/compute-engine/compilation/constant-folding.d.ts +50 -0
- package/dist/types/compute-engine/compilation/fractal-orbit.d.ts +13 -0
- package/dist/types/compute-engine/compilation/glsl-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/gpu-target.d.ts +47 -1
- package/dist/types/compute-engine/compilation/interval-javascript-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/javascript-target.d.ts +23 -1
- package/dist/types/compute-engine/compilation/python-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/types.d.ts +48 -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-library-bootstrap.d.ts +1 -1
- package/dist/types/compute-engine/engine-numeric-configuration.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/default-dictionary.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/latex-syntax.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/linear-algebra.d.ts +1 -1
- package/dist/types/compute-engine/numerics/monte-carlo.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-bigint.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-bignum.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-complex.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric.d.ts +1 -1
- package/dist/types/compute-engine/numerics/primes.d.ts +1 -1
- package/dist/types/compute-engine/numerics/rationals.d.ts +1 -1
- package/dist/types/compute-engine/numerics/richardson.d.ts +1 -1
- package/dist/types/compute-engine/numerics/special-functions.d.ts +1 -1
- package/dist/types/compute-engine/numerics/statistics.d.ts +1 -1
- package/dist/types/compute-engine/numerics/strings.d.ts +1 -1
- package/dist/types/compute-engine/numerics/types.d.ts +1 -1
- package/dist/types/compute-engine/numerics/unit-data.d.ts +1 -1
- package/dist/types/compute-engine/oeis.d.ts +1 -1
- package/dist/types/compute-engine/sequence.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/antiderivative.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/derivative.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/distribute.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/fu-cost.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/fu-transforms.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/fu.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/logic-utils.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-abs.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-divide.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-factorial.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-hyperbolic.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-infinity.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-log.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-logic.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-power.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-product.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-rules.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-sum.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-trig.d.ts +1 -1
- package/dist/types/compute-engine/tensor/tensor-fields.d.ts +1 -1
- package/dist/types/compute-engine/tensor/tensors.d.ts +1 -1
- package/dist/types/compute-engine/types-definitions.d.ts +1 -1
- package/dist/types/compute-engine/types-engine.d.ts +1 -1
- package/dist/types/compute-engine/types-evaluation.d.ts +1 -1
- package/dist/types/compute-engine/types-expression.d.ts +1 -1
- package/dist/types/compute-engine/types-kernel-evaluation.d.ts +1 -1
- package/dist/types/compute-engine/types-kernel-serialization.d.ts +1 -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/core.d.ts +1 -1
- package/dist/types/interval.d.ts +1 -1
- package/dist/types/latex-syntax.d.ts +2 -2
- 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/dist/types/numerics.d.ts +1 -1
- package/package.json +3 -3
package/dist/compile.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Compute Engine 0.55.
|
|
1
|
+
/** Compute Engine 0.55.4 */
|
|
2
2
|
|
|
3
3
|
// src/compute-engine/numerics/richardson.ts
|
|
4
4
|
function extrapolate(f, x0, options = {}) {
|
|
@@ -3936,12 +3936,6 @@ function makeLambda(expr) {
|
|
|
3936
3936
|
function applicable(fn) {
|
|
3937
3937
|
return makeLambda(fn) ?? ((xs) => fn.engine.function("Apply", [fn, ...xs]).evaluate());
|
|
3938
3938
|
}
|
|
3939
|
-
function applicableN1(fn) {
|
|
3940
|
-
const lambda = makeLambda(fn);
|
|
3941
|
-
const ce = fn.engine;
|
|
3942
|
-
if (lambda) return (x) => lambda([ce.number(x)])?.re ?? NaN;
|
|
3943
|
-
return (x) => ce.function("Apply", [fn, ce.number(x)]).evaluate().re;
|
|
3944
|
-
}
|
|
3945
3939
|
|
|
3946
3940
|
// src/compute-engine/collection-utils.ts
|
|
3947
3941
|
function isFiniteIndexedCollection(col) {
|
|
@@ -14666,8 +14660,11 @@ var BaseCompiler = class _BaseCompiler {
|
|
|
14666
14660
|
for (const local of locals) {
|
|
14667
14661
|
for (const arg of args) {
|
|
14668
14662
|
if (isFunction2(arg, "Assign") && isSymbol2(arg.ops[0], local)) {
|
|
14669
|
-
|
|
14663
|
+
const rhs = arg.ops[1];
|
|
14664
|
+
if (_BaseCompiler.isComplexValued(rhs)) {
|
|
14670
14665
|
typeHints[local] = isWGSL ? "vec2f" : "vec2";
|
|
14666
|
+
} else if (_BaseCompiler.isIntegerValued(rhs)) {
|
|
14667
|
+
typeHints[local] = isWGSL ? "i32" : "int";
|
|
14671
14668
|
}
|
|
14672
14669
|
break;
|
|
14673
14670
|
}
|
|
@@ -14872,12 +14869,9 @@ var BaseCompiler = class _BaseCompiler {
|
|
|
14872
14869
|
/**
|
|
14873
14870
|
* Determine at compile time whether an expression produces a complex value.
|
|
14874
14871
|
*
|
|
14875
|
-
*
|
|
14876
|
-
*
|
|
14877
|
-
*
|
|
14878
|
-
* (undefined is treated as real -- assume-real policy)
|
|
14879
|
-
* - Functions: Abs, Arg, Re, Im always return real.
|
|
14880
|
-
* All others: complex if any operand is complex.
|
|
14872
|
+
* Uses the expression's declared type (from operator signatures) when
|
|
14873
|
+
* available. Falls back to operand inspection for functions whose
|
|
14874
|
+
* return type is unknown.
|
|
14881
14875
|
*/
|
|
14882
14876
|
static isComplexValued(expr) {
|
|
14883
14877
|
if (isNumber(expr)) return expr.im !== 0;
|
|
@@ -14888,13 +14882,24 @@ var BaseCompiler = class _BaseCompiler {
|
|
|
14888
14882
|
return t.matches("complex") && !t.matches("real");
|
|
14889
14883
|
}
|
|
14890
14884
|
if (isFunction2(expr)) {
|
|
14891
|
-
const
|
|
14892
|
-
if (
|
|
14893
|
-
|
|
14885
|
+
const t = expr.type;
|
|
14886
|
+
if (t.matches("complex") && !t.matches("real")) return true;
|
|
14887
|
+
if (t.matches("real")) return false;
|
|
14894
14888
|
return expr.ops.some((arg) => _BaseCompiler.isComplexValued(arg));
|
|
14895
14889
|
}
|
|
14896
14890
|
return false;
|
|
14897
14891
|
}
|
|
14892
|
+
/** True if the expression is provably integer-typed. */
|
|
14893
|
+
static isIntegerValued(expr) {
|
|
14894
|
+
if (isNumber(expr)) return expr.im === 0 && Number.isInteger(expr.re);
|
|
14895
|
+
const t = expr.type;
|
|
14896
|
+
return t ? t.matches("integer") : false;
|
|
14897
|
+
}
|
|
14898
|
+
/** True if the expression is provably non-negative (sign ≥ 0). */
|
|
14899
|
+
static isNonNegative(expr) {
|
|
14900
|
+
if (isNumber(expr)) return expr.im === 0 && expr.re >= 0;
|
|
14901
|
+
return expr.isNonNegative === true;
|
|
14902
|
+
}
|
|
14898
14903
|
/**
|
|
14899
14904
|
* Generate a temporary variable name
|
|
14900
14905
|
*/
|
|
@@ -15066,20 +15071,113 @@ function compile(expr, options) {
|
|
|
15066
15071
|
} catch (e) {
|
|
15067
15072
|
if (options?.fallback ?? true) {
|
|
15068
15073
|
console.warn(
|
|
15069
|
-
`Compilation fallback for "${expr.operator}": ${e.message}`
|
|
15074
|
+
`Compilation fallback for "${expr.operator}" (target: ${options?.to ?? "javascript"}): ${e.message}`
|
|
15070
15075
|
);
|
|
15076
|
+
const ce = expr.engine;
|
|
15077
|
+
const fallbackRun = ((vars) => {
|
|
15078
|
+
ce.pushScope();
|
|
15079
|
+
try {
|
|
15080
|
+
if (vars && typeof vars === "object") {
|
|
15081
|
+
for (const [k, v] of Object.entries(vars))
|
|
15082
|
+
ce.assign(k, v);
|
|
15083
|
+
}
|
|
15084
|
+
return expr.evaluate().re;
|
|
15085
|
+
} finally {
|
|
15086
|
+
ce.popScope();
|
|
15087
|
+
}
|
|
15088
|
+
});
|
|
15071
15089
|
return {
|
|
15072
15090
|
target: options?.to ?? "javascript",
|
|
15073
15091
|
success: false,
|
|
15074
15092
|
code: "",
|
|
15075
15093
|
calling: "expression",
|
|
15076
|
-
run:
|
|
15094
|
+
run: fallbackRun
|
|
15077
15095
|
};
|
|
15078
15096
|
}
|
|
15079
15097
|
throw e;
|
|
15080
15098
|
}
|
|
15081
15099
|
}
|
|
15082
15100
|
|
|
15101
|
+
// src/compute-engine/compilation/constant-folding.ts
|
|
15102
|
+
function formatFloat(n) {
|
|
15103
|
+
const str = n.toString();
|
|
15104
|
+
if (!str.includes(".") && !str.includes("e") && !str.includes("E")) {
|
|
15105
|
+
return `${str}.0`;
|
|
15106
|
+
}
|
|
15107
|
+
return str;
|
|
15108
|
+
}
|
|
15109
|
+
function tryGetConstant(expr) {
|
|
15110
|
+
if (!isNumber(expr)) return void 0;
|
|
15111
|
+
if (expr.im !== 0) return void 0;
|
|
15112
|
+
const re = expr.re;
|
|
15113
|
+
if (!isFinite(re)) return void 0;
|
|
15114
|
+
return re;
|
|
15115
|
+
}
|
|
15116
|
+
var NUMERIC_LITERAL_RE = /^-?\d+(\.\d+)?$/;
|
|
15117
|
+
function foldTerms(terms, identity, op) {
|
|
15118
|
+
const identityValue = op === "+" ? 0 : 1;
|
|
15119
|
+
let numericAcc = null;
|
|
15120
|
+
const symbolic = [];
|
|
15121
|
+
for (const term of terms) {
|
|
15122
|
+
if (NUMERIC_LITERAL_RE.test(term)) {
|
|
15123
|
+
const val = parseFloat(term);
|
|
15124
|
+
if (op === "*" && val === 0) return "0.0";
|
|
15125
|
+
if (numericAcc === null) {
|
|
15126
|
+
numericAcc = val;
|
|
15127
|
+
} else {
|
|
15128
|
+
numericAcc = op === "+" ? numericAcc + val : numericAcc * val;
|
|
15129
|
+
}
|
|
15130
|
+
} else {
|
|
15131
|
+
symbolic.push(term);
|
|
15132
|
+
}
|
|
15133
|
+
}
|
|
15134
|
+
if (numericAcc !== null && numericAcc !== identityValue) {
|
|
15135
|
+
symbolic.unshift(formatFloat(numericAcc));
|
|
15136
|
+
}
|
|
15137
|
+
if (symbolic.length === 0) {
|
|
15138
|
+
if (numericAcc !== null) return formatFloat(numericAcc);
|
|
15139
|
+
return identity;
|
|
15140
|
+
}
|
|
15141
|
+
if (symbolic.length === 1) return symbolic[0];
|
|
15142
|
+
return symbolic.join(op === "+" ? " + " : " * ");
|
|
15143
|
+
}
|
|
15144
|
+
function tryGetComplexParts(expr, compile2) {
|
|
15145
|
+
if (isSymbol2(expr, "ImaginaryUnit")) {
|
|
15146
|
+
return { re: null, im: "1.0" };
|
|
15147
|
+
}
|
|
15148
|
+
if (isNumber(expr) && expr.im !== 0) {
|
|
15149
|
+
const re = expr.re;
|
|
15150
|
+
const im = expr.im;
|
|
15151
|
+
return {
|
|
15152
|
+
re: re !== 0 ? formatFloat(re) : null,
|
|
15153
|
+
im: formatFloat(im)
|
|
15154
|
+
};
|
|
15155
|
+
}
|
|
15156
|
+
if (isFunction2(expr, "Multiply")) {
|
|
15157
|
+
const ops = expr.ops;
|
|
15158
|
+
const iIndex = ops.findIndex(
|
|
15159
|
+
(op) => isSymbol2(op, "ImaginaryUnit") || isNumber(op) && op.re === 0 && op.im !== 0
|
|
15160
|
+
);
|
|
15161
|
+
if (iIndex >= 0) {
|
|
15162
|
+
const iFactor = ops[iIndex];
|
|
15163
|
+
const iScale = isSymbol2(iFactor, "ImaginaryUnit") ? 1 : iFactor.im;
|
|
15164
|
+
const remaining = ops.filter((_, idx) => idx !== iIndex);
|
|
15165
|
+
if (remaining.length === 0) {
|
|
15166
|
+
return { re: null, im: formatFloat(iScale) };
|
|
15167
|
+
}
|
|
15168
|
+
const compiledFactors = remaining.map((r) => compile2(r));
|
|
15169
|
+
if (iScale !== 1)
|
|
15170
|
+
compiledFactors.unshift(formatFloat(iScale));
|
|
15171
|
+
const imCode = foldTerms(compiledFactors, "1.0", "*");
|
|
15172
|
+
return { re: null, im: imCode };
|
|
15173
|
+
}
|
|
15174
|
+
}
|
|
15175
|
+
if (BaseCompiler.isComplexValued(expr)) {
|
|
15176
|
+
return null;
|
|
15177
|
+
}
|
|
15178
|
+
return { re: compile2(expr), im: null };
|
|
15179
|
+
}
|
|
15180
|
+
|
|
15083
15181
|
// node_modules/@arnog/colors/dist/index.mjs
|
|
15084
15182
|
function gammaCorrect(channel) {
|
|
15085
15183
|
const abs2 = Math.abs(channel);
|
|
@@ -16374,30 +16472,6 @@ var COOLWARM = [
|
|
|
16374
16472
|
"#ae2036",
|
|
16375
16473
|
"#b40426"
|
|
16376
16474
|
];
|
|
16377
|
-
var OCEAN_BALANCE = [
|
|
16378
|
-
"#00441b",
|
|
16379
|
-
"#006d5b",
|
|
16380
|
-
"#1a8c7d",
|
|
16381
|
-
"#2fa394",
|
|
16382
|
-
"#4fb3a3",
|
|
16383
|
-
"#6fc1b3",
|
|
16384
|
-
"#8dcfc3",
|
|
16385
|
-
"#a6dbd1",
|
|
16386
|
-
"#bfe6de",
|
|
16387
|
-
"#d7f0ea",
|
|
16388
|
-
"#f7f7f7",
|
|
16389
|
-
"#eeeeee",
|
|
16390
|
-
"#ddd8e6",
|
|
16391
|
-
"#c7bcda",
|
|
16392
|
-
"#b3a0d0",
|
|
16393
|
-
"#9f86c7",
|
|
16394
|
-
"#8d6dbd",
|
|
16395
|
-
"#7b56b1",
|
|
16396
|
-
"#6a42a3",
|
|
16397
|
-
"#5a3093",
|
|
16398
|
-
"#4a1f82",
|
|
16399
|
-
"#3b0f70"
|
|
16400
|
-
];
|
|
16401
16475
|
var reversePalette = (palette) => palette.slice().reverse();
|
|
16402
16476
|
var DIVERGING_PALETTES = {
|
|
16403
16477
|
roma: ROMA,
|
|
@@ -16409,9 +16483,7 @@ var DIVERGING_PALETTES = {
|
|
|
16409
16483
|
rdbu: RDBU,
|
|
16410
16484
|
"rdbu-reversed": reversePalette(RDBU),
|
|
16411
16485
|
coolwarm: COOLWARM,
|
|
16412
|
-
"coolwarm-reversed": reversePalette(COOLWARM)
|
|
16413
|
-
"ocean-balance": OCEAN_BALANCE,
|
|
16414
|
-
"ocean-balance-reversed": reversePalette(OCEAN_BALANCE)
|
|
16486
|
+
"coolwarm-reversed": reversePalette(COOLWARM)
|
|
16415
16487
|
};
|
|
16416
16488
|
var TURBO = [
|
|
16417
16489
|
"#30123b",
|
|
@@ -18495,6 +18567,40 @@ var GREY = [
|
|
|
18495
18567
|
"#eeeeee",
|
|
18496
18568
|
"#ffffff"
|
|
18497
18569
|
];
|
|
18570
|
+
var CMOCEAN_PHASE = [
|
|
18571
|
+
"#a8780d",
|
|
18572
|
+
"#b3701b",
|
|
18573
|
+
"#be6828",
|
|
18574
|
+
"#c75f35",
|
|
18575
|
+
"#cf5643",
|
|
18576
|
+
"#d54b53",
|
|
18577
|
+
"#db4066",
|
|
18578
|
+
"#de357b",
|
|
18579
|
+
"#df2a93",
|
|
18580
|
+
"#dc25ad",
|
|
18581
|
+
"#d529c4",
|
|
18582
|
+
"#cc34d7",
|
|
18583
|
+
"#c041e5",
|
|
18584
|
+
"#b24fef",
|
|
18585
|
+
"#a25cf3",
|
|
18586
|
+
"#9168f4",
|
|
18587
|
+
"#7d73f0",
|
|
18588
|
+
"#687ce8",
|
|
18589
|
+
"#5285dc",
|
|
18590
|
+
"#3d8bcd",
|
|
18591
|
+
"#2c90bc",
|
|
18592
|
+
"#2093ac",
|
|
18593
|
+
"#19959c",
|
|
18594
|
+
"#12978c",
|
|
18595
|
+
"#0c987c",
|
|
18596
|
+
"#119a69",
|
|
18597
|
+
"#249a52",
|
|
18598
|
+
"#409839",
|
|
18599
|
+
"#5e9420",
|
|
18600
|
+
"#778d12",
|
|
18601
|
+
"#8b860d",
|
|
18602
|
+
"#9b7f0d"
|
|
18603
|
+
];
|
|
18498
18604
|
var reversePalette2 = (palette) => palette.slice().reverse();
|
|
18499
18605
|
var SEQUENTIAL_PALETTES = {
|
|
18500
18606
|
turbo: TURBO,
|
|
@@ -18518,7 +18624,9 @@ var SEQUENTIAL_PALETTES = {
|
|
|
18518
18624
|
"rocket-reversed": reversePalette2(ROCKET),
|
|
18519
18625
|
mako: MAKO,
|
|
18520
18626
|
// blue to teal
|
|
18521
|
-
"mako-reversed": reversePalette2(MAKO)
|
|
18627
|
+
"mako-reversed": reversePalette2(MAKO),
|
|
18628
|
+
"cmocean-phase": CMOCEAN_PHASE,
|
|
18629
|
+
"cmocean-phase-reversed": reversePalette2(CMOCEAN_PHASE)
|
|
18522
18630
|
};
|
|
18523
18631
|
|
|
18524
18632
|
// src/compute-engine/numerics/special-functions.ts
|
|
@@ -19418,12 +19526,21 @@ var JAVASCRIPT_FUNCTIONS = {
|
|
|
19418
19526
|
Abs: (args, compile2) => {
|
|
19419
19527
|
if (BaseCompiler.isComplexValued(args[0]))
|
|
19420
19528
|
return `_SYS.cabs(${compile2(args[0])})`;
|
|
19529
|
+
if (BaseCompiler.isNonNegative(args[0])) return compile2(args[0]);
|
|
19421
19530
|
return `Math.abs(${compile2(args[0])})`;
|
|
19422
19531
|
},
|
|
19423
19532
|
Add: (args, compile2) => {
|
|
19424
19533
|
if (args.length === 1) return compile2(args[0]);
|
|
19425
19534
|
const anyComplex = args.some((a) => BaseCompiler.isComplexValued(a));
|
|
19426
|
-
if (!anyComplex)
|
|
19535
|
+
if (!anyComplex) {
|
|
19536
|
+
const constants = args.map(tryGetConstant);
|
|
19537
|
+
if (constants.every((c) => c !== void 0))
|
|
19538
|
+
return String(constants.reduce((a, b) => a + b, 0));
|
|
19539
|
+
const nonZero = args.filter((a) => tryGetConstant(a) !== 0);
|
|
19540
|
+
if (nonZero.length === 0) return "0";
|
|
19541
|
+
if (nonZero.length === 1) return compile2(nonZero[0]);
|
|
19542
|
+
return `(${nonZero.map((x) => compile2(x)).join(" + ")})`;
|
|
19543
|
+
}
|
|
19427
19544
|
const parts = args.map((a) => {
|
|
19428
19545
|
const code = compile2(a);
|
|
19429
19546
|
return { code, isComplex: BaseCompiler.isComplexValued(a) };
|
|
@@ -19480,7 +19597,10 @@ var JAVASCRIPT_FUNCTIONS = {
|
|
|
19480
19597
|
return `Math.atan(${compile2(args[0])})`;
|
|
19481
19598
|
},
|
|
19482
19599
|
Artanh: "Math.atanh",
|
|
19483
|
-
Ceil:
|
|
19600
|
+
Ceil: (args, compile2) => {
|
|
19601
|
+
if (BaseCompiler.isIntegerValued(args[0])) return compile2(args[0]);
|
|
19602
|
+
return `Math.ceil(${compile2(args[0])})`;
|
|
19603
|
+
},
|
|
19484
19604
|
Chop: "_SYS.chop",
|
|
19485
19605
|
Cos: (args, compile2) => {
|
|
19486
19606
|
if (BaseCompiler.isComplexValued(args[0]))
|
|
@@ -19523,7 +19643,10 @@ var JAVASCRIPT_FUNCTIONS = {
|
|
|
19523
19643
|
return `_SYS.cexp(${compile2(args[0])})`;
|
|
19524
19644
|
return `Math.exp(${compile2(args[0])})`;
|
|
19525
19645
|
},
|
|
19526
|
-
Floor:
|
|
19646
|
+
Floor: (args, compile2) => {
|
|
19647
|
+
if (BaseCompiler.isIntegerValued(args[0])) return compile2(args[0]);
|
|
19648
|
+
return `Math.floor(${compile2(args[0])})`;
|
|
19649
|
+
},
|
|
19527
19650
|
Fract: ([x], compile2) => {
|
|
19528
19651
|
if (x === null) throw new Error("Fract: no argument");
|
|
19529
19652
|
return BaseCompiler.inlineExpression("${x} - Math.floor(${x})", compile2(x));
|
|
@@ -19619,12 +19742,20 @@ var JAVASCRIPT_FUNCTIONS = {
|
|
|
19619
19742
|
if (BaseCompiler.isComplexValued(base) || BaseCompiler.isComplexValued(exp3)) {
|
|
19620
19743
|
return `_SYS.cpow(${compile2(base)}, ${compile2(exp3)})`;
|
|
19621
19744
|
}
|
|
19622
|
-
const
|
|
19623
|
-
|
|
19624
|
-
if (
|
|
19625
|
-
|
|
19626
|
-
if (
|
|
19627
|
-
if (
|
|
19745
|
+
const bConst = tryGetConstant(base);
|
|
19746
|
+
const eConst = tryGetConstant(exp3);
|
|
19747
|
+
if (bConst !== void 0 && eConst !== void 0)
|
|
19748
|
+
return String(Math.pow(bConst, eConst));
|
|
19749
|
+
if (eConst === 0) return "1";
|
|
19750
|
+
if (eConst === 1) return compile2(base);
|
|
19751
|
+
if (eConst === 2 && (isSymbol2(base) || isNumber(base))) {
|
|
19752
|
+
const code = compile2(base);
|
|
19753
|
+
return `(${code} * ${code})`;
|
|
19754
|
+
}
|
|
19755
|
+
if (eConst === -1) return `(1 / (${compile2(base)}))`;
|
|
19756
|
+
if (eConst === 0.5) return `Math.sqrt(${compile2(base)})`;
|
|
19757
|
+
if (eConst === 1 / 3) return `Math.cbrt(${compile2(base)})`;
|
|
19758
|
+
if (eConst === -0.5) return `(1 / Math.sqrt(${compile2(base)}))`;
|
|
19628
19759
|
return `Math.pow(${compile2(base)}, ${compile2(exp3)})`;
|
|
19629
19760
|
},
|
|
19630
19761
|
Range: (args, compile2) => {
|
|
@@ -19661,16 +19792,29 @@ var JAVASCRIPT_FUNCTIONS = {
|
|
|
19661
19792
|
Root: ([arg, exp3], compile2) => {
|
|
19662
19793
|
if (arg === null) throw new Error("Root: no argument");
|
|
19663
19794
|
if (exp3 === null) return `Math.sqrt(${compile2(arg)})`;
|
|
19664
|
-
|
|
19665
|
-
|
|
19666
|
-
if (
|
|
19795
|
+
const aConst = tryGetConstant(arg);
|
|
19796
|
+
const nConst = tryGetConstant(exp3);
|
|
19797
|
+
if (aConst !== void 0 && nConst !== void 0 && nConst !== 0)
|
|
19798
|
+
return String(Math.pow(aConst, 1 / nConst));
|
|
19799
|
+
if (nConst === 2) return `Math.sqrt(${compile2(arg)})`;
|
|
19800
|
+
if (nConst === 3) return `Math.cbrt(${compile2(arg)})`;
|
|
19801
|
+
if (nConst !== void 0) return `Math.pow(${compile2(arg)}, ${1 / nConst})`;
|
|
19667
19802
|
return `Math.pow(${compile2(arg)}, 1 / (${compile2(exp3)}))`;
|
|
19668
19803
|
},
|
|
19669
19804
|
Random: "Math.random",
|
|
19670
|
-
Round:
|
|
19805
|
+
Round: (args, compile2) => {
|
|
19806
|
+
if (BaseCompiler.isIntegerValued(args[0])) return compile2(args[0]);
|
|
19807
|
+
return `Math.round(${compile2(args[0])})`;
|
|
19808
|
+
},
|
|
19671
19809
|
Square: (args, compile2) => {
|
|
19672
19810
|
const arg = args[0];
|
|
19673
19811
|
if (arg === null) throw new Error("Square: no argument");
|
|
19812
|
+
const c = tryGetConstant(arg);
|
|
19813
|
+
if (c !== void 0) return String(c * c);
|
|
19814
|
+
if (isSymbol2(arg)) {
|
|
19815
|
+
const code = compile2(arg);
|
|
19816
|
+
return `(${code} * ${code})`;
|
|
19817
|
+
}
|
|
19674
19818
|
return `Math.pow(${compile2(arg)}, 2)`;
|
|
19675
19819
|
},
|
|
19676
19820
|
Sec: (args, compile2) => {
|
|
@@ -19703,6 +19847,8 @@ var JAVASCRIPT_FUNCTIONS = {
|
|
|
19703
19847
|
Sqrt: (args, compile2) => {
|
|
19704
19848
|
if (BaseCompiler.isComplexValued(args[0]))
|
|
19705
19849
|
return `_SYS.csqrt(${compile2(args[0])})`;
|
|
19850
|
+
const c = tryGetConstant(args[0]);
|
|
19851
|
+
if (c !== void 0) return String(Math.sqrt(c));
|
|
19706
19852
|
return `Math.sqrt(${compile2(args[0])})`;
|
|
19707
19853
|
},
|
|
19708
19854
|
Tan: (args, compile2) => {
|
|
@@ -19719,9 +19865,14 @@ var JAVASCRIPT_FUNCTIONS = {
|
|
|
19719
19865
|
if (a === null || b === null) throw new Error("Mod: missing argument");
|
|
19720
19866
|
const ca = compile2(a);
|
|
19721
19867
|
const cb = compile2(b);
|
|
19868
|
+
if (BaseCompiler.isIntegerValued(a) && BaseCompiler.isIntegerValued(b) && BaseCompiler.isNonNegative(a))
|
|
19869
|
+
return `(${ca} % ${cb})`;
|
|
19722
19870
|
return `((${ca} % ${cb}) + ${cb}) % ${cb}`;
|
|
19723
19871
|
},
|
|
19724
|
-
Truncate:
|
|
19872
|
+
Truncate: (args, compile2) => {
|
|
19873
|
+
if (BaseCompiler.isIntegerValued(args[0])) return compile2(args[0]);
|
|
19874
|
+
return `Math.trunc(${compile2(args[0])})`;
|
|
19875
|
+
},
|
|
19725
19876
|
Remainder: ([a, b], compile2) => {
|
|
19726
19877
|
if (a === null || b === null)
|
|
19727
19878
|
throw new Error("Remainder: missing argument");
|
|
@@ -19729,25 +19880,20 @@ var JAVASCRIPT_FUNCTIONS = {
|
|
|
19729
19880
|
a
|
|
19730
19881
|
)} / ${compile2(b)}))`;
|
|
19731
19882
|
},
|
|
19732
|
-
//
|
|
19733
|
-
|
|
19734
|
-
if (a === null || b === null) throw new Error("Subtract: missing argument");
|
|
19735
|
-
const ac = BaseCompiler.isComplexValued(a);
|
|
19736
|
-
const bc = BaseCompiler.isComplexValued(b);
|
|
19737
|
-
if (!ac && !bc) return `(${compile2(a)} - ${compile2(b)})`;
|
|
19738
|
-
const ca = compile2(a);
|
|
19739
|
-
const cb = compile2(b);
|
|
19740
|
-
const reA = ac ? `(${ca}).re` : ca;
|
|
19741
|
-
const imA = ac ? `(${ca}).im` : "0";
|
|
19742
|
-
const reB = bc ? `(${cb}).re` : cb;
|
|
19743
|
-
const imB = bc ? `(${cb}).im` : "0";
|
|
19744
|
-
return `({ re: ${reA} - ${reB}, im: ${imA} - ${imB} })`;
|
|
19745
|
-
},
|
|
19883
|
+
// No Subtract function handler — Subtract canonicalizes to Add+Negate.
|
|
19884
|
+
// The operator entry in JAVASCRIPT_OPERATORS handles any edge cases.
|
|
19746
19885
|
Divide: ([a, b], compile2) => {
|
|
19747
19886
|
if (a === null || b === null) throw new Error("Divide: missing argument");
|
|
19748
19887
|
const ac = BaseCompiler.isComplexValued(a);
|
|
19749
19888
|
const bc = BaseCompiler.isComplexValued(b);
|
|
19750
|
-
if (!ac && !bc)
|
|
19889
|
+
if (!ac && !bc) {
|
|
19890
|
+
const ca = tryGetConstant(a);
|
|
19891
|
+
const cb = tryGetConstant(b);
|
|
19892
|
+
if (ca !== void 0 && cb !== void 0 && cb !== 0)
|
|
19893
|
+
return String(ca / cb);
|
|
19894
|
+
if (cb === 1) return compile2(a);
|
|
19895
|
+
return `(${compile2(a)} / ${compile2(b)})`;
|
|
19896
|
+
}
|
|
19751
19897
|
if (ac && bc) {
|
|
19752
19898
|
return `(() => { const _a = ${compile2(a)}, _b = ${compile2(
|
|
19753
19899
|
b
|
|
@@ -19764,13 +19910,26 @@ var JAVASCRIPT_FUNCTIONS = {
|
|
|
19764
19910
|
},
|
|
19765
19911
|
Negate: ([x], compile2) => {
|
|
19766
19912
|
if (x === null) throw new Error("Negate: no argument");
|
|
19767
|
-
if (!BaseCompiler.isComplexValued(x))
|
|
19913
|
+
if (!BaseCompiler.isComplexValued(x)) {
|
|
19914
|
+
const c = tryGetConstant(x);
|
|
19915
|
+
if (c !== void 0) return String(-c);
|
|
19916
|
+
return `(-${compile2(x)})`;
|
|
19917
|
+
}
|
|
19768
19918
|
return `_SYS.cneg(${compile2(x)})`;
|
|
19769
19919
|
},
|
|
19770
19920
|
Multiply: (args, compile2) => {
|
|
19771
19921
|
if (args.length === 1) return compile2(args[0]);
|
|
19772
19922
|
const anyComplex = args.some((a) => BaseCompiler.isComplexValued(a));
|
|
19773
|
-
if (!anyComplex)
|
|
19923
|
+
if (!anyComplex) {
|
|
19924
|
+
if (args.some((a) => tryGetConstant(a) === 0)) return "0";
|
|
19925
|
+
const constants = args.map(tryGetConstant);
|
|
19926
|
+
if (constants.every((c) => c !== void 0))
|
|
19927
|
+
return String(constants.reduce((a, b) => a * b, 1));
|
|
19928
|
+
const nonOne = args.filter((a) => tryGetConstant(a) !== 1);
|
|
19929
|
+
if (nonOne.length === 0) return "1";
|
|
19930
|
+
if (nonOne.length === 1) return compile2(nonOne[0]);
|
|
19931
|
+
return `(${nonOne.map((x) => compile2(x)).join(" * ")})`;
|
|
19932
|
+
}
|
|
19774
19933
|
if (args.length === 2) {
|
|
19775
19934
|
const ac = BaseCompiler.isComplexValued(args[0]);
|
|
19776
19935
|
const bc = BaseCompiler.isComplexValued(args[1]);
|
|
@@ -19855,20 +20014,30 @@ var JAVASCRIPT_FUNCTIONS = {
|
|
|
19855
20014
|
AiryAi: "_SYS.airyAi",
|
|
19856
20015
|
AiryBi: "_SYS.airyBi",
|
|
19857
20016
|
// Combinatorics
|
|
20017
|
+
Mandelbrot: ([c, maxIter], compile2) => {
|
|
20018
|
+
if (c === null || maxIter === null)
|
|
20019
|
+
throw new Error("Mandelbrot: missing arguments");
|
|
20020
|
+
return `_SYS.mandelbrot(${compile2(c)}, ${compile2(maxIter)})`;
|
|
20021
|
+
},
|
|
20022
|
+
Julia: ([z, c, maxIter], compile2) => {
|
|
20023
|
+
if (z === null || c === null || maxIter === null)
|
|
20024
|
+
throw new Error("Julia: missing arguments");
|
|
20025
|
+
return `_SYS.julia(${compile2(z)}, ${compile2(c)}, ${compile2(maxIter)})`;
|
|
20026
|
+
},
|
|
19858
20027
|
Binomial: (args, compile2) => `_SYS.binomial(${compile2(args[0])}, ${compile2(args[1])})`,
|
|
19859
20028
|
Fibonacci: "_SYS.fibonacci",
|
|
19860
20029
|
// Complex-specific functions
|
|
19861
|
-
|
|
20030
|
+
Real: (args, compile2) => {
|
|
19862
20031
|
if (BaseCompiler.isComplexValued(args[0]))
|
|
19863
20032
|
return `(${compile2(args[0])}).re`;
|
|
19864
20033
|
return compile2(args[0]);
|
|
19865
20034
|
},
|
|
19866
|
-
|
|
20035
|
+
Imaginary: (args, compile2) => {
|
|
19867
20036
|
if (BaseCompiler.isComplexValued(args[0]))
|
|
19868
20037
|
return `(${compile2(args[0])}).im`;
|
|
19869
20038
|
return "0";
|
|
19870
20039
|
},
|
|
19871
|
-
|
|
20040
|
+
Argument: (args, compile2) => {
|
|
19872
20041
|
if (BaseCompiler.isComplexValued(args[0]))
|
|
19873
20042
|
return `_SYS.carg(${compile2(args[0])})`;
|
|
19874
20043
|
return `(${compile2(args[0])} >= 0 ? 0 : Math.PI)`;
|
|
@@ -20204,6 +20373,41 @@ var SYS_HELPERS = {
|
|
|
20204
20373
|
sinc,
|
|
20205
20374
|
fresnelS,
|
|
20206
20375
|
fresnelC,
|
|
20376
|
+
mandelbrot: (c, maxIter) => {
|
|
20377
|
+
let zx = 0, zy = 0;
|
|
20378
|
+
const cx = typeof c === "number" ? c : c.re;
|
|
20379
|
+
const cy = typeof c === "number" ? 0 : c.im;
|
|
20380
|
+
const n = Math.round(maxIter);
|
|
20381
|
+
for (let i = 0; i < n; i++) {
|
|
20382
|
+
const newZx = zx * zx - zy * zy + cx;
|
|
20383
|
+
zy = 2 * zx * zy + cy;
|
|
20384
|
+
zx = newZx;
|
|
20385
|
+
const mag2 = zx * zx + zy * zy;
|
|
20386
|
+
if (mag2 > 4) {
|
|
20387
|
+
const smooth = (i - Math.log2(Math.log2(mag2)) + 4) / n;
|
|
20388
|
+
return Math.max(0, Math.min(1, smooth));
|
|
20389
|
+
}
|
|
20390
|
+
}
|
|
20391
|
+
return 1;
|
|
20392
|
+
},
|
|
20393
|
+
julia: (z, c, maxIter) => {
|
|
20394
|
+
let zx = typeof z === "number" ? z : z.re;
|
|
20395
|
+
let zy = typeof z === "number" ? 0 : z.im;
|
|
20396
|
+
const cx = typeof c === "number" ? c : c.re;
|
|
20397
|
+
const cy = typeof c === "number" ? 0 : c.im;
|
|
20398
|
+
const n = Math.round(maxIter);
|
|
20399
|
+
for (let i = 0; i < n; i++) {
|
|
20400
|
+
const newZx = zx * zx - zy * zy + cx;
|
|
20401
|
+
zy = 2 * zx * zy + cy;
|
|
20402
|
+
zx = newZx;
|
|
20403
|
+
const mag2 = zx * zx + zy * zy;
|
|
20404
|
+
if (mag2 > 4) {
|
|
20405
|
+
const smooth = (i - Math.log2(Math.log2(mag2)) + 4) / n;
|
|
20406
|
+
return Math.max(0, Math.min(1, smooth));
|
|
20407
|
+
}
|
|
20408
|
+
}
|
|
20409
|
+
return 1;
|
|
20410
|
+
},
|
|
20207
20411
|
binomial: choose,
|
|
20208
20412
|
fibonacci,
|
|
20209
20413
|
// Complex helpers
|
|
@@ -20544,11 +20748,39 @@ function fibonacci(n) {
|
|
|
20544
20748
|
return b;
|
|
20545
20749
|
}
|
|
20546
20750
|
|
|
20751
|
+
// src/compute-engine/compilation/fractal-orbit.ts
|
|
20752
|
+
function computeReferenceOrbit(center, maxIter, precision) {
|
|
20753
|
+
const prevPrecision = BigDecimal.precision;
|
|
20754
|
+
BigDecimal.precision = precision;
|
|
20755
|
+
try {
|
|
20756
|
+
const cr = new BigDecimal(center[0]);
|
|
20757
|
+
const ci = new BigDecimal(center[1]);
|
|
20758
|
+
let zr = BigDecimal.ZERO;
|
|
20759
|
+
let zi = BigDecimal.ZERO;
|
|
20760
|
+
const ESCAPE = new BigDecimal(256);
|
|
20761
|
+
const points = [];
|
|
20762
|
+
for (let i = 0; i < maxIter; i++) {
|
|
20763
|
+
points.push(zr.toNumber(), zi.toNumber());
|
|
20764
|
+
const zr2 = zr.mul(zr).toPrecision(precision);
|
|
20765
|
+
const zi2 = zi.mul(zi).toPrecision(precision);
|
|
20766
|
+
const mag2 = zr2.add(zi2);
|
|
20767
|
+
if (mag2.cmp(ESCAPE) > 0) break;
|
|
20768
|
+
const new_zi = zr.mul(zi).toPrecision(precision).mul(2).add(ci);
|
|
20769
|
+
zr = zr2.sub(zi2).add(cr);
|
|
20770
|
+
zi = new_zi;
|
|
20771
|
+
}
|
|
20772
|
+
return new Float32Array(points);
|
|
20773
|
+
} finally {
|
|
20774
|
+
BigDecimal.precision = prevPrecision;
|
|
20775
|
+
}
|
|
20776
|
+
}
|
|
20777
|
+
|
|
20547
20778
|
// src/compute-engine/compilation/gpu-target.ts
|
|
20548
20779
|
var GPU_OPERATORS = {
|
|
20549
20780
|
Add: ["+", 11],
|
|
20550
20781
|
Negate: ["-", 14],
|
|
20551
20782
|
Subtract: ["-", 11],
|
|
20783
|
+
// Subtract canonicalizes to Add+Negate; kept as fallback
|
|
20552
20784
|
Multiply: ["*", 12],
|
|
20553
20785
|
Divide: ["/", 13],
|
|
20554
20786
|
Equal: ["==", 8],
|
|
@@ -20564,6 +20796,12 @@ var GPU_OPERATORS = {
|
|
|
20564
20796
|
function gpuVec2(target) {
|
|
20565
20797
|
return target?.language === "wgsl" ? "vec2f" : "vec2";
|
|
20566
20798
|
}
|
|
20799
|
+
function compileIntArg(expr, compile2, target) {
|
|
20800
|
+
const c = tryGetConstant(expr);
|
|
20801
|
+
if (c !== void 0 && Number.isInteger(c)) return c.toString();
|
|
20802
|
+
const intCast = target?.language === "wgsl" ? "i32" : "int";
|
|
20803
|
+
return `${intCast}(${compile2(expr)})`;
|
|
20804
|
+
}
|
|
20567
20805
|
var GPU_UNROLL_LIMIT = 100;
|
|
20568
20806
|
function compileGPUSumProduct(kind, args, _compile, target) {
|
|
20569
20807
|
if (!args[0]) throw new Error(`${kind}: no body`);
|
|
@@ -20620,94 +20858,126 @@ function compileGPUSumProduct(kind, args, _compile, target) {
|
|
|
20620
20858
|
];
|
|
20621
20859
|
return lines.join("\n");
|
|
20622
20860
|
}
|
|
20861
|
+
function selectFractalStrategy(target) {
|
|
20862
|
+
const radius = target.hints?.viewport?.radius;
|
|
20863
|
+
if (radius === void 0) return "single";
|
|
20864
|
+
if (radius > 1e-6) return "single";
|
|
20865
|
+
if (radius > 1e-14) return "double";
|
|
20866
|
+
return "perturbation";
|
|
20867
|
+
}
|
|
20623
20868
|
var GPU_FUNCTIONS = {
|
|
20624
20869
|
// Variadic arithmetic (for function-call form, e.g., with vectors)
|
|
20625
20870
|
Add: (args, compile2, target) => {
|
|
20626
20871
|
if (args.length === 0) return "0.0";
|
|
20627
20872
|
if (args.length === 1) return compile2(args[0]);
|
|
20628
20873
|
const anyComplex = args.some((a) => BaseCompiler.isComplexValued(a));
|
|
20629
|
-
if (!anyComplex)
|
|
20630
|
-
|
|
20631
|
-
|
|
20632
|
-
|
|
20633
|
-
|
|
20634
|
-
|
|
20635
|
-
},
|
|
20636
|
-
Multiply: (args, compile2, _target) => {
|
|
20637
|
-
if (args.length === 0) return "1.0";
|
|
20638
|
-
if (args.length === 1) return compile2(args[0]);
|
|
20639
|
-
const anyComplex = args.some((a) => BaseCompiler.isComplexValued(a));
|
|
20640
|
-
if (!anyComplex) return args.map((x) => compile2(x)).join(" * ");
|
|
20641
|
-
let result = compile2(args[0]);
|
|
20642
|
-
let resultIsComplex = BaseCompiler.isComplexValued(args[0]);
|
|
20643
|
-
for (let i = 1; i < args.length; i++) {
|
|
20644
|
-
const code = compile2(args[i]);
|
|
20645
|
-
const argIsComplex = BaseCompiler.isComplexValued(args[i]);
|
|
20646
|
-
if (!resultIsComplex && !argIsComplex) {
|
|
20647
|
-
result = `(${result} * ${code})`;
|
|
20648
|
-
} else if (resultIsComplex && !argIsComplex) {
|
|
20649
|
-
result = `(${code} * ${result})`;
|
|
20650
|
-
} else if (!resultIsComplex && argIsComplex) {
|
|
20651
|
-
result = `(${result} * ${code})`;
|
|
20652
|
-
resultIsComplex = true;
|
|
20653
|
-
} else {
|
|
20654
|
-
result = `_gpu_cmul(${result}, ${code})`;
|
|
20655
|
-
}
|
|
20874
|
+
if (!anyComplex) {
|
|
20875
|
+
return foldTerms(
|
|
20876
|
+
args.map((x) => compile2(x)),
|
|
20877
|
+
"0.0",
|
|
20878
|
+
"+"
|
|
20879
|
+
);
|
|
20656
20880
|
}
|
|
20657
|
-
|
|
20658
|
-
|
|
20659
|
-
|
|
20660
|
-
|
|
20881
|
+
const parts = args.map((a) => tryGetComplexParts(a, compile2));
|
|
20882
|
+
if (parts.some((p) => p === null)) {
|
|
20883
|
+
const v2 = gpuVec2(target);
|
|
20884
|
+
return args.map((a) => {
|
|
20885
|
+
const code = compile2(a);
|
|
20886
|
+
return BaseCompiler.isComplexValued(a) ? code : `${v2}(${code}, 0.0)`;
|
|
20887
|
+
}).join(" + ");
|
|
20888
|
+
}
|
|
20889
|
+
const reParts = [];
|
|
20890
|
+
const imParts = [];
|
|
20891
|
+
for (const p of parts) {
|
|
20892
|
+
if (p.re !== null) reParts.push(p.re);
|
|
20893
|
+
if (p.im !== null) imParts.push(p.im);
|
|
20894
|
+
}
|
|
20895
|
+
const reSum = foldTerms(reParts, "0.0", "+");
|
|
20896
|
+
const imSum = foldTerms(imParts, "0.0", "+");
|
|
20897
|
+
return `${gpuVec2(target)}(${reSum}, ${imSum})`;
|
|
20898
|
+
},
|
|
20899
|
+
Multiply: (args, compile2, target) => {
|
|
20900
|
+
if (args.length === 0) return "1.0";
|
|
20661
20901
|
if (args.length === 1) return compile2(args[0]);
|
|
20662
20902
|
const anyComplex = args.some((a) => BaseCompiler.isComplexValued(a));
|
|
20663
20903
|
if (!anyComplex) {
|
|
20664
|
-
|
|
20665
|
-
|
|
20666
|
-
|
|
20667
|
-
|
|
20668
|
-
|
|
20669
|
-
return result2;
|
|
20670
|
-
}
|
|
20671
|
-
const v2 = gpuVec2(target);
|
|
20672
|
-
const promote = (a) => {
|
|
20673
|
-
const code = compile2(a);
|
|
20674
|
-
return BaseCompiler.isComplexValued(a) ? code : `${v2}(${code}, 0.0)`;
|
|
20675
|
-
};
|
|
20676
|
-
if (args.length === 2) return `${promote(args[0])} - ${promote(args[1])}`;
|
|
20677
|
-
let result = promote(args[0]);
|
|
20678
|
-
for (let i = 1; i < args.length; i++) {
|
|
20679
|
-
result = `${result} - ${promote(args[i])}`;
|
|
20904
|
+
return foldTerms(
|
|
20905
|
+
args.map((x) => compile2(x)),
|
|
20906
|
+
"1.0",
|
|
20907
|
+
"*"
|
|
20908
|
+
);
|
|
20680
20909
|
}
|
|
20910
|
+
const iIndex = args.findIndex(
|
|
20911
|
+
(op) => isSymbol2(op, "ImaginaryUnit") || isNumber(op) && op.re === 0 && op.im !== 0
|
|
20912
|
+
);
|
|
20913
|
+
if (iIndex >= 0) {
|
|
20914
|
+
const iFactor = args[iIndex];
|
|
20915
|
+
const iScale = isSymbol2(iFactor, "ImaginaryUnit") ? 1 : iFactor.im;
|
|
20916
|
+
const realFactors = args.filter((_, i) => i !== iIndex);
|
|
20917
|
+
const v2 = gpuVec2(target);
|
|
20918
|
+
if (realFactors.length === 0)
|
|
20919
|
+
return `${v2}(0.0, ${formatFloat(iScale)})`;
|
|
20920
|
+
const factors = realFactors.map((f) => compile2(f));
|
|
20921
|
+
if (iScale !== 1) factors.unshift(formatFloat(iScale));
|
|
20922
|
+
const imCode = foldTerms(factors, "1.0", "*");
|
|
20923
|
+
return `${v2}(0.0, ${imCode})`;
|
|
20924
|
+
}
|
|
20925
|
+
const realCodes = [];
|
|
20926
|
+
const complexCodes = [];
|
|
20927
|
+
for (const a of args) {
|
|
20928
|
+
if (BaseCompiler.isComplexValued(a)) complexCodes.push(compile2(a));
|
|
20929
|
+
else realCodes.push(compile2(a));
|
|
20930
|
+
}
|
|
20931
|
+
const scalarCode = foldTerms(realCodes, "1.0", "*");
|
|
20932
|
+
let result = complexCodes[0];
|
|
20933
|
+
for (let i = 1; i < complexCodes.length; i++) {
|
|
20934
|
+
result = `_gpu_cmul(${result}, ${complexCodes[i]})`;
|
|
20935
|
+
}
|
|
20936
|
+
if (scalarCode !== "1.0") result = `(${scalarCode} * ${result})`;
|
|
20681
20937
|
return result;
|
|
20682
20938
|
},
|
|
20939
|
+
// No Subtract function handler — Subtract canonicalizes to Add+Negate.
|
|
20940
|
+
// The operator entry in GPU_OPERATORS handles any edge cases.
|
|
20683
20941
|
Divide: (args, compile2, target) => {
|
|
20684
20942
|
if (args.length === 0) return "1.0";
|
|
20685
20943
|
if (args.length === 1) return compile2(args[0]);
|
|
20686
20944
|
const ac = BaseCompiler.isComplexValued(args[0]);
|
|
20687
20945
|
const bc = args.length >= 2 && BaseCompiler.isComplexValued(args[1]);
|
|
20688
20946
|
if (!ac && !bc) {
|
|
20689
|
-
if (args.length === 2)
|
|
20947
|
+
if (args.length === 2) {
|
|
20948
|
+
const a = tryGetConstant(args[0]);
|
|
20949
|
+
const b = tryGetConstant(args[1]);
|
|
20950
|
+
if (a !== void 0 && b !== void 0 && b !== 0)
|
|
20951
|
+
return formatFloat(a / b);
|
|
20952
|
+
if (b === 1) return compile2(args[0]);
|
|
20953
|
+
return `${compile2(args[0])} / ${compile2(args[1])}`;
|
|
20954
|
+
}
|
|
20690
20955
|
let result = compile2(args[0]);
|
|
20691
|
-
for (let i = 1; i < args.length; i++)
|
|
20956
|
+
for (let i = 1; i < args.length; i++)
|
|
20692
20957
|
result = `${result} / ${compile2(args[i])}`;
|
|
20693
|
-
}
|
|
20694
20958
|
return result;
|
|
20695
20959
|
}
|
|
20696
20960
|
if (ac && bc) return `_gpu_cdiv(${compile2(args[0])}, ${compile2(args[1])})`;
|
|
20697
|
-
if (ac && !bc) {
|
|
20698
|
-
return `(${compile2(args[0])} / ${compile2(args[1])})`;
|
|
20699
|
-
}
|
|
20961
|
+
if (ac && !bc) return `(${compile2(args[0])} / ${compile2(args[1])})`;
|
|
20700
20962
|
const v2 = gpuVec2(target);
|
|
20701
20963
|
return `_gpu_cdiv(${v2}(${compile2(args[0])}, 0.0), ${compile2(args[1])})`;
|
|
20702
20964
|
},
|
|
20703
|
-
Negate: ([x], compile2) => {
|
|
20965
|
+
Negate: ([x], compile2, target) => {
|
|
20704
20966
|
if (x === null) throw new Error("Negate: no argument");
|
|
20967
|
+
const c = tryGetConstant(x);
|
|
20968
|
+
if (c !== void 0) return formatFloat(-c);
|
|
20969
|
+
if (isNumber(x) && x.im !== 0) {
|
|
20970
|
+
return `${gpuVec2(target)}(${formatFloat(-x.re)}, ${formatFloat(-x.im)})`;
|
|
20971
|
+
}
|
|
20972
|
+
if (isSymbol2(x, "ImaginaryUnit"))
|
|
20973
|
+
return `${gpuVec2(target)}(0.0, -1.0)`;
|
|
20705
20974
|
return `(-${compile2(x)})`;
|
|
20706
20975
|
},
|
|
20707
20976
|
// Standard math functions with complex dispatch
|
|
20708
20977
|
Abs: (args, compile2) => {
|
|
20709
20978
|
if (BaseCompiler.isComplexValued(args[0]))
|
|
20710
20979
|
return `length(${compile2(args[0])})`;
|
|
20980
|
+
if (BaseCompiler.isNonNegative(args[0])) return compile2(args[0]);
|
|
20711
20981
|
return `abs(${compile2(args[0])})`;
|
|
20712
20982
|
},
|
|
20713
20983
|
Arccos: (args, compile2) => {
|
|
@@ -20725,7 +20995,10 @@ var GPU_FUNCTIONS = {
|
|
|
20725
20995
|
return `_gpu_catan(${compile2(args[0])})`;
|
|
20726
20996
|
return `atan(${compile2(args[0])})`;
|
|
20727
20997
|
},
|
|
20728
|
-
Ceil:
|
|
20998
|
+
Ceil: (args, compile2) => {
|
|
20999
|
+
if (BaseCompiler.isIntegerValued(args[0])) return compile2(args[0]);
|
|
21000
|
+
return `ceil(${compile2(args[0])})`;
|
|
21001
|
+
},
|
|
20729
21002
|
Clamp: "clamp",
|
|
20730
21003
|
Cos: (args, compile2) => {
|
|
20731
21004
|
if (BaseCompiler.isComplexValued(args[0]))
|
|
@@ -20739,7 +21012,10 @@ var GPU_FUNCTIONS = {
|
|
|
20739
21012
|
return `exp(${compile2(args[0])})`;
|
|
20740
21013
|
},
|
|
20741
21014
|
Exp2: "exp2",
|
|
20742
|
-
Floor:
|
|
21015
|
+
Floor: (args, compile2) => {
|
|
21016
|
+
if (BaseCompiler.isIntegerValued(args[0])) return compile2(args[0]);
|
|
21017
|
+
return `floor(${compile2(args[0])})`;
|
|
21018
|
+
},
|
|
20743
21019
|
Fract: "fract",
|
|
20744
21020
|
Ln: (args, compile2) => {
|
|
20745
21021
|
if (BaseCompiler.isComplexValued(args[0]))
|
|
@@ -20761,10 +21037,25 @@ var GPU_FUNCTIONS = {
|
|
|
20761
21037
|
const eCode = BaseCompiler.isComplexValued(exp3) ? compile2(exp3) : `${v2}(${compile2(exp3)}, 0.0)`;
|
|
20762
21038
|
return `_gpu_cpow(${bCode}, ${eCode})`;
|
|
20763
21039
|
}
|
|
21040
|
+
const bConst = tryGetConstant(base);
|
|
21041
|
+
const eConst = tryGetConstant(exp3);
|
|
21042
|
+
if (bConst !== void 0 && eConst !== void 0)
|
|
21043
|
+
return formatFloat(Math.pow(bConst, eConst));
|
|
21044
|
+
if (eConst === 0) return "1.0";
|
|
21045
|
+
if (eConst === 1) return compile2(base);
|
|
21046
|
+
if (eConst === 2 && (isSymbol2(base) || isNumber(base))) {
|
|
21047
|
+
const code = compile2(base);
|
|
21048
|
+
return `(${code} * ${code})`;
|
|
21049
|
+
}
|
|
21050
|
+
if (eConst === -1) return `(1.0 / ${compile2(base)})`;
|
|
21051
|
+
if (eConst === 0.5) return `sqrt(${compile2(base)})`;
|
|
20764
21052
|
return `pow(${compile2(base)}, ${compile2(exp3)})`;
|
|
20765
21053
|
},
|
|
20766
21054
|
Radians: "radians",
|
|
20767
|
-
Round:
|
|
21055
|
+
Round: (args, compile2) => {
|
|
21056
|
+
if (BaseCompiler.isIntegerValued(args[0])) return compile2(args[0]);
|
|
21057
|
+
return `round(${compile2(args[0])})`;
|
|
21058
|
+
},
|
|
20768
21059
|
Sign: "sign",
|
|
20769
21060
|
Sin: (args, compile2) => {
|
|
20770
21061
|
if (BaseCompiler.isComplexValued(args[0]))
|
|
@@ -20775,6 +21066,8 @@ var GPU_FUNCTIONS = {
|
|
|
20775
21066
|
Sqrt: (args, compile2) => {
|
|
20776
21067
|
if (BaseCompiler.isComplexValued(args[0]))
|
|
20777
21068
|
return `_gpu_csqrt(${compile2(args[0])})`;
|
|
21069
|
+
const c = tryGetConstant(args[0]);
|
|
21070
|
+
if (c !== void 0) return formatFloat(Math.sqrt(c));
|
|
20778
21071
|
return `sqrt(${compile2(args[0])})`;
|
|
20779
21072
|
},
|
|
20780
21073
|
Step: "step",
|
|
@@ -20783,17 +21076,20 @@ var GPU_FUNCTIONS = {
|
|
|
20783
21076
|
return `_gpu_ctan(${compile2(args[0])})`;
|
|
20784
21077
|
return `tan(${compile2(args[0])})`;
|
|
20785
21078
|
},
|
|
20786
|
-
Truncate:
|
|
21079
|
+
Truncate: (args, compile2) => {
|
|
21080
|
+
if (BaseCompiler.isIntegerValued(args[0])) return compile2(args[0]);
|
|
21081
|
+
return `trunc(${compile2(args[0])})`;
|
|
21082
|
+
},
|
|
20787
21083
|
// Complex-specific functions
|
|
20788
|
-
|
|
21084
|
+
Real: (args, compile2) => {
|
|
20789
21085
|
if (BaseCompiler.isComplexValued(args[0])) return `(${compile2(args[0])}).x`;
|
|
20790
21086
|
return compile2(args[0]);
|
|
20791
21087
|
},
|
|
20792
|
-
|
|
21088
|
+
Imaginary: (args, compile2) => {
|
|
20793
21089
|
if (BaseCompiler.isComplexValued(args[0])) return `(${compile2(args[0])}).y`;
|
|
20794
21090
|
return "0.0";
|
|
20795
21091
|
},
|
|
20796
|
-
|
|
21092
|
+
Argument: (args, compile2) => {
|
|
20797
21093
|
if (BaseCompiler.isComplexValued(args[0])) {
|
|
20798
21094
|
const code = compile2(args[0]);
|
|
20799
21095
|
return `atan(${code}.y, ${code}.x)`;
|
|
@@ -21008,13 +21304,20 @@ var GPU_FUNCTIONS = {
|
|
|
21008
21304
|
},
|
|
21009
21305
|
Square: ([x], compile2) => {
|
|
21010
21306
|
if (x === null) throw new Error("Square: no argument");
|
|
21011
|
-
|
|
21012
|
-
|
|
21307
|
+
if (isSymbol2(x) || isNumber(x)) {
|
|
21308
|
+
const arg = compile2(x);
|
|
21309
|
+
return `(${arg} * ${arg})`;
|
|
21310
|
+
}
|
|
21311
|
+
return `pow(${compile2(x)}, 2.0)`;
|
|
21013
21312
|
},
|
|
21014
21313
|
Root: ([x, n], compile2) => {
|
|
21015
21314
|
if (x === null) throw new Error("Root: no argument");
|
|
21016
21315
|
if (n === null || n === void 0) return `sqrt(${compile2(x)})`;
|
|
21017
|
-
|
|
21316
|
+
const nConst = tryGetConstant(n);
|
|
21317
|
+
if (nConst === 2) return `sqrt(${compile2(x)})`;
|
|
21318
|
+
const xConst = tryGetConstant(x);
|
|
21319
|
+
if (xConst !== void 0 && nConst !== void 0)
|
|
21320
|
+
return formatFloat(Math.pow(xConst, 1 / nConst));
|
|
21018
21321
|
return `pow(${compile2(x)}, 1.0 / ${compile2(n)})`;
|
|
21019
21322
|
},
|
|
21020
21323
|
// Color functions (pure-math, GPU-compilable)
|
|
@@ -21056,18 +21359,34 @@ var GPU_FUNCTIONS = {
|
|
|
21056
21359
|
Mandelbrot: ([c, maxIter], compile2, target) => {
|
|
21057
21360
|
if (c === null || maxIter === null)
|
|
21058
21361
|
throw new Error("Mandelbrot: missing arguments");
|
|
21059
|
-
const
|
|
21060
|
-
|
|
21061
|
-
|
|
21062
|
-
|
|
21362
|
+
const iterCode = compileIntArg(maxIter, compile2, target);
|
|
21363
|
+
const strategy = selectFractalStrategy(target);
|
|
21364
|
+
if (strategy === "double") {
|
|
21365
|
+
const cCode = compile2(c);
|
|
21366
|
+
return `_fractal_mandelbrot_dp(vec4(${cCode}, vec2(0.0)), ${iterCode})`;
|
|
21367
|
+
}
|
|
21368
|
+
if (strategy === "perturbation") {
|
|
21369
|
+
const cCode = compile2(c);
|
|
21370
|
+
return `_fractal_mandelbrot_pt(${cCode}, ${iterCode})`;
|
|
21371
|
+
}
|
|
21372
|
+
return `_fractal_mandelbrot(${compile2(c)}, ${iterCode})`;
|
|
21063
21373
|
},
|
|
21064
21374
|
Julia: ([z, c, maxIter], compile2, target) => {
|
|
21065
21375
|
if (z === null || c === null || maxIter === null)
|
|
21066
21376
|
throw new Error("Julia: missing arguments");
|
|
21067
|
-
const
|
|
21068
|
-
|
|
21069
|
-
|
|
21070
|
-
|
|
21377
|
+
const iterCode = compileIntArg(maxIter, compile2, target);
|
|
21378
|
+
const strategy = selectFractalStrategy(target);
|
|
21379
|
+
if (strategy === "double") {
|
|
21380
|
+
const zCode = compile2(z);
|
|
21381
|
+
const cCode = compile2(c);
|
|
21382
|
+
return `_fractal_julia_dp(vec4(${zCode}, vec2(0.0)), vec4(${cCode}, vec2(0.0)), ${iterCode})`;
|
|
21383
|
+
}
|
|
21384
|
+
if (strategy === "perturbation") {
|
|
21385
|
+
const zCode = compile2(z);
|
|
21386
|
+
const cCode = compile2(c);
|
|
21387
|
+
return `_fractal_julia_pt(${zCode}, ${cCode}, ${iterCode})`;
|
|
21388
|
+
}
|
|
21389
|
+
return `_fractal_julia(${compile2(z)}, ${compile2(c)}, ${iterCode})`;
|
|
21071
21390
|
},
|
|
21072
21391
|
// Vector/Matrix operations
|
|
21073
21392
|
Cross: "cross",
|
|
@@ -21664,6 +21983,200 @@ fn _gpu_besselJ(n_in: i32, x_in: f32) -> f32 {
|
|
|
21664
21983
|
return sgn * vals[n] / norm;
|
|
21665
21984
|
}
|
|
21666
21985
|
`;
|
|
21986
|
+
var GPU_DS_ARITHMETIC_PREAMBLE_GLSL = `
|
|
21987
|
+
// Split a float into high and low parts for exact multiplication
|
|
21988
|
+
vec2 ds_split(float a) {
|
|
21989
|
+
const float SPLIT = 4097.0; // 2^12 + 1
|
|
21990
|
+
float t = SPLIT * a;
|
|
21991
|
+
float hi = t - (t - a);
|
|
21992
|
+
float lo = a - hi;
|
|
21993
|
+
return vec2(hi, lo);
|
|
21994
|
+
}
|
|
21995
|
+
|
|
21996
|
+
// Create a double-single from a single float
|
|
21997
|
+
vec2 ds_from(float a) {
|
|
21998
|
+
return vec2(a, 0.0);
|
|
21999
|
+
}
|
|
22000
|
+
|
|
22001
|
+
// Error-free addition (Knuth TwoSum)
|
|
22002
|
+
vec2 ds_add(vec2 a, vec2 b) {
|
|
22003
|
+
float s = a.x + b.x;
|
|
22004
|
+
float v = s - a.x;
|
|
22005
|
+
float e = (a.x - (s - v)) + (b.x - v);
|
|
22006
|
+
float lo = (a.y + b.y) + e;
|
|
22007
|
+
float hi = s + lo;
|
|
22008
|
+
lo = lo - (hi - s);
|
|
22009
|
+
return vec2(hi, lo);
|
|
22010
|
+
}
|
|
22011
|
+
|
|
22012
|
+
// Double-single subtraction
|
|
22013
|
+
vec2 ds_sub(vec2 a, vec2 b) {
|
|
22014
|
+
return ds_add(a, vec2(-b.x, -b.y));
|
|
22015
|
+
}
|
|
22016
|
+
|
|
22017
|
+
// Error-free multiplication (Dekker TwoProduct)
|
|
22018
|
+
vec2 ds_mul(vec2 a, vec2 b) {
|
|
22019
|
+
float p = a.x * b.x;
|
|
22020
|
+
vec2 sa = ds_split(a.x);
|
|
22021
|
+
vec2 sb = ds_split(b.x);
|
|
22022
|
+
float err = ((sa.x * sb.x - p) + sa.x * sb.y + sa.y * sb.x) + sa.y * sb.y;
|
|
22023
|
+
err += a.x * b.y + a.y * b.x;
|
|
22024
|
+
float hi = p + err;
|
|
22025
|
+
float lo = err - (hi - p);
|
|
22026
|
+
return vec2(hi, lo);
|
|
22027
|
+
}
|
|
22028
|
+
|
|
22029
|
+
// Optimized self-multiply
|
|
22030
|
+
vec2 ds_sqr(vec2 a) {
|
|
22031
|
+
float p = a.x * a.x;
|
|
22032
|
+
vec2 sa = ds_split(a.x);
|
|
22033
|
+
float err = ((sa.x * sa.x - p) + 2.0 * sa.x * sa.y) + sa.y * sa.y;
|
|
22034
|
+
err += 2.0 * a.x * a.y;
|
|
22035
|
+
float hi = p + err;
|
|
22036
|
+
float lo = err - (hi - p);
|
|
22037
|
+
return vec2(hi, lo);
|
|
22038
|
+
}
|
|
22039
|
+
|
|
22040
|
+
// Compare magnitude: returns -1, 0, or 1
|
|
22041
|
+
float ds_cmp(vec2 a, vec2 b) {
|
|
22042
|
+
float d = a.x - b.x;
|
|
22043
|
+
if (d != 0.0) return sign(d);
|
|
22044
|
+
return sign(a.y - b.y);
|
|
22045
|
+
}
|
|
22046
|
+
`;
|
|
22047
|
+
var GPU_DS_ARITHMETIC_PREAMBLE_WGSL = `
|
|
22048
|
+
fn ds_split(a: f32) -> vec2f {
|
|
22049
|
+
const SPLIT: f32 = 4097.0;
|
|
22050
|
+
let t = SPLIT * a;
|
|
22051
|
+
let hi = t - (t - a);
|
|
22052
|
+
let lo = a - hi;
|
|
22053
|
+
return vec2f(hi, lo);
|
|
22054
|
+
}
|
|
22055
|
+
|
|
22056
|
+
fn ds_from(a: f32) -> vec2f {
|
|
22057
|
+
return vec2f(a, 0.0);
|
|
22058
|
+
}
|
|
22059
|
+
|
|
22060
|
+
fn ds_add(a: vec2f, b: vec2f) -> vec2f {
|
|
22061
|
+
let s = a.x + b.x;
|
|
22062
|
+
let v = s - a.x;
|
|
22063
|
+
let e = (a.x - (s - v)) + (b.x - v);
|
|
22064
|
+
let lo_t = (a.y + b.y) + e;
|
|
22065
|
+
let hi = s + lo_t;
|
|
22066
|
+
let lo = lo_t - (hi - s);
|
|
22067
|
+
return vec2f(hi, lo);
|
|
22068
|
+
}
|
|
22069
|
+
|
|
22070
|
+
fn ds_sub(a: vec2f, b: vec2f) -> vec2f {
|
|
22071
|
+
return ds_add(a, vec2f(-b.x, -b.y));
|
|
22072
|
+
}
|
|
22073
|
+
|
|
22074
|
+
fn ds_mul(a: vec2f, b: vec2f) -> vec2f {
|
|
22075
|
+
let p = a.x * b.x;
|
|
22076
|
+
let sa = ds_split(a.x);
|
|
22077
|
+
let sb = ds_split(b.x);
|
|
22078
|
+
var err = ((sa.x * sb.x - p) + sa.x * sb.y + sa.y * sb.x) + sa.y * sb.y;
|
|
22079
|
+
err += a.x * b.y + a.y * b.x;
|
|
22080
|
+
let hi = p + err;
|
|
22081
|
+
let lo = err - (hi - p);
|
|
22082
|
+
return vec2f(hi, lo);
|
|
22083
|
+
}
|
|
22084
|
+
|
|
22085
|
+
fn ds_sqr(a: vec2f) -> vec2f {
|
|
22086
|
+
let p = a.x * a.x;
|
|
22087
|
+
let sa = ds_split(a.x);
|
|
22088
|
+
var err = ((sa.x * sa.x - p) + 2.0 * sa.x * sa.y) + sa.y * sa.y;
|
|
22089
|
+
err += 2.0 * a.x * a.y;
|
|
22090
|
+
let hi = p + err;
|
|
22091
|
+
let lo = err - (hi - p);
|
|
22092
|
+
return vec2f(hi, lo);
|
|
22093
|
+
}
|
|
22094
|
+
|
|
22095
|
+
fn ds_cmp(a: vec2f, b: vec2f) -> f32 {
|
|
22096
|
+
let d = a.x - b.x;
|
|
22097
|
+
if (d != 0.0) { return sign(d); }
|
|
22098
|
+
return sign(a.y - b.y);
|
|
22099
|
+
}
|
|
22100
|
+
`;
|
|
22101
|
+
var GPU_FRACTAL_DP_PREAMBLE_GLSL = `
|
|
22102
|
+
float _fractal_mandelbrot_dp(vec4 c, int maxIter) {
|
|
22103
|
+
// c = (re_hi, im_hi, re_lo, im_lo)
|
|
22104
|
+
vec2 cr = vec2(c.x, c.z); // real part as ds
|
|
22105
|
+
vec2 ci = vec2(c.y, c.w); // imag part as ds
|
|
22106
|
+
vec2 zr = vec2(0.0, 0.0);
|
|
22107
|
+
vec2 zi = vec2(0.0, 0.0);
|
|
22108
|
+
for (int i = 0; i < maxIter; i++) {
|
|
22109
|
+
vec2 zr2 = ds_sqr(zr);
|
|
22110
|
+
vec2 zi2 = ds_sqr(zi);
|
|
22111
|
+
// |z|^2 > 4.0 ?
|
|
22112
|
+
vec2 mag2 = ds_add(zr2, zi2);
|
|
22113
|
+
if (mag2.x > 4.0)
|
|
22114
|
+
return clamp((float(i) - log2(log2(mag2.x)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
22115
|
+
// z = z^2 + c
|
|
22116
|
+
vec2 new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci); // 2*zr*zi + ci
|
|
22117
|
+
zr = ds_add(ds_sub(zr2, zi2), cr); // zr^2 - zi^2 + cr
|
|
22118
|
+
zi = new_zi;
|
|
22119
|
+
}
|
|
22120
|
+
return 1.0;
|
|
22121
|
+
}
|
|
22122
|
+
|
|
22123
|
+
float _fractal_julia_dp(vec4 z_in, vec4 c, int maxIter) {
|
|
22124
|
+
vec2 zr = vec2(z_in.x, z_in.z);
|
|
22125
|
+
vec2 zi = vec2(z_in.y, z_in.w);
|
|
22126
|
+
vec2 cr = vec2(c.x, c.z);
|
|
22127
|
+
vec2 ci = vec2(c.y, c.w);
|
|
22128
|
+
for (int i = 0; i < maxIter; i++) {
|
|
22129
|
+
vec2 zr2 = ds_sqr(zr);
|
|
22130
|
+
vec2 zi2 = ds_sqr(zi);
|
|
22131
|
+
vec2 mag2 = ds_add(zr2, zi2);
|
|
22132
|
+
if (mag2.x > 4.0)
|
|
22133
|
+
return clamp((float(i) - log2(log2(mag2.x)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
22134
|
+
vec2 new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
|
|
22135
|
+
zr = ds_add(ds_sub(zr2, zi2), cr);
|
|
22136
|
+
zi = new_zi;
|
|
22137
|
+
}
|
|
22138
|
+
return 1.0;
|
|
22139
|
+
}
|
|
22140
|
+
`;
|
|
22141
|
+
var GPU_FRACTAL_DP_PREAMBLE_WGSL = `
|
|
22142
|
+
fn _fractal_mandelbrot_dp(c: vec4f, maxIter: i32) -> f32 {
|
|
22143
|
+
let cr = vec2f(c.x, c.z);
|
|
22144
|
+
let ci = vec2f(c.y, c.w);
|
|
22145
|
+
var zr = vec2f(0.0, 0.0);
|
|
22146
|
+
var zi = vec2f(0.0, 0.0);
|
|
22147
|
+
for (var i: i32 = 0; i < maxIter; i++) {
|
|
22148
|
+
let zr2 = ds_sqr(zr);
|
|
22149
|
+
let zi2 = ds_sqr(zi);
|
|
22150
|
+
let mag2 = ds_add(zr2, zi2);
|
|
22151
|
+
if (mag2.x > 4.0) {
|
|
22152
|
+
return clamp((f32(i) - log2(log2(mag2.x)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
22153
|
+
}
|
|
22154
|
+
let new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
|
|
22155
|
+
zr = ds_add(ds_sub(zr2, zi2), cr);
|
|
22156
|
+
zi = new_zi;
|
|
22157
|
+
}
|
|
22158
|
+
return 1.0;
|
|
22159
|
+
}
|
|
22160
|
+
|
|
22161
|
+
fn _fractal_julia_dp(z_in: vec4f, c: vec4f, maxIter: i32) -> f32 {
|
|
22162
|
+
var zr = vec2f(z_in.x, z_in.z);
|
|
22163
|
+
var zi = vec2f(z_in.y, z_in.w);
|
|
22164
|
+
let cr = vec2f(c.x, c.z);
|
|
22165
|
+
let ci = vec2f(c.y, c.w);
|
|
22166
|
+
for (var i: i32 = 0; i < maxIter; i++) {
|
|
22167
|
+
let zr2 = ds_sqr(zr);
|
|
22168
|
+
let zi2 = ds_sqr(zi);
|
|
22169
|
+
let mag2 = ds_add(zr2, zi2);
|
|
22170
|
+
if (mag2.x > 4.0) {
|
|
22171
|
+
return clamp((f32(i) - log2(log2(mag2.x)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
22172
|
+
}
|
|
22173
|
+
let new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
|
|
22174
|
+
zr = ds_add(ds_sub(zr2, zi2), cr);
|
|
22175
|
+
zi = new_zi;
|
|
22176
|
+
}
|
|
22177
|
+
return 1.0;
|
|
22178
|
+
}
|
|
22179
|
+
`;
|
|
21667
22180
|
var GPU_FRACTAL_PREAMBLE_GLSL = `
|
|
21668
22181
|
float _fractal_mandelbrot(vec2 c, int maxIter) {
|
|
21669
22182
|
vec2 z = vec2(0.0, 0.0);
|
|
@@ -21707,6 +22220,188 @@ fn _fractal_julia(z_in: vec2f, c: vec2f, maxIter: i32) -> f32 {
|
|
|
21707
22220
|
return 1.0;
|
|
21708
22221
|
}
|
|
21709
22222
|
`;
|
|
22223
|
+
var GPU_FRACTAL_PT_PREAMBLE_GLSL = `
|
|
22224
|
+
uniform sampler2D _refOrbit;
|
|
22225
|
+
uniform int _refOrbitLen;
|
|
22226
|
+
uniform int _refOrbitTexWidth;
|
|
22227
|
+
|
|
22228
|
+
vec2 _pt_fetch_orbit(int i) {
|
|
22229
|
+
int y = i / _refOrbitTexWidth;
|
|
22230
|
+
int x = i - y * _refOrbitTexWidth;
|
|
22231
|
+
return texelFetch(_refOrbit, ivec2(x, y), 0).rg;
|
|
22232
|
+
}
|
|
22233
|
+
|
|
22234
|
+
float _fractal_mandelbrot_pt(vec2 delta_c, int maxIter) {
|
|
22235
|
+
float dr = 0.0;
|
|
22236
|
+
float di = 0.0;
|
|
22237
|
+
int orbitLen = min(maxIter, _refOrbitLen);
|
|
22238
|
+
for (int i = 0; i < orbitLen; i++) {
|
|
22239
|
+
vec2 Zn = _pt_fetch_orbit(i);
|
|
22240
|
+
// delta_{n+1} = 2*Z_n*delta_n + delta_n^2 + delta_c
|
|
22241
|
+
float new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
22242
|
+
float new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
22243
|
+
dr = new_dr;
|
|
22244
|
+
di = new_di;
|
|
22245
|
+
// Full z = Z_{n+1} + delta for escape check
|
|
22246
|
+
vec2 Zn1 = (i + 1 < orbitLen) ? _pt_fetch_orbit(i + 1) : vec2(0.0);
|
|
22247
|
+
float zr = Zn1.x + dr;
|
|
22248
|
+
float zi = Zn1.y + di;
|
|
22249
|
+
float mag2 = zr * zr + zi * zi;
|
|
22250
|
+
if (mag2 > 4.0)
|
|
22251
|
+
return clamp((float(i) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
22252
|
+
// Glitch detection: |delta|^2 > |Z|^2
|
|
22253
|
+
float dmag2 = dr * dr + di * di;
|
|
22254
|
+
float Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
22255
|
+
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
22256
|
+
// Rebase to absolute coordinates and continue with single-float
|
|
22257
|
+
float abs_zr = Zn1.x + dr;
|
|
22258
|
+
float abs_zi = Zn1.y + di;
|
|
22259
|
+
// Reconstruct absolute c from reference + delta
|
|
22260
|
+
// (Use ds_from for the concept, but single-float suffices for fallback)
|
|
22261
|
+
float cx = abs_zr - dr + delta_c.x;
|
|
22262
|
+
float cy = abs_zi - di + delta_c.y;
|
|
22263
|
+
for (int j = i + 1; j < maxIter; j++) {
|
|
22264
|
+
float new_zr = abs_zr * abs_zr - abs_zi * abs_zi + cx;
|
|
22265
|
+
abs_zi = 2.0 * abs_zr * abs_zi + cy;
|
|
22266
|
+
abs_zr = new_zr;
|
|
22267
|
+
mag2 = abs_zr * abs_zr + abs_zi * abs_zi;
|
|
22268
|
+
if (mag2 > 4.0)
|
|
22269
|
+
return clamp((float(j) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
22270
|
+
}
|
|
22271
|
+
return 1.0;
|
|
22272
|
+
}
|
|
22273
|
+
}
|
|
22274
|
+
return 1.0;
|
|
22275
|
+
}
|
|
22276
|
+
|
|
22277
|
+
float _fractal_julia_pt(vec2 z_delta, vec2 delta_c, int maxIter) {
|
|
22278
|
+
float dr = z_delta.x;
|
|
22279
|
+
float di = z_delta.y;
|
|
22280
|
+
int orbitLen = min(maxIter, _refOrbitLen);
|
|
22281
|
+
for (int i = 0; i < orbitLen; i++) {
|
|
22282
|
+
vec2 Zn = _pt_fetch_orbit(i);
|
|
22283
|
+
float new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
22284
|
+
float new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
22285
|
+
dr = new_dr;
|
|
22286
|
+
di = new_di;
|
|
22287
|
+
vec2 Zn1 = (i + 1 < orbitLen) ? _pt_fetch_orbit(i + 1) : vec2(0.0);
|
|
22288
|
+
float zr = Zn1.x + dr;
|
|
22289
|
+
float zi = Zn1.y + di;
|
|
22290
|
+
float mag2 = zr * zr + zi * zi;
|
|
22291
|
+
if (mag2 > 4.0)
|
|
22292
|
+
return clamp((float(i) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
22293
|
+
float dmag2 = dr * dr + di * di;
|
|
22294
|
+
float Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
22295
|
+
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
22296
|
+
float abs_zr = Zn1.x + dr;
|
|
22297
|
+
float abs_zi = Zn1.y + di;
|
|
22298
|
+
float cx = delta_c.x;
|
|
22299
|
+
float cy = delta_c.y;
|
|
22300
|
+
for (int j = i + 1; j < maxIter; j++) {
|
|
22301
|
+
float new_zr = abs_zr * abs_zr - abs_zi * abs_zi + cx;
|
|
22302
|
+
abs_zi = 2.0 * abs_zr * abs_zi + cy;
|
|
22303
|
+
abs_zr = new_zr;
|
|
22304
|
+
mag2 = abs_zr * abs_zr + abs_zi * abs_zi;
|
|
22305
|
+
if (mag2 > 4.0)
|
|
22306
|
+
return clamp((float(j) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
22307
|
+
}
|
|
22308
|
+
return 1.0;
|
|
22309
|
+
}
|
|
22310
|
+
}
|
|
22311
|
+
return 1.0;
|
|
22312
|
+
}
|
|
22313
|
+
`;
|
|
22314
|
+
var GPU_FRACTAL_PT_PREAMBLE_WGSL = `
|
|
22315
|
+
@group(0) @binding(1) var _refOrbit: texture_2d<f32>;
|
|
22316
|
+
var<uniform> _refOrbitLen: i32;
|
|
22317
|
+
var<uniform> _refOrbitTexWidth: i32;
|
|
22318
|
+
|
|
22319
|
+
fn _pt_fetch_orbit(i: i32) -> vec2f {
|
|
22320
|
+
let y = i / _refOrbitTexWidth;
|
|
22321
|
+
let x = i - y * _refOrbitTexWidth;
|
|
22322
|
+
return textureLoad(_refOrbit, vec2i(x, y), 0).rg;
|
|
22323
|
+
}
|
|
22324
|
+
|
|
22325
|
+
fn _fractal_mandelbrot_pt(delta_c: vec2f, maxIter: i32) -> f32 {
|
|
22326
|
+
var dr: f32 = 0.0;
|
|
22327
|
+
var di: f32 = 0.0;
|
|
22328
|
+
let orbitLen = min(maxIter, _refOrbitLen);
|
|
22329
|
+
for (var i: i32 = 0; i < orbitLen; i++) {
|
|
22330
|
+
let Zn = _pt_fetch_orbit(i);
|
|
22331
|
+
let new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
22332
|
+
let new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
22333
|
+
dr = new_dr;
|
|
22334
|
+
di = new_di;
|
|
22335
|
+
var Zn1 = vec2f(0.0);
|
|
22336
|
+
if (i + 1 < orbitLen) { Zn1 = _pt_fetch_orbit(i + 1); }
|
|
22337
|
+
let zr = Zn1.x + dr;
|
|
22338
|
+
let zi = Zn1.y + di;
|
|
22339
|
+
var mag2 = zr * zr + zi * zi;
|
|
22340
|
+
if (mag2 > 4.0) {
|
|
22341
|
+
return clamp((f32(i) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
22342
|
+
}
|
|
22343
|
+
let dmag2 = dr * dr + di * di;
|
|
22344
|
+
let Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
22345
|
+
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
22346
|
+
var f_zr = Zn1.x + dr;
|
|
22347
|
+
var f_zi = Zn1.y + di;
|
|
22348
|
+
let cx = delta_c.x;
|
|
22349
|
+
let cy = delta_c.y;
|
|
22350
|
+
for (var j: i32 = i + 1; j < maxIter; j++) {
|
|
22351
|
+
let t_zr = f_zr * f_zr - f_zi * f_zi + cx;
|
|
22352
|
+
f_zi = 2.0 * f_zr * f_zi + cy;
|
|
22353
|
+
f_zr = t_zr;
|
|
22354
|
+
mag2 = f_zr * f_zr + f_zi * f_zi;
|
|
22355
|
+
if (mag2 > 4.0) {
|
|
22356
|
+
return clamp((f32(j) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
22357
|
+
}
|
|
22358
|
+
}
|
|
22359
|
+
return 1.0;
|
|
22360
|
+
}
|
|
22361
|
+
}
|
|
22362
|
+
return 1.0;
|
|
22363
|
+
}
|
|
22364
|
+
|
|
22365
|
+
fn _fractal_julia_pt(z_delta: vec2f, delta_c: vec2f, maxIter: i32) -> f32 {
|
|
22366
|
+
var dr = z_delta.x;
|
|
22367
|
+
var di = z_delta.y;
|
|
22368
|
+
let orbitLen = min(maxIter, _refOrbitLen);
|
|
22369
|
+
for (var i: i32 = 0; i < orbitLen; i++) {
|
|
22370
|
+
let Zn = _pt_fetch_orbit(i);
|
|
22371
|
+
let new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
22372
|
+
let new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
22373
|
+
dr = new_dr;
|
|
22374
|
+
di = new_di;
|
|
22375
|
+
var Zn1 = vec2f(0.0);
|
|
22376
|
+
if (i + 1 < orbitLen) { Zn1 = _pt_fetch_orbit(i + 1); }
|
|
22377
|
+
let zr = Zn1.x + dr;
|
|
22378
|
+
let zi = Zn1.y + di;
|
|
22379
|
+
var mag2 = zr * zr + zi * zi;
|
|
22380
|
+
if (mag2 > 4.0) {
|
|
22381
|
+
return clamp((f32(i) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
22382
|
+
}
|
|
22383
|
+
let dmag2 = dr * dr + di * di;
|
|
22384
|
+
let Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
22385
|
+
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
22386
|
+
var f_zr = Zn1.x + dr;
|
|
22387
|
+
var f_zi = Zn1.y + di;
|
|
22388
|
+
let cx = delta_c.x;
|
|
22389
|
+
let cy = delta_c.y;
|
|
22390
|
+
for (var j: i32 = i + 1; j < maxIter; j++) {
|
|
22391
|
+
let t_zr = f_zr * f_zr - f_zi * f_zi + cx;
|
|
22392
|
+
f_zi = 2.0 * f_zr * f_zi + cy;
|
|
22393
|
+
f_zr = t_zr;
|
|
22394
|
+
mag2 = f_zr * f_zr + f_zi * f_zi;
|
|
22395
|
+
if (mag2 > 4.0) {
|
|
22396
|
+
return clamp((f32(j) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
22397
|
+
}
|
|
22398
|
+
}
|
|
22399
|
+
return 1.0;
|
|
22400
|
+
}
|
|
22401
|
+
}
|
|
22402
|
+
return 1.0;
|
|
22403
|
+
}
|
|
22404
|
+
`;
|
|
21710
22405
|
var GPU_COLOR_PREAMBLE_GLSL = `
|
|
21711
22406
|
float _gpu_srgb_to_linear(float c) {
|
|
21712
22407
|
if (c <= 0.04045) return c / 12.92;
|
|
@@ -22145,6 +22840,7 @@ var GPUShaderTarget = class {
|
|
|
22145
22840
|
const constants = this.getConstants();
|
|
22146
22841
|
const v2 = this.languageId === "wgsl" ? "vec2f" : "vec2";
|
|
22147
22842
|
const target = this.createTarget({
|
|
22843
|
+
hints: options.hints,
|
|
22148
22844
|
functions: (id) => {
|
|
22149
22845
|
if (userFunctions && id in userFunctions) {
|
|
22150
22846
|
const fn = userFunctions[id];
|
|
@@ -22183,12 +22879,65 @@ var GPUShaderTarget = class {
|
|
|
22183
22879
|
if (code.includes("_gpu_besselJ"))
|
|
22184
22880
|
preamble += this.languageId === "wgsl" ? GPU_BESSELJ_PREAMBLE_WGSL : GPU_BESSELJ_PREAMBLE_GLSL;
|
|
22185
22881
|
if (code.includes("_fractal_")) {
|
|
22186
|
-
|
|
22882
|
+
if (code.includes("_fractal_mandelbrot_pt") || code.includes("_fractal_julia_pt")) {
|
|
22883
|
+
preamble += this.languageId === "wgsl" ? GPU_DS_ARITHMETIC_PREAMBLE_WGSL : GPU_DS_ARITHMETIC_PREAMBLE_GLSL;
|
|
22884
|
+
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PT_PREAMBLE_WGSL : GPU_FRACTAL_PT_PREAMBLE_GLSL;
|
|
22885
|
+
} else if (code.includes("_fractal_mandelbrot_dp") || code.includes("_fractal_julia_dp")) {
|
|
22886
|
+
preamble += this.languageId === "wgsl" ? GPU_DS_ARITHMETIC_PREAMBLE_WGSL : GPU_DS_ARITHMETIC_PREAMBLE_GLSL;
|
|
22887
|
+
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_DP_PREAMBLE_WGSL : GPU_FRACTAL_DP_PREAMBLE_GLSL;
|
|
22888
|
+
} else {
|
|
22889
|
+
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PREAMBLE_WGSL : GPU_FRACTAL_PREAMBLE_GLSL;
|
|
22890
|
+
}
|
|
22187
22891
|
}
|
|
22188
22892
|
if (code.includes("_gpu_srgb_to") || code.includes("_gpu_oklab") || code.includes("_gpu_oklch") || code.includes("_gpu_color_mix") || code.includes("_gpu_apca")) {
|
|
22189
22893
|
preamble += this.languageId === "wgsl" ? GPU_COLOR_PREAMBLE_WGSL : GPU_COLOR_PREAMBLE_GLSL;
|
|
22190
22894
|
}
|
|
22191
22895
|
if (preamble) result.preamble = preamble;
|
|
22896
|
+
if (code.includes("_fractal_") && options.hints?.viewport) {
|
|
22897
|
+
const strategy = selectFractalStrategy(target);
|
|
22898
|
+
const radius = options.hints.viewport.radius;
|
|
22899
|
+
switch (strategy) {
|
|
22900
|
+
case "single":
|
|
22901
|
+
result.staleWhen = { radiusBelow: 1e-6 };
|
|
22902
|
+
break;
|
|
22903
|
+
case "double":
|
|
22904
|
+
result.staleWhen = { radiusBelow: 1e-14, radiusAbove: 1e-5 };
|
|
22905
|
+
break;
|
|
22906
|
+
case "perturbation":
|
|
22907
|
+
result.staleWhen = {
|
|
22908
|
+
radiusAbove: 1e-5,
|
|
22909
|
+
radiusBelow: radius * 0.01,
|
|
22910
|
+
centerDistance: radius * 2
|
|
22911
|
+
};
|
|
22912
|
+
break;
|
|
22913
|
+
}
|
|
22914
|
+
}
|
|
22915
|
+
if ((code.includes("_fractal_mandelbrot_pt") || code.includes("_fractal_julia_pt")) && options.hints?.viewport) {
|
|
22916
|
+
const viewport = options.hints.viewport;
|
|
22917
|
+
const digits = Math.max(50, Math.ceil(-Math.log10(viewport.radius)) + 10);
|
|
22918
|
+
const maxIter = 1e3;
|
|
22919
|
+
const orbit = computeReferenceOrbit(
|
|
22920
|
+
viewport.center,
|
|
22921
|
+
maxIter,
|
|
22922
|
+
digits
|
|
22923
|
+
);
|
|
22924
|
+
const orbitLen = orbit.length / 2;
|
|
22925
|
+
const texWidth = Math.min(orbitLen, 4096);
|
|
22926
|
+
const texHeight = Math.ceil(orbitLen / texWidth);
|
|
22927
|
+
result.textures = {
|
|
22928
|
+
_refOrbit: {
|
|
22929
|
+
data: orbit,
|
|
22930
|
+
width: texWidth,
|
|
22931
|
+
height: texHeight,
|
|
22932
|
+
format: "rg32f"
|
|
22933
|
+
}
|
|
22934
|
+
};
|
|
22935
|
+
result.uniforms = {
|
|
22936
|
+
...result.uniforms,
|
|
22937
|
+
_refOrbitLen: orbitLen,
|
|
22938
|
+
_refOrbitTexWidth: texWidth
|
|
22939
|
+
};
|
|
22940
|
+
}
|
|
22192
22941
|
return result;
|
|
22193
22942
|
}
|
|
22194
22943
|
compileToSource(expr, _options = {}) {
|
|
@@ -22422,6 +23171,7 @@ var PYTHON_OPERATORS = {
|
|
|
22422
23171
|
Negate: ["-", 14],
|
|
22423
23172
|
// Unary operator
|
|
22424
23173
|
Subtract: ["-", 11],
|
|
23174
|
+
// Subtract canonicalizes to Add+Negate; kept as fallback
|
|
22425
23175
|
Multiply: ["*", 12],
|
|
22426
23176
|
Divide: ["/", 13],
|
|
22427
23177
|
Power: ["**", 15],
|
|
@@ -22449,16 +23199,7 @@ var PYTHON_FUNCTIONS = {
|
|
|
22449
23199
|
if (args.length === 1) return compile2(args[0]);
|
|
22450
23200
|
return args.map((x) => compile2(x)).join(" * ");
|
|
22451
23201
|
},
|
|
22452
|
-
Subtract
|
|
22453
|
-
if (args.length === 0) return "0";
|
|
22454
|
-
if (args.length === 1) return compile2(args[0]);
|
|
22455
|
-
if (args.length === 2) return `${compile2(args[0])} - ${compile2(args[1])}`;
|
|
22456
|
-
let result = compile2(args[0]);
|
|
22457
|
-
for (let i = 1; i < args.length; i++) {
|
|
22458
|
-
result = `${result} - ${compile2(args[i])}`;
|
|
22459
|
-
}
|
|
22460
|
-
return result;
|
|
22461
|
-
},
|
|
23202
|
+
// No Subtract handler — canonicalizes to Add+Negate before compilation.
|
|
22462
23203
|
Divide: (args, compile2) => {
|
|
22463
23204
|
if (args.length === 0) return "1";
|
|
22464
23205
|
if (args.length === 1) return compile2(args[0]);
|
|
@@ -24123,6 +24864,7 @@ var INTERVAL_JAVASCRIPT_OPERATORS = {
|
|
|
24123
24864
|
Add: ["_IA.add", 20],
|
|
24124
24865
|
Negate: ["_IA.negate", 20],
|
|
24125
24866
|
Subtract: ["_IA.sub", 20],
|
|
24867
|
+
// Subtract canonicalizes to Add+Negate; kept as fallback
|
|
24126
24868
|
Multiply: ["_IA.mul", 20],
|
|
24127
24869
|
Divide: ["_IA.div", 20],
|
|
24128
24870
|
// Comparisons return BoolInterval
|
|
@@ -24147,17 +24889,7 @@ var INTERVAL_JAVASCRIPT_FUNCTIONS = {
|
|
|
24147
24889
|
}
|
|
24148
24890
|
return result;
|
|
24149
24891
|
},
|
|
24150
|
-
Subtract
|
|
24151
|
-
if (args.length === 0) return "_IA.point(0)";
|
|
24152
|
-
if (args.length === 1) return `_IA.negate(${compile2(args[0])})`;
|
|
24153
|
-
if (args.length === 2)
|
|
24154
|
-
return `_IA.sub(${compile2(args[0])}, ${compile2(args[1])})`;
|
|
24155
|
-
let result = compile2(args[0]);
|
|
24156
|
-
for (let i = 1; i < args.length; i++) {
|
|
24157
|
-
result = `_IA.sub(${result}, ${compile2(args[i])})`;
|
|
24158
|
-
}
|
|
24159
|
-
return result;
|
|
24160
|
-
},
|
|
24892
|
+
// No Subtract handler — canonicalizes to Add+Negate before compilation.
|
|
24161
24893
|
Multiply: (args, compile2) => {
|
|
24162
24894
|
if (args.length === 0) return "_IA.point(1)";
|
|
24163
24895
|
if (args.length === 1) return compile2(args[0]);
|
|
@@ -24540,7 +25272,7 @@ function compileToIntervalTarget(expr, target) {
|
|
|
24540
25272
|
}
|
|
24541
25273
|
|
|
24542
25274
|
// src/compile.ts
|
|
24543
|
-
var version = "0.55.
|
|
25275
|
+
var version = "0.55.4";
|
|
24544
25276
|
export {
|
|
24545
25277
|
BaseCompiler,
|
|
24546
25278
|
GLSLTarget,
|