runmat-runtime 0.4.1

Core runtime for RunMat with builtins, BLAS/LAPACK integration, and execution APIs
Documentation
{
  "title": "setdiff",
  "category": "array/sorting_sets",
  "keywords": [
    "setdiff",
    "difference",
    "stable",
    "rows",
    "indices",
    "gpu"
  ],
  "summary": "Return values that appear in the first input but not the second, matching MATLAB ordering rules.",
  "references": [
    "https://www.mathworks.com/help/matlab/ref/setdiff.html"
  ],
  "gpu_support": {
    "elementwise": false,
    "reduction": false,
    "precisions": [
      "f32",
      "f64"
    ],
    "broadcasting": "none",
    "notes": "When providers lack a dedicated `setdiff` hook, RunMat gathers GPU tensors to host memory and reuses the CPU path."
  },
  "fusion": {
    "elementwise": false,
    "reduction": false,
    "max_inputs": 2,
    "constants": "inline"
  },
  "requires_feature": null,
  "tested": {
    "unit": "builtins::array::sorting_sets::setdiff::tests",
    "integration": "builtins::array::sorting_sets::setdiff::tests::setdiff_gpu_roundtrip"
  },
  "description": "`setdiff(A, B)` returns the set of values (or rows) that appear in `A` but not in `B`. Results are unique, and the function can operate in sorted or stable order as well as row mode.",
  "behaviors": [
    "`setdiff(A, B)` flattens inputs column-major, removes duplicates, subtracts the values of `B` from `A`, and returns the remaining elements **sorted** ascending by default.",
    "`[C, IA] = setdiff(A, B)` also returns indices so that `C = A(IA)`.",
    "`setdiff(A, B, 'stable')` preserves the first appearance order from `A` instead of sorting.",
    "`setdiff(A, B, 'rows')` treats each row as an element. Inputs must share the same number of columns.",
    "Character arrays, string arrays, logical arrays, numeric types, and complex values are all supported.",
    "Legacy flags (`'legacy'`, `'R2012a'`) are not supported; RunMat always follows modern MATLAB semantics."
  ],
  "examples": [
    {
      "description": "Finding values exclusive to the first numeric vector",
      "input": "A = [5 7 5 1];\nB = [7 1 3];\n[C, IA] = setdiff(A, B)",
      "output": "C =\n     5\nIA =\n     1"
    },
    {
      "description": "Preserving input order with `'stable'`",
      "input": "A = [4 2 4 1 3];\nB = [3 4 5 1];\n[C, IA] = setdiff(A, B, 'stable')",
      "output": "C =\n     2\nIA =\n     2"
    },
    {
      "description": "Working with rows of numeric matrices",
      "input": "A = [1 2; 3 4; 1 2];\nB = [3 4; 5 6];\n[C, IA] = setdiff(A, B, 'rows')",
      "output": "C =\n     1     2\nIA =\n     1"
    },
    {
      "description": "Computing set difference for character data",
      "input": "A = ['m','z'; 'm','a'];\nB = ['a','x'; 'm','a'];\n[C, IA] = setdiff(A, B)",
      "output": "C =\n    m\nIA =\n     1"
    },
    {
      "description": "Subtracting string arrays by row",
      "input": "A = [\"alpha\" \"beta\"; \"gamma\" \"beta\"];\nB = [\"gamma\" \"beta\"; \"delta\" \"beta\"];\n[C, IA] = setdiff(A, B, 'rows', 'stable')",
      "output": "C =\n  1x2 string array\n    \"alpha\"    \"beta\"\nIA =\n     1"
    },
    {
      "description": "Using `setdiff` with GPU arrays",
      "input": "G = gpuArray([10 4 6 4]);\nH = gpuArray([6 4 2]);\nC = setdiff(G, H)",
      "output": "C =\n    10"
    }
  ],
  "faqs": [
    {
      "question": "What ordering does `setdiff` use by default?",
      "answer": "Results are sorted ascending. Specify `'stable'` to preserve the first appearance order from the first input."
    },
    {
      "question": "How are the index outputs defined?",
      "answer": "`IA` points to the positions in `A` that correspond to each element (or row) returned in `C`, using MATLAB's one-based indexing."
    },
    {
      "question": "Can I combine `'rows'` with `'stable'`?",
      "answer": "Yes. `'rows'` can be paired with either `'sorted'` (default) or `'stable'`. Other option combinations that conflict (e.g. `'sorted'` with `'stable'`) are rejected."
    },
    {
      "question": "Does `setdiff` remove `NaN` values from `A` when they exist in `B`?",
      "answer": "Yes. `NaN` values are considered equal. If `B` contains `NaN`, all `NaN` entries from `A` are removed."
    },
    {
      "question": "Are complex numbers supported?",
      "answer": "Absolutely. Complex values use MATLAB's ordering rules (magnitude, then real part, then imaginary part) for the sorted output."
    },
    {
      "question": "Does GPU execution change the results?",
      "answer": "No. Until providers supply a device implementation, RunMat gathers GPU inputs and executes the CPU path to guarantee MATLAB-compatible behaviour."
    },
    {
      "question": "What happens if the inputs have different classes?",
      "answer": "RunMat follows MATLAB's rules: both inputs must share the same class (numeric/logical, complex, char, or string). Mixed-class inputs raise descriptive errors."
    },
    {
      "question": "Can I request `'legacy'` behaviour?",
      "answer": "No. RunMat implements the modern semantics only. Passing `'legacy'` or `'R2012a'` results in an error."
    }
  ],
  "links": [
    {
      "label": "unique",
      "url": "./unique"
    },
    {
      "label": "union",
      "url": "./union"
    },
    {
      "label": "intersect",
      "url": "./intersect"
    },
    {
      "label": "ismember",
      "url": "./ismember"
    },
    {
      "label": "gpuArray",
      "url": "./gpuarray"
    },
    {
      "label": "gather",
      "url": "./gather"
    },
    {
      "label": "argsort",
      "url": "./argsort"
    },
    {
      "label": "issorted",
      "url": "./issorted"
    },
    {
      "label": "sort",
      "url": "./sort"
    },
    {
      "label": "sortrows",
      "url": "./sortrows"
    }
  ],
  "source": {
    "label": "crates/runmat-runtime/src/builtins/array/sorting_sets/setdiff.rs",
    "url": "crates/runmat-runtime/src/builtins/array/sorting_sets/setdiff.rs"
  },
  "gpu_behavior": [
    "`setdiff` is registered as a residency sink. When tensors reside on the GPU and the active provider does not yet implement a `setdiff` hook, RunMat gathers them to host memory, performs the CPU implementation, and materialises host-resident results. Future providers can wire a custom hook to perform the set difference directly on-device without affecting existing callers."
  ]
}