runmat-runtime 0.4.1

Core runtime for RunMat with builtins, BLAS/LAPACK integration, and execution APIs
Documentation
{
  "title": "sort",
  "category": "array/sorting_sets",
  "keywords": [
    "sort",
    "ascending",
    "descending",
    "indices",
    "comparisonmethod",
    "gpu"
  ],
  "summary": "Sort scalars, vectors, matrices, or N-D tensors along a dimension, with optional index outputs.",
  "references": [
    "https://www.mathworks.com/help/matlab/ref/sort.html"
  ],
  "gpu_support": {
    "elementwise": false,
    "reduction": false,
    "precisions": [
      "f32",
      "f64"
    ],
    "broadcasting": "none",
    "notes": "Uses the provider `sort_dim` hook when available; otherwise tensors are gathered and sorted on the host."
  },
  "fusion": {
    "elementwise": false,
    "reduction": false,
    "max_inputs": 1,
    "constants": "inline"
  },
  "requires_feature": null,
  "tested": {
    "unit": "builtins::array::sorting_sets::sort::tests",
    "integration": "builtins::array::sorting_sets::sort::tests::sort_gpu_round_trip"
  },
  "description": "`sort` orders the elements of its input along a chosen dimension. By default, it sorts ascending along the first non-singleton dimension and can also return the permutation indices that achieve the ordering.",
  "behaviors": [
    "Scalars remain unchanged; vectors are reordered into ascending or descending order.",
    "For matrices and higher-dimensional tensors, the sort operates along a specified dimension (default: first non-singleton). All other dimensions remain untouched.",
    "`[B, I] = sort(A, ...)` returns both the sorted values `B` and the permutation indices `I`, using MATLAB's one-based indexing.",
    "Direction arguments accept `'ascend'` (default) or `'descend'`.",
    "Name-value pairs support `'ComparisonMethod'` with values `'auto'`, `'real'`, or `'abs'`. The `'abs'` option sorts by absolute value while breaking ties using the signed value.",
    "For complex inputs, the default `'ComparisonMethod'='auto'` behaves like `'abs'` (magnitude ordering) and `'real'` compares the real component first with the imaginary component used for tie-breaking.",
    "NaN values are treated as missing: they appear at the end for ascending sorts and at the beginning for descending sorts (matching MATLAB's `'MissingPlacement','auto'` behaviour for doubles).",
    "Dimensions greater than `ndims(A)` are treated as singleton dimensions (size 1) and therefore leave `A` unchanged while returning index values of `1`."
  ],
  "examples": [
    {
      "description": "Sorting a column vector in ascending order",
      "input": "A = [3; 1; 2];\nB = sort(A)",
      "output": "B =\n     1\n     2\n     3"
    },
    {
      "description": "Sorting rows by specifying the dimension",
      "input": "A = [1 4 2; 3 2 5];\nB = sort(A, 2)",
      "output": "B =\n     1     2     4\n     2     3     5"
    },
    {
      "description": "Sorting values in descending order",
      "input": "A = [10 4 7 9];\nB = sort(A, 'descend')",
      "output": "B =\n    10     9     7     4"
    },
    {
      "description": "Retrieving permutation indices alongside the sorted values",
      "input": "A = [4 1 9 2];\n[B, I] = sort(A)",
      "output": "B =\n     1     2     4     9\nI =\n     2     4     1     3"
    },
    {
      "description": "Sorting by absolute value using `ComparisonMethod`",
      "input": "A = [-8 -1 3 -2];\nB = sort(A, 'ComparisonMethod', 'abs')",
      "output": "B =\n    -1    -2     3    -8"
    },
    {
      "description": "Sorting tensors containing NaN values",
      "input": "A = [NaN 4 1 2];\n[B, I] = sort(A)",
      "output": "B =\n     1     2     4   NaN\nI =\n     3     4     2     1"
    },
    {
      "description": "Sorting GPU tensors with automatic host fallback",
      "input": "G = gpuArray(randn(5, 1));\n[B, I] = sort(G, 'descend')"
    }
  ],
  "faqs": [
    {
      "question": "Can `sort` return both values and indices?",
      "answer": "Yes. Use `[B, I] = sort(A, ...)` to receive the permutation indices alongside the sorted values."
    },
    {
      "question": "How are NaN values handled?",
      "answer": "NaN values are considered missing. They appear last for ascending sorts and first for descending sorts, matching MATLAB's `'MissingPlacement','auto'` default for doubles."
    },
    {
      "question": "What happens when I sort along a dimension that does not exist?",
      "answer": "`sort(A, dim)` treats dimensions beyond `ndims(A)` as singleton dimensions (size 1). The data remains unchanged and the index output is filled with ones."
    },
    {
      "question": "Does `sort` support name-value arguments?",
      "answer": "Yes. `'ComparisonMethod'` accepts `'auto'`, `'real'`, or `'abs'`. Other name-value pairs such as `'MissingPlacement'` are currently not supported and raise an error."
    },
    {
      "question": "Are GPU tensors sorted in-place?",
      "answer": "Not yet. `sort` is a sink builtin that gathers GPU tensors to host memory when no GPU sort kernel is available. Providers can implement specialised hooks in the future."
    },
    {
      "question": "Does `sort` preserve the shape of the input?",
      "answer": "Yes. The output is the same size as the input tensor. Only values along the selected dimension are reordered."
    },
    {
      "question": "What numeric type do the index outputs use?",
      "answer": "Permutation indices are returned as double-precision tensors (or scalars) using MATLAB's one-based indexing."
    },
    {
      "question": "Is the sorting stable?",
      "answer": "Yes. Equal elements (including ties when sorting by absolute value) preserve their original order."
    },
    {
      "question": "How does `ComparisonMethod` behave with real inputs?",
      "answer": "`'auto'` and `'real'` behave identically. `'abs'` sorts by absolute value and uses the signed value to break ties so that results match MATLAB."
    },
    {
      "question": "How does `ComparisonMethod` behave with complex inputs?",
      "answer": "`'auto'` (the default) and `'abs'` order values by magnitude. `'real'` compares the real component first and falls back to the imaginary component to break ties while preserving stability."
    },
    {
      "question": "Do logical or scalar inputs work?",
      "answer": "Yes. Logical inputs are promoted to double precision automatically. Scalars are returned unchanged with an index output of `1` when requested."
    }
  ],
  "links": [
    {
      "label": "sortrows",
      "url": "./sortrows"
    },
    {
      "label": "unique",
      "url": "./unique"
    },
    {
      "label": "max",
      "url": "./max"
    },
    {
      "label": "min",
      "url": "./min"
    },
    {
      "label": "permute",
      "url": "./permute"
    },
    {
      "label": "argsort",
      "url": "./argsort"
    },
    {
      "label": "intersect",
      "url": "./intersect"
    },
    {
      "label": "ismember",
      "url": "./ismember"
    },
    {
      "label": "issorted",
      "url": "./issorted"
    },
    {
      "label": "setdiff",
      "url": "./setdiff"
    },
    {
      "label": "union",
      "url": "./union"
    }
  ],
  "source": {
    "label": "`crates/runmat-runtime/src/builtins/array/sorting_sets/sort.rs`",
    "url": "https://github.com/runmat-org/runmat/blob/main/crates/runmat-runtime/src/builtins/array/sorting_sets/sort.rs"
  },
  "gpu_behavior": [
    "`sort` is registered as a sink builtin. When tensors reside on a GPU without a specialised sort kernel, RunMat gathers them to host memory, performs the sort, and returns host-resident outputs.",
    "Providers may implement a future `sort_dim` hook to keep data on the GPU. Until then, all providers fall back to the host path automatically.",
    "The returned index tensor is always host-resident double precision."
  ]
}