From d1184802bd811d379cf68be9041268194aaa90e1 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Wed, 9 Sep 2020 23:42:43 +0700 Subject: [PATCH 01/20] Drop koma module, implement kmath-ejml module copying it, but for EJML SimpleMatrix --- README.md | 3 - doc/features.md | 3 - examples/build.gradle.kts | 3 +- .../kmath/linear/LinearAlgebraBenchmark.kt | 25 ++-- .../kmath/linear/MultiplicationBenchmark.kt | 29 ++--- kmath-ejml/build.gradle.kts | 6 + .../scientifik/kmath/ejml/EjmlMatrix.kt | 69 +++++++++++ .../kmath/ejml/EjmlMatrixContext.kt | 75 ++++++++++++ .../scientifik/kmath/ejml/EjmlVector.kt | 30 +++++ kmath-koma/build.gradle.kts | 31 ----- .../scientifik.kmath.linear/KomaMatrix.kt | 110 ------------------ settings.gradle.kts | 4 +- 12 files changed, 203 insertions(+), 185 deletions(-) create mode 100644 kmath-ejml/build.gradle.kts create mode 100644 kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt create mode 100644 kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrixContext.kt create mode 100644 kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlVector.kt delete mode 100644 kmath-koma/build.gradle.kts delete mode 100644 kmath-koma/src/commonMain/kotlin/scientifik.kmath.linear/KomaMatrix.kt diff --git a/README.md b/README.md index 24a7d7a4a..6bfbc717a 100644 --- a/README.md +++ b/README.md @@ -53,9 +53,6 @@ can be used for a wide variety of purposes from high performance calculations to * **Commons-math wrapper** It is planned to gradually wrap most parts of [Apache commons-math](http://commons.apache.org/proper/commons-math/) library in Kotlin code and maybe rewrite some parts to better suit the Kotlin programming paradigm, however there is no fixed roadmap for that. Feel free to submit a feature request if you want something to be done first. - -* **Koma wrapper** [Koma](https://github.com/kyonifer/koma) is a well established numerics library in Kotlin, specifically linear algebra. -The plan is to have wrappers for koma implementations for compatibility with kmath API. ## Planned features diff --git a/doc/features.md b/doc/features.md index e6a820c1e..0f2c4203f 100644 --- a/doc/features.md +++ b/doc/features.md @@ -12,6 +12,3 @@ api and multiple library back-ends. * [Expressions](./expressions.md) * Commons math integration - -* Koma integration - diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts index f5a4d5831..519c72615 100644 --- a/examples/build.gradle.kts +++ b/examples/build.gradle.kts @@ -29,10 +29,9 @@ dependencies { implementation(project(":kmath-coroutines")) implementation(project(":kmath-commons")) implementation(project(":kmath-prob")) - implementation(project(":kmath-koma")) implementation(project(":kmath-viktor")) implementation(project(":kmath-dimensions")) - implementation("com.kyonifer:koma-core-ejml:0.12") + implementation(project(":kmath-ejml")) implementation("org.jetbrains.kotlinx:kotlinx-io-jvm:0.2.0-npm-dev-6") implementation("org.jetbrains.kotlinx:kotlinx.benchmark.runtime:0.2.0-dev-8") "benchmarksCompile"(sourceSets.main.get().output + sourceSets.main.get().compileClasspath) //sourceSets.main.output + sourceSets.main.runtimeClasspath diff --git a/examples/src/main/kotlin/scientifik/kmath/linear/LinearAlgebraBenchmark.kt b/examples/src/main/kotlin/scientifik/kmath/linear/LinearAlgebraBenchmark.kt index 6cc5411b8..9b6d3e585 100644 --- a/examples/src/main/kotlin/scientifik/kmath/linear/LinearAlgebraBenchmark.kt +++ b/examples/src/main/kotlin/scientifik/kmath/linear/LinearAlgebraBenchmark.kt @@ -1,9 +1,10 @@ package scientifik.kmath.linear -import koma.matrix.ejml.EJMLMatrixFactory import scientifik.kmath.commons.linear.CMMatrixContext import scientifik.kmath.commons.linear.inverse import scientifik.kmath.commons.linear.toCM +import scientifik.kmath.ejml.EjmlMatrixContext +import scientifik.kmath.ejml.inverse import scientifik.kmath.operations.RealField import scientifik.kmath.operations.invoke import scientifik.kmath.structures.Matrix @@ -23,8 +24,8 @@ fun main() { val n = 5000 // iterations MatrixContext.real { - repeat(50) { val res = inverse(matrix) } - val inverseTime = measureTimeMillis { repeat(n) { val res = inverse(matrix) } } + repeat(50) { inverse(matrix) } + val inverseTime = measureTimeMillis { repeat(n) { inverse(matrix) } } println("[kmath] Inversion of $n matrices $dim x $dim finished in $inverseTime millis") } @@ -33,23 +34,19 @@ fun main() { val commonsTime = measureTimeMillis { CMMatrixContext { val cm = matrix.toCM() //avoid overhead on conversion - repeat(n) { val res = inverse(cm) } + repeat(n) { inverse(cm) } } } println("[commons-math] Inversion of $n matrices $dim x $dim finished in $commonsTime millis") - //koma-ejml - - val komaTime = measureTimeMillis { - (KomaMatrixContext(EJMLMatrixFactory(), RealField)) { - val km = matrix.toKoma() //avoid overhead on conversion - repeat(n) { - val res = inverse(km) - } + val ejmlTime = measureTimeMillis { + (EjmlMatrixContext(RealField)) { + val km = matrix.toEjml() //avoid overhead on conversion + repeat(n) { inverse(km) } } } - println("[koma-ejml] Inversion of $n matrices $dim x $dim finished in $komaTime millis") -} \ No newline at end of file + println("[ejml] Inversion of $n matrices $dim x $dim finished in $ejmlTime millis") +} diff --git a/examples/src/main/kotlin/scientifik/kmath/linear/MultiplicationBenchmark.kt b/examples/src/main/kotlin/scientifik/kmath/linear/MultiplicationBenchmark.kt index 3ae550682..6e3f786ea 100644 --- a/examples/src/main/kotlin/scientifik/kmath/linear/MultiplicationBenchmark.kt +++ b/examples/src/main/kotlin/scientifik/kmath/linear/MultiplicationBenchmark.kt @@ -1,8 +1,8 @@ package scientifik.kmath.linear -import koma.matrix.ejml.EJMLMatrixFactory import scientifik.kmath.commons.linear.CMMatrixContext import scientifik.kmath.commons.linear.toCM +import scientifik.kmath.ejml.EjmlMatrixContext import scientifik.kmath.operations.RealField import scientifik.kmath.operations.invoke import scientifik.kmath.structures.Matrix @@ -22,28 +22,17 @@ fun main() { CMMatrixContext { val cmMatrix1 = matrix1.toCM() val cmMatrix2 = matrix2.toCM() - - val cmTime = measureTimeMillis { - cmMatrix1 dot cmMatrix2 - } - + val cmTime = measureTimeMillis { cmMatrix1 dot cmMatrix2 } println("CM implementation time: $cmTime") } - (KomaMatrixContext(EJMLMatrixFactory(), RealField)) { - val komaMatrix1 = matrix1.toKoma() - val komaMatrix2 = matrix2.toKoma() - - val komaTime = measureTimeMillis { - komaMatrix1 dot komaMatrix2 - } - - println("Koma-ejml implementation time: $komaTime") - } - - val genericTime = measureTimeMillis { - val res = matrix1 dot matrix2 + (EjmlMatrixContext(RealField)) { + val ejmlMatrix1 = matrix1.toEjml() + val ejmlMatrix2 = matrix2.toEjml() + val ejmlTime = measureTimeMillis { ejmlMatrix1 dot ejmlMatrix2 } + println("EJML implementation time: $ejmlTime") } + val genericTime = measureTimeMillis { val res = matrix1 dot matrix2 } println("Generic implementation time: $genericTime") -} \ No newline at end of file +} diff --git a/kmath-ejml/build.gradle.kts b/kmath-ejml/build.gradle.kts new file mode 100644 index 000000000..cfc52af5d --- /dev/null +++ b/kmath-ejml/build.gradle.kts @@ -0,0 +1,6 @@ +plugins { id("scientifik.jvm") } + +dependencies { + implementation("org.ejml:ejml-simple:0.39") + implementation(project(":kmath-core")) +} diff --git a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt new file mode 100644 index 000000000..a53856af0 --- /dev/null +++ b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt @@ -0,0 +1,69 @@ +package scientifik.kmath.ejml + +import org.ejml.dense.row.factory.DecompositionFactory_DDRM +import org.ejml.simple.SimpleMatrix +import scientifik.kmath.linear.DeterminantFeature +import scientifik.kmath.linear.FeaturedMatrix +import scientifik.kmath.linear.LUPDecompositionFeature +import scientifik.kmath.linear.MatrixFeature +import scientifik.kmath.structures.NDStructure + +/** + * Represents featured matrix over EJML [SimpleMatrix]. + * + * @property origin the underlying [SimpleMatrix]. + */ +class EjmlMatrix(val origin: SimpleMatrix, features: Set? = null) : FeaturedMatrix { + override val rowNum: Int + get() = origin.numRows() + + override val colNum: Int + get() = origin.numCols() + + override val shape: IntArray + get() = intArrayOf(origin.numRows(), origin.numCols()) + + override val features: Set = features ?: hashSetOf( + object : DeterminantFeature { + override val determinant: Double + get() = origin.determinant() + }, + + object : LUPDecompositionFeature { + private val lup by lazy { + val ludecompositionF64 = DecompositionFactory_DDRM.lu(origin.numRows(), origin.numCols()) + .also { it.decompose(origin.ddrm.copy()) } + + Triple( + EjmlMatrix(SimpleMatrix(ludecompositionF64.getRowPivot(null))), + EjmlMatrix(SimpleMatrix(ludecompositionF64.getLower(null))), + EjmlMatrix(SimpleMatrix(ludecompositionF64.getUpper(null))) + ) + } + + override val l: FeaturedMatrix + get() = lup.second + + override val u: FeaturedMatrix + get() = lup.third + + override val p: FeaturedMatrix + get() = lup.first + } + ) + + override fun suggestFeature(vararg features: MatrixFeature): FeaturedMatrix = + EjmlMatrix(origin, this.features + features) + + override operator fun get(i: Int, j: Int): Double = origin[i, j] + + override fun equals(other: Any?): Boolean { + return NDStructure.equals(this, other as? NDStructure<*> ?: return false) + } + + override fun hashCode(): Int { + var result = origin.hashCode() + result = 31 * result + features.hashCode() + return result + } +} diff --git a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrixContext.kt b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrixContext.kt new file mode 100644 index 000000000..142f1bee3 --- /dev/null +++ b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrixContext.kt @@ -0,0 +1,75 @@ +package scientifik.kmath.ejml + +import org.ejml.simple.SimpleMatrix +import scientifik.kmath.linear.MatrixContext +import scientifik.kmath.linear.Point +import scientifik.kmath.operations.Space +import scientifik.kmath.operations.invoke +import scientifik.kmath.structures.Matrix + +/** + * Represents context of basic operations operating with [EjmlMatrix]. + */ +class EjmlMatrixContext(private val space: Space) : MatrixContext { + override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> Double): EjmlMatrix = + EjmlMatrix(SimpleMatrix(rows, columns).also { + (0 until it.numRows()).forEach { row -> + (0 until it.numCols()).forEach { col -> it[row, col] = initializer(row, col) } + } + }) + + fun Matrix.toEjml(): EjmlMatrix = + if (this is EjmlMatrix) this else produce(rowNum, colNum) { i, j -> get(i, j) } + + fun Point.toEjml(): EjmlVector = + if (this is EjmlVector) this else EjmlVector(SimpleMatrix(size, 1).also { + (0 until it.numRows()).forEach { row -> it[row, 0] = get(row) } + }) + + override fun Matrix.dot(other: Matrix): EjmlMatrix = + EjmlMatrix(toEjml().origin.mult(other.toEjml().origin)) + + override fun Matrix.dot(vector: Point): EjmlVector = + EjmlVector(toEjml().origin.mult(vector.toEjml().origin)) + + override fun add(a: Matrix, b: Matrix): EjmlMatrix = + EjmlMatrix(a.toEjml().origin + b.toEjml().origin) + + override operator fun Matrix.minus(b: Matrix): EjmlMatrix = + EjmlMatrix(toEjml().origin - b.toEjml().origin) + + override fun multiply(a: Matrix, k: Number): Matrix = + produce(a.rowNum, a.colNum) { i, j -> space { a[i, j] * k } } + + override operator fun Matrix.times(value: Double): EjmlMatrix = EjmlMatrix(toEjml().origin.scale(value)) + + companion object +} + +/** + * Solves for X in the following equation: x = a^-1*b, where 'a' is base matrix and 'b' is an n by p matrix. + * + * @param a the base matrix. + * @param b n by p matrix. + * @return the solution for 'x' that is n by p. + */ +fun EjmlMatrixContext.solve(a: Matrix, b: Matrix): EjmlMatrix = + EjmlMatrix(a.toEjml().origin.solve(b.toEjml().origin)) + +/** + * Solves for X in the following equation: x = a^(-1)*b, where 'a' is base matrix and 'b' is an n by p matrix. + * + * @param a the base matrix. + * @param b n by p vector. + * @return the solution for 'x' that is n by p. + */ +fun EjmlMatrixContext.solve(a: Matrix, b: Point): EjmlVector = + EjmlVector(a.toEjml().origin.solve(b.toEjml().origin)) + +/** + * Returns the inverse of given matrix: b = a^(-1). + * + * @param a the matrix. + * @return the inverse of this matrix. + */ +fun EjmlMatrixContext.inverse(a: Matrix): EjmlMatrix = EjmlMatrix(a.toEjml().origin.invert()) diff --git a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlVector.kt b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlVector.kt new file mode 100644 index 000000000..ab9d4e87c --- /dev/null +++ b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlVector.kt @@ -0,0 +1,30 @@ +package scientifik.kmath.ejml + +import org.ejml.simple.SimpleMatrix +import scientifik.kmath.linear.Point + +/** + * Represents point over EJML [SimpleMatrix]. + * + * @property origin the underlying [SimpleMatrix]. + */ +class EjmlVector internal constructor(val origin: SimpleMatrix) : Point { + override val size: Int get() = origin.numRows() + + init { + require(origin.numCols() == 1) { error("Only single column matrices are allowed") } + } + + override operator fun get(index: Int): Double = origin[index] + + override operator fun iterator(): Iterator = object : Iterator { + private var cursor: Int = 0 + + override fun next(): Double { + cursor += 1 + return origin[cursor - 1] + } + + override fun hasNext(): Boolean = cursor < origin.numCols() * origin.numRows() + } +} diff --git a/kmath-koma/build.gradle.kts b/kmath-koma/build.gradle.kts deleted file mode 100644 index 26955bca7..000000000 --- a/kmath-koma/build.gradle.kts +++ /dev/null @@ -1,31 +0,0 @@ -plugins { - id("scientifik.mpp") -} - -repositories { - maven("http://dl.bintray.com/kyonifer/maven") -} - -kotlin.sourceSets { - commonMain { - dependencies { - api(project(":kmath-core")) - api("com.kyonifer:koma-core-api-common:0.12") - } - } - jvmMain { - dependencies { - api("com.kyonifer:koma-core-api-jvm:0.12") - } - } - jvmTest { - dependencies { - implementation("com.kyonifer:koma-core-ejml:0.12") - } - } - jsMain { - dependencies { - api("com.kyonifer:koma-core-api-js:0.12") - } - } -} diff --git a/kmath-koma/src/commonMain/kotlin/scientifik.kmath.linear/KomaMatrix.kt b/kmath-koma/src/commonMain/kotlin/scientifik.kmath.linear/KomaMatrix.kt deleted file mode 100644 index bd8fa782a..000000000 --- a/kmath-koma/src/commonMain/kotlin/scientifik.kmath.linear/KomaMatrix.kt +++ /dev/null @@ -1,110 +0,0 @@ -package scientifik.kmath.linear - -import koma.extensions.fill -import koma.matrix.MatrixFactory -import scientifik.kmath.operations.Space -import scientifik.kmath.operations.invoke -import scientifik.kmath.structures.Matrix -import scientifik.kmath.structures.NDStructure - -class KomaMatrixContext( - private val factory: MatrixFactory>, - private val space: Space -) : MatrixContext { - - override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> T): KomaMatrix = - KomaMatrix(factory.zeros(rows, columns).fill(initializer)) - - fun Matrix.toKoma(): KomaMatrix = if (this is KomaMatrix) { - this - } else { - produce(rowNum, colNum) { i, j -> get(i, j) } - } - - fun Point.toKoma(): KomaVector = if (this is KomaVector) { - this - } else { - KomaVector(factory.zeros(size, 1).fill { i, _ -> get(i) }) - } - - - override fun Matrix.dot(other: Matrix): KomaMatrix = - KomaMatrix(toKoma().origin * other.toKoma().origin) - - override fun Matrix.dot(vector: Point): KomaVector = - KomaVector(toKoma().origin * vector.toKoma().origin) - - override operator fun Matrix.unaryMinus(): KomaMatrix = - KomaMatrix(toKoma().origin.unaryMinus()) - - override fun add(a: Matrix, b: Matrix): KomaMatrix = - KomaMatrix(a.toKoma().origin + b.toKoma().origin) - - override operator fun Matrix.minus(b: Matrix): KomaMatrix = - KomaMatrix(toKoma().origin - b.toKoma().origin) - - override fun multiply(a: Matrix, k: Number): Matrix = - produce(a.rowNum, a.colNum) { i, j -> space { a[i, j] * k } } - - override operator fun Matrix.times(value: T): KomaMatrix = - KomaMatrix(toKoma().origin * value) - - companion object -} - -fun KomaMatrixContext.solve(a: Matrix, b: Matrix) = - KomaMatrix(a.toKoma().origin.solve(b.toKoma().origin)) - -fun KomaMatrixContext.solve(a: Matrix, b: Point) = - KomaVector(a.toKoma().origin.solve(b.toKoma().origin)) - -fun KomaMatrixContext.inverse(a: Matrix) = - KomaMatrix(a.toKoma().origin.inv()) - -class KomaMatrix(val origin: koma.matrix.Matrix, features: Set? = null) : FeaturedMatrix { - override val rowNum: Int get() = origin.numRows() - override val colNum: Int get() = origin.numCols() - - override val shape: IntArray get() = intArrayOf(origin.numRows(), origin.numCols()) - - override val features: Set = features ?: hashSetOf( - object : DeterminantFeature { - override val determinant: T get() = origin.det() - }, - - object : LUPDecompositionFeature { - private val lup by lazy { origin.LU() } - override val l: FeaturedMatrix get() = KomaMatrix(lup.second) - override val u: FeaturedMatrix get() = KomaMatrix(lup.third) - override val p: FeaturedMatrix get() = KomaMatrix(lup.first) - } - ) - - override fun suggestFeature(vararg features: MatrixFeature): FeaturedMatrix = - KomaMatrix(this.origin, this.features + features) - - override operator fun get(i: Int, j: Int): T = origin.getGeneric(i, j) - - override fun equals(other: Any?): Boolean { - return NDStructure.equals(this, other as? NDStructure<*> ?: return false) - } - - override fun hashCode(): Int { - var result = origin.hashCode() - result = 31 * result + features.hashCode() - return result - } - - -} - -class KomaVector internal constructor(val origin: koma.matrix.Matrix) : Point { - override val size: Int get() = origin.numRows() - - init { - require(origin.numCols() == 1) { error("Only single column matrices are allowed") } - } - - override operator fun get(index: Int): T = origin.getGeneric(index) - override operator fun iterator(): Iterator = origin.toIterable().iterator() -} diff --git a/settings.gradle.kts b/settings.gradle.kts index 487e1d87f..7c5c00212 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -40,12 +40,12 @@ include( ":kmath-histograms", ":kmath-commons", ":kmath-viktor", - ":kmath-koma", ":kmath-prob", ":kmath-io", ":kmath-dimensions", ":kmath-for-real", ":kmath-geometry", ":kmath-ast", - ":examples" + ":examples", + ":kmath-ejml" ) -- 2.34.1 From 413d129ffc7638fc7ab91c564f009aa69127e70c Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Wed, 9 Sep 2020 23:46:10 +0700 Subject: [PATCH 02/20] Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3944c673e..e787a5d2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ - Blocking chains in `kmath-coroutines` - Full hyperbolic functions support and default implementations within `ExtendedField` - Norm support for `Complex` +- `kmath-ejml` to supply EJML SimpleMatrix wrapper. ### Changed - `readAsMemory` now has `throws IOException` in JVM signature. @@ -36,3 +37,6 @@ - Multiplication in integer rings in `kmath-core` (https://github.com/mipt-npm/kmath/pull/101) - Commons RNG compatibility (https://github.com/mipt-npm/kmath/issues/93) - Multiplication of BigInt by scalar + +### Removed +- `kmath-koma` module. -- 2.34.1 From edd3022aaccb49aed040547ada66c92dd2eeb0eb Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Thu, 10 Sep 2020 05:53:44 +0700 Subject: [PATCH 03/20] Add dynamic operations and add documentations --- .../scientifik/kmath/linear/MatrixContext.kt | 33 +++++++ .../kmath/ejml/EjmlMatrixContext.kt | 91 +++++++++++-------- 2 files changed, 87 insertions(+), 37 deletions(-) diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixContext.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixContext.kt index 763bb1615..b7e79f1bc 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixContext.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixContext.kt @@ -18,12 +18,45 @@ interface MatrixContext : SpaceOperations> { */ fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> T): Matrix + override fun binaryOperation(operation: String, left: Matrix, right: Matrix): Matrix = when (operation) { + "dot" -> left dot right + else -> super.binaryOperation(operation, left, right) + } + + /** + * Computes the dot product of this matrix and another one. + * + * @receiver the multiplicand. + * @param other the multiplier. + * @return the dot product. + */ infix fun Matrix.dot(other: Matrix): Matrix + /** + * Computes the dot product of this matrix and a vector. + * + * @receiver the multiplicand. + * @param vector the multiplier. + * @return the dot product. + */ infix fun Matrix.dot(vector: Point): Point + /** + * Multiplies a matrix by its element. + * + * @receiver the multiplicand. + * @param value the multiplier. + * @receiver the product. + */ operator fun Matrix.times(value: T): Matrix + /** + * Multiplies an element by a matrix of it. + * + * @receiver the multiplicand. + * @param value the multiplier. + * @receiver the product. + */ operator fun T.times(m: Matrix): Matrix = m * this companion object { diff --git a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrixContext.kt b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrixContext.kt index 142f1bee3..ee44cd686 100644 --- a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrixContext.kt +++ b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrixContext.kt @@ -11,6 +11,59 @@ import scientifik.kmath.structures.Matrix * Represents context of basic operations operating with [EjmlMatrix]. */ class EjmlMatrixContext(private val space: Space) : MatrixContext { + /** + * Solves for X in the following equation: x = a^-1*b, where 'a' is base matrix and 'b' is an n by p matrix. + * + * @param a the base matrix. + * @param b n by p matrix. + * @return the solution for 'x' that is n by p. + */ + fun solve(a: Matrix, b: Matrix): EjmlMatrix = + EjmlMatrix(a.toEjml().origin.solve(b.toEjml().origin)) + + /** + * Solves for X in the following equation: x = a^(-1)*b, where 'a' is base matrix and 'b' is an n by p matrix. + * + * @param a the base matrix. + * @param b n by p vector. + * @return the solution for 'x' that is n by p. + */ + fun solve(a: Matrix, b: Point): EjmlVector = + EjmlVector(a.toEjml().origin.solve(b.toEjml().origin)) + + /** + * Returns the inverse of given matrix: b = a^(-1). + * + * @param a the matrix. + * @return the inverse of this matrix. + */ + fun inverse(a: Matrix): EjmlMatrix = EjmlMatrix(a.toEjml().origin.invert()) + + /** + * Converts this matrix to EJML one. + */ + fun Matrix.toEjml(): EjmlMatrix = + if (this is EjmlMatrix) this else produce(rowNum, colNum) { i, j -> get(i, j) } + + /** + * Converts this vector to EJML one. + */ + fun Point.toEjml(): EjmlVector = + if (this is EjmlVector) this else EjmlVector(SimpleMatrix(size, 1).also { + (0 until it.numRows()).forEach { row -> it[row, 0] = get(row) } + }) + + override fun unaryOperation(operation: String, arg: Matrix): Matrix = when (operation) { + "inverse" -> inverse(arg) + else -> super.unaryOperation(operation, arg) + } + + override fun binaryOperation(operation: String, left: Matrix, right: Matrix): Matrix = + when (operation) { + "solve" -> solve(left, right) + else -> super.binaryOperation(operation, left, right) + } + override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> Double): EjmlMatrix = EjmlMatrix(SimpleMatrix(rows, columns).also { (0 until it.numRows()).forEach { row -> @@ -18,14 +71,6 @@ class EjmlMatrixContext(private val space: Space) : MatrixContext.toEjml(): EjmlMatrix = - if (this is EjmlMatrix) this else produce(rowNum, colNum) { i, j -> get(i, j) } - - fun Point.toEjml(): EjmlVector = - if (this is EjmlVector) this else EjmlVector(SimpleMatrix(size, 1).also { - (0 until it.numRows()).forEach { row -> it[row, 0] = get(row) } - }) - override fun Matrix.dot(other: Matrix): EjmlMatrix = EjmlMatrix(toEjml().origin.mult(other.toEjml().origin)) @@ -38,38 +83,10 @@ class EjmlMatrixContext(private val space: Space) : MatrixContext.minus(b: Matrix): EjmlMatrix = EjmlMatrix(toEjml().origin - b.toEjml().origin) - override fun multiply(a: Matrix, k: Number): Matrix = + override fun multiply(a: Matrix, k: Number): EjmlMatrix = produce(a.rowNum, a.colNum) { i, j -> space { a[i, j] * k } } override operator fun Matrix.times(value: Double): EjmlMatrix = EjmlMatrix(toEjml().origin.scale(value)) companion object } - -/** - * Solves for X in the following equation: x = a^-1*b, where 'a' is base matrix and 'b' is an n by p matrix. - * - * @param a the base matrix. - * @param b n by p matrix. - * @return the solution for 'x' that is n by p. - */ -fun EjmlMatrixContext.solve(a: Matrix, b: Matrix): EjmlMatrix = - EjmlMatrix(a.toEjml().origin.solve(b.toEjml().origin)) - -/** - * Solves for X in the following equation: x = a^(-1)*b, where 'a' is base matrix and 'b' is an n by p matrix. - * - * @param a the base matrix. - * @param b n by p vector. - * @return the solution for 'x' that is n by p. - */ -fun EjmlMatrixContext.solve(a: Matrix, b: Point): EjmlVector = - EjmlVector(a.toEjml().origin.solve(b.toEjml().origin)) - -/** - * Returns the inverse of given matrix: b = a^(-1). - * - * @param a the matrix. - * @return the inverse of this matrix. - */ -fun EjmlMatrixContext.inverse(a: Matrix): EjmlMatrix = EjmlMatrix(a.toEjml().origin.invert()) -- 2.34.1 From d088fdf77cd061a63f2fb8338a8e28014f7aadf3 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sat, 12 Sep 2020 09:23:47 +0700 Subject: [PATCH 04/20] Move matrix solving and inverting to extensions because of consistency --- .../kmath/ejml/EjmlMatrixContext.kt | 67 ++++++++----------- 1 file changed, 28 insertions(+), 39 deletions(-) diff --git a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrixContext.kt b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrixContext.kt index ee44cd686..1b59a89ca 100644 --- a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrixContext.kt +++ b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrixContext.kt @@ -11,34 +11,6 @@ import scientifik.kmath.structures.Matrix * Represents context of basic operations operating with [EjmlMatrix]. */ class EjmlMatrixContext(private val space: Space) : MatrixContext { - /** - * Solves for X in the following equation: x = a^-1*b, where 'a' is base matrix and 'b' is an n by p matrix. - * - * @param a the base matrix. - * @param b n by p matrix. - * @return the solution for 'x' that is n by p. - */ - fun solve(a: Matrix, b: Matrix): EjmlMatrix = - EjmlMatrix(a.toEjml().origin.solve(b.toEjml().origin)) - - /** - * Solves for X in the following equation: x = a^(-1)*b, where 'a' is base matrix and 'b' is an n by p matrix. - * - * @param a the base matrix. - * @param b n by p vector. - * @return the solution for 'x' that is n by p. - */ - fun solve(a: Matrix, b: Point): EjmlVector = - EjmlVector(a.toEjml().origin.solve(b.toEjml().origin)) - - /** - * Returns the inverse of given matrix: b = a^(-1). - * - * @param a the matrix. - * @return the inverse of this matrix. - */ - fun inverse(a: Matrix): EjmlMatrix = EjmlMatrix(a.toEjml().origin.invert()) - /** * Converts this matrix to EJML one. */ @@ -53,17 +25,6 @@ class EjmlMatrixContext(private val space: Space) : MatrixContext it[row, 0] = get(row) } }) - override fun unaryOperation(operation: String, arg: Matrix): Matrix = when (operation) { - "inverse" -> inverse(arg) - else -> super.unaryOperation(operation, arg) - } - - override fun binaryOperation(operation: String, left: Matrix, right: Matrix): Matrix = - when (operation) { - "solve" -> solve(left, right) - else -> super.binaryOperation(operation, left, right) - } - override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> Double): EjmlMatrix = EjmlMatrix(SimpleMatrix(rows, columns).also { (0 until it.numRows()).forEach { row -> @@ -90,3 +51,31 @@ class EjmlMatrixContext(private val space: Space) : MatrixContext, b: Matrix): EjmlMatrix = + EjmlMatrix(a.toEjml().origin.solve(b.toEjml().origin)) + +/** + * Solves for X in the following equation: x = a^(-1)*b, where 'a' is base matrix and 'b' is an n by p matrix. + * + * @param a the base matrix. + * @param b n by p vector. + * @return the solution for 'x' that is n by p. + */ +fun EjmlMatrixContext.solve(a: Matrix, b: Point): EjmlVector = + EjmlVector(a.toEjml().origin.solve(b.toEjml().origin)) + +/** + * Returns the inverse of given matrix: b = a^(-1). + * + * @param a the matrix. + * @return the inverse of this matrix. + */ +fun EjmlMatrixContext.inverse(a: Matrix): EjmlMatrix = EjmlMatrix(a.toEjml().origin.invert()) -- 2.34.1 From 1c495759cd23d7e4f3ea826715d179c9713d6447 Mon Sep 17 00:00:00 2001 From: Iaroslav Date: Mon, 14 Sep 2020 19:53:31 +0700 Subject: [PATCH 05/20] Replace ?: with set merging --- .../src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt index a53856af0..90f6e64cd 100644 --- a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt +++ b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt @@ -23,7 +23,7 @@ class EjmlMatrix(val origin: SimpleMatrix, features: Set? = null) override val shape: IntArray get() = intArrayOf(origin.numRows(), origin.numCols()) - override val features: Set = features ?: hashSetOf( + override val features: Set = hashSetOf( object : DeterminantFeature { override val determinant: Double get() = origin.determinant() @@ -50,7 +50,7 @@ class EjmlMatrix(val origin: SimpleMatrix, features: Set? = null) override val p: FeaturedMatrix get() = lup.first } - ) + ).addAll(features) override fun suggestFeature(vararg features: MatrixFeature): FeaturedMatrix = EjmlMatrix(origin, this.features + features) -- 2.34.1 From a046f5c060fc8f046c80ddf96a187e057a023d2b Mon Sep 17 00:00:00 2001 From: Iaroslav Date: Mon, 14 Sep 2020 20:02:53 +0700 Subject: [PATCH 06/20] Update features --- .../src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt index 90f6e64cd..09b9c4fcd 100644 --- a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt +++ b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt @@ -24,12 +24,10 @@ class EjmlMatrix(val origin: SimpleMatrix, features: Set? = null) get() = intArrayOf(origin.numRows(), origin.numCols()) override val features: Set = hashSetOf( - object : DeterminantFeature { + object : LUPDecompositionFeature, DeterminantFeature { override val determinant: Double get() = origin.determinant() - }, - object : LUPDecompositionFeature { private val lup by lazy { val ludecompositionF64 = DecompositionFactory_DDRM.lu(origin.numRows(), origin.numCols()) .also { it.decompose(origin.ddrm.copy()) } @@ -50,7 +48,7 @@ class EjmlMatrix(val origin: SimpleMatrix, features: Set? = null) override val p: FeaturedMatrix get() = lup.first } - ).addAll(features) + ).addAll(features.orEmpty()) override fun suggestFeature(vararg features: MatrixFeature): FeaturedMatrix = EjmlMatrix(origin, this.features + features) -- 2.34.1 From 91d692381c6705f2fdd8b947f5ee3e0e7238d3b9 Mon Sep 17 00:00:00 2001 From: Iaroslav Date: Mon, 14 Sep 2020 20:15:11 +0700 Subject: [PATCH 07/20] Update comparison and fix type error --- .../src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt index 09b9c4fcd..4bf0a505f 100644 --- a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt +++ b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt @@ -23,7 +23,7 @@ class EjmlMatrix(val origin: SimpleMatrix, features: Set? = null) override val shape: IntArray get() = intArrayOf(origin.numRows(), origin.numCols()) - override val features: Set = hashSetOf( + override val features: Set = setOf( object : LUPDecompositionFeature, DeterminantFeature { override val determinant: Double get() = origin.determinant() @@ -48,7 +48,7 @@ class EjmlMatrix(val origin: SimpleMatrix, features: Set? = null) override val p: FeaturedMatrix get() = lup.first } - ).addAll(features.orEmpty()) + ) union features.orEmpty() override fun suggestFeature(vararg features: MatrixFeature): FeaturedMatrix = EjmlMatrix(origin, this.features + features) @@ -56,6 +56,7 @@ class EjmlMatrix(val origin: SimpleMatrix, features: Set? = null) override operator fun get(i: Int, j: Int): Double = origin[i, j] override fun equals(other: Any?): Boolean { + if (other is EjmlMatrix) return origin.isIdentical(other.origin, 0.0) return NDStructure.equals(this, other as? NDStructure<*> ?: return false) } -- 2.34.1 From 2f2315f6cdeaadc59aab96014fc3f68e85898b65 Mon Sep 17 00:00:00 2001 From: Iaroslav Date: Mon, 14 Sep 2020 20:18:43 +0700 Subject: [PATCH 08/20] Override toString --- kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt index 4bf0a505f..a4923b5e3 100644 --- a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt +++ b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt @@ -65,4 +65,6 @@ class EjmlMatrix(val origin: SimpleMatrix, features: Set? = null) result = 31 * result + features.hashCode() return result } + + override fun toString(): String = "EjmlMatrix(origin=$origin, features=$features)" } -- 2.34.1 From 09b82a891063630e170faf84fb15cf22490baf0f Mon Sep 17 00:00:00 2001 From: Iaroslav Date: Mon, 14 Sep 2020 20:20:07 +0700 Subject: [PATCH 09/20] Override toString and contentEquals --- .../src/main/kotlin/scientifik/kmath/ejml/EjmlVector.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlVector.kt b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlVector.kt index ab9d4e87c..dd7969e83 100644 --- a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlVector.kt +++ b/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlVector.kt @@ -2,6 +2,7 @@ package scientifik.kmath.ejml import org.ejml.simple.SimpleMatrix import scientifik.kmath.linear.Point +import scientifik.kmath.structures.Buffer /** * Represents point over EJML [SimpleMatrix]. @@ -27,4 +28,11 @@ class EjmlVector internal constructor(val origin: SimpleMatrix) : Point override fun hasNext(): Boolean = cursor < origin.numCols() * origin.numRows() } + + override fun contentEquals(other: Buffer<*>): Boolean { + if (other is EjmlVector) return origin.isIdentical(other.origin, 0.0) + return super.contentEquals(other) + } + + override fun toString(): String = "EjmlVector(origin=$origin)" } -- 2.34.1 From 148c0c8bc58362db79f8c835b8cc51a472afd26b Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Tue, 15 Sep 2020 17:47:49 +0700 Subject: [PATCH 10/20] Update changelog --- CHANGELOG.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4aaf69038..ba271bb01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,14 @@ ## [Unreleased] ### Added +- `kmath-ejml` to supply EJML SimpleMatrix wrapper. ### Changed ### Deprecated ### Removed +- `kmath-koma` module. ### Fixed @@ -30,7 +32,6 @@ - Blocking chains in `kmath-coroutines` - Full hyperbolic functions support and default implementations within `ExtendedField` - Norm support for `Complex` -- `kmath-ejml` to supply EJML SimpleMatrix wrapper. ### Changed - `readAsMemory` now has `throws IOException` in JVM signature. @@ -49,6 +50,3 @@ - Multiplication in integer rings in `kmath-core` (https://github.com/mipt-npm/kmath/pull/101) - Commons RNG compatibility (https://github.com/mipt-npm/kmath/issues/93) - Multiplication of BigInt by scalar - -### Removed -- `kmath-koma` module. -- 2.34.1 From 1e67ffb5ef329daaa6350efdbcd52df5ffdc4685 Mon Sep 17 00:00:00 2001 From: Iaroslav Date: Sun, 20 Sep 2020 16:40:07 +0700 Subject: [PATCH 11/20] Make one-liner not a one-liner --- kmath-ejml/build.gradle.kts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kmath-ejml/build.gradle.kts b/kmath-ejml/build.gradle.kts index cfc52af5d..58d8972b8 100644 --- a/kmath-ejml/build.gradle.kts +++ b/kmath-ejml/build.gradle.kts @@ -1,4 +1,6 @@ -plugins { id("scientifik.jvm") } +plugins { + id("scientifik.jvm") +} dependencies { implementation("org.ejml:ejml-simple:0.39") -- 2.34.1 From 267b6086a9fb65b70300137aa322ac38c98d054d Mon Sep 17 00:00:00 2001 From: Iaroslav Date: Mon, 21 Sep 2020 18:59:02 +0700 Subject: [PATCH 12/20] Change package and specify public visibilities, fix old plugin ID --- kmath-ejml/build.gradle.kts | 2 +- .../kmath/ejml/EjmlMatrix.kt | 32 +++++++++---------- .../kmath/ejml/EjmlMatrixContext.kt | 26 +++++++-------- .../kmath/ejml/EjmlVector.kt | 6 ++-- 4 files changed, 33 insertions(+), 33 deletions(-) rename kmath-ejml/src/main/kotlin/{scientifik => kscience}/kmath/ejml/EjmlMatrix.kt (64%) rename kmath-ejml/src/main/kotlin/{scientifik => kscience}/kmath/ejml/EjmlMatrixContext.kt (76%) rename kmath-ejml/src/main/kotlin/{scientifik => kscience}/kmath/ejml/EjmlVector.kt (90%) diff --git a/kmath-ejml/build.gradle.kts b/kmath-ejml/build.gradle.kts index 58d8972b8..fa4aa3e39 100644 --- a/kmath-ejml/build.gradle.kts +++ b/kmath-ejml/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("scientifik.jvm") + id("ru.mipt.npm.jvm") } dependencies { diff --git a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt similarity index 64% rename from kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt rename to kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt index a4923b5e3..60e3aec8e 100644 --- a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrix.kt +++ b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt @@ -1,29 +1,29 @@ -package scientifik.kmath.ejml +package kscience.kmath.ejml import org.ejml.dense.row.factory.DecompositionFactory_DDRM import org.ejml.simple.SimpleMatrix -import scientifik.kmath.linear.DeterminantFeature -import scientifik.kmath.linear.FeaturedMatrix -import scientifik.kmath.linear.LUPDecompositionFeature -import scientifik.kmath.linear.MatrixFeature -import scientifik.kmath.structures.NDStructure +import kscience.kmath.linear.DeterminantFeature +import kscience.kmath.linear.FeaturedMatrix +import kscience.kmath.linear.LUPDecompositionFeature +import kscience.kmath.linear.MatrixFeature +import kscience.kmath.structures.NDStructure /** * Represents featured matrix over EJML [SimpleMatrix]. * * @property origin the underlying [SimpleMatrix]. */ -class EjmlMatrix(val origin: SimpleMatrix, features: Set? = null) : FeaturedMatrix { - override val rowNum: Int +public class EjmlMatrix(public val origin: SimpleMatrix, features: Set? = null) : FeaturedMatrix { + public override val rowNum: Int get() = origin.numRows() - override val colNum: Int + public override val colNum: Int get() = origin.numCols() - override val shape: IntArray + public override val shape: IntArray get() = intArrayOf(origin.numRows(), origin.numCols()) - override val features: Set = setOf( + public override val features: Set = setOf( object : LUPDecompositionFeature, DeterminantFeature { override val determinant: Double get() = origin.determinant() @@ -50,21 +50,21 @@ class EjmlMatrix(val origin: SimpleMatrix, features: Set? = null) } ) union features.orEmpty() - override fun suggestFeature(vararg features: MatrixFeature): FeaturedMatrix = + public override fun suggestFeature(vararg features: MatrixFeature): FeaturedMatrix = EjmlMatrix(origin, this.features + features) - override operator fun get(i: Int, j: Int): Double = origin[i, j] + public override operator fun get(i: Int, j: Int): Double = origin[i, j] - override fun equals(other: Any?): Boolean { + public override fun equals(other: Any?): Boolean { if (other is EjmlMatrix) return origin.isIdentical(other.origin, 0.0) return NDStructure.equals(this, other as? NDStructure<*> ?: return false) } - override fun hashCode(): Int { + public override fun hashCode(): Int { var result = origin.hashCode() result = 31 * result + features.hashCode() return result } - override fun toString(): String = "EjmlMatrix(origin=$origin, features=$features)" + public override fun toString(): String = "EjmlMatrix(origin=$origin, features=$features)" } diff --git a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrixContext.kt b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrixContext.kt similarity index 76% rename from kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrixContext.kt rename to kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrixContext.kt index 1b59a89ca..b2d99ac3d 100644 --- a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlMatrixContext.kt +++ b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrixContext.kt @@ -1,26 +1,26 @@ -package scientifik.kmath.ejml +package kscience.kmath.ejml import org.ejml.simple.SimpleMatrix -import scientifik.kmath.linear.MatrixContext -import scientifik.kmath.linear.Point -import scientifik.kmath.operations.Space -import scientifik.kmath.operations.invoke -import scientifik.kmath.structures.Matrix +import kscience.kmath.linear.MatrixContext +import kscience.kmath.linear.Point +import kscience.kmath.operations.Space +import kscience.kmath.operations.invoke +import kscience.kmath.structures.Matrix /** * Represents context of basic operations operating with [EjmlMatrix]. */ -class EjmlMatrixContext(private val space: Space) : MatrixContext { +public class EjmlMatrixContext(private val space: Space) : MatrixContext { /** * Converts this matrix to EJML one. */ - fun Matrix.toEjml(): EjmlMatrix = + public fun Matrix.toEjml(): EjmlMatrix = if (this is EjmlMatrix) this else produce(rowNum, colNum) { i, j -> get(i, j) } /** * Converts this vector to EJML one. */ - fun Point.toEjml(): EjmlVector = + public fun Point.toEjml(): EjmlVector = if (this is EjmlVector) this else EjmlVector(SimpleMatrix(size, 1).also { (0 until it.numRows()).forEach { row -> it[row, 0] = get(row) } }) @@ -49,7 +49,7 @@ class EjmlMatrixContext(private val space: Space) : MatrixContext.times(value: Double): EjmlMatrix = EjmlMatrix(toEjml().origin.scale(value)) - companion object + public companion object } /** @@ -59,7 +59,7 @@ class EjmlMatrixContext(private val space: Space) : MatrixContext, b: Matrix): EjmlMatrix = +public fun EjmlMatrixContext.solve(a: Matrix, b: Matrix): EjmlMatrix = EjmlMatrix(a.toEjml().origin.solve(b.toEjml().origin)) /** @@ -69,7 +69,7 @@ fun EjmlMatrixContext.solve(a: Matrix, b: Matrix): EjmlMatrix = * @param b n by p vector. * @return the solution for 'x' that is n by p. */ -fun EjmlMatrixContext.solve(a: Matrix, b: Point): EjmlVector = +public fun EjmlMatrixContext.solve(a: Matrix, b: Point): EjmlVector = EjmlVector(a.toEjml().origin.solve(b.toEjml().origin)) /** @@ -78,4 +78,4 @@ fun EjmlMatrixContext.solve(a: Matrix, b: Point): EjmlVector = * @param a the matrix. * @return the inverse of this matrix. */ -fun EjmlMatrixContext.inverse(a: Matrix): EjmlMatrix = EjmlMatrix(a.toEjml().origin.invert()) +public fun EjmlMatrixContext.inverse(a: Matrix): EjmlMatrix = EjmlMatrix(a.toEjml().origin.invert()) diff --git a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlVector.kt b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt similarity index 90% rename from kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlVector.kt rename to kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt index dd7969e83..ccd660cc6 100644 --- a/kmath-ejml/src/main/kotlin/scientifik/kmath/ejml/EjmlVector.kt +++ b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt @@ -1,8 +1,8 @@ -package scientifik.kmath.ejml +package kscience.kmath.ejml import org.ejml.simple.SimpleMatrix -import scientifik.kmath.linear.Point -import scientifik.kmath.structures.Buffer +import kscience.kmath.linear.Point +import kscience.kmath.structures.Buffer /** * Represents point over EJML [SimpleMatrix]. -- 2.34.1 From 5910c587e2a019b248aafa52773790e43da25d2b Mon Sep 17 00:00:00 2001 From: Iaroslav Date: Mon, 21 Sep 2020 18:59:32 +0700 Subject: [PATCH 13/20] Add missing public visibilities --- .../src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt index 60e3aec8e..478d9c6f8 100644 --- a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt +++ b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt @@ -39,13 +39,13 @@ public class EjmlMatrix(public val origin: SimpleMatrix, features: Set + public override val l: FeaturedMatrix get() = lup.second - override val u: FeaturedMatrix + public override val u: FeaturedMatrix get() = lup.third - override val p: FeaturedMatrix + public override val p: FeaturedMatrix get() = lup.first } ) union features.orEmpty() -- 2.34.1 From 2c21f5669568a6a254c108199ebc68faa9aced09 Mon Sep 17 00:00:00 2001 From: Iaroslav Date: Mon, 21 Sep 2020 19:00:55 +0700 Subject: [PATCH 14/20] Add missing public visibilities and add @author markers --- .../kotlin/kscience/kmath/ejml/EjmlMatrix.kt | 1 + .../kscience/kmath/ejml/EjmlMatrixContext.kt | 17 +++++++++++------ .../kotlin/kscience/kmath/ejml/EjmlVector.kt | 3 ++- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt index 478d9c6f8..15574489e 100644 --- a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt +++ b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt @@ -12,6 +12,7 @@ import kscience.kmath.structures.NDStructure * Represents featured matrix over EJML [SimpleMatrix]. * * @property origin the underlying [SimpleMatrix]. + * @author Iaroslav Postovalov */ public class EjmlMatrix(public val origin: SimpleMatrix, features: Set? = null) : FeaturedMatrix { public override val rowNum: Int diff --git a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrixContext.kt b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrixContext.kt index b2d99ac3d..52826a7b1 100644 --- a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrixContext.kt +++ b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrixContext.kt @@ -9,6 +9,8 @@ import kscience.kmath.structures.Matrix /** * Represents context of basic operations operating with [EjmlMatrix]. + * + * @author Iaroslav Postovalov */ public class EjmlMatrixContext(private val space: Space) : MatrixContext { /** @@ -32,22 +34,22 @@ public class EjmlMatrixContext(private val space: Space) : MatrixContext } }) - override fun Matrix.dot(other: Matrix): EjmlMatrix = + public override fun Matrix.dot(other: Matrix): EjmlMatrix = EjmlMatrix(toEjml().origin.mult(other.toEjml().origin)) - override fun Matrix.dot(vector: Point): EjmlVector = + public override fun Matrix.dot(vector: Point): EjmlVector = EjmlVector(toEjml().origin.mult(vector.toEjml().origin)) - override fun add(a: Matrix, b: Matrix): EjmlMatrix = + public override fun add(a: Matrix, b: Matrix): EjmlMatrix = EjmlMatrix(a.toEjml().origin + b.toEjml().origin) - override operator fun Matrix.minus(b: Matrix): EjmlMatrix = + public override operator fun Matrix.minus(b: Matrix): EjmlMatrix = EjmlMatrix(toEjml().origin - b.toEjml().origin) - override fun multiply(a: Matrix, k: Number): EjmlMatrix = + public override fun multiply(a: Matrix, k: Number): EjmlMatrix = produce(a.rowNum, a.colNum) { i, j -> space { a[i, j] * k } } - override operator fun Matrix.times(value: Double): EjmlMatrix = EjmlMatrix(toEjml().origin.scale(value)) + public override operator fun Matrix.times(value: Double): EjmlMatrix = EjmlMatrix(toEjml().origin.scale(value)) public companion object } @@ -58,6 +60,7 @@ public class EjmlMatrixContext(private val space: Space) : MatrixContext * @param a the base matrix. * @param b n by p matrix. * @return the solution for 'x' that is n by p. + * @author Iaroslav Postovalov */ public fun EjmlMatrixContext.solve(a: Matrix, b: Matrix): EjmlMatrix = EjmlMatrix(a.toEjml().origin.solve(b.toEjml().origin)) @@ -68,6 +71,7 @@ public fun EjmlMatrixContext.solve(a: Matrix, b: Matrix): EjmlMa * @param a the base matrix. * @param b n by p vector. * @return the solution for 'x' that is n by p. + * @author Iaroslav Postovalov */ public fun EjmlMatrixContext.solve(a: Matrix, b: Point): EjmlVector = EjmlVector(a.toEjml().origin.solve(b.toEjml().origin)) @@ -77,5 +81,6 @@ public fun EjmlMatrixContext.solve(a: Matrix, b: Point): EjmlVec * * @param a the matrix. * @return the inverse of this matrix. + * @author Iaroslav Postovalov */ public fun EjmlMatrixContext.inverse(a: Matrix): EjmlMatrix = EjmlMatrix(a.toEjml().origin.invert()) diff --git a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt index ccd660cc6..b3a19849f 100644 --- a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt +++ b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt @@ -8,8 +8,9 @@ import kscience.kmath.structures.Buffer * Represents point over EJML [SimpleMatrix]. * * @property origin the underlying [SimpleMatrix]. + * @author Iaroslav Postavalov */ -class EjmlVector internal constructor(val origin: SimpleMatrix) : Point { +public class EjmlVector internal constructor(public val origin: SimpleMatrix) : Point { override val size: Int get() = origin.numRows() init { -- 2.34.1 From 66d5df7a51e09ee4cfa62c779bc5bb93d84ad0f9 Mon Sep 17 00:00:00 2001 From: Iaroslav Date: Mon, 21 Sep 2020 19:01:24 +0700 Subject: [PATCH 15/20] Add missing public visibilities --- .../src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt | 6 +++--- .../src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt index 15574489e..140c415b7 100644 --- a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt +++ b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt @@ -40,13 +40,13 @@ public class EjmlMatrix(public val origin: SimpleMatrix, features: Set + override val l: FeaturedMatrix get() = lup.second - public override val u: FeaturedMatrix + override val u: FeaturedMatrix get() = lup.third - public override val p: FeaturedMatrix + override val p: FeaturedMatrix get() = lup.first } ) union features.orEmpty() diff --git a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt index b3a19849f..d228e4b39 100644 --- a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt +++ b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt @@ -17,9 +17,9 @@ public class EjmlVector internal constructor(public val origin: SimpleMatrix) : require(origin.numCols() == 1) { error("Only single column matrices are allowed") } } - override operator fun get(index: Int): Double = origin[index] + public override operator fun get(index: Int): Double = origin[index] - override operator fun iterator(): Iterator = object : Iterator { + public override operator fun iterator(): Iterator = object : Iterator { private var cursor: Int = 0 override fun next(): Double { @@ -30,10 +30,10 @@ public class EjmlVector internal constructor(public val origin: SimpleMatrix) : override fun hasNext(): Boolean = cursor < origin.numCols() * origin.numRows() } - override fun contentEquals(other: Buffer<*>): Boolean { + public override fun contentEquals(other: Buffer<*>): Boolean { if (other is EjmlVector) return origin.isIdentical(other.origin, 0.0) return super.contentEquals(other) } - override fun toString(): String = "EjmlVector(origin=$origin)" + public override fun toString(): String = "EjmlVector(origin=$origin)" } -- 2.34.1 From 1c11d25306c453339eee9f687d2efd97986ab9f4 Mon Sep 17 00:00:00 2001 From: Iaroslav Date: Mon, 21 Sep 2020 19:01:36 +0700 Subject: [PATCH 16/20] Fix typo --- kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt index d228e4b39..66da91fdd 100644 --- a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt +++ b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt @@ -8,7 +8,7 @@ import kscience.kmath.structures.Buffer * Represents point over EJML [SimpleMatrix]. * * @property origin the underlying [SimpleMatrix]. - * @author Iaroslav Postavalov + * @author Iaroslav Postovalov */ public class EjmlVector internal constructor(public val origin: SimpleMatrix) : Point { override val size: Int get() = origin.numRows() -- 2.34.1 From 964ac8a702b8a7fc77f0c41cf415573378ca663b Mon Sep 17 00:00:00 2001 From: Iaroslav Date: Mon, 21 Sep 2020 19:02:12 +0700 Subject: [PATCH 17/20] Fix weird guard check --- kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt index 66da91fdd..f7cd1b66d 100644 --- a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt +++ b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlVector.kt @@ -11,10 +11,11 @@ import kscience.kmath.structures.Buffer * @author Iaroslav Postovalov */ public class EjmlVector internal constructor(public val origin: SimpleMatrix) : Point { - override val size: Int get() = origin.numRows() + public override val size: Int + get() = origin.numRows() init { - require(origin.numCols() == 1) { error("Only single column matrices are allowed") } + require(origin.numCols() == 1) { "Only single column matrices are allowed" } } public override operator fun get(index: Int): Double = origin[index] -- 2.34.1 From 91cb95544c055429e89f5d9a218d72fbc6d64989 Mon Sep 17 00:00:00 2001 From: Iaroslav Date: Mon, 21 Sep 2020 19:29:56 +0700 Subject: [PATCH 18/20] Add tests --- .../kotlin/kscience/kmath/ejml/EjmlMatrix.kt | 4 +- .../kscience/kmath/ejml/EjmlMatrixTest.kt | 75 +++++++++++++++++++ .../kscience/kmath/ejml/EjmlVectorTest.kt | 47 ++++++++++++ 3 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 kmath-ejml/src/test/kotlin/kscience/kmath/ejml/EjmlMatrixTest.kt create mode 100644 kmath-ejml/src/test/kotlin/kscience/kmath/ejml/EjmlVectorTest.kt diff --git a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt index 140c415b7..ed6b1571e 100644 --- a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt +++ b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt @@ -36,7 +36,7 @@ public class EjmlMatrix(public val origin: SimpleMatrix, features: Set = + public override fun suggestFeature(vararg features: MatrixFeature): EjmlMatrix = EjmlMatrix(origin, this.features + features) public override operator fun get(i: Int, j: Int): Double = origin[i, j] diff --git a/kmath-ejml/src/test/kotlin/kscience/kmath/ejml/EjmlMatrixTest.kt b/kmath-ejml/src/test/kotlin/kscience/kmath/ejml/EjmlMatrixTest.kt new file mode 100644 index 000000000..e0f15be83 --- /dev/null +++ b/kmath-ejml/src/test/kotlin/kscience/kmath/ejml/EjmlMatrixTest.kt @@ -0,0 +1,75 @@ +package kscience.kmath.ejml + +import kscience.kmath.linear.DeterminantFeature +import kscience.kmath.linear.LUPDecompositionFeature +import kscience.kmath.linear.MatrixFeature +import kscience.kmath.linear.getFeature +import org.ejml.dense.row.factory.DecompositionFactory_DDRM +import org.ejml.simple.SimpleMatrix +import kotlin.random.Random +import kotlin.random.asJavaRandom +import kotlin.test.* + +internal class EjmlMatrixTest { + private val random = Random(0) + + private val randomMatrix: SimpleMatrix + get() { + val s = random.nextInt(2, 100) + return SimpleMatrix.random_DDRM(s, s, 0.0, 10.0, random.asJavaRandom()) + } + + @Test + fun rowNum() { + val m = randomMatrix + assertEquals(m.numRows(), EjmlMatrix(m).rowNum) + } + + @Test + fun colNum() { + val m = randomMatrix + assertEquals(m.numCols(), EjmlMatrix(m).rowNum) + } + + @Test + fun shape() { + val m = randomMatrix + val w = EjmlMatrix(m) + assertEquals(listOf(m.numRows(), m.numCols()), w.shape.toList()) + } + + @Test + fun features() { + val m = randomMatrix + val w = EjmlMatrix(m) + val det = w.getFeature>() ?: fail() + assertEquals(m.determinant(), det.determinant) + val lup = w.getFeature>() ?: fail() + + val ludecompositionF64 = DecompositionFactory_DDRM.lu(m.numRows(), m.numCols()) + .also { it.decompose(m.ddrm.copy()) } + + assertEquals(EjmlMatrix(SimpleMatrix(ludecompositionF64.getLower(null))), lup.l) + assertEquals(EjmlMatrix(SimpleMatrix(ludecompositionF64.getUpper(null))), lup.u) + assertEquals(EjmlMatrix(SimpleMatrix(ludecompositionF64.getRowPivot(null))), lup.p) + } + + private object SomeFeature : MatrixFeature {} + + @Test + fun suggestFeature() { + assertNotNull(EjmlMatrix(randomMatrix).suggestFeature(SomeFeature).getFeature()) + } + + @Test + fun get() { + val m = randomMatrix + assertEquals(m[0, 0], EjmlMatrix(m)[0, 0]) + } + + @Test + fun origin() { + val m = randomMatrix + assertSame(m, EjmlMatrix(m).origin) + } +} diff --git a/kmath-ejml/src/test/kotlin/kscience/kmath/ejml/EjmlVectorTest.kt b/kmath-ejml/src/test/kotlin/kscience/kmath/ejml/EjmlVectorTest.kt new file mode 100644 index 000000000..e27f977d2 --- /dev/null +++ b/kmath-ejml/src/test/kotlin/kscience/kmath/ejml/EjmlVectorTest.kt @@ -0,0 +1,47 @@ +package kscience.kmath.ejml + +import org.ejml.simple.SimpleMatrix +import kotlin.random.Random +import kotlin.random.asJavaRandom +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertSame + +internal class EjmlVectorTest { + private val random = Random(0) + + private val randomMatrix: SimpleMatrix + get() = SimpleMatrix.random_DDRM(random.nextInt(2, 100), 1, 0.0, 10.0, random.asJavaRandom()) + + @Test + fun size() { + val m = randomMatrix + val w = EjmlVector(m) + assertEquals(m.numRows(), w.size) + } + + @Test + fun get() { + val m = randomMatrix + val w = EjmlVector(m) + assertEquals(m[0, 0], w[0]) + } + + @Test + fun iterator() { + val m = randomMatrix + val w = EjmlVector(m) + + assertEquals( + m.iterator(true, 0, 0, m.numRows() - 1, 0).asSequence().toList(), + w.iterator().asSequence().toList() + ) + } + + @Test + fun origin() { + val m = randomMatrix + val w = EjmlVector(m) + assertSame(m, w.origin) + } +} -- 2.34.1 From 02264f84e9051a51dbc031956483bbde6e7ea332 Mon Sep 17 00:00:00 2001 From: Iaroslav Date: Mon, 21 Sep 2020 19:33:12 +0700 Subject: [PATCH 19/20] Add EJML module references in the readme and doc --- README.md | 4 +++- doc/features.md | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c2e67e815..e6938608b 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,9 @@ can be used for a wide variety of purposes from high performance calculations to * **Commons-math wrapper** It is planned to gradually wrap most parts of [Apache commons-math](http://commons.apache.org/proper/commons-math/) library in Kotlin code and maybe rewrite some parts to better suit the Kotlin programming paradigm, however there is no fixed roadmap for that. Feel free to submit a feature request if you want something to be done first. - + +* **EJML wrapper** Provides EJML `SimpleMatrix` wrapper consistent with the core matrix structures. + ## Planned features * **Messaging** A mathematical notation to support multi-language and multi-node communication for mathematical tasks. diff --git a/doc/features.md b/doc/features.md index 0f2c4203f..ff97310c7 100644 --- a/doc/features.md +++ b/doc/features.md @@ -12,3 +12,5 @@ api and multiple library back-ends. * [Expressions](./expressions.md) * Commons math integration + +* EJML integration -- 2.34.1 From 86793d6faca2a04281fae5d3064679551654def9 Mon Sep 17 00:00:00 2001 From: Iaroslav Date: Mon, 21 Sep 2020 20:56:30 +0700 Subject: [PATCH 20/20] Fix package --- examples/build.gradle.kts | 4 +++- .../kmath/linear/LinearAlgebraBenchmark.kt | 0 .../kmath/linear/MultiplicationBenchmark.kt | 11 ----------- 3 files changed, 3 insertions(+), 12 deletions(-) rename examples/src/main/kotlin/{scientifik => kscience}/kmath/linear/LinearAlgebraBenchmark.kt (100%) rename examples/src/main/kotlin/{scientifik => kscience}/kmath/linear/MultiplicationBenchmark.kt (76%) diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts index 1c90db101..3046b7ce8 100644 --- a/examples/build.gradle.kts +++ b/examples/build.gradle.kts @@ -29,7 +29,9 @@ dependencies { implementation(project(":kmath-ejml")) implementation("org.jetbrains.kotlinx:kotlinx-io-jvm:0.2.0-npm-dev-6") implementation("org.jetbrains.kotlinx:kotlinx.benchmark.runtime:0.2.0-dev-20") - "benchmarksCompile"(sourceSets.main.get().output + sourceSets.main.get().compileClasspath) //sourceSets.main.output + sourceSets.main.runtimeClasspath + implementation("org.slf4j:slf4j-simple:1.7.30") + "benchmarksImplementation"("org.jetbrains.kotlinx:kotlinx.benchmark.runtime-jvm:0.2.0-dev-8") + "benchmarksImplementation"(sourceSets.main.get().output + sourceSets.main.get().runtimeClasspath) } // Configure benchmark diff --git a/examples/src/main/kotlin/scientifik/kmath/linear/LinearAlgebraBenchmark.kt b/examples/src/main/kotlin/kscience/kmath/linear/LinearAlgebraBenchmark.kt similarity index 100% rename from examples/src/main/kotlin/scientifik/kmath/linear/LinearAlgebraBenchmark.kt rename to examples/src/main/kotlin/kscience/kmath/linear/LinearAlgebraBenchmark.kt diff --git a/examples/src/main/kotlin/scientifik/kmath/linear/MultiplicationBenchmark.kt b/examples/src/main/kotlin/kscience/kmath/linear/MultiplicationBenchmark.kt similarity index 76% rename from examples/src/main/kotlin/scientifik/kmath/linear/MultiplicationBenchmark.kt rename to examples/src/main/kotlin/kscience/kmath/linear/MultiplicationBenchmark.kt index b82c8aac4..d1011e8f5 100644 --- a/examples/src/main/kotlin/scientifik/kmath/linear/MultiplicationBenchmark.kt +++ b/examples/src/main/kotlin/kscience/kmath/linear/MultiplicationBenchmark.kt @@ -36,14 +36,3 @@ fun main() { val genericTime = measureTimeMillis { val res = matrix1 dot matrix2 } println("Generic implementation time: $genericTime") } - - (EjmlMatrixContext(RealField)) { - val ejmlMatrix1 = matrix1.toEjml() - val ejmlMatrix2 = matrix2.toEjml() - val ejmlTime = measureTimeMillis { ejmlMatrix1 dot ejmlMatrix2 } - println("EJML implementation time: $ejmlTime") - } - - val genericTime = measureTimeMillis { val res = matrix1 dot matrix2 } - println("Generic implementation time: $genericTime") -} -- 2.34.1