{
"title": "colon",
"category": "array/creation",
"keywords": [
"colon",
"sequence",
"range",
"step",
"gpu"
],
"summary": "Generate MATLAB-style arithmetic progressions with optional step size.",
"references": [],
"gpu_support": {
"elementwise": false,
"reduction": false,
"precisions": [
"f32",
"f64"
],
"broadcasting": "none",
"notes": "Prefers provider `linspace` kernels when available; otherwise the runtime uploads the host-generated vector so residency stays on device."
},
"fusion": {
"elementwise": false,
"reduction": false,
"max_inputs": 0,
"constants": "inline"
},
"requires_feature": null,
"tested": {
"unit": "builtins::array::creation::colon::tests",
"integration": "builtins::array::creation::colon::tests::colon_gpu_roundtrip",
"wgpu": "builtins::array::creation::colon::tests::colon_wgpu_matches_cpu"
},
"description": "`colon(start, stop)` and `colon(start, step, stop)` build row vectors that mirror the MATLAB colon operator. The function returns an arithmetic progression that begins at `start`, advances by `step` (default `+1` or `-1` depending on the bounds), and stops before exceeding `stop`.",
"behaviors": [
"Inputs must be real scalars (numeric, logical, scalar tensors, or single-character arrays). Imaginary parts must be zero.",
"`colon(start, stop)` picks an increment of `+1` when `stop ≥ start`, otherwise `-1`.",
"`colon(start, step, stop)` uses the supplied increment. A zero increment raises an error.",
"When the endpoints are character scalars, the result is a row vector of characters; otherwise a double-precision row vector. Empty progressions are `1×0`.",
"`stop` is included only when it lies on the arithmetic progression; otherwise the sequence stops at the last admissible value before overshooting.",
"Arguments may be `gpuArray` scalars; the result stays on the GPU when a provider is active.",
"Floating-point tolerance follows MATLAB’s rules, so values that should land on `stop` are preserved even when rounding noise accumulates."
],
"examples": [
{
"description": "Generating consecutive integers",
"input": "x = colon(1, 5)",
"output": "x = [1 2 3 4 5]"
},
{
"description": "Counting down without specifying a step",
"input": "y = colon(5, 1)",
"output": "y = [5 4 3 2 1]"
},
{
"description": "Using a custom increment",
"input": "z = colon(0, 0.5, 2)",
"output": "z = [0 0.5 1.0 1.5 2.0]"
},
{
"description": "Stopping before overshooting the end point",
"input": "vals = colon(0, 2, 5)",
"output": "vals = [0 2 4]"
},
{
"description": "Working with fractional radians",
"input": "theta = colon(-pi, pi/4, pi/2)",
"output": "theta = [-3.1416 -2.3562 -1.5708 -0.7854 0.0000 0.7854 1.5708]"
},
{
"description": "Keeping sequences on the GPU",
"input": "g = gpuArray(0);\nh = colon(g, 0.25, 1);\nresult = gather(h)",
"output": "result = [0 0.25 0.5 0.75 1.0]"
},
{
"description": "Building character ranges",
"input": "letters = colon('a', 'f')\nodds = colon('a', 2, 'g')",
"output": "letters = 'abcdef';\nodds = 'aceg'"
}
],
"faqs": [
{
"question": "What happens when `start == stop`?",
"answer": "The output is a single-element vector containing `start`. With two arguments the implicit step is `+1`, so the result is `[start]`."
},
{
"question": "Why is `stop` sometimes missing from the result?",
"answer": "`stop` is included only when it aligns with the arithmetic progression. For example, `colon(0, 2, 5)` produces `[0 2 4]` because `6` would overshoot the upper bound."
},
{
"question": "Can I use zero or complex increments?",
"answer": "No. The increment must be a finite, non-zero real scalar. Supplying `0` or a value with a non-zero imaginary part raises an error."
},
{
"question": "Can I generate character sequences?",
"answer": "Yes. When both `start` and `stop` are single-character arrays, `colon` returns a character row vector. Step values can still be numeric (for example, `colon('a', 2, 'g')` produces `'aceg'`)."
},
{
"question": "Does the function accept logical inputs?",
"answer": "Yes. Logical scalars are promoted to doubles (`true → 1`, `false → 0`) before building the sequence."
},
{
"question": "How does this differ from `linspace`?",
"answer": "`linspace(start, stop, n)` lets you pick the number of points directly, whereas `colon` fixes the increment (`start:step:stop`). When `stop` is not exactly reachable, `colon` stops short instead of nudging the final value."
}
],
"links": [
{
"label": "linspace",
"url": "./linspace"
},
{
"label": "logspace",
"url": "./logspace"
},
{
"label": "range",
"url": "./range"
},
{
"label": "gpuArray",
"url": "./gpuarray"
},
{
"label": "gather",
"url": "./gather"
},
{
"label": "eye",
"url": "./eye"
},
{
"label": "false",
"url": "./false"
},
{
"label": "fill",
"url": "./fill"
},
{
"label": "magic",
"url": "./magic"
},
{
"label": "meshgrid",
"url": "./meshgrid"
},
{
"label": "ones",
"url": "./ones"
},
{
"label": "rand",
"url": "./rand"
},
{
"label": "randi",
"url": "./randi"
},
{
"label": "randn",
"url": "./randn"
},
{
"label": "randperm",
"url": "./randperm"
},
{
"label": "true",
"url": "./true"
},
{
"label": "zeros",
"url": "./zeros"
}
],
"source": {
"label": "`crates/runmat-runtime/src/builtins/array/creation/colon.rs`",
"url": "https://github.com/runmat-org/runmat/blob/main/crates/runmat-runtime/src/builtins/array/creation/colon.rs"
},
"gpu_residency": "RunMat automatically keeps the output on the GPU when any input scalar already resides there and an acceleration provider is active. Providers that implement the `linspace` hook (such as the wgpu backend) generate the progression entirely on device. Other providers still return a GPU tensor by uploading the host-generated vector, so downstream kernels can fuse without an extra gather."
}