runmat-runtime 0.4.1

Core runtime for RunMat with builtins, BLAS/LAPACK integration, and execution APIs
Documentation
{
  "title": "cummin",
  "category": "math/reduction",
  "keywords": [
    "cummin",
    "cumulative minimum",
    "running minimum",
    "reverse",
    "omitnan",
    "indices",
    "gpu"
  ],
  "summary": "Running minimum and index tracking for scalars, vectors, matrices, or N-D tensors.",
  "references": [],
  "gpu_support": {
    "elementwise": false,
    "reduction": false,
    "precisions": [
      "f32",
      "f64"
    ],
    "broadcasting": "matlab",
    "notes": "Uses provider cummin_scan when available; otherwise gathers to host and computes MATLAB-compatible results."
  },
  "fusion": {
    "elementwise": false,
    "reduction": false,
    "max_inputs": 1,
    "constants": "inline"
  },
  "requires_feature": null,
  "tested": {
    "unit": "builtins::math::reduction::cummin::tests",
    "integration": "builtins::math::reduction::cummin::tests::cummin_gpu_provider_roundtrip"
  },
  "description": "`cummin(X)` computes the cumulative minimum of the elements in `X` along a chosen dimension. It also tracks where each running minimum occurs, mirroring MATLAB's two-output behaviour.",
  "behaviors": [
    "By default the running minimum follows the first non-singleton dimension. Use `cummin(X, dim)` to choose a dimension explicitly; if `dim > ndims(X)`, the input is returned unchanged and the indices are ones.",
    "`[Y, I] = cummin(X, ...)` returns both the running minima (`Y`) and the indices of where those minima were observed (`I`). Indices are one-based and match MATLAB exactly.",
    "Add `\"reverse\"` (or `\"forward\"`) to control the scan direction. Reverse mode walks from the end of the chosen dimension back to the beginning.",
    "`\"omitnan\"` skips `NaN` values when choosing the running minimum, returning `NaN` only when every value seen so far is `NaN`. `\"includenan\"` (default) propagates `NaN` once one is encountered.",
    "Synonyms such as `\"omitmissing\"` / `\"includemissing\"` are accepted for MATLAB compatibility.",
    "Real and complex inputs are supported. Complex numbers are ordered using MATLAB's magnitude-and-angle rules."
  ],
  "examples": [
    {
      "description": "Tracking column-wise running minima",
      "input": "A = [4 2 7; 3 5 1];\n[Y, I] = cummin(A)",
      "output": "Y =\n     4     2     7\n     3     2     1\nI =\n     1     1     1\n     2     1     2"
    },
    {
      "description": "Requesting running minima across rows",
      "input": "A = [4 2 7; 3 5 1];\n[Y, I] = cummin(A, 2)",
      "output": "Y =\n     4     2     2\n     3     3     1\nI =\n     1     2     2\n     1     1     3"
    },
    {
      "description": "Getting cumulative minima in reverse order",
      "input": "v = [8 3 6 2];\n[Y, I] = cummin(v, \"reverse\")",
      "output": "Y = [2 2 2 2]\nI = [4 4 4 4]"
    },
    {
      "description": "Ignoring NaN values in running minima",
      "input": "v = [NaN 5 NaN 3];\n[Y, I] = cummin(v, \"omitnan\")",
      "output": "Y = [NaN 5 5 3]\nI = [NaN 2 2 4]"
    },
    {
      "description": "Capturing running minima and indices on the GPU",
      "input": "G = gpuArray([3 1 4 1 5]);\n[Y, I] = cummin(G);\nhostY = gather(Y);\nhostI = gather(I)"
    }
  ],
  "faqs": [
    {
      "question": "Does `cummin` always return indices?",
      "answer": "Yes. The builtin produces MATLAB-compatible indices internally. When a call requests two outputs (`[Y, I] = cummin(...)`), `I` is surfaced directly. For single-output calls the indices remain available to the runtime for later retrieval."
    },
    {
      "question": "How are complex numbers ordered?",
      "answer": "Complex minima follow MATLAB's rules: values compare by magnitude, and ties break by phase angle. `\"omitnan\"` treats elements with `NaN` real or imaginary parts as missing."
    },
    {
      "question": "What happens when all elements seen so far are `NaN` with `\"omitnan\"`?",
      "answer": "The running minimum stays `NaN` and the corresponding index is `NaN` until a finite value is encountered. Once a finite value appears, subsequent `NaN`s leave the minimum and index unchanged."
    },
    {
      "question": "Does the `\"reverse\"` option change the reported indices?",
      "answer": "Indices are still reported using 1-based positions along the chosen dimension. `\"reverse\"` simply walks the dimension from end to start before writing the outputs."
    },
    {
      "question": "What if the requested dimension exceeds `ndims(X)`?",
      "answer": "The input is returned unchanged. Every index is `1`, matching MATLAB's treatment of singleton trailing dimensions."
    }
  ],
  "links": [
    {
      "label": "min",
      "url": "./min"
    },
    {
      "label": "max",
      "url": "./max"
    },
    {
      "label": "cumsum",
      "url": "./cumsum"
    },
    {
      "label": "cumprod",
      "url": "./cumprod"
    },
    {
      "label": "gpuArray",
      "url": "./gpuarray"
    },
    {
      "label": "gather",
      "url": "./gather"
    },
    {
      "label": "all",
      "url": "./all"
    },
    {
      "label": "any",
      "url": "./any"
    },
    {
      "label": "cummax",
      "url": "./cummax"
    },
    {
      "label": "diff",
      "url": "./diff"
    },
    {
      "label": "mean",
      "url": "./mean"
    },
    {
      "label": "median",
      "url": "./median"
    },
    {
      "label": "nnz",
      "url": "./nnz"
    },
    {
      "label": "prod",
      "url": "./prod"
    },
    {
      "label": "std",
      "url": "./std"
    },
    {
      "label": "sum",
      "url": "./sum"
    },
    {
      "label": "var",
      "url": "./var"
    }
  ],
  "source": {
    "label": "`crates/runmat-runtime/src/builtins/math/reduction/cummin.rs`",
    "url": "https://github.com/runmat-org/runmat/blob/main/crates/runmat-runtime/src/builtins/math/reduction/cummin.rs"
  },
  "gpu_residency": "Manual `gpuArray` calls are optional. The planner keeps tensors on the GPU when profitable, and the cummin builtin preserves residency whenever the provider implements `cummin_scan`. If the hook is unavailable, RunMat gathers to the host transparently and still returns MATLAB-compatible minima and indices. You can still use `gpuArray` to match MATLAB scripts or force residency ahead of a tight GPU loop.",
  "gpu_behavior": [
    "When the input already resides on the GPU, RunMat calls the acceleration provider's `cummin_scan` hook. Providers that implement this hook return GPU handles for both the running minima and their indices. If the hook is missing—or if it rejects the requested options (such as `\"omitnan\"` or `\"reverse\"`)—RunMat gathers the data to the host, computes the MATLAB-compatible result, and returns dense tensors on the CPU. Residency metadata is cleared so downstream kernels can re-promote values when profitable."
  ]
}