{
  "access": "public",
  "type": "reference",
  "format": "markdown",
  "title": "Math Tools Reference",
  "chunked": true,
  "url": "https://library.datagrout.ai/math-tools",
  "summary": "Generate, analyze, and model numeric data — no LLM, no credits, fully deterministic.",
  "content_markdown": "# Math Tools\n\nGenerate, analyze, and model numeric data — no LLM, no credits, fully deterministic.\n\nMath 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`.\n\nThe suite covers three areas:\n\n- **Generation**: `range`, `linspace`, `sequence`, `sample`, `interpolate` — produce numeric arrays from parameters.\n- **Analysis**: `describe`, `window`, `normalize`, `outliers`, `rank` — summarize distributions, detect anomalies, scale, and rank data.\n- **Modeling**: `correlate`, `trend` — measure relationships and fit regressions (linear, polynomial, exponential, logarithmic).\n\nAnalysis 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.\n\n---\n\n## `math.range@1`\n\nGenerate 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.\n\n### Parameters\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `stop` | number | yes | -- | Upper bound (inclusive when exactly reachable by the step) |\n| `start` | number | no | `0` | First value in the sequence |\n| `step` | number | no | `1` | Increment between consecutive values. Use a negative value when `start > stop` |\n| `label` | string | no | `\"value\"` | Field name for the value column in each record object |\n\n### Example\n\n```json\n{\n  \"name\": \"data-grout@1/math.range@1\",\n  \"arguments\": {\n    \"start\": 0,\n    \"stop\": 1,\n    \"step\": 0.25\n  }\n}\n```\n\nResponse:\n\n```json\n{\n  \"values\": [0, 0.25, 0.5, 0.75, 1.0],\n  \"records\": [\n    { \"index\": 0, \"value\": 0 },\n    { \"index\": 1, \"value\": 0.25 },\n    { \"index\": 2, \"value\": 0.5 },\n    { \"index\": 3, \"value\": 0.75 },\n    { \"index\": 4, \"value\": 1.0 }\n  ],\n  \"count\": 5,\n  \"start\": 0,\n  \"stop\": 1,\n  \"step\": 0.25\n}\n```\n\nMinimal forms: `\"range of 50\"` produces 0, 1, 2, …, 50. `\"step of -1 from 5 to 0\"` produces 5, 4, 3, 2, 1, 0.\n\n---\n\n## `math.linspace@1`\n\nGenerate 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.\n\n### Parameters\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `n` | integer | yes | -- | Number of points to generate. Must be ≥ 1 |\n| `start` | number | no | `0` | First value |\n| `stop` | number | no | `1` | Last value (inclusive) |\n| `label` | string | no | `\"value\"` | Field name for the value column in each record |\n\n### Example\n\n```json\n{\n  \"name\": \"data-grout@1/math.linspace@1\",\n  \"arguments\": {\n    \"n\": 5,\n    \"start\": 0,\n    \"stop\": 100\n  }\n}\n```\n\nResponse:\n\n```json\n{\n  \"values\": [0, 25, 50, 75, 100],\n  \"records\": [\n    { \"index\": 0, \"value\": 0 },\n    { \"index\": 1, \"value\": 25 },\n    { \"index\": 2, \"value\": 50 },\n    { \"index\": 3, \"value\": 75 },\n    { \"index\": 4, \"value\": 100 }\n  ],\n  \"count\": 5,\n  \"start\": 0,\n  \"stop\": 100,\n  \"n\": 5\n}\n```\n\n---\n\n## `math.sequence@1`\n\nGenerate a named mathematical sequence of N terms. Maximum 1,000 terms per call.\n\n### Parameters\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `count` | integer | yes | -- | Number of terms to generate. Must be ≥ 1 |\n| `type` | string | no | `\"arithmetic\"` | Sequence type. See table below |\n| `start` | number | no | type-dependent | First term override |\n| `step` | number | no | `1` | Common difference (arithmetic only) |\n| `ratio` | number | no | `2` | Common ratio (geometric only) |\n| `base` | number | no | `2` | Base (powers only) |\n| `label` | string | no | `\"value\"` | Field name for the value column in each record |\n\n### Sequence types\n\n| Type | Description | Default parameters |\n|------|-------------|-------------------|\n| `arithmetic` | a, a+d, a+2d, … | start=0, step=1 |\n| `geometric` | a, a·r, a·r², … | start=1, ratio=2 |\n| `fibonacci` | 1, 1, 2, 3, 5, 8, … | -- |\n| `triangular` | 1, 3, 6, 10, 15, … | -- |\n| `square` | 1, 4, 9, 16, 25, … | -- |\n| `prime` | 2, 3, 5, 7, 11, … | -- |\n| `powers` | 1, b, b², b³, … | base=2 |\n\n### Example\n\n```json\n{\n  \"name\": \"data-grout@1/math.sequence@1\",\n  \"arguments\": {\n    \"type\": \"fibonacci\",\n    \"count\": 8\n  }\n}\n```\n\nResponse:\n\n```json\n{\n  \"values\": [1, 1, 2, 3, 5, 8, 13, 21],\n  \"records\": [\n    { \"index\": 0, \"n\": 1, \"value\": 1 },\n    { \"index\": 1, \"n\": 2, \"value\": 1 },\n    { \"index\": 2, \"n\": 3, \"value\": 2 }\n  ],\n  \"count\": 8,\n  \"type\": \"fibonacci\"\n}\n```\n\n---\n\n## `math.sample@1`\n\nDraw 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.\n\n### Parameters\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `count` | integer | yes | -- | Number of samples to draw. Must be ≥ 1 |\n| `distribution` | string | no | `\"uniform\"` | One of `\"uniform\"`, `\"normal\"`, `\"exponential\"` |\n| `min` | number | no | `0` | Lower bound (uniform only) |\n| `max` | number | no | `1` | Upper bound (uniform only) |\n| `mean` | number | no | `0` | Mean μ (normal only) |\n| `std` | number | no | `1` | Standard deviation σ (normal only) |\n| `rate` | number | no | `1` | Rate λ (exponential only, must be > 0) |\n| `seed` | integer | no | -- | Integer seed for reproducible output |\n| `label` | string | no | `\"value\"` | Field name for the value column in each record |\n\n### Example\n\n```json\n{\n  \"name\": \"data-grout@1/math.sample@1\",\n  \"arguments\": {\n    \"distribution\": \"normal\",\n    \"count\": 500,\n    \"mean\": 100,\n    \"std\": 15,\n    \"seed\": 42\n  }\n}\n```\n\nResponse (abbreviated):\n\n```json\n{\n  \"values\": [97.3, 112.1, 88.6, \"...\"],\n  \"records\": [{ \"index\": 0, \"value\": 97.3 }, \"...\"],\n  \"count\": 500,\n  \"distribution\": \"normal\",\n  \"stats\": {\n    \"mean\": 99.87,\n    \"std\": 14.92,\n    \"min\": 58.4,\n    \"max\": 143.2\n  }\n}\n```\n\n---\n\n## `math.interpolate@1`\n\nApply 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.\n\n### Parameters\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `operation` | string | yes | -- | Operation to apply. See table below |\n| `values` | array | no | -- | List of values to map the operation over. When given, the scalar input parameter is ignored |\n| `t` | number | no | -- | Interpolation factor [0..1] for lerp and easing operations |\n| `a` | number | no | -- | Start value for `lerp` / `inverse_lerp` |\n| `b` | number | no | -- | End value for `lerp` / `inverse_lerp` |\n| `v` | number | no | -- | Input value for `inverse_lerp`, `clamp`, `remap` |\n| `x` | number | no | -- | Input value for `smoothstep`, `smootherstep` |\n| `min` | number | no | -- | Lower bound for `clamp` |\n| `max` | number | no | -- | Upper bound for `clamp` |\n| `edge0` | number | no | -- | Lower edge for `smoothstep` / `smootherstep` |\n| `edge1` | number | no | -- | Upper edge for `smoothstep` / `smootherstep` |\n| `in_min` | number | no | -- | Input range minimum for `remap` |\n| `in_max` | number | no | -- | Input range maximum for `remap` |\n| `out_min` | number | no | -- | Output range minimum for `remap` |\n| `out_max` | number | no | -- | Output range maximum for `remap` |\n\n### Operations\n\n| Operation | Description |\n|-----------|-------------|\n| `lerp` | Linear interpolation: `a + t * (b - a)` |\n| `inverse_lerp` | Normalize v into [a, b]: `(v - a) / (b - a)` |\n| `clamp` | Clamp v to [min, max] |\n| `remap` | Map v from [in_min, in_max] to [out_min, out_max] |\n| `smoothstep` | Ken Perlin's smoothstep curve |\n| `smootherstep` | Smoothstep with zero first and second derivatives at edges |\n| `ease_in_quad` / `ease_out_quad` / `ease_in_out_quad` | Quadratic easing |\n| `ease_in_cubic` / `ease_out_cubic` / `ease_in_out_cubic` | Cubic easing |\n| `ease_in_quart` / `ease_out_quart` / `ease_in_out_quart` | Quartic easing |\n| `ease_in_sine` / `ease_out_sine` / `ease_in_out_sine` | Sinusoidal easing |\n\n### Example: apply easing to a linspace\n\n```json\n{\n  \"name\": \"data-grout@1/math.interpolate@1\",\n  \"arguments\": {\n    \"operation\": \"ease_in_out_cubic\",\n    \"values\": [0, 0.25, 0.5, 0.75, 1.0]\n  }\n}\n```\n\nResponse:\n\n```json\n{\n  \"values\": [0.0, 0.0625, 0.5, 0.9375, 1.0],\n  \"records\": [\n    { \"index\": 0, \"t\": 0.0, \"value\": 0.0 },\n    { \"index\": 1, \"t\": 0.25, \"value\": 0.0625 },\n    { \"index\": 2, \"t\": 0.5, \"value\": 0.5 },\n    { \"index\": 3, \"t\": 0.75, \"value\": 0.9375 },\n    { \"index\": 4, \"t\": 1.0, \"value\": 1.0 }\n  ],\n  \"operation\": \"ease_in_out_cubic\",\n  \"count\": 5\n}\n```\n\n### Example: scalar clamp\n\n```json\n{\n  \"name\": \"data-grout@1/math.interpolate@1\",\n  \"arguments\": {\n    \"operation\": \"clamp\",\n    \"v\": 1.75,\n    \"min\": 0,\n    \"max\": 1\n  }\n}\n```\n\nResponse:\n\n```json\n{ \"result\": 1.0, \"operation\": \"clamp\" }\n```\n\n---\n\n## `math.describe@1`\n\nCompute 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.\n\n### Parameters\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `payload` | array | no | -- | Inline numeric array or array of records. Alternative to `cache_ref` |\n| `cache_ref` | string | no | -- | Reference from a prior tool response |\n| `field` | string | no | -- | When payload is records, extract this field's numeric values |\n| `bins` | integer | no | `10` | Number of histogram bins (2–100) |\n\n### Example\n\n```json\n{\n  \"name\": \"data-grout@1/math.describe@1\",\n  \"arguments\": {\n    \"payload\": [12, 15, 14, 10, 18, 22, 19, 13, 16, 20]\n  }\n}\n```\n\nResponse (abbreviated):\n\n```json\n{\n  \"count\": 10,\n  \"mean\": 15.9,\n  \"median\": 15.5,\n  \"std\": 3.59,\n  \"variance\": 12.89,\n  \"min\": 10,\n  \"max\": 22,\n  \"sum\": 159,\n  \"range\": 12,\n  \"skewness\": 0.18,\n  \"percentiles\": { \"p5\": 10.45, \"p25\": 13.25, \"p50\": 15.5, \"p75\": 19.25, \"p95\": 21.55 },\n  \"histogram\": [\n    { \"bin_start\": 10, \"bin_end\": 12.4, \"count\": 1 },\n    \"...\"\n  ]\n}\n```\n\nWorks with records too: pass `\"field\": \"revenue\"` to describe a specific column from tabular data.\n\n---\n\n## `math.window@1`\n\nApply 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.\n\n### Parameters\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `op` | string | yes | -- | Operation: `moving_avg`, `moving_sum`, `cumsum`, `diff`, `pct_change`, `lag`, `ewma` |\n| `payload` | array | no | -- | Inline numeric array or array of records. Alternative to `cache_ref` |\n| `cache_ref` | string | no | -- | Reference from a prior tool response |\n| `field` | string | no | -- | When payload is records, extract this field's numeric values |\n| `window` | integer | no | `3` | Window size for `moving_avg` and `moving_sum` |\n| `n` | integer | no | `1` | Period for `lag` and `diff` |\n| `alpha` | number | no | `0.3` | Smoothing factor for `ewma` (0 < α < 1) |\n| `label` | string | no | `\"value\"` | Field name for the value column in records |\n\n### Operations\n\n| Operation | Description |\n|-----------|-------------|\n| `moving_avg` | Rolling mean over a sliding window |\n| `moving_sum` | Rolling sum over a sliding window |\n| `cumsum` | Running cumulative sum |\n| `diff` | First differences: x[i] − x[i−n] |\n| `pct_change` | Percentage change period-over-period: (x[i] − x[i−n]) / x[i−n] × 100 |\n| `lag` | Shift values forward by n positions (nulls at start) |\n| `ewma` | Exponentially weighted moving average with smoothing factor α |\n\n### Example\n\n```json\n{\n  \"name\": \"data-grout@1/math.window@1\",\n  \"arguments\": {\n    \"op\": \"moving_avg\",\n    \"payload\": [10, 20, 30, 40, 50, 60, 70],\n    \"window\": 3\n  }\n}\n```\n\nResponse:\n\n```json\n{\n  \"values\": [null, null, 20.0, 30.0, 40.0, 50.0, 60.0],\n  \"records\": [\n    { \"index\": 0, \"value\": null },\n    { \"index\": 1, \"value\": null },\n    { \"index\": 2, \"value\": 20.0 },\n    { \"index\": 3, \"value\": 30.0 },\n    \"...\"\n  ],\n  \"count\": 7,\n  \"op\": \"moving_avg\",\n  \"window\": 3\n}\n```\n\nNull values at the start indicate insufficient data for the window. Pass `records` directly to `prism.chart` for time-series visualization.\n\n---\n\n## `math.correlate@1`\n\nCompute 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.\n\n### Parameters\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `x` | array | no | -- | First numeric series. Alternative to `payload` + `x_field` |\n| `y` | array | no | -- | Second numeric series. Same length as `x` |\n| `payload` | array | no | -- | Array of records containing both series. Alternative to `cache_ref` |\n| `cache_ref` | string | no | -- | Reference from a prior tool response |\n| `x_field` | string | no | -- | Field name for x when using payload of records |\n| `y_field` | string | no | -- | Field name for y when using payload of records |\n| `method` | string | no | `\"both\"` | `\"pearson\"`, `\"spearman\"`, or `\"both\"` |\n\n### Example: inline arrays\n\n```json\n{\n  \"name\": \"data-grout@1/math.correlate@1\",\n  \"arguments\": {\n    \"x\": [1, 2, 3, 4, 5],\n    \"y\": [2, 4, 5, 4, 5]\n  }\n}\n```\n\nResponse:\n\n```json\n{\n  \"n\": 5,\n  \"pearson\": {\n    \"r\": 0.8,\n    \"r_squared\": 0.64,\n    \"interpretation\": \"strong positive\"\n  },\n  \"spearman\": {\n    \"r\": 0.82,\n    \"r_squared\": 0.67,\n    \"interpretation\": \"strong positive\"\n  },\n  \"records\": [\n    { \"index\": 0, \"x\": 1, \"y\": 2 },\n    { \"index\": 1, \"x\": 2, \"y\": 4 },\n    \"...\"\n  ]\n}\n```\n\n### Example: from records\n\n```json\n{\n  \"name\": \"data-grout@1/math.correlate@1\",\n  \"arguments\": {\n    \"cache_ref\": \"abc123\",\n    \"x_field\": \"ad_spend\",\n    \"y_field\": \"revenue\",\n    \"method\": \"pearson\"\n  }\n}\n```\n\nPass `records` to `prism.chart` with `chart_type: \"scatter\"` for instant correlation visualization.\n\n---\n\n## `math.trend@1`\n\nFit 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.\n\n### Parameters\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `y` | array | no | -- | Dependent variable series |\n| `x` | array | no | -- | Independent variable series. If omitted, 0-based indices are used |\n| `payload` | array | no | -- | Array of records or numeric values. Alternative to `cache_ref` |\n| `cache_ref` | string | no | -- | Reference from a prior tool response |\n| `x_field` | string | no | -- | Field name for x when using payload of records |\n| `y_field` | string | no | -- | Field name for y when using payload of records |\n| `field` | string | no | -- | When payload has one numeric field, use it as y (x = indices) |\n| `model` | string | no | `\"linear\"` | Regression model: `linear`, `polynomial`, `exponential`, `logarithmic` |\n| `degree` | integer | no | `2` | Polynomial degree (2–5). Only used with `polynomial` model |\n| `forecast` | integer | no | `0` | Number of future points to project beyond the data (0–1000) |\n| `label` | string | no | `\"value\"` | Field name for values in records |\n\n### Example: simple trend\n\n```json\n{\n  \"name\": \"data-grout@1/math.trend@1\",\n  \"arguments\": {\n    \"y\": [10, 12, 15, 18, 22]\n  }\n}\n```\n\nResponse:\n\n```json\n{\n  \"model\": \"linear\",\n  \"slope\": 2.9,\n  \"intercept\": 9.5,\n  \"coefficients\": [2.9, 9.5],\n  \"r_squared\": 0.99,\n  \"direction\": \"increasing\",\n  \"equation\": \"y = 2.9x + 9.5\",\n  \"n\": 5,\n  \"values\": [9.5, 12.4, 15.3, 18.2, 21.1],\n  \"fitted\": [\n    { \"index\": 0, \"x\": 0, \"y_actual\": 10, \"y_fitted\": 9.5, \"value\": 9.5 },\n    \"...\"\n  ]\n}\n```\n\n### Example: polynomial fit\n\n```json\n{\n  \"name\": \"data-grout@1/math.trend@1\",\n  \"arguments\": {\n    \"x\": [0, 1, 2, 3, 4],\n    \"y\": [0, 1, 4, 9, 16],\n    \"model\": \"polynomial\",\n    \"degree\": 2\n  }\n}\n```\n\nResponse includes `\"model\": \"polynomial\"`, `\"degree\": 2`, and `\"coefficients\": [1.0, 0.0, 0.0]` (for y = x²).\n\n### Example: exponential fit\n\n```json\n{\n  \"name\": \"data-grout@1/math.trend@1\",\n  \"arguments\": {\n    \"y\": [100, 150, 225, 337, 506],\n    \"model\": \"exponential\"\n  }\n}\n```\n\nReturns `\"equation\": \"y = 100.0 * e^(0.405x)\"` with `\"coefficients\": [100.0, 0.405]`.\n\n### Example: with forecast\n\n```json\n{\n  \"name\": \"data-grout@1/math.trend@1\",\n  \"arguments\": {\n    \"cache_ref\": \"abc123\",\n    \"field\": \"revenue\",\n    \"forecast\": 3\n  }\n}\n```\n\nForecast 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`.\n\nOverlay `fitted` on original data in `prism.chart` to visualize the trend line and projections.\n\n---\n\n## `math.normalize@1`\n\nScale 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.\n\n### Parameters\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `payload` | array | no | -- | Inline numeric array or array of records. Alternative to `cache_ref` |\n| `cache_ref` | string | no | -- | Reference from a prior tool response |\n| `field` | string | no | -- | When payload is records, extract this field's numeric values |\n| `method` | string | no | `\"zscore\"` | Normalization method: `zscore`, `minmax`, `rank` |\n| `min_out` | number | no | `0` | Lower bound for minmax output range |\n| `max_out` | number | no | `1` | Upper bound for minmax output range |\n| `label` | string | no | `\"value\"` | Field name for the normalized value in records |\n\n### Methods\n\n| Method | Description |\n|--------|-------------|\n| `zscore` | (x − mean) / std — centers data to mean=0, std=1 |\n| `minmax` | (x − min) / (max − min), scaled to [min_out, max_out] |\n| `rank` | Percentile rank 0–100 |\n\n### Example\n\n```json\n{\n  \"name\": \"data-grout@1/math.normalize@1\",\n  \"arguments\": {\n    \"payload\": [10, 20, 30, 40, 50],\n    \"method\": \"minmax\"\n  }\n}\n```\n\nResponse:\n\n```json\n{\n  \"values\": [0.0, 0.25, 0.5, 0.75, 1.0],\n  \"records\": [\n    { \"index\": 0, \"original\": 10, \"value\": 0.0 },\n    { \"index\": 1, \"original\": 20, \"value\": 0.25 },\n    \"...\"\n  ],\n  \"count\": 5,\n  \"method\": \"minmax\",\n  \"stats\": { \"input_min\": 10, \"input_max\": 50, \"output_min\": 0, \"output_max\": 1 }\n}\n```\n\nUseful for preparing features for comparison, scoring, or visualization when values are on different scales.\n\n---\n\n## `math.outliers@1`\n\nDetect 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.\n\n### Parameters\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `payload` | array | no | -- | Inline numeric array or array of records. Alternative to `cache_ref` |\n| `cache_ref` | string | no | -- | Reference from a prior tool response |\n| `field` | string | no | -- | When payload is records, extract this field's numeric values |\n| `method` | string | no | `\"iqr\"` | Detection method: `iqr` or `zscore` |\n| `k` | number | no | `1.5` | IQR multiplier: 1.5 = standard outliers, 3.0 = extreme outliers |\n| `threshold` | number | no | `3.0` | Z-score threshold for the zscore method |\n\n### Example\n\n```json\n{\n  \"name\": \"data-grout@1/math.outliers@1\",\n  \"arguments\": {\n    \"payload\": [12, 14, 13, 15, 14, 13, 100, 12, 15, 14],\n    \"method\": \"iqr\"\n  }\n}\n```\n\nResponse:\n\n```json\n{\n  \"count\": 10,\n  \"outlier_count\": 1,\n  \"outlier_pct\": 10.0,\n  \"method\": \"iqr\",\n  \"bounds\": { \"lower\": 9.25, \"upper\": 18.75 },\n  \"outliers\": [\n    { \"index\": 6, \"value\": 100, \"side\": \"high\" }\n  ],\n  \"clean_values\": [12, 14, 13, 15, 14, 13, 12, 15, 14],\n  \"values\": [false, false, false, false, false, false, true, false, false, false],\n  \"records\": [\n    { \"index\": 0, \"value\": 12, \"is_outlier\": false },\n    \"...\"\n  ]\n}\n```\n\nUse `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.\n\n---\n\n## `math.rank@1`\n\nAssign 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.\n\n### Parameters\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `payload` | array | no | -- | Inline numeric array or array of records. Alternative to `cache_ref` |\n| `cache_ref` | string | no | -- | Reference from a prior tool response |\n| `field` | string | no | -- | When payload is records, extract this field's numeric values |\n| `method` | string | no | `\"dense\"` | Ranking method: `ordinal`, `dense`, `average`, `percentile` |\n| `ascending` | boolean | no | `false` | If true, smallest value gets rank 1 |\n| `label` | string | no | `\"rank\"` | Field name for the rank column in records |\n\n### Methods\n\n| Method | Description | Example (values: 30, 20, 20, 10) |\n|--------|-------------|-----------------------------------|\n| `ordinal` | Each value gets a unique sequential rank | 1, 2, 3, 4 |\n| `dense` | Ties share rank, next rank increments by 1 | 1, 2, 2, 3 |\n| `average` | Ties share the mean of their ordinal ranks | 1, 2.5, 2.5, 4 |\n| `percentile` | Percentile rank 0–100 | 0, 33.3, 33.3, 100 |\n\n### Example\n\n```json\n{\n  \"name\": \"data-grout@1/math.rank@1\",\n  \"arguments\": {\n    \"payload\": [85, 92, 78, 92, 88],\n    \"method\": \"dense\"\n  }\n}\n```\n\nResponse:\n\n```json\n{\n  \"values\": [3, 1, 4, 1, 2],\n  \"records\": [\n    { \"index\": 0, \"original\": 85, \"rank\": 3 },\n    { \"index\": 1, \"original\": 92, \"rank\": 1 },\n    { \"index\": 2, \"original\": 78, \"rank\": 4 },\n    { \"index\": 3, \"original\": 92, \"rank\": 1 },\n    { \"index\": 4, \"original\": 88, \"rank\": 2 }\n  ],\n  \"count\": 5,\n  \"method\": \"dense\",\n  \"ties\": 1\n}\n```\n\nUseful for leaderboards, percentile scoring, and rank-based comparisons across datasets with different scales.\n"
}