Kwker

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

C#Add the Kwker NuGet package, then dotnet run.
public enum Order : uint

Sort order flags (combine with |): smallest first unless Descending; NaNs last unless NansFirst.

Order

Order.Ascending Page

C#Add the Kwker NuGet package, then dotnet run.
Ascending = 0

Ascending order (the default).

Order.Descending Page

C#Add the Kwker NuGet package, then dotnet run.
Descending = 1

Descending order.

Order.NansFirst Page

C#Add the Kwker NuGet package, then dotnet run.
NansFirst = 2

Floats: NaNs before all numbers instead of after them.

Types

Side Page

C#Add the Kwker NuGet package, then dotnet run.
public enum Side

Where SearchSorted puts a query among equal keys.

Side

Side.Left Page

C#Add the Kwker NuGet package, then dotnet run.
Left = 0

Before the keys equal to it: the lower bound.

Side.Right Page

C#Add the Kwker NuGet package, then dotnet run.
Right = 1

After the keys equal to it: the upper bound.

Types

Ties Page

C#Add the Kwker NuGet package, then dotnet run.
public enum Ties

How Rank ranks equal keys.

Ties

Ties.Ordinal Page

C#Add the Kwker NuGet package, then dotnet run.
Ordinal = 0

Distinct ranks in input order (stable).

Ties.Min Page

C#Add the Kwker NuGet package, then dotnet run.
Min = 1

The lowest rank of the group for each.

Ties.Max Page

C#Add the Kwker NuGet package, then dotnet run.
Max = 2

The highest rank of the group for each.

Ties.Dense Page

C#Add the Kwker NuGet package, then dotnet run.
Dense = 3

Consecutive ranks per distinct key, no gaps.

Types

SetOp Page

C#Add the Kwker NuGet package, then dotnet run.
public enum SetOp

The set operation of SetOperation.

SetOp

SetOp.Intersection Page

C#Add the Kwker NuGet package, then dotnet run.
Intersection = 0

Keys in both.

SetOp.Union Page

C#Add the Kwker NuGet package, then dotnet run.
Union = 1

Keys in either.

SetOp.Difference Page

C#Add the Kwker NuGet package, then dotnet run.
Difference = 2

Keys of the first that are not in the second.

SetOp.SymmetricDifference Page

C#Add the Kwker NuGet package, then dotnet run.
SymmetricDifference = 3

Keys in exactly one of them.

Sorter

Sort Page

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
public enum Reduce

The reduction ReduceByKey applies per key.

Reduce

Reduce.Sum Page

C#Add the Kwker NuGet package, then dotnet run.
Sum = 0

Integers wrap; floats add in input order.

Reduce.Min Page

C#Add the Kwker NuGet package, then dotnet run.
Min = 1

In the ascending order: -0.0 below +0.0, NaN above all.

Reduce.Max Page

C#Add the Kwker NuGet package, then dotnet run.
Max = 2

In the ascending order.

Reduce.First Page

C#Add the Kwker NuGet package, then dotnet run.
First = 3

The key's first value in input order.

Reduce.Last Page

C#Add the Kwker NuGet package, then dotnet run.
Last = 4

The key's last value in input order.

ReduceByKey Page

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
public enum Collation : uint

How SortStrings and ArgsortStrings compare strings.

Collation

Collation.Bytes Page

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
Caseless = 1

ASCII letters compare without case; other characters by their UTF-8 bytes.

Collation.Natural Page

C#Add the Kwker NuGet package, then dotnet run.
Natural = 2

Digit runs compare as numbers ("file2" before "file10"), leading zeros ignored.

Collation.NaturalCaseless Page

C#Add the Kwker NuGet package, then dotnet run.
NaturalCaseless = 3

Natural and Caseless together.

ArgsortStrings Page

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
public readonly struct Column

One key column for LexSort / GroupCodes: an array of any key type and its order.

Column

Of Page

C#Add the Kwker NuGet package, then dotnet run.
public static Column Of<T>(T[] keys, Order order = Order.Ascending) where T : unmanaged;

A column over keys in the given order.

LexSort Page

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
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

C#Add the Kwker NuGet package, then dotnet run.
public static string Version;

The library version.

Applies to Kwker 0.1 · C#
Last updated
Was this page helpful?
Kwker 0.1.x: the engines each platform chooses from at run time (details)
PlatformEngines
Linux x86-64AVX-512, AVX2, SSE4.2, portable
Linux ARM64SVE / SVE2 (64-bit keys), NEON, portable
Windows x64AVX-512, AVX2, SSE4.2, portable
Windows ARM64NEON, portable
macOS ARM64NEON, portable
macOS x86-64AVX2, SSE4.2, portable
Other CPUs (RISC-V, POWER, x86 without SSE4.2, ...)portable