From 01bbb4bb1313f91cc584a6c9b6fdf904e34cddb7 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 2 Oct 2021 09:55:52 +0300 Subject: [PATCH] API cleanup --- build.gradle.kts | 2 +- .../space/kscience/kmath/tensors/PCA.kt | 10 +- ...rmalization.kt => dataSetNormalization.kt} | 6 +- ...thLUP.kt => linearSystemSolvingWithLUP.kt} | 6 +- .../{NeuralNetwork.kt => neuralNetwork.kt} | 0 .../kmath/linear/BufferedLinearSpace.kt | 19 ++- .../kmath/linear/DoubleLinearSpace.kt | 109 ++++++++++++++++++ .../space/kscience/kmath/nd/Structure1D.kt | 2 +- .../space/kscience/kmath/nd/Structure2D.kt | 4 +- .../space/kscience/kmath/operations/BigInt.kt | 4 +- .../kscience/kmath/structures/DoubleBuffer.kt | 6 + .../kmath/linear/DoubleLUSolverTest.kt | 35 +++--- .../space/kscience/kmath/linear/MatrixTest.kt | 30 ++--- .../kmath/structures/NumberNDFieldTest.kt | 10 +- .../kscience/kmath/dimensions/Wrappers.kt | 8 +- .../kscience/kmath/real/DoubleMatrixTest.kt | 12 +- .../kscience/kmath/real/DoubleVectorTest.kt | 8 +- .../kmath/optimization/QowOptimizer.kt | 3 +- .../core/BroadcastDoubleTensorAlgebra.kt | 11 +- .../kmath/tensors/core/DoubleTensorAlgebra.kt | 2 + settings.gradle.kts | 7 +- 21 files changed, 211 insertions(+), 83 deletions(-) rename examples/src/main/kotlin/space/kscience/kmath/tensors/{DataSetNormalization.kt => dataSetNormalization.kt} (84%) rename examples/src/main/kotlin/space/kscience/kmath/tensors/{LinearSystemSolvingWithLUP.kt => linearSystemSolvingWithLUP.kt} (92%) rename examples/src/main/kotlin/space/kscience/kmath/tensors/{NeuralNetwork.kt => neuralNetwork.kt} (100%) create mode 100644 kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/DoubleLinearSpace.kt diff --git a/build.gradle.kts b/build.gradle.kts index 6bb19cd35..68b894d06 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -19,7 +19,7 @@ allprojects { } group = "space.kscience" - version = "0.3.0-dev-14" + version = "0.3.0-dev-15" } subprojects { diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/PCA.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/PCA.kt index 3302b49a8..d83d47805 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/PCA.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/PCA.kt @@ -5,19 +5,19 @@ package space.kscience.kmath.tensors -import space.kscience.kmath.operations.invoke -import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra +import space.kscience.kmath.tensors.core.tensorAlgebra +import space.kscience.kmath.tensors.core.withBroadcast // simple PCA -fun main(): Unit = BroadcastDoubleTensorAlgebra { // work in context with broadcast methods +fun main(): Unit = Double.tensorAlgebra.withBroadcast { // work in context with broadcast methods val seed = 100500L // assume x is range from 0 until 10 val x = fromArray( intArrayOf(10), - (0 until 10).toList().map { it.toDouble() }.toDoubleArray() + DoubleArray(10) { it.toDouble() } ) // take y dependent on x with noise @@ -62,7 +62,7 @@ fun main(): Unit = BroadcastDoubleTensorAlgebra { // work in context with broad println("Eigenvector:\n$v") // reduce dimension of dataset - val datasetReduced = v dot stack(listOf(xScaled, yScaled)) + val datasetReduced = v dot stack(listOf(xScaled, yScaled)) println("Reduced data:\n$datasetReduced") // we can restore original data from reduced data; diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/DataSetNormalization.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/dataSetNormalization.kt similarity index 84% rename from examples/src/main/kotlin/space/kscience/kmath/tensors/DataSetNormalization.kt rename to examples/src/main/kotlin/space/kscience/kmath/tensors/dataSetNormalization.kt index 3ef745da3..9d5b8c2a5 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/DataSetNormalization.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/dataSetNormalization.kt @@ -5,13 +5,13 @@ package space.kscience.kmath.tensors -import space.kscience.kmath.operations.invoke -import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra +import space.kscience.kmath.tensors.core.tensorAlgebra +import space.kscience.kmath.tensors.core.withBroadcast // Dataset normalization -fun main() = BroadcastDoubleTensorAlgebra { // work in context with broadcast methods +fun main() = Double.tensorAlgebra.withBroadcast { // work in context with broadcast methods // take dataset of 5-element vectors from normal distribution val dataset = randomNormal(intArrayOf(100, 5)) * 1.5 // all elements from N(0, 1.5) diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LinearSystemSolvingWithLUP.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/linearSystemSolvingWithLUP.kt similarity index 92% rename from examples/src/main/kotlin/space/kscience/kmath/tensors/LinearSystemSolvingWithLUP.kt rename to examples/src/main/kotlin/space/kscience/kmath/tensors/linearSystemSolvingWithLUP.kt index 27886413f..846e338da 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LinearSystemSolvingWithLUP.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/linearSystemSolvingWithLUP.kt @@ -5,13 +5,13 @@ package space.kscience.kmath.tensors -import space.kscience.kmath.operations.invoke -import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra import space.kscience.kmath.tensors.core.DoubleTensor +import space.kscience.kmath.tensors.core.tensorAlgebra +import space.kscience.kmath.tensors.core.withBroadcast // solving linear system with LUP decomposition -fun main() = BroadcastDoubleTensorAlgebra {// work in context with linear operations +fun main() = Double.tensorAlgebra.withBroadcast {// work in context with linear operations // set true value of x val trueX = fromArray( diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/NeuralNetwork.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/neuralNetwork.kt similarity index 100% rename from examples/src/main/kotlin/space/kscience/kmath/tensors/NeuralNetwork.kt rename to examples/src/main/kotlin/space/kscience/kmath/tensors/neuralNetwork.kt diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt index 5f17de607..3d562f26f 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt @@ -8,12 +8,14 @@ package space.kscience.kmath.linear import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.nd.BufferedRingND import space.kscience.kmath.nd.as2D +import space.kscience.kmath.nd.asND import space.kscience.kmath.nd.ndAlgebra -import space.kscience.kmath.nd.unwrap -import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Ring import space.kscience.kmath.operations.invoke -import space.kscience.kmath.structures.* +import space.kscience.kmath.structures.Buffer +import space.kscience.kmath.structures.BufferFactory +import space.kscience.kmath.structures.VirtualBuffer +import space.kscience.kmath.structures.indices public class BufferedLinearSpace>( @@ -33,17 +35,17 @@ public class BufferedLinearSpace>( bufferFactory(size) { elementAlgebra.initializer(it) } override fun Matrix.unaryMinus(): Matrix = ndRing(rowNum, colNum).run { - unwrap().map { -it }.as2D() + asND().map { -it }.as2D() } override fun Matrix.plus(other: Matrix): Matrix = ndRing(rowNum, colNum).run { require(shape.contentEquals(other.shape)) { "Shape mismatch on Matrix::plus. Expected $shape but found ${other.shape}" } - unwrap().plus(other.unwrap()).as2D() + asND().plus(other.asND()).as2D() } override fun Matrix.minus(other: Matrix): Matrix = ndRing(rowNum, colNum).run { require(shape.contentEquals(other.shape)) { "Shape mismatch on Matrix::minus. Expected $shape but found ${other.shape}" } - unwrap().minus(other.unwrap()).as2D() + asND().minus(other.asND()).as2D() } private fun Buffer.linearize() = if (this is VirtualBuffer) { @@ -87,13 +89,10 @@ public class BufferedLinearSpace>( } override fun Matrix.times(value: T): Matrix = ndRing(rowNum, colNum).run { - unwrap().map { it * value }.as2D() + asND().map { it * value }.as2D() } } public fun > A.linearSpace(bufferFactory: BufferFactory): BufferedLinearSpace = BufferedLinearSpace(this, bufferFactory) - -public val DoubleField.linearSpace: BufferedLinearSpace - get() = BufferedLinearSpace(this, ::DoubleBuffer) \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/DoubleLinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/DoubleLinearSpace.kt new file mode 100644 index 000000000..a3e031902 --- /dev/null +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/DoubleLinearSpace.kt @@ -0,0 +1,109 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ + +package space.kscience.kmath.linear + +import space.kscience.kmath.misc.PerformancePitfall +import space.kscience.kmath.nd.DoubleFieldND +import space.kscience.kmath.nd.as2D +import space.kscience.kmath.nd.asND +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.structures.Buffer +import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.indices + +public object DoubleLinearSpace : LinearSpace { + + override val elementAlgebra: DoubleField get() = DoubleField + + private fun ndRing( + rows: Int, + cols: Int, + ): DoubleFieldND = DoubleFieldND(intArrayOf(rows, cols)) + + override fun buildMatrix( + rows: Int, + columns: Int, + initializer: DoubleField.(i: Int, j: Int) -> Double + ): Matrix = ndRing(rows, columns).produce { (i, j) -> DoubleField.initializer(i, j) }.as2D() + + + override fun buildVector(size: Int, initializer: DoubleField.(Int) -> Double): DoubleBuffer = + DoubleBuffer(size) { DoubleField.initializer(it) } + + override fun Matrix.unaryMinus(): Matrix = ndRing(rowNum, colNum).run { + asND().map { -it }.as2D() + } + + override fun Matrix.plus(other: Matrix): Matrix = ndRing(rowNum, colNum).run { + require(shape.contentEquals(other.shape)) { "Shape mismatch on Matrix::plus. Expected $shape but found ${other.shape}" } + asND().plus(other.asND()).as2D() + } + + override fun Matrix.minus(other: Matrix): Matrix = ndRing(rowNum, colNum).run { + require(shape.contentEquals(other.shape)) { "Shape mismatch on Matrix::minus. Expected $shape but found ${other.shape}" } + asND().minus(other.asND()).as2D() + } + + // Create a continuous in-memory representation of this vector for better memory layout handling + private fun Buffer.linearize() = if (this is DoubleBuffer) { + this + } else { + DoubleBuffer(size) { get(it) } + } + + @OptIn(PerformancePitfall::class) + override fun Matrix.dot(other: Matrix): Matrix { + require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" } + val rows = this@dot.rows.map { it.linearize() } + val columns = other.columns.map { it.linearize() } + return buildMatrix(rowNum, other.colNum) { i, j -> + val r = rows[i] + val c = columns[j] + var res = 0.0 + for (l in r.indices) { + res += r[l] * c[l] + } + res + } + } + + @OptIn(PerformancePitfall::class) + override fun Matrix.dot(vector: Point): DoubleBuffer { + require(colNum == vector.size) { "Matrix dot vector operation dimension mismatch: ($rowNum, $colNum) x (${vector.size})" } + val rows = this@dot.rows.map { it.linearize() } + return DoubleBuffer(rowNum) { i -> + val r = rows[i] + var res = 0.0 + for (j in r.indices) { + res += r[j] * vector[j] + } + res + } + + } + + override fun Matrix.times(value: Double): Matrix = ndRing(rowNum, colNum).run { + asND().map { it * value }.as2D() + } + + public override fun Point.plus(other: Point): DoubleBuffer = DoubleBuffer(size) { + get(it) + other[it] + } + + public override fun Point.minus(other: Point): DoubleBuffer = DoubleBuffer(size) { + get(it) - other[it] + } + + public override fun Point.times(value: Double): DoubleBuffer = DoubleBuffer(size) { i -> get(i) * value } + + public operator fun Point.div(value: Double): DoubleBuffer = DoubleBuffer(size) { i -> get(i) / value } + + public override fun Double.times(v: Point): DoubleBuffer = v * this + + +} + +public val DoubleField.linearSpace: DoubleLinearSpace get() = DoubleLinearSpace diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt index 91cd5abe9..f2a4336eb 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt @@ -136,7 +136,7 @@ public fun Buffer.asND(): Structure1D = Buffer1DWrapper(this) /** * Expose inner buffer of this [Structure1D] if possible */ -internal fun Structure1D.unwrap(): Buffer = when { +internal fun Structure1D.asND(): Buffer = when { this is Buffer1DWrapper -> buffer this is Structure1DWrapper && structure is BufferND -> structure.buffer else -> this diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt index 57836a9ef..8d3cc3a3f 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt @@ -160,10 +160,10 @@ public fun MutableStructureND.as2D(): MutableStructure2D = this as? Mu /** * Expose inner [StructureND] if possible */ -internal fun Structure2D.unwrap(): StructureND = +internal fun Structure2D.asND(): StructureND = if (this is Structure2DWrapper) structure else this -internal fun MutableStructure2D.unwrap(): MutableStructureND = +internal fun MutableStructure2D.asND(): MutableStructureND = if (this is MutableStructure2DWrapper) structure else this diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt index 9797027c7..82754e43d 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt @@ -532,7 +532,7 @@ public val BigInt.algebra: BigIntField get() = BigIntField public inline fun Buffer.Companion.bigInt(size: Int, initializer: (Int) -> BigInt): Buffer = boxing(size, initializer) -public inline fun BigInt.buffer(size: Int, initializer: (Int) -> BigInt): Buffer = +public inline fun BigInt.Companion.buffer(size: Int, initializer: (Int) -> BigInt): Buffer = Buffer.boxing(size, initializer) @Deprecated("Use BigInt::mutableBuffer") @@ -543,4 +543,4 @@ public inline fun BigInt.mutableBuffer(size: Int, initializer: (Int) -> BigInt): Buffer.boxing(size, initializer) public fun BigIntField.nd(vararg shape: Int): BufferedRingND = - BufferedRingND(shape, BigIntField, Buffer.Companion::bigInt) + BufferedRingND(shape, BigIntField, BigInt::buffer) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/DoubleBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/DoubleBuffer.kt index b94a36bab..3b554ab07 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/DoubleBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/DoubleBuffer.kt @@ -25,6 +25,12 @@ public value class DoubleBuffer(public val array: DoubleArray) : MutableBuffer assertMatrixEquals(expected: StructureND, actual: StructureND = VirtualMatrix(6, 6) { row, col -> when { col == 0 -> .50 @@ -49,7 +50,7 @@ class MatrixTest { infix fun Matrix.pow(power: Int): Matrix { var res = this repeat(power - 1) { - res = LinearSpace.double.run { res dot this@pow } + res = res dot this@pow } return res } @@ -58,19 +59,18 @@ class MatrixTest { } @Test - fun test2DDot() { + fun test2DDot() = Double.algebra.linearSpace.run { val firstMatrix = StructureND.auto(2, 3) { (i, j) -> (i + j).toDouble() }.as2D() val secondMatrix = StructureND.auto(3, 2) { (i, j) -> (i + j).toDouble() }.as2D() - LinearSpace.double.run { // val firstMatrix = produce(2, 3) { i, j -> (i + j).toDouble() } // val secondMatrix = produce(3, 2) { i, j -> (i + j).toDouble() } - val result = firstMatrix dot secondMatrix - assertEquals(2, result.rowNum) - assertEquals(2, result.colNum) - assertEquals(8.0, result[0, 1]) - assertEquals(8.0, result[1, 0]) - assertEquals(14.0, result[1, 1]) - } + val result = firstMatrix dot secondMatrix + assertEquals(2, result.rowNum) + assertEquals(2, result.colNum) + assertEquals(8.0, result[0, 1]) + assertEquals(8.0, result[1, 0]) + assertEquals(14.0, result[1, 1]) + } } diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt index b2982b335..e58976f4a 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt @@ -5,7 +5,7 @@ package space.kscience.kmath.structures -import space.kscience.kmath.linear.LinearSpace +import space.kscience.kmath.linear.linearSpace import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.combine @@ -13,6 +13,7 @@ import space.kscience.kmath.nd.get import space.kscience.kmath.nd.ndAlgebra import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Norm +import space.kscience.kmath.operations.algebra import space.kscience.kmath.operations.invoke import kotlin.math.abs import kotlin.math.pow @@ -42,17 +43,18 @@ class NumberNDFieldTest { } @Test - fun testGeneration() { + fun testGeneration() = Double.algebra.linearSpace.run { - val array = LinearSpace.double.buildMatrix(3, 3) { i, j -> + val array = buildMatrix(3, 3) { i, j -> (i * 10 + j).toDouble() } - for (i in 0..2) + for (i in 0..2) { for (j in 0..2) { val expected = (i * 10 + j).toDouble() assertEquals(expected, array[i, j], "Error at index [$i, $j]") } + } } @Test diff --git a/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt b/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt index f6c4415dc..c47f43723 100644 --- a/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt +++ b/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt @@ -5,13 +5,11 @@ package space.kscience.kmath.dimensions -import space.kscience.kmath.linear.LinearSpace -import space.kscience.kmath.linear.Matrix -import space.kscience.kmath.linear.Point -import space.kscience.kmath.linear.transpose +import space.kscience.kmath.linear.* import space.kscience.kmath.nd.Structure2D import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Ring +import space.kscience.kmath.operations.algebra import kotlin.jvm.JvmInline /** @@ -151,7 +149,7 @@ public value class DMatrixContext>(public val context: context.run { (this@transpose as Matrix).transpose() }.coerce() public companion object { - public val real: DMatrixContext = DMatrixContext(LinearSpace.double) + public val real: DMatrixContext = DMatrixContext(Double.algebra.linearSpace) } } diff --git a/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleMatrixTest.kt b/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleMatrixTest.kt index 79f05daa5..3277410c0 100644 --- a/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleMatrixTest.kt +++ b/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleMatrixTest.kt @@ -5,12 +5,12 @@ package space.kscience.kmath.real -import space.kscience.kmath.linear.LinearSpace +import space.kscience.kmath.linear.linearSpace import space.kscience.kmath.linear.matrix import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.nd.StructureND -import space.kscience.kmath.real.* +import space.kscience.kmath.operations.algebra import space.kscience.kmath.structures.contentEquals import kotlin.test.Test import kotlin.test.assertEquals @@ -59,13 +59,13 @@ internal class DoubleMatrixTest { } @Test - fun testMatrixAndDouble() { + fun testMatrixAndDouble() = Double.algebra.linearSpace.run { val matrix1 = realMatrix(2, 3)( 1.0, 0.0, 3.0, 4.0, 6.0, 2.0 ) val matrix2 = (matrix1 * 2.5 + 1.0 - 2.0) / 2.0 - val expectedResult = LinearSpace.double.matrix(2, 3)( + val expectedResult = matrix(2, 3)( 0.75, -0.5, 3.25, 4.5, 7.0, 2.0 ) @@ -159,8 +159,8 @@ internal class DoubleMatrixTest { } @Test - fun testAllElementOperations() { - val matrix1 = LinearSpace.double.matrix(2, 4)( + fun testAllElementOperations() = Double.algebra.linearSpace.run { + val matrix1 = matrix(2, 4)( -1.0, 0.0, 3.0, 15.0, 4.0, -6.0, 7.0, -11.0 ) diff --git a/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleVectorTest.kt b/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleVectorTest.kt index 7bb936658..771981772 100644 --- a/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleVectorTest.kt +++ b/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleVectorTest.kt @@ -5,10 +5,10 @@ package space.kscience.kmath.real -import space.kscience.kmath.linear.LinearSpace import space.kscience.kmath.linear.asMatrix +import space.kscience.kmath.linear.linearSpace import space.kscience.kmath.linear.transpose -import space.kscience.kmath.real.plus +import space.kscience.kmath.operations.algebra import space.kscience.kmath.structures.DoubleBuffer import kotlin.test.Test import kotlin.test.assertEquals @@ -30,12 +30,12 @@ internal class DoubleVectorTest { } @Test - fun testDot() { + fun testDot() = Double.algebra.linearSpace.run { val vector1 = DoubleBuffer(5) { it.toDouble() } val vector2 = DoubleBuffer(5) { 5 - it.toDouble() } val matrix1 = vector1.asMatrix() val matrix2 = vector2.asMatrix().transpose() - val product = LinearSpace.double.run { matrix1 dot matrix2 } + val product = matrix1 dot matrix2 assertEquals(5.0, product[1, 0]) assertEquals(6.0, product[2, 2]) } diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt index 00df0944f..68941304f 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt @@ -13,6 +13,7 @@ import space.kscience.kmath.linear.* import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.misc.log import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.algebra import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.DoubleL2Norm @@ -32,7 +33,7 @@ public class QowRuns(public val runs: Int) : OptimizationFeature { @UnstableKMathAPI public object QowOptimizer : Optimizer { - private val linearSpace: LinearSpace = LinearSpace.double + private val linearSpace: LinearSpace = Double.algebra.linearSpace private val solver: LinearSolver = linearSpace.lupSolver() @OptIn(UnstableKMathAPI::class) diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt index 3eb8e5636..3d73fd53b 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.tensors.core +import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.tensors.api.Tensor import space.kscience.kmath.tensors.core.internal.array import space.kscience.kmath.tensors.core.internal.broadcastTensors @@ -90,4 +91,12 @@ public object BroadcastDoubleTensorAlgebra : DoubleTensorAlgebra() { newOther.mutableBuffer.array()[tensor.bufferStart + i] } } -} \ No newline at end of file +} + + +/** + * Compute a value using broadcast double tensor algebra + */ +@UnstableKMathAPI +public fun DoubleTensorAlgebra.withBroadcast(block: BroadcastDoubleTensorAlgebra.() -> R): R = + BroadcastDoubleTensorAlgebra.block() \ No newline at end of file diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt index db18220cd..8e39e6cdd 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt @@ -949,4 +949,6 @@ public open class DoubleTensorAlgebra : override fun Tensor.lu(): Triple = lu(1e-9) } +public val Double.Companion.tensorAlgebra: DoubleTensorAlgebra.Companion get() = DoubleTensorAlgebra + diff --git a/settings.gradle.kts b/settings.gradle.kts index 0fc77b38e..8cfa62133 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,11 +5,11 @@ pluginManagement { gradlePluginPortal() } - val kotlinVersion = "1.5.30" + val kotlinVersion = "1.6.0-M1" plugins { id("org.jetbrains.kotlinx.benchmark") version "0.3.1" - id("ru.mipt.npm.gradle.project") version "0.10.3" + id("ru.mipt.npm.gradle.project") version "0.10.4" kotlin("multiplatform") version kotlinVersion kotlin("plugin.allopen") version kotlinVersion } @@ -17,6 +17,9 @@ pluginManagement { rootProject.name = "kmath" +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") +enableFeaturePreview("VERSION_CATALOGS") + include( ":kmath-memory", ":kmath-complex",