diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 25f2cfd0d..f39e12a12 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,6 +8,7 @@ jobs: matrix: os: [ macOS-latest, windows-latest ] runs-on: ${{matrix.os}} + timeout-minutes: 30 steps: - name: Checkout the repo uses: actions/checkout@v2 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/.gitignore b/.gitignore index 07589aa00..2a13b9e3c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,11 @@ .gradle build/ out/ + .idea/ + +!.idea/copyright/ + .vscode/ # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) diff --git a/.idea/copyright/kmath.xml b/.idea/copyright/kmath.xml new file mode 100644 index 000000000..6fe438777 --- /dev/null +++ b/.idea/copyright/kmath.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 000000000..6cc25cb4a --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index eb97698c6..c3bd2641a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,20 +4,35 @@ ### Added - ScaleOperations interface - Field extends ScaleOperations +- Basic integration API +- Basic MPP distributions and samplers +- bindSymbolOrNull +- Blocking chains and Statistics +- Multiplatform integration +- Integration for any Field element ### 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 +- DataSets are moved from functions to core +- Redesign advanced Chain API +- Redesign MST. Remove MSTExpression. +- Move MST to core ### 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. +- MSTExpression ### Fixed +- Ring inherits RingOperations, not GroupOperations ### Security @@ -73,6 +88,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 bfa5c7fb0..0210b4caf 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ [![JetBrains Research](https://jb.gg/badges/research.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub) [![DOI](https://zenodo.org/badge/129486382.svg)](https://zenodo.org/badge/latestdoi/129486382) - ![Gradle build](https://github.com/mipt-npm/kmath/workflows/Gradle%20build/badge.svg) - -[![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) +[![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) +[![Space](https://img.shields.io/maven-metadata/v?label=Space&metadataUrl=https%3A%2F%2Fmaven.pkg.jetbrains.space%2Fmipt-npm%2Fp%2Fsci%2Fmaven%2Fkscience%2Fkmath%2Fkmath-core%2Fmaven-metadata.xml)](https://maven.pkg.jetbrains.space/mipt-npm/p/sci/maven/space/kscience/) # KMath @@ -89,12 +88,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 +109,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 +120,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
@@ -149,6 +148,12 @@ performance calculations to code generation. > > > **Maturity**: PROTOTYPE +> +> **Features:** +> - [ejml-vector](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : The Point implementation using SimpleMatrix. +> - [ejml-matrix](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : The Matrix implementation using SimpleMatrix. +> - [ejml-linear-space](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : The LinearSpace implementation using SimpleMatrix. +
* ### [kmath-for-real](kmath-for-real) @@ -159,22 +164,23 @@ 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
* ### [kmath-functions](kmath-functions) -> Functions and interpolation +> Functions, integration and interpolation > -> **Maturity**: PROTOTYPE +> **Maturity**: EXPERIMENTAL > > **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/src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt) : Piecewise functions. +> - [polynomials](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt) : Polynomial functions. +> - [linear interpolation](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt) : Linear XY interpolator. +> - [spline interpolation](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt) : Cubic spline XY interpolator. +> - [integration](kmath-functions/#) : Univariate and multivariate quadratures
@@ -208,9 +214,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
@@ -245,6 +251,10 @@ cases. We expect the worst KMath benchmarks will perform better than native Pyth native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be better than SciPy. +## Requirements + +KMath currently relies on JDK 11 for compilation and execution of Kotlin-JVM part. We recommend to use GraalVM-CE 11 for execution in order to get better performance. + ### Repositories Release and development artifacts are accessible from mipt-npm [Space](https://www.jetbrains.com/space/) repository `https://maven.pkg.jetbrains.space/mipt-npm/p/sci/maven` (see documentation of @@ -256,8 +266,8 @@ repositories { } dependencies { - api("space.kscience:kmath-core:0.3.0-dev-2") - // api("space.kscience:kmath-core-jvm:0.3.0-dev-2") for jvm-specific version + api("space.kscience:kmath-core:0.3.0-dev-6") + // api("space.kscience:kmath-core-jvm:0.3.0-dev-6") for jvm-specific version } ``` diff --git a/build.gradle.kts b/build.gradle.kts index ce9cb1528..9b2200cb4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,7 +3,8 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ -import ru.mipt.npm.gradle.KSciencePublishingPlugin +import org.jetbrains.dokka.gradle.DokkaTask +import java.net.URL plugins { id("ru.mipt.npm.gradle.project") @@ -15,21 +16,41 @@ allprojects { maven("https://clojars.org/repo") maven("https://dl.bintray.com/egor-bogomolov/astminer/") maven("https://dl.bintray.com/hotkeytlt/maven") - maven("https://dl.bintray.com/kotlin/kotlin-eap") - maven("https://dl.bintray.com/kotlin/kotlinx") - maven("https://dl.bintray.com/mipt-npm/dev") - maven("https://dl.bintray.com/mipt-npm/kscience") maven("https://jitpack.io") - maven("http://logicrunch.research.it.uu.se/maven/") + maven{ + setUrl("http://logicrunch.research.it.uu.se/maven/") + isAllowInsecureProtocol = true + } mavenCentral() } group = "space.kscience" - version = "0.3.0-dev-2" + version = "0.3.0-dev-6" } subprojects { - if (name.startsWith("kmath")) apply() + if (name.startsWith("kmath")) apply() + + afterEvaluate { + tasks.withType { + dokkaSourceSets.all { + val readmeFile = File(this@subprojects.projectDir, "./README.md") + if (readmeFile.exists()) + includes.setFrom(includes + readmeFile.absolutePath) + + arrayOf( + "http://ejml.org/javadoc/", + "https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/", + "https://deeplearning4j.org/api/latest/" + ).map { URL("${it}package-list") to URL(it) }.forEach { (a, b) -> + externalDocumentationLink { + packageListUrl.set(a) + url.set(b) + } + } + } + } + } } readme { 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 + + + + + + + + + + + + + + + + + + + + + #### Artifact: -> -> This module artifact: `${group}:${name}:${version}`. -> -> Bintray release version: [ ![Download](https://api.bintray.com/packages/mipt-npm/kscience/${name}/images/download.svg) ](https://bintray.com/mipt-npm/kscience/${name}/_latestVersion) -> -> Bintray development version: [ ![Download](https://api.bintray.com/packages/mipt-npm/dev/${name}/images/download.svg) ](https://bintray.com/mipt-npm/dev/${name}/_latestVersion) -> -> **Gradle:** -> -> ```gradle -> repositories { -> maven { url 'https://repo.kotlin.link' } -> maven { url 'https://dl.bintray.com/hotkeytlt/maven' } -> maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap -> } -> -> dependencies { -> implementation '${group}:${name}:${version}' -> } -> ``` -> **Gradle Kotlin DSL:** -> -> ```kotlin -> repositories { -> maven("https://repo.kotlin.link") -> maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap -> maven("https://dl.bintray.com/hotkeytlt/maven") // required for a -> } -> -> dependencies { -> implementation("${group}:${name}:${version}") -> } -> ``` \ No newline at end of file +## Artifact: + +The Maven coordinates of this project are `${group}:${name}:${version}`. + +**Gradle:** +```gradle +repositories { + maven { url 'https://repo.kotlin.link' } + maven { url 'https://dl.bintray.com/hotkeytlt/maven' } + maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap +} + +dependencies { + implementation '${group}:${name}:${version}' +} +``` +**Gradle Kotlin DSL:** +```kotlin +repositories { + maven("https://repo.kotlin.link") + maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap + maven("https://dl.bintray.com/hotkeytlt/maven") // required for a +} + +dependencies { + implementation("${group}:${name}:${version}") +} +``` \ No newline at end of file diff --git a/docs/templates/README-TEMPLATE.md b/docs/templates/README-TEMPLATE.md index f0e68f575..99951b4d6 100644 --- a/docs/templates/README-TEMPLATE.md +++ b/docs/templates/README-TEMPLATE.md @@ -1,9 +1,8 @@ [![JetBrains Research](https://jb.gg/badges/research.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub) [![DOI](https://zenodo.org/badge/129486382.svg)](https://zenodo.org/badge/latestdoi/129486382) - ![Gradle build](https://github.com/mipt-npm/kmath/workflows/Gradle%20build/badge.svg) - -[![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) +[![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) +[![Space](https://img.shields.io/maven-metadata/v?label=Space&metadataUrl=https%3A%2F%2Fmaven.pkg.jetbrains.space%2Fmipt-npm%2Fp%2Fsci%2Fmaven%2Fkscience%2Fkmath%2Fkmath-core%2Fmaven-metadata.xml)](https://maven.pkg.jetbrains.space/mipt-npm/p/sci/maven/space/kscience/) # KMath @@ -95,6 +94,10 @@ cases. We expect the worst KMath benchmarks will perform better than native Pyth native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be better than SciPy. +## Requirements + +KMath currently relies on JDK 11 for compilation and execution of Kotlin-JVM part. We recommend to use GraalVM-CE 11 for execution in order to get better performance. + ### Repositories Release and development artifacts are accessible from mipt-npm [Space](https://www.jetbrains.com/space/) repository `https://maven.pkg.jetbrains.space/mipt-npm/p/sci/maven` (see documentation of diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts index 86ffa94a3..98d7b7073 100644 --- a/examples/build.gradle.kts +++ b/examples/build.gradle.kts @@ -4,11 +4,12 @@ */ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import ru.mipt.npm.gradle.Maturity plugins { kotlin("jvm") kotlin("plugin.allopen") - id("kotlinx.benchmark") + id("org.jetbrains.kotlinx.benchmark") } allOpen.annotation("org.openjdk.jmh.annotations.State") @@ -25,7 +26,10 @@ repositories { maven("https://dl.bintray.com/mipt-npm/dev") maven("https://dl.bintray.com/mipt-npm/kscience") maven("https://jitpack.io") - maven("http://logicrunch.research.it.uu.se/maven/") + maven{ + setUrl("http://logicrunch.research.it.uu.se/maven/") + isAllowInsecureProtocol = true + } mavenCentral() } @@ -58,7 +62,7 @@ dependencies { implementation("org.nd4j:nd4j-native-platform:1.0.0-beta7") implementation("org.jetbrains.kotlinx:kotlinx-io:0.2.0-npm-dev-11") - implementation("org.jetbrains.kotlinx:kotlinx.benchmark.runtime:0.2.0-dev-20") + implementation("org.jetbrains.kotlinx:kotlinx-benchmark-runtime:0.3.0") implementation("org.slf4j:slf4j-simple:1.7.30") // plotting @@ -105,19 +109,31 @@ benchmark { iterationTimeUnit = "ms" // time unity for iterationTime, default is seconds include("MatrixInverseBenchmark") } + + configurations.register("bigInt") { + 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("BigIntBenchmark") + } } kotlin.sourceSets.all { with(languageSettings) { useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts") useExperimentalAnnotation("kotlin.ExperimentalUnsignedTypes") + useExperimentalAnnotation("space.kscience.kmath.misc.UnstableKMathAPI") } } tasks.withType { - kotlinOptions.jvmTarget = "11" + kotlinOptions{ + jvmTarget = "11" + freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all" + } } -readme{ - maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL +readme { + maturity = Maturity.EXPERIMENTAL } diff --git a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt new file mode 100644 index 000000000..672efd5c2 --- /dev/null +++ b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.benchmarks + +import kotlinx.benchmark.Blackhole +import org.openjdk.jmh.annotations.Benchmark +import org.openjdk.jmh.annotations.Scope +import org.openjdk.jmh.annotations.State +import space.kscience.kmath.operations.BigIntField +import space.kscience.kmath.operations.JBigIntegerField +import space.kscience.kmath.operations.invoke + +@State(Scope.Benchmark) +internal class BigIntBenchmark { + + val kmNumber = BigIntField.number(Int.MAX_VALUE) + val jvmNumber = JBigIntegerField.number(Int.MAX_VALUE) + + @Benchmark + fun kmAdd(blackhole: Blackhole) = BigIntField { + blackhole.consume(kmNumber + kmNumber + kmNumber) + } + + @Benchmark + fun jvmAdd(blackhole: Blackhole) = JBigIntegerField { + blackhole.consume(jvmNumber + jvmNumber + jvmNumber) + } + + @Benchmark + fun kmMultiply(blackhole: Blackhole) = BigIntField { + blackhole.consume(kmNumber * kmNumber * kmNumber) + } + + @Benchmark + fun jvmMultiply(blackhole: Blackhole) = JBigIntegerField { + blackhole.consume(jvmNumber * jvmNumber * jvmNumber) + } +} \ No newline at end of file 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 8df4ce4da..39819d407 100644 --- a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt +++ b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt @@ -10,14 +10,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 ad6b8cbd3..23e73cb5f 100644 --- a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt +++ b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt @@ -13,7 +13,7 @@ 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.RealField +import space.kscience.kmath.operations.DoubleField import kotlin.random.Random @State(Scope.Benchmark) @@ -56,7 +56,7 @@ internal class DotBenchmark { @Benchmark fun bufferedDot(blackhole: Blackhole) { - LinearSpace.auto(RealField).invoke { + LinearSpace.auto(DoubleField).invoke { 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 c8e4a5a6f..d6fde8398 100644 --- a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt +++ b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt @@ -9,14 +9,12 @@ import kotlinx.benchmark.Benchmark import kotlinx.benchmark.Blackhole import kotlinx.benchmark.Scope import kotlinx.benchmark.State -import space.kscience.kmath.asm.compile -import space.kscience.kmath.ast.mstInField -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.asm.compileToExpression +import space.kscience.kmath.expressions.* +import space.kscience.kmath.misc.symbol +import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.bindSymbol +import space.kscience.kmath.operations.invoke import kotlin.random.Random @State(Scope.Benchmark) @@ -33,20 +31,20 @@ internal class ExpressionsInterpretersBenchmark { @Benchmark fun mstExpression(blackhole: Blackhole) { - val expr = algebra.mstInField { + val expr = MstField { val x = bindSymbol(x) x * 2.0 + number(2.0) / x - 16.0 - } + }.toExpression(algebra) invokeAndSum(expr, blackhole) } @Benchmark fun asmExpression(blackhole: Blackhole) { - val expr = algebra.mstInField { + val expr = MstField { val x = bindSymbol(x) x * 2.0 + number(2.0) / x - 16.0 - }.compile() + }.compileToExpression(algebra) invokeAndSum(expr, blackhole) } @@ -73,7 +71,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/NDFieldBenchmark.kt b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt index 9a67d2afa..5e0c6735f 100644 --- a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt +++ b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt @@ -10,7 +10,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) @@ -18,7 +18,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) } @@ -27,7 +27,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) } @@ -37,7 +37,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) } @@ -46,8 +46,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 4aac2568e..d2359a791 100644 --- a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt +++ b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt @@ -10,11 +10,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) @@ -22,7 +22,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) } @@ -31,7 +31,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) } @@ -59,8 +59,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 cd4b18f7b..eac8634f5 100644 --- a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt +++ b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt @@ -10,11 +10,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.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 { @@ -51,8 +51,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 realNdField = 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/astRendering.kt b/examples/src/main/kotlin/space/kscience/kmath/ast/astRendering.kt new file mode 100644 index 000000000..e16769464 --- /dev/null +++ b/examples/src/main/kotlin/space/kscience/kmath/ast/astRendering.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.ast + +import space.kscience.kmath.ast.rendering.FeaturedMathRendererWithPostProcess +import space.kscience.kmath.ast.rendering.LatexSyntaxRenderer +import space.kscience.kmath.ast.rendering.MathMLSyntaxRenderer +import space.kscience.kmath.ast.rendering.renderWithStringBuilder + +public fun main() { + val mst = "exp(sqrt(x))-asin(2*x)/(2e10+x^3)/(-12)".parseMath() + val syntax = FeaturedMathRendererWithPostProcess.Default.render(mst) + println("MathSyntax:") + println(syntax) + println() + val latex = LatexSyntaxRenderer.renderWithStringBuilder(syntax) + println("LaTeX:") + println(latex) + println() + val mathML = MathMLSyntaxRenderer.renderWithStringBuilder(syntax) + println("MathML:") + println(mathML) +} 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 c4531df51..918134e04 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/ast/expressions.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/ast/expressions.kt @@ -5,16 +5,20 @@ package space.kscience.kmath.ast -import space.kscience.kmath.expressions.invoke -import space.kscience.kmath.operations.RealField +import space.kscience.kmath.expressions.MstField +import space.kscience.kmath.expressions.interpret +import space.kscience.kmath.misc.Symbol.Companion.x +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.bindSymbol +import space.kscience.kmath.operations.invoke fun main() { - val expr = RealField.mstInField { - val x = bindSymbol("x") + val expr = MstField { + val x = bindSymbol(x) x * 2.0 + number(2.0) / x - 16.0 } repeat(10000000) { - expr.invoke("x" to 1.0) + expr.interpret(DoubleField, x to 1.0) } } \ No newline at end of file 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 de784fbef..4a31f33a3 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/ast/kotlingradSupport.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/ast/kotlingradSupport.kt @@ -5,12 +5,12 @@ package space.kscience.kmath.ast -import space.kscience.kmath.asm.compile +import space.kscience.kmath.asm.compileToExpression 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.kotlingrad.toDiffExpression +import space.kscience.kmath.misc.symbol +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 @@ -19,11 +19,11 @@ import space.kscience.kmath.operations.RealField fun main() { val x by symbol - val actualDerivative = MstExpression(RealField, "x^2-4*x-44".parseMath()) - .differentiable() + val actualDerivative = "x^2-4*x-44".parseMath() + .toDiffExpression(DoubleField) .derivative(x) - .compile() - val expectedDerivative = MstExpression(RealField, "2*x-4".parseMath()).compile() + + val expectedDerivative = "2*x-4".parseMath().compileToExpression(DoubleField) 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 a569e7bb0..be4dc461b 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 @@ -12,11 +12,14 @@ import kscience.plotly.models.ScatterMode 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.distributions.NormalDistribution +import space.kscience.kmath.misc.symbol +import space.kscience.kmath.optimization.FunctionOptimization +import space.kscience.kmath.optimization.OptimizationResult +import space.kscience.kmath.real.DoubleVector import space.kscience.kmath.real.map import space.kscience.kmath.real.step -import space.kscience.kmath.stat.* +import space.kscience.kmath.stat.RandomGenerator import space.kscience.kmath.structures.asIterable import space.kscience.kmath.structures.toList import kotlin.math.pow @@ -31,17 +34,16 @@ 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() } /** * Least squares fie with auto-differentiation. Uses `kmath-commons` and `kmath-for-real` modules. */ -fun main() { - +suspend fun main() { //A generator for a normally distributed values - val generator = Distribution.normal() + val generator = NormalDistribution(2.0, 7.0) //A chain/flow of random values with the given seed val chain = generator.sample(RandomGenerator.default(112667)) @@ -54,7 +56,7 @@ fun main() { //Perform an operation on each x value (much more effective, than numpy) val y = x.map { val value = it.pow(2) + it + 1 - value + chain.nextDouble() * sqrt(value) + value + chain.next() * sqrt(value) } // this will also work, but less effective: // val y = x.pow(2)+ x + 1 + chain.nextDouble() @@ -63,10 +65,10 @@ fun main() { val yErr = y.map { sqrt(it) }//RealVector.same(x.size, sigma) // compute differentiable chi^2 sum for given model ax^2 + bx + c - val chi2 = Fitting.chiSquared(x, y, yErr) { x1 -> + val chi2 = FunctionOptimization.chiSquared(x, y, yErr) { x1 -> //bind variables to autodiff context - val a = bind(a) - val b = bind(b) + val a = bindSymbol(a) + val b = bindSymbol(b) //Include default value for c if it is not provided as a parameter val c = bindSymbolOrNull(c) ?: one a * x1.pow(2) + b * x1 + c @@ -95,13 +97,13 @@ fun main() { } } br() - h3{ + h3 { +"Fit result: $result" } - h3{ + h3 { +"Chi2/dof = ${result.value / (x.size - 3)}" } } page.makeFile() -} \ No newline at end of file +} diff --git a/examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt b/examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt new file mode 100644 index 000000000..90542adf4 --- /dev/null +++ b/examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt @@ -0,0 +1,17 @@ +package space.kscience.kmath.functions + +import space.kscience.kmath.integration.integrate +import space.kscience.kmath.integration.value +import space.kscience.kmath.operations.DoubleField +import kotlin.math.pow + +fun main() { + //Define a function + val function: UnivariateFunction = { x -> 3 * x.pow(2) + 2 * x + 1 } + + //get the result of the integration + val result = DoubleField.integrate(0.0..10.0, function = function) + + //the value is nullable because in some cases the integration could not succeed + println(result.value) +} \ No newline at end of file diff --git a/examples/src/main/kotlin/space/kscience/kmath/functions/matrixIntegration.kt b/examples/src/main/kotlin/space/kscience/kmath/functions/matrixIntegration.kt new file mode 100644 index 000000000..bd431c22c --- /dev/null +++ b/examples/src/main/kotlin/space/kscience/kmath/functions/matrixIntegration.kt @@ -0,0 +1,27 @@ +package space.kscience.kmath.functions + +import space.kscience.kmath.integration.integrate +import space.kscience.kmath.integration.value +import space.kscience.kmath.nd.StructureND +import space.kscience.kmath.nd.nd +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.invoke + +fun main(): Unit = DoubleField { + nd(2, 2) { + + //Produce a diagonal StructureND + fun diagonal(v: Double) = produce { (i, j) -> + if (i == j) v else 0.0 + } + + //Define a function in a nd space + val function: (Double) -> StructureND = { x: Double -> 3 * number(x).pow(2) + 2 * diagonal(x) + 1 } + + //get the result of the integration + val result = integrate(0.0..10.0, function = function) + + //the value is nullable because in some cases the integration could not succeed + println(result.value) + } +} \ No newline at end of file diff --git a/examples/src/main/kotlin/space/kscience/kmath/linear/gradient.kt b/examples/src/main/kotlin/space/kscience/kmath/linear/gradient.kt index 77bb75a5f..f7b284e89 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/linear/gradient.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/linear/gradient.kt @@ -6,11 +6,11 @@ package space.kscience.kmath.linear import space.kscience.kmath.real.* -import space.kscience.kmath.structures.RealBuffer +import space.kscience.kmath.structures.DoubleBuffer fun main() { - val x0 = Point(0.0, 0.0, 0.0) - val sigma = Point(1.0, 1.0, 1.0) + 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) @@ -19,9 +19,9 @@ fun main() { fun ((Point) -> Double).grad(x: Point): Point { require(x.size == x0.size) - return RealBuffer(x.size) { i -> + return DoubleBuffer(x.size) { i -> val h = sigma[i] / 5 - val dVector = RealBuffer(x.size) { if (it == i) h else 0.0 } + 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 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 324ce641f..f99dd8c0e 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/operations/ComplexDemo.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/operations/ComplexDemo.kt @@ -7,17 +7,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/stat/DistributionBenchmark.kt b/examples/src/main/kotlin/space/kscience/kmath/stat/DistributionBenchmark.kt index eb50b26be..8e3cdf86f 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/stat/DistributionBenchmark.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/stat/DistributionBenchmark.kt @@ -3,26 +3,27 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ -package kscience.kmath.commons.prob +package space.kscience.kmath.stat import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.runBlocking -import org.apache.commons.rng.sampling.distribution.ZigguratNormalizedGaussianSampler +import org.apache.commons.rng.sampling.distribution.BoxMullerNormalizedGaussianSampler import org.apache.commons.rng.simple.RandomSource -import space.kscience.kmath.stat.* +import space.kscience.kmath.samplers.GaussianSampler import java.time.Duration import java.time.Instant +import org.apache.commons.rng.sampling.distribution.GaussianSampler as CMGaussianSampler -private fun runChain(): Duration { +private suspend fun runKMathChained(): Duration { val generator = RandomGenerator.fromSource(RandomSource.MT, 123L) - val normal = Distribution.normal(NormalSamplerMethod.Ziggurat) + val normal = GaussianSampler(7.0, 2.0) val chain = normal.sample(generator) val startTime = Instant.now() var sum = 0.0 repeat(10000001) { counter -> - sum += chain.nextDouble() + sum += chain.next() if (counter % 100000 == 0) { val duration = Duration.between(startTime, Instant.now()) @@ -34,9 +35,15 @@ private fun runChain(): Duration { return Duration.between(startTime, Instant.now()) } -private fun runDirect(): Duration { - val provider = RandomSource.create(RandomSource.MT, 123L) - val sampler = ZigguratNormalizedGaussianSampler(provider) +private fun runApacheDirect(): Duration { + val rng = RandomSource.create(RandomSource.MT, 123L) + + val sampler = CMGaussianSampler.of( + BoxMullerNormalizedGaussianSampler.of(rng), + 7.0, + 2.0 + ) + val startTime = Instant.now() var sum = 0.0 @@ -56,11 +63,9 @@ private fun runDirect(): Duration { /** * Comparing chain sampling performance with direct sampling performance */ -fun main() { - runBlocking(Dispatchers.Default) { - val chainJob = async { runChain() } - val directJob = async { runDirect() } - println("Chain: ${chainJob.await()}") - println("Direct: ${directJob.await()}") - } +fun main(): Unit = runBlocking(Dispatchers.Default) { + val directJob = async { runApacheDirect() } + val chainJob = async { runKMathChained() } + println("KMath Chained: ${chainJob.await()}") + println("Apache Direct: ${directJob.await()}") } diff --git a/examples/src/main/kotlin/space/kscience/kmath/stat/DistributionDemo.kt b/examples/src/main/kotlin/space/kscience/kmath/stat/DistributionDemo.kt index 0883e70c5..b319766e3 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/stat/DistributionDemo.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/stat/DistributionDemo.kt @@ -8,14 +8,15 @@ package space.kscience.kmath.stat import kotlinx.coroutines.runBlocking import space.kscience.kmath.chains.Chain import space.kscience.kmath.chains.collectWithState +import space.kscience.kmath.distributions.NormalDistribution /** - * The state of distribution averager + * The state of distribution averager. */ private data class AveragingChainState(var num: Int = 0, var value: Double = 0.0) /** - * Averaging + * Averaging. */ private fun Chain.mean(): Chain = collectWithState(AveragingChainState(), { it.copy() }) { chain -> val next = chain.next() @@ -26,7 +27,7 @@ private fun Chain.mean(): Chain = collectWithState(AveragingChai fun main() { - val normal = Distribution.normal() + val normal = NormalDistribution(0.0, 2.0) val chain = normal.sample(RandomGenerator.default).mean() runBlocking { @@ -37,4 +38,4 @@ fun main() { } } } -} \ No newline at end of file +} 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 90e54bbd8..b30165f71 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/ComplexND.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/ComplexND.kt @@ -9,8 +9,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 @@ -20,12 +20,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 } @@ -36,7 +36,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 65f1d13a5..cc1f5f680 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt @@ -9,7 +9,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 @@ -29,56 +29,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 596142013..000000000 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/ParallelRealNDField.kt +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2018-2021 KMath contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -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..d53cfa9b9 --- /dev/null +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt @@ -0,0 +1,108 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.structures + +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 [java.util.stream.DoubleStream] for parallel + * execution. + */ +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) 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 095467e5a..0d5358354 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/StructureReadBenchmark.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/StructureReadBenchmark.kt @@ -5,17 +5,17 @@ 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 @@ -39,4 +39,4 @@ fun main() { strides.indices().forEach { res = array[strides.offset(it)] } } println("Array reading finished in $time3 millis") -} \ No newline at end of file +} 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 f087a7166..dea7095a8 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/StructureWriteBenchmark.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/StructureWriteBenchmark.kt @@ -5,14 +5,14 @@ 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.buffered(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") @@ -25,10 +25,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/gradle.properties b/gradle.properties index 3aaade368..7e9516660 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,5 +9,5 @@ kotlin.mpp.stability.nowarn=true kotlin.native.enableDependencyPropagation=false kotlin.parallel.tasks.in.project=true org.gradle.configureondemand=true -org.gradle.jvmargs=-XX:MaxMetaspaceSize=2G +org.gradle.jvmargs=-XX:MaxMetaspaceSize=1G org.gradle.parallel=true diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2059e8ea0..442d9132e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,8 +1,3 @@ -# -# Copyright 2018-2021 KMath contributors. -# Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. -# - distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip diff --git a/kmath-ast/README.md b/kmath-ast/README.md index 529586424..b1ef9c7d3 100644 --- a/kmath-ast/README.md +++ b/kmath-ast/README.md @@ -1,49 +1,43 @@ -# Abstract Syntax Tree Expression Representation and Operations (`kmath-ast`) +# Module kmath-ast -This subproject implements the following features: +Abstract syntax tree expression representation and related optimizations. - - [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.3.0-dev-2`. -> -> 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) -> -> Bintray development version: [ ![Download](https://api.bintray.com/packages/mipt-npm/dev/kmath-ast/images/download.svg) ](https://bintray.com/mipt-npm/dev/kmath-ast/_latestVersion) -> -> **Gradle:** -> -> ```gradle -> repositories { -> maven { url 'https://repo.kotlin.link' } -> maven { url 'https://dl.bintray.com/hotkeytlt/maven' } -> maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap -> } -> -> dependencies { -> implementation 'space.kscience:kmath-ast:0.3.0-dev-2' -> } -> ``` -> **Gradle Kotlin DSL:** -> -> ```kotlin -> repositories { -> maven("https://repo.kotlin.link") -> maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap -> maven("https://dl.bintray.com/hotkeytlt/maven") // required for a -> } -> -> dependencies { -> implementation("space.kscience:kmath-ast:0.3.0-dev-2") -> } -> ``` +## Artifact: + +The Maven coordinates of this project are `space.kscience:kmath-ast:0.3.0-dev-6`. + +**Gradle:** +```gradle +repositories { + maven { url 'https://repo.kotlin.link' } + maven { url 'https://dl.bintray.com/hotkeytlt/maven' } + maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap +} + +dependencies { + implementation 'space.kscience:kmath-ast:0.3.0-dev-6' +} +``` +**Gradle Kotlin DSL:** +```kotlin +repositories { + maven("https://repo.kotlin.link") + maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap + maven("https://dl.bintray.com/hotkeytlt/maven") // required for a +} + +dependencies { + implementation("space.kscience:kmath-ast:0.3.0-dev-6") +} +``` ## Dynamic expression code generation @@ -55,7 +49,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: @@ -88,8 +82,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 @@ -103,7 +97,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: @@ -117,3 +111,39 @@ var executable = function (constants, arguments) { #### Known issues - This feature uses `eval` which can be unavailable in several environments. + +## Rendering expressions + +kmath-ast also includes an extensible engine to display expressions in LaTeX or MathML syntax. + +Example usage: + +```kotlin +import space.kscience.kmath.ast.* +import space.kscience.kmath.ast.rendering.* + +public fun main() { + val mst = "exp(sqrt(x))-asin(2*x)/(2e10+x^3)/(-12)".parseMath() + val syntax = FeaturedMathRendererWithPostProcess.Default.render(mst) + val latex = LatexSyntaxRenderer.renderWithStringBuilder(syntax) + println("LaTeX:") + println(latex) + println() + val mathML = MathMLSyntaxRenderer.renderWithStringBuilder(syntax) + println("MathML:") + println(mathML) +} +``` + +Result LaTeX: + +![](http://chart.googleapis.com/chart?cht=tx&chl=e%5E%7B%5Csqrt%7Bx%7D%7D-%5Cfrac%7B%5Cfrac%7B%5Coperatorname%7Bsin%7D%5E%7B-1%7D%5C,%5Cleft(2%5C,x%5Cright)%7D%7B2%5Ctimes10%5E%7B10%7D%2Bx%5E%7B3%7D%7D%7D%7B-12%7D) + +Result MathML (embedding MathML is not allowed by GitHub Markdown): + +```html +ex-sin-12x2×1010+x3-12 +``` + +It is also possible to create custom algorithms of render, and even add support of other markup languages +(see API reference). diff --git a/kmath-ast/build.gradle.kts b/kmath-ast/build.gradle.kts index 76a78a271..3f309b67c 100644 --- a/kmath-ast/build.gradle.kts +++ b/kmath-ast/build.gradle.kts @@ -6,7 +6,8 @@ import ru.mipt.npm.gradle.Maturity plugins { - id("ru.mipt.npm.gradle.mpp") + kotlin("multiplatform") + id("ru.mipt.npm.gradle.common") } kotlin.js { @@ -63,36 +64,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..9ed44d584 100644 --- a/kmath-ast/docs/README-TEMPLATE.md +++ b/kmath-ast/docs/README-TEMPLATE.md @@ -1,6 +1,6 @@ -# Abstract Syntax Tree Expression Representation and Operations (`kmath-ast`) +# Module kmath-ast -This subproject implements the following features: +Abstract syntax tree expression representation and related optimizations. ${features} @@ -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: @@ -78,3 +78,39 @@ var executable = function (constants, arguments) { #### Known issues - This feature uses `eval` which can be unavailable in several environments. + +## Rendering expressions + +kmath-ast also includes an extensible engine to display expressions in LaTeX or MathML syntax. + +Example usage: + +```kotlin +import space.kscience.kmath.ast.* +import space.kscience.kmath.ast.rendering.* + +public fun main() { + val mst = "exp(sqrt(x))-asin(2*x)/(2e10+x^3)/(-12)".parseMath() + val syntax = FeaturedMathRendererWithPostProcess.Default.render(mst) + val latex = LatexSyntaxRenderer.renderWithStringBuilder(syntax) + println("LaTeX:") + println(latex) + println() + val mathML = MathMLSyntaxRenderer.renderWithStringBuilder(syntax) + println("MathML:") + println(mathML) +} +``` + +Result LaTeX: + +![](http://chart.googleapis.com/chart?cht=tx&chl=e%5E%7B%5Csqrt%7Bx%7D%7D-%5Cfrac%7B%5Cfrac%7B%5Coperatorname%7Bsin%7D%5E%7B-1%7D%5C,%5Cleft(2%5C,x%5Cright)%7D%7B2%5Ctimes10%5E%7B10%7D%2Bx%5E%7B3%7D%7D%7D%7B-12%7D) + +Result MathML (embedding MathML is not allowed by GitHub Markdown): + +```html +ex-sin-12x2×1010+x3-12 +``` + +It is also possible to create custom algorithms of render, and even add support of other markup languages +(see API reference). diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/MstExpression.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/MstExpression.kt deleted file mode 100644 index 9329d5877..000000000 --- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/MstExpression.kt +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2018-2021 KMath contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package space.kscience.kmath.ast - -import space.kscience.kmath.expressions.* -import space.kscience.kmath.operations.* -import kotlin.contracts.InvocationKind -import kotlin.contracts.contract - -/** - * The expression evaluates MST on-flight. Should be much faster than functional expression, but slower than - * ASM-generated expressions. - * - * @property algebra the algebra that provides operations. - * @property mst the [MST] node. - * @author Alexander Nozik - */ -public class MstExpression>(public val algebra: A, public val mst: MST) : Expression { - private inner class InnerAlgebra(val arguments: Map) : NumericAlgebra { - override fun bindSymbol(value: String): T = try { - algebra.bindSymbol(value) - } catch (ignored: IllegalStateException) { - null - } ?: arguments.getValue(StringSymbol(value)) - - override fun unaryOperation(operation: String, arg: T): T = - algebra.unaryOperation(operation, arg) - - override fun binaryOperation(operation: String, left: T, right: T): T = - algebra.binaryOperation(operation, left, right) - - override fun unaryOperationFunction(operation: String): (arg: T) -> T = - algebra.unaryOperationFunction(operation) - - override fun binaryOperationFunction(operation: String): (left: T, right: T) -> T = - algebra.binaryOperationFunction(operation) - - @Suppress("UNCHECKED_CAST") - override fun number(value: Number): T = if (algebra is NumericAlgebra<*>) - (algebra as NumericAlgebra).number(value) - else - error("Numeric nodes are not supported by $this") - } - - override operator fun invoke(arguments: Map): T = InnerAlgebra(arguments).evaluate(mst) -} - -/** - * Builds [MstExpression] over [Algebra]. - * - * @author Alexander Nozik - */ -public inline fun , E : Algebra> A.mst( - mstAlgebra: E, - block: E.() -> MST, -): MstExpression = MstExpression(this, mstAlgebra.block()) - -/** - * Builds [MstExpression] over [Group]. - * - * @author Alexander Nozik - */ -public inline fun > A.mstInGroup(block: MstGroup.() -> MST): MstExpression { - contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } - return MstExpression(this, MstGroup.block()) -} - -/** - * Builds [MstExpression] over [Ring]. - * - * @author Alexander Nozik - */ -public inline fun > A.mstInRing(block: MstRing.() -> MST): MstExpression { - contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } - return MstExpression(this, MstRing.block()) -} - -/** - * Builds [MstExpression] over [Field]. - * - * @author Alexander Nozik - */ -public inline fun > A.mstInField(block: MstField.() -> MST): MstExpression { - contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } - return MstExpression(this, MstField.block()) -} - -/** - * Builds [MstExpression] over [ExtendedField]. - * - * @author Iaroslav Postovalov - */ -public inline fun > A.mstInExtendedField(block: MstExtendedField.() -> MST): MstExpression { - contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } - return MstExpression(this, MstExtendedField.block()) -} - -/** - * Builds [MstExpression] over [FunctionalExpressionGroup]. - * - * @author Alexander Nozik - */ -public inline fun > FunctionalExpressionGroup.mstInGroup(block: MstGroup.() -> MST): MstExpression { - contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } - return algebra.mstInGroup(block) -} - -/** - * Builds [MstExpression] over [FunctionalExpressionRing]. - * - * @author Alexander Nozik - */ -public inline fun > FunctionalExpressionRing.mstInRing(block: MstRing.() -> MST): MstExpression { - contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } - return algebra.mstInRing(block) -} - -/** - * Builds [MstExpression] over [FunctionalExpressionField]. - * - * @author Alexander Nozik - */ -public inline fun > FunctionalExpressionField.mstInField(block: MstField.() -> MST): MstExpression { - contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } - return algebra.mstInField(block) -} - -/** - * Builds [MstExpression] over [FunctionalExpressionExtendedField]. - * - * @author Iaroslav Postovalov - */ -public inline fun > FunctionalExpressionExtendedField.mstInExtendedField( - block: MstExtendedField.() -> MST, -): MstExpression { - contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } - return algebra.mstInExtendedField(block) -} diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/LatexSyntaxRenderer.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/LatexSyntaxRenderer.kt new file mode 100644 index 000000000..34230f3c8 --- /dev/null +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/LatexSyntaxRenderer.kt @@ -0,0 +1,134 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.ast.rendering + +/** + * [SyntaxRenderer] implementation for LaTeX. + * + * The generated string is a valid LaTeX fragment to be used in the Math Mode. + * + * Example usage: + * + * ``` + * \documentclass{article} + * \begin{document} + * \begin{equation} + * %code generated by the syntax renderer + * \end{equation} + * \end{document} + * ``` + * + * @author Iaroslav Postovalov + */ +public object LatexSyntaxRenderer : SyntaxRenderer { + public override fun render(node: MathSyntax, output: Appendable): Unit = output.run { + fun render(syntax: MathSyntax) = render(syntax, output) + + when (node) { + is NumberSyntax -> append(node.string) + is SymbolSyntax -> append(node.string) + + is OperatorNameSyntax -> { + append("\\operatorname{") + append(node.name) + append('}') + } + + is SpecialSymbolSyntax -> when (node.kind) { + SpecialSymbolSyntax.Kind.INFINITY -> append("\\infty") + SpecialSymbolSyntax.Kind.SMALL_PI -> append("\\pi") + } + + is OperandSyntax -> { + if (node.parentheses) append("\\left(") + render(node.operand) + if (node.parentheses) append("\\right)") + } + + is UnaryOperatorSyntax -> { + render(node.prefix) + append("\\,") + render(node.operand) + } + + is UnaryPlusSyntax -> { + append('+') + render(node.operand) + } + + is UnaryMinusSyntax -> { + append('-') + render(node.operand) + } + + is RadicalSyntax -> { + append("\\sqrt") + append('{') + render(node.operand) + append('}') + } + + is SuperscriptSyntax -> { + render(node.left) + append("^{") + render(node.right) + append('}') + } + + is SubscriptSyntax -> { + render(node.left) + append("_{") + render(node.right) + append('}') + } + + is BinaryOperatorSyntax -> { + render(node.prefix) + append("\\left(") + render(node.left) + append(',') + render(node.right) + append("\\right)") + } + + is BinaryPlusSyntax -> { + render(node.left) + append('+') + render(node.right) + } + + is BinaryMinusSyntax -> { + render(node.left) + append('-') + render(node.right) + } + + is FractionSyntax -> { + append("\\frac{") + render(node.left) + append("}{") + render(node.right) + append('}') + } + + is RadicalWithIndexSyntax -> { + append("\\sqrt") + append('[') + render(node.left) + append(']') + append('{') + render(node.right) + append('}') + } + + is MultiplicationSyntax -> { + render(node.left) + append(if (node.times) "\\times" else "\\,") + render(node.right) + } + } + } +} diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathMLSyntaxRenderer.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathMLSyntaxRenderer.kt new file mode 100644 index 000000000..f7487a356 --- /dev/null +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathMLSyntaxRenderer.kt @@ -0,0 +1,139 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.ast.rendering + +/** + * [SyntaxRenderer] implementation for MathML. + * + * The generated XML string is a valid MathML instance. + * + * @author Iaroslav Postovalov + */ +public object MathMLSyntaxRenderer : SyntaxRenderer { + public override fun render(node: MathSyntax, output: Appendable) { + output.append("") + render0(node, output) + output.append("") + } + + private fun render0(node: MathSyntax, output: Appendable): Unit = output.run { + fun tag(tagName: String, vararg attr: Pair, block: () -> Unit = {}) { + append('<') + append(tagName) + + if (attr.isNotEmpty()) { + append(' ') + var count = 0 + + for ((name, value) in attr) { + if (++count > 1) append(' ') + append(name) + append("=\"") + append(value) + append('"') + } + } + + append('>') + block() + append("') + } + + fun render(syntax: MathSyntax) = render0(syntax, output) + + when (node) { + is NumberSyntax -> tag("mn") { append(node.string) } + is SymbolSyntax -> tag("mi") { append(node.string) } + is OperatorNameSyntax -> tag("mo") { append(node.name) } + + is SpecialSymbolSyntax -> when (node.kind) { + SpecialSymbolSyntax.Kind.INFINITY -> tag("mo") { append("∞") } + SpecialSymbolSyntax.Kind.SMALL_PI -> tag("mo") { append("π") } + } + + is OperandSyntax -> if (node.parentheses) { + tag("mfenced", "open" to "(", "close" to ")", "separators" to "") { + render(node.operand) + } + } else { + render(node.operand) + } + + is UnaryOperatorSyntax -> { + render(node.prefix) + tag("mspace", "width" to "0.167em") + render(node.operand) + } + + is UnaryPlusSyntax -> { + tag("mo") { append('+') } + render(node.operand) + } + + is UnaryMinusSyntax -> { + tag("mo") { append("-") } + render(node.operand) + } + + is RadicalSyntax -> tag("msqrt") { render(node.operand) } + + is SuperscriptSyntax -> tag("msup") { + tag("mrow") { render(node.left) } + tag("mrow") { render(node.right) } + } + + is SubscriptSyntax -> tag("msub") { + tag("mrow") { render(node.left) } + tag("mrow") { render(node.right) } + } + + is BinaryOperatorSyntax -> { + render(node.prefix) + + tag("mfenced", "open" to "(", "close" to ")", "separators" to "") { + render(node.left) + tag("mo") { append(',') } + render(node.right) + } + } + + is BinaryPlusSyntax -> { + render(node.left) + tag("mo") { append('+') } + render(node.right) + } + + is BinaryMinusSyntax -> { + render(node.left) + tag("mo") { append('-') } + render(node.right) + } + + is FractionSyntax -> tag("mfrac") { + tag("mrow") { + render(node.left) + } + + tag("mrow") { + render(node.right) + } + } + + is RadicalWithIndexSyntax -> tag("mroot") { + tag("mrow") { render(node.right) } + tag("mrow") { render(node.left) } + } + + is MultiplicationSyntax -> { + render(node.left) + if (node.times) tag("mo") { append("×") } else tag("mspace", "width" to "0.167em") + render(node.right) + } + } + } +} diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt new file mode 100644 index 000000000..891e8f05b --- /dev/null +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt @@ -0,0 +1,108 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.ast.rendering + +import space.kscience.kmath.expressions.MST + +/** + * Renders [MST] to [MathSyntax]. + * + * @author Iaroslav Postovalov + */ +public fun interface MathRenderer { + /** + * Renders [MST] to [MathSyntax]. + */ + public fun render(mst: MST): MathSyntax +} + +/** + * Implements [MST] render process with sequence of features. + * + * @property features The applied features. + * @author Iaroslav Postovalov + */ +public open class FeaturedMathRenderer(public val features: List) : MathRenderer { + public override fun render(mst: MST): MathSyntax { + for (feature in features) feature.render(this, mst)?.let { return it } + throw UnsupportedOperationException("Renderer $this has no appropriate feature to render node $mst.") + } + + /** + * Logical unit of [MST] rendering. + */ + public fun interface RenderFeature { + /** + * Renders [MST] to [MathSyntax] in the context of owning renderer. + */ + public fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? + } +} + +/** + * Extends [FeaturedMathRenderer] by adding post-processing stages. + * + * @property stages The applied stages. + * @author Iaroslav Postovalov + */ +public open class FeaturedMathRendererWithPostProcess( + features: List, + public val stages: List, +) : FeaturedMathRenderer(features) { + public override fun render(mst: MST): MathSyntax { + val res = super.render(mst) + for (stage in stages) stage.perform(res) + return res + } + + /** + * Logical unit of [MathSyntax] post-processing. + */ + public fun interface PostProcessStage { + /** + * Performs the specified action over [MathSyntax]. + */ + public fun perform(node: MathSyntax) + } + + public companion object { + /** + * The default setup of [FeaturedMathRendererWithPostProcess]. + */ + public val Default: FeaturedMathRendererWithPostProcess = FeaturedMathRendererWithPostProcess( + listOf( + // Printing known operations + BinaryPlus.Default, + BinaryMinus.Default, + UnaryPlus.Default, + UnaryMinus.Default, + Multiplication.Default, + Fraction.Default, + Power.Default, + SquareRoot.Default, + Exponential.Default, + InverseTrigonometricOperations.Default, + + // Fallback option for unknown operations - printing them as operator + BinaryOperator.Default, + UnaryOperator.Default, + + // Pretty printing for some objects + PrettyPrintFloats.Default, + PrettyPrintIntegers.Default, + PrettyPrintPi.Default, + + // Printing terminal nodes as string + PrintNumeric, + PrintSymbolic, + ), + listOf( + SimplifyParentheses.Default, + BetterMultiplication, + ), + ) + } +} diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathSyntax.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathSyntax.kt new file mode 100644 index 000000000..069e56c71 --- /dev/null +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathSyntax.kt @@ -0,0 +1,336 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.ast.rendering + +/** + * Mathematical typography syntax node. + * + * @author Iaroslav Postovalov + */ +public sealed class MathSyntax { + /** + * The parent node of this syntax node. + */ + public var parent: MathSyntax? = null +} + +/** + * Terminal node, which should not have any children nodes. + * + * @author Iaroslav Postovalov + */ +public sealed class TerminalSyntax : MathSyntax() + +/** + * Node containing a certain operation. + * + * @author Iaroslav Postovalov + */ +public sealed class OperationSyntax : MathSyntax() { + /** + * The operation token. + */ + public abstract val operation: String +} + +/** + * Unary node, which has only one child. + * + * @author Iaroslav Postovalov + */ +public sealed class UnarySyntax : OperationSyntax() { + /** + * The operand of this node. + */ + public abstract val operand: MathSyntax +} + +/** + * Binary node, which has only two children. + * + * @author Iaroslav Postovalov + */ +public sealed class BinarySyntax : OperationSyntax() { + /** + * The left-hand side operand. + */ + public abstract val left: MathSyntax + + /** + * The right-hand side operand. + */ + public abstract val right: MathSyntax +} + +/** + * Represents a number. + * + * @property string The digits of number. + * @author Iaroslav Postovalov + */ +public data class NumberSyntax(public var string: String) : TerminalSyntax() + +/** + * Represents a symbol. + * + * @property string The symbol. + * @author Iaroslav Postovalov + */ +public data class SymbolSyntax(public var string: String) : TerminalSyntax() + +/** + * Represents special typing for operator name. + * + * @property name The operator name. + * @see BinaryOperatorSyntax + * @see UnaryOperatorSyntax + * @author Iaroslav Postovalov + */ +public data class OperatorNameSyntax(public var name: String) : TerminalSyntax() + +/** + * Represents a usage of special symbols. + * + * @property kind The kind of symbol. + * @author Iaroslav Postovalov + */ +public data class SpecialSymbolSyntax(public var kind: Kind) : TerminalSyntax() { + /** + * The kind of symbol. + */ + public enum class Kind { + /** + * The infinity (∞) symbol. + */ + INFINITY, + + /** + * The Pi (π) symbol. + */ + SMALL_PI; + } +} + +/** + * Represents operand of a certain operator wrapped with parentheses or not. + * + * @property operand The operand. + * @property parentheses Whether the operand should be wrapped with parentheses. + * @author Iaroslav Postovalov + */ +public data class OperandSyntax( + public val operand: MathSyntax, + public var parentheses: Boolean, +) : MathSyntax() { + init { + operand.parent = this + } +} + +/** + * Represents unary, prefix operator syntax (like f x). + * + * @property prefix The prefix. + * @author Iaroslav Postovalov + */ +public data class UnaryOperatorSyntax( + public override val operation: String, + public var prefix: MathSyntax, + public override val operand: OperandSyntax, +) : UnarySyntax() { + init { + operand.parent = this + } +} + +/** + * Represents prefix, unary plus operator. + * + * @author Iaroslav Postovalov + */ +public data class UnaryPlusSyntax( + public override val operation: String, + public override val operand: OperandSyntax, +) : UnarySyntax() { + init { + operand.parent = this + } +} + +/** + * Represents prefix, unary minus operator. + * + * @author Iaroslav Postovalov + */ +public data class UnaryMinusSyntax( + public override val operation: String, + public override val operand: OperandSyntax, +) : UnarySyntax() { + init { + operand.parent = this + } +} + +/** + * Represents radical with a node inside it. + * + * @property operand The radicand. + * @author Iaroslav Postovalov + */ +public data class RadicalSyntax( + public override val operation: String, + public override val operand: MathSyntax, +) : UnarySyntax() { + init { + operand.parent = this + } +} + +/** + * Represents a syntax node with superscript (usually, for exponentiation). + * + * @property left The node. + * @property right The superscript. + * @author Iaroslav Postovalov + */ +public data class SuperscriptSyntax( + public override val operation: String, + public override val left: MathSyntax, + public override val right: MathSyntax, +) : BinarySyntax() { + init { + left.parent = this + right.parent = this + } +} + +/** + * Represents a syntax node with subscript. + * + * @property left The node. + * @property right The subscript. + * @author Iaroslav Postovalov + */ +public data class SubscriptSyntax( + public override val operation: String, + public override val left: MathSyntax, + public override val right: MathSyntax, +) : BinarySyntax() { + init { + left.parent = this + right.parent = this + } +} + +/** + * Represents binary, prefix operator syntax (like f(a, b)). + * + * @property prefix The prefix. + * @author Iaroslav Postovalov + */ +public data class BinaryOperatorSyntax( + public override val operation: String, + public var prefix: MathSyntax, + public override val left: MathSyntax, + public override val right: MathSyntax, +) : BinarySyntax() { + init { + left.parent = this + right.parent = this + } +} + +/** + * Represents binary, infix addition. + * + * @param left The augend. + * @param right The addend. + * @author Iaroslav Postovalov + */ +public data class BinaryPlusSyntax( + public override val operation: String, + public override val left: OperandSyntax, + public override val right: OperandSyntax, +) : BinarySyntax() { + init { + left.parent = this + right.parent = this + } +} + +/** + * Represents binary, infix subtraction. + * + * @param left The minuend. + * @param right The subtrahend. + * @author Iaroslav Postovalov + */ +public data class BinaryMinusSyntax( + public override val operation: String, + public override val left: OperandSyntax, + public override val right: OperandSyntax, +) : BinarySyntax() { + init { + left.parent = this + right.parent = this + } +} + +/** + * Represents fraction with numerator and denominator. + * + * @property left The numerator. + * @property right The denominator. + * @author Iaroslav Postovalov + */ +public data class FractionSyntax( + public override val operation: String, + public override val left: MathSyntax, + public override val right: MathSyntax, +) : BinarySyntax() { + init { + left.parent = this + right.parent = this + } +} + +/** + * Represents radical syntax with index. + * + * @property left The index. + * @property right The radicand. + * @author Iaroslav Postovalov + */ +public data class RadicalWithIndexSyntax( + public override val operation: String, + public override val left: MathSyntax, + public override val right: MathSyntax, +) : BinarySyntax() { + init { + left.parent = this + right.parent = this + } +} + +/** + * Represents binary, infix multiplication in the form of coefficient (2 x) or with operator (x×2). + * + * @property left The multiplicand. + * @property right The multiplier. + * @property times whether the times (×) symbol should be used. + * @author Iaroslav Postovalov + */ +public data class MultiplicationSyntax( + public override val operation: String, + public override val left: OperandSyntax, + public override val right: OperandSyntax, + public var times: Boolean, +) : BinarySyntax() { + init { + left.parent = this + right.parent = this + } +} diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/SyntaxRenderer.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/SyntaxRenderer.kt new file mode 100644 index 000000000..7fa91e158 --- /dev/null +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/SyntaxRenderer.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.ast.rendering + +/** + * Abstraction of writing [MathSyntax] as a string of an actual markup language. Typical implementation should + * involve traversal of MathSyntax with handling each its subtype. + * + * @author Iaroslav Postovalov + */ +public fun interface SyntaxRenderer { + /** + * Renders the [MathSyntax] to [output]. + */ + public fun render(node: MathSyntax, output: Appendable) +} + +/** + * Calls [SyntaxRenderer.render] with given [node] and a new [StringBuilder] instance, and returns its content. + * + * @author Iaroslav Postovalov + */ +public fun SyntaxRenderer.renderWithStringBuilder(node: MathSyntax): String { + val sb = StringBuilder() + render(node, sb) + return sb.toString() +} diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt new file mode 100644 index 000000000..5d6c7bb0a --- /dev/null +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt @@ -0,0 +1,336 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.ast.rendering + +import space.kscience.kmath.ast.rendering.FeaturedMathRenderer.RenderFeature +import space.kscience.kmath.expressions.MST +import space.kscience.kmath.operations.* +import kotlin.reflect.KClass + +/** + * Prints any [MST.Symbolic] as a [SymbolSyntax] containing the [MST.Symbolic.value] of it. + * + * @author Iaroslav Postovalov + */ +public object PrintSymbolic : RenderFeature { + public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? { + if (node !is MST.Symbolic) return null + return SymbolSyntax(string = node.value) + } +} + +/** + * Prints any [MST.Numeric] as a [NumberSyntax] containing the [Any.toString] result of it. + * + * @author Iaroslav Postovalov + */ +public object PrintNumeric : RenderFeature { + public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? { + if (node !is MST.Numeric) return null + return NumberSyntax(string = node.value.toString()) + } +} + +private fun printSignedNumberString(s: String): MathSyntax { + if (s.startsWith('-')) + return UnaryMinusSyntax( + operation = GroupOperations.MINUS_OPERATION, + operand = OperandSyntax( + operand = NumberSyntax(string = s.removePrefix("-")), + parentheses = true, + ), + ) + + return NumberSyntax(string = s) +} + +/** + * Special printing for numeric types which are printed in form of + * *('-'? (DIGIT+ ('.' DIGIT+)? ('E' '-'? DIGIT+)? | 'Infinity')) | 'NaN'*. + * + * @property types The suitable types. + */ +public class PrettyPrintFloats(public val types: Set>) : RenderFeature { + public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? { + if (node !is MST.Numeric || node.value::class !in types) return null + val toString = node.value.toString().removeSuffix(".0") + + if ('E' in toString) { + val (beforeE, afterE) = toString.split('E') + val significand = beforeE.toDouble().toString().removeSuffix(".0") + val exponent = afterE.toDouble().toString().removeSuffix(".0") + + return MultiplicationSyntax( + operation = RingOperations.TIMES_OPERATION, + left = OperandSyntax(operand = NumberSyntax(significand), parentheses = true), + right = OperandSyntax( + operand = SuperscriptSyntax( + operation = PowerOperations.POW_OPERATION, + left = NumberSyntax(string = "10"), + right = printSignedNumberString(exponent), + ), + parentheses = true, + ), + times = true, + ) + } + + if (toString.endsWith("Infinity")) { + val infty = SpecialSymbolSyntax(SpecialSymbolSyntax.Kind.INFINITY) + + if (toString.startsWith('-')) + return UnaryMinusSyntax( + operation = GroupOperations.MINUS_OPERATION, + operand = OperandSyntax(operand = infty, parentheses = true), + ) + + return infty + } + + return printSignedNumberString(toString) + } + + public companion object { + /** + * The default instance containing [Float], and [Double]. + */ + public val Default: PrettyPrintFloats = PrettyPrintFloats(setOf(Float::class, Double::class)) + } +} + +/** + * Special printing for numeric types which are printed in form of *'-'? DIGIT+*. + * + * @property types The suitable types. + */ +public class PrettyPrintIntegers(public val types: Set>) : RenderFeature { + public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? { + if (node !is MST.Numeric || node.value::class !in types) + return null + + return printSignedNumberString(node.value.toString()) + } + + public companion object { + /** + * The default instance containing [Byte], [Short], [Int], and [Long]. + */ + public val Default: PrettyPrintIntegers = + PrettyPrintIntegers(setOf(Byte::class, Short::class, Int::class, Long::class)) + } +} + +/** + * Special printing for symbols meaning Pi. + * + * @property symbols The allowed symbols. + */ +public class PrettyPrintPi(public val symbols: Set) : RenderFeature { + public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? { + if (node !is MST.Symbolic || node.value !in symbols) return null + return SpecialSymbolSyntax(kind = SpecialSymbolSyntax.Kind.SMALL_PI) + } + + public companion object { + /** + * The default instance containing `pi`. + */ + public val Default: PrettyPrintPi = PrettyPrintPi(setOf("pi")) + } +} + +/** + * Abstract printing of unary operations which discards [MST] if their operation is not in [operations] or its type is + * not [MST.Unary]. + * + * @param operations the allowed operations. If `null`, any operation is accepted. + */ +public abstract class Unary(public val operations: Collection?) : RenderFeature { + /** + * The actual render function. + */ + protected abstract fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax? + + public final override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? { + if (node !is MST.Unary || operations != null && node.operation !in operations) return null + return render0(renderer, node) + } +} + +/** + * Abstract printing of unary operations which discards [MST] if their operation is not in [operations] or its type is + * not [MST.Binary]. + * + * @property operations the allowed operations. If `null`, any operation is accepted. + */ +public abstract class Binary(public val operations: Collection?) : RenderFeature { + /** + * The actual render function. + */ + protected abstract fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax? + + public final override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? { + if (node !is MST.Binary || operations != null && node.operation !in operations) return null + return render0(renderer, node) + } +} + +public class BinaryPlus(operations: Collection?) : Binary(operations) { + public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = BinaryPlusSyntax( + operation = node.operation, + left = OperandSyntax(parent.render(node.left), true), + right = OperandSyntax(parent.render(node.right), true), + ) + + public companion object { + public val Default: BinaryPlus = BinaryPlus(setOf(GroupOperations.PLUS_OPERATION)) + } +} + +public class BinaryMinus(operations: Collection?) : Binary(operations) { + public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = BinaryMinusSyntax( + operation = node.operation, + left = OperandSyntax(operand = parent.render(node.left), parentheses = true), + right = OperandSyntax(operand = parent.render(node.right), parentheses = true), + ) + + public companion object { + public val Default: BinaryMinus = BinaryMinus(setOf(GroupOperations.MINUS_OPERATION)) + } +} + +public class UnaryPlus(operations: Collection?) : Unary(operations) { + public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = UnaryPlusSyntax( + operation = node.operation, + operand = OperandSyntax(operand = parent.render(node.value), parentheses = true), + ) + + public companion object { + public val Default: UnaryPlus = UnaryPlus(setOf(GroupOperations.PLUS_OPERATION)) + } +} + +public class UnaryMinus(operations: Collection?) : Unary(operations) { + public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = UnaryMinusSyntax( + operation = node.operation, + operand = OperandSyntax(operand = parent.render(node.value), parentheses = true), + ) + + public companion object { + public val Default: UnaryMinus = UnaryMinus(setOf(GroupOperations.MINUS_OPERATION)) + } +} + +public class Fraction(operations: Collection?) : Binary(operations) { + public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = FractionSyntax( + operation = node.operation, + left = parent.render(node.left), + right = parent.render(node.right), + ) + + public companion object { + public val Default: Fraction = Fraction(setOf(FieldOperations.DIV_OPERATION)) + } +} + +public class BinaryOperator(operations: Collection?) : Binary(operations) { + public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = BinaryOperatorSyntax( + operation = node.operation, + prefix = OperatorNameSyntax(name = node.operation), + left = parent.render(node.left), + right = parent.render(node.right), + ) + + public companion object { + public val Default: BinaryOperator = BinaryOperator(null) + } +} + +public class UnaryOperator(operations: Collection?) : Unary(operations) { + public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = UnaryOperatorSyntax( + operation = node.operation, + prefix = OperatorNameSyntax(node.operation), + operand = OperandSyntax(parent.render(node.value), true), + ) + + public companion object { + public val Default: UnaryOperator = UnaryOperator(null) + } +} + +public class Power(operations: Collection?) : Binary(operations) { + public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = SuperscriptSyntax( + operation = node.operation, + left = OperandSyntax(parent.render(node.left), true), + right = OperandSyntax(parent.render(node.right), true), + ) + + public companion object { + public val Default: Power = Power(setOf(PowerOperations.POW_OPERATION)) + } +} + +public class SquareRoot(operations: Collection?) : Unary(operations) { + public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = + RadicalSyntax(operation = node.operation, operand = parent.render(node.value)) + + public companion object { + public val Default: SquareRoot = SquareRoot(setOf(PowerOperations.SQRT_OPERATION)) + } +} + +public class Exponential(operations: Collection?) : Unary(operations) { + public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = SuperscriptSyntax( + operation = node.operation, + left = SymbolSyntax(string = "e"), + right = parent.render(node.value), + ) + + public companion object { + public val Default: Exponential = Exponential(setOf(ExponentialOperations.EXP_OPERATION)) + } +} + +public class Multiplication(operations: Collection?) : Binary(operations) { + public override fun render0(parent: FeaturedMathRenderer, node: MST.Binary): MathSyntax = MultiplicationSyntax( + operation = node.operation, + left = OperandSyntax(operand = parent.render(node.left), parentheses = true), + right = OperandSyntax(operand = parent.render(node.right), parentheses = true), + times = true, + ) + + public companion object { + public val Default: Multiplication = Multiplication(setOf( + RingOperations.TIMES_OPERATION, + )) + } +} + +public class InverseTrigonometricOperations(operations: Collection?) : Unary(operations) { + public override fun render0(parent: FeaturedMathRenderer, node: MST.Unary): MathSyntax = UnaryOperatorSyntax( + operation = node.operation, + prefix = SuperscriptSyntax( + operation = PowerOperations.POW_OPERATION, + left = OperatorNameSyntax(name = node.operation.removePrefix("a")), + right = UnaryMinusSyntax( + operation = GroupOperations.MINUS_OPERATION, + operand = OperandSyntax(operand = NumberSyntax(string = "1"), parentheses = true), + ), + ), + operand = OperandSyntax(operand = parent.render(node.value), parentheses = true), + ) + + public companion object { + public val Default: InverseTrigonometricOperations = InverseTrigonometricOperations(setOf( + TrigonometricOperations.ACOS_OPERATION, + TrigonometricOperations.ASIN_OPERATION, + TrigonometricOperations.ATAN_OPERATION, + ExponentialOperations.ACOSH_OPERATION, + ExponentialOperations.ASINH_OPERATION, + ExponentialOperations.ATANH_OPERATION, + )) + } +} diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/stages.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/stages.kt new file mode 100644 index 000000000..0ebb41b28 --- /dev/null +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/stages.kt @@ -0,0 +1,202 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.ast.rendering + +import space.kscience.kmath.operations.FieldOperations +import space.kscience.kmath.operations.GroupOperations +import space.kscience.kmath.operations.PowerOperations +import space.kscience.kmath.operations.RingOperations + +/** + * Removes unnecessary times (×) symbols from [MultiplicationSyntax]. + * + * @author Iaroslav Postovalov + */ +public object BetterMultiplication : FeaturedMathRendererWithPostProcess.PostProcessStage { + public override fun perform(node: MathSyntax) { + when (node) { + is NumberSyntax -> Unit + is SymbolSyntax -> Unit + is OperatorNameSyntax -> Unit + is SpecialSymbolSyntax -> Unit + is OperandSyntax -> perform(node.operand) + + is UnaryOperatorSyntax -> { + perform(node.prefix) + perform(node.operand) + } + + is UnaryPlusSyntax -> perform(node.operand) + is UnaryMinusSyntax -> perform(node.operand) + is RadicalSyntax -> perform(node.operand) + + is SuperscriptSyntax -> { + perform(node.left) + perform(node.right) + } + + is SubscriptSyntax -> { + perform(node.left) + perform(node.right) + } + + is BinaryOperatorSyntax -> { + perform(node.prefix) + perform(node.left) + perform(node.right) + } + + is BinaryPlusSyntax -> { + perform(node.left) + perform(node.right) + } + + is BinaryMinusSyntax -> { + perform(node.left) + perform(node.right) + } + + is FractionSyntax -> { + perform(node.left) + perform(node.right) + } + + is RadicalWithIndexSyntax -> { + perform(node.left) + perform(node.right) + } + + is MultiplicationSyntax -> { + node.times = node.right.operand is NumberSyntax && !node.right.parentheses + || node.left.operand is NumberSyntax && node.right.operand is FractionSyntax + || node.left.operand is NumberSyntax && node.right.operand is NumberSyntax + || node.left.operand is NumberSyntax && node.right.operand is SuperscriptSyntax && node.right.operand.left is NumberSyntax + + perform(node.left) + perform(node.right) + } + } + } +} + +/** + * Removes unnecessary parentheses from [OperandSyntax]. + * + * @property precedenceFunction Returns the precedence number for syntax node. Higher number is lower priority. + * @author Iaroslav Postovalov + */ +public class SimplifyParentheses(public val precedenceFunction: (MathSyntax) -> Int) : + FeaturedMathRendererWithPostProcess.PostProcessStage { + public override fun perform(node: MathSyntax) { + when (node) { + is NumberSyntax -> Unit + is SymbolSyntax -> Unit + is OperatorNameSyntax -> Unit + is SpecialSymbolSyntax -> Unit + + is OperandSyntax -> { + val isRightOfSuperscript = + (node.parent is SuperscriptSyntax) && (node.parent as SuperscriptSyntax).right === node + + val precedence = precedenceFunction(node.operand) + + val needParenthesesByPrecedence = when (val parent = node.parent) { + null -> false + + is BinarySyntax -> { + val parentPrecedence = precedenceFunction(parent) + + parentPrecedence < precedence || + parentPrecedence == precedence && parentPrecedence != 0 && node === parent.right + } + + else -> precedence > precedenceFunction(parent) + } + + node.parentheses = !isRightOfSuperscript + && (needParenthesesByPrecedence || node.parent is UnaryOperatorSyntax) + + perform(node.operand) + } + + is UnaryOperatorSyntax -> { + perform(node.prefix) + perform(node.operand) + } + + is UnaryPlusSyntax -> perform(node.operand) + is UnaryMinusSyntax -> { + perform(node.operand) + } + is RadicalSyntax -> perform(node.operand) + + is SuperscriptSyntax -> { + perform(node.left) + perform(node.right) + } + + is SubscriptSyntax -> { + perform(node.left) + perform(node.right) + } + + is BinaryOperatorSyntax -> { + perform(node.prefix) + perform(node.left) + perform(node.right) + } + + is BinaryPlusSyntax -> { + perform(node.left) + perform(node.right) + } + + is BinaryMinusSyntax -> { + perform(node.left) + perform(node.right) + } + + is FractionSyntax -> { + perform(node.left) + perform(node.right) + } + + is MultiplicationSyntax -> { + perform(node.left) + perform(node.right) + } + + is RadicalWithIndexSyntax -> { + perform(node.left) + perform(node.right) + } + } + } + + public companion object { + /** + * The default configuration of [SimplifyParentheses] where power is 1, multiplicative operations are 2, + * additive operations are 3. + */ + public val Default: SimplifyParentheses = SimplifyParentheses { + when (it) { + is TerminalSyntax -> 0 + is UnarySyntax -> 2 + + is BinarySyntax -> when (it.operation) { + PowerOperations.POW_OPERATION -> 1 + RingOperations.TIMES_OPERATION -> 3 + FieldOperations.DIV_OPERATION -> 3 + GroupOperations.MINUS_OPERATION -> 4 + GroupOperations.PLUS_OPERATION -> 4 + else -> 0 + } + + else -> 0 + } + } + } +} diff --git a/kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/InterpretTest.kt b/kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/InterpretTest.kt new file mode 100644 index 000000000..93fde5aab --- /dev/null +++ b/kmath-ast/src/commonTest/kotlin/space/kscisnce/kmath/ast/InterpretTest.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscisnce.kmath.ast + +import space.kscience.kmath.expressions.MstField +import space.kscience.kmath.expressions.invoke +import space.kscience.kmath.expressions.toExpression +import space.kscience.kmath.misc.Symbol.Companion.x +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.bindSymbol +import space.kscience.kmath.operations.invoke +import kotlin.test.Test + +class InterpretTest { + + @Test + fun interpretation(){ + val expr = MstField { + val x = bindSymbol(x) + x * 2.0 + number(2.0) / x - 16.0 + }.toExpression(DoubleField) + expr(x to 2.2) + } +} \ No newline at end of file diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt index 909e8e575..83914f3ec 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt @@ -5,12 +5,13 @@ package space.kscience.kmath.estree -import space.kscience.kmath.ast.MST -import space.kscience.kmath.ast.MST.* -import space.kscience.kmath.ast.MstExpression import space.kscience.kmath.estree.internal.ESTreeBuilder import space.kscience.kmath.estree.internal.estree.BaseExpression import space.kscience.kmath.expressions.Expression +import space.kscience.kmath.expressions.MST +import space.kscience.kmath.expressions.MST.* +import space.kscience.kmath.expressions.invoke +import space.kscience.kmath.misc.Symbol import space.kscience.kmath.operations.Algebra import space.kscience.kmath.operations.NumericAlgebra @@ -18,11 +19,7 @@ import space.kscience.kmath.operations.NumericAlgebra internal fun MST.compileWith(algebra: Algebra): Expression { fun ESTreeBuilder.visit(node: MST): BaseExpression = when (node) { is Symbolic -> { - val symbol = try { - algebra.bindSymbol(node.value) - } catch (ignored: IllegalStateException) { - null - } + val symbol = algebra.bindSymbolOrNull(node.value) if (symbol != null) constant(symbol) @@ -34,16 +31,17 @@ internal fun MST.compileWith(algebra: Algebra): Expression { is Unary -> when { algebra is NumericAlgebra && node.value is Numeric -> constant( - algebra.unaryOperationFunction(node.operation)(algebra.number(node.value.value))) + algebra.unaryOperationFunction(node.operation)(algebra.number((node.value as Numeric).value))) else -> call(algebra.unaryOperationFunction(node.operation), visit(node.value)) } is Binary -> when { algebra is NumericAlgebra && node.left is Numeric && node.right is Numeric -> constant( - algebra - .binaryOperationFunction(node.operation) - .invoke(algebra.number(node.left.value), algebra.number(node.right.value)) + algebra.binaryOperationFunction(node.operation).invoke( + algebra.number((node.left as Numeric).value), + algebra.number((node.right as Numeric).value) + ) ) algebra is NumericAlgebra && node.left is Numeric -> call( @@ -69,19 +67,21 @@ internal fun MST.compileWith(algebra: Algebra): Expression { return ESTreeBuilder { visit(this@compileWith) }.instance } +/** + * Create a compiled expression with given [MST] and given [algebra]. + */ +public fun MST.compileToExpression(algebra: Algebra): Expression = compileWith(algebra) + /** - * Compiles an [MST] to ESTree generated expression using given algebra. - * - * @author Alexander Nozik. + * Compile given MST to expression and evaluate it against [arguments] */ -public fun Algebra.expression(mst: MST): Expression = - mst.compileWith(this) +public inline fun MST.compile(algebra: Algebra, arguments: Map): T = + compileToExpression(algebra).invoke(arguments) + /** - * Optimizes performance of an [MstExpression] by compiling it into ESTree generated expression. - * - * @author Alexander Nozik. + * Compile given MST to expression and evaluate it against [arguments] */ -public fun MstExpression>.compile(): Expression = - mst.compileWith(algebra) +public inline fun MST.compile(algebra: Algebra, vararg arguments: Pair): T = + compileToExpression(algebra).invoke(*arguments) diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/ESTreeBuilder.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/ESTreeBuilder.kt index b7dfc31af..6f917a24c 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/ESTreeBuilder.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/ESTreeBuilder.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.estree.internal import space.kscience.kmath.estree.internal.astring.generate import space.kscience.kmath.estree.internal.estree.* import space.kscience.kmath.expressions.Expression -import space.kscience.kmath.expressions.Symbol +import space.kscience.kmath.misc.Symbol internal class ESTreeBuilder(val bodyCallback: ESTreeBuilder.() -> BaseExpression) { private class GeneratedExpression(val executable: dynamic, val constants: Array) : Expression { 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 99f037b7c..5823518ce 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,19 +5,22 @@ package space.kscience.kmath.estree -import space.kscience.kmath.ast.* import space.kscience.kmath.complex.ComplexField import space.kscience.kmath.complex.toComplex -import space.kscience.kmath.expressions.invoke +import space.kscience.kmath.expressions.* +import space.kscience.kmath.misc.Symbol import space.kscience.kmath.operations.ByteRing -import space.kscience.kmath.operations.RealField +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.invoke import kotlin.test.Test import kotlin.test.assertEquals internal class TestESTreeConsistencyWithInterpreter { + @Test fun mstSpace() { - val res1 = MstGroup.mstInGroup { + + val mst = MstGroup { binaryOperationFunction("+")( unaryOperationFunction("+")( number(3.toByte()) - (number(2.toByte()) + (scale( @@ -28,27 +31,17 @@ internal class TestESTreeConsistencyWithInterpreter { number(1) ) + bindSymbol("x") + zero - }("x" to MST.Numeric(2)) + } - val res2 = MstGroup.mstInGroup { - binaryOperationFunction("+")( - unaryOperationFunction("+")( - number(3.toByte()) - (number(2.toByte()) + (scale( - add(number(1), number(1)), - 2.0 - ) + number(1.toByte()) * 3.toByte() - number(1.toByte()))) - ), - - number(1) - ) + bindSymbol("x") + zero - }.compile()("x" to MST.Numeric(2)) - - assertEquals(res1, res2) + assertEquals( + mst.interpret(MstGroup, Symbol.x to MST.Numeric(2)), + mst.compile(MstGroup, Symbol.x to MST.Numeric(2)) + ) } @Test fun byteRing() { - val res1 = ByteRing.mstInRing { + val mst = MstRing { binaryOperationFunction("+")( unaryOperationFunction("+")( (bindSymbol("x") - (2.toByte() + (scale( @@ -59,62 +52,43 @@ internal class TestESTreeConsistencyWithInterpreter { number(1) ) * number(2) - }("x" to 3.toByte()) + } - val res2 = ByteRing.mstInRing { - binaryOperationFunction("+")( - unaryOperationFunction("+")( - (bindSymbol("x") - (2.toByte() + (scale( - add(number(1), number(1)), - 2.0 - ) + 1.toByte()))) * 3.0 - 1.toByte() - ), - number(1) - ) * number(2) - }.compile()("x" to 3.toByte()) - - assertEquals(res1, res2) + assertEquals( + mst.interpret(ByteRing, Symbol.x to 3.toByte()), + mst.compile(ByteRing, Symbol.x to 3.toByte()) + ) } @Test fun realField() { - val res1 = RealField.mstInField { + val mst = MstField { +(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), number(1) / 2 + number(2.0) * one ) + zero - }("x" to 2.0) + } - val res2 = RealField.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), - number(1) / 2 + number(2.0) * one - ) + zero - }.compile()("x" to 2.0) - - assertEquals(res1, res2) + assertEquals( + mst.interpret(DoubleField, Symbol.x to 2.0), + mst.compile(DoubleField, Symbol.x to 2.0) + ) } @Test fun complexField() { - val res1 = ComplexField.mstInField { + val mst = MstField { +(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), number(1) / 2 + number(2.0) * one ) + zero - }("x" to 2.0.toComplex()) + } - val res2 = ComplexField.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), - number(1) / 2 + number(2.0) * one - ) + zero - }.compile()("x" to 2.0.toComplex()) - - assertEquals(res1, res2) + assertEquals( + mst.interpret(ComplexField, Symbol.x to 2.0.toComplex()), + mst.compile(ComplexField, Symbol.x to 2.0.toComplex()) + ) } } 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 834495990..a1bff92d0 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 @@ -5,11 +5,10 @@ package space.kscience.kmath.estree -import space.kscience.kmath.ast.mstInExtendedField -import space.kscience.kmath.ast.mstInField -import space.kscience.kmath.ast.mstInGroup +import space.kscience.kmath.expressions.MstExtendedField import space.kscience.kmath.expressions.invoke -import space.kscience.kmath.operations.RealField +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.invoke import kotlin.random.Random import kotlin.test.Test import kotlin.test.assertEquals @@ -17,27 +16,29 @@ import kotlin.test.assertEquals internal class TestESTreeOperationsSupport { @Test fun testUnaryOperationInvocation() { - val expression = RealField.mstInGroup { -bindSymbol("x") }.compile() + val expression = MstExtendedField { -bindSymbol("x") }.compileToExpression(DoubleField) 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 = MstExtendedField { -bindSymbol("x") + number(1.0) }.compileToExpression(DoubleField) 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 = MstExtendedField { bindSymbol("x") * 2 }.compileToExpression(DoubleField)("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 = + MstExtendedField { sin(bindSymbol("x")).pow(4) - 6 * bindSymbol("x") / tanh(bindSymbol("x")) } + .compileToExpression(DoubleField) 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 8824b08af..b5ae1ca3f 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 @@ -5,54 +5,64 @@ package space.kscience.kmath.estree -import space.kscience.kmath.ast.mstInField +import space.kscience.kmath.expressions.MstExtendedField import space.kscience.kmath.expressions.invoke -import space.kscience.kmath.operations.RealField +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.invoke import kotlin.test.Test import kotlin.test.assertEquals internal class TestESTreeSpecialization { @Test fun testUnaryPlus() { - val expr = RealField.mstInField { unaryOperationFunction("+")(bindSymbol("x")) }.compile() + val expr = MstExtendedField { unaryOperationFunction("+")(bindSymbol("x")) }.compileToExpression(DoubleField) assertEquals(2.0, expr("x" to 2.0)) } @Test fun testUnaryMinus() { - val expr = RealField.mstInField { unaryOperationFunction("-")(bindSymbol("x")) }.compile() + val expr = MstExtendedField { unaryOperationFunction("-")(bindSymbol("x")) }.compileToExpression(DoubleField) assertEquals(-2.0, expr("x" to 2.0)) } @Test fun testAdd() { - val expr = RealField.mstInField { binaryOperationFunction("+")(bindSymbol("x"), bindSymbol("x")) }.compile() + val expr = MstExtendedField { + binaryOperationFunction("+")(bindSymbol("x"), + bindSymbol("x")) + }.compileToExpression(DoubleField) assertEquals(4.0, expr("x" to 2.0)) } @Test fun testSine() { - val expr = RealField.mstInField { unaryOperationFunction("sin")(bindSymbol("x")) }.compile() + val expr = MstExtendedField { unaryOperationFunction("sin")(bindSymbol("x")) }.compileToExpression(DoubleField) assertEquals(0.0, expr("x" to 0.0)) } @Test fun testMinus() { - val expr = RealField.mstInField { binaryOperationFunction("-")(bindSymbol("x"), bindSymbol("x")) }.compile() + val expr = MstExtendedField { + binaryOperationFunction("-")(bindSymbol("x"), + bindSymbol("x")) + }.compileToExpression(DoubleField) assertEquals(0.0, expr("x" to 2.0)) } @Test fun testDivide() { - val expr = RealField.mstInField { binaryOperationFunction("/")(bindSymbol("x"), bindSymbol("x")) }.compile() + val expr = MstExtendedField { + binaryOperationFunction("/")(bindSymbol("x"), + bindSymbol("x")) + }.compileToExpression(DoubleField) assertEquals(1.0, expr("x" to 2.0)) } @Test fun testPower() { - val expr = RealField - .mstInField { binaryOperationFunction("pow")(bindSymbol("x"), number(2)) } - .compile() + val expr = MstExtendedField { + binaryOperationFunction("pow")(bindSymbol("x"), number(2)) + }.compileToExpression(DoubleField) assertEquals(4.0, expr("x" to 2.0)) } diff --git a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeVariables.kt b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeVariables.kt index 5af26e147..1effe14e1 100644 --- a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeVariables.kt +++ b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/estree/TestESTreeVariables.kt @@ -5,9 +5,10 @@ package space.kscience.kmath.estree -import space.kscience.kmath.ast.mstInRing +import space.kscience.kmath.expressions.MstRing import space.kscience.kmath.expressions.invoke import space.kscience.kmath.operations.ByteRing +import space.kscience.kmath.operations.invoke import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFailsWith @@ -15,13 +16,13 @@ import kotlin.test.assertFailsWith internal class TestESTreeVariables { @Test fun testVariable() { - val expr = ByteRing.mstInRing { bindSymbol("x") }.compile() + val expr = MstRing{ bindSymbol("x") }.compileToExpression(ByteRing) assertEquals(1.toByte(), expr("x" to 1.toByte())) } @Test fun testUndefinedVariableFails() { - val expr = ByteRing.mstInRing { bindSymbol("x") }.compile() + val expr = MstRing { bindSymbol("x") }.compileToExpression(ByteRing) assertFailsWith { expr() } } } diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt index d2a6505a0..dbce893d1 100644 --- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt +++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt @@ -7,10 +7,11 @@ package space.kscience.kmath.asm import space.kscience.kmath.asm.internal.AsmBuilder import space.kscience.kmath.asm.internal.buildName -import space.kscience.kmath.ast.MST -import space.kscience.kmath.ast.MST.* -import space.kscience.kmath.ast.MstExpression import space.kscience.kmath.expressions.Expression +import space.kscience.kmath.expressions.MST +import space.kscience.kmath.expressions.MST.* +import space.kscience.kmath.expressions.invoke +import space.kscience.kmath.misc.Symbol import space.kscience.kmath.operations.Algebra import space.kscience.kmath.operations.NumericAlgebra @@ -26,11 +27,7 @@ import space.kscience.kmath.operations.NumericAlgebra internal fun MST.compileWith(type: Class, algebra: Algebra): Expression { fun AsmBuilder.visit(node: MST): Unit = when (node) { is Symbolic -> { - val symbol = try { - algebra.bindSymbol(node.value) - } catch (ignored: IllegalStateException) { - null - } + val symbol = algebra.bindSymbolOrNull(node.value) if (symbol != null) loadObjectConstant(symbol as Any) @@ -42,15 +39,17 @@ internal fun MST.compileWith(type: Class, algebra: Algebra): Exp is Unary -> when { algebra is NumericAlgebra && node.value is Numeric -> loadObjectConstant( - algebra.unaryOperationFunction(node.operation)(algebra.number(node.value.value))) + algebra.unaryOperationFunction(node.operation)(algebra.number((node.value as Numeric).value))) else -> buildCall(algebra.unaryOperationFunction(node.operation)) { visit(node.value) } } is Binary -> when { algebra is NumericAlgebra && node.left is Numeric && node.right is Numeric -> loadObjectConstant( - algebra.binaryOperationFunction(node.operation) - .invoke(algebra.number(node.left.value), algebra.number(node.right.value)) + algebra.binaryOperationFunction(node.operation).invoke( + algebra.number((node.left as Numeric).value), + algebra.number((node.right as Numeric).value) + ) ) algebra is NumericAlgebra && node.left is Numeric -> buildCall( @@ -75,18 +74,22 @@ internal fun MST.compileWith(type: Class, algebra: Algebra): Exp return AsmBuilder(type, buildName(this)) { visit(this@compileWith) }.instance } -/** - * Compiles an [MST] to ASM using given algebra. - * - * @author Alexander Nozik. - */ -public inline fun Algebra.expression(mst: MST): Expression = - mst.compileWith(T::class.java, this) /** - * Optimizes performance of an [MstExpression] using ASM codegen. - * - * @author Alexander Nozik. + * Create a compiled expression with given [MST] and given [algebra]. */ -public inline fun MstExpression>.compile(): Expression = - mst.compileWith(T::class.java, algebra) +public inline fun MST.compileToExpression(algebra: Algebra): Expression = + compileWith(T::class.java, algebra) + + +/** + * Compile given MST to expression and evaluate it against [arguments] + */ +public inline fun MST.compile(algebra: Algebra, arguments: Map): T = + compileToExpression(algebra).invoke(arguments) + +/** + * Compile given MST to expression and evaluate it against [arguments] + */ +public inline fun MST.compile(algebra: Algebra, vararg arguments: Pair): T = + compileToExpression(algebra).invoke(*arguments) diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/AsmBuilder.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/AsmBuilder.kt index 55fbe5d70..bdd8f52b6 100644 --- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/AsmBuilder.kt +++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/AsmBuilder.kt @@ -10,8 +10,8 @@ import org.objectweb.asm.Opcodes.* import org.objectweb.asm.Type.* import org.objectweb.asm.commons.InstructionAdapter import space.kscience.kmath.asm.internal.AsmBuilder.ClassLoader -import space.kscience.kmath.ast.MST import space.kscience.kmath.expressions.Expression +import space.kscience.kmath.expressions.MST import java.lang.invoke.MethodHandles import java.lang.invoke.MethodType import java.util.stream.Collectors.toMap 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 de73c3748..560780f99 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 @@ -7,8 +7,8 @@ package space.kscience.kmath.asm.internal import org.objectweb.asm.* import org.objectweb.asm.commons.InstructionAdapter -import space.kscience.kmath.ast.MST import space.kscience.kmath.expressions.Expression +import space.kscience.kmath.expressions.MST import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -91,7 +91,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/jvmMain/kotlin/space/kscience/kmath/asm/internal/mapIntrinsics.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/mapIntrinsics.kt index 8f4daecf9..dc8f19fb6 100644 --- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/mapIntrinsics.kt +++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/mapIntrinsics.kt @@ -7,8 +7,8 @@ package space.kscience.kmath.asm.internal -import space.kscience.kmath.expressions.StringSymbol -import space.kscience.kmath.expressions.Symbol +import space.kscience.kmath.misc.StringSymbol +import space.kscience.kmath.misc.Symbol /** * Gets value with given [key] or throws [NoSuchElementException] whenever it is not present. diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/ast/parser.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/ast/parser.kt index b2157558e..025f4984c 100644 --- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/ast/parser.kt +++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/ast/parser.kt @@ -18,6 +18,7 @@ import com.github.h0tk3y.betterParse.lexer.literalToken import com.github.h0tk3y.betterParse.lexer.regexToken import com.github.h0tk3y.betterParse.parser.ParseResult import com.github.h0tk3y.betterParse.parser.Parser +import space.kscience.kmath.expressions.MST import space.kscience.kmath.operations.FieldOperations import space.kscience.kmath.operations.GroupOperations import space.kscience.kmath.operations.PowerOperations @@ -26,7 +27,8 @@ import space.kscience.kmath.operations.RingOperations /** * better-parse implementation of grammar defined in the ArithmeticsEvaluator.g4. * - * @author Alexander Nozik and Iaroslav Postovalov + * @author Alexander Nozik + * @author Iaroslav Postovalov */ public object ArithmeticsEvaluator : Grammar() { // TODO replace with "...".toRegex() when better-parse 0.4.1 is released 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 e16311215..77cfb2241 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,19 +5,22 @@ package space.kscience.kmath.asm -import space.kscience.kmath.ast.* import space.kscience.kmath.complex.ComplexField import space.kscience.kmath.complex.toComplex -import space.kscience.kmath.expressions.invoke +import space.kscience.kmath.expressions.* +import space.kscience.kmath.misc.Symbol.Companion.x import space.kscience.kmath.operations.ByteRing -import space.kscience.kmath.operations.RealField +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.invoke import kotlin.test.Test import kotlin.test.assertEquals internal class TestAsmConsistencyWithInterpreter { + @Test fun mstSpace() { - val res1 = MstGroup.mstInGroup { + + val mst = MstGroup { binaryOperationFunction("+")( unaryOperationFunction("+")( number(3.toByte()) - (number(2.toByte()) + (scale( @@ -28,27 +31,17 @@ internal class TestAsmConsistencyWithInterpreter { number(1) ) + bindSymbol("x") + zero - }("x" to MST.Numeric(2)) + } - val res2 = MstGroup.mstInGroup { - binaryOperationFunction("+")( - unaryOperationFunction("+")( - number(3.toByte()) - (number(2.toByte()) + (scale( - add(number(1), number(1)), - 2.0 - ) + number(1.toByte()) * 3.toByte() - number(1.toByte()))) - ), - - number(1) - ) + bindSymbol("x") + zero - }.compile()("x" to MST.Numeric(2)) - - assertEquals(res1, res2) + assertEquals( + mst.interpret(MstGroup, x to MST.Numeric(2)), + mst.compile(MstGroup, x to MST.Numeric(2)) + ) } @Test fun byteRing() { - val res1 = ByteRing.mstInRing { + val mst = MstRing { binaryOperationFunction("+")( unaryOperationFunction("+")( (bindSymbol("x") - (2.toByte() + (scale( @@ -59,62 +52,43 @@ internal class TestAsmConsistencyWithInterpreter { number(1) ) * number(2) - }("x" to 3.toByte()) + } - val res2 = ByteRing.mstInRing { - binaryOperationFunction("+")( - unaryOperationFunction("+")( - (bindSymbol("x") - (2.toByte() + (scale( - add(number(1), number(1)), - 2.0 - ) + 1.toByte()))) * 3.0 - 1.toByte() - ), - number(1) - ) * number(2) - }.compile()("x" to 3.toByte()) - - assertEquals(res1, res2) + assertEquals( + mst.interpret(ByteRing, x to 3.toByte()), + mst.compile(ByteRing, x to 3.toByte()) + ) } @Test fun realField() { - val res1 = RealField.mstInField { + val mst = MstField { +(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), number(1) / 2 + number(2.0) * one ) + zero - }("x" to 2.0) + } - val res2 = RealField.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), - number(1) / 2 + number(2.0) * one - ) + zero - }.compile()("x" to 2.0) - - assertEquals(res1, res2) + assertEquals( + mst.interpret(DoubleField, x to 2.0), + mst.compile(DoubleField, x to 2.0) + ) } @Test fun complexField() { - val res1 = ComplexField.mstInField { + val mst = MstField { +(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), number(1) / 2 + number(2.0) * one ) + zero - }("x" to 2.0.toComplex()) + } - val res2 = ComplexField.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), - number(1) / 2 + number(2.0) * one - ) + zero - }.compile()("x" to 2.0.toComplex()) - - assertEquals(res1, res2) + assertEquals( + mst.interpret(ComplexField, x to 2.0.toComplex()), + mst.compile(ComplexField, x to 2.0.toComplex()) + ) } } 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 4caa35080..757235fb7 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 @@ -5,11 +5,12 @@ package space.kscience.kmath.asm -import space.kscience.kmath.ast.mstInExtendedField -import space.kscience.kmath.ast.mstInField -import space.kscience.kmath.ast.mstInGroup +import space.kscience.kmath.expressions.MstExtendedField +import space.kscience.kmath.expressions.MstField +import space.kscience.kmath.expressions.MstGroup import space.kscience.kmath.expressions.invoke -import space.kscience.kmath.operations.RealField +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.invoke import kotlin.random.Random import kotlin.test.Test import kotlin.test.assertEquals @@ -17,27 +18,29 @@ import kotlin.test.assertEquals internal class TestAsmOperationsSupport { @Test fun testUnaryOperationInvocation() { - val expression = RealField.mstInGroup { -bindSymbol("x") }.compile() + val expression = MstGroup { -bindSymbol("x") }.compileToExpression(DoubleField) 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 = MstGroup { -bindSymbol("x") + number(1.0) }.compileToExpression(DoubleField) 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 = MstField { bindSymbol("x") * 2 }.compileToExpression(DoubleField)("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 = + MstExtendedField { sin(bindSymbol("x")).pow(4) - 6 * bindSymbol("x") / tanh(bindSymbol("x")) } + .compileToExpression(DoubleField) 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 330cb969f..b09d79515 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 @@ -5,54 +5,64 @@ package space.kscience.kmath.asm -import space.kscience.kmath.ast.mstInField +import space.kscience.kmath.expressions.MstExtendedField import space.kscience.kmath.expressions.invoke -import space.kscience.kmath.operations.RealField +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.invoke import kotlin.test.Test import kotlin.test.assertEquals internal class TestAsmSpecialization { @Test fun testUnaryPlus() { - val expr = RealField.mstInField { unaryOperationFunction("+")(bindSymbol("x")) }.compile() + val expr = MstExtendedField { unaryOperationFunction("+")(bindSymbol("x")) }.compileToExpression(DoubleField) assertEquals(2.0, expr("x" to 2.0)) } @Test fun testUnaryMinus() { - val expr = RealField.mstInField { unaryOperationFunction("-")(bindSymbol("x")) }.compile() + val expr = MstExtendedField { unaryOperationFunction("-")(bindSymbol("x")) }.compileToExpression(DoubleField) assertEquals(-2.0, expr("x" to 2.0)) } @Test fun testAdd() { - val expr = RealField.mstInField { binaryOperationFunction("+")(bindSymbol("x"), bindSymbol("x")) }.compile() + val expr = MstExtendedField { + binaryOperationFunction("+")(bindSymbol("x"), + bindSymbol("x")) + }.compileToExpression(DoubleField) assertEquals(4.0, expr("x" to 2.0)) } @Test fun testSine() { - val expr = RealField.mstInField { unaryOperationFunction("sin")(bindSymbol("x")) }.compile() + val expr = MstExtendedField { unaryOperationFunction("sin")(bindSymbol("x")) }.compileToExpression(DoubleField) assertEquals(0.0, expr("x" to 0.0)) } @Test fun testMinus() { - val expr = RealField.mstInField { binaryOperationFunction("-")(bindSymbol("x"), bindSymbol("x")) }.compile() + val expr = MstExtendedField { + binaryOperationFunction("-")(bindSymbol("x"), + bindSymbol("x")) + }.compileToExpression(DoubleField) assertEquals(0.0, expr("x" to 2.0)) } @Test fun testDivide() { - val expr = RealField.mstInField { binaryOperationFunction("/")(bindSymbol("x"), bindSymbol("x")) }.compile() + val expr = MstExtendedField { + binaryOperationFunction("/")(bindSymbol("x"), + bindSymbol("x")) + }.compileToExpression(DoubleField) assertEquals(1.0, expr("x" to 2.0)) } @Test fun testPower() { - val expr = RealField - .mstInField { binaryOperationFunction("pow")(bindSymbol("x"), number(2)) } - .compile() + val expr = MstExtendedField { + binaryOperationFunction("pow")(bindSymbol("x"), number(2)) + }.compileToExpression(DoubleField) assertEquals(4.0, expr("x" to 2.0)) } diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmVariables.kt b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmVariables.kt index 71fa99747..740326a59 100644 --- a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmVariables.kt +++ b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/asm/TestAsmVariables.kt @@ -5,9 +5,10 @@ package space.kscience.kmath.asm -import space.kscience.kmath.ast.mstInRing +import space.kscience.kmath.expressions.MstRing import space.kscience.kmath.expressions.invoke import space.kscience.kmath.operations.ByteRing +import space.kscience.kmath.operations.invoke import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFailsWith @@ -15,13 +16,13 @@ import kotlin.test.assertFailsWith internal class TestAsmVariables { @Test fun testVariable() { - val expr = ByteRing.mstInRing { bindSymbol("x") }.compile() + val expr = MstRing { bindSymbol("x") }.compileToExpression(ByteRing) assertEquals(1.toByte(), expr("x" to 1.toByte())) } @Test fun testUndefinedVariableFails() { - val expr = ByteRing.mstInRing { bindSymbol("x") }.compile() + val expr = MstRing { bindSymbol("x") }.compileToExpression(ByteRing) assertFailsWith { expr() } } } 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 b09a04f23..6273eff27 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 @@ -5,13 +5,14 @@ package space.kscience.kmath.ast +import space.kscience.kmath.expressions.evaluate +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 ae2c000bf..53afaa674 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 @@ -7,9 +7,12 @@ package space.kscience.kmath.ast import space.kscience.kmath.complex.Complex import space.kscience.kmath.complex.ComplexField -import space.kscience.kmath.expressions.invoke +import space.kscience.kmath.expressions.MstField +import space.kscience.kmath.expressions.evaluate +import space.kscience.kmath.expressions.interpret import space.kscience.kmath.operations.Algebra -import space.kscience.kmath.operations.RealField +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.invoke import kotlin.test.Test import kotlin.test.assertEquals @@ -23,7 +26,7 @@ internal class ParserTest { @Test fun `evaluate MSTExpression`() { - val res = ComplexField.mstInField { number(2) + number(2) * (number(2) + number(2)) }() + val res = MstField.invoke { number(2) + number(2) * (number(2) + number(2)) }.interpret(ComplexField) assertEquals(Complex(10.0, 0.0), res) } @@ -38,14 +41,14 @@ 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) } @Test fun `evaluate MST with binary function`() { val magicalAlgebra = object : Algebra { - override fun bindSymbol(value: String): String = value + override fun bindSymbolOrNull(value: String): String = value override fun unaryOperationFunction(operation: String): (arg: String) -> String { throw NotImplementedError() diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt new file mode 100644 index 000000000..1584293ce --- /dev/null +++ b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt @@ -0,0 +1,100 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.ast.rendering + +import space.kscience.kmath.ast.rendering.TestUtils.testLatex +import space.kscience.kmath.expressions.MST.Numeric +import kotlin.test.Test + +internal class TestFeatures { + @Test + fun printSymbolic() = testLatex("x", "x") + + @Test + fun printNumeric() { + val num = object : Number() { + override fun toByte(): Byte = throw UnsupportedOperationException() + override fun toChar(): Char = throw UnsupportedOperationException() + override fun toDouble(): Double = throw UnsupportedOperationException() + override fun toFloat(): Float = throw UnsupportedOperationException() + override fun toInt(): Int = throw UnsupportedOperationException() + override fun toLong(): Long = throw UnsupportedOperationException() + override fun toShort(): Short = throw UnsupportedOperationException() + override fun toString(): String = "foo" + } + + testLatex(Numeric(num), "foo") + } + + @Test + fun prettyPrintFloats() { + testLatex(Numeric(Double.NaN), "NaN") + testLatex(Numeric(Double.POSITIVE_INFINITY), "\\infty") + testLatex(Numeric(Double.NEGATIVE_INFINITY), "-\\infty") + testLatex(Numeric(1.0), "1") + testLatex(Numeric(-1.0), "-1") + testLatex(Numeric(1.42), "1.42") + testLatex(Numeric(-1.42), "-1.42") + testLatex(Numeric(1.1e10), "1.1\\times10^{10}") + testLatex(Numeric(1.1e-10), "1.1\\times10^{-10}") + testLatex(Numeric(-1.1e-10), "-1.1\\times10^{-10}") + testLatex(Numeric(-1.1e10), "-1.1\\times10^{10}") + } + + @Test + fun prettyPrintIntegers() { + testLatex(Numeric(42), "42") + testLatex(Numeric(-42), "-42") + } + + @Test + fun prettyPrintPi() { + testLatex("pi", "\\pi") + } + + @Test + fun binaryPlus() = testLatex("2+2", "2+2") + + @Test + fun binaryMinus() = testLatex("2-2", "2-2") + + @Test + fun fraction() = testLatex("2/2", "\\frac{2}{2}") + + @Test + fun binaryOperator() = testLatex("f(x, y)", "\\operatorname{f}\\left(x,y\\right)") + + @Test + fun unaryOperator() = testLatex("f(x)", "\\operatorname{f}\\,\\left(x\\right)") + + @Test + fun power() = testLatex("x^y", "x^{y}") + + @Test + fun squareRoot() = testLatex("sqrt(x)", "\\sqrt{x}") + + @Test + fun exponential() = testLatex("exp(x)", "e^{x}") + + @Test + fun multiplication() = testLatex("x*1", "x\\times1") + + @Test + fun inverseTrigonometry() { + testLatex("asin(x)", "\\operatorname{sin}^{-1}\\,\\left(x\\right)") + testLatex("asinh(x)", "\\operatorname{sinh}^{-1}\\,\\left(x\\right)") + testLatex("acos(x)", "\\operatorname{cos}^{-1}\\,\\left(x\\right)") + testLatex("acosh(x)", "\\operatorname{cosh}^{-1}\\,\\left(x\\right)") + testLatex("atan(x)", "\\operatorname{tan}^{-1}\\,\\left(x\\right)") + testLatex("atanh(x)", "\\operatorname{tanh}^{-1}\\,\\left(x\\right)") + } + +// @Test +// fun unaryPlus() { +// testLatex("+1", "+1") +// testLatex("+1", "++1") +// } +} diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestLatex.kt b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestLatex.kt new file mode 100644 index 000000000..6322df25d --- /dev/null +++ b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestLatex.kt @@ -0,0 +1,73 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.ast.rendering + +import space.kscience.kmath.ast.rendering.TestUtils.testLatex +import space.kscience.kmath.expressions.MST +import space.kscience.kmath.operations.GroupOperations +import kotlin.test.Test + +internal class TestLatex { + @Test + fun number() = testLatex("42", "42") + + @Test + fun symbol() = testLatex("x", "x") + + @Test + fun operatorName() = testLatex("sin(1)", "\\operatorname{sin}\\,\\left(1\\right)") + + @Test + fun specialSymbol() { + testLatex(MST.Numeric(Double.POSITIVE_INFINITY), "\\infty") + testLatex("pi", "\\pi") + } + + @Test + fun operand() { + testLatex("sin(1)", "\\operatorname{sin}\\,\\left(1\\right)") + testLatex("1+1", "1+1") + } + + @Test + fun unaryOperator() = testLatex("sin(1)", "\\operatorname{sin}\\,\\left(1\\right)") + + @Test + fun unaryPlus() = testLatex(MST.Unary(GroupOperations.PLUS_OPERATION, MST.Numeric(1)), "+1") + + @Test + fun unaryMinus() = testLatex("-x", "-x") + + @Test + fun radical() = testLatex("sqrt(x)", "\\sqrt{x}") + + @Test + fun superscript() = testLatex("x^y", "x^{y}") + + @Test + fun subscript() = testLatex(SubscriptSyntax("", SymbolSyntax("x"), NumberSyntax("123")), "x_{123}") + + @Test + fun binaryOperator() = testLatex("f(x, y)", "\\operatorname{f}\\left(x,y\\right)") + + @Test + fun binaryPlus() = testLatex("x+x", "x+x") + + @Test + fun binaryMinus() = testLatex("x-x", "x-x") + + @Test + fun fraction() = testLatex("x/x", "\\frac{x}{x}") + + @Test + fun radicalWithIndex() = testLatex(RadicalWithIndexSyntax("", SymbolSyntax("x"), SymbolSyntax("y")), "\\sqrt[x]{y}") + + @Test + fun multiplication() { + testLatex("x*1", "x\\times1") + testLatex("1*x", "1\\,x") + } +} diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestMathML.kt b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestMathML.kt new file mode 100644 index 000000000..2d7bfad19 --- /dev/null +++ b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestMathML.kt @@ -0,0 +1,92 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.ast.rendering + +import space.kscience.kmath.ast.rendering.TestUtils.testMathML +import space.kscience.kmath.expressions.MST +import space.kscience.kmath.operations.GroupOperations +import kotlin.test.Test + +internal class TestMathML { + @Test + fun number() = testMathML("42", "42") + + @Test + fun symbol() = testMathML("x", "x") + + @Test + fun operatorName() = testMathML( + "sin(1)", + "sin1", + ) + + @Test + fun specialSymbol() { + testMathML(MST.Numeric(Double.POSITIVE_INFINITY), "") + testMathML("pi", "π") + } + + @Test + fun operand() { + testMathML( + "sin(1)", + "sin1", + ) + + testMathML("1+1", "1+1") + } + + @Test + fun unaryOperator() = testMathML( + "sin(1)", + "sin1", + ) + + @Test + fun unaryPlus() = + testMathML(MST.Unary(GroupOperations.PLUS_OPERATION, MST.Numeric(1)), "+1") + + @Test + fun unaryMinus() = testMathML("-x", "-x") + + @Test + fun radical() = testMathML("sqrt(x)", "x") + + @Test + fun superscript() = testMathML("x^y", "xy") + + @Test + fun subscript() = testMathML( + SubscriptSyntax("", SymbolSyntax("x"), NumberSyntax("123")), + "x123", + ) + + @Test + fun binaryOperator() = testMathML( + "f(x, y)", + "fx,y", + ) + + @Test + fun binaryPlus() = testMathML("x+x", "x+x") + + @Test + fun binaryMinus() = testMathML("x-x", "x-x") + + @Test + fun fraction() = testMathML("x/x", "xx") + + @Test + fun radicalWithIndex() = + testMathML(RadicalWithIndexSyntax("", SymbolSyntax("x"), SymbolSyntax("y")), + "yx") + + @Test + fun multiplication() { + testMathML("x*1", "x×1") + testMathML("1*x", "1x") + } +} diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt new file mode 100644 index 000000000..a4017fdb4 --- /dev/null +++ b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.ast.rendering + +import space.kscience.kmath.ast.rendering.TestUtils.testLatex +import kotlin.test.Test + +internal class TestStages { + @Test + fun betterMultiplication() { + testLatex("a*1", "a\\times1") + testLatex("1*(2/3)", "1\\times\\left(\\frac{2}{3}\\right)") + testLatex("1*1", "1\\times1") + testLatex("2e10", "2\\times10^{10}") + testLatex("2*x", "2\\,x") + testLatex("2*(x+1)", "2\\,\\left(x+1\\right)") + testLatex("x*y", "x\\,y") + } + + @Test + fun parentheses() { + testLatex("(x+1)", "x+1") + testLatex("x*x*x", "x\\,x\\,x") + testLatex("(x+x)*x", "\\left(x+x\\right)\\,x") + testLatex("x+x*x", "x+x\\,x") + testLatex("x+x^x*x+x", "x+x^{x}\\,x+x") + testLatex("(x+x)^x+x*x", "\\left(x+x\\right)^{x}+x\\,x") + testLatex("x^(x+x)", "x^{x+x}") + } +} diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestUtils.kt b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestUtils.kt new file mode 100644 index 000000000..7c9400532 --- /dev/null +++ b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/rendering/TestUtils.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.ast.rendering + +import space.kscience.kmath.ast.parseMath +import space.kscience.kmath.expressions.MST +import kotlin.test.assertEquals + +internal object TestUtils { + private fun mathSyntax(mst: MST) = FeaturedMathRendererWithPostProcess.Default.render(mst) + private fun latex(mst: MST) = LatexSyntaxRenderer.renderWithStringBuilder(mathSyntax(mst)) + private fun mathML(mst: MST) = MathMLSyntaxRenderer.renderWithStringBuilder(mathSyntax(mst)) + + internal fun testLatex(mst: MST, expectedLatex: String) = assertEquals( + expected = expectedLatex, + actual = latex(mst), + ) + + internal fun testLatex(expression: String, expectedLatex: String) = assertEquals( + expected = expectedLatex, + actual = latex(expression.parseMath()), + ) + + internal fun testLatex(expression: MathSyntax, expectedLatex: String) = assertEquals( + expected = expectedLatex, + actual = LatexSyntaxRenderer.renderWithStringBuilder(expression), + ) + + internal fun testMathML(mst: MST, expectedMathML: String) = assertEquals( + expected = "$expectedMathML", + actual = mathML(mst), + ) + + internal fun testMathML(expression: String, expectedMathML: String) = assertEquals( + expected = "$expectedMathML", + actual = mathML(expression.parseMath()), + ) + + internal fun testMathML(expression: MathSyntax, expectedMathML: String) = assertEquals( + expected = "$expectedMathML", + actual = MathMLSyntaxRenderer.renderWithStringBuilder(expression), + ) +} diff --git a/kmath-commons/build.gradle.kts b/kmath-commons/build.gradle.kts index e73c4e527..570ac2b74 100644 --- a/kmath-commons/build.gradle.kts +++ b/kmath-commons/build.gradle.kts @@ -4,7 +4,8 @@ */ plugins { - id("ru.mipt.npm.gradle.jvm") + kotlin("jvm") + id("ru.mipt.npm.gradle.common") } description = "Commons math binding for kmath" @@ -17,6 +18,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/expressions/DerivativeStructureExpression.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpression.kt index aec62b264..736685789 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpression.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpression.kt @@ -7,6 +7,7 @@ package space.kscience.kmath.commons.expressions import org.apache.commons.math3.analysis.differentiation.DerivativeStructure import space.kscience.kmath.expressions.* +import space.kscience.kmath.misc.Symbol import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.operations.ExtendedField import space.kscience.kmath.operations.NumbersAddOperations @@ -28,7 +29,7 @@ public class DerivativeStructureField( public override val zero: DerivativeStructure by lazy { DerivativeStructure(numberOfVariables, order) } public override val one: DerivativeStructure by lazy { DerivativeStructure(numberOfVariables, order, 1.0) } - override fun number(value: Number): DerivativeStructure = const(value.toDouble()) + public override fun number(value: Number): DerivativeStructure = const(value.toDouble()) /** * A class that implements both [DerivativeStructure] and a [Symbol] @@ -39,10 +40,10 @@ public class DerivativeStructureField( symbol: Symbol, value: Double, ) : DerivativeStructure(size, order, index, value), Symbol { - override val identity: String = symbol.identity - override fun toString(): String = identity - override fun equals(other: Any?): Boolean = this.identity == (other as? Symbol)?.identity - override fun hashCode(): Int = identity.hashCode() + public override val identity: String = symbol.identity + public override fun toString(): String = identity + public override fun equals(other: Any?): Boolean = this.identity == (other as? Symbol)?.identity + public override fun hashCode(): Int = identity.hashCode() } /** @@ -52,13 +53,13 @@ public class DerivativeStructureField( key.identity to DerivativeStructureSymbol(numberOfVariables, index, key, value) }.toMap() - override fun const(value: Double): DerivativeStructure = DerivativeStructure(numberOfVariables, order, value) + public override fun const(value: Double): DerivativeStructure = DerivativeStructure(numberOfVariables, order, value) - public override fun bindSymbolOrNull(symbol: Symbol): DerivativeStructureSymbol? = variables[symbol.identity] + public override fun bindSymbolOrNull(value: String): DerivativeStructureSymbol? = variables[value] + public override fun bindSymbol(value: String): DerivativeStructureSymbol = variables.getValue(value) - public fun bind(symbol: Symbol): DerivativeStructureSymbol = variables.getValue(symbol.identity) - - override fun bindSymbol(value: String): DerivativeStructureSymbol = bind(StringSymbol(value)) + public fun bindSymbolOrNull(symbol: Symbol): DerivativeStructureSymbol? = variables[symbol.identity] + public fun bindSymbol(symbol: Symbol): DerivativeStructureSymbol = variables.getValue(symbol.identity) public fun DerivativeStructure.derivative(symbols: List): Double { require(symbols.size <= order) { "The order of derivative ${symbols.size} exceeds computed order $order" } @@ -68,7 +69,7 @@ public class DerivativeStructureField( public fun DerivativeStructure.derivative(vararg symbols: Symbol): Double = derivative(symbols.toList()) - override fun DerivativeStructure.unaryMinus(): DerivativeStructure = negate() + public override fun DerivativeStructure.unaryMinus(): DerivativeStructure = negate() public override fun add(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.add(b) @@ -111,7 +112,6 @@ public class DerivativeStructureField( } } - /** * A constructs that creates a derivative structure with required order on-demand */ 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..535c6b39e --- /dev/null +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt @@ -0,0 +1,97 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +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) + + IntegrandCallsPerformed(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..071bac315 --- /dev/null +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/GaussRuleIntegrator.kt @@ -0,0 +1,83 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ +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) + IntegrandCallsPerformed(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 65ce2f3a3..11b097831 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 @@ -8,9 +8,9 @@ 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.nd.NDStructure -import space.kscience.kmath.operations.RealField -import space.kscience.kmath.structures.RealBuffer +import space.kscience.kmath.nd.StructureFeature +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.structures.DoubleBuffer import kotlin.reflect.KClass import kotlin.reflect.cast @@ -19,17 +19,9 @@ public class CMMatrix(public val origin: RealMatrix) : Matrix { public override val colNum: Int get() = origin.columnDimension public override operator fun get(i: Int, j: Int): Double = origin.getEntry(i, j) - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is NDStructure<*>) return false - return NDStructure.contentEquals(this, other) - } - - override fun hashCode(): Int = origin.hashCode() } -public inline class CMVector(public val origin: RealVector) : Point { +public 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) @@ -39,15 +31,15 @@ public inline class CMVector(public val origin: RealVector) : Point { public fun RealVector.toPoint(): CMVector = CMVector(this) -public object CMLinearSpace : LinearSpace { - override val elementAlgebra: RealField get() = RealField +public object CMLinearSpace : LinearSpace { + override val elementAlgebra: DoubleField get() = DoubleField public override fun buildMatrix( rows: Int, columns: Int, - initializer: RealField.(i: Int, j: Int) -> Double, + initializer: DoubleField.(i: Int, j: Int) -> Double, ): CMMatrix { - val array = Array(rows) { i -> DoubleArray(columns) { j -> RealField.initializer(i, j) } } + val array = Array(rows) { i -> DoubleArray(columns) { j -> DoubleField.initializer(i, j) } } return CMMatrix(Array2DRowRealMatrix(array)) } @@ -69,8 +61,8 @@ public object CMLinearSpace : LinearSpace { internal fun RealMatrix.wrap(): CMMatrix = CMMatrix(this) internal fun RealVector.wrap(): CMVector = CMVector(this) - override fun buildVector(size: Int, initializer: RealField.(Int) -> Double): Point = - ArrayRealVector(DoubleArray(size) { RealField.initializer(it) }).wrap() + 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() @@ -103,7 +95,7 @@ public object CMLinearSpace : LinearSpace { v * this @UnstableKMathAPI - override fun getFeature(structure: Matrix, type: KClass): F? { + override fun getFeature(structure: Matrix, type: KClass): F? { //Return the feature if it is intrinsic to the structure structure.getFeature(type)?.let { return it } @@ -140,7 +132,7 @@ public object CMLinearSpace : LinearSpace { 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) } + override val singularValues: Point by lazy { DoubleBuffer(sv.singularValues) } } else -> null }?.let(type::cast) diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMSolver.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMSolver.kt index de8f9b4ce..ee602ca06 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMSolver.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMSolver.kt @@ -19,7 +19,7 @@ public enum class CMDecomposition { public fun CMLinearSpace.solver( a: Matrix, - decomposition: CMDecomposition = CMDecomposition.LUP + decomposition: CMDecomposition = CMDecomposition.LUP, ): DecompositionSolver = when (decomposition) { CMDecomposition.LUP -> LUDecomposition(a.toCM().origin).solver CMDecomposition.RRQR -> RRQRDecomposition(a.toCM().origin).solver @@ -31,16 +31,16 @@ public fun CMLinearSpace.solver( public fun CMLinearSpace.solve( a: Matrix, b: Matrix, - decomposition: CMDecomposition = CMDecomposition.LUP + decomposition: CMDecomposition = CMDecomposition.LUP, ): CMMatrix = solver(a, decomposition).solve(b.toCM().origin).wrap() public fun CMLinearSpace.solve( a: Matrix, b: Point, - decomposition: CMDecomposition = CMDecomposition.LUP + decomposition: CMDecomposition = CMDecomposition.LUP, ): CMVector = solver(a, decomposition).solve(b.toCM().origin).toPoint() public fun CMLinearSpace.inverse( a: Matrix, - decomposition: CMDecomposition = CMDecomposition.LUP + decomposition: CMDecomposition = CMDecomposition.LUP, ): CMMatrix = solver(a, decomposition).inverse.wrap() diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimizationProblem.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimization.kt similarity index 65% rename from kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimizationProblem.kt rename to kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimization.kt index 8b943ad8b..cfb8c39be 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimizationProblem.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimization.kt @@ -14,22 +14,36 @@ import org.apache.commons.math3.optim.nonlinear.scalar.gradient.NonLinearConjuga import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.AbstractSimplex import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.NelderMeadSimplex import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.SimplexOptimizer -import space.kscience.kmath.expressions.* -import space.kscience.kmath.stat.OptimizationFeature -import space.kscience.kmath.stat.OptimizationProblem -import space.kscience.kmath.stat.OptimizationProblemFactory -import space.kscience.kmath.stat.OptimizationResult +import space.kscience.kmath.expressions.DifferentiableExpression +import space.kscience.kmath.expressions.Expression +import space.kscience.kmath.expressions.SymbolIndexer +import space.kscience.kmath.expressions.derivative +import space.kscience.kmath.misc.Symbol +import space.kscience.kmath.misc.UnstableKMathAPI +import space.kscience.kmath.optimization.* import kotlin.reflect.KClass public operator fun PointValuePair.component1(): DoubleArray = point public operator fun PointValuePair.component2(): Double = value -public class CMOptimizationProblem(override val symbols: List, ) : - OptimizationProblem, SymbolIndexer, OptimizationFeature { +@OptIn(UnstableKMathAPI::class) +public class CMOptimization( + override val symbols: List, +) : FunctionOptimization, NoDerivFunctionOptimization, SymbolIndexer, OptimizationFeature { + private val optimizationData: HashMap, OptimizationData> = HashMap() - private var optimizatorBuilder: (() -> MultivariateOptimizer)? = null - public var convergenceChecker: ConvergenceChecker = SimpleValueChecker(DEFAULT_RELATIVE_TOLERANCE, - DEFAULT_ABSOLUTE_TOLERANCE, DEFAULT_MAX_ITER) + private var optimizerBuilder: (() -> MultivariateOptimizer)? = null + public var convergenceChecker: ConvergenceChecker = SimpleValueChecker( + DEFAULT_RELATIVE_TOLERANCE, + DEFAULT_ABSOLUTE_TOLERANCE, + DEFAULT_MAX_ITER + ) + + override var maximize: Boolean + get() = optimizationData[GoalType::class] == GoalType.MAXIMIZE + set(value) { + optimizationData[GoalType::class] = if (value) GoalType.MAXIMIZE else GoalType.MINIMIZE + } public fun addOptimizationData(data: OptimizationData) { optimizationData[data::class] = data @@ -45,7 +59,7 @@ public class CMOptimizationProblem(override val symbols: List, ) : addOptimizationData(InitialGuess(map.toDoubleArray())) } - public override fun expression(expression: Expression): Unit { + public override fun function(expression: Expression): Unit { val objectiveFunction = ObjectiveFunction { val args = it.toMap() expression(args) @@ -53,8 +67,8 @@ public class CMOptimizationProblem(override val symbols: List, ) : addOptimizationData(objectiveFunction) } - public override fun diffExpression(expression: DifferentiableExpression>) { - expression(expression) + public override fun diffFunction(expression: DifferentiableExpression>) { + function(expression) val gradientFunction = ObjectiveFunctionGradient { val args = it.toMap() DoubleArray(symbols.size) { index -> @@ -62,8 +76,8 @@ public class CMOptimizationProblem(override val symbols: List, ) : } } addOptimizationData(gradientFunction) - if (optimizatorBuilder == null) { - optimizatorBuilder = { + if (optimizerBuilder == null) { + optimizerBuilder = { NonLinearConjugateGradientOptimizer( NonLinearConjugateGradientOptimizer.Formula.FLETCHER_REEVES, convergenceChecker @@ -75,8 +89,8 @@ public class CMOptimizationProblem(override val symbols: List, ) : public fun simplex(simplex: AbstractSimplex) { addOptimizationData(simplex) //Set optimization builder to simplex if it is not present - if (optimizatorBuilder == null) { - optimizatorBuilder = { SimplexOptimizer(convergenceChecker) } + if (optimizerBuilder == null) { + optimizerBuilder = { SimplexOptimizer(convergenceChecker) } } } @@ -89,7 +103,7 @@ public class CMOptimizationProblem(override val symbols: List, ) : } public fun optimizer(block: () -> MultivariateOptimizer) { - optimizatorBuilder = block + optimizerBuilder = block } override fun update(result: OptimizationResult) { @@ -97,19 +111,19 @@ public class CMOptimizationProblem(override val symbols: List, ) : } override fun optimize(): OptimizationResult { - val optimizer = optimizatorBuilder?.invoke() ?: error("Optimizer not defined") + val optimizer = optimizerBuilder?.invoke() ?: error("Optimizer not defined") val (point, value) = optimizer.optimize(*optimizationData.values.toTypedArray()) return OptimizationResult(point.toMap(), value, setOf(this)) } - public companion object : OptimizationProblemFactory { + public companion object : OptimizationProblemFactory { public const val DEFAULT_RELATIVE_TOLERANCE: Double = 1e-4 public const val DEFAULT_ABSOLUTE_TOLERANCE: Double = 1e-4 public const val DEFAULT_MAX_ITER: Int = 1000 - override fun build(symbols: List): CMOptimizationProblem = CMOptimizationProblem(symbols) + override fun build(symbols: List): CMOptimization = CMOptimization(symbols) } } -public fun CMOptimizationProblem.initialGuess(vararg pairs: Pair): Unit = initialGuess(pairs.toMap()) -public fun CMOptimizationProblem.simplexSteps(vararg pairs: Pair): Unit = simplexSteps(pairs.toMap()) +public fun CMOptimization.initialGuess(vararg pairs: Pair): Unit = initialGuess(pairs.toMap()) +public fun CMOptimization.simplexSteps(vararg pairs: Pair): Unit = simplexSteps(pairs.toMap()) diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/cmFit.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/cmFit.kt index 14e995445..13b5c73f4 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/cmFit.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/cmFit.kt @@ -6,21 +6,21 @@ package space.kscience.kmath.commons.optimization import org.apache.commons.math3.analysis.differentiation.DerivativeStructure -import org.apache.commons.math3.optim.nonlinear.scalar.GoalType import space.kscience.kmath.commons.expressions.DerivativeStructureField import space.kscience.kmath.expressions.DifferentiableExpression import space.kscience.kmath.expressions.Expression -import space.kscience.kmath.expressions.Symbol -import space.kscience.kmath.stat.Fitting -import space.kscience.kmath.stat.OptimizationResult -import space.kscience.kmath.stat.optimizeWith +import space.kscience.kmath.misc.Symbol +import space.kscience.kmath.optimization.FunctionOptimization +import space.kscience.kmath.optimization.OptimizationResult +import space.kscience.kmath.optimization.noDerivOptimizeWith +import space.kscience.kmath.optimization.optimizeWith import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.asBuffer /** * Generate a chi squared expression from given x-y-sigma data and inline model. Provides automatic differentiation */ -public fun Fitting.chiSquared( +public fun FunctionOptimization.Companion.chiSquared( x: Buffer, y: Buffer, yErr: Buffer, @@ -30,7 +30,7 @@ public fun Fitting.chiSquared( /** * Generate a chi squared expression from given x-y-sigma data and inline model. Provides automatic differentiation */ -public fun Fitting.chiSquared( +public fun FunctionOptimization.Companion.chiSquared( x: Iterable, y: Iterable, yErr: Iterable, @@ -48,25 +48,26 @@ public fun Fitting.chiSquared( */ public fun Expression.optimize( vararg symbols: Symbol, - configuration: CMOptimizationProblem.() -> Unit, -): OptimizationResult = optimizeWith(CMOptimizationProblem, symbols = symbols, configuration) + configuration: CMOptimization.() -> Unit, +): OptimizationResult = noDerivOptimizeWith(CMOptimization, symbols = symbols, configuration) /** * Optimize differentiable expression */ public fun DifferentiableExpression>.optimize( vararg symbols: Symbol, - configuration: CMOptimizationProblem.() -> Unit, -): OptimizationResult = optimizeWith(CMOptimizationProblem, symbols = symbols, configuration) + configuration: CMOptimization.() -> Unit, +): OptimizationResult = optimizeWith(CMOptimization, symbols = symbols, configuration) public fun DifferentiableExpression>.minimize( vararg startPoint: Pair, - configuration: CMOptimizationProblem.() -> Unit = {}, + configuration: CMOptimization.() -> Unit = {}, ): OptimizationResult { - require(startPoint.isNotEmpty()) { "Must provide a list of symbols for optimization" } - val problem = CMOptimizationProblem(startPoint.map { it.first }).apply(configuration) - problem.diffExpression(this) - problem.initialGuess(startPoint.toMap()) - problem.goal(GoalType.MINIMIZE) - return problem.optimize() + val symbols = startPoint.map { it.first }.toTypedArray() + return optimize(*symbols){ + maximize = false + initialGuess(startPoint.toMap()) + diffFunction(this@minimize) + configuration() + } } \ No newline at end of file diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/transform/Transformations.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/transform/Transformations.kt index 93fa56322..d29491d63 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/transform/Transformations.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/transform/Transformations.kt @@ -15,6 +15,7 @@ import space.kscience.kmath.streaming.spread import space.kscience.kmath.structures.* + /** * Streaming and buffer transformations */ @@ -22,7 +23,7 @@ public object Transformations { private fun Buffer.toArray(): Array = Array(size) { org.apache.commons.math3.complex.Complex(get(it).re, get(it).im) } - private fun Buffer.asArray() = if (this is RealBuffer) { + private fun Buffer.asArray() = if (this is DoubleBuffer) { array } else { DoubleArray(size) { i -> get(i) } @@ -38,34 +39,34 @@ public object Transformations { public fun fourier( normalization: DftNormalization = DftNormalization.STANDARD, - direction: TransformType = TransformType.FORWARD + direction: TransformType = TransformType.FORWARD, ): SuspendBufferTransform = { FastFourierTransformer(normalization).transform(it.toArray(), direction).asBuffer() } public fun realFourier( normalization: DftNormalization = DftNormalization.STANDARD, - direction: TransformType = TransformType.FORWARD + direction: TransformType = TransformType.FORWARD, ): SuspendBufferTransform = { FastFourierTransformer(normalization).transform(it.asArray(), direction).asBuffer() } public fun sine( normalization: DstNormalization = DstNormalization.STANDARD_DST_I, - direction: TransformType = TransformType.FORWARD + direction: TransformType = TransformType.FORWARD, ): SuspendBufferTransform = { FastSineTransformer(normalization).transform(it.asArray(), direction).asBuffer() } public fun cosine( normalization: DctNormalization = DctNormalization.STANDARD_DCT_I, - direction: TransformType = TransformType.FORWARD + direction: TransformType = TransformType.FORWARD, ): SuspendBufferTransform = { FastCosineTransformer(normalization).transform(it.asArray(), direction).asBuffer() } public fun hadamard( - direction: TransformType = TransformType.FORWARD + direction: TransformType = TransformType.FORWARD, ): SuspendBufferTransform = { FastHadamardTransformer().transform(it.asArray(), direction).asBuffer() } @@ -77,7 +78,7 @@ public object Transformations { @FlowPreview public fun Flow>.FFT( normalization: DftNormalization = DftNormalization.STANDARD, - direction: TransformType = TransformType.FORWARD + direction: TransformType = TransformType.FORWARD, ): Flow> { val transform = Transformations.fourier(normalization, direction) return map { transform(it) } @@ -87,7 +88,7 @@ public fun Flow>.FFT( @JvmName("realFFT") public fun Flow>.FFT( normalization: DftNormalization = DftNormalization.STANDARD, - direction: TransformType = TransformType.FORWARD + direction: TransformType = TransformType.FORWARD, ): Flow> { val transform = Transformations.realFourier(normalization, direction) return map(transform) @@ -101,7 +102,7 @@ public fun Flow>.FFT( public fun Flow.FFT( bufferSize: Int = Int.MAX_VALUE, normalization: DftNormalization = DftNormalization.STANDARD, - direction: TransformType = TransformType.FORWARD + direction: TransformType = TransformType.FORWARD, ): Flow = chunked(bufferSize).FFT(normalization, direction).spread() /** diff --git a/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpressionTest.kt b/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpressionTest.kt index 6e3088dc7..879cd75b1 100644 --- a/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpressionTest.kt +++ b/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpressionTest.kt @@ -5,7 +5,11 @@ package space.kscience.kmath.commons.expressions -import space.kscience.kmath.expressions.* +import space.kscience.kmath.expressions.binding +import space.kscience.kmath.expressions.derivative +import space.kscience.kmath.expressions.invoke +import space.kscience.kmath.misc.Symbol +import space.kscience.kmath.misc.symbol import kotlin.contracts.InvocationKind import kotlin.contracts.contract import kotlin.test.Test @@ -28,14 +32,14 @@ internal class AutoDiffTest { @Test fun derivativeStructureFieldTest() { diff(2, x to 1.0, y to 1.0) { - val x = bind(x)//by binding() + val x = bindSymbol(x)//by binding() val y = bindSymbol("y") val z = x * (-sin(x * y) + y) + 2.0 println(z.derivative(x)) - println(z.derivative(y,x)) + println(z.derivative(y, x)) assertEquals(z.derivative(x, y), z.derivative(y, x)) //check that improper order cause failure - assertFails { z.derivative(x,x,y) } + assertFails { z.derivative(x, x, y) } } } diff --git a/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt b/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt new file mode 100644 index 000000000..9d475d04d --- /dev/null +++ b/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.commons.integration + +import org.junit.jupiter.api.Test +import space.kscience.kmath.integration.integrate +import space.kscience.kmath.misc.UnstableKMathAPI +import space.kscience.kmath.operations.DoubleField.sin +import kotlin.math.PI +import kotlin.math.abs +import kotlin.test.assertTrue + +@UnstableKMathAPI +internal class IntegrationTest { + private val function: (Double) -> Double = { sin(it) } + + @Test + fun simpson() { + val res = CMIntegrator.simpson().integrate(0.0..2 * PI, function) + assertTrue { abs(res) < 1e-3 } + } + + @Test + fun customSimpson() { + val res = CMIntegrator.simpson().integrate(0.0..PI, function) { + targetRelativeAccuracy = 1e-4 + targetAbsoluteAccuracy = 1e-4 + } + assertTrue { abs(res - 2) < 1e-3 } + assertTrue { abs(res - 2) > 1e-12 } + } +} \ No newline at end of file diff --git a/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt b/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt index 404215f71..716cd1b0f 100644 --- a/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt +++ b/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt @@ -5,21 +5,22 @@ package space.kscience.kmath.commons.optimization -import org.junit.jupiter.api.Test +import kotlinx.coroutines.runBlocking import space.kscience.kmath.commons.expressions.DerivativeStructureExpression -import space.kscience.kmath.expressions.symbol -import space.kscience.kmath.stat.Distribution -import space.kscience.kmath.stat.Fitting +import space.kscience.kmath.distributions.NormalDistribution +import space.kscience.kmath.misc.symbol +import space.kscience.kmath.optimization.FunctionOptimization import space.kscience.kmath.stat.RandomGenerator -import space.kscience.kmath.stat.normal import kotlin.math.pow +import kotlin.test.Test internal class OptimizeTest { val x by symbol val y by symbol val normal = DerivativeStructureExpression { - exp(-bind(x).pow(2) / 2) + exp(-bind(y).pow(2) / 2) + exp(-bindSymbol(x).pow(2) / 2) + exp(-bindSymbol(y) + .pow(2) / 2) } @Test @@ -39,35 +40,35 @@ internal class OptimizeTest { simplexSteps(x to 2.0, y to 0.5) //this sets simplex optimizer } + println(result.point) println(result.value) } @Test - fun testCmFit() { + fun testCmFit() = runBlocking { val a by symbol val b by symbol val c by symbol val sigma = 1.0 - val generator = Distribution.normal(0.0, sigma) + val generator = NormalDistribution(0.0, sigma) val chain = generator.sample(RandomGenerator.default(112667)) val x = (1..100).map(Int::toDouble) val y = x.map { - it.pow(2) + it + 1 + chain.nextDouble() + it.pow(2) + it + 1 + chain.next() } val yErr = List(x.size) { sigma } - val chi2 = Fitting.chiSquared(x, y, yErr) { x1 -> + val chi2 = FunctionOptimization.chiSquared(x, y, yErr) { x1 -> val cWithDefault = bindSymbolOrNull(c) ?: one - bind(a) * x1.pow(2) + bind(b) * x1 + cWithDefault + bindSymbol(a) * x1.pow(2) + bindSymbol(b) * x1 + cWithDefault } val result = chi2.minimize(a to 1.5, b to 0.9, c to 1.0) println(result) println("Chi2/dof = ${result.value / (x.size - 3)}") } - -} \ No newline at end of file +} diff --git a/kmath-complex/README.md b/kmath-complex/README.md index a6b87b81c..3a05c3d6d 100644 --- a/kmath-complex/README.md +++ b/kmath-complex/README.md @@ -1,42 +1,36 @@ -# The Core Module (`kmath-core`) +# Module kmath-complex -Complex and hypercomplex number systems in KMath: +Complex and hypercomplex number systems in KMath. - - [complex](src/commonMain/kotlin/kscience/kmath/complex/Complex.kt) : Complex Numbers - - [quaternion](src/commonMain/kotlin/kscience/kmath/complex/Quaternion.kt) : Quaternions + - [complex](src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt) : Complex Numbers + - [quaternion](src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt) : Quaternions -> #### Artifact: -> -> This module artifact: `space.kscience:kmath-complex:0.3.0-dev-2`. -> -> Bintray release version: [ ![Download](https://api.bintray.com/packages/mipt-npm/kscience/kmath-complex/images/download.svg) ](https://bintray.com/mipt-npm/kscience/kmath-complex/_latestVersion) -> -> Bintray development version: [ ![Download](https://api.bintray.com/packages/mipt-npm/dev/kmath-complex/images/download.svg) ](https://bintray.com/mipt-npm/dev/kmath-complex/_latestVersion) -> -> **Gradle:** -> -> ```gradle -> repositories { -> maven { url 'https://repo.kotlin.link' } -> maven { url 'https://dl.bintray.com/hotkeytlt/maven' } -> maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap -> } -> -> dependencies { -> implementation 'space.kscience:kmath-complex:0.3.0-dev-2' -> } -> ``` -> **Gradle Kotlin DSL:** -> -> ```kotlin -> repositories { -> maven("https://repo.kotlin.link") -> maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap -> maven("https://dl.bintray.com/hotkeytlt/maven") // required for a -> } -> -> dependencies { -> implementation("space.kscience:kmath-complex:0.3.0-dev-2") -> } -> ``` +## Artifact: + +The Maven coordinates of this project are `space.kscience:kmath-complex:0.3.0-dev-6`. + +**Gradle:** +```gradle +repositories { + maven { url 'https://repo.kotlin.link' } + maven { url 'https://dl.bintray.com/hotkeytlt/maven' } + maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap +} + +dependencies { + implementation 'space.kscience:kmath-complex:0.3.0-dev-6' +} +``` +**Gradle Kotlin DSL:** +```kotlin +repositories { + maven("https://repo.kotlin.link") + maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap + maven("https://dl.bintray.com/hotkeytlt/maven") // required for a +} + +dependencies { + implementation("space.kscience:kmath-complex:0.3.0-dev-6") +} +``` diff --git a/kmath-complex/build.gradle.kts b/kmath-complex/build.gradle.kts index 876e325d0..43911e70d 100644 --- a/kmath-complex/build.gradle.kts +++ b/kmath-complex/build.gradle.kts @@ -1,12 +1,13 @@ +import ru.mipt.npm.gradle.Maturity + /* * Copyright 2018-2021 KMath contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ -import ru.mipt.npm.gradle.Maturity - plugins { - id("ru.mipt.npm.gradle.mpp") + kotlin("multiplatform") + id("ru.mipt.npm.gradle.common") id("ru.mipt.npm.gradle.native") } @@ -30,12 +31,12 @@ readme { feature( id = "complex", description = "Complex Numbers", - ref = "src/commonMain/kotlin/kscience/kmath/complex/Complex.kt" + ref = "src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt" ) feature( id = "quaternion", description = "Quaternions", - ref = "src/commonMain/kotlin/kscience/kmath/complex/Quaternion.kt" + ref = "src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt" ) } diff --git a/kmath-complex/docs/README-TEMPLATE.md b/kmath-complex/docs/README-TEMPLATE.md index 462fd617e..106d4aff1 100644 --- a/kmath-complex/docs/README-TEMPLATE.md +++ b/kmath-complex/docs/README-TEMPLATE.md @@ -1,6 +1,6 @@ -# The Core Module (`kmath-core`) +# Module kmath-complex -Complex and hypercomplex number systems in KMath: +Complex and hypercomplex number systems in KMath. ${features} diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt index 21e223306..8d626c17d 100644 --- a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt +++ b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt @@ -126,8 +126,8 @@ public object ComplexField : ExtendedField, Norm, Num /** * Adds complex number to real one. * - * @receiver the addend. - * @param c the augend. + * @receiver the augend. + * @param c the addend. * @return the sum. */ public operator fun Double.plus(c: Complex): Complex = add(this.toComplex(), c) @@ -144,8 +144,8 @@ public object ComplexField : ExtendedField, Norm, Num /** * Adds real number to complex one. * - * @receiver the addend. - * @param d the augend. + * @receiver the augend. + * @param d the addend. * @return the sum. */ public operator fun Complex.plus(d: Double): Complex = d + this @@ -170,8 +170,7 @@ public object ComplexField : ExtendedField, Norm, Num public override fun norm(arg: Complex): Complex = sqrt(arg.conjugate * arg) - public override fun bindSymbol(value: String): Complex = - if (value == "i") i else super.bindSymbol(value) + public override fun bindSymbolOrNull(value: String): Complex? = if (value == "i") i else null } /** diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/ComplexFieldND.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/ComplexFieldND.kt new file mode 100644 index 000000000..2c783eda0 --- /dev/null +++ b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/ComplexFieldND.kt @@ -0,0 +1,124 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.complex + +import space.kscience.kmath.misc.UnstableKMathAPI +import space.kscience.kmath.nd.AlgebraND +import space.kscience.kmath.nd.BufferND +import space.kscience.kmath.nd.BufferedFieldND +import space.kscience.kmath.nd.StructureND +import space.kscience.kmath.operations.ExtendedField +import space.kscience.kmath.operations.NumbersAddOperations +import space.kscience.kmath.structures.Buffer +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract + + +/** + * An optimized nd-field for complex numbers + */ +@OptIn(UnstableKMathAPI::class) +public class ComplexFieldND( + shape: IntArray, +) : BufferedFieldND(shape, ComplexField, Buffer.Companion::complex), + NumbersAddOperations>, + ExtendedField> { + + public override val zero: BufferND by lazy { produce { zero } } + public override val one: BufferND by lazy { produce { one } } + + public override fun number(value: Number): BufferND { + val d = value.toComplex() // minimize conversions + return produce { d } + } + +// +// @Suppress("OVERRIDE_BY_INLINE") +// override inline fun map( +// arg: AbstractNDBuffer, +// transform: DoubleField.(Double) -> Double, +// ): RealNDElement { +// check(arg) +// val array = RealBuffer(arg.strides.linearSize) { offset -> DoubleField.transform(arg.buffer[offset]) } +// return BufferedNDFieldElement(this, array) +// } +// +// @Suppress("OVERRIDE_BY_INLINE") +// override inline fun produce(initializer: DoubleField.(IntArray) -> Double): RealNDElement { +// val array = RealBuffer(strides.linearSize) { offset -> elementContext.initializer(strides.index(offset)) } +// return BufferedNDFieldElement(this, array) +// } +// +// @Suppress("OVERRIDE_BY_INLINE") +// override inline fun mapIndexed( +// arg: AbstractNDBuffer, +// transform: DoubleField.(index: IntArray, Double) -> Double, +// ): RealNDElement { +// check(arg) +// return BufferedNDFieldElement( +// this, +// RealBuffer(arg.strides.linearSize) { offset -> +// elementContext.transform( +// arg.strides.index(offset), +// arg.buffer[offset] +// ) +// }) +// } +// +// @Suppress("OVERRIDE_BY_INLINE") +// override inline fun combine( +// a: AbstractNDBuffer, +// b: AbstractNDBuffer, +// transform: DoubleField.(Double, Double) -> Double, +// ): RealNDElement { +// check(a, b) +// val buffer = RealBuffer(strides.linearSize) { offset -> +// elementContext.transform(a.buffer[offset], b.buffer[offset]) +// } +// return BufferedNDFieldElement(this, buffer) +// } + + public override fun power(arg: StructureND, pow: Number): BufferND = arg.map { power(it, pow) } + + public override fun exp(arg: StructureND): BufferND = arg.map { exp(it) } + + public override fun ln(arg: StructureND): BufferND = arg.map { ln(it) } + + public override fun sin(arg: StructureND): BufferND = arg.map { sin(it) } + public override fun cos(arg: StructureND): BufferND = arg.map { cos(it) } + public override fun tan(arg: StructureND): BufferND = arg.map { tan(it) } + public override fun asin(arg: StructureND): BufferND = arg.map { asin(it) } + public override fun acos(arg: StructureND): BufferND = arg.map { acos(it) } + public override fun atan(arg: StructureND): BufferND = arg.map { atan(it) } + + public override fun sinh(arg: StructureND): BufferND = arg.map { sinh(it) } + public override fun cosh(arg: StructureND): BufferND = arg.map { cosh(it) } + public override fun tanh(arg: StructureND): BufferND = arg.map { tanh(it) } + public override fun asinh(arg: StructureND): BufferND = arg.map { asinh(it) } + public override fun acosh(arg: StructureND): BufferND = arg.map { acosh(it) } + public override fun atanh(arg: StructureND): BufferND = arg.map { atanh(it) } +} + + +/** + * Fast element production using function inlining + */ +public inline fun BufferedFieldND.produceInline(initializer: ComplexField.(Int) -> Complex): BufferND { + contract { callsInPlace(initializer, InvocationKind.EXACTLY_ONCE) } + val buffer = Buffer.complex(strides.linearSize) { offset -> ComplexField.initializer(offset) } + return BufferND(strides, buffer) +} + + +public fun AlgebraND.Companion.complex(vararg shape: Int): ComplexFieldND = ComplexFieldND(shape) + +/** + * Produce a context for n-dimensional operations inside this real field + */ +public inline fun ComplexField.nd(vararg shape: Int, action: ComplexFieldND.() -> R): R { + contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } + return ComplexFieldND(shape).action() +} diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/ComplexNDField.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/ComplexNDField.kt deleted file mode 100644 index 497d96cc2..000000000 --- a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/ComplexNDField.kt +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2018-2021 KMath contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package space.kscience.kmath.complex - -import space.kscience.kmath.misc.UnstableKMathAPI -import space.kscience.kmath.nd.BufferedNDField -import space.kscience.kmath.nd.NDAlgebra -import space.kscience.kmath.nd.NDBuffer -import space.kscience.kmath.nd.NDStructure -import space.kscience.kmath.operations.ExtendedField -import space.kscience.kmath.operations.NumbersAddOperations -import space.kscience.kmath.structures.Buffer -import kotlin.contracts.InvocationKind -import kotlin.contracts.contract - - -/** - * An optimized nd-field for complex numbers - */ -@OptIn(UnstableKMathAPI::class) -public class ComplexNDField( - shape: IntArray, -) : BufferedNDField(shape, ComplexField, Buffer.Companion::complex), - NumbersAddOperations>, - ExtendedField> { - - 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.toComplex() // minimize conversions - return produce { d } - } - -// -// @Suppress("OVERRIDE_BY_INLINE") -// override inline fun map( -// arg: AbstractNDBuffer, -// transform: RealField.(Double) -> Double, -// ): RealNDElement { -// check(arg) -// val array = RealBuffer(arg.strides.linearSize) { offset -> RealField.transform(arg.buffer[offset]) } -// return BufferedNDFieldElement(this, array) -// } -// -// @Suppress("OVERRIDE_BY_INLINE") -// override inline fun produce(initializer: RealField.(IntArray) -> Double): RealNDElement { -// val array = RealBuffer(strides.linearSize) { offset -> elementContext.initializer(strides.index(offset)) } -// return BufferedNDFieldElement(this, array) -// } -// -// @Suppress("OVERRIDE_BY_INLINE") -// override inline fun mapIndexed( -// arg: AbstractNDBuffer, -// transform: RealField.(index: IntArray, Double) -> Double, -// ): RealNDElement { -// check(arg) -// return BufferedNDFieldElement( -// this, -// RealBuffer(arg.strides.linearSize) { offset -> -// elementContext.transform( -// arg.strides.index(offset), -// arg.buffer[offset] -// ) -// }) -// } -// -// @Suppress("OVERRIDE_BY_INLINE") -// override inline fun combine( -// a: AbstractNDBuffer, -// b: AbstractNDBuffer, -// transform: RealField.(Double, Double) -> Double, -// ): RealNDElement { -// check(a, b) -// val buffer = RealBuffer(strides.linearSize) { offset -> -// elementContext.transform(a.buffer[offset], b.buffer[offset]) -// } -// return BufferedNDFieldElement(this, buffer) -// } - - 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) } -} - - -/** - * Fast element production using function inlining - */ -public inline fun BufferedNDField.produceInline(initializer: ComplexField.(Int) -> Complex): NDBuffer { - contract { callsInPlace(initializer, InvocationKind.EXACTLY_ONCE) } - val buffer = Buffer.complex(strides.linearSize) { offset -> ComplexField.initializer(offset) } - return NDBuffer(strides, buffer) -} - - -public fun NDAlgebra.Companion.complex(vararg shape: Int): ComplexNDField = ComplexNDField(shape) - -/** - * Produce a context for n-dimensional operations inside this real field - */ -public inline fun ComplexField.nd(vararg shape: Int, action: ComplexNDField.() -> R): R { - contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } - return ComplexNDField(shape).action() -} diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt index a09f02f0f..382b5cc05 100644 --- a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt +++ b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt @@ -170,14 +170,14 @@ public object QuaternionField : Field, Norm, public override fun Quaternion.unaryMinus(): Quaternion = Quaternion(-w, -x, -y, -z) public override fun norm(arg: Quaternion): Quaternion = sqrt(arg.conjugate * arg) - public override fun bindSymbol(value: String): Quaternion = when (value) { + public override fun bindSymbolOrNull(value: String): Quaternion? = when (value) { "i" -> i "j" -> j "k" -> k - else -> super.bindSymbol(value) + else -> null } - override fun number(value: Number): Quaternion =value.toQuaternion() + override fun number(value: Number): Quaternion = value.toQuaternion() public override fun sinh(arg: Quaternion): Quaternion = (exp(arg) - exp(-arg)) / 2.0 public override fun cosh(arg: Quaternion): Quaternion = (exp(arg) + exp(-arg)) / 2.0 diff --git a/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ExpressionFieldForComplexTest.kt b/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ExpressionFieldForComplexTest.kt index 8dd27d588..e023fcb81 100644 --- a/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ExpressionFieldForComplexTest.kt +++ b/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ExpressionFieldForComplexTest.kt @@ -6,9 +6,9 @@ package space.kscience.kmath.complex import space.kscience.kmath.expressions.FunctionalExpressionField -import space.kscience.kmath.expressions.bindSymbol import space.kscience.kmath.expressions.invoke -import space.kscience.kmath.expressions.symbol +import space.kscience.kmath.misc.symbol +import space.kscience.kmath.operations.bindSymbol import kotlin.test.Test import kotlin.test.assertEquals diff --git a/kmath-core/README.md b/kmath-core/README.md index 2ec97073e..b83fb13d0 100644 --- a/kmath-core/README.md +++ b/kmath-core/README.md @@ -1,49 +1,43 @@ -# The Core Module (`kmath-core`) +# Module kmath-core -The core features of KMath: +The core interfaces of KMath. - - [algebras](src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt) : Algebraic structures like rings, spaces and fields. - - [nd](src/commonMain/kotlin/kscience/kmath/structures/NDStructure.kt) : Many-dimensional structures and operations on them. - - [linear](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](src/commonMain/kotlin/kscience/kmath/structures/Buffers.kt) : One-dimensional structure - - [expressions](src/commonMain/kotlin/kscience/kmath/expressions) : By writing a single mathematical expression once, users will be able to apply different types of + - [algebras](src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Algebraic structures like rings, spaces and fields. + - [nd](src/commonMain/kotlin/space/kscience/kmath/structures/StructureND.kt) : Many-dimensional structures and operations on them. + - [linear](src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Basic linear algebra operations (sums, products, etc.), backed by the `Space` API. Advanced linear algebra operations like matrix inversion and LU decomposition. + - [buffers](src/commonMain/kotlin/space/kscience/kmath/structures/Buffers.kt) : One-dimensional structure + - [expressions](src/commonMain/kotlin/space/kscience/kmath/expressions) : By writing a single mathematical expression once, users will be able to apply different types of objects to the expression by providing a context. Expressions can be used for a wide variety of purposes from high performance calculations to code generation. - - [domains](src/commonMain/kotlin/kscience/kmath/domains) : Domains - - [autodif](src/commonMain/kotlin/kscience/kmath/expressions/SimpleAutoDiff.kt) : Automatic differentiation + - [domains](src/commonMain/kotlin/space/kscience/kmath/domains) : Domains + - [autodif](src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt) : Automatic differentiation -> #### Artifact: -> -> This module artifact: `space.kscience:kmath-core:0.3.0-dev-2`. -> -> Bintray release version: [ ![Download](https://api.bintray.com/packages/mipt-npm/kscience/kmath-core/images/download.svg) ](https://bintray.com/mipt-npm/kscience/kmath-core/_latestVersion) -> -> Bintray development version: [ ![Download](https://api.bintray.com/packages/mipt-npm/dev/kmath-core/images/download.svg) ](https://bintray.com/mipt-npm/dev/kmath-core/_latestVersion) -> -> **Gradle:** -> -> ```gradle -> repositories { -> maven { url 'https://repo.kotlin.link' } -> maven { url 'https://dl.bintray.com/hotkeytlt/maven' } -> maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap -> } -> -> dependencies { -> implementation 'space.kscience:kmath-core:0.3.0-dev-2' -> } -> ``` -> **Gradle Kotlin DSL:** -> -> ```kotlin -> repositories { -> maven("https://repo.kotlin.link") -> maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap -> maven("https://dl.bintray.com/hotkeytlt/maven") // required for a -> } -> -> dependencies { -> implementation("space.kscience:kmath-core:0.3.0-dev-2") -> } -> ``` +## Artifact: + +The Maven coordinates of this project are `space.kscience:kmath-core:0.3.0-dev-6`. + +**Gradle:** +```gradle +repositories { + maven { url 'https://repo.kotlin.link' } + maven { url 'https://dl.bintray.com/hotkeytlt/maven' } + maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap +} + +dependencies { + implementation 'space.kscience:kmath-core:0.3.0-dev-6' +} +``` +**Gradle Kotlin DSL:** +```kotlin +repositories { + maven("https://repo.kotlin.link") + maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap + maven("https://dl.bintray.com/hotkeytlt/maven") // required for a +} + +dependencies { + implementation("space.kscience:kmath-core:0.3.0-dev-6") +} +``` diff --git a/kmath-core/api/kmath-core.api b/kmath-core/api/kmath-core.api index c5e13fe20..6b300123c 100644 --- a/kmath-core/api/kmath-core.api +++ b/kmath-core/api/kmath-core.api @@ -1,3 +1,10 @@ +public final class space/kscience/kmath/data/ColumnarDataKt { +} + +public final class space/kscience/kmath/data/XYColumnarDataKt { + public static synthetic fun asXYData$default (Lspace/kscience/kmath/nd/Structure2D;IIILjava/lang/Object;)Lspace/kscience/kmath/data/XYColumnarData; +} + public abstract interface class space/kscience/kmath/domains/Domain { public abstract fun contains (Lspace/kscience/kmath/structures/Buffer;)Z public abstract fun getDimension ()I @@ -14,7 +21,7 @@ public class space/kscience/kmath/expressions/AutoDiffValue { public final class space/kscience/kmath/expressions/DerivationResult { public fun (Ljava/lang/Object;Ljava/util/Map;Lspace/kscience/kmath/operations/Field;)V - public final fun derivative (Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; + public final fun derivative (Lspace/kscience/kmath/misc/Symbol;)Ljava/lang/Object; public final fun div ()Ljava/lang/Object; public final fun getContext ()Lspace/kscience/kmath/operations/Field; public final fun getValue ()Ljava/lang/Object; @@ -27,7 +34,7 @@ public abstract interface class space/kscience/kmath/expressions/DifferentiableE public final class space/kscience/kmath/expressions/DifferentiableExpressionKt { public static final fun derivative (Lspace/kscience/kmath/expressions/DifferentiableExpression;Ljava/lang/String;)Lspace/kscience/kmath/expressions/Expression; public static final fun derivative (Lspace/kscience/kmath/expressions/DifferentiableExpression;Ljava/util/List;)Lspace/kscience/kmath/expressions/Expression; - public static final fun derivative (Lspace/kscience/kmath/expressions/DifferentiableExpression;[Lspace/kscience/kmath/expressions/Symbol;)Lspace/kscience/kmath/expressions/Expression; + public static final fun derivative (Lspace/kscience/kmath/expressions/DifferentiableExpression;[Lspace/kscience/kmath/misc/Symbol;)Lspace/kscience/kmath/expressions/Expression; } public abstract interface class space/kscience/kmath/expressions/Expression { @@ -35,55 +42,37 @@ public abstract interface class space/kscience/kmath/expressions/Expression { } public abstract interface class space/kscience/kmath/expressions/ExpressionAlgebra : space/kscience/kmath/operations/Algebra { - public abstract fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; - public abstract fun bindSymbolOrNull (Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; public abstract fun const (Ljava/lang/Object;)Ljava/lang/Object; } -public final class space/kscience/kmath/expressions/ExpressionAlgebra$DefaultImpls { - public static fun binaryOperation (Lspace/kscience/kmath/expressions/ExpressionAlgebra;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun binaryOperationFunction (Lspace/kscience/kmath/expressions/ExpressionAlgebra;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun bindSymbol (Lspace/kscience/kmath/expressions/ExpressionAlgebra;Ljava/lang/String;)Ljava/lang/Object; - public static fun unaryOperation (Lspace/kscience/kmath/expressions/ExpressionAlgebra;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperationFunction (Lspace/kscience/kmath/expressions/ExpressionAlgebra;Ljava/lang/String;)Lkotlin/jvm/functions/Function1; -} - public final class space/kscience/kmath/expressions/ExpressionBuildersKt { public static final fun extendedFieldExpression (Lspace/kscience/kmath/operations/ExtendedField;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression; public static final fun fieldExpression (Lspace/kscience/kmath/operations/Field;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression; public static final fun ringExpression (Lspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression; - public static final fun spaceExpression (Lspace/kscience/kmath/operations/Group;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression; + public static final fun spaceExpression (Lspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression; } public final class space/kscience/kmath/expressions/ExpressionKt { - public static final fun bindSymbol (Lspace/kscience/kmath/expressions/ExpressionAlgebra;Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; public static final fun binding (Lspace/kscience/kmath/expressions/ExpressionAlgebra;)Lkotlin/properties/ReadOnlyProperty; public static final fun callByString (Lspace/kscience/kmath/expressions/Expression;[Lkotlin/Pair;)Ljava/lang/Object; public static final fun callBySymbol (Lspace/kscience/kmath/expressions/Expression;[Lkotlin/Pair;)Ljava/lang/Object; - public static final fun getSymbol ()Lkotlin/properties/ReadOnlyProperty; public static final fun invoke (Lspace/kscience/kmath/expressions/Expression;)Ljava/lang/Object; } public abstract class space/kscience/kmath/expressions/FirstDerivativeExpression : space/kscience/kmath/expressions/DifferentiableExpression { public fun ()V public final fun derivativeOrNull (Ljava/util/List;)Lspace/kscience/kmath/expressions/Expression; - public abstract fun derivativeOrNull (Lspace/kscience/kmath/expressions/Symbol;)Lspace/kscience/kmath/expressions/Expression; + public abstract fun derivativeOrNull (Lspace/kscience/kmath/misc/Symbol;)Lspace/kscience/kmath/expressions/Expression; } public abstract class space/kscience/kmath/expressions/FunctionalExpressionAlgebra : space/kscience/kmath/expressions/ExpressionAlgebra { public fun (Lspace/kscience/kmath/operations/Algebra;)V - public synthetic fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperation (Ljava/lang/String;Lspace/kscience/kmath/expressions/Expression;Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; - public fun bindSymbol (Ljava/lang/String;)Lspace/kscience/kmath/expressions/Expression; - public synthetic fun bindSymbolOrNull (Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; - public fun bindSymbolOrNull (Lspace/kscience/kmath/expressions/Symbol;)Lspace/kscience/kmath/expressions/Expression; + public synthetic fun bindSymbolOrNull (Ljava/lang/String;)Ljava/lang/Object; + public fun bindSymbolOrNull (Ljava/lang/String;)Lspace/kscience/kmath/expressions/Expression; public synthetic fun const (Ljava/lang/Object;)Ljava/lang/Object; public fun const (Ljava/lang/Object;)Lspace/kscience/kmath/expressions/Expression; public final fun getAlgebra ()Lspace/kscience/kmath/operations/Algebra; - public synthetic fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperation (Ljava/lang/String;Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; } @@ -91,77 +80,48 @@ public final class space/kscience/kmath/expressions/FunctionalExpressionAlgebraK public static final fun expressionInExtendedField (Lspace/kscience/kmath/operations/ExtendedField;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression; public static final fun expressionInField (Lspace/kscience/kmath/operations/Field;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression; public static final fun expressionInRing (Lspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression; - public static final fun expressionInSpace (Lspace/kscience/kmath/operations/Group;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression; + public static final fun expressionInSpace (Lspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression; } public class space/kscience/kmath/expressions/FunctionalExpressionExtendedField : space/kscience/kmath/expressions/FunctionalExpressionField, space/kscience/kmath/operations/ExtendedField { public fun (Lspace/kscience/kmath/operations/ExtendedField;)V public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; public fun acos (Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; - public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun acosh (Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; public fun asin (Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; - public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun asinh (Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; public fun atan (Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; - public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun atanh (Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; + public fun bindSymbol (Ljava/lang/String;)Lspace/kscience/kmath/expressions/Expression; public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; public fun cos (Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; - public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun cosh (Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; public fun exp (Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; public fun ln (Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/expressions/Expression; - public synthetic fun pow (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun pow (Lspace/kscience/kmath/expressions/Expression;Ljava/lang/Number;)Lspace/kscience/kmath/expressions/Expression; public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; public fun power (Lspace/kscience/kmath/expressions/Expression;Ljava/lang/Number;)Lspace/kscience/kmath/expressions/Expression; - public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; public fun sin (Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; - public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun sinh (Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; public synthetic fun sqrt (Ljava/lang/Object;)Ljava/lang/Object; public fun sqrt (Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; - public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; - public fun tan (Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; - public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun tanh (Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; } public class space/kscience/kmath/expressions/FunctionalExpressionField : space/kscience/kmath/expressions/FunctionalExpressionRing, space/kscience/kmath/operations/Field, space/kscience/kmath/operations/ScaleOperations { public fun (Lspace/kscience/kmath/operations/Field;)V public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun bindSymbolOrNull (Ljava/lang/String;)Ljava/lang/Object; + public fun bindSymbolOrNull (Ljava/lang/String;)Lspace/kscience/kmath/expressions/Expression; public final fun div (Ljava/lang/Object;Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; - public fun div (Lspace/kscience/kmath/expressions/Expression;Ljava/lang/Number;)Lspace/kscience/kmath/expressions/Expression; public final fun div (Lspace/kscience/kmath/expressions/Expression;Ljava/lang/Object;)Lspace/kscience/kmath/expressions/Expression; - public fun div (Lspace/kscience/kmath/expressions/Expression;Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun divide (Lspace/kscience/kmath/expressions/Expression;Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; - public synthetic fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; - public fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; - public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/expressions/Expression; - public synthetic fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun rightSideNumberOperation (Ljava/lang/String;Lspace/kscience/kmath/expressions/Expression;Ljava/lang/Number;)Lspace/kscience/kmath/expressions/Expression; - public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; public fun scale (Lspace/kscience/kmath/expressions/Expression;D)Lspace/kscience/kmath/expressions/Expression; - public synthetic fun times (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun times (Ljava/lang/Number;Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun times (Lspace/kscience/kmath/expressions/Expression;Ljava/lang/Number;)Lspace/kscience/kmath/expressions/Expression; public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; } @@ -172,19 +132,13 @@ public class space/kscience/kmath/expressions/FunctionalExpressionGroup : space/ public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public synthetic fun getZero ()Ljava/lang/Object; public fun getZero ()Lspace/kscience/kmath/expressions/Expression; - public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public final fun minus (Ljava/lang/Object;Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; public final fun minus (Lspace/kscience/kmath/expressions/Expression;Ljava/lang/Object;)Lspace/kscience/kmath/expressions/Expression; - public fun minus (Lspace/kscience/kmath/expressions/Expression;Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public final fun plus (Ljava/lang/Object;Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; public final fun plus (Lspace/kscience/kmath/expressions/Expression;Ljava/lang/Object;)Lspace/kscience/kmath/expressions/Expression; - public fun plus (Lspace/kscience/kmath/expressions/Expression;Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; public fun unaryMinus (Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryPlus (Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; } public class space/kscience/kmath/expressions/FunctionalExpressionRing : space/kscience/kmath/expressions/FunctionalExpressionGroup, space/kscience/kmath/operations/Ring { @@ -194,16 +148,220 @@ public class space/kscience/kmath/expressions/FunctionalExpressionRing : space/k public fun getOne ()Lspace/kscience/kmath/expressions/Expression; public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun multiply (Lspace/kscience/kmath/expressions/Expression;Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public final fun times (Ljava/lang/Object;Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; public final fun times (Lspace/kscience/kmath/expressions/Expression;Ljava/lang/Object;)Lspace/kscience/kmath/expressions/Expression; - public fun times (Lspace/kscience/kmath/expressions/Expression;Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression; public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; } +public abstract class space/kscience/kmath/expressions/MST { +} + +public final class space/kscience/kmath/expressions/MST$Binary : space/kscience/kmath/expressions/MST { + public fun (Ljava/lang/String;Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/expressions/MST;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Lspace/kscience/kmath/expressions/MST; + public final fun component3 ()Lspace/kscience/kmath/expressions/MST; + public final fun copy (Ljava/lang/String;Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Binary; + public static synthetic fun copy$default (Lspace/kscience/kmath/expressions/MST$Binary;Ljava/lang/String;Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/expressions/MST;ILjava/lang/Object;)Lspace/kscience/kmath/expressions/MST$Binary; + public fun equals (Ljava/lang/Object;)Z + public final fun getLeft ()Lspace/kscience/kmath/expressions/MST; + public final fun getOperation ()Ljava/lang/String; + public final fun getRight ()Lspace/kscience/kmath/expressions/MST; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class space/kscience/kmath/expressions/MST$Numeric : space/kscience/kmath/expressions/MST { + public fun (Ljava/lang/Number;)V + public final fun component1 ()Ljava/lang/Number; + public final fun copy (Ljava/lang/Number;)Lspace/kscience/kmath/expressions/MST$Numeric; + public static synthetic fun copy$default (Lspace/kscience/kmath/expressions/MST$Numeric;Ljava/lang/Number;ILjava/lang/Object;)Lspace/kscience/kmath/expressions/MST$Numeric; + public fun equals (Ljava/lang/Object;)Z + public final fun getValue ()Ljava/lang/Number; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class space/kscience/kmath/expressions/MST$Symbolic : space/kscience/kmath/expressions/MST { + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lspace/kscience/kmath/expressions/MST$Symbolic; + public static synthetic fun copy$default (Lspace/kscience/kmath/expressions/MST$Symbolic;Ljava/lang/String;ILjava/lang/Object;)Lspace/kscience/kmath/expressions/MST$Symbolic; + public fun equals (Ljava/lang/Object;)Z + public final fun getValue ()Ljava/lang/String; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class space/kscience/kmath/expressions/MST$Unary : space/kscience/kmath/expressions/MST { + public fun (Ljava/lang/String;Lspace/kscience/kmath/expressions/MST;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Lspace/kscience/kmath/expressions/MST; + public final fun copy (Ljava/lang/String;Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public static synthetic fun copy$default (Lspace/kscience/kmath/expressions/MST$Unary;Ljava/lang/String;Lspace/kscience/kmath/expressions/MST;ILjava/lang/Object;)Lspace/kscience/kmath/expressions/MST$Unary; + public fun equals (Ljava/lang/Object;)Z + public final fun getOperation ()Ljava/lang/String; + public final fun getValue ()Lspace/kscience/kmath/expressions/MST; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class space/kscience/kmath/expressions/MSTKt { + public static final fun evaluate (Lspace/kscience/kmath/operations/Algebra;Lspace/kscience/kmath/expressions/MST;)Ljava/lang/Object; + public static final fun interpret (Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/operations/Algebra;Ljava/util/Map;)Ljava/lang/Object; + public static final fun interpret (Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/operations/Algebra;[Lkotlin/Pair;)Ljava/lang/Object; + public static final fun toExpression (Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/operations/Algebra;)Lspace/kscience/kmath/expressions/Expression; +} + +public final class space/kscience/kmath/expressions/MstAlgebra : space/kscience/kmath/operations/NumericAlgebra { + public static final field INSTANCE Lspace/kscience/kmath/expressions/MstAlgebra; + public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; + public fun bindSymbol (Ljava/lang/String;)Lspace/kscience/kmath/expressions/MST$Symbolic; + public synthetic fun bindSymbolOrNull (Ljava/lang/String;)Ljava/lang/Object; + public fun bindSymbolOrNull (Ljava/lang/String;)Lspace/kscience/kmath/expressions/MST$Symbolic; + public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/expressions/MST$Numeric; + public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; +} + +public final class space/kscience/kmath/expressions/MstExtendedField : space/kscience/kmath/operations/ExtendedField, space/kscience/kmath/operations/NumericAlgebra { + public static final field INSTANCE Lspace/kscience/kmath/expressions/MstExtendedField; + public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; + public fun acos (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun acosh (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun add (Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Binary; + public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; + public fun asin (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun asinh (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; + public fun atan (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun atanh (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public synthetic fun bindSymbolOrNull (Ljava/lang/String;)Ljava/lang/Object; + public fun bindSymbolOrNull (Ljava/lang/String;)Lspace/kscience/kmath/expressions/MST$Symbolic; + public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; + public fun cos (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun cosh (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun divide (Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Binary; + public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; + public fun exp (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public synthetic fun getOne ()Ljava/lang/Object; + public fun getOne ()Lspace/kscience/kmath/expressions/MST$Numeric; + public synthetic fun getZero ()Ljava/lang/Object; + public fun getZero ()Lspace/kscience/kmath/expressions/MST$Numeric; + public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; + public fun ln (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun minus (Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Binary; + public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun multiply (Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Binary; + public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/expressions/MST$Numeric; + public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public fun power (Lspace/kscience/kmath/expressions/MST;Ljava/lang/Number;)Lspace/kscience/kmath/expressions/MST$Binary; + public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; + public fun scale (Lspace/kscience/kmath/expressions/MST;D)Lspace/kscience/kmath/expressions/MST; + public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; + public fun sin (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun sinh (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; + public fun tan (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun tanh (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryMinus (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; + public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryPlus (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; +} + +public final class space/kscience/kmath/expressions/MstField : space/kscience/kmath/operations/Field, space/kscience/kmath/operations/NumbersAddOperations, space/kscience/kmath/operations/ScaleOperations { + public static final field INSTANCE Lspace/kscience/kmath/expressions/MstField; + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun add (Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Binary; + public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public synthetic fun bindSymbolOrNull (Ljava/lang/String;)Ljava/lang/Object; + public fun bindSymbolOrNull (Ljava/lang/String;)Lspace/kscience/kmath/expressions/MST$Symbolic; + public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun divide (Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Binary; + public synthetic fun getOne ()Ljava/lang/Object; + public fun getOne ()Lspace/kscience/kmath/expressions/MST$Numeric; + public synthetic fun getZero ()Ljava/lang/Object; + public fun getZero ()Lspace/kscience/kmath/expressions/MST$Numeric; + public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun minus (Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Binary; + public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun multiply (Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Binary; + public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/expressions/MST$Numeric; + public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; + public fun scale (Lspace/kscience/kmath/expressions/MST;D)Lspace/kscience/kmath/expressions/MST$Binary; + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryMinus (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; + public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryPlus (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; +} + +public final class space/kscience/kmath/expressions/MstGroup : space/kscience/kmath/operations/Group, space/kscience/kmath/operations/NumericAlgebra, space/kscience/kmath/operations/ScaleOperations { + public static final field INSTANCE Lspace/kscience/kmath/expressions/MstGroup; + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun add (Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Binary; + public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public synthetic fun bindSymbolOrNull (Ljava/lang/String;)Ljava/lang/Object; + public fun bindSymbolOrNull (Ljava/lang/String;)Lspace/kscience/kmath/expressions/MST$Symbolic; + public synthetic fun getZero ()Ljava/lang/Object; + public fun getZero ()Lspace/kscience/kmath/expressions/MST$Numeric; + public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun minus (Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Binary; + public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/expressions/MST$Numeric; + public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; + public fun scale (Lspace/kscience/kmath/expressions/MST;D)Lspace/kscience/kmath/expressions/MST$Binary; + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryMinus (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; + public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryPlus (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; +} + +public final class space/kscience/kmath/expressions/MstRing : space/kscience/kmath/operations/NumbersAddOperations, space/kscience/kmath/operations/Ring, space/kscience/kmath/operations/ScaleOperations { + public static final field INSTANCE Lspace/kscience/kmath/expressions/MstRing; + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun add (Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Binary; + public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public synthetic fun bindSymbolOrNull (Ljava/lang/String;)Ljava/lang/Object; + public fun bindSymbolOrNull (Ljava/lang/String;)Lspace/kscience/kmath/expressions/MST$Symbolic; + public synthetic fun getOne ()Ljava/lang/Object; + public fun getOne ()Lspace/kscience/kmath/expressions/MST$Numeric; + public synthetic fun getZero ()Ljava/lang/Object; + public fun getZero ()Lspace/kscience/kmath/expressions/MST$Numeric; + public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun minus (Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Binary; + public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun multiply (Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Binary; + public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/expressions/MST$Numeric; + public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; + public fun scale (Lspace/kscience/kmath/expressions/MST;D)Lspace/kscience/kmath/expressions/MST$Binary; + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryMinus (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; + public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryPlus (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; +} + public final class space/kscience/kmath/expressions/SimpleAutoDiffExpression : space/kscience/kmath/expressions/FirstDerivativeExpression { public fun (Lspace/kscience/kmath/operations/Field;Lkotlin/jvm/functions/Function1;)V - public fun derivativeOrNull (Lspace/kscience/kmath/expressions/Symbol;)Lspace/kscience/kmath/expressions/Expression; + public fun derivativeOrNull (Lspace/kscience/kmath/misc/Symbol;)Lspace/kscience/kmath/expressions/Expression; public final fun getField ()Lspace/kscience/kmath/operations/Field; public final fun getFunction ()Lkotlin/jvm/functions/Function1; public fun invoke (Ljava/util/Map;)Ljava/lang/Object; @@ -223,6 +381,8 @@ public final class space/kscience/kmath/expressions/SimpleAutoDiffExtendedField public fun atan (Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; public fun atanh (Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; + public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; + public fun bindSymbol (Ljava/lang/String;)Lspace/kscience/kmath/expressions/AutoDiffValue; public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; public fun cos (Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; @@ -233,12 +393,9 @@ public final class space/kscience/kmath/expressions/SimpleAutoDiffExtendedField public fun ln (Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public synthetic fun pow (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun pow (Lspace/kscience/kmath/expressions/AutoDiffValue;Ljava/lang/Number;)Lspace/kscience/kmath/expressions/AutoDiffValue; public final fun pow (Lspace/kscience/kmath/expressions/AutoDiffValue;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; public fun power (Lspace/kscience/kmath/expressions/AutoDiffValue;Ljava/lang/Number;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; public fun scale (Lspace/kscience/kmath/expressions/AutoDiffValue;D)Lspace/kscience/kmath/expressions/AutoDiffValue; public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; @@ -252,28 +409,18 @@ public final class space/kscience/kmath/expressions/SimpleAutoDiffExtendedField public fun tan (Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; public fun tanh (Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; } public class space/kscience/kmath/expressions/SimpleAutoDiffField : space/kscience/kmath/expressions/ExpressionAlgebra, space/kscience/kmath/operations/Field, space/kscience/kmath/operations/NumbersAddOperations { public fun (Lspace/kscience/kmath/operations/Field;Ljava/util/Map;)V public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun add (Lspace/kscience/kmath/expressions/AutoDiffValue;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public synthetic fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperation (Ljava/lang/String;Lspace/kscience/kmath/expressions/AutoDiffValue;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; - public fun bindSymbol (Ljava/lang/String;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public synthetic fun bindSymbolOrNull (Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; - public fun bindSymbolOrNull (Lspace/kscience/kmath/expressions/Symbol;)Lspace/kscience/kmath/expressions/AutoDiffValue; + public synthetic fun bindSymbolOrNull (Ljava/lang/String;)Ljava/lang/Object; + public fun bindSymbolOrNull (Ljava/lang/String;)Lspace/kscience/kmath/expressions/AutoDiffValue; public synthetic fun const (Ljava/lang/Object;)Ljava/lang/Object; public fun const (Ljava/lang/Object;)Lspace/kscience/kmath/expressions/AutoDiffValue; public final fun const (Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/AutoDiffValue; public final fun derive (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun div (Lspace/kscience/kmath/expressions/AutoDiffValue;Ljava/lang/Number;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public fun div (Lspace/kscience/kmath/expressions/AutoDiffValue;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun divide (Lspace/kscience/kmath/expressions/AutoDiffValue;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; public final fun getContext ()Lspace/kscience/kmath/operations/Field; @@ -282,44 +429,15 @@ public class space/kscience/kmath/expressions/SimpleAutoDiffField : space/kscien public fun getOne ()Lspace/kscience/kmath/expressions/AutoDiffValue; public synthetic fun getZero ()Ljava/lang/Object; public fun getZero ()Lspace/kscience/kmath/expressions/AutoDiffValue; - public synthetic fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun minus (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun minus (Ljava/lang/Number;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun minus (Lspace/kscience/kmath/expressions/AutoDiffValue;Ljava/lang/Number;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public fun minus (Lspace/kscience/kmath/expressions/AutoDiffValue;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun multiply (Lspace/kscience/kmath/expressions/AutoDiffValue;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public synthetic fun plus (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun plus (Ljava/lang/Number;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun plus (Lspace/kscience/kmath/expressions/AutoDiffValue;Ljava/lang/Number;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public fun plus (Lspace/kscience/kmath/expressions/AutoDiffValue;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public synthetic fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun rightSideNumberOperation (Ljava/lang/String;Lspace/kscience/kmath/expressions/AutoDiffValue;Ljava/lang/Number;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; public fun scale (Lspace/kscience/kmath/expressions/AutoDiffValue;D)Lspace/kscience/kmath/expressions/AutoDiffValue; public final fun setD (Lspace/kscience/kmath/expressions/AutoDiffValue;Ljava/lang/Object;)V - public synthetic fun times (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun times (Ljava/lang/Number;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun times (Lspace/kscience/kmath/expressions/AutoDiffValue;Ljava/lang/Number;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public fun times (Lspace/kscience/kmath/expressions/AutoDiffValue;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; public fun unaryMinus (Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public synthetic fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperation (Ljava/lang/String;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryPlus (Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; } public final class space/kscience/kmath/expressions/SimpleAutoDiffKt { @@ -332,7 +450,7 @@ public final class space/kscience/kmath/expressions/SimpleAutoDiffKt { public static final fun cos (Lspace/kscience/kmath/expressions/SimpleAutoDiffField;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; public static final fun cosh (Lspace/kscience/kmath/expressions/SimpleAutoDiffField;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; public static final fun exp (Lspace/kscience/kmath/expressions/SimpleAutoDiffField;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public static final fun grad (Lspace/kscience/kmath/expressions/DerivationResult;[Lspace/kscience/kmath/expressions/Symbol;)Lspace/kscience/kmath/structures/Buffer; + public static final fun grad (Lspace/kscience/kmath/expressions/DerivationResult;[Lspace/kscience/kmath/misc/Symbol;)Lspace/kscience/kmath/structures/Buffer; public static final fun ln (Lspace/kscience/kmath/expressions/SimpleAutoDiffField;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; public static final fun pow (Lspace/kscience/kmath/expressions/SimpleAutoDiffField;Lspace/kscience/kmath/expressions/AutoDiffValue;D)Lspace/kscience/kmath/expressions/AutoDiffValue; public static final fun pow (Lspace/kscience/kmath/expressions/SimpleAutoDiffField;Lspace/kscience/kmath/expressions/AutoDiffValue;I)Lspace/kscience/kmath/expressions/AutoDiffValue; @@ -348,88 +466,7 @@ public final class space/kscience/kmath/expressions/SimpleAutoDiffKt { public static final fun tanh (Lspace/kscience/kmath/expressions/SimpleAutoDiffField;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; } -public final class space/kscience/kmath/expressions/SimpleSymbolIndexer : space/kscience/kmath/expressions/SymbolIndexer { - public static final synthetic fun box-impl (Ljava/util/List;)Lspace/kscience/kmath/expressions/SimpleSymbolIndexer; - public static fun constructor-impl (Ljava/util/List;)Ljava/util/List; - public fun equals (Ljava/lang/Object;)Z - public static fun equals-impl (Ljava/util/List;Ljava/lang/Object;)Z - public static final fun equals-impl0 (Ljava/util/List;Ljava/util/List;)Z - public fun get (Ljava/util/List;Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; - public fun get (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/expressions/Symbol;Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; - public fun get (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; - public fun get ([DLspace/kscience/kmath/expressions/Symbol;)D - public fun get ([Ljava/lang/Object;Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; - public static fun get-impl (Ljava/util/List;Ljava/util/List;Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; - public static fun get-impl (Ljava/util/List;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/expressions/Symbol;Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; - public static fun get-impl (Ljava/util/List;Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; - public static fun get-impl (Ljava/util/List;[DLspace/kscience/kmath/expressions/Symbol;)D - public static fun get-impl (Ljava/util/List;[Ljava/lang/Object;Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; - public fun getSymbols ()Ljava/util/List; - public fun hashCode ()I - public static fun hashCode-impl (Ljava/util/List;)I - public fun indexOf (Lspace/kscience/kmath/expressions/Symbol;)I - public static fun indexOf-impl (Ljava/util/List;Lspace/kscience/kmath/expressions/Symbol;)I - public fun toDoubleArray (Ljava/util/Map;)[D - public static fun toDoubleArray-impl (Ljava/util/List;Ljava/util/Map;)[D - public fun toList (Ljava/util/Map;)Ljava/util/List; - public static fun toList-impl (Ljava/util/List;Ljava/util/Map;)Ljava/util/List; - public fun toMap ([D)Ljava/util/Map; - public static fun toMap-impl (Ljava/util/List;[D)Ljava/util/Map; - public fun toPoint (Ljava/util/Map;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/structures/Buffer; - public static fun toPoint-impl (Ljava/util/List;Ljava/util/Map;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/structures/Buffer; - public fun toString ()Ljava/lang/String; - public static fun toString-impl (Ljava/util/List;)Ljava/lang/String; - public final synthetic fun unbox-impl ()Ljava/util/List; -} - -public final class space/kscience/kmath/expressions/StringSymbol : space/kscience/kmath/expressions/Symbol { - public static final synthetic fun box-impl (Ljava/lang/String;)Lspace/kscience/kmath/expressions/StringSymbol; - public static fun constructor-impl (Ljava/lang/String;)Ljava/lang/String; - public fun equals (Ljava/lang/Object;)Z - public static fun equals-impl (Ljava/lang/String;Ljava/lang/Object;)Z - public static final fun equals-impl0 (Ljava/lang/String;Ljava/lang/String;)Z - public fun getIdentity ()Ljava/lang/String; - public fun hashCode ()I - public static fun hashCode-impl (Ljava/lang/String;)I - public fun toString ()Ljava/lang/String; - public static fun toString-impl (Ljava/lang/String;)Ljava/lang/String; - public final synthetic fun unbox-impl ()Ljava/lang/String; -} - -public abstract interface class space/kscience/kmath/expressions/Symbol { - public abstract fun getIdentity ()Ljava/lang/String; -} - -public abstract interface class space/kscience/kmath/expressions/SymbolIndexer { - public abstract fun get (Ljava/util/List;Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; - public abstract fun get (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/expressions/Symbol;Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; - public abstract fun get (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; - public abstract fun get ([DLspace/kscience/kmath/expressions/Symbol;)D - public abstract fun get ([Ljava/lang/Object;Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; - public abstract fun getSymbols ()Ljava/util/List; - public abstract fun indexOf (Lspace/kscience/kmath/expressions/Symbol;)I - public abstract fun toDoubleArray (Ljava/util/Map;)[D - public abstract fun toList (Ljava/util/Map;)Ljava/util/List; - public abstract fun toMap ([D)Ljava/util/Map; - public abstract fun toPoint (Ljava/util/Map;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/structures/Buffer; -} - -public final class space/kscience/kmath/expressions/SymbolIndexer$DefaultImpls { - public static fun get (Lspace/kscience/kmath/expressions/SymbolIndexer;Ljava/util/List;Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; - public static fun get (Lspace/kscience/kmath/expressions/SymbolIndexer;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/expressions/Symbol;Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; - public static fun get (Lspace/kscience/kmath/expressions/SymbolIndexer;Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; - public static fun get (Lspace/kscience/kmath/expressions/SymbolIndexer;[DLspace/kscience/kmath/expressions/Symbol;)D - public static fun get (Lspace/kscience/kmath/expressions/SymbolIndexer;[Ljava/lang/Object;Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; - public static fun indexOf (Lspace/kscience/kmath/expressions/SymbolIndexer;Lspace/kscience/kmath/expressions/Symbol;)I - public static fun toDoubleArray (Lspace/kscience/kmath/expressions/SymbolIndexer;Ljava/util/Map;)[D - public static fun toList (Lspace/kscience/kmath/expressions/SymbolIndexer;Ljava/util/Map;)Ljava/util/List; - public static fun toMap (Lspace/kscience/kmath/expressions/SymbolIndexer;[D)Ljava/util/Map; - public static fun toPoint (Lspace/kscience/kmath/expressions/SymbolIndexer;Ljava/util/Map;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/structures/Buffer; -} - public final class space/kscience/kmath/expressions/SymbolIndexerKt { - public static final fun withSymbols (Ljava/util/Collection;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; - public static final fun withSymbols ([Lspace/kscience/kmath/expressions/Symbol;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; } public final class space/kscience/kmath/linear/BufferedLinearSpace : space/kscience/kmath/linear/LinearSpace { @@ -440,15 +477,9 @@ public final class space/kscience/kmath/linear/BufferedLinearSpace : space/kscie public fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; public fun getElementAlgebra ()Lspace/kscience/kmath/operations/Ring; public fun minus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; - public fun minus (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; public fun plus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; - public fun plus (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public fun times (Ljava/lang/Object;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; - public fun times (Ljava/lang/Object;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; public fun times (Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D; - public fun times (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Object;)Lspace/kscience/kmath/structures/Buffer; public fun unaryMinus (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; - public fun unaryMinus (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; } public abstract interface class space/kscience/kmath/linear/CholeskyDecompositionFeature : space/kscience/kmath/linear/MatrixFeature { @@ -477,11 +508,7 @@ public final class space/kscience/kmath/linear/LFeature : space/kscience/kmath/l public abstract interface class space/kscience/kmath/linear/LinearSolver { public abstract fun inverse (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; public abstract fun solve (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; - public abstract fun solve (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; -} - -public final class space/kscience/kmath/linear/LinearSolver$DefaultImpls { - public static fun solve (Lspace/kscience/kmath/linear/LinearSolver;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; + public fun solve (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; } public final class space/kscience/kmath/linear/LinearSolverKt { @@ -493,19 +520,19 @@ public abstract interface class space/kscience/kmath/linear/LinearSpace { public static final field Companion Lspace/kscience/kmath/linear/LinearSpace$Companion; public abstract fun buildMatrix (IILkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/Structure2D; public abstract fun buildVector (ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/structures/Buffer; - public abstract fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; - public abstract fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; + public fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; + public fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; public abstract fun getElementAlgebra ()Lspace/kscience/kmath/operations/Ring; - public abstract fun minus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; - public abstract fun minus (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public abstract fun plus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; - public abstract fun plus (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public abstract fun times (Ljava/lang/Object;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; - public abstract fun times (Ljava/lang/Object;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public abstract fun times (Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D; - public abstract fun times (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Object;)Lspace/kscience/kmath/structures/Buffer; - public abstract fun unaryMinus (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; - public abstract fun unaryMinus (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; + public fun minus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; + public fun minus (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; + public fun plus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; + public fun plus (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; + public fun times (Ljava/lang/Object;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; + public fun times (Ljava/lang/Object;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; + public fun times (Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D; + public fun times (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Object;)Lspace/kscience/kmath/structures/Buffer; + public fun unaryMinus (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; + public fun unaryMinus (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; } public final class space/kscience/kmath/linear/LinearSpace$Companion { @@ -514,21 +541,6 @@ public final class space/kscience/kmath/linear/LinearSpace$Companion { public final fun getReal ()Lspace/kscience/kmath/linear/LinearSpace; } -public final class space/kscience/kmath/linear/LinearSpace$DefaultImpls { - public static fun dot (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; - public static fun dot (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public static fun minus (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; - public static fun minus (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public static fun plus (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; - public static fun plus (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public static fun times (Lspace/kscience/kmath/linear/LinearSpace;Ljava/lang/Object;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; - public static fun times (Lspace/kscience/kmath/linear/LinearSpace;Ljava/lang/Object;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public static fun times (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D; - public static fun times (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Object;)Lspace/kscience/kmath/structures/Buffer; - public static fun unaryMinus (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; - public static fun unaryMinus (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; -} - public final class space/kscience/kmath/linear/LinearSpaceKt { public static final fun invoke (Lspace/kscience/kmath/linear/LinearSpace;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; } @@ -575,7 +587,7 @@ public final class space/kscience/kmath/linear/MatrixBuilderKt { public static final fun row (Lspace/kscience/kmath/linear/LinearSpace;[Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D; } -public abstract interface class space/kscience/kmath/linear/MatrixFeature { +public abstract interface class space/kscience/kmath/linear/MatrixFeature : space/kscience/kmath/nd/StructureFeature { } public final class space/kscience/kmath/linear/MatrixFeaturesKt { @@ -584,7 +596,6 @@ public final class space/kscience/kmath/linear/MatrixFeaturesKt { public final class space/kscience/kmath/linear/MatrixWrapper : space/kscience/kmath/nd/Structure2D { public fun elements ()Lkotlin/sequences/Sequence; - public fun equals (Ljava/lang/Object;)Z public fun get (II)Ljava/lang/Object; public fun get ([I)Ljava/lang/Object; public fun getColNum ()I @@ -595,7 +606,6 @@ public final class space/kscience/kmath/linear/MatrixWrapper : space/kscience/km public fun getRowNum ()I public fun getRows ()Ljava/util/List; public fun getShape ()[I - public fun hashCode ()I public fun toString ()Ljava/lang/String; } @@ -639,18 +649,11 @@ public final class space/kscience/kmath/linear/UnitFeature : space/kscience/kmat public final class space/kscience/kmath/linear/VirtualMatrix : space/kscience/kmath/nd/Structure2D { public fun (IILkotlin/jvm/functions/Function2;)V - public fun elements ()Lkotlin/sequences/Sequence; - public fun equals (Ljava/lang/Object;)Z public fun get (II)Ljava/lang/Object; - public fun get ([I)Ljava/lang/Object; public fun getColNum ()I - public fun getColumns ()Ljava/util/List; - public fun getDimension ()I public final fun getGenerator ()Lkotlin/jvm/functions/Function2; public fun getRowNum ()I - public fun getRows ()Ljava/util/List; public fun getShape ()[I - public fun hashCode ()I } public final class space/kscience/kmath/linear/ZeroFeature : space/kscience/kmath/linear/DiagonalFeature { @@ -662,9 +665,9 @@ public final class space/kscience/kmath/misc/CumulativeKt { public static final fun cumulative (Ljava/util/Iterator;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/util/Iterator; public static final fun cumulative (Ljava/util/List;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/util/List; public static final fun cumulative (Lkotlin/sequences/Sequence;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Lkotlin/sequences/Sequence; - public static final fun cumulativeSum (Ljava/lang/Iterable;Lspace/kscience/kmath/operations/Group;)Ljava/lang/Iterable; - public static final fun cumulativeSum (Ljava/util/List;Lspace/kscience/kmath/operations/Group;)Ljava/util/List; - public static final fun cumulativeSum (Lkotlin/sequences/Sequence;Lspace/kscience/kmath/operations/Group;)Lkotlin/sequences/Sequence; + public static final fun cumulativeSum (Ljava/lang/Iterable;Lspace/kscience/kmath/operations/Ring;)Ljava/lang/Iterable; + public static final fun cumulativeSum (Ljava/util/List;Lspace/kscience/kmath/operations/Ring;)Ljava/util/List; + public static final fun cumulativeSum (Lkotlin/sequences/Sequence;Lspace/kscience/kmath/operations/Ring;)Lkotlin/sequences/Sequence; public static final fun cumulativeSumOfDouble (Ljava/lang/Iterable;)Ljava/lang/Iterable; public static final fun cumulativeSumOfDouble (Ljava/util/List;)Ljava/util/List; public static final fun cumulativeSumOfDouble (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence; @@ -676,118 +679,108 @@ public final class space/kscience/kmath/misc/CumulativeKt { public static final fun cumulativeSumOfLong (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence; } +public final class space/kscience/kmath/misc/StringSymbol : space/kscience/kmath/misc/Symbol { + public static final synthetic fun box-impl (Ljava/lang/String;)Lspace/kscience/kmath/misc/StringSymbol; + public static fun constructor-impl (Ljava/lang/String;)Ljava/lang/String; + public fun equals (Ljava/lang/Object;)Z + public static fun equals-impl (Ljava/lang/String;Ljava/lang/Object;)Z + public static final fun equals-impl0 (Ljava/lang/String;Ljava/lang/String;)Z + public fun getIdentity ()Ljava/lang/String; + public fun hashCode ()I + public static fun hashCode-impl (Ljava/lang/String;)I + public fun toString ()Ljava/lang/String; + public static fun toString-impl (Ljava/lang/String;)Ljava/lang/String; + public final synthetic fun unbox-impl ()Ljava/lang/String; +} + +public abstract interface class space/kscience/kmath/misc/Symbol { + public static final field Companion Lspace/kscience/kmath/misc/Symbol$Companion; + public abstract fun getIdentity ()Ljava/lang/String; +} + +public final class space/kscience/kmath/misc/Symbol$Companion { + public final fun getX-tWtZOCg ()Ljava/lang/String; + public final fun getY-tWtZOCg ()Ljava/lang/String; + public final fun getZ-tWtZOCg ()Ljava/lang/String; +} + +public final class space/kscience/kmath/misc/SymbolKt { + public static final fun getSymbol ()Lkotlin/properties/ReadOnlyProperty; +} + public abstract interface annotation class space/kscience/kmath/misc/UnstableKMathAPI : java/lang/annotation/Annotation { } -public abstract interface class space/kscience/kmath/nd/BufferNDAlgebra : space/kscience/kmath/nd/NDAlgebra { - public abstract fun combine (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/NDBuffer; - public abstract fun getBuffer (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/structures/Buffer; +public abstract interface class space/kscience/kmath/nd/AlgebraND { + public static final field Companion Lspace/kscience/kmath/nd/AlgebraND$Companion; + public abstract fun combine (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/StructureND; + public abstract fun getElementContext ()Lspace/kscience/kmath/operations/Algebra; + public abstract fun getShape ()[I + public fun invoke (Lkotlin/jvm/functions/Function1;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public abstract fun map (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; + public abstract fun mapIndexed (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/StructureND; + public abstract fun produce (Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; +} + +public final class space/kscience/kmath/nd/AlgebraND$Companion { +} + +public abstract interface class space/kscience/kmath/nd/BufferAlgebraND : space/kscience/kmath/nd/AlgebraND { + public fun combine (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun combine (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/StructureND; + public fun getBuffer (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/structures/Buffer; public abstract fun getBufferFactory ()Lkotlin/jvm/functions/Function2; public abstract fun getStrides ()Lspace/kscience/kmath/nd/Strides; - public abstract fun map (Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/NDBuffer; - public abstract fun mapIndexed (Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/NDBuffer; - public abstract fun produce (Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/NDBuffer; + public fun map (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun map (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; + public fun mapIndexed (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun mapIndexed (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/StructureND; + public fun produce (Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun produce (Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; } -public final class space/kscience/kmath/nd/BufferNDAlgebra$DefaultImpls { - public static fun combine (Lspace/kscience/kmath/nd/BufferNDAlgebra;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/NDBuffer; - public static fun getBuffer (Lspace/kscience/kmath/nd/BufferNDAlgebra;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/structures/Buffer; - public static fun invoke (Lspace/kscience/kmath/nd/BufferNDAlgebra;Lkotlin/jvm/functions/Function1;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun map (Lspace/kscience/kmath/nd/BufferNDAlgebra;Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/NDBuffer; - public static fun mapIndexed (Lspace/kscience/kmath/nd/BufferNDAlgebra;Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/NDBuffer; - public static fun produce (Lspace/kscience/kmath/nd/BufferNDAlgebra;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/NDBuffer; -} - -public final class space/kscience/kmath/nd/BufferNDAlgebraKt { - public static final fun field (Lspace/kscience/kmath/nd/NDAlgebra$Companion;Lspace/kscience/kmath/operations/Field;Lkotlin/jvm/functions/Function2;[I)Lspace/kscience/kmath/nd/BufferedNDField; - public static final fun group (Lspace/kscience/kmath/nd/NDAlgebra$Companion;Lspace/kscience/kmath/operations/Group;Lkotlin/jvm/functions/Function2;[I)Lspace/kscience/kmath/nd/BufferedNDGroup; +public final class space/kscience/kmath/nd/BufferAlgebraNDKt { + public static final fun field (Lspace/kscience/kmath/nd/AlgebraND$Companion;Lspace/kscience/kmath/operations/Field;Lkotlin/jvm/functions/Function2;[I)Lspace/kscience/kmath/nd/BufferedFieldND; + public static final fun group (Lspace/kscience/kmath/nd/AlgebraND$Companion;Lspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function2;[I)Lspace/kscience/kmath/nd/BufferedGroupND; public static final fun ndField (Lspace/kscience/kmath/operations/Field;Lkotlin/jvm/functions/Function2;[ILkotlin/jvm/functions/Function1;)Ljava/lang/Object; - public static final fun ndGroup (Lspace/kscience/kmath/operations/Group;Lkotlin/jvm/functions/Function2;[ILkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public static final fun ndGroup (Lspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function2;[ILkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static final fun ndRing (Lspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function2;[ILkotlin/jvm/functions/Function1;)Ljava/lang/Object; - public static final fun ring (Lspace/kscience/kmath/nd/NDAlgebra$Companion;Lspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function2;[I)Lspace/kscience/kmath/nd/BufferedNDRing; + public static final fun ring (Lspace/kscience/kmath/nd/AlgebraND$Companion;Lspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function2;[I)Lspace/kscience/kmath/nd/BufferedRingND; } -public class space/kscience/kmath/nd/BufferedNDField : space/kscience/kmath/nd/BufferedNDRing, space/kscience/kmath/nd/NDField { +public final class space/kscience/kmath/nd/BufferND : space/kscience/kmath/nd/StructureND { + public fun (Lspace/kscience/kmath/nd/Strides;Lspace/kscience/kmath/structures/Buffer;)V + public fun elements ()Lkotlin/sequences/Sequence; + public fun get ([I)Ljava/lang/Object; + public final fun getBuffer ()Lspace/kscience/kmath/structures/Buffer; + public fun getShape ()[I + public final fun getStrides ()Lspace/kscience/kmath/nd/Strides; + public fun toString ()Ljava/lang/String; +} + +public class space/kscience/kmath/nd/BufferedFieldND : space/kscience/kmath/nd/BufferedRingND, space/kscience/kmath/nd/FieldND { public fun ([ILspace/kscience/kmath/operations/Field;Lkotlin/jvm/functions/Function2;)V - public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun div (Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun div (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; - public fun div (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; - public fun div (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun divide (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; - public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun rightSideNumberOperation (Ljava/lang/String;Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; - public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; - public fun scale (Lspace/kscience/kmath/nd/NDStructure;D)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun times (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun times (Ljava/lang/Number;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun times (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; + public fun scale (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd/StructureND; } -public class space/kscience/kmath/nd/BufferedNDGroup : space/kscience/kmath/nd/BufferNDAlgebra, space/kscience/kmath/nd/NDGroup { +public class space/kscience/kmath/nd/BufferedGroupND : space/kscience/kmath/nd/BufferAlgebraND, space/kscience/kmath/nd/GroupND { public fun ([ILspace/kscience/kmath/operations/Group;Lkotlin/jvm/functions/Function2;)V - public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun add (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperation (Ljava/lang/String;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; - public fun bindSymbol (Ljava/lang/String;)Lspace/kscience/kmath/nd/NDStructure; - public fun combine (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun combine (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/NDStructure; - public fun getBuffer (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/structures/Buffer; public final fun getBufferFactory ()Lkotlin/jvm/functions/Function2; public synthetic fun getElementContext ()Lspace/kscience/kmath/operations/Algebra; public final fun getElementContext ()Lspace/kscience/kmath/operations/Group; public final fun getShape ()[I public fun getStrides ()Lspace/kscience/kmath/nd/Strides; public synthetic fun getZero ()Ljava/lang/Object; - public fun getZero ()Lspace/kscience/kmath/nd/NDBuffer; - public fun invoke (Lkotlin/jvm/functions/Function1;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun map (Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun map (Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/NDStructure; - public fun mapIndexed (Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun mapIndexed (Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun minus (Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun minus (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; - public fun minus (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun plus (Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun plus (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; - public fun plus (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun produce (Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun produce (Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/NDStructure; + public fun getZero ()Lspace/kscience/kmath/nd/BufferND; public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryMinus (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperation (Ljava/lang/String;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryPlus (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; + public fun unaryMinus (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; } -public class space/kscience/kmath/nd/BufferedNDRing : space/kscience/kmath/nd/BufferedNDGroup, space/kscience/kmath/nd/NDRing { +public class space/kscience/kmath/nd/BufferedRingND : space/kscience/kmath/nd/BufferedGroupND, space/kscience/kmath/nd/RingND { public fun ([ILspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function2;)V - public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public synthetic fun getOne ()Ljava/lang/Object; - public fun getOne ()Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun multiply (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun times (Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun times (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; - public fun times (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; + public fun getOne ()Lspace/kscience/kmath/nd/BufferND; } public final class space/kscience/kmath/nd/DefaultStrides : space/kscience/kmath/nd/Strides { @@ -799,7 +792,6 @@ public final class space/kscience/kmath/nd/DefaultStrides : space/kscience/kmath public fun getStrides ()Ljava/util/List; public fun hashCode ()I public fun index (I)[I - public fun indices ()Lkotlin/sequences/Sequence; public fun offset ([I)I } @@ -807,250 +799,96 @@ public final class space/kscience/kmath/nd/DefaultStrides$Companion { public final fun invoke ([I)Lspace/kscience/kmath/nd/Strides; } -public final class space/kscience/kmath/nd/MutableNDBuffer : space/kscience/kmath/nd/NDBuffer, space/kscience/kmath/nd/MutableNDStructure { - public fun (Lspace/kscience/kmath/nd/Strides;Lspace/kscience/kmath/structures/MutableBuffer;)V - public synthetic fun getBuffer ()Lspace/kscience/kmath/structures/Buffer; - public fun getBuffer ()Lspace/kscience/kmath/structures/MutableBuffer; - public fun set ([ILjava/lang/Object;)V +public final class space/kscience/kmath/nd/DoubleFieldND : space/kscience/kmath/nd/BufferedFieldND, space/kscience/kmath/operations/ExtendedField, space/kscience/kmath/operations/NumbersAddOperations, space/kscience/kmath/operations/ScaleOperations { + public fun ([I)V + public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; + public fun acos (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun acosh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; + public fun asin (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun asinh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; + public fun atan (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun atanh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/BufferND; + public fun combine (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun combine (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; + public fun cos (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun cosh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; + public fun exp (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun getBuffer (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/structures/Buffer; + public fun getBuffer-Udx-57Q (Lspace/kscience/kmath/nd/StructureND;)[D + public synthetic fun getOne ()Ljava/lang/Object; + public fun getOne ()Lspace/kscience/kmath/nd/BufferND; + public synthetic fun getZero ()Ljava/lang/Object; + public fun getZero ()Lspace/kscience/kmath/nd/BufferND; + public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; + public fun ln (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/BufferND; + public fun map (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun map (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; + public fun mapIndexed (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun mapIndexed (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public fun power (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/nd/BufferND; + public fun produce (Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun produce (Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; + public fun scale (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; + public fun sin (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun sinh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; + public fun tan (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun tanh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/BufferND; } -public abstract interface class space/kscience/kmath/nd/MutableNDStructure : space/kscience/kmath/nd/NDStructure { +public final class space/kscience/kmath/nd/DoubleFieldNDKt { + public static final fun nd (Lspace/kscience/kmath/operations/DoubleField;[ILkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public static final fun real (Lspace/kscience/kmath/nd/AlgebraND$Companion;[I)Lspace/kscience/kmath/nd/DoubleFieldND; +} + +public abstract interface class space/kscience/kmath/nd/FieldND : space/kscience/kmath/nd/RingND, space/kscience/kmath/operations/Field, space/kscience/kmath/operations/ScaleOperations { + public fun div (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun div (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun divide (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; +} + +public abstract interface class space/kscience/kmath/nd/GroupND : space/kscience/kmath/nd/AlgebraND, space/kscience/kmath/operations/Group { + public static final field Companion Lspace/kscience/kmath/nd/GroupND$Companion; + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun add (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun minus (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun minus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public fun plus (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun plus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; +} + +public final class space/kscience/kmath/nd/GroupND$Companion { +} + +public abstract interface class space/kscience/kmath/nd/MutableStructureND : space/kscience/kmath/nd/StructureND { public abstract fun set ([ILjava/lang/Object;)V } -public final class space/kscience/kmath/nd/MutableNDStructure$DefaultImpls { - public static fun getDimension (Lspace/kscience/kmath/nd/MutableNDStructure;)I +public abstract interface class space/kscience/kmath/nd/RingND : space/kscience/kmath/nd/GroupND, space/kscience/kmath/operations/Ring { + public static final field Companion Lspace/kscience/kmath/nd/RingND$Companion; + public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun multiply (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun times (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun times (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; } -public abstract interface class space/kscience/kmath/nd/NDAlgebra { - public static final field Companion Lspace/kscience/kmath/nd/NDAlgebra$Companion; - public abstract fun combine (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/NDStructure; - public abstract fun getElementContext ()Lspace/kscience/kmath/operations/Algebra; - public abstract fun getShape ()[I - public abstract fun invoke (Lkotlin/jvm/functions/Function1;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public abstract fun map (Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/NDStructure; - public abstract fun mapIndexed (Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/NDStructure; - public abstract fun produce (Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/NDStructure; -} - -public final class space/kscience/kmath/nd/NDAlgebra$Companion { -} - -public final class space/kscience/kmath/nd/NDAlgebra$DefaultImpls { - public static fun invoke (Lspace/kscience/kmath/nd/NDAlgebra;Lkotlin/jvm/functions/Function1;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; -} - -public class space/kscience/kmath/nd/NDBuffer : space/kscience/kmath/nd/NDStructure { - public fun (Lspace/kscience/kmath/nd/Strides;Lspace/kscience/kmath/structures/Buffer;)V - public fun elements ()Lkotlin/sequences/Sequence; - public fun equals (Ljava/lang/Object;)Z - public fun get ([I)Ljava/lang/Object; - public fun getBuffer ()Lspace/kscience/kmath/structures/Buffer; - public fun getDimension ()I - public fun getShape ()[I - public final fun getStrides ()Lspace/kscience/kmath/nd/Strides; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public abstract interface class space/kscience/kmath/nd/NDField : space/kscience/kmath/nd/NDRing, space/kscience/kmath/operations/Field, space/kscience/kmath/operations/ScaleOperations { - public abstract fun div (Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public abstract fun div (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; - public abstract fun divide (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; -} - -public final class space/kscience/kmath/nd/NDField$DefaultImpls { - public static fun add (Lspace/kscience/kmath/nd/NDField;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun binaryOperation (Lspace/kscience/kmath/nd/NDField;Ljava/lang/String;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun binaryOperationFunction (Lspace/kscience/kmath/nd/NDField;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun bindSymbol (Lspace/kscience/kmath/nd/NDField;Ljava/lang/String;)Lspace/kscience/kmath/nd/NDStructure; - public static fun div (Lspace/kscience/kmath/nd/NDField;Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun div (Lspace/kscience/kmath/nd/NDField;Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; - public static fun div (Lspace/kscience/kmath/nd/NDField;Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; - public static fun div (Lspace/kscience/kmath/nd/NDField;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun divide (Lspace/kscience/kmath/nd/NDField;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun invoke (Lspace/kscience/kmath/nd/NDField;Lkotlin/jvm/functions/Function1;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun leftSideNumberOperation (Lspace/kscience/kmath/nd/NDField;Ljava/lang/String;Ljava/lang/Number;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun leftSideNumberOperationFunction (Lspace/kscience/kmath/nd/NDField;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun minus (Lspace/kscience/kmath/nd/NDField;Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun minus (Lspace/kscience/kmath/nd/NDField;Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; - public static fun minus (Lspace/kscience/kmath/nd/NDField;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun multiply (Lspace/kscience/kmath/nd/NDField;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun number (Lspace/kscience/kmath/nd/NDField;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; - public static fun plus (Lspace/kscience/kmath/nd/NDField;Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun plus (Lspace/kscience/kmath/nd/NDField;Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; - public static fun plus (Lspace/kscience/kmath/nd/NDField;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun rightSideNumberOperation (Lspace/kscience/kmath/nd/NDField;Ljava/lang/String;Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; - public static fun rightSideNumberOperationFunction (Lspace/kscience/kmath/nd/NDField;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun times (Lspace/kscience/kmath/nd/NDField;Ljava/lang/Number;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun times (Lspace/kscience/kmath/nd/NDField;Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun times (Lspace/kscience/kmath/nd/NDField;Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; - public static fun times (Lspace/kscience/kmath/nd/NDField;Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; - public static fun times (Lspace/kscience/kmath/nd/NDField;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun unaryOperation (Lspace/kscience/kmath/nd/NDField;Ljava/lang/String;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun unaryOperationFunction (Lspace/kscience/kmath/nd/NDField;Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public static fun unaryPlus (Lspace/kscience/kmath/nd/NDField;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; -} - -public abstract interface class space/kscience/kmath/nd/NDGroup : space/kscience/kmath/nd/NDAlgebra, space/kscience/kmath/operations/Group { - public static final field Companion Lspace/kscience/kmath/nd/NDGroup$Companion; - public abstract fun add (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public abstract fun minus (Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public abstract fun minus (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; - public abstract fun plus (Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public abstract fun plus (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; -} - -public final class space/kscience/kmath/nd/NDGroup$Companion { -} - -public final class space/kscience/kmath/nd/NDGroup$DefaultImpls { - public static fun add (Lspace/kscience/kmath/nd/NDGroup;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun binaryOperation (Lspace/kscience/kmath/nd/NDGroup;Ljava/lang/String;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun binaryOperationFunction (Lspace/kscience/kmath/nd/NDGroup;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun bindSymbol (Lspace/kscience/kmath/nd/NDGroup;Ljava/lang/String;)Lspace/kscience/kmath/nd/NDStructure; - public static fun invoke (Lspace/kscience/kmath/nd/NDGroup;Lkotlin/jvm/functions/Function1;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun minus (Lspace/kscience/kmath/nd/NDGroup;Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun minus (Lspace/kscience/kmath/nd/NDGroup;Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; - public static fun minus (Lspace/kscience/kmath/nd/NDGroup;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun plus (Lspace/kscience/kmath/nd/NDGroup;Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun plus (Lspace/kscience/kmath/nd/NDGroup;Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; - public static fun plus (Lspace/kscience/kmath/nd/NDGroup;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun unaryOperation (Lspace/kscience/kmath/nd/NDGroup;Ljava/lang/String;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun unaryOperationFunction (Lspace/kscience/kmath/nd/NDGroup;Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public static fun unaryPlus (Lspace/kscience/kmath/nd/NDGroup;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; -} - -public abstract interface class space/kscience/kmath/nd/NDRing : space/kscience/kmath/nd/NDGroup, space/kscience/kmath/operations/Ring { - public static final field Companion Lspace/kscience/kmath/nd/NDRing$Companion; - public abstract fun multiply (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public abstract fun times (Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public abstract fun times (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; -} - -public final class space/kscience/kmath/nd/NDRing$Companion { -} - -public final class space/kscience/kmath/nd/NDRing$DefaultImpls { - public static fun add (Lspace/kscience/kmath/nd/NDRing;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun binaryOperation (Lspace/kscience/kmath/nd/NDRing;Ljava/lang/String;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun binaryOperationFunction (Lspace/kscience/kmath/nd/NDRing;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun bindSymbol (Lspace/kscience/kmath/nd/NDRing;Ljava/lang/String;)Lspace/kscience/kmath/nd/NDStructure; - public static fun invoke (Lspace/kscience/kmath/nd/NDRing;Lkotlin/jvm/functions/Function1;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun minus (Lspace/kscience/kmath/nd/NDRing;Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun minus (Lspace/kscience/kmath/nd/NDRing;Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; - public static fun minus (Lspace/kscience/kmath/nd/NDRing;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun multiply (Lspace/kscience/kmath/nd/NDRing;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun plus (Lspace/kscience/kmath/nd/NDRing;Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun plus (Lspace/kscience/kmath/nd/NDRing;Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; - public static fun plus (Lspace/kscience/kmath/nd/NDRing;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun times (Lspace/kscience/kmath/nd/NDRing;Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun times (Lspace/kscience/kmath/nd/NDRing;Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; - public static fun times (Lspace/kscience/kmath/nd/NDRing;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun unaryOperation (Lspace/kscience/kmath/nd/NDRing;Ljava/lang/String;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public static fun unaryOperationFunction (Lspace/kscience/kmath/nd/NDRing;Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public static fun unaryPlus (Lspace/kscience/kmath/nd/NDRing;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; -} - -public abstract interface class space/kscience/kmath/nd/NDStructure { - public static final field Companion Lspace/kscience/kmath/nd/NDStructure$Companion; - public abstract fun elements ()Lkotlin/sequences/Sequence; - public abstract fun equals (Ljava/lang/Object;)Z - public abstract fun get ([I)Ljava/lang/Object; - public abstract fun getDimension ()I - public abstract fun getShape ()[I - public abstract fun hashCode ()I -} - -public final class space/kscience/kmath/nd/NDStructure$Companion { - public final fun auto (Lkotlin/reflect/KClass;Lspace/kscience/kmath/nd/Strides;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/NDBuffer; - public final fun auto (Lkotlin/reflect/KClass;[ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/NDBuffer; - public final fun buffered (Lspace/kscience/kmath/nd/Strides;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/NDBuffer; - public final fun buffered ([ILkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/NDBuffer; - public static synthetic fun buffered$default (Lspace/kscience/kmath/nd/NDStructure$Companion;Lspace/kscience/kmath/nd/Strides;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/kmath/nd/NDBuffer; - public static synthetic fun buffered$default (Lspace/kscience/kmath/nd/NDStructure$Companion;[ILkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/kmath/nd/NDBuffer; - public final fun contentEquals (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Z -} - -public final class space/kscience/kmath/nd/NDStructure$DefaultImpls { - public static fun getDimension (Lspace/kscience/kmath/nd/NDStructure;)I -} - -public final class space/kscience/kmath/nd/NDStructureKt { - public static final fun get (Lspace/kscience/kmath/nd/NDStructure;[I)Ljava/lang/Object; - public static final fun mapInPlace (Lspace/kscience/kmath/nd/MutableNDStructure;Lkotlin/jvm/functions/Function2;)V -} - -public final class space/kscience/kmath/nd/RealNDField : space/kscience/kmath/nd/BufferedNDField, space/kscience/kmath/operations/ExtendedField, space/kscience/kmath/operations/NumbersAddOperations, space/kscience/kmath/operations/ScaleOperations { - public fun ([I)V - public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; - public fun acos (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun acosh (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; - public fun asin (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun asinh (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; - public fun atan (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun atanh (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDBuffer; - public fun combine (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun combine (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; - public fun cos (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun cosh (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; - public fun exp (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun getBuffer (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/structures/Buffer; - public fun getBuffer-LGjt3BI (Lspace/kscience/kmath/nd/NDStructure;)[D - public synthetic fun getOne ()Ljava/lang/Object; - public fun getOne ()Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun getZero ()Ljava/lang/Object; - public fun getZero ()Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; - public fun ln (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDBuffer; - public fun map (Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun map (Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/NDStructure; - public fun mapIndexed (Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun mapIndexed (Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun minus (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun minus (Ljava/lang/Number;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun minus (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; - public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun number (Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun plus (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun plus (Ljava/lang/Number;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun plus (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun pow (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun pow (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun power (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDBuffer; - public fun produce (Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun produce (Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/NDStructure; - public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; - public fun scale (Lspace/kscience/kmath/nd/NDStructure;D)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; - public fun sin (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun sinh (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun sqrt (Ljava/lang/Object;)Ljava/lang/Object; - public fun sqrt (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; - public fun tan (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun tanh (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDBuffer; - public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; -} - -public final class space/kscience/kmath/nd/RealNDFieldKt { - public static final fun nd (Lspace/kscience/kmath/operations/RealField;[ILkotlin/jvm/functions/Function1;)Ljava/lang/Object; - public static final fun real (Lspace/kscience/kmath/nd/NDAlgebra$Companion;[I)Lspace/kscience/kmath/nd/RealNDField; +public final class space/kscience/kmath/nd/RingND$Companion { } public final class space/kscience/kmath/nd/ShapeMismatchException : java/lang/RuntimeException { @@ -1059,33 +897,19 @@ public final class space/kscience/kmath/nd/ShapeMismatchException : java/lang/Ru public final fun getExpected ()[I } -public final class space/kscience/kmath/nd/ShortNDRing : space/kscience/kmath/nd/BufferedNDRing, space/kscience/kmath/operations/NumbersAddOperations { +public final class space/kscience/kmath/nd/ShortRingND : space/kscience/kmath/nd/BufferedRingND, space/kscience/kmath/operations/NumbersAddOperations { public fun ([I)V public synthetic fun getOne ()Ljava/lang/Object; - public fun getOne ()Lspace/kscience/kmath/nd/NDBuffer; + public fun getOne ()Lspace/kscience/kmath/nd/BufferND; public synthetic fun getZero ()Ljava/lang/Object; - public fun getZero ()Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun minus (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun minus (Ljava/lang/Number;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun minus (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; + public fun getZero ()Lspace/kscience/kmath/nd/BufferND; public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; - public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDBuffer; - public synthetic fun plus (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun plus (Ljava/lang/Number;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun plus (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun rightSideNumberOperation (Ljava/lang/String;Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; - public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/nd/BufferND; } -public final class space/kscience/kmath/nd/ShortNDRingKt { +public final class space/kscience/kmath/nd/ShortRingNDKt { public static final fun nd (Lspace/kscience/kmath/operations/ShortRing;[ILkotlin/jvm/functions/Function1;)Ljava/lang/Object; - public static final fun produceInline (Lspace/kscience/kmath/nd/BufferedNDRing;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/NDBuffer; + public static final fun produceInline (Lspace/kscience/kmath/nd/BufferedRingND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/BufferND; } public abstract interface class space/kscience/kmath/nd/Strides { @@ -1093,74 +917,78 @@ public abstract interface class space/kscience/kmath/nd/Strides { public abstract fun getShape ()[I public abstract fun getStrides ()Ljava/util/List; public abstract fun index (I)[I - public abstract fun indices ()Lkotlin/sequences/Sequence; + public fun indices ()Lkotlin/sequences/Sequence; public abstract fun offset ([I)I } -public final class space/kscience/kmath/nd/Strides$DefaultImpls { - public static fun indices (Lspace/kscience/kmath/nd/Strides;)Lkotlin/sequences/Sequence; +public abstract interface class space/kscience/kmath/nd/Structure1D : space/kscience/kmath/nd/StructureND, space/kscience/kmath/structures/Buffer { + public static final field Companion Lspace/kscience/kmath/nd/Structure1D$Companion; + public fun get ([I)Ljava/lang/Object; + public fun getDimension ()I + public fun iterator ()Ljava/util/Iterator; } -public abstract interface class space/kscience/kmath/nd/Structure1D : space/kscience/kmath/nd/NDStructure, space/kscience/kmath/structures/Buffer { - public abstract fun get ([I)Ljava/lang/Object; - public abstract fun getDimension ()I - public abstract fun iterator ()Ljava/util/Iterator; -} - -public final class space/kscience/kmath/nd/Structure1D$DefaultImpls { - public static fun contentEquals (Lspace/kscience/kmath/nd/Structure1D;Lspace/kscience/kmath/structures/Buffer;)Z - public static fun get (Lspace/kscience/kmath/nd/Structure1D;[I)Ljava/lang/Object; - public static fun getDimension (Lspace/kscience/kmath/nd/Structure1D;)I - public static fun iterator (Lspace/kscience/kmath/nd/Structure1D;)Ljava/util/Iterator; +public final class space/kscience/kmath/nd/Structure1D$Companion { } public final class space/kscience/kmath/nd/Structure1DKt { - public static final fun as1D (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/Structure1D; + public static final fun as1D (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Structure1D; public static final fun asND (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/nd/Structure1D; } -public abstract interface class space/kscience/kmath/nd/Structure2D : space/kscience/kmath/nd/NDStructure { +public abstract interface class space/kscience/kmath/nd/Structure2D : space/kscience/kmath/nd/StructureND { public static final field Companion Lspace/kscience/kmath/nd/Structure2D$Companion; - public abstract fun elements ()Lkotlin/sequences/Sequence; + public fun elements ()Lkotlin/sequences/Sequence; public abstract fun get (II)Ljava/lang/Object; - public abstract fun get ([I)Ljava/lang/Object; + public fun get ([I)Ljava/lang/Object; public abstract fun getColNum ()I - public abstract fun getColumns ()Ljava/util/List; + public fun getColumns ()Ljava/util/List; public abstract fun getRowNum ()I - public abstract fun getRows ()Ljava/util/List; - public abstract fun getShape ()[I + public fun getRows ()Ljava/util/List; + public fun getShape ()[I } public final class space/kscience/kmath/nd/Structure2D$Companion { } -public final class space/kscience/kmath/nd/Structure2D$DefaultImpls { - public static fun elements (Lspace/kscience/kmath/nd/Structure2D;)Lkotlin/sequences/Sequence; - public static fun get (Lspace/kscience/kmath/nd/Structure2D;[I)Ljava/lang/Object; - public static fun getColumns (Lspace/kscience/kmath/nd/Structure2D;)Ljava/util/List; - public static fun getDimension (Lspace/kscience/kmath/nd/Structure2D;)I - public static fun getRows (Lspace/kscience/kmath/nd/Structure2D;)Ljava/util/List; - public static fun getShape (Lspace/kscience/kmath/nd/Structure2D;)[I +public final class space/kscience/kmath/nd/Structure2DKt { + public static final fun as2D (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Structure2D; } -public final class space/kscience/kmath/nd/Structure2DKt { - public static final fun as2D (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/Structure2D; +public abstract interface class space/kscience/kmath/nd/StructureFeature { +} + +public abstract interface class space/kscience/kmath/nd/StructureND { + public static final field Companion Lspace/kscience/kmath/nd/StructureND$Companion; + public abstract fun elements ()Lkotlin/sequences/Sequence; + public abstract fun get ([I)Ljava/lang/Object; + public fun getDimension ()I + public abstract fun getShape ()[I +} + +public final class space/kscience/kmath/nd/StructureND$Companion { + public final fun auto (Lkotlin/reflect/KClass;Lspace/kscience/kmath/nd/Strides;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/BufferND; + public final fun auto (Lkotlin/reflect/KClass;[ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/BufferND; + public final fun buffered (Lspace/kscience/kmath/nd/Strides;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/BufferND; + public final fun buffered ([ILkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/BufferND; + public static synthetic fun buffered$default (Lspace/kscience/kmath/nd/StructureND$Companion;Lspace/kscience/kmath/nd/Strides;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/kmath/nd/BufferND; + public static synthetic fun buffered$default (Lspace/kscience/kmath/nd/StructureND$Companion;[ILkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/kmath/nd/BufferND; + public final fun contentEquals (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Z + public final fun toString (Lspace/kscience/kmath/nd/StructureND;)Ljava/lang/String; +} + +public final class space/kscience/kmath/nd/StructureNDKt { + public static final fun get (Lspace/kscience/kmath/nd/StructureND;[I)Ljava/lang/Object; + public static final fun mapInPlace (Lspace/kscience/kmath/nd/MutableStructureND;Lkotlin/jvm/functions/Function2;)V } public abstract interface class space/kscience/kmath/operations/Algebra { - public abstract fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public abstract fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; - public abstract fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; -} - -public final class space/kscience/kmath/operations/Algebra$DefaultImpls { - public static fun binaryOperation (Lspace/kscience/kmath/operations/Algebra;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun binaryOperationFunction (Lspace/kscience/kmath/operations/Algebra;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun bindSymbol (Lspace/kscience/kmath/operations/Algebra;Ljava/lang/String;)Ljava/lang/Object; - public static fun unaryOperation (Lspace/kscience/kmath/operations/Algebra;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperationFunction (Lspace/kscience/kmath/operations/Algebra;Ljava/lang/String;)Lkotlin/jvm/functions/Function1; + public fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; + public fun bindSymbolOrNull (Ljava/lang/String;)Ljava/lang/Object; + public fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; } public abstract interface class space/kscience/kmath/operations/AlgebraElement { @@ -1174,21 +1002,22 @@ public final class space/kscience/kmath/operations/AlgebraElementsKt { } public final class space/kscience/kmath/operations/AlgebraExtensionsKt { - public static final fun abs (Lspace/kscience/kmath/operations/Group;Ljava/lang/Comparable;)Ljava/lang/Comparable; - public static final fun average (Lspace/kscience/kmath/operations/Group;Ljava/lang/Iterable;)Ljava/lang/Object; - public static final fun average (Lspace/kscience/kmath/operations/Group;Lkotlin/sequences/Sequence;)Ljava/lang/Object; - public static final fun averageWith (Ljava/lang/Iterable;Lspace/kscience/kmath/operations/Group;)Ljava/lang/Object; - public static final fun averageWith (Lkotlin/sequences/Sequence;Lspace/kscience/kmath/operations/Group;)Ljava/lang/Object; + public static final fun abs (Lspace/kscience/kmath/operations/Ring;Ljava/lang/Comparable;)Ljava/lang/Comparable; + public static final fun average (Lspace/kscience/kmath/operations/Ring;Ljava/lang/Iterable;)Ljava/lang/Object; + public static final fun average (Lspace/kscience/kmath/operations/Ring;Lkotlin/sequences/Sequence;)Ljava/lang/Object; + public static final fun averageWith (Ljava/lang/Iterable;Lspace/kscience/kmath/operations/Ring;)Ljava/lang/Object; + public static final fun averageWith (Lkotlin/sequences/Sequence;Lspace/kscience/kmath/operations/Ring;)Ljava/lang/Object; public static final fun power (Lspace/kscience/kmath/operations/Field;Ljava/lang/Object;I)Ljava/lang/Object; public static final fun power (Lspace/kscience/kmath/operations/Ring;Ljava/lang/Object;I)Ljava/lang/Object; - public static final fun sum (Lspace/kscience/kmath/operations/Group;Ljava/lang/Iterable;)Ljava/lang/Object; - public static final fun sum (Lspace/kscience/kmath/operations/Group;Lkotlin/sequences/Sequence;)Ljava/lang/Object; - public static final fun sumWith (Ljava/lang/Iterable;Lspace/kscience/kmath/operations/Group;)Ljava/lang/Object; - public static final fun sumWith (Lkotlin/sequences/Sequence;Lspace/kscience/kmath/operations/Group;)Ljava/lang/Object; + public static final fun sum (Lspace/kscience/kmath/operations/Ring;Ljava/lang/Iterable;)Ljava/lang/Object; + public static final fun sum (Lspace/kscience/kmath/operations/Ring;Lkotlin/sequences/Sequence;)Ljava/lang/Object; + public static final fun sumWith (Ljava/lang/Iterable;Lspace/kscience/kmath/operations/Ring;)Ljava/lang/Object; + public static final fun sumWith (Lkotlin/sequences/Sequence;Lspace/kscience/kmath/operations/Ring;)Ljava/lang/Object; } public final class space/kscience/kmath/operations/AlgebraKt { - public static final fun bindSymbol (Lspace/kscience/kmath/operations/Algebra;Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; + public static final fun bindSymbol (Lspace/kscience/kmath/operations/Algebra;Lspace/kscience/kmath/misc/Symbol;)Ljava/lang/Object; + public static final fun bindSymbolOrNull (Lspace/kscience/kmath/operations/Algebra;Lspace/kscience/kmath/misc/Symbol;)Ljava/lang/Object; public static final fun invoke (Lspace/kscience/kmath/operations/Algebra;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; } @@ -1229,65 +1058,27 @@ public final class space/kscience/kmath/operations/BigIntField : space/kscience/ public static final field INSTANCE Lspace/kscience/kmath/operations/BigIntField; public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun add (Lspace/kscience/kmath/operations/BigInt;Lspace/kscience/kmath/operations/BigInt;)Lspace/kscience/kmath/operations/BigInt; - public synthetic fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperation (Ljava/lang/String;Lspace/kscience/kmath/operations/BigInt;Lspace/kscience/kmath/operations/BigInt;)Lspace/kscience/kmath/operations/BigInt; - public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; - public fun bindSymbol (Ljava/lang/String;)Lspace/kscience/kmath/operations/BigInt; - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun div (Lspace/kscience/kmath/operations/BigInt;Ljava/lang/Number;)Lspace/kscience/kmath/operations/BigInt; - public fun div (Lspace/kscience/kmath/operations/BigInt;Lspace/kscience/kmath/operations/BigInt;)Lspace/kscience/kmath/operations/BigInt; public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun divide (Lspace/kscience/kmath/operations/BigInt;Lspace/kscience/kmath/operations/BigInt;)Lspace/kscience/kmath/operations/BigInt; public synthetic fun getOne ()Ljava/lang/Object; public fun getOne ()Lspace/kscience/kmath/operations/BigInt; public synthetic fun getZero ()Ljava/lang/Object; public fun getZero ()Lspace/kscience/kmath/operations/BigInt; - public synthetic fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Lspace/kscience/kmath/operations/BigInt;)Lspace/kscience/kmath/operations/BigInt; - public fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun minus (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun minus (Ljava/lang/Number;Lspace/kscience/kmath/operations/BigInt;)Lspace/kscience/kmath/operations/BigInt; - public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun minus (Lspace/kscience/kmath/operations/BigInt;Ljava/lang/Number;)Lspace/kscience/kmath/operations/BigInt; - public fun minus (Lspace/kscience/kmath/operations/BigInt;Lspace/kscience/kmath/operations/BigInt;)Lspace/kscience/kmath/operations/BigInt; public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun multiply (Lspace/kscience/kmath/operations/BigInt;Lspace/kscience/kmath/operations/BigInt;)Lspace/kscience/kmath/operations/BigInt; public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/operations/BigInt; - public synthetic fun plus (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun plus (Ljava/lang/Number;Lspace/kscience/kmath/operations/BigInt;)Lspace/kscience/kmath/operations/BigInt; - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun plus (Lspace/kscience/kmath/operations/BigInt;Ljava/lang/Number;)Lspace/kscience/kmath/operations/BigInt; - public fun plus (Lspace/kscience/kmath/operations/BigInt;Lspace/kscience/kmath/operations/BigInt;)Lspace/kscience/kmath/operations/BigInt; - public synthetic fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun rightSideNumberOperation (Ljava/lang/String;Lspace/kscience/kmath/operations/BigInt;Ljava/lang/Number;)Lspace/kscience/kmath/operations/BigInt; - public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; public fun scale (Lspace/kscience/kmath/operations/BigInt;D)Lspace/kscience/kmath/operations/BigInt; - public synthetic fun times (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun times (Ljava/lang/Number;Lspace/kscience/kmath/operations/BigInt;)Lspace/kscience/kmath/operations/BigInt; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun times (Lspace/kscience/kmath/operations/BigInt;Ljava/lang/Number;)Lspace/kscience/kmath/operations/BigInt; - public fun times (Lspace/kscience/kmath/operations/BigInt;Lspace/kscience/kmath/operations/BigInt;)Lspace/kscience/kmath/operations/BigInt; public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; public final fun unaryMinus (Ljava/lang/String;)Lspace/kscience/kmath/operations/BigInt; public fun unaryMinus (Lspace/kscience/kmath/operations/BigInt;)Lspace/kscience/kmath/operations/BigInt; - public synthetic fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperation (Ljava/lang/String;Lspace/kscience/kmath/operations/BigInt;)Lspace/kscience/kmath/operations/BigInt; - public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; public final fun unaryPlus (Ljava/lang/String;)Lspace/kscience/kmath/operations/BigInt; - public fun unaryPlus (Lspace/kscience/kmath/operations/BigInt;)Lspace/kscience/kmath/operations/BigInt; } public final class space/kscience/kmath/operations/BigIntKt { public static final fun abs (Lspace/kscience/kmath/operations/BigInt;)Lspace/kscience/kmath/operations/BigInt; - public static final fun bigInt (Lspace/kscience/kmath/nd/NDAlgebra$Companion;[I)Lspace/kscience/kmath/nd/BufferedNDRing; + public static final fun bigInt (Lspace/kscience/kmath/nd/AlgebraND$Companion;[I)Lspace/kscience/kmath/nd/BufferedRingND; public static final fun bigInt (Lspace/kscience/kmath/structures/Buffer$Companion;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/Buffer; public static final fun bigInt (Lspace/kscience/kmath/structures/MutableBuffer$Companion;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/MutableBuffer; public static final fun parseBigInteger (Ljava/lang/String;)Lspace/kscience/kmath/operations/BigInt; @@ -1302,18 +1093,10 @@ public final class space/kscience/kmath/operations/ByteRing : space/kscience/kma public static final field INSTANCE Lspace/kscience/kmath/operations/ByteRing; public fun add (BB)Ljava/lang/Byte; public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperation (Ljava/lang/String;BB)Ljava/lang/Byte; - public synthetic fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public fun bindSymbol (Ljava/lang/String;)Ljava/lang/Byte; - public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; public fun getOne ()Ljava/lang/Byte; public synthetic fun getOne ()Ljava/lang/Object; public fun getZero ()Ljava/lang/Byte; public synthetic fun getZero ()Ljava/lang/Object; - public fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;B)Ljava/lang/Byte; - public synthetic fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public fun minus (BB)Ljava/lang/Byte; public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun multiply (BB)Ljava/lang/Byte; @@ -1324,18 +1107,71 @@ public final class space/kscience/kmath/operations/ByteRing : space/kscience/kma public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; public fun plus (BB)Ljava/lang/Byte; public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun rightSideNumberOperation (Ljava/lang/String;BLjava/lang/Number;)Ljava/lang/Byte; - public synthetic fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public fun times (BB)Ljava/lang/Byte; public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun unaryMinus (B)Ljava/lang/Byte; public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperation (Ljava/lang/String;B)Ljava/lang/Byte; - public synthetic fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public fun unaryPlus (B)Ljava/lang/Byte; - public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; +} + +public final class space/kscience/kmath/operations/DoubleField : space/kscience/kmath/operations/ExtendedField, space/kscience/kmath/operations/Norm, space/kscience/kmath/operations/ScaleOperations { + public static final field INSTANCE Lspace/kscience/kmath/operations/DoubleField; + public fun acos (D)Ljava/lang/Double; + public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; + public fun acosh (D)Ljava/lang/Double; + public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun add (DD)Ljava/lang/Double; + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun asin (D)Ljava/lang/Double; + public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; + public fun asinh (D)Ljava/lang/Double; + public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun atan (D)Ljava/lang/Double; + public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; + public fun atanh (D)Ljava/lang/Double; + public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public fun cos (D)Ljava/lang/Double; + public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; + public fun cosh (D)Ljava/lang/Double; + public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun div (DD)Ljava/lang/Double; + public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun divide (DD)Ljava/lang/Double; + public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun exp (D)Ljava/lang/Double; + public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; + public fun getOne ()Ljava/lang/Double; + public synthetic fun getOne ()Ljava/lang/Object; + public fun getZero ()Ljava/lang/Double; + public synthetic fun getZero ()Ljava/lang/Object; + public fun ln (D)Ljava/lang/Double; + public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; + public fun minus (DD)Ljava/lang/Double; + public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun multiply (DD)Ljava/lang/Double; + public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun norm (D)Ljava/lang/Double; + public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Ljava/lang/Double; + public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; + public fun plus (DD)Ljava/lang/Double; + public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun power (DLjava/lang/Number;)Ljava/lang/Double; + public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public fun scale (DD)Ljava/lang/Double; + public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; + public fun sin (D)Ljava/lang/Double; + public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; + public fun sinh (D)Ljava/lang/Double; + public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun tan (D)Ljava/lang/Double; + public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; + public fun tanh (D)Ljava/lang/Double; + public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun times (DD)Ljava/lang/Double; + public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryMinus (D)Ljava/lang/Double; + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; } public abstract interface class space/kscience/kmath/operations/ExponentialOperations : space/kscience/kmath/operations/Algebra { @@ -1369,107 +1205,32 @@ public final class space/kscience/kmath/operations/ExponentialOperations$Compani public static final field TANH_OPERATION Ljava/lang/String; } -public final class space/kscience/kmath/operations/ExponentialOperations$DefaultImpls { - public static fun binaryOperation (Lspace/kscience/kmath/operations/ExponentialOperations;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun binaryOperationFunction (Lspace/kscience/kmath/operations/ExponentialOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun bindSymbol (Lspace/kscience/kmath/operations/ExponentialOperations;Ljava/lang/String;)Ljava/lang/Object; - public static fun unaryOperation (Lspace/kscience/kmath/operations/ExponentialOperations;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperationFunction (Lspace/kscience/kmath/operations/ExponentialOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function1; -} - public abstract interface class space/kscience/kmath/operations/ExtendedField : space/kscience/kmath/operations/ExtendedFieldOperations, space/kscience/kmath/operations/Field, space/kscience/kmath/operations/NumericAlgebra, space/kscience/kmath/operations/ScaleOperations { - public abstract fun acosh (Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun asinh (Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun atanh (Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun cosh (Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public abstract fun sinh (Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun tanh (Ljava/lang/Object;)Ljava/lang/Object; -} - -public final class space/kscience/kmath/operations/ExtendedField$DefaultImpls { - public static fun acosh (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/Object;)Ljava/lang/Object; - public static fun asinh (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/Object;)Ljava/lang/Object; - public static fun atanh (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/Object;)Ljava/lang/Object; - public static fun binaryOperation (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun binaryOperationFunction (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun bindSymbol (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/String;)Ljava/lang/Object; - public static fun cosh (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/Object;)Ljava/lang/Object; - public static fun div (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public static fun div (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun leftSideNumberOperation (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public static fun leftSideNumberOperationFunction (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun minus (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun number (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/Number;)Ljava/lang/Object; - public static fun plus (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun pow (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public static fun rightSideNumberOperation (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public static fun rightSideNumberOperationFunction (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun sinh (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/Object;)Ljava/lang/Object; - public static fun sqrt (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/Object;)Ljava/lang/Object; - public static fun tan (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/Object;)Ljava/lang/Object; - public static fun tanh (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/Object;)Ljava/lang/Object; - public static fun times (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public static fun times (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public static fun times (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperation (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperationFunction (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public static fun unaryPlus (Lspace/kscience/kmath/operations/ExtendedField;Ljava/lang/Object;)Ljava/lang/Object; + public fun acosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun asinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun atanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; + public fun cosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public fun sinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun tanh (Ljava/lang/Object;)Ljava/lang/Object; } public abstract interface class space/kscience/kmath/operations/ExtendedFieldOperations : space/kscience/kmath/operations/ExponentialOperations, space/kscience/kmath/operations/FieldOperations, space/kscience/kmath/operations/PowerOperations, space/kscience/kmath/operations/TrigonometricOperations { - public abstract fun tan (Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun tanh (Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; -} - -public final class space/kscience/kmath/operations/ExtendedFieldOperations$DefaultImpls { - public static fun binaryOperation (Lspace/kscience/kmath/operations/ExtendedFieldOperations;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun binaryOperationFunction (Lspace/kscience/kmath/operations/ExtendedFieldOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun bindSymbol (Lspace/kscience/kmath/operations/ExtendedFieldOperations;Ljava/lang/String;)Ljava/lang/Object; - public static fun div (Lspace/kscience/kmath/operations/ExtendedFieldOperations;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun minus (Lspace/kscience/kmath/operations/ExtendedFieldOperations;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun plus (Lspace/kscience/kmath/operations/ExtendedFieldOperations;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun pow (Lspace/kscience/kmath/operations/ExtendedFieldOperations;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public static fun sqrt (Lspace/kscience/kmath/operations/ExtendedFieldOperations;Ljava/lang/Object;)Ljava/lang/Object; - public static fun tan (Lspace/kscience/kmath/operations/ExtendedFieldOperations;Ljava/lang/Object;)Ljava/lang/Object; - public static fun tanh (Lspace/kscience/kmath/operations/ExtendedFieldOperations;Ljava/lang/Object;)Ljava/lang/Object; - public static fun times (Lspace/kscience/kmath/operations/ExtendedFieldOperations;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperation (Lspace/kscience/kmath/operations/ExtendedFieldOperations;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperationFunction (Lspace/kscience/kmath/operations/ExtendedFieldOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public static fun unaryPlus (Lspace/kscience/kmath/operations/ExtendedFieldOperations;Ljava/lang/Object;)Ljava/lang/Object; + public fun tan (Ljava/lang/Object;)Ljava/lang/Object; + public fun tanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; } public abstract interface class space/kscience/kmath/operations/Field : space/kscience/kmath/operations/FieldOperations, space/kscience/kmath/operations/NumericAlgebra, space/kscience/kmath/operations/Ring, space/kscience/kmath/operations/ScaleOperations { - public abstract fun number (Ljava/lang/Number;)Ljava/lang/Object; -} - -public final class space/kscience/kmath/operations/Field$DefaultImpls { - public static fun binaryOperation (Lspace/kscience/kmath/operations/Field;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun binaryOperationFunction (Lspace/kscience/kmath/operations/Field;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun bindSymbol (Lspace/kscience/kmath/operations/Field;Ljava/lang/String;)Ljava/lang/Object; - public static fun div (Lspace/kscience/kmath/operations/Field;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public static fun div (Lspace/kscience/kmath/operations/Field;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun leftSideNumberOperation (Lspace/kscience/kmath/operations/Field;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public static fun leftSideNumberOperationFunction (Lspace/kscience/kmath/operations/Field;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun minus (Lspace/kscience/kmath/operations/Field;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun number (Lspace/kscience/kmath/operations/Field;Ljava/lang/Number;)Ljava/lang/Object; - public static fun plus (Lspace/kscience/kmath/operations/Field;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun rightSideNumberOperation (Lspace/kscience/kmath/operations/Field;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public static fun rightSideNumberOperationFunction (Lspace/kscience/kmath/operations/Field;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun times (Lspace/kscience/kmath/operations/Field;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public static fun times (Lspace/kscience/kmath/operations/Field;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public static fun times (Lspace/kscience/kmath/operations/Field;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperation (Lspace/kscience/kmath/operations/Field;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperationFunction (Lspace/kscience/kmath/operations/Field;Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public static fun unaryPlus (Lspace/kscience/kmath/operations/Field;Ljava/lang/Object;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Ljava/lang/Object; } public abstract interface class space/kscience/kmath/operations/FieldOperations : space/kscience/kmath/operations/RingOperations { public static final field Companion Lspace/kscience/kmath/operations/FieldOperations$Companion; public static final field DIV_OPERATION Ljava/lang/String; - public abstract fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public abstract fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public abstract fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; } @@ -1477,19 +1238,6 @@ public final class space/kscience/kmath/operations/FieldOperations$Companion { public static final field DIV_OPERATION Ljava/lang/String; } -public final class space/kscience/kmath/operations/FieldOperations$DefaultImpls { - public static fun binaryOperation (Lspace/kscience/kmath/operations/FieldOperations;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun binaryOperationFunction (Lspace/kscience/kmath/operations/FieldOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun bindSymbol (Lspace/kscience/kmath/operations/FieldOperations;Ljava/lang/String;)Ljava/lang/Object; - public static fun div (Lspace/kscience/kmath/operations/FieldOperations;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun minus (Lspace/kscience/kmath/operations/FieldOperations;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun plus (Lspace/kscience/kmath/operations/FieldOperations;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun times (Lspace/kscience/kmath/operations/FieldOperations;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperation (Lspace/kscience/kmath/operations/FieldOperations;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperationFunction (Lspace/kscience/kmath/operations/FieldOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public static fun unaryPlus (Lspace/kscience/kmath/operations/FieldOperations;Ljava/lang/Object;)Ljava/lang/Object; -} - public final class space/kscience/kmath/operations/FloatField : space/kscience/kmath/operations/ExtendedField, space/kscience/kmath/operations/Norm { public static final field INSTANCE Lspace/kscience/kmath/operations/FloatField; public fun acos (F)Ljava/lang/Float; @@ -1506,18 +1254,12 @@ public final class space/kscience/kmath/operations/FloatField : space/kscience/k public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; public fun atanh (F)Ljava/lang/Float; public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperation (Ljava/lang/String;FF)Ljava/lang/Float; - public synthetic fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public fun bindSymbol (Ljava/lang/String;)Ljava/lang/Float; - public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; public fun cos (F)Ljava/lang/Float; public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; public fun cosh (F)Ljava/lang/Float; public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; public fun div (FF)Ljava/lang/Float; - public fun div (FLjava/lang/Number;)Ljava/lang/Float; - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun divide (FF)Ljava/lang/Float; public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; @@ -1527,9 +1269,6 @@ public final class space/kscience/kmath/operations/FloatField : space/kscience/k public synthetic fun getOne ()Ljava/lang/Object; public fun getZero ()Ljava/lang/Float; public synthetic fun getZero ()Ljava/lang/Object; - public fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;F)Ljava/lang/Float; - public synthetic fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public fun ln (F)Ljava/lang/Float; public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; public fun minus (FF)Ljava/lang/Float; @@ -1542,66 +1281,39 @@ public final class space/kscience/kmath/operations/FloatField : space/kscience/k public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; public fun plus (FF)Ljava/lang/Float; public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun pow (FLjava/lang/Number;)Ljava/lang/Float; - public synthetic fun pow (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; public fun power (FLjava/lang/Number;)Ljava/lang/Float; public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun rightSideNumberOperation (Ljava/lang/String;FLjava/lang/Number;)Ljava/lang/Float; - public synthetic fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public fun scale (FD)Ljava/lang/Float; public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; public fun sin (F)Ljava/lang/Float; public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; public fun sinh (F)Ljava/lang/Float; public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun sqrt (F)Ljava/lang/Float; - public synthetic fun sqrt (Ljava/lang/Object;)Ljava/lang/Object; public fun tan (F)Ljava/lang/Float; public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; public fun tanh (F)Ljava/lang/Float; public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; public fun times (FF)Ljava/lang/Float; - public fun times (FLjava/lang/Number;)Ljava/lang/Float; - public fun times (Ljava/lang/Number;F)Ljava/lang/Float; - public synthetic fun times (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun unaryMinus (F)Ljava/lang/Float; public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperation (Ljava/lang/String;F)Ljava/lang/Float; - public synthetic fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public fun unaryPlus (F)Ljava/lang/Float; - public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; } public abstract interface class space/kscience/kmath/operations/Group : space/kscience/kmath/operations/GroupOperations { public abstract fun getZero ()Ljava/lang/Object; } -public final class space/kscience/kmath/operations/Group$DefaultImpls { - public static fun binaryOperation (Lspace/kscience/kmath/operations/Group;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun binaryOperationFunction (Lspace/kscience/kmath/operations/Group;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun bindSymbol (Lspace/kscience/kmath/operations/Group;Ljava/lang/String;)Ljava/lang/Object; - public static fun minus (Lspace/kscience/kmath/operations/Group;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun plus (Lspace/kscience/kmath/operations/Group;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperation (Lspace/kscience/kmath/operations/Group;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperationFunction (Lspace/kscience/kmath/operations/Group;Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public static fun unaryPlus (Lspace/kscience/kmath/operations/Group;Ljava/lang/Object;)Ljava/lang/Object; -} - public abstract interface class space/kscience/kmath/operations/GroupOperations : space/kscience/kmath/operations/Algebra { public static final field Companion Lspace/kscience/kmath/operations/GroupOperations$Companion; public static final field MINUS_OPERATION Ljava/lang/String; public static final field PLUS_OPERATION Ljava/lang/String; public abstract fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public abstract fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public abstract fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public abstract fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; + public fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; } public final class space/kscience/kmath/operations/GroupOperations$Companion { @@ -1609,33 +1321,14 @@ public final class space/kscience/kmath/operations/GroupOperations$Companion { public static final field PLUS_OPERATION Ljava/lang/String; } -public final class space/kscience/kmath/operations/GroupOperations$DefaultImpls { - public static fun binaryOperation (Lspace/kscience/kmath/operations/GroupOperations;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun binaryOperationFunction (Lspace/kscience/kmath/operations/GroupOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun bindSymbol (Lspace/kscience/kmath/operations/GroupOperations;Ljava/lang/String;)Ljava/lang/Object; - public static fun minus (Lspace/kscience/kmath/operations/GroupOperations;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun plus (Lspace/kscience/kmath/operations/GroupOperations;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperation (Lspace/kscience/kmath/operations/GroupOperations;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperationFunction (Lspace/kscience/kmath/operations/GroupOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public static fun unaryPlus (Lspace/kscience/kmath/operations/GroupOperations;Ljava/lang/Object;)Ljava/lang/Object; -} - public final class space/kscience/kmath/operations/IntRing : space/kscience/kmath/operations/Norm, space/kscience/kmath/operations/NumericAlgebra, space/kscience/kmath/operations/Ring { public static final field INSTANCE Lspace/kscience/kmath/operations/IntRing; public fun add (II)Ljava/lang/Integer; public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperation (Ljava/lang/String;II)Ljava/lang/Integer; - public synthetic fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public fun bindSymbol (Ljava/lang/String;)Ljava/lang/Integer; - public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; public fun getOne ()Ljava/lang/Integer; public synthetic fun getOne ()Ljava/lang/Object; public fun getZero ()Ljava/lang/Integer; public synthetic fun getZero ()Ljava/lang/Object; - public fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;I)Ljava/lang/Integer; - public synthetic fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public fun minus (II)Ljava/lang/Integer; public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun multiply (II)Ljava/lang/Integer; @@ -1646,18 +1339,10 @@ public final class space/kscience/kmath/operations/IntRing : space/kscience/kmat public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; public fun plus (II)Ljava/lang/Integer; public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun rightSideNumberOperation (Ljava/lang/String;ILjava/lang/Number;)Ljava/lang/Integer; - public synthetic fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public fun times (II)Ljava/lang/Integer; public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun unaryMinus (I)Ljava/lang/Integer; public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperation (Ljava/lang/String;I)Ljava/lang/Integer; - public synthetic fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public fun unaryPlus (I)Ljava/lang/Integer; - public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; } public final class space/kscience/kmath/operations/JBigDecimalField : space/kscience/kmath/operations/JBigDecimalFieldBase { @@ -1674,94 +1359,44 @@ public abstract class space/kscience/kmath/operations/JBigDecimalFieldBase : spa public fun ()V public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun add (Ljava/math/BigDecimal;Ljava/math/BigDecimal;)Ljava/math/BigDecimal; - public synthetic fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperation (Ljava/lang/String;Ljava/math/BigDecimal;Ljava/math/BigDecimal;)Ljava/math/BigDecimal; - public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; - public fun bindSymbol (Ljava/lang/String;)Ljava/math/BigDecimal; - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun div (Ljava/math/BigDecimal;Ljava/lang/Number;)Ljava/math/BigDecimal; - public fun div (Ljava/math/BigDecimal;Ljava/math/BigDecimal;)Ljava/math/BigDecimal; public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun divide (Ljava/math/BigDecimal;Ljava/math/BigDecimal;)Ljava/math/BigDecimal; public synthetic fun getOne ()Ljava/lang/Object; public fun getOne ()Ljava/math/BigDecimal; public synthetic fun getZero ()Ljava/lang/Object; public fun getZero ()Ljava/math/BigDecimal; - public synthetic fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/math/BigDecimal;)Ljava/math/BigDecimal; - public fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun minus (Ljava/math/BigDecimal;Ljava/math/BigDecimal;)Ljava/math/BigDecimal; public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun multiply (Ljava/math/BigDecimal;Ljava/math/BigDecimal;)Ljava/math/BigDecimal; public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; public fun number (Ljava/lang/Number;)Ljava/math/BigDecimal; - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun plus (Ljava/math/BigDecimal;Ljava/math/BigDecimal;)Ljava/math/BigDecimal; - public synthetic fun pow (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun pow (Ljava/math/BigDecimal;Ljava/lang/Number;)Ljava/math/BigDecimal; public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; public fun power (Ljava/math/BigDecimal;Ljava/lang/Number;)Ljava/math/BigDecimal; - public synthetic fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun rightSideNumberOperation (Ljava/lang/String;Ljava/math/BigDecimal;Ljava/lang/Number;)Ljava/math/BigDecimal; - public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; public fun scale (Ljava/math/BigDecimal;D)Ljava/math/BigDecimal; public synthetic fun sqrt (Ljava/lang/Object;)Ljava/lang/Object; public fun sqrt (Ljava/math/BigDecimal;)Ljava/math/BigDecimal; - public synthetic fun times (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun times (Ljava/lang/Number;Ljava/math/BigDecimal;)Ljava/math/BigDecimal; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun times (Ljava/math/BigDecimal;Ljava/lang/Number;)Ljava/math/BigDecimal; - public fun times (Ljava/math/BigDecimal;Ljava/math/BigDecimal;)Ljava/math/BigDecimal; public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; public fun unaryMinus (Ljava/math/BigDecimal;)Ljava/math/BigDecimal; - public synthetic fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperation (Ljava/lang/String;Ljava/math/BigDecimal;)Ljava/math/BigDecimal; - public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryPlus (Ljava/math/BigDecimal;)Ljava/math/BigDecimal; } public final class space/kscience/kmath/operations/JBigIntegerField : space/kscience/kmath/operations/NumericAlgebra, space/kscience/kmath/operations/Ring { public static final field INSTANCE Lspace/kscience/kmath/operations/JBigIntegerField; public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun add (Ljava/math/BigInteger;Ljava/math/BigInteger;)Ljava/math/BigInteger; - public synthetic fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperation (Ljava/lang/String;Ljava/math/BigInteger;Ljava/math/BigInteger;)Ljava/math/BigInteger; - public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; - public fun bindSymbol (Ljava/lang/String;)Ljava/math/BigInteger; public synthetic fun getOne ()Ljava/lang/Object; public fun getOne ()Ljava/math/BigInteger; public synthetic fun getZero ()Ljava/lang/Object; public fun getZero ()Ljava/math/BigInteger; - public synthetic fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/math/BigInteger;)Ljava/math/BigInteger; - public fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun minus (Ljava/math/BigInteger;Ljava/math/BigInteger;)Ljava/math/BigInteger; public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun multiply (Ljava/math/BigInteger;Ljava/math/BigInteger;)Ljava/math/BigInteger; public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; public fun number (Ljava/lang/Number;)Ljava/math/BigInteger; - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun plus (Ljava/math/BigInteger;Ljava/math/BigInteger;)Ljava/math/BigInteger; - public synthetic fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun rightSideNumberOperation (Ljava/lang/String;Ljava/math/BigInteger;Ljava/lang/Number;)Ljava/math/BigInteger; - public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun times (Ljava/math/BigInteger;Ljava/math/BigInteger;)Ljava/math/BigInteger; public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; public fun unaryMinus (Ljava/math/BigInteger;)Ljava/math/BigInteger; - public synthetic fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperation (Ljava/lang/String;Ljava/math/BigInteger;)Ljava/math/BigInteger; - public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryPlus (Ljava/math/BigInteger;)Ljava/math/BigInteger; } public abstract interface annotation class space/kscience/kmath/operations/KMathContext : java/lang/annotation/Annotation { @@ -1771,18 +1406,10 @@ public final class space/kscience/kmath/operations/LongRing : space/kscience/kma public static final field INSTANCE Lspace/kscience/kmath/operations/LongRing; public fun add (JJ)Ljava/lang/Long; public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperation (Ljava/lang/String;JJ)Ljava/lang/Long; - public synthetic fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public fun bindSymbol (Ljava/lang/String;)Ljava/lang/Long; - public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; public fun getOne ()Ljava/lang/Long; public synthetic fun getOne ()Ljava/lang/Object; public fun getZero ()Ljava/lang/Long; public synthetic fun getZero ()Ljava/lang/Object; - public fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;J)Ljava/lang/Long; - public synthetic fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public fun minus (JJ)Ljava/lang/Long; public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun multiply (JJ)Ljava/lang/Long; @@ -1793,61 +1420,28 @@ public final class space/kscience/kmath/operations/LongRing : space/kscience/kma public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; public fun plus (JJ)Ljava/lang/Long; public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun rightSideNumberOperation (Ljava/lang/String;JLjava/lang/Number;)Ljava/lang/Long; - public synthetic fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public fun times (JJ)Ljava/lang/Long; public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun unaryMinus (J)Ljava/lang/Long; public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperation (Ljava/lang/String;J)Ljava/lang/Long; - public synthetic fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public fun unaryPlus (J)Ljava/lang/Long; - public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; } public abstract interface class space/kscience/kmath/operations/Norm { public abstract fun norm (Ljava/lang/Object;)Ljava/lang/Object; } -public final class space/kscience/kmath/operations/NumbersAddOperations$DefaultImpls { - public static fun binaryOperation (Lspace/kscience/kmath/operations/NumbersAddOperations;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun binaryOperationFunction (Lspace/kscience/kmath/operations/NumbersAddOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun bindSymbol (Lspace/kscience/kmath/operations/NumbersAddOperations;Ljava/lang/String;)Ljava/lang/Object; - public static fun leftSideNumberOperation (Lspace/kscience/kmath/operations/NumbersAddOperations;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public static fun leftSideNumberOperationFunction (Lspace/kscience/kmath/operations/NumbersAddOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun minus (Lspace/kscience/kmath/operations/NumbersAddOperations;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public static fun minus (Lspace/kscience/kmath/operations/NumbersAddOperations;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public static fun minus (Lspace/kscience/kmath/operations/NumbersAddOperations;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun plus (Lspace/kscience/kmath/operations/NumbersAddOperations;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public static fun plus (Lspace/kscience/kmath/operations/NumbersAddOperations;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public static fun plus (Lspace/kscience/kmath/operations/NumbersAddOperations;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun rightSideNumberOperation (Lspace/kscience/kmath/operations/NumbersAddOperations;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public static fun rightSideNumberOperationFunction (Lspace/kscience/kmath/operations/NumbersAddOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun unaryOperation (Lspace/kscience/kmath/operations/NumbersAddOperations;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperationFunction (Lspace/kscience/kmath/operations/NumbersAddOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public static fun unaryPlus (Lspace/kscience/kmath/operations/NumbersAddOperations;Ljava/lang/Object;)Ljava/lang/Object; -} - public abstract interface class space/kscience/kmath/operations/NumericAlgebra : space/kscience/kmath/operations/Algebra { - public abstract fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public fun bindSymbolOrNull (Ljava/lang/String;)Ljava/lang/Object; + public fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; + public fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public abstract fun number (Ljava/lang/Number;)Ljava/lang/Object; - public abstract fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public abstract fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; } -public final class space/kscience/kmath/operations/NumericAlgebra$DefaultImpls { - public static fun binaryOperation (Lspace/kscience/kmath/operations/NumericAlgebra;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun binaryOperationFunction (Lspace/kscience/kmath/operations/NumericAlgebra;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun bindSymbol (Lspace/kscience/kmath/operations/NumericAlgebra;Ljava/lang/String;)Ljava/lang/Object; - public static fun leftSideNumberOperation (Lspace/kscience/kmath/operations/NumericAlgebra;Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public static fun leftSideNumberOperationFunction (Lspace/kscience/kmath/operations/NumericAlgebra;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun rightSideNumberOperation (Lspace/kscience/kmath/operations/NumericAlgebra;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public static fun rightSideNumberOperationFunction (Lspace/kscience/kmath/operations/NumericAlgebra;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun unaryOperation (Lspace/kscience/kmath/operations/NumericAlgebra;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperationFunction (Lspace/kscience/kmath/operations/NumericAlgebra;Ljava/lang/String;)Lkotlin/jvm/functions/Function1; +public final class space/kscience/kmath/operations/NumericAlgebraKt { + public static final fun getE (Lspace/kscience/kmath/operations/NumericAlgebra;)Ljava/lang/Object; + public static final fun getPi (Lspace/kscience/kmath/operations/NumericAlgebra;)Ljava/lang/Object; } public final class space/kscience/kmath/operations/OptionalOperationsKt { @@ -1857,9 +1451,9 @@ public abstract interface class space/kscience/kmath/operations/PowerOperations public static final field Companion Lspace/kscience/kmath/operations/PowerOperations$Companion; public static final field POW_OPERATION Ljava/lang/String; public static final field SQRT_OPERATION Ljava/lang/String; - public abstract fun pow (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public fun pow (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; public abstract fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public abstract fun sqrt (Ljava/lang/Object;)Ljava/lang/Object; + public fun sqrt (Ljava/lang/Object;)Ljava/lang/Object; } public final class space/kscience/kmath/operations/PowerOperations$Companion { @@ -1867,176 +1461,37 @@ public final class space/kscience/kmath/operations/PowerOperations$Companion { public static final field SQRT_OPERATION Ljava/lang/String; } -public final class space/kscience/kmath/operations/PowerOperations$DefaultImpls { - public static fun binaryOperation (Lspace/kscience/kmath/operations/PowerOperations;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun binaryOperationFunction (Lspace/kscience/kmath/operations/PowerOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun bindSymbol (Lspace/kscience/kmath/operations/PowerOperations;Ljava/lang/String;)Ljava/lang/Object; - public static fun pow (Lspace/kscience/kmath/operations/PowerOperations;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public static fun sqrt (Lspace/kscience/kmath/operations/PowerOperations;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperation (Lspace/kscience/kmath/operations/PowerOperations;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperationFunction (Lspace/kscience/kmath/operations/PowerOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function1; -} - -public final class space/kscience/kmath/operations/RealField : space/kscience/kmath/operations/ExtendedField, space/kscience/kmath/operations/Norm, space/kscience/kmath/operations/ScaleOperations { - public static final field INSTANCE Lspace/kscience/kmath/operations/RealField; - public fun acos (D)Ljava/lang/Double; - public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; - public fun acosh (D)Ljava/lang/Double; - public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun add (DD)Ljava/lang/Double; - public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun asin (D)Ljava/lang/Double; - public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; - public fun asinh (D)Ljava/lang/Double; - public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun atan (D)Ljava/lang/Double; - public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; - public fun atanh (D)Ljava/lang/Double; - public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperation (Ljava/lang/String;DD)Ljava/lang/Double; - public synthetic fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public fun bindSymbol (Ljava/lang/String;)Ljava/lang/Double; - public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; - public fun cos (D)Ljava/lang/Double; - public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; - public fun cosh (D)Ljava/lang/Double; - public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun div (DD)Ljava/lang/Double; - public fun div (DLjava/lang/Number;)Ljava/lang/Double; - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun divide (DD)Ljava/lang/Double; - public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun exp (D)Ljava/lang/Double; - public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; - public fun getOne ()Ljava/lang/Double; - public synthetic fun getOne ()Ljava/lang/Object; - public fun getZero ()Ljava/lang/Double; - public synthetic fun getZero ()Ljava/lang/Object; - public fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;D)Ljava/lang/Double; - public synthetic fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public fun ln (D)Ljava/lang/Double; - public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; - public fun minus (DD)Ljava/lang/Double; - public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun multiply (DD)Ljava/lang/Double; - public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun norm (D)Ljava/lang/Double; - public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object; - public fun number (Ljava/lang/Number;)Ljava/lang/Double; - public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; - public fun plus (DD)Ljava/lang/Double; - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun pow (DLjava/lang/Number;)Ljava/lang/Double; - public synthetic fun pow (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun power (DLjava/lang/Number;)Ljava/lang/Double; - public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun rightSideNumberOperation (Ljava/lang/String;DLjava/lang/Number;)Ljava/lang/Double; - public synthetic fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public fun scale (DD)Ljava/lang/Double; - public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; - public fun sin (D)Ljava/lang/Double; - public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; - public fun sinh (D)Ljava/lang/Double; - public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun sqrt (D)Ljava/lang/Double; - public synthetic fun sqrt (Ljava/lang/Object;)Ljava/lang/Object; - public fun tan (D)Ljava/lang/Double; - public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; - public fun tanh (D)Ljava/lang/Double; - public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun times (DD)Ljava/lang/Double; - public fun times (DLjava/lang/Number;)Ljava/lang/Double; - public fun times (Ljava/lang/Number;D)Ljava/lang/Double; - public synthetic fun times (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryMinus (D)Ljava/lang/Double; - public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperation (Ljava/lang/String;D)Ljava/lang/Double; - public synthetic fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public fun unaryPlus (D)Ljava/lang/Double; - public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; -} - public abstract interface class space/kscience/kmath/operations/Ring : space/kscience/kmath/operations/Group, space/kscience/kmath/operations/RingOperations { public abstract fun getOne ()Ljava/lang/Object; } -public final class space/kscience/kmath/operations/Ring$DefaultImpls { - public static fun binaryOperation (Lspace/kscience/kmath/operations/Ring;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun binaryOperationFunction (Lspace/kscience/kmath/operations/Ring;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun bindSymbol (Lspace/kscience/kmath/operations/Ring;Ljava/lang/String;)Ljava/lang/Object; - public static fun minus (Lspace/kscience/kmath/operations/Ring;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun plus (Lspace/kscience/kmath/operations/Ring;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun times (Lspace/kscience/kmath/operations/Ring;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperation (Lspace/kscience/kmath/operations/Ring;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperationFunction (Lspace/kscience/kmath/operations/Ring;Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public static fun unaryPlus (Lspace/kscience/kmath/operations/Ring;Ljava/lang/Object;)Ljava/lang/Object; -} - public abstract interface class space/kscience/kmath/operations/RingOperations : space/kscience/kmath/operations/GroupOperations { public static final field Companion Lspace/kscience/kmath/operations/RingOperations$Companion; public static final field TIMES_OPERATION Ljava/lang/String; - public abstract fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public abstract fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; } public final class space/kscience/kmath/operations/RingOperations$Companion { public static final field TIMES_OPERATION Ljava/lang/String; } -public final class space/kscience/kmath/operations/RingOperations$DefaultImpls { - public static fun binaryOperation (Lspace/kscience/kmath/operations/RingOperations;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun binaryOperationFunction (Lspace/kscience/kmath/operations/RingOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun bindSymbol (Lspace/kscience/kmath/operations/RingOperations;Ljava/lang/String;)Ljava/lang/Object; - public static fun minus (Lspace/kscience/kmath/operations/RingOperations;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun plus (Lspace/kscience/kmath/operations/RingOperations;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun times (Lspace/kscience/kmath/operations/RingOperations;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperation (Lspace/kscience/kmath/operations/RingOperations;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperationFunction (Lspace/kscience/kmath/operations/RingOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public static fun unaryPlus (Lspace/kscience/kmath/operations/RingOperations;Ljava/lang/Object;)Ljava/lang/Object; -} - public abstract interface class space/kscience/kmath/operations/ScaleOperations : space/kscience/kmath/operations/Algebra { - public abstract fun div (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public fun div (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; public abstract fun scale (Ljava/lang/Object;D)Ljava/lang/Object; - public abstract fun times (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public abstract fun times (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; -} - -public final class space/kscience/kmath/operations/ScaleOperations$DefaultImpls { - public static fun binaryOperation (Lspace/kscience/kmath/operations/ScaleOperations;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun binaryOperationFunction (Lspace/kscience/kmath/operations/ScaleOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun bindSymbol (Lspace/kscience/kmath/operations/ScaleOperations;Ljava/lang/String;)Ljava/lang/Object; - public static fun div (Lspace/kscience/kmath/operations/ScaleOperations;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public static fun times (Lspace/kscience/kmath/operations/ScaleOperations;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public static fun times (Lspace/kscience/kmath/operations/ScaleOperations;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public static fun unaryOperation (Lspace/kscience/kmath/operations/ScaleOperations;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperationFunction (Lspace/kscience/kmath/operations/ScaleOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function1; + public fun times (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; + public fun times (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; } public final class space/kscience/kmath/operations/ShortRing : space/kscience/kmath/operations/Norm, space/kscience/kmath/operations/NumericAlgebra, space/kscience/kmath/operations/Ring { public static final field INSTANCE Lspace/kscience/kmath/operations/ShortRing; public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun add (SS)Ljava/lang/Short; - public synthetic fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperation (Ljava/lang/String;SS)Ljava/lang/Short; - public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; - public fun bindSymbol (Ljava/lang/String;)Ljava/lang/Short; public synthetic fun getOne ()Ljava/lang/Object; public fun getOne ()Ljava/lang/Short; public synthetic fun getZero ()Ljava/lang/Object; public fun getZero ()Ljava/lang/Short; - public synthetic fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;S)Ljava/lang/Short; - public fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun minus (SS)Ljava/lang/Short; public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; @@ -2047,18 +1502,10 @@ public final class space/kscience/kmath/operations/ShortRing : space/kscience/km public fun number (Ljava/lang/Number;)Ljava/lang/Short; public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun plus (SS)Ljava/lang/Short; - public synthetic fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun rightSideNumberOperation (Ljava/lang/String;SLjava/lang/Number;)Ljava/lang/Short; - public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun times (SS)Ljava/lang/Short; public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; public fun unaryMinus (S)Ljava/lang/Short; - public synthetic fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperation (Ljava/lang/String;S)Ljava/lang/Short; - public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryPlus (S)Ljava/lang/Short; } public abstract interface class space/kscience/kmath/operations/TrigonometricOperations : space/kscience/kmath/operations/Algebra { @@ -2086,17 +1533,8 @@ public final class space/kscience/kmath/operations/TrigonometricOperations$Compa public static final field TAN_OPERATION Ljava/lang/String; } -public final class space/kscience/kmath/operations/TrigonometricOperations$DefaultImpls { - public static fun binaryOperation (Lspace/kscience/kmath/operations/TrigonometricOperations;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public static fun binaryOperationFunction (Lspace/kscience/kmath/operations/TrigonometricOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public static fun bindSymbol (Lspace/kscience/kmath/operations/TrigonometricOperations;Ljava/lang/String;)Ljava/lang/Object; - public static fun unaryOperation (Lspace/kscience/kmath/operations/TrigonometricOperations;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public static fun unaryOperationFunction (Lspace/kscience/kmath/operations/TrigonometricOperations;Ljava/lang/String;)Lkotlin/jvm/functions/Function1; -} - public final class space/kscience/kmath/structures/ArrayBuffer : space/kscience/kmath/structures/MutableBuffer { public fun ([Ljava/lang/Object;)V - public fun contentEquals (Lspace/kscience/kmath/structures/Buffer;)Z public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; public fun get (I)Ljava/lang/Object; public fun getSize ()I @@ -2106,7 +1544,6 @@ public final class space/kscience/kmath/structures/ArrayBuffer : space/kscience/ public abstract interface class space/kscience/kmath/structures/Buffer { public static final field Companion Lspace/kscience/kmath/structures/Buffer$Companion; - public abstract fun contentEquals (Lspace/kscience/kmath/structures/Buffer;)Z public abstract fun get (I)Ljava/lang/Object; public abstract fun getSize ()I public abstract fun iterator ()Ljava/util/Iterator; @@ -2115,14 +1552,11 @@ public abstract interface class space/kscience/kmath/structures/Buffer { public final class space/kscience/kmath/structures/Buffer$Companion { public final fun auto (Lkotlin/reflect/KClass;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/Buffer; public final fun boxing (ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/Buffer; -} - -public final class space/kscience/kmath/structures/Buffer$DefaultImpls { - public static fun contentEquals (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Z + public final fun contentEquals (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Z } public final class space/kscience/kmath/structures/BufferKt { - public static final fun asBuffer (Ljava/util/List;)Ljava/util/List; + public static final fun asBuffer (Ljava/util/List;)Lspace/kscience/kmath/structures/ListBuffer; public static final fun asBuffer ([Ljava/lang/Object;)Lspace/kscience/kmath/structures/ArrayBuffer; public static final fun asMutableBuffer (Ljava/util/List;)Ljava/util/List; public static final fun asReadOnly (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; @@ -2132,27 +1566,153 @@ public final class space/kscience/kmath/structures/BufferKt { public final class space/kscience/kmath/structures/BufferOperationKt { public static final fun asIterable (Lspace/kscience/kmath/structures/Buffer;)Ljava/lang/Iterable; public static final fun asSequence (Lspace/kscience/kmath/structures/Buffer;)Lkotlin/sequences/Sequence; + public static final fun fold (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; + public static final fun map (Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/Buffer; public static final fun toList (Lspace/kscience/kmath/structures/Buffer;)Ljava/util/List; } +public final class space/kscience/kmath/structures/DoubleBuffer : space/kscience/kmath/structures/MutableBuffer { + public static final synthetic fun box-impl ([D)Lspace/kscience/kmath/structures/DoubleBuffer; + public static fun constructor-impl ([D)[D + public synthetic fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; + public fun copy-Dv3HvWU ()[D + public static fun copy-Dv3HvWU ([D)[D + public fun equals (Ljava/lang/Object;)Z + public static fun equals-impl ([DLjava/lang/Object;)Z + public static final fun equals-impl0 ([D[D)Z + public fun get (I)Ljava/lang/Double; + public synthetic fun get (I)Ljava/lang/Object; + public static fun get-impl ([DI)Ljava/lang/Double; + public final fun getArray ()[D + public fun getSize ()I + public static fun getSize-impl ([D)I + public fun hashCode ()I + public static fun hashCode-impl ([D)I + public synthetic fun iterator ()Ljava/util/Iterator; + public fun iterator ()Lkotlin/collections/DoubleIterator; + public static fun iterator-impl ([D)Lkotlin/collections/DoubleIterator; + public fun set (ID)V + public synthetic fun set (ILjava/lang/Object;)V + public static fun set-impl ([DID)V + public fun toString ()Ljava/lang/String; + public static fun toString-impl ([D)Ljava/lang/String; + public final synthetic fun unbox-impl ()[D +} + +public final class space/kscience/kmath/structures/DoubleBufferField : space/kscience/kmath/operations/ExtendedField { + public fun (I)V + public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; + public fun acos-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun acosh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun add-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; + public fun asin-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun asinh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; + public fun atan-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun atanh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; + public fun cos-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun cosh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun divide-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; + public fun exp-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun getOne ()Ljava/lang/Object; + public fun getOne ()Lspace/kscience/kmath/structures/Buffer; + public final fun getSize ()I + public synthetic fun getZero ()Ljava/lang/Object; + public fun getZero ()Lspace/kscience/kmath/structures/Buffer; + public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; + public fun ln-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun multiply-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/structures/Buffer; + public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public fun power-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)[D + public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; + public fun scale-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;D)[D + public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; + public fun sin-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun sinh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; + public fun tan-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun tanh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryMinus (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; +} + +public final class space/kscience/kmath/structures/DoubleBufferFieldOperations : space/kscience/kmath/operations/ExtendedFieldOperations { + public static final field INSTANCE Lspace/kscience/kmath/structures/DoubleBufferFieldOperations; + public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; + public fun acos-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun acosh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun add-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; + public fun asin-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun asinh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; + public fun atan-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun atanh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; + public fun cos-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun cosh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun divide-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; + public fun exp-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; + public fun ln-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun multiply-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public fun power-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)[D + public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; + public fun sin-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun sinh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; + public fun tan-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun tanh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryMinus-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D +} + +public final class space/kscience/kmath/structures/DoubleBufferKt { + public static final fun DoubleBuffer (ILkotlin/jvm/functions/Function1;)[D + public static final fun DoubleBuffer ([D)[D + public static final fun asBuffer ([D)[D + public static final fun contentEquals-2c9zdjM ([D[D)Z + public static final fun toDoubleArray (Lspace/kscience/kmath/structures/Buffer;)[D +} + public abstract interface class space/kscience/kmath/structures/FlaggedBuffer : space/kscience/kmath/structures/Buffer { public abstract fun getFlag (I)B } -public final class space/kscience/kmath/structures/FlaggedBuffer$DefaultImpls { - public static fun contentEquals (Lspace/kscience/kmath/structures/FlaggedBuffer;Lspace/kscience/kmath/structures/Buffer;)Z -} - public final class space/kscience/kmath/structures/FlaggedBufferKt { - public static final fun forEachValid (Lspace/kscience/kmath/structures/FlaggedRealBuffer;Lkotlin/jvm/functions/Function1;)V + public static final fun forEachValid (Lspace/kscience/kmath/structures/FlaggedDoubleBuffer;Lkotlin/jvm/functions/Function1;)V public static final fun hasFlag (Lspace/kscience/kmath/structures/FlaggedBuffer;ILspace/kscience/kmath/structures/ValueFlag;)Z public static final fun isMissing (Lspace/kscience/kmath/structures/FlaggedBuffer;I)Z public static final fun isValid (Lspace/kscience/kmath/structures/FlaggedBuffer;I)Z } -public final class space/kscience/kmath/structures/FlaggedRealBuffer : space/kscience/kmath/structures/Buffer, space/kscience/kmath/structures/FlaggedBuffer { +public final class space/kscience/kmath/structures/FlaggedDoubleBuffer : space/kscience/kmath/structures/Buffer, space/kscience/kmath/structures/FlaggedBuffer { public fun ([D[B)V - public fun contentEquals (Lspace/kscience/kmath/structures/Buffer;)Z public fun get (I)Ljava/lang/Double; public synthetic fun get (I)Ljava/lang/Object; public fun getFlag (I)B @@ -2165,8 +1725,6 @@ public final class space/kscience/kmath/structures/FlaggedRealBuffer : space/ksc public final class space/kscience/kmath/structures/FloatBuffer : space/kscience/kmath/structures/MutableBuffer { public static final synthetic fun box-impl ([F)Lspace/kscience/kmath/structures/FloatBuffer; public static fun constructor-impl ([F)[F - public fun contentEquals (Lspace/kscience/kmath/structures/Buffer;)Z - public static fun contentEquals-impl ([FLspace/kscience/kmath/structures/Buffer;)Z public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; public static fun copy-impl ([F)Lspace/kscience/kmath/structures/MutableBuffer; public fun equals (Ljava/lang/Object;)Z @@ -2201,8 +1759,6 @@ public final class space/kscience/kmath/structures/FloatBufferKt { public final class space/kscience/kmath/structures/IntBuffer : space/kscience/kmath/structures/MutableBuffer { public static final synthetic fun box-impl ([I)Lspace/kscience/kmath/structures/IntBuffer; public static fun constructor-impl ([I)[I - public fun contentEquals (Lspace/kscience/kmath/structures/Buffer;)Z - public static fun contentEquals-impl ([ILspace/kscience/kmath/structures/Buffer;)Z public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; public static fun copy-impl ([I)Lspace/kscience/kmath/structures/MutableBuffer; public fun equals (Ljava/lang/Object;)Z @@ -2235,32 +1791,17 @@ public final class space/kscience/kmath/structures/IntBufferKt { } public final class space/kscience/kmath/structures/ListBuffer : space/kscience/kmath/structures/Buffer { - public static final synthetic fun box-impl (Ljava/util/List;)Lspace/kscience/kmath/structures/ListBuffer; - public static fun constructor-impl (Ljava/util/List;)Ljava/util/List; - public fun contentEquals (Lspace/kscience/kmath/structures/Buffer;)Z - public static fun contentEquals-impl (Ljava/util/List;Lspace/kscience/kmath/structures/Buffer;)Z - public fun equals (Ljava/lang/Object;)Z - public static fun equals-impl (Ljava/util/List;Ljava/lang/Object;)Z - public static final fun equals-impl0 (Ljava/util/List;Ljava/util/List;)Z + public fun (ILkotlin/jvm/functions/Function1;)V + public fun (Ljava/util/List;)V public fun get (I)Ljava/lang/Object; - public static fun get-impl (Ljava/util/List;I)Ljava/lang/Object; public final fun getList ()Ljava/util/List; public fun getSize ()I - public static fun getSize-impl (Ljava/util/List;)I - public fun hashCode ()I - public static fun hashCode-impl (Ljava/util/List;)I public fun iterator ()Ljava/util/Iterator; - public static fun iterator-impl (Ljava/util/List;)Ljava/util/Iterator; - public fun toString ()Ljava/lang/String; - public static fun toString-impl (Ljava/util/List;)Ljava/lang/String; - public final synthetic fun unbox-impl ()Ljava/util/List; } public final class space/kscience/kmath/structures/LongBuffer : space/kscience/kmath/structures/MutableBuffer { public static final synthetic fun box-impl ([J)Lspace/kscience/kmath/structures/LongBuffer; public static fun constructor-impl ([J)[J - public fun contentEquals (Lspace/kscience/kmath/structures/Buffer;)Z - public static fun contentEquals-impl ([JLspace/kscience/kmath/structures/Buffer;)Z public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; public static fun copy-impl ([J)Lspace/kscience/kmath/structures/MutableBuffer; public fun equals (Ljava/lang/Object;)Z @@ -2295,7 +1836,6 @@ public final class space/kscience/kmath/structures/LongBufferKt { public class space/kscience/kmath/structures/MemoryBuffer : space/kscience/kmath/structures/Buffer { public static final field Companion Lspace/kscience/kmath/structures/MemoryBuffer$Companion; public fun (Lspace/kscience/kmath/memory/Memory;Lspace/kscience/kmath/memory/MemorySpec;)V - public fun contentEquals (Lspace/kscience/kmath/structures/Buffer;)Z public fun get (I)Ljava/lang/Object; protected final fun getMemory ()Lspace/kscience/kmath/memory/Memory; public fun getSize ()I @@ -2317,22 +1857,17 @@ public abstract interface class space/kscience/kmath/structures/MutableBuffer : public final class space/kscience/kmath/structures/MutableBuffer$Companion { public final fun auto (Lkotlin/reflect/KClass;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/MutableBuffer; public final fun boxing (ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/MutableBuffer; + public final fun double-CZ9oacQ (ILkotlin/jvm/functions/Function1;)[D public final fun float-YxruXGw (ILkotlin/jvm/functions/Function1;)[F public final fun int-Ye6GY2U (ILkotlin/jvm/functions/Function1;)[I public final fun long-BuQOeTY (ILkotlin/jvm/functions/Function1;)[J - public final fun real-8hrHhI4 (ILkotlin/jvm/functions/Function1;)[D public final fun short-1yRgbGw (ILkotlin/jvm/functions/Function1;)[S } -public final class space/kscience/kmath/structures/MutableBuffer$DefaultImpls { - public static fun contentEquals (Lspace/kscience/kmath/structures/MutableBuffer;Lspace/kscience/kmath/structures/Buffer;)Z -} - public final class space/kscience/kmath/structures/MutableListBuffer : space/kscience/kmath/structures/MutableBuffer { public static final synthetic fun box-impl (Ljava/util/List;)Lspace/kscience/kmath/structures/MutableListBuffer; + public static fun constructor-impl (ILkotlin/jvm/functions/Function1;)Ljava/util/List; public static fun constructor-impl (Ljava/util/List;)Ljava/util/List; - public fun contentEquals (Lspace/kscience/kmath/structures/Buffer;)Z - public static fun contentEquals-impl (Ljava/util/List;Lspace/kscience/kmath/structures/Buffer;)Z public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; public static fun copy-impl (Ljava/util/List;)Lspace/kscience/kmath/structures/MutableBuffer; public fun equals (Ljava/lang/Object;)Z @@ -2369,8 +1904,6 @@ public final class space/kscience/kmath/structures/MutableMemoryBuffer$Companion public final class space/kscience/kmath/structures/ReadOnlyBuffer : space/kscience/kmath/structures/Buffer { public static final synthetic fun box-impl (Lspace/kscience/kmath/structures/MutableBuffer;)Lspace/kscience/kmath/structures/ReadOnlyBuffer; public static fun constructor-impl (Lspace/kscience/kmath/structures/MutableBuffer;)Lspace/kscience/kmath/structures/MutableBuffer; - public fun contentEquals (Lspace/kscience/kmath/structures/Buffer;)Z - public static fun contentEquals-impl (Lspace/kscience/kmath/structures/MutableBuffer;Lspace/kscience/kmath/structures/Buffer;)Z public fun equals (Ljava/lang/Object;)Z public static fun equals-impl (Lspace/kscience/kmath/structures/MutableBuffer;Ljava/lang/Object;)Z public static final fun equals-impl0 (Lspace/kscience/kmath/structures/MutableBuffer;Lspace/kscience/kmath/structures/MutableBuffer;)Z @@ -2388,198 +1921,9 @@ public final class space/kscience/kmath/structures/ReadOnlyBuffer : space/kscien public final synthetic fun unbox-impl ()Lspace/kscience/kmath/structures/MutableBuffer; } -public final class space/kscience/kmath/structures/RealBuffer : space/kscience/kmath/structures/MutableBuffer { - public static final synthetic fun box-impl ([D)Lspace/kscience/kmath/structures/RealBuffer; - public static fun constructor-impl ([D)[D - public fun contentEquals (Lspace/kscience/kmath/structures/Buffer;)Z - public static fun contentEquals-impl ([DLspace/kscience/kmath/structures/Buffer;)Z - public synthetic fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; - public fun copy-88GwAag ()[D - public static fun copy-88GwAag ([D)[D - public fun equals (Ljava/lang/Object;)Z - public static fun equals-impl ([DLjava/lang/Object;)Z - public static final fun equals-impl0 ([D[D)Z - public fun get (I)Ljava/lang/Double; - public synthetic fun get (I)Ljava/lang/Object; - public static fun get-impl ([DI)Ljava/lang/Double; - public final fun getArray ()[D - public fun getSize ()I - public static fun getSize-impl ([D)I - public fun hashCode ()I - public static fun hashCode-impl ([D)I - public synthetic fun iterator ()Ljava/util/Iterator; - public fun iterator ()Lkotlin/collections/DoubleIterator; - public static fun iterator-impl ([D)Lkotlin/collections/DoubleIterator; - public fun set (ID)V - public synthetic fun set (ILjava/lang/Object;)V - public static fun set-impl ([DID)V - public fun toString ()Ljava/lang/String; - public static fun toString-impl ([D)Ljava/lang/String; - public final synthetic fun unbox-impl ()[D -} - -public final class space/kscience/kmath/structures/RealBufferField : space/kscience/kmath/operations/ExtendedField { - public fun (I)V - public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; - public fun acos-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun acosh-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun add-8hrHhI4 (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; - public fun asin-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun asinh-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; - public fun atan-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun atanh-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperation (Ljava/lang/String;Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; - public fun bindSymbol (Ljava/lang/String;)Lspace/kscience/kmath/structures/Buffer; - public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; - public fun cos-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun cosh-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun div (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)Lspace/kscience/kmath/structures/Buffer; - public fun div (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun divide-8hrHhI4 (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; - public fun exp-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun getOne ()Ljava/lang/Object; - public fun getOne ()Lspace/kscience/kmath/structures/Buffer; - public final fun getSize ()I - public synthetic fun getZero ()Ljava/lang/Object; - public fun getZero ()Lspace/kscience/kmath/structures/Buffer; - public synthetic fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; - public fun ln-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun minus (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun multiply-8hrHhI4 (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; - public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/structures/Buffer; - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun plus (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public synthetic fun pow (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun pow (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)Lspace/kscience/kmath/structures/Buffer; - public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun power-8hrHhI4 (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)[D - public synthetic fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun rightSideNumberOperation (Ljava/lang/String;Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)Lspace/kscience/kmath/structures/Buffer; - public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; - public fun scale-8hrHhI4 (Lspace/kscience/kmath/structures/Buffer;D)[D - public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; - public fun sin-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun sinh-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun sqrt (Ljava/lang/Object;)Ljava/lang/Object; - public fun sqrt (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; - public fun tan-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun tanh-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun times (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun times (Ljava/lang/Number;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun times (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)Lspace/kscience/kmath/structures/Buffer; - public fun times (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryMinus (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public synthetic fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperation (Ljava/lang/String;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryPlus (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; -} - -public final class space/kscience/kmath/structures/RealBufferFieldOperations : space/kscience/kmath/operations/ExtendedFieldOperations { - public static final field INSTANCE Lspace/kscience/kmath/structures/RealBufferFieldOperations; - public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; - public fun acos-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun acosh-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun add-8hrHhI4 (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; - public fun asin-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun asinh-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; - public fun atan-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun atanh-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperation (Ljava/lang/String;Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; - public fun bindSymbol (Ljava/lang/String;)Lspace/kscience/kmath/structures/Buffer; - public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; - public fun cos-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun cosh-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun div (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun divide-8hrHhI4 (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; - public fun exp-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; - public fun ln-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun minus (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun multiply-8hrHhI4 (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun plus (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public synthetic fun pow (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun pow (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)Lspace/kscience/kmath/structures/Buffer; - public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun power-8hrHhI4 (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)[D - public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; - public fun sin-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun sinh-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun sqrt (Ljava/lang/Object;)Ljava/lang/Object; - public fun sqrt (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; - public fun tan-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun tanh-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun times (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryMinus-LGjt3BI (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperation (Ljava/lang/String;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryPlus (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; -} - -public final class space/kscience/kmath/structures/RealBufferKt { - public static final fun RealBuffer (ILkotlin/jvm/functions/Function1;)[D - public static final fun RealBuffer ([D)[D - public static final fun asBuffer ([D)[D - public static final fun contentEquals-2uVC2J0 ([D[D)Z - public static final fun toDoubleArray (Lspace/kscience/kmath/structures/Buffer;)[D -} - public final class space/kscience/kmath/structures/ShortBuffer : space/kscience/kmath/structures/MutableBuffer { public static final synthetic fun box-impl ([S)Lspace/kscience/kmath/structures/ShortBuffer; public static fun constructor-impl ([S)[S - public fun contentEquals (Lspace/kscience/kmath/structures/Buffer;)Z - public static fun contentEquals-impl ([SLspace/kscience/kmath/structures/Buffer;)Z public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; public static fun copy-impl ([S)Lspace/kscience/kmath/structures/MutableBuffer; public fun equals (Ljava/lang/Object;)Z @@ -2623,7 +1967,6 @@ public final class space/kscience/kmath/structures/ValueFlag : java/lang/Enum { public final class space/kscience/kmath/structures/VirtualBuffer : space/kscience/kmath/structures/Buffer { public fun (ILkotlin/jvm/functions/Function1;)V - public fun contentEquals (Lspace/kscience/kmath/structures/Buffer;)Z public fun get (I)Ljava/lang/Object; public fun getSize ()I public fun iterator ()Ljava/util/Iterator; diff --git a/kmath-core/build.gradle.kts b/kmath-core/build.gradle.kts index 4f1028095..df70aa40b 100644 --- a/kmath-core/build.gradle.kts +++ b/kmath-core/build.gradle.kts @@ -6,7 +6,8 @@ import ru.mipt.npm.gradle.Maturity plugins { - id("ru.mipt.npm.gradle.mpp") + kotlin("multiplatform") + id("ru.mipt.npm.gradle.common") id("ru.mipt.npm.gradle.native") } @@ -28,13 +29,13 @@ readme { description = """ Algebraic structures like rings, spaces and fields. """.trimIndent(), - ref = "src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt" + ref = "src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt" ) feature( id = "nd", description = "Many-dimensional structures and operations on them.", - ref = "src/commonMain/kotlin/kscience/kmath/structures/NDStructure.kt" + ref = "src/commonMain/kotlin/space/kscience/kmath/structures/StructureND.kt" ) feature( @@ -42,13 +43,13 @@ readme { description = """ Basic linear algebra operations (sums, products, etc.), backed by the `Space` API. Advanced linear algebra operations like matrix inversion and LU decomposition. """.trimIndent(), - ref = "src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt" + ref = "src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt" ) feature( id = "buffers", description = "One-dimensional structure", - ref = "src/commonMain/kotlin/kscience/kmath/structures/Buffers.kt" + ref = "src/commonMain/kotlin/space/kscience/kmath/structures/Buffers.kt" ) feature( @@ -58,18 +59,18 @@ readme { 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. """.trimIndent(), - ref = "src/commonMain/kotlin/kscience/kmath/expressions" + ref = "src/commonMain/kotlin/space/kscience/kmath/expressions" ) feature( id = "domains", description = "Domains", - ref = "src/commonMain/kotlin/kscience/kmath/domains" + ref = "src/commonMain/kotlin/space/kscience/kmath/domains" ) feature( id = "autodif", description = "Automatic differentiation", - ref = "src/commonMain/kotlin/kscience/kmath/expressions/SimpleAutoDiff.kt" + ref = "src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt" ) } diff --git a/kmath-core/docs/README-TEMPLATE.md b/kmath-core/docs/README-TEMPLATE.md index 83d1ebdce..41cfe1ccb 100644 --- a/kmath-core/docs/README-TEMPLATE.md +++ b/kmath-core/docs/README-TEMPLATE.md @@ -1,6 +1,6 @@ -# The Core Module (`kmath-core`) +# Module kmath-core -The core features of KMath: +The core interfaces of KMath. ${features} diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/ColumnarData.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/ColumnarData.kt new file mode 100644 index 000000000..abbb46583 --- /dev/null +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/ColumnarData.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.data + +import space.kscience.kmath.misc.Symbol +import space.kscience.kmath.misc.UnstableKMathAPI +import space.kscience.kmath.nd.Structure2D +import space.kscience.kmath.structures.Buffer + +/** + * A column-based data set with all columns of the same size (not necessary fixed in time). + * The column could be retrieved by a [get] operation. + */ +@UnstableKMathAPI +public interface ColumnarData { + public val size: Int + + public operator fun get(symbol: Symbol): Buffer +} + +/** + * A zero-copy method to represent a [Structure2D] as a two-column x-y data. + * There could more than two columns in the structure. + */ +@UnstableKMathAPI +public fun Structure2D.asColumnarData(mapping: Map): ColumnarData { + require(shape[1] >= mapping.maxOf { it.value }) { "Column index out of bounds" } + return object : ColumnarData { + override val size: Int get() = shape[0] + override fun get(symbol: Symbol): Buffer { + val index = mapping[symbol] ?: error("No column mapping for symbol $symbol") + return columns[index] + } + } +} + diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt new file mode 100644 index 000000000..663908e90 --- /dev/null +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt @@ -0,0 +1,60 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.data + +import space.kscience.kmath.misc.Symbol +import space.kscience.kmath.misc.UnstableKMathAPI +import space.kscience.kmath.nd.Structure2D +import space.kscience.kmath.structures.Buffer +import kotlin.math.max + +/** + * The buffer of X values. + */ +@UnstableKMathAPI +public interface XYColumnarData : ColumnarData { + /** + * The buffer of X values + */ + public val x: Buffer + + /** + * The buffer of Y values. + */ + public val y: Buffer + + override fun get(symbol: Symbol): Buffer = when (symbol) { + Symbol.x -> x + Symbol.y -> y + else -> error("A column for symbol $symbol not found") + } +} + +@Suppress("FunctionName") +@UnstableKMathAPI +public fun XYColumnarData(x: Buffer, y: Buffer): XYColumnarData { + require(x.size == y.size) { "Buffer size mismatch. x buffer size is ${x.size}, y buffer size is ${y.size}" } + return object : XYColumnarData { + override val size: Int = x.size + override val x: Buffer = x + override val y: Buffer = y + } +} + + +/** + * A zero-copy method to represent a [Structure2D] as a two-column x-y data. + * There could more than two columns in the structure. + */ +@UnstableKMathAPI +public fun Structure2D.asXYData(xIndex: Int = 0, yIndex: Int = 1): XYColumnarData { + require(shape[1] >= max(xIndex, yIndex)) { "Column index out of bounds" } + return object : XYColumnarData { + override val size: Int get() = this@asXYData.shape[0] + override val x: Buffer get() = columns[xIndex] + override val y: Buffer get() = columns[yIndex] + } +} diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYZColumnarData.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYZColumnarData.kt new file mode 100644 index 000000000..d76a44e9e --- /dev/null +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYZColumnarData.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.data + +import space.kscience.kmath.misc.Symbol +import space.kscience.kmath.misc.UnstableKMathAPI +import space.kscience.kmath.structures.Buffer + +/** + * A [XYColumnarData] with guaranteed [x], [y] and [z] columns designated by corresponding symbols. + * Inherits [XYColumnarData]. + */ +@UnstableKMathAPI +public interface XYZColumnarData : XYColumnarData { + public val z: Buffer + + override fun get(symbol: Symbol): Buffer = when (symbol) { + Symbol.x -> x + Symbol.y -> y + Symbol.z -> z + else -> error("A column for symbol $symbol not found") + } +} \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/RealDomain.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/DoubleDomain.kt similarity index 93% rename from kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/RealDomain.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/DoubleDomain.kt index 861fc9375..ee1bebde0 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/RealDomain.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/DoubleDomain.kt @@ -12,8 +12,7 @@ import space.kscience.kmath.misc.UnstableKMathAPI * @author Alexander Nozik */ @UnstableKMathAPI -public interface RealDomain : Domain { - +public interface DoubleDomain : Domain { /** * Global lower edge * @param num axis number diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/HyperSquareDomain.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/HyperSquareDomain.kt index c71f2fd33..f5560d935 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/HyperSquareDomain.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/HyperSquareDomain.kt @@ -16,7 +16,7 @@ import space.kscience.kmath.structures.indices * @author Alexander Nozik */ @UnstableKMathAPI -public class HyperSquareDomain(private val lower: Buffer, private val upper: Buffer) : RealDomain { +public class HyperSquareDomain(private val lower: Buffer, private val upper: Buffer) : DoubleDomain { public override val dimension: Int get() = lower.size public override operator fun contains(point: Point): Boolean = point.indices.all { i -> diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/UnconstrainedDomain.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/UnconstrainedDomain.kt index 43d9d27a6..7ffc0659d 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/UnconstrainedDomain.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/UnconstrainedDomain.kt @@ -8,7 +8,7 @@ import space.kscience.kmath.linear.Point import space.kscience.kmath.misc.UnstableKMathAPI @UnstableKMathAPI -public class UnconstrainedDomain(public override val dimension: Int) : RealDomain { +public class UnconstrainedDomain(public override val dimension: Int) : DoubleDomain { public override operator fun contains(point: Point): Boolean = true public override fun getLowerBound(num: Int): Double = Double.NEGATIVE_INFINITY diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/UnivariateDomain.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/UnivariateDomain.kt index fff9a4ca3..e7acada85 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/UnivariateDomain.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/UnivariateDomain.kt @@ -9,7 +9,7 @@ import space.kscience.kmath.linear.Point import space.kscience.kmath.misc.UnstableKMathAPI @UnstableKMathAPI -public inline class UnivariateDomain(public val range: ClosedFloatingPointRange) : RealDomain { +public class UnivariateDomain(public val range: ClosedFloatingPointRange) : DoubleDomain { public override val dimension: Int get() = 1 public operator fun contains(d: Double): Boolean = range.contains(d) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DifferentiableExpression.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DifferentiableExpression.kt index 33d72afad..dbc1431b3 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DifferentiableExpression.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DifferentiableExpression.kt @@ -5,6 +5,9 @@ package space.kscience.kmath.expressions +import space.kscience.kmath.misc.StringSymbol +import space.kscience.kmath.misc.Symbol + /** * Represents expression which structure can be differentiated. * diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Expression.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Expression.kt index 597b51791..a9ab8648f 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Expression.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Expression.kt @@ -5,27 +5,12 @@ package space.kscience.kmath.expressions +import space.kscience.kmath.misc.StringSymbol +import space.kscience.kmath.misc.Symbol import space.kscience.kmath.operations.Algebra import kotlin.jvm.JvmName import kotlin.properties.ReadOnlyProperty -/** - * A marker interface for a symbol. A symbol mus have an identity - */ -public interface Symbol { - /** - * Identity object for the symbol. Two symbols with the same identity are considered to be the same symbol. - */ - public val identity: String -} - -/** - * A [Symbol] with a [String] identity - */ -public inline class StringSymbol(override val identity: String) : Symbol { - override fun toString(): String = identity -} - /** * An elementary function that could be invoked on a map of arguments. * @@ -75,15 +60,6 @@ public operator fun Expression.invoke(vararg pairs: Pair): T = * @param E type of the actual expression state */ public interface ExpressionAlgebra : Algebra { - /** - * Bind a given [Symbol] to this context variable and produce context-specific object. Return null if symbol could not be bound in current context. - */ - public fun bindSymbolOrNull(symbol: Symbol): E? - - /** - * Bind a string to a context using [StringSymbol] - */ - override fun bindSymbol(value: String): E = bindSymbol(StringSymbol(value)) /** * A constant expression which does not depend on arguments @@ -91,22 +67,9 @@ public interface ExpressionAlgebra : Algebra { public fun const(value: T): E } -/** - * Bind a given [Symbol] to this context variable and produce context-specific object. - */ -public fun ExpressionAlgebra.bindSymbol(symbol: Symbol): E = - bindSymbolOrNull(symbol) ?: error("Symbol $symbol could not be bound to $this") - -/** - * A delegate to create a symbol with a string identity in this scope - */ -public val symbol: ReadOnlyProperty = ReadOnlyProperty { _, property -> - StringSymbol(property.name) -} - /** * Bind a symbol by name inside the [ExpressionAlgebra] */ public fun ExpressionAlgebra.binding(): ReadOnlyProperty = ReadOnlyProperty { _, property -> - bindSymbol(StringSymbol(property.name)) ?: error("A variable with name ${property.name} does not exist") + bindSymbol(property.name) ?: error("A variable with name ${property.name} does not exist") } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt index aa0815155..994d52a73 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.expressions +import space.kscience.kmath.misc.StringSymbol import space.kscience.kmath.operations.* /** @@ -23,8 +24,10 @@ public abstract class FunctionalExpressionAlgebra>( /** * Builds an Expression to access a variable. */ - public override fun bindSymbolOrNull(symbol: Symbol): Expression? = Expression { arguments -> - arguments[symbol] ?: error("Argument not found: $symbol") + public override fun bindSymbolOrNull(value: String): Expression? = Expression { arguments -> + algebra.bindSymbolOrNull(value) + ?: arguments[StringSymbol(value)] + ?: error("Symbol '$value' is not supported in $this") } /** @@ -46,14 +49,14 @@ public abstract class FunctionalExpressionAlgebra>( } /** - * A context class for [Expression] construction for [Group] algebras. + * A context class for [Expression] construction for [Ring] algebras. */ public open class FunctionalExpressionGroup>( algebra: A, ) : FunctionalExpressionAlgebra(algebra), Group> { public override val zero: Expression get() = const(algebra.zero) - override fun Expression.unaryMinus(): Expression = + public override fun Expression.unaryMinus(): Expression = unaryOperation(GroupOperations.MINUS_OPERATION, this) /** @@ -105,8 +108,7 @@ public open class FunctionalExpressionRing>( public open class FunctionalExpressionField>( algebra: A, -) : FunctionalExpressionRing(algebra), Field>, - ScaleOperations> { +) : FunctionalExpressionRing(algebra), Field>, ScaleOperations> { /** * Builds an Expression of division an expression by another one. */ @@ -122,16 +124,21 @@ public open class FunctionalExpressionField>( public override fun binaryOperationFunction(operation: String): (left: Expression, right: Expression) -> Expression = super.binaryOperationFunction(operation) - override fun scale(a: Expression, value: Double): Expression = algebra { + public override fun scale(a: Expression, value: Double): Expression = algebra { Expression { args -> a(args) * value } } + + public override fun bindSymbolOrNull(value: String): Expression? = + super.bindSymbolOrNull(value) } public open class FunctionalExpressionExtendedField>( algebra: A, ) : FunctionalExpressionField(algebra), ExtendedField> { + public override fun number(value: Number): Expression = const(algebra.number(value)) - override fun number(value: Number): Expression = const(algebra.number(value)) + public override fun sqrt(arg: Expression): Expression = + unaryOperationFunction(PowerOperations.SQRT_OPERATION)(arg) public override fun sin(arg: Expression): Expression = unaryOperationFunction(TrigonometricOperations.SIN_OPERATION)(arg) @@ -162,9 +169,11 @@ public open class FunctionalExpressionExtendedField>( public override fun binaryOperationFunction(operation: String): (left: Expression, right: Expression) -> Expression = super.binaryOperationFunction(operation) + + public override fun bindSymbol(value: String): Expression = super.bindSymbol(value) } -public inline fun > A.expressionInSpace(block: FunctionalExpressionGroup.() -> Expression): Expression = +public inline fun > A.expressionInSpace(block: FunctionalExpressionGroup.() -> Expression): Expression = FunctionalExpressionGroup(this).block() public inline fun > A.expressionInRing(block: FunctionalExpressionRing.() -> Expression): Expression = diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/MST.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MST.kt similarity index 62% rename from kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/MST.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MST.kt index 468b919c1..67881d9af 100644 --- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/MST.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MST.kt @@ -3,8 +3,10 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ -package space.kscience.kmath.ast +package space.kscience.kmath.expressions +import space.kscience.kmath.misc.StringSymbol +import space.kscience.kmath.misc.Symbol import space.kscience.kmath.operations.Algebra import space.kscience.kmath.operations.NumericAlgebra @@ -81,11 +83,47 @@ public fun Algebra.evaluate(node: MST): T = when (node) { } } +internal class InnerAlgebra(val algebra: Algebra, val arguments: Map) : NumericAlgebra { + override fun bindSymbolOrNull(value: String): T? = algebra.bindSymbolOrNull(value) ?: arguments[StringSymbol(value)] + + override fun unaryOperation(operation: String, arg: T): T = + algebra.unaryOperation(operation, arg) + + override fun binaryOperation(operation: String, left: T, right: T): T = + algebra.binaryOperation(operation, left, right) + + override fun unaryOperationFunction(operation: String): (arg: T) -> T = + algebra.unaryOperationFunction(operation) + + override fun binaryOperationFunction(operation: String): (left: T, right: T) -> T = + algebra.binaryOperationFunction(operation) + + @Suppress("UNCHECKED_CAST") + override fun number(value: Number): T = if (algebra is NumericAlgebra<*>) + (algebra as NumericAlgebra).number(value) + else + error("Numeric nodes are not supported by $this") +} + /** - * Interprets the [MST] node with this [Algebra]. + * Interprets the [MST] node with this [Algebra] and optional [arguments] + */ +public fun MST.interpret(algebra: Algebra, arguments: Map): T = + InnerAlgebra(algebra, arguments).evaluate(this) + +/** + * Interprets the [MST] node with this [Algebra] and optional [arguments] * * @receiver the node to evaluate. * @param algebra the algebra that provides operations. * @return the value of expression. */ -public fun MST.interpret(algebra: Algebra): T = algebra.evaluate(this) +public fun MST.interpret(algebra: Algebra, vararg arguments: Pair): T = + interpret(algebra, mapOf(*arguments)) + +/** + * Interpret this [MST] as expression. + */ +public fun MST.toExpression(algebra: Algebra): Expression = Expression { arguments -> + interpret(algebra, arguments) +} diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/MstAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MstAlgebra.kt similarity index 87% rename from kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/MstAlgebra.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MstAlgebra.kt index 519a93dc6..32a7efc1e 100644 --- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/MstAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MstAlgebra.kt @@ -3,7 +3,7 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ -package space.kscience.kmath.ast +package space.kscience.kmath.expressions import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.operations.* @@ -13,7 +13,8 @@ import space.kscience.kmath.operations.* */ public object MstAlgebra : NumericAlgebra { public override fun number(value: Number): MST.Numeric = MST.Numeric(value) - public override fun bindSymbol(value: String): MST.Symbolic = MST.Symbolic(value) + public override fun bindSymbolOrNull(value: String): MST.Symbolic = MST.Symbolic(value) + override fun bindSymbol(value: String): MST.Symbolic = bindSymbolOrNull(value) public override fun unaryOperationFunction(operation: String): (arg: MST) -> MST.Unary = { arg -> MST.Unary(operation, arg) } @@ -29,7 +30,7 @@ public object MstGroup : Group, NumericAlgebra, ScaleOperations { public override val zero: MST.Numeric = number(0.0) public override fun number(value: Number): MST.Numeric = MstAlgebra.number(value) - public override fun bindSymbol(value: String): MST.Symbolic = MstAlgebra.bindSymbol(value) + public override fun bindSymbolOrNull(value: String): MST.Symbolic = MstAlgebra.bindSymbolOrNull(value) public override fun add(a: MST, b: MST): MST.Binary = binaryOperationFunction(GroupOperations.PLUS_OPERATION)(a, b) public override operator fun MST.unaryPlus(): MST.Unary = unaryOperationFunction(GroupOperations.PLUS_OPERATION)(this) @@ -53,13 +54,14 @@ public object MstGroup : Group, NumericAlgebra, ScaleOperations { /** * [Ring] over [MST] nodes. */ +@Suppress("OVERRIDE_BY_INLINE") @OptIn(UnstableKMathAPI::class) public object MstRing : Ring, NumbersAddOperations, ScaleOperations { - public override val zero: MST.Numeric get() = MstGroup.zero + public override inline 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 = MstAlgebra.bindSymbol(value) + public override fun bindSymbolOrNull(value: String): MST.Symbolic = MstAlgebra.bindSymbolOrNull(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 = @@ -82,13 +84,13 @@ public object MstRing : Ring, NumbersAddOperations, ScaleOperations, NumbersAddOperations, ScaleOperations { - public override val zero: MST.Numeric get() = MstRing.zero + public override inline val zero: MST.Numeric get() = MstRing.zero + public override inline val one: MST.Numeric get() = MstRing.one - public override val one: MST.Numeric get() = MstRing.one - - public override fun bindSymbol(value: String): MST.Symbolic = MstAlgebra.bindSymbol(value) + public override fun bindSymbolOrNull(value: String): MST.Symbolic = MstAlgebra.bindSymbolOrNull(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) @@ -113,11 +115,12 @@ public object MstField : Field, NumbersAddOperations, ScaleOperations< /** * [ExtendedField] over [MST] nodes. */ +@Suppress("OVERRIDE_BY_INLINE") 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 inline val zero: MST.Numeric get() = MstField.zero + public override inline val one: MST.Numeric get() = MstField.one - public override fun bindSymbol(value: String): MST.Symbolic = MstAlgebra.bindSymbol(value) + public override fun bindSymbolOrNull(value: String): MST.Symbolic = MstAlgebra.bindSymbolOrNull(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-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt index 0774d7211..09a5faa12 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt @@ -6,6 +6,7 @@ package space.kscience.kmath.expressions import space.kscience.kmath.linear.Point +import space.kscience.kmath.misc.Symbol import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.operations.* import space.kscience.kmath.structures.asBuffer @@ -89,7 +90,7 @@ public open class SimpleAutoDiffField>( override fun hashCode(): Int = identity.hashCode() } - public override fun bindSymbolOrNull(symbol: Symbol): AutoDiffValue? = bindings[symbol.identity] + override fun bindSymbolOrNull(value: String): AutoDiffValue? = bindings[value] private fun getDerivative(variable: AutoDiffValue): T = (variable as? AutoDiffVariableWithDerivative)?.d ?: derivatives[variable] ?: context.zero @@ -203,7 +204,7 @@ public open class SimpleAutoDiffField>( * Example: * ``` * val x by symbol // define variable(s) and their values - * val y = RealField.withAutoDiff() { sqr(x) + 5 * x + 3 } // write formulate in deriv context + * val y = DoubleField.withAutoDiff() { sqr(x) + 5 * x + 3 } // write formulate in deriv context * assertEquals(17.0, y.x) // the value of result (y) * assertEquals(9.0, x.d) // dy/dx * ``` @@ -341,9 +342,11 @@ public class SimpleAutoDiffExtendedField>( ) : ExtendedField>, ScaleOperations>, SimpleAutoDiffField(context, bindings) { - override fun number(value: Number): AutoDiffValue = const { number(value) } + override fun bindSymbol(value: String): AutoDiffValue = super.bindSymbol(value) - override fun scale(a: AutoDiffValue, value: Double): AutoDiffValue = a * number(value) + public override fun number(value: Number): AutoDiffValue = const { number(value) } + + public override fun scale(a: AutoDiffValue, value: Double): AutoDiffValue = a * number(value) // x ^ 2 public fun sqr(x: AutoDiffValue): AutoDiffValue = diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SymbolIndexer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SymbolIndexer.kt index 7bb74d125..886008983 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SymbolIndexer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SymbolIndexer.kt @@ -6,13 +6,17 @@ package space.kscience.kmath.expressions import space.kscience.kmath.linear.Point +import space.kscience.kmath.misc.Symbol +import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.nd.Structure2D import space.kscience.kmath.structures.BufferFactory +import kotlin.jvm.JvmInline /** * An environment to easy transform indexed variables to symbols and back. * TODO requires multi-receivers to be beautiful */ +@UnstableKMathAPI public interface SymbolIndexer { public val symbols: List public fun indexOf(symbol: Symbol): Int = symbols.indexOf(symbol) @@ -54,13 +58,17 @@ public interface SymbolIndexer { public fun Map.toDoubleArray(): DoubleArray = DoubleArray(symbols.size) { getValue(symbols[it]) } } -public inline class SimpleSymbolIndexer(override val symbols: List) : SymbolIndexer +@UnstableKMathAPI +@JvmInline +public value class SimpleSymbolIndexer(override val symbols: List) : SymbolIndexer /** * Execute the block with symbol indexer based on given symbol order */ +@UnstableKMathAPI public inline fun withSymbols(vararg symbols: Symbol, block: SymbolIndexer.() -> R): R = with(SimpleSymbolIndexer(symbols.toList()), block) +@UnstableKMathAPI public inline fun withSymbols(symbols: Collection, block: SymbolIndexer.() -> R): R = with(SimpleSymbolIndexer(symbols.toList()), block) \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/expressionBuilders.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/expressionBuilders.kt index 37a75abc1..142194070 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/expressionBuilders.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/expressionBuilders.kt @@ -7,16 +7,15 @@ package space.kscience.kmath.expressions import space.kscience.kmath.operations.ExtendedField import space.kscience.kmath.operations.Field -import space.kscience.kmath.operations.Group import space.kscience.kmath.operations.Ring import kotlin.contracts.InvocationKind import kotlin.contracts.contract /** - * Creates a functional expression with this [Group]. + * Creates a functional expression with this [Ring]. */ -public inline fun Group.spaceExpression(block: FunctionalExpressionGroup>.() -> Expression): Expression { +public inline fun Ring.spaceExpression(block: FunctionalExpressionGroup>.() -> Expression): Expression { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return FunctionalExpressionGroup(this).block() } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt index 7a8cf9744..62d2408e3 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt @@ -22,7 +22,7 @@ public class BufferedLinearSpace>( private fun ndRing( rows: Int, cols: Int, - ): BufferedNDRing = NDAlgebra.ring(elementAlgebra, bufferFactory, rows, cols) + ): BufferedRingND = AlgebraND.ring(elementAlgebra, bufferFactory, rows, cols) override fun buildMatrix(rows: Int, columns: Int, initializer: A.(i: Int, j: Int) -> T): Matrix = ndRing(rows, columns).produce { (i, j) -> elementAlgebra.initializer(i, j) }.as2D() diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSolver.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSolver.kt index 0b24d212d..9c3ffd819 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSolver.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSolver.kt @@ -8,7 +8,10 @@ package space.kscience.kmath.linear import space.kscience.kmath.nd.as1D /** - * A group of methods to resolve equation A dot X = B, where A and B are matrices or vectors + * A group of methods to solve for *X* in equation *X = A -1 · B*, where *A* and *B* are matrices or + * vectors. + * + * @param T the type of items. */ public interface LinearSolver { /** @@ -28,7 +31,7 @@ public interface LinearSolver { } /** - * Convert matrix to vector if it is possible + * Convert matrix to vector if it is possible. */ public fun Matrix.asVector(): Point = if (this.colNum == 1) @@ -36,4 +39,11 @@ public fun Matrix.asVector(): Point = else error("Can't convert matrix with more than one column to vector") +/** + * Creates an n × 1 [VirtualMatrix], where n is the size of the given buffer. + * + * @param T the type of elements contained in the buffer. + * @receiver a buffer. + * @return the new matrix. + */ public fun Point.asMatrix(): VirtualMatrix = VirtualMatrix(size, 1) { i, _ -> get(i) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt index 094656aa6..0798e8763 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt @@ -10,7 +10,7 @@ import space.kscience.kmath.nd.* import space.kscience.kmath.operations.* import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.BufferFactory -import space.kscience.kmath.structures.RealBuffer +import space.kscience.kmath.structures.DoubleBuffer import kotlin.reflect.KClass /** @@ -22,6 +22,8 @@ public typealias Matrix = Structure2D /** * Alias or using [Buffer] as a point/vector in a many-dimensional space. + * + * @param T the type of elements contained in the buffer. */ public typealias Point = Buffer @@ -169,7 +171,7 @@ public interface LinearSpace> { * @return a feature object or `null` if it isn't present. */ @UnstableKMathAPI - public fun getFeature(structure: Matrix, type: KClass): F? = structure.getFeature(type) + public fun getFeature(structure: Matrix, type: KClass): F? = structure.getFeature(type) public companion object { @@ -181,7 +183,7 @@ public interface LinearSpace> { bufferFactory: BufferFactory = Buffer.Companion::boxing, ): LinearSpace = BufferedLinearSpace(algebra, bufferFactory) - public val real: LinearSpace = buffered(RealField, ::RealBuffer) + public val real: LinearSpace = buffered(DoubleField, ::DoubleBuffer) /** * Automatic buffered matrix, unboxed if it is possible @@ -199,7 +201,7 @@ public interface LinearSpace> { * @return a feature object or `null` if it isn't present. */ @UnstableKMathAPI -public inline fun LinearSpace.getFeature(structure: Matrix): F? = +public inline fun LinearSpace.getFeature(structure: Matrix): F? = getFeature(structure, F::class) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt index e1b16e64e..f3653d394 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt @@ -9,9 +9,9 @@ import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.nd.getFeature import space.kscience.kmath.operations.* import space.kscience.kmath.structures.BufferAccessor2D +import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.MutableBuffer import space.kscience.kmath.structures.MutableBufferFactory -import space.kscience.kmath.structures.RealBuffer /** * Common implementation of [LupDecompositionFeature]. @@ -156,8 +156,8 @@ public inline fun > LinearSpace>.lup( noinline checkSingular: (T) -> Boolean, ): LupDecomposition = lup(MutableBuffer.Companion::auto, matrix, checkSingular) -public fun LinearSpace.lup(matrix: Matrix): LupDecomposition = - lup(::RealBuffer, matrix) { it < 1e-11 } +public fun LinearSpace.lup(matrix: Matrix): LupDecomposition = + lup(::DoubleBuffer, matrix) { it < 1e-11 } public fun LupDecomposition.solveWithLup( factory: MutableBufferFactory, @@ -233,9 +233,9 @@ public inline fun > LinearSpace>.inverseWi @OptIn(UnstableKMathAPI::class) -public fun LinearSpace.solveWithLup(a: Matrix, b: Matrix): Matrix { +public fun LinearSpace.solveWithLup(a: Matrix, b: Matrix): Matrix { // Use existing decomposition if it is provided by matrix - val bufferFactory: MutableBufferFactory = ::RealBuffer + val bufferFactory: MutableBufferFactory = ::DoubleBuffer val decomposition: LupDecomposition = a.getFeature() ?: lup(bufferFactory, a) { it < 1e-11 } return decomposition.solveWithLup(bufferFactory, b) } @@ -243,5 +243,5 @@ public fun LinearSpace.solveWithLup(a: Matrix, b: Mat /** * Inverses a square matrix using LUP decomposition. Non square matrix will throw a error. */ -public fun LinearSpace.inverseWithLup(matrix: Matrix): Matrix = +public fun LinearSpace.inverseWithLup(matrix: Matrix): Matrix = solveWithLup(matrix, one(matrix.rowNum, matrix.colNum)) \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt index 21f0b969d..4a0ca7dfe 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt @@ -5,11 +5,13 @@ package space.kscience.kmath.linear +import space.kscience.kmath.nd.StructureFeature + /** * A marker interface representing some properties of matrices or additional transformations of them. Features are used * to optimize matrix operations performance in some cases or retrieve the APIs. */ -public interface MatrixFeature +public interface MatrixFeature: StructureFeature /** * Matrices with this feature are considered to have only diagonal non-null elements. diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt index ec90c1e39..4d1180c17 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt @@ -6,6 +6,7 @@ package space.kscience.kmath.linear import space.kscience.kmath.misc.UnstableKMathAPI +import space.kscience.kmath.nd.StructureFeature import space.kscience.kmath.nd.getFeature import space.kscience.kmath.operations.Ring import kotlin.reflect.KClass @@ -25,11 +26,9 @@ public class MatrixWrapper internal constructor( */ @UnstableKMathAPI @Suppress("UNCHECKED_CAST") - override fun getFeature(type: KClass): T? = features.singleOrNull { type.isInstance(it) } as? T + override fun getFeature(type: KClass): F? = features.singleOrNull { type.isInstance(it) } as? F ?: origin.getFeature(type) - override fun equals(other: Any?): Boolean = origin == other - override fun hashCode(): Int = origin.hashCode() override fun toString(): String { return "MatrixWrapper(matrix=$origin, features=$features)" } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt index bd9d82fe7..e4c2b49f0 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt @@ -5,8 +5,6 @@ package space.kscience.kmath.linear -import space.kscience.kmath.nd.NDStructure - /** * The matrix where each element is evaluated each time when is being accessed. * @@ -21,17 +19,4 @@ public class VirtualMatrix( override val shape: IntArray get() = intArrayOf(rowNum, colNum) override operator fun get(i: Int, j: Int): T = generator(i, j) - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is NDStructure<*>) return false - return NDStructure.contentEquals(this, other) - } - - override fun hashCode(): Int { - var result = rowNum - result = 31 * result + colNum - result = 31 * result + generator.hashCode() - return result - } } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/Symbol.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/Symbol.kt new file mode 100644 index 000000000..737acc025 --- /dev/null +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/Symbol.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.misc + +import kotlin.jvm.JvmInline +import kotlin.properties.ReadOnlyProperty + +/** + * A marker interface for a symbol. A symbol mus have an identity + */ +public interface Symbol { + /** + * Identity object for the symbol. Two symbols with the same identity are considered to be the same symbol. + */ + public val identity: String + + public companion object{ + public val x: StringSymbol = StringSymbol("x") + public val y: StringSymbol = StringSymbol("y") + public val z: StringSymbol = StringSymbol("z") + } +} + +/** + * A [Symbol] with a [String] identity + */ +@JvmInline +public value class StringSymbol(override val identity: String) : Symbol { + override fun toString(): String = identity +} + + +/** + * A delegate to create a symbol with a string identity in this scope + */ +public val symbol: ReadOnlyProperty = ReadOnlyProperty { _, property -> + StringSymbol(property.name) +} diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/cumulative.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/cumulative.kt index a4a37e717..889eb4f22 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/cumulative.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/cumulative.kt @@ -5,7 +5,7 @@ package space.kscience.kmath.misc -import space.kscience.kmath.operations.Group +import space.kscience.kmath.operations.Ring import space.kscience.kmath.operations.invoke import kotlin.jvm.JvmName @@ -42,8 +42,8 @@ public fun List.cumulative(initial: R, operation: (R, T) -> R): List Iterable.cumulativeSum(space: Group): Iterable = - space { cumulative(zero) { element: T, sum: T -> sum + element } } +public fun Iterable.cumulativeSum(group: Ring): Iterable = + group { cumulative(zero) { element: T, sum: T -> sum + element } } @JvmName("cumulativeSumOfDouble") public fun Iterable.cumulativeSum(): Iterable = cumulative(0.0) { element, sum -> sum + element } @@ -54,8 +54,8 @@ public fun Iterable.cumulativeSum(): Iterable = cumulative(0) { elemen @JvmName("cumulativeSumOfLong") public fun Iterable.cumulativeSum(): Iterable = cumulative(0L) { element, sum -> sum + element } -public fun Sequence.cumulativeSum(space: Group): Sequence = - space { cumulative(zero) { element: T, sum: T -> sum + element } } +public fun Sequence.cumulativeSum(group: Ring): Sequence = + group { cumulative(zero) { element: T, sum: T -> sum + element } } @JvmName("cumulativeSumOfDouble") public fun Sequence.cumulativeSum(): Sequence = cumulative(0.0) { element, sum -> sum + element } @@ -66,8 +66,8 @@ public fun Sequence.cumulativeSum(): Sequence = cumulative(0) { elemen @JvmName("cumulativeSumOfLong") public fun Sequence.cumulativeSum(): Sequence = cumulative(0L) { element, sum -> sum + element } -public fun List.cumulativeSum(space: Group): List = - space { cumulative(zero) { element: T, sum: T -> sum + element } } +public fun List.cumulativeSum(group: Ring): List = + group { cumulative(zero) { element: T, sum: T -> sum + element } } @JvmName("cumulativeSumOfDouble") public fun List.cumulativeSum(): List = cumulative(0.0) { element, sum -> sum + element } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/NDAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt similarity index 73% rename from kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/NDAlgebra.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt index 5730377e6..1b3cb9e0a 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/NDAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt @@ -26,7 +26,7 @@ public class ShapeMismatchException(public val expected: IntArray, public val ac * @param C the type of the element context. * @param N the type of the structure. */ -public interface NDAlgebra> { +public interface AlgebraND> { /** * The shape of ND-structures this algebra operates on. */ @@ -40,27 +40,27 @@ public interface NDAlgebra> { /** * Produces a new NDStructure using given initializer function. */ - public fun produce(initializer: C.(IntArray) -> T): NDStructure + public fun produce(initializer: C.(IntArray) -> T): StructureND /** * Maps elements from one structure to another one by applying [transform] to them. */ - public fun NDStructure.map(transform: C.(T) -> T): NDStructure + public fun StructureND.map(transform: C.(T) -> T): StructureND /** * Maps elements from one structure to another one by applying [transform] to them alongside with their indices. */ - public fun NDStructure.mapIndexed(transform: C.(index: IntArray, T) -> T): NDStructure + public fun StructureND.mapIndexed(transform: C.(index: IntArray, T) -> T): StructureND /** * Combines two structures into one. */ - public fun combine(a: NDStructure, b: NDStructure, transform: C.(T, T) -> T): NDStructure + public fun combine(a: StructureND, b: StructureND, transform: C.(T, T) -> T): StructureND /** - * Element-wise invocation of function working on [T] on a [NDStructure]. + * Element-wise invocation of function working on [T] on a [StructureND]. */ - public operator fun Function1.invoke(structure: NDStructure): NDStructure = + public operator fun Function1.invoke(structure: StructureND): StructureND = structure.map { value -> this@invoke(value) } /** @@ -72,7 +72,8 @@ public interface NDAlgebra> { * @return a feature object or `null` if it isn't present. */ @UnstableKMathAPI - public fun getFeature(structure: NDStructure, type: KClass): F? = structure.getFeature(type) + public fun getFeature(structure: StructureND, type: KClass): F? = + structure.getFeature(type) public companion object } @@ -86,7 +87,7 @@ public interface NDAlgebra> { * @return a feature object or `null` if it isn't present. */ @UnstableKMathAPI -public inline fun NDAlgebra.getFeature(structure: NDStructure): F? = +public inline fun AlgebraND.getFeature(structure: StructureND): F? = getFeature(structure, F::class) /** @@ -95,11 +96,11 @@ public inline fun NDAlgebra.getFeature(structur * @param structures the structures to check. * @return the array of valid structures. */ -internal fun > NDAlgebra.checkShape(vararg structures: NDStructure): Array> = +internal fun > AlgebraND.checkShape(vararg structures: StructureND): Array> = structures - .map(NDStructure::shape) + .map(StructureND::shape) .singleOrNull { !shape.contentEquals(it) } - ?.let>> { throw ShapeMismatchException(shape, it) } + ?.let>> { throw ShapeMismatchException(shape, it) } ?: structures /** @@ -108,27 +109,27 @@ internal fun > NDAlgebra.checkShape(vararg structures: N * @param element the structure to check. * @return the valid structure. */ -internal fun > NDAlgebra.checkShape(element: NDStructure): NDStructure { +internal fun > AlgebraND.checkShape(element: StructureND): StructureND { if (!element.shape.contentEquals(shape)) throw ShapeMismatchException(shape, element.shape) return element } /** - * Space of [NDStructure]. + * Space of [StructureND]. * * @param T the type of the element contained in ND structure. * @param N the type of ND structure. * @param S the type of space of structure elements. */ -public interface NDGroup> : Group>, NDAlgebra { +public interface GroupND> : Group>, AlgebraND { /** * Element-wise addition. * - * @param a the addend. - * @param b the augend. + * @param a the augend. + * @param b the addend. * @return the sum. */ - public override fun add(a: NDStructure, b: NDStructure): NDStructure = + public override fun add(a: StructureND, b: StructureND): StructureND = combine(a, b) { aValue, bValue -> add(aValue, bValue) } // /** @@ -145,11 +146,11 @@ public interface NDGroup> : Group>, NDAlgebra.plus(arg: T): NDStructure = this.map { value -> add(arg, value) } + public operator fun StructureND.plus(arg: T): StructureND = this.map { value -> add(arg, value) } /** * Subtracts an element from ND structure of it. @@ -158,16 +159,16 @@ public interface NDGroup> : Group>, NDAlgebra.minus(arg: T): NDStructure = this.map { value -> add(arg, -value) } + public operator fun StructureND.minus(arg: T): StructureND = this.map { value -> add(arg, -value) } /** * Adds an element to ND structure of it. * - * @receiver the addend. - * @param arg the augend. + * @receiver the augend. + * @param arg the addend. * @return the sum. */ - public operator fun T.plus(arg: NDStructure): NDStructure = arg.map { value -> add(this@plus, value) } + public operator fun T.plus(arg: StructureND): StructureND = arg.map { value -> add(this@plus, value) } /** * Subtracts an ND structure from an element of it. @@ -176,19 +177,19 @@ public interface NDGroup> : Group>, NDAlgebra): NDStructure = arg.map { value -> add(-this@minus, value) } + public operator fun T.minus(arg: StructureND): StructureND = arg.map { value -> add(-this@minus, value) } public companion object } /** - * Ring of [NDStructure]. + * Ring of [StructureND]. * * @param T the type of the element contained in ND structure. * @param N the type of ND structure. * @param R the type of ring of structure elements. */ -public interface NDRing> : Ring>, NDGroup { +public interface RingND> : Ring>, GroupND { /** * Element-wise multiplication. * @@ -196,7 +197,7 @@ public interface NDRing> : Ring>, NDGroup { * @param b the multiplier. * @return the product. */ - public override fun multiply(a: NDStructure, b: NDStructure): NDStructure = + public override fun multiply(a: StructureND, b: StructureND): StructureND = combine(a, b) { aValue, bValue -> multiply(aValue, bValue) } //TODO move to extensions after KEEP-176 @@ -208,7 +209,7 @@ public interface NDRing> : Ring>, NDGroup { * @param arg the multiplier. * @return the product. */ - public operator fun NDStructure.times(arg: T): NDStructure = this.map { value -> multiply(arg, value) } + public operator fun StructureND.times(arg: T): StructureND = this.map { value -> multiply(arg, value) } /** * Multiplies an element by a ND structure of it. @@ -217,19 +218,19 @@ public interface NDRing> : Ring>, NDGroup { * @param arg the multiplier. * @return the product. */ - public operator fun T.times(arg: NDStructure): NDStructure = arg.map { value -> multiply(this@times, value) } + public operator fun T.times(arg: StructureND): StructureND = arg.map { value -> multiply(this@times, value) } public companion object } /** - * Field of [NDStructure]. + * Field of [StructureND]. * * @param T the type of the element contained in ND structure. * @param N the type of ND structure. * @param F the type field of structure elements. */ -public interface NDField> : Field>, NDRing, ScaleOperations> { +public interface FieldND> : Field>, RingND, ScaleOperations> { /** * Element-wise division. * @@ -237,7 +238,7 @@ public interface NDField> : Field>, NDRing, * @param b the divisor. * @return the quotient. */ - public override fun divide(a: NDStructure, b: NDStructure): NDStructure = + public override fun divide(a: StructureND, b: StructureND): StructureND = combine(a, b) { aValue, bValue -> divide(aValue, bValue) } //TODO move to extensions after KEEP-176 @@ -248,7 +249,7 @@ public interface NDField> : Field>, NDRing, * @param arg the divisor. * @return the quotient. */ - public operator fun NDStructure.div(arg: T): NDStructure = this.map { value -> divide(arg, value) } + public operator fun StructureND.div(arg: T): StructureND = this.map { value -> divide(arg, value) } /** * Divides an element by an ND structure of it. @@ -257,7 +258,7 @@ public interface NDField> : Field>, NDRing, * @param arg the divisor. * @return the quotient. */ - public operator fun T.div(arg: NDStructure): NDStructure = arg.map { divide(it, this@div) } + public operator fun T.div(arg: StructureND): StructureND = arg.map { divide(it, this@div) } // @ThreadLocal // public companion object { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferNDAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt similarity index 52% rename from kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferNDAlgebra.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt index e1545c4d0..905a48d5c 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferNDAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt @@ -11,132 +11,132 @@ import space.kscience.kmath.structures.BufferFactory import kotlin.contracts.InvocationKind import kotlin.contracts.contract -public interface BufferNDAlgebra> : NDAlgebra { +public interface BufferAlgebraND> : AlgebraND { public val strides: Strides public val bufferFactory: BufferFactory - override fun produce(initializer: A.(IntArray) -> T): NDBuffer = NDBuffer( + override fun produce(initializer: A.(IntArray) -> T): BufferND = BufferND( strides, bufferFactory(strides.linearSize) { offset -> elementContext.initializer(strides.index(offset)) } ) - public val NDStructure.buffer: Buffer + public val StructureND.buffer: Buffer get() = when { - !shape.contentEquals(this@BufferNDAlgebra.shape) -> throw ShapeMismatchException( - this@BufferNDAlgebra.shape, + !shape.contentEquals(this@BufferAlgebraND.shape) -> throw ShapeMismatchException( + this@BufferAlgebraND.shape, shape ) - this is NDBuffer && this.strides == this@BufferNDAlgebra.strides -> this.buffer + this is BufferND && this.strides == this@BufferAlgebraND.strides -> this.buffer else -> bufferFactory(strides.linearSize) { offset -> get(strides.index(offset)) } } - override fun NDStructure.map(transform: A.(T) -> T): NDBuffer { + override fun StructureND.map(transform: A.(T) -> T): BufferND { val buffer = bufferFactory(strides.linearSize) { offset -> elementContext.transform(buffer[offset]) } - return NDBuffer(strides, buffer) + return BufferND(strides, buffer) } - override fun NDStructure.mapIndexed(transform: A.(index: IntArray, T) -> T): NDBuffer { + override fun StructureND.mapIndexed(transform: A.(index: IntArray, T) -> T): BufferND { val buffer = bufferFactory(strides.linearSize) { offset -> elementContext.transform( strides.index(offset), buffer[offset] ) } - return NDBuffer(strides, buffer) + return BufferND(strides, buffer) } - override fun combine(a: NDStructure, b: NDStructure, transform: A.(T, T) -> T): NDBuffer { + override fun combine(a: StructureND, b: StructureND, transform: A.(T, T) -> T): BufferND { val buffer = bufferFactory(strides.linearSize) { offset -> elementContext.transform(a.buffer[offset], b.buffer[offset]) } - return NDBuffer(strides, buffer) + return BufferND(strides, buffer) } } -public open class BufferedNDGroup>( +public open class BufferedGroupND>( final override val shape: IntArray, final override val elementContext: A, final override val bufferFactory: BufferFactory, -) : NDGroup, BufferNDAlgebra { +) : GroupND, BufferAlgebraND { override val strides: Strides = DefaultStrides(shape) - override val zero: NDBuffer by lazy { produce { zero } } - override fun NDStructure.unaryMinus(): NDStructure = produce { -get(it) } + override val zero: BufferND by lazy { produce { zero } } + override fun StructureND.unaryMinus(): StructureND = produce { -get(it) } } -public open class BufferedNDRing>( +public open class BufferedRingND>( shape: IntArray, elementContext: R, bufferFactory: BufferFactory, -) : BufferedNDGroup(shape, elementContext, bufferFactory), NDRing { - override val one: NDBuffer by lazy { produce { one } } +) : BufferedGroupND(shape, elementContext, bufferFactory), RingND { + override val one: BufferND by lazy { produce { one } } } -public open class BufferedNDField>( +public open class BufferedFieldND>( shape: IntArray, elementContext: R, bufferFactory: BufferFactory, -) : BufferedNDRing(shape, elementContext, bufferFactory), NDField { +) : BufferedRingND(shape, elementContext, bufferFactory), FieldND { - override fun scale(a: NDStructure, value: Double): NDStructure = a.map { it * value } + override fun scale(a: StructureND, value: Double): StructureND = a.map { it * value } } // group factories -public fun > NDAlgebra.Companion.group( +public fun > AlgebraND.Companion.group( space: A, bufferFactory: BufferFactory, vararg shape: Int, -): BufferedNDGroup = BufferedNDGroup(shape, space, bufferFactory) +): BufferedGroupND = BufferedGroupND(shape, space, bufferFactory) -public inline fun , R> A.ndGroup( +public inline fun , R> A.ndGroup( noinline bufferFactory: BufferFactory, vararg shape: Int, - action: BufferedNDGroup.() -> R, + action: BufferedGroupND.() -> R, ): R { contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } - return NDAlgebra.group(this, bufferFactory, *shape).run(action) + return AlgebraND.group(this, bufferFactory, *shape).run(action) } //ring factories -public fun > NDAlgebra.Companion.ring( +public fun > AlgebraND.Companion.ring( ring: A, bufferFactory: BufferFactory, vararg shape: Int, -): BufferedNDRing = BufferedNDRing(shape, ring, bufferFactory) +): BufferedRingND = BufferedRingND(shape, ring, bufferFactory) public inline fun , R> A.ndRing( noinline bufferFactory: BufferFactory, vararg shape: Int, - action: BufferedNDRing.() -> R, + action: BufferedRingND.() -> R, ): R { contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } - return NDAlgebra.ring(this, bufferFactory, *shape).run(action) + return AlgebraND.ring(this, bufferFactory, *shape).run(action) } //field factories -public fun > NDAlgebra.Companion.field( +public fun > AlgebraND.Companion.field( field: A, bufferFactory: BufferFactory, vararg shape: Int, -): BufferedNDField = BufferedNDField(shape, field, bufferFactory) +): BufferedFieldND = BufferedFieldND(shape, field, bufferFactory) @Suppress("UNCHECKED_CAST") -public inline fun > NDAlgebra.Companion.auto( +public inline fun > AlgebraND.Companion.auto( field: A, vararg shape: Int, -): NDField = when (field) { - RealField -> RealNDField(shape) as NDField - else -> BufferedNDField(shape, field, Buffer.Companion::auto) +): FieldND = when (field) { + DoubleField -> DoubleFieldND(shape) as FieldND + else -> BufferedFieldND(shape, field, Buffer.Companion::auto) } public inline fun , R> A.ndField( noinline bufferFactory: BufferFactory, vararg shape: Int, - action: BufferedNDField.() -> R, + action: BufferedFieldND.() -> R, ): R { contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } - return NDAlgebra.field(this, bufferFactory, *shape).run(action) + return AlgebraND.field(this, bufferFactory, *shape).run(action) } \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt new file mode 100644 index 000000000..23d961a7e --- /dev/null +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.nd + +import space.kscience.kmath.structures.Buffer +import space.kscience.kmath.structures.BufferFactory + +/** + * Represents [StructureND] over [Buffer]. + * + * @param T the type of items. + * @param strides The strides to access elements of [Buffer] by linear indices. + * @param buffer The underlying buffer. + */ +public class BufferND( + public val strides: Strides, + public val buffer: Buffer, +) : StructureND { + + init { + if (strides.linearSize != buffer.size) { + error("Expected buffer side of ${strides.linearSize}, but found ${buffer.size}") + } + } + + override operator fun get(index: IntArray): T = buffer[strides.offset(index)] + + override val shape: IntArray get() = strides.shape + + override fun elements(): Sequence> = strides.indices().map { + it to this[it] + } + + override fun toString(): String = StructureND.toString(this) +} + +/** + * Transform structure to a new structure using provided [BufferFactory] and optimizing if argument is [BufferND] + */ +public inline fun StructureND.mapToBuffer( + factory: BufferFactory = Buffer.Companion::auto, + crossinline transform: (T) -> R, +): BufferND { + return if (this is BufferND) + BufferND(this.strides, factory.invoke(strides.linearSize) { transform(buffer[it]) }) + else { + val strides = DefaultStrides(shape) + BufferND(strides, factory.invoke(strides.linearSize) { transform(get(strides.index(it))) }) + } +} \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/DoubleFieldND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/DoubleFieldND.kt new file mode 100644 index 000000000..71532594e --- /dev/null +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/DoubleFieldND.kt @@ -0,0 +1,114 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.nd + +import space.kscience.kmath.misc.UnstableKMathAPI +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.ExtendedField +import space.kscience.kmath.operations.NumbersAddOperations +import space.kscience.kmath.operations.ScaleOperations +import space.kscience.kmath.structures.DoubleBuffer +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract + +@OptIn(UnstableKMathAPI::class) +public class DoubleFieldND( + shape: IntArray, +) : BufferedFieldND(shape, DoubleField, ::DoubleBuffer), + NumbersAddOperations>, + ScaleOperations>, + ExtendedField> { + + public override val zero: BufferND by lazy { produce { zero } } + public override val one: BufferND by lazy { produce { one } } + + public override fun number(value: Number): BufferND { + val d = value.toDouble() // minimize conversions + return produce { d } + } + + public override val StructureND.buffer: DoubleBuffer + get() = when { + !shape.contentEquals(this@DoubleFieldND.shape) -> throw ShapeMismatchException( + this@DoubleFieldND.shape, + shape + ) + this is BufferND && this.strides == this@DoubleFieldND.strides -> this.buffer as DoubleBuffer + else -> DoubleBuffer(strides.linearSize) { offset -> get(strides.index(offset)) } + } + + @Suppress("OVERRIDE_BY_INLINE") + public override inline fun StructureND.map( + transform: DoubleField.(Double) -> Double, + ): BufferND { + val buffer = DoubleBuffer(strides.linearSize) { offset -> DoubleField.transform(buffer.array[offset]) } + return BufferND(strides, buffer) + } + + @Suppress("OVERRIDE_BY_INLINE") + public override inline fun produce(initializer: DoubleField.(IntArray) -> Double): BufferND { + val array = DoubleArray(strides.linearSize) { offset -> + val index = strides.index(offset) + DoubleField.initializer(index) + } + return BufferND(strides, DoubleBuffer(array)) + } + + @Suppress("OVERRIDE_BY_INLINE") + public override inline fun StructureND.mapIndexed( + transform: DoubleField.(index: IntArray, Double) -> Double, + ): BufferND = BufferND( + strides, + buffer = DoubleBuffer(strides.linearSize) { offset -> + DoubleField.transform( + strides.index(offset), + buffer.array[offset] + ) + }) + + @Suppress("OVERRIDE_BY_INLINE") + public override inline fun combine( + a: StructureND, + b: StructureND, + transform: DoubleField.(Double, Double) -> Double, + ): BufferND { + val buffer = DoubleBuffer(strides.linearSize) { offset -> + DoubleField.transform(a.buffer.array[offset], b.buffer.array[offset]) + } + return BufferND(strides, buffer) + } + + public override fun scale(a: StructureND, value: Double): StructureND = a.map { it * value } + + public override fun power(arg: StructureND, pow: Number): BufferND = arg.map { power(it, pow) } + + public override fun exp(arg: StructureND): BufferND = arg.map { exp(it) } + public override fun ln(arg: StructureND): BufferND = arg.map { ln(it) } + + public override fun sin(arg: StructureND): BufferND = arg.map { sin(it) } + public override fun cos(arg: StructureND): BufferND = arg.map { cos(it) } + public override fun tan(arg: StructureND): BufferND = arg.map { tan(it) } + public override fun asin(arg: StructureND): BufferND = arg.map { asin(it) } + public override fun acos(arg: StructureND): BufferND = arg.map { acos(it) } + public override fun atan(arg: StructureND): BufferND = arg.map { atan(it) } + + public override fun sinh(arg: StructureND): BufferND = arg.map { sinh(it) } + public override fun cosh(arg: StructureND): BufferND = arg.map { cosh(it) } + public override fun tanh(arg: StructureND): BufferND = arg.map { tanh(it) } + public override fun asinh(arg: StructureND): BufferND = arg.map { asinh(it) } + public override fun acosh(arg: StructureND): BufferND = arg.map { acosh(it) } + public override fun atanh(arg: StructureND): BufferND = arg.map { atanh(it) } +} + +public fun AlgebraND.Companion.real(vararg shape: Int): DoubleFieldND = DoubleFieldND(shape) + +/** + * Produce a context for n-dimensional operations inside this real field + */ +public inline fun DoubleField.nd(vararg shape: Int, action: DoubleFieldND.() -> R): R { + contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } + return DoubleFieldND(shape).run(action) +} diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/RealNDField.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/RealNDField.kt deleted file mode 100644 index 448abd571..000000000 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/RealNDField.kt +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2018-2021 KMath contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package space.kscience.kmath.nd - -import space.kscience.kmath.misc.UnstableKMathAPI -import space.kscience.kmath.operations.ExtendedField -import space.kscience.kmath.operations.NumbersAddOperations -import space.kscience.kmath.operations.RealField -import space.kscience.kmath.operations.ScaleOperations -import space.kscience.kmath.structures.RealBuffer -import kotlin.contracts.InvocationKind -import kotlin.contracts.contract - -@OptIn(UnstableKMathAPI::class) -public class RealNDField( - shape: IntArray, -) : BufferedNDField(shape, RealField, ::RealBuffer), - NumbersAddOperations>, - ScaleOperations>, - ExtendedField> { - - 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 } - } - - override val NDStructure.buffer: RealBuffer - get() = when { - !shape.contentEquals(this@RealNDField.shape) -> throw ShapeMismatchException( - this@RealNDField.shape, - shape - ) - this is NDBuffer && this.strides == this@RealNDField.strides -> this.buffer as RealBuffer - else -> RealBuffer(strides.linearSize) { offset -> get(strides.index(offset)) } - } - - @Suppress("OVERRIDE_BY_INLINE") - override inline fun NDStructure.map( - transform: RealField.(Double) -> Double, - ): NDBuffer { - val buffer = RealBuffer(strides.linearSize) { offset -> RealField.transform(buffer.array[offset]) } - return NDBuffer(strides, buffer) - } - - @Suppress("OVERRIDE_BY_INLINE") - override inline fun produce(initializer: RealField.(IntArray) -> Double): NDBuffer { - val array = DoubleArray(strides.linearSize) { offset -> - val index = strides.index(offset) - RealField.initializer(index) - } - return NDBuffer(strides, RealBuffer(array)) - } - - @Suppress("OVERRIDE_BY_INLINE") - override inline fun NDStructure.mapIndexed( - transform: RealField.(index: IntArray, Double) -> Double, - ): NDBuffer = NDBuffer( - strides, - buffer = RealBuffer(strides.linearSize) { offset -> - RealField.transform( - strides.index(offset), - buffer.array[offset] - ) - }) - - @Suppress("OVERRIDE_BY_INLINE") - override inline fun combine( - a: NDStructure, - b: NDStructure, - transform: RealField.(Double, Double) -> Double, - ): NDBuffer { - val buffer = RealBuffer(strides.linearSize) { offset -> - RealField.transform(a.buffer.array[offset], b.buffer.array[offset]) - } - return NDBuffer(strides, buffer) - } - - 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) } -} - -public fun NDAlgebra.Companion.real(vararg shape: Int): RealNDField = RealNDField(shape) - -/** - * Produce a context for n-dimensional operations inside this real field - */ -public inline fun RealField.nd(vararg shape: Int, action: RealNDField.() -> R): R { - contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } - return RealNDField(shape).run(action) -} diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShortNDRing.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShortRingND.kt similarity index 62% rename from kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShortNDRing.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShortRingND.kt index baf1c5732..720a06ace 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShortNDRing.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShortRingND.kt @@ -14,15 +14,15 @@ import kotlin.contracts.InvocationKind import kotlin.contracts.contract @OptIn(UnstableKMathAPI::class) -public class ShortNDRing( +public class ShortRingND( shape: IntArray, -) : BufferedNDRing(shape, ShortRing, Buffer.Companion::auto), - NumbersAddOperations> { +) : BufferedRingND(shape, ShortRing, Buffer.Companion::auto), + NumbersAddOperations> { - override val zero: NDBuffer by lazy { produce { zero } } - override val one: NDBuffer by lazy { produce { one } } + override val zero: BufferND by lazy { produce { zero } } + override val one: BufferND by lazy { produce { one } } - override fun number(value: Number): NDBuffer { + override fun number(value: Number): BufferND { val d = value.toShort() // minimize conversions return produce { d } } @@ -31,11 +31,11 @@ public class ShortNDRing( /** * Fast element production using function inlining. */ -public inline fun BufferedNDRing.produceInline(crossinline initializer: ShortRing.(Int) -> Short): NDBuffer { - return NDBuffer(strides, ShortBuffer(ShortArray(strides.linearSize) { offset -> ShortRing.initializer(offset) })) +public inline fun BufferedRingND.produceInline(crossinline initializer: ShortRing.(Int) -> Short): BufferND { + return BufferND(strides, ShortBuffer(ShortArray(strides.linearSize) { offset -> ShortRing.initializer(offset) })) } -public inline fun ShortRing.nd(vararg shape: Int, action: ShortNDRing.() -> R): R { +public inline fun ShortRing.nd(vararg shape: Int, action: ShortRingND.() -> R): R { contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } - return ShortNDRing(shape).run(action) + return ShortRingND(shape).run(action) } \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt index c607728ef..0f0588fda 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt @@ -7,11 +7,12 @@ package space.kscience.kmath.nd import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.asSequence +import kotlin.jvm.JvmInline /** * A structure that is guaranteed to be one-dimensional */ -public interface Structure1D : NDStructure, Buffer { +public interface Structure1D : StructureND, Buffer { public override val dimension: Int get() = 1 public override operator fun get(index: IntArray): T { @@ -20,12 +21,15 @@ public interface Structure1D : NDStructure, Buffer { } public override operator fun iterator(): Iterator = (0 until size).asSequence().map(::get).iterator() + + public companion object } /** * A 1D wrapper for nd-structure */ -private inline class Structure1DWrapper(val structure: NDStructure) : Structure1D { +@JvmInline +private value class Structure1DWrapper(val structure: StructureND) : Structure1D { override val shape: IntArray get() = structure.shape override val size: Int get() = structure.shape[0] @@ -37,7 +41,8 @@ private inline class Structure1DWrapper(val structure: NDStructure) : Stru /** * A structure wrapper for buffer */ -private inline class Buffer1DWrapper(val buffer: Buffer) : Structure1D { +@JvmInline +private value class Buffer1DWrapper(val buffer: Buffer) : Structure1D { override val shape: IntArray get() = intArrayOf(buffer.size) override val size: Int get() = buffer.size @@ -48,11 +53,11 @@ private inline class Buffer1DWrapper(val buffer: Buffer) : Structure1D } /** - * Represent a [NDStructure] as [Structure1D]. Throw error in case of dimension mismatch + * Represent a [StructureND] as [Structure1D]. Throw error in case of dimension mismatch */ -public fun NDStructure.as1D(): Structure1D = this as? Structure1D ?: if (shape.size == 1) { +public fun StructureND.as1D(): Structure1D = this as? Structure1D ?: if (shape.size == 1) { when (this) { - is NDBuffer -> Buffer1DWrapper(this.buffer) + is BufferND -> Buffer1DWrapper(this.buffer) else -> Structure1DWrapper(this) } } else error("Can't create 1d-structure from ${shape.size}d-structure") @@ -67,6 +72,6 @@ public fun Buffer.asND(): Structure1D = Buffer1DWrapper(this) */ internal fun Structure1D.unwrap(): Buffer = when { this is Buffer1DWrapper -> buffer - this is Structure1DWrapper && structure is NDBuffer -> structure.buffer + this is Structure1DWrapper && structure is BufferND -> structure.buffer else -> this } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt index dc568a513..3eee41832 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt @@ -8,6 +8,7 @@ package space.kscience.kmath.nd import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.VirtualBuffer +import kotlin.jvm.JvmInline import kotlin.reflect.KClass /** @@ -15,7 +16,7 @@ import kotlin.reflect.KClass * * @param T the type of items. */ -public interface Structure2D : NDStructure { +public interface Structure2D : StructureND { /** * The number of rows in this structure. */ @@ -65,7 +66,8 @@ public interface Structure2D : NDStructure { /** * A 2D wrapper for nd-structure */ -private class Structure2DWrapper(val structure: NDStructure) : Structure2D { +@JvmInline +private value class Structure2DWrapper(val structure: StructureND) : Structure2D { override val shape: IntArray get() = structure.shape override val rowNum: Int get() = shape[0] @@ -74,26 +76,22 @@ private class Structure2DWrapper(val structure: NDStructure) : Structure2D override operator fun get(i: Int, j: Int): T = structure[i, j] @UnstableKMathAPI - override fun getFeature(type: KClass): F? = structure.getFeature(type) + override fun getFeature(type: KClass): F? = structure.getFeature(type) override fun elements(): Sequence> = structure.elements() - - override fun equals(other: Any?): Boolean = structure == other - - override fun hashCode(): Int = structure.hashCode() } /** - * Represent a [NDStructure] as [Structure1D]. Throw error in case of dimension mismatch + * Represent a [StructureND] as [Structure1D]. Throw error in case of dimension mismatch */ -public fun NDStructure.as2D(): Structure2D = this as? Structure2D ?: when (shape.size) { +public fun StructureND.as2D(): Structure2D = this as? Structure2D ?: when (shape.size) { 2 -> Structure2DWrapper(this) else -> error("Can't create 2d-structure from ${shape.size}d-structure") } /** - * Expose inner [NDStructure] if possible + * Expose inner [StructureND] if possible */ -internal fun Structure2D.unwrap(): NDStructure = +internal fun Structure2D.unwrap(): StructureND = if (this is Structure2DWrapper) structure else this \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/NDStructure.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt similarity index 61% rename from kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/NDStructure.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt index 620f52edf..0656b1f7f 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/NDStructure.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt @@ -8,20 +8,22 @@ package space.kscience.kmath.nd import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.BufferFactory -import space.kscience.kmath.structures.MutableBuffer -import space.kscience.kmath.structures.asSequence import kotlin.jvm.JvmName import kotlin.native.concurrent.ThreadLocal import kotlin.reflect.KClass +public interface StructureFeature + /** * Represents n-dimensional structure, i.e. multidimensional container of items of the same type and size. The number * of dimensions and items in an array is defined by its shape, which is a sequence of non-negative integers that * specify the sizes of each dimension. * + * StructureND is in general identity-free. [StructureND.contentEquals] should be used in tests to compare contents. + * * @param T the type of items. */ -public interface NDStructure { +public interface StructureND { /** * The shape of structure, i.e. non-empty sequence of non-negative integers that specify sizes of dimensions of * this structure. @@ -48,32 +50,47 @@ public interface NDStructure { */ public fun elements(): Sequence> - //force override equality and hash code - public override fun equals(other: Any?): Boolean - public override fun hashCode(): Int - /** * Feature is some additional strucure information which allows to access it special properties or hints. * If the feature is not present, null is returned. */ @UnstableKMathAPI - public fun getFeature(type: KClass): F? = null + public fun getFeature(type: KClass): F? = null public companion object { /** - * Indicates whether some [NDStructure] is equal to another one. + * Indicates whether some [StructureND] is equal to another one. */ - public fun contentEquals(st1: NDStructure<*>, st2: NDStructure<*>): Boolean { + public fun contentEquals(st1: StructureND, st2: StructureND): Boolean { if (st1 === st2) return true // fast comparison of buffers if possible - if (st1 is NDBuffer && st2 is NDBuffer && st1.strides == st2.strides) - return st1.buffer.contentEquals(st2.buffer) + if (st1 is BufferND && st2 is BufferND && st1.strides == st2.strides) + return Buffer.contentEquals(st1.buffer, st2.buffer) //element by element comparison if it could not be avoided return st1.elements().all { (index, value) -> value == st2[index] } } + /** + * Debug output to string + */ + public fun toString(structure: StructureND<*>): String { + val bufferRepr: String = when (structure.shape.size) { + 1 -> (0 until structure.shape[0]).map { structure[it] } + .joinToString(prefix = "[", postfix = "]", separator = ", ") + 2 -> (0 until structure.shape[0]).joinToString(prefix = "[", postfix = "]", separator = ", ") { i -> + (0 until structure.shape[1]).joinToString(prefix = "[", postfix = "]", separator = ", ") { j -> + structure[i, j].toString() + } + } + else -> "..." + } + val className = structure::class.simpleName ?: "StructureND" + + return "$className(shape=${structure.shape.contentToString()}, buffer=$bufferRepr)" + } + /** * Creates a NDStructure with explicit buffer factory. * @@ -83,7 +100,7 @@ public interface NDStructure { strides: Strides, bufferFactory: BufferFactory = Buffer.Companion::boxing, initializer: (IntArray) -> T, - ): NDBuffer = NDBuffer(strides, bufferFactory(strides.linearSize) { i -> initializer(strides.index(i)) }) + ): BufferND = BufferND(strides, bufferFactory(strides.linearSize) { i -> initializer(strides.index(i)) }) /** * Inline create NDStructure with non-boxing buffer implementation if it is possible @@ -91,37 +108,37 @@ public interface NDStructure { public inline fun auto( strides: Strides, crossinline initializer: (IntArray) -> T, - ): NDBuffer = NDBuffer(strides, Buffer.auto(strides.linearSize) { i -> initializer(strides.index(i)) }) + ): BufferND = BufferND(strides, Buffer.auto(strides.linearSize) { i -> initializer(strides.index(i)) }) public inline fun auto( type: KClass, strides: Strides, crossinline initializer: (IntArray) -> T, - ): NDBuffer = NDBuffer(strides, Buffer.auto(type, strides.linearSize) { i -> initializer(strides.index(i)) }) + ): BufferND = BufferND(strides, Buffer.auto(type, strides.linearSize) { i -> initializer(strides.index(i)) }) public fun buffered( shape: IntArray, bufferFactory: BufferFactory = Buffer.Companion::boxing, initializer: (IntArray) -> T, - ): NDBuffer = buffered(DefaultStrides(shape), bufferFactory, initializer) + ): BufferND = buffered(DefaultStrides(shape), bufferFactory, initializer) public inline fun auto( shape: IntArray, crossinline initializer: (IntArray) -> T, - ): NDBuffer = auto(DefaultStrides(shape), initializer) + ): BufferND = auto(DefaultStrides(shape), initializer) @JvmName("autoVarArg") public inline fun auto( vararg shape: Int, crossinline initializer: (IntArray) -> T, - ): NDBuffer = + ): BufferND = auto(DefaultStrides(shape), initializer) public inline fun auto( type: KClass, vararg shape: Int, crossinline initializer: (IntArray) -> T, - ): NDBuffer = auto(type, DefaultStrides(shape), initializer) + ): BufferND = auto(type, DefaultStrides(shape), initializer) } } @@ -131,15 +148,15 @@ public interface NDStructure { * @param index the indices. * @return the value. */ -public operator fun NDStructure.get(vararg index: Int): T = get(index) +public operator fun StructureND.get(vararg index: Int): T = get(index) @UnstableKMathAPI -public inline fun NDStructure<*>.getFeature(): T? = getFeature(T::class) +public inline fun StructureND<*>.getFeature(): T? = getFeature(T::class) /** - * Represents mutable [NDStructure]. + * Represents mutable [StructureND]. */ -public interface MutableNDStructure : NDStructure { +public interface MutableStructureND : StructureND { /** * Inserts an item at the specified indices. * @@ -152,7 +169,7 @@ public interface MutableNDStructure : NDStructure { /** * Transform a structure element-by element in place. */ -public inline fun MutableNDStructure.mapInPlace(action: (IntArray, T) -> T): Unit = +public inline fun MutableStructureND.mapInPlace(action: (IntArray, T) -> T): Unit = elements().forEach { (index, oldValue) -> this[index] = action(index, oldValue) } /** @@ -256,97 +273,10 @@ public class DefaultStrides private constructor(override val shape: IntArray) : } } -/** - * Represents [NDStructure] over [Buffer]. - * - * @param T the type of items. - * @param strides The strides to access elements of [Buffer] by linear indices. - * @param buffer The underlying buffer. - */ -public open class NDBuffer( - public val strides: Strides, - buffer: Buffer, -) : NDStructure { - - init { - if (strides.linearSize != buffer.size) { - error("Expected buffer side of ${strides.linearSize}, but found ${buffer.size}") - } - } - - public open val buffer: Buffer = buffer - - override operator fun get(index: IntArray): T = buffer[strides.offset(index)] - - override val shape: IntArray get() = strides.shape - - override fun elements(): Sequence> = strides.indices().map { - it to this[it] - } - - override fun equals(other: Any?): Boolean { - return NDStructure.contentEquals(this, other as? NDStructure<*> ?: return false) - } - - override fun hashCode(): Int { - var result = strides.hashCode() - result = 31 * result + buffer.hashCode() - return result - } - - override fun toString(): String { - val bufferRepr: String = when (shape.size) { - 1 -> buffer.asSequence().joinToString(prefix = "[", postfix = "]", separator = ", ") - 2 -> (0 until shape[0]).joinToString(prefix = "[", postfix = "]", separator = ", ") { i -> - (0 until shape[1]).joinToString(prefix = "[", postfix = "]", separator = ", ") { j -> - val offset = strides.offset(intArrayOf(i, j)) - buffer[offset].toString() - } - } - else -> "..." - } - return "NDBuffer(shape=${shape.contentToString()}, buffer=$bufferRepr)" - } -} - -/** - * Transform structure to a new structure using provided [BufferFactory] and optimizing if argument is [NDBuffer] - */ -public inline fun NDStructure.mapToBuffer( - factory: BufferFactory = Buffer.Companion::auto, - crossinline transform: (T) -> R, -): NDBuffer { - return if (this is NDBuffer) - NDBuffer(this.strides, factory.invoke(strides.linearSize) { transform(buffer[it]) }) - else { - val strides = DefaultStrides(shape) - NDBuffer(strides, factory.invoke(strides.linearSize) { transform(get(strides.index(it))) }) - } -} - -/** - * Mutable ND buffer based on linear [MutableBuffer]. - */ -public class MutableNDBuffer( - strides: Strides, - buffer: MutableBuffer, -) : NDBuffer(strides, buffer), MutableNDStructure { - - init { - require(strides.linearSize == buffer.size) { - "Expected buffer side of ${strides.linearSize}, but found ${buffer.size}" - } - } - - override val buffer: MutableBuffer = super.buffer as MutableBuffer - - override operator fun set(index: IntArray, value: T): Unit = buffer.set(strides.offset(index), value) -} - -public inline fun NDStructure.combine( - struct: NDStructure, +public inline fun StructureND.combine( + struct: StructureND, crossinline block: (T, T) -> T, -): NDStructure { +): StructureND { require(shape.contentEquals(struct.shape)) { "Shape mismatch in structure combination" } - return NDStructure.auto(shape) { block(this[it], struct[it]) } + return StructureND.auto(shape) { block(this[it], struct[it]) } } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt index 300e1cb44..0334e0466 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt @@ -5,7 +5,7 @@ package space.kscience.kmath.operations -import space.kscience.kmath.expressions.Symbol +import space.kscience.kmath.misc.Symbol /** * Stub for DSL the [Algebra] is. @@ -28,10 +28,18 @@ public interface Algebra { * * In case if algebra can't parse the string, this method must throw [kotlin.IllegalStateException]. * + * Returns `null` if symbol could not be bound to the context + * * @param value the raw string. * @return an object. */ - public fun bindSymbol(value: String): T = error("Wrapping of '$value' is not supported in $this") + public fun bindSymbolOrNull(value: String): T? = null + + /** + * The same as [bindSymbolOrNull] but throws an error if symbol could not be bound + */ + public fun bindSymbol(value: String): T = + bindSymbolOrNull(value) ?: error("Symbol '$value' is not supported in $this") /** * Dynamically dispatches an unary operation with the certain name. @@ -96,7 +104,9 @@ public interface Algebra { binaryOperationFunction(operation)(left, right) } -public fun Algebra.bindSymbol(symbol: Symbol): T = bindSymbol(symbol.identity) +public fun Algebra.bindSymbolOrNull(symbol: Symbol): T? = bindSymbolOrNull(symbol.identity) + +public fun Algebra.bindSymbol(symbol: Symbol): T = bindSymbol(symbol.identity) /** * Call a block with an [Algebra] as receiver. @@ -105,8 +115,8 @@ public fun Algebra.bindSymbol(symbol: Symbol): T = bindSymbol(symbo public inline operator fun , R> A.invoke(block: A.() -> R): R = run(block) /** - * Represents linear space without neutral element, i.e. algebraic structure with associative, binary operation [add] - * and scalar multiplication [multiply]. + * Represents group without neutral element (also known as inverse semigroup), i.e. algebraic structure with + * associative, binary operation [add]. * * @param T the type of element of this semispace. */ @@ -114,8 +124,8 @@ public interface GroupOperations : Algebra { /** * Addition of two elements. * - * @param a the addend. - * @param b the augend. + * @param a the augend. + * @param b the addend. * @return the sum. */ public fun add(a: T, b: T): T @@ -141,8 +151,8 @@ public interface GroupOperations : Algebra { /** * Addition of two elements. * - * @receiver the addend. - * @param b the augend. + * @receiver the augend. + * @param b the addend. * @return the sum. */ public operator fun T.plus(b: T): T = add(this, b) @@ -182,7 +192,7 @@ public interface GroupOperations : Algebra { } /** - * Represents linear space with neutral element, i.e. algebraic structure with associative, binary operation [add]. + * Represents group, i.e. algebraic structure with associative, binary operation [add]. * * @param T the type of element of this semispace. */ @@ -194,8 +204,8 @@ public interface Group : GroupOperations { } /** - * Represents rng, i.e. algebraic structure with associative, binary, commutative operation [add] and associative, - * operation [multiply] distributive over [add]. + * Represents ring without multiplicative and additive identities, i.e. algebraic structure with + * associative, binary, commutative operation [add] and associative, operation [multiply] distributive over [add]. * * @param T the type of element of this semiring. */ @@ -243,7 +253,7 @@ public interface Ring : Group, RingOperations { } /** - * Represents field without identity elements, i.e. algebraic structure with associative, binary, commutative operations + * Represents field without without multiplicative and additive identities, i.e. algebraic structure with associative, binary, commutative operations * [add] and [multiply]; binary operation [divide] as multiplication of left operand by reciprocal of right one. * * @param T the type of element of this semifield. @@ -281,11 +291,12 @@ public interface FieldOperations : RingOperations { } /** - * Represents field, i.e. algebraic structure with three operations: associative "addition" and "multiplication", - * and "division" and their neutral elements. + * Represents field, i.e. algebraic structure with three operations: associative, commutative addition and + * multiplication, and division. **This interface differs from the eponymous mathematical definition: fields in KMath + * also support associative multiplication by scalar.** * - * @param T the type of element of this semifield. + * @param T the type of element of this field. */ public interface Field : Ring, FieldOperations, ScaleOperations, NumericAlgebra { - override fun number(value: Number): T = scale(one, value.toDouble()) -} \ No newline at end of file + public override fun number(value: Number): T = scale(one, value.toDouble()) +} diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/AlgebraElements.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/AlgebraElements.kt index c9337d369..d7c87f213 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/AlgebraElements.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/AlgebraElements.kt @@ -51,10 +51,11 @@ public operator fun , S : NumbersAddOperations> T.mi /** * Adds element to this one. * - * @param b the augend. + * @receiver the augend. + * @param b the addend. * @return the sum. */ -public operator fun , S : Group> T.plus(b: T): T = +public operator fun , S : Ring> T.plus(b: T): T = context.add(this, b) ///** @@ -63,11 +64,11 @@ public operator fun , S : Group> T.plus(b: T): T = //public operator fun , S : Space> Number.times(element: T): T = // element.times(this) - /** * Multiplies this element by another one. * - * @param b the multiplicand. + * @receiver the multiplicand. + * @param b the multiplier. * @return the product. */ public operator fun , R : Ring> T.times(b: T): T = @@ -92,7 +93,7 @@ public operator fun , F : Field> T.div(b: T): T = * @param S the type of space. */ @UnstableKMathAPI -public interface SpaceElement, S : Group> : AlgebraElement +public interface GroupElement, S : Group> : AlgebraElement /** * The element of [Ring]. @@ -102,7 +103,7 @@ public interface SpaceElement, S : Group> : AlgebraEle * @param R the type of ring. */ @UnstableKMathAPI -public interface RingElement, R : Ring> : SpaceElement +public interface RingElement, R : Ring> : GroupElement /** * The element of [Field]. diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt index 7756ec22e..e74efa9ca 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt @@ -6,8 +6,8 @@ package space.kscience.kmath.operations import space.kscience.kmath.misc.UnstableKMathAPI -import space.kscience.kmath.nd.BufferedNDRing -import space.kscience.kmath.nd.NDAlgebra +import space.kscience.kmath.nd.AlgebraND +import space.kscience.kmath.nd.BufferedRingND import space.kscience.kmath.operations.BigInt.Companion.BASE import space.kscience.kmath.operations.BigInt.Companion.BASE_SIZE import space.kscience.kmath.structures.Buffer @@ -17,13 +17,14 @@ import kotlin.math.max import kotlin.math.min import kotlin.math.sign -public typealias Magnitude = UIntArray -public typealias TBase = ULong +private typealias Magnitude = UIntArray +private typealias TBase = ULong /** * Kotlin Multiplatform implementation of Big Integer numbers (KBigInteger). * - * @author Robert Drynkin (https://github.com/robdrynkin) and Peter Klimai (https://github.com/pklimai) + * @author Robert Drynkin + * @author Peter Klimai */ @OptIn(UnstableKMathAPI::class) public object BigIntField : Field, NumbersAddOperations, ScaleOperations { @@ -246,18 +247,18 @@ public class BigInt internal constructor( ) private fun compareMagnitudes(mag1: Magnitude, mag2: Magnitude): Int { - when { - mag1.size > mag2.size -> return 1 - mag1.size < mag2.size -> return -1 + return when { + mag1.size > mag2.size -> 1 + mag1.size < mag2.size -> -1 + else -> { - for (i in mag1.size - 1 downTo 0) { - if (mag1[i] > mag2[i]) { - return 1 - } else if (mag1[i] < mag2[i]) { - return -1 - } + for (i in mag1.size - 1 downTo 0) return when { + mag1[i] > mag2[i] -> 1 + mag1[i] < mag2[i] -> -1 + else -> continue } - return 0 + + 0 } } } @@ -307,10 +308,11 @@ public class BigInt internal constructor( var carry = 0uL for (i in mag.indices) { - val cur: ULong = carry + mag[i].toULong() * x.toULong() + val cur = carry + mag[i].toULong() * x.toULong() result[i] = (cur and BASE).toUInt() carry = cur shr BASE_SIZE } + result[resultLength - 1] = (carry and BASE).toUInt() return stripLeadingZeros(result) @@ -363,6 +365,9 @@ private fun stripLeadingZeros(mag: Magnitude): Magnitude { return mag.sliceArray(IntRange(0, resSize)) } +/** + * Returns the absolute value of the given value [x]. + */ public fun abs(x: BigInt): BigInt = x.abs() /** @@ -440,7 +445,7 @@ public fun String.parseBigInteger(): BigInt? { var res = BigInt.ZERO var digitValue = BigInt.ONE - val sPositiveUpper = sPositive.toUpperCase() + val sPositiveUpper = sPositive.uppercase() if (sPositiveUpper.startsWith("0X")) { // hex representation val sHex = sPositiveUpper.substring(2) @@ -456,7 +461,7 @@ public fun String.parseBigInteger(): BigInt? { if (ch !in '0'..'9') { return null } - res += digitValue * (ch.toInt() - '0'.toInt()) + res += digitValue * (ch.code - '0'.code) digitValue *= 10.toBigInt() } @@ -469,5 +474,5 @@ public inline fun Buffer.Companion.bigInt(size: Int, initializer: (Int) -> BigIn public inline fun MutableBuffer.Companion.bigInt(size: Int, initializer: (Int) -> BigInt): MutableBuffer = boxing(size, initializer) -public fun NDAlgebra.Companion.bigInt(vararg shape: Int): BufferedNDRing = - BufferedNDRing(shape, BigIntField, Buffer.Companion::bigInt) +public fun AlgebraND.Companion.bigInt(vararg shape: Int): BufferedRingND = + BufferedRingND(shape, BigIntField, Buffer.Companion::bigInt) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/NumericAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/NumericAlgebra.kt index 19933fda9..6a35828ee 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/NumericAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/NumericAlgebra.kt @@ -6,6 +6,8 @@ package space.kscience.kmath.operations import space.kscience.kmath.misc.UnstableKMathAPI +import kotlin.math.E +import kotlin.math.PI /** * An algebraic structure where elements can have numeric representation. @@ -84,8 +86,26 @@ public interface NumericAlgebra : Algebra { */ public fun rightSideNumberOperation(operation: String, left: T, right: Number): T = rightSideNumberOperationFunction(operation)(left, right) + + public override fun bindSymbolOrNull(value: String): T? = when (value) { + "pi" -> number(PI) + "e" -> number(E) + else -> super.bindSymbolOrNull(value) + } } +/** + * The π mathematical constant. + */ +public val NumericAlgebra.pi: T + get() = bindSymbolOrNull("pi") ?: number(PI) + +/** + * The *e* mathematical constant. + */ +public val NumericAlgebra.e: T + get() = number(E) + /** * Scale by scalar operations */ @@ -132,20 +152,20 @@ public interface ScaleOperations : Algebra { * TODO to be removed and replaced by extensions after multiple receivers are there */ @UnstableKMathAPI -public interface NumbersAddOperations : Group, NumericAlgebra { +public interface NumbersAddOperations : Ring, NumericAlgebra { /** * Addition of element and scalar. * - * @receiver the addend. - * @param b the augend. + * @receiver the augend. + * @param b the addend. */ public operator fun T.plus(b: Number): T = this + number(b) /** * Addition of scalar and element. * - * @receiver the addend. - * @param b the augend. + * @receiver the augend. + * @param b the addend. */ public operator fun Number.plus(b: T): T = b + this diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/algebraExtensions.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/algebraExtensions.kt index a32c7c981..b8670553d 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/algebraExtensions.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/algebraExtensions.kt @@ -6,88 +6,92 @@ package space.kscience.kmath.operations /** - * Returns the sum of all elements in the iterable in this [Group]. + * Returns the sum of all elements in the iterable in this [Ring]. * * @receiver the algebra that provides addition. * @param data the iterable to sum up. * @return the sum. */ -public fun Group.sum(data: Iterable): T = data.fold(zero) { left, right -> add(left, right) } +public fun Ring.sum(data: Iterable): T = data.fold(zero) { left, right -> + add(left, right) +} /** - * Returns the sum of all elements in the sequence in this [Group]. + * Returns the sum of all elements in the sequence in this [Ring]. * * @receiver the algebra that provides addition. * @param data the sequence to sum up. * @return the sum. */ -public fun Group.sum(data: Sequence): T = data.fold(zero) { left, right -> add(left, right) } +public fun Ring.sum(data: Sequence): T = data.fold(zero) { left, right -> + add(left, right) +} /** - * Returns an average value of elements in the iterable in this [Group]. + * Returns an average value of elements in the iterable in this [Ring]. * * @receiver the algebra that provides addition and division. * @param data the iterable to find average. * @return the average value. * @author Iaroslav Postovalov */ -public fun S.average(data: Iterable): T where S : Group, S : ScaleOperations = +public fun S.average(data: Iterable): T where S : Ring, S : ScaleOperations = sum(data) / data.count() /** - * Returns an average value of elements in the sequence in this [Group]. + * Returns an average value of elements in the sequence in this [Ring]. * * @receiver the algebra that provides addition and division. * @param data the sequence to find average. * @return the average value. * @author Iaroslav Postovalov */ -public fun S.average(data: Sequence): T where S : Group, S : ScaleOperations = +public fun S.average(data: Sequence): T where S : Ring, S : ScaleOperations = sum(data) / data.count() /** * Absolute of the comparable [value] */ -public fun > Group.abs(value: T): T = if (value > zero) value else -value +public fun > Ring.abs(value: T): T = if (value > zero) value else -value /** * Returns the sum of all elements in the iterable in provided space. * * @receiver the collection to sum up. - * @param space the algebra that provides addition. + * @param group the algebra that provides addition. * @return the sum. */ -public fun Iterable.sumWith(space: Group): T = space.sum(this) +public fun Iterable.sumWith(group: Ring): T = group.sum(this) /** * Returns the sum of all elements in the sequence in provided space. * * @receiver the collection to sum up. - * @param space the algebra that provides addition. + * @param group the algebra that provides addition. * @return the sum. */ -public fun Sequence.sumWith(space: Group): T = space.sum(this) +public fun Sequence.sumWith(group: Ring): T = group.sum(this) /** - * Returns an average value of elements in the iterable in this [Group]. + * Returns an average value of elements in the iterable in this [Ring]. * * @receiver the iterable to find average. * @param space the algebra that provides addition and division. * @return the average value. * @author Iaroslav Postovalov */ -public fun Iterable.averageWith(space: S): T where S : Group, S : ScaleOperations = +public fun Iterable.averageWith(space: S): T where S : Ring, S : ScaleOperations = space.average(this) /** - * Returns an average value of elements in the sequence in this [Group]. + * Returns an average value of elements in the sequence in this [Ring]. * * @receiver the sequence to find average. * @param space the algebra that provides addition and division. * @return the average value. * @author Iaroslav Postovalov */ -public fun Sequence.averageWith(space: S): T where S : Group, S : ScaleOperations = +public fun Sequence.averageWith(space: S): T where S : Ring, S : ScaleOperations = space.average(this) //TODO optimized power operation diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt index d8243868b..3b0abf657 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt @@ -49,6 +49,12 @@ public interface ExtendedField : ExtendedFieldOperations, Field, Numeri public override fun acosh(arg: T): T = ln(arg + sqrt((arg - one) * (arg + one))) public override fun atanh(arg: T): T = (ln(arg + one) - ln(one - arg)) / 2.0 + public override fun bindSymbol(value: String): T = when (value) { + "pi" -> pi + "e" -> e + else -> super.bindSymbol(value) + } + public override fun rightSideNumberOperationFunction(operation: String): (left: T, right: Number) -> T = when (operation) { PowerOperations.POW_OPERATION -> ::power @@ -60,11 +66,11 @@ public interface ExtendedField : ExtendedFieldOperations, Field, Numeri * A field for [Double] without boxing. Does not produce appropriate field element. */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") -public object RealField : ExtendedField, Norm, ScaleOperations { - public override val zero: Double = 0.0 - public override val one: Double = 1.0 +public object DoubleField : ExtendedField, Norm, ScaleOperations { + public override inline val zero: Double get() = 0.0 + public override inline val one: Double get() = 1.0 - override fun number(value: Number): Double = value.toDouble() + public override fun number(value: Number): Double = value.toDouble() public override fun binaryOperationFunction(operation: String): (left: Double, right: Double) -> Double = when (operation) { @@ -73,13 +79,11 @@ public object RealField : ExtendedField, Norm, ScaleOper } public override inline fun add(a: Double, b: Double): Double = a + b -// public override inline fun multiply(a: Double, k: Number): Double = a * k.toDouble() -// override fun divide(a: Double, k: Number): Double = a / k.toDouble() public override inline fun multiply(a: Double, b: Double): Double = a * b public override inline fun divide(a: Double, b: Double): Double = a / b - override fun scale(a: Double, value: Double): Double = a * value + public override fun scale(a: Double, value: Double): Double = a * value public override inline fun sin(arg: Double): Double = kotlin.math.sin(arg) public override inline fun cos(arg: Double): Double = kotlin.math.cos(arg) @@ -113,10 +117,10 @@ public object RealField : ExtendedField, Norm, ScaleOper */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") public object FloatField : ExtendedField, Norm { - public override val zero: Float = 0.0f - public override val one: Float = 1.0f + public override inline val zero: Float get() = 0.0f + public override inline val one: Float get() = 1.0f - override fun number(value: Number): Float = value.toFloat() + public override fun number(value: Number): Float = value.toFloat() public override fun binaryOperationFunction(operation: String): (left: Float, right: Float) -> Float = when (operation) { @@ -125,7 +129,7 @@ public object FloatField : ExtendedField, Norm { } public override inline fun add(a: Float, b: Float): Float = a + b - override fun scale(a: Float, value: Double): Float = a * value.toFloat() + public override fun scale(a: Float, value: Double): Float = a * value.toFloat() public override inline fun multiply(a: Float, b: Float): Float = a * b @@ -163,13 +167,13 @@ public object FloatField : ExtendedField, Norm { */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") public object IntRing : Ring, Norm, NumericAlgebra { - public override val zero: Int + public override inline val zero: Int get() = 0 - public override val one: Int + public override inline val one: Int get() = 1 - override fun number(value: Number): Int = value.toInt() + public override fun number(value: Number): Int = value.toInt() public override inline fun add(a: Int, b: Int): Int = a + b public override inline fun multiply(a: Int, b: Int): Int = a * b public override inline fun norm(arg: Int): Int = abs(arg) @@ -185,13 +189,13 @@ public object IntRing : Ring, Norm, NumericAlgebra { */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") public object ShortRing : Ring, Norm, NumericAlgebra { - public override val zero: Short + public override inline val zero: Short get() = 0 - public override val one: Short + public override inline val one: Short get() = 1 - override fun number(value: Number): Short = value.toShort() + public override fun number(value: Number): Short = value.toShort() public override inline fun add(a: Short, b: Short): Short = (a + b).toShort() public override inline fun multiply(a: Short, b: Short): Short = (a * b).toShort() public override fun norm(arg: Short): Short = if (arg > 0) arg else (-arg).toShort() @@ -207,13 +211,13 @@ public object ShortRing : Ring, Norm, NumericAlgebra */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") public object ByteRing : Ring, Norm, NumericAlgebra { - public override val zero: Byte + public override inline val zero: Byte get() = 0 - public override val one: Byte + public override inline val one: Byte get() = 1 - override fun number(value: Number): Byte = value.toByte() + public override fun number(value: Number): Byte = value.toByte() public override inline fun add(a: Byte, b: Byte): Byte = (a + b).toByte() public override inline fun multiply(a: Byte, b: Byte): Byte = (a * b).toByte() public override fun norm(arg: Byte): Byte = if (arg > 0) arg else (-arg).toByte() @@ -229,13 +233,13 @@ public object ByteRing : Ring, Norm, NumericAlgebra { */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") public object LongRing : Ring, Norm, NumericAlgebra { - public override val zero: Long + public override inline val zero: Long get() = 0L - public override val one: Long + public override inline val one: Long get() = 1L - override fun number(value: Number): Long = value.toLong() + public override fun number(value: Number): Long = value.toLong() public override inline fun add(a: Long, b: Long): Long = a + b public override inline fun multiply(a: Long, b: Long): Long = a * b public override fun norm(arg: Long): Long = abs(arg) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt index 9201b5b1d..d187beab1 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.structures +import kotlin.jvm.JvmInline import kotlin.reflect.KClass /** @@ -22,7 +23,9 @@ public typealias BufferFactory = (Int, (Int) -> T) -> Buffer public typealias MutableBufferFactory = (Int, (Int) -> T) -> MutableBuffer /** - * A generic immutable random-access structure for both primitives and objects. + * A generic read-only random-access structure for both primitives and objects. + * + * [Buffer] is in general identity-free. [Buffer.contentEquals] should be used for content equality checks. * * @param T the type of elements contained in the buffer. */ @@ -42,13 +45,18 @@ public interface Buffer { */ public operator fun iterator(): Iterator - /** - * Checks content equality with another buffer. - */ - public fun contentEquals(other: Buffer<*>): Boolean = - asSequence().mapIndexed { index, value -> value == other[index] }.all { it } - public companion object { + /** + * Check the element-by-element match of content of two buffers. + */ + public fun contentEquals(first: Buffer, second: Buffer): Boolean { + if (first.size != second.size) return false + for (i in first.indices) { + if (first[i] != second[i]) return false + } + return true + } + /** * Creates a [ListBuffer] of given type [T] with given [size]. Each element is calculated by calling the * specified [initializer] function. @@ -58,14 +66,14 @@ public interface Buffer { /** * Creates a [Buffer] of given [type]. If the type is primitive, specialized buffers are used ([IntBuffer], - * [RealBuffer], etc.), [ListBuffer] is returned otherwise. + * [DoubleBuffer], etc.), [ListBuffer] is returned otherwise. * * The [size] is specified, and each element is calculated by calling the specified [initializer] function. */ @Suppress("UNCHECKED_CAST") public inline fun auto(type: KClass, size: Int, initializer: (Int) -> T): Buffer = when (type) { - Double::class -> MutableBuffer.real(size) { initializer(it) as Double } as Buffer + Double::class -> MutableBuffer.double(size) { initializer(it) as Double } as Buffer Short::class -> MutableBuffer.short(size) { initializer(it) as Short } as Buffer Int::class -> MutableBuffer.int(size) { initializer(it) as Int } as Buffer Long::class -> MutableBuffer.long(size) { initializer(it) as Long } as Buffer @@ -75,7 +83,7 @@ public interface Buffer { /** * Creates a [Buffer] of given type [T]. If the type is primitive, specialized buffers are used ([IntBuffer], - * [RealBuffer], etc.), [ListBuffer] is returned otherwise. + * [DoubleBuffer], etc.), [ListBuffer] is returned otherwise. * * The [size] is specified, and each element is calculated by calling the specified [initializer] function. */ @@ -107,13 +115,12 @@ public interface MutableBuffer : Buffer { public fun copy(): MutableBuffer public companion object { - /** - * Creates a [RealBuffer] with the specified [size], where each element is calculated by calling the specified + * Creates a [DoubleBuffer] with the specified [size], where each element is calculated by calling the specified * [initializer] function. */ - public inline fun real(size: Int, initializer: (Int) -> Double): RealBuffer = - RealBuffer(size, initializer) + public inline fun double(size: Int, initializer: (Int) -> Double): DoubleBuffer = + DoubleBuffer(size, initializer) /** * Creates a [ShortBuffer] with the specified [size], where each element is calculated by calling the specified @@ -153,14 +160,14 @@ public interface MutableBuffer : Buffer { /** * Creates a [MutableBuffer] of given [type]. If the type is primitive, specialized buffers are used - * ([IntBuffer], [RealBuffer], etc.), [ListBuffer] is returned otherwise. + * ([IntBuffer], [DoubleBuffer], etc.), [ListBuffer] is returned otherwise. * * The [size] is specified, and each element is calculated by calling the specified [initializer] function. */ @Suppress("UNCHECKED_CAST") public inline fun auto(type: KClass, size: Int, initializer: (Int) -> T): MutableBuffer = when (type) { - Double::class -> real(size) { initializer(it) as Double } as MutableBuffer + Double::class -> double(size) { initializer(it) as Double } as MutableBuffer Short::class -> short(size) { initializer(it) as Short } as MutableBuffer Int::class -> int(size) { initializer(it) as Int } as MutableBuffer Float::class -> float(size) { initializer(it) as Float } as MutableBuffer @@ -170,7 +177,7 @@ public interface MutableBuffer : Buffer { /** * Creates a [MutableBuffer] of given type [T]. If the type is primitive, specialized buffers are used - * ([IntBuffer], [RealBuffer], etc.), [ListBuffer] is returned otherwise. + * ([IntBuffer], [DoubleBuffer], etc.), [ListBuffer] is returned otherwise. * * The [size] is specified, and each element is calculated by calling the specified [initializer] function. */ @@ -186,9 +193,11 @@ public interface MutableBuffer : Buffer { * @param T the type of elements contained in the buffer. * @property list The underlying list. */ -public inline class ListBuffer(public val list: List) : Buffer { - override val size: Int - get() = list.size +public class ListBuffer(public val list: List) : Buffer { + + public constructor(size: Int, initializer: (Int) -> T) : this(List(size, initializer)) + + override val size: Int get() = list.size override operator fun get(index: Int): T = list[index] override operator fun iterator(): Iterator = list.iterator() @@ -205,9 +214,12 @@ public fun List.asBuffer(): ListBuffer = ListBuffer(this) * @param T the type of elements contained in the buffer. * @property list The underlying list. */ -public inline class MutableListBuffer(public val list: MutableList) : MutableBuffer { - override val size: Int - get() = list.size +@JvmInline +public value class MutableListBuffer(public val list: MutableList) : MutableBuffer { + + public constructor(size: Int, initializer: (Int) -> T) : this(MutableList(size, initializer)) + + override val size: Int get() = list.size override operator fun get(index: Int): T = list[index] @@ -256,7 +268,8 @@ public fun Array.asBuffer(): ArrayBuffer = ArrayBuffer(this) * @param T the type of elements contained in the buffer. * @property buffer The underlying buffer. */ -public inline class ReadOnlyBuffer(public val buffer: MutableBuffer) : Buffer { +@JvmInline +public value class ReadOnlyBuffer(public val buffer: MutableBuffer) : Buffer { override val size: Int get() = buffer.size override operator fun get(index: Int): T = buffer[index] @@ -277,14 +290,6 @@ public class VirtualBuffer(override val size: Int, private val generator: (In } override operator fun iterator(): Iterator = (0 until size).asSequence().map(generator).iterator() - - override fun contentEquals(other: Buffer<*>): Boolean { - return if (other is VirtualBuffer) { - this.size == other.size && this.generator == other.generator - } else { - super.contentEquals(other) - } - } } /** diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt index bc2cb3348..352c75956 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt @@ -6,8 +6,8 @@ package space.kscience.kmath.structures import space.kscience.kmath.nd.DefaultStrides -import space.kscience.kmath.nd.NDStructure import space.kscience.kmath.nd.Structure2D +import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.as2D /** @@ -30,7 +30,7 @@ internal class BufferAccessor2D( public fun create(mat: Structure2D): MutableBuffer = create { i, j -> mat[i, j] } //TODO optimize wrapper - public fun MutableBuffer.collect(): Structure2D = NDStructure.buffered( + public fun MutableBuffer.collect(): Structure2D = StructureND.buffered( DefaultStrides(intArrayOf(rowNum, colNum)), factory ) { (i, j) -> diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/RealBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/DoubleBuffer.kt similarity index 55% rename from kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/RealBuffer.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/DoubleBuffer.kt index 2df33b5a5..b4ef37598 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/RealBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/DoubleBuffer.kt @@ -5,13 +5,15 @@ package space.kscience.kmath.structures +import kotlin.jvm.JvmInline + /** * Specialized [MutableBuffer] implementation over [DoubleArray]. * * @property array the underlying array. */ -@Suppress("OVERRIDE_BY_INLINE") -public inline class RealBuffer(public val array: DoubleArray) : MutableBuffer { +@JvmInline +public value class DoubleBuffer(public val array: DoubleArray) : MutableBuffer { override val size: Int get() = array.size override operator fun get(index: Int): Double = array[index] @@ -22,40 +24,40 @@ public inline class RealBuffer(public val array: DoubleArray) : MutableBuffer Double): RealBuffer = RealBuffer(DoubleArray(size) { init(it) }) +public inline fun DoubleBuffer(size: Int, init: (Int) -> Double): DoubleBuffer = DoubleBuffer(DoubleArray(size) { init(it) }) /** - * Returns a new [RealBuffer] of given elements. + * Returns a new [DoubleBuffer] of given elements. */ -public fun RealBuffer(vararg doubles: Double): RealBuffer = RealBuffer(doubles) +public fun DoubleBuffer(vararg doubles: Double): DoubleBuffer = DoubleBuffer(doubles) /** - * Simplified [RealBuffer] to array comparison + * Simplified [DoubleBuffer] to array comparison */ -public fun RealBuffer.contentEquals(vararg doubles: Double): Boolean = array.contentEquals(doubles) +public fun DoubleBuffer.contentEquals(vararg doubles: Double): Boolean = array.contentEquals(doubles) /** * Returns a new [DoubleArray] containing all of the elements of this [Buffer]. */ public fun Buffer.toDoubleArray(): DoubleArray = when (this) { - is RealBuffer -> array.copyOf() + is DoubleBuffer -> array.copyOf() else -> DoubleArray(size, ::get) } /** - * Returns [RealBuffer] over this array. + * Returns [DoubleBuffer] over this array. * * @receiver the array. * @return the new buffer. */ -public fun DoubleArray.asBuffer(): RealBuffer = RealBuffer(this) +public fun DoubleArray.asBuffer(): DoubleBuffer = DoubleBuffer(this) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/DoubleBufferField.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/DoubleBufferField.kt new file mode 100644 index 000000000..34b5e373b --- /dev/null +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/DoubleBufferField.kt @@ -0,0 +1,277 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.structures + +import space.kscience.kmath.operations.ExtendedField +import space.kscience.kmath.operations.ExtendedFieldOperations +import kotlin.math.* + +/** + * [ExtendedFieldOperations] over [DoubleBuffer]. + */ +public object DoubleBufferFieldOperations : ExtendedFieldOperations> { + override fun Buffer.unaryMinus(): DoubleBuffer = if (this is DoubleBuffer) { + DoubleBuffer(size) { -array[it] } + } else { + DoubleBuffer(size) { -get(it) } + } + + public override fun add(a: Buffer, b: Buffer): DoubleBuffer { + require(b.size == a.size) { + "The size of the first buffer ${a.size} should be the same as for second one: ${b.size} " + } + + return if (a is DoubleBuffer && b is DoubleBuffer) { + val aArray = a.array + val bArray = b.array + DoubleBuffer(DoubleArray(a.size) { aArray[it] + bArray[it] }) + } else DoubleBuffer(DoubleArray(a.size) { a[it] + b[it] }) + } +// +// public override fun multiply(a: Buffer, k: Number): RealBuffer { +// val kValue = k.toDouble() +// +// return if (a is RealBuffer) { +// val aArray = a.array +// RealBuffer(DoubleArray(a.size) { aArray[it] * kValue }) +// } else RealBuffer(DoubleArray(a.size) { a[it] * kValue }) +// } +// +// public override fun divide(a: Buffer, k: Number): RealBuffer { +// val kValue = k.toDouble() +// +// return if (a is RealBuffer) { +// val aArray = a.array +// RealBuffer(DoubleArray(a.size) { aArray[it] / kValue }) +// } else RealBuffer(DoubleArray(a.size) { a[it] / kValue }) +// } + + public override fun multiply(a: Buffer, b: Buffer): DoubleBuffer { + require(b.size == a.size) { + "The size of the first buffer ${a.size} should be the same as for second one: ${b.size} " + } + + return if (a is DoubleBuffer && b is DoubleBuffer) { + val aArray = a.array + val bArray = b.array + DoubleBuffer(DoubleArray(a.size) { aArray[it] * bArray[it] }) + } else + DoubleBuffer(DoubleArray(a.size) { a[it] * b[it] }) + } + + public override fun divide(a: Buffer, b: Buffer): DoubleBuffer { + require(b.size == a.size) { + "The size of the first buffer ${a.size} should be the same as for second one: ${b.size} " + } + + return if (a is DoubleBuffer && b is DoubleBuffer) { + val aArray = a.array + val bArray = b.array + DoubleBuffer(DoubleArray(a.size) { aArray[it] / bArray[it] }) + } else DoubleBuffer(DoubleArray(a.size) { a[it] / b[it] }) + } + + public override fun sin(arg: Buffer): DoubleBuffer = if (arg is DoubleBuffer) { + val array = arg.array + DoubleBuffer(DoubleArray(arg.size) { sin(array[it]) }) + } else DoubleBuffer(DoubleArray(arg.size) { sin(arg[it]) }) + + public override fun cos(arg: Buffer): DoubleBuffer = if (arg is DoubleBuffer) { + val array = arg.array + DoubleBuffer(DoubleArray(arg.size) { cos(array[it]) }) + } else DoubleBuffer(DoubleArray(arg.size) { cos(arg[it]) }) + + public override fun tan(arg: Buffer): DoubleBuffer = if (arg is DoubleBuffer) { + val array = arg.array + DoubleBuffer(DoubleArray(arg.size) { tan(array[it]) }) + } else DoubleBuffer(DoubleArray(arg.size) { tan(arg[it]) }) + + public override fun asin(arg: Buffer): DoubleBuffer = if (arg is DoubleBuffer) { + val array = arg.array + DoubleBuffer(DoubleArray(arg.size) { asin(array[it]) }) + } else + DoubleBuffer(DoubleArray(arg.size) { asin(arg[it]) }) + + public override fun acos(arg: Buffer): DoubleBuffer = if (arg is DoubleBuffer) { + val array = arg.array + DoubleBuffer(DoubleArray(arg.size) { acos(array[it]) }) + } else + DoubleBuffer(DoubleArray(arg.size) { acos(arg[it]) }) + + public override fun atan(arg: Buffer): DoubleBuffer = if (arg is DoubleBuffer) { + val array = arg.array + DoubleBuffer(DoubleArray(arg.size) { atan(array[it]) }) + } else + DoubleBuffer(DoubleArray(arg.size) { atan(arg[it]) }) + + public override fun sinh(arg: Buffer): DoubleBuffer = if (arg is DoubleBuffer) { + val array = arg.array + DoubleBuffer(DoubleArray(arg.size) { sinh(array[it]) }) + } else + DoubleBuffer(DoubleArray(arg.size) { sinh(arg[it]) }) + + public override fun cosh(arg: Buffer): DoubleBuffer = if (arg is DoubleBuffer) { + val array = arg.array + DoubleBuffer(DoubleArray(arg.size) { cosh(array[it]) }) + } else + DoubleBuffer(DoubleArray(arg.size) { cosh(arg[it]) }) + + public override fun tanh(arg: Buffer): DoubleBuffer = if (arg is DoubleBuffer) { + val array = arg.array + DoubleBuffer(DoubleArray(arg.size) { tanh(array[it]) }) + } else + DoubleBuffer(DoubleArray(arg.size) { tanh(arg[it]) }) + + public override fun asinh(arg: Buffer): DoubleBuffer = if (arg is DoubleBuffer) { + val array = arg.array + DoubleBuffer(DoubleArray(arg.size) { asinh(array[it]) }) + } else + DoubleBuffer(DoubleArray(arg.size) { asinh(arg[it]) }) + + public override fun acosh(arg: Buffer): DoubleBuffer = if (arg is DoubleBuffer) { + val array = arg.array + DoubleBuffer(DoubleArray(arg.size) { acosh(array[it]) }) + } else + DoubleBuffer(DoubleArray(arg.size) { acosh(arg[it]) }) + + public override fun atanh(arg: Buffer): DoubleBuffer = if (arg is DoubleBuffer) { + val array = arg.array + DoubleBuffer(DoubleArray(arg.size) { atanh(array[it]) }) + } else + DoubleBuffer(DoubleArray(arg.size) { atanh(arg[it]) }) + + public override fun power(arg: Buffer, pow: Number): DoubleBuffer = if (arg is DoubleBuffer) { + val array = arg.array + DoubleBuffer(DoubleArray(arg.size) { array[it].pow(pow.toDouble()) }) + } else + DoubleBuffer(DoubleArray(arg.size) { arg[it].pow(pow.toDouble()) }) + + public override fun exp(arg: Buffer): DoubleBuffer = if (arg is DoubleBuffer) { + val array = arg.array + DoubleBuffer(DoubleArray(arg.size) { exp(array[it]) }) + } else DoubleBuffer(DoubleArray(arg.size) { exp(arg[it]) }) + + public override fun ln(arg: Buffer): DoubleBuffer = if (arg is DoubleBuffer) { + val array = arg.array + DoubleBuffer(DoubleArray(arg.size) { ln(array[it]) }) + } else + DoubleBuffer(DoubleArray(arg.size) { ln(arg[it]) }) +} + +/** + * [ExtendedField] over [DoubleBuffer]. + * + * @property size the size of buffers to operate on. + */ +public class DoubleBufferField(public val size: Int) : ExtendedField> { + public override val zero: Buffer by lazy { DoubleBuffer(size) { 0.0 } } + public override val one: Buffer by lazy { DoubleBuffer(size) { 1.0 } } + + override fun number(value: Number): Buffer = DoubleBuffer(size) { value.toDouble() } + + override fun Buffer.unaryMinus(): Buffer = DoubleBufferFieldOperations.run { + -this@unaryMinus + } + + public override fun add(a: Buffer, b: Buffer): DoubleBuffer { + require(a.size == size) { "The buffer size ${a.size} does not match context size $size" } + return DoubleBufferFieldOperations.add(a, b) + } + + public override fun scale(a: Buffer, value: Double): DoubleBuffer { + require(a.size == size) { "The buffer size ${a.size} does not match context size $size" } + + return if (a is DoubleBuffer) { + val aArray = a.array + DoubleBuffer(DoubleArray(a.size) { aArray[it] * value }) + } else DoubleBuffer(DoubleArray(a.size) { a[it] * value }) + } + + public override fun multiply(a: Buffer, b: Buffer): DoubleBuffer { + require(a.size == size) { "The buffer size ${a.size} does not match context size $size" } + return DoubleBufferFieldOperations.multiply(a, b) + } + + public override fun divide(a: Buffer, b: Buffer): DoubleBuffer { + require(a.size == size) { "The buffer size ${a.size} does not match context size $size" } + return DoubleBufferFieldOperations.divide(a, b) + } + + public override fun sin(arg: Buffer): DoubleBuffer { + require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } + return DoubleBufferFieldOperations.sin(arg) + } + + public override fun cos(arg: Buffer): DoubleBuffer { + require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } + return DoubleBufferFieldOperations.cos(arg) + } + + public override fun tan(arg: Buffer): DoubleBuffer { + require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } + return DoubleBufferFieldOperations.tan(arg) + } + + public override fun asin(arg: Buffer): DoubleBuffer { + require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } + return DoubleBufferFieldOperations.asin(arg) + } + + public override fun acos(arg: Buffer): DoubleBuffer { + require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } + return DoubleBufferFieldOperations.acos(arg) + } + + public override fun atan(arg: Buffer): DoubleBuffer { + require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } + return DoubleBufferFieldOperations.atan(arg) + } + + public override fun sinh(arg: Buffer): DoubleBuffer { + require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } + return DoubleBufferFieldOperations.sinh(arg) + } + + public override fun cosh(arg: Buffer): DoubleBuffer { + require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } + return DoubleBufferFieldOperations.cosh(arg) + } + + public override fun tanh(arg: Buffer): DoubleBuffer { + require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } + return DoubleBufferFieldOperations.tanh(arg) + } + + public override fun asinh(arg: Buffer): DoubleBuffer { + require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } + return DoubleBufferFieldOperations.asinh(arg) + } + + public override fun acosh(arg: Buffer): DoubleBuffer { + require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } + return DoubleBufferFieldOperations.acosh(arg) + } + + public override fun atanh(arg: Buffer): DoubleBuffer { + require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } + return DoubleBufferFieldOperations.atanh(arg) + } + + public override fun power(arg: Buffer, pow: Number): DoubleBuffer { + require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } + return DoubleBufferFieldOperations.power(arg, pow) + } + + public override fun exp(arg: Buffer): DoubleBuffer { + require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } + return DoubleBufferFieldOperations.exp(arg) + } + + public override fun ln(arg: Buffer): DoubleBuffer { + require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } + return DoubleBufferFieldOperations.ln(arg) + } +} diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt index 65be5d052..a63f452f5 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt @@ -53,7 +53,7 @@ public fun FlaggedBuffer<*>.isMissing(index: Int): Boolean = hasFlag(index, Valu /** * A real buffer which supports flags for each value like NaN or Missing */ -public class FlaggedRealBuffer(public val values: DoubleArray, public val flags: ByteArray) : FlaggedBuffer, +public class FlaggedDoubleBuffer(public val values: DoubleArray, public val flags: ByteArray) : FlaggedBuffer, Buffer { init { require(values.size == flags.size) { "Values and flags must have the same dimensions" } @@ -70,7 +70,7 @@ public class FlaggedRealBuffer(public val values: DoubleArray, public val flags: }.iterator() } -public inline fun FlaggedRealBuffer.forEachValid(block: (Double) -> Unit) { +public inline fun FlaggedDoubleBuffer.forEachValid(block: (Double) -> Unit) { indices .asSequence() .filter(::isValid) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FloatBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FloatBuffer.kt index 95837796d..58b7c6aea 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FloatBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FloatBuffer.kt @@ -5,13 +5,16 @@ package space.kscience.kmath.structures +import kotlin.jvm.JvmInline + /** * Specialized [MutableBuffer] implementation over [FloatArray]. * * @property array the underlying array. * @author Iaroslav Postovalov */ -public inline class FloatBuffer(public val array: FloatArray) : MutableBuffer { +@JvmInline +public value class FloatBuffer(public val array: FloatArray) : MutableBuffer { override val size: Int get() = array.size override operator fun get(index: Int): Float = array[index] diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/IntBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/IntBuffer.kt index e2b3d0fd6..57b6cfde3 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/IntBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/IntBuffer.kt @@ -5,12 +5,15 @@ package space.kscience.kmath.structures +import kotlin.jvm.JvmInline + /** * Specialized [MutableBuffer] implementation over [IntArray]. * * @property array the underlying array. */ -public inline class IntBuffer(public val array: IntArray) : MutableBuffer { +@JvmInline +public value class IntBuffer(public val array: IntArray) : MutableBuffer { override val size: Int get() = array.size override operator fun get(index: Int): Int = array[index] diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/LongBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/LongBuffer.kt index d03957d8f..57affa1c5 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/LongBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/LongBuffer.kt @@ -5,12 +5,15 @@ package space.kscience.kmath.structures +import kotlin.jvm.JvmInline + /** * Specialized [MutableBuffer] implementation over [LongArray]. * * @property array the underlying array. */ -public inline class LongBuffer(public val array: LongArray) : MutableBuffer { +@JvmInline +public value class LongBuffer(public val array: LongArray) : MutableBuffer { override val size: Int get() = array.size override operator fun get(index: Int): Long = array[index] diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/RealBufferField.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/RealBufferField.kt deleted file mode 100644 index 5658ce83f..000000000 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/RealBufferField.kt +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright 2018-2021 KMath contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package space.kscience.kmath.structures - -import space.kscience.kmath.operations.ExtendedField -import space.kscience.kmath.operations.ExtendedFieldOperations -import kotlin.math.* - -/** - * [ExtendedFieldOperations] over [RealBuffer]. - */ -public object RealBufferFieldOperations : ExtendedFieldOperations> { - override fun Buffer.unaryMinus(): RealBuffer = if (this is RealBuffer) { - RealBuffer(size) { -array[it] } - } else { - RealBuffer(size) { -get(it) } - } - - public override fun add(a: Buffer, b: Buffer): RealBuffer { - require(b.size == a.size) { - "The size of the first buffer ${a.size} should be the same as for second one: ${b.size} " - } - - return if (a is RealBuffer && b is RealBuffer) { - val aArray = a.array - val bArray = b.array - RealBuffer(DoubleArray(a.size) { aArray[it] + bArray[it] }) - } else RealBuffer(DoubleArray(a.size) { a[it] + b[it] }) - } -// -// public override fun multiply(a: Buffer, k: Number): RealBuffer { -// val kValue = k.toDouble() -// -// return if (a is RealBuffer) { -// val aArray = a.array -// RealBuffer(DoubleArray(a.size) { aArray[it] * kValue }) -// } else RealBuffer(DoubleArray(a.size) { a[it] * kValue }) -// } -// -// public override fun divide(a: Buffer, k: Number): RealBuffer { -// val kValue = k.toDouble() -// -// return if (a is RealBuffer) { -// val aArray = a.array -// RealBuffer(DoubleArray(a.size) { aArray[it] / kValue }) -// } else RealBuffer(DoubleArray(a.size) { a[it] / kValue }) -// } - - public override fun multiply(a: Buffer, b: Buffer): RealBuffer { - require(b.size == a.size) { - "The size of the first buffer ${a.size} should be the same as for second one: ${b.size} " - } - - return if (a is RealBuffer && b is RealBuffer) { - val aArray = a.array - val bArray = b.array - RealBuffer(DoubleArray(a.size) { aArray[it] * bArray[it] }) - } else - RealBuffer(DoubleArray(a.size) { a[it] * b[it] }) - } - - public override fun divide(a: Buffer, b: Buffer): RealBuffer { - require(b.size == a.size) { - "The size of the first buffer ${a.size} should be the same as for second one: ${b.size} " - } - - return if (a is RealBuffer && b is RealBuffer) { - val aArray = a.array - val bArray = b.array - RealBuffer(DoubleArray(a.size) { aArray[it] / bArray[it] }) - } else RealBuffer(DoubleArray(a.size) { a[it] / b[it] }) - } - - public override fun sin(arg: Buffer): RealBuffer = if (arg is RealBuffer) { - val array = arg.array - RealBuffer(DoubleArray(arg.size) { sin(array[it]) }) - } else RealBuffer(DoubleArray(arg.size) { sin(arg[it]) }) - - public override fun cos(arg: Buffer): RealBuffer = if (arg is RealBuffer) { - val array = arg.array - RealBuffer(DoubleArray(arg.size) { cos(array[it]) }) - } else RealBuffer(DoubleArray(arg.size) { cos(arg[it]) }) - - public override fun tan(arg: Buffer): RealBuffer = if (arg is RealBuffer) { - val array = arg.array - RealBuffer(DoubleArray(arg.size) { tan(array[it]) }) - } else RealBuffer(DoubleArray(arg.size) { tan(arg[it]) }) - - public override fun asin(arg: Buffer): RealBuffer = if (arg is RealBuffer) { - val array = arg.array - RealBuffer(DoubleArray(arg.size) { asin(array[it]) }) - } else - RealBuffer(DoubleArray(arg.size) { asin(arg[it]) }) - - public override fun acos(arg: Buffer): RealBuffer = if (arg is RealBuffer) { - val array = arg.array - RealBuffer(DoubleArray(arg.size) { acos(array[it]) }) - } else - RealBuffer(DoubleArray(arg.size) { acos(arg[it]) }) - - public override fun atan(arg: Buffer): RealBuffer = if (arg is RealBuffer) { - val array = arg.array - RealBuffer(DoubleArray(arg.size) { atan(array[it]) }) - } else - RealBuffer(DoubleArray(arg.size) { atan(arg[it]) }) - - public override fun sinh(arg: Buffer): RealBuffer = if (arg is RealBuffer) { - val array = arg.array - RealBuffer(DoubleArray(arg.size) { sinh(array[it]) }) - } else - RealBuffer(DoubleArray(arg.size) { sinh(arg[it]) }) - - public override fun cosh(arg: Buffer): RealBuffer = if (arg is RealBuffer) { - val array = arg.array - RealBuffer(DoubleArray(arg.size) { cosh(array[it]) }) - } else - RealBuffer(DoubleArray(arg.size) { cosh(arg[it]) }) - - public override fun tanh(arg: Buffer): RealBuffer = if (arg is RealBuffer) { - val array = arg.array - RealBuffer(DoubleArray(arg.size) { tanh(array[it]) }) - } else - RealBuffer(DoubleArray(arg.size) { tanh(arg[it]) }) - - public override fun asinh(arg: Buffer): RealBuffer = if (arg is RealBuffer) { - val array = arg.array - RealBuffer(DoubleArray(arg.size) { asinh(array[it]) }) - } else - RealBuffer(DoubleArray(arg.size) { asinh(arg[it]) }) - - public override fun acosh(arg: Buffer): RealBuffer = if (arg is RealBuffer) { - val array = arg.array - RealBuffer(DoubleArray(arg.size) { acosh(array[it]) }) - } else - RealBuffer(DoubleArray(arg.size) { acosh(arg[it]) }) - - public override fun atanh(arg: Buffer): RealBuffer = if (arg is RealBuffer) { - val array = arg.array - RealBuffer(DoubleArray(arg.size) { atanh(array[it]) }) - } else - RealBuffer(DoubleArray(arg.size) { atanh(arg[it]) }) - - public override fun power(arg: Buffer, pow: Number): RealBuffer = if (arg is RealBuffer) { - val array = arg.array - RealBuffer(DoubleArray(arg.size) { array[it].pow(pow.toDouble()) }) - } else - RealBuffer(DoubleArray(arg.size) { arg[it].pow(pow.toDouble()) }) - - public override fun exp(arg: Buffer): RealBuffer = if (arg is RealBuffer) { - val array = arg.array - RealBuffer(DoubleArray(arg.size) { exp(array[it]) }) - } else RealBuffer(DoubleArray(arg.size) { exp(arg[it]) }) - - public override fun ln(arg: Buffer): RealBuffer = if (arg is RealBuffer) { - val array = arg.array - RealBuffer(DoubleArray(arg.size) { ln(array[it]) }) - } else - RealBuffer(DoubleArray(arg.size) { ln(arg[it]) }) -} - -/** - * [ExtendedField] over [RealBuffer]. - * - * @property size the size of buffers to operate on. - */ -public class RealBufferField(public val size: Int) : ExtendedField> { - public override val zero: Buffer by lazy { RealBuffer(size) { 0.0 } } - public override val one: Buffer by lazy { RealBuffer(size) { 1.0 } } - - override fun number(value: Number): Buffer = RealBuffer(size) { value.toDouble() } - - override fun Buffer.unaryMinus(): Buffer = RealBufferFieldOperations.run { - -this@unaryMinus - } - - public override fun add(a: Buffer, b: Buffer): RealBuffer { - require(a.size == size) { "The buffer size ${a.size} does not match context size $size" } - return RealBufferFieldOperations.add(a, b) - } - - public override fun scale(a: Buffer, value: Double): RealBuffer { - require(a.size == size) { "The buffer size ${a.size} does not match context size $size" } - - return if (a is RealBuffer) { - val aArray = a.array - RealBuffer(DoubleArray(a.size) { aArray[it] * value }) - } else RealBuffer(DoubleArray(a.size) { a[it] * value }) - } - - public override fun multiply(a: Buffer, b: Buffer): RealBuffer { - require(a.size == size) { "The buffer size ${a.size} does not match context size $size" } - return RealBufferFieldOperations.multiply(a, b) - } - - public override fun divide(a: Buffer, b: Buffer): RealBuffer { - require(a.size == size) { "The buffer size ${a.size} does not match context size $size" } - return RealBufferFieldOperations.divide(a, b) - } - - public override fun sin(arg: Buffer): RealBuffer { - require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } - return RealBufferFieldOperations.sin(arg) - } - - public override fun cos(arg: Buffer): RealBuffer { - require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } - return RealBufferFieldOperations.cos(arg) - } - - public override fun tan(arg: Buffer): RealBuffer { - require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } - return RealBufferFieldOperations.tan(arg) - } - - public override fun asin(arg: Buffer): RealBuffer { - require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } - return RealBufferFieldOperations.asin(arg) - } - - public override fun acos(arg: Buffer): RealBuffer { - require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } - return RealBufferFieldOperations.acos(arg) - } - - public override fun atan(arg: Buffer): RealBuffer { - require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } - return RealBufferFieldOperations.atan(arg) - } - - public override fun sinh(arg: Buffer): RealBuffer { - require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } - return RealBufferFieldOperations.sinh(arg) - } - - public override fun cosh(arg: Buffer): RealBuffer { - require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } - return RealBufferFieldOperations.cosh(arg) - } - - public override fun tanh(arg: Buffer): RealBuffer { - require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } - return RealBufferFieldOperations.tanh(arg) - } - - public override fun asinh(arg: Buffer): RealBuffer { - require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } - return RealBufferFieldOperations.asinh(arg) - } - - public override fun acosh(arg: Buffer): RealBuffer { - require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } - return RealBufferFieldOperations.acosh(arg) - } - - public override fun atanh(arg: Buffer): RealBuffer { - require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } - return RealBufferFieldOperations.atanh(arg) - } - - public override fun power(arg: Buffer, pow: Number): RealBuffer { - require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } - return RealBufferFieldOperations.power(arg, pow) - } - - public override fun exp(arg: Buffer): RealBuffer { - require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } - return RealBufferFieldOperations.exp(arg) - } - - public override fun ln(arg: Buffer): RealBuffer { - require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" } - return RealBufferFieldOperations.ln(arg) - } -} diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ShortBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ShortBuffer.kt index 9ed507d3f..3d4c68b3c 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ShortBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ShortBuffer.kt @@ -5,12 +5,15 @@ package space.kscience.kmath.structures +import kotlin.jvm.JvmInline + /** * Specialized [MutableBuffer] implementation over [ShortArray]. * * @property array the underlying array. */ -public inline class ShortBuffer(public val array: ShortArray) : MutableBuffer { +@JvmInline +public value class ShortBuffer(public val array: ShortArray) : MutableBuffer { public override val size: Int get() = array.size public override operator fun get(index: Int): Short = array[index] diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/bufferOperation.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/bufferOperation.kt index 3ec403bdd..1b89e7838 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/bufferOperation.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/bufferOperation.kt @@ -58,12 +58,18 @@ public fun Buffer.toMutableList(): MutableList = when (this) { public inline fun Buffer.toTypedArray(): Array = Array(size, ::get) /** - * Create a new buffer from this one with the given mapping function. - * Provided [BufferFactory] is used to construct the new buffer. + * Create a new buffer from this one with the given mapping function and using [Buffer.Companion.auto] buffer factory. */ -public inline fun Buffer.map( - bufferFactory: BufferFactory = Buffer.Companion::auto, - crossinline block: (T) -> R, +public inline fun Buffer.map(block: (T) -> R): Buffer = + Buffer.auto(size) { block(get(it)) } + +/** + * Create a new buffer from this one with the given mapping function. + * Provided [bufferFactory] is used to construct the new buffer. + */ +public fun Buffer.map( + bufferFactory: BufferFactory, + block: (T) -> R, ): Buffer = bufferFactory(size) { block(get(it)) } /** @@ -75,6 +81,15 @@ public inline fun Buffer.mapIndexed( crossinline block: (index: Int, value: T) -> R, ): Buffer = bufferFactory(size) { block(it, get(it)) } +/** + * Fold given buffer according to [operation] + */ +public inline fun Buffer.fold(initial: R, operation: (acc: R, T) -> R): R { + var accumulator = initial + for (index in this.indices) accumulator = operation(accumulator, get(index)) + return accumulator +} + /** * Zip two buffers using given [transform]. */ diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/ExpressionFieldTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/ExpressionFieldTest.kt index 313dd8393..cf3a565bc 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/ExpressionFieldTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/ExpressionFieldTest.kt @@ -5,7 +5,8 @@ package space.kscience.kmath.expressions -import space.kscience.kmath.operations.RealField +import space.kscience.kmath.misc.symbol +import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.invoke import kotlin.test.Test import kotlin.test.assertEquals @@ -16,7 +17,7 @@ class ExpressionFieldTest { @Test fun testExpression() { - val expression = FunctionalExpressionField(RealField).invoke { + val expression = FunctionalExpressionField(DoubleField).invoke { val x by binding() x * x + 2 * x + one } @@ -32,7 +33,7 @@ class ExpressionFieldTest { return x * x + 2 * x + one } - val expression = FunctionalExpressionField(RealField).expression() + val expression = FunctionalExpressionField(DoubleField).expression() assertEquals(expression(x to 1.0), 4.0) } @@ -43,7 +44,7 @@ class ExpressionFieldTest { x * x + 2 * x + one } - val expression = FunctionalExpressionField(RealField).expressionBuilder() + val expression = FunctionalExpressionField(DoubleField).expressionBuilder() assertEquals(expression(x to 1.0), 4.0) } } diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/SimpleAutoDiffTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/SimpleAutoDiffTest.kt index 0672cc4c7..ab509650a 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/SimpleAutoDiffTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/SimpleAutoDiffTest.kt @@ -5,7 +5,11 @@ package space.kscience.kmath.expressions -import space.kscience.kmath.operations.RealField +import space.kscience.kmath.misc.Symbol +import space.kscience.kmath.misc.symbol +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.bindSymbol +import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.asBuffer import kotlin.math.E import kotlin.math.PI @@ -19,19 +23,19 @@ class SimpleAutoDiffTest { fun dx( xBinding: Pair, - body: SimpleAutoDiffField.(x: AutoDiffValue) -> AutoDiffValue, - ): DerivationResult = RealField.simpleAutoDiff(xBinding) { body(bindSymbol(xBinding.first)) } + body: SimpleAutoDiffField.(x: AutoDiffValue) -> AutoDiffValue, + ): DerivationResult = DoubleField.simpleAutoDiff(xBinding) { body(bindSymbol(xBinding.first)) } fun dxy( xBinding: Pair, yBinding: Pair, - body: SimpleAutoDiffField.(x: AutoDiffValue, y: AutoDiffValue) -> AutoDiffValue, - ): DerivationResult = RealField.simpleAutoDiff(xBinding, yBinding) { + body: SimpleAutoDiffField.(x: AutoDiffValue, y: AutoDiffValue) -> AutoDiffValue, + ): DerivationResult = DoubleField.simpleAutoDiff(xBinding, yBinding) { body(bindSymbol(xBinding.first), bindSymbol(yBinding.first)) } - fun diff(block: SimpleAutoDiffField.() -> AutoDiffValue): SimpleAutoDiffExpression { - return SimpleAutoDiffExpression(RealField, block) + fun diff(block: SimpleAutoDiffField.() -> AutoDiffValue): SimpleAutoDiffExpression { + return SimpleAutoDiffExpression(DoubleField, block) } val x by symbol @@ -40,7 +44,7 @@ class SimpleAutoDiffTest { @Test fun testPlusX2() { - val y = RealField.simpleAutoDiff(x to 3.0) { + val y = DoubleField.simpleAutoDiff(x to 3.0) { // diff w.r.t this x at 3 val x = bindSymbol(x) x + x @@ -63,7 +67,7 @@ class SimpleAutoDiffTest { @Test fun testPlus() { // two variables - val z = RealField.simpleAutoDiff(x to 2.0, y to 3.0) { + val z = DoubleField.simpleAutoDiff(x to 2.0, y to 3.0) { val x = bindSymbol(x) val y = bindSymbol(y) x + y @@ -76,7 +80,7 @@ class SimpleAutoDiffTest { @Test fun testMinus() { // two variables - val z = RealField.simpleAutoDiff(x to 7.0, y to 3.0) { + val z = DoubleField.simpleAutoDiff(x to 7.0, y to 3.0) { val x = bindSymbol(x) val y = bindSymbol(y) @@ -281,7 +285,7 @@ class SimpleAutoDiffTest { fun testDivGrad() { val res = dxy(x to 1.0, y to 2.0) { x, y -> x * x + y * y } assertEquals(6.0, res.div()) - assertTrue(res.grad(x, y).contentEquals(doubleArrayOf(2.0, 4.0).asBuffer())) + assertTrue(Buffer.contentEquals(res.grad(x, y), doubleArrayOf(2.0, 4.0).asBuffer())) } private fun assertApprox(a: Double, b: Double) { diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/RealLUSolverTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt similarity index 73% rename from kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/RealLUSolverTest.kt rename to kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt index eb62b36c3..ebbbbe392 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/RealLUSolverTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt @@ -6,17 +6,23 @@ package space.kscience.kmath.linear import space.kscience.kmath.misc.UnstableKMathAPI +import space.kscience.kmath.nd.StructureND import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.test.assertTrue + +fun assertMatrixEquals(expected: StructureND, actual: StructureND) { + assertTrue { StructureND.contentEquals(expected, actual) } +} @UnstableKMathAPI -class RealLUSolverTest { +class DoubleLUSolverTest { @Test fun testInvertOne() { val matrix = LinearSpace.real.one(2, 2) val inverted = LinearSpace.real.inverseWithLup(matrix) - assertEquals(matrix, inverted) + assertMatrixEquals(matrix, inverted) } @Test @@ -32,7 +38,7 @@ class RealLUSolverTest { //Check determinant assertEquals(7.0, lup.determinant) - assertEquals(lup.p dot matrix, lup.l dot lup.u) + assertMatrixEquals(lup.p dot matrix, lup.l dot lup.u) } } @@ -50,6 +56,6 @@ class RealLUSolverTest { -0.125, 0.375 ) - assertEquals(expected, inverted) + assertMatrixEquals(expected, inverted) } } diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt index 5569743cd..250fa3433 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt @@ -6,10 +6,11 @@ package space.kscience.kmath.linear import space.kscience.kmath.misc.UnstableKMathAPI -import space.kscience.kmath.nd.NDStructure +import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.as2D import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.test.assertTrue @UnstableKMathAPI @Suppress("UNUSED_VARIABLE") @@ -18,7 +19,7 @@ class MatrixTest { fun testTranspose() { val matrix = LinearSpace.real.one(3, 3) val transposed = matrix.transpose() - assertEquals(matrix, transposed) + assertTrue { StructureND.contentEquals(matrix, transposed) } } @Test @@ -55,8 +56,8 @@ class MatrixTest { @Test fun test2DDot() { - val firstMatrix = NDStructure.auto(2, 3) { (i, j) -> (i + j).toDouble() }.as2D() - val secondMatrix = NDStructure.auto(3, 2) { (i, j) -> (i + j).toDouble() }.as2D() + val firstMatrix = StructureND.auto(2, 3) { (i, j) -> (i + j).toDouble() }.as2D() + val secondMatrix = StructureND.auto(3, 2) { (i, j) -> (i + j).toDouble() }.as2D() LinearSpace.real.run { // val firstMatrix = produce(2, 3) { i, j -> (i + j).toDouble() } diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/RealFieldTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/DoubleFieldTest.kt similarity index 71% rename from kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/RealFieldTest.kt rename to kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/DoubleFieldTest.kt index d6636550f..c482dc978 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/RealFieldTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/DoubleFieldTest.kt @@ -9,13 +9,13 @@ import space.kscience.kmath.testutils.FieldVerifier import kotlin.test.Test import kotlin.test.assertEquals -internal class RealFieldTest { +internal class DoubleFieldTest { @Test - fun verify() = FieldVerifier(RealField, 42.0, 66.0, 2.0, 5).verify() + fun verify() = FieldVerifier(DoubleField, 42.0, 66.0, 2.0, 5).verify() @Test fun testSqrt() { - val sqrt = RealField { sqrt(25 * one) } + val sqrt = DoubleField { sqrt(25 * one) } assertEquals(5.0, sqrt) } } diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NDFieldTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NDFieldTest.kt index 0257dec9e..fdfa49d1d 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NDFieldTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NDFieldTest.kt @@ -5,7 +5,7 @@ package space.kscience.kmath.structures -import space.kscience.kmath.nd.NDAlgebra +import space.kscience.kmath.nd.AlgebraND import space.kscience.kmath.nd.get import space.kscience.kmath.nd.real import space.kscience.kmath.operations.invoke @@ -16,12 +16,12 @@ import kotlin.test.assertEquals internal class NDFieldTest { @Test fun verify() { - (NDAlgebra.real(12, 32)) { FieldVerifier(this, one + 3, one - 23, one * 12, 6.66) } + (AlgebraND.real(12, 32)) { FieldVerifier(this, one + 3, one - 23, one * 12, 6.66) } } @Test fun testStrides() { - val ndArray = NDAlgebra.real(10, 10).produce { (it[0] + it[1]).toDouble() } + val ndArray = AlgebraND.real(10, 10).produce { (it[0] + it[1]).toDouble() } assertEquals(ndArray[5, 5], 10.0) } } diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt index 95c09d24f..99743d879 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt @@ -16,7 +16,7 @@ import kotlin.test.assertEquals @Suppress("UNUSED_VARIABLE") class NumberNDFieldTest { - val algebra = NDAlgebra.real(3, 3) + val algebra = AlgebraND.real(3, 3) val array1 = algebra.produce { (i, j) -> (i + j).toDouble() } val array2 = algebra.produce { (i, j) -> (i - j).toDouble() } @@ -43,12 +43,11 @@ class NumberNDFieldTest { (i * 10 + j).toDouble() } - for (i in 0..2) { + for (i in 0..2) for (j in 0..2) { val expected = (i * 10 + j).toDouble() assertEquals(expected, array[i, j], "Error at index [$i, $j]") } - } } @Test @@ -74,15 +73,15 @@ class NumberNDFieldTest { val division = array1.combine(array2, Double::div) } - object L2Norm : Norm, Double> { - override fun norm(arg: NDStructure): Double = - kotlin.math.sqrt(arg.elements().sumByDouble { it.second.toDouble() }) + object L2Norm : Norm, Double> { + override fun norm(arg: StructureND): Double = + kotlin.math.sqrt(arg.elements().sumOf { it.second.toDouble() }) } @Test fun testInternalContext() { algebra { - (NDAlgebra.real(*array1.shape)) { with(L2Norm) { 1 + norm(array1) + exp(array2) } } + (AlgebraND.real(*array1.shape)) { with(L2Norm) { 1 + norm(array1) + exp(array2) } } } } } diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/testutils/SpaceVerifier.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/testutils/SpaceVerifier.kt index 71bd6f879..951197fc6 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/testutils/SpaceVerifier.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/testutils/SpaceVerifier.kt @@ -5,7 +5,7 @@ package space.kscience.kmath.testutils -import space.kscience.kmath.operations.Group +import space.kscience.kmath.operations.Ring import space.kscience.kmath.operations.ScaleOperations import space.kscience.kmath.operations.invoke import kotlin.test.assertEquals @@ -17,7 +17,7 @@ internal open class SpaceVerifier( val b: T, val c: T, val x: Number, -) : AlgebraicVerifier> where S : Group, S : ScaleOperations { +) : AlgebraicVerifier> where S : Ring, S : ScaleOperations { override fun verify() { algebra { assertEquals(a + b + c, a + (b + c), "Addition in $algebra is not associative.") diff --git a/kmath-coroutines/build.gradle.kts b/kmath-coroutines/build.gradle.kts index 722c7adee..30f9ce1f9 100644 --- a/kmath-coroutines/build.gradle.kts +++ b/kmath-coroutines/build.gradle.kts @@ -3,7 +3,12 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ -plugins { id("ru.mipt.npm.gradle.mpp") } +import ru.mipt.npm.gradle.Maturity + +plugins { + kotlin("multiplatform") + id("ru.mipt.npm.gradle.common") +} kotlin.sourceSets { all { @@ -23,6 +28,6 @@ kotlin.sourceSets { } } -readme{ - maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL +readme { + maturity = Maturity.EXPERIMENTAL } \ No newline at end of file diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingChain.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingChain.kt new file mode 100644 index 000000000..70849f942 --- /dev/null +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingChain.kt @@ -0,0 +1,55 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.chains + +import space.kscience.kmath.structures.Buffer + + +public interface BufferChain : Chain { + public suspend fun nextBuffer(size: Int): Buffer + override suspend fun fork(): BufferChain +} + +/** + * A chain with blocking generator that could be used without suspension + */ +public interface BlockingChain : Chain { + /** + * Get the next value without concurrency support. Not guaranteed to be thread safe. + */ + public fun nextBlocking(): T + + override suspend fun next(): T = nextBlocking() + + override suspend fun fork(): BlockingChain +} + + +public interface BlockingBufferChain : BlockingChain, BufferChain { + + public fun nextBufferBlocking(size: Int): Buffer + + public override fun nextBlocking(): T = nextBufferBlocking(1)[0] + + public override suspend fun nextBuffer(size: Int): Buffer = nextBufferBlocking(size) + + override suspend fun fork(): BlockingBufferChain +} + + +public suspend inline fun Chain.nextBuffer(size: Int): Buffer = if (this is BufferChain) { + nextBuffer(size) +} else { + Buffer.auto(size) { next() } +} + +public inline fun BlockingChain.nextBufferBlocking( + size: Int, +): Buffer = if (this is BlockingBufferChain) { + nextBufferBlocking(size) +} else { + Buffer.auto(size) { nextBlocking() } +} \ No newline at end of file diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingDoubleChain.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingDoubleChain.kt new file mode 100644 index 000000000..526250cf0 --- /dev/null +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingDoubleChain.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.chains + +import space.kscience.kmath.structures.DoubleBuffer + +/** + * Chunked, specialized chain for double values, which supports blocking [nextBlocking] operation + */ +public interface BlockingDoubleChain : BlockingBufferChain { + + /** + * Returns an [DoubleArray] chunk of [size] values of [next]. + */ + public override fun nextBufferBlocking(size: Int): DoubleBuffer + + override suspend fun fork(): BlockingDoubleChain + + public companion object +} + +public fun BlockingDoubleChain.map(transform: (Double) -> Double): BlockingDoubleChain = object : BlockingDoubleChain { + override fun nextBufferBlocking(size: Int): DoubleBuffer { + val block = this@map.nextBufferBlocking(size) + return DoubleBuffer(size) { transform(block[it]) } + } + + override suspend fun fork(): BlockingDoubleChain = this@map.fork().map(transform) +} \ No newline at end of file diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingIntChain.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingIntChain.kt index 2186cb85f..ac0327d0b 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingIntChain.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingIntChain.kt @@ -5,13 +5,13 @@ package space.kscience.kmath.chains +import space.kscience.kmath.structures.IntBuffer + /** * Performance optimized chain for integer values */ -public abstract class BlockingIntChain : Chain { - public abstract fun nextInt(): Int +public interface BlockingIntChain : BlockingBufferChain { + override fun nextBufferBlocking(size: Int): IntBuffer - override suspend fun next(): Int = nextInt() - - public fun nextBlock(size: Int): IntArray = IntArray(size) { nextInt() } -} + override suspend fun fork(): BlockingIntChain +} \ No newline at end of file diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingRealChain.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingRealChain.kt deleted file mode 100644 index 5ff271721..000000000 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingRealChain.kt +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2018-2021 KMath contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package space.kscience.kmath.chains - -/** - * Performance optimized chain for real values - */ -public abstract class BlockingRealChain : Chain { - public abstract fun nextDouble(): Double - - override suspend fun next(): Double = nextDouble() - - public fun nextBlock(size: Int): DoubleArray = DoubleArray(size) { nextDouble() } -} diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/Chain.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/Chain.kt index 55cfd6523..b29165e32 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/Chain.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/Chain.kt @@ -13,20 +13,20 @@ import kotlinx.coroutines.sync.withLock /** * A not-necessary-Markov chain of some type - * @param R - the chain element type + * @param T - the chain element type */ -public interface Chain : Flow { +public interface Chain : Flow { /** * Generate next value, changing state if needed */ - public suspend fun next(): R + public suspend fun next(): T /** * Create a copy of current chain state. Consuming resulting chain does not affect initial chain */ - public fun fork(): Chain + public suspend fun fork(): Chain - override suspend fun collect(collector: FlowCollector): Unit = + override suspend fun collect(collector: FlowCollector): Unit = flow { while (true) emit(next()) }.collect(collector) public companion object @@ -40,7 +40,7 @@ public fun Sequence.asChain(): Chain = iterator().asChain() */ public class SimpleChain(private val gen: suspend () -> R) : Chain { public override suspend fun next(): R = gen() - public override fun fork(): Chain = this + public override suspend fun fork(): Chain = this } /** @@ -52,15 +52,13 @@ public class MarkovChain(private val seed: suspend () -> R, private public fun value(): R? = value - public override suspend fun next(): R { - mutex.withLock { - val newValue = gen(value ?: seed()) - value = newValue - return newValue - } + public override suspend fun next(): R = mutex.withLock { + val newValue = gen(value ?: seed()) + value = newValue + newValue } - public override fun fork(): Chain = MarkovChain(seed = { value ?: seed() }, gen = gen) + public override suspend fun fork(): Chain = MarkovChain(seed = { value ?: seed() }, gen = gen) } /** @@ -72,22 +70,20 @@ public class StatefulChain( private val state: S, private val seed: S.() -> R, private val forkState: ((S) -> S), - private val gen: suspend S.(R) -> R + private val gen: suspend S.(R) -> R, ) : Chain { private val mutex: Mutex = Mutex() private var value: R? = null public fun value(): R? = value - public override suspend fun next(): R { - mutex.withLock { - val newValue = state.gen(value ?: state.seed()) - value = newValue - return newValue - } + public override suspend fun next(): R = mutex.withLock { + val newValue = state.gen(value ?: state.seed()) + value = newValue + newValue } - public override fun fork(): Chain = StatefulChain(forkState(state), seed, forkState, gen) + public override suspend fun fork(): Chain = StatefulChain(forkState(state), seed, forkState, gen) } /** @@ -95,7 +91,7 @@ public class StatefulChain( */ public class ConstantChain(public val value: T) : Chain { public override suspend fun next(): T = value - public override fun fork(): Chain = this + public override suspend fun fork(): Chain = this } /** @@ -104,7 +100,7 @@ public class ConstantChain(public val value: T) : Chain { */ public fun Chain.map(func: suspend (T) -> R): Chain = object : Chain { override suspend fun next(): R = func(this@map.next()) - override fun fork(): Chain = this@map.fork().map(func) + override suspend fun fork(): Chain = this@map.fork().map(func) } /** @@ -120,7 +116,7 @@ public fun Chain.filter(block: (T) -> Boolean): Chain = object : Chain return next } - override fun fork(): Chain = this@filter.fork().filter(block) + override suspend fun fork(): Chain = this@filter.fork().filter(block) } /** @@ -128,17 +124,17 @@ public fun Chain.filter(block: (T) -> Boolean): Chain = object : Chain */ public fun Chain.collect(mapper: suspend (Chain) -> R): Chain = object : Chain { override suspend fun next(): R = mapper(this@collect) - override fun fork(): Chain = this@collect.fork().collect(mapper) + override suspend fun fork(): Chain = this@collect.fork().collect(mapper) } public fun Chain.collectWithState( state: S, stateFork: (S) -> S, - mapper: suspend S.(Chain) -> R + mapper: suspend S.(Chain) -> R, ): Chain = object : Chain { override suspend fun next(): R = state.mapper(this@collectWithState) - override fun fork(): Chain = + override suspend fun fork(): Chain = this@collectWithState.fork().collectWithState(stateFork(state), stateFork, mapper) } @@ -147,5 +143,5 @@ public fun Chain.collectWithState( */ public fun Chain.zip(other: Chain, block: suspend (T, U) -> R): Chain = object : Chain { override suspend fun next(): R = block(this@zip.next(), other.next()) - override fun fork(): Chain = this@zip.fork().zip(other.fork(), block) + override suspend fun fork(): Chain = this@zip.fork().zip(other.fork(), block) } diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/flowExtra.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/flowExtra.kt index 2bdb9334e..ec1203740 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/flowExtra.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/flowExtra.kt @@ -10,8 +10,8 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.runningReduce import kotlinx.coroutines.flow.scan -import space.kscience.kmath.operations.Group import space.kscience.kmath.operations.GroupOperations +import space.kscience.kmath.operations.Ring import space.kscience.kmath.operations.ScaleOperations import space.kscience.kmath.operations.invoke @@ -19,7 +19,7 @@ public fun Flow.cumulativeSum(group: GroupOperations): Flow = group { runningReduce { sum, element -> sum + element } } @ExperimentalCoroutinesApi -public fun Flow.mean(algebra: S): Flow where S : Group, S : ScaleOperations = algebra { +public fun Flow.mean(space: S): Flow where S : Ring, S : ScaleOperations = space { data class Accumulator(var sum: T, var num: Int) scan(Accumulator(zero, 0)) { sum, element -> diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/coroutines/coroutinesExtra.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/coroutines/coroutinesExtra.kt index c796a14c2..49f32f82f 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/coroutines/coroutinesExtra.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/coroutines/coroutinesExtra.kt @@ -32,7 +32,7 @@ public class AsyncFlow internal constructor(internal val deferredFlow: Flow Flow.async( dispatcher: CoroutineDispatcher = Dispatchers.Default, - block: suspend CoroutineScope.(T) -> R + block: suspend CoroutineScope.(T) -> R, ): AsyncFlow { val flow = map { LazyDeferred(dispatcher) { block(it) } } return AsyncFlow(flow) @@ -77,12 +77,12 @@ public suspend fun AsyncFlow.collect(concurrency: Int, collector: FlowCol public suspend inline fun AsyncFlow.collect( concurrency: Int, - crossinline action: suspend (value: T) -> Unit + crossinline action: suspend (value: T) -> Unit, ): Unit = collect(concurrency, object : FlowCollector { override suspend fun emit(value: T): Unit = action(value) }) public inline fun Flow.mapParallel( dispatcher: CoroutineDispatcher = Dispatchers.Default, - crossinline transform: suspend (T) -> R + crossinline transform: suspend (T) -> R, ): Flow = flatMapMerge { value -> flow { emit(transform(value)) } }.flowOn(dispatcher) diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt index 00b19c655..0d6a1178a 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt @@ -7,11 +7,10 @@ package space.kscience.kmath.streaming import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.* -import space.kscience.kmath.chains.BlockingRealChain +import space.kscience.kmath.chains.BlockingDoubleChain import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.BufferFactory -import space.kscience.kmath.structures.RealBuffer -import space.kscience.kmath.structures.asBuffer +import space.kscience.kmath.structures.DoubleBuffer /** * Create a [Flow] from buffer @@ -33,7 +32,7 @@ public fun Flow.chunked(bufferSize: Int, bufferFactory: BufferFactory) var counter = 0 this@chunked.collect { element -> - list.add(element) + list += element counter++ if (counter == bufferSize) { @@ -50,12 +49,12 @@ public fun Flow.chunked(bufferSize: Int, bufferFactory: BufferFactory) /** * Specialized flow chunker for real buffer */ -public fun Flow.chunked(bufferSize: Int): Flow = flow { +public fun Flow.chunked(bufferSize: Int): Flow = flow { require(bufferSize > 0) { "Resulting chunk size must be more than zero" } - if (this@chunked is BlockingRealChain) { + if (this@chunked is BlockingDoubleChain) { // performance optimization for blocking primitive chain - while (true) emit(nextBlock(bufferSize).asBuffer()) + while (true) emit(nextBufferBlocking(bufferSize)) } else { val array = DoubleArray(bufferSize) var counter = 0 @@ -65,13 +64,13 @@ public fun Flow.chunked(bufferSize: Int): Flow = flow { counter++ if (counter == bufferSize) { - val buffer = RealBuffer(array) + val buffer = DoubleBuffer(array) emit(buffer) counter = 0 } } - if (counter > 0) emit(RealBuffer(counter) { array[it] }) + if (counter > 0) emit(DoubleBuffer(counter) { array[it] }) } } diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt index 395613ef2..05f2876e3 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt @@ -18,7 +18,7 @@ import space.kscience.kmath.structures.VirtualBuffer public class RingBuffer( private val buffer: MutableBuffer, private var startIndex: Int = 0, - size: Int = 0 + size: Int = 0, ) : Buffer { private val mutex: Mutex = Mutex() @@ -53,11 +53,9 @@ public class RingBuffer( /** * A safe snapshot operation */ - public suspend fun snapshot(): Buffer { - mutex.withLock { - val copy = buffer.copy() - return VirtualBuffer(size) { i -> copy[startIndex.forward(i)] as T } - } + public suspend fun snapshot(): Buffer = mutex.withLock { + val copy = buffer.copy() + VirtualBuffer(size) { i -> copy[startIndex.forward(i)] as T } } public suspend fun push(element: T) { diff --git a/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyNDStructure.kt b/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyNDStructure.kt deleted file mode 100644 index 0241c32f7..000000000 --- a/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyNDStructure.kt +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2018-2021 KMath contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package space.kscience.kmath.structures - -import kotlinx.coroutines.* -import space.kscience.kmath.coroutines.Math -import space.kscience.kmath.nd.DefaultStrides -import space.kscience.kmath.nd.NDStructure - -public class LazyNDStructure( - public val scope: CoroutineScope, - public override val shape: IntArray, - public val function: suspend (IntArray) -> T -) : NDStructure { - private val cache: MutableMap> = hashMapOf() - - public fun deferred(index: IntArray): Deferred = cache.getOrPut(index) { - scope.async(context = Dispatchers.Math) { function(index) } - } - - public suspend fun await(index: IntArray): T = deferred(index).await() - public override operator fun get(index: IntArray): T = runBlocking { deferred(index).await() } - - public override fun elements(): Sequence> { - val strides = DefaultStrides(shape) - val res = runBlocking { strides.indices().toList().map { index -> index to await(index) } } - return res.asSequence() - } - - public override fun equals(other: Any?): Boolean { - return NDStructure.contentEquals(this, other as? NDStructure<*> ?: return false) - } - - public override fun hashCode(): Int { - var result = scope.hashCode() - result = 31 * result + shape.contentHashCode() - result = 31 * result + function.hashCode() - result = 31 * result + cache.hashCode() - return result - } -} - -public fun NDStructure.deferred(index: IntArray): Deferred = - if (this is LazyNDStructure) deferred(index) else CompletableDeferred(get(index)) - -public suspend fun NDStructure.await(index: IntArray): T = - if (this is LazyNDStructure) await(index) else get(index) - -/** - * PENDING would benefit from KEEP-176 - */ -public inline fun NDStructure.mapAsyncIndexed( - scope: CoroutineScope, - crossinline function: suspend (T, index: IntArray) -> R -): LazyNDStructure = LazyNDStructure(scope, shape) { index -> function(get(index), index) } - -public inline fun NDStructure.mapAsync( - scope: CoroutineScope, - crossinline function: suspend (T) -> R -): LazyNDStructure = LazyNDStructure(scope, shape) { index -> function(get(index)) } diff --git a/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt b/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt new file mode 100644 index 000000000..e2ecb4b2f --- /dev/null +++ b/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.structures + +import kotlinx.coroutines.* +import space.kscience.kmath.coroutines.Math +import space.kscience.kmath.nd.DefaultStrides +import space.kscience.kmath.nd.StructureND + +public class LazyStructureND( + public val scope: CoroutineScope, + public override val shape: IntArray, + public val function: suspend (IntArray) -> T, +) : StructureND { + private val cache: MutableMap> = HashMap() + + public fun deferred(index: IntArray): Deferred = cache.getOrPut(index) { + scope.async(context = Dispatchers.Math) { function(index) } + } + + public suspend fun await(index: IntArray): T = deferred(index).await() + public override operator fun get(index: IntArray): T = runBlocking { deferred(index).await() } + + public override fun elements(): Sequence> { + val strides = DefaultStrides(shape) + val res = runBlocking { strides.indices().toList().map { index -> index to await(index) } } + return res.asSequence() + } +} + +public fun StructureND.deferred(index: IntArray): Deferred = + if (this is LazyStructureND) deferred(index) else CompletableDeferred(get(index)) + +public suspend fun StructureND.await(index: IntArray): T = + if (this is LazyStructureND) await(index) else get(index) + +/** + * PENDING would benefit from KEEP-176 + */ +public inline fun StructureND.mapAsyncIndexed( + scope: CoroutineScope, + crossinline function: suspend (T, index: IntArray) -> R, +): LazyStructureND = LazyStructureND(scope, shape) { index -> function(get(index), index) } + +public inline fun StructureND.mapAsync( + scope: CoroutineScope, + crossinline function: suspend (T) -> R, +): LazyStructureND = LazyStructureND(scope, shape) { index -> function(get(index)) } diff --git a/kmath-dimensions/build.gradle.kts b/kmath-dimensions/build.gradle.kts index 0702d4bc8..a9a9177c0 100644 --- a/kmath-dimensions/build.gradle.kts +++ b/kmath-dimensions/build.gradle.kts @@ -4,7 +4,8 @@ */ plugins { - id("ru.mipt.npm.gradle.mpp") + kotlin("multiplatform") + id("ru.mipt.npm.gradle.common") id("ru.mipt.npm.gradle.native") } @@ -24,6 +25,6 @@ kotlin.sourceSets { } } -readme{ +readme { maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE } diff --git a/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt b/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt index 3f7dcadc4..2ebcc454d 100644 --- a/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt +++ b/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt @@ -5,10 +5,14 @@ package space.kscience.kmath.dimensions -import space.kscience.kmath.linear.* +import space.kscience.kmath.linear.LinearSpace +import space.kscience.kmath.linear.Matrix +import space.kscience.kmath.linear.Point +import space.kscience.kmath.linear.transpose import space.kscience.kmath.nd.Structure2D -import space.kscience.kmath.operations.RealField +import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Ring +import kotlin.jvm.JvmInline /** * A matrix with compile-time controlled dimension @@ -41,7 +45,8 @@ public interface DMatrix : Structure2D { /** * An inline wrapper for a Matrix */ -public inline class DMatrixWrapper( +@JvmInline +public value class DMatrixWrapper( private val structure: Structure2D, ) : DMatrix { override val shape: IntArray get() = structure.shape @@ -70,7 +75,8 @@ public interface DPoint : Point { /** * Dimension-safe point wrapper */ -public inline class DPointWrapper(public val point: Point) : +@JvmInline +public value class DPointWrapper(public val point: Point) : DPoint { override val size: Int get() = point.size @@ -83,7 +89,8 @@ public inline class DPointWrapper(public val point: Point) /** * Basic operations on dimension-safe matrices. Operates on [Matrix] */ -public inline class DMatrixContext>(public val context: LinearSpace) { +@JvmInline +public value class DMatrixContext>(public val context: LinearSpace) { public inline fun Matrix.coerce(): DMatrix { require(rowNum == Dimension.dim().toInt()) { "Row number mismatch: expected ${Dimension.dim()} but found $rowNum" @@ -100,7 +107,7 @@ public inline class DMatrixContext>(public val context: * Produce a matrix with this context and given dimensions */ public inline fun produce( - noinline initializer: A.(i: Int, j: Int) -> T + noinline initializer: A.(i: Int, j: Int) -> T, ): DMatrix { val rows = Dimension.dim() val cols = Dimension.dim() @@ -144,7 +151,7 @@ public inline class DMatrixContext>(public val context: context.run { (this@transpose as Matrix).transpose() }.coerce() public companion object { - public val real: DMatrixContext = DMatrixContext(LinearSpace.real) + public val real: DMatrixContext = DMatrixContext(LinearSpace.real) } } @@ -152,11 +159,12 @@ public inline class DMatrixContext>(public val context: /** * A square unit matrix */ -public inline fun DMatrixContext.one(): DMatrix = produce { i, j -> - if (i == j) 1.0 else 0.0 -} +public inline fun DMatrixContext.one(): DMatrix = + produce { i, j -> + if (i == j) 1.0 else 0.0 + } -public inline fun DMatrixContext.zero(): DMatrix = +public inline fun DMatrixContext.zero(): DMatrix = produce { _, _ -> 0.0 } \ No newline at end of file diff --git a/kmath-dimensions/src/commonTest/kotlin/kscience/dimensions/DMatrixContextTest.kt b/kmath-dimensions/src/commonTest/kotlin/kscience/dimensions/DMatrixContextTest.kt index c9d5ee6e7..59260fe73 100644 --- a/kmath-dimensions/src/commonTest/kotlin/kscience/dimensions/DMatrixContextTest.kt +++ b/kmath-dimensions/src/commonTest/kotlin/kscience/dimensions/DMatrixContextTest.kt @@ -3,7 +3,7 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ -package kscience.dimensions +package space.kscience.dimensions import space.kscience.kmath.dimensions.D2 import space.kscience.kmath.dimensions.D3 diff --git a/kmath-ejml/README.md b/kmath-ejml/README.md new file mode 100644 index 000000000..cae11724d --- /dev/null +++ b/kmath-ejml/README.md @@ -0,0 +1,37 @@ +# Module kmath-ejml + +EJML based linear algebra implementation. + + - [ejml-vector](src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : The Point implementation using SimpleMatrix. + - [ejml-matrix](src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : The Matrix implementation using SimpleMatrix. + - [ejml-linear-space](src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : The LinearSpace implementation using SimpleMatrix. + + +## Artifact: + +The Maven coordinates of this project are `space.kscience:kmath-ejml:0.3.0-dev-6`. + +**Gradle:** +```gradle +repositories { + maven { url 'https://repo.kotlin.link' } + maven { url 'https://dl.bintray.com/hotkeytlt/maven' } + maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap +} + +dependencies { + implementation 'space.kscience:kmath-ejml:0.3.0-dev-6' +} +``` +**Gradle Kotlin DSL:** +```kotlin +repositories { + maven("https://repo.kotlin.link") + maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap + maven("https://dl.bintray.com/hotkeytlt/maven") // required for a +} + +dependencies { + implementation("space.kscience:kmath-ejml:0.3.0-dev-6") +} +``` diff --git a/kmath-ejml/build.gradle.kts b/kmath-ejml/build.gradle.kts index f1286310c..6ae0dcec6 100644 --- a/kmath-ejml/build.gradle.kts +++ b/kmath-ejml/build.gradle.kts @@ -3,15 +3,37 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ +import ru.mipt.npm.gradle.Maturity + plugins { - id("ru.mipt.npm.gradle.jvm") + kotlin("jvm") + id("ru.mipt.npm.gradle.common") } dependencies { - implementation("org.ejml:ejml-simple:0.39") - implementation(project(":kmath-core")) + api("org.ejml:ejml-simple:0.40") + api(project(":kmath-core")) } -readme{ - maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE -} \ No newline at end of file +readme { + maturity = Maturity.PROTOTYPE + propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md")) + + feature( + id = "ejml-vector", + description = "The Point implementation using SimpleMatrix.", + ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt" + ) + + feature( + id = "ejml-matrix", + description = "The Matrix implementation using SimpleMatrix.", + ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt" + ) + + feature( + id = "ejml-linear-space", + description = "The LinearSpace implementation using SimpleMatrix.", + ref = "src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt" + ) +} diff --git a/kmath-ejml/docs/README-TEMPLATE.md b/kmath-ejml/docs/README-TEMPLATE.md new file mode 100644 index 000000000..27fcedd65 --- /dev/null +++ b/kmath-ejml/docs/README-TEMPLATE.md @@ -0,0 +1,7 @@ +# Module kmath-ejml + +EJML based linear algebra implementation. + +${features} + +${artifact} diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt index 3905d9418..4b6421c9b 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt @@ -9,9 +9,10 @@ import org.ejml.dense.row.factory.DecompositionFactory_DDRM import org.ejml.simple.SimpleMatrix import space.kscience.kmath.linear.* import space.kscience.kmath.misc.UnstableKMathAPI +import space.kscience.kmath.nd.StructureFeature import space.kscience.kmath.nd.getFeature -import space.kscience.kmath.operations.RealField -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 @@ -19,10 +20,13 @@ import kotlin.reflect.cast * Represents context of basic operations operating with [EjmlMatrix]. * * @author Iaroslav Postovalov + * @author Alexander Nozik */ -public object EjmlLinearSpace : LinearSpace { - - override val elementAlgebra: RealField get() = RealField +public object EjmlLinearSpace : LinearSpace { + /** + * The [DoubleField] reference. + */ + public override val elementAlgebra: DoubleField get() = DoubleField /** * Converts this matrix to EJML one. @@ -43,22 +47,25 @@ public object EjmlLinearSpace : LinearSpace { }) } - override fun buildMatrix(rows: Int, columns: Int, initializer: RealField.(i: Int, j: Int) -> Double): EjmlMatrix = - EjmlMatrix(SimpleMatrix(rows, columns).also { - (0 until rows).forEach { row -> - (0 until columns).forEach { col -> it[row, col] = RealField.initializer(row, col) } - } - }) + public override fun buildMatrix( + rows: Int, + columns: Int, + initializer: DoubleField.(i: Int, j: Int) -> Double, + ): EjmlMatrix = EjmlMatrix(SimpleMatrix(rows, columns).also { + (0 until rows).forEach { row -> + (0 until columns).forEach { col -> it[row, col] = DoubleField.initializer(row, col) } + } + }) - override fun buildVector(size: Int, initializer: RealField.(Int) -> Double): Point = + public override fun buildVector(size: Int, initializer: DoubleField.(Int) -> Double): Point = EjmlVector(SimpleMatrix(size, 1).also { - (0 until it.numRows()).forEach { row -> it[row, 0] = RealField.initializer(row) } + (0 until it.numRows()).forEach { row -> it[row, 0] = DoubleField.initializer(row) } }) private fun SimpleMatrix.wrapMatrix() = EjmlMatrix(this) private fun SimpleMatrix.wrapVector() = EjmlVector(this) - override fun Matrix.unaryMinus(): Matrix = this * (-1.0) + public override fun Matrix.unaryMinus(): Matrix = this * (-1.0) public override fun Matrix.dot(other: Matrix): EjmlMatrix = EjmlMatrix(toEjml().origin.mult(other.toEjml().origin)) @@ -72,29 +79,29 @@ public object EjmlLinearSpace : LinearSpace { public override operator fun Matrix.times(value: Double): EjmlMatrix = toEjml().origin.scale(value).wrapMatrix() - override fun Point.unaryMinus(): EjmlVector = + public override fun Point.unaryMinus(): EjmlVector = toEjml().origin.negative().wrapVector() - override fun Matrix.plus(other: Matrix): EjmlMatrix = + public override fun Matrix.plus(other: Matrix): EjmlMatrix = (toEjml().origin + other.toEjml().origin).wrapMatrix() - override fun Point.plus(other: Point): EjmlVector = + public override fun Point.plus(other: Point): EjmlVector = (toEjml().origin + other.toEjml().origin).wrapVector() - override fun Point.minus(other: Point): EjmlVector = + public override fun Point.minus(other: Point): EjmlVector = (toEjml().origin - other.toEjml().origin).wrapVector() - override fun Double.times(m: Matrix): EjmlMatrix = + public override fun Double.times(m: Matrix): EjmlMatrix = m.toEjml().origin.scale(this).wrapMatrix() - override fun Point.times(value: Double): EjmlVector = + public override fun Point.times(value: Double): EjmlVector = toEjml().origin.scale(value).wrapVector() - override fun Double.times(v: Point): EjmlVector = + public override fun Double.times(v: Point): EjmlVector = v.toEjml().origin.scale(this).wrapVector() @UnstableKMathAPI - override fun getFeature(structure: Matrix, type: KClass): F? { + public override fun getFeature(structure: Matrix, type: KClass): F? { //Return the feature if it is intrinsic to the structure structure.getFeature(type)?.let { return it } @@ -118,7 +125,7 @@ public object EjmlLinearSpace : LinearSpace { override val u: Matrix by lazy { EjmlMatrix(SimpleMatrix(svd.getU(null, false))) } override val s: Matrix by lazy { EjmlMatrix(SimpleMatrix(svd.getW(null))) } override val v: Matrix by lazy { EjmlMatrix(SimpleMatrix(svd.getV(null, false))) } - override val singularValues: Point by lazy { RealBuffer(svd.singularValues) } + override val singularValues: Point by lazy { DoubleBuffer(svd.singularValues) } } QRDecompositionFeature::class -> object : QRDecompositionFeature { @@ -165,7 +172,7 @@ public object EjmlLinearSpace : LinearSpace { } /** - * Solves for X in the following equation: x = a^-1*b, where 'a' is base matrix and 'b' is an n by p matrix. + * Solves for *x* in the following equation: *x = [a] -1 · [b]*. * * @param a the base matrix. * @param b n by p matrix. @@ -176,7 +183,7 @@ public fun EjmlLinearSpace.solve(a: Matrix, b: Matrix): EjmlMatr EjmlMatrix(a.toEjml().origin.solve(b.toEjml().origin)) /** - * Solves for X in the following equation: x = a^(-1)*b, where 'a' is base matrix and 'b' is an n by p matrix. + * Solves for *x* in the following equation: *x = [a] -1 · [b]*. * * @param a the base matrix. * @param b n by p vector. @@ -186,7 +193,17 @@ public fun EjmlLinearSpace.solve(a: Matrix, b: Matrix): EjmlMatr public fun EjmlLinearSpace.solve(a: Matrix, b: Point): EjmlVector = EjmlVector(a.toEjml().origin.solve(b.toEjml().origin)) +/** + * Inverts this matrix. + * + * @author Alexander Nozik + */ @OptIn(UnstableKMathAPI::class) public fun EjmlMatrix.inverted(): EjmlMatrix = getFeature>()!!.inverse as EjmlMatrix +/** + * Inverts the given matrix. + * + * @author Alexander Nozik + */ public fun EjmlLinearSpace.inverse(matrix: Matrix): Matrix = matrix.toEjml().inverted() \ No newline at end of file diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt index 656871034..32907d199 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt @@ -7,10 +7,9 @@ package space.kscience.kmath.ejml import org.ejml.simple.SimpleMatrix import space.kscience.kmath.linear.Matrix -import space.kscience.kmath.nd.NDStructure /** - * Represents featured matrix over EJML [SimpleMatrix]. + * The matrix implementation over EJML [SimpleMatrix]. * * @property origin the underlying [SimpleMatrix]. * @author Iaroslav Postovalov @@ -20,14 +19,4 @@ public class EjmlMatrix(public val origin: SimpleMatrix) : Matrix { public override val colNum: Int get() = origin.numCols() public override operator fun get(i: Int, j: Int): Double = origin[i, j] - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is NDStructure<*>) return false - return NDStructure.contentEquals(this, other) - } - - override fun hashCode(): Int = origin.hashCode() - - } diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt index ddf543d91..2f4b4a8e2 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt @@ -7,7 +7,6 @@ package space.kscience.kmath.ejml import org.ejml.simple.SimpleMatrix import space.kscience.kmath.linear.Point -import space.kscience.kmath.structures.Buffer /** * Represents point over EJML [SimpleMatrix]. @@ -36,10 +35,5 @@ public class EjmlVector internal constructor(public val origin: SimpleMatrix) : override fun hasNext(): Boolean = cursor < origin.numCols() * origin.numRows() } - public override fun contentEquals(other: Buffer<*>): Boolean { - if (other is EjmlVector) return origin.isIdentical(other.origin, 0.0) - return super.contentEquals(other) - } - public override fun toString(): String = "EjmlVector(origin=$origin)" } diff --git a/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt b/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt index e4a65858e..59f9602d6 100644 --- a/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt +++ b/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt @@ -9,11 +9,16 @@ import org.ejml.dense.row.factory.DecompositionFactory_DDRM import org.ejml.simple.SimpleMatrix import space.kscience.kmath.linear.* import space.kscience.kmath.misc.UnstableKMathAPI +import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.getFeature import kotlin.random.Random import kotlin.random.asJavaRandom import kotlin.test.* +fun assertMatrixEquals(expected: StructureND, actual: StructureND) { + assertTrue { StructureND.contentEquals(expected, actual) } +} + internal class EjmlMatrixTest { private val random = Random(0) @@ -54,9 +59,9 @@ internal class EjmlMatrixTest { val ludecompositionF64 = DecompositionFactory_DDRM.lu(m.numRows(), m.numCols()) .also { it.decompose(m.ddrm.copy()) } - assertEquals(EjmlMatrix(SimpleMatrix(ludecompositionF64.getLower(null))), lup.l) - assertEquals(EjmlMatrix(SimpleMatrix(ludecompositionF64.getUpper(null))), lup.u) - assertEquals(EjmlMatrix(SimpleMatrix(ludecompositionF64.getRowPivot(null))), lup.p) + assertMatrixEquals(EjmlMatrix(SimpleMatrix(ludecompositionF64.getLower(null))), lup.l) + assertMatrixEquals(EjmlMatrix(SimpleMatrix(ludecompositionF64.getUpper(null))), lup.u) + assertMatrixEquals(EjmlMatrix(SimpleMatrix(ludecompositionF64.getRowPivot(null))), lup.p) } private object SomeFeature : MatrixFeature {} diff --git a/kmath-for-real/README.md b/kmath-for-real/README.md index 4cc434787..922e6572b 100644 --- a/kmath-for-real/README.md +++ b/kmath-for-real/README.md @@ -1,41 +1,37 @@ -# Real number specialization module (`kmath-for-real`) +# Module kmath-for-real - - [RealVector](src/commonMain/kotlin/kscience/kmath/real/RealVector.kt) : Numpy-like operations for Buffers/Points - - [RealMatrix](src/commonMain/kotlin/kscience/kmath/real/RealMatrix.kt) : Numpy-like operations for 2d real structures - - [grids](src/commonMain/kotlin/kscience/kmath/structures/grids.kt) : Uniform grid generators +Specialization of KMath APIs for Double numbers. + + - [DoubleVector](src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt) : Numpy-like operations for Buffers/Points + - [DoubleMatrix](src/commonMain/kotlin/space/kscience/kmath/real/DoubleMatrix.kt) : Numpy-like operations for 2d real structures + - [grids](src/commonMain/kotlin/space/kscience/kmath/structures/grids.kt) : Uniform grid generators -> #### Artifact: -> -> This module artifact: `space.kscience:kmath-for-real:0.3.0-dev-2`. -> -> Bintray release version: [ ![Download](https://api.bintray.com/packages/mipt-npm/kscience/kmath-for-real/images/download.svg) ](https://bintray.com/mipt-npm/kscience/kmath-for-real/_latestVersion) -> -> Bintray development version: [ ![Download](https://api.bintray.com/packages/mipt-npm/dev/kmath-for-real/images/download.svg) ](https://bintray.com/mipt-npm/dev/kmath-for-real/_latestVersion) -> -> **Gradle:** -> -> ```gradle -> repositories { -> maven { url 'https://repo.kotlin.link' } -> maven { url 'https://dl.bintray.com/hotkeytlt/maven' } -> maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap -> } -> -> dependencies { -> implementation 'space.kscience:kmath-for-real:0.3.0-dev-2' -> } -> ``` -> **Gradle Kotlin DSL:** -> -> ```kotlin -> repositories { -> maven("https://repo.kotlin.link") -> maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap -> maven("https://dl.bintray.com/hotkeytlt/maven") // required for a -> } -> -> dependencies { -> implementation("space.kscience:kmath-for-real:0.3.0-dev-2") -> } -> ``` +## Artifact: + +The Maven coordinates of this project are `space.kscience:kmath-for-real:0.3.0-dev-6`. + +**Gradle:** +```gradle +repositories { + maven { url 'https://repo.kotlin.link' } + maven { url 'https://dl.bintray.com/hotkeytlt/maven' } + maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap +} + +dependencies { + implementation 'space.kscience:kmath-for-real:0.3.0-dev-6' +} +``` +**Gradle Kotlin DSL:** +```kotlin +repositories { + maven("https://repo.kotlin.link") + maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap + maven("https://dl.bintray.com/hotkeytlt/maven") // required for a +} + +dependencies { + implementation("space.kscience:kmath-for-real:0.3.0-dev-6") +} +``` diff --git a/kmath-for-real/build.gradle.kts b/kmath-for-real/build.gradle.kts index c2be77d5f..fc454205b 100644 --- a/kmath-for-real/build.gradle.kts +++ b/kmath-for-real/build.gradle.kts @@ -3,8 +3,11 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ +import ru.mipt.npm.gradle.Maturity + plugins { - id("ru.mipt.npm.gradle.mpp") + kotlin("multiplatform") + id("ru.mipt.npm.gradle.common") } kotlin.sourceSets.commonMain { @@ -19,24 +22,24 @@ readme { All operations are specialized to work with `Double` numbers without declaring algebraic contexts. One can still use generic algebras though. """.trimIndent() - maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL + maturity = Maturity.EXPERIMENTAL propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md")) feature( - id = "RealVector", + id = "DoubleVector", description = "Numpy-like operations for Buffers/Points", - ref = "src/commonMain/kotlin/kscience/kmath/real/RealVector.kt" + ref = "src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt" ) feature( - id = "RealMatrix", + id = "DoubleMatrix", description = "Numpy-like operations for 2d real structures", - ref = "src/commonMain/kotlin/kscience/kmath/real/RealMatrix.kt" + ref = "src/commonMain/kotlin/space/kscience/kmath/real/DoubleMatrix.kt" ) feature( id = "grids", description = "Uniform grid generators", - ref = "src/commonMain/kotlin/kscience/kmath/structures/grids.kt" + ref = "src/commonMain/kotlin/space/kscience/kmath/structures/grids.kt" ) } diff --git a/kmath-for-real/docs/README-TEMPLATE.md b/kmath-for-real/docs/README-TEMPLATE.md index 670844bd0..c2ef25aa7 100644 --- a/kmath-for-real/docs/README-TEMPLATE.md +++ b/kmath-for-real/docs/README-TEMPLATE.md @@ -1,4 +1,6 @@ -# Real number specialization module (`kmath-for-real`) +# Module kmath-for-real + +Specialization of KMath APIs for Double numbers. ${features} diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt index b2c391c3b..c4656dd8a 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt @@ -7,9 +7,9 @@ package space.kscience.kmath.real import space.kscience.kmath.linear.* import space.kscience.kmath.misc.UnstableKMathAPI -import space.kscience.kmath.operations.RealField +import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.RealBuffer +import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.asIterable import kotlin.math.pow @@ -27,11 +27,11 @@ import kotlin.math.pow public typealias RealMatrix = Matrix -public fun realMatrix(rowNum: Int, colNum: Int, initializer: RealField.(i: Int, j: Int) -> Double): RealMatrix = +public fun realMatrix(rowNum: Int, colNum: Int, initializer: DoubleField.(i: Int, j: Int) -> Double): RealMatrix = LinearSpace.real.buildMatrix(rowNum, colNum, initializer) @OptIn(UnstableKMathAPI::class) -public fun realMatrix(rowNum: Int, colNum: Int): MatrixBuilder = +public fun realMatrix(rowNum: Int, colNum: Int): MatrixBuilder = LinearSpace.real.matrix(rowNum, colNum) public fun Array.toMatrix(): RealMatrix { @@ -125,19 +125,19 @@ public fun RealMatrix.extractColumns(columnRange: IntRange): RealMatrix = public fun RealMatrix.extractColumn(columnIndex: Int): RealMatrix = extractColumns(columnIndex..columnIndex) -public fun RealMatrix.sumByColumn(): RealBuffer = RealBuffer(colNum) { j -> +public fun RealMatrix.sumByColumn(): DoubleBuffer = DoubleBuffer(colNum) { j -> columns[j].asIterable().sum() } -public fun RealMatrix.minByColumn(): RealBuffer = RealBuffer(colNum) { j -> +public fun RealMatrix.minByColumn(): DoubleBuffer = DoubleBuffer(colNum) { j -> columns[j].asIterable().minOrNull() ?: error("Cannot produce min on empty column") } -public fun RealMatrix.maxByColumn(): RealBuffer = RealBuffer(colNum) { j -> +public fun RealMatrix.maxByColumn(): DoubleBuffer = DoubleBuffer(colNum) { j -> columns[j].asIterable().maxOrNull() ?: error("Cannot produce min on empty column") } -public fun RealMatrix.averageByColumn(): RealBuffer = RealBuffer(colNum) { j -> +public fun RealMatrix.averageByColumn(): DoubleBuffer = DoubleBuffer(colNum) { j -> columns[j].asIterable().average() } diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealVector.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealVector.kt index a0802f5e0..d3867ea89 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealVector.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealVector.kt @@ -9,101 +9,104 @@ import space.kscience.kmath.linear.Point import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.operations.Norm import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.MutableBuffer.Companion.real +import space.kscience.kmath.structures.MutableBuffer.Companion.double import space.kscience.kmath.structures.asBuffer -import space.kscience.kmath.structures.asIterable +import space.kscience.kmath.structures.fold import space.kscience.kmath.structures.indices import kotlin.math.pow import kotlin.math.sqrt -public typealias RealVector = Point +public typealias DoubleVector = Point -public object VectorL2Norm : Norm, Double> { - override fun norm(arg: Point): Double = sqrt(arg.asIterable().sumByDouble(Number::toDouble)) -} - -public operator fun Buffer.Companion.invoke(vararg doubles: Double): RealVector = doubles.asBuffer() +@Suppress("FunctionName") +public fun DoubleVector(vararg doubles: Double): DoubleVector = doubles.asBuffer() /** * Fill the vector of given [size] with given [value] */ @UnstableKMathAPI -public fun Buffer.Companion.same(size: Int, value: Number): RealVector = real(size) { value.toDouble() } +public fun Buffer.Companion.same(size: Int, value: Number): DoubleVector = double(size) { value.toDouble() } // Transformation methods -public inline fun RealVector.map(transform: (Double) -> Double): RealVector = - real(size) { transform(get(it)) } +public inline fun DoubleVector.map(transform: (Double) -> Double): DoubleVector = + double(size) { transform(get(it)) } -public inline fun RealVector.mapIndexed(transform: (index: Int, value: Double) -> Double): RealVector = - real(size) { transform(it, get(it)) } +public inline fun DoubleVector.mapIndexed(transform: (index: Int, value: Double) -> Double): DoubleVector = + double(size) { transform(it, get(it)) } -public operator fun RealVector.plus(other: RealVector): RealVector { +public operator fun DoubleVector.plus(other: DoubleVector): DoubleVector { require(size == other.size) { "Vector size $size expected but ${other.size} found" } return mapIndexed { index, value -> value + other[index] } } -public operator fun RealVector.plus(number: Number): RealVector = map { it + number.toDouble() } +public operator fun DoubleVector.plus(number: Number): DoubleVector = map { it + number.toDouble() } -public operator fun Number.plus(vector: RealVector): RealVector = vector + this +public operator fun Number.plus(vector: DoubleVector): DoubleVector = vector + this -public operator fun RealVector.unaryMinus(): Buffer = map { -it } +public operator fun DoubleVector.unaryMinus(): Buffer = map { -it } -public operator fun RealVector.minus(other: RealVector): RealVector { +public operator fun DoubleVector.minus(other: DoubleVector): DoubleVector { require(size == other.size) { "Vector size $size expected but ${other.size} found" } return mapIndexed { index, value -> value - other[index] } } -public operator fun RealVector.minus(number: Number): RealVector = map { it - number.toDouble() } +public operator fun DoubleVector.minus(number: Number): DoubleVector = map { it - number.toDouble() } -public operator fun Number.minus(vector: RealVector): RealVector = vector.map { toDouble() - it } +public operator fun Number.minus(vector: DoubleVector): DoubleVector = vector.map { toDouble() - it } -public operator fun RealVector.times(other: RealVector): RealVector { +public operator fun DoubleVector.times(other: DoubleVector): DoubleVector { require(size == other.size) { "Vector size $size expected but ${other.size} found" } return mapIndexed { index, value -> value * other[index] } } -public operator fun RealVector.times(number: Number): RealVector = map { it * number.toDouble() } +public operator fun DoubleVector.times(number: Number): DoubleVector = map { it * number.toDouble() } -public operator fun Number.times(vector: RealVector): RealVector = vector * this +public operator fun Number.times(vector: DoubleVector): DoubleVector = vector * this -public operator fun RealVector.div(other: RealVector): RealVector { +public operator fun DoubleVector.div(other: DoubleVector): DoubleVector { require(size == other.size) { "Vector size $size expected but ${other.size} found" } return mapIndexed { index, value -> value / other[index] } } -public operator fun RealVector.div(number: Number): RealVector = map { it / number.toDouble() } +public operator fun DoubleVector.div(number: Number): DoubleVector = map { it / number.toDouble() } -public operator fun Number.div(vector: RealVector): RealVector = vector.map { toDouble() / it } +public operator fun Number.div(vector: DoubleVector): DoubleVector = vector.map { toDouble() / it } //extended operations -public fun RealVector.pow(p: Double): RealVector = map { it.pow(p) } +public fun DoubleVector.pow(p: Double): DoubleVector = map { it.pow(p) } -public fun RealVector.pow(p: Int): RealVector = map { it.pow(p) } +public fun DoubleVector.pow(p: Int): DoubleVector = map { it.pow(p) } -public fun exp(vector: RealVector): RealVector = vector.map { kotlin.math.exp(it) } +public fun exp(vector: DoubleVector): DoubleVector = vector.map { kotlin.math.exp(it) } -public fun sqrt(vector: RealVector): RealVector = vector.map { kotlin.math.sqrt(it) } +public fun sqrt(vector: DoubleVector): DoubleVector = vector.map { kotlin.math.sqrt(it) } -public fun RealVector.square(): RealVector = map { it.pow(2) } +public fun DoubleVector.square(): DoubleVector = map { it.pow(2) } -public fun sin(vector: RealVector): RealVector = vector.map { kotlin.math.sin(it) } +public fun sin(vector: DoubleVector): DoubleVector = vector.map { kotlin.math.sin(it) } -public fun cos(vector: RealVector): RealVector = vector.map { kotlin.math.cos(it) } +public fun cos(vector: DoubleVector): DoubleVector = vector.map { kotlin.math.cos(it) } -public fun tan(vector: RealVector): RealVector = vector.map { kotlin.math.tan(it) } +public fun tan(vector: DoubleVector): DoubleVector = vector.map { kotlin.math.tan(it) } -public fun ln(vector: RealVector): RealVector = vector.map { kotlin.math.ln(it) } +public fun ln(vector: DoubleVector): DoubleVector = vector.map { kotlin.math.ln(it) } -public fun log10(vector: RealVector): RealVector = vector.map { kotlin.math.log10(it) } +public fun log10(vector: DoubleVector): DoubleVector = vector.map { kotlin.math.log10(it) } // reductions methods -public fun RealVector.sum(): Double { +public fun DoubleVector.sum(): Double { var res = 0.0 for (i in indices) { res += get(i) } return res -} \ No newline at end of file +} + +public object VectorL2Norm : Norm { + override fun norm(arg: DoubleVector): Double = sqrt(arg.fold(0.0) { acc: Double, d: Double -> acc + d.pow(2) }) +} + +public val DoubleVector.norm: Double get() = VectorL2Norm.norm(this) \ No newline at end of file diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/dot.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/dot.kt index de8cda355..b79e5030c 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/dot.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/dot.kt @@ -12,6 +12,6 @@ import space.kscience.kmath.linear.Matrix /** * Optimized dot product for real matrices */ -public infix fun Matrix.dot(other: Matrix): Matrix = LinearSpace.real.run{ +public infix fun Matrix.dot(other: Matrix): Matrix = LinearSpace.real.run { this@dot dot other } \ No newline at end of file diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/grids.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/grids.kt index d89d48db5..c3556216d 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/grids.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/grids.kt @@ -5,8 +5,42 @@ package space.kscience.kmath.real -import space.kscience.kmath.structures.asBuffer -import kotlin.math.abs +import space.kscience.kmath.misc.UnstableKMathAPI +import space.kscience.kmath.structures.Buffer +import space.kscience.kmath.structures.DoubleBuffer +import kotlin.math.floor + +public val ClosedFloatingPointRange.length: Double get() = endInclusive - start + +/** + * Create a Buffer-based grid with equally distributed [numberOfPoints] points. The range could be increasing or decreasing. + * If range has a zero size, then the buffer consisting of [numberOfPoints] equal values is returned. + */ +public fun Buffer.Companion.fromRange(range: ClosedFloatingPointRange, numberOfPoints: Int): DoubleBuffer { + require(numberOfPoints >= 2) { "Number of points in grid must be more than 1" } + val normalizedRange = when { + range.endInclusive > range.start -> range + range.endInclusive < range.start -> range.endInclusive..range.start + else -> return DoubleBuffer(numberOfPoints) { range.start } + } + val step = normalizedRange.length / (numberOfPoints - 1) + return DoubleBuffer(numberOfPoints) { normalizedRange.start + step * it } +} + +/** + * Create a Buffer-based grid with equally distributed points with a fixed [step]. The range could be increasing or decreasing. + * If the step is larger than the range size, single point is returned. + */ +public fun Buffer.Companion.withFixedStep(range: ClosedFloatingPointRange, step: Double): DoubleBuffer { + require(step > 0) { "The grid step must be positive" } + val normalizedRange = when { + range.endInclusive > range.start -> range + range.endInclusive < range.start -> range.endInclusive..range.start + else -> return DoubleBuffer(range.start) + } + val numberOfPoints = floor(normalizedRange.length / step).toInt() + 1 + return DoubleBuffer(numberOfPoints) { normalizedRange.start + step * it } +} /** * Convert double range to sequence. @@ -16,35 +50,5 @@ import kotlin.math.abs * * If step is negative, the same goes from upper boundary downwards */ -public fun ClosedFloatingPointRange.toSequenceWithStep(step: Double): Sequence = when { - step == 0.0 -> error("Zero step in double progression") - - step > 0 -> sequence { - var current = start - - while (current <= endInclusive) { - yield(current) - current += step - } - } - - else -> sequence { - var current = endInclusive - - while (current >= start) { - yield(current) - current += step - } - } -} - -public infix fun ClosedFloatingPointRange.step(step: Double): RealVector = - toSequenceWithStep(step).toList().asBuffer() - -/** - * Convert double range to sequence with the fixed number of points - */ -public fun ClosedFloatingPointRange.toSequenceWithPoints(numPoints: Int): Sequence { - require(numPoints > 1) { "The number of points should be more than 2" } - return toSequenceWithStep(abs(endInclusive - start) / (numPoints - 1)) -} +@UnstableKMathAPI +public infix fun ClosedFloatingPointRange.step(step: Double): DoubleBuffer = Buffer.withFixedStep(this, step) \ No newline at end of file diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/realND.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/realND.kt index ff4414efe..31a00c1ca 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/realND.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/realND.kt @@ -5,32 +5,32 @@ package space.kscience.kmath.real -import space.kscience.kmath.nd.NDBuffer -import space.kscience.kmath.operations.RealField -import space.kscience.kmath.structures.RealBuffer +import space.kscience.kmath.nd.BufferND +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.structures.DoubleBuffer /** - * Map one [NDBuffer] using function without indices. + * Map one [BufferND] using function without indices. */ -public inline fun NDBuffer.mapInline(crossinline transform: RealField.(Double) -> Double): NDBuffer { - val array = DoubleArray(strides.linearSize) { offset -> RealField.transform(buffer[offset]) } - return NDBuffer(strides, RealBuffer(array)) +public inline fun BufferND.mapInline(crossinline transform: DoubleField.(Double) -> Double): BufferND { + val array = DoubleArray(strides.linearSize) { offset -> DoubleField.transform(buffer[offset]) } + return BufferND(strides, DoubleBuffer(array)) } /** * Element by element application of any operation on elements to the whole array. Just like in numpy. */ -public operator fun Function1.invoke(ndElement: NDBuffer): NDBuffer = - ndElement.mapInline { this@invoke(it) } +public operator fun Function1.invoke(elementND: BufferND): BufferND = + elementND.mapInline { this@invoke(it) } /* plus and minus */ /** - * Summation operation for [NDBuffer] and single element + * Summation operation for [BufferND] and single element */ -public operator fun NDBuffer.plus(arg: Double): NDBuffer = mapInline { it + arg } +public operator fun BufferND.plus(arg: Double): BufferND = mapInline { it + arg } /** - * Subtraction operation between [NDBuffer] and single element + * Subtraction operation between [BufferND] and single element */ -public operator fun NDBuffer.minus(arg: Double): NDBuffer = mapInline { it - arg } \ No newline at end of file +public operator fun BufferND.minus(arg: Double): BufferND = mapInline { it - arg } \ No newline at end of file diff --git a/kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/RealMatrixTest.kt b/kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/DoubleMatrixTest.kt similarity index 86% rename from kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/RealMatrixTest.kt rename to kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/DoubleMatrixTest.kt index 924e2fcf4..84e604b18 100644 --- a/kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/RealMatrixTest.kt +++ b/kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/DoubleMatrixTest.kt @@ -8,14 +8,19 @@ package kaceince.kmath.real import space.kscience.kmath.linear.LinearSpace import space.kscience.kmath.linear.matrix import space.kscience.kmath.misc.UnstableKMathAPI +import space.kscience.kmath.nd.StructureND import space.kscience.kmath.real.* import space.kscience.kmath.structures.contentEquals import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue +fun assertMatrixEquals(expected: StructureND, actual: StructureND) { + assertTrue { StructureND.contentEquals(expected, actual) } +} + @UnstableKMathAPI -internal class RealMatrixTest { +internal class DoubleMatrixTest { @Test fun testSum() { val m = realMatrix(10, 10) { i, j -> (i + j).toDouble() } @@ -48,7 +53,7 @@ internal class RealMatrixTest { 1.0, 0.0, 0.0, 0.0, 1.0, 2.0 ) - assertEquals(matrix2, matrix1.repeatStackVertical(3)) + assertMatrixEquals(matrix2, matrix1.repeatStackVertical(3)) } @Test @@ -62,7 +67,7 @@ internal class RealMatrixTest { 0.75, -0.5, 3.25, 4.5, 7.0, 2.0 ) - assertEquals(matrix2, expectedResult) + assertMatrixEquals(matrix2, expectedResult) } @Test @@ -77,7 +82,7 @@ internal class RealMatrixTest { 5.0, 10.0, -5.0, -10.0, -20.0, 0.0 ) - assertEquals(matrix2, expectedResult) + assertMatrixEquals(matrix2, expectedResult) } @Test @@ -94,8 +99,8 @@ internal class RealMatrixTest { -1.0, 0.0, 27.0, 64.0, -216.0, -8.0 ) - assertEquals(matrix1.square(), matrix2) - assertEquals(matrix1.pow(3), matrix3) + assertMatrixEquals(matrix1.square(), matrix2) + assertMatrixEquals(matrix1.pow(3), matrix3) } @OptIn(UnstableKMathAPI::class) @@ -114,7 +119,7 @@ internal class RealMatrixTest { -3.0, 0.0, 9.0, 16.0, -48.0, -5.0 ) - assertEquals(result, expectedResult) + assertMatrixEquals(result, expectedResult) } @Test @@ -133,9 +138,9 @@ internal class RealMatrixTest { -6.0, 7.0 ) - assertEquals(matrix1.appendColumn { it[0] }, matrix2) - assertEquals(matrix1.extractColumn(1), col1) - assertEquals(matrix1.extractColumns(1..2), cols1to2) + assertMatrixEquals(matrix1.appendColumn { it[0] }, matrix2) + assertMatrixEquals(matrix1.extractColumn(1), col1) + assertMatrixEquals(matrix1.extractColumns(1..2), cols1to2) //equals should never be called on buffers assertTrue { matrix1.sumByColumn().contentEquals(3.0, -6.0, 10.0, 4.0) diff --git a/kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/RealVectorTest.kt b/kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/DoubleVectorTest.kt similarity index 71% rename from kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/RealVectorTest.kt rename to kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/DoubleVectorTest.kt index 7f9eb0f16..9de54381c 100644 --- a/kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/RealVectorTest.kt +++ b/kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/DoubleVectorTest.kt @@ -9,30 +9,30 @@ import space.kscience.kmath.linear.LinearSpace import space.kscience.kmath.linear.asMatrix import space.kscience.kmath.linear.transpose import space.kscience.kmath.real.plus -import space.kscience.kmath.structures.RealBuffer +import space.kscience.kmath.structures.DoubleBuffer import kotlin.test.Test import kotlin.test.assertEquals -internal class RealVectorTest { +internal class DoubleVectorTest { @Test fun testSum() { - val vector1 = RealBuffer(5) { it.toDouble() } - val vector2 = RealBuffer(5) { 5 - it.toDouble() } + val vector1 = DoubleBuffer(5) { it.toDouble() } + val vector2 = DoubleBuffer(5) { 5 - it.toDouble() } val sum = vector1 + vector2 assertEquals(5.0, sum[2]) } @Test fun testVectorToMatrix() { - val vector = RealBuffer(5) { it.toDouble() } + val vector = DoubleBuffer(5) { it.toDouble() } val matrix = vector.asMatrix() assertEquals(4.0, matrix[4, 0]) } @Test fun testDot() { - val vector1 = RealBuffer(5) { it.toDouble() } - val vector2 = RealBuffer(5) { 5 - it.toDouble() } + val vector1 = DoubleBuffer(5) { it.toDouble() } + val vector2 = DoubleBuffer(5) { 5 - it.toDouble() } val matrix1 = vector1.asMatrix() val matrix2 = vector2.asMatrix().transpose() val product = LinearSpace.real.run { matrix1 dot matrix2 } diff --git a/kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/GridTest.kt b/kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/GridTest.kt index 9e27071cf..0d3b80336 100644 --- a/kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/GridTest.kt +++ b/kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real/GridTest.kt @@ -5,14 +5,30 @@ package kaceince.kmath.real +import space.kscience.kmath.misc.UnstableKMathAPI +import space.kscience.kmath.real.DoubleVector +import space.kscience.kmath.real.minus +import space.kscience.kmath.real.norm import space.kscience.kmath.real.step import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.test.assertTrue +@UnstableKMathAPI class GridTest { @Test - fun testStepGrid(){ + fun testStepGrid() { val grid = 0.0..1.0 step 0.2 assertEquals(6, grid.size) + assertTrue { (grid - DoubleVector(0.0, 0.2, 0.4, 0.6, 0.8, 1.0)).norm < 1e-4 } + } + + @Test + fun testIterateGrid(){ + var res = 0.0 + for(d in 0.0..1.0 step 0.2){ + res = d + } + assertEquals(1.0, res) } } \ No newline at end of file diff --git a/kmath-functions/README.md b/kmath-functions/README.md index b8aa4dee7..eef677565 100644 --- a/kmath-functions/README.md +++ b/kmath-functions/README.md @@ -1,44 +1,39 @@ -# Functions (`kmath-functions`) +# Module kmath-functions -Functions and interpolations: +Functions and interpolations. - - [piecewise](Piecewise functions.) : src/commonMain/kotlin/kscience/kmath/functions/Piecewise.kt - - [polynomials](Polynomial functions.) : src/commonMain/kotlin/kscience/kmath/functions/Polynomial.kt - - [linear interpolation](Linear XY interpolator.) : src/commonMain/kotlin/kscience/kmath/interpolation/LinearInterpolator.kt - - [spline interpolation](Cubic spline XY interpolator.) : src/commonMain/kotlin/kscience/kmath/interpolation/SplineInterpolator.kt + - [piecewise](src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt) : Piecewise functions. + - [polynomials](src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt) : Polynomial functions. + - [linear interpolation](src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt) : Linear XY interpolator. + - [spline interpolation](src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt) : Cubic spline XY interpolator. + - [integration](#) : Univariate and multivariate quadratures -> #### Artifact: -> -> This module artifact: `space.kscience:kmath-functions:0.3.0-dev-2`. -> -> Bintray release version: [ ![Download](https://api.bintray.com/packages/mipt-npm/kscience/kmath-functions/images/download.svg) ](https://bintray.com/mipt-npm/kscience/kmath-functions/_latestVersion) -> -> Bintray development version: [ ![Download](https://api.bintray.com/packages/mipt-npm/dev/kmath-functions/images/download.svg) ](https://bintray.com/mipt-npm/dev/kmath-functions/_latestVersion) -> -> **Gradle:** -> -> ```gradle -> repositories { -> maven { url 'https://repo.kotlin.link' } -> maven { url 'https://dl.bintray.com/hotkeytlt/maven' } -> maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap -> } -> -> dependencies { -> implementation 'space.kscience:kmath-functions:0.3.0-dev-2' -> } -> ``` -> **Gradle Kotlin DSL:** -> -> ```kotlin -> repositories { -> maven("https://repo.kotlin.link") -> maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap -> maven("https://dl.bintray.com/hotkeytlt/maven") // required for a -> } -> -> dependencies { -> implementation("space.kscience:kmath-functions:0.3.0-dev-2") -> } -> ``` +## Artifact: + +The Maven coordinates of this project are `space.kscience:kmath-functions:0.3.0-dev-6`. + +**Gradle:** +```gradle +repositories { + maven { url 'https://repo.kotlin.link' } + maven { url 'https://dl.bintray.com/hotkeytlt/maven' } + maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap +} + +dependencies { + implementation 'space.kscience:kmath-functions:0.3.0-dev-6' +} +``` +**Gradle Kotlin DSL:** +```kotlin +repositories { + maven("https://repo.kotlin.link") + maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap + maven("https://dl.bintray.com/hotkeytlt/maven") // required for a +} + +dependencies { + implementation("space.kscience:kmath-functions:0.3.0-dev-6") +} +``` diff --git a/kmath-functions/build.gradle.kts b/kmath-functions/build.gradle.kts index 0a3c1cfb5..ca678bc0e 100644 --- a/kmath-functions/build.gradle.kts +++ b/kmath-functions/build.gradle.kts @@ -4,7 +4,8 @@ */ plugins { - id("ru.mipt.npm.gradle.mpp") + kotlin("multiplatform") + id("ru.mipt.npm.gradle.common") } kotlin.sourceSets.commonMain { @@ -14,12 +15,23 @@ kotlin.sourceSets.commonMain { } readme { - description = "Functions and interpolation" - maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE + description = "Functions, integration and interpolation" + maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md")) - feature("piecewise", "src/commonMain/kotlin/kscience/kmath/functions/Piecewise.kt", "Piecewise functions.") - feature("polynomials", "src/commonMain/kotlin/kscience/kmath/functions/Polynomial.kt", "Polynomial functions.") - feature("linear interpolation", "src/commonMain/kotlin/kscience/kmath/interpolation/LinearInterpolator.kt", "Linear XY interpolator.") - feature("spline interpolation", "src/commonMain/kotlin/kscience/kmath/interpolation/SplineInterpolator.kt", "Cubic spline XY interpolator.") + feature("piecewise", "src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt") { + "Piecewise functions." + } + feature("polynomials", "src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt") { + "Polynomial functions." + } + feature("linear interpolation", "src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt") { + "Linear XY interpolator." + } + feature("spline interpolation", "src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt") { + "Cubic spline XY interpolator." + } + feature("integration") { + "Univariate and multivariate quadratures" + } } \ No newline at end of file diff --git a/kmath-functions/docs/README-TEMPLATE.md b/kmath-functions/docs/README-TEMPLATE.md index 8a34a7cc4..2e163eee5 100644 --- a/kmath-functions/docs/README-TEMPLATE.md +++ b/kmath-functions/docs/README-TEMPLATE.md @@ -1,6 +1,6 @@ -# Functions (`kmath-functions`) +# Module kmath-functions -Functions and interpolations: +Functions and interpolations. ${features} diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt index eb30d048d..6d481e334 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt @@ -7,14 +7,28 @@ package space.kscience.kmath.functions import space.kscience.kmath.operations.Ring +/** + * Represents piecewise-defined function. + * + * @param T the piece key type. + * @param R the sub-function type. + */ public fun interface Piecewise { + /** + * Returns the appropriate sub-function for given piece key. + */ public fun findPiece(arg: T): R? } +/** + * Represents piecewise-defined function where all the sub-functions are polynomials. + */ public fun interface PiecewisePolynomial : Piecewise> /** - * Ordered list of pieces in piecewise function + * Basic [Piecewise] implementation where all the pieces are ordered by the [Comparable] type instances. + * + * @param T the comparable piece key type. */ public class OrderedPiecewisePolynomial>(delimiter: T) : PiecewisePolynomial { @@ -22,22 +36,30 @@ public class OrderedPiecewisePolynomial>(delimiter: T) : private val pieces: MutableList> = arrayListOf() /** - * Dynamically add a piece to the "right" side (beyond maximum argument value of previous piece) - * @param right new rightmost position. If is less then current rightmost position, a error is thrown. + * Dynamically adds a piece to the right side (beyond maximum argument value of previous piece) + * + * @param right new rightmost position. If is less then current rightmost position, an error is thrown. + * @param piece the sub-function. */ public fun putRight(right: T, piece: Polynomial) { require(right > delimiters.last()) { "New delimiter should be to the right of old one" } - delimiters.add(right) - pieces.add(piece) + delimiters += right + pieces += piece } + /** + * Dynamically adds a piece to the left side (beyond maximum argument value of previous piece) + * + * @param left the new leftmost position. If is less then current rightmost position, an error is thrown. + * @param piece the sub-function. + */ public fun putLeft(left: T, piece: Polynomial) { require(left < delimiters.first()) { "New delimiter should be to the left of old one" } delimiters.add(0, left) pieces.add(0, piece) } - override fun findPiece(arg: T): Polynomial? { + public override fun findPiece(arg: T): Polynomial? { if (arg < delimiters.first() || arg >= delimiters.last()) return null else { @@ -51,9 +73,10 @@ public class OrderedPiecewisePolynomial>(delimiter: T) : } /** - * Return a value of polynomial function with given [ring] an given [arg] or null if argument is outside of piecewise definition. + * Return a value of polynomial function with given [ring] an given [arg] or null if argument is outside of piecewise + * definition. */ public fun , C : Ring> PiecewisePolynomial.value(ring: C, arg: T): T? = findPiece(arg)?.value(ring, arg) -public fun , C : Ring> PiecewisePolynomial.asFunction(ring: C): (T) -> T? = { value(ring, it) } \ No newline at end of file +public fun , C : Ring> PiecewisePolynomial.asFunction(ring: C): (T) -> T? = { value(ring, it) } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt index bbe3f00d4..efae71b0e 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt @@ -15,16 +15,26 @@ import kotlin.math.max import kotlin.math.pow /** - * Polynomial coefficients without fixation on specific context they are applied to - * @param coefficients constant is the leftmost coefficient + * Polynomial coefficients model without fixation on specific context they are applied to. + * + * @param coefficients constant is the leftmost coefficient. */ -public inline class Polynomial(public val coefficients: List) +public class Polynomial(public val coefficients: List) +/** + * Returns a [Polynomial] instance with given [coefficients]. + */ @Suppress("FunctionName") public fun Polynomial(vararg coefficients: T): Polynomial = Polynomial(coefficients.toList()) +/** + * Evaluates the value of the given double polynomial for given double argument. + */ public fun Polynomial.value(): Double = coefficients.reduceIndexed { index, acc, d -> acc + d.pow(index) } +/** + * Evaluates the value of the given polynomial for given argument. + */ public fun > Polynomial.value(ring: C, arg: T): T = ring { if (coefficients.isEmpty()) return@ring zero var res = coefficients.first() @@ -40,19 +50,23 @@ public fun > Polynomial.value(ring: C, arg: T): T = ring } /** - * Represent the polynomial as a regular context-less function + * Represent the polynomial as a regular context-less function. */ public fun > Polynomial.asFunction(ring: C): (T) -> T = { value(ring, it) } /** - * An algebra for polynomials + * Space of polynomials. + * + * @param T the type of operated polynomials. + * @param C the intersection of [Ring] of [T] and [ScaleOperations] of [T]. + * @param ring the [C] instance. */ public class PolynomialSpace( private val ring: C, ) : Group>, ScaleOperations> where C : Ring, C : ScaleOperations { public override val zero: Polynomial = Polynomial(emptyList()) - override fun Polynomial.unaryMinus(): Polynomial = with(ring) { + override fun Polynomial.unaryMinus(): Polynomial = ring { Polynomial(coefficients.map { -it }) } @@ -69,6 +83,9 @@ public class PolynomialSpace( public override fun scale(a: Polynomial, value: Double): Polynomial = ring { Polynomial(List(a.coefficients.size) { index -> a.coefficients[index] * value }) } + /** + * Evaluates the polynomial for the given value [arg]. + */ public operator fun Polynomial.invoke(arg: T): T = value(ring, arg) } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/functionTypes.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/functionTypes.kt new file mode 100644 index 000000000..88b24c756 --- /dev/null +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/functionTypes.kt @@ -0,0 +1,12 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.functions + +import space.kscience.kmath.structures.Buffer + +public typealias UnivariateFunction = (T) -> T + +public typealias MultivariateFunction = (Buffer) -> T \ No newline at end of file diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt new file mode 100644 index 000000000..bc23e2f1b --- /dev/null +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt @@ -0,0 +1,78 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ +package space.kscience.kmath.integration + +import space.kscience.kmath.misc.UnstableKMathAPI +import space.kscience.kmath.operations.Field +import space.kscience.kmath.structures.* + + +/** + * A simple one-pass integrator based on Gauss rule + */ +public class GaussIntegrator( + public val algebra: Field, +) : UnivariateIntegrator { + + private fun buildRule(integrand: UnivariateIntegrand): Pair, Buffer> { + val factory = integrand.getFeature() ?: GaussLegendreRuleFactory + val numPoints = integrand.getFeature()?.maxCalls ?: 100 + val range = integrand.getFeature>()?.range ?: 0.0..1.0 + return factory.build(numPoints, range) + } + + override fun integrate(integrand: UnivariateIntegrand): UnivariateIntegrand = with(algebra) { + val f = integrand.function + val (points, weights) = buildRule(integrand) + var res = zero + var c = zero + for (i in points.indices) { + val x = points[i] + val weight = weights[i] + val y: T = weight * f(x) - c + val t = res + y + c = t - res - y + res = t + } + return integrand + IntegrandValue(res) + IntegrandCallsPerformed(integrand.calls + points.size) + } + + public companion object { + + } +} + +/** + * Integrate [T]-valued univariate function using provided set of [IntegrandFeature] + * Following features are evaluated: + * * [GaussIntegratorRuleFactory] - A factory for computing the Gauss integration rule. By default uses [GaussLegendreRuleFactory] + * * [IntegrationRange] - the univariate range of integration. By default uses 0..1 interval. + * * [IntegrandMaxCalls] - the maximum number of function calls during integration. For non-iterative rules, always uses the maximum number of points. By default uses 100 points. + */ +@UnstableKMathAPI +public fun Field.integrate( + vararg features: IntegrandFeature, + function: (Double) -> T, +): UnivariateIntegrand = GaussIntegrator(this).integrate(UnivariateIntegrand(function, *features)) + + +/** + * Use [GaussIntegrator.Companion.integrate] to integrate the function in the current algebra with given [range] and [numPoints] + */ +@UnstableKMathAPI +public fun Field.integrate( + range: ClosedRange, + numPoints: Int = 100, + vararg features: IntegrandFeature, + function: (Double) -> T, +): UnivariateIntegrand = GaussIntegrator(this).integrate( + UnivariateIntegrand( + function, + IntegrationRange(range), + GaussLegendreRuleFactory, + IntegrandMaxCalls(numPoints), + *features + ) +) \ No newline at end of file diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt new file mode 100644 index 000000000..133f829e3 --- /dev/null +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt @@ -0,0 +1,167 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.integration + +import space.kscience.kmath.structures.Buffer +import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.asBuffer +import space.kscience.kmath.structures.map +import kotlin.jvm.Synchronized +import kotlin.math.ulp +import kotlin.native.concurrent.ThreadLocal + +public interface GaussIntegratorRuleFactory : IntegrandFeature { + public fun build(numPoints: Int): Pair, Buffer> + + public companion object { + public fun double(numPoints: Int, range: ClosedRange): Pair, Buffer> = + GaussLegendreRuleFactory.build(numPoints, range) + } +} + +/** + * Create an integration rule by scaling existing normalized rule + * + */ +public fun GaussIntegratorRuleFactory.build( + numPoints: Int, + range: ClosedRange, +): Pair, Buffer> { + val normalized = build(numPoints) + val length = range.endInclusive - range.start + + val points = normalized.first.map(::DoubleBuffer) { + range.start + length / 2 + length / 2 * it + } + + val weights = normalized.second.map(::DoubleBuffer) { + it * length / 2 + } + + return points to weights + +} + + +/** + * Gauss integrator rule based ont Legendre polynomials. All rules are normalized to + * + * The code is based on [Apache Commons Math source code version 3.6.1](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/analysis/integration/gauss/LegendreRuleFactory.html) + * + */ +@ThreadLocal +public object GaussLegendreRuleFactory : GaussIntegratorRuleFactory { + + private val cache = HashMap, Buffer>>() + + @Synchronized + private fun getOrBuildRule(numPoints: Int): Pair, Buffer> = + cache.getOrPut(numPoints) { buildRule(numPoints) } + + + private fun buildRule(numPoints: Int): Pair, Buffer> { + if (numPoints == 1) { + // Break recursion. + return Pair( + DoubleBuffer(0.0), + DoubleBuffer(0.0) + ) + } + + // Get previous rule. + // If it has not been computed yet it will trigger a recursive call + // to this method. + val previousPoints: Buffer = getOrBuildRule(numPoints - 1).first + + // Compute next rule. + val points = DoubleArray(numPoints) + val weights = DoubleArray(numPoints) + + // Find i-th root of P[n+1] by bracketing. + val iMax = numPoints / 2 + for (i in 0 until iMax) { + // Lower-bound of the interval. + var a: Double = if (i == 0) -1.0 else previousPoints[i - 1] + // Upper-bound of the interval. + var b: Double = if (iMax == 1) 1.0 else previousPoints[i] + // P[j-1](a) + var pma = 1.0 + // P[j](a) + var pa = a + // P[j-1](b) + var pmb = 1.0 + // P[j](b) + var pb = b + for (j in 1 until numPoints) { + val twoJP1 = 2 * j + 1 + val jP1 = j + 1 + // P[j+1](a) + val ppa = (twoJP1 * a * pa - j * pma) / jP1 + // P[j+1](b) + val ppb = (twoJP1 * b * pb - j * pmb) / jP1 + pma = pa + pa = ppa + pmb = pb + pb = ppb + } + // Now pa = P[n+1](a), and pma = P[n](a) (same holds for b). + // Middle of the interval. + var c = 0.5 * (a + b) + // P[j-1](c) + var pmc = 1.0 + // P[j](c) + var pc = c + var done = false + while (!done) { + done = b - a <= c.ulp + pmc = 1.0 + pc = c + for (j in 1 until numPoints) { + // P[j+1](c) + val ppc = ((2 * j + 1) * c * pc - j * pmc) / (j + 1) + pmc = pc + pc = ppc + } + // Now pc = P[n+1](c) and pmc = P[n](c). + if (!done) { + if (pa * pc <= 0) { + b = c + } else { + a = c + pa = pc + } + c = 0.5 * (a + b) + } + } + val d = numPoints * (pmc - c * pc) + val w = 2 * (1 - c * c) / (d * d) + points[i] = c + weights[i] = w + val idx = numPoints - i - 1 + points[idx] = -c + weights[idx] = w + } + // If "numPoints" is odd, 0 is a root. + // Note: as written, the test for oddness will work for negative + // integers too (although it is not necessary here), preventing + // a FindBugs warning. + if (numPoints % 2 != 0) { + var pmc = 1.0 + var j = 1 + while (j < numPoints) { + pmc = -j * pmc / (j + 1) + j += 2 + } + val d = numPoints * pmc + val w = 2 / (d * d) + points[iMax] = 0.0 + weights[iMax] = w + } + return Pair(points.asBuffer(), weights.asBuffer()) + } + + override fun build(numPoints: Int): Pair, Buffer> = getOrBuildRule(numPoints) +} \ No newline at end of file diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt new file mode 100644 index 000000000..1ff8e422e --- /dev/null +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.integration + +import kotlin.reflect.KClass + +public interface IntegrandFeature + +public interface Integrand { + public fun getFeature(type: KClass): T? +} + +public inline fun Integrand.getFeature(): T? = getFeature(T::class) + +public class IntegrandValue(public val value: T) : IntegrandFeature + +public class IntegrandRelativeAccuracy(public val accuracy: Double) : IntegrandFeature + +public class IntegrandAbsoluteAccuracy(public val accuracy: Double) : IntegrandFeature + +public class IntegrandCallsPerformed(public val calls: Int) : IntegrandFeature + +public val Integrand.calls: Int get() = getFeature()?.calls ?: 0 + +public class IntegrandMaxCalls(public val maxCalls: Int) : IntegrandFeature diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrator.kt new file mode 100644 index 000000000..abe6ea5ff --- /dev/null +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrator.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.integration + +/** + * A general interface for all integrators. + */ +public interface Integrator { + /** + * Runs one integration pass and return a new [Integrand] with a new set of features. + */ + public fun integrate(integrand: I): I +} diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt new file mode 100644 index 000000000..12d0ef0a6 --- /dev/null +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.integration + +import space.kscience.kmath.linear.Point +import kotlin.reflect.KClass + +public class MultivariateIntegrand internal constructor( + private val features: Map, IntegrandFeature>, + public val function: (Point) -> T, +) : Integrand { + + @Suppress("UNCHECKED_CAST") + override fun getFeature(type: KClass): T? = features[type] as? T + + public operator fun plus(pair: Pair, F>): MultivariateIntegrand = + MultivariateIntegrand(features + pair, function) + + public operator fun plus(feature: F): MultivariateIntegrand = + plus(feature::class to feature) +} + +@Suppress("FunctionName") +public fun MultivariateIntegrand( + vararg features: IntegrandFeature, + function: (Point) -> T, +): MultivariateIntegrand = MultivariateIntegrand(features.associateBy { it::class }, function) + +public val MultivariateIntegrand.value: T? get() = getFeature>()?.value diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt new file mode 100644 index 000000000..0b41a3f8b --- /dev/null +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt @@ -0,0 +1,71 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.integration + +import space.kscience.kmath.misc.UnstableKMathAPI +import kotlin.jvm.JvmInline +import kotlin.reflect.KClass + +public class UnivariateIntegrand internal constructor( + private val features: Map, IntegrandFeature>, + public val function: (Double) -> T, +) : Integrand { + + @Suppress("UNCHECKED_CAST") + override fun getFeature(type: KClass): T? = features[type] as? T + + public operator fun plus(pair: Pair, F>): UnivariateIntegrand = + UnivariateIntegrand(features + pair, function) + + public operator fun plus(feature: F): UnivariateIntegrand = + plus(feature::class to feature) +} + +@Suppress("FunctionName") +public fun UnivariateIntegrand( + function: (Double) -> T, + vararg features: IntegrandFeature, +): UnivariateIntegrand = UnivariateIntegrand(features.associateBy { it::class }, function) + +public typealias UnivariateIntegrator = Integrator> + +@JvmInline +public value class IntegrationRange>(public val range: ClosedRange) : IntegrandFeature + +public val UnivariateIntegrand.value: T? get() = getFeature>()?.value + +/** + * A shortcut method to integrate a [function] in [range] with additional [features]. + * The [function] is placed in the end position to allow passing a lambda. + */ +@UnstableKMathAPI +public fun UnivariateIntegrator.integrate( + range: ClosedRange, + vararg features: IntegrandFeature, + function: (Double) -> Double, +): Double = integrate( + UnivariateIntegrand(function, IntegrationRange(range), *features) +).value ?: error("Unexpected: no value after integration.") + +/** + * A shortcut method to integrate a [function] in [range] with additional [features]. + * The [function] is placed in the end position to allow passing a lambda. + */ +@UnstableKMathAPI +public fun UnivariateIntegrator.integrate( + range: ClosedRange, + function: (Double) -> Double, + featureBuilder: (MutableList.() -> Unit) = {}, +): Double { + //TODO use dedicated feature builder class instead or add extensions to MutableList + val features = buildList { + featureBuilder() + add(IntegrationRange(range)) + } + return integrate( + UnivariateIntegrand(function, *features.toTypedArray()) + ).value ?: error("Unexpected: no value after integration.") +} diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt index 052fe74ae..08090a522 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt @@ -3,48 +3,53 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ +@file:OptIn(UnstableKMathAPI::class) + package space.kscience.kmath.interpolation +import space.kscience.kmath.data.XYColumnarData import space.kscience.kmath.functions.PiecewisePolynomial import space.kscience.kmath.functions.value +import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.operations.Ring import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.asBuffer -public fun interface Interpolator { - public fun interpolate(points: XYPointSet): (X) -> Y +public fun interface Interpolator { + public fun interpolate(points: XYColumnarData): (X) -> Y } -public interface PolynomialInterpolator> : Interpolator { +public interface PolynomialInterpolator> : Interpolator { public val algebra: Ring public fun getDefaultValue(): T = error("Out of bounds") - public fun interpolatePolynomials(points: XYPointSet): PiecewisePolynomial + public fun interpolatePolynomials(points: XYColumnarData): PiecewisePolynomial - override fun interpolate(points: XYPointSet): (T) -> T = { x -> + override fun interpolate(points: XYColumnarData): (T) -> T = { x -> interpolatePolynomials(points).value(algebra, x) ?: getDefaultValue() } } + public fun > PolynomialInterpolator.interpolatePolynomials( x: Buffer, - y: Buffer + y: Buffer, ): PiecewisePolynomial { - val pointSet = BufferXYPointSet(x, y) + val pointSet = XYColumnarData(x, y) return interpolatePolynomials(pointSet) } public fun > PolynomialInterpolator.interpolatePolynomials( - data: Map + data: Map, ): PiecewisePolynomial { - val pointSet = BufferXYPointSet(data.keys.toList().asBuffer(), data.values.toList().asBuffer()) + val pointSet = XYColumnarData(data.keys.toList().asBuffer(), data.values.toList().asBuffer()) return interpolatePolynomials(pointSet) } public fun > PolynomialInterpolator.interpolatePolynomials( - data: List> + data: List>, ): PiecewisePolynomial { - val pointSet = BufferXYPointSet(data.map { it.first }.asBuffer(), data.map { it.second }.asBuffer()) + val pointSet = XYColumnarData(data.map { it.first }.asBuffer(), data.map { it.second }.asBuffer()) return interpolatePolynomials(pointSet) } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt index 06db47f24..3fbf6157e 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt @@ -5,17 +5,26 @@ package space.kscience.kmath.interpolation +import space.kscience.kmath.data.XYColumnarData import space.kscience.kmath.functions.OrderedPiecewisePolynomial import space.kscience.kmath.functions.PiecewisePolynomial import space.kscience.kmath.functions.Polynomial +import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.operations.Field import space.kscience.kmath.operations.invoke +@OptIn(UnstableKMathAPI::class) +internal fun > insureSorted(points: XYColumnarData<*, T, *>) { + for (i in 0 until points.size - 1) + require(points.x[i + 1] > points.x[i]) { "Input data is not sorted at index $i" } +} + /** * Reference JVM implementation: https://github.com/apache/commons-math/blob/master/src/main/java/org/apache/commons/math4/analysis/interpolation/LinearInterpolator.java */ public class LinearInterpolator>(public override val algebra: Field) : PolynomialInterpolator { - public override fun interpolatePolynomials(points: XYPointSet): PiecewisePolynomial = algebra { + @OptIn(UnstableKMathAPI::class) + public override fun interpolatePolynomials(points: XYColumnarData): PiecewisePolynomial = algebra { require(points.size > 0) { "Point array should not be empty" } insureSorted(points) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LoessInterpolator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LoessInterpolator.kt deleted file mode 100644 index ea8255f38..000000000 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LoessInterpolator.kt +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright 2018-2021 KMath contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package space.kscience.kmath.interpolation -// -//import space.kscience.kmath.functions.PiecewisePolynomial -//import space.kscience.kmath.operations.Ring -//import space.kscience.kmath.structures.Buffer -//import kotlin.math.abs -//import kotlin.math.sqrt -// -// -///** -// * Original code: https://github.com/apache/commons-math/blob/eb57d6d457002a0bb5336d789a3381a24599affe/src/main/java/org/apache/commons/math4/analysis/interpolation/LoessInterpolator.java -// */ -//class LoessInterpolator>(override val algebra: Ring) : PolynomialInterpolator { -// /** -// * The bandwidth parameter: when computing the loess fit at -// * a particular point, this fraction of source points closest -// * to the current point is taken into account for computing -// * a least-squares regression. -// * -// * -// * A sensible value is usually 0.25 to 0.5. -// */ -// private var bandwidth = 0.0 -// -// /** -// * The number of robustness iterations parameter: this many -// * robustness iterations are done. -// * -// * -// * A sensible value is usually 0 (just the initial fit without any -// * robustness iterations) to 4. -// */ -// private var robustnessIters = 0 -// -// /** -// * If the median residual at a certain robustness iteration -// * is less than this amount, no more iterations are done. -// */ -// private var accuracy = 0.0 -// -// /** -// * Constructs a new [LoessInterpolator] -// * with a bandwidth of [.DEFAULT_BANDWIDTH], -// * [.DEFAULT_ROBUSTNESS_ITERS] robustness iterations -// * and an accuracy of {#link #DEFAULT_ACCURACY}. -// * See [.LoessInterpolator] for an explanation of -// * the parameters. -// */ -// fun LoessInterpolator() { -// bandwidth = DEFAULT_BANDWIDTH -// robustnessIters = DEFAULT_ROBUSTNESS_ITERS -// accuracy = DEFAULT_ACCURACY -// } -// -// fun LoessInterpolator(bandwidth: Double, robustnessIters: Int) { -// this(bandwidth, robustnessIters, DEFAULT_ACCURACY) -// } -// -// fun LoessInterpolator(bandwidth: Double, robustnessIters: Int, accuracy: Double) { -// if (bandwidth < 0 || -// bandwidth > 1 -// ) { -// throw OutOfRangeException(LocalizedFormats.BANDWIDTH, bandwidth, 0, 1) -// } -// this.bandwidth = bandwidth -// if (robustnessIters < 0) { -// throw NotPositiveException(LocalizedFormats.ROBUSTNESS_ITERATIONS, robustnessIters) -// } -// this.robustnessIters = robustnessIters -// this.accuracy = accuracy -// } -// -// fun interpolate( -// xval: DoubleArray, -// yval: DoubleArray -// ): PolynomialSplineFunction { -// return SplineInterpolator().interpolate(xval, smooth(xval, yval)) -// } -// -// fun XYZPointSet.smooth(): XYPointSet { -// checkAllFiniteReal(x) -// checkAllFiniteReal(y) -// checkAllFiniteReal(z) -// MathArrays.checkOrder(xval) -// if (size == 1) { -// return doubleArrayOf(y[0]) -// } -// if (size == 2) { -// return doubleArrayOf(y[0], y[1]) -// } -// val bandwidthInPoints = (bandwidth * size).toInt() -// if (bandwidthInPoints < 2) { -// throw NumberIsTooSmallException( -// LocalizedFormats.BANDWIDTH, -// bandwidthInPoints, 2, true -// ) -// } -// val res = DoubleArray(size) -// val residuals = DoubleArray(size) -// val sortedResiduals = DoubleArray(size) -// val robustnessWeights = DoubleArray(size) -// // Do an initial fit and 'robustnessIters' robustness iterations. -// // This is equivalent to doing 'robustnessIters+1' robustness iterations -// // starting with all robustness weights set to 1. -// Arrays.fill(robustnessWeights, 1.0) -// for (iter in 0..robustnessIters) { -// val bandwidthInterval = intArrayOf(0, bandwidthInPoints - 1) -// // At each x, compute a local weighted linear regression -// for (i in 0 until size) { -//// val x = x[i] -// // Find out the interval of source points on which -// // a regression is to be made. -// if (i > 0) { -// updateBandwidthInterval(x, z, i, bandwidthInterval) -// } -// val ileft = bandwidthInterval[0] -// val iright = bandwidthInterval[1] -// // Compute the point of the bandwidth interval that is -// // farthest from x -// val edge: Int -// edge = if (x[i] - x[ileft] > x[iright] - x[i]) { -// ileft -// } else { -// iright -// } -// // Compute a least-squares linear fit weighted by -// // the product of robustness weights and the tricube -// // weight function. -// // See http://en.wikipedia.org/wiki/Linear_regression -// // (section "Univariate linear case") -// // and http://en.wikipedia.org/wiki/Weighted_least_squares -// // (section "Weighted least squares") -// var sumWeights = 0.0 -// var sumX = 0.0 -// var sumXSquared = 0.0 -// var sumY = 0.0 -// var sumXY = 0.0 -// val denom: Double = abs(1.0 / (x[edge] - x[i])) -// for (k in ileft..iright) { -// val xk = x[k] -// val yk = y[k] -// val dist = if (k < i) x - xk else xk - x[i] -// val w = tricube(dist * denom) * robustnessWeights[k] * z[k] -// val xkw = xk * w -// sumWeights += w -// sumX += xkw -// sumXSquared += xk * xkw -// sumY += yk * w -// sumXY += yk * xkw -// } -// val meanX = sumX / sumWeights -// val meanY = sumY / sumWeights -// val meanXY = sumXY / sumWeights -// val meanXSquared = sumXSquared / sumWeights -// val beta: Double -// beta = if (sqrt(abs(meanXSquared - meanX * meanX)) < accuracy) { -// 0.0 -// } else { -// (meanXY - meanX * meanY) / (meanXSquared - meanX * meanX) -// } -// val alpha = meanY - beta * meanX -// res[i] = beta * x[i] + alpha -// residuals[i] = abs(y[i] - res[i]) -// } -// // No need to recompute the robustness weights at the last -// // iteration, they won't be needed anymore -// if (iter == robustnessIters) { -// break -// } -// // Recompute the robustness weights. -// // Find the median residual. -// // An arraycopy and a sort are completely tractable here, -// // because the preceding loop is a lot more expensive -// java.lang.System.arraycopy(residuals, 0, sortedResiduals, 0, size) -// Arrays.sort(sortedResiduals) -// val medianResidual = sortedResiduals[size / 2] -// if (abs(medianResidual) < accuracy) { -// break -// } -// for (i in 0 until size) { -// val arg = residuals[i] / (6 * medianResidual) -// if (arg >= 1) { -// robustnessWeights[i] = 0.0 -// } else { -// val w = 1 - arg * arg -// robustnessWeights[i] = w * w -// } -// } -// } -// return res -// } -// -// fun smooth(xval: DoubleArray, yval: DoubleArray): DoubleArray { -// if (xval.size != yval.size) { -// throw DimensionMismatchException(xval.size, yval.size) -// } -// val unitWeights = DoubleArray(xval.size) -// Arrays.fill(unitWeights, 1.0) -// return smooth(xval, yval, unitWeights) -// } -// -// /** -// * Given an index interval into xval that embraces a certain number of -// * points closest to `xval[i-1]`, update the interval so that it -// * embraces the same number of points closest to `xval[i]`, -// * ignoring zero weights. -// * -// * @param xval Arguments array. -// * @param weights Weights array. -// * @param i Index around which the new interval should be computed. -// * @param bandwidthInterval a two-element array {left, right} such that: -// * `(left==0 or xval[i] - xval[left-1] > xval[right] - xval[i])` -// * and -// * `(right==xval.length-1 or xval[right+1] - xval[i] > xval[i] - xval[left])`. -// * The array will be updated. -// */ -// private fun updateBandwidthInterval( -// xval: Buffer, weights: Buffer, -// i: Int, -// bandwidthInterval: IntArray -// ) { -// val left = bandwidthInterval[0] -// val right = bandwidthInterval[1] -// // The right edge should be adjusted if the next point to the right -// // is closer to xval[i] than the leftmost point of the current interval -// val nextRight = nextNonzero(weights, right) -// if (nextRight < xval.size && xval[nextRight] - xval[i] < xval[i] - xval[left]) { -// val nextLeft = nextNonzero(weights, bandwidthInterval[0]) -// bandwidthInterval[0] = nextLeft -// bandwidthInterval[1] = nextRight -// } -// } -// -// /** -// * Return the smallest index `j` such that -// * `j > i && (j == weights.length || weights[j] != 0)`. -// * -// * @param weights Weights array. -// * @param i Index from which to start search. -// * @return the smallest compliant index. -// */ -// private fun nextNonzero(weights: Buffer, i: Int): Int { -// var j = i + 1 -// while (j < weights.size && weights[j] == 0.0) { -// ++j -// } -// return j -// } -// -// /** -// * Compute the -// * [tricube](http://en.wikipedia.org/wiki/Local_regression#Weight_function) -// * weight function -// * -// * @param x Argument. -// * @return `(1 - |x|3)3` for |x| < 1, 0 otherwise. -// */ -// private fun tricube(x: Double): Double { -// val absX: Double = FastMath.abs(x) -// if (absX >= 1.0) { -// return 0.0 -// } -// val tmp = 1 - absX * absX * absX -// return tmp * tmp * tmp -// } -// -// /** -// * Check that all elements of an array are finite real numbers. -// * -// * @param values Values array. -// * @throws org.apache.commons.math4.exception.NotFiniteNumberException -// * if one of the values is not a finite real number. -// */ -// private fun checkAllFiniteReal(values: DoubleArray) { -// for (i in values.indices) { -// MathUtils.checkFinite(values[i]) -// } -// } -// -// override fun interpolatePolynomials(points: Collection>): PiecewisePolynomial { -// TODO("not implemented") //To change body of created functions use File | Settings | File Templates. -// } -// -// companion object { -// /** Default value of the bandwidth parameter. */ -// const val DEFAULT_BANDWIDTH = 0.3 -// -// /** Default value of the number of robustness iterations. */ -// const val DEFAULT_ROBUSTNESS_ITERS = 2 -// -// /** -// * Default value for accuracy. -// */ -// const val DEFAULT_ACCURACY = 1e-12 -// } -//} \ No newline at end of file diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt index b4b009426..f00b66a4c 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt @@ -5,16 +5,21 @@ package space.kscience.kmath.interpolation +import space.kscience.kmath.data.XYColumnarData import space.kscience.kmath.functions.OrderedPiecewisePolynomial import space.kscience.kmath.functions.PiecewisePolynomial import space.kscience.kmath.functions.Polynomial +import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.operations.Field import space.kscience.kmath.operations.invoke import space.kscience.kmath.structures.MutableBufferFactory /** - * Generic spline interpolator. Not recommended for performance critical places, use platform-specific and type specific ones. - * Based on https://github.com/apache/commons-math/blob/eb57d6d457002a0bb5336d789a3381a24599affe/src/main/java/org/apache/commons/math4/analysis/interpolation/SplineInterpolator.java + * Generic spline interpolator. Not recommended for performance critical places, use platform-specific and type + * specific ones. + * + * Based on + * https://github.com/apache/commons-math/blob/eb57d6d457002a0bb5336d789a3381a24599affe/src/main/java/org/apache/commons/math4/analysis/interpolation/SplineInterpolator.java */ public class SplineInterpolator>( public override val algebra: Field, @@ -22,7 +27,8 @@ public class SplineInterpolator>( ) : PolynomialInterpolator { //TODO possibly optimize zeroed buffers - public override fun interpolatePolynomials(points: XYPointSet): PiecewisePolynomial = algebra { + @OptIn(UnstableKMathAPI::class) + public override fun interpolatePolynomials(points: XYColumnarData): PiecewisePolynomial = algebra { require(points.size >= 3) { "Can't use spline interpolator with less than 3 points" } insureSorted(points) // Number of intervals. The number of data points is n + 1. diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/XYPointSet.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/XYPointSet.kt deleted file mode 100644 index fa5315e94..000000000 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/XYPointSet.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2018-2021 KMath contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package space.kscience.kmath.interpolation - -import space.kscience.kmath.nd.Structure2D -import space.kscience.kmath.structures.Buffer - -public interface XYPointSet { - public val size: Int - public val x: Buffer - public val y: Buffer -} - -public interface XYZPointSet : XYPointSet { - public val z: Buffer -} - -internal fun > insureSorted(points: XYPointSet) { - for (i in 0 until points.size - 1) - require(points.x[i + 1] > points.x[i]) { "Input data is not sorted at index $i" } -} - -public class NDStructureColumn(public val structure: Structure2D, public val column: Int) : Buffer { - public override val size: Int - get() = structure.rowNum - - init { - require(column < structure.colNum) { "Column index is outside of structure column range" } - } - - public override operator fun get(index: Int): T = structure[index, column] - public override operator fun iterator(): Iterator = sequence { repeat(size) { yield(get(it)) } }.iterator() -} - -public class BufferXYPointSet( - public override val x: Buffer, - public override val y: Buffer -) : XYPointSet { - public override val size: Int - get() = x.size - - init { - require(x.size == y.size) { "Sizes of x and y buffers should be the same" } - } -} - -public fun Structure2D.asXYPointSet(): XYPointSet { - require(shape[1] == 2) { "Structure second dimension should be of size 2" } - - return object : XYPointSet { - override val size: Int get() = this@asXYPointSet.shape[0] - override val x: Buffer get() = NDStructureColumn(this@asXYPointSet, 0) - override val y: Buffer get() = NDStructureColumn(this@asXYPointSet, 1) - } -} diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt new file mode 100644 index 000000000..5ec90f42a --- /dev/null +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.integration + +import space.kscience.kmath.misc.UnstableKMathAPI +import space.kscience.kmath.operations.DoubleField +import kotlin.math.PI +import kotlin.math.sin +import kotlin.test.Test +import kotlin.test.assertEquals + +@OptIn(UnstableKMathAPI::class) +class GaussIntegralTest { + @Test + fun gaussSin() { + val res = DoubleField.integrate(0.0..2 * PI) { x -> + sin(x) + } + assertEquals(0.0, res.value!!, 1e-4) + } + + @Test + fun gaussUniform() { + val res = DoubleField.integrate(0.0..100.0,300) { x -> + if(x in 30.0..50.0){ + 1.0 + } else { + 0.0 + } + } + assertEquals(20.0, res.value!!, 0.5) + } + + +} \ No newline at end of file diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/LinearInterpolatorTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/LinearInterpolatorTest.kt index 8293a9e19..bec678bae 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/LinearInterpolatorTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/LinearInterpolatorTest.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.interpolation import space.kscience.kmath.functions.PiecewisePolynomial import space.kscience.kmath.functions.asFunction -import space.kscience.kmath.operations.RealField +import space.kscience.kmath.operations.DoubleField import kotlin.test.Test import kotlin.test.assertEquals @@ -21,8 +21,8 @@ internal class LinearInterpolatorTest { 3.0 to 4.0 ) - val polynomial: PiecewisePolynomial = LinearInterpolator(RealField).interpolatePolynomials(data) - val function = polynomial.asFunction(RealField) + val polynomial: PiecewisePolynomial = LinearInterpolator(DoubleField).interpolatePolynomials(data) + val function = polynomial.asFunction(DoubleField) assertEquals(null, function(-1.0)) assertEquals(0.5, function(0.5)) assertEquals(2.0, function(1.5)) diff --git a/kmath-geometry/build.gradle.kts b/kmath-geometry/build.gradle.kts index bccba0601..65db43edf 100644 --- a/kmath-geometry/build.gradle.kts +++ b/kmath-geometry/build.gradle.kts @@ -3,7 +3,12 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ -plugins { id("ru.mipt.npm.gradle.mpp") } +import ru.mipt.npm.gradle.Maturity + +plugins { + kotlin("multiplatform") + id("ru.mipt.npm.gradle.common") +} kotlin.sourceSets.commonMain { dependencies { @@ -11,6 +16,6 @@ kotlin.sourceSets.commonMain { } } -readme{ - maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE +readme { + maturity = Maturity.PROTOTYPE } diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean2DSpace.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean2DSpace.kt index a36208ee5..3604fda31 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean2DSpace.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean2DSpace.kt @@ -7,13 +7,13 @@ package space.kscience.kmath.geometry import space.kscience.kmath.linear.Point import space.kscience.kmath.misc.UnstableKMathAPI +import space.kscience.kmath.operations.GroupElement import space.kscience.kmath.operations.ScaleOperations -import space.kscience.kmath.operations.SpaceElement import space.kscience.kmath.operations.invoke import kotlin.math.sqrt @OptIn(UnstableKMathAPI::class) -public interface Vector2D : Point, Vector, SpaceElement { +public interface Vector2D : Point, Vector, GroupElement { public val x: Double public val y: Double public override val context: Euclidean2DSpace get() = Euclidean2DSpace diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean3DSpace.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean3DSpace.kt index 0f2ac1c87..8643b2dbb 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean3DSpace.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean3DSpace.kt @@ -7,13 +7,13 @@ package space.kscience.kmath.geometry import space.kscience.kmath.linear.Point import space.kscience.kmath.misc.UnstableKMathAPI +import space.kscience.kmath.operations.GroupElement import space.kscience.kmath.operations.ScaleOperations -import space.kscience.kmath.operations.SpaceElement import space.kscience.kmath.operations.invoke import kotlin.math.sqrt @OptIn(UnstableKMathAPI::class) -public interface Vector3D : Point, Vector, SpaceElement { +public interface Vector3D : Point, Vector, GroupElement { public val x: Double public val y: Double public val z: Double diff --git a/kmath-histograms/build.gradle.kts b/kmath-histograms/build.gradle.kts index 2ff5807c9..024e34076 100644 --- a/kmath-histograms/build.gradle.kts +++ b/kmath-histograms/build.gradle.kts @@ -3,8 +3,11 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ +import ru.mipt.npm.gradle.Maturity + plugins { - id("ru.mipt.npm.gradle.mpp") + kotlin("multiplatform") + id("ru.mipt.npm.gradle.common") } kscience { @@ -25,5 +28,5 @@ kotlin.sourceSets { } readme { - this.maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE + maturity = Maturity.PROTOTYPE } diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt index 988fd4294..3e5d93768 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt @@ -7,8 +7,8 @@ package space.kscience.kmath.histogram import kotlinx.atomicfu.atomic import kotlinx.atomicfu.getAndUpdate -import space.kscience.kmath.operations.Group -import space.kscience.kmath.operations.RealField +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Ring /** * Common representation for atomic counters @@ -16,8 +16,9 @@ import space.kscience.kmath.operations.RealField public interface Counter { public fun add(delta: T) public val value: T - public companion object{ - public fun real(): ObjectCounter = ObjectCounter(RealField) + + public companion object { + public fun real(): ObjectCounter = ObjectCounter(DoubleField) } } @@ -41,11 +42,11 @@ public class LongCounter : Counter { override val value: Long get() = innerValue.value } -public class ObjectCounter(public val space: Group) : Counter { - private val innerValue = atomic(space.zero) +public class ObjectCounter(public val group: Ring) : Counter { + private val innerValue = atomic(group.zero) override fun add(delta: T) { - innerValue.getAndUpdate { space.run { it + delta } } + innerValue.getAndUpdate { group.run { it + delta } } } override val value: T get() = innerValue.value diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/RealHistogramSpace.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/DoubleHistogramSpace.kt similarity index 88% rename from kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/RealHistogramSpace.kt rename to kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/DoubleHistogramSpace.kt index 56a8b0e9a..e792ef767 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/RealHistogramSpace.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/DoubleHistogramSpace.kt @@ -12,7 +12,7 @@ import space.kscience.kmath.nd.* import space.kscience.kmath.structures.* import kotlin.math.floor -public class RealHistogramSpace( +public class DoubleHistogramSpace( private val lower: Buffer, private val upper: Buffer, private val binNums: IntArray = IntArray(lower.size) { 20 }, @@ -28,13 +28,13 @@ public class RealHistogramSpace( public val dimension: Int get() = lower.size private val shape = IntArray(binNums.size) { binNums[it] + 2 } - override val histogramValueSpace: RealNDField = NDAlgebra.real(*shape) + override val histogramValueSpace: DoubleFieldND = AlgebraND.real(*shape) override val strides: Strides get() = histogramValueSpace.strides - private val binSize = RealBuffer(dimension) { (upper[it] - lower[it]) / binNums[it] } + private val binSize = DoubleBuffer(dimension) { (upper[it] - lower[it]) / binNums[it] } /** - * Get internal [NDStructure] bin index for given axis + * Get internal [StructureND] bin index for given axis */ private fun getIndex(axis: Int, value: Double): Int = when { value >= upper[axis] -> binNums[axis] + 1 // overflow @@ -74,13 +74,13 @@ public class RealHistogramSpace( } override fun produce(builder: HistogramBuilder.() -> Unit): IndexedHistogram { - val ndCounter = NDStructure.auto(strides) { Counter.real() } + val ndCounter = StructureND.auto(strides) { Counter.real() } val hBuilder = HistogramBuilder { point, value -> val index = getIndex(point) ndCounter[index].add(value.toDouble()) } hBuilder.apply(builder) - val values: NDBuffer = ndCounter.mapToBuffer { it.value } + val values: BufferND = ndCounter.mapToBuffer { it.value } return IndexedHistogram(this, values) } @@ -96,7 +96,7 @@ public class RealHistogramSpace( *) *``` */ - public fun fromRanges(vararg ranges: ClosedFloatingPointRange): RealHistogramSpace = RealHistogramSpace( + public fun fromRanges(vararg ranges: ClosedFloatingPointRange): DoubleHistogramSpace = DoubleHistogramSpace( ranges.map(ClosedFloatingPointRange::start).asBuffer(), ranges.map(ClosedFloatingPointRange::endInclusive).asBuffer() ) @@ -110,8 +110,8 @@ public class RealHistogramSpace( *) *``` */ - public fun fromRanges(vararg ranges: Pair, Int>): RealHistogramSpace = - RealHistogramSpace( + public fun fromRanges(vararg ranges: Pair, Int>): DoubleHistogramSpace = + DoubleHistogramSpace( ListBuffer( ranges .map(Pair, Int>::first) diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram.kt index cf53b5079..fcb5e96dc 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.histogram import space.kscience.kmath.domains.Domain import space.kscience.kmath.linear.Point -import space.kscience.kmath.structures.RealBuffer +import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.asBuffer /** @@ -34,7 +34,7 @@ public interface Histogram> { public val bins: Iterable } -public fun interface HistogramBuilder { +public fun interface HistogramBuilder { /** * Increment appropriate bin @@ -48,9 +48,9 @@ public fun > HistogramBuilder.put(point: Point): U public fun HistogramBuilder.put(vararg point: T): Unit = put(point.asBuffer()) public fun HistogramBuilder.put(vararg point: Number): Unit = - put(RealBuffer(point.map { it.toDouble() }.toDoubleArray())) + put(DoubleBuffer(point.map { it.toDouble() }.toDoubleArray())) -public fun HistogramBuilder.put(vararg point: Double): Unit = put(RealBuffer(point)) +public fun HistogramBuilder.put(vararg point: Double): Unit = put(DoubleBuffer(point)) public fun HistogramBuilder.fill(sequence: Iterable>): Unit = sequence.forEach { put(it) } /** diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/IndexedHistogramSpace.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/IndexedHistogramSpace.kt index 960d3400e..818d81ab0 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/IndexedHistogramSpace.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/IndexedHistogramSpace.kt @@ -8,12 +8,12 @@ package space.kscience.kmath.histogram import space.kscience.kmath.domains.Domain import space.kscience.kmath.linear.Point import space.kscience.kmath.misc.UnstableKMathAPI -import space.kscience.kmath.nd.NDField -import space.kscience.kmath.nd.NDStructure +import space.kscience.kmath.nd.FieldND import space.kscience.kmath.nd.Strides +import space.kscience.kmath.nd.StructureND import space.kscience.kmath.operations.Group +import space.kscience.kmath.operations.GroupElement import space.kscience.kmath.operations.ScaleOperations -import space.kscience.kmath.operations.SpaceElement import space.kscience.kmath.operations.invoke /** @@ -27,8 +27,8 @@ public data class DomainBin>( @OptIn(UnstableKMathAPI::class) public class IndexedHistogram, V : Any>( override val context: IndexedHistogramSpace, - public val values: NDStructure, -) : Histogram>, SpaceElement, IndexedHistogramSpace> { + public val values: StructureND, +) : Histogram>, GroupElement, IndexedHistogramSpace> { override fun get(point: Point): Bin? { val index = context.getIndex(point) ?: return null @@ -51,7 +51,7 @@ public interface IndexedHistogramSpace, V : Any> : Group>, ScaleOperations> { //public val valueSpace: Space public val strides: Strides - public val histogramValueSpace: NDField //= NDAlgebra.space(valueSpace, Buffer.Companion::boxing, *shape), + public val histogramValueSpace: FieldND //= NDAlgebra.space(valueSpace, Buffer.Companion::boxing, *shape), /** * Resolve index of the bin including given [point] diff --git a/kmath-histograms/src/commonTest/kotlin/space/kscience/kmath/histogram/MultivariateHistogramTest.kt b/kmath-histograms/src/commonTest/kotlin/space/kscience/kmath/histogram/MultivariateHistogramTest.kt index 92a308d02..51f9dabc5 100644 --- a/kmath-histograms/src/commonTest/kotlin/space/kscience/kmath/histogram/MultivariateHistogramTest.kt +++ b/kmath-histograms/src/commonTest/kotlin/space/kscience/kmath/histogram/MultivariateHistogramTest.kt @@ -6,15 +6,14 @@ package space.kscience.kmath.histogram import space.kscience.kmath.operations.invoke -import space.kscience.kmath.real.RealVector -import space.kscience.kmath.real.invoke +import space.kscience.kmath.real.DoubleVector import kotlin.random.Random import kotlin.test.* internal class MultivariateHistogramTest { @Test fun testSinglePutHistogram() { - val hSpace = RealHistogramSpace.fromRanges( + val hSpace = DoubleHistogramSpace.fromRanges( (-1.0..1.0), (-1.0..1.0) ) @@ -22,14 +21,14 @@ internal class MultivariateHistogramTest { put(0.55, 0.55) } val bin = histogram.bins.find { it.value.toInt() > 0 } ?: fail() - assertTrue { bin.contains(RealVector(0.55, 0.55)) } - assertTrue { bin.contains(RealVector(0.6, 0.5)) } - assertFalse { bin.contains(RealVector(-0.55, 0.55)) } + assertTrue { bin.contains(DoubleVector(0.55, 0.55)) } + assertTrue { bin.contains(DoubleVector(0.6, 0.5)) } + assertFalse { bin.contains(DoubleVector(-0.55, 0.55)) } } @Test fun testSequentialPut() { - val hSpace = RealHistogramSpace.fromRanges( + val hSpace = DoubleHistogramSpace.fromRanges( (-1.0..1.0), (-1.0..1.0), (-1.0..1.0) @@ -44,12 +43,12 @@ internal class MultivariateHistogramTest { put(nextDouble(), nextDouble(), nextDouble()) } } - assertEquals(n, histogram.bins.sumBy { it.value.toInt() }) + assertEquals(n, histogram.bins.sumOf { it.value.toInt() }) } @Test fun testHistogramAlgebra() { - RealHistogramSpace.fromRanges( + DoubleHistogramSpace.fromRanges( (-1.0..1.0), (-1.0..1.0), (-1.0..1.0) @@ -77,7 +76,7 @@ internal class MultivariateHistogramTest { assertTrue { res.bins.count() >= histogram1.bins.count() } - assertEquals(0.0, res.bins.sumByDouble { it.value.toDouble() }) + assertEquals(0.0, res.bins.sumOf { it.value.toDouble() }) } } } \ No newline at end of file diff --git a/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/UnivariateHistogram.kt b/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/UnivariateHistogram.kt index 278f65ce2..645116ade 100644 --- a/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/UnivariateHistogram.kt +++ b/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/UnivariateHistogram.kt @@ -8,13 +8,14 @@ package space.kscience.kmath.histogram import space.kscience.kmath.domains.UnivariateDomain import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.operations.Group -import space.kscience.kmath.operations.SpaceElement +import space.kscience.kmath.operations.GroupElement import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.asSequence @UnstableKMathAPI -public val UnivariateDomain.center: Double get() = (range.endInclusive - range.start) / 2 +public val UnivariateDomain.center: Double + get() = (range.endInclusive - range.start) / 2 /** * A univariate bin based an a range @@ -35,7 +36,7 @@ public class UnivariateBin( @OptIn(UnstableKMathAPI::class) public interface UnivariateHistogram : Histogram, - SpaceElement> { + GroupElement> { public operator fun get(value: Double): UnivariateBin? public override operator fun get(point: Buffer): UnivariateBin? = get(point[0]) diff --git a/kmath-kotlingrad/build.gradle.kts b/kmath-kotlingrad/build.gradle.kts index fbeee2b95..576c073c3 100644 --- a/kmath-kotlingrad/build.gradle.kts +++ b/kmath-kotlingrad/build.gradle.kts @@ -4,7 +4,8 @@ */ plugins { - id("ru.mipt.npm.gradle.jvm") + kotlin("jvm") + id("ru.mipt.npm.gradle.common") } dependencies { @@ -13,6 +14,6 @@ dependencies { api(project(":kmath-ast")) } -readme{ +readme { maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE } \ No newline at end of file diff --git a/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/DifferentiableMstExpression.kt b/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/DifferentiableMstExpression.kt index 78161cbb9..222145d2d 100644 --- a/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/DifferentiableMstExpression.kt +++ b/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/DifferentiableMstExpression.kt @@ -6,11 +6,11 @@ package space.kscience.kmath.kotlingrad import edu.umontreal.kotlingrad.api.SFun -import space.kscience.kmath.ast.MST -import space.kscience.kmath.ast.MstAlgebra -import space.kscience.kmath.ast.MstExpression import space.kscience.kmath.expressions.DifferentiableExpression -import space.kscience.kmath.expressions.Symbol +import space.kscience.kmath.expressions.MST +import space.kscience.kmath.expressions.MstAlgebra +import space.kscience.kmath.expressions.interpret +import space.kscience.kmath.misc.Symbol import space.kscience.kmath.operations.NumericAlgebra /** @@ -23,36 +23,26 @@ import space.kscience.kmath.operations.NumericAlgebra * @param A the [NumericAlgebra] of [T]. * @property expr the underlying [MstExpression]. */ -public inline class DifferentiableMstExpression(public val expr: MstExpression) : - DifferentiableExpression> where A : NumericAlgebra, T : Number { - public constructor(algebra: A, mst: MST) : this(MstExpression(algebra, mst)) +public class DifferentiableMstExpression>( + public val algebra: A, + public val mst: MST, +) : DifferentiableExpression> { - /** - * The [MstExpression.algebra] of [expr]. - */ - public val algebra: A - get() = expr.algebra + public override fun invoke(arguments: Map): T = mst.interpret(algebra, arguments) - /** - * The [MstExpression.mst] of [expr]. - */ - public val mst: MST - get() = expr.mst - - public override fun invoke(arguments: Map): T = expr(arguments) - - public override fun derivativeOrNull(symbols: List): MstExpression = MstExpression( - algebra, - symbols.map(Symbol::identity) - .map(MstAlgebra::bindSymbol) - .map { it.toSVar>() } - .fold(mst.toSFun(), SFun>::d) - .toMst(), - ) + public override fun derivativeOrNull(symbols: List): DifferentiableMstExpression = + DifferentiableMstExpression( + algebra, + symbols.map(Symbol::identity) + .map(MstAlgebra::bindSymbol) + .map { it.toSVar>() } + .fold(mst.toSFun(), SFun>::d) + .toMst(), + ) } /** - * Wraps this [MstExpression] into [DifferentiableMstExpression]. + * Wraps this [MST] into [DifferentiableMstExpression]. */ -public fun > MstExpression.differentiable(): DifferentiableMstExpression = - DifferentiableMstExpression(this) +public fun > MST.toDiffExpression(algebra: A): DifferentiableMstExpression = + DifferentiableMstExpression(algebra, this) diff --git a/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/ScalarsAdapters.kt b/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/ScalarsAdapters.kt index fdab303c1..f65d2948d 100644 --- a/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/ScalarsAdapters.kt +++ b/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/ScalarsAdapters.kt @@ -6,10 +6,10 @@ package space.kscience.kmath.kotlingrad import edu.umontreal.kotlingrad.api.* -import space.kscience.kmath.ast.MST -import space.kscience.kmath.ast.MstAlgebra -import space.kscience.kmath.ast.MstExtendedField -import space.kscience.kmath.ast.MstExtendedField.unaryMinus +import space.kscience.kmath.expressions.MST +import space.kscience.kmath.expressions.MstAlgebra +import space.kscience.kmath.expressions.MstExtendedField +import space.kscience.kmath.expressions.MstExtendedField.unaryMinus import space.kscience.kmath.operations.* /** diff --git a/kmath-kotlingrad/src/test/kotlin/space/kscience/kmath/kotlingrad/AdaptingTests.kt b/kmath-kotlingrad/src/test/kotlin/space/kscience/kmath/kotlingrad/AdaptingTests.kt index 9311e5ec2..66018a227 100644 --- a/kmath-kotlingrad/src/test/kotlin/space/kscience/kmath/kotlingrad/AdaptingTests.kt +++ b/kmath-kotlingrad/src/test/kotlin/space/kscience/kmath/kotlingrad/AdaptingTests.kt @@ -6,12 +6,11 @@ package space.kscience.kmath.kotlingrad import edu.umontreal.kotlingrad.api.* -import space.kscience.kmath.asm.compile -import space.kscience.kmath.ast.MstAlgebra -import space.kscience.kmath.ast.MstExpression +import space.kscience.kmath.asm.compileToExpression import space.kscience.kmath.ast.parseMath +import space.kscience.kmath.expressions.MstAlgebra 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 import kotlin.test.assertTrue @@ -21,8 +20,8 @@ internal class AdaptingTests { @Test fun symbol() { val c1 = MstAlgebra.bindSymbol("x") - assertTrue(c1.toSVar>().name == "x") - val c2 = "kitten".parseMath().toSFun>() + assertTrue(c1.toSVar>().name == "x") + val c2 = "kitten".parseMath().toSFun>() if (c2 is SVar) assertTrue(c2.name == "kitten") else fail() } @@ -30,15 +29,15 @@ internal class AdaptingTests { fun number() { val c1 = MstAlgebra.number(12354324) assertTrue(c1.toSConst().doubleValue == 12354324.0) - val c2 = "0.234".parseMath().toSFun>() + val c2 = "0.234".parseMath().toSFun>() if (c2 is SConst) assertTrue(c2.doubleValue == 0.234) else fail() - val c3 = "1e-3".parseMath().toSFun>() + val c3 = "1e-3".parseMath().toSFun>() if (c3 is SConst) assertEquals(0.001, c3.value) else fail() } @Test fun simpleFunctionShape() { - val linear = "2*x+16".parseMath().toSFun>() + val linear = "2*x+16".parseMath().toSFun>() if (linear !is Sum) fail() if (linear.left !is Prod) fail() if (linear.right !is SConst) fail() @@ -46,23 +45,22 @@ internal class AdaptingTests { @Test fun simpleFunctionDerivative() { - val x = MstAlgebra.bindSymbol("x").toSVar>() - val quadratic = "x^2-4*x-44".parseMath().toSFun>() - val actualDerivative = MstExpression(RealField, quadratic.d(x).toMst()).compile() - val expectedDerivative = MstExpression(RealField, "2*x-4".parseMath()).compile() + val x = MstAlgebra.bindSymbol("x").toSVar>() + val quadratic = "x^2-4*x-44".parseMath().toSFun>() + val actualDerivative = quadratic.d(x).toMst().compileToExpression(DoubleField) + val expectedDerivative = "2*x-4".parseMath().compileToExpression(DoubleField) assertEquals(actualDerivative("x" to 123.0), expectedDerivative("x" to 123.0)) } @Test fun moreComplexDerivative() { - val x = MstAlgebra.bindSymbol("x").toSVar>() - val composition = "-sqrt(sin(x^2)-cos(x)^2-16*x)".parseMath().toSFun>() - val actualDerivative = MstExpression(RealField, composition.d(x).toMst()).compile() + val x = MstAlgebra.bindSymbol("x").toSVar>() + val composition = "-sqrt(sin(x^2)-cos(x)^2-16*x)".parseMath().toSFun>() + val actualDerivative = composition.d(x).toMst().compileToExpression(DoubleField) + + val expectedDerivative = + "-(2*x*cos(x^2)+2*sin(x)*cos(x)-16)/(2*sqrt(sin(x^2)-16*x-cos(x)^2))".parseMath().compileToExpression(DoubleField) - val expectedDerivative = MstExpression( - RealField, - "-(2*x*cos(x^2)+2*sin(x)*cos(x)-16)/(2*sqrt(sin(x^2)-16*x-cos(x)^2))".parseMath() - ).compile() assertEquals(actualDerivative("x" to 0.1), expectedDerivative("x" to 0.1)) } diff --git a/kmath-memory/build.gradle.kts b/kmath-memory/build.gradle.kts index 355afa5bb..50c317324 100644 --- a/kmath-memory/build.gradle.kts +++ b/kmath-memory/build.gradle.kts @@ -4,13 +4,14 @@ */ plugins { - id("ru.mipt.npm.gradle.mpp") + kotlin("multiplatform") + id("ru.mipt.npm.gradle.common") id("ru.mipt.npm.gradle.native") } -readme{ +readme { + maturity = ru.mipt.npm.gradle.Maturity.DEVELOPMENT description = """ An API and basic implementation for arranging objects in a continous memory block. """.trimIndent() - maturity = ru.mipt.npm.gradle.Maturity.DEVELOPMENT } \ No newline at end of file diff --git a/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemorySpec.kt b/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemorySpec.kt index d09a50f30..1ee1cf4e2 100644 --- a/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemorySpec.kt +++ b/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemorySpec.kt @@ -37,7 +37,8 @@ public fun MemoryReader.read(spec: MemorySpec, offset: Int): T = wi /** * Writes the object [value] with [spec] starting from [offset]. */ -public fun MemoryWriter.write(spec: MemorySpec, offset: Int, value: T): Unit = with(spec) { write(offset, value) } +public fun MemoryWriter.write(spec: MemorySpec, offset: Int, value: T): Unit = + with(spec) { write(offset, value) } /** * Reads array of [size] objects mapped by [spec] at certain [offset]. diff --git a/kmath-memory/src/jvmMain/kotlin/space/kscience/kmath/memory/ByteBufferMemory.kt b/kmath-memory/src/jvmMain/kotlin/space/kscience/kmath/memory/ByteBufferMemory.kt index 5ae3c279f..944e8455b 100644 --- a/kmath-memory/src/jvmMain/kotlin/space/kscience/kmath/memory/ByteBufferMemory.kt +++ b/kmath-memory/src/jvmMain/kotlin/space/kscience/kmath/memory/ByteBufferMemory.kt @@ -18,7 +18,7 @@ import kotlin.contracts.contract internal class ByteBufferMemory( val buffer: ByteBuffer, val startOffset: Int = 0, - override val size: Int = buffer.limit() + override val size: Int = buffer.limit(), ) : Memory { @Suppress("NOTHING_TO_INLINE") private inline fun position(o: Int): Int = startOffset + o @@ -105,7 +105,8 @@ public actual fun Memory.Companion.allocate(length: Int): Memory = * Wraps a [Memory] around existing [ByteArray]. This operation is unsafe since the array is not copied * and could be mutated independently from the resulting [Memory]. */ -public actual fun Memory.Companion.wrap(array: ByteArray): Memory = ByteBufferMemory(checkNotNull(ByteBuffer.wrap(array))) +public actual fun Memory.Companion.wrap(array: ByteArray): Memory = + ByteBufferMemory(checkNotNull(ByteBuffer.wrap(array))) /** * Wraps this [ByteBuffer] to [Memory] object. diff --git a/kmath-memory/src/nativeMain/kotlin/space/kscience/kmath/memory/NativeMemory.kt b/kmath-memory/src/nativeMain/kotlin/space/kscience/kmath/memory/NativeMemory.kt index 94532fb77..d31c9e8f4 100644 --- a/kmath-memory/src/nativeMain/kotlin/space/kscience/kmath/memory/NativeMemory.kt +++ b/kmath-memory/src/nativeMain/kotlin/space/kscience/kmath/memory/NativeMemory.kt @@ -9,7 +9,7 @@ package space.kscience.kmath.memory internal class NativeMemory( val array: ByteArray, val startOffset: Int = 0, - override val size: Int = array.size + override val size: Int = array.size, ) : Memory { @Suppress("NOTHING_TO_INLINE") private inline fun position(o: Int): Int = startOffset + o diff --git a/kmath-nd4j/README.md b/kmath-nd4j/README.md index 7e38eb6ab..829fe4142 100644 --- a/kmath-nd4j/README.md +++ b/kmath-nd4j/README.md @@ -1,46 +1,40 @@ -# ND4J NDStructure implementation (`kmath-nd4j`) +# Module kmath-nd4j -This subproject implements the following features: +ND4J based implementations of KMath abstractions. - - [nd4jarraystructure](src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt) : NDStructure wrapper for INDArray - - [nd4jarrayrings](src/commonMain/kotlin/kscience/kmath/structures/NDStructure.kt) : Rings over Nd4jArrayStructure of Int and Long - - [nd4jarrayfields](src/commonMain/kotlin/kscience/kmath/structures/Buffers.kt) : Fields over Nd4jArrayStructure of Float and Double + - [nd4jarraystructure](#) : NDStructure wrapper for INDArray + - [nd4jarrayrings](#) : Rings over Nd4jArrayStructure of Int and Long + - [nd4jarrayfields](#) : Fields over Nd4jArrayStructure of Float and Double -> #### Artifact: -> -> This module artifact: `space.kscience:kmath-nd4j:0.3.0-dev-2`. -> -> Bintray release version: [ ![Download](https://api.bintray.com/packages/mipt-npm/kscience/kmath-nd4j/images/download.svg) ](https://bintray.com/mipt-npm/kscience/kmath-nd4j/_latestVersion) -> -> Bintray development version: [ ![Download](https://api.bintray.com/packages/mipt-npm/dev/kmath-nd4j/images/download.svg) ](https://bintray.com/mipt-npm/dev/kmath-nd4j/_latestVersion) -> -> **Gradle:** -> -> ```gradle -> repositories { -> maven { url 'https://repo.kotlin.link' } -> maven { url 'https://dl.bintray.com/hotkeytlt/maven' } -> maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap -> } -> -> dependencies { -> implementation 'space.kscience:kmath-nd4j:0.3.0-dev-2' -> } -> ``` -> **Gradle Kotlin DSL:** -> -> ```kotlin -> repositories { -> maven("https://repo.kotlin.link") -> maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap -> maven("https://dl.bintray.com/hotkeytlt/maven") // required for a -> } -> -> dependencies { -> implementation("space.kscience:kmath-nd4j:0.3.0-dev-2") -> } -> ``` +## Artifact: + +The Maven coordinates of this project are `space.kscience:kmath-nd4j:0.3.0-dev-6`. + +**Gradle:** +```gradle +repositories { + maven { url 'https://repo.kotlin.link' } + maven { url 'https://dl.bintray.com/hotkeytlt/maven' } + maven { url "https://dl.bintray.com/kotlin/kotlin-eap" } // include for builds based on kotlin-eap +} + +dependencies { + implementation 'space.kscience:kmath-nd4j:0.3.0-dev-6' +} +``` +**Gradle Kotlin DSL:** +```kotlin +repositories { + maven("https://repo.kotlin.link") + maven("https://dl.bintray.com/kotlin/kotlin-eap") // include for builds based on kotlin-eap + maven("https://dl.bintray.com/hotkeytlt/maven") // required for a +} + +dependencies { + implementation("space.kscience:kmath-nd4j:0.3.0-dev-6") +} +``` ## Examples @@ -51,7 +45,7 @@ import org.nd4j.linalg.factory.* import scientifik.kmath.nd4j.* import scientifik.kmath.structures.* -val array = Nd4j.ones(2, 2).asRealStructure() +val array = Nd4j.ones(2, 2).asDoubleStructure() println(array[0, 0]) // 1.0 array[intArrayOf(0, 0)] = 24.0 println(array[0, 0]) // 24.0 @@ -64,8 +58,8 @@ import org.nd4j.linalg.factory.* import scientifik.kmath.nd4j.* import scientifik.kmath.operations.* -val field = RealNd4jArrayField(intArrayOf(2, 2)) -val array = Nd4j.rand(2, 2).asRealStructure() +val field = DoubleNd4jArrayField(intArrayOf(2, 2)) +val array = Nd4j.rand(2, 2).asDoubleStructure() val res = field { (25.0 / array + 20) * 4 diff --git a/kmath-nd4j/build.gradle.kts b/kmath-nd4j/build.gradle.kts index f268884c1..17232b44f 100644 --- a/kmath-nd4j/build.gradle.kts +++ b/kmath-nd4j/build.gradle.kts @@ -6,7 +6,8 @@ import ru.mipt.npm.gradle.Maturity plugins { - id("ru.mipt.npm.gradle.jvm") + kotlin("jvm") + id("ru.mipt.npm.gradle.common") } dependencies { @@ -24,19 +25,16 @@ readme { feature( id = "nd4jarraystructure", - description = "NDStructure wrapper for INDArray", - ref = "src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt" + description = "NDStructure wrapper for INDArray" ) feature( id = "nd4jarrayrings", - description = "Rings over Nd4jArrayStructure of Int and Long", - ref = "src/commonMain/kotlin/kscience/kmath/structures/NDStructure.kt" + description = "Rings over Nd4jArrayStructure of Int and Long" ) feature( id = "nd4jarrayfields", - description = "Fields over Nd4jArrayStructure of Float and Double", - ref = "src/commonMain/kotlin/kscience/kmath/structures/Buffers.kt" + description = "Fields over Nd4jArrayStructure of Float and Double" ) } diff --git a/kmath-nd4j/docs/README-TEMPLATE.md b/kmath-nd4j/docs/README-TEMPLATE.md index 76ce8c9a7..5f325cab5 100644 --- a/kmath-nd4j/docs/README-TEMPLATE.md +++ b/kmath-nd4j/docs/README-TEMPLATE.md @@ -1,6 +1,6 @@ -# ND4J NDStructure implementation (`kmath-nd4j`) +# Module kmath-nd4j -This subproject implements the following features: +ND4J based implementations of KMath abstractions. ${features} @@ -15,7 +15,7 @@ import org.nd4j.linalg.factory.* import scientifik.kmath.nd4j.* import scientifik.kmath.structures.* -val array = Nd4j.ones(2, 2).asRealStructure() +val array = Nd4j.ones(2, 2).asDoubleStructure() println(array[0, 0]) // 1.0 array[intArrayOf(0, 0)] = 24.0 println(array[0, 0]) // 24.0 @@ -28,8 +28,8 @@ import org.nd4j.linalg.factory.* import scientifik.kmath.nd4j.* import scientifik.kmath.operations.* -val field = RealNd4jArrayField(intArrayOf(2, 2)) -val array = Nd4j.rand(2, 2).asRealStructure() +val field = DoubleNd4jArrayField(intArrayOf(2, 2)) +val array = Nd4j.rand(2, 2).asDoubleStructure() val res = field { (25.0 / array + 20) * 4 diff --git a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt index 2bede1402..f2c69adee 100644 --- a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt +++ b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt @@ -12,7 +12,7 @@ import space.kscience.kmath.nd.* import space.kscience.kmath.operations.* import space.kscience.kmath.structures.* -internal fun NDAlgebra<*, *>.checkShape(array: INDArray): INDArray { +internal fun AlgebraND<*, *>.checkShape(array: INDArray): INDArray { val arrayShape = array.shape().toIntArray() if (!shape.contentEquals(arrayShape)) throw ShapeMismatchException(shape, arrayShape) return array @@ -20,18 +20,18 @@ internal fun NDAlgebra<*, *>.checkShape(array: INDArray): INDArray { /** - * Represents [NDAlgebra] over [Nd4jArrayAlgebra]. + * Represents [AlgebraND] over [Nd4jArrayAlgebra]. * * @param T the type of ND-structure element. * @param C the type of the element context. */ -public interface Nd4jArrayAlgebra> : NDAlgebra { +public interface Nd4jArrayAlgebra> : AlgebraND { /** * Wraps [INDArray] to [N]. */ public fun INDArray.wrap(): Nd4jArrayStructure - public val NDStructure.ndArray: INDArray + public val StructureND.ndArray: INDArray get() = when { !shape.contentEquals(this@Nd4jArrayAlgebra.shape) -> throw ShapeMismatchException( this@Nd4jArrayAlgebra.shape, @@ -49,13 +49,13 @@ public interface Nd4jArrayAlgebra> : NDAlgebra { return struct } - public override fun NDStructure.map(transform: C.(T) -> T): Nd4jArrayStructure { + public override fun StructureND.map(transform: C.(T) -> T): Nd4jArrayStructure { val newStruct = ndArray.dup().wrap() newStruct.elements().forEach { (idx, value) -> newStruct[idx] = elementContext.transform(value) } return newStruct } - public override fun NDStructure.mapIndexed( + public override fun StructureND.mapIndexed( transform: C.(index: IntArray, T) -> T, ): Nd4jArrayStructure { val new = Nd4j.create(*this@Nd4jArrayAlgebra.shape).wrap() @@ -64,8 +64,8 @@ public interface Nd4jArrayAlgebra> : NDAlgebra { } public override fun combine( - a: NDStructure, - b: NDStructure, + a: StructureND, + b: StructureND, transform: C.(T, T) -> T, ): Nd4jArrayStructure { val new = Nd4j.create(*shape).wrap() @@ -75,42 +75,42 @@ public interface Nd4jArrayAlgebra> : NDAlgebra { } /** - * Represents [NDGroup] over [Nd4jArrayStructure]. + * Represents [GroupND] over [Nd4jArrayStructure]. * * @param T the type of the element contained in ND structure. * @param S the type of space of structure elements. */ -public interface Nd4JArrayGroup> : NDGroup, Nd4jArrayAlgebra { +public interface Nd4JArrayGroup> : GroupND, Nd4jArrayAlgebra { public override val zero: Nd4jArrayStructure get() = Nd4j.zeros(*shape).wrap() - public override fun add(a: NDStructure, b: NDStructure): Nd4jArrayStructure = + public override fun add(a: StructureND, b: StructureND): Nd4jArrayStructure = a.ndArray.add(b.ndArray).wrap() - public override operator fun NDStructure.minus(b: NDStructure): Nd4jArrayStructure = + public override operator fun StructureND.minus(b: StructureND): Nd4jArrayStructure = ndArray.sub(b.ndArray).wrap() - public override operator fun NDStructure.unaryMinus(): Nd4jArrayStructure = + public override operator fun StructureND.unaryMinus(): Nd4jArrayStructure = ndArray.neg().wrap() - public fun multiply(a: NDStructure, k: Number): Nd4jArrayStructure = + public fun multiply(a: StructureND, k: Number): Nd4jArrayStructure = a.ndArray.mul(k).wrap() } /** - * Represents [NDRing] over [Nd4jArrayStructure]. + * Represents [RingND] over [Nd4jArrayStructure]. * * @param T the type of the element contained in ND structure. * @param R the type of ring of structure elements. */ @OptIn(UnstableKMathAPI::class) -public interface Nd4jArrayRing> : NDRing, Nd4JArrayGroup { +public interface Nd4jArrayRing> : RingND, Nd4JArrayGroup { public override val one: Nd4jArrayStructure get() = Nd4j.ones(*shape).wrap() - public override fun multiply(a: NDStructure, b: NDStructure): Nd4jArrayStructure = + public override fun multiply(a: StructureND, b: StructureND): Nd4jArrayStructure = a.ndArray.mul(b.ndArray).wrap() // // public override operator fun Nd4jArrayStructure.minus(b: Number): Nd4jArrayStructure { @@ -136,19 +136,19 @@ public interface Nd4jArrayRing> : NDRing, Nd4JArrayGroup = intNd4jArrayRingCache.get().getOrPut(shape) { IntNd4jArrayRing(shape) } /** - * Creates an [NDRing] for [Long] values or pull it from cache if it was created previously. + * Creates an [RingND] for [Long] values or pull it from cache if it was created previously. */ public fun long(vararg shape: Int): Nd4jArrayRing = longNd4jArrayRingCache.get().getOrPut(shape) { LongNd4jArrayRing(shape) } /** - * Creates a most suitable implementation of [NDRing] using reified class. + * Creates a most suitable implementation of [RingND] using reified class. */ @Suppress("UNCHECKED_CAST") public inline fun auto(vararg shape: Int): Nd4jArrayRing> = when { @@ -160,40 +160,40 @@ public interface Nd4jArrayRing> : NDRing, Nd4JArrayGroup> : NDField, Nd4jArrayRing { +public interface Nd4jArrayField> : FieldND, Nd4jArrayRing { - public override fun divide(a: NDStructure, b: NDStructure): Nd4jArrayStructure = + public override fun divide(a: StructureND, b: StructureND): Nd4jArrayStructure = a.ndArray.div(b.ndArray).wrap() - public operator fun Number.div(b: NDStructure): Nd4jArrayStructure = b.ndArray.rdiv(this).wrap() + public operator fun Number.div(b: StructureND): Nd4jArrayStructure = b.ndArray.rdiv(this).wrap() public companion object { private val floatNd4jArrayFieldCache: ThreadLocal> = ThreadLocal.withInitial { hashMapOf() } - private val realNd4jArrayFieldCache: ThreadLocal> = + private val doubleNd4JArrayFieldCache: ThreadLocal> = ThreadLocal.withInitial { hashMapOf() } /** - * Creates an [NDField] for [Float] values or pull it from cache if it was created previously. + * Creates an [FieldND] for [Float] values or pull it from cache if it was created previously. */ public fun float(vararg shape: Int): Nd4jArrayRing = floatNd4jArrayFieldCache.get().getOrPut(shape) { FloatNd4jArrayField(shape) } /** - * Creates an [NDField] for [Double] values or pull it from cache if it was created previously. + * Creates an [FieldND] for [Double] values or pull it from cache if it was created previously. */ - public fun real(vararg shape: Int): Nd4jArrayRing = - realNd4jArrayFieldCache.get().getOrPut(shape) { RealNd4jArrayField(shape) } + public fun real(vararg shape: Int): Nd4jArrayRing = + doubleNd4JArrayFieldCache.get().getOrPut(shape) { DoubleNd4jArrayField(shape) } /** - * Creates a most suitable implementation of [NDRing] using reified class. + * Creates a most suitable implementation of [RingND] using reified class. */ @Suppress("UNCHECKED_CAST") public inline fun auto(vararg shape: Int): Nd4jArrayField> = when { @@ -205,44 +205,44 @@ public interface Nd4jArrayField> : NDField, Nd4jArrayRing< } /** - * Represents [NDField] over [Nd4jArrayRealStructure]. + * Represents [FieldND] over [Nd4jArrayDoubleStructure]. */ -public class RealNd4jArrayField(public override val shape: IntArray) : Nd4jArrayField { - public override val elementContext: RealField get() = RealField +public class DoubleNd4jArrayField(public override val shape: IntArray) : Nd4jArrayField { + public override val elementContext: DoubleField get() = DoubleField - public override fun INDArray.wrap(): Nd4jArrayStructure = checkShape(this).asRealStructure() + public override fun INDArray.wrap(): Nd4jArrayStructure = checkShape(this).asDoubleStructure() - override fun scale(a: NDStructure, value: Double): Nd4jArrayStructure { + override fun scale(a: StructureND, value: Double): Nd4jArrayStructure { return a.ndArray.mul(value).wrap() } - public override operator fun NDStructure.div(arg: Double): Nd4jArrayStructure { + public override operator fun StructureND.div(arg: Double): Nd4jArrayStructure { return ndArray.div(arg).wrap() } - public override operator fun NDStructure.plus(arg: Double): Nd4jArrayStructure { + public override operator fun StructureND.plus(arg: Double): Nd4jArrayStructure { return ndArray.add(arg).wrap() } - public override operator fun NDStructure.minus(arg: Double): Nd4jArrayStructure { + public override operator fun StructureND.minus(arg: Double): Nd4jArrayStructure { return ndArray.sub(arg).wrap() } - public override operator fun NDStructure.times(arg: Double): Nd4jArrayStructure { + public override operator fun StructureND.times(arg: Double): Nd4jArrayStructure { return ndArray.mul(arg).wrap() } - public override operator fun Double.div(arg: NDStructure): Nd4jArrayStructure { + public override operator fun Double.div(arg: StructureND): Nd4jArrayStructure { return arg.ndArray.rdiv(this).wrap() } - public override operator fun Double.minus(arg: NDStructure): Nd4jArrayStructure { + public override operator fun Double.minus(arg: StructureND): Nd4jArrayStructure { return arg.ndArray.rsub(this).wrap() } } /** - * Represents [NDField] over [Nd4jArrayStructure] of [Float]. + * Represents [FieldND] over [Nd4jArrayStructure] of [Float]. */ public class FloatNd4jArrayField(public override val shape: IntArray) : Nd4jArrayField { public override val elementContext: FloatField @@ -250,30 +250,30 @@ public class FloatNd4jArrayField(public override val shape: IntArray) : Nd4jArra public override fun INDArray.wrap(): Nd4jArrayStructure = checkShape(this).asFloatStructure() - override fun scale(a: NDStructure, value: Double): NDStructure = + override fun scale(a: StructureND, value: Double): StructureND = a.ndArray.mul(value).wrap() - public override operator fun NDStructure.div(arg: Float): Nd4jArrayStructure = + public override operator fun StructureND.div(arg: Float): Nd4jArrayStructure = ndArray.div(arg).wrap() - public override operator fun NDStructure.plus(arg: Float): Nd4jArrayStructure = + public override operator fun StructureND.plus(arg: Float): Nd4jArrayStructure = ndArray.add(arg).wrap() - public override operator fun NDStructure.minus(arg: Float): Nd4jArrayStructure = + public override operator fun StructureND.minus(arg: Float): Nd4jArrayStructure = ndArray.sub(arg).wrap() - public override operator fun NDStructure.times(arg: Float): Nd4jArrayStructure = + public override operator fun StructureND.times(arg: Float): Nd4jArrayStructure = ndArray.mul(arg).wrap() - public override operator fun Float.div(arg: NDStructure): Nd4jArrayStructure = + public override operator fun Float.div(arg: StructureND): Nd4jArrayStructure = arg.ndArray.rdiv(this).wrap() - public override operator fun Float.minus(arg: NDStructure): Nd4jArrayStructure = + public override operator fun Float.minus(arg: StructureND): Nd4jArrayStructure = arg.ndArray.rsub(this).wrap() } /** - * Represents [NDRing] over [Nd4jArrayIntStructure]. + * Represents [RingND] over [Nd4jArrayIntStructure]. */ public class IntNd4jArrayRing(public override val shape: IntArray) : Nd4jArrayRing { public override val elementContext: IntRing @@ -281,21 +281,21 @@ public class IntNd4jArrayRing(public override val shape: IntArray) : Nd4jArrayRi public override fun INDArray.wrap(): Nd4jArrayStructure = checkShape(this).asIntStructure() - public override operator fun NDStructure.plus(arg: Int): Nd4jArrayStructure = + public override operator fun StructureND.plus(arg: Int): Nd4jArrayStructure = ndArray.add(arg).wrap() - public override operator fun NDStructure.minus(arg: Int): Nd4jArrayStructure = + public override operator fun StructureND.minus(arg: Int): Nd4jArrayStructure = ndArray.sub(arg).wrap() - public override operator fun NDStructure.times(arg: Int): Nd4jArrayStructure = + public override operator fun StructureND.times(arg: Int): Nd4jArrayStructure = ndArray.mul(arg).wrap() - public override operator fun Int.minus(arg: NDStructure): Nd4jArrayStructure = + public override operator fun Int.minus(arg: StructureND): Nd4jArrayStructure = arg.ndArray.rsub(this).wrap() } /** - * Represents [NDRing] over [Nd4jArrayStructure] of [Long]. + * Represents [RingND] over [Nd4jArrayStructure] of [Long]. */ public class LongNd4jArrayRing(public override val shape: IntArray) : Nd4jArrayRing { public override val elementContext: LongRing @@ -303,15 +303,15 @@ public class LongNd4jArrayRing(public override val shape: IntArray) : Nd4jArrayR public override fun INDArray.wrap(): Nd4jArrayStructure = checkShape(this).asLongStructure() - public override operator fun NDStructure.plus(arg: Long): Nd4jArrayStructure = + public override operator fun StructureND.plus(arg: Long): Nd4jArrayStructure = ndArray.add(arg).wrap() - public override operator fun NDStructure.minus(arg: Long): Nd4jArrayStructure = + public override operator fun StructureND.minus(arg: Long): Nd4jArrayStructure = ndArray.sub(arg).wrap() - public override operator fun NDStructure.times(arg: Long): Nd4jArrayStructure = + public override operator fun StructureND.times(arg: Long): Nd4jArrayStructure = ndArray.mul(arg).wrap() - public override operator fun Long.minus(arg: NDStructure): Nd4jArrayStructure = + public override operator fun Long.minus(arg: StructureND): Nd4jArrayStructure = arg.ndArray.rsub(this).wrap() } diff --git a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayIterator.kt b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayIterator.kt index 77e1edd5f..71887ca3c 100644 --- a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayIterator.kt +++ b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayIterator.kt @@ -42,11 +42,11 @@ private sealed class Nd4jArrayIteratorBase(protected val iterateOver: INDArra } } -private class Nd4jArrayRealIterator(iterateOver: INDArray) : Nd4jArrayIteratorBase(iterateOver) { +private class Nd4jArrayDoubleIterator(iterateOver: INDArray) : Nd4jArrayIteratorBase(iterateOver) { override fun getSingle(indices: LongArray): Double = iterateOver.getDouble(*indices) } -internal fun INDArray.realIterator(): Iterator> = Nd4jArrayRealIterator(this) +internal fun INDArray.realIterator(): Iterator> = Nd4jArrayDoubleIterator(this) private class Nd4jArrayLongIterator(iterateOver: INDArray) : Nd4jArrayIteratorBase(iterateOver) { override fun getSingle(indices: LongArray) = iterateOver.getLong(*indices) diff --git a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt index 70b2570c9..b9aa251d2 100644 --- a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt +++ b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt @@ -6,15 +6,15 @@ package space.kscience.kmath.nd4j import org.nd4j.linalg.api.ndarray.INDArray -import space.kscience.kmath.nd.MutableNDStructure -import space.kscience.kmath.nd.NDStructure +import space.kscience.kmath.nd.MutableStructureND +import space.kscience.kmath.nd.StructureND /** - * Represents a [NDStructure] wrapping an [INDArray] object. + * Represents a [StructureND] wrapping an [INDArray] object. * * @param T the type of items. */ -public sealed class Nd4jArrayStructure : MutableNDStructure { +public sealed class Nd4jArrayStructure : MutableStructureND { /** * The wrapped [INDArray]. */ @@ -50,7 +50,7 @@ private data class Nd4jArrayLongStructure(override val ndArray: INDArray) : Nd4j */ public fun INDArray.asLongStructure(): Nd4jArrayStructure = Nd4jArrayLongStructure(this) -private data class Nd4jArrayRealStructure(override val ndArray: INDArray) : Nd4jArrayStructure() { +private data class Nd4jArrayDoubleStructure(override val ndArray: INDArray) : Nd4jArrayStructure() { override fun elementsIterator(): Iterator> = ndArray.realIterator() override fun get(index: IntArray): Double = ndArray.getDouble(*index) override fun set(index: IntArray, value: Double): Unit = run { ndArray.putScalar(index, value) } @@ -59,7 +59,7 @@ private data class Nd4jArrayRealStructure(override val ndArray: INDArray) : Nd4j /** * Wraps this [INDArray] to [Nd4jArrayStructure]. */ -public fun INDArray.asRealStructure(): Nd4jArrayStructure = Nd4jArrayRealStructure(this) +public fun INDArray.asDoubleStructure(): Nd4jArrayStructure = Nd4jArrayDoubleStructure(this) private data class Nd4jArrayFloatStructure(override val ndArray: INDArray) : Nd4jArrayStructure() { override fun elementsIterator(): Iterator> = ndArray.floatIterator() diff --git a/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebraTest.kt b/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebraTest.kt index 5ada02d4b..c3874b249 100644 --- a/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebraTest.kt +++ b/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebraTest.kt @@ -13,8 +13,8 @@ import kotlin.test.fail internal class Nd4jArrayAlgebraTest { @Test fun testProduce() { - val res = with(RealNd4jArrayField(intArrayOf(2, 2))){ produce { it.sum().toDouble() } } - val expected = (Nd4j.create(2, 2) ?: fail()).asRealStructure() + val res = with(DoubleNd4jArrayField(intArrayOf(2, 2))) { produce { it.sum().toDouble() } } + val expected = (Nd4j.create(2, 2) ?: fail()).asDoubleStructure() expected[intArrayOf(0, 0)] = 0.0 expected[intArrayOf(0, 1)] = 1.0 expected[intArrayOf(1, 0)] = 1.0 diff --git a/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructureTest.kt b/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructureTest.kt index f05bf9c84..d59e04194 100644 --- a/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructureTest.kt +++ b/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructureTest.kt @@ -16,7 +16,7 @@ internal class Nd4jArrayStructureTest { @Test fun testElements() { val nd = Nd4j.create(doubleArrayOf(1.0, 2.0, 3.0))!! - val struct = nd.asRealStructure() + val struct = nd.asDoubleStructure() val res = struct.elements().map(Pair::second).toList() assertEquals(listOf(1.0, 2.0, 3.0), res) } @@ -24,32 +24,32 @@ internal class Nd4jArrayStructureTest { @Test fun testShape() { val nd = Nd4j.rand(10, 2, 3, 6) ?: fail() - val struct = nd.asRealStructure() + val struct = nd.asDoubleStructure() assertEquals(intArrayOf(10, 2, 3, 6).toList(), struct.shape.toList()) } @Test fun testEquals() { val nd1 = Nd4j.create(doubleArrayOf(1.0, 2.0, 3.0)) ?: fail() - val struct1 = nd1.asRealStructure() + val struct1 = nd1.asDoubleStructure() assertEquals(struct1, struct1) assertNotEquals(struct1 as Any?, null) val nd2 = Nd4j.create(doubleArrayOf(1.0, 2.0, 3.0)) ?: fail() - val struct2 = nd2.asRealStructure() + val struct2 = nd2.asDoubleStructure() assertEquals(struct1, struct2) assertEquals(struct2, struct1) val nd3 = Nd4j.create(doubleArrayOf(1.0, 2.0, 3.0)) ?: fail() - val struct3 = nd3.asRealStructure() + val struct3 = nd3.asDoubleStructure() assertEquals(struct2, struct3) assertEquals(struct1, struct3) } @Test fun testHashCode() { - val nd1 = Nd4j.create(doubleArrayOf(1.0, 2.0, 3.0))?:fail() - val struct1 = nd1.asRealStructure() - val nd2 = Nd4j.create(doubleArrayOf(1.0, 2.0, 3.0))?:fail() - val struct2 = nd2.asRealStructure() + val nd1 = Nd4j.create(doubleArrayOf(1.0, 2.0, 3.0)) ?: fail() + val struct1 = nd1.asDoubleStructure() + val nd2 = Nd4j.create(doubleArrayOf(1.0, 2.0, 3.0)) ?: fail() + val struct2 = nd2.asDoubleStructure() assertEquals(struct1.hashCode(), struct2.hashCode()) } @@ -62,7 +62,7 @@ internal class Nd4jArrayStructureTest { @Test fun testGet() { - val nd = Nd4j.rand(10, 2, 3, 6)?:fail() + val nd = Nd4j.rand(10, 2, 3, 6) ?: fail() val struct = nd.asIntStructure() assertEquals(nd.getInt(0, 0, 0, 0), struct[0, 0, 0, 0]) } diff --git a/kmath-stat/build.gradle.kts b/kmath-stat/build.gradle.kts index 28361c0bc..dff504ef0 100644 --- a/kmath-stat/build.gradle.kts +++ b/kmath-stat/build.gradle.kts @@ -3,19 +3,18 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ +import ru.mipt.npm.gradle.Maturity + plugins { - id("ru.mipt.npm.gradle.mpp") + kotlin("multiplatform") + id("ru.mipt.npm.gradle.common") +} + +kscience { + useAtomic() } kotlin.sourceSets { - all { - languageSettings.apply { - useExperimentalAnnotation("kotlinx.coroutines.FlowPreview") - useExperimentalAnnotation("kotlinx.coroutines.ExperimentalCoroutinesApi") - useExperimentalAnnotation("kotlinx.coroutines.ObsoleteCoroutinesApi") - } - } - commonMain { dependencies { api(project(":kmath-coroutines")) @@ -30,6 +29,6 @@ kotlin.sourceSets { } } -readme{ - maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL +readme { + maturity = Maturity.EXPERIMENTAL } \ No newline at end of file diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/Distribution.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/Distribution.kt new file mode 100644 index 000000000..e3adcdc44 --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/Distribution.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.distributions + +import space.kscience.kmath.chains.Chain +import space.kscience.kmath.stat.RandomGenerator +import space.kscience.kmath.stat.Sampler + +/** + * A distribution of typed objects. + */ +public interface Distribution : Sampler { + /** + * A probability value for given argument [arg]. + * For continuous distributions returns PDF + */ + public fun probability(arg: T): Double + + public override fun sample(generator: RandomGenerator): Chain + + /** + * An empty companion. Distribution factories should be written as its extensions + */ + public companion object +} + +public interface UnivariateDistribution> : Distribution { + /** + * Cumulative distribution for ordered parameter (CDF) + */ + public fun cumulative(arg: T): Double +} + +/** + * Compute probability integral in an interval + */ +public fun > UnivariateDistribution.integral(from: T, to: T): Double { + require(to > from) + return cumulative(to) - cumulative(from) +} diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/FactorizedDistribution.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/FactorizedDistribution.kt similarity index 87% rename from kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/FactorizedDistribution.kt rename to kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/FactorizedDistribution.kt index a57a0af4d..dde429244 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/FactorizedDistribution.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/FactorizedDistribution.kt @@ -3,10 +3,11 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ -package space.kscience.kmath.stat +package space.kscience.kmath.distributions import space.kscience.kmath.chains.Chain import space.kscience.kmath.chains.SimpleChain +import space.kscience.kmath.stat.RandomGenerator /** * A multivariate distribution which takes a map of parameters @@ -19,7 +20,7 @@ public interface NamedDistribution : Distribution> public class FactorizedDistribution(public val distributions: Collection>) : NamedDistribution { override fun probability(arg: Map): Double = - distributions.fold(1.0) { acc, distr -> acc * distr.probability(arg) } + distributions.fold(1.0) { acc, dist -> acc * dist.probability(arg) } override fun sample(generator: RandomGenerator): Chain> { val chains = distributions.map { it.sample(generator) } @@ -43,6 +44,6 @@ public class DistributionBuilder { private val distributions = ArrayList>() public infix fun String.to(distribution: Distribution) { - distributions.add(NamedDistributionWrapper(this, distribution)) + distributions += NamedDistributionWrapper(this, distribution) } } diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/NormalDistribution.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/NormalDistribution.kt new file mode 100644 index 000000000..04ec8b171 --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/NormalDistribution.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.distributions + +import space.kscience.kmath.chains.Chain +import space.kscience.kmath.internal.InternalErf +import space.kscience.kmath.samplers.GaussianSampler +import space.kscience.kmath.samplers.NormalizedGaussianSampler +import space.kscience.kmath.samplers.ZigguratNormalizedGaussianSampler +import space.kscience.kmath.stat.RandomGenerator +import kotlin.math.* + +/** + * Implements [UnivariateDistribution] for the normal (gaussian) distribution. + */ +public class NormalDistribution(public val sampler: GaussianSampler) : UnivariateDistribution { + public constructor( + mean: Double, + standardDeviation: Double, + normalized: NormalizedGaussianSampler = ZigguratNormalizedGaussianSampler, + ) : this(GaussianSampler(mean, standardDeviation, normalized)) + + public override fun probability(arg: Double): Double { + val x1 = (arg - sampler.mean) / sampler.standardDeviation + return exp(-0.5 * x1 * x1 - (ln(sampler.standardDeviation) + 0.5 * ln(2 * PI))) + } + + public override fun sample(generator: RandomGenerator): Chain = sampler.sample(generator) + + public override fun cumulative(arg: Double): Double { + val dev = arg - sampler.mean + + return when { + abs(dev) > 40 * sampler.standardDeviation -> if (dev < 0) 0.0 else 1.0 + else -> 0.5 * InternalErf.erfc(-dev / (sampler.standardDeviation * SQRT2)) + } + } + + private companion object { + private val SQRT2 = sqrt(2.0) + } +} diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/internal/InternalErf.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/internal/InternalErf.kt new file mode 100644 index 000000000..25668446c --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/internal/InternalErf.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.internal + +import kotlin.math.abs + +/** + * Based on Commons Math implementation. + * See [https://commons.apache.org/proper/commons-math/javadocs/api-3.3/org/apache/commons/math3/special/Erf.html]. + */ +internal object InternalErf { + fun erfc(x: Double): Double { + if (abs(x) > 40) return if (x > 0) 0.0 else 2.0 + val ret = InternalGamma.regularizedGammaQ(0.5, x * x, 10000) + return if (x < 0) 2 - ret else ret + } +} \ No newline at end of file diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/internal/InternalGamma.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/internal/InternalGamma.kt new file mode 100644 index 000000000..a584af4f9 --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/internal/InternalGamma.kt @@ -0,0 +1,243 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.internal + +import kotlin.math.* + +private abstract class ContinuedFraction protected constructor() { + protected abstract fun getA(n: Int, x: Double): Double + protected abstract fun getB(n: Int, x: Double): Double + + fun evaluate(x: Double, maxIterations: Int): Double { + val small = 1e-50 + var hPrev = getA(0, x) + if (hPrev == 0.0 || abs(0.0 - hPrev) <= small) hPrev = small + var n = 1 + var dPrev = 0.0 + var cPrev = hPrev + var hN = hPrev + + while (n < maxIterations) { + val a = getA(n, x) + val b = getB(n, x) + var dN = a + b * dPrev + if (dN == 0.0 || abs(0.0 - dN) <= small) dN = small + var cN = a + b / cPrev + if (cN == 0.0 || abs(0.0 - cN) <= small) cN = small + dN = 1 / dN + val deltaN = cN * dN + hN = hPrev * deltaN + check(!hN.isInfinite()) { "hN is infinite" } + check(!hN.isNaN()) { "hN is NaN" } + if (abs(deltaN - 1.0) < 10e-9) break + dPrev = dN + cPrev = cN + hPrev = hN + n++ + } + + check(n < maxIterations) { "n is more than maxIterations" } + return hN + } +} + +internal object InternalGamma { + const val LANCZOS_G = 607.0 / 128.0 + + private val LANCZOS = doubleArrayOf( + 0.99999999999999709182, + 57.156235665862923517, + -59.597960355475491248, + 14.136097974741747174, + -0.49191381609762019978, + .33994649984811888699e-4, + .46523628927048575665e-4, + -.98374475304879564677e-4, + .15808870322491248884e-3, + -.21026444172410488319e-3, + .21743961811521264320e-3, + -.16431810653676389022e-3, + .84418223983852743293e-4, + -.26190838401581408670e-4, + .36899182659531622704e-5 + ) + + private val HALF_LOG_2_PI = 0.5 * ln(2.0 * PI) + private const val INV_GAMMA1P_M1_A0 = .611609510448141581788E-08 + private const val INV_GAMMA1P_M1_A1 = .624730830116465516210E-08 + private const val INV_GAMMA1P_M1_B1 = .203610414066806987300E+00 + private const val INV_GAMMA1P_M1_B2 = .266205348428949217746E-01 + private const val INV_GAMMA1P_M1_B3 = .493944979382446875238E-03 + private const val INV_GAMMA1P_M1_B4 = -.851419432440314906588E-05 + private const val INV_GAMMA1P_M1_B5 = -.643045481779353022248E-05 + private const val INV_GAMMA1P_M1_B6 = .992641840672773722196E-06 + private const val INV_GAMMA1P_M1_B7 = -.607761895722825260739E-07 + private const val INV_GAMMA1P_M1_B8 = .195755836614639731882E-09 + private const val INV_GAMMA1P_M1_P0 = .6116095104481415817861E-08 + private const val INV_GAMMA1P_M1_P1 = .6871674113067198736152E-08 + private const val INV_GAMMA1P_M1_P2 = .6820161668496170657918E-09 + private const val INV_GAMMA1P_M1_P3 = .4686843322948848031080E-10 + private const val INV_GAMMA1P_M1_P4 = .1572833027710446286995E-11 + private const val INV_GAMMA1P_M1_P5 = -.1249441572276366213222E-12 + private const val INV_GAMMA1P_M1_P6 = .4343529937408594255178E-14 + private const val INV_GAMMA1P_M1_Q1 = .3056961078365221025009E+00 + private const val INV_GAMMA1P_M1_Q2 = .5464213086042296536016E-01 + private const val INV_GAMMA1P_M1_Q3 = .4956830093825887312020E-02 + private const val INV_GAMMA1P_M1_Q4 = .2692369466186361192876E-03 + private const val INV_GAMMA1P_M1_C = -.422784335098467139393487909917598E+00 + private const val INV_GAMMA1P_M1_C0 = .577215664901532860606512090082402E+00 + private const val INV_GAMMA1P_M1_C1 = -.655878071520253881077019515145390E+00 + private const val INV_GAMMA1P_M1_C2 = -.420026350340952355290039348754298E-01 + private const val INV_GAMMA1P_M1_C3 = .166538611382291489501700795102105E+00 + private const val INV_GAMMA1P_M1_C4 = -.421977345555443367482083012891874E-01 + private const val INV_GAMMA1P_M1_C5 = -.962197152787697356211492167234820E-02 + private const val INV_GAMMA1P_M1_C6 = .721894324666309954239501034044657E-02 + private const val INV_GAMMA1P_M1_C7 = -.116516759185906511211397108401839E-02 + private const val INV_GAMMA1P_M1_C8 = -.215241674114950972815729963053648E-03 + private const val INV_GAMMA1P_M1_C9 = .128050282388116186153198626328164E-03 + private const val INV_GAMMA1P_M1_C10 = -.201348547807882386556893914210218E-04 + private const val INV_GAMMA1P_M1_C11 = -.125049348214267065734535947383309E-05 + private const val INV_GAMMA1P_M1_C12 = .113302723198169588237412962033074E-05 + private const val INV_GAMMA1P_M1_C13 = -.205633841697760710345015413002057E-06 + + fun logGamma(x: Double): Double = when { + x.isNaN() || x <= 0.0 -> Double.NaN + x < 0.5 -> logGamma1p(x) - ln(x) + x <= 2.5 -> logGamma1p(x - 0.5 - 0.5) + + x <= 8.0 -> { + val n = floor(x - 1.5).toInt() + val prod = (1..n).fold(1.0, { prod, i -> prod * (x - i) }) + logGamma1p(x - (n + 1)) + ln(prod) + } + + else -> { + val tmp = x + LANCZOS_G + .5 + (x + .5) * ln(tmp) - tmp + HALF_LOG_2_PI + ln(lanczos(x) / x) + } + } + + private fun regularizedGammaP( + a: Double, + x: Double, + maxIterations: Int = Int.MAX_VALUE + ): Double = when { + a.isNaN() || x.isNaN() || a <= 0.0 || x < 0.0 -> Double.NaN + x == 0.0 -> 0.0 + x >= a + 1 -> 1.0 - regularizedGammaQ(a, x, maxIterations) + + else -> { + // calculate series + var n = 0.0 // current element index + var an = 1.0 / a // n-th element in the series + var sum = an // partial sum + + while (abs(an / sum) > 10e-15 && n < maxIterations && sum < Double.POSITIVE_INFINITY) { + // compute next element in the series + n += 1.0 + an *= x / (a + n) + + // update partial sum + sum += an + } + + when { + n >= maxIterations -> throw error("Maximal iterations is exceeded $maxIterations") + sum.isInfinite() -> 1.0 + else -> exp(-x + a * ln(x) - logGamma(a)) * sum + } + } + } + + fun regularizedGammaQ( + a: Double, + x: Double, + maxIterations: Int = Int.MAX_VALUE + ): Double = when { + a.isNaN() || x.isNaN() || a <= 0.0 || x < 0.0 -> Double.NaN + x == 0.0 -> 1.0 + x < a + 1.0 -> 1.0 - regularizedGammaP(a, x, maxIterations) + + else -> 1.0 / object : ContinuedFraction() { + override fun getA(n: Int, x: Double): Double = 2.0 * n + 1.0 - a + x + override fun getB(n: Int, x: Double): Double = n * (a - n) + }.evaluate(x, maxIterations) * exp(-x + a * ln(x) - logGamma(a)) + } + + private fun lanczos(x: Double): Double = + (LANCZOS.size - 1 downTo 1).sumOf { LANCZOS[it] / (x + it) } + LANCZOS[0] + + private fun invGamma1pm1(x: Double): Double { + require(x >= -0.5) + require(x <= 1.5) + val ret: Double + val t = if (x <= 0.5) x else x - 0.5 - 0.5 + + if (t < 0.0) { + val a = INV_GAMMA1P_M1_A0 + t * INV_GAMMA1P_M1_A1 + var b = INV_GAMMA1P_M1_B8 + b = INV_GAMMA1P_M1_B7 + t * b + b = INV_GAMMA1P_M1_B6 + t * b + b = INV_GAMMA1P_M1_B5 + t * b + b = INV_GAMMA1P_M1_B4 + t * b + b = INV_GAMMA1P_M1_B3 + t * b + b = INV_GAMMA1P_M1_B2 + t * b + b = INV_GAMMA1P_M1_B1 + t * b + b = 1.0 + t * b + var c = INV_GAMMA1P_M1_C13 + t * (a / b) + c = INV_GAMMA1P_M1_C12 + t * c + c = INV_GAMMA1P_M1_C11 + t * c + c = INV_GAMMA1P_M1_C10 + t * c + c = INV_GAMMA1P_M1_C9 + t * c + c = INV_GAMMA1P_M1_C8 + t * c + c = INV_GAMMA1P_M1_C7 + t * c + c = INV_GAMMA1P_M1_C6 + t * c + c = INV_GAMMA1P_M1_C5 + t * c + c = INV_GAMMA1P_M1_C4 + t * c + c = INV_GAMMA1P_M1_C3 + t * c + c = INV_GAMMA1P_M1_C2 + t * c + c = INV_GAMMA1P_M1_C1 + t * c + c = INV_GAMMA1P_M1_C + t * c + ret = (if (x > 0.5) t * c / x else x * (c + 0.5 + 0.5)) + } else { + var p = INV_GAMMA1P_M1_P6 + p = INV_GAMMA1P_M1_P5 + t * p + p = INV_GAMMA1P_M1_P4 + t * p + p = INV_GAMMA1P_M1_P3 + t * p + p = INV_GAMMA1P_M1_P2 + t * p + p = INV_GAMMA1P_M1_P1 + t * p + p = INV_GAMMA1P_M1_P0 + t * p + var q = INV_GAMMA1P_M1_Q4 + q = INV_GAMMA1P_M1_Q3 + t * q + q = INV_GAMMA1P_M1_Q2 + t * q + q = INV_GAMMA1P_M1_Q1 + t * q + q = 1.0 + t * q + var c = INV_GAMMA1P_M1_C13 + p / q * t + c = INV_GAMMA1P_M1_C12 + t * c + c = INV_GAMMA1P_M1_C11 + t * c + c = INV_GAMMA1P_M1_C10 + t * c + c = INV_GAMMA1P_M1_C9 + t * c + c = INV_GAMMA1P_M1_C8 + t * c + c = INV_GAMMA1P_M1_C7 + t * c + c = INV_GAMMA1P_M1_C6 + t * c + c = INV_GAMMA1P_M1_C5 + t * c + c = INV_GAMMA1P_M1_C4 + t * c + c = INV_GAMMA1P_M1_C3 + t * c + c = INV_GAMMA1P_M1_C2 + t * c + c = INV_GAMMA1P_M1_C1 + t * c + c = INV_GAMMA1P_M1_C0 + t * c + ret = (if (x > 0.5) t / x * (c - 0.5 - 0.5) else x * c) + } + + return ret + } + + private fun logGamma1p(x: Double): Double { + require(x >= -0.5) + require(x <= 1.5) + return -ln1p(invGamma1pm1(x)) + } +} diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/internal/InternalUtils.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/internal/InternalUtils.kt new file mode 100644 index 000000000..3997a77b3 --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/internal/InternalUtils.kt @@ -0,0 +1,75 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.internal + +import kotlin.math.ln +import kotlin.math.min + +internal object InternalUtils { + private val FACTORIALS = longArrayOf( + 1L, 1L, 2L, + 6L, 24L, 120L, + 720L, 5040L, 40320L, + 362880L, 3628800L, 39916800L, + 479001600L, 6227020800L, 87178291200L, + 1307674368000L, 20922789888000L, 355687428096000L, + 6402373705728000L, 121645100408832000L, 2432902008176640000L + ) + + private const val BEGIN_LOG_FACTORIALS = 2 + + fun factorial(n: Int): Long = FACTORIALS[n] + + fun validateProbabilities(probabilities: DoubleArray?): Double { + require(!(probabilities == null || probabilities.isEmpty())) { "Probabilities must not be empty." } + + val sumProb = probabilities.sumOf { prob -> + require(!(prob < 0 || prob.isInfinite() || prob.isNaN())) { "Invalid probability: $prob" } + prob + } + + require(!(sumProb.isInfinite() || sumProb <= 0)) { "Invalid sum of probabilities: $sumProb" } + return sumProb + } + + class FactorialLog private constructor(numValues: Int, cache: DoubleArray?) { + private val logFactorials: DoubleArray = DoubleArray(numValues) + + init { + val endCopy: Int + + if (cache != null && cache.size > BEGIN_LOG_FACTORIALS) { + // Copy available values. + endCopy = min(cache.size, numValues) + + cache.copyInto( + logFactorials, + BEGIN_LOG_FACTORIALS, + BEGIN_LOG_FACTORIALS, endCopy + ) + } else + // All values to be computed + endCopy = BEGIN_LOG_FACTORIALS + + // Compute remaining values. + (endCopy until numValues).forEach { i -> + if (i < FACTORIALS.size) + logFactorials[i] = ln(FACTORIALS[i].toDouble()) + else + logFactorials[i] = logFactorials[i - 1] + ln(i.toDouble()) + } + } + + fun value(n: Int): Double { + if (n < logFactorials.size) return logFactorials[n] + return if (n < FACTORIALS.size) ln(FACTORIALS[n].toDouble()) else InternalGamma.logGamma(n + 1.0) + } + + companion object { + fun create(): FactorialLog = FactorialLog(0, null) + } + } +} \ No newline at end of file diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt new file mode 100644 index 000000000..38f3038c2 --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt @@ -0,0 +1,94 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.optimization + +import space.kscience.kmath.expressions.AutoDiffProcessor +import space.kscience.kmath.expressions.DifferentiableExpression +import space.kscience.kmath.expressions.Expression +import space.kscience.kmath.expressions.ExpressionAlgebra +import space.kscience.kmath.misc.Symbol +import space.kscience.kmath.operations.ExtendedField +import space.kscience.kmath.structures.Buffer +import space.kscience.kmath.structures.indices + +/** + * A likelihood function optimization problem with provided derivatives + */ +public interface FunctionOptimization : Optimization { + /** + * The optimization direction. If true search for function maximum, if false, search for the minimum + */ + public var maximize: Boolean + + /** + * Define the initial guess for the optimization problem + */ + public fun initialGuess(map: Map) + + /** + * Set a differentiable expression as objective function as function and gradient provider + */ + public fun diffFunction(expression: DifferentiableExpression>) + + public companion object { + /** + * Generate a chi squared expression from given x-y-sigma data and inline model. Provides automatic differentiation + */ + public fun chiSquared( + autoDiff: AutoDiffProcessor>, + x: Buffer, + y: Buffer, + yErr: Buffer, + model: A.(I) -> I, + ): DifferentiableExpression> where A : ExtendedField, A : ExpressionAlgebra { + require(x.size == y.size) { "X and y buffers should be of the same size" } + require(y.size == yErr.size) { "Y and yErr buffer should of the same size" } + + return autoDiff.process { + var sum = zero + + x.indices.forEach { + val xValue = const(x[it]) + val yValue = const(y[it]) + val yErrValue = const(yErr[it]) + val modelValue = model(xValue) + sum += ((yValue - modelValue) / yErrValue).pow(2) + } + + sum + } + } + } +} + +/** + * Define a chi-squared-based objective function + */ +public fun FunctionOptimization.chiSquared( + autoDiff: AutoDiffProcessor>, + x: Buffer, + y: Buffer, + yErr: Buffer, + model: A.(I) -> I, +) where A : ExtendedField, A : ExpressionAlgebra { + val chiSquared = FunctionOptimization.chiSquared(autoDiff, x, y, yErr, model) + diffFunction(chiSquared) + maximize = false +} + +/** + * Optimize differentiable expression using specific [OptimizationProblemFactory] + */ +public fun > DifferentiableExpression>.optimizeWith( + factory: OptimizationProblemFactory, + vararg symbols: Symbol, + configuration: F.() -> Unit, +): OptimizationResult { + require(symbols.isNotEmpty()) { "Must provide a list of symbols for optimization" } + val problem = factory(symbols.toList(), configuration) + problem.diffFunction(this) + return problem.optimize() +} diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/NoDerivFunctionOptimization.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/NoDerivFunctionOptimization.kt new file mode 100644 index 000000000..67a21bf2a --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/NoDerivFunctionOptimization.kt @@ -0,0 +1,74 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.optimization + +import space.kscience.kmath.expressions.Expression +import space.kscience.kmath.misc.Symbol +import space.kscience.kmath.structures.Buffer +import space.kscience.kmath.structures.indices +import kotlin.math.pow + +/** + * A likelihood function optimization problem + */ +public interface NoDerivFunctionOptimization : Optimization { + /** + * The optimization direction. If true search for function maximum, if false, search for the minimum + */ + public var maximize: Boolean + + /** + * Define the initial guess for the optimization problem + */ + public fun initialGuess(map: Map) + + /** + * Set an objective function expression + */ + public fun function(expression: Expression) + + public companion object { + /** + * Generate a chi squared expression from given x-y-sigma model represented by an expression. Does not provide derivatives + */ + public fun chiSquared( + x: Buffer, + y: Buffer, + yErr: Buffer, + model: Expression, + xSymbol: Symbol = Symbol.x, + ): Expression { + require(x.size == y.size) { "X and y buffers should be of the same size" } + require(y.size == yErr.size) { "Y and yErr buffer should of the same size" } + + return Expression { arguments -> + x.indices.sumOf { + val xValue = x[it] + val yValue = y[it] + val yErrValue = yErr[it] + val modifiedArgs = arguments + (xSymbol to xValue) + val modelValue = model(modifiedArgs) + ((yValue - modelValue) / yErrValue).pow(2) + } + } + } + } +} + + +/** + * Optimize expression without derivatives using specific [OptimizationProblemFactory] + */ +public fun > Expression.noDerivOptimizeWith( + factory: OptimizationProblemFactory, + vararg symbols: Symbol, + configuration: F.() -> Unit, +): OptimizationResult { + require(symbols.isNotEmpty()) { "Must provide a list of symbols for optimization" } + val problem = factory(symbols.toList(), configuration) + problem.function(this) + return problem.optimize() +} diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/Optimization.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/Optimization.kt new file mode 100644 index 000000000..3b9868815 --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/Optimization.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.optimization + +import space.kscience.kmath.misc.Symbol + +public interface OptimizationFeature + +public class OptimizationResult( + public val point: Map, + public val value: T, + public val features: Set = emptySet(), +) { + override fun toString(): String { + return "OptimizationResult(point=$point, value=$value)" + } +} + +public operator fun OptimizationResult.plus( + feature: OptimizationFeature, +): OptimizationResult = OptimizationResult(point, value, features + feature) + +/** + * An optimization problem builder over [T] variables + */ +public interface Optimization { + + /** + * Update the problem from previous optimization run + */ + public fun update(result: OptimizationResult) + + /** + * Make an optimization run + */ + public fun optimize(): OptimizationResult +} + +public fun interface OptimizationProblemFactory> { + public fun build(symbols: List): P +} + +public operator fun > OptimizationProblemFactory.invoke( + symbols: List, + block: P.() -> Unit, +): P = build(symbols).apply(block) diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt new file mode 100644 index 000000000..f5cfa05e6 --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.optimization + +import space.kscience.kmath.data.ColumnarData +import space.kscience.kmath.expressions.AutoDiffProcessor +import space.kscience.kmath.expressions.DifferentiableExpression +import space.kscience.kmath.expressions.Expression +import space.kscience.kmath.expressions.ExpressionAlgebra +import space.kscience.kmath.misc.Symbol +import space.kscience.kmath.misc.UnstableKMathAPI +import space.kscience.kmath.operations.ExtendedField +import space.kscience.kmath.operations.Field + +@UnstableKMathAPI +public interface XYFit : Optimization { + + public val algebra: Field + + /** + * Set X-Y data for this fit optionally including x and y errors + */ + public fun data( + dataSet: ColumnarData, + xSymbol: Symbol, + ySymbol: Symbol, + xErrSymbol: Symbol? = null, + yErrSymbol: Symbol? = null, + ) + + public fun model(model: (T) -> DifferentiableExpression) + + /** + * Set the differentiable model for this fit + */ + public fun model( + autoDiff: AutoDiffProcessor>, + modelFunction: A.(I) -> I, + ): Unit where A : ExtendedField, A : ExpressionAlgebra = model { arg -> + autoDiff.process { modelFunction(const(arg)) } + } +} \ No newline at end of file diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterExponentialSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterExponentialSampler.kt new file mode 100644 index 000000000..a231842df --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterExponentialSampler.kt @@ -0,0 +1,77 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.samplers + +import space.kscience.kmath.chains.BlockingDoubleChain +import space.kscience.kmath.stat.RandomGenerator +import space.kscience.kmath.stat.Sampler +import space.kscience.kmath.structures.DoubleBuffer +import kotlin.math.ln +import kotlin.math.pow + +/** + * Sampling from an [exponential distribution](http://mathworld.wolfram.com/ExponentialDistribution.html). + * + * Based on Commons RNG implementation. + * See [https://commons.apache.org/proper/commons-rng/commons-rng-sampling/apidocs/org/apache/commons/rng/sampling/distribution/AhrensDieterExponentialSampler.html]. + */ +public class AhrensDieterExponentialSampler(public val mean: Double) : Sampler { + + init { + require(mean > 0) { "mean is not strictly positive: $mean" } + } + + public override fun sample(generator: RandomGenerator): BlockingDoubleChain = object : BlockingDoubleChain { + override fun nextBlocking(): Double { + // Step 1: + var a = 0.0 + var u = generator.nextDouble() + + // Step 2 and 3: + while (u < 0.5) { + a += EXPONENTIAL_SA_QI[0] + u *= 2.0 + } + + // Step 4 (now u >= 0.5): + u += u - 1 + // Step 5: + if (u <= EXPONENTIAL_SA_QI[0]) return mean * (a + u) + // Step 6: + var i = 0 // Should be 1, be we iterate before it in while using 0. + var u2 = generator.nextDouble() + var umin = u2 + + // Step 7 and 8: + do { + ++i + u2 = generator.nextDouble() + if (u2 < umin) umin = u2 + // Step 8: + } while (u > EXPONENTIAL_SA_QI[i]) // Ensured to exit since EXPONENTIAL_SA_QI[MAX] = 1. + + return mean * (a + umin * EXPONENTIAL_SA_QI[0]) + } + + override fun nextBufferBlocking(size: Int): DoubleBuffer = DoubleBuffer(size) { nextBlocking() } + + override suspend fun fork(): BlockingDoubleChain = sample(generator.fork()) + } + + public companion object { + private val EXPONENTIAL_SA_QI by lazy { + val ln2 = ln(2.0) + var qi = 0.0 + + DoubleArray(16) { i -> + qi += ln2.pow(i + 1.0) / space.kscience.kmath.internal.InternalUtils.factorial(i + 1) + qi + } + } + } + +} + diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterMarsagliaTsangGammaSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterMarsagliaTsangGammaSampler.kt new file mode 100644 index 000000000..2f32eee85 --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterMarsagliaTsangGammaSampler.kt @@ -0,0 +1,125 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.samplers + +import space.kscience.kmath.chains.Chain +import space.kscience.kmath.stat.RandomGenerator +import space.kscience.kmath.stat.Sampler +import space.kscience.kmath.stat.chain +import space.kscience.kmath.stat.next +import kotlin.math.* + +/** + * Sampling from the [gamma distribution](http://mathworld.wolfram.com/GammaDistribution.html). + * - For 0 < alpha < 1: + * Ahrens, J. H. and Dieter, U., Computer methods for sampling from gamma, beta, Poisson and binomial distributions, Computing, 12, 223-246, 1974. + * - For alpha >= 1: + * Marsaglia and Tsang, A Simple Method for Generating Gamma Variables. ACM Transactions on Mathematical Software, Volume 26 Issue 3, September, 2000. + * + * Based on Commons RNG implementation. + * + * See [https://commons.apache.org/proper/commons-rng/commons-rng-sampling/apidocs/org/apache/commons/rng/sampling/distribution/AhrensDieterMarsagliaTsangGammaSampler.html]. + */ +public class AhrensDieterMarsagliaTsangGammaSampler private constructor( + alpha: Double, + theta: Double +) : Sampler { + private val delegate: BaseGammaSampler = + if (alpha < 1) AhrensDieterGammaSampler(alpha, theta) else MarsagliaTsangGammaSampler(alpha, theta) + + private abstract class BaseGammaSampler internal constructor( + protected val alpha: Double, + protected val theta: Double + ) : Sampler { + init { + require(alpha > 0) { "alpha is not strictly positive: $alpha" } + require(theta > 0) { "theta is not strictly positive: $theta" } + } + + override fun toString(): String = "Ahrens-Dieter-Marsaglia-Tsang Gamma deviate" + } + + private class AhrensDieterGammaSampler(alpha: Double, theta: Double) : + BaseGammaSampler(alpha, theta) { + private val oneOverAlpha: Double = 1.0 / alpha + private val bGSOptim: Double = 1.0 + alpha / E + + override fun sample(generator: RandomGenerator): Chain = generator.chain { + var x: Double + + // [1]: p. 228, Algorithm GS. + while (true) { + // Step 1: + val u = generator.nextDouble() + val p = bGSOptim * u + + if (p <= 1) { + // Step 2: + x = p.pow(oneOverAlpha) + val u2 = generator.nextDouble() + + if (u2 > exp(-x)) // Reject. + continue + + break + } + + // Step 3: + x = -ln((bGSOptim - p) * oneOverAlpha) + val u2: Double = generator.nextDouble() + if (u2 <= x.pow(alpha - 1.0)) break + // Reject and continue. + } + + x * theta + } + } + + private class MarsagliaTsangGammaSampler(alpha: Double, theta: Double) : + BaseGammaSampler(alpha, theta) { + private val dOptim: Double + private val cOptim: Double + private val gaussian: NormalizedGaussianSampler + + init { + gaussian = ZigguratNormalizedGaussianSampler + dOptim = alpha - ONE_THIRD + cOptim = ONE_THIRD / sqrt(dOptim) + } + + override fun sample(generator: RandomGenerator): Chain = generator.chain { + var v: Double + + while (true) { + val x = gaussian.next(generator) + val oPcTx = 1 + cOptim * x + v = oPcTx * oPcTx * oPcTx + if (v <= 0) continue + val x2 = x * x + val u = generator.nextDouble() + // Squeeze. + if (u < 1 - 0.0331 * x2 * x2) break + if (ln(u) < 0.5 * x2 + dOptim * (1 - v + ln(v))) break + } + + theta * dOptim * v + } + + companion object { + private const val ONE_THIRD = 1.0 / 3.0 + } + } + + public override fun sample(generator: RandomGenerator): Chain = delegate.sample(generator) + public override fun toString(): String = delegate.toString() + + public companion object { + public fun of( + alpha: Double, + theta: Double + ): Sampler = AhrensDieterMarsagliaTsangGammaSampler(alpha, theta) + } +} \ No newline at end of file diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AliasMethodDiscreteSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AliasMethodDiscreteSampler.kt new file mode 100644 index 000000000..db4f598b7 --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AliasMethodDiscreteSampler.kt @@ -0,0 +1,293 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.samplers + +import space.kscience.kmath.chains.Chain +import space.kscience.kmath.internal.InternalUtils +import space.kscience.kmath.stat.RandomGenerator +import space.kscience.kmath.stat.Sampler +import space.kscience.kmath.stat.chain +import kotlin.math.ceil +import kotlin.math.max +import kotlin.math.min + +/** + * Distribution sampler that uses the Alias method. It can be used to sample from n values each with an associated + * probability. This implementation is based on the detailed explanation of the alias method by Keith Schartz and + * implements Vose's algorithm. + * + * Vose, M.D., A linear algorithm for generating random numbers with a given distribution, IEEE Transactions on + * Software Engineering, 17, 972-975, 1991. he algorithm will sample values in O(1) time after a pre-processing step + * of O(n) time. + * + * The alias tables are constructed using fraction probabilities with an assumed denominator of 253. In the generic + * case sampling uses UniformRandomProvider.nextInt(int) and the upper 53-bits from UniformRandomProvider.nextLong(). + * + * Zero padding the input probabilities can be used to make more sampling more efficient. Any zero entry will always be + * aliased removing the requirement to compute a long. Increased sampling speed comes at the cost of increased storage + * space. The algorithm requires approximately 12 bytes of storage per input probability, that is n * 12 for size n. + * Zero-padding only requires 4 bytes of storage per padded value as the probability is known to be zero. + * + * An optimisation is performed for small table sizes that are a power of 2. In this case the sampling uses 1 or 2 + * calls from UniformRandomProvider.nextInt() to generate up to 64-bits for creation of an 11-bit index and 53-bits + * for the long. This optimisation requires a generator with a high cycle length for the lower order bits. + * + * Larger table sizes that are a power of 2 will benefit from fast algorithms for UniformRandomProvider.nextInt(int) + * that exploit the power of 2. + * + * Based on Commons RNG implementation. + * See [https://commons.apache.org/proper/commons-rng/commons-rng-sampling/apidocs/org/apache/commons/rng/sampling/distribution/AliasMethodDiscreteSampler.html]. + */ +public open class AliasMethodDiscreteSampler private constructor( + // Deliberate direct storage of input arrays + protected val probability: LongArray, + protected val alias: IntArray, +) : Sampler { + + private class SmallTableAliasMethodDiscreteSampler( + probability: LongArray, + alias: IntArray, + ) : AliasMethodDiscreteSampler(probability, alias) { + // Assume the table size is a power of 2 and create the mask + private val mask: Int = alias.size - 1 + + override fun sample(generator: RandomGenerator): Chain = generator.chain { + val bits = generator.nextInt() + // Isolate lower bits + val j = bits and mask + + // Optimisation for zero-padded input tables + if (j >= probability.size) + // No probability must use the alias + return@chain alias[j] + + // Create a uniform random deviate as a long. + // This replicates functionality from the o.a.c.rng.core.utils.NumberFactory.makeLong + val longBits = generator.nextInt().toLong() shl 32 or (bits.toLong() and hex_ffffffff) + // Choose between the two. Use a 53-bit long for the probability. + if (longBits ushr 11 < probability[j]) j else alias[j] + } + + private companion object { + private const val hex_ffffffff = 4294967295L + } + } + + public override fun sample(generator: RandomGenerator): Chain = generator.chain { + // This implements the algorithm as per Vose (1991): + // v = uniform() in [0, 1) + // j = uniform(n) in [0, n) + // if v < prob[j] then + // return j + // else + // return alias[j] + val j = generator.nextInt(alias.size) + + // Optimisation for zero-padded input tables + // No probability must use the alias + if (j >= probability.size) return@chain alias[j] + + // Note: We could check the probability before computing a deviate. + // p(j) == 0 => alias[j] + // p(j) == 1 => j + // However it is assumed these edge cases are rare: + // + // The probability table will be 1 for approximately 1/n samples, i.e. only the + // last unpaired probability. This is only worth checking for when the table size (n) + // is small. But in that case the user should zero-pad the table for performance. + // + // The probability table will be 0 when an input probability was zero. We + // will assume this is also rare if modelling a discrete distribution where + // all samples are possible. The edge case for zero-padded tables is handled above. + + // Choose between the two. Use a 53-bit long for the probability. + if (generator.nextLong() ushr 11 < probability[j]) j else alias[j] + } + + public override fun toString(): String = "Alias method" + + public companion object { + private const val DEFAULT_ALPHA = 0 + private const val ZERO = 0.0 + private const val ONE_AS_NUMERATOR = 1L shl 53 + private const val CONVERT_TO_NUMERATOR: Double = ONE_AS_NUMERATOR.toDouble() + private const val MAX_SMALL_POWER_2_SIZE = 1 shl 11 + + private fun fillRemainingIndices(length: Int, indices: IntArray, small: Int): Int { + var updatedSmall = small + (length until indices.size).forEach { i -> indices[updatedSmall++] = i } + return updatedSmall + } + + private fun findLastNonZeroIndex(probabilities: DoubleArray): Int { + // No bounds check is performed when decrementing as the array contains at least one + // value above zero. + var nonZeroIndex = probabilities.size - 1 + while (probabilities[nonZeroIndex] == ZERO) nonZeroIndex-- + return nonZeroIndex + } + + private fun computeSize(length: Int, alpha: Int): Int { + // If No padding + if (alpha < 0) return length + // Use the number of leading zeros function to find the next power of 2, + // i.e. ceil(log2(x)) + var pow2 = 32 - numberOfLeadingZeros(length - 1) + // Increase by the alpha. Clip this to limit to a positive integer (2^30) + pow2 = min(30, pow2 + alpha) + // Use max to handle a length above the highest possible power of 2 + return max(length, 1 shl pow2) + } + + private fun fillTable( + probability: LongArray, + alias: IntArray, + indices: IntArray, + start: Int, + end: Int, + ) = (start until end).forEach { i -> + val index = indices[i] + probability[index] = ONE_AS_NUMERATOR + alias[index] = index + } + + private fun isSmallPowerOf2(n: Int): Boolean = n <= MAX_SMALL_POWER_2_SIZE && n and n - 1 == 0 + + private fun numberOfLeadingZeros(i: Int): Int { + var mutI = i + if (mutI <= 0) return if (mutI == 0) 32 else 0 + var n = 31 + + if (mutI >= 1 shl 16) { + n -= 16 + mutI = mutI ushr 16 + } + + if (mutI >= 1 shl 8) { + n -= 8 + mutI = mutI ushr 8 + } + + if (mutI >= 1 shl 4) { + n -= 4 + mutI = mutI ushr 4 + } + + if (mutI >= 1 shl 2) { + n -= 2 + mutI = mutI ushr 2 + } + + return n - (mutI ushr 1) + } + } + + @Suppress("FunctionName") + public fun AliasMethodDiscreteSampler( + probabilities: DoubleArray, + alpha: Int = DEFAULT_ALPHA, + ): Sampler { + // The Alias method balances N categories with counts around the mean into N sections, + // each allocated 'mean' observations. + // + // Consider 4 categories with counts 6,3,2,1. The histogram can be balanced into a + // 2D array as 4 sections with a height of the mean: + // + // 6 + // 6 + // 6 + // 63 => 6366 -- + // 632 6326 |-- mean + // 6321 6321 -- + // + // section abcd + // + // Each section is divided as: + // a: 6=1/1 + // b: 3=1/1 + // c: 2=2/3; 6=1/3 (6 is the alias) + // d: 1=1/3; 6=2/3 (6 is the alias) + // + // The sample is obtained by randomly selecting a section, then choosing which category + // from the pair based on a uniform random deviate. + val sumProb = InternalUtils.validateProbabilities(probabilities) + // Allow zero-padding + val n = computeSize(probabilities.size, alpha) + // Partition into small and large by splitting on the average. + val mean = sumProb / n + // The cardinality of smallSize + largeSize = n. + // So fill the same array from either end. + val indices = IntArray(n) + var large = n + var small = 0 + + probabilities.indices.forEach { i -> + if (probabilities[i] >= mean) indices[--large] = i else indices[small++] = i + } + + small = fillRemainingIndices(probabilities.size, indices, small) + // This may be smaller than the input length if the probabilities were already padded. + val nonZeroIndex = findLastNonZeroIndex(probabilities) + // The probabilities are modified so use a copy. + // Note: probabilities are required only up to last nonZeroIndex + val remainingProbabilities = probabilities.copyOf(nonZeroIndex + 1) + // Allocate the final tables. + // Probability table may be truncated (when zero padded). + // The alias table is full length. + val probability = LongArray(remainingProbabilities.size) + val alias = IntArray(n) + + // This loop uses each large in turn to fill the alias table for small probabilities that + // do not reach the requirement to fill an entire section alone (i.e. p < mean). + // Since the sum of the small should be less than the sum of the large it should use up + // all the small first. However floating point round-off can result in + // misclassification of items as small or large. The Vose algorithm handles this using + // a while loop conditioned on the size of both sets and a subsequent loop to use + // unpaired items. + while (large != n && small != 0) { + // Index of the small and the large probabilities. + val j = indices[--small] + val k = indices[large++] + + // Optimisation for zero-padded input: + // p(j) = 0 above the last nonZeroIndex + if (j > nonZeroIndex) + // The entire amount for the section is taken from the alias. + remainingProbabilities[k] -= mean + else { + val pj = remainingProbabilities[j] + // Item j is a small probability that is below the mean. + // Compute the weight of the section for item j: pj / mean. + // This is scaled by 2^53 and the ceiling function used to round-up + // the probability to a numerator of a fraction in the range [1,2^53]. + // Ceiling ensures non-zero values. + probability[j] = ceil(CONVERT_TO_NUMERATOR * (pj / mean)).toLong() + // The remaining amount for the section is taken from the alias. + // Effectively: probabilities[k] -= (mean - pj) + remainingProbabilities[k] += pj - mean + } + + // If not j then the alias is k + alias[j] = k + + // Add the remaining probability from large to the appropriate list. + if (remainingProbabilities[k] >= mean) indices[--large] = k else indices[small++] = k + } + + // Final loop conditions to consume unpaired items. + // Note: The large set should never be non-empty but this can occur due to round-off + // error so consume from both. + fillTable(probability, alias, indices, 0, small) + fillTable(probability, alias, indices, large, n) + + // Change the algorithm for small power of 2 sized tables + return if (isSmallPowerOf2(n)) { + SmallTableAliasMethodDiscreteSampler(probability, alias) + } else { + AliasMethodDiscreteSampler(probability, alias) + } + } +} diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/BoxMullerSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/BoxMullerSampler.kt new file mode 100644 index 000000000..b3c014553 --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/BoxMullerSampler.kt @@ -0,0 +1,57 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.samplers + +import space.kscience.kmath.chains.BlockingDoubleChain +import space.kscience.kmath.stat.RandomGenerator +import space.kscience.kmath.structures.DoubleBuffer +import kotlin.math.* + +/** + * [Box-Muller algorithm](https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform) for sampling from a Gaussian + * distribution. + * + * Based on Commons RNG implementation. + * See [https://commons.apache.org/proper/commons-rng/commons-rng-sampling/apidocs/org/apache/commons/rng/sampling/distribution/BoxMullerNormalizedGaussianSampler.html]. + */ + +public object BoxMullerSampler : NormalizedGaussianSampler { + override fun sample(generator: RandomGenerator): BlockingDoubleChain = object : BlockingDoubleChain { + var state = Double.NaN + + override fun nextBufferBlocking(size: Int): DoubleBuffer { + val xs = generator.nextDoubleBuffer(size) + val ys = generator.nextDoubleBuffer(size) + + return DoubleBuffer(size) { index -> + if (state.isNaN()) { + // Generate a pair of Gaussian numbers. + val x = xs[index] + val y = ys[index] + val alpha = 2 * PI * x + val r = sqrt(-2 * ln(y)) + + // Keep second element of the pair for next invocation. + state = r * sin(alpha) + + // Return the first element of the generated pair. + r * cos(alpha) + } else { + // Use the second element of the pair (generated at the + // previous invocation). + state.also { + // Both elements of the pair have been used. + state = Double.NaN + } + } + } + } + + + override suspend fun fork(): BlockingDoubleChain = sample(generator.fork()) + } + +} diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/ConstantSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/ConstantSampler.kt new file mode 100644 index 000000000..0d38fe19b --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/ConstantSampler.kt @@ -0,0 +1,18 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.samplers + +import space.kscience.kmath.chains.BlockingBufferChain +import space.kscience.kmath.stat.RandomGenerator +import space.kscience.kmath.stat.Sampler +import space.kscience.kmath.structures.Buffer + +public class ConstantSampler(public val const: T) : Sampler { + override fun sample(generator: RandomGenerator): BlockingBufferChain = object : BlockingBufferChain { + override fun nextBufferBlocking(size: Int): Buffer = Buffer.boxing(size) { const } + override suspend fun fork(): BlockingBufferChain = this + } +} \ No newline at end of file diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/GaussianSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/GaussianSampler.kt new file mode 100644 index 000000000..d7d8e87b7 --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/GaussianSampler.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.samplers + +import space.kscience.kmath.chains.BlockingDoubleChain +import space.kscience.kmath.chains.map +import space.kscience.kmath.stat.RandomGenerator + +/** + * Sampling from a Gaussian distribution with given mean and standard deviation. + * + * Based on Commons RNG implementation. + * See [https://commons.apache.org/proper/commons-rng/commons-rng-sampling/apidocs/org/apache/commons/rng/sampling/distribution/GaussianSampler.html]. + * + * @property mean the mean of the distribution. + * @property standardDeviation the variance of the distribution. + */ +public class GaussianSampler( + public val mean: Double, + public val standardDeviation: Double, + private val normalized: NormalizedGaussianSampler = BoxMullerSampler +) : BlockingDoubleSampler { + + init { + require(standardDeviation > 0.0) { "standard deviation is not strictly positive: $standardDeviation" } + } + + public override fun sample(generator: RandomGenerator): BlockingDoubleChain = normalized + .sample(generator) + .map { standardDeviation * it + mean } + + override fun toString(): String = "N($mean, $standardDeviation)" + + public companion object +} diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/KempSmallMeanPoissonSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/KempSmallMeanPoissonSampler.kt new file mode 100644 index 000000000..9bb48fe4e --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/KempSmallMeanPoissonSampler.kt @@ -0,0 +1,73 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.samplers + +import space.kscience.kmath.chains.BlockingIntChain +import space.kscience.kmath.stat.RandomGenerator +import space.kscience.kmath.stat.Sampler +import space.kscience.kmath.structures.IntBuffer +import kotlin.math.exp + +/** + * Sampler for the Poisson distribution. + * - Kemp, A, W, (1981) Efficient Generation of Logarithmically Distributed Pseudo-Random Variables. Journal of the Royal Statistical Society. Vol. 30, No. 3, pp. 249-253. + * This sampler is suitable for mean < 40. For large means, LargeMeanPoissonSampler should be used instead. + * + * Note: The algorithm uses a recurrence relation to compute the Poisson probability and a rolling summation for the cumulative probability. When the mean is large the initial probability (Math.exp(-mean)) is zero and an exception is raised by the constructor. + * + * Sampling uses 1 call to UniformRandomProvider.nextDouble(). This method provides an alternative to the SmallMeanPoissonSampler for slow generators of double. + * + * Based on Commons RNG implementation. + * See [https://commons.apache.org/proper/commons-rng/commons-rng-sampling/apidocs/org/apache/commons/rng/sampling/distribution/KempSmallMeanPoissonSampler.html]. + */ +public class KempSmallMeanPoissonSampler internal constructor( + private val p0: Double, + private val mean: Double, +) : Sampler { + public override fun sample(generator: RandomGenerator): BlockingIntChain = object : BlockingIntChain { + override fun nextBlocking(): Int { + //TODO move to nextBufferBlocking + // Note on the algorithm: + // - X is the unknown sample deviate (the output of the algorithm) + // - x is the current value from the distribution + // - p is the probability of the current value x, p(X=x) + // - u is effectively the cumulative probability that the sample X + // is equal or above the current value x, p(X>=x) + // So if p(X>=x) > p(X=x) the sample must be above x, otherwise it is x + var u = generator.nextDouble() + var x = 0 + var p = p0 + + while (u > p) { + u -= p + // Compute the next probability using a recurrence relation. + // p(x+1) = p(x) * mean / (x+1) + p *= mean / ++x + // The algorithm listed in Kemp (1981) does not check that the rolling probability + // is positive. This check is added to ensure no errors when the limit of the summation + // 1 - sum(p(x)) is above 0 due to cumulative error in floating point arithmetic. + if (p == 0.0) return x + } + + return x + } + + override fun nextBufferBlocking(size: Int): IntBuffer = IntBuffer(size) { nextBlocking() } + + override suspend fun fork(): BlockingIntChain = sample(generator.fork()) + } + + public override fun toString(): String = "Kemp Small Mean Poisson deviate" +} + +public fun KempSmallMeanPoissonSampler(mean: Double): KempSmallMeanPoissonSampler { + require(mean > 0) { "Mean is not strictly positive: $mean" } + val p0 = exp(-mean) + // Probability must be positive. As mean increases then p(0) decreases. + require(p0 > 0) { "No probability for mean: $mean" } + return KempSmallMeanPoissonSampler(p0, mean) +} + diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/MarsagliaNormalizedGaussianSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/MarsagliaNormalizedGaussianSampler.kt new file mode 100644 index 000000000..0a68e5c88 --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/MarsagliaNormalizedGaussianSampler.kt @@ -0,0 +1,66 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.samplers + +import space.kscience.kmath.chains.BlockingDoubleChain +import space.kscience.kmath.stat.RandomGenerator +import space.kscience.kmath.structures.DoubleBuffer +import kotlin.math.ln +import kotlin.math.sqrt + +/** + * [Marsaglia polar method](https://en.wikipedia.org/wiki/Marsaglia_polar_method) for sampling from a Gaussian + * distribution with mean 0 and standard deviation 1. This is a variation of the algorithm implemented in + * [BoxMullerNormalizedGaussianSampler]. + * + * Based on Commons RNG implementation. + * See [https://commons.apache.org/proper/commons-rng/commons-rng-sampling/apidocs/org/apache/commons/rng/sampling/distribution/MarsagliaNormalizedGaussianSampler.html] + */ +public object MarsagliaNormalizedGaussianSampler : NormalizedGaussianSampler { + + override fun sample(generator: RandomGenerator): BlockingDoubleChain = object : BlockingDoubleChain { + var nextGaussian = Double.NaN + + override fun nextBlocking(): Double { + return if (nextGaussian.isNaN()) { + val alpha: Double + var x: Double + + // Rejection scheme for selecting a pair that lies within the unit circle. + while (true) { + // Generate a pair of numbers within [-1 , 1). + x = 2.0 * generator.nextDouble() - 1.0 + val y = 2.0 * generator.nextDouble() - 1.0 + val r2 = x * x + y * y + + if (r2 < 1 && r2 > 0) { + // Pair (x, y) is within unit circle. + alpha = sqrt(-2 * ln(r2) / r2) + // Keep second element of the pair for next invocation. + nextGaussian = alpha * y + // Return the first element of the generated pair. + break + } + // Pair is not within the unit circle: Generate another one. + } + + // Return the first element of the generated pair. + alpha * x + } else { + // Use the second element of the pair (generated at the + // previous invocation). + val r = nextGaussian + // Both elements of the pair have been used. + nextGaussian = Double.NaN + r + } + } + + override fun nextBufferBlocking(size: Int): DoubleBuffer = DoubleBuffer(size) { nextBlocking() } + + override suspend fun fork(): BlockingDoubleChain = sample(generator.fork()) + } +} diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/NormalizedGaussianSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/NormalizedGaussianSampler.kt new file mode 100644 index 000000000..83f87e832 --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/NormalizedGaussianSampler.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.samplers + +import space.kscience.kmath.chains.BlockingDoubleChain +import space.kscience.kmath.stat.RandomGenerator +import space.kscience.kmath.stat.Sampler + +public interface BlockingDoubleSampler: Sampler{ + override fun sample(generator: RandomGenerator): BlockingDoubleChain +} + + +/** + * Marker interface for a sampler that generates values from an N(0,1) + * [Gaussian distribution](https://en.wikipedia.org/wiki/Normal_distribution). + */ +public fun interface NormalizedGaussianSampler : BlockingDoubleSampler{ + public companion object +} diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/PoissonSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/PoissonSampler.kt new file mode 100644 index 000000000..e95778b9e --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/PoissonSampler.kt @@ -0,0 +1,208 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.samplers + +import space.kscience.kmath.chains.BlockingIntChain +import space.kscience.kmath.internal.InternalUtils +import space.kscience.kmath.stat.RandomGenerator +import space.kscience.kmath.stat.Sampler +import space.kscience.kmath.structures.IntBuffer +import kotlin.math.* + + +private const val PIVOT = 40.0 + +/** + * Sampler for the Poisson distribution. + * - For small means, a Poisson process is simulated using uniform deviates, as described in + * Knuth (1969). Seminumerical Algorithms. The Art of Computer Programming, Volume 2. Chapter 3.4.1.F.3 + * Important integer-valued distributions: The Poisson distribution. Addison Wesley. + * The Poisson process (and hence, the returned value) is bounded by 1000 * mean. + * - For large means, we use the rejection algorithm described in + * Devroye, Luc. (1981). The Computer Generation of Poisson Random Variables Computing vol. 26 pp. 197-207. + * + * Based on Commons RNG implementation. + * See [https://commons.apache.org/proper/commons-rng/commons-rng-sampling/apidocs/org/apache/commons/rng/sampling/distribution/PoissonSampler.html]. + */ +@Suppress("FunctionName") +public fun PoissonSampler(mean: Double): Sampler { + return if (mean < PIVOT) SmallMeanPoissonSampler(mean) else LargeMeanPoissonSampler(mean) +} + +/** + * Sampler for the Poisson distribution. + * - For small means, a Poisson process is simulated using uniform deviates, as described in + * Knuth (1969). Seminumerical Algorithms. The Art of Computer Programming, Volume 2. Chapter 3.4.1.F.3 Important + * integer-valued distributions: The Poisson distribution. Addison Wesley. + * - The Poisson process (and hence, the returned value) is bounded by 1000 * mean. + * This sampler is suitable for mean < 40. For large means, [LargeMeanPoissonSampler] should be used instead. + * + * Based on Commons RNG implementation. + * + * See [https://commons.apache.org/proper/commons-rng/commons-rng-sampling/apidocs/org/apache/commons/rng/sampling/distribution/SmallMeanPoissonSampler.html]. + */ +public class SmallMeanPoissonSampler(public val mean: Double) : Sampler { + + init { + require(mean > 0) { "mean is not strictly positive: $mean" } + } + + private val p0: Double = exp(-mean) + + private val limit: Int = if (p0 > 0) { + ceil(1000 * mean) + } else { + throw IllegalArgumentException("No p(x=0) probability for mean: $mean") + }.toInt() + + public override fun sample(generator: RandomGenerator): BlockingIntChain = object : BlockingIntChain { + override fun nextBlocking(): Int { + var n = 0 + var r = 1.0 + + while (n < limit) { + r *= generator.nextDouble() + if (r >= p0) n++ else break + } + + return n + } + + override fun nextBufferBlocking(size: Int): IntBuffer = IntBuffer(size) { nextBlocking() } + + override suspend fun fork(): BlockingIntChain = sample(generator.fork()) + } + + public override fun toString(): String = "Small Mean Poisson deviate" +} + + +/** + * Sampler for the Poisson distribution. + * - For large means, we use the rejection algorithm described in + * Devroye, Luc. (1981).The Computer Generation of Poisson Random Variables + * Computing vol. 26 pp. 197-207. + * + * This sampler is suitable for mean >= 40. + * + * Based on Commons RNG implementation. + * See [https://commons.apache.org/proper/commons-rng/commons-rng-sampling/apidocs/org/apache/commons/rng/sampling/distribution/LargeMeanPoissonSampler.html]. + */ +public class LargeMeanPoissonSampler(public val mean: Double) : Sampler { + + init { + require(mean >= 1) { "mean is not >= 1: $mean" } + // The algorithm is not valid if Math.floor(mean) is not an integer. + require(mean <= MAX_MEAN) { "mean $mean > $MAX_MEAN" } + } + + private val factorialLog: InternalUtils.FactorialLog = NO_CACHE_FACTORIAL_LOG + private val lambda: Double = floor(mean) + private val logLambda: Double = ln(lambda) + private val logLambdaFactorial: Double = getFactorialLog(lambda.toInt()) + private val delta: Double = sqrt(lambda * ln(32 * lambda / PI + 1)) + private val halfDelta: Double = delta / 2 + private val twolpd: Double = 2 * lambda + delta + private val c1: Double = 1 / (8 * lambda) + private val a1: Double = sqrt(PI * twolpd) * exp(c1) + private val a2: Double = twolpd / delta * exp(-delta * (1 + delta) / twolpd) + private val aSum: Double = a1 + a2 + 1 + private val p1: Double = a1 / aSum + private val p2: Double = a2 / aSum + + public override fun sample(generator: RandomGenerator): BlockingIntChain = object : BlockingIntChain { + override fun nextBlocking(): Int { + val exponential = AhrensDieterExponentialSampler(1.0).sample(generator) + val gaussian = ZigguratNormalizedGaussianSampler.sample(generator) + + val smallMeanPoissonSampler = if (mean - lambda < Double.MIN_VALUE) { + null + } else { + KempSmallMeanPoissonSampler(mean - lambda).sample(generator) + } + + val y2 = smallMeanPoissonSampler?.nextBlocking() ?: 0 + var x: Double + var y: Double + var v: Double + var a: Int + var t: Double + var qr: Double + var qa: Double + + while (true) { + // Step 1: + val u = generator.nextDouble() + + if (u <= p1) { + // Step 2: + val n = gaussian.nextBlocking() + x = n * sqrt(lambda + halfDelta) - 0.5 + if (x > delta || x < -lambda) continue + y = if (x < 0) floor(x) else ceil(x) + val e = exponential.nextBlocking() + v = -e - 0.5 * n * n + c1 + } else { + // Step 3: + if (u > p1 + p2) { + y = lambda + break + } + + x = delta + twolpd / delta * exponential.nextBlocking() + y = ceil(x) + v = -exponential.nextBlocking() - delta * (x + 1) / twolpd + } + + // The Squeeze Principle + // Step 4.1: + a = if (x < 0) 1 else 0 + t = y * (y + 1) / (2 * lambda) + + // Step 4.2 + if (v < -t && a == 0) { + y += lambda + break + } + + // Step 4.3: + qr = t * ((2 * y + 1) / (6 * lambda) - 1) + qa = qr - t * t / (3 * (lambda + a * (y + 1))) + + // Step 4.4: + if (v < qa) { + y += lambda + break + } + + // Step 4.5: + if (v > qr) continue + + // Step 4.6: + if (v < y * logLambda - getFactorialLog((y + lambda).toInt()) + logLambdaFactorial) { + y += lambda + break + } + } + + return min(y2 + y.toLong(), Int.MAX_VALUE.toLong()).toInt() + } + + override fun nextBufferBlocking(size: Int): IntBuffer = IntBuffer(size) { nextBlocking() } + + override suspend fun fork(): BlockingIntChain = sample(generator.fork()) + } + + private fun getFactorialLog(n: Int): Double = factorialLog.value(n) + public override fun toString(): String = "Large Mean Poisson deviate" + + public companion object { + private const val MAX_MEAN: Double = 0.5 * Int.MAX_VALUE + private val NO_CACHE_FACTORIAL_LOG: InternalUtils.FactorialLog = InternalUtils.FactorialLog.create() + } +} + + diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/ZigguratNormalizedGaussianSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/ZigguratNormalizedGaussianSampler.kt new file mode 100644 index 000000000..24148271d --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/ZigguratNormalizedGaussianSampler.kt @@ -0,0 +1,93 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.samplers + +import space.kscience.kmath.chains.BlockingDoubleChain +import space.kscience.kmath.stat.RandomGenerator +import space.kscience.kmath.structures.DoubleBuffer +import kotlin.math.* + +/** + * [Marsaglia and Tsang "Ziggurat"](https://en.wikipedia.org/wiki/Ziggurat_algorithm) method for sampling from a + * Gaussian distribution with mean 0 and standard deviation 1. The algorithm is explained in this paper and this + * implementation has been adapted from the C code provided therein. + * + * Based on Commons RNG implementation. + * See [https://commons.apache.org/proper/commons-rng/commons-rng-sampling/apidocs/org/apache/commons/rng/sampling/distribution/ZigguratNormalizedGaussianSampler.html]. + */ +public object ZigguratNormalizedGaussianSampler : NormalizedGaussianSampler { + + private const val R: Double = 3.442619855899 + private const val ONE_OVER_R: Double = 1 / R + private const val V: Double = 9.91256303526217e-3 + private val MAX: Double = 2.0.pow(63.0) + private val ONE_OVER_MAX: Double = 1.0 / MAX + private const val LEN: Int = 128 + private const val LAST: Int = LEN - 1 + private val K: LongArray = LongArray(LEN) + private val W: DoubleArray = DoubleArray(LEN) + private val F: DoubleArray = DoubleArray(LEN) + + init { + // Filling the tables. + var d = R + var t = d + var fd = gauss(d) + val q = V / fd + K[0] = (d / q * MAX).toLong() + K[1] = 0 + W[0] = q * ONE_OVER_MAX + W[LAST] = d * ONE_OVER_MAX + F[0] = 1.0 + F[LAST] = fd + + (LAST - 1 downTo 1).forEach { i -> + d = sqrt(-2 * ln(V / d + fd)) + fd = gauss(d) + K[i + 1] = (d / t * MAX).toLong() + t = d + F[i] = fd + W[i] = d * ONE_OVER_MAX + } + } + + private fun gauss(x: Double): Double = exp(-0.5 * x * x) + + private fun sampleOne(generator: RandomGenerator): Double { + val j = generator.nextLong() + val i = (j and LAST.toLong()).toInt() + return if (abs(j) < K[i]) j * W[i] else fix(generator, j, i) + } + + override fun sample(generator: RandomGenerator): BlockingDoubleChain = object : BlockingDoubleChain { + override fun nextBufferBlocking(size: Int): DoubleBuffer = DoubleBuffer(size) { sampleOne(generator) } + + override suspend fun fork(): BlockingDoubleChain = sample(generator.fork()) + } + + + private fun fix(generator: RandomGenerator, hz: Long, iz: Int): Double { + var x = hz * W[iz] + + return when { + iz == 0 -> { + var y: Double + + do { + y = -ln(generator.nextDouble()) + x = -ln(generator.nextDouble()) * ONE_OVER_R + } while (y + y < x * x) + + val out = R + x + if (hz > 0) out else -out + } + + F[iz] + generator.nextDouble() * (F[iz - 1] - F[iz]) < gauss(x) -> x + else -> sampleOne(generator) + } + } + +} diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Distribution.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Distribution.kt deleted file mode 100644 index 8b89f5ea1..000000000 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Distribution.kt +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2018-2021 KMath contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package space.kscience.kmath.stat - -import space.kscience.kmath.chains.Chain -import space.kscience.kmath.chains.collect -import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.BufferFactory -import space.kscience.kmath.structures.RealBuffer - -public interface Sampler { - public fun sample(generator: RandomGenerator): Chain -} - -/** - * A distribution of typed objects - */ -public interface Distribution : Sampler { - /** - * A probability value for given argument [arg]. - * For continuous distributions returns PDF - */ - public fun probability(arg: T): Double - - /** - * Create a chain of samples from this distribution. - * The chain is not guaranteed to be stateless, but different sample chains should be independent. - */ - override fun sample(generator: RandomGenerator): Chain - - /** - * An empty companion. Distribution factories should be written as its extensions - */ - public companion object -} - -public interface UnivariateDistribution> : Distribution { - /** - * Cumulative distribution for ordered parameter (CDF) - */ - public fun cumulative(arg: T): Double -} - -/** - * Compute probability integral in an interval - */ -public fun > UnivariateDistribution.integral(from: T, to: T): Double { - require(to > from) - return cumulative(to) - cumulative(from) -} - -/** - * Sample a bunch of values - */ -public fun Sampler.sampleBuffer( - generator: RandomGenerator, - size: Int, - bufferFactory: BufferFactory = Buffer.Companion::boxing -): Chain> { - require(size > 1) - //creating temporary storage once - val tmp = ArrayList(size) - - return sample(generator).collect { chain -> - //clear list from previous run - tmp.clear() - //Fill list - repeat(size) { - tmp.add(chain.next()) - } - //return new buffer with elements from tmp - bufferFactory(size) { tmp[it] } - } -} - -/** - * Generate a bunch of samples from real distributions - */ -public fun Sampler.sampleBuffer(generator: RandomGenerator, size: Int): Chain> = - sampleBuffer(generator, size, ::RealBuffer) diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Fitting.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Fitting.kt deleted file mode 100644 index 56ab8e06a..000000000 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Fitting.kt +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2018-2021 KMath contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package space.kscience.kmath.stat - -import space.kscience.kmath.expressions.* -import space.kscience.kmath.operations.ExtendedField -import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.indices -import kotlin.math.pow - -public object Fitting { - - /** - * Generate a chi squared expression from given x-y-sigma data and inline model. Provides automatic differentiation - */ - public fun chiSquared( - autoDiff: AutoDiffProcessor>, - x: Buffer, - y: Buffer, - yErr: Buffer, - model: A.(I) -> I, - ): DifferentiableExpression> where A : ExtendedField, A : ExpressionAlgebra { - require(x.size == y.size) { "X and y buffers should be of the same size" } - require(y.size == yErr.size) { "Y and yErr buffer should of the same size" } - - return autoDiff.process { - var sum = zero - - x.indices.forEach { - val xValue = const(x[it]) - val yValue = const(y[it]) - val yErrValue = const(yErr[it]) - val modelValue = model(xValue) - sum += ((yValue - modelValue) / yErrValue).pow(2) - } - - sum - } - } - - /** - * Generate a chi squared expression from given x-y-sigma model represented by an expression. Does not provide derivatives - */ - public fun chiSquared( - x: Buffer, - y: Buffer, - yErr: Buffer, - model: Expression, - xSymbol: Symbol = StringSymbol("x"), - ): Expression { - require(x.size == y.size) { "X and y buffers should be of the same size" } - require(y.size == yErr.size) { "Y and yErr buffer should of the same size" } - - return Expression { arguments -> - x.indices.sumByDouble { - val xValue = x[it] - val yValue = y[it] - val yErrValue = yErr[it] - val modifiedArgs = arguments + (xSymbol to xValue) - val modelValue = model(modifiedArgs) - ((yValue - modelValue) / yErrValue).pow(2) - } - } - } -} diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Mean.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Mean.kt new file mode 100644 index 000000000..9769146fb --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Mean.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.stat + +import space.kscience.kmath.operations.* +import space.kscience.kmath.structures.Buffer +import space.kscience.kmath.structures.indices + +/** + * Arithmetic mean + */ +public class Mean( + private val group: Ring, + private val division: (sum: T, count: Int) -> T, +) : ComposableStatistic, T>, BlockingStatistic { + + override fun evaluateBlocking(data: Buffer): T = group { + var res = zero + for (i in data.indices) { + res += data[i] + } + division(res, data.size) + } + + override suspend fun evaluate(data: Buffer): T = super.evaluate(data) + + public override suspend fun computeIntermediate(data: Buffer): Pair = + evaluateBlocking(data) to data.size + + public override suspend fun composeIntermediate(first: Pair, second: Pair): Pair = + group { first.first + second.first } to (first.second + second.second) + + public override suspend fun toResult(intermediate: Pair): T = group { + division(intermediate.first, intermediate.second) + } + + public companion object { + //TODO replace with optimized version which respects overflow + public val double: Mean = Mean(DoubleField) { sum, count -> sum / count } + public val int: Mean = Mean(IntRing) { sum, count -> sum / count } + public val long: Mean = Mean(LongRing) { sum, count -> sum / count } + + public fun evaluate(buffer: Buffer): Double = double.evaluateBlocking(buffer) + public fun evaluate(buffer: Buffer): Int = int.evaluateBlocking(buffer) + public fun evaluate(buffer: Buffer): Long = long.evaluateBlocking(buffer) + } +} \ No newline at end of file diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Median.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Median.kt new file mode 100644 index 000000000..70754eab7 --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Median.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.stat + +import space.kscience.kmath.structures.Buffer +import space.kscience.kmath.structures.asSequence + +/** + * Non-composable median + */ +public class Median(private val comparator: Comparator) : BlockingStatistic { + public override fun evaluateBlocking(data: Buffer): T = + data.asSequence().sortedWith(comparator).toList()[data.size / 2] //TODO check if this is correct + + public companion object { + public val real: Median = Median { a: Double, b: Double -> a.compareTo(b) } + } +} \ No newline at end of file diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/OptimizationProblem.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/OptimizationProblem.kt deleted file mode 100644 index d881f881c..000000000 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/OptimizationProblem.kt +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2018-2021 KMath contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package space.kscience.kmath.stat - -import space.kscience.kmath.expressions.DifferentiableExpression -import space.kscience.kmath.expressions.Expression -import space.kscience.kmath.expressions.Symbol - -public interface OptimizationFeature - -public class OptimizationResult( - public val point: Map, - public val value: T, - public val features: Set = emptySet(), -) { - override fun toString(): String { - return "OptimizationResult(point=$point, value=$value)" - } -} - -public operator fun OptimizationResult.plus( - feature: OptimizationFeature, -): OptimizationResult = OptimizationResult(point, value, features + feature) - -/** - * A configuration builder for optimization problem - */ -public interface OptimizationProblem { - /** - * Define the initial guess for the optimization problem - */ - public fun initialGuess(map: Map) - - /** - * Set an objective function expression - */ - public fun expression(expression: Expression) - - /** - * Set a differentiable expression as objective function as function and gradient provider - */ - public fun diffExpression(expression: DifferentiableExpression>) - - /** - * Update the problem from previous optimization run - */ - public fun update(result: OptimizationResult) - - /** - * Make an optimization run - */ - public fun optimize(): OptimizationResult -} - -public fun interface OptimizationProblemFactory> { - public fun build(symbols: List): P -} - -public operator fun > OptimizationProblemFactory.invoke( - symbols: List, - block: P.() -> Unit, -): P = build(symbols).apply(block) - -/** - * Optimize expression without derivatives using specific [OptimizationProblemFactory] - */ -public fun > Expression.optimizeWith( - factory: OptimizationProblemFactory, - vararg symbols: Symbol, - configuration: F.() -> Unit, -): OptimizationResult { - require(symbols.isNotEmpty()) { "Must provide a list of symbols for optimization" } - val problem = factory(symbols.toList(),configuration) - problem.expression(this) - return problem.optimize() -} - -/** - * Optimize differentiable expression using specific [OptimizationProblemFactory] - */ -public fun > DifferentiableExpression>.optimizeWith( - factory: OptimizationProblemFactory, - vararg symbols: Symbol, - configuration: F.() -> Unit, -): OptimizationResult { - require(symbols.isNotEmpty()) { "Must provide a list of symbols for optimization" } - val problem = factory(symbols.toList(), configuration) - problem.diffExpression(this) - return problem.optimize() -} diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/RandomChain.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/RandomChain.kt index 20dd8cf20..5041e7359 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/RandomChain.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/RandomChain.kt @@ -5,18 +5,35 @@ package space.kscience.kmath.stat +import space.kscience.kmath.chains.BlockingDoubleChain import space.kscience.kmath.chains.Chain +import space.kscience.kmath.structures.DoubleBuffer /** * A possibly stateful chain producing random values. + * + * @property generator the underlying [RandomGenerator] instance. */ public class RandomChain( public val generator: RandomGenerator, - private val gen: suspend RandomGenerator.() -> R + private val gen: suspend RandomGenerator.() -> R, ) : Chain { override suspend fun next(): R = generator.gen() - - override fun fork(): Chain = RandomChain(generator.fork(), gen) + override suspend fun fork(): Chain = RandomChain(generator.fork(), gen) +} + +/** + * Create a generic random chain with provided [generator] + */ +public fun RandomGenerator.chain(generator: suspend RandomGenerator.() -> R): RandomChain = RandomChain(this, generator) + +/** + * A type-specific double chunk random chain + */ +public class UniformDoubleChain(public val generator: RandomGenerator) : BlockingDoubleChain { + public override fun nextBufferBlocking(size: Int): DoubleBuffer = generator.nextDoubleBuffer(size) + override suspend fun nextBuffer(size: Int): DoubleBuffer = nextBufferBlocking(size) + + override suspend fun fork(): UniformDoubleChain = UniformDoubleChain(generator.fork()) } -public fun RandomGenerator.chain(gen: suspend RandomGenerator.() -> R): RandomChain = RandomChain(this, gen) diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/RandomGenerator.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/RandomGenerator.kt index 02f2ff33c..3ff12f383 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/RandomGenerator.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/RandomGenerator.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.stat +import space.kscience.kmath.structures.DoubleBuffer import kotlin.random.Random /** @@ -21,6 +22,11 @@ public interface RandomGenerator { */ public fun nextDouble(): Double + /** + * A chunk of doubles of given [size] + */ + public fun nextDoubleBuffer(size: Int): DoubleBuffer = DoubleBuffer(size) { nextDouble() } + /** * Gets the next random `Int` from the random number generator. * @@ -87,6 +93,8 @@ public interface RandomGenerator { /** * Implements [RandomGenerator] by delegating all operations to [Random]. + * + * @property random the underlying [Random] object. */ public class DefaultGenerator(public val random: Random = Random) : RandomGenerator { public override fun nextBoolean(): Boolean = random.nextBoolean() diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Sampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Sampler.kt new file mode 100644 index 000000000..51ae78d3d --- /dev/null +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Sampler.kt @@ -0,0 +1,66 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.stat + +import kotlinx.coroutines.flow.first +import space.kscience.kmath.chains.Chain +import space.kscience.kmath.chains.collect +import space.kscience.kmath.structures.* +import kotlin.jvm.JvmName + +/** + * Sampler that generates chains of values of type [T] in a chain of type [C]. + */ +public fun interface Sampler { + /** + * Generates a chain of samples. + * + * @param generator the randomness provider. + * @return the new chain. + */ + public fun sample(generator: RandomGenerator): Chain +} + +/** + * Sample a bunch of values + */ +public fun Sampler.sampleBuffer( + generator: RandomGenerator, + size: Int, + bufferFactory: BufferFactory = Buffer.Companion::boxing, +): Chain> { + require(size > 1) + //creating temporary storage once + val tmp = ArrayList(size) + + return sample(generator).collect { chain -> + //clear list from previous run + tmp.clear() + //Fill list + repeat(size) { tmp.add(chain.next()) } + //return new buffer with elements from tmp + bufferFactory(size) { tmp[it] } + } +} + +/** + * Samples one value from this [Sampler]. + */ +public suspend fun Sampler.next(generator: RandomGenerator): T = sample(generator).first() + +/** + * Generates [size] real samples and chunks them into some buffers. + */ +@JvmName("sampleRealBuffer") +public fun Sampler.sampleBuffer(generator: RandomGenerator, size: Int): Chain> = + sampleBuffer(generator, size, ::DoubleBuffer) + +/** + * Generates [size] integer samples and chunks them into some buffers. + */ +@JvmName("sampleIntBuffer") +public fun Sampler.sampleBuffer(generator: RandomGenerator, size: Int): Chain> = + sampleBuffer(generator, size, ::IntBuffer) diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/SamplerAlgebra.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/SamplerAlgebra.kt index 763f01018..b3d607ab0 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/SamplerAlgebra.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/SamplerAlgebra.kt @@ -13,16 +13,28 @@ import space.kscience.kmath.operations.Group import space.kscience.kmath.operations.ScaleOperations import space.kscience.kmath.operations.invoke -public class BasicSampler(public val chainBuilder: (RandomGenerator) -> Chain) : Sampler { - public override fun sample(generator: RandomGenerator): Chain = chainBuilder(generator) -} - +/** + * Implements [Sampler] by sampling only certain [value]. + * + * @property value the value to sample. + */ public class ConstantSampler(public val value: T) : Sampler { public override fun sample(generator: RandomGenerator): Chain = ConstantChain(value) } /** - * A space for samplers. Allows to perform simple operations on distributions + * Implements [Sampler] by delegating sampling to value of [chainBuilder]. + * + * @property chainBuilder the provider of [Chain]. + */ +public class BasicSampler(public val chainBuilder: (RandomGenerator) -> Chain) : Sampler { + public override fun sample(generator: RandomGenerator): Chain = chainBuilder(generator) +} + +/** + * A space of samplers. Allows to perform simple operations on distributions. + * + * @property algebra the space to provide addition and scalar multiplication for [T]. */ public class SamplerSpace(public val algebra: S) : Group>, ScaleOperations> where S : Group, S : ScaleOperations { @@ -34,8 +46,10 @@ public class SamplerSpace(public val algebra: S) : Group> } public override fun scale(a: Sampler, value: Double): Sampler = BasicSampler { generator -> - a.sample(generator).map { algebra { it * value } } + a.sample(generator).map { a -> + algebra { a * value } + } } - override fun Sampler.unaryMinus(): Sampler = scale(this, -1.0) + public override fun Sampler.unaryMinus(): Sampler = scale(this, -1.0) } diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Statistic.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Statistic.kt index b55555563..1b05aa9cd 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Statistic.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Statistic.kt @@ -13,16 +13,19 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.runningReduce import space.kscience.kmath.coroutines.mapParallel -import space.kscience.kmath.operations.* import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.asIterable -import space.kscience.kmath.structures.asSequence /** * A function, that transforms a buffer of random quantities to some resulting value */ public interface Statistic { - public suspend operator fun invoke(data: Buffer): R + public suspend fun evaluate(data: Buffer): R +} + +public interface BlockingStatistic: Statistic{ + public fun evaluateBlocking(data: Buffer): R + + override suspend fun evaluate(data: Buffer): R = evaluateBlocking(data) } /** @@ -41,7 +44,7 @@ public interface ComposableStatistic : Statistic { //Transform block to result public suspend fun toResult(intermediate: I): R - public override suspend fun invoke(data: Buffer): R = toResult(computeIntermediate(data)) + public override suspend fun evaluate(data: Buffer): R = toResult(computeIntermediate(data)) } @FlowPreview @@ -60,46 +63,9 @@ private fun ComposableStatistic.flowIntermediate( * * The resulting flow contains values that include the whole previous statistics, not only the last chunk. */ -@FlowPreview -@ExperimentalCoroutinesApi +@OptIn(FlowPreview::class, ExperimentalCoroutinesApi::class) public fun ComposableStatistic.flow( flow: Flow>, dispatcher: CoroutineDispatcher = Dispatchers.Default, ): Flow = flowIntermediate(flow, dispatcher).map(::toResult) -/** - * Arithmetic mean - */ -public class Mean( - private val space: Group, - private val division: (sum: T, count: Int) -> T, -) : ComposableStatistic, T> { - public override suspend fun computeIntermediate(data: Buffer): Pair = - space { sum(data.asIterable()) } to data.size - - public override suspend fun composeIntermediate(first: Pair, second: Pair): Pair = - space { first.first + second.first } to (first.second + second.second) - - public override suspend fun toResult(intermediate: Pair): T = space { - division(intermediate.first, intermediate.second) - } - - public companion object { - //TODO replace with optimized version which respects overflow - public val real: Mean = Mean(RealField) { sum, count -> sum / count } - public val int: Mean = Mean(IntRing) { sum, count -> sum / count } - public val long: Mean = Mean(LongRing) { sum, count -> sum / count } - } -} - -/** - * Non-composable median - */ -public class Median(private val comparator: Comparator) : Statistic { - public override suspend fun invoke(data: Buffer): T = - data.asSequence().sortedWith(comparator).toList()[data.size / 2] //TODO check if this is correct - - public companion object { - public val real: Median = Median { a: Double, b: Double -> a.compareTo(b) } - } -} diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/UniformDistribution.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/UniformDistribution.kt index 8204e8593..970a3aab5 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/UniformDistribution.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/UniformDistribution.kt @@ -7,6 +7,8 @@ package space.kscience.kmath.stat import space.kscience.kmath.chains.Chain import space.kscience.kmath.chains.SimpleChain +import space.kscience.kmath.distributions.Distribution +import space.kscience.kmath.distributions.UnivariateDistribution public class UniformDistribution(public val range: ClosedFloatingPointRange) : UnivariateDistribution { private val length: Double = range.endInclusive - range.start diff --git a/kmath-stat/src/jvmMain/kotlin/space/kscience/kmath/stat/RandomSourceGenerator.kt b/kmath-stat/src/jvmMain/kotlin/space/kscience/kmath/stat/RandomSourceGenerator.kt index 309d26b4d..1ff6481ac 100644 --- a/kmath-stat/src/jvmMain/kotlin/space/kscience/kmath/stat/RandomSourceGenerator.kt +++ b/kmath-stat/src/jvmMain/kotlin/space/kscience/kmath/stat/RandomSourceGenerator.kt @@ -8,10 +8,14 @@ package space.kscience.kmath.stat import org.apache.commons.rng.UniformRandomProvider import org.apache.commons.rng.simple.RandomSource -public class RandomSourceGenerator(public val source: RandomSource, seed: Long?) : RandomGenerator { - internal val random: UniformRandomProvider = seed?.let { - RandomSource.create(source, seed) - } ?: RandomSource.create(source) +/** + * Implements [RandomGenerator] by delegating all operations to [RandomSource]. + * + * @property source the underlying [RandomSource] object. + */ +public class RandomSourceGenerator internal constructor(public val source: RandomSource, seed: Long?) : RandomGenerator { + internal val random: UniformRandomProvider = seed?.let { RandomSource.create(source, seed) } + ?: RandomSource.create(source) public override fun nextBoolean(): Boolean = random.nextBoolean() public override fun nextDouble(): Double = random.nextDouble() @@ -28,22 +32,84 @@ public class RandomSourceGenerator(public val source: RandomSource, seed: Long?) public override fun fork(): RandomGenerator = RandomSourceGenerator(source, nextLong()) } -public inline class RandomGeneratorProvider(public val generator: RandomGenerator) : UniformRandomProvider { +/** + * Implements [UniformRandomProvider] by delegating all operations to [RandomGenerator]. + * + * @property generator the underlying [RandomGenerator] object. + */ +public class RandomGeneratorProvider(public val generator: RandomGenerator) : UniformRandomProvider { + /** + * Generates a [Boolean] value. + * + * @return the next random value. + */ public override fun nextBoolean(): Boolean = generator.nextBoolean() + + /** + * Generates a [Float] value between 0 and 1. + * + * @return the next random value between 0 and 1. + */ public override fun nextFloat(): Float = generator.nextDouble().toFloat() - public override fun nextBytes(bytes: ByteArray) { - generator.fillBytes(bytes) - } + /** + * Generates [Byte] values and places them into a user-supplied array. + * + * The number of random bytes produced is equal to the length of the the byte array. + * + * @param bytes byte array in which to put the random bytes. + */ + public override fun nextBytes(bytes: ByteArray): Unit = generator.fillBytes(bytes) + /** + * Generates [Byte] values and places them into a user-supplied array. + * + * The array is filled with bytes extracted from random integers. This implies that the number of random bytes + * generated may be larger than the length of the byte array. + * + * @param bytes the array in which to put the generated bytes. + * @param start the index at which to start inserting the generated bytes. + * @param len the number of bytes to insert. + */ public override fun nextBytes(bytes: ByteArray, start: Int, len: Int) { generator.fillBytes(bytes, start, start + len) } + /** + * Generates an [Int] value. + * + * @return the next random value. + */ public override fun nextInt(): Int = generator.nextInt() + + /** + * Generates an [Int] value between 0 (inclusive) and the specified value (exclusive). + * + * @param n the bound on the random number to be returned. Must be positive. + * @return a random integer between 0 (inclusive) and [n] (exclusive). + */ public override fun nextInt(n: Int): Int = generator.nextInt(n) + + /** + * Generates a [Double] value between 0 and 1. + * + * @return the next random value between 0 and 1. + */ public override fun nextDouble(): Double = generator.nextDouble() + + /** + * Generates a [Long] value. + * + * @return the next random value. + */ public override fun nextLong(): Long = generator.nextLong() + + /** + * Generates a [Long] value between 0 (inclusive) and the specified value (exclusive). + * + * @param n Bound on the random number to be returned. Must be positive. + * @return a random long value between 0 (inclusive) and [n] (exclusive). + */ public override fun nextLong(n: Long): Long = generator.nextLong(n) } @@ -56,8 +122,14 @@ public fun RandomGenerator.asUniformRandomProvider(): UniformRandomProvider = if else RandomGeneratorProvider(this) +/** + * Returns [RandomSourceGenerator] with given [RandomSource] and [seed]. + */ public fun RandomGenerator.Companion.fromSource(source: RandomSource, seed: Long? = null): RandomSourceGenerator = RandomSourceGenerator(source, seed) +/** + * Returns [RandomSourceGenerator] with [RandomSource.MT] algorithm and given [seed]. + */ public fun RandomGenerator.Companion.mersenneTwister(seed: Long? = null): RandomSourceGenerator = fromSource(RandomSource.MT, seed) diff --git a/kmath-stat/src/jvmMain/kotlin/space/kscience/kmath/stat/distributions.kt b/kmath-stat/src/jvmMain/kotlin/space/kscience/kmath/stat/distributions.kt deleted file mode 100644 index cfd0538df..000000000 --- a/kmath-stat/src/jvmMain/kotlin/space/kscience/kmath/stat/distributions.kt +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2018-2021 KMath contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package space.kscience.kmath.stat - -import org.apache.commons.rng.UniformRandomProvider -import org.apache.commons.rng.sampling.distribution.* -import space.kscience.kmath.chains.BlockingIntChain -import space.kscience.kmath.chains.BlockingRealChain -import space.kscience.kmath.chains.Chain -import kotlin.math.PI -import kotlin.math.exp -import kotlin.math.pow -import kotlin.math.sqrt - -public abstract class ContinuousSamplerDistribution : Distribution { - private inner class ContinuousSamplerChain(val generator: RandomGenerator) : BlockingRealChain() { - private val sampler = buildCMSampler(generator) - - override fun nextDouble(): Double = sampler.sample() - override fun fork(): Chain = ContinuousSamplerChain(generator.fork()) - } - - protected abstract fun buildCMSampler(generator: RandomGenerator): ContinuousSampler - - public override fun sample(generator: RandomGenerator): BlockingRealChain = ContinuousSamplerChain(generator) -} - -public abstract class DiscreteSamplerDistribution : Distribution { - private inner class ContinuousSamplerChain(val generator: RandomGenerator) : BlockingIntChain() { - private val sampler = buildSampler(generator) - - override fun nextInt(): Int = sampler.sample() - override fun fork(): Chain = ContinuousSamplerChain(generator.fork()) - } - - protected abstract fun buildSampler(generator: RandomGenerator): DiscreteSampler - - public override fun sample(generator: RandomGenerator): BlockingIntChain = ContinuousSamplerChain(generator) -} - -public enum class NormalSamplerMethod { - BoxMuller, - Marsaglia, - Ziggurat -} - -private fun normalSampler(method: NormalSamplerMethod, provider: UniformRandomProvider): NormalizedGaussianSampler = - when (method) { - NormalSamplerMethod.BoxMuller -> BoxMullerNormalizedGaussianSampler(provider) - NormalSamplerMethod.Marsaglia -> MarsagliaNormalizedGaussianSampler(provider) - NormalSamplerMethod.Ziggurat -> ZigguratNormalizedGaussianSampler(provider) - } - -public fun Distribution.Companion.normal( - method: NormalSamplerMethod = NormalSamplerMethod.Ziggurat -): ContinuousSamplerDistribution = object : ContinuousSamplerDistribution() { - override fun buildCMSampler(generator: RandomGenerator): ContinuousSampler { - val provider = generator.asUniformRandomProvider() - return normalSampler(method, provider) - } - - override fun probability(arg: Double): Double = exp(-arg.pow(2) / 2) / sqrt(PI * 2) -} - -/** - * A univariate normal distribution with given [mean] and [sigma]. [method] defines commons-rng generation method - */ -public fun Distribution.Companion.normal( - mean: Double, - sigma: Double, - method: NormalSamplerMethod = NormalSamplerMethod.Ziggurat -): ContinuousSamplerDistribution = object : ContinuousSamplerDistribution() { - private val sigma2 = sigma.pow(2) - private val norm = sigma * sqrt(PI * 2) - - override fun buildCMSampler(generator: RandomGenerator): ContinuousSampler { - val provider = generator.asUniformRandomProvider() - val normalizedSampler = normalSampler(method, provider) - return GaussianSampler(normalizedSampler, mean, sigma) - } - - override fun probability(arg: Double): Double = exp(-(arg - mean).pow(2) / 2 / sigma2) / norm -} - -public fun Distribution.Companion.poisson(lambda: Double): DiscreteSamplerDistribution = - object : DiscreteSamplerDistribution() { - private val computedProb: MutableMap = hashMapOf(0 to exp(-lambda)) - - override fun buildSampler(generator: RandomGenerator): DiscreteSampler = - PoissonSampler.of(generator.asUniformRandomProvider(), lambda) - - override fun probability(arg: Int): Double { - require(arg >= 0) { "The argument must be >= 0" } - - return if (arg > 40) - exp(-(arg - lambda).pow(2) / 2 / lambda) / sqrt(2 * PI * lambda) - else - computedProb.getOrPut(arg) { probability(arg - 1) * lambda / arg } - } - } diff --git a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/CommonsDistributionsTest.kt b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/CommonsDistributionsTest.kt index 39f593dbe..066fd69e6 100644 --- a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/CommonsDistributionsTest.kt +++ b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/CommonsDistributionsTest.kt @@ -5,28 +5,26 @@ package space.kscience.kmath.stat -import kotlinx.coroutines.flow.take -import kotlinx.coroutines.flow.toList -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test +import space.kscience.kmath.samplers.GaussianSampler internal class CommonsDistributionsTest { @Test - fun testNormalDistributionSuspend() { - val distribution = Distribution.normal(7.0, 2.0) + fun testNormalDistributionSuspend() = GlobalScope.launch { + val distribution = GaussianSampler(7.0, 2.0) val generator = RandomGenerator.default(1) - val sample = runBlocking { - distribution.sample(generator).take(1000).toList() - } - Assertions.assertEquals(7.0, sample.average(), 0.1) + val sample = distribution.sample(generator).nextBuffer(1000) + Assertions.assertEquals(7.0, Mean.evaluate(sample), 0.2) } @Test fun testNormalDistributionBlocking() { - val distribution = Distribution.normal(7.0, 2.0) + val distribution = GaussianSampler(7.0, 2.0) val generator = RandomGenerator.default(1) - val sample = distribution.sample(generator).nextBlock(1000) - Assertions.assertEquals(7.0, sample.average(), 0.1) + val sample = distribution.sample(generator).nextBufferBlocking(1000) + Assertions.assertEquals(7.0, Mean.evaluate(sample), 0.2) } } diff --git a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/SamplerTest.kt b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/SamplerTest.kt index b55940815..1dbbf591b 100644 --- a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/SamplerTest.kt +++ b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/SamplerTest.kt @@ -12,11 +12,8 @@ class SamplerTest { @Test fun bufferSamplerTest() { - val sampler: Sampler = - BasicSampler { it.chain { nextDouble() } } + val sampler = Sampler { it.chain { nextDouble() } } val data = sampler.sampleBuffer(RandomGenerator.default, 100) - runBlocking { - println(data.next()) - } + runBlocking { println(data.next()) } } } \ No newline at end of file diff --git a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/StatisticTest.kt b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/StatisticTest.kt index c747749ce..1dd5c5161 100644 --- a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/StatisticTest.kt +++ b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/StatisticTest.kt @@ -8,7 +8,6 @@ package space.kscience.kmath.stat import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.first import kotlinx.coroutines.runBlocking - import space.kscience.kmath.streaming.chunked import kotlin.test.Test @@ -23,14 +22,12 @@ internal class StatisticTest { val chunked = data.chunked(1000) @Test - fun testParallelMean() { - runBlocking { - val average = Mean.real - .flow(chunked) //create a flow with results - .drop(99) // Skip first 99 values and use one with total data - .first() //get 1e5 data samples average + fun testParallelMean() = runBlocking { + val average = Mean.double + .flow(chunked) //create a flow with results + .drop(99) // Skip first 99 values and use one with total data + .first() //get 1e5 data samples average - println(average) - } + println(average) } } diff --git a/kmath-viktor/api/kmath-viktor.api b/kmath-viktor/api/kmath-viktor.api index ebb97b150..59882627b 100644 --- a/kmath-viktor/api/kmath-viktor.api +++ b/kmath-viktor/api/kmath-viktor.api @@ -1,181 +1,83 @@ public final class space/kscience/kmath/viktor/ViktorBuffer : space/kscience/kmath/structures/MutableBuffer { - public static final synthetic fun box-impl (Lorg/jetbrains/bio/viktor/F64FlatArray;)Lspace/kscience/kmath/viktor/ViktorBuffer; - public static fun constructor-impl (Lorg/jetbrains/bio/viktor/F64FlatArray;)Lorg/jetbrains/bio/viktor/F64FlatArray; - public fun contentEquals (Lspace/kscience/kmath/structures/Buffer;)Z - public static fun contentEquals-impl (Lorg/jetbrains/bio/viktor/F64FlatArray;Lspace/kscience/kmath/structures/Buffer;)Z + public fun (Lorg/jetbrains/bio/viktor/F64FlatArray;)V public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; - public static fun copy-impl (Lorg/jetbrains/bio/viktor/F64FlatArray;)Lspace/kscience/kmath/structures/MutableBuffer; - public fun equals (Ljava/lang/Object;)Z - public static fun equals-impl (Lorg/jetbrains/bio/viktor/F64FlatArray;Ljava/lang/Object;)Z - public static final fun equals-impl0 (Lorg/jetbrains/bio/viktor/F64FlatArray;Lorg/jetbrains/bio/viktor/F64FlatArray;)Z public fun get (I)Ljava/lang/Double; public synthetic fun get (I)Ljava/lang/Object; - public static fun get-impl (Lorg/jetbrains/bio/viktor/F64FlatArray;I)Ljava/lang/Double; public final fun getFlatArray ()Lorg/jetbrains/bio/viktor/F64FlatArray; public fun getSize ()I - public static fun getSize-impl (Lorg/jetbrains/bio/viktor/F64FlatArray;)I - public fun hashCode ()I - public static fun hashCode-impl (Lorg/jetbrains/bio/viktor/F64FlatArray;)I public fun iterator ()Ljava/util/Iterator; - public static fun iterator-impl (Lorg/jetbrains/bio/viktor/F64FlatArray;)Ljava/util/Iterator; public fun set (ID)V public synthetic fun set (ILjava/lang/Object;)V - public static fun set-impl (Lorg/jetbrains/bio/viktor/F64FlatArray;ID)V - public fun toString ()Ljava/lang/String; - public static fun toString-impl (Lorg/jetbrains/bio/viktor/F64FlatArray;)Ljava/lang/String; - public final synthetic fun unbox-impl ()Lorg/jetbrains/bio/viktor/F64FlatArray; } -public final class space/kscience/kmath/viktor/ViktorNDField : space/kscience/kmath/nd/NDField, space/kscience/kmath/operations/ExtendedField, space/kscience/kmath/operations/NumbersAddOperations, space/kscience/kmath/operations/ScaleOperations { +public final class space/kscience/kmath/viktor/ViktorFieldND : space/kscience/kmath/nd/FieldND, space/kscience/kmath/operations/ExtendedField, space/kscience/kmath/operations/NumbersAddOperations, space/kscience/kmath/operations/ScaleOperations { public fun ([I)V public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; - public fun acos-Q7Xurp0 (Lspace/kscience/kmath/nd/NDStructure;)Lorg/jetbrains/bio/viktor/F64Array; - public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun acosh (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; + public fun acos (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public synthetic fun add (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun add-s8yP2C4 (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lorg/jetbrains/bio/viktor/F64Array; + public synthetic fun add (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun add (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; - public fun asin-Q7Xurp0 (Lspace/kscience/kmath/nd/NDStructure;)Lorg/jetbrains/bio/viktor/F64Array; - public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun asinh (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; + public fun asin (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; - public fun atan-Q7Xurp0 (Lspace/kscience/kmath/nd/NDStructure;)Lorg/jetbrains/bio/viktor/F64Array; - public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun atanh (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperation (Ljava/lang/String;Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; - public fun bindSymbol (Ljava/lang/String;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun combine (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/NDStructure; - public fun combine-ZQYDhZg (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function3;)Lorg/jetbrains/bio/viktor/F64Array; + public fun atan (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/viktor/ViktorStructureND; + public synthetic fun combine (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/StructureND; + public fun combine (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; - public fun cos-Q7Xurp0 (Lspace/kscience/kmath/nd/NDStructure;)Lorg/jetbrains/bio/viktor/F64Array; - public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun cosh (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun div (DLspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public synthetic fun div (Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun div (Lspace/kscience/kmath/nd/NDStructure;D)Lspace/kscience/kmath/nd/NDStructure; - public fun div (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun div (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; - public fun div (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun divide (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; + public fun cos (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; - public fun exp-Q7Xurp0 (Lspace/kscience/kmath/nd/NDStructure;)Lorg/jetbrains/bio/viktor/F64Array; + public fun exp (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun getElementContext ()Lspace/kscience/kmath/operations/Algebra; - public fun getElementContext ()Lspace/kscience/kmath/operations/RealField; - public final fun getF64Buffer (Lspace/kscience/kmath/nd/NDStructure;)Lorg/jetbrains/bio/viktor/F64Array; + public fun getElementContext ()Lspace/kscience/kmath/operations/DoubleField; + public final fun getF64Buffer (Lspace/kscience/kmath/nd/StructureND;)Lorg/jetbrains/bio/viktor/F64Array; public synthetic fun getOne ()Ljava/lang/Object; - public fun getOne-MSOxzaI ()Lorg/jetbrains/bio/viktor/F64Array; + public fun getOne ()Lspace/kscience/kmath/viktor/ViktorStructureND; public fun getShape ()[I public synthetic fun getZero ()Ljava/lang/Object; - public fun getZero-MSOxzaI ()Lorg/jetbrains/bio/viktor/F64Array; - public fun invoke (Lkotlin/jvm/functions/Function1;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public fun getZero ()Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; - public fun ln-Q7Xurp0 (Lspace/kscience/kmath/nd/NDStructure;)Lorg/jetbrains/bio/viktor/F64Array; - public synthetic fun map (Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/NDStructure; - public fun map-s8yP2C4 (Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function2;)Lorg/jetbrains/bio/viktor/F64Array; - public synthetic fun mapIndexed (Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/NDStructure; - public fun mapIndexed-s8yP2C4 (Lspace/kscience/kmath/nd/NDStructure;Lkotlin/jvm/functions/Function3;)Lorg/jetbrains/bio/viktor/F64Array; - public fun minus (DLspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun minus (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun minus (Ljava/lang/Number;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public fun ln (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/viktor/ViktorStructureND; + public synthetic fun map (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; + public fun map (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/viktor/ViktorStructureND; + public synthetic fun mapIndexed (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/StructureND; + public fun mapIndexed (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public synthetic fun minus (Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun minus (Lspace/kscience/kmath/nd/NDStructure;D)Lspace/kscience/kmath/nd/NDStructure; - public fun minus (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun minus (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; - public fun minus-s8yP2C4 (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lorg/jetbrains/bio/viktor/F64Array; - public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun multiply (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; + public fun minus (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; - public fun number-Q7Xurp0 (Ljava/lang/Number;)Lorg/jetbrains/bio/viktor/F64Array; - public fun plus (DLspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun plus (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun plus (Ljava/lang/Number;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public synthetic fun plus (Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun plus (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun plus (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; - public fun plus-s8yP2C4 (Lspace/kscience/kmath/nd/NDStructure;D)Lorg/jetbrains/bio/viktor/F64Array; - public fun plus-s8yP2C4 (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lorg/jetbrains/bio/viktor/F64Array; - public synthetic fun pow (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun pow (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; + public fun plus (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/viktor/ViktorStructureND; + public synthetic fun plus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public fun plus (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun power-s8yP2C4 (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lorg/jetbrains/bio/viktor/F64Array; - public synthetic fun produce (Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/NDStructure; - public fun produce-Q7Xurp0 (Lkotlin/jvm/functions/Function2;)Lorg/jetbrains/bio/viktor/F64Array; - public synthetic fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun rightSideNumberOperation (Ljava/lang/String;Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure; - public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public fun power (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/viktor/ViktorStructureND; + public synthetic fun produce (Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; + public fun produce (Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; - public fun scale-s8yP2C4 (Lspace/kscience/kmath/nd/NDStructure;D)Lorg/jetbrains/bio/viktor/F64Array; + public fun scale (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; - public fun sin-Q7Xurp0 (Lspace/kscience/kmath/nd/NDStructure;)Lorg/jetbrains/bio/viktor/F64Array; - public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun sinh (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun sqrt (Ljava/lang/Object;)Ljava/lang/Object; - public fun sqrt (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; + public fun sin (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; - public fun tan (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun tanh (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun times (DLspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun times (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun times (Ljava/lang/Number;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; + public fun tan (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun times (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public synthetic fun times (Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun times (Lspace/kscience/kmath/nd/NDStructure;D)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun times (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Object;)Lspace/kscience/kmath/nd/NDStructure; - public fun times (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun times-s8yP2C4 (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lorg/jetbrains/bio/viktor/F64Array; + public fun times (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryMinus (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public synthetic fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryOperation (Ljava/lang/String;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; - public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryPlus (Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure; + public fun unaryMinus (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; } -public final class space/kscience/kmath/viktor/ViktorNDStructure : space/kscience/kmath/nd/MutableNDStructure { - public static final synthetic fun box-impl (Lorg/jetbrains/bio/viktor/F64Array;)Lspace/kscience/kmath/viktor/ViktorNDStructure; - public static fun constructor-impl (Lorg/jetbrains/bio/viktor/F64Array;)Lorg/jetbrains/bio/viktor/F64Array; +public final class space/kscience/kmath/viktor/ViktorStructureND : space/kscience/kmath/nd/MutableStructureND { + public fun (Lorg/jetbrains/bio/viktor/F64Array;)V public fun elements ()Lkotlin/sequences/Sequence; - public static fun elements-impl (Lorg/jetbrains/bio/viktor/F64Array;)Lkotlin/sequences/Sequence; - public fun equals (Ljava/lang/Object;)Z - public static fun equals-impl (Lorg/jetbrains/bio/viktor/F64Array;Ljava/lang/Object;)Z - public static final fun equals-impl0 (Lorg/jetbrains/bio/viktor/F64Array;Lorg/jetbrains/bio/viktor/F64Array;)Z public fun get ([I)Ljava/lang/Double; public synthetic fun get ([I)Ljava/lang/Object; - public static fun get-impl (Lorg/jetbrains/bio/viktor/F64Array;[I)Ljava/lang/Double; - public fun getDimension ()I - public static fun getDimension-impl (Lorg/jetbrains/bio/viktor/F64Array;)I public final fun getF64Buffer ()Lorg/jetbrains/bio/viktor/F64Array; public fun getShape ()[I - public static fun getShape-impl (Lorg/jetbrains/bio/viktor/F64Array;)[I - public fun hashCode ()I - public static fun hashCode-impl (Lorg/jetbrains/bio/viktor/F64Array;)I public fun set ([ID)V public synthetic fun set ([ILjava/lang/Object;)V - public static fun set-impl (Lorg/jetbrains/bio/viktor/F64Array;[ID)V - public fun toString ()Ljava/lang/String; - public static fun toString-impl (Lorg/jetbrains/bio/viktor/F64Array;)Ljava/lang/String; - public final synthetic fun unbox-impl ()Lorg/jetbrains/bio/viktor/F64Array; } -public final class space/kscience/kmath/viktor/ViktorNDStructureKt { - public static final fun ViktorNDField ([I)Lspace/kscience/kmath/viktor/ViktorNDField; - public static final fun asStructure (Lorg/jetbrains/bio/viktor/F64Array;)Lorg/jetbrains/bio/viktor/F64Array; +public final class space/kscience/kmath/viktor/ViktorStructureNDKt { + public static final fun ViktorNDField ([I)Lspace/kscience/kmath/viktor/ViktorFieldND; + public static final fun asStructure (Lorg/jetbrains/bio/viktor/F64Array;)Lspace/kscience/kmath/viktor/ViktorStructureND; } diff --git a/kmath-viktor/build.gradle.kts b/kmath-viktor/build.gradle.kts index d28862d01..0d853dea7 100644 --- a/kmath-viktor/build.gradle.kts +++ b/kmath-viktor/build.gradle.kts @@ -3,8 +3,11 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ +import ru.mipt.npm.gradle.Maturity + plugins { - id("ru.mipt.npm.gradle.jvm") + kotlin("jvm") + id("ru.mipt.npm.gradle.common") } description = "Binding for https://github.com/JetBrains-Research/viktor" @@ -14,6 +17,6 @@ dependencies { api("org.jetbrains.bio:viktor:1.0.1") } -readme{ - maturity = ru.mipt.npm.gradle.Maturity.DEVELOPMENT +readme { + maturity = Maturity.DEVELOPMENT } \ No newline at end of file diff --git a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt index 9e24bf43d..bbf502faf 100644 --- a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt +++ b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt @@ -9,7 +9,7 @@ import org.jetbrains.bio.viktor.F64FlatArray import space.kscience.kmath.structures.MutableBuffer @Suppress("NOTHING_TO_INLINE", "OVERRIDE_BY_INLINE") -public inline class ViktorBuffer(public val flatArray: F64FlatArray) : MutableBuffer { +public class ViktorBuffer(public val flatArray: F64FlatArray) : MutableBuffer { public override val size: Int get() = flatArray.size diff --git a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorNDStructure.kt b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorNDStructure.kt deleted file mode 100644 index 89c2e5967..000000000 --- a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorNDStructure.kt +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2018-2021 KMath contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package space.kscience.kmath.viktor - -import org.jetbrains.bio.viktor.F64Array -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 space.kscience.kmath.operations.ScaleOperations - -@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") -public inline class ViktorNDStructure(public val f64Buffer: F64Array) : MutableNDStructure { - public override val shape: IntArray get() = f64Buffer.shape - - public override inline fun get(index: IntArray): Double = f64Buffer.get(*index) - - public override inline fun set(index: IntArray, value: Double) { - f64Buffer.set(*index, value = value) - } - - public override fun elements(): Sequence> = - DefaultStrides(shape).indices().map { it to get(it) } -} - -public fun F64Array.asStructure(): ViktorNDStructure = ViktorNDStructure(this) - -@OptIn(UnstableKMathAPI::class) -@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") -public class ViktorNDField(public override val shape: IntArray) : NDField, - NumbersAddOperations>, ExtendedField>, - ScaleOperations> { - - public val NDStructure.f64Buffer: F64Array - get() = when { - !shape.contentEquals(this@ViktorNDField.shape) -> throw ShapeMismatchException( - this@ViktorNDField.shape, - shape - ) - this is ViktorNDStructure && this.f64Buffer.shape.contentEquals(this@ViktorNDField.shape) -> this.f64Buffer - else -> produce { this@f64Buffer[it] }.f64Buffer - } - - public override val zero: ViktorNDStructure by lazy { F64Array.full(init = 0.0, shape = shape).asStructure() } - - public override val one: ViktorNDStructure by lazy { F64Array.full(init = 1.0, shape = shape).asStructure() } - - private val strides: Strides = DefaultStrides(shape) - - public override val elementContext: RealField get() = RealField - - public override fun produce(initializer: RealField.(IntArray) -> Double): ViktorNDStructure = - F64Array(*shape).apply { - this@ViktorNDField.strides.indices().forEach { index -> - set(value = RealField.initializer(index), indices = index) - } - }.asStructure() - - override fun NDStructure.unaryMinus(): NDStructure = -1 * this - - public override fun NDStructure.map(transform: RealField.(Double) -> Double): ViktorNDStructure = - F64Array(*this@ViktorNDField.shape).apply { - this@ViktorNDField.strides.indices().forEach { index -> - set(value = RealField.transform(this@map[index]), indices = index) - } - }.asStructure() - - public override fun NDStructure.mapIndexed( - transform: RealField.(index: IntArray, Double) -> Double, - ): ViktorNDStructure = F64Array(*this@ViktorNDField.shape).apply { - this@ViktorNDField.strides.indices().forEach { index -> - set(value = RealField.transform(index, this@mapIndexed[index]), indices = index) - } - }.asStructure() - - public override fun combine( - a: NDStructure, - b: NDStructure, - transform: RealField.(Double, Double) -> Double, - ): ViktorNDStructure = F64Array(*shape).apply { - this@ViktorNDField.strides.indices().forEach { index -> - set(value = RealField.transform(a[index], b[index]), indices = index) - } - }.asStructure() - - public override fun add(a: NDStructure, b: NDStructure): ViktorNDStructure = - (a.f64Buffer + b.f64Buffer).asStructure() - - public override fun scale(a: NDStructure, value: Double): ViktorNDStructure = - (a.f64Buffer * value.toDouble()).asStructure() - - public override inline fun NDStructure.plus(b: NDStructure): ViktorNDStructure = - (f64Buffer + b.f64Buffer).asStructure() - - public override inline fun NDStructure.minus(b: NDStructure): ViktorNDStructure = - (f64Buffer - b.f64Buffer).asStructure() - - public override inline fun NDStructure.times(k: Number): ViktorNDStructure = - (f64Buffer * k.toDouble()).asStructure() - - public override inline fun NDStructure.plus(arg: Double): ViktorNDStructure = - (f64Buffer.plus(arg)).asStructure() - - override fun number(value: Number): ViktorNDStructure = - F64Array.full(init = value.toDouble(), shape = shape).asStructure() - - override fun sin(arg: NDStructure): ViktorNDStructure = arg.map { sin(it) } - - override fun cos(arg: NDStructure): ViktorNDStructure = arg.map { cos(it) } - - override fun asin(arg: NDStructure): ViktorNDStructure = arg.map { asin(it) } - - override fun acos(arg: NDStructure): ViktorNDStructure = arg.map { acos(it) } - - override fun atan(arg: NDStructure): ViktorNDStructure = arg.map { atan(it) } - - override fun power(arg: NDStructure, pow: Number): ViktorNDStructure = arg.map { it.pow(pow) } - - override fun exp(arg: NDStructure): ViktorNDStructure = arg.f64Buffer.exp().asStructure() - - override fun ln(arg: NDStructure): ViktorNDStructure = arg.f64Buffer.log().asStructure() -} - -public fun ViktorNDField(vararg shape: Int): ViktorNDField = ViktorNDField(shape) \ No newline at end of file diff --git a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt new file mode 100644 index 000000000..dc1b45f5d --- /dev/null +++ b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt @@ -0,0 +1,124 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.viktor + +import org.jetbrains.bio.viktor.F64Array +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 space.kscience.kmath.operations.ScaleOperations + +@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") +public class ViktorStructureND(public val f64Buffer: F64Array) : MutableStructureND { + public override val shape: IntArray get() = f64Buffer.shape + + public override inline fun get(index: IntArray): Double = f64Buffer.get(*index) + + public override inline fun set(index: IntArray, value: Double) { + f64Buffer.set(*index, value = value) + } + + public override fun elements(): Sequence> = + DefaultStrides(shape).indices().map { it to get(it) } +} + +public fun F64Array.asStructure(): ViktorStructureND = ViktorStructureND(this) + +@OptIn(UnstableKMathAPI::class) +@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") +public class ViktorFieldND(public override val shape: IntArray) : FieldND, + NumbersAddOperations>, ExtendedField>, + ScaleOperations> { + + public val StructureND.f64Buffer: F64Array + get() = when { + !shape.contentEquals(this@ViktorFieldND.shape) -> throw ShapeMismatchException( + this@ViktorFieldND.shape, + shape + ) + this is ViktorStructureND && this.f64Buffer.shape.contentEquals(this@ViktorFieldND.shape) -> this.f64Buffer + else -> produce { this@f64Buffer[it] }.f64Buffer + } + + public override val zero: ViktorStructureND by lazy { F64Array.full(init = 0.0, shape = shape).asStructure() } + public override val one: ViktorStructureND by lazy { F64Array.full(init = 1.0, shape = shape).asStructure() } + + private val strides: Strides = DefaultStrides(shape) + + public override val elementContext: DoubleField get() = DoubleField + + public override fun produce(initializer: DoubleField.(IntArray) -> Double): ViktorStructureND = + F64Array(*shape).apply { + this@ViktorFieldND.strides.indices().forEach { index -> + set(value = DoubleField.initializer(index), indices = index) + } + }.asStructure() + + public override fun StructureND.unaryMinus(): StructureND = -1 * this + + public override fun StructureND.map(transform: DoubleField.(Double) -> Double): ViktorStructureND = + F64Array(*this@ViktorFieldND.shape).apply { + this@ViktorFieldND.strides.indices().forEach { index -> + set(value = DoubleField.transform(this@map[index]), indices = index) + } + }.asStructure() + + public override fun StructureND.mapIndexed( + transform: DoubleField.(index: IntArray, Double) -> Double, + ): ViktorStructureND = F64Array(*this@ViktorFieldND.shape).apply { + this@ViktorFieldND.strides.indices().forEach { index -> + set(value = DoubleField.transform(index, this@mapIndexed[index]), indices = index) + } + }.asStructure() + + public override fun combine( + a: StructureND, + b: StructureND, + transform: DoubleField.(Double, Double) -> Double, + ): ViktorStructureND = F64Array(*shape).apply { + this@ViktorFieldND.strides.indices().forEach { index -> + set(value = DoubleField.transform(a[index], b[index]), indices = index) + } + }.asStructure() + + public override fun add(a: StructureND, b: StructureND): ViktorStructureND = + (a.f64Buffer + b.f64Buffer).asStructure() + + public override fun scale(a: StructureND, value: Double): ViktorStructureND = + (a.f64Buffer * value.toDouble()).asStructure() + + public override inline fun StructureND.plus(b: StructureND): ViktorStructureND = + (f64Buffer + b.f64Buffer).asStructure() + + public override inline fun StructureND.minus(b: StructureND): ViktorStructureND = + (f64Buffer - b.f64Buffer).asStructure() + + public override inline fun StructureND.times(k: Number): ViktorStructureND = + (f64Buffer * k.toDouble()).asStructure() + + public override inline fun StructureND.plus(arg: Double): ViktorStructureND = + (f64Buffer.plus(arg)).asStructure() + + public override fun number(value: Number): ViktorStructureND = + F64Array.full(init = value.toDouble(), shape = shape).asStructure() + + public override fun sin(arg: StructureND): ViktorStructureND = arg.map { sin(it) } + public override fun cos(arg: StructureND): ViktorStructureND = arg.map { cos(it) } + public override fun tan(arg: StructureND): ViktorStructureND = arg.map { tan(it) } + public override fun asin(arg: StructureND): ViktorStructureND = arg.map { asin(it) } + public override fun acos(arg: StructureND): ViktorStructureND = arg.map { acos(it) } + public override fun atan(arg: StructureND): ViktorStructureND = arg.map { atan(it) } + + public override fun power(arg: StructureND, pow: Number): ViktorStructureND = arg.map { it.pow(pow) } + + public override fun exp(arg: StructureND): ViktorStructureND = arg.f64Buffer.exp().asStructure() + + public override fun ln(arg: StructureND): ViktorStructureND = arg.f64Buffer.log().asStructure() +} + +public fun ViktorNDField(vararg shape: Int): ViktorFieldND = ViktorFieldND(shape) diff --git a/license/README.md b/license/README.md index 6d51e7a05..cfef3de79 100644 --- a/license/README.md +++ b/license/README.md @@ -1,17 +1,63 @@ -The Apache 2 license (given in full in LICENSE.txt) applies to all code in this repository, which is copyright by the -contributors of KMath. The following sections of the repository contain third-party code, to which different licenses +The Apache 2 license (given in full in LICENSE.txt) applies to all code in this repository, which is copyright by the +contributors of KMath. The following sections of the repository contain third-party code, to which different licenses may apply: ## KMath Libraries The following modules contain third-party code and are incorporated into the KMath Libraries: - - Path: kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt +- Path: kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt - License: Apache 2 ([cm](third_party/cm_license.txt)) - Origin: Derived from Apache Commons Math, (c) 2001-2020 The Apache Software Foundation - - Path: kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt +- Path: kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt - License: Apache 2 ([cm](third_party/cm_license.txt)) - - Origin: Derived from Apache Commons Math, (c) 2001-2020 The Apache Software Foundation + - Origin: Derived from Apache Commons Math, (c) 2001-2020 The Apache Software Foundation - Path: kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LoessInterpolator.kt - License: Apache 2 ([cm](third_party/cm_license.txt)) - Origin: Derived from Apache Commons Math, (c) 2001-2020 The Apache Software Foundation +- Path: kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt + - License: Apache 2 ([cm](third_party/cm_license.txt)) + - Origin: Derived from Apache Commons Math, (c) 2001-2020 The Apache Software Foundation +- Path: kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt + - License: Apache 2 ([numky](third_party/numky_license.txt)) + - Origin: Initial implementation was taken from Numky +- Path: kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterExponentialSampler.kt + - License: Apache 2 ([cm](third_party/crng_license.txt)) + - Origin: Derived from Apache Commons RNG, (c) 2001-2020 The Apache Software Foundation +- Path: kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterMarsagliaTsangGammaSampler.kt + - License: Apache 2 ([cm](third_party/crng_license.txt)) + - Origin: Derived from Apache Commons RNG, (c) 2001-2020 The Apache Software Foundation +- Path: kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AliasMethodDiscreteSampler.kt + - License: Apache 2 ([cm](third_party/crng_license.txt)) + - Origin: Derived from Apache Commons RNG, (c) 2001-2020 The Apache Software Foundation +- Path: kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/BoxMullerSampler.kt + - License: Apache 2 ([cm](third_party/crng_license.txt)) + - Origin: Derived from Apache Commons RNG, (c) 2001-2020 The Apache Software Foundation +- Path: kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/GaussianSampler.kt + - License: Apache 2 ([cm](third_party/crng_license.txt)) + - Origin: Derived from Apache Commons RNG, (c) 2001-2020 The Apache Software Foundation +- Path: kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/KempSmallMeanPoissonSampler.kt + - License: Apache 2 ([cm](third_party/crng_license.txt)) + - Origin: Derived from Apache Commons RNG, (c) 2001-2020 The Apache Software Foundation +- Path: kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/MarsagliaNormalizedGaussianSampler.kt + - License: Apache 2 ([cm](third_party/crng_license.txt)) + - Origin: Derived from Apache Commons RNG, (c) 2001-2020 The Apache Software Foundation +- Path: kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/NormalizedGaussianSampler.kt + - License: Apache 2 ([cm](third_party/crng_license.txt)) + - Origin: Derived from Apache Commons RNG, (c) 2001-2020 The Apache Software Foundation +- Path: kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/PoissonSampler.kt + - License: Apache 2 ([cm](third_party/crng_license.txt)) + - Origin: Derived from Apache Commons RNG, (c) 2001-2020 The Apache Software Foundation +- Path: kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/ZigguratNormalizedGaussianSampler.kt + - License: Apache 2 ([cm](third_party/crng_license.txt)) + - Origin: Derived from Apache Commons RNG, (c) 2001-2020 The Apache Software Foundation +- Path: + - License: Apache 2 ([cm](third_party/crng_license.txt)) + - Origin: Derived from Apache Commons RNG, (c) 2001-2020 The Apache Software Foundation +- Path: + - License: Apache 2 ([cm](third_party/crng_license.txt)) + - Origin: Derived from Apache Commons RNG, (c) 2001-2020 The Apache Software Foundation +- Path: + - License: Apache 2 ([cm](third_party/crng_license.txt)) + - Origin: Derived from Apache Commons RNG, (c) 2001-2020 The Apache Software Foundation + \ No newline at end of file diff --git a/license/third_party/crng_license.txt b/license/third_party/crng_license.txt new file mode 100644 index 000000000..dec0e2a5c --- /dev/null +++ b/license/third_party/crng_license.txt @@ -0,0 +1,275 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + +================================================================================ + +Class "org.apache.commons.rng.core.source64.MersenneTwister64" contains +Java code partly ported from the reference implementation in C. +That source file contained the following notice: + + Copyright (C) 2004, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +================================================================================ + +Class "org.apache.commons.rng.core.source32.MersenneTwister" contains +Java code partly ported from the reference implementation in C. +That source file contained the following notice: + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +================================================================================ \ No newline at end of file diff --git a/license/third_party/numky_license.txt b/license/third_party/numky_license.txt new file mode 100644 index 000000000..f49a4e16e --- /dev/null +++ b/license/third_party/numky_license.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index b2bcd9b1d..babad3672 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,25 +5,23 @@ pluginManagement { repositories { - maven("https://repo.kotlin.link") mavenLocal() + mavenCentral() gradlePluginPortal() - jcenter() - maven("https://dl.bintray.com/kotlin/kotlin-eap") - maven("https://dl.bintray.com/kotlin/kotlinx") + maven("https://repo.kotlin.link") } - val toolsVersion = "0.9.1" - val kotlinVersion = "1.4.31" + val toolsVersion = "0.9.5-dev-2" + val kotlinVersion = "1.5.0-RC" plugins { - id("kotlinx.benchmark") version "0.2.0-dev-20" + kotlin("multiplatform") version kotlinVersion + kotlin("jvm") version kotlinVersion + kotlin("plugin.allopen") version kotlinVersion + id("org.jetbrains.kotlinx.benchmark") version "0.3.0" id("ru.mipt.npm.gradle.project") version toolsVersion id("ru.mipt.npm.gradle.mpp") version toolsVersion id("ru.mipt.npm.gradle.jvm") version toolsVersion - id("ru.mipt.npm.gradle.publish") version toolsVersion - kotlin("jvm") version kotlinVersion - kotlin("plugin.allopen") version kotlinVersion } }