diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
new file mode 100644
index 000000000..82b0fb303
--- /dev/null
+++ b/.github/workflows/pages.yml
@@ -0,0 +1,40 @@
+name: Dokka publication
+
+on:
+ push:
+ branches:
+ - master
+
+jobs:
+ build:
+ runs-on: ubuntu-20.04
+ steps:
+ - name: Checkout the repo
+ uses: actions/checkout@v2
+ - name: Set up JDK 11
+ uses: actions/setup-java@v1
+ with:
+ java-version: 11
+ - name: Cache gradle
+ uses: actions/cache@v2
+ with:
+ path: ~/.gradle/caches
+ key: ubuntu-20.04-gradle-${{ hashFiles('*.gradle.kts') }}
+ restore-keys: |
+ ubuntu-20.04-gradle-
+ - name: Cache konan
+ uses: actions/cache@v2
+ with:
+ path: ~/.konan
+ key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
+ restore-keys: |
+ ${{ runner.os }}-gradle-
+ - name: Build
+ run: |
+ ./gradlew dokkaHtmlMultiModule --no-daemon --no-parallel --stacktrace
+ mv build/dokka/htmlMultiModule/-modules.html build/dokka/htmlMultiModule/index.html
+ - name: Deploy to GitHub Pages
+ uses: JamesIves/github-pages-deploy-action@4.1.0
+ with:
+ branch: gh-pages
+ folder: build/dokka/htmlMultiModule
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 42fa6d3b6..ca374574e 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -12,7 +12,7 @@ jobs:
name: publish
strategy:
matrix:
- os: [macOS-latest, windows-latest]
+ os: [ macOS-latest, windows-latest ]
runs-on: ${{matrix.os}}
steps:
- name: Checkout the repo
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 05c956de3..8b4dddf81 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,17 +4,22 @@
### Added
- ScaleOperations interface
- Field extends ScaleOperations
+- Basic integration API
### Changed
- Exponential operations merged with hyperbolic functions
- Space is replaced by Group. Space is reserved for vector spaces.
- VectorSpace is now a vector space
+- Buffer factories for primitives moved to MutableBuffer.Companion
+- NDStructure and NDAlgebra to StructureND and AlgebraND respectively
+- Real -> Double
### Deprecated
### Removed
- Nearest in Domain. To be implemented in geometry package.
- Number multiplication and division in main Algebra chain
+- `contentEquals` from Buffer. It moved to the companion.
### Fixed
@@ -72,6 +77,7 @@
- `toGrid` method.
- Public visibility of `BufferAccessor2D`
- `Real` class
+- StructureND identity and equals
### Fixed
- `symbol` method in `MstExtendedField` (https://github.com/mipt-npm/kmath/pull/140)
diff --git a/README.md b/README.md
index e9cf64ea0..cc9439d27 100644
--- a/README.md
+++ b/README.md
@@ -3,9 +3,7 @@
![Gradle build](https://github.com/mipt-npm/kmath/workflows/Gradle%20build/badge.svg)
-Bintray: [ ![Download](https://api.bintray.com/packages/mipt-npm/kscience/kmath-core/images/download.svg) ](https://bintray.com/mipt-npm/kscience/kmath-core/_latestVersion)
-
-Bintray-dev: [ ![Download](https://api.bintray.com/packages/mipt-npm/dev/kmath-core/images/download.svg) ](https://bintray.com/mipt-npm/dev/kmath-core/_latestVersion)
+[![Maven Central](https://img.shields.io/maven-central/v/space.kscience/kmath-core.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22space.kscience%22%20AND%20a:%22kmath-core%22)
# KMath
@@ -89,12 +87,12 @@ KMath is a modular library. Different modules provide different features with di
> **Maturity**: PROTOTYPE
>
> **Features:**
-> - [expression-language](kmath-ast/src/jvmMain/kotlin/kscience/kmath/ast/parser.kt) : Expression language and its parser
-> - [mst](kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MST.kt) : MST (Mathematical Syntax Tree) as expression language's syntax intermediate representation
-> - [mst-building](kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt) : MST building algebraic structure
-> - [mst-interpreter](kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MST.kt) : MST interpreter
-> - [mst-jvm-codegen](kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode compiler
-> - [mst-js-codegen](kmath-ast/src/jsMain/kotlin/kscience/kmath/estree/estree.kt) : Dynamic MST to JS compiler
+> - [expression-language](kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser
+> - [mst](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/MST.kt) : MST (Mathematical Syntax Tree) as expression language's syntax intermediate representation
+> - [mst-building](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/MstAlgebra.kt) : MST building algebraic structure
+> - [mst-interpreter](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/MST.kt) : MST interpreter
+> - [mst-jvm-codegen](kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode compiler
+> - [mst-js-codegen](kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt) : Dynamic MST to JS compiler
@@ -110,8 +108,8 @@ KMath is a modular library. Different modules provide different features with di
> **Maturity**: PROTOTYPE
>
> **Features:**
-> - [complex](kmath-complex/src/commonMain/kotlin/kscience/kmath/complex/Complex.kt) : Complex Numbers
-> - [quaternion](kmath-complex/src/commonMain/kotlin/kscience/kmath/complex/Quaternion.kt) : Quaternions
+> - [complex](kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt) : Complex Numbers
+> - [quaternion](kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt) : Quaternions
@@ -121,15 +119,15 @@ KMath is a modular library. Different modules provide different features with di
> **Maturity**: DEVELOPMENT
>
> **Features:**
-> - [algebras](kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt) : Algebraic structures like rings, spaces and fields.
-> - [nd](kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDStructure.kt) : Many-dimensional structures and operations on them.
-> - [linear](kmath-core/src/commonMain/kotlin/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/kscience/kmath/structures/Buffers.kt) : One-dimensional structure
-> - [expressions](kmath-core/src/commonMain/kotlin/kscience/kmath/expressions) : By writing a single mathematical expression once, users will be able to apply different types of
+> - [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/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/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/kscience/kmath/domains) : Domains
-> - [autodif](kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/SimpleAutoDiff.kt) : Automatic differentiation
+> - [domains](kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains) : Domains
+> - [autodif](kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt) : Automatic differentiation
@@ -159,9 +157,9 @@ One can still use generic algebras though.
> **Maturity**: EXPERIMENTAL
>
> **Features:**
-> - [RealVector](kmath-for-real/src/commonMain/kotlin/kscience/kmath/real/RealVector.kt) : Numpy-like operations for Buffers/Points
-> - [RealMatrix](kmath-for-real/src/commonMain/kotlin/kscience/kmath/real/RealMatrix.kt) : Numpy-like operations for 2d real structures
-> - [grids](kmath-for-real/src/commonMain/kotlin/kscience/kmath/structures/grids.kt) : Uniform grid generators
+> - [DoubleVector](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt) : Numpy-like operations for Buffers/Points
+> - [DoubleMatrix](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleMatrix.kt) : Numpy-like operations for 2d real structures
+> - [grids](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/structures/grids.kt) : Uniform grid generators
@@ -171,10 +169,10 @@ One can still use generic algebras though.
> **Maturity**: PROTOTYPE
>
> **Features:**
-> - [piecewise](kmath-functions/Piecewise functions.) : src/commonMain/kotlin/kscience/kmath/functions/Piecewise.kt
-> - [polynomials](kmath-functions/Polynomial functions.) : src/commonMain/kotlin/kscience/kmath/functions/Polynomial.kt
-> - [linear interpolation](kmath-functions/Linear XY interpolator.) : src/commonMain/kotlin/kscience/kmath/interpolation/LinearInterpolator.kt
-> - [spline interpolation](kmath-functions/Cubic spline XY interpolator.) : src/commonMain/kotlin/kscience/kmath/interpolation/SplineInterpolator.kt
+> - [piecewise](kmath-functions/Piecewise functions.) : src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt
+> - [polynomials](kmath-functions/Polynomial functions.) : src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt
+> - [linear interpolation](kmath-functions/Linear XY interpolator.) : src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt
+> - [spline interpolation](kmath-functions/Cubic spline XY interpolator.) : src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt
@@ -208,9 +206,9 @@ One can still use generic algebras though.
> **Maturity**: EXPERIMENTAL
>
> **Features:**
-> - [nd4jarraystructure](kmath-nd4j/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt) : NDStructure wrapper for INDArray
-> - [nd4jarrayrings](kmath-nd4j/src/commonMain/kotlin/kscience/kmath/structures/NDStructure.kt) : Rings over Nd4jArrayStructure of Int and Long
-> - [nd4jarrayfields](kmath-nd4j/src/commonMain/kotlin/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
@@ -256,8 +254,8 @@ repositories {
}
dependencies {
- api("kscience.kmath:kmath-core:() -> kotlin.Any")
- // api("kscience.kmath:kmath-core-jvm:() -> kotlin.Any") for jvm-specific version
+ api("space.kscience:kmath-core:0.3.0-dev-3")
+ // api("kscience.kmath:kmath-core-jvm:0.3.0-dev-3") for jvm-specific version
}
```
diff --git a/build.gradle.kts b/build.gradle.kts
index 113107f69..5f1a8b88a 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -20,7 +20,7 @@ allprojects {
}
group = "space.kscience"
- version = "0.3.0"
+ version = "0.3.0-dev-3"
}
subprojects {
diff --git a/docs/algebra.md b/docs/algebra.md
index 6bfcde043..84693bb81 100644
--- a/docs/algebra.md
+++ b/docs/algebra.md
@@ -31,7 +31,7 @@ multiplication;
- [Ring](http://mathworld.wolfram.com/Ring.html) adds multiplication and its neutral element (i.e. 1);
- [Field](http://mathworld.wolfram.com/Field.html) adds division operation.
-A typical implementation of `Field` is the `RealField` which works on doubles, and `VectorSpace` for `Space`.
+A typical implementation of `Field` is the `DoubleField` which works on doubles, and `VectorSpace` for `Space`.
In some cases algebra context can hold additional operations like `exp` or `sin`, and then it inherits appropriate
interface. Also, contexts may have operations, which produce elements outside of the context. For example, `Matrix.dot`
diff --git a/docs/images/KM.svg b/docs/images/KM.svg
index 50126cbc5..83af21f35 100644
--- a/docs/images/KM.svg
+++ b/docs/images/KM.svg
@@ -13,27 +13,30 @@
version="1.1">image/svg+xml
+
+
+ image/svg+xml
+
+ image/svg+xml
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
->// Uncomment if repo.kotlin.link is unavailable
->// maven { url 'https://dl.bintray.com/mipt-npm/kscience' }
->// maven { url 'https://dl.bintray.com/mipt-npm/dev' }
> }
>
> dependencies {
@@ -29,9 +26,6 @@
> 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
->// Uncomment if repo.kotlin.link is unavailable
->// maven("https://dl.bintray.com/mipt-npm/kscience")
->// maven("https://dl.bintray.com/mipt-npm/dev")
> }
>
> dependencies {
diff --git a/docs/templates/README-TEMPLATE.md b/docs/templates/README-TEMPLATE.md
index 10bc7aab1..4366c8fcd 100644
--- a/docs/templates/README-TEMPLATE.md
+++ b/docs/templates/README-TEMPLATE.md
@@ -3,9 +3,7 @@
![Gradle build](https://github.com/mipt-npm/kmath/workflows/Gradle%20build/badge.svg)
-Bintray: [ ![Download](https://api.bintray.com/packages/mipt-npm/kscience/kmath-core/images/download.svg) ](https://bintray.com/mipt-npm/kscience/kmath-core/_latestVersion)
-
-Bintray-dev: [ ![Download](https://api.bintray.com/packages/mipt-npm/dev/kmath-core/images/download.svg) ](https://bintray.com/mipt-npm/dev/kmath-core/_latestVersion)
+[![Maven Central](https://img.shields.io/maven-central/v/space.kscience/kmath-core.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22space.kscience%22%20AND%20a:%22kmath-core%22)
# KMath
@@ -106,7 +104,7 @@ repositories {
}
dependencies {
- api("kscience.kmath:kmath-core:$version")
+ api("${group}:kmath-core:$version")
// api("kscience.kmath:kmath-core-jvm:$version") for jvm-specific version
}
```
diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts
index 77152dc0a..5dd40b609 100644
--- a/examples/build.gradle.kts
+++ b/examples/build.gradle.kts
@@ -92,6 +92,14 @@ benchmark {
iterationTimeUnit = "ms" // time unity for iterationTime, default is seconds
include("ExpressionsInterpretersBenchmark")
}
+
+ configurations.register("matrixInverse") {
+ warmups = 1 // number of warmup iterations
+ iterations = 3 // number of iterations
+ iterationTime = 500 // time in seconds per iteration
+ iterationTimeUnit = "ms" // time unity for iterationTime, default is seconds
+ include("MatrixInverseBenchmark")
+ }
}
kotlin.sourceSets.all {
@@ -105,6 +113,6 @@ tasks.withType {
kotlinOptions.jvmTarget = "11"
}
-readme{
+readme {
maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL
}
diff --git a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt
index 1c3bbab75..1db1d77dc 100644
--- a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt
+++ b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt
@@ -5,14 +5,14 @@ import kotlinx.benchmark.Scope
import kotlinx.benchmark.State
import space.kscience.kmath.complex.Complex
import space.kscience.kmath.complex.complex
+import space.kscience.kmath.structures.DoubleBuffer
import space.kscience.kmath.structures.MutableBuffer
-import space.kscience.kmath.structures.RealBuffer
@State(Scope.Benchmark)
internal class BufferBenchmark {
@Benchmark
- fun genericRealBufferReadWrite() {
- val buffer = RealBuffer(size) { it.toDouble() }
+ fun genericDoubleBufferReadWrite() {
+ val buffer = DoubleBuffer(size) { it.toDouble() }
(0 until size).forEach {
buffer[it]
diff --git a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt
index 93b5c5549..6a2126dc1 100644
--- a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt
+++ b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt
@@ -4,14 +4,11 @@ import kotlinx.benchmark.Benchmark
import kotlinx.benchmark.Blackhole
import kotlinx.benchmark.Scope
import kotlinx.benchmark.State
-import space.kscience.kmath.commons.linear.CMMatrixContext
-import space.kscience.kmath.ejml.EjmlMatrixContext
-import space.kscience.kmath.linear.BufferMatrixContext
-import space.kscience.kmath.linear.Matrix
-import space.kscience.kmath.linear.RealMatrixContext
-import space.kscience.kmath.operations.RealField
-import space.kscience.kmath.operations.invoke
-import space.kscience.kmath.structures.Buffer
+import space.kscience.kmath.commons.linear.CMLinearSpace
+import space.kscience.kmath.ejml.EjmlLinearSpace
+import space.kscience.kmath.linear.LinearSpace
+import space.kscience.kmath.linear.invoke
+import space.kscience.kmath.operations.DoubleField
import kotlin.random.Random
@State(Scope.Benchmark)
@@ -21,47 +18,47 @@ internal class DotBenchmark {
const val dim = 1000
//creating invertible matrix
- val matrix1 = Matrix.real(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
- val matrix2 = Matrix.real(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
+ val matrix1 = LinearSpace.real.buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
+ val matrix2 = LinearSpace.real.buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
- val cmMatrix1 = CMMatrixContext { matrix1.toCM() }
- val cmMatrix2 = CMMatrixContext { matrix2.toCM() }
+ val cmMatrix1 = CMLinearSpace { matrix1.toCM() }
+ val cmMatrix2 = CMLinearSpace { matrix2.toCM() }
- val ejmlMatrix1 = EjmlMatrixContext { matrix1.toEjml() }
- val ejmlMatrix2 = EjmlMatrixContext { matrix2.toEjml() }
+ val ejmlMatrix1 = EjmlLinearSpace { matrix1.toEjml() }
+ val ejmlMatrix2 = EjmlLinearSpace { matrix2.toEjml() }
}
@Benchmark
fun cmDot(blackhole: Blackhole) {
- CMMatrixContext {
+ CMLinearSpace.run {
blackhole.consume(cmMatrix1 dot cmMatrix2)
}
}
@Benchmark
fun ejmlDot(blackhole: Blackhole) {
- EjmlMatrixContext {
+ EjmlLinearSpace {
blackhole.consume(ejmlMatrix1 dot ejmlMatrix2)
}
}
@Benchmark
fun ejmlDotWithConversion(blackhole: Blackhole) {
- EjmlMatrixContext {
+ EjmlLinearSpace {
blackhole.consume(matrix1 dot matrix2)
}
}
@Benchmark
fun bufferedDot(blackhole: Blackhole) {
- BufferMatrixContext(RealField, Buffer.Companion::real).invoke {
+ LinearSpace.auto(DoubleField).invoke {
blackhole.consume(matrix1 dot matrix2)
}
}
@Benchmark
fun realDot(blackhole: Blackhole) {
- RealMatrixContext {
+ LinearSpace.real {
blackhole.consume(matrix1 dot matrix2)
}
}
diff --git a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt
index 9c150f074..0899241f9 100644
--- a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt
+++ b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt
@@ -10,7 +10,7 @@ import space.kscience.kmath.expressions.Expression
import space.kscience.kmath.expressions.expressionInField
import space.kscience.kmath.expressions.invoke
import space.kscience.kmath.expressions.symbol
-import space.kscience.kmath.operations.RealField
+import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.bindSymbol
import kotlin.random.Random
@@ -30,7 +30,7 @@ internal class ExpressionsInterpretersBenchmark {
fun mstExpression(blackhole: Blackhole) {
val expr = algebra.mstInField {
val x = bindSymbol(x)
- x * 2.0 + 2.0 / x - 16.0
+ x * 2.0 + number(2.0) / x - 16.0
}
invokeAndSum(expr, blackhole)
@@ -40,7 +40,7 @@ internal class ExpressionsInterpretersBenchmark {
fun asmExpression(blackhole: Blackhole) {
val expr = algebra.mstInField {
val x = bindSymbol(x)
- x * 2.0 + 2.0 / x - 16.0
+ x * 2.0 + number(2.0) / x - 16.0
}.compile()
invokeAndSum(expr, blackhole)
@@ -68,7 +68,7 @@ internal class ExpressionsInterpretersBenchmark {
}
private companion object {
- private val algebra = RealField
+ private val algebra = DoubleField
private val x by symbol
}
}
diff --git a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/LinearAlgebraBenchmark.kt b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt
similarity index 54%
rename from examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/LinearAlgebraBenchmark.kt
rename to examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt
index 30cb6c0b9..7aa8ac975 100644
--- a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/LinearAlgebraBenchmark.kt
+++ b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt
@@ -4,44 +4,44 @@ import kotlinx.benchmark.Benchmark
import kotlinx.benchmark.Blackhole
import kotlinx.benchmark.Scope
import kotlinx.benchmark.State
-import space.kscience.kmath.commons.linear.CMMatrixContext
-import space.kscience.kmath.commons.linear.CMMatrixContext.dot
+import space.kscience.kmath.commons.linear.CMLinearSpace
import space.kscience.kmath.commons.linear.inverse
-import space.kscience.kmath.ejml.EjmlMatrixContext
+import space.kscience.kmath.ejml.EjmlLinearSpace
import space.kscience.kmath.ejml.inverse
-import space.kscience.kmath.linear.Matrix
-import space.kscience.kmath.linear.MatrixContext
+import space.kscience.kmath.linear.LinearSpace
import space.kscience.kmath.linear.inverseWithLup
-import space.kscience.kmath.linear.real
+import space.kscience.kmath.linear.invoke
import kotlin.random.Random
@State(Scope.Benchmark)
-internal class LinearAlgebraBenchmark {
+internal class MatrixInverseBenchmark {
companion object {
val random = Random(1224)
const val dim = 100
+ private val space = LinearSpace.real
+
//creating invertible matrix
- val u = Matrix.real(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
- val l = Matrix.real(dim, dim) { i, j -> if (i >= j) random.nextDouble() else 0.0 }
- val matrix = l dot u
+ 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 }
+ val matrix = space { l dot u }
}
@Benchmark
fun kmathLupInversion(blackhole: Blackhole) {
- blackhole.consume(MatrixContext.real.inverseWithLup(matrix))
+ blackhole.consume(LinearSpace.real.inverseWithLup(matrix))
}
@Benchmark
fun cmLUPInversion(blackhole: Blackhole) {
- with(CMMatrixContext) {
+ with(CMLinearSpace) {
blackhole.consume(inverse(matrix))
}
}
@Benchmark
fun ejmlInverse(blackhole: Blackhole) {
- with(EjmlMatrixContext) {
+ with(EjmlLinearSpace) {
blackhole.consume(inverse(matrix))
}
}
diff --git a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt
index aeee0dafe..09c415d9a 100644
--- a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt
+++ b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt
@@ -5,7 +5,7 @@ import kotlinx.benchmark.Blackhole
import kotlinx.benchmark.Scope
import kotlinx.benchmark.State
import space.kscience.kmath.nd.*
-import space.kscience.kmath.operations.RealField
+import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.structures.Buffer
@State(Scope.Benchmark)
@@ -13,7 +13,7 @@ internal class NDFieldBenchmark {
@Benchmark
fun autoFieldAdd(blackhole: Blackhole) {
with(autoField) {
- var res: NDStructure = one
+ var res: StructureND = one
repeat(n) { res += one }
blackhole.consume(res)
}
@@ -22,7 +22,7 @@ internal class NDFieldBenchmark {
@Benchmark
fun specializedFieldAdd(blackhole: Blackhole) {
with(specializedField) {
- var res: NDStructure = one
+ var res: StructureND = one
repeat(n) { res += 1.0 }
blackhole.consume(res)
}
@@ -32,7 +32,7 @@ internal class NDFieldBenchmark {
@Benchmark
fun boxingFieldAdd(blackhole: Blackhole) {
with(genericField) {
- var res: NDStructure = one
+ var res: StructureND = one
repeat(n) { res += 1.0 }
blackhole.consume(res)
}
@@ -41,8 +41,8 @@ internal class NDFieldBenchmark {
private companion object {
private const val dim = 1000
private const val n = 100
- private val autoField = NDAlgebra.auto(RealField, dim, dim)
- private val specializedField = NDAlgebra.real(dim, dim)
- private val genericField = NDAlgebra.field(RealField, Buffer.Companion::boxing, dim, dim)
+ private val autoField = AlgebraND.auto(DoubleField, dim, dim)
+ private val specializedField = AlgebraND.real(dim, dim)
+ private val genericField = AlgebraND.field(DoubleField, Buffer.Companion::boxing, dim, dim)
}
}
diff --git a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt
index c511173a9..fd0188bd6 100644
--- a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt
+++ b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt
@@ -5,11 +5,11 @@ import kotlinx.benchmark.Blackhole
import kotlinx.benchmark.Scope
import kotlinx.benchmark.State
import org.jetbrains.bio.viktor.F64Array
-import space.kscience.kmath.nd.NDAlgebra
-import space.kscience.kmath.nd.NDStructure
+import space.kscience.kmath.nd.AlgebraND
+import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.auto
import space.kscience.kmath.nd.real
-import space.kscience.kmath.operations.RealField
+import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.viktor.ViktorNDField
@State(Scope.Benchmark)
@@ -17,7 +17,7 @@ internal class ViktorBenchmark {
@Benchmark
fun automaticFieldAddition(blackhole: Blackhole) {
with(autoField) {
- var res: NDStructure = one
+ var res: StructureND = one
repeat(n) { res += 1.0 }
blackhole.consume(res)
}
@@ -26,7 +26,7 @@ internal class ViktorBenchmark {
@Benchmark
fun realFieldAddition(blackhole: Blackhole) {
with(realField) {
- var res: NDStructure = one
+ var res: StructureND = one
repeat(n) { res += 1.0 }
blackhole.consume(res)
}
@@ -54,8 +54,8 @@ internal class ViktorBenchmark {
private const val n = 100
// automatically build context most suited for given type.
- private val autoField = NDAlgebra.auto(RealField, dim, dim)
- private val realField = NDAlgebra.real(dim, dim)
+ private val autoField = AlgebraND.auto(DoubleField, dim, dim)
+ private val realField = AlgebraND.real(dim, dim)
private val viktorField = ViktorNDField(dim, dim)
}
}
diff --git a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt
index c48c86af9..b6bd036ba 100644
--- a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt
+++ b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt
@@ -5,17 +5,17 @@ import kotlinx.benchmark.Blackhole
import kotlinx.benchmark.Scope
import kotlinx.benchmark.State
import org.jetbrains.bio.viktor.F64Array
-import space.kscience.kmath.nd.NDAlgebra
+import space.kscience.kmath.nd.AlgebraND
import space.kscience.kmath.nd.auto
import space.kscience.kmath.nd.real
-import space.kscience.kmath.operations.RealField
-import space.kscience.kmath.viktor.ViktorNDField
+import space.kscience.kmath.operations.DoubleField
+import space.kscience.kmath.viktor.ViktorFieldND
@State(Scope.Benchmark)
internal class ViktorLogBenchmark {
@Benchmark
fun realFieldLog(blackhole: Blackhole) {
- with(realField) {
+ with(realNdField) {
val fortyTwo = produce { 42.0 }
var res = one
repeat(n) { res = ln(fortyTwo) }
@@ -46,8 +46,8 @@ internal class ViktorLogBenchmark {
private const val n = 100
// automatically build context most suited for given type.
- private val autoField = NDAlgebra.auto(RealField, dim, dim)
- private val realField = NDAlgebra.real(dim, dim)
- private val viktorField = ViktorNDField(intArrayOf(dim, dim))
+ private val autoField = AlgebraND.auto(DoubleField, dim, dim)
+ private val realNdField = AlgebraND.real(dim, dim)
+ private val viktorField = ViktorFieldND(intArrayOf(dim, dim))
}
}
diff --git a/examples/src/main/kotlin/space/kscience/kmath/ast/expressions.kt b/examples/src/main/kotlin/space/kscience/kmath/ast/expressions.kt
index c342fc3ef..17c85eea5 100644
--- a/examples/src/main/kotlin/space/kscience/kmath/ast/expressions.kt
+++ b/examples/src/main/kotlin/space/kscience/kmath/ast/expressions.kt
@@ -1,10 +1,10 @@
package space.kscience.kmath.ast
import space.kscience.kmath.expressions.invoke
-import space.kscience.kmath.operations.RealField
+import space.kscience.kmath.operations.DoubleField
fun main() {
- val expr = RealField.mstInField {
+ val expr = DoubleField.mstInField {
val x = bindSymbol("x")
x * 2.0 + number(2.0) / x - 16.0
}
diff --git a/examples/src/main/kotlin/space/kscience/kmath/ast/kotlingradSupport.kt b/examples/src/main/kotlin/space/kscience/kmath/ast/kotlingradSupport.kt
index 16304a458..23c9d5b41 100644
--- a/examples/src/main/kotlin/space/kscience/kmath/ast/kotlingradSupport.kt
+++ b/examples/src/main/kotlin/space/kscience/kmath/ast/kotlingradSupport.kt
@@ -5,7 +5,7 @@ import space.kscience.kmath.expressions.derivative
import space.kscience.kmath.expressions.invoke
import space.kscience.kmath.expressions.symbol
import space.kscience.kmath.kotlingrad.differentiable
-import space.kscience.kmath.operations.RealField
+import space.kscience.kmath.operations.DoubleField
/**
* In this example, x^2-4*x-44 function is differentiated with Kotlin∇, and the autodiff result is compared with
@@ -14,11 +14,11 @@ import space.kscience.kmath.operations.RealField
fun main() {
val x by symbol
- val actualDerivative = MstExpression(RealField, "x^2-4*x-44".parseMath())
+ val actualDerivative = MstExpression(DoubleField, "x^2-4*x-44".parseMath())
.differentiable()
.derivative(x)
.compile()
- val expectedDerivative = MstExpression(RealField, "2*x-4".parseMath()).compile()
+ val expectedDerivative = MstExpression(DoubleField, "2*x-4".parseMath()).compile()
assert(actualDerivative("x" to 123.0) == expectedDerivative("x" to 123.0))
}
diff --git a/examples/src/main/kotlin/space/kscience/kmath/commons/fit/fitWithAutoDiff.kt b/examples/src/main/kotlin/space/kscience/kmath/commons/fit/fitWithAutoDiff.kt
index 63b819dc9..ef0c29a2d 100644
--- a/examples/src/main/kotlin/space/kscience/kmath/commons/fit/fitWithAutoDiff.kt
+++ b/examples/src/main/kotlin/space/kscience/kmath/commons/fit/fitWithAutoDiff.kt
@@ -8,7 +8,7 @@ import kscience.plotly.models.TraceValues
import space.kscience.kmath.commons.optimization.chiSquared
import space.kscience.kmath.commons.optimization.minimize
import space.kscience.kmath.expressions.symbol
-import space.kscience.kmath.real.RealVector
+import space.kscience.kmath.real.DoubleVector
import space.kscience.kmath.real.map
import space.kscience.kmath.real.step
import space.kscience.kmath.stat.*
@@ -26,7 +26,7 @@ private val c by symbol
/**
* Shortcut to use buffers in plotly
*/
-operator fun TraceValues.invoke(vector: RealVector) {
+operator fun TraceValues.invoke(vector: DoubleVector) {
numbers = vector.asIterable()
}
@@ -90,10 +90,10 @@ fun main() {
}
}
br()
- h3{
+ h3 {
+"Fit result: $result"
}
- h3{
+ h3 {
+"Chi2/dof = ${result.value / (x.size - 3)}"
}
}
diff --git a/examples/src/main/kotlin/space/kscience/kmath/linear/gradient.kt b/examples/src/main/kotlin/space/kscience/kmath/linear/gradient.kt
new file mode 100644
index 000000000..8940aeac9
--- /dev/null
+++ b/examples/src/main/kotlin/space/kscience/kmath/linear/gradient.kt
@@ -0,0 +1,28 @@
+package space.kscience.kmath.linear
+
+import space.kscience.kmath.real.*
+import space.kscience.kmath.structures.DoubleBuffer
+
+fun main() {
+ val x0 = DoubleVector(0.0, 0.0, 0.0)
+ val sigma = DoubleVector(1.0, 1.0, 1.0)
+
+ val gaussian: (Point) -> Double = { x ->
+ require(x.size == x0.size)
+ kotlin.math.exp(-((x - x0) / sigma).square().sum())
+ }
+
+ fun ((Point) -> Double).grad(x: Point): Point {
+ require(x.size == x0.size)
+ return DoubleBuffer(x.size) { i ->
+ val h = sigma[i] / 5
+ val dVector = DoubleBuffer(x.size) { if (it == i) h else 0.0 }
+ val f1 = invoke(x + dVector / 2)
+ val f0 = invoke(x - dVector / 2)
+ (f1 - f0) / h
+ }
+ }
+
+ println(gaussian.grad(x0))
+
+}
\ No newline at end of file
diff --git a/examples/src/main/kotlin/space/kscience/kmath/operations/ComplexDemo.kt b/examples/src/main/kotlin/space/kscience/kmath/operations/ComplexDemo.kt
index 5330d9e40..105fb108e 100644
--- a/examples/src/main/kotlin/space/kscience/kmath/operations/ComplexDemo.kt
+++ b/examples/src/main/kotlin/space/kscience/kmath/operations/ComplexDemo.kt
@@ -2,17 +2,17 @@ package space.kscience.kmath.operations
import space.kscience.kmath.complex.Complex
import space.kscience.kmath.complex.complex
-import space.kscience.kmath.nd.NDAlgebra
+import space.kscience.kmath.nd.AlgebraND
fun main() {
// 2d element
- val element = NDAlgebra.complex(2, 2).produce { (i, j) ->
+ val element = AlgebraND.complex(2, 2).produce { (i, j) ->
Complex(i.toDouble() - j.toDouble(), i.toDouble() + j.toDouble())
}
println(element)
// 1d element operation
- val result = with(NDAlgebra.complex(8)) {
+ val result = with(AlgebraND.complex(8)) {
val a = produce { (it) -> i * it - it.toDouble() }
val b = 3
val c = Complex(1.0, 1.0)
diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/ComplexND.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/ComplexND.kt
index b8cbc9a57..68af2560b 100644
--- a/examples/src/main/kotlin/space/kscience/kmath/structures/ComplexND.kt
+++ b/examples/src/main/kotlin/space/kscience/kmath/structures/ComplexND.kt
@@ -4,8 +4,8 @@ package space.kscience.kmath.structures
import space.kscience.kmath.complex.*
import space.kscience.kmath.linear.transpose
-import space.kscience.kmath.nd.NDAlgebra
-import space.kscience.kmath.nd.NDStructure
+import space.kscience.kmath.nd.AlgebraND
+import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.as2D
import space.kscience.kmath.nd.real
import space.kscience.kmath.operations.invoke
@@ -15,12 +15,12 @@ fun main() {
val dim = 1000
val n = 1000
- val realField = NDAlgebra.real(dim, dim)
- val complexField: ComplexNDField = NDAlgebra.complex(dim, dim)
+ val realField = AlgebraND.real(dim, dim)
+ val complexField: ComplexFieldND = AlgebraND.complex(dim, dim)
val realTime = measureTimeMillis {
realField {
- var res: NDStructure = one
+ var res: StructureND = one
repeat(n) {
res += 1.0
}
@@ -31,7 +31,7 @@ fun main() {
val complexTime = measureTimeMillis {
complexField {
- var res: NDStructure = one
+ var res: StructureND = one
repeat(n) {
res += 1.0
}
diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt
index 10fb3cb3d..f7dc3280a 100644
--- a/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt
+++ b/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt
@@ -4,7 +4,7 @@ import kotlinx.coroutines.GlobalScope
import org.nd4j.linalg.factory.Nd4j
import space.kscience.kmath.nd.*
import space.kscience.kmath.nd4j.Nd4jArrayField
-import space.kscience.kmath.operations.RealField
+import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.invoke
import space.kscience.kmath.viktor.ViktorNDField
import kotlin.contracts.InvocationKind
@@ -24,56 +24,56 @@ fun main() {
val n = 1000
// automatically build context most suited for given type.
- val autoField = NDAlgebra.auto(RealField, dim, dim)
+ val autoField = AlgebraND.auto(DoubleField, dim, dim)
// specialized nd-field for Double. It works as generic Double field as well
- val realField = NDAlgebra.real(dim, dim)
+ val realField = AlgebraND.real(dim, dim)
//A generic boxing field. It should be used for objects, not primitives.
- val boxingField = NDAlgebra.field(RealField, Buffer.Companion::boxing, dim, dim)
+ val boxingField = AlgebraND.field(DoubleField, Buffer.Companion::boxing, dim, dim)
// Nd4j specialized field.
val nd4jField = Nd4jArrayField.real(dim, dim)
//viktor field
- val viktorField = ViktorNDField(dim,dim)
+ val viktorField = ViktorNDField(dim, dim)
//parallel processing based on Java Streams
- val parallelField = NDAlgebra.realWithStream(dim,dim)
+ val parallelField = AlgebraND.realWithStream(dim, dim)
measureAndPrint("Boxing addition") {
boxingField {
- var res: NDStructure = one
+ var res: StructureND = one
repeat(n) { res += 1.0 }
}
}
measureAndPrint("Specialized addition") {
realField {
- var res: NDStructure = one
+ var res: StructureND = one
repeat(n) { res += 1.0 }
}
}
measureAndPrint("Nd4j specialized addition") {
nd4jField {
- var res: NDStructure = one
+ var res: StructureND = one
repeat(n) { res += 1.0 }
}
}
measureAndPrint("Viktor addition") {
viktorField {
- var res: NDStructure = one
+ var res: StructureND = one
repeat(n) { res += 1.0 }
}
}
measureAndPrint("Parallel stream addition") {
parallelField {
- var res: NDStructure = one
+ var res: StructureND = one
repeat(n) { res += 1.0 }
}
}
measureAndPrint("Automatic field addition") {
autoField {
- var res: NDStructure = one
+ var res: StructureND = one
repeat(n) { res += 1.0 }
}
}
diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/ParallelRealNDField.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/ParallelRealNDField.kt
deleted file mode 100644
index 0c914468d..000000000
--- a/examples/src/main/kotlin/space/kscience/kmath/structures/ParallelRealNDField.kt
+++ /dev/null
@@ -1,107 +0,0 @@
-package space.kscience.kmath.structures
-
-import space.kscience.kmath.misc.UnstableKMathAPI
-import space.kscience.kmath.nd.*
-import space.kscience.kmath.operations.ExtendedField
-import space.kscience.kmath.operations.NumbersAddOperations
-import space.kscience.kmath.operations.RealField
-import java.util.*
-import java.util.stream.IntStream
-
-/**
- * A demonstration implementation of NDField over Real using Java [DoubleStream] for parallel execution
- */
-@OptIn(UnstableKMathAPI::class)
-class StreamRealNDField(
- override val shape: IntArray,
-) : NDField,
- NumbersAddOperations>,
- ExtendedField> {
-
- private val strides = DefaultStrides(shape)
- override val elementContext: RealField get() = RealField
- override val zero: NDBuffer by lazy { produce { zero } }
- override val one: NDBuffer by lazy { produce { one } }
-
- override fun number(value: Number): NDBuffer {
- val d = value.toDouble() // minimize conversions
- return produce { d }
- }
-
- private val NDStructure.buffer: RealBuffer
- get() = when {
- !shape.contentEquals(this@StreamRealNDField.shape) -> throw ShapeMismatchException(
- this@StreamRealNDField.shape,
- shape
- )
- this is NDBuffer && this.strides == this@StreamRealNDField.strides -> this.buffer as RealBuffer
- else -> RealBuffer(strides.linearSize) { offset -> get(strides.index(offset)) }
- }
-
-
- override fun produce(initializer: RealField.(IntArray) -> Double): NDBuffer {
- val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
- val index = strides.index(offset)
- RealField.initializer(index)
- }.toArray()
-
- return NDBuffer(strides, array.asBuffer())
- }
-
- override fun NDStructure.map(
- transform: RealField.(Double) -> Double,
- ): NDBuffer {
- val array = Arrays.stream(buffer.array).parallel().map { RealField.transform(it) }.toArray()
- return NDBuffer(strides, array.asBuffer())
- }
-
- override fun NDStructure.mapIndexed(
- transform: RealField.(index: IntArray, Double) -> Double,
- ): NDBuffer {
- val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
- RealField.transform(
- strides.index(offset),
- buffer.array[offset]
- )
- }.toArray()
-
- return NDBuffer(strides, array.asBuffer())
- }
-
- override fun combine(
- a: NDStructure,
- b: NDStructure,
- transform: RealField.(Double, Double) -> Double,
- ): NDBuffer {
- val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
- RealField.transform(a.buffer.array[offset], b.buffer.array[offset])
- }.toArray()
- return NDBuffer(strides, array.asBuffer())
- }
-
- override fun NDStructure.unaryMinus(): NDStructure = map { -it }
-
- override fun scale(a: NDStructure, value: Double): NDStructure = a.map { it * value }
-
- override fun power(arg: NDStructure, pow: Number): NDBuffer = arg.map { power(it, pow) }
-
- override fun exp(arg: NDStructure): NDBuffer = arg.map { exp(it) }
-
- override fun ln(arg: NDStructure): NDBuffer = arg.map { ln(it) }
-
- override fun sin(arg: NDStructure): NDBuffer = arg.map { sin(it) }
- override fun cos(arg: NDStructure): NDBuffer = arg.map { cos(it) }
- override fun tan(arg: NDStructure): NDBuffer = arg.map { tan(it) }
- override fun asin(arg: NDStructure): NDBuffer = arg.map { asin(it) }
- override fun acos(arg: NDStructure): NDBuffer = arg.map { acos(it) }
- override fun atan(arg: NDStructure): NDBuffer = arg.map { atan(it) }
-
- override fun sinh(arg: NDStructure): NDBuffer = arg.map { sinh(it) }
- override fun cosh(arg: NDStructure): NDBuffer = arg.map { cosh(it) }
- override fun tanh(arg: NDStructure): NDBuffer = arg.map { tanh(it) }
- override fun asinh(arg: NDStructure): NDBuffer = arg.map { asinh(it) }
- override fun acosh(arg: NDStructure): NDBuffer = arg.map { acosh(it) }
- override fun atanh(arg: NDStructure): NDBuffer = arg.map { atanh(it) }
-}
-
-fun NDAlgebra.Companion.realWithStream(vararg shape: Int): StreamRealNDField = StreamRealNDField(shape)
\ No newline at end of file
diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt
new file mode 100644
index 000000000..6741209fc
--- /dev/null
+++ b/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt
@@ -0,0 +1,107 @@
+package space.kscience.kmath.structures
+
+import space.kscience.kmath.misc.UnstableKMathAPI
+import space.kscience.kmath.nd.*
+import space.kscience.kmath.operations.DoubleField
+import space.kscience.kmath.operations.ExtendedField
+import space.kscience.kmath.operations.NumbersAddOperations
+import java.util.*
+import java.util.stream.IntStream
+
+/**
+ * A demonstration implementation of NDField over Real using Java [DoubleStream] for parallel execution
+ */
+@OptIn(UnstableKMathAPI::class)
+class StreamDoubleFieldND(
+ override val shape: IntArray,
+) : FieldND,
+ NumbersAddOperations>,
+ ExtendedField> {
+
+ private val strides = DefaultStrides(shape)
+ override val elementContext: DoubleField get() = DoubleField
+ override val zero: BufferND by lazy { produce { zero } }
+ override val one: BufferND by lazy { produce { one } }
+
+ override fun number(value: Number): BufferND {
+ val d = value.toDouble() // minimize conversions
+ return produce { d }
+ }
+
+ private val StructureND.buffer: DoubleBuffer
+ get() = when {
+ !shape.contentEquals(this@StreamDoubleFieldND.shape) -> throw ShapeMismatchException(
+ this@StreamDoubleFieldND.shape,
+ shape
+ )
+ this is BufferND && this.strides == this@StreamDoubleFieldND.strides -> this.buffer as DoubleBuffer
+ else -> DoubleBuffer(strides.linearSize) { offset -> get(strides.index(offset)) }
+ }
+
+
+ override fun produce(initializer: DoubleField.(IntArray) -> Double): BufferND {
+ val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
+ val index = strides.index(offset)
+ DoubleField.initializer(index)
+ }.toArray()
+
+ return BufferND(strides, array.asBuffer())
+ }
+
+ override fun StructureND.map(
+ transform: DoubleField.(Double) -> Double,
+ ): BufferND {
+ val array = Arrays.stream(buffer.array).parallel().map { DoubleField.transform(it) }.toArray()
+ return BufferND(strides, array.asBuffer())
+ }
+
+ override fun StructureND.mapIndexed(
+ transform: DoubleField.(index: IntArray, Double) -> Double,
+ ): BufferND {
+ val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
+ DoubleField.transform(
+ strides.index(offset),
+ buffer.array[offset]
+ )
+ }.toArray()
+
+ return BufferND(strides, array.asBuffer())
+ }
+
+ override fun combine(
+ a: StructureND,
+ b: StructureND,
+ transform: DoubleField.(Double, Double) -> Double,
+ ): BufferND {
+ val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
+ DoubleField.transform(a.buffer.array[offset], b.buffer.array[offset])
+ }.toArray()
+ return BufferND(strides, array.asBuffer())
+ }
+
+ override fun StructureND.unaryMinus(): StructureND = map { -it }
+
+ override fun scale(a: StructureND, value: Double): StructureND = a.map { it * value }
+
+ override fun power(arg: StructureND, pow: Number): BufferND = arg.map { power(it, pow) }
+
+ override fun exp(arg: StructureND): BufferND = arg.map { exp(it) }
+
+ override fun ln(arg: StructureND): BufferND = arg.map { ln(it) }
+
+ override fun sin(arg: StructureND): BufferND = arg.map { sin(it) }
+ override fun cos(arg: StructureND): BufferND = arg.map { cos(it) }
+ override fun tan(arg: StructureND): BufferND = arg.map { tan(it) }
+ override fun asin(arg: StructureND): BufferND = arg.map { asin(it) }
+ override fun acos(arg: StructureND): BufferND = arg.map { acos(it) }
+ override fun atan(arg: StructureND): BufferND = arg.map { atan(it) }
+
+ override fun sinh(arg: StructureND): BufferND = arg.map { sinh(it) }
+ override fun cosh(arg: StructureND): BufferND = arg.map { cosh(it) }
+ override fun tanh(arg: StructureND): BufferND = arg.map { tanh(it) }
+ override fun asinh(arg: StructureND): BufferND = arg.map { asinh(it) }
+ override fun acosh(arg: StructureND): BufferND = arg.map { acosh(it) }
+ override fun atanh(arg: StructureND): BufferND = arg.map { atanh(it) }
+}
+
+fun AlgebraND.Companion.realWithStream(vararg shape: Int): StreamDoubleFieldND = StreamDoubleFieldND(shape)
\ No newline at end of file
diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/StructureReadBenchmark.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/StructureReadBenchmark.kt
index 7f6d73394..1c8a923c7 100644
--- a/examples/src/main/kotlin/space/kscience/kmath/structures/StructureReadBenchmark.kt
+++ b/examples/src/main/kotlin/space/kscience/kmath/structures/StructureReadBenchmark.kt
@@ -1,16 +1,16 @@
package space.kscience.kmath.structures
+import space.kscience.kmath.nd.BufferND
import space.kscience.kmath.nd.DefaultStrides
-import space.kscience.kmath.nd.NDBuffer
import kotlin.system.measureTimeMillis
@Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE")
fun main() {
val n = 6000
val array = DoubleArray(n * n) { 1.0 }
- val buffer = RealBuffer(array)
+ val buffer = DoubleBuffer(array)
val strides = DefaultStrides(intArrayOf(n, n))
- val structure = NDBuffer(strides, buffer)
+ val structure = BufferND(strides, buffer)
measureTimeMillis {
var res = 0.0
diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/StructureWriteBenchmark.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/StructureWriteBenchmark.kt
index 13d6f00e4..27741be61 100644
--- a/examples/src/main/kotlin/space/kscience/kmath/structures/StructureWriteBenchmark.kt
+++ b/examples/src/main/kotlin/space/kscience/kmath/structures/StructureWriteBenchmark.kt
@@ -1,13 +1,13 @@
package space.kscience.kmath.structures
-import space.kscience.kmath.nd.NDStructure
+import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.mapToBuffer
import kotlin.system.measureTimeMillis
@Suppress("UNUSED_VARIABLE")
fun main() {
val n = 6000
- val structure = NDStructure.build(intArrayOf(n, n), Buffer.Companion::auto) { 1.0 }
+ val structure = StructureND.buffered(intArrayOf(n, n), Buffer.Companion::auto) { 1.0 }
structure.mapToBuffer { it + 1 } // warm-up
val time1 = measureTimeMillis { val res = structure.mapToBuffer { it + 1 } }
println("Structure mapping finished in $time1 millis")
@@ -20,10 +20,10 @@ fun main() {
println("Array mapping finished in $time2 millis")
- val buffer = RealBuffer(DoubleArray(n * n) { 1.0 })
+ val buffer = DoubleBuffer(DoubleArray(n * n) { 1.0 })
val time3 = measureTimeMillis {
- val target = RealBuffer(DoubleArray(n * n))
+ val target = DoubleBuffer(DoubleArray(n * n))
val res = array.forEachIndexed { index, value ->
target[index] = value + 1
}
diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/typeSafeDimensions.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/typeSafeDimensions.kt
index fdd631238..d2d130ab4 100644
--- a/examples/src/main/kotlin/space/kscience/kmath/structures/typeSafeDimensions.kt
+++ b/examples/src/main/kotlin/space/kscience/kmath/structures/typeSafeDimensions.kt
@@ -5,7 +5,7 @@ import space.kscience.kmath.dimensions.D3
import space.kscience.kmath.dimensions.DMatrixContext
import space.kscience.kmath.dimensions.Dimension
-private fun DMatrixContext.simple() {
+private fun DMatrixContext.simple() {
val m1 = produce { i, j -> (i + j).toDouble() }
val m2 = produce { i, j -> (i + j).toDouble() }
@@ -17,7 +17,7 @@ private object D5 : Dimension {
override val dim: UInt = 5u
}
-private fun DMatrixContext.custom() {
+private fun DMatrixContext.custom() {
val m1 = produce { i, j -> (i + j).toDouble() }
val m2 = produce { i, j -> (i - j).toDouble() }
val m3 = produce { i, j -> (i - j).toDouble() }
diff --git a/gradle.properties b/gradle.properties
index aadc76c52..7ff50a435 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,10 +1,8 @@
kotlin.code.style=official
+kotlin.mpp.enableGranularSourceSetsMetadata=true
kotlin.mpp.stability.nowarn=true
+kotlin.native.enableDependencyPropagation=false
kotlin.parallel.tasks.in.project=true
org.gradle.configureondemand=true
-org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m
+org.gradle.jvmargs=-XX:MaxMetaspaceSize=2G
org.gradle.parallel=true
-
-kotlin.mpp.enableGranularSourceSetsMetadata=true
-kotlin.native.enableDependencyPropagation=false
-
diff --git a/kmath-ast/README.md b/kmath-ast/README.md
index e52f0fa96..ee14604d2 100644
--- a/kmath-ast/README.md
+++ b/kmath-ast/README.md
@@ -2,17 +2,17 @@
This subproject implements the following features:
- - [expression-language](src/jvmMain/kotlin/kscience/kmath/ast/parser.kt) : Expression language and its parser
- - [mst](src/commonMain/kotlin/kscience/kmath/ast/MST.kt) : MST (Mathematical Syntax Tree) as expression language's syntax intermediate representation
- - [mst-building](src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt) : MST building algebraic structure
- - [mst-interpreter](src/commonMain/kotlin/kscience/kmath/ast/MST.kt) : MST interpreter
- - [mst-jvm-codegen](src/jvmMain/kotlin/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode compiler
- - [mst-js-codegen](src/jsMain/kotlin/kscience/kmath/estree/estree.kt) : Dynamic MST to JS compiler
+ - [expression-language](src/jvmMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser
+ - [mst](src/commonMain/kotlin/space/kscience/kmath/ast/MST.kt) : MST (Mathematical Syntax Tree) as expression language's syntax intermediate representation
+ - [mst-building](src/commonMain/kotlin/space/kscience/kmath/ast/MstAlgebra.kt) : MST building algebraic structure
+ - [mst-interpreter](src/commonMain/kotlin/space/kscience/kmath/ast/MST.kt) : MST interpreter
+ - [mst-jvm-codegen](src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode compiler
+ - [mst-js-codegen](src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt) : Dynamic MST to JS compiler
> #### Artifact:
>
-> This module artifact: `space.kscience:kmath-ast:0.2.0`.
+> This module artifact: `space.kscience:kmath-ast:0.3.0-dev-3`.
>
> Bintray release version: [ ![Download](https://api.bintray.com/packages/mipt-npm/kscience/kmath-ast/images/download.svg) ](https://bintray.com/mipt-npm/kscience/kmath-ast/_latestVersion)
>
@@ -25,13 +25,10 @@ This subproject implements the following features:
> 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
->// Uncomment if repo.kotlin.link is unavailable
->// maven { url 'https://dl.bintray.com/mipt-npm/kscience' }
->// maven { url 'https://dl.bintray.com/mipt-npm/dev' }
> }
>
> dependencies {
-> implementation 'space.kscience:kmath-ast:0.2.0'
+> implementation 'space.kscience:kmath-ast:0.3.0-dev-3'
> }
> ```
> **Gradle Kotlin DSL:**
@@ -41,13 +38,10 @@ This subproject implements the following features:
> 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
->// Uncomment if repo.kotlin.link is unavailable
->// maven("https://dl.bintray.com/mipt-npm/kscience")
->// maven("https://dl.bintray.com/mipt-npm/dev")
> }
>
> dependencies {
-> implementation("space.kscience:kmath-ast:0.2.0")
+> implementation("space.kscience:kmath-ast:0.3.0-dev-3")
> }
> ```
@@ -61,10 +55,10 @@ a special implementation of `Expression` with implemented `invoke` function.
For example, the following builder:
```kotlin
-RealField.mstInField { symbol("x") + 2 }.compile()
+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;
@@ -94,8 +88,8 @@ public final class AsmCompiledExpression_45045_0 implements Expression {
This API extends MST and MstExpression, so you may optimize as both of them:
```kotlin
-RealField.mstInField { symbol("x") + 2 }.compile()
-RealField.expression("x+2".parseMath())
+DoubleField.mstInField { symbol("x") + 2 }.compile()
+DoubleField.expression("x+2".parseMath())
```
#### Known issues
@@ -109,7 +103,7 @@ RealField.expression("x+2".parseMath())
A similar feature is also available on JS.
```kotlin
-RealField.mstInField { symbol("x") + 2 }.compile()
+DoubleField.mstInField { symbol("x") + 2 }.compile()
```
The code above returns expression implemented with such a JS function:
diff --git a/kmath-ast/build.gradle.kts b/kmath-ast/build.gradle.kts
index 5b764459c..e3a7faf0a 100644
--- a/kmath-ast/build.gradle.kts
+++ b/kmath-ast/build.gradle.kts
@@ -58,36 +58,36 @@ readme {
feature(
id = "expression-language",
description = "Expression language and its parser",
- ref = "src/jvmMain/kotlin/kscience/kmath/ast/parser.kt"
+ ref = "src/jvmMain/kotlin/space/kscience/kmath/ast/parser.kt"
)
feature(
id = "mst",
description = "MST (Mathematical Syntax Tree) as expression language's syntax intermediate representation",
- ref = "src/commonMain/kotlin/kscience/kmath/ast/MST.kt"
+ ref = "src/commonMain/kotlin/space/kscience/kmath/ast/MST.kt"
)
feature(
id = "mst-building",
description = "MST building algebraic structure",
- ref = "src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt"
+ ref = "src/commonMain/kotlin/space/kscience/kmath/ast/MstAlgebra.kt"
)
feature(
id = "mst-interpreter",
description = "MST interpreter",
- ref = "src/commonMain/kotlin/kscience/kmath/ast/MST.kt"
+ ref = "src/commonMain/kotlin/space/kscience/kmath/ast/MST.kt"
)
feature(
id = "mst-jvm-codegen",
description = "Dynamic MST to JVM bytecode compiler",
- ref = "src/jvmMain/kotlin/kscience/kmath/asm/asm.kt"
+ ref = "src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt"
)
feature(
id = "mst-js-codegen",
description = "Dynamic MST to JS compiler",
- ref = "src/jsMain/kotlin/kscience/kmath/estree/estree.kt"
+ ref = "src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt"
)
}
diff --git a/kmath-ast/docs/README-TEMPLATE.md b/kmath-ast/docs/README-TEMPLATE.md
index 2712cba75..80e48008b 100644
--- a/kmath-ast/docs/README-TEMPLATE.md
+++ b/kmath-ast/docs/README-TEMPLATE.md
@@ -16,7 +16,7 @@ a special implementation of `Expression` with implemented `invoke` function.
For example, the following builder:
```kotlin
-RealField.mstInField { symbol("x") + 2 }.compile()
+DoubleField.mstInField { symbol("x") + 2 }.compile()
```
… leads to generation of bytecode, which can be decompiled to the following Java class:
@@ -49,8 +49,8 @@ public final class AsmCompiledExpression_45045_0 implements Expression {
This API extends MST and MstExpression, so you may optimize as both of them:
```kotlin
-RealField.mstInField { symbol("x") + 2 }.compile()
-RealField.expression("x+2".parseMath())
+DoubleField.mstInField { symbol("x") + 2 }.compile()
+DoubleField.expression("x+2".parseMath())
```
#### Known issues
@@ -64,7 +64,7 @@ RealField.expression("x+2".parseMath())
A similar feature is also available on JS.
```kotlin
-RealField.mstInField { symbol("x") + 2 }.compile()
+DoubleField.mstInField { symbol("x") + 2 }.compile()
```
The code above returns expression implemented with such a JS function:
diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/MstAlgebra.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/MstAlgebra.kt
index 16fdfbeac..c1aeae90e 100644
--- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/MstAlgebra.kt
+++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/MstAlgebra.kt
@@ -50,11 +50,11 @@ public object MstGroup : Group, NumericAlgebra, ScaleOperations {
*/
@OptIn(UnstableKMathAPI::class)
public object MstRing : Ring, NumbersAddOperations, ScaleOperations {
- public override val zero: MST.Numeric get() = MstGroup.zero
+ public override val zero: MST.Numeric get() = MstGroup.zero
public override val one: MST.Numeric = number(1.0)
public override fun number(value: Number): MST.Numeric = MstGroup.number(value)
- public override fun bindSymbol(value: String): MST.Symbolic = MstGroup.bindSymbol(value)
+ public override fun bindSymbol(value: String): MST.Symbolic = MstAlgebra.bindSymbol(value)
public override fun add(a: MST, b: MST): MST.Binary = MstGroup.add(a, b)
public override fun scale(a: MST, value: Double): MST.Binary =
@@ -83,7 +83,7 @@ public object MstField : Field, NumbersAddOperations, ScaleOperations<
public override val one: MST.Numeric get() = MstRing.one
- public override fun bindSymbol(value: String): MST.Symbolic = MstRing.bindSymbol(value)
+ public override fun bindSymbol(value: String): MST.Symbolic = MstAlgebra.bindSymbol(value)
public override fun number(value: Number): MST.Numeric = MstRing.number(value)
public override fun add(a: MST, b: MST): MST.Binary = MstRing.add(a, b)
@@ -112,7 +112,7 @@ public object MstExtendedField : ExtendedField, NumericAlgebra {
public override val zero: MST.Numeric get() = MstField.zero
public override val one: MST.Numeric get() = MstField.one
- public override fun bindSymbol(value: String): MST.Symbolic = MstField.bindSymbol(value)
+ public override fun bindSymbol(value: String): MST.Symbolic = MstAlgebra.bindSymbol(value)
public override fun number(value: Number): MST.Numeric = MstRing.number(value)
public override fun sin(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.SIN_OPERATION)(arg)
public override fun cos(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.COS_OPERATION)(arg)
diff --git a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeConsistencyWithInterpreter.kt b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeConsistencyWithInterpreter.kt
index bb34254b1..683c0337c 100644
--- a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeConsistencyWithInterpreter.kt
+++ b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeConsistencyWithInterpreter.kt
@@ -5,7 +5,7 @@ import space.kscience.kmath.complex.ComplexField
import space.kscience.kmath.complex.toComplex
import space.kscience.kmath.expressions.invoke
import space.kscience.kmath.operations.ByteRing
-import space.kscience.kmath.operations.RealField
+import space.kscience.kmath.operations.DoubleField
import kotlin.test.Test
import kotlin.test.assertEquals
@@ -73,7 +73,7 @@ internal class TestESTreeConsistencyWithInterpreter {
@Test
fun realField() {
- val res1 = RealField.mstInField {
+ val res1 = DoubleField.mstInField {
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
(3.0 - (bindSymbol("x") + (scale(add(number(1.0), number(1.0)), 2.0) + 1.0))) * 3 - 1.0
+ number(1),
@@ -81,7 +81,7 @@ internal class TestESTreeConsistencyWithInterpreter {
) + zero
}("x" to 2.0)
- val res2 = RealField.mstInField {
+ val res2 = DoubleField.mstInField {
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
(3.0 - (bindSymbol("x") + (scale(add(number(1.0), number(1.0)), 2.0) + 1.0))) * 3 - 1.0
+ number(1),
diff --git a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeOperationsSupport.kt b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeOperationsSupport.kt
index 27bf2f167..d59c048b6 100644
--- a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeOperationsSupport.kt
+++ b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeOperationsSupport.kt
@@ -4,7 +4,7 @@ import space.kscience.kmath.ast.mstInExtendedField
import space.kscience.kmath.ast.mstInField
import space.kscience.kmath.ast.mstInGroup
import space.kscience.kmath.expressions.invoke
-import space.kscience.kmath.operations.RealField
+import space.kscience.kmath.operations.DoubleField
import kotlin.random.Random
import kotlin.test.Test
import kotlin.test.assertEquals
@@ -12,27 +12,29 @@ import kotlin.test.assertEquals
internal class TestESTreeOperationsSupport {
@Test
fun testUnaryOperationInvocation() {
- val expression = RealField.mstInGroup { -bindSymbol("x") }.compile()
+ val expression = DoubleField.mstInGroup { -bindSymbol("x") }.compile()
val res = expression("x" to 2.0)
assertEquals(-2.0, res)
}
@Test
fun testBinaryOperationInvocation() {
- val expression = RealField.mstInGroup { -bindSymbol("x") + number(1.0) }.compile()
+ val expression = DoubleField.mstInGroup { -bindSymbol("x") + number(1.0) }.compile()
val res = expression("x" to 2.0)
assertEquals(-1.0, res)
}
@Test
fun testConstProductInvocation() {
- val res = RealField.mstInField { bindSymbol("x") * 2 }("x" to 2.0)
+ val res = DoubleField.mstInField { bindSymbol("x") * 2 }("x" to 2.0)
assertEquals(4.0, res)
}
@Test
fun testMultipleCalls() {
- val e = RealField.mstInExtendedField { sin(bindSymbol("x")).pow(4) - 6 * bindSymbol("x") / tanh(bindSymbol("x")) }.compile()
+ val e =
+ DoubleField.mstInExtendedField { sin(bindSymbol("x")).pow(4) - 6 * bindSymbol("x") / tanh(bindSymbol("x")) }
+ .compile()
val r = Random(0)
var s = 0.0
repeat(1000000) { s += e("x" to r.nextDouble()) }
diff --git a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeSpecialization.kt b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeSpecialization.kt
index c5e43241a..6be963175 100644
--- a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeSpecialization.kt
+++ b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeSpecialization.kt
@@ -2,50 +2,50 @@ package space.kscience.kmath.estree
import space.kscience.kmath.ast.mstInField
import space.kscience.kmath.expressions.invoke
-import space.kscience.kmath.operations.RealField
+import space.kscience.kmath.operations.DoubleField
import kotlin.test.Test
import kotlin.test.assertEquals
internal class TestESTreeSpecialization {
@Test
fun testUnaryPlus() {
- val expr = RealField.mstInField { unaryOperationFunction("+")(bindSymbol("x")) }.compile()
+ val expr = DoubleField.mstInField { unaryOperationFunction("+")(bindSymbol("x")) }.compile()
assertEquals(2.0, expr("x" to 2.0))
}
@Test
fun testUnaryMinus() {
- val expr = RealField.mstInField { unaryOperationFunction("-")(bindSymbol("x")) }.compile()
+ val expr = DoubleField.mstInField { unaryOperationFunction("-")(bindSymbol("x")) }.compile()
assertEquals(-2.0, expr("x" to 2.0))
}
@Test
fun testAdd() {
- val expr = RealField.mstInField { binaryOperationFunction("+")(bindSymbol("x"), bindSymbol("x")) }.compile()
+ val expr = DoubleField.mstInField { binaryOperationFunction("+")(bindSymbol("x"), bindSymbol("x")) }.compile()
assertEquals(4.0, expr("x" to 2.0))
}
@Test
fun testSine() {
- val expr = RealField.mstInField { unaryOperationFunction("sin")(bindSymbol("x")) }.compile()
+ val expr = DoubleField.mstInField { unaryOperationFunction("sin")(bindSymbol("x")) }.compile()
assertEquals(0.0, expr("x" to 0.0))
}
@Test
fun testMinus() {
- val expr = RealField.mstInField { binaryOperationFunction("-")(bindSymbol("x"), bindSymbol("x")) }.compile()
+ val expr = DoubleField.mstInField { binaryOperationFunction("-")(bindSymbol("x"), bindSymbol("x")) }.compile()
assertEquals(0.0, expr("x" to 2.0))
}
@Test
fun testDivide() {
- val expr = RealField.mstInField { binaryOperationFunction("/")(bindSymbol("x"), bindSymbol("x")) }.compile()
+ val expr = DoubleField.mstInField { binaryOperationFunction("/")(bindSymbol("x"), bindSymbol("x")) }.compile()
assertEquals(1.0, expr("x" to 2.0))
}
@Test
fun testPower() {
- val expr = RealField
+ val expr = DoubleField
.mstInField { binaryOperationFunction("pow")(bindSymbol("x"), number(2)) }
.compile()
diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/codegenUtils.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/codegenUtils.kt
index 1124a860f..4522c966f 100644
--- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/codegenUtils.kt
+++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/codegenUtils.kt
@@ -86,7 +86,7 @@ internal inline fun ClassWriter.visitField(
descriptor: String,
signature: String?,
value: Any?,
- block: FieldVisitor.() -> Unit
+ block: FieldVisitor.() -> Unit,
): FieldVisitor {
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
return visitField(access, name, descriptor, signature, value).apply(block)
diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmConsistencyWithInterpreter.kt b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmConsistencyWithInterpreter.kt
index 7cc1497d0..abc320360 100644
--- a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmConsistencyWithInterpreter.kt
+++ b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmConsistencyWithInterpreter.kt
@@ -5,7 +5,7 @@ import space.kscience.kmath.complex.ComplexField
import space.kscience.kmath.complex.toComplex
import space.kscience.kmath.expressions.invoke
import space.kscience.kmath.operations.ByteRing
-import space.kscience.kmath.operations.RealField
+import space.kscience.kmath.operations.DoubleField
import kotlin.test.Test
import kotlin.test.assertEquals
@@ -73,7 +73,7 @@ internal class TestAsmConsistencyWithInterpreter {
@Test
fun realField() {
- val res1 = RealField.mstInField {
+ val res1 = DoubleField.mstInField {
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
(3.0 - (bindSymbol("x") + (scale(add(number(1.0), number(1.0)), 2.0) + 1.0))) * 3 - 1.0
+ number(1),
@@ -81,7 +81,7 @@ internal class TestAsmConsistencyWithInterpreter {
) + zero
}("x" to 2.0)
- val res2 = RealField.mstInField {
+ val res2 = DoubleField.mstInField {
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
(3.0 - (bindSymbol("x") + (scale(add(number(1.0), number(1.0)), 2.0) + 1.0))) * 3 - 1.0
+ number(1),
diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmOperationsSupport.kt b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmOperationsSupport.kt
index e99075f07..5d70cb76b 100644
--- a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmOperationsSupport.kt
+++ b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmOperationsSupport.kt
@@ -4,7 +4,7 @@ import space.kscience.kmath.ast.mstInExtendedField
import space.kscience.kmath.ast.mstInField
import space.kscience.kmath.ast.mstInGroup
import space.kscience.kmath.expressions.invoke
-import space.kscience.kmath.operations.RealField
+import space.kscience.kmath.operations.DoubleField
import kotlin.random.Random
import kotlin.test.Test
import kotlin.test.assertEquals
@@ -12,27 +12,29 @@ import kotlin.test.assertEquals
internal class TestAsmOperationsSupport {
@Test
fun testUnaryOperationInvocation() {
- val expression = RealField.mstInGroup { -bindSymbol("x") }.compile()
+ val expression = DoubleField.mstInGroup { -bindSymbol("x") }.compile()
val res = expression("x" to 2.0)
assertEquals(-2.0, res)
}
@Test
fun testBinaryOperationInvocation() {
- val expression = RealField.mstInGroup { -bindSymbol("x") + number(1.0) }.compile()
+ val expression = DoubleField.mstInGroup { -bindSymbol("x") + number(1.0) }.compile()
val res = expression("x" to 2.0)
assertEquals(-1.0, res)
}
@Test
fun testConstProductInvocation() {
- val res = RealField.mstInField { bindSymbol("x") * 2 }("x" to 2.0)
+ val res = DoubleField.mstInField { bindSymbol("x") * 2 }("x" to 2.0)
assertEquals(4.0, res)
}
@Test
fun testMultipleCalls() {
- val e = RealField.mstInExtendedField { sin(bindSymbol("x")).pow(4) - 6 * bindSymbol("x") / tanh(bindSymbol("x")) }.compile()
+ val e =
+ DoubleField.mstInExtendedField { sin(bindSymbol("x")).pow(4) - 6 * bindSymbol("x") / tanh(bindSymbol("x")) }
+ .compile()
val r = Random(0)
var s = 0.0
repeat(1000000) { s += e("x" to r.nextDouble()) }
diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmSpecialization.kt b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmSpecialization.kt
index a214ca4ad..f485260c9 100644
--- a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmSpecialization.kt
+++ b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmSpecialization.kt
@@ -2,50 +2,50 @@ package space.kscience.kmath.asm
import space.kscience.kmath.ast.mstInField
import space.kscience.kmath.expressions.invoke
-import space.kscience.kmath.operations.RealField
+import space.kscience.kmath.operations.DoubleField
import kotlin.test.Test
import kotlin.test.assertEquals
internal class TestAsmSpecialization {
@Test
fun testUnaryPlus() {
- val expr = RealField.mstInField { unaryOperationFunction("+")(bindSymbol("x")) }.compile()
+ val expr = DoubleField.mstInField { unaryOperationFunction("+")(bindSymbol("x")) }.compile()
assertEquals(2.0, expr("x" to 2.0))
}
@Test
fun testUnaryMinus() {
- val expr = RealField.mstInField { unaryOperationFunction("-")(bindSymbol("x")) }.compile()
+ val expr = DoubleField.mstInField { unaryOperationFunction("-")(bindSymbol("x")) }.compile()
assertEquals(-2.0, expr("x" to 2.0))
}
@Test
fun testAdd() {
- val expr = RealField.mstInField { binaryOperationFunction("+")(bindSymbol("x"), bindSymbol("x")) }.compile()
+ val expr = DoubleField.mstInField { binaryOperationFunction("+")(bindSymbol("x"), bindSymbol("x")) }.compile()
assertEquals(4.0, expr("x" to 2.0))
}
@Test
fun testSine() {
- val expr = RealField.mstInField { unaryOperationFunction("sin")(bindSymbol("x")) }.compile()
+ val expr = DoubleField.mstInField { unaryOperationFunction("sin")(bindSymbol("x")) }.compile()
assertEquals(0.0, expr("x" to 0.0))
}
@Test
fun testMinus() {
- val expr = RealField.mstInField { binaryOperationFunction("-")(bindSymbol("x"), bindSymbol("x")) }.compile()
+ val expr = DoubleField.mstInField { binaryOperationFunction("-")(bindSymbol("x"), bindSymbol("x")) }.compile()
assertEquals(0.0, expr("x" to 2.0))
}
@Test
fun testDivide() {
- val expr = RealField.mstInField { binaryOperationFunction("/")(bindSymbol("x"), bindSymbol("x")) }.compile()
+ val expr = DoubleField.mstInField { binaryOperationFunction("/")(bindSymbol("x"), bindSymbol("x")) }.compile()
assertEquals(1.0, expr("x" to 2.0))
}
@Test
fun testPower() {
- val expr = RealField
+ val expr = DoubleField
.mstInField { binaryOperationFunction("pow")(bindSymbol("x"), number(2)) }
.compile()
diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/ParserPrecedenceTest.kt b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/ParserPrecedenceTest.kt
index 7153f4bfc..1450cab84 100644
--- a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/ParserPrecedenceTest.kt
+++ b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/ParserPrecedenceTest.kt
@@ -1,12 +1,12 @@
package space.kscience.kmath.ast
+import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Field
-import space.kscience.kmath.operations.RealField
import kotlin.test.Test
import kotlin.test.assertEquals
internal class ParserPrecedenceTest {
- private val f: Field = RealField
+ private val f: Field = DoubleField
@Test
fun test1(): Unit = assertEquals(6.0, f.evaluate("2*2+2".parseMath()))
diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/ParserTest.kt b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/ParserTest.kt
index 6807d5c5d..3d5449043 100644
--- a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/ParserTest.kt
+++ b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/ParserTest.kt
@@ -4,7 +4,7 @@ import space.kscience.kmath.complex.Complex
import space.kscience.kmath.complex.ComplexField
import space.kscience.kmath.expressions.invoke
import space.kscience.kmath.operations.Algebra
-import space.kscience.kmath.operations.RealField
+import space.kscience.kmath.operations.DoubleField
import kotlin.test.Test
import kotlin.test.assertEquals
@@ -33,7 +33,7 @@ internal class ParserTest {
@Test
fun `evaluate MST with unary function`() {
val mst = "sin(0)".parseMath()
- val res = RealField.evaluate(mst)
+ val res = DoubleField.evaluate(mst)
assertEquals(0.0, res)
}
diff --git a/kmath-commons/build.gradle.kts b/kmath-commons/build.gradle.kts
index 4fe16605a..56dcef29a 100644
--- a/kmath-commons/build.gradle.kts
+++ b/kmath-commons/build.gradle.kts
@@ -12,6 +12,6 @@ dependencies {
api("org.apache.commons:commons-math3:3.6.1")
}
-readme{
+readme {
maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL
}
\ No newline at end of file
diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt
new file mode 100644
index 000000000..e1ba7d777
--- /dev/null
+++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt
@@ -0,0 +1,92 @@
+package space.kscience.kmath.commons.integration
+
+import org.apache.commons.math3.analysis.integration.IterativeLegendreGaussIntegrator
+import org.apache.commons.math3.analysis.integration.SimpsonIntegrator
+import space.kscience.kmath.integration.*
+import space.kscience.kmath.misc.UnstableKMathAPI
+
+/**
+ * Integration wrapper for Common-maths UnivariateIntegrator
+ */
+public class CMIntegrator(
+ private val defaultMaxCalls: Int = 200,
+ public val integratorBuilder: (Integrand) -> org.apache.commons.math3.analysis.integration.UnivariateIntegrator,
+) : UnivariateIntegrator {
+
+ public class TargetRelativeAccuracy(public val value: Double) : IntegrandFeature
+ public class TargetAbsoluteAccuracy(public val value: Double) : IntegrandFeature
+
+ public class MinIterations(public val value: Int) : IntegrandFeature
+ public class MaxIterations(public val value: Int) : IntegrandFeature
+
+ override fun integrate(integrand: UnivariateIntegrand): UnivariateIntegrand {
+ val integrator = integratorBuilder(integrand)
+ val maxCalls = integrand.getFeature()?.maxCalls ?: defaultMaxCalls
+ val remainingCalls = maxCalls - integrand.calls
+ val range = integrand.getFeature>()?.range
+ ?: error("Integration range is not provided")
+ val res = integrator.integrate(remainingCalls, integrand.function, range.start, range.endInclusive)
+
+ return integrand +
+ IntegrandValue(res) +
+ IntegrandAbsoluteAccuracy(integrator.absoluteAccuracy) +
+ IntegrandRelativeAccuracy(integrator.relativeAccuracy) +
+ IntegrandCalls(integrator.evaluations + integrand.calls)
+ }
+
+
+ public companion object {
+ /**
+ * Create a Simpson integrator based on [SimpsonIntegrator]
+ */
+ public fun simpson(defaultMaxCalls: Int = 200): CMIntegrator = CMIntegrator(defaultMaxCalls) { integrand ->
+ val absoluteAccuracy = integrand.getFeature()?.value
+ ?: SimpsonIntegrator.DEFAULT_ABSOLUTE_ACCURACY
+ val relativeAccuracy = integrand.getFeature()?.value
+ ?: SimpsonIntegrator.DEFAULT_ABSOLUTE_ACCURACY
+ val minIterations = integrand.getFeature()?.value
+ ?: SimpsonIntegrator.DEFAULT_MIN_ITERATIONS_COUNT
+ val maxIterations = integrand.getFeature()?.value
+ ?: SimpsonIntegrator.SIMPSON_MAX_ITERATIONS_COUNT
+
+ SimpsonIntegrator(relativeAccuracy, absoluteAccuracy, minIterations, maxIterations)
+ }
+
+ /**
+ * Create a Gauss-Legandre integrator based on [IterativeLegendreGaussIntegrator]
+ */
+ public fun legandre(numPoints: Int, defaultMaxCalls: Int = numPoints * 5): CMIntegrator =
+ CMIntegrator(defaultMaxCalls) { integrand ->
+ val absoluteAccuracy = integrand.getFeature()?.value
+ ?: IterativeLegendreGaussIntegrator.DEFAULT_ABSOLUTE_ACCURACY
+ val relativeAccuracy = integrand.getFeature()?.value
+ ?: IterativeLegendreGaussIntegrator.DEFAULT_ABSOLUTE_ACCURACY
+ val minIterations = integrand.getFeature()?.value
+ ?: IterativeLegendreGaussIntegrator.DEFAULT_MIN_ITERATIONS_COUNT
+ val maxIterations = integrand.getFeature()?.value
+ ?: IterativeLegendreGaussIntegrator.DEFAULT_MAX_ITERATIONS_COUNT
+
+ IterativeLegendreGaussIntegrator(
+ numPoints,
+ relativeAccuracy,
+ absoluteAccuracy,
+ minIterations,
+ maxIterations
+ )
+ }
+ }
+}
+
+@UnstableKMathAPI
+public var MutableList.targetAbsoluteAccuracy: Double?
+ get() = filterIsInstance().lastOrNull()?.value
+ set(value) {
+ value?.let { add(CMIntegrator.TargetAbsoluteAccuracy(value)) }
+ }
+
+@UnstableKMathAPI
+public var MutableList.targetRelativeAccuracy: Double?
+ get() = filterIsInstance().lastOrNull()?.value
+ set(value) {
+ value?.let { add(CMIntegrator.TargetRelativeAccuracy(value)) }
+ }
\ No newline at end of file
diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/GaussRuleIntegrator.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/GaussRuleIntegrator.kt
new file mode 100644
index 000000000..5a18756ac
--- /dev/null
+++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/GaussRuleIntegrator.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2015 Alexander Nozik.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package space.kscience.kmath.commons.integration
+
+import org.apache.commons.math3.analysis.integration.gauss.GaussIntegrator
+import org.apache.commons.math3.analysis.integration.gauss.GaussIntegratorFactory
+import space.kscience.kmath.integration.*
+
+/**
+ * A simple one-pass integrator based on Gauss rule
+ */
+public class GaussRuleIntegrator(
+ private val numpoints: Int,
+ private var type: GaussRule = GaussRule.LEGANDRE,
+) : UnivariateIntegrator {
+
+ override fun integrate(integrand: UnivariateIntegrand): UnivariateIntegrand {
+ val range = integrand.getFeature>()?.range
+ ?: error("Integration range is not provided")
+ val integrator: GaussIntegrator = getIntegrator(range)
+ //TODO check performance
+ val res: Double = integrator.integrate(integrand.function)
+ return integrand + IntegrandValue(res) + IntegrandCalls(integrand.calls + numpoints)
+ }
+
+ private fun getIntegrator(range: ClosedRange): GaussIntegrator {
+ return when (type) {
+ GaussRule.LEGANDRE -> factory.legendre(
+ numpoints,
+ range.start,
+ range.endInclusive
+ )
+ GaussRule.LEGANDREHP -> factory.legendreHighPrecision(
+ numpoints,
+ range.start,
+ range.endInclusive
+ )
+ GaussRule.UNIFORM -> GaussIntegrator(
+ getUniformRule(
+ range.start,
+ range.endInclusive,
+ numpoints
+ )
+ )
+ }
+ }
+
+ private fun getUniformRule(
+ min: Double,
+ max: Double,
+ numPoints: Int,
+ ): org.apache.commons.math3.util.Pair {
+ assert(numPoints > 2)
+ val points = DoubleArray(numPoints)
+ val weights = DoubleArray(numPoints)
+ val step = (max - min) / (numPoints - 1)
+ points[0] = min
+ for (i in 1 until numPoints) {
+ points[i] = points[i - 1] + step
+ weights[i] = step
+ }
+ return org.apache.commons.math3.util.Pair(points, weights)
+ }
+
+ public enum class GaussRule {
+ UNIFORM, LEGANDRE, LEGANDREHP
+ }
+
+ public companion object {
+ private val factory: GaussIntegratorFactory = GaussIntegratorFactory()
+
+ public fun integrate(
+ range: ClosedRange,
+ numPoints: Int = 100,
+ type: GaussRule = GaussRule.LEGANDRE,
+ function: (Double) -> Double,
+ ): Double = GaussRuleIntegrator(numPoints, type).integrate(
+ UnivariateIntegrand(function, IntegrationRange(range))
+ ).value!!
+ }
+}
\ No newline at end of file
diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt
index 393b28973..89e9649e9 100644
--- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt
+++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt
@@ -3,7 +3,8 @@ package space.kscience.kmath.commons.linear
import org.apache.commons.math3.linear.*
import space.kscience.kmath.linear.*
import space.kscience.kmath.misc.UnstableKMathAPI
-import space.kscience.kmath.structures.RealBuffer
+import space.kscience.kmath.operations.DoubleField
+import space.kscience.kmath.structures.DoubleBuffer
import kotlin.reflect.KClass
import kotlin.reflect.cast
@@ -11,51 +12,10 @@ public inline class CMMatrix(public val origin: RealMatrix) : Matrix {
public override val rowNum: Int get() = origin.rowDimension
public override val colNum: Int get() = origin.columnDimension
- @UnstableKMathAPI
- override fun getFeature(type: KClass): T? = when (type) {
- DiagonalFeature::class -> if (origin is DiagonalMatrix) DiagonalFeature else null
-
- DeterminantFeature::class, LupDecompositionFeature::class -> object :
- DeterminantFeature,
- LupDecompositionFeature {
- private val lup by lazy { LUDecomposition(origin) }
- override val determinant: Double by lazy { lup.determinant }
- override val l: Matrix by lazy { CMMatrix(lup.l) + LFeature }
- override val u: Matrix by lazy { CMMatrix(lup.u) + UFeature }
- override val p: Matrix by lazy { CMMatrix(lup.p) }
- }
-
- CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature {
- override val l: Matrix by lazy {
- val cholesky = CholeskyDecomposition(origin)
- CMMatrix(cholesky.l) + LFeature
- }
- }
-
- QRDecompositionFeature::class -> object : QRDecompositionFeature {
- private val qr by lazy { QRDecomposition(origin) }
- override val q: Matrix by lazy { CMMatrix(qr.q) + OrthogonalFeature }
- override val r: Matrix by lazy { CMMatrix(qr.r) + UFeature }
- }
-
- SingularValueDecompositionFeature::class -> object : SingularValueDecompositionFeature {
- private val sv by lazy { SingularValueDecomposition(origin) }
- override val u: Matrix by lazy { CMMatrix(sv.u) }
- override val s: Matrix by lazy { CMMatrix(sv.s) }
- override val v: Matrix by lazy { CMMatrix(sv.v) }
- override val singularValues: Point by lazy { RealBuffer(sv.singularValues) }
- }
-
- else -> null
- }?.let(type::cast)
-
public override operator fun get(i: Int, j: Int): Double = origin.getEntry(i, j)
}
-
-public fun RealMatrix.asMatrix(): CMMatrix = CMMatrix(this)
-
-public class CMVector(public val origin: RealVector) : Point {
+public inline class CMVector(public val origin: RealVector) : Point {
public override val size: Int get() = origin.dimension
public override operator fun get(index: Int): Double = origin.getEntry(index)
@@ -63,16 +23,17 @@ public class CMVector(public val origin: RealVector) : Point {
public override operator fun iterator(): Iterator = origin.toArray().iterator()
}
-public fun Point.toCM(): CMVector = if (this is CMVector) this else {
- val array = DoubleArray(size) { this[it] }
- CMVector(ArrayRealVector(array))
-}
-
public fun RealVector.toPoint(): CMVector = CMVector(this)
-public object CMMatrixContext : MatrixContext {
- public override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> Double): CMMatrix {
- val array = Array(rows) { i -> DoubleArray(columns) { j -> initializer(i, j) } }
+public object CMLinearSpace : LinearSpace {
+ override val elementAlgebra: DoubleField get() = DoubleField
+
+ public override fun buildMatrix(
+ rows: Int,
+ columns: Int,
+ initializer: DoubleField.(i: Int, j: Int) -> Double,
+ ): CMMatrix {
+ val array = Array(rows) { i -> DoubleArray(columns) { j -> DoubleField.initializer(i, j) } }
return CMMatrix(Array2DRowRealMatrix(array))
}
@@ -82,40 +43,98 @@ public object CMMatrixContext : MatrixContext {
else -> {
//TODO add feature analysis
val array = Array(rowNum) { i -> DoubleArray(colNum) { j -> get(i, j) } }
- CMMatrix(Array2DRowRealMatrix(array))
+ Array2DRowRealMatrix(array).wrap()
}
}
- override fun scale(a: Matrix, value: Double): Matrix = a.toCM().times(value)
+ public fun Point.toCM(): CMVector = if (this is CMVector) this else {
+ val array = DoubleArray(size) { this[it] }
+ ArrayRealVector(array).wrap()
+ }
+ internal fun RealMatrix.wrap(): CMMatrix = CMMatrix(this)
+ internal fun RealVector.wrap(): CMVector = CMVector(this)
+
+ override fun buildVector(size: Int, initializer: DoubleField.(Int) -> Double): Point =
+ ArrayRealVector(DoubleArray(size) { DoubleField.initializer(it) }).wrap()
+
+ override fun Matrix.plus(other: Matrix): CMMatrix =
+ toCM().origin.add(other.toCM().origin).wrap()
+
+ override fun Point.plus(other: Point): CMVector =
+ toCM().origin.add(other.toCM().origin).wrap()
+
+ override fun Point.minus(other: Point): CMVector =
+ toCM().origin.subtract(other.toCM().origin).wrap()
public override fun Matrix.dot(other: Matrix): CMMatrix =
- CMMatrix(toCM().origin.multiply(other.toCM().origin))
+ toCM().origin.multiply(other.toCM().origin).wrap()
public override fun Matrix.dot(vector: Point): CMVector =
- CMVector(toCM().origin.preMultiply(vector.toCM().origin))
+ toCM().origin.preMultiply(vector.toCM().origin).wrap()
- public override operator fun Matrix.unaryMinus(): CMMatrix =
- produce(rowNum, colNum) { i, j -> -get(i, j) }
-
- public override fun add(a: Matrix, b: Matrix): CMMatrix =
- CMMatrix(a.toCM().origin.multiply(b.toCM().origin))
-
- public override operator fun Matrix.minus(b: Matrix): CMMatrix =
- CMMatrix(toCM().origin.subtract(b.toCM().origin))
-
-// public override fun multiply(a: Matrix, k: Number): CMMatrix =
-// CMMatrix(a.toCM().origin.scalarMultiply(k.toDouble()))
+ public override operator fun Matrix