From 0a8044ddb3cf4fd6fc38431106daea4aa4ff5302 Mon Sep 17 00:00:00 2001 From: Iaroslav Date: Fri, 7 Aug 2020 15:20:26 +0700 Subject: [PATCH] Update buffers documentation, make API more consistent, minor changes --- .../scientifik/kmath/expressions/Builders.kt | 6 +- .../kmath/operations/AlgebraElements.kt | 13 ++++ .../scientifik/kmath/structures/Buffers.kt | 63 +++++++++++++++---- .../kmath/structures/FlaggedBuffer.kt | 22 ++++++- .../kmath/structures/FloatBuffer.kt | 49 +++++++++++++++ .../scientifik/kmath/structures/IntBuffer.kt | 4 +- .../scientifik/kmath/structures/LongBuffer.kt | 31 +++++++++ .../kmath/structures/MemoryBuffer.kt | 13 +++- .../scientifik/kmath/structures/NDAlgebra.kt | 4 +- .../scientifik/kmath/structures/RealBuffer.kt | 11 ++-- .../kmath/structures/RealBufferField.kt | 7 ++- .../kmath/structures/ShortBuffer.kt | 31 +++++++++ 12 files changed, 227 insertions(+), 27 deletions(-) create mode 100644 kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/FloatBuffer.kt diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/Builders.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/Builders.kt index 9f1503285..834ef9e24 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/Builders.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/Builders.kt @@ -5,19 +5,19 @@ import scientifik.kmath.operations.Ring import scientifik.kmath.operations.Space /** - * Create a functional expression on this [Space] + * Creates a functional expression with this [Space]. */ fun Space.spaceExpression(block: FunctionalExpressionSpace>.() -> Expression): Expression = FunctionalExpressionSpace(this).run(block) /** - * Create a functional expression on this [Ring] + * Creates a functional expression with this [Ring]. */ fun Ring.ringExpression(block: FunctionalExpressionRing>.() -> Expression): Expression = FunctionalExpressionRing(this).run(block) /** - * Create a functional expression on this [Field] + * Creates a functional expression with this [Field]. */ fun Field.fieldExpression(block: FunctionalExpressionField>.() -> Expression): Expression = FunctionalExpressionField(this).run(block) diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraElements.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraElements.kt index 534f56e0d..197897c14 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraElements.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraElements.kt @@ -12,8 +12,21 @@ interface MathElement { val context: C } +/** + * Represents element that can be wrapped to its "primitive" value. + * + * @param T the type wrapped by this wrapper. + * @param I the type of this wrapper. + */ interface MathWrapper { + /** + * Unwraps [I] to [T]. + */ fun unwrap(): T + + /** + * Wraps [T] to [I]. + */ fun T.wrap(): I } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Buffers.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Buffers.kt index 73c3f96f4..5fdf79e88 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Buffers.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Buffers.kt @@ -19,10 +19,11 @@ typealias BufferFactory = (Int, (Int) -> T) -> Buffer typealias MutableBufferFactory = (Int, (Int) -> T) -> MutableBuffer /** - * A generic random-access structure for both primitives and objects. + * A generic immutable random-access structure for both primitives and objects. + * + * @param T the type of elements contained in the buffer. */ interface Buffer { - /** * The size of this buffer. */ @@ -45,7 +46,6 @@ interface Buffer { asSequence().mapIndexed { index, value -> value == other[index] }.all { it } companion object { - inline fun real(size: Int, initializer: (Int) -> Double): RealBuffer { val array = DoubleArray(size) { initializer(it) } return RealBuffer(array) @@ -95,6 +95,8 @@ val Buffer<*>.indices: IntRange get() = 0 until size /** * A generic mutable random-access structure for both primitives and objects. + * + * @param T the type of elements contained in the buffer. */ interface MutableBuffer : Buffer { /** @@ -138,8 +140,13 @@ interface MutableBuffer : Buffer { } } +/** + * [Buffer] implementation over [List]. + * + * @param T the type of elements contained in the buffer. + * @property list The underlying list. + */ inline class ListBuffer(val list: List) : Buffer { - override val size: Int get() = list.size @@ -148,10 +155,26 @@ inline class ListBuffer(val list: List) : Buffer { override fun iterator(): Iterator = list.iterator() } +/** + * Returns an [ListBuffer] that wraps the original list. + */ fun List.asBuffer(): ListBuffer = ListBuffer(this) +/** + * Creates a new [ListBuffer] with the specified [size], where each element is calculated by calling the specified + * [init] function. + * + * The function [init] is called for each array element sequentially starting from the first one. + * It should return the value for an array element given its index. + */ inline fun ListBuffer(size: Int, init: (Int) -> T): ListBuffer = List(size, init).asBuffer() +/** + * [MutableBuffer] implementation over [MutableList]. + * + * @param T the type of elements contained in the buffer. + * @property list The underlying list. + */ inline class MutableListBuffer(val list: MutableList) : MutableBuffer { override val size: Int @@ -167,8 +190,14 @@ inline class MutableListBuffer(val list: MutableList) : MutableBuffer { override fun copy(): MutableBuffer = MutableListBuffer(ArrayList(list)) } +/** + * [MutableBuffer] implementation over [Array]. + * + * @param T the type of elements contained in the buffer. + * @property array The underlying array. + */ class ArrayBuffer(private val array: Array) : MutableBuffer { - //Can't inline because array is invariant + // Can't inline because array is invariant override val size: Int get() = array.size @@ -183,8 +212,17 @@ class ArrayBuffer(private val array: Array) : MutableBuffer { override fun copy(): MutableBuffer = ArrayBuffer(array.copyOf()) } +/** + * Returns an [ArrayBuffer] that wraps the original array. + */ fun Array.asBuffer(): ArrayBuffer = ArrayBuffer(this) +/** + * Immutable wrapper for [MutableBuffer]. + * + * @param T the type of elements contained in the buffer. + * @property buffer The underlying buffer. + */ inline class ReadOnlyBuffer(val buffer: MutableBuffer) : Buffer { override val size: Int get() = buffer.size @@ -196,6 +234,8 @@ inline class ReadOnlyBuffer(val buffer: MutableBuffer) : Buffer { /** * A buffer with content calculated on-demand. The calculated content is not stored, so it is recalculated on each call. * Useful when one needs single element from the buffer. + * + * @param T the type of elements provided by the buffer. */ class VirtualBuffer(override val size: Int, private val generator: (Int) -> T) : Buffer { override fun get(index: Int): T { @@ -215,17 +255,16 @@ class VirtualBuffer(override val size: Int, private val generator: (Int) -> T } /** - * Convert this buffer to read-only buffer + * Convert this buffer to read-only buffer. */ -fun Buffer.asReadOnly(): Buffer = if (this is MutableBuffer) { - ReadOnlyBuffer(this) -} else { - this -} +fun Buffer.asReadOnly(): Buffer = if (this is MutableBuffer) ReadOnlyBuffer(this) else this /** - * Typealias for buffer transformations + * Typealias for buffer transformations. */ typealias BufferTransform = (Buffer) -> Buffer +/** + * Typealias for buffer transformations with suspend function. + */ typealias SuspendBufferTransform = suspend (Buffer) -> Buffer diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/FlaggedBuffer.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/FlaggedBuffer.kt index 2382e2c57..a2d0a71b3 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/FlaggedBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/FlaggedBuffer.kt @@ -2,15 +2,35 @@ package scientifik.kmath.structures import kotlin.experimental.and +/** + * Represents flags to supply additional info about values of buffer. + * + * @property mask bit mask value of this flag. + */ enum class ValueFlag(val mask: Byte) { + /** + * Reports the value is NaN. + */ NAN(0b0000_0001), + + /** + * Reports the value doesn't present in the buffer (when the type of value doesn't support `null`). + */ MISSING(0b0000_0010), + + /** + * Reports the value is negative infinity. + */ NEGATIVE_INFINITY(0b0000_0100), + + /** + * Reports the value is positive infinity + */ POSITIVE_INFINITY(0b0000_1000) } /** - * A buffer with flagged values + * A buffer with flagged values. */ interface FlaggedBuffer : Buffer { fun getFlag(index: Int): Byte diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/FloatBuffer.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/FloatBuffer.kt new file mode 100644 index 000000000..e42df8c14 --- /dev/null +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/FloatBuffer.kt @@ -0,0 +1,49 @@ +package scientifik.kmath.structures + +/** + * Specialized [MutableBuffer] implementation over [FloatArray]. + * + * @property array the underlying array. + */ +inline class FloatBuffer(val array: FloatArray) : MutableBuffer { + override val size: Int get() = array.size + + override fun get(index: Int): Float = array[index] + + override fun set(index: Int, value: Float) { + array[index] = value + } + + override fun iterator(): FloatIterator = array.iterator() + + override fun copy(): MutableBuffer = + FloatBuffer(array.copyOf()) +} + +/** + * Creates a new [FloatBuffer] with the specified [size], where each element is calculated by calling the specified + * [init] function. + * + * The function [init] is called for each array element sequentially starting from the first one. + * It should return the value for an buffer element given its index. + */ +inline fun FloatBuffer(size: Int, init: (Int) -> Float): FloatBuffer = FloatBuffer(FloatArray(size) { init(it) }) + +/** + * Returns a new [FloatBuffer] of given elements. + */ +fun FloatBuffer(vararg floats: Float): FloatBuffer = FloatBuffer(floats) + +/** + * Returns a [FloatArray] containing all of the elements of this [MutableBuffer]. + */ +val MutableBuffer.array: FloatArray + get() = (if (this is FloatBuffer) array else FloatArray(size) { get(it) }) + +/** + * Returns [FloatBuffer] over this array. + * + * @receiver the array. + * @return the new buffer. + */ +fun FloatArray.asBuffer(): FloatBuffer = FloatBuffer(this) diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/IntBuffer.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/IntBuffer.kt index 3bf8ef6ab..a3f0f3c3e 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/IntBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/IntBuffer.kt @@ -26,15 +26,13 @@ inline class IntBuffer(val array: IntArray) : MutableBuffer { * [init] function. * * The function [init] is called for each array element sequentially starting from the first one. - * It should return the value for an array element given its index. + * It should return the value for an buffer element given its index. */ -@Suppress("FunctionName") inline fun IntBuffer(size: Int, init: (Int) -> Int): IntBuffer = IntBuffer(IntArray(size) { init(it) }) /** * Returns a new [IntBuffer] of given elements. */ -@Suppress("FunctionName") fun IntBuffer(vararg ints: Int): IntBuffer = IntBuffer(ints) /** diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/LongBuffer.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/LongBuffer.kt index 3ee2e75a2..912656c68 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/LongBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/LongBuffer.kt @@ -1,5 +1,10 @@ package scientifik.kmath.structures +/** + * Specialized [MutableBuffer] implementation over [LongArray]. + * + * @property array the underlying array. + */ inline class LongBuffer(val array: LongArray) : MutableBuffer { override val size: Int get() = array.size @@ -16,4 +21,30 @@ inline class LongBuffer(val array: LongArray) : MutableBuffer { } +/** + * Creates a new [LongBuffer] with the specified [size], where each element is calculated by calling the specified + * [init] function. + * + * The function [init] is called for each array element sequentially starting from the first one. + * It should return the value for an buffer element given its index. + */ +inline fun LongBuffer(size: Int, init: (Int) -> Long): LongBuffer = LongBuffer(LongArray(size) { init(it) }) + +/** + * Returns a new [LongBuffer] of given elements. + */ +fun LongBuffer(vararg longs: Long): LongBuffer = LongBuffer(longs) + +/** + * Returns a [IntArray] containing all of the elements of this [MutableBuffer]. + */ +val MutableBuffer.array: LongArray + get() = (if (this is LongBuffer) array else LongArray(size) { get(it) }) + +/** + * Returns [LongBuffer] over this array. + * + * @receiver the array. + * @return the new buffer. + */ fun LongArray.asBuffer(): LongBuffer = LongBuffer(this) diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/MemoryBuffer.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/MemoryBuffer.kt index b15487114..70e4a8f0f 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/MemoryBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/MemoryBuffer.kt @@ -4,12 +4,16 @@ import scientifik.memory.* /** * A non-boxing buffer over [Memory] object. + * + * @param T the type of elements contained in the buffer. + * @property memory the underlying memory segment. + * @property spec the spec of [T] type. */ open class MemoryBuffer(protected val memory: Memory, protected val spec: MemorySpec) : Buffer { override val size: Int get() = memory.size / spec.objectSize - private val reader = memory.reader() + private val reader: MemoryReader = memory.reader() override fun get(index: Int): T = reader.read(spec, spec.objectSize * index) @@ -33,6 +37,13 @@ open class MemoryBuffer(protected val memory: Memory, protected val spe } } +/** + * A mutable non-boxing buffer over [Memory] object. + * + * @param T the type of elements contained in the buffer. + * @property memory the underlying memory segment. + * @property spec the spec of [T] type. + */ class MutableMemoryBuffer(memory: Memory, spec: MemorySpec) : MemoryBuffer(memory, spec), MutableBuffer { diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDAlgebra.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDAlgebra.kt index 750133351..f2805529c 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDAlgebra.kt @@ -107,8 +107,8 @@ interface NDRing, N : NDStructure> : Ring, NDSpace /** * Field for n-dimensional structures. * - * @param T - the type of the element contained in ND structure - * @param F - field of structure elements + * @param T the type of the element contained in ND structure + * @param F field of structure elements */ interface NDField, N : NDStructure> : Field, NDRing { diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealBuffer.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealBuffer.kt index 715f3a017..e999e12b2 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealBuffer.kt @@ -1,5 +1,10 @@ package scientifik.kmath.structures +/** + * Specialized [MutableBuffer] implementation over [DoubleArray]. + * + * @property array the underlying array. + */ inline class RealBuffer(val array: DoubleArray) : MutableBuffer { override val size: Int get() = array.size @@ -16,19 +21,17 @@ inline class RealBuffer(val array: DoubleArray) : MutableBuffer { } /** - * Creates a new array with the specified [size], where each element is calculated by calling the specified + * Creates a new [RealBuffer] with the specified [size], where each element is calculated by calling the specified * [init] function. * * The function [init] is called for each array element sequentially starting from the first one. - * It should return the value for an array element given its index. + * It should return the value for an buffer element given its index. */ -@Suppress("FunctionName") inline fun RealBuffer(size: Int, init: (Int) -> Double): RealBuffer = RealBuffer(DoubleArray(size) { init(it) }) /** * Returns a new [RealBuffer] of given elements. */ -@Suppress("FunctionName") fun RealBuffer(vararg doubles: Double): RealBuffer = RealBuffer(doubles) /** diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealBufferField.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealBufferField.kt index 826203d1f..33198aac1 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealBufferField.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealBufferField.kt @@ -6,7 +6,7 @@ import kotlin.math.* /** - * A simple field over linear buffers of [Double] + * [ExtendedFieldOperations] over [RealBuffer]. */ object RealBufferFieldOperations : ExtendedFieldOperations> { override fun add(a: Buffer, b: Buffer): RealBuffer { @@ -109,6 +109,11 @@ object RealBufferFieldOperations : ExtendedFieldOperations> { RealBuffer(DoubleArray(arg.size) { ln(arg[it]) }) } +/** + * [ExtendedField] over [RealBuffer]. + * + * @property size the size of buffers to operate on. + */ class RealBufferField(val size: Int) : ExtendedField> { override val zero: Buffer by lazy { RealBuffer(size) { 0.0 } } override val one: Buffer by lazy { RealBuffer(size) { 1.0 } } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ShortBuffer.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ShortBuffer.kt index 24c94a885..a67cbec62 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ShortBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ShortBuffer.kt @@ -1,5 +1,10 @@ package scientifik.kmath.structures +/** + * Specialized [MutableBuffer] implementation over [ShortBuffer]. + * + * @property array the underlying array. + */ inline class ShortBuffer(val array: ShortArray) : MutableBuffer { override val size: Int get() = array.size @@ -16,4 +21,30 @@ inline class ShortBuffer(val array: ShortArray) : MutableBuffer { } +/** + * Creates a new [ShortBuffer] with the specified [size], where each element is calculated by calling the specified + * [init] function. + * + * The function [init] is called for each array element sequentially starting from the first one. + * It should return the value for an buffer element given its index. + */ +inline fun ShortBuffer(size: Int, init: (Int) -> Short): ShortBuffer = ShortBuffer(ShortArray(size) { init(it) }) + +/** + * Returns a new [ShortBuffer] of given elements. + */ +fun ShortBuffer(vararg shorts: Short): ShortBuffer = ShortBuffer(shorts) + +/** + * Returns a [ShortArray] containing all of the elements of this [MutableBuffer]. + */ +val MutableBuffer.array: ShortArray + get() = (if (this is ShortBuffer) array else ShortArray(size) { get(it) }) + +/** + * Returns [ShortBuffer] over this array. + * + * @receiver the array. + * @return the new buffer. + */ fun ShortArray.asBuffer(): ShortBuffer = ShortBuffer(this)