ReferenceControlArcStandard librarymath

math

Look up math.avg, math.min, math.max, math.derivative, the float checks, and the float constants of the Arc math module.

The math module gives running statistics and rates of change of a numeric value, and checks and constants for NaN and infinity. Import it with import math. avg, min, max, and derivative are flow functions: a function body cannot call them.

avg, min, and max share these parameters:

durationi64 ns = 0

Start again when this much time has passed, measured on trigger timestamps.

counti64 = 0

Start again on the next trigger after this many values.

resetbool = false

Has no effect in text mode, which cannot wire a trigger to it.

With duration and count at 0, the value covers every trigger since the stage started. A window starts again with the trigger that ends the old window. Synnax reads duration and count once, when the automation starts.

avg

Gives the average of all trigger values since the window started.

  • Trigger -> a numeric value.
  • Output -> one value for each trigger batch, of the same type as the trigger. It has the timestamp of the last value in the batch. It is not a moving average.
  • Runs -> on each new trigger. Its window starts again when its stage starts.
import math

tank_pt -> math.avg(duration=5s) -> tank_pt_avg

An integer trigger gives an integer average, rounded toward zero. On the Core, the sum uses the trigger type, so it can overflow and loses precision. Use a float trigger. A Driver sums in f64.

derivative

Gives the rate of change of the trigger, in units per second.

  • Trigger -> a numeric value.
  • Output -> one f64 value for each trigger value, with the same timestamp. The rate is the change from the previous value, divided by the time between their timestamps.
  • Runs -> on each new trigger. The first value, and a value with a timestamp that is not later than the one before it, give 0. It starts again when its stage starts.

derivative has no parameters.

import math

tank_pt -> math.derivative() -> tank_pt_rate

max

Gives the largest trigger value since the window started.

  • Trigger -> a numeric value.
  • Output -> one value for each trigger batch, of the same type as the trigger.
  • Runs -> on each new trigger. Its window starts again when its stage starts.
import math

tank_pt -> math.max() -> tank_pt_max

min

Gives the smallest trigger value since the window started.

  • Trigger -> a numeric value.
  • Output -> one value for each trigger batch, of the same type as the trigger.
  • Runs -> on each new trigger. Its window starts again when its stage starts.
import math

tank_pt -> math.min(count=1000) -> tank_pt_min

Float checks

  • is_nan(x) -> true if x is NaN.
  • is_infinite(x) -> true if x is positive or negative infinity.
  • is_finite(x) -> true if x is not NaN and not infinite.

Each check takes one f32 or f64 value and gives a bool. An integer variable fails to compile. An integer literal is read as a float. Use a check in an expression, a stage condition, or a function body.

import math

sequence main {
    stage spin_down {
        not math.is_finite(pump_speed) or pump_speed < 15 => next
    }
    stage stopped {
        1 -> pump_stopped
    }
}

Float constants

  • nan -> the NaN value.
  • inf -> the positive infinity value. -math.inf is negative infinity.

A constant fits f32 or f64, and it defaults to f64. It does not fit an integer type, and a cast of one to an integer type is a compile error. Use a constant in an expression, such as limit := math.inf * 2.0, a $= initializer, or a function input. In a flow, a constant sends its value: x -> math.nan -> y.

import math

func lowest() {x f64} f64 {
    low f64 $= math.inf
    if x < low {
        low = x
    }
    return low
}

To test for NaN, use is_nan. x != math.nan is always true, and ==, <, >, <=, or >= with math.nan is always false, so each fails with error ARC2004. Write math.is_nan(x) and not math.is_nan(x).