diff --git a/build.gradle.kts b/build.gradle.kts index 2d7b9f119..8f8bcaa34 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,12 +1,14 @@ buildscript { - val kotlin_version = "1.3.10" + extra["kotlinVersion"] = "1.3.10" + + val kotlinVersion: String by extra repositories { jcenter() } dependencies { - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") classpath("org.jfrog.buildinfo:build-info-extractor-gradle:4+") } } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/histogram/PhantomHistogram.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/histogram/PhantomHistogram.kt index 469856daa..0bd5de0e2 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/histogram/PhantomHistogram.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/histogram/PhantomHistogram.kt @@ -22,6 +22,10 @@ class PhantomBin(val template: BinTemplate, override val value: Number) : Bin, val data: NDStructure diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/LinearAlgrebra.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/LinearAlgrebra.kt index 39931b676..62852ff5d 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/LinearAlgrebra.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/LinearAlgrebra.kt @@ -225,7 +225,7 @@ class ArrayVectorSpace( /** * Member of [ArrayMatrixSpace] which wraps 2-D array */ -class ArrayMatrix internal constructor(override val context: ArrayMatrixSpace, val array: NDArray) : Matrix { +class ArrayMatrix internal constructor(override val context: ArrayMatrixSpace, val element: NDElement) : Matrix { constructor(context: ArrayMatrixSpace, initializer: (Int, Int) -> T) : this(context, context.ndField.produce { list -> initializer(list[0], list[1]) }) @@ -234,32 +234,32 @@ class ArrayMatrix internal constructor(override val context: ArrayMatri override val columns: Int get() = context.columns override fun get(i: Int, j: Int): T { - return array[i, j] + return element[i, j] } override val self: ArrayMatrix get() = this } -class ArrayVector internal constructor(override val context: ArrayVectorSpace, val array: NDArray) : Vector { +class ArrayVector internal constructor(override val context: ArrayVectorSpace, val element: NDElement) : Vector { constructor(context: ArrayVectorSpace, initializer: (Int) -> T) : this(context, context.ndField.produce { list -> initializer(list[0]) }) init { - if (context.size != array.shape[0]) { + if (context.size != element.shape[0]) { error("Array dimension mismatch") } } override fun get(index: Int): T { - return array[index] + return element[index] } override val self: ArrayVector get() = this - override fun iterator(): Iterator = (0 until size).map { array[it] }.iterator() + override fun iterator(): Iterator = (0 until size).map { element[it] }.iterator() - override fun copy(): ArrayVector = ArrayVector(context, array) + override fun copy(): ArrayVector = ArrayVector(context, element) override fun toString(): String = this.joinToString(prefix = "[", postfix = "]", separator = ", ") { it.toString() } } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ExtendedNDField.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ExtendedNDField.kt index 6392aeec6..08751d934 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ExtendedNDField.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ExtendedNDField.kt @@ -1,37 +1,40 @@ package scientifik.kmath.structures -import scientifik.kmath.operations.* +import scientifik.kmath.operations.ExponentialOperations +import scientifik.kmath.operations.ExtendedField +import scientifik.kmath.operations.PowerOperations +import scientifik.kmath.operations.TrigonometricOperations /** * NDField that supports [ExtendedField] operations on its elements */ class ExtendedNDField(shape: IntArray, override val field: ExtendedField) : NDField(shape, field), - TrigonometricOperations>, - PowerOperations>, - ExponentialOperations> { + TrigonometricOperations>, + PowerOperations>, + ExponentialOperations> { override fun produceStructure(initializer: (IntArray) -> N): NDStructure { return genericNdStructure(shape, initializer) } - override fun power(arg: NDArray, pow: Double): NDArray { + override fun power(arg: NDElement, pow: Double): NDElement { return arg.transform { d -> with(field){power(d,pow)} } } - override fun exp(arg: NDArray): NDArray { + override fun exp(arg: NDElement): NDElement { return arg.transform { d -> with(field){exp(d)} } } - override fun ln(arg: NDArray): NDArray { + override fun ln(arg: NDElement): NDElement { return arg.transform { d -> with(field){ln(d)} } } - override fun sin(arg: NDArray): NDArray { + override fun sin(arg: NDElement): NDElement { return arg.transform { d -> with(field){sin(d)} } } - override fun cos(arg: NDArray): NDArray { + override fun cos(arg: NDElement): NDElement { return arg.transform { d -> with(field){cos(d)} } } } diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDField.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDField.kt index 74bffa7ad..6d3ce05a5 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDField.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDField.kt @@ -15,7 +15,7 @@ class ShapeMismatchException(val expected: IntArray, val actual: IntArray) : Run * @param field - operations field defined on individual array element * @param T the type of the element contained in NDArray */ -abstract class NDField(val shape: IntArray, open val field: Field) : Field> { +abstract class NDField(val shape: IntArray, open val field: Field) : Field> { abstract fun produceStructure(initializer: (IntArray) -> T): NDStructure @@ -23,17 +23,17 @@ abstract class NDField(val shape: IntArray, open val field: Field) : Field * Create new instance of NDArray using field shape and given initializer * The producer takes list of indices as argument and returns contained value */ - fun produce(initializer: (IntArray) -> T): NDArray = NDArray(this, produceStructure(initializer)) + fun produce(initializer: (IntArray) -> T): NDElement = NDElement(this, produceStructure(initializer)) - override val zero: NDArray by lazy { + override val zero: NDElement by lazy { produce { this.field.zero } } /** * Check the shape of given NDArray and throw exception if it does not coincide with shape of the field */ - private fun checkShape(vararg arrays: NDArray) { - arrays.forEach { + private fun checkShape(vararg elements: NDElement) { + elements.forEach { if (!shape.contentEquals(it.shape)) { throw ShapeMismatchException(shape, it.shape) } @@ -43,7 +43,7 @@ abstract class NDField(val shape: IntArray, open val field: Field) : Field /** * Element-by-element addition */ - override fun add(a: NDArray, b: NDArray): NDArray { + override fun add(a: NDElement, b: NDElement): NDElement { checkShape(a, b) return produce { with(field) { a[it] + b[it] } } } @@ -51,18 +51,18 @@ abstract class NDField(val shape: IntArray, open val field: Field) : Field /** * Multiply all elements by cinstant */ - override fun multiply(a: NDArray, k: Double): NDArray { + override fun multiply(a: NDElement, k: Double): NDElement { checkShape(a) return produce { with(field) { a[it] * k } } } - override val one: NDArray + override val one: NDElement get() = produce { this.field.one } /** * Element-by-element multiplication */ - override fun multiply(a: NDArray, b: NDArray): NDArray { + override fun multiply(a: NDElement, b: NDElement): NDElement { checkShape(a) return produce { with(field) { a[it] * b[it] } } } @@ -70,7 +70,7 @@ abstract class NDField(val shape: IntArray, open val field: Field) : Field /** * Element-by-element division */ - override fun divide(a: NDArray, b: NDArray): NDArray { + override fun divide(a: NDElement, b: NDElement): NDElement { checkShape(a) return produce { with(field) { a[it] / b[it] } } } @@ -78,12 +78,12 @@ abstract class NDField(val shape: IntArray, open val field: Field) : Field /** * Reverse sum operation */ - operator fun T.plus(arg: NDArray): NDArray = arg + this + operator fun T.plus(arg: NDElement): NDElement = arg + this /** * Reverse minus operation */ - operator fun T.minus(arg: NDArray): NDArray = arg.transform { _, value -> + operator fun T.minus(arg: NDElement): NDElement = arg.transform { _, value -> with(arg.context.field) { this@minus - value } @@ -92,12 +92,12 @@ abstract class NDField(val shape: IntArray, open val field: Field) : Field /** * Reverse product operation */ - operator fun T.times(arg: NDArray): NDArray = arg * this + operator fun T.times(arg: NDElement): NDElement = arg * this /** * Reverse division operation */ - operator fun T.div(arg: NDArray): NDArray = arg.transform { _, value -> + operator fun T.div(arg: NDElement): NDElement = arg.transform { _, value -> with(arg.context.field) { this@div / value } @@ -107,37 +107,37 @@ abstract class NDField(val shape: IntArray, open val field: Field) : Field /** * Immutable [NDStructure] coupled to the context. Emulates Python ndarray */ -class NDArray(override val context: NDField, private val structure: NDStructure) : FieldElement, NDField>, NDStructure by structure { +class NDElement(override val context: NDField, private val structure: NDStructure) : FieldElement, NDField>, NDStructure by structure { //TODO ensure structure is immutable - override val self: NDArray + override val self: NDElement get() = this - inline fun transform(crossinline action: (IntArray, T) -> T): NDArray = context.produce { action(it, get(*it)) } - inline fun transform(crossinline action: (T) -> T): NDArray = context.produce { action(get(*it)) } + inline fun transform(crossinline action: (IntArray, T) -> T): NDElement = context.produce { action(it, get(*it)) } + inline fun transform(crossinline action: (T) -> T): NDElement = context.produce { action(get(*it)) } } /** * Element by element application of any operation on elements to the whole array. Just like in numpy */ -operator fun Function1.invoke(ndArray: NDArray): NDArray = ndArray.transform { _, value -> this(value) } +operator fun Function1.invoke(ndElement: NDElement): NDElement = ndElement.transform { _, value -> this(value) } /* plus and minus */ /** - * Summation operation for [NDArray] and single element + * Summation operation for [NDElement] and single element */ -operator fun NDArray.plus(arg: T): NDArray = transform { _, value -> +operator fun NDElement.plus(arg: T): NDElement = transform { _, value -> with(context.field) { arg + value } } /** - * Subtraction operation between [NDArray] and single element + * Subtraction operation between [NDElement] and single element */ -operator fun NDArray.minus(arg: T): NDArray = transform { _, value -> +operator fun NDElement.minus(arg: T): NDElement = transform { _, value -> with(context.field) { arg - value } @@ -146,18 +146,18 @@ operator fun NDArray.minus(arg: T): NDArray = transform { _, value -> /* prod and div */ /** - * Product operation for [NDArray] and single element + * Product operation for [NDElement] and single element */ -operator fun NDArray.times(arg: T): NDArray = transform { _, value -> +operator fun NDElement.times(arg: T): NDElement = transform { _, value -> with(context.field) { arg * value } } /** - * Division operation between [NDArray] and single element + * Division operation between [NDElement] and single element */ -operator fun NDArray.div(arg: T): NDArray = transform { _, value -> +operator fun NDElement.div(arg: T): NDElement = transform { _, value -> with(context.field) { arg / value } @@ -173,23 +173,23 @@ object NDArrays { /** * Create a platform-optimized NDArray of doubles */ - fun realNDArray(shape: IntArray, initializer: (IntArray) -> Double = { 0.0 }): NDArray { + fun realNDArray(shape: IntArray, initializer: (IntArray) -> Double = { 0.0 }): NDElement { return ExtendedNDField(shape, DoubleField).produce(initializer) } - fun real1DArray(dim: Int, initializer: (Int) -> Double = { _ -> 0.0 }): NDArray { + fun real1DArray(dim: Int, initializer: (Int) -> Double = { _ -> 0.0 }): NDElement { return realNDArray(intArrayOf(dim)) { initializer(it[0]) } } - fun real2DArray(dim1: Int, dim2: Int, initializer: (Int, Int) -> Double = { _, _ -> 0.0 }): NDArray { + fun real2DArray(dim1: Int, dim2: Int, initializer: (Int, Int) -> Double = { _, _ -> 0.0 }): NDElement { return realNDArray(intArrayOf(dim1, dim2)) { initializer(it[0], it[1]) } } - fun real3DArray(dim1: Int, dim2: Int, dim3: Int, initializer: (Int, Int, Int) -> Double = { _, _, _ -> 0.0 }): NDArray { + fun real3DArray(dim1: Int, dim2: Int, dim3: Int, initializer: (Int, Int, Int) -> Double = { _, _, _ -> 0.0 }): NDElement { return realNDArray(intArrayOf(dim1, dim2, dim3)) { initializer(it[0], it[1], it[2]) } } - inline fun produceReal(shape: IntArray, block: ExtendedNDField.() -> NDArray) = ExtendedNDField(shape, DoubleField).run(block) + inline fun produceReal(shape: IntArray, block: ExtendedNDField.() -> NDElement) = ExtendedNDField(shape, DoubleField).run(block) // /** // * Simple boxing NDField @@ -199,7 +199,7 @@ object NDArrays { /** * Simple boxing NDArray */ - fun create(field: Field, shape: IntArray, initializer: (IntArray) -> T): NDArray { + fun create(field: Field, shape: IntArray, initializer: (IntArray) -> T): NDElement { return GenericNDField(shape, field).produce { initializer(it) } } } diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/structures/NumberNDFieldTest.kt b/kmath-core/src/commonTest/kotlin/scientifik/kmath/structures/NumberNDFieldTest.kt index 844535fa8..cd58a63b4 100644 --- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/structures/NumberNDFieldTest.kt +++ b/kmath-core/src/commonTest/kotlin/scientifik/kmath/structures/NumberNDFieldTest.kt @@ -1,7 +1,5 @@ package scientifik.kmath.structures -import scientifik.kmath.linear.Vector -import scientifik.kmath.linear.VectorL2Norm import scientifik.kmath.operations.Norm import scientifik.kmath.structures.NDArrays.produceReal import scientifik.kmath.structures.NDArrays.real2DArray @@ -53,8 +51,8 @@ class NumberNDFieldTest { assertEquals(2.0, result[0,2]) } - object L2Norm: Norm, Double> { - override fun norm(arg: NDArray): Double { + object L2Norm: Norm, Double> { + override fun norm(arg: NDElement): Double { return kotlin.math.sqrt(arg.sumByDouble { it.second.toDouble() }) } }