forked from kscience/kmath
Merge pull request #294 from mipt-npm/commandertvis/rework-ejml
Rewrite EJML module by dropping ejml-simple abstraction level
This commit is contained in:
commit
fd7e26d6c5
4
.github/workflows/pages.yml
vendored
4
.github/workflows/pages.yml
vendored
@ -30,9 +30,7 @@ jobs:
|
|||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-gradle-
|
${{ runner.os }}-gradle-
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: ./gradlew dokkaHtmlMultiModule --no-daemon --no-parallel --stacktrace
|
||||||
./gradlew dokkaHtmlMultiModule --no-daemon --no-parallel --stacktrace
|
|
||||||
mv build/dokka/htmlMultiModule/-modules.html build/dokka/htmlMultiModule/index.html
|
|
||||||
- name: Deploy to GitHub Pages
|
- name: Deploy to GitHub Pages
|
||||||
uses: JamesIves/github-pages-deploy-action@4.1.0
|
uses: JamesIves/github-pages-deploy-action@4.1.0
|
||||||
with:
|
with:
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
- Blocking chains and Statistics
|
- Blocking chains and Statistics
|
||||||
- Multiplatform integration
|
- Multiplatform integration
|
||||||
- Integration for any Field element
|
- Integration for any Field element
|
||||||
- Extendend operations for ND4J fields
|
- Extended operations for ND4J fields
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Exponential operations merged with hyperbolic functions
|
- Exponential operations merged with hyperbolic functions
|
||||||
@ -24,6 +24,7 @@
|
|||||||
- Redesign MST. Remove MSTExpression.
|
- Redesign MST. Remove MSTExpression.
|
||||||
- Move MST to core
|
- Move MST to core
|
||||||
- Separated benchmarks and examples
|
- Separated benchmarks and examples
|
||||||
|
- Rewritten EJML module without ejml-simple
|
||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
||||||
|
@ -9,14 +9,10 @@ sourceSets.register("benchmarks")
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
jcenter()
|
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://clojars.org/repo")
|
maven("https://clojars.org/repo")
|
||||||
maven("https://dl.bintray.com/egor-bogomolov/astminer/")
|
|
||||||
maven("https://dl.bintray.com/hotkeytlt/maven")
|
|
||||||
maven("https://jitpack.io")
|
maven("https://jitpack.io")
|
||||||
maven {
|
maven("http://logicrunch.research.it.uu.se/maven") {
|
||||||
setUrl("http://logicrunch.research.it.uu.se/maven/")
|
|
||||||
isAllowInsecureProtocol = true
|
isAllowInsecureProtocol = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import kotlinx.benchmark.Blackhole
|
|||||||
import kotlinx.benchmark.Scope
|
import kotlinx.benchmark.Scope
|
||||||
import kotlinx.benchmark.State
|
import kotlinx.benchmark.State
|
||||||
import space.kscience.kmath.commons.linear.CMLinearSpace
|
import space.kscience.kmath.commons.linear.CMLinearSpace
|
||||||
import space.kscience.kmath.ejml.EjmlLinearSpace
|
import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM
|
||||||
import space.kscience.kmath.linear.LinearSpace
|
import space.kscience.kmath.linear.LinearSpace
|
||||||
import space.kscience.kmath.linear.invoke
|
import space.kscience.kmath.linear.invoke
|
||||||
import space.kscience.kmath.operations.DoubleField
|
import space.kscience.kmath.operations.DoubleField
|
||||||
@ -29,8 +29,8 @@ internal class DotBenchmark {
|
|||||||
val cmMatrix1 = CMLinearSpace { matrix1.toCM() }
|
val cmMatrix1 = CMLinearSpace { matrix1.toCM() }
|
||||||
val cmMatrix2 = CMLinearSpace { matrix2.toCM() }
|
val cmMatrix2 = CMLinearSpace { matrix2.toCM() }
|
||||||
|
|
||||||
val ejmlMatrix1 = EjmlLinearSpace { matrix1.toEjml() }
|
val ejmlMatrix1 = EjmlLinearSpaceDDRM { matrix1.toEjml() }
|
||||||
val ejmlMatrix2 = EjmlLinearSpace { matrix2.toEjml() }
|
val ejmlMatrix2 = EjmlLinearSpaceDDRM { matrix2.toEjml() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
@ -42,14 +42,14 @@ internal class DotBenchmark {
|
|||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
fun ejmlDot(blackhole: Blackhole) {
|
fun ejmlDot(blackhole: Blackhole) {
|
||||||
EjmlLinearSpace {
|
EjmlLinearSpaceDDRM {
|
||||||
blackhole.consume(ejmlMatrix1 dot ejmlMatrix2)
|
blackhole.consume(ejmlMatrix1 dot ejmlMatrix2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
fun ejmlDotWithConversion(blackhole: Blackhole) {
|
fun ejmlDotWithConversion(blackhole: Blackhole) {
|
||||||
EjmlLinearSpace {
|
EjmlLinearSpaceDDRM {
|
||||||
blackhole.consume(matrix1 dot matrix2)
|
blackhole.consume(matrix1 dot matrix2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,25 +11,26 @@ import kotlinx.benchmark.Scope
|
|||||||
import kotlinx.benchmark.State
|
import kotlinx.benchmark.State
|
||||||
import space.kscience.kmath.commons.linear.CMLinearSpace
|
import space.kscience.kmath.commons.linear.CMLinearSpace
|
||||||
import space.kscience.kmath.commons.linear.inverse
|
import space.kscience.kmath.commons.linear.inverse
|
||||||
import space.kscience.kmath.ejml.EjmlLinearSpace
|
import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM
|
||||||
import space.kscience.kmath.ejml.inverse
|
import space.kscience.kmath.linear.InverseMatrixFeature
|
||||||
import space.kscience.kmath.linear.LinearSpace
|
import space.kscience.kmath.linear.LinearSpace
|
||||||
import space.kscience.kmath.linear.inverseWithLup
|
import space.kscience.kmath.linear.inverseWithLup
|
||||||
import space.kscience.kmath.linear.invoke
|
import space.kscience.kmath.linear.invoke
|
||||||
|
import space.kscience.kmath.nd.getFeature
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
@State(Scope.Benchmark)
|
@State(Scope.Benchmark)
|
||||||
internal class MatrixInverseBenchmark {
|
internal class MatrixInverseBenchmark {
|
||||||
companion object {
|
private companion object {
|
||||||
val random = Random(1224)
|
private val random = Random(1224)
|
||||||
const val dim = 100
|
private const val dim = 100
|
||||||
|
|
||||||
private val space = LinearSpace.real
|
private val space = LinearSpace.real
|
||||||
|
|
||||||
//creating invertible matrix
|
//creating invertible matrix
|
||||||
val u = space.buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
|
private val u = space.buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
|
||||||
val l = space.buildMatrix(dim, dim) { i, j -> if (i >= j) random.nextDouble() else 0.0 }
|
private val l = space.buildMatrix(dim, dim) { i, j -> if (i >= j) random.nextDouble() else 0.0 }
|
||||||
val matrix = space { l dot u }
|
private val matrix = space { l dot u }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
@ -46,8 +47,8 @@ internal class MatrixInverseBenchmark {
|
|||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
fun ejmlInverse(blackhole: Blackhole) {
|
fun ejmlInverse(blackhole: Blackhole) {
|
||||||
with(EjmlLinearSpace) {
|
with(EjmlLinearSpaceDDRM) {
|
||||||
blackhole.consume(inverse(matrix))
|
blackhole.consume(matrix.getFeature<InverseMatrixFeature<Double>>()?.inverse)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,12 @@ plugins {
|
|||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
|
||||||
maven("https://clojars.org/repo")
|
maven("https://clojars.org/repo")
|
||||||
maven("https://dl.bintray.com/egor-bogomolov/astminer/")
|
|
||||||
maven("https://dl.bintray.com/hotkeytlt/maven")
|
|
||||||
maven("https://jitpack.io")
|
maven("https://jitpack.io")
|
||||||
maven("http://logicrunch.research.it.uu.se/maven/") {
|
maven("http://logicrunch.research.it.uu.se/maven") {
|
||||||
isAllowInsecureProtocol = true
|
isAllowInsecureProtocol = true
|
||||||
}
|
}
|
||||||
|
maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven")
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,22 +21,16 @@ subprojects {
|
|||||||
if (name.startsWith("kmath")) apply<MavenPublishPlugin>()
|
if (name.startsWith("kmath")) apply<MavenPublishPlugin>()
|
||||||
|
|
||||||
afterEvaluate {
|
afterEvaluate {
|
||||||
tasks.withType<org.jetbrains.dokka.gradle.DokkaTask> {
|
tasks.withType<org.jetbrains.dokka.gradle.DokkaTaskPartial> {
|
||||||
dokkaSourceSets.all {
|
dependsOn(tasks.getByName("assemble"))
|
||||||
val readmeFile = File(this@subprojects.projectDir, "./README.md")
|
|
||||||
if (readmeFile.exists())
|
|
||||||
includes.setFrom(includes + readmeFile.absolutePath)
|
|
||||||
|
|
||||||
arrayOf(
|
dokkaSourceSets.all {
|
||||||
"http://ejml.org/javadoc/",
|
val readmeFile = File(this@subprojects.projectDir, "README.md")
|
||||||
"https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/",
|
if (readmeFile.exists()) includes.setFrom(includes + readmeFile.absolutePath)
|
||||||
"https://deeplearning4j.org/api/latest/"
|
externalDocumentationLink("http://ejml.org/javadoc/")
|
||||||
).map { java.net.URL("${it}package-list") to java.net.URL(it) }.forEach { (a, b) ->
|
externalDocumentationLink("https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/")
|
||||||
externalDocumentationLink {
|
externalDocumentationLink("https://deeplearning4j.org/api/latest/")
|
||||||
packageListUrl.set(a)
|
externalDocumentationLink("https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/")
|
||||||
url.set(b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
docs/templates/ARTIFACT-TEMPLATE.md
vendored
6
docs/templates/ARTIFACT-TEMPLATE.md
vendored
@ -6,8 +6,7 @@ The Maven coordinates of this project are `${group}:${name}:${version}`.
|
|||||||
```gradle
|
```gradle
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://repo.kotlin.link' }
|
maven { url 'https://repo.kotlin.link' }
|
||||||
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
|
mavenCentral()
|
||||||
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -18,8 +17,7 @@ dependencies {
|
|||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
|
mavenCentral()
|
||||||
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -4,14 +4,11 @@ plugins {
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
jcenter()
|
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://clojars.org/repo")
|
maven("https://clojars.org/repo")
|
||||||
maven("https://dl.bintray.com/egor-bogomolov/astminer/")
|
|
||||||
maven("https://dl.bintray.com/hotkeytlt/maven")
|
|
||||||
maven("https://jitpack.io")
|
maven("https://jitpack.io")
|
||||||
maven{
|
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-js-wrappers")
|
||||||
setUrl("http://logicrunch.research.it.uu.se/maven/")
|
maven("http://logicrunch.research.it.uu.se/maven") {
|
||||||
isAllowInsecureProtocol = true
|
isAllowInsecureProtocol = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,7 @@ The Maven coordinates of this project are `space.kscience:kmath-ast:0.3.0-dev-7`
|
|||||||
```gradle
|
```gradle
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://repo.kotlin.link' }
|
maven { url 'https://repo.kotlin.link' }
|
||||||
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
|
mavenCentral()
|
||||||
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -28,8 +27,7 @@ dependencies {
|
|||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
|
mavenCentral()
|
||||||
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -14,8 +14,7 @@ The Maven coordinates of this project are `space.kscience:kmath-complex:0.3.0-de
|
|||||||
```gradle
|
```gradle
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://repo.kotlin.link' }
|
maven { url 'https://repo.kotlin.link' }
|
||||||
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
|
mavenCentral()
|
||||||
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -26,8 +25,7 @@ dependencies {
|
|||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
|
mavenCentral()
|
||||||
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -21,8 +21,7 @@ The Maven coordinates of this project are `space.kscience:kmath-core:0.3.0-dev-7
|
|||||||
```gradle
|
```gradle
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://repo.kotlin.link' }
|
maven { url 'https://repo.kotlin.link' }
|
||||||
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
|
mavenCentral()
|
||||||
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -33,8 +32,7 @@ dependencies {
|
|||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
|
mavenCentral()
|
||||||
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
EJML based linear algebra implementation.
|
EJML based linear algebra implementation.
|
||||||
|
|
||||||
- [ejml-vector](src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : The Point implementation using SimpleMatrix.
|
- [ejml-vector](src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : Point implementations.
|
||||||
- [ejml-matrix](src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : The Matrix implementation using SimpleMatrix.
|
- [ejml-matrix](src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : Matrix implementation.
|
||||||
- [ejml-linear-space](src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : The LinearSpace implementation using SimpleMatrix.
|
- [ejml-linear-space](src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : LinearSpace implementations.
|
||||||
|
|
||||||
|
|
||||||
## Artifact:
|
## Artifact:
|
||||||
@ -15,8 +15,7 @@ The Maven coordinates of this project are `space.kscience:kmath-ejml:0.3.0-dev-7
|
|||||||
```gradle
|
```gradle
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://repo.kotlin.link' }
|
maven { url 'https://repo.kotlin.link' }
|
||||||
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
|
mavenCentral()
|
||||||
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -27,8 +26,7 @@ dependencies {
|
|||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
|
mavenCentral()
|
||||||
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -4,7 +4,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api("org.ejml:ejml-simple:0.40")
|
api("org.ejml:ejml-ddense:0.40")
|
||||||
api(project(":kmath-core"))
|
api(project(":kmath-core"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14,19 +14,19 @@ readme {
|
|||||||
|
|
||||||
feature(
|
feature(
|
||||||
id = "ejml-vector",
|
id = "ejml-vector",
|
||||||
description = "The Point implementation using SimpleMatrix.",
|
description = "Point implementations.",
|
||||||
ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt"
|
ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt"
|
||||||
)
|
)
|
||||||
|
|
||||||
feature(
|
feature(
|
||||||
id = "ejml-matrix",
|
id = "ejml-matrix",
|
||||||
description = "The Matrix implementation using SimpleMatrix.",
|
description = "Matrix implementation.",
|
||||||
ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt"
|
ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt"
|
||||||
)
|
)
|
||||||
|
|
||||||
feature(
|
feature(
|
||||||
id = "ejml-linear-space",
|
id = "ejml-linear-space",
|
||||||
description = "The LinearSpace implementation using SimpleMatrix.",
|
description = "LinearSpace implementations.",
|
||||||
ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt"
|
ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -5,45 +5,71 @@
|
|||||||
|
|
||||||
package space.kscience.kmath.ejml
|
package space.kscience.kmath.ejml
|
||||||
|
|
||||||
|
import org.ejml.data.DMatrix
|
||||||
|
import org.ejml.data.DMatrixD1
|
||||||
|
import org.ejml.data.DMatrixRMaj
|
||||||
|
import org.ejml.dense.row.CommonOps_DDRM
|
||||||
import org.ejml.dense.row.factory.DecompositionFactory_DDRM
|
import org.ejml.dense.row.factory.DecompositionFactory_DDRM
|
||||||
import org.ejml.simple.SimpleMatrix
|
|
||||||
import space.kscience.kmath.linear.*
|
import space.kscience.kmath.linear.*
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.nd.StructureFeature
|
import space.kscience.kmath.nd.StructureFeature
|
||||||
import space.kscience.kmath.nd.getFeature
|
|
||||||
import space.kscience.kmath.operations.DoubleField
|
import space.kscience.kmath.operations.DoubleField
|
||||||
|
import space.kscience.kmath.operations.Ring
|
||||||
import space.kscience.kmath.structures.DoubleBuffer
|
import space.kscience.kmath.structures.DoubleBuffer
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.reflect.cast
|
import kotlin.reflect.cast
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents context of basic operations operating with [EjmlMatrix].
|
* [LinearSpace] implementation specialized for a certain EJML type.
|
||||||
|
*
|
||||||
|
* @param T the type of items in the matrices.
|
||||||
|
* @param A the element context type.
|
||||||
|
* @param M the EJML matrix type.
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
|
*/
|
||||||
|
public abstract class EjmlLinearSpace<T : Any, out A : Ring<T>, M : org.ejml.data.Matrix> : LinearSpace<T, A> {
|
||||||
|
/**
|
||||||
|
* Converts this matrix to EJML one.
|
||||||
|
*/
|
||||||
|
public abstract fun Matrix<T>.toEjml(): EjmlMatrix<T, M>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts this vector to EJML one.
|
||||||
|
*/
|
||||||
|
public abstract fun Point<T>.toEjml(): EjmlVector<T, M>
|
||||||
|
|
||||||
|
public abstract override fun buildMatrix(
|
||||||
|
rows: Int,
|
||||||
|
columns: Int,
|
||||||
|
initializer: A.(i: Int, j: Int) -> T,
|
||||||
|
): EjmlMatrix<T, M>
|
||||||
|
|
||||||
|
public abstract override fun buildVector(size: Int, initializer: A.(Int) -> T): EjmlVector<T, M>
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [EjmlLinearSpace] implementation based on [CommonOps_DDRM], [DecompositionFactory_DDRM] operations and
|
||||||
|
* [DMatrixRMaj] matrices.
|
||||||
*
|
*
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
* @author Alexander Nozik
|
|
||||||
*/
|
*/
|
||||||
public object EjmlLinearSpace : LinearSpace<Double, DoubleField> {
|
public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, DoubleField, DMatrixRMaj>() {
|
||||||
/**
|
/**
|
||||||
* The [DoubleField] reference.
|
* The [DoubleField] reference.
|
||||||
*/
|
*/
|
||||||
public override val elementAlgebra: DoubleField get() = DoubleField
|
public override val elementAlgebra: DoubleField get() = DoubleField
|
||||||
|
|
||||||
/**
|
@Suppress("UNCHECKED_CAST")
|
||||||
* Converts this matrix to EJML one.
|
public override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixRMaj> = when {
|
||||||
*/
|
this is EjmlDoubleMatrix<*> && origin is DMatrixRMaj -> this as EjmlDoubleMatrix<DMatrixRMaj>
|
||||||
@OptIn(UnstableKMathAPI::class)
|
|
||||||
public fun Matrix<Double>.toEjml(): EjmlMatrix = when (val matrix = origin) {
|
|
||||||
is EjmlMatrix -> matrix
|
|
||||||
else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) }
|
else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Suppress("UNCHECKED_CAST")
|
||||||
* Converts this vector to EJML one.
|
public override fun Point<Double>.toEjml(): EjmlDoubleVector<DMatrixRMaj> = when {
|
||||||
*/
|
this is EjmlDoubleVector<*> && origin is DMatrixRMaj -> this as EjmlDoubleVector<DMatrixRMaj>
|
||||||
public fun Point<Double>.toEjml(): EjmlVector = when (this) {
|
else -> EjmlDoubleVector(DMatrixRMaj(size, 1).also {
|
||||||
is EjmlVector -> this
|
(0 until it.numRows).forEach { row -> it[row, 0] = get(row) }
|
||||||
else -> EjmlVector(SimpleMatrix(size, 1).also {
|
|
||||||
(0 until it.numRows()).forEach { row -> it[row, 0] = get(row) }
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,159 +77,178 @@ public object EjmlLinearSpace : LinearSpace<Double, DoubleField> {
|
|||||||
rows: Int,
|
rows: Int,
|
||||||
columns: Int,
|
columns: Int,
|
||||||
initializer: DoubleField.(i: Int, j: Int) -> Double,
|
initializer: DoubleField.(i: Int, j: Int) -> Double,
|
||||||
): EjmlMatrix = EjmlMatrix(SimpleMatrix(rows, columns).also {
|
): EjmlDoubleMatrix<DMatrixRMaj> = EjmlDoubleMatrix(DMatrixRMaj(rows, columns).also {
|
||||||
(0 until rows).forEach { row ->
|
(0 until rows).forEach { row ->
|
||||||
(0 until columns).forEach { col -> it[row, col] = DoubleField.initializer(row, col) }
|
(0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
public override fun buildVector(size: Int, initializer: DoubleField.(Int) -> Double): Point<Double> =
|
public override fun buildVector(
|
||||||
EjmlVector(SimpleMatrix(size, 1).also {
|
size: Int,
|
||||||
(0 until it.numRows()).forEach { row -> it[row, 0] = DoubleField.initializer(row) }
|
initializer: DoubleField.(Int) -> Double,
|
||||||
})
|
): EjmlDoubleVector<DMatrixRMaj> = EjmlDoubleVector(DMatrixRMaj(size, 1).also {
|
||||||
|
(0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) }
|
||||||
|
})
|
||||||
|
|
||||||
private fun SimpleMatrix.wrapMatrix() = EjmlMatrix(this)
|
private fun <T : DMatrix> T.wrapMatrix() = EjmlDoubleMatrix(this)
|
||||||
private fun SimpleMatrix.wrapVector() = EjmlVector(this)
|
private fun <T : DMatrixD1> T.wrapVector() = EjmlDoubleVector(this)
|
||||||
|
|
||||||
public 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 =
|
public override fun Matrix<Double>.dot(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> {
|
||||||
EjmlMatrix(toEjml().origin.mult(other.toEjml().origin))
|
val out = DMatrixRMaj(1, 1)
|
||||||
|
CommonOps_DDRM.mult(toEjml().origin, other.toEjml().origin, out)
|
||||||
|
return out.wrapMatrix()
|
||||||
|
}
|
||||||
|
|
||||||
public override fun Matrix<Double>.dot(vector: Point<Double>): EjmlVector =
|
public override fun Matrix<Double>.dot(vector: Point<Double>): EjmlDoubleVector<DMatrixRMaj> {
|
||||||
EjmlVector(toEjml().origin.mult(vector.toEjml().origin))
|
val out = DMatrixRMaj(1, 1)
|
||||||
|
CommonOps_DDRM.mult(toEjml().origin, vector.toEjml().origin, out)
|
||||||
|
return out.wrapVector()
|
||||||
|
}
|
||||||
|
|
||||||
public override operator fun Matrix<Double>.minus(other: Matrix<Double>): EjmlMatrix =
|
public override operator fun Matrix<Double>.minus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> {
|
||||||
(toEjml().origin - other.toEjml().origin).wrapMatrix()
|
val out = DMatrixRMaj(1, 1)
|
||||||
|
CommonOps_DDRM.subtract(toEjml().origin, other.toEjml().origin, out)
|
||||||
|
return out.wrapMatrix()
|
||||||
|
}
|
||||||
|
|
||||||
public override operator fun Matrix<Double>.times(value: Double): EjmlMatrix =
|
public override operator fun Matrix<Double>.times(value: Double): EjmlDoubleMatrix<DMatrixRMaj> {
|
||||||
toEjml().origin.scale(value).wrapMatrix()
|
val res = this.toEjml().origin.copy()
|
||||||
|
CommonOps_DDRM.scale(value, res)
|
||||||
|
return res.wrapMatrix()
|
||||||
|
}
|
||||||
|
|
||||||
public override fun Point<Double>.unaryMinus(): EjmlVector =
|
public override fun Point<Double>.unaryMinus(): EjmlDoubleVector<DMatrixRMaj> {
|
||||||
toEjml().origin.negative().wrapVector()
|
val out = toEjml().origin.copy()
|
||||||
|
CommonOps_DDRM.changeSign(out)
|
||||||
|
return out.wrapVector()
|
||||||
|
}
|
||||||
|
|
||||||
public override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlMatrix =
|
public override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> {
|
||||||
(toEjml().origin + other.toEjml().origin).wrapMatrix()
|
val out = DMatrixRMaj(1, 1)
|
||||||
|
CommonOps_DDRM.add(toEjml().origin, other.toEjml().origin, out)
|
||||||
|
return out.wrapMatrix()
|
||||||
|
}
|
||||||
|
|
||||||
public override fun Point<Double>.plus(other: Point<Double>): EjmlVector =
|
public override fun Point<Double>.plus(other: Point<Double>): EjmlDoubleVector<DMatrixRMaj> {
|
||||||
(toEjml().origin + other.toEjml().origin).wrapVector()
|
val out = DMatrixRMaj(1, 1)
|
||||||
|
CommonOps_DDRM.add(toEjml().origin, other.toEjml().origin, out)
|
||||||
|
return out.wrapVector()
|
||||||
|
}
|
||||||
|
|
||||||
public override fun Point<Double>.minus(other: Point<Double>): EjmlVector =
|
public override fun Point<Double>.minus(other: Point<Double>): EjmlDoubleVector<DMatrixRMaj> {
|
||||||
(toEjml().origin - other.toEjml().origin).wrapVector()
|
val out = DMatrixRMaj(1, 1)
|
||||||
|
CommonOps_DDRM.subtract(toEjml().origin, other.toEjml().origin, out)
|
||||||
|
return out.wrapVector()
|
||||||
|
}
|
||||||
|
|
||||||
public override fun Double.times(m: Matrix<Double>): EjmlMatrix =
|
public override fun Double.times(m: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> = m * this
|
||||||
m.toEjml().origin.scale(this).wrapMatrix()
|
|
||||||
|
|
||||||
public override fun Point<Double>.times(value: Double): EjmlVector =
|
public override fun Point<Double>.times(value: Double): EjmlDoubleVector<DMatrixRMaj> {
|
||||||
toEjml().origin.scale(value).wrapVector()
|
val res = this.toEjml().origin.copy()
|
||||||
|
CommonOps_DDRM.scale(value, res)
|
||||||
|
return res.wrapVector()
|
||||||
|
}
|
||||||
|
|
||||||
public override fun Double.times(v: Point<Double>): EjmlVector =
|
public override fun Double.times(v: Point<Double>): EjmlDoubleVector<DMatrixRMaj> = v * this
|
||||||
v.toEjml().origin.scale(this).wrapVector()
|
|
||||||
|
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public override fun <F : StructureFeature> getFeature(structure: Matrix<Double>, type: KClass<out F>): F? {
|
public override fun <F : StructureFeature> getFeature(structure: Matrix<Double>, type: KClass<out F>): F? {
|
||||||
//Return the feature if it is intrinsic to the structure
|
// Return the feature if it is intrinsic to the structure
|
||||||
structure.getFeature(type)?.let { return it }
|
structure.getFeature(type)?.let { return it }
|
||||||
|
|
||||||
val origin = structure.toEjml().origin
|
val origin = structure.toEjml().origin
|
||||||
|
|
||||||
return when (type) {
|
return when (type) {
|
||||||
InverseMatrixFeature::class -> object : InverseMatrixFeature<Double> {
|
InverseMatrixFeature::class -> object : InverseMatrixFeature<Double> {
|
||||||
override val inverse: Matrix<Double> by lazy { EjmlMatrix(origin.invert()) }
|
override val inverse: Matrix<Double> by lazy {
|
||||||
|
val res = origin.copy()
|
||||||
|
CommonOps_DDRM.invert(res)
|
||||||
|
EjmlDoubleMatrix(res)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DeterminantFeature::class -> object : DeterminantFeature<Double> {
|
DeterminantFeature::class -> object : DeterminantFeature<Double> {
|
||||||
override val determinant: Double by lazy(origin::determinant)
|
override val determinant: Double by lazy { CommonOps_DDRM.det(DMatrixRMaj(origin)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
SingularValueDecompositionFeature::class -> object : SingularValueDecompositionFeature<Double> {
|
SingularValueDecompositionFeature::class -> object : SingularValueDecompositionFeature<Double> {
|
||||||
private val svd by lazy {
|
private val svd by lazy {
|
||||||
DecompositionFactory_DDRM.svd(origin.numRows(), origin.numCols(), true, true, false)
|
DecompositionFactory_DDRM.svd(origin.numRows, origin.numCols, true, true, false)
|
||||||
.apply { decompose(origin.ddrm.copy()) }
|
.apply { decompose(origin.copy()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override val u: Matrix<Double> by lazy { EjmlMatrix(SimpleMatrix(svd.getU(null, false))) }
|
override val u: Matrix<Double> by lazy { EjmlDoubleMatrix(svd.getU(null, false)) }
|
||||||
override val s: Matrix<Double> by lazy { EjmlMatrix(SimpleMatrix(svd.getW(null))) }
|
override val s: Matrix<Double> by lazy { EjmlDoubleMatrix(svd.getW(null)) }
|
||||||
override val v: Matrix<Double> by lazy { EjmlMatrix(SimpleMatrix(svd.getV(null, false))) }
|
override val v: Matrix<Double> by lazy { EjmlDoubleMatrix(svd.getV(null, false)) }
|
||||||
override val singularValues: Point<Double> by lazy { DoubleBuffer(svd.singularValues) }
|
override val singularValues: Point<Double> by lazy { DoubleBuffer(svd.singularValues) }
|
||||||
}
|
}
|
||||||
|
|
||||||
QRDecompositionFeature::class -> object : QRDecompositionFeature<Double> {
|
QRDecompositionFeature::class -> object : QRDecompositionFeature<Double> {
|
||||||
private val qr by lazy {
|
private val qr by lazy {
|
||||||
DecompositionFactory_DDRM.qr().apply { decompose(origin.ddrm.copy()) }
|
DecompositionFactory_DDRM.qr().apply { decompose(origin.copy()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override val q: Matrix<Double> by lazy {
|
override val q: Matrix<Double> by lazy {
|
||||||
EjmlMatrix(SimpleMatrix(qr.getQ(null, false))) + OrthogonalFeature
|
EjmlDoubleMatrix(qr.getQ(null, false)) + OrthogonalFeature
|
||||||
}
|
}
|
||||||
|
|
||||||
override val r: Matrix<Double> by lazy { EjmlMatrix(SimpleMatrix(qr.getR(null, false))) + UFeature }
|
override val r: Matrix<Double> by lazy { EjmlDoubleMatrix(qr.getR(null, false)) + UFeature }
|
||||||
}
|
}
|
||||||
|
|
||||||
CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<Double> {
|
CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<Double> {
|
||||||
override val l: Matrix<Double> by lazy {
|
override val l: Matrix<Double> by lazy {
|
||||||
val cholesky =
|
val cholesky =
|
||||||
DecompositionFactory_DDRM.chol(structure.rowNum, true).apply { decompose(origin.ddrm.copy()) }
|
DecompositionFactory_DDRM.chol(structure.rowNum, true).apply { decompose(origin.copy()) }
|
||||||
|
|
||||||
EjmlMatrix(SimpleMatrix(cholesky.getT(null))) + LFeature
|
EjmlDoubleMatrix(cholesky.getT(null)) + LFeature
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LupDecompositionFeature::class -> object : LupDecompositionFeature<Double> {
|
LupDecompositionFeature::class -> object : LupDecompositionFeature<Double> {
|
||||||
private val lup by lazy {
|
private val lup by lazy {
|
||||||
DecompositionFactory_DDRM.lu(origin.numRows(), origin.numCols())
|
DecompositionFactory_DDRM.lu(origin.numRows, origin.numCols).apply { decompose(origin.copy()) }
|
||||||
.apply { decompose(origin.ddrm.copy()) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override val l: Matrix<Double> by lazy {
|
override val l: Matrix<Double> by lazy {
|
||||||
EjmlMatrix(SimpleMatrix(lup.getLower(null))) + LFeature
|
EjmlDoubleMatrix(lup.getLower(null)) + LFeature
|
||||||
}
|
}
|
||||||
|
|
||||||
override val u: Matrix<Double> by lazy {
|
override val u: Matrix<Double> by lazy {
|
||||||
EjmlMatrix(SimpleMatrix(lup.getUpper(null))) + UFeature
|
EjmlDoubleMatrix(lup.getUpper(null)) + UFeature
|
||||||
}
|
}
|
||||||
|
|
||||||
override val p: Matrix<Double> by lazy { EjmlMatrix(SimpleMatrix(lup.getRowPivot(null))) }
|
override val p: Matrix<Double> by lazy { EjmlDoubleMatrix(lup.getRowPivot(null)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
}?.let(type::cast)
|
}?.let(type::cast)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*.
|
||||||
|
*
|
||||||
|
* @param a the base matrix.
|
||||||
|
* @param b n by p matrix.
|
||||||
|
* @return the solution for 'x' that is n by p.
|
||||||
|
*/
|
||||||
|
public fun solve(a: Matrix<Double>, b: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> {
|
||||||
|
val res = DMatrixRMaj(1, 1)
|
||||||
|
CommonOps_DDRM.solve(DMatrixRMaj(a.toEjml().origin), DMatrixRMaj(b.toEjml().origin), res)
|
||||||
|
return EjmlDoubleMatrix(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*.
|
||||||
|
*
|
||||||
|
* @param a the base matrix.
|
||||||
|
* @param b n by p vector.
|
||||||
|
* @return the solution for 'x' that is n by p.
|
||||||
|
*/
|
||||||
|
public fun solve(a: Matrix<Double>, b: Point<Double>): EjmlDoubleVector<DMatrixRMaj> {
|
||||||
|
val res = DMatrixRMaj(1, 1)
|
||||||
|
CommonOps_DDRM.solve(DMatrixRMaj(a.toEjml().origin), DMatrixRMaj(b.toEjml().origin), res)
|
||||||
|
return EjmlDoubleVector(res)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*.
|
|
||||||
*
|
|
||||||
* @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 EjmlLinearSpace.solve(a: Matrix<Double>, b: Matrix<Double>): EjmlMatrix =
|
|
||||||
EjmlMatrix(a.toEjml().origin.solve(b.toEjml().origin))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*.
|
|
||||||
*
|
|
||||||
* @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 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()
|
|
@ -5,18 +5,28 @@
|
|||||||
|
|
||||||
package space.kscience.kmath.ejml
|
package space.kscience.kmath.ejml
|
||||||
|
|
||||||
import org.ejml.simple.SimpleMatrix
|
import org.ejml.data.DMatrix
|
||||||
import space.kscience.kmath.linear.Matrix
|
import org.ejml.data.Matrix
|
||||||
|
import space.kscience.kmath.nd.Structure2D
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The matrix implementation over EJML [SimpleMatrix].
|
* [space.kscience.kmath.linear.Matrix] implementation based on EJML [Matrix].
|
||||||
*
|
*
|
||||||
* @property origin the underlying [SimpleMatrix].
|
* @param T the type of elements contained in the buffer.
|
||||||
|
* @param M the type of EJML matrix.
|
||||||
|
* @property origin The underlying EJML matrix.
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
public class EjmlMatrix(public val origin: SimpleMatrix) : Matrix<Double> {
|
public abstract class EjmlMatrix<T, out M : Matrix>(public open val origin: M) : Structure2D<T> {
|
||||||
public override val rowNum: Int get() = origin.numRows()
|
public override val rowNum: Int get() = origin.numRows
|
||||||
public override val colNum: Int get() = origin.numCols()
|
public override val colNum: Int get() = origin.numCols
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [EjmlMatrix] specialization for [Double].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
|
*/
|
||||||
|
public class EjmlDoubleMatrix<out M : DMatrix>(public override val origin: M) : EjmlMatrix<Double, M>(origin) {
|
||||||
public 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]
|
||||||
}
|
}
|
||||||
|
@ -5,35 +5,41 @@
|
|||||||
|
|
||||||
package space.kscience.kmath.ejml
|
package space.kscience.kmath.ejml
|
||||||
|
|
||||||
import org.ejml.simple.SimpleMatrix
|
import org.ejml.data.DMatrixD1
|
||||||
|
import org.ejml.data.Matrix
|
||||||
import space.kscience.kmath.linear.Point
|
import space.kscience.kmath.linear.Point
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents point over EJML [SimpleMatrix].
|
* [Point] implementation based on EJML [Matrix].
|
||||||
*
|
*
|
||||||
* @property origin the underlying [SimpleMatrix].
|
* @param T the type of elements contained in the buffer.
|
||||||
|
* @param M the type of EJML matrix.
|
||||||
|
* @property origin The underlying matrix.
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
public class EjmlVector internal constructor(public val origin: SimpleMatrix) : Point<Double> {
|
public abstract class EjmlVector<out T, out M : Matrix>(public open val origin: M) : Point<T> {
|
||||||
public override val size: Int
|
public override val size: Int
|
||||||
get() = origin.numRows()
|
get() = origin.numRows
|
||||||
|
|
||||||
init {
|
public override operator fun iterator(): Iterator<T> = object : Iterator<T> {
|
||||||
require(origin.numCols() == 1) { "Only single column matrices are allowed" }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override operator fun get(index: Int): Double = origin[index]
|
|
||||||
|
|
||||||
public override operator fun iterator(): Iterator<Double> = object : Iterator<Double> {
|
|
||||||
private var cursor: Int = 0
|
private var cursor: Int = 0
|
||||||
|
|
||||||
override fun next(): Double {
|
override fun next(): T {
|
||||||
cursor += 1
|
cursor += 1
|
||||||
return origin[cursor - 1]
|
return this@EjmlVector[cursor - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hasNext(): Boolean = cursor < origin.numCols() * origin.numRows()
|
override fun hasNext(): Boolean = cursor < origin.numCols * origin.numRows
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun toString(): String = "EjmlVector(origin=$origin)"
|
public override fun toString(): String = "EjmlVector(origin=$origin)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [EjmlVector] specialization for [Double].
|
||||||
|
*
|
||||||
|
* @author Iaroslav Postovalov
|
||||||
|
*/
|
||||||
|
public class EjmlDoubleVector<out M : DMatrixD1>(public override val origin: M) : EjmlVector<Double, M>(origin) {
|
||||||
|
public override operator fun get(index: Int): Double = origin[index]
|
||||||
|
}
|
||||||
|
@ -5,12 +5,15 @@
|
|||||||
|
|
||||||
package space.kscience.kmath.ejml
|
package space.kscience.kmath.ejml
|
||||||
|
|
||||||
|
import org.ejml.data.DMatrixRMaj
|
||||||
|
import org.ejml.dense.row.CommonOps_DDRM
|
||||||
|
import org.ejml.dense.row.RandomMatrices_DDRM
|
||||||
import org.ejml.dense.row.factory.DecompositionFactory_DDRM
|
import org.ejml.dense.row.factory.DecompositionFactory_DDRM
|
||||||
import org.ejml.simple.SimpleMatrix
|
import space.kscience.kmath.linear.DeterminantFeature
|
||||||
import space.kscience.kmath.linear.*
|
import space.kscience.kmath.linear.LupDecompositionFeature
|
||||||
|
import space.kscience.kmath.linear.getFeature
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.nd.StructureND
|
import space.kscience.kmath.nd.StructureND
|
||||||
import space.kscience.kmath.nd.getFeature
|
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
import kotlin.random.asJavaRandom
|
import kotlin.random.asJavaRandom
|
||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
@ -22,65 +25,59 @@ fun <T : Any> assertMatrixEquals(expected: StructureND<T>, actual: StructureND<T
|
|||||||
internal class EjmlMatrixTest {
|
internal class EjmlMatrixTest {
|
||||||
private val random = Random(0)
|
private val random = Random(0)
|
||||||
|
|
||||||
private val randomMatrix: SimpleMatrix
|
private val randomMatrix: DMatrixRMaj
|
||||||
get() {
|
get() {
|
||||||
val s = random.nextInt(2, 100)
|
val s = random.nextInt(2, 100)
|
||||||
return SimpleMatrix.random_DDRM(s, s, 0.0, 10.0, random.asJavaRandom())
|
val d = DMatrixRMaj(s, s)
|
||||||
|
RandomMatrices_DDRM.fillUniform(d, random.asJavaRandom())
|
||||||
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun rowNum() {
|
fun rowNum() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
assertEquals(m.numRows(), EjmlMatrix(m).rowNum)
|
assertEquals(m.numRows, EjmlDoubleMatrix(m).rowNum)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun colNum() {
|
fun colNum() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
assertEquals(m.numCols(), EjmlMatrix(m).rowNum)
|
assertEquals(m.numCols, EjmlDoubleMatrix(m).rowNum)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun shape() {
|
fun shape() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
val w = EjmlMatrix(m)
|
val w = EjmlDoubleMatrix(m)
|
||||||
assertEquals(listOf(m.numRows(), m.numCols()), w.shape.toList())
|
assertContentEquals(intArrayOf(m.numRows, m.numCols), w.shape)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
@Test
|
@Test
|
||||||
fun features() {
|
fun features() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
val w = EjmlMatrix(m)
|
val w = EjmlDoubleMatrix(m)
|
||||||
val det: DeterminantFeature<Double> = EjmlLinearSpace.getFeature(w) ?: fail()
|
val det: DeterminantFeature<Double> = EjmlLinearSpaceDDRM.getFeature(w) ?: fail()
|
||||||
assertEquals(m.determinant(), det.determinant)
|
assertEquals(CommonOps_DDRM.det(m), det.determinant)
|
||||||
val lup: LupDecompositionFeature<Double> = EjmlLinearSpace.getFeature(w) ?: fail()
|
val lup: LupDecompositionFeature<Double> = EjmlLinearSpaceDDRM.getFeature(w) ?: fail()
|
||||||
|
|
||||||
val ludecompositionF64 = DecompositionFactory_DDRM.lu(m.numRows(), m.numCols())
|
val ludecompositionF64 = DecompositionFactory_DDRM.lu(m.numRows, m.numCols)
|
||||||
.also { it.decompose(m.ddrm.copy()) }
|
.also { it.decompose(m.copy()) }
|
||||||
|
|
||||||
assertMatrixEquals(EjmlMatrix(SimpleMatrix(ludecompositionF64.getLower(null))), lup.l)
|
assertMatrixEquals(EjmlDoubleMatrix(ludecompositionF64.getLower(null)), lup.l)
|
||||||
assertMatrixEquals(EjmlMatrix(SimpleMatrix(ludecompositionF64.getUpper(null))), lup.u)
|
assertMatrixEquals(EjmlDoubleMatrix(ludecompositionF64.getUpper(null)), lup.u)
|
||||||
assertMatrixEquals(EjmlMatrix(SimpleMatrix(ludecompositionF64.getRowPivot(null))), lup.p)
|
assertMatrixEquals(EjmlDoubleMatrix(ludecompositionF64.getRowPivot(null)), lup.p)
|
||||||
}
|
|
||||||
|
|
||||||
private object SomeFeature : MatrixFeature {}
|
|
||||||
|
|
||||||
@OptIn(UnstableKMathAPI::class)
|
|
||||||
@Test
|
|
||||||
fun suggestFeature() {
|
|
||||||
assertNotNull((EjmlMatrix(randomMatrix) + SomeFeature).getFeature<SomeFeature>())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun get() {
|
fun get() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
assertEquals(m[0, 0], EjmlMatrix(m)[0, 0])
|
assertEquals(m[0, 0], EjmlDoubleMatrix(m)[0, 0])
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun origin() {
|
fun origin() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
assertSame(m, EjmlMatrix(m).origin)
|
assertSame(m, EjmlDoubleMatrix(m).origin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
|
|
||||||
package space.kscience.kmath.ejml
|
package space.kscience.kmath.ejml
|
||||||
|
|
||||||
import org.ejml.simple.SimpleMatrix
|
import org.ejml.data.DMatrixRMaj
|
||||||
|
import org.ejml.dense.row.RandomMatrices_DDRM
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
import kotlin.random.asJavaRandom
|
import kotlin.random.asJavaRandom
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
@ -15,30 +16,34 @@ import kotlin.test.assertSame
|
|||||||
internal class EjmlVectorTest {
|
internal class EjmlVectorTest {
|
||||||
private val random = Random(0)
|
private val random = Random(0)
|
||||||
|
|
||||||
private val randomMatrix: SimpleMatrix
|
private val randomMatrix: DMatrixRMaj
|
||||||
get() = SimpleMatrix.random_DDRM(random.nextInt(2, 100), 1, 0.0, 10.0, random.asJavaRandom())
|
get() {
|
||||||
|
val d = DMatrixRMaj(random.nextInt(2, 100), 1)
|
||||||
|
RandomMatrices_DDRM.fillUniform(d, random.asJavaRandom())
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun size() {
|
fun size() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
val w = EjmlVector(m)
|
val w = EjmlDoubleVector(m)
|
||||||
assertEquals(m.numRows(), w.size)
|
assertEquals(m.numRows, w.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun get() {
|
fun get() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
val w = EjmlVector(m)
|
val w = EjmlDoubleVector(m)
|
||||||
assertEquals(m[0, 0], w[0])
|
assertEquals(m[0, 0], w[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun iterator() {
|
fun iterator() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
val w = EjmlVector(m)
|
val w = EjmlDoubleVector(m)
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
m.iterator(true, 0, 0, m.numRows() - 1, 0).asSequence().toList(),
|
m.iterator(true, 0, 0, m.numRows - 1, 0).asSequence().toList(),
|
||||||
w.iterator().asSequence().toList()
|
w.iterator().asSequence().toList()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -46,7 +51,7 @@ internal class EjmlVectorTest {
|
|||||||
@Test
|
@Test
|
||||||
fun origin() {
|
fun origin() {
|
||||||
val m = randomMatrix
|
val m = randomMatrix
|
||||||
val w = EjmlVector(m)
|
val w = EjmlDoubleVector(m)
|
||||||
assertSame(m, w.origin)
|
assertSame(m, w.origin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@ The Maven coordinates of this project are `space.kscience:kmath-for-real:0.3.0-d
|
|||||||
```gradle
|
```gradle
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://repo.kotlin.link' }
|
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
|
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,7 +27,6 @@ dependencies {
|
|||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
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/kotlin/kotlin-eap") // include for builds based on kotlin-eap
|
||||||
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -17,7 +17,6 @@ The Maven coordinates of this project are `space.kscience:kmath-functions:0.3.0-
|
|||||||
```gradle
|
```gradle
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://repo.kotlin.link' }
|
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
|
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,7 +29,6 @@ dependencies {
|
|||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
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/kotlin/kotlin-eap") // include for builds based on kotlin-eap
|
||||||
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -4,8 +4,8 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("com.github.breandan:kaliningraph:0.1.4")
|
api("com.github.breandan:kaliningraph:0.1.4")
|
||||||
implementation("com.github.breandan:kotlingrad:0.4.0")
|
api("com.github.breandan:kotlingrad:0.4.5")
|
||||||
api(project(":kmath-ast"))
|
api(project(":kmath-ast"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,7 @@ The Maven coordinates of this project are `space.kscience:kmath-nd4j:0.3.0-dev-7
|
|||||||
```gradle
|
```gradle
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://repo.kotlin.link' }
|
maven { url 'https://repo.kotlin.link' }
|
||||||
maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
|
mavenCentral()
|
||||||
maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -27,8 +26,7 @@ dependencies {
|
|||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap
|
mavenCentral()
|
||||||
maven("https://dl.bintray.com/hotkeytlt/maven") // required for a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -7,7 +7,7 @@ description = "Binding for https://github.com/JetBrains-Research/viktor"
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(project(":kmath-core"))
|
api(project(":kmath-core"))
|
||||||
api("org.jetbrains.bio:viktor:1.0.1")
|
api("org.jetbrains.bio:viktor:1.1.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
readme {
|
readme {
|
||||||
|
Loading…
Reference in New Issue
Block a user