Tensor Math
Shippingtensor_mathElement-wise binary op on N-D arrays with numpy broadcasting; IEEE-pure, units propagate
Signature
Inputs
aVector|Matrix|Tensor|Scalarrequired— Left operand. Any rank array, or a Scalar/Integer that broadcasts to a 1-element array.bVector|Matrix|Tensor|Scalarrequired— Right operand. Broadcast against `a` by numpy rules; a Scalar/Integer broadcasts to every element.
Outputs
resultVector|Matrix|Tensor|Scalar— The broadcast result. Rank-0 collapses to a Scalar; rank ≥ 1 is a unified Array carrying the result unit.
Parameters
| Key | Type | Default | Notes |
|---|---|---|---|
operation | enum | add | one 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-pure — 1/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.