Tensor Math

Shipping
tensor_math

Element-wise binary op on N-D arrays with numpy broadcasting; IEEE-pure, units propagate

Signature

Inputs

  • aVector|Matrix|Tensor|ScalarrequiredLeft operand. Any rank array, or a Scalar/Integer that broadcasts to a 1-element array.
  • bVector|Matrix|Tensor|ScalarrequiredRight operand. Broadcast against `a` by numpy rules; a Scalar/Integer broadcasts to every element.

Outputs

  • resultVector|Matrix|Tensor|ScalarThe broadcast result. Rank-0 collapses to a Scalar; rank ≥ 1 is a unified Array carrying the result unit.

Parameters

KeyTypeDefaultNotes
operationenumaddone of: add, subtract, multiply, divide, power, modulo, floor_divide, min, max, atan2

Description

Tensor Math is the pure-array element-wise node: it takes two operands (a, b) — each a Vector, Matrix, Tensor, or a Scalar/Integer that broadcasts — and applies one binary operation element-by-element under numpy broadcasting. Shapes are aligned by trailing-dimension matching (size-1 axes stretch), so a column combined with a row yields a result.

It exposes the full op set, including two that the unit/σ-aware math_operator deliberately omits: floor_divide (//) and atan2(y, x). Arithmetic is IEEE-pure1/0 → +inf, 0/0 → nan, and min/max propagate NaN rather than skipping it.

Units propagate at every rank. Additive ops (add, subtract, min, max) convert the right operand into the left's unit and require matching dimensions; multiplicative ops (multiply, divide) compose units; atan2 yields radians. Unit algebra is gated on the workspace's quantities toggle, so a quantities-off user keeps bare numbers. Unlike math_operator, the pure-array path carries no σ — Arrays have no per-element variance in the data model. A Signal on either port is rejected (use math_operator for time-series).

Mathematics

Examples

Outer-style broadcast add

Wire a matrix [[0],[10],[20]] into a and a matrix [[1,2,3,4]] into b with operation = add. Broadcasting stretches both to :

[[ 1,  2,  3,  4],
 [11, 12, 13, 14],
 [21, 22, 23, 24]]

Scalar floor-divide

Feed a vector [7, 8] into a and the Scalar 2 into b with operation = floor_divide. The scalar broadcasts to every element, giving [3, 4] — the integer quotient , .

Direction from components

With operation = atan2, wire a -component vector into a and the -component into b. The result is the per-element bearing in radians, correct across all four quadrants, ready for a unit_convert to degrees.

Applications

  • Combining two N-D fields element-wise (e.g. scaling a stress tensor by a per-cell factor grid) with automatic broadcasting.
  • Quadrant-correct angle recovery from separate x/y component arrays via atan2, unavailable on the scalar math_operator.
  • Integer-style bucketing or index math on arrays with floor_divide and modulo.
  • Unit-aware array arithmetic where multiply/divide compose physical dimensions across whole grids at once.

Neat

The only `power` case with a definable result unit is a scalar-broadcast right operand — a matrix exponent has no single dimension, so the planner special-cases it.

min/max are deliberately NaN-propagating (not NaN-skipping), matching IEEE array semantics rather than the 'ignore missing' convention of the statistics node.

Unit handling reuses the same `plan_binary` semantics as the scalar path, so additive-op dimension checks and multiplicative composition behave identically from a Scalar up to an N-D Tensor.

Known issues

A Signal on either input is a hard type error — this node is array-only; route time-series through math_operator or formula.

Arrays carry no per-element uncertainty, so σ is silently absent from the result even if an upstream scalar had one.

IEEE purity means division and modulo by zero yield ±inf / nan rather than raising; check downstream for non-finite values if that matters.

See also

tensorarrayelement-wisebroadcastnumpyarithmeticatan2stateless