Merge pull request #252 from mipt-npm/commandertvis/ejml

Some adjustments to the EJML module
This commit is contained in:
Alexander Nozik 2021-03-17 19:25:49 +03:00 committed by GitHub
commit 4dafb8eb49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 122 additions and 35 deletions

View File

@ -120,10 +120,10 @@ KMath is a modular library. Different modules provide different features with di
>
> **Features:**
> - [algebras](kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Algebraic structures like rings, spaces and fields.
> - [nd](kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt) : Many-dimensional structures and operations on them.
> - [nd](kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/StructureND.kt) : Many-dimensional structures and operations on them.
> - [linear](kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Basic linear algebra operations (sums, products, etc.), backed by the `Space` API. Advanced linear algebra operations like matrix inversion and LU decomposition.
> - [buffers](kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt) : One-dimensional structure
> - [expressions](kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions) : By writing a single mathematical expression once, users will be able to apply different types of
> - [buffers](kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffers.kt) : One-dimensional structure
> - [expressions](kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions) : By writing a single mathematical expression once, users will be able to apply different types of
objects to the expression by providing a context. Expressions can be used for a wide variety of purposes from high
performance calculations to code generation.
> - [domains](kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains) : Domains
@ -206,9 +206,9 @@ One can still use generic algebras though.
> **Maturity**: EXPERIMENTAL
>
> **Features:**
> - [nd4jarraystructure](kmath-nd4j/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : NDStructure wrapper for INDArray
> - [nd4jarrayrings](kmath-nd4j/src/commonMain/kotlin/space/kscience/kmath/structures/NDStructure.kt) : Rings over Nd4jArrayStructure of Int and Long
> - [nd4jarrayfields](kmath-nd4j/src/commonMain/kotlin/space/kscience/kmath/structures/Buffers.kt) : Fields over Nd4jArrayStructure of Float and Double
> - [nd4jarraystructure](kmath-nd4j/#) : NDStructure wrapper for INDArray
> - [nd4jarrayrings](kmath-nd4j/#) : Rings over Nd4jArrayStructure of Int and Long
> - [nd4jarrayfields](kmath-nd4j/#) : Fields over Nd4jArrayStructure of Float and Double
<hr/>

View File

@ -58,7 +58,7 @@ For example, the following builder:
DoubleField.mstInField { symbol("x") + 2 }.compile()
```
… leads to generation of bytecode, which can be decompiled to the following Java class:
leads to generation of bytecode, which can be decompiled to the following Java class:
```java
package space.kscience.kmath.asm.generated;

View File

@ -3,10 +3,10 @@
The core features of KMath:
- [algebras](src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Algebraic structures like rings, spaces and fields.
- [nd](src/commonMain/kotlin/space/kscience/kmath/structures/NDStructure.kt) : Many-dimensional structures and operations on them.
- [nd](src/commonMain/kotlin/space/kscience/kmath/structures/StructureND.kt) : Many-dimensional structures and operations on them.
- [linear](src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Basic linear algebra operations (sums, products, etc.), backed by the `Space` API. Advanced linear algebra operations like matrix inversion and LU decomposition.
- [buffers](src/commonMain/kotlin/space/kscience/kmath/structures/Buffers.kt) : One-dimensional structure
- [expressions](src/commonMain/kotlin/space/kscience/kmath/expressions) : By writing a single mathematical expression once, users will be able to apply different types of
- [expressions](src/commonMain/kotlin/space/kscience/kmath/expressions) : By writing a single mathematical expression once, users will be able to apply different types of
objects to the expression by providing a context. Expressions can be used for a wide variety of purposes from high
performance calculations to code generation.
- [domains](src/commonMain/kotlin/space/kscience/kmath/domains) : Domains

43
kmath-ejml/README.md Normal file
View File

@ -0,0 +1,43 @@
# ejml-simple support (`kmath-ejml`)
This subproject implements the following features:
- [ejml-vector](src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : The Point implementation using SimpleMatrix.
- [ejml-matrix](src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : The Matrix implementation using SimpleMatrix.
- [ejml-linear-space](src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : The LinearSpace implementation using SimpleMatrix.
> #### Artifact:
>
> This module artifact: `space.kscience:kmath-ejml:0.3.0-dev-3`.
>
> Bintray release version: [ ![Download](https://api.bintray.com/packages/mipt-npm/kscience/kmath-ejml/images/download.svg) ](https://bintray.com/mipt-npm/kscience/kmath-ejml/_latestVersion)
>
> Bintray development version: [ ![Download](https://api.bintray.com/packages/mipt-npm/dev/kmath-ejml/images/download.svg) ](https://bintray.com/mipt-npm/dev/kmath-ejml/_latestVersion)
>
> **Gradle:**
>
> ```gradle
> repositories {
> maven { url 'https://repo.kotlin.link' }
> maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
> maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
> }
>
> dependencies {
> implementation 'space.kscience:kmath-ejml:0.3.0-dev-3'
> }
> ```
> **Gradle Kotlin DSL:**
>
> ```kotlin
> repositories {
> maven("https://repo.kotlin.link")
> maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
> maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
> }
>
> dependencies {
> implementation("space.kscience:kmath-ejml:0.3.0-dev-3")
> }
> ```

View File

@ -1,12 +1,33 @@
import ru.mipt.npm.gradle.Maturity
plugins {
id("ru.mipt.npm.gradle.jvm")
}
dependencies {
implementation("org.ejml:ejml-simple:0.39")
implementation(project(":kmath-core"))
api("org.ejml:ejml-simple:0.40")
api(project(":kmath-core"))
}
readme {
maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE
}
maturity = Maturity.PROTOTYPE
propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md"))
feature(
id = "ejml-vector",
description = "The Point implementation using SimpleMatrix.",
ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt"
)
feature(
id = "ejml-matrix",
description = "The Matrix implementation using SimpleMatrix.",
ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt"
)
feature(
id = "ejml-linear-space",
description = "The LinearSpace implementation using SimpleMatrix.",
ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt"
)
}

View File

@ -0,0 +1,7 @@
# ejml-simple support (`kmath-ejml`)
This subproject implements the following features:
${features}
${artifact}

View File

@ -14,10 +14,13 @@ import kotlin.reflect.cast
* Represents context of basic operations operating with [EjmlMatrix].
*
* @author Iaroslav Postovalov
* @author Alexander Nozik
*/
public object EjmlLinearSpace : LinearSpace<Double, DoubleField> {
override val elementAlgebra: DoubleField get() = DoubleField
/**
* The [DoubleField] reference.
*/
public override val elementAlgebra: DoubleField get() = DoubleField
/**
* Converts this matrix to EJML one.
@ -38,14 +41,17 @@ public object EjmlLinearSpace : LinearSpace<Double, DoubleField> {
})
}
override fun buildMatrix(rows: Int, columns: Int, initializer: DoubleField.(i: Int, j: Int) -> Double): EjmlMatrix =
EjmlMatrix(SimpleMatrix(rows, columns).also {
(0 until rows).forEach { row ->
(0 until columns).forEach { col -> it[row, col] = DoubleField.initializer(row, col) }
}
})
public override fun buildMatrix(
rows: Int,
columns: Int,
initializer: DoubleField.(i: Int, j: Int) -> Double,
): EjmlMatrix = EjmlMatrix(SimpleMatrix(rows, columns).also {
(0 until rows).forEach { row ->
(0 until columns).forEach { col -> it[row, col] = DoubleField.initializer(row, col) }
}
})
override fun buildVector(size: Int, initializer: DoubleField.(Int) -> Double): Point<Double> =
public override fun buildVector(size: Int, initializer: DoubleField.(Int) -> Double): Point<Double> =
EjmlVector(SimpleMatrix(size, 1).also {
(0 until it.numRows()).forEach { row -> it[row, 0] = DoubleField.initializer(row) }
})
@ -53,7 +59,7 @@ public object EjmlLinearSpace : LinearSpace<Double, DoubleField> {
private fun SimpleMatrix.wrapMatrix() = EjmlMatrix(this)
private fun SimpleMatrix.wrapVector() = EjmlVector(this)
override fun Matrix<Double>.unaryMinus(): Matrix<Double> = this * (-1.0)
public override fun Matrix<Double>.unaryMinus(): Matrix<Double> = this * (-1.0)
public override fun Matrix<Double>.dot(other: Matrix<Double>): EjmlMatrix =
EjmlMatrix(toEjml().origin.mult(other.toEjml().origin))
@ -67,29 +73,29 @@ public object EjmlLinearSpace : LinearSpace<Double, DoubleField> {
public override operator fun Matrix<Double>.times(value: Double): EjmlMatrix =
toEjml().origin.scale(value).wrapMatrix()
override fun Point<Double>.unaryMinus(): EjmlVector =
public override fun Point<Double>.unaryMinus(): EjmlVector =
toEjml().origin.negative().wrapVector()
override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlMatrix =
public override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlMatrix =
(toEjml().origin + other.toEjml().origin).wrapMatrix()
override fun Point<Double>.plus(other: Point<Double>): EjmlVector =
public override fun Point<Double>.plus(other: Point<Double>): EjmlVector =
(toEjml().origin + other.toEjml().origin).wrapVector()
override fun Point<Double>.minus(other: Point<Double>): EjmlVector =
public override fun Point<Double>.minus(other: Point<Double>): EjmlVector =
(toEjml().origin - other.toEjml().origin).wrapVector()
override fun Double.times(m: Matrix<Double>): EjmlMatrix =
public override fun Double.times(m: Matrix<Double>): EjmlMatrix =
m.toEjml().origin.scale(this).wrapMatrix()
override fun Point<Double>.times(value: Double): EjmlVector =
public override fun Point<Double>.times(value: Double): EjmlVector =
toEjml().origin.scale(value).wrapVector()
override fun Double.times(v: Point<Double>): EjmlVector =
public override fun Double.times(v: Point<Double>): EjmlVector =
v.toEjml().origin.scale(this).wrapVector()
@UnstableKMathAPI
override fun <F : Any> getFeature(structure: Matrix<Double>, type: KClass<F>): F? {
public override fun <F : Any> getFeature(structure: Matrix<Double>, type: KClass<F>): F? {
//Return the feature if it is intrinsic to the structure
structure.getFeature(type)?.let { return it }
@ -160,7 +166,7 @@ public object EjmlLinearSpace : LinearSpace<Double, DoubleField> {
}
/**
* Solves for X in the following equation: x = a^-1*b, where 'a' is base matrix and 'b' is an n by p matrix.
* Solves for *x* in the following equation: *x = [a] <sup>-1</sup> &middot; [b]*.
*
* @param a the base matrix.
* @param b n by p matrix.
@ -171,7 +177,7 @@ public fun EjmlLinearSpace.solve(a: Matrix<Double>, b: Matrix<Double>): EjmlMatr
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.
* Solves for *x* in the following equation: *x = [a] <sup>-1</sup> &middot; [b]*.
*
* @param a the base matrix.
* @param b n by p vector.
@ -181,7 +187,17 @@ public fun EjmlLinearSpace.solve(a: Matrix<Double>, b: Matrix<Double>): EjmlMatr
public fun EjmlLinearSpace.solve(a: Matrix<Double>, b: Point<Double>): EjmlVector =
EjmlVector(a.toEjml().origin.solve(b.toEjml().origin))
/**
* Inverts this matrix.
*
* @author Alexander Nozik
*/
@OptIn(UnstableKMathAPI::class)
public fun EjmlMatrix.inverted(): EjmlMatrix = getFeature<InverseMatrixFeature<Double>>()!!.inverse as EjmlMatrix
/**
* Inverts the given matrix.
*
* @author Alexander Nozik
*/
public fun EjmlLinearSpace.inverse(matrix: Matrix<Double>): Matrix<Double> = matrix.toEjml().inverted()

View File

@ -4,7 +4,7 @@ import org.ejml.simple.SimpleMatrix
import space.kscience.kmath.linear.Matrix
/**
* Represents featured matrix over EJML [SimpleMatrix].
* The matrix implementation over EJML [SimpleMatrix].
*
* @property origin the underlying [SimpleMatrix].
* @author Iaroslav Postovalov

View File

@ -9,7 +9,7 @@ import space.kscience.kmath.linear.Point
* @property origin the underlying [SimpleMatrix].
* @author Iaroslav Postovalov
*/
public class EjmlVector internal constructor(public val origin: SimpleMatrix) : Point<Double> {
public inline class EjmlVector internal constructor(public val origin: SimpleMatrix) : Point<Double> {
public override val size: Int
get() = origin.numRows()