koblas

SparseSlices

Stateless, allocation-free sparse arithmetic over caller-owned array slices.

The caller owns every buffer and retains it between calls. Scatter input indices and touched indices used by gather or clear operations must be unique within their supplied slices; reductions explicitly permit repeated indices. Required uniqueness, and agreement between an active mark and the touched slice, are caller preconditions: checking either without temporary storage would require quadratic work or a full-dimension scan. Bounds, windows, capacities, overlap, and scatter's incoming indices are validated before any destination is mutated. The existing touched slice is trusted and is never scanned by scatter. Roles without two explicit comparable slices must use distinct arrays; explicit IntArray slices may share an array only when their reserved windows do not overlap.

Unlike com.eignex.koblas.Workspace, this object owns and borrows no storage. These helpers manipulate arithmetic values and active support only. Pivot selection, merit calculations, permutations, dropping policy, and factorization state remain caller responsibilities.

Properties

ARITHMETIC_NONFINITE

Bit reported by scatterAxpyChecked when a product or updated accumulator value is not finite.

ARITHMETIC_NONZERO_PRODUCT_UNDERFLOW

Bit reported by scatterAxpyChecked when nonzero operands produce a zero product.

Functions

activeColumnMaxAbs

fun activeColumnMaxAbs(rowIndices: IntArray, indexOffset: Int, values: DoubleArray, valueOffset: Int, count: Int, activeRows: BooleanArray): Double(source)

Maximum absolute finite value whose row is active. Inactive entries are ignored, empty active support returns zero, and any active NaN or infinity returns NaN.

clearTouched

fun clearTouched(touched: IntArray, touchedOffset: Int, touchedCount: Int, values: DoubleArray, marks: IntArray)(source)

Clears the selected values and marks entries without consuming or changing touched.

The two state arrays must have the same logical dimension. The touched window, including an empty window at the array end, and every selected index are validated before mutation. Selected indices must be unique as a caller precondition; verifying uniqueness without temporary storage would require quadratic work. Values are written as positive zero and marks as zero.

gatherClearTouched

fun gatherClearTouched(touched: IntArray, touchedOffset: Int, touchedCount: Int, accumulator: DoubleArray, marks: IntArray, outIndices: IntArray, outIndexOffset: Int, outValues: DoubleArray, outValueOffset: Int, compactExactZeros: Boolean = false): Int(source)

Writes touched entries as gatherTouched, then clears every visited accumulator and mark entry. Clearing includes exact zeroes omitted by compaction. The caller resets its touched count to zero after the call; touched storage itself is deliberately left intact for reuse.

gatherTouched

fun gatherTouched(touched: IntArray, touchedOffset: Int, touchedCount: Int, accumulator: DoubleArray, outIndices: IntArray, outIndexOffset: Int, outValues: DoubleArray, outValueOffset: Int, compactExactZeros: Boolean = false): Int(source)

Writes touched accumulator entries in touched order and returns the number written. When compactExactZeros is true, both signed zeroes are omitted; NaN and infinities are retained. The accumulator and touched support are left unchanged.

pivotCandidatePositions

fun pivotCandidatePositions(rowIndices: IntArray, indexOffset: Int, values: DoubleArray, valueOffset: Int, count: Int, activeRows: BooleanArray, columnMaximum: Double, absoluteTolerance: Double, relativeThreshold: Double, outPositions: IntArray, outOffset: Int): Int(source)

Writes relative entry positions for active nonzero entries meeting both caller thresholds.

columnMaximum, absoluteTolerance, and relativeThreshold must be finite and nonnegative. The output reserves count positions before filtering. Nonfinite active entries are omitted: a maximum produced by activeColumnMaxAbs would already be NaN, so a finite maximum means they are not eligible arithmetic data.

reduceDotChecked

fun reduceDotChecked(initial: Double, subtractProducts: Boolean, indices: IntArray, indexOffset: Int, values: DoubleArray, valueOffset: Int, count: Int, dense: DoubleArray, arithmeticStatus: IntArray, statusOffset: Int): Double(source)

Reduces indexed products into initial in strict input order and latches arithmetic diagnostics.

Each product is evaluated once, then added to or subtracted from the running result once according to subtractProducts. ARITHMETIC_NONFINITE reports a nonfinite initial value, operand, product, or updated result. ARITHMETIC_NONZERO_PRODUCT_UNDERFLOW reports two nonzero finite operands whose product is zero. Existing status bits are preserved, and the IEEE result is returned rather than converted to an exception. A zero updated sum is not classified as addition underflow because it may be exact cancellation.

Status and input windows and every index are validated before any arithmetic is evaluated. Repeated and unsorted indices are permitted and contribute in their supplied order. values and dense may alias.

scatterAxpy

fun scatterAxpy(alpha: Double, indices: IntArray, indexOffset: Int, values: DoubleArray, valueOffset: Int, count: Int, accumulator: DoubleArray, marks: IntArray, epoch: Int, touched: IntArray, touchedOffset: Int, touchedCount: Int): Int(source)

Accumulates alpha * values(k) at indices(k) and returns the new total touched count.

A first touch initializes the accumulator entry from positive zero, writes epoch to its mark, and appends the index once in input order. Already touched entries keep their original position. Exact cancellation does not remove support. epoch must be nonzero and is caller-managed; marks must be reset before epoch reuse or wrap. The existing touched slice must contain every entry encountered here whose mark already equals epoch. This is a trusted precondition: the existing touched slice and its marks are not scanned. Capacity is required only for indices whose mark does not yet equal epoch.

Zero alpha is evaluated, not treated as a no-op. Thus finite values still become touched and 0 * infinity produces NaN according to IEEE 754 arithmetic.

scatterAxpyChecked

fun scatterAxpyChecked(alpha: Double, indices: IntArray, indexOffset: Int, values: DoubleArray, valueOffset: Int, count: Int, accumulator: DoubleArray, marks: IntArray, epoch: Int, touched: IntArray, touchedOffset: Int, touchedCount: Int, arithmeticStatus: IntArray, statusOffset: Int): Int(source)

Performs scatterAxpy while latching arithmetic diagnostics into arithmeticStatus at statusOffset.

ARITHMETIC_NONFINITE is set when a multiplication or updated accumulator value is nonfinite. ARITHMETIC_NONZERO_PRODUCT_UNDERFLOW is set when two nonzero operands produce a zero product. Existing bits in the status element are preserved, allowing one caller-owned element to collect diagnostics across repeated scatters. The IEEE result is always written, and each product and sum is evaluated exactly once.