Math Tools
Generate, analyze, and model numeric data β no LLM, no credits, fully deterministic.
Math tools operate entirely in-process. There are no external calls, no AI generation, and no credit cost. Every response includes a deterministic receipt under _meta.datagrout so the gateway can verify the operation was reproducible. Output shapes are compatible with prism.chart (pass records) and prism.refract (pass values). All Math tools are available at data-grout@1/math.*@1.
The suite covers three areas:
-
Generation:
range,linspace,sequence,sample,interpolateβ produce numeric arrays from parameters. -
Analysis:
describe,window,normalize,outliers,rankβ summarize distributions, detect anomalies, scale, and rank data. -
Modeling:
correlate,trendβ measure relationships and fit regressions (linear, polynomial, exponential, logarithmic).
Analysis and modeling tools accept payload/cache_ref, so you can pipe integration data (or Data/Frame tool output) directly into them without re-sending through the LLM context.
math.range@1
Generate an evenly-spaced numeric sequence from start to stop. The step is computed exactly as start + i * step to avoid cumulative floating-point drift. Maximum 10,000 values per call.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
stop |
number | yes | β | Upper bound (inclusive when exactly reachable by the step) |
start |
number | no |
0 |
First value in the sequence |
step |
number | no |
1 |
Increment between consecutive values. Use a negative value when start > stop |
label |
string | no |
"value" |
Field name for the value column in each record object |
Example
{
"name": "data-grout@1/math.range@1",
"arguments": {
"start": 0,
"stop": 1,
"step": 0.25
}
}
Response:
{
"values": [0, 0.25, 0.5, 0.75, 1.0],
"records": [
{ "index": 0, "value": 0 },
{ "index": 1, "value": 0.25 },
{ "index": 2, "value": 0.5 },
{ "index": 3, "value": 0.75 },
{ "index": 4, "value": 1.0 }
],
"count": 5,
"start": 0,
"stop": 1,
"step": 0.25
}
Minimal forms: "range of 50" produces 0, 1, 2, β¦, 50. "step of -1 from 5 to 0" produces 5, 4, 3, 2, 1, 0.
math.linspace@1
Generate exactly N evenly-spaced points between start and stop. Unlike math.range (which uses a step), Linspace takes a count β equivalent to NumPyβs linspace. Maximum 10,000 points per call.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
n |
integer | yes | β | Number of points to generate. Must be β₯ 1 |
start |
number | no |
0 |
First value |
stop |
number | no |
1 |
Last value (inclusive) |
label |
string | no |
"value" |
Field name for the value column in each record |
Example
{
"name": "data-grout@1/math.linspace@1",
"arguments": {
"n": 5,
"start": 0,
"stop": 100
}
}
Response:
{
"values": [0, 25, 50, 75, 100],
"records": [
{ "index": 0, "value": 0 },
{ "index": 1, "value": 25 },
{ "index": 2, "value": 50 },
{ "index": 3, "value": 75 },
{ "index": 4, "value": 100 }
],
"count": 5,
"start": 0,
"stop": 100,
"n": 5
}
math.sequence@1
Generate a named mathematical sequence of N terms. Maximum 1,000 terms per call.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
count |
integer | yes | β | Number of terms to generate. Must be β₯ 1 |
type |
string | no |
"arithmetic" |
Sequence type. See table below |
start |
number | no | type-dependent | First term override |
step |
number | no |
1 |
Common difference (arithmetic only) |
ratio |
number | no |
2 |
Common ratio (geometric only) |
base |
number | no |
2 |
Base (powers only) |
label |
string | no |
"value" |
Field name for the value column in each record |
Sequence types
| Type | Description | Default parameters |
|---|---|---|
arithmetic |
a, a+d, a+2d, β¦ | start=0, step=1 |
geometric |
a, aΒ·r, aΒ·rΒ², β¦ | start=1, ratio=2 |
fibonacci |
1, 1, 2, 3, 5, 8, β¦ | β |
triangular |
1, 3, 6, 10, 15, β¦ | β |
square |
1, 4, 9, 16, 25, β¦ | β |
prime |
2, 3, 5, 7, 11, β¦ | β |
powers |
1, b, bΒ², bΒ³, β¦ | base=2 |
Example
{
"name": "data-grout@1/math.sequence@1",
"arguments": {
"type": "fibonacci",
"count": 8
}
}
Response:
{
"values": [1, 1, 2, 3, 5, 8, 13, 21],
"records": [
{ "index": 0, "n": 1, "value": 1 },
{ "index": 1, "n": 2, "value": 1 },
{ "index": 2, "n": 3, "value": 2 }
],
"count": 8,
"type": "fibonacci"
}
math.sample@1
Draw N random samples from a statistical distribution. Pass a seed for reproducible output. Includes a stats summary (mean, std, min, max) in the response. Maximum 10,000 samples per call.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
count |
integer | yes | β | Number of samples to draw. Must be β₯ 1 |
distribution |
string | no |
"uniform" |
One of "uniform", "normal", "exponential" |
min |
number | no |
0 |
Lower bound (uniform only) |
max |
number | no |
1 |
Upper bound (uniform only) |
mean |
number | no |
0 |
Mean ΞΌ (normal only) |
std |
number | no |
1 |
Standard deviation Ο (normal only) |
rate |
number | no |
1 |
Rate Ξ» (exponential only, must be > 0) |
seed |
integer | no | β | Integer seed for reproducible output |
label |
string | no |
"value" |
Field name for the value column in each record |
Example
{
"name": "data-grout@1/math.sample@1",
"arguments": {
"distribution": "normal",
"count": 500,
"mean": 100,
"std": 15,
"seed": 42
}
}
Response (abbreviated):
{
"values": [97.3, 112.1, 88.6, "..."],
"records": [{ "index": 0, "value": 97.3 }, "..."],
"count": 500,
"distribution": "normal",
"stats": {
"mean": 99.87,
"std": 14.92,
"min": 58.4,
"max": 143.2
}
}
math.interpolate@1
Apply an interpolation or easing operation to a scalar or a list of values. When values is provided, the operation is mapped over every element (each element serves as the primary input t/v/x). This makes it easy to apply easing curves to sequences from math.linspace or math.range without a separate prism.refract step.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
operation |
string | yes | β | Operation to apply. See table below |
values |
array | no | β | List of values to map the operation over. When given, the scalar input parameter is ignored |
t |
number | no | β | Interpolation factor [0..1] for lerp and easing operations |
a |
number | no | β |
Start value for lerp / inverse_lerp |
b |
number | no | β |
End value for lerp / inverse_lerp |
v |
number | no | β |
Input value for inverse_lerp, clamp, remap |
x |
number | no | β |
Input value for smoothstep, smootherstep |
min |
number | no | β |
Lower bound for clamp |
max |
number | no | β |
Upper bound for clamp |
edge0 |
number | no | β |
Lower edge for smoothstep / smootherstep |
edge1 |
number | no | β |
Upper edge for smoothstep / smootherstep |
in_min |
number | no | β |
Input range minimum for remap |
in_max |
number | no | β |
Input range maximum for remap |
out_min |
number | no | β |
Output range minimum for remap |
out_max |
number | no | β |
Output range maximum for remap |
Operations
| Operation | Description |
|---|---|
lerp |
Linear interpolation: a + t * (b - a) |
inverse_lerp |
Normalize v into [a, b]: (v - a) / (b - a) |
clamp |
Clamp v to [min, max] |
remap |
Map v from [in_min, in_max] to [out_min, out_max] |
smoothstep |
Ken Perlinβs smoothstep curve |
smootherstep |
Smoothstep with zero first and second derivatives at edges |
ease_in_quad / ease_out_quad / ease_in_out_quad |
Quadratic easing |
ease_in_cubic / ease_out_cubic / ease_in_out_cubic |
Cubic easing |
ease_in_quart / ease_out_quart / ease_in_out_quart |
Quartic easing |
ease_in_sine / ease_out_sine / ease_in_out_sine |
Sinusoidal easing |
Example: apply easing to a linspace
{
"name": "data-grout@1/math.interpolate@1",
"arguments": {
"operation": "ease_in_out_cubic",
"values": [0, 0.25, 0.5, 0.75, 1.0]
}
}
Response:
{
"values": [0.0, 0.0625, 0.5, 0.9375, 1.0],
"records": [
{ "index": 0, "t": 0.0, "value": 0.0 },
{ "index": 1, "t": 0.25, "value": 0.0625 },
{ "index": 2, "t": 0.5, "value": 0.5 },
{ "index": 3, "t": 0.75, "value": 0.9375 },
{ "index": 4, "t": 1.0, "value": 1.0 }
],
"operation": "ease_in_out_cubic",
"count": 5
}
Example: scalar clamp
{
"name": "data-grout@1/math.interpolate@1",
"arguments": {
"operation": "clamp",
"v": 1.75,
"min": 0,
"max": 1
}
}
Response:
{ "result": 1.0, "operation": "clamp" }
math.describe@1
Compute descriptive statistics for a numeric array. Returns count, mean, median, standard deviation, variance, min, max, sum, range, skewness, percentiles (p5/p25/p50/p75/p95), and a binned histogram for distribution visualization. Maximum 100,000 values per call.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
payload |
array | no | β |
Inline numeric array or array of records. Alternative to cache_ref |
cache_ref |
string | no | β | Reference from a prior tool response |
field |
string | no | β | When payload is records, extract this fieldβs numeric values |
bins |
integer | no |
10 |
Number of histogram bins (2β100) |
Example
{
"name": "data-grout@1/math.describe@1",
"arguments": {
"payload": [12, 15, 14, 10, 18, 22, 19, 13, 16, 20]
}
}
Response (abbreviated):
{
"count": 10,
"mean": 15.9,
"median": 15.5,
"std": 3.59,
"variance": 12.89,
"min": 10,
"max": 22,
"sum": 159,
"range": 12,
"skewness": 0.18,
"percentiles": { "p5": 10.45, "p25": 13.25, "p50": 15.5, "p75": 19.25, "p95": 21.55 },
"histogram": [
{ "bin_start": 10, "bin_end": 12.4, "count": 1 },
"..."
]
}
Works with records too: pass "field": "revenue" to describe a specific column from tabular data.
math.window@1
Apply sliding window operations to a numeric array. Supports moving average, moving sum, cumulative sum, first differences, lag, and exponentially weighted moving average (EWMA). Maximum 100,000 values per call.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
op |
string | yes | β |
Operation: moving_avg, moving_sum, cumsum, diff, pct_change, lag, ewma |
payload |
array | no | β |
Inline numeric array or array of records. Alternative to cache_ref |
cache_ref |
string | no | β | Reference from a prior tool response |
field |
string | no | β | When payload is records, extract this fieldβs numeric values |
window |
integer | no |
3 |
Window size for moving_avg and moving_sum |
n |
integer | no |
1 |
Period for lag and diff |
alpha |
number | no |
0.3 |
Smoothing factor for ewma (0 < Ξ± < 1) |
label |
string | no |
"value" |
Field name for the value column in records |
Operations
| Operation | Description |
|---|---|
moving_avg |
Rolling mean over a sliding window |
moving_sum |
Rolling sum over a sliding window |
cumsum |
Running cumulative sum |
diff |
First differences: x[i] β x[iβn] |
pct_change |
Percentage change period-over-period: (x[i] β x[iβn]) / x[iβn] Γ 100 |
lag |
Shift values forward by n positions (nulls at start) |
ewma |
Exponentially weighted moving average with smoothing factor Ξ± |
Example
{
"name": "data-grout@1/math.window@1",
"arguments": {
"op": "moving_avg",
"payload": [10, 20, 30, 40, 50, 60, 70],
"window": 3
}
}
Response:
{
"values": [null, null, 20.0, 30.0, 40.0, 50.0, 60.0],
"records": [
{ "index": 0, "value": null },
{ "index": 1, "value": null },
{ "index": 2, "value": 20.0 },
{ "index": 3, "value": 30.0 },
"..."
],
"count": 7,
"op": "moving_avg",
"window": 3
}
Null values at the start indicate insufficient data for the window. Pass records directly to prism.chart for time-series visualization.
math.correlate@1
Compute Pearson and/or Spearman correlation between two numeric series. Returns correlation coefficient, r-squared, interpretation label, and paired records for scatter plotting. Both series must have the same length.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
x |
array | no | β |
First numeric series. Alternative to payload + x_field |
y |
array | no | β |
Second numeric series. Same length as x |
payload |
array | no | β |
Array of records containing both series. Alternative to cache_ref |
cache_ref |
string | no | β | Reference from a prior tool response |
x_field |
string | no | β | Field name for x when using payload of records |
y_field |
string | no | β | Field name for y when using payload of records |
method |
string | no |
"both" |
"pearson", "spearman", or "both" |
Example: inline arrays
{
"name": "data-grout@1/math.correlate@1",
"arguments": {
"x": [1, 2, 3, 4, 5],
"y": [2, 4, 5, 4, 5]
}
}
Response:
{
"n": 5,
"pearson": {
"r": 0.8,
"r_squared": 0.64,
"interpretation": "strong positive"
},
"spearman": {
"r": 0.82,
"r_squared": 0.67,
"interpretation": "strong positive"
},
"records": [
{ "index": 0, "x": 1, "y": 2 },
{ "index": 1, "x": 2, "y": 4 },
"..."
]
}
Example: from records
{
"name": "data-grout@1/math.correlate@1",
"arguments": {
"cache_ref": "abc123",
"x_field": "ad_spend",
"y_field": "revenue",
"method": "pearson"
}
}
Pass records to prism.chart with chart_type: "scatter" for instant correlation visualization.
math.trend@1
Fit a regression model to numeric data. Supports linear (y = mx + b), polynomial (degree 2β5), exponential (y = a Γ e^(bx)), and logarithmic (y = a Γ ln(x) + b) models. Returns coefficients, r-squared, direction label, equation string, fitted values for overlay charting, and optional forecast points. Maximum 100,000 values per call.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
y |
array | no | β | Dependent variable series |
x |
array | no | β | Independent variable series. If omitted, 0-based indices are used |
payload |
array | no | β |
Array of records or numeric values. Alternative to cache_ref |
cache_ref |
string | no | β | Reference from a prior tool response |
x_field |
string | no | β | Field name for x when using payload of records |
y_field |
string | no | β | Field name for y when using payload of records |
field |
string | no | β | When payload has one numeric field, use it as y (x = indices) |
model |
string | no |
"linear" |
Regression model: linear, polynomial, exponential, logarithmic |
degree |
integer | no |
2 |
Polynomial degree (2β5). Only used with polynomial model |
forecast |
integer | no |
0 |
Number of future points to project beyond the data (0β1000) |
label |
string | no |
"value" |
Field name for values in records |
Example: simple trend
{
"name": "data-grout@1/math.trend@1",
"arguments": {
"y": [10, 12, 15, 18, 22]
}
}
Response:
{
"model": "linear",
"slope": 2.9,
"intercept": 9.5,
"coefficients": [2.9, 9.5],
"r_squared": 0.99,
"direction": "increasing",
"equation": "y = 2.9x + 9.5",
"n": 5,
"values": [9.5, 12.4, 15.3, 18.2, 21.1],
"fitted": [
{ "index": 0, "x": 0, "y_actual": 10, "y_fitted": 9.5, "value": 9.5 },
"..."
]
}
Example: polynomial fit
{
"name": "data-grout@1/math.trend@1",
"arguments": {
"x": [0, 1, 2, 3, 4],
"y": [0, 1, 4, 9, 16],
"model": "polynomial",
"degree": 2
}
}
Response includes "model": "polynomial", "degree": 2, and "coefficients": [1.0, 0.0, 0.0] (for y = xΒ²).
Example: exponential fit
{
"name": "data-grout@1/math.trend@1",
"arguments": {
"y": [100, 150, 225, 337, 506],
"model": "exponential"
}
}
Returns "equation": "y = 100.0 * e^(0.405x)" with "coefficients": [100.0, 0.405].
Example: with forecast
{
"name": "data-grout@1/math.trend@1",
"arguments": {
"cache_ref": "abc123",
"field": "revenue",
"forecast": 3
}
}
Forecast points extend beyond the original data using the fitted model. The response includes both in-sample fitted values and out-of-sample forecasts in a single fitted array, with forecast records having y_actual: null.
Overlay fitted on original data in prism.chart to visualize the trend line and projections.
math.normalize@1
Scale a numeric array using z-score, min-max, or percentile rank normalization. Returns normalized values, transform parameters, and records for charting original vs. normalized values. Maximum 100,000 values per call.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
payload |
array | no | β |
Inline numeric array or array of records. Alternative to cache_ref |
cache_ref |
string | no | β | Reference from a prior tool response |
field |
string | no | β | When payload is records, extract this fieldβs numeric values |
method |
string | no |
"zscore" |
Normalization method: zscore, minmax, rank |
min_out |
number | no |
0 |
Lower bound for minmax output range |
max_out |
number | no |
1 |
Upper bound for minmax output range |
label |
string | no |
"value" |
Field name for the normalized value in records |
Methods
| Method | Description |
|---|---|
zscore |
(x β mean) / std β centers data to mean=0, std=1 |
minmax |
(x β min) / (max β min), scaled to [min_out, max_out] |
rank |
Percentile rank 0β100 |
Example
{
"name": "data-grout@1/math.normalize@1",
"arguments": {
"payload": [10, 20, 30, 40, 50],
"method": "minmax"
}
}
Response:
{
"values": [0.0, 0.25, 0.5, 0.75, 1.0],
"records": [
{ "index": 0, "original": 10, "value": 0.0 },
{ "index": 1, "original": 20, "value": 0.25 },
"..."
],
"count": 5,
"method": "minmax",
"stats": { "input_min": 10, "input_max": 50, "output_min": 0, "output_max": 1 }
}
Useful for preparing features for comparison, scoring, or visualization when values are on different scales.
math.outliers@1
Detect outliers in a numeric array using IQR (interquartile range) or z-score methods. Returns outlier indices, threshold bounds, a clean array with outliers removed, and per-value records with outlier flags. Maximum 100,000 values per call.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
payload |
array | no | β |
Inline numeric array or array of records. Alternative to cache_ref |
cache_ref |
string | no | β | Reference from a prior tool response |
field |
string | no | β | When payload is records, extract this fieldβs numeric values |
method |
string | no |
"iqr" |
Detection method: iqr or zscore |
k |
number | no |
1.5 |
IQR multiplier: 1.5 = standard outliers, 3.0 = extreme outliers |
threshold |
number | no |
3.0 |
Z-score threshold for the zscore method |
Example
{
"name": "data-grout@1/math.outliers@1",
"arguments": {
"payload": [12, 14, 13, 15, 14, 13, 100, 12, 15, 14],
"method": "iqr"
}
}
Response:
{
"count": 10,
"outlier_count": 1,
"outlier_pct": 10.0,
"method": "iqr",
"bounds": { "lower": 9.25, "upper": 18.75 },
"outliers": [
{ "index": 6, "value": 100, "side": "high" }
],
"clean_values": [12, 14, 13, 15, 14, 13, 12, 15, 14],
"values": [false, false, false, false, false, false, true, false, false, false],
"records": [
{ "index": 0, "value": 12, "is_outlier": false },
"..."
]
}
Use clean_values as input to downstream tools to automatically exclude anomalies. The values boolean mask and records with is_outlier flags enable visualization of outlier positions.
math.rank@1
Assign ranks to a numeric array. Supports ordinal, dense, average, and percentile ranking methods. By default, ranks in descending order (highest value = rank 1). Maximum 100,000 values per call.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
payload |
array | no | β |
Inline numeric array or array of records. Alternative to cache_ref |
cache_ref |
string | no | β | Reference from a prior tool response |
field |
string | no | β | When payload is records, extract this fieldβs numeric values |
method |
string | no |
"dense" |
Ranking method: ordinal, dense, average, percentile |
ascending |
boolean | no |
false |
If true, smallest value gets rank 1 |
label |
string | no |
"rank" |
Field name for the rank column in records |
Methods
| Method | Description | Example (values: 30, 20, 20, 10) |
|---|---|---|
ordinal |
Each value gets a unique sequential rank | 1, 2, 3, 4 |
dense |
Ties share rank, next rank increments by 1 | 1, 2, 2, 3 |
average |
Ties share the mean of their ordinal ranks | 1, 2.5, 2.5, 4 |
percentile |
Percentile rank 0β100 | 0, 33.3, 33.3, 100 |
Example
{
"name": "data-grout@1/math.rank@1",
"arguments": {
"payload": [85, 92, 78, 92, 88],
"method": "dense"
}
}
Response:
{
"values": [3, 1, 4, 1, 2],
"records": [
{ "index": 0, "original": 85, "rank": 3 },
{ "index": 1, "original": 92, "rank": 1 },
{ "index": 2, "original": 78, "rank": 4 },
{ "index": 3, "original": 92, "rank": 1 },
{ "index": 4, "original": 88, "rank": 2 }
],
"count": 5,
"method": "dense",
"ties": 1
}
Useful for leaderboards, percentile scoring, and rank-based comparisons across datasets with different scales.