C# API reference
Every public function of the .NET library (.NET 8), with its parameters and results (Kwker 0.1.0).
Kwker for .NET: sorting, selection, argsort, top-k, key-value sorts, searching, ranks, unique keys and set operations on spans of sbyte / byte / short / ushort / int / uint / long / ulong / float / double through the Kwker C library (P/Invoke, the span's own memory - no copies).
Types
Order Page
public enum Order : uint
Sort order flags (combine with |): smallest first unless Descending; NaNs last unless NansFirst.
Order
Order.Ascending Page
Ascending = 0
Ascending order (the default).
Order.Descending Page
Descending = 1
Descending order.
Order.NansFirst Page
NansFirst = 2
Floats: NaNs before all numbers instead of after them.
Types
Side Page
public enum Side
Where SearchSorted puts a query among equal keys.
Side
Side.Left Page
Left = 0
Before the keys equal to it: the lower bound.
Side.Right Page
Right = 1
After the keys equal to it: the upper bound.
Types
Ties Page
public enum Ties
How Rank ranks equal keys.
Ties
Ties.Ordinal Page
Ordinal = 0
Distinct ranks in input order (stable).
Ties.Min Page
Min = 1
The lowest rank of the group for each.
Ties.Max Page
Max = 2
The highest rank of the group for each.
Ties.Dense Page
Dense = 3
Consecutive ranks per distinct key, no gaps.
Types
SetOp Page
public enum SetOp
The set operation of SetOperation.
SetOp
SetOp.Intersection Page
Intersection = 0
Keys in both.
SetOp.Union Page
Union = 1
Keys in either.
SetOp.Difference Page
Difference = 2
Keys of the first that are not in the second.
SetOp.SymmetricDifference Page
SymmetricDifference = 3
Keys in exactly one of them.
Sorter
Sort Page
public static void Sort<T>(Span<T> a, Order order = Order.Ascending) where T : unmanaged;
public static void Sort<T>(T[] a, Order order = Order.Ascending) where T : unmanaged;
Sorts the span in place (not stable: equal keys are identical).
Remarks: Not stable (rule 5): keys that are equal but can be told apart (NaNs with different bits) may change places. Keys follow the key order: -0.0 before +0.0, every NaN in one block, last unless NaNs-first is asked for.
Examples: Quickstart: Kwker Core: Sort an array, Core concepts: In place or a copy, Runtime controls: Fallback switches, Sorting: Sort in place
Select Page
public static void Select<T>(Span<T> a, int k, Order order = Order.Ascending) where T : unmanaged;
public static void Select<T>(T[] a, int k, Order order = Order.Ascending) where T : unmanaged;
a[k] gets the key a full sort would put there; every key before it sorts before or equal to it, every key after it after or equal. Neither side is sorted.
Remarks: Position k holds the key a full sort puts there; the keys before it are ordered before or equal to it, the keys after it after or equal (rule 7). Keys follow the key order: -0.0 before +0.0, every NaN in one block, last unless NaNs-first is asked for.
Examples: Quickstart: Kwker Core: The median, without a full sort, Top-k and selection: The median and other positions
PartialSort Page
public static void PartialSort<T>(Span<T> a, int k, Order order = Order.Ascending) where T : unmanaged;
public static void PartialSort<T>(T[] a, int k, Order order = Order.Ascending) where T : unmanaged;
The first k keys in order, the rest in any order.
Remarks: The first k positions hold exactly what a full sort puts there; the rest hold the other keys in any order (rule 8). Keys follow the key order: -0.0 before +0.0, every NaN in one block, last unless NaNs-first is asked for.
Examples: Top-k and selection: Sort only the beginning
ArgSort Page
public static int[] ArgSort<T>(ReadOnlySpan<T> a, Order order = Order.Ascending) where T : unmanaged;
public static int[] ArgSort<T>(T[] a, Order order = Order.Ascending) where T : unmanaged;
The stable sorting permutation (the span unchanged).
Remarks: Stable (rule 6): equal keys keep their input order, so the same input always gives the same positions. Keys follow the key order: -0.0 before +0.0, every NaN in one block, last unless NaNs-first is asked for.
Examples: Quickstart: Kwker Core: Get the order, not the sorted data, Order and ranking: The order of an array: argsort, Languages: The same calls in every language, Order and ranking: Reorder several columns together
ArgSelect Page
public static int[] ArgSelect<T>(ReadOnlySpan<T> a, int k, Order order = Order.Ascending) where T : unmanaged;
public static int[] ArgSelect<T>(T[] a, int k, Order order = Order.Ascending) where T : unmanaged;
The indices of the stable order's first k keys, in any order.
Remarks: The positions of the stable order's first k keys, in any order (rule 6). Keys follow the key order: -0.0 before +0.0, every NaN in one block, last unless NaNs-first is asked for.
Examples: Top-k and selection: Only the positions
TopK Page
public static (T[] Values, int[] Indices) TopK<T>(ReadOnlySpan<T> a, int k, Order order = Order.Ascending) where T : unmanaged;
public static (T[] Values, int[] Indices) TopK<T>(T[] a, int k, Order order = Order.Ascending) where T : unmanaged;
The stable order's first k keys and their indices, in that order (the k smallest; Descending: the k largest; equal keys by index); the span unchanged.
Remarks: The first k keys of the stable order and their positions; equal keys keep their input order (rule 9). Keys follow the key order: -0.0 before +0.0, every NaN in one block, last unless NaNs-first is asked for.
Examples: Quickstart: Kwker Core: Find the top results, Use Kwker from C# and .NET: The program, Top-k and selection: The k largest or smallest values, Languages: The same calls in every language
SortKV Page
public static void SortKV<TKey, TValue>(Span<TKey> keys, Span<TValue> values, Order order = Order.Ascending);
public static void SortKV<TKey, TValue>(TKey[] keys, TValue[] values, Order order = Order.Ascending) where TKey : unmanaged where TValue : unmanaged;
Sorts the keys in place and moves each value with its key; equal keys' values end in unspecified order (SortKVStable keeps their input order). Values of any unmanaged type (int, double, a struct, ...); both spans the same length.
Remarks: Unless the stable form is asked for, pairs with equal keys may come out in any order; the stable form keeps their input order (rule 6). Keys follow the key order: -0.0 before +0.0, every NaN in one block, last unless NaNs-first is asked for.
Examples: Core concepts: In place or a copy, Sorting keys with values: Sort keys and values together
SortKVStable Page
public static void SortKVStable<TKey, TValue>(Span<TKey> keys, Span<TValue> values, Order order = Order.Ascending);
public static void SortKVStable<TKey, TValue>(TKey[] keys, TValue[] values, Order order = Order.Ascending) where TKey : unmanaged where TValue : unmanaged;
SortKV, stable: equal keys keep their values in input order.
Remarks: Stable (rule 6): equal keys keep their input order, so the same input always gives the same positions. Keys follow the key order: -0.0 before +0.0, every NaN in one block, last unless NaNs-first is asked for.
Examples: Sorting keys with values: Keep equal keys in order: the stable sort
PartialSortKV Page
public static void PartialSortKV<TKey, TValue>(Span<TKey> keys, Span<TValue> values, int k, Order order = Order.Ascending);
public static void PartialSortKV<TKey, TValue>(TKey[] keys, TValue[] values, int k, Order order = Order.Ascending) where TKey : unmanaged where TValue : unmanaged;
The first k keys in order, each with its value; the rest in any order.
Remarks: The first k positions hold exactly what a full sort puts there; the rest hold the other keys in any order (rule 8). Unless the stable form is asked for, pairs with equal keys may come out in any order; the stable form keeps their input order (rule 6).
Examples: Sorting keys with values: Only the first k pairs
SelectKV Page
public static void SelectKV<TKey, TValue>(Span<TKey> keys, Span<TValue> values, int k, Order order = Order.Ascending);
public static void SelectKV<TKey, TValue>(TKey[] keys, TValue[] values, int k, Order order = Order.Ascending) where TKey : unmanaged where TValue : unmanaged;
keys[k] gets the key a full sort would put there, with its value; every key before it sorts before or equal to it, every key after it after or equal. Neither side is sorted.
Remarks: Position k holds the key a full sort puts there; the keys before it are ordered before or equal to it, the keys after it after or equal (rule 7). Unless the stable form is asked for, pairs with equal keys may come out in any order; the stable form keeps their input order (rule 6).
SortRows Page
public static void SortRows<T>(Span<T> a, int rowLength, Order order = Order.Ascending) where T : unmanaged;
public static void SortRows<T>(T[] a, int rowLength, Order order = Order.Ascending) where T : unmanaged;
Sorts each row of a row-major array of rows of rowLength keys (a.Length a multiple of rowLength).
Remarks: Not stable (rule 5): keys that are equal but can be told apart (NaNs with different bits) may change places. Keys follow the key order: -0.0 before +0.0, every NaN in one block, last unless NaNs-first is asked for.
Examples: Sorting: Sort each row
SearchSorted Page
public static int[] SearchSorted<T>(ReadOnlySpan<T> sorted, ReadOnlySpan<T> queries, Side side = Side.Left, Order order = Order.Ascending);
public static int[] SearchSorted<T>(T[] sorted, T[] queries, Side side = Side.Left, Order order = Order.Ascending) where T : unmanaged;
The position where each query goes in sorted, which must already be in order (not checked): before the keys equal to it (Side.Left, the lower bound) or after them (Side.Right, the upper bound). Values compare as in NumPy: -0.0 equals 0.0.
Remarks: -0.0 and +0.0 compare equal here, as in NumPy (rule 14).
Examples: Searching sorted data: Where does a value go? searchsorted, Searching sorted data: Which bucket? bucketize
Rank Page
public static int[] Rank<T>(ReadOnlySpan<T> a, Ties ties = Ties.Ordinal, Order order = Order.Ascending) where T : unmanaged;
public static int[] Rank<T>(T[] a, Ties ties = Ties.Ordinal, Order order = Order.Ascending) where T : unmanaged;
The 1-based rank of every key (ranks[i] is a[i]'s); equal keys ranked as ties says.
Remarks: Ordinal ranks give equal keys increasing ranks in input order (rule 6). Equal values are one key here, as in NumPy: -0.0 and +0.0 are equal, and so are all NaNs (rule 13).
Examples: Order and ranking: Ranks
RankAverage Page
public static double[] RankAverage<T>(ReadOnlySpan<T> a, Order order = Order.Ascending) where T : unmanaged;
public static double[] RankAverage<T>(T[] a, Order order = Order.Ascending) where T : unmanaged;
The 1-based rank of every key, equal keys sharing the mean of their ranks (2, 3 -> 2.5 each).
Remarks: Equal values are one key here, as in NumPy: -0.0 and +0.0 are equal, and so are all NaNs (rule 13).
Examples: Order and ranking: Ranks
PercentRank Page
public static double[] PercentRank<T>(ReadOnlySpan<T> a, Order order = Order.Ascending) where T : unmanaged;
public static double[] PercentRank<T>(T[] a, Order order = Order.Ascending) where T : unmanaged;
Every key's percent rank, (min rank - 1) / (n - 1): 0 for the first key in order, 1 for the last.
Remarks: Equal values are one key here, as in NumPy: -0.0 and +0.0 are equal, and so are all NaNs (rule 13).
Examples: Order and ranking: Ranks
Unique Page
public static (T[] Values, int[] Inverse, int[] Counts) Unique<T>(ReadOnlySpan<T> a) where T : unmanaged;
public static (T[] Values, int[] Inverse, int[] Counts) Unique<T>(T[] a) where T : unmanaged;
The distinct keys in ascending order, the group of every key (Inverse[i]: the index of a[i] in Values) and each group's size. Floats: -0.0 and 0.0 are one key, every NaN its own.
Remarks: -0.0 and +0.0 are one value; every NaN is a value of its own, listed last (rule 15).
SetOperation Page
public static T[] SetOperation<T>(ReadOnlySpan<T> a, ReadOnlySpan<T> b, SetOp op, bool multiset = false, Order order = Order.Ascending);
public static T[] SetOperation<T>(T[] a, T[] b, SetOp op, bool multiset = false, Order order = Order.Ascending) where T : unmanaged;
A set operation on two spans that are both in order: their intersection, union, difference (a without b) or symmetric difference, in that order. Each key once, or with multiset the counts min / max / a - b / |a - b|.
Remarks: Equal values are one key here, as in NumPy: -0.0 and +0.0 are equal, and so are all NaNs (rule 13).
Examples: Groups, merges and sets: Set operations
SortMT Page
public static void SortMT<T>(Span<T> a, Order order = Order.Ascending, int threads = 0) where T : unmanaged;
public static void SortMT<T>(T[] a, Order order = Order.Ascending, int threads = 0) where T : unmanaged;
Sorts in place on threads threads (0: the default count); the result is exactly
Sort's.
Remarks: Not stable (rule 5): keys that are equal but can be told apart (NaNs with different bits) may change places. Keys follow the key order: -0.0 before +0.0, every NaN in one block, last unless NaNs-first is asked for. Threads change only the speed: the result follows the same rules on any thread count (rule 10).
Examples: Sorting: Big arrays: use more cores, Large data: Use several cores
ScratchLimit Page
public static long? ScratchLimit;
The calling thread's scratch-memory limit for later calls, in bytes (null: none, the default; 0: Sort, Select, PartialSort and SortKV allocate nothing). Results never change; some inputs sort slower.
Remarks: The scratch limit changes only the speed and memory use, never a result (rule 12).
BucketCounts Page
public static long[] BucketCounts<T>(ReadOnlySpan<T> values, ReadOnlySpan<T> boundaries, bool right = false, Order order = Order.Ascending) where T : unmanaged;
public static long[] BucketCounts<T>(T[] values, T[] boundaries, bool right = false, Order order = Order.Ascending);
Values per bucket of the sorted boundaries (boundaries.Length + 1 counts): with right false a value v lands in bucket i when boundaries[i-1] < v <= boundaries[i] (torch.bucketize), with right true when boundaries[i-1] <= v < boundaries[i].
Remarks: -0.0 and +0.0 compare equal here, as in NumPy (rule 14).
Examples: Searching sorted data: How many in each bucket? bucket_counts
TopKMasked Page
public static (T[] Values, int[] Indices) TopKMasked<T>(ReadOnlySpan<T> a, ReadOnlySpan<bool> mask, int k, Order order = Order.Ascending, bool sorted = true) where T : unmanaged;
The first k keys of the stable order among the positions where mask is true, and their indices (fewer when fewer positions take part).
Examples: Top-k and selection: Top-k with a filter
TopKByGroup Page
public static (long[] Labels, int[][] Indices) TopKByGroup<T>(ReadOnlySpan<T> a, ReadOnlySpan<long> groups, int k, Order order = Order.Ascending) where T : unmanaged;
For every distinct group label (ascending), the indices of that group's first k keys in the stable order.
Examples: Top-k and selection: Top-k per group
KWayMerge Page
public static T[] KWayMerge<T>(Order order, params T[][] runs) where T : unmanaged;
Merges runs, each sorted in order, into one sorted array; equal keys keep run, then
index order.
Examples: Groups, merges and sets: Merge sorted lists: kway_merge
Types
Reduce Page
public enum Reduce
The reduction ReduceByKey applies per key.
Reduce
Reduce.Sum Page
Sum = 0
Integers wrap; floats add in input order.
Reduce.Min Page
Min = 1
In the ascending order: -0.0 below +0.0, NaN above all.
Reduce.Max Page
Max = 2
In the ascending order.
Reduce.First Page
First = 3
The key's first value in input order.
Reduce.Last Page
Last = 4
The key's last value in input order.
ReduceByKey Page
public static (TKey[] Keys, TValue[] Values) ReduceByKey<TKey, TValue>(ReadOnlySpan<TKey> keys, ReadOnlySpan<TValue> values, Reduce op = Reduce.Sum, Order order = Order.Ascending) where TKey : unmanaged where TValue : unmanaged;
The distinct keys in order and one reduction of their values each (values: int, long, uint, ulong, float or double).
Examples: Groups, merges and sets: Totals per key: reduce_by_key
CountByKey Page
public static (T[] Keys, long[] Counts) CountByKey<T>(ReadOnlySpan<T> keys, Order order = Order.Ascending) where T : unmanaged;
The distinct keys in order and how often each occurs.
Examples: Groups, merges and sets: Totals per key: reduce_by_key
PermuteInPlace Page
public static void PermuteInPlace<TRecord>(Span<TRecord> records, ReadOnlySpan<int> perm) where TRecord : unmanaged;
Reorders records so that record j becomes the one at perm[j] (an ArgSort result applied), with no copy of the records. perm must be a permutation of 0..records.Length.
Types
Collation Page
public enum Collation : uint
How SortStrings and ArgsortStrings compare strings.
Collation
Collation.Bytes Page
Bytes = 0
Byte order of the UTF-8 encoding: Unicode code point order (string.CompareOrdinal orders UTF-16 code units, which differs for characters above U+FFFF).
Collation.Caseless Page
Caseless = 1
ASCII letters compare without case; other characters by their UTF-8 bytes.
Collation.Natural Page
Natural = 2
Digit runs compare as numbers ("file2" before "file10"), leading zeros ignored.
Collation.NaturalCaseless Page
NaturalCaseless = 3
Natural and Caseless together.
ArgsortStrings Page
public static int[] ArgsortStrings(string[] a, Collation collation = Collation.Bytes);
The stable order of the strings in a collation: a[r[0]], a[r[1]], ... is sorted, and strings the collation treats as equal keep their input order. The array is not modified; null strings throw.
Examples: Strings: The order of strings
SortStrings Page
public static void SortStrings(string[] a, Collation collation = Collation.Bytes);
Sorts the strings in place in a collation (see ArgsortStrings); stable.
Examples: Strings: Sort a list of strings
Types
Column Page
public readonly struct Column
One key column for LexSort / GroupCodes: an array of any key type and its order.
Column
Of Page
public static Column Of<T>(T[] keys, Order order = Order.Ascending) where T : unmanaged;
A column over keys in the given order.
LexSort Page
public static int[] LexSort(params Column[] cols);
The stable permutation sorting the rows by the columns, the first most significant (SQL ORDER BY a, b).
Examples: Order and ranking: Sort by several columns
LexTopK Page
public static int[] LexTopK(int k, params Column[] cols);
The first min(k, n) rows of LexSort's order, without sorting every row (SQL ORDER BY .. LIMIT k).
Examples: Order and ranking: Sort by several columns
GroupCodes Page
public static (int[] Codes, int[] FirstRow, int[] Size) GroupCodes(params Column[] cols);
The rows' groups numbered 0.. in the columns' lexicographic order (equal keys: one group): a code per row, and each group's first row and size.
Examples: Groups, merges and sets: Group several key columns: group_codes
SortFile Page
public static void SortFile<T>(string input, string output, long memory = 0, Order order = Order.Ascending, int threads = 0);
Sorts the file input of native-endian T keys into output (may be the
same path) with about memory bytes of buffers (0: 256 MiB) - files larger than memory included.
Throws IOException for an I/O error or a length that is not a whole number of keys.
Examples: Large data: Sort a file larger than memory
SetIsa Page
public static string SetIsa(string? name);
Caps the engine of later calls ("avx512", "avx2", "sse42", "neon", "simd128", "portable"; null: the best the CPU and KWKER_ISA allow) and returns the engine now in use. Results never depend on the engine, only speed. Process-wide. Throws ArgumentException for an unknown name.
Remarks: The engine changes only the speed, never a result (rule 11).
Examples: Runtime controls: Fallback switches
Isa Page
public static string Isa;
The engine in use: "avx512", "avx2" or "portable".
Remarks: The engine changes only the speed, never a result (rule 11).
Version Page
public static string Version;
The library version.