forked from kscience/kmath
Merge pull request #219 from mipt-npm/refactor/algebra-scale
Fully refactor algebra split ScaleOperations from Space.
This commit is contained in:
commit
f449bdd58f
3
.github/workflows/build.yml
vendored
3
.github/workflows/build.yml
vendored
@ -1,6 +1,5 @@
|
|||||||
# Based on https://github.com/touchlab/Stately/blob/main/.github/workflows/build.yml
|
name: Gradle build
|
||||||
|
|
||||||
name: build
|
|
||||||
on: [ push ]
|
on: [ push ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
# Based on https://github.com/touchlab/Stately/blob/main/.github/workflows/deploy.yml
|
name: Gradle publish
|
||||||
|
|
||||||
name: deploy
|
on:
|
||||||
on: workflow_dispatch
|
workflow_dispatch:
|
||||||
|
release:
|
||||||
|
types:
|
||||||
|
- created
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
publish:
|
||||||
|
environment:
|
||||||
|
name: publish
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [macOS-latest, windows-latest]
|
os: [macOS-latest, windows-latest]
|
||||||
@ -33,13 +38,22 @@ jobs:
|
|||||||
key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
|
key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-gradle-
|
${{ runner.os }}-gradle-
|
||||||
- name: Publish Mac Artifacts
|
|
||||||
if: matrix.os == 'macOS-latest'
|
|
||||||
run: ./gradlew publishAllPublicationsToSpaceRepository publishAllPublicationsToSonatypeRepository --no-daemon --stacktrace -PsonatypePublish=true -PsonatypeUser=${{ secrets.SONATYPE_USERNAME }} -PsonatypePassword=${{ secrets.SONATYPE_PASSWORD }} -PspaceUser=${{ secrets.SPACE_USERNAME }} -PspacePassword=${{ secrets.SPACE_PASSWORD }}
|
|
||||||
env:
|
|
||||||
signingKey: ${{ secrets.SIGNING_KEY }}
|
|
||||||
- name: Publish Windows Artifacts
|
- name: Publish Windows Artifacts
|
||||||
if: matrix.os == 'windows-latest'
|
if: matrix.os == 'windows-latest'
|
||||||
run: ./gradlew publishAllPublicationsToSpaceRepository publishAllPublicationsToSonatypeRepository --no-daemon --stacktrace -PsonatypePublish=true -PsonatypeUser=${{ secrets.SONATYPE_USERNAME }} -PsonatypePassword=${{ secrets.SONATYPE_PASSWORD }} -PspaceUser=${{ secrets.SPACE_USERNAME }} -PspacePassword=${{ secrets.SPACE_PASSWORD }}
|
run: >
|
||||||
env:
|
./gradlew release --no-daemon
|
||||||
signingKey: ${{ secrets.SIGNING_KEY }}
|
-Ppublishing.enabled=true
|
||||||
|
-Ppublishing.github.user=${{ secrets.PUBLISHING_GITHUB_USER }}
|
||||||
|
-Ppublishing.github.token=${{ secrets.PUBLISHING_GITHUB_TOKEN }}
|
||||||
|
-Ppublishing.space.user=${{ secrets.PUBLISHING_SPACE_USER }}
|
||||||
|
-Ppublishing.space.token=${{ secrets.PUBLISHING_SPACE_TOKEN }}
|
||||||
|
- name: Publish Mac Artifacts
|
||||||
|
if: matrix.os == 'macOS-latest'
|
||||||
|
run: >
|
||||||
|
./gradlew release --no-daemon
|
||||||
|
-Ppublishing.enabled=true
|
||||||
|
-Ppublishing.platform=macosX64
|
||||||
|
-Ppublishing.github.user=${{ secrets.PUBLISHING_GITHUB_USER }}
|
||||||
|
-Ppublishing.github.token=${{ secrets.PUBLISHING_GITHUB_TOKEN }}
|
||||||
|
-Ppublishing.space.user=${{ secrets.PUBLISHING_SPACE_USER }}
|
||||||
|
-Ppublishing.space.token=${{ secrets.PUBLISHING_SPACE_TOKEN }}
|
@ -2,12 +2,19 @@
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
### Added
|
### Added
|
||||||
|
- ScaleOperations interface
|
||||||
|
- Field extends ScaleOperations
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
- Exponential operations merged with hyperbolic functions
|
||||||
|
- Space is replaced by Group. Space is reserved for vector spaces.
|
||||||
|
- VectorSpace is now a vector space
|
||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
- Nearest in Domain. To be implemented in geometry package.
|
||||||
|
- Number multiplication and division in main Algebra chain
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ allprojects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "space.kscience"
|
group = "space.kscience"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
@ -32,9 +32,9 @@ readme {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ksciencePublish {
|
ksciencePublish {
|
||||||
spaceRepo = "https://maven.pkg.jetbrains.space/mipt-npm/p/sci/maven"
|
github("kmath")
|
||||||
bintrayRepo = "kscience"
|
space()
|
||||||
githubProject = "kmath"
|
sonatype()
|
||||||
}
|
}
|
||||||
|
|
||||||
apiValidation {
|
apiValidation {
|
||||||
|
@ -6,10 +6,10 @@ import space.kscience.kmath.operations.RealField
|
|||||||
fun main() {
|
fun main() {
|
||||||
val expr = RealField.mstInField {
|
val expr = RealField.mstInField {
|
||||||
val x = bindSymbol("x")
|
val x = bindSymbol("x")
|
||||||
x * 2.0 + 2.0 / x - 16.0
|
x * 2.0 + number(2.0) / x - 16.0
|
||||||
}
|
}
|
||||||
|
|
||||||
repeat(10000000){
|
repeat(10000000) {
|
||||||
expr.invoke("x" to 1.0)
|
expr.invoke("x" to 1.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,8 +3,8 @@ package space.kscience.kmath.structures
|
|||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.nd.*
|
import space.kscience.kmath.nd.*
|
||||||
import space.kscience.kmath.operations.ExtendedField
|
import space.kscience.kmath.operations.ExtendedField
|
||||||
|
import space.kscience.kmath.operations.NumbersAddOperations
|
||||||
import space.kscience.kmath.operations.RealField
|
import space.kscience.kmath.operations.RealField
|
||||||
import space.kscience.kmath.operations.RingWithNumbers
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.stream.IntStream
|
import java.util.stream.IntStream
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ import java.util.stream.IntStream
|
|||||||
class StreamRealNDField(
|
class StreamRealNDField(
|
||||||
override val shape: IntArray,
|
override val shape: IntArray,
|
||||||
) : NDField<Double, RealField>,
|
) : NDField<Double, RealField>,
|
||||||
RingWithNumbers<NDStructure<Double>>,
|
NumbersAddOperations<NDStructure<Double>>,
|
||||||
ExtendedField<NDStructure<Double>> {
|
ExtendedField<NDStructure<Double>> {
|
||||||
|
|
||||||
private val strides = DefaultStrides(shape)
|
private val strides = DefaultStrides(shape)
|
||||||
@ -79,25 +79,29 @@ class StreamRealNDField(
|
|||||||
return NDBuffer(strides, array.asBuffer())
|
return NDBuffer(strides, array.asBuffer())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun power(arg: NDStructure<Double>, pow: Number): NDBuffer<Double> = arg.map() { power(it, pow) }
|
override fun NDStructure<Double>.unaryMinus(): NDStructure<Double> = map { -it }
|
||||||
|
|
||||||
override fun exp(arg: NDStructure<Double>): NDBuffer<Double> = arg.map() { exp(it) }
|
override fun scale(a: NDStructure<Double>, value: Double): NDStructure<Double> = a.map { it * value }
|
||||||
|
|
||||||
override fun ln(arg: NDStructure<Double>): NDBuffer<Double> = arg.map() { ln(it) }
|
override fun power(arg: NDStructure<Double>, pow: Number): NDBuffer<Double> = arg.map { power(it, pow) }
|
||||||
|
|
||||||
override fun sin(arg: NDStructure<Double>): NDBuffer<Double> = arg.map() { sin(it) }
|
override fun exp(arg: NDStructure<Double>): NDBuffer<Double> = arg.map { exp(it) }
|
||||||
override fun cos(arg: NDStructure<Double>): NDBuffer<Double> = arg.map() { cos(it) }
|
|
||||||
override fun tan(arg: NDStructure<Double>): NDBuffer<Double> = arg.map() { tan(it) }
|
|
||||||
override fun asin(arg: NDStructure<Double>): NDBuffer<Double> = arg.map() { asin(it) }
|
|
||||||
override fun acos(arg: NDStructure<Double>): NDBuffer<Double> = arg.map() { acos(it) }
|
|
||||||
override fun atan(arg: NDStructure<Double>): NDBuffer<Double> = arg.map() { atan(it) }
|
|
||||||
|
|
||||||
override fun sinh(arg: NDStructure<Double>): NDBuffer<Double> = arg.map() { sinh(it) }
|
override fun ln(arg: NDStructure<Double>): NDBuffer<Double> = arg.map { ln(it) }
|
||||||
override fun cosh(arg: NDStructure<Double>): NDBuffer<Double> = arg.map() { cosh(it) }
|
|
||||||
override fun tanh(arg: NDStructure<Double>): NDBuffer<Double> = arg.map() { tanh(it) }
|
override fun sin(arg: NDStructure<Double>): NDBuffer<Double> = arg.map { sin(it) }
|
||||||
override fun asinh(arg: NDStructure<Double>): NDBuffer<Double> = arg.map() { asinh(it) }
|
override fun cos(arg: NDStructure<Double>): NDBuffer<Double> = arg.map { cos(it) }
|
||||||
override fun acosh(arg: NDStructure<Double>): NDBuffer<Double> = arg.map() { acosh(it) }
|
override fun tan(arg: NDStructure<Double>): NDBuffer<Double> = arg.map { tan(it) }
|
||||||
override fun atanh(arg: NDStructure<Double>): NDBuffer<Double> = arg.map() { atanh(it) }
|
override fun asin(arg: NDStructure<Double>): NDBuffer<Double> = arg.map { asin(it) }
|
||||||
|
override fun acos(arg: NDStructure<Double>): NDBuffer<Double> = arg.map { acos(it) }
|
||||||
|
override fun atan(arg: NDStructure<Double>): NDBuffer<Double> = arg.map { atan(it) }
|
||||||
|
|
||||||
|
override fun sinh(arg: NDStructure<Double>): NDBuffer<Double> = arg.map { sinh(it) }
|
||||||
|
override fun cosh(arg: NDStructure<Double>): NDBuffer<Double> = arg.map { cosh(it) }
|
||||||
|
override fun tanh(arg: NDStructure<Double>): NDBuffer<Double> = arg.map { tanh(it) }
|
||||||
|
override fun asinh(arg: NDStructure<Double>): NDBuffer<Double> = arg.map { asinh(it) }
|
||||||
|
override fun acosh(arg: NDStructure<Double>): NDBuffer<Double> = arg.map { acosh(it) }
|
||||||
|
override fun atanh(arg: NDStructure<Double>): NDBuffer<Double> = arg.map { atanh(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun NDAlgebra.Companion.realWithStream(vararg shape: Int): StreamRealNDField = StreamRealNDField(shape)
|
fun NDAlgebra.Companion.realWithStream(vararg shape: Int): StreamRealNDField = StreamRealNDField(shape)
|
@ -1,9 +1,10 @@
|
|||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
kotlin.mpp.enableGranularSourceSetsMetadata=true
|
|
||||||
kotlin.mpp.stability.nowarn=true
|
kotlin.mpp.stability.nowarn=true
|
||||||
kotlin.native.enableDependencyPropagation=false
|
|
||||||
kotlin.parallel.tasks.in.project=true
|
kotlin.parallel.tasks.in.project=true
|
||||||
org.gradle.configureondemand=true
|
org.gradle.configureondemand=true
|
||||||
org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m
|
org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m
|
||||||
org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
systemProp.org.gradle.internal.publish.checksums.insecure=true
|
|
||||||
|
kotlin.mpp.enableGranularSourceSetsMetadata=true
|
||||||
|
kotlin.native.enableDependencyPropagation=false
|
||||||
|
|
||||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
@ -18,25 +18,25 @@ public object MstAlgebra : NumericAlgebra<MST> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [Space] over [MST] nodes.
|
* [Group] over [MST] nodes.
|
||||||
*/
|
*/
|
||||||
public object MstSpace : Space<MST>, NumericAlgebra<MST> {
|
public object MstGroup : Group<MST>, NumericAlgebra<MST>, ScaleOperations<MST> {
|
||||||
public override val zero: MST.Numeric by lazy { number(0.0) }
|
public override val zero: MST.Numeric = number(0.0)
|
||||||
|
|
||||||
public override fun number(value: Number): MST.Numeric = MstAlgebra.number(value)
|
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 bindSymbol(value: String): MST.Symbolic = MstAlgebra.bindSymbol(value)
|
||||||
public override fun add(a: MST, b: MST): MST.Binary = binaryOperationFunction(SpaceOperations.PLUS_OPERATION)(a, b)
|
public override fun add(a: MST, b: MST): MST.Binary = binaryOperationFunction(GroupOperations.PLUS_OPERATION)(a, b)
|
||||||
public override operator fun MST.unaryPlus(): MST.Unary =
|
public override operator fun MST.unaryPlus(): MST.Unary =
|
||||||
unaryOperationFunction(SpaceOperations.PLUS_OPERATION)(this)
|
unaryOperationFunction(GroupOperations.PLUS_OPERATION)(this)
|
||||||
|
|
||||||
public override operator fun MST.unaryMinus(): MST.Unary =
|
public override operator fun MST.unaryMinus(): MST.Unary =
|
||||||
unaryOperationFunction(SpaceOperations.MINUS_OPERATION)(this)
|
unaryOperationFunction(GroupOperations.MINUS_OPERATION)(this)
|
||||||
|
|
||||||
public override operator fun MST.minus(b: MST): MST.Binary =
|
public override operator fun MST.minus(b: MST): MST.Binary =
|
||||||
binaryOperationFunction(SpaceOperations.MINUS_OPERATION)(this, b)
|
binaryOperationFunction(GroupOperations.MINUS_OPERATION)(this, b)
|
||||||
|
|
||||||
public override fun multiply(a: MST, k: Number): MST.Binary =
|
public override fun scale(a: MST, value: Double): MST.Binary =
|
||||||
binaryOperationFunction(RingOperations.TIMES_OPERATION)(a, number(k))
|
binaryOperationFunction(RingOperations.TIMES_OPERATION)(a, number(value))
|
||||||
|
|
||||||
public override fun binaryOperationFunction(operation: String): (left: MST, right: MST) -> MST.Binary =
|
public override fun binaryOperationFunction(operation: String): (left: MST, right: MST) -> MST.Binary =
|
||||||
MstAlgebra.binaryOperationFunction(operation)
|
MstAlgebra.binaryOperationFunction(operation)
|
||||||
@ -49,25 +49,26 @@ public object MstSpace : Space<MST>, NumericAlgebra<MST> {
|
|||||||
* [Ring] over [MST] nodes.
|
* [Ring] over [MST] nodes.
|
||||||
*/
|
*/
|
||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
public object MstRing : Ring<MST>, RingWithNumbers<MST> {
|
public object MstRing : Ring<MST>, NumbersAddOperations<MST>, ScaleOperations<MST> {
|
||||||
public override val zero: MST.Numeric
|
public override val zero: MST.Numeric get() = MstGroup.zero
|
||||||
get() = MstSpace.zero
|
public override val one: MST.Numeric = number(1.0)
|
||||||
|
|
||||||
public override val one: MST.Numeric by lazy { number(1.0) }
|
public override fun number(value: Number): MST.Numeric = MstGroup.number(value)
|
||||||
|
public override fun bindSymbol(value: String): MST.Symbolic = MstGroup.bindSymbol(value)
|
||||||
|
public override fun add(a: MST, b: MST): MST.Binary = MstGroup.add(a, b)
|
||||||
|
|
||||||
|
public override fun scale(a: MST, value: Double): MST.Binary =
|
||||||
|
MstGroup.binaryOperationFunction(RingOperations.TIMES_OPERATION)(a, MstGroup.number(value))
|
||||||
|
|
||||||
public override fun number(value: Number): MST.Numeric = MstSpace.number(value)
|
|
||||||
public override fun bindSymbol(value: String): MST.Symbolic = MstSpace.bindSymbol(value)
|
|
||||||
public override fun add(a: MST, b: MST): MST.Binary = MstSpace.add(a, b)
|
|
||||||
public override fun multiply(a: MST, k: Number): MST.Binary = MstSpace.multiply(a, k)
|
|
||||||
public override fun multiply(a: MST, b: MST): MST.Binary =
|
public override fun multiply(a: MST, b: MST): MST.Binary =
|
||||||
binaryOperationFunction(RingOperations.TIMES_OPERATION)(a, b)
|
binaryOperationFunction(RingOperations.TIMES_OPERATION)(a, b)
|
||||||
|
|
||||||
public override operator fun MST.unaryPlus(): MST.Unary = MstSpace { +this@unaryPlus }
|
public override operator fun MST.unaryPlus(): MST.Unary = MstGroup { +this@unaryPlus }
|
||||||
public override operator fun MST.unaryMinus(): MST.Unary = MstSpace { -this@unaryMinus }
|
public override operator fun MST.unaryMinus(): MST.Unary = MstGroup { -this@unaryMinus }
|
||||||
public override operator fun MST.minus(b: MST): MST.Binary = MstSpace { this@minus - b }
|
public override operator fun MST.minus(b: MST): MST.Binary = MstGroup { this@minus - b }
|
||||||
|
|
||||||
public override fun binaryOperationFunction(operation: String): (left: MST, right: MST) -> MST.Binary =
|
public override fun binaryOperationFunction(operation: String): (left: MST, right: MST) -> MST.Binary =
|
||||||
MstSpace.binaryOperationFunction(operation)
|
MstGroup.binaryOperationFunction(operation)
|
||||||
|
|
||||||
public override fun unaryOperationFunction(operation: String): (arg: MST) -> MST.Unary =
|
public override fun unaryOperationFunction(operation: String): (arg: MST) -> MST.Unary =
|
||||||
MstAlgebra.unaryOperationFunction(operation)
|
MstAlgebra.unaryOperationFunction(operation)
|
||||||
@ -77,17 +78,18 @@ public object MstRing : Ring<MST>, RingWithNumbers<MST> {
|
|||||||
* [Field] over [MST] nodes.
|
* [Field] over [MST] nodes.
|
||||||
*/
|
*/
|
||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
public object MstField : Field<MST>, RingWithNumbers<MST> {
|
public object MstField : Field<MST>, NumbersAddOperations<MST>, ScaleOperations<MST> {
|
||||||
public override val zero: MST.Numeric
|
public override val zero: MST.Numeric get() = MstRing.zero
|
||||||
get() = MstRing.zero
|
|
||||||
|
|
||||||
public override val one: MST.Numeric
|
public override val one: MST.Numeric get() = MstRing.one
|
||||||
get() = MstRing.one
|
|
||||||
|
|
||||||
public override fun bindSymbol(value: String): MST.Symbolic = MstRing.bindSymbol(value)
|
public override fun bindSymbol(value: String): MST.Symbolic = MstRing.bindSymbol(value)
|
||||||
public override fun number(value: Number): MST.Numeric = MstRing.number(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)
|
public override fun add(a: MST, b: MST): MST.Binary = MstRing.add(a, b)
|
||||||
public override fun multiply(a: MST, k: Number): MST.Binary = MstRing.multiply(a, k)
|
|
||||||
|
public override fun scale(a: MST, value: Double): MST.Binary =
|
||||||
|
MstGroup.binaryOperationFunction(RingOperations.TIMES_OPERATION)(a, MstGroup.number(value))
|
||||||
|
|
||||||
public override fun multiply(a: MST, b: MST): MST.Binary = MstRing.multiply(a, b)
|
public override fun multiply(a: MST, b: MST): MST.Binary = MstRing.multiply(a, b)
|
||||||
public override fun divide(a: MST, b: MST): MST.Binary =
|
public override fun divide(a: MST, b: MST): MST.Binary =
|
||||||
binaryOperationFunction(FieldOperations.DIV_OPERATION)(a, b)
|
binaryOperationFunction(FieldOperations.DIV_OPERATION)(a, b)
|
||||||
@ -107,11 +109,8 @@ public object MstField : Field<MST>, RingWithNumbers<MST> {
|
|||||||
* [ExtendedField] over [MST] nodes.
|
* [ExtendedField] over [MST] nodes.
|
||||||
*/
|
*/
|
||||||
public object MstExtendedField : ExtendedField<MST>, NumericAlgebra<MST> {
|
public object MstExtendedField : ExtendedField<MST>, NumericAlgebra<MST> {
|
||||||
public override val zero: MST.Numeric
|
public override val zero: MST.Numeric get() = MstField.zero
|
||||||
get() = MstField.zero
|
public override val one: MST.Numeric get() = MstField.one
|
||||||
|
|
||||||
public override val one: MST.Numeric
|
|
||||||
get() = MstField.one
|
|
||||||
|
|
||||||
public override fun bindSymbol(value: String): MST.Symbolic = MstField.bindSymbol(value)
|
public override fun bindSymbol(value: String): MST.Symbolic = MstField.bindSymbol(value)
|
||||||
public override fun number(value: Number): MST.Numeric = MstRing.number(value)
|
public override fun number(value: Number): MST.Numeric = MstRing.number(value)
|
||||||
@ -121,14 +120,17 @@ public object MstExtendedField : ExtendedField<MST>, NumericAlgebra<MST> {
|
|||||||
public override fun asin(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.ASIN_OPERATION)(arg)
|
public override fun asin(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.ASIN_OPERATION)(arg)
|
||||||
public override fun acos(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.ACOS_OPERATION)(arg)
|
public override fun acos(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.ACOS_OPERATION)(arg)
|
||||||
public override fun atan(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.ATAN_OPERATION)(arg)
|
public override fun atan(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.ATAN_OPERATION)(arg)
|
||||||
public override fun sinh(arg: MST): MST.Unary = unaryOperationFunction(HyperbolicOperations.SINH_OPERATION)(arg)
|
public override fun sinh(arg: MST): MST.Unary = unaryOperationFunction(ExponentialOperations.SINH_OPERATION)(arg)
|
||||||
public override fun cosh(arg: MST): MST.Unary = unaryOperationFunction(HyperbolicOperations.COSH_OPERATION)(arg)
|
public override fun cosh(arg: MST): MST.Unary = unaryOperationFunction(ExponentialOperations.COSH_OPERATION)(arg)
|
||||||
public override fun tanh(arg: MST): MST.Unary = unaryOperationFunction(HyperbolicOperations.TANH_OPERATION)(arg)
|
public override fun tanh(arg: MST): MST.Unary = unaryOperationFunction(ExponentialOperations.TANH_OPERATION)(arg)
|
||||||
public override fun asinh(arg: MST): MST.Unary = unaryOperationFunction(HyperbolicOperations.ASINH_OPERATION)(arg)
|
public override fun asinh(arg: MST): MST.Unary = unaryOperationFunction(ExponentialOperations.ASINH_OPERATION)(arg)
|
||||||
public override fun acosh(arg: MST): MST.Unary = unaryOperationFunction(HyperbolicOperations.ACOSH_OPERATION)(arg)
|
public override fun acosh(arg: MST): MST.Unary = unaryOperationFunction(ExponentialOperations.ACOSH_OPERATION)(arg)
|
||||||
public override fun atanh(arg: MST): MST.Unary = unaryOperationFunction(HyperbolicOperations.ATANH_OPERATION)(arg)
|
public override fun atanh(arg: MST): MST.Unary = unaryOperationFunction(ExponentialOperations.ATANH_OPERATION)(arg)
|
||||||
public override fun add(a: MST, b: MST): MST.Binary = MstField.add(a, b)
|
public override fun add(a: MST, b: MST): MST.Binary = MstField.add(a, b)
|
||||||
public override fun multiply(a: MST, k: Number): MST.Binary = MstField.multiply(a, k)
|
|
||||||
|
public override fun scale(a: MST, value: Double): MST =
|
||||||
|
binaryOperation(GroupOperations.PLUS_OPERATION, a, number(value))
|
||||||
|
|
||||||
public override fun multiply(a: MST, b: MST): MST.Binary = MstField.multiply(a, b)
|
public override fun multiply(a: MST, b: MST): MST.Binary = MstField.multiply(a, b)
|
||||||
public override fun divide(a: MST, b: MST): MST.Binary = MstField.divide(a, b)
|
public override fun divide(a: MST, b: MST): MST.Binary = MstField.divide(a, b)
|
||||||
public override operator fun MST.unaryPlus(): MST.Unary = MstField { +this@unaryPlus }
|
public override operator fun MST.unaryPlus(): MST.Unary = MstField { +this@unaryPlus }
|
||||||
|
@ -54,13 +54,13 @@ public inline fun <reified T : Any, A : Algebra<T>, E : Algebra<MST>> A.mst(
|
|||||||
): MstExpression<T, A> = MstExpression(this, mstAlgebra.block())
|
): MstExpression<T, A> = MstExpression(this, mstAlgebra.block())
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds [MstExpression] over [Space].
|
* Builds [MstExpression] over [Group].
|
||||||
*
|
*
|
||||||
* @author Alexander Nozik
|
* @author Alexander Nozik
|
||||||
*/
|
*/
|
||||||
public inline fun <reified T : Any, A : Space<T>> A.mstInSpace(block: MstSpace.() -> MST): MstExpression<T, A> {
|
public inline fun <reified T : Any, A : Group<T>> A.mstInGroup(block: MstGroup.() -> MST): MstExpression<T, A> {
|
||||||
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
||||||
return MstExpression(this, MstSpace.block())
|
return MstExpression(this, MstGroup.block())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,13 +94,13 @@ public inline fun <reified T : Any, A : ExtendedField<T>> A.mstInExtendedField(b
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds [MstExpression] over [FunctionalExpressionSpace].
|
* Builds [MstExpression] over [FunctionalExpressionGroup].
|
||||||
*
|
*
|
||||||
* @author Alexander Nozik
|
* @author Alexander Nozik
|
||||||
*/
|
*/
|
||||||
public inline fun <reified T : Any, A : Space<T>> FunctionalExpressionSpace<T, A>.mstInSpace(block: MstSpace.() -> MST): MstExpression<T, A> {
|
public inline fun <reified T : Any, A : Group<T>> FunctionalExpressionGroup<T, A>.mstInGroup(block: MstGroup.() -> MST): MstExpression<T, A> {
|
||||||
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
||||||
return algebra.mstInSpace(block)
|
return algebra.mstInGroup(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,12 +12,12 @@ import kotlin.test.assertEquals
|
|||||||
internal class TestESTreeConsistencyWithInterpreter {
|
internal class TestESTreeConsistencyWithInterpreter {
|
||||||
@Test
|
@Test
|
||||||
fun mstSpace() {
|
fun mstSpace() {
|
||||||
val res1 = MstSpace.mstInSpace {
|
val res1 = MstGroup.mstInGroup {
|
||||||
binaryOperationFunction("+")(
|
binaryOperationFunction("+")(
|
||||||
unaryOperationFunction("+")(
|
unaryOperationFunction("+")(
|
||||||
number(3.toByte()) - (number(2.toByte()) + (multiply(
|
number(3.toByte()) - (number(2.toByte()) + (scale(
|
||||||
add(number(1), number(1)),
|
add(number(1), number(1)),
|
||||||
2
|
2.0
|
||||||
) + number(1.toByte()) * 3.toByte() - number(1.toByte())))
|
) + number(1.toByte()) * 3.toByte() - number(1.toByte())))
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -25,12 +25,12 @@ internal class TestESTreeConsistencyWithInterpreter {
|
|||||||
) + bindSymbol("x") + zero
|
) + bindSymbol("x") + zero
|
||||||
}("x" to MST.Numeric(2))
|
}("x" to MST.Numeric(2))
|
||||||
|
|
||||||
val res2 = MstSpace.mstInSpace {
|
val res2 = MstGroup.mstInGroup {
|
||||||
binaryOperationFunction("+")(
|
binaryOperationFunction("+")(
|
||||||
unaryOperationFunction("+")(
|
unaryOperationFunction("+")(
|
||||||
number(3.toByte()) - (number(2.toByte()) + (multiply(
|
number(3.toByte()) - (number(2.toByte()) + (scale(
|
||||||
add(number(1), number(1)),
|
add(number(1), number(1)),
|
||||||
2
|
2.0
|
||||||
) + number(1.toByte()) * 3.toByte() - number(1.toByte())))
|
) + number(1.toByte()) * 3.toByte() - number(1.toByte())))
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -46,9 +46,9 @@ internal class TestESTreeConsistencyWithInterpreter {
|
|||||||
val res1 = ByteRing.mstInRing {
|
val res1 = ByteRing.mstInRing {
|
||||||
binaryOperationFunction("+")(
|
binaryOperationFunction("+")(
|
||||||
unaryOperationFunction("+")(
|
unaryOperationFunction("+")(
|
||||||
(bindSymbol("x") - (2.toByte() + (multiply(
|
(bindSymbol("x") - (2.toByte() + (scale(
|
||||||
add(number(1), number(1)),
|
add(number(1), number(1)),
|
||||||
2
|
2.0
|
||||||
) + 1.toByte()))) * 3.0 - 1.toByte()
|
) + 1.toByte()))) * 3.0 - 1.toByte()
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -59,9 +59,9 @@ internal class TestESTreeConsistencyWithInterpreter {
|
|||||||
val res2 = ByteRing.mstInRing {
|
val res2 = ByteRing.mstInRing {
|
||||||
binaryOperationFunction("+")(
|
binaryOperationFunction("+")(
|
||||||
unaryOperationFunction("+")(
|
unaryOperationFunction("+")(
|
||||||
(bindSymbol("x") - (2.toByte() + (multiply(
|
(bindSymbol("x") - (2.toByte() + (scale(
|
||||||
add(number(1), number(1)),
|
add(number(1), number(1)),
|
||||||
2
|
2.0
|
||||||
) + 1.toByte()))) * 3.0 - 1.toByte()
|
) + 1.toByte()))) * 3.0 - 1.toByte()
|
||||||
),
|
),
|
||||||
number(1)
|
number(1)
|
||||||
@ -75,7 +75,7 @@ internal class TestESTreeConsistencyWithInterpreter {
|
|||||||
fun realField() {
|
fun realField() {
|
||||||
val res1 = RealField.mstInField {
|
val res1 = RealField.mstInField {
|
||||||
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
|
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
|
||||||
(3.0 - (bindSymbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0
|
(3.0 - (bindSymbol("x") + (scale(add(number(1.0), number(1.0)), 2.0) + 1.0))) * 3 - 1.0
|
||||||
+ number(1),
|
+ number(1),
|
||||||
number(1) / 2 + number(2.0) * one
|
number(1) / 2 + number(2.0) * one
|
||||||
) + zero
|
) + zero
|
||||||
@ -83,7 +83,7 @@ internal class TestESTreeConsistencyWithInterpreter {
|
|||||||
|
|
||||||
val res2 = RealField.mstInField {
|
val res2 = RealField.mstInField {
|
||||||
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
|
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
|
||||||
(3.0 - (bindSymbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0
|
(3.0 - (bindSymbol("x") + (scale(add(number(1.0), number(1.0)), 2.0) + 1.0))) * 3 - 1.0
|
||||||
+ number(1),
|
+ number(1),
|
||||||
number(1) / 2 + number(2.0) * one
|
number(1) / 2 + number(2.0) * one
|
||||||
) + zero
|
) + zero
|
||||||
@ -96,7 +96,7 @@ internal class TestESTreeConsistencyWithInterpreter {
|
|||||||
fun complexField() {
|
fun complexField() {
|
||||||
val res1 = ComplexField.mstInField {
|
val res1 = ComplexField.mstInField {
|
||||||
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
|
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
|
||||||
(3.0 - (bindSymbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0
|
(3.0 - (bindSymbol("x") + (scale(add(number(1.0), number(1.0)), 2.0) + 1.0))) * 3 - 1.0
|
||||||
+ number(1),
|
+ number(1),
|
||||||
number(1) / 2 + number(2.0) * one
|
number(1) / 2 + number(2.0) * one
|
||||||
) + zero
|
) + zero
|
||||||
@ -104,7 +104,7 @@ internal class TestESTreeConsistencyWithInterpreter {
|
|||||||
|
|
||||||
val res2 = ComplexField.mstInField {
|
val res2 = ComplexField.mstInField {
|
||||||
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
|
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
|
||||||
(3.0 - (bindSymbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0
|
(3.0 - (bindSymbol("x") + (scale(add(number(1.0), number(1.0)), 2.0) + 1.0))) * 3 - 1.0
|
||||||
+ number(1),
|
+ number(1),
|
||||||
number(1) / 2 + number(2.0) * one
|
number(1) / 2 + number(2.0) * one
|
||||||
) + zero
|
) + zero
|
||||||
|
@ -2,7 +2,7 @@ package space.kscience.kmath.estree
|
|||||||
|
|
||||||
import space.kscience.kmath.ast.mstInExtendedField
|
import space.kscience.kmath.ast.mstInExtendedField
|
||||||
import space.kscience.kmath.ast.mstInField
|
import space.kscience.kmath.ast.mstInField
|
||||||
import space.kscience.kmath.ast.mstInSpace
|
import space.kscience.kmath.ast.mstInGroup
|
||||||
import space.kscience.kmath.expressions.invoke
|
import space.kscience.kmath.expressions.invoke
|
||||||
import space.kscience.kmath.operations.RealField
|
import space.kscience.kmath.operations.RealField
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
@ -12,14 +12,14 @@ import kotlin.test.assertEquals
|
|||||||
internal class TestESTreeOperationsSupport {
|
internal class TestESTreeOperationsSupport {
|
||||||
@Test
|
@Test
|
||||||
fun testUnaryOperationInvocation() {
|
fun testUnaryOperationInvocation() {
|
||||||
val expression = RealField.mstInSpace { -bindSymbol("x") }.compile()
|
val expression = RealField.mstInGroup { -bindSymbol("x") }.compile()
|
||||||
val res = expression("x" to 2.0)
|
val res = expression("x" to 2.0)
|
||||||
assertEquals(-2.0, res)
|
assertEquals(-2.0, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testBinaryOperationInvocation() {
|
fun testBinaryOperationInvocation() {
|
||||||
val expression = RealField.mstInSpace { -bindSymbol("x") + number(1.0) }.compile()
|
val expression = RealField.mstInGroup { -bindSymbol("x") + number(1.0) }.compile()
|
||||||
val res = expression("x" to 2.0)
|
val res = expression("x" to 2.0)
|
||||||
assertEquals(-1.0, res)
|
assertEquals(-1.0, res)
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,9 @@ import com.github.h0tk3y.betterParse.lexer.regexToken
|
|||||||
import com.github.h0tk3y.betterParse.parser.ParseResult
|
import com.github.h0tk3y.betterParse.parser.ParseResult
|
||||||
import com.github.h0tk3y.betterParse.parser.Parser
|
import com.github.h0tk3y.betterParse.parser.Parser
|
||||||
import space.kscience.kmath.operations.FieldOperations
|
import space.kscience.kmath.operations.FieldOperations
|
||||||
|
import space.kscience.kmath.operations.GroupOperations
|
||||||
import space.kscience.kmath.operations.PowerOperations
|
import space.kscience.kmath.operations.PowerOperations
|
||||||
import space.kscience.kmath.operations.RingOperations
|
import space.kscience.kmath.operations.RingOperations
|
||||||
import space.kscience.kmath.operations.SpaceOperations
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* better-parse implementation of grammar defined in the ArithmeticsEvaluator.g4.
|
* better-parse implementation of grammar defined in the ArithmeticsEvaluator.g4.
|
||||||
@ -55,7 +55,7 @@ public object ArithmeticsEvaluator : Grammar<MST>() {
|
|||||||
.or(binaryFunction)
|
.or(binaryFunction)
|
||||||
.or(unaryFunction)
|
.or(unaryFunction)
|
||||||
.or(singular)
|
.or(singular)
|
||||||
.or(-minus and parser(ArithmeticsEvaluator::term) map { MST.Unary(SpaceOperations.MINUS_OPERATION, it) })
|
.or(-minus and parser(ArithmeticsEvaluator::term) map { MST.Unary(GroupOperations.MINUS_OPERATION, it) })
|
||||||
.or(-lpar and parser(ArithmeticsEvaluator::subSumChain) and -rpar)
|
.or(-lpar and parser(ArithmeticsEvaluator::subSumChain) and -rpar)
|
||||||
|
|
||||||
private val powChain: Parser<MST> by leftAssociative(term = term, operator = pow) { a, _, b ->
|
private val powChain: Parser<MST> by leftAssociative(term = term, operator = pow) { a, _, b ->
|
||||||
@ -77,9 +77,9 @@ public object ArithmeticsEvaluator : Grammar<MST>() {
|
|||||||
operator = plus or minus use TokenMatch::type
|
operator = plus or minus use TokenMatch::type
|
||||||
) { a, op, b ->
|
) { a, op, b ->
|
||||||
if (op == plus)
|
if (op == plus)
|
||||||
MST.Binary(SpaceOperations.PLUS_OPERATION, a, b)
|
MST.Binary(GroupOperations.PLUS_OPERATION, a, b)
|
||||||
else
|
else
|
||||||
MST.Binary(SpaceOperations.MINUS_OPERATION, a, b)
|
MST.Binary(GroupOperations.MINUS_OPERATION, a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val rootParser: Parser<MST> by subSumChain
|
override val rootParser: Parser<MST> by subSumChain
|
||||||
|
@ -12,12 +12,12 @@ import kotlin.test.assertEquals
|
|||||||
internal class TestAsmConsistencyWithInterpreter {
|
internal class TestAsmConsistencyWithInterpreter {
|
||||||
@Test
|
@Test
|
||||||
fun mstSpace() {
|
fun mstSpace() {
|
||||||
val res1 = MstSpace.mstInSpace {
|
val res1 = MstGroup.mstInGroup {
|
||||||
binaryOperationFunction("+")(
|
binaryOperationFunction("+")(
|
||||||
unaryOperationFunction("+")(
|
unaryOperationFunction("+")(
|
||||||
number(3.toByte()) - (number(2.toByte()) + (multiply(
|
number(3.toByte()) - (number(2.toByte()) + (scale(
|
||||||
add(number(1), number(1)),
|
add(number(1), number(1)),
|
||||||
2
|
2.0
|
||||||
) + number(1.toByte()) * 3.toByte() - number(1.toByte())))
|
) + number(1.toByte()) * 3.toByte() - number(1.toByte())))
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -25,12 +25,12 @@ internal class TestAsmConsistencyWithInterpreter {
|
|||||||
) + bindSymbol("x") + zero
|
) + bindSymbol("x") + zero
|
||||||
}("x" to MST.Numeric(2))
|
}("x" to MST.Numeric(2))
|
||||||
|
|
||||||
val res2 = MstSpace.mstInSpace {
|
val res2 = MstGroup.mstInGroup {
|
||||||
binaryOperationFunction("+")(
|
binaryOperationFunction("+")(
|
||||||
unaryOperationFunction("+")(
|
unaryOperationFunction("+")(
|
||||||
number(3.toByte()) - (number(2.toByte()) + (multiply(
|
number(3.toByte()) - (number(2.toByte()) + (scale(
|
||||||
add(number(1), number(1)),
|
add(number(1), number(1)),
|
||||||
2
|
2.0
|
||||||
) + number(1.toByte()) * 3.toByte() - number(1.toByte())))
|
) + number(1.toByte()) * 3.toByte() - number(1.toByte())))
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -46,9 +46,9 @@ internal class TestAsmConsistencyWithInterpreter {
|
|||||||
val res1 = ByteRing.mstInRing {
|
val res1 = ByteRing.mstInRing {
|
||||||
binaryOperationFunction("+")(
|
binaryOperationFunction("+")(
|
||||||
unaryOperationFunction("+")(
|
unaryOperationFunction("+")(
|
||||||
(bindSymbol("x") - (2.toByte() + (multiply(
|
(bindSymbol("x") - (2.toByte() + (scale(
|
||||||
add(number(1), number(1)),
|
add(number(1), number(1)),
|
||||||
2
|
2.0
|
||||||
) + 1.toByte()))) * 3.0 - 1.toByte()
|
) + 1.toByte()))) * 3.0 - 1.toByte()
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -59,9 +59,9 @@ internal class TestAsmConsistencyWithInterpreter {
|
|||||||
val res2 = ByteRing.mstInRing {
|
val res2 = ByteRing.mstInRing {
|
||||||
binaryOperationFunction("+")(
|
binaryOperationFunction("+")(
|
||||||
unaryOperationFunction("+")(
|
unaryOperationFunction("+")(
|
||||||
(bindSymbol("x") - (2.toByte() + (multiply(
|
(bindSymbol("x") - (2.toByte() + (scale(
|
||||||
add(number(1), number(1)),
|
add(number(1), number(1)),
|
||||||
2
|
2.0
|
||||||
) + 1.toByte()))) * 3.0 - 1.toByte()
|
) + 1.toByte()))) * 3.0 - 1.toByte()
|
||||||
),
|
),
|
||||||
number(1)
|
number(1)
|
||||||
@ -75,7 +75,7 @@ internal class TestAsmConsistencyWithInterpreter {
|
|||||||
fun realField() {
|
fun realField() {
|
||||||
val res1 = RealField.mstInField {
|
val res1 = RealField.mstInField {
|
||||||
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
|
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
|
||||||
(3.0 - (bindSymbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0
|
(3.0 - (bindSymbol("x") + (scale(add(number(1.0), number(1.0)), 2.0) + 1.0))) * 3 - 1.0
|
||||||
+ number(1),
|
+ number(1),
|
||||||
number(1) / 2 + number(2.0) * one
|
number(1) / 2 + number(2.0) * one
|
||||||
) + zero
|
) + zero
|
||||||
@ -83,7 +83,7 @@ internal class TestAsmConsistencyWithInterpreter {
|
|||||||
|
|
||||||
val res2 = RealField.mstInField {
|
val res2 = RealField.mstInField {
|
||||||
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
|
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
|
||||||
(3.0 - (bindSymbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0
|
(3.0 - (bindSymbol("x") + (scale(add(number(1.0), number(1.0)), 2.0) + 1.0))) * 3 - 1.0
|
||||||
+ number(1),
|
+ number(1),
|
||||||
number(1) / 2 + number(2.0) * one
|
number(1) / 2 + number(2.0) * one
|
||||||
) + zero
|
) + zero
|
||||||
@ -96,7 +96,7 @@ internal class TestAsmConsistencyWithInterpreter {
|
|||||||
fun complexField() {
|
fun complexField() {
|
||||||
val res1 = ComplexField.mstInField {
|
val res1 = ComplexField.mstInField {
|
||||||
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
|
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
|
||||||
(3.0 - (bindSymbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0
|
(3.0 - (bindSymbol("x") + (scale(add(number(1.0), number(1.0)), 2.0) + 1.0))) * 3 - 1.0
|
||||||
+ number(1),
|
+ number(1),
|
||||||
number(1) / 2 + number(2.0) * one
|
number(1) / 2 + number(2.0) * one
|
||||||
) + zero
|
) + zero
|
||||||
@ -104,7 +104,7 @@ internal class TestAsmConsistencyWithInterpreter {
|
|||||||
|
|
||||||
val res2 = ComplexField.mstInField {
|
val res2 = ComplexField.mstInField {
|
||||||
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
|
+(3 - 2 + 2 * number(1) + 1.0) + binaryOperationFunction("+")(
|
||||||
(3.0 - (bindSymbol("x") + (multiply(add(number(1.0), number(1.0)), 2) + 1.0))) * 3 - 1.0
|
(3.0 - (bindSymbol("x") + (scale(add(number(1.0), number(1.0)), 2.0) + 1.0))) * 3 - 1.0
|
||||||
+ number(1),
|
+ number(1),
|
||||||
number(1) / 2 + number(2.0) * one
|
number(1) / 2 + number(2.0) * one
|
||||||
) + zero
|
) + zero
|
||||||
|
@ -2,7 +2,7 @@ package space.kscience.kmath.asm
|
|||||||
|
|
||||||
import space.kscience.kmath.ast.mstInExtendedField
|
import space.kscience.kmath.ast.mstInExtendedField
|
||||||
import space.kscience.kmath.ast.mstInField
|
import space.kscience.kmath.ast.mstInField
|
||||||
import space.kscience.kmath.ast.mstInSpace
|
import space.kscience.kmath.ast.mstInGroup
|
||||||
import space.kscience.kmath.expressions.invoke
|
import space.kscience.kmath.expressions.invoke
|
||||||
import space.kscience.kmath.operations.RealField
|
import space.kscience.kmath.operations.RealField
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
@ -12,14 +12,14 @@ import kotlin.test.assertEquals
|
|||||||
internal class TestAsmOperationsSupport {
|
internal class TestAsmOperationsSupport {
|
||||||
@Test
|
@Test
|
||||||
fun testUnaryOperationInvocation() {
|
fun testUnaryOperationInvocation() {
|
||||||
val expression = RealField.mstInSpace { -bindSymbol("x") }.compile()
|
val expression = RealField.mstInGroup { -bindSymbol("x") }.compile()
|
||||||
val res = expression("x" to 2.0)
|
val res = expression("x" to 2.0)
|
||||||
assertEquals(-2.0, res)
|
assertEquals(-2.0, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testBinaryOperationInvocation() {
|
fun testBinaryOperationInvocation() {
|
||||||
val expression = RealField.mstInSpace { -bindSymbol("x") + number(1.0) }.compile()
|
val expression = RealField.mstInGroup { -bindSymbol("x") + number(1.0) }.compile()
|
||||||
val res = expression("x" to 2.0)
|
val res = expression("x" to 2.0)
|
||||||
assertEquals(-1.0, res)
|
assertEquals(-1.0, res)
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import org.apache.commons.math3.analysis.differentiation.DerivativeStructure
|
|||||||
import space.kscience.kmath.expressions.*
|
import space.kscience.kmath.expressions.*
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.operations.ExtendedField
|
import space.kscience.kmath.operations.ExtendedField
|
||||||
import space.kscience.kmath.operations.RingWithNumbers
|
import space.kscience.kmath.operations.NumbersAddOperations
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A field over commons-math [DerivativeStructure].
|
* A field over commons-math [DerivativeStructure].
|
||||||
@ -16,7 +16,8 @@ import space.kscience.kmath.operations.RingWithNumbers
|
|||||||
public class DerivativeStructureField(
|
public class DerivativeStructureField(
|
||||||
public val order: Int,
|
public val order: Int,
|
||||||
bindings: Map<Symbol, Double>,
|
bindings: Map<Symbol, Double>,
|
||||||
) : ExtendedField<DerivativeStructure>, ExpressionAlgebra<Double, DerivativeStructure>, RingWithNumbers<DerivativeStructure> {
|
) : ExtendedField<DerivativeStructure>, ExpressionAlgebra<Double, DerivativeStructure>,
|
||||||
|
NumbersAddOperations<DerivativeStructure> {
|
||||||
public val numberOfVariables: Int = bindings.size
|
public val numberOfVariables: Int = bindings.size
|
||||||
|
|
||||||
public override val zero: DerivativeStructure by lazy { DerivativeStructure(numberOfVariables, order) }
|
public override val zero: DerivativeStructure by lazy { DerivativeStructure(numberOfVariables, order) }
|
||||||
@ -62,13 +63,11 @@ public class DerivativeStructureField(
|
|||||||
|
|
||||||
public fun DerivativeStructure.derivative(vararg symbols: Symbol): Double = derivative(symbols.toList())
|
public fun DerivativeStructure.derivative(vararg symbols: Symbol): Double = derivative(symbols.toList())
|
||||||
|
|
||||||
|
override fun DerivativeStructure.unaryMinus(): DerivativeStructure = negate()
|
||||||
|
|
||||||
public override fun add(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.add(b)
|
public override fun add(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.add(b)
|
||||||
|
|
||||||
public override fun multiply(a: DerivativeStructure, k: Number): DerivativeStructure = when (k) {
|
public override fun scale(a: DerivativeStructure, value: Double): DerivativeStructure = a.multiply(value)
|
||||||
is Double -> a.multiply(k)
|
|
||||||
is Int -> a.multiply(k)
|
|
||||||
else -> a.multiply(k.toDouble())
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun multiply(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.multiply(b)
|
public override fun multiply(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.multiply(b)
|
||||||
public override fun divide(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.divide(b)
|
public override fun divide(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.divide(b)
|
||||||
|
@ -86,6 +86,9 @@ public object CMMatrixContext : MatrixContext<Double, CMMatrix> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun scale(a: Matrix<Double>, value: Double): Matrix<Double> = a.toCM().times(value)
|
||||||
|
|
||||||
|
|
||||||
public override fun Matrix<Double>.dot(other: Matrix<Double>): CMMatrix =
|
public override fun Matrix<Double>.dot(other: Matrix<Double>): CMMatrix =
|
||||||
CMMatrix(toCM().origin.multiply(other.toCM().origin))
|
CMMatrix(toCM().origin.multiply(other.toCM().origin))
|
||||||
|
|
||||||
@ -101,8 +104,8 @@ public object CMMatrixContext : MatrixContext<Double, CMMatrix> {
|
|||||||
public override operator fun Matrix<Double>.minus(b: Matrix<Double>): CMMatrix =
|
public override operator fun Matrix<Double>.minus(b: Matrix<Double>): CMMatrix =
|
||||||
CMMatrix(toCM().origin.subtract(b.toCM().origin))
|
CMMatrix(toCM().origin.subtract(b.toCM().origin))
|
||||||
|
|
||||||
public override fun multiply(a: Matrix<Double>, k: Number): CMMatrix =
|
// public override fun multiply(a: Matrix<Double>, k: Number): CMMatrix =
|
||||||
CMMatrix(a.toCM().origin.scalarMultiply(k.toDouble()))
|
// CMMatrix(a.toCM().origin.scalarMultiply(k.toDouble()))
|
||||||
|
|
||||||
public override operator fun Matrix<Double>.times(value: Double): CMMatrix =
|
public override operator fun Matrix<Double>.times(value: Double): CMMatrix =
|
||||||
produce(rowNum, colNum) { i, j -> get(i, j) * value }
|
produce(rowNum, colNum) { i, j -> get(i, j) * value }
|
||||||
|
@ -4,10 +4,7 @@ import space.kscience.kmath.memory.MemoryReader
|
|||||||
import space.kscience.kmath.memory.MemorySpec
|
import space.kscience.kmath.memory.MemorySpec
|
||||||
import space.kscience.kmath.memory.MemoryWriter
|
import space.kscience.kmath.memory.MemoryWriter
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.operations.ExtendedField
|
import space.kscience.kmath.operations.*
|
||||||
import space.kscience.kmath.operations.FieldElement
|
|
||||||
import space.kscience.kmath.operations.Norm
|
|
||||||
import space.kscience.kmath.operations.RingWithNumbers
|
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
import space.kscience.kmath.structures.MemoryBuffer
|
import space.kscience.kmath.structures.MemoryBuffer
|
||||||
import space.kscience.kmath.structures.MutableBuffer
|
import space.kscience.kmath.structures.MutableBuffer
|
||||||
@ -47,7 +44,8 @@ private val PI_DIV_2 = Complex(PI / 2, 0)
|
|||||||
* A field of [Complex].
|
* A field of [Complex].
|
||||||
*/
|
*/
|
||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
public object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex>, RingWithNumbers<Complex> {
|
public object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex>, NumbersAddOperations<Complex>,
|
||||||
|
ScaleOperations<Complex> {
|
||||||
public override val zero: Complex = 0.0.toComplex()
|
public override val zero: Complex = 0.0.toComplex()
|
||||||
public override val one: Complex = 1.0.toComplex()
|
public override val one: Complex = 1.0.toComplex()
|
||||||
|
|
||||||
@ -56,8 +54,14 @@ public object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex>, Rin
|
|||||||
*/
|
*/
|
||||||
public val i: Complex by lazy { Complex(0.0, 1.0) }
|
public val i: Complex by lazy { Complex(0.0, 1.0) }
|
||||||
|
|
||||||
|
override fun Complex.unaryMinus(): Complex = Complex(-re, -im)
|
||||||
|
|
||||||
|
override fun number(value: Number): Complex = Complex(value.toDouble(), 0.0)
|
||||||
|
|
||||||
|
override fun scale(a: Complex, value: Double): Complex = Complex(a.re * value, a.im * value)
|
||||||
|
|
||||||
public override fun add(a: Complex, b: Complex): Complex = Complex(a.re + b.re, a.im + b.im)
|
public override fun add(a: Complex, b: Complex): Complex = Complex(a.re + b.re, a.im + b.im)
|
||||||
public override fun multiply(a: Complex, k: Number): Complex = Complex(a.re * k.toDouble(), a.im * k.toDouble())
|
// public override fun multiply(a: Complex, k: Number): Complex = Complex(a.re * k.toDouble(), a.im * k.toDouble())
|
||||||
|
|
||||||
public override fun multiply(a: Complex, b: Complex): Complex =
|
public override fun multiply(a: Complex, b: Complex): Complex =
|
||||||
Complex(a.re * b.re - a.im * b.im, a.re * b.im + a.im * b.re)
|
Complex(a.re * b.re - a.im * b.im, a.re * b.im + a.im * b.re)
|
||||||
@ -86,8 +90,10 @@ public object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex>, Rin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun sin(arg: Complex): Complex = i * (exp(-i * arg) - exp(i * arg)) / 2
|
override operator fun Complex.div(k: Number): Complex = Complex(re / k.toDouble(), im / k.toDouble())
|
||||||
public override fun cos(arg: Complex): Complex = (exp(-i * arg) + exp(i * arg)) / 2
|
|
||||||
|
public override fun sin(arg: Complex): Complex = i * (exp(-i * arg) - exp(i * arg)) / 2.0
|
||||||
|
public override fun cos(arg: Complex): Complex = (exp(-i * arg) + exp(i * arg)) / 2.0
|
||||||
|
|
||||||
public override fun tan(arg: Complex): Complex {
|
public override fun tan(arg: Complex): Complex {
|
||||||
val e1 = exp(-i * arg)
|
val e1 = exp(-i * arg)
|
||||||
@ -159,7 +165,8 @@ public object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex>, Rin
|
|||||||
|
|
||||||
public override fun norm(arg: Complex): Complex = sqrt(arg.conjugate * arg)
|
public override fun norm(arg: Complex): Complex = sqrt(arg.conjugate * arg)
|
||||||
|
|
||||||
public override fun bindSymbol(value: String): Complex = if (value == "i") i else super<ExtendedField>.bindSymbol(value)
|
public override fun bindSymbol(value: String): Complex =
|
||||||
|
if (value == "i") i else super<ExtendedField>.bindSymbol(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -181,7 +188,8 @@ public data class Complex(val re: Double, val im: Double) : FieldElement<Complex
|
|||||||
public override val objectSize: Int
|
public override val objectSize: Int
|
||||||
get() = 16
|
get() = 16
|
||||||
|
|
||||||
public override fun MemoryReader.read(offset: Int): Complex = Complex(readDouble(offset), readDouble(offset + 8))
|
public override fun MemoryReader.read(offset: Int): Complex =
|
||||||
|
Complex(readDouble(offset), readDouble(offset + 8))
|
||||||
|
|
||||||
public override fun MemoryWriter.write(offset: Int, value: Complex) {
|
public override fun MemoryWriter.write(offset: Int, value: Complex) {
|
||||||
writeDouble(offset, value.re)
|
writeDouble(offset, value.re)
|
||||||
|
@ -6,7 +6,7 @@ import space.kscience.kmath.nd.NDAlgebra
|
|||||||
import space.kscience.kmath.nd.NDBuffer
|
import space.kscience.kmath.nd.NDBuffer
|
||||||
import space.kscience.kmath.nd.NDStructure
|
import space.kscience.kmath.nd.NDStructure
|
||||||
import space.kscience.kmath.operations.ExtendedField
|
import space.kscience.kmath.operations.ExtendedField
|
||||||
import space.kscience.kmath.operations.RingWithNumbers
|
import space.kscience.kmath.operations.NumbersAddOperations
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
import kotlin.contracts.InvocationKind
|
import kotlin.contracts.InvocationKind
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
@ -19,7 +19,7 @@ import kotlin.contracts.contract
|
|||||||
public class ComplexNDField(
|
public class ComplexNDField(
|
||||||
shape: IntArray,
|
shape: IntArray,
|
||||||
) : BufferedNDField<Complex, ComplexField>(shape, ComplexField, Buffer.Companion::complex),
|
) : BufferedNDField<Complex, ComplexField>(shape, ComplexField, Buffer.Companion::complex),
|
||||||
RingWithNumbers<NDStructure<Complex>>,
|
NumbersAddOperations<NDStructure<Complex>>,
|
||||||
ExtendedField<NDStructure<Complex>> {
|
ExtendedField<NDStructure<Complex>> {
|
||||||
|
|
||||||
override val zero: NDBuffer<Complex> by lazy { produce { zero } }
|
override val zero: NDBuffer<Complex> by lazy { produce { zero } }
|
||||||
@ -29,6 +29,7 @@ public class ComplexNDField(
|
|||||||
val d = value.toComplex() // minimize conversions
|
val d = value.toComplex() // minimize conversions
|
||||||
return produce { d }
|
return produce { d }
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// @Suppress("OVERRIDE_BY_INLINE")
|
// @Suppress("OVERRIDE_BY_INLINE")
|
||||||
// override inline fun map(
|
// override inline fun map(
|
||||||
@ -75,25 +76,25 @@ public class ComplexNDField(
|
|||||||
// return BufferedNDFieldElement(this, buffer)
|
// return BufferedNDFieldElement(this, buffer)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
override fun power(arg: NDStructure<Complex>, pow: Number): NDBuffer<Complex> = arg.map() { power(it, pow) }
|
override fun power(arg: NDStructure<Complex>, pow: Number): NDBuffer<Complex> = arg.map { power(it, pow) }
|
||||||
|
|
||||||
override fun exp(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map() { exp(it) }
|
override fun exp(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map { exp(it) }
|
||||||
|
|
||||||
override fun ln(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map() { ln(it) }
|
override fun ln(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map { ln(it) }
|
||||||
|
|
||||||
override fun sin(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map() { sin(it) }
|
override fun sin(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map { sin(it) }
|
||||||
override fun cos(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map() { cos(it) }
|
override fun cos(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map { cos(it) }
|
||||||
override fun tan(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map() { tan(it) }
|
override fun tan(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map { tan(it) }
|
||||||
override fun asin(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map() { asin(it) }
|
override fun asin(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map { asin(it) }
|
||||||
override fun acos(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map() { acos(it) }
|
override fun acos(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map { acos(it) }
|
||||||
override fun atan(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map() { atan(it) }
|
override fun atan(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map { atan(it) }
|
||||||
|
|
||||||
override fun sinh(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map() { sinh(it) }
|
override fun sinh(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map { sinh(it) }
|
||||||
override fun cosh(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map() { cosh(it) }
|
override fun cosh(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map { cosh(it) }
|
||||||
override fun tanh(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map() { tanh(it) }
|
override fun tanh(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map { tanh(it) }
|
||||||
override fun asinh(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map() { asinh(it) }
|
override fun asinh(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map { asinh(it) }
|
||||||
override fun acosh(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map() { acosh(it) }
|
override fun acosh(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map { acosh(it) }
|
||||||
override fun atanh(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map() { atanh(it) }
|
override fun atanh(arg: NDStructure<Complex>): NDBuffer<Complex> = arg.map { atanh(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ public val Quaternion.r: Double
|
|||||||
*/
|
*/
|
||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
public object QuaternionField : Field<Quaternion>, Norm<Quaternion, Quaternion>, PowerOperations<Quaternion>,
|
public object QuaternionField : Field<Quaternion>, Norm<Quaternion, Quaternion>, PowerOperations<Quaternion>,
|
||||||
ExponentialOperations<Quaternion>, RingWithNumbers<Quaternion> {
|
ExponentialOperations<Quaternion>, NumbersAddOperations<Quaternion>, ScaleOperations<Quaternion> {
|
||||||
override val zero: Quaternion = 0.toQuaternion()
|
override val zero: Quaternion = 0.toQuaternion()
|
||||||
override val one: Quaternion = 1.toQuaternion()
|
override val one: Quaternion = 1.toQuaternion()
|
||||||
|
|
||||||
@ -59,10 +59,8 @@ public object QuaternionField : Field<Quaternion>, Norm<Quaternion, Quaternion>,
|
|||||||
public override fun add(a: Quaternion, b: Quaternion): Quaternion =
|
public override fun add(a: Quaternion, b: Quaternion): Quaternion =
|
||||||
Quaternion(a.w + b.w, a.x + b.x, a.y + b.y, a.z + b.z)
|
Quaternion(a.w + b.w, a.x + b.x, a.y + b.y, a.z + b.z)
|
||||||
|
|
||||||
public override fun multiply(a: Quaternion, k: Number): Quaternion {
|
public override fun scale(a: Quaternion, value: Double): Quaternion =
|
||||||
val d = k.toDouble()
|
Quaternion(a.w * value, a.x * value, a.y * value, a.z * value)
|
||||||
return Quaternion(a.w * d, a.x * d, a.y * d, a.z * d)
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun multiply(a: Quaternion, b: Quaternion): Quaternion = Quaternion(
|
public override fun multiply(a: Quaternion, b: Quaternion): Quaternion = Quaternion(
|
||||||
a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z,
|
a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z,
|
||||||
@ -173,6 +171,15 @@ public object QuaternionField : Field<Quaternion>, Norm<Quaternion, Quaternion>,
|
|||||||
"k" -> k
|
"k" -> k
|
||||||
else -> super<Field>.bindSymbol(value)
|
else -> super<Field>.bindSymbol(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
public override fun tanh(arg: Quaternion): Quaternion = (exp(arg) - exp(-arg)) / (exp(-arg) + exp(arg))
|
||||||
|
public override fun asinh(arg: Quaternion): Quaternion = ln(sqrt(arg * arg + one) + arg)
|
||||||
|
public override fun acosh(arg: Quaternion): Quaternion = ln(arg + sqrt((arg - one) * (arg + one)))
|
||||||
|
public override fun atanh(arg: Quaternion): Quaternion = (ln(arg + one) - ln(one - arg)) / 2.0
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -207,8 +214,7 @@ public data class Quaternion(
|
|||||||
require(!z.isNaN()) { "x-component of quaternion is not-a-number" }
|
require(!z.isNaN()) { "x-component of quaternion is not-a-number" }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override val context: QuaternionField
|
public override val context: QuaternionField get() = QuaternionField
|
||||||
get() = QuaternionField
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a string representation of this quaternion.
|
* Returns a string representation of this quaternion.
|
||||||
|
@ -4,7 +4,6 @@ import space.kscience.kmath.expressions.FunctionalExpressionField
|
|||||||
import space.kscience.kmath.expressions.bindSymbol
|
import space.kscience.kmath.expressions.bindSymbol
|
||||||
import space.kscience.kmath.expressions.invoke
|
import space.kscience.kmath.expressions.invoke
|
||||||
import space.kscience.kmath.expressions.symbol
|
import space.kscience.kmath.expressions.symbol
|
||||||
import space.kscience.kmath.operations.invoke
|
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
@ -13,14 +12,11 @@ internal class ExpressionFieldForComplexTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testComplex() {
|
fun testComplex() {
|
||||||
val context = FunctionalExpressionField(ComplexField)
|
val expression = FunctionalExpressionField(ComplexField).run {
|
||||||
|
|
||||||
val expression = context {
|
|
||||||
val x = bindSymbol(x)
|
val x = bindSymbol(x)
|
||||||
x * x + 2 * x + one
|
x * x + 2 * x + one
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(expression(x to Complex(1.0, 0.0)), Complex(4.0, 0.0))
|
assertEquals(expression(x to Complex(1.0, 0.0)), Complex(4.0, 0.0))
|
||||||
//assertEquals(expression(), Complex(9.0, 0.0))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
# The Core Module (`kmath-core`)
|
|
||||||
|
|
||||||
The core features 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
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
> #### Artifact:
|
|
||||||
>
|
|
||||||
> This module artifact: `space.kscience:kmath-core:0.2.0`.
|
|
||||||
>
|
|
||||||
> 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
|
|
||||||
>// Uncomment if repo.kotlin.link is unavailable
|
|
||||||
>// maven { url 'https://dl.bintray.com/mipt-npm/kscience' }
|
|
||||||
>// maven { url 'https://dl.bintray.com/mipt-npm/dev' }
|
|
||||||
> }
|
|
||||||
>
|
|
||||||
> dependencies {
|
|
||||||
> implementation 'space.kscience:kmath-core:0.2.0'
|
|
||||||
> }
|
|
||||||
> ```
|
|
||||||
> **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
|
|
||||||
>// Uncomment if repo.kotlin.link is unavailable
|
|
||||||
>// maven("https://dl.bintray.com/mipt-npm/kscience")
|
|
||||||
>// maven("https://dl.bintray.com/mipt-npm/dev")
|
|
||||||
> }
|
|
||||||
>
|
|
||||||
> dependencies {
|
|
||||||
> implementation("space.kscience:kmath-core:0.2.0")
|
|
||||||
> }
|
|
||||||
> ```
|
|
File diff suppressed because it is too large
Load Diff
@ -16,8 +16,8 @@
|
|||||||
package space.kscience.kmath.domains
|
package space.kscience.kmath.domains
|
||||||
|
|
||||||
import space.kscience.kmath.linear.Point
|
import space.kscience.kmath.linear.Point
|
||||||
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
import space.kscience.kmath.structures.RealBuffer
|
|
||||||
import space.kscience.kmath.structures.indices
|
import space.kscience.kmath.structures.indices
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,6 +26,7 @@ import space.kscience.kmath.structures.indices
|
|||||||
*
|
*
|
||||||
* @author Alexander Nozik
|
* @author Alexander Nozik
|
||||||
*/
|
*/
|
||||||
|
@UnstableKMathAPI
|
||||||
public class HyperSquareDomain(private val lower: Buffer<Double>, private val upper: Buffer<Double>) : RealDomain {
|
public class HyperSquareDomain(private val lower: Buffer<Double>, private val upper: Buffer<Double>) : RealDomain {
|
||||||
public override val dimension: Int get() = lower.size
|
public override val dimension: Int get() = lower.size
|
||||||
|
|
||||||
@ -33,26 +34,10 @@ public class HyperSquareDomain(private val lower: Buffer<Double>, private val up
|
|||||||
point[i] in lower[i]..upper[i]
|
point[i] in lower[i]..upper[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun getLowerBound(num: Int, point: Point<Double>): Double = lower[num]
|
|
||||||
|
|
||||||
public override fun getLowerBound(num: Int): Double = lower[num]
|
public override fun getLowerBound(num: Int): Double = lower[num]
|
||||||
|
|
||||||
public override fun getUpperBound(num: Int, point: Point<Double>): Double = upper[num]
|
|
||||||
|
|
||||||
public override fun getUpperBound(num: Int): Double = upper[num]
|
public override fun getUpperBound(num: Int): Double = upper[num]
|
||||||
|
|
||||||
public override fun nearestInDomain(point: Point<Double>): Point<Double> {
|
|
||||||
val res = DoubleArray(point.size) { i ->
|
|
||||||
when {
|
|
||||||
point[i] < lower[i] -> lower[i]
|
|
||||||
point[i] > upper[i] -> upper[i]
|
|
||||||
else -> point[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return RealBuffer(*res)
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun volume(): Double {
|
public override fun volume(): Double {
|
||||||
var res = 1.0
|
var res = 1.0
|
||||||
|
|
||||||
|
@ -15,45 +15,27 @@
|
|||||||
*/
|
*/
|
||||||
package space.kscience.kmath.domains
|
package space.kscience.kmath.domains
|
||||||
|
|
||||||
import space.kscience.kmath.linear.Point
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* n-dimensional volume
|
* n-dimensional volume
|
||||||
*
|
*
|
||||||
* @author Alexander Nozik
|
* @author Alexander Nozik
|
||||||
*/
|
*/
|
||||||
|
@UnstableKMathAPI
|
||||||
public interface RealDomain : Domain<Double> {
|
public interface RealDomain : Domain<Double> {
|
||||||
public fun nearestInDomain(point: Point<Double>): Point<Double>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The lower edge for the domain going down from point
|
|
||||||
* @param num
|
|
||||||
* @param point
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public fun getLowerBound(num: Int, point: Point<Double>): Double?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The upper edge of the domain going up from point
|
|
||||||
* @param num
|
|
||||||
* @param point
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public fun getUpperBound(num: Int, point: Point<Double>): Double?
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Global lower edge
|
* Global lower edge
|
||||||
* @param num
|
* @param num axis number
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public fun getLowerBound(num: Int): Double?
|
public fun getLowerBound(num: Int): Double
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Global upper edge
|
* Global upper edge
|
||||||
* @param num
|
* @param num axis number
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public fun getUpperBound(num: Int): Double?
|
public fun getUpperBound(num: Int): Double
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hyper volume
|
* Hyper volume
|
||||||
|
@ -16,19 +16,15 @@
|
|||||||
package space.kscience.kmath.domains
|
package space.kscience.kmath.domains
|
||||||
|
|
||||||
import space.kscience.kmath.linear.Point
|
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) : RealDomain {
|
||||||
public override operator fun contains(point: Point<Double>): Boolean = true
|
public override operator fun contains(point: Point<Double>): Boolean = true
|
||||||
|
|
||||||
public override fun getLowerBound(num: Int, point: Point<Double>): Double? = Double.NEGATIVE_INFINITY
|
public override fun getLowerBound(num: Int): Double = Double.NEGATIVE_INFINITY
|
||||||
|
|
||||||
public override fun getLowerBound(num: Int): Double? = Double.NEGATIVE_INFINITY
|
public override fun getUpperBound(num: Int): Double = Double.POSITIVE_INFINITY
|
||||||
|
|
||||||
public override fun getUpperBound(num: Int, point: Point<Double>): Double? = Double.POSITIVE_INFINITY
|
|
||||||
|
|
||||||
public override fun getUpperBound(num: Int): Double? = Double.POSITIVE_INFINITY
|
|
||||||
|
|
||||||
public override fun nearestInDomain(point: Point<Double>): Point<Double> = point
|
|
||||||
|
|
||||||
public override fun volume(): Double = Double.POSITIVE_INFINITY
|
public override fun volume(): Double = Double.POSITIVE_INFINITY
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package space.kscience.kmath.domains
|
package space.kscience.kmath.domains
|
||||||
|
|
||||||
import space.kscience.kmath.linear.Point
|
import space.kscience.kmath.linear.Point
|
||||||
import space.kscience.kmath.structures.asBuffer
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
|
|
||||||
|
@UnstableKMathAPI
|
||||||
public inline class UnivariateDomain(public val range: ClosedFloatingPointRange<Double>) : RealDomain {
|
public inline class UnivariateDomain(public val range: ClosedFloatingPointRange<Double>) : RealDomain {
|
||||||
public override val dimension: Int
|
public override val dimension: Int get() = 1
|
||||||
get() = 1
|
|
||||||
|
|
||||||
public operator fun contains(d: Double): Boolean = range.contains(d)
|
public operator fun contains(d: Double): Boolean = range.contains(d)
|
||||||
|
|
||||||
@ -14,33 +14,12 @@ public inline class UnivariateDomain(public val range: ClosedFloatingPointRange<
|
|||||||
return contains(point[0])
|
return contains(point[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun nearestInDomain(point: Point<Double>): Point<Double> {
|
public override fun getLowerBound(num: Int): Double {
|
||||||
require(point.size == 1)
|
|
||||||
val value = point[0]
|
|
||||||
|
|
||||||
return when {
|
|
||||||
value in range -> point
|
|
||||||
value >= range.endInclusive -> doubleArrayOf(range.endInclusive).asBuffer()
|
|
||||||
else -> doubleArrayOf(range.start).asBuffer()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun getLowerBound(num: Int, point: Point<Double>): Double? {
|
|
||||||
require(num == 0)
|
require(num == 0)
|
||||||
return range.start
|
return range.start
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun getUpperBound(num: Int, point: Point<Double>): Double? {
|
public override fun getUpperBound(num: Int): Double {
|
||||||
require(num == 0)
|
|
||||||
return range.endInclusive
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun getLowerBound(num: Int): Double? {
|
|
||||||
require(num == 0)
|
|
||||||
return range.start
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun getUpperBound(num: Int): Double? {
|
|
||||||
require(num == 0)
|
require(num == 0)
|
||||||
return range.endInclusive
|
return range.endInclusive
|
||||||
}
|
}
|
||||||
|
@ -41,25 +41,28 @@ public abstract class FunctionalExpressionAlgebra<T, A : Algebra<T>>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A context class for [Expression] construction for [Space] algebras.
|
* A context class for [Expression] construction for [Group] algebras.
|
||||||
*/
|
*/
|
||||||
public open class FunctionalExpressionSpace<T, A : Space<T>>(
|
public open class FunctionalExpressionGroup<T, A : Group<T>>(
|
||||||
algebra: A,
|
algebra: A,
|
||||||
) : FunctionalExpressionAlgebra<T, A>(algebra), Space<Expression<T>> {
|
) : FunctionalExpressionAlgebra<T, A>(algebra), Group<Expression<T>> {
|
||||||
public override val zero: Expression<T> get() = const(algebra.zero)
|
public override val zero: Expression<T> get() = const(algebra.zero)
|
||||||
|
|
||||||
|
override fun Expression<T>.unaryMinus(): Expression<T> =
|
||||||
|
unaryOperation(GroupOperations.MINUS_OPERATION, this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds an Expression of addition of two another expressions.
|
* Builds an Expression of addition of two another expressions.
|
||||||
*/
|
*/
|
||||||
public override fun add(a: Expression<T>, b: Expression<T>): Expression<T> =
|
public override fun add(a: Expression<T>, b: Expression<T>): Expression<T> =
|
||||||
binaryOperationFunction(SpaceOperations.PLUS_OPERATION)(a, b)
|
binaryOperation(GroupOperations.PLUS_OPERATION, a, b)
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Builds an Expression of multiplication of expression by number.
|
// * Builds an Expression of multiplication of expression by number.
|
||||||
*/
|
// */
|
||||||
public override fun multiply(a: Expression<T>, k: Number): Expression<T> = Expression { arguments ->
|
// public override fun multiply(a: Expression<T>, k: Number): Expression<T> = Expression { arguments ->
|
||||||
algebra.multiply(a.invoke(arguments), k)
|
// algebra.multiply(a.invoke(arguments), k)
|
||||||
}
|
// }
|
||||||
|
|
||||||
public operator fun Expression<T>.plus(arg: T): Expression<T> = this + const(arg)
|
public operator fun Expression<T>.plus(arg: T): Expression<T> = this + const(arg)
|
||||||
public operator fun Expression<T>.minus(arg: T): Expression<T> = this - const(arg)
|
public operator fun Expression<T>.minus(arg: T): Expression<T> = this - const(arg)
|
||||||
@ -71,13 +74,13 @@ public open class FunctionalExpressionSpace<T, A : Space<T>>(
|
|||||||
|
|
||||||
public override fun binaryOperationFunction(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> =
|
public override fun binaryOperationFunction(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> =
|
||||||
super<FunctionalExpressionAlgebra>.binaryOperationFunction(operation)
|
super<FunctionalExpressionAlgebra>.binaryOperationFunction(operation)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public open class FunctionalExpressionRing<T, A : Ring<T>>(
|
public open class FunctionalExpressionRing<T, A : Ring<T>>(
|
||||||
algebra: A,
|
algebra: A,
|
||||||
) : FunctionalExpressionSpace<T, A>(algebra), Ring<Expression<T>> {
|
) : FunctionalExpressionGroup<T, A>(algebra), Ring<Expression<T>> {
|
||||||
public override val one: Expression<T>
|
public override val one: Expression<T> get() = const(algebra.one)
|
||||||
get() = const(algebra.one)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds an Expression of multiplication of two expressions.
|
* Builds an Expression of multiplication of two expressions.
|
||||||
@ -89,15 +92,16 @@ public open class FunctionalExpressionRing<T, A : Ring<T>>(
|
|||||||
public operator fun T.times(arg: Expression<T>): Expression<T> = arg * this
|
public operator fun T.times(arg: Expression<T>): Expression<T> = arg * this
|
||||||
|
|
||||||
public override fun unaryOperationFunction(operation: String): (arg: Expression<T>) -> Expression<T> =
|
public override fun unaryOperationFunction(operation: String): (arg: Expression<T>) -> Expression<T> =
|
||||||
super<FunctionalExpressionSpace>.unaryOperationFunction(operation)
|
super<FunctionalExpressionGroup>.unaryOperationFunction(operation)
|
||||||
|
|
||||||
public override fun binaryOperationFunction(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> =
|
public override fun binaryOperationFunction(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> =
|
||||||
super<FunctionalExpressionSpace>.binaryOperationFunction(operation)
|
super<FunctionalExpressionGroup>.binaryOperationFunction(operation)
|
||||||
}
|
}
|
||||||
|
|
||||||
public open class FunctionalExpressionField<T, A : Field<T>>(
|
public open class FunctionalExpressionField<T, A: Field<T>>(
|
||||||
algebra: A,
|
algebra: A,
|
||||||
) : FunctionalExpressionRing<T, A>(algebra), Field<Expression<T>> {
|
) : FunctionalExpressionRing<T, A>(algebra), Field<Expression<T>>,
|
||||||
|
ScaleOperations<Expression<T>> {
|
||||||
/**
|
/**
|
||||||
* Builds an Expression of division an expression by another one.
|
* Builds an Expression of division an expression by another one.
|
||||||
*/
|
*/
|
||||||
@ -112,6 +116,10 @@ public open class FunctionalExpressionField<T, A : Field<T>>(
|
|||||||
|
|
||||||
public override fun binaryOperationFunction(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> =
|
public override fun binaryOperationFunction(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> =
|
||||||
super<FunctionalExpressionRing>.binaryOperationFunction(operation)
|
super<FunctionalExpressionRing>.binaryOperationFunction(operation)
|
||||||
|
|
||||||
|
override fun scale(a: Expression<T>, value: Double): Expression<T> = algebra {
|
||||||
|
Expression { args -> a(args) * value }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public open class FunctionalExpressionExtendedField<T, A : ExtendedField<T>>(
|
public open class FunctionalExpressionExtendedField<T, A : ExtendedField<T>>(
|
||||||
@ -151,8 +159,8 @@ public open class FunctionalExpressionExtendedField<T, A : ExtendedField<T>>(
|
|||||||
super<FunctionalExpressionField>.binaryOperationFunction(operation)
|
super<FunctionalExpressionField>.binaryOperationFunction(operation)
|
||||||
}
|
}
|
||||||
|
|
||||||
public inline fun <T, A : Space<T>> A.expressionInSpace(block: FunctionalExpressionSpace<T, A>.() -> Expression<T>): Expression<T> =
|
public inline fun <T, A : Group<T>> A.expressionInSpace(block: FunctionalExpressionGroup<T, A>.() -> Expression<T>): Expression<T> =
|
||||||
FunctionalExpressionSpace(this).block()
|
FunctionalExpressionGroup(this).block()
|
||||||
|
|
||||||
public inline fun <T, A : Ring<T>> A.expressionInRing(block: FunctionalExpressionRing<T, A>.() -> Expression<T>): Expression<T> =
|
public inline fun <T, A : Ring<T>> A.expressionInRing(block: FunctionalExpressionRing<T, A>.() -> Expression<T>): Expression<T> =
|
||||||
FunctionalExpressionRing(this).block()
|
FunctionalExpressionRing(this).block()
|
||||||
@ -160,5 +168,6 @@ public inline fun <T, A : Ring<T>> A.expressionInRing(block: FunctionalExpressio
|
|||||||
public inline fun <T, A : Field<T>> A.expressionInField(block: FunctionalExpressionField<T, A>.() -> Expression<T>): Expression<T> =
|
public inline fun <T, A : Field<T>> A.expressionInField(block: FunctionalExpressionField<T, A>.() -> Expression<T>): Expression<T> =
|
||||||
FunctionalExpressionField(this).block()
|
FunctionalExpressionField(this).block()
|
||||||
|
|
||||||
public inline fun <T, A : ExtendedField<T>> A.expressionInExtendedField(block: FunctionalExpressionExtendedField<T, A>.() -> Expression<T>): Expression<T> =
|
public inline fun <T, A : ExtendedField<T>> A.expressionInExtendedField(
|
||||||
FunctionalExpressionExtendedField(this).block()
|
block: FunctionalExpressionExtendedField<T, A>.() -> Expression<T>,
|
||||||
|
): Expression<T> = FunctionalExpressionExtendedField(this).block()
|
||||||
|
@ -47,36 +47,6 @@ public fun <T : Any> DerivationResult<T>.grad(vararg variables: Symbol): Point<T
|
|||||||
return variables.map(::derivative).asBuffer()
|
return variables.map(::derivative).asBuffer()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs differentiation and establishes [SimpleAutoDiffField] context inside the block of code.
|
|
||||||
*
|
|
||||||
* The partial derivatives are placed in argument `d` variable
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* assertEquals(17.0, y.x) // the value of result (y)
|
|
||||||
* assertEquals(9.0, x.d) // dy/dx
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @param body the action in [SimpleAutoDiffField] context returning [AutoDiffVariable] to differentiate with respect to.
|
|
||||||
* @return the result of differentiation.
|
|
||||||
*/
|
|
||||||
public fun <T : Any, F : Field<T>> F.simpleAutoDiff(
|
|
||||||
bindings: Map<Symbol, T>,
|
|
||||||
body: SimpleAutoDiffField<T, F>.() -> AutoDiffValue<T>,
|
|
||||||
): DerivationResult<T> {
|
|
||||||
contract { callsInPlace(body, InvocationKind.EXACTLY_ONCE) }
|
|
||||||
|
|
||||||
return SimpleAutoDiffField(this, bindings).differentiate(body)
|
|
||||||
}
|
|
||||||
|
|
||||||
public fun <T : Any, F : Field<T>> F.simpleAutoDiff(
|
|
||||||
vararg bindings: Pair<Symbol, T>,
|
|
||||||
body: SimpleAutoDiffField<T, F>.() -> AutoDiffValue<T>,
|
|
||||||
): DerivationResult<T> = simpleAutoDiff(bindings.toMap(), body)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents field in context of which functions can be derived.
|
* Represents field in context of which functions can be derived.
|
||||||
*/
|
*/
|
||||||
@ -84,12 +54,9 @@ public fun <T : Any, F : Field<T>> F.simpleAutoDiff(
|
|||||||
public open class SimpleAutoDiffField<T : Any, F : Field<T>>(
|
public open class SimpleAutoDiffField<T : Any, F : Field<T>>(
|
||||||
public val context: F,
|
public val context: F,
|
||||||
bindings: Map<Symbol, T>,
|
bindings: Map<Symbol, T>,
|
||||||
) : Field<AutoDiffValue<T>>, ExpressionAlgebra<T, AutoDiffValue<T>>, RingWithNumbers<AutoDiffValue<T>> {
|
) : Field<AutoDiffValue<T>>, ExpressionAlgebra<T, AutoDiffValue<T>>, NumbersAddOperations<AutoDiffValue<T>> {
|
||||||
public override val zero: AutoDiffValue<T>
|
public override val zero: AutoDiffValue<T> get() = const(context.zero)
|
||||||
get() = const(context.zero)
|
public override val one: AutoDiffValue<T> get() = const(context.one)
|
||||||
|
|
||||||
public override val one: AutoDiffValue<T>
|
|
||||||
get() = const(context.one)
|
|
||||||
|
|
||||||
// this stack contains pairs of blocks and values to apply them to
|
// this stack contains pairs of blocks and values to apply them to
|
||||||
private var stack: Array<Any?> = arrayOfNulls<Any?>(8)
|
private var stack: Array<Any?> = arrayOfNulls<Any?>(8)
|
||||||
@ -137,6 +104,8 @@ public open class SimpleAutoDiffField<T : Any, F : Field<T>>(
|
|||||||
|
|
||||||
override fun const(value: T): AutoDiffValue<T> = AutoDiffValue(value)
|
override fun const(value: T): AutoDiffValue<T> = AutoDiffValue(value)
|
||||||
|
|
||||||
|
override fun number(value: Number): AutoDiffValue<T> = const { one * value }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A variable accessing inner state of derivatives.
|
* A variable accessing inner state of derivatives.
|
||||||
* Use this value in inner builders to avoid creating additional derivative bindings.
|
* Use this value in inner builders to avoid creating additional derivative bindings.
|
||||||
@ -175,21 +144,24 @@ public open class SimpleAutoDiffField<T : Any, F : Field<T>>(
|
|||||||
return DerivationResult(result.value, bindings.mapValues { it.value.d }, context)
|
return DerivationResult(result.value, bindings.mapValues { it.value.d }, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overloads for Double constants
|
// // Overloads for Double constants
|
||||||
|
//
|
||||||
|
// public override operator fun Number.plus(b: AutoDiffValue<T>): AutoDiffValue<T> =
|
||||||
|
// derive(const { this@plus.toDouble() * one + b.value }) { z ->
|
||||||
|
// b.d += z.d
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public override operator fun AutoDiffValue<T>.plus(b: Number): AutoDiffValue<T> = b.plus(this)
|
||||||
|
//
|
||||||
|
// public override operator fun Number.minus(b: AutoDiffValue<T>): AutoDiffValue<T> =
|
||||||
|
// derive(const { this@minus.toDouble() * one - b.value }) { z -> b.d -= z.d }
|
||||||
|
//
|
||||||
|
// public override operator fun AutoDiffValue<T>.minus(b: Number): AutoDiffValue<T> =
|
||||||
|
// derive(const { this@minus.value - one * b.toDouble() }) { z -> d += z.d }
|
||||||
|
|
||||||
public override operator fun Number.plus(b: AutoDiffValue<T>): AutoDiffValue<T> =
|
|
||||||
derive(const { this@plus.toDouble() * one + b.value }) { z ->
|
|
||||||
b.d += z.d
|
|
||||||
}
|
|
||||||
|
|
||||||
public override operator fun AutoDiffValue<T>.plus(b: Number): AutoDiffValue<T> = b.plus(this)
|
|
||||||
|
|
||||||
public override operator fun Number.minus(b: AutoDiffValue<T>): AutoDiffValue<T> =
|
|
||||||
derive(const { this@minus.toDouble() * one - b.value }) { z -> b.d -= z.d }
|
|
||||||
|
|
||||||
public override operator fun AutoDiffValue<T>.minus(b: Number): AutoDiffValue<T> =
|
|
||||||
derive(const { this@minus.value - one * b.toDouble() }) { z -> this@minus.d += z.d }
|
|
||||||
|
|
||||||
|
override fun AutoDiffValue<T>.unaryMinus(): AutoDiffValue<T> =
|
||||||
|
derive(const { -value }) { z -> d -= z.d }
|
||||||
|
|
||||||
// Basic math (+, -, *, /)
|
// Basic math (+, -, *, /)
|
||||||
|
|
||||||
@ -211,12 +183,44 @@ public open class SimpleAutoDiffField<T : Any, F : Field<T>>(
|
|||||||
b.d -= z.d * a.value / (b.value * b.value)
|
b.d -= z.d * a.value / (b.value * b.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun multiply(a: AutoDiffValue<T>, k: Number): AutoDiffValue<T> =
|
public override fun scale(a: AutoDiffValue<T>, value: Double): AutoDiffValue<T> =
|
||||||
derive(const { k.toDouble() * a.value }) { z ->
|
derive(const { value * a.value }) { z ->
|
||||||
a.d += z.d * k.toDouble()
|
a.d += z.d * value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs differentiation and establishes [SimpleAutoDiffField] context inside the block of code.
|
||||||
|
*
|
||||||
|
* The partial derivatives are placed in argument `d` variable
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* assertEquals(17.0, y.x) // the value of result (y)
|
||||||
|
* assertEquals(9.0, x.d) // dy/dx
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param body the action in [SimpleAutoDiffField] context returning [AutoDiffVariable] to differentiate with respect to.
|
||||||
|
* @return the result of differentiation.
|
||||||
|
*/
|
||||||
|
public fun <T : Any, F : Field<T>> F.simpleAutoDiff(
|
||||||
|
bindings: Map<Symbol, T>,
|
||||||
|
body: SimpleAutoDiffField<T, F>.() -> AutoDiffValue<T>,
|
||||||
|
): DerivationResult<T> {
|
||||||
|
contract { callsInPlace(body, InvocationKind.EXACTLY_ONCE) }
|
||||||
|
|
||||||
|
return SimpleAutoDiffField(this, bindings).differentiate(body)
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun <T : Any, F : Field<T>> F.simpleAutoDiff(
|
||||||
|
vararg bindings: Pair<Symbol, T>,
|
||||||
|
body: SimpleAutoDiffField<T, F>.() -> AutoDiffValue<T>,
|
||||||
|
): DerivationResult<T> = simpleAutoDiff(bindings.toMap(), body)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A constructs that creates a derivative structure with required order on-demand
|
* A constructs that creates a derivative structure with required order on-demand
|
||||||
*/
|
*/
|
||||||
@ -247,19 +251,20 @@ public fun <T : Any, F : Field<T>> simpleAutoDiff(field: F): AutoDiffProcessor<T
|
|||||||
// Extensions for differentiation of various basic mathematical functions
|
// Extensions for differentiation of various basic mathematical functions
|
||||||
|
|
||||||
// x ^ 2
|
// x ^ 2
|
||||||
public fun <T : Any, F : Field<T>> SimpleAutoDiffField<T, F>.sqr(x: AutoDiffValue<T>): AutoDiffValue<T> =
|
public fun <T : Any, F : ExtendedField<T>> SimpleAutoDiffField<T, F>.sqr(x: AutoDiffValue<T>): AutoDiffValue<T> =
|
||||||
derive(const { x.value * x.value }) { z -> x.d += z.d * 2 * x.value }
|
derive(const { x.value * x.value }) { z -> x.d += z.d * 2.0 * x.value }
|
||||||
|
|
||||||
// x ^ 1/2
|
// x ^ 1/2
|
||||||
public fun <T : Any, F : ExtendedField<T>> SimpleAutoDiffField<T, F>.sqrt(x: AutoDiffValue<T>): AutoDiffValue<T> =
|
public fun <T : Any, F : ExtendedField<T>> SimpleAutoDiffField<T, F>.sqrt(x: AutoDiffValue<T>): AutoDiffValue<T> =
|
||||||
derive(const { sqrt(x.value) }) { z -> x.d += z.d * 0.5 / z.value }
|
derive(const { sqrt(x.value) }) { z -> x.d += z.d / 2.0 / z.value }
|
||||||
|
|
||||||
// x ^ y (const)
|
// x ^ y (const)
|
||||||
public fun <T : Any, F : ExtendedField<T>> SimpleAutoDiffField<T, F>.pow(
|
public fun <T : Any, F : ExtendedField<T>> SimpleAutoDiffField<T, F>.pow(
|
||||||
x: AutoDiffValue<T>,
|
x: AutoDiffValue<T>,
|
||||||
y: Double,
|
y: Double,
|
||||||
): AutoDiffValue<T> =
|
): AutoDiffValue<T> = derive(const { power(x.value, y) }) { z ->
|
||||||
derive(const { power(x.value, y) }) { z -> x.d += z.d * y * power(x.value, y - 1) }
|
x.d += z.d * y * power(x.value, y - 1)
|
||||||
|
}
|
||||||
|
|
||||||
public fun <T : Any, F : ExtendedField<T>> SimpleAutoDiffField<T, F>.pow(
|
public fun <T : Any, F : ExtendedField<T>> SimpleAutoDiffField<T, F>.pow(
|
||||||
x: AutoDiffValue<T>,
|
x: AutoDiffValue<T>,
|
||||||
@ -328,7 +333,13 @@ public fun <T : Any, F : ExtendedField<T>> SimpleAutoDiffField<T, F>.atanh(x: Au
|
|||||||
public class SimpleAutoDiffExtendedField<T : Any, F : ExtendedField<T>>(
|
public class SimpleAutoDiffExtendedField<T : Any, F : ExtendedField<T>>(
|
||||||
context: F,
|
context: F,
|
||||||
bindings: Map<Symbol, T>,
|
bindings: Map<Symbol, T>,
|
||||||
) : ExtendedField<AutoDiffValue<T>>, SimpleAutoDiffField<T, F>(context, bindings) {
|
) : ExtendedField<AutoDiffValue<T>>, ScaleOperations<AutoDiffValue<T>>,
|
||||||
|
SimpleAutoDiffField<T, F>(context, bindings) {
|
||||||
|
|
||||||
|
override fun number(value: Number): AutoDiffValue<T> = const { number(value) }
|
||||||
|
|
||||||
|
override fun scale(a: AutoDiffValue<T>, value: Double): AutoDiffValue<T> = a * number(value)
|
||||||
|
|
||||||
// x ^ 2
|
// x ^ 2
|
||||||
public fun sqr(x: AutoDiffValue<T>): AutoDiffValue<T> =
|
public fun sqr(x: AutoDiffValue<T>): AutoDiffValue<T> =
|
||||||
(this as SimpleAutoDiffField<T, F>).sqr(x)
|
(this as SimpleAutoDiffField<T, F>).sqr(x)
|
||||||
|
@ -2,18 +2,18 @@ package space.kscience.kmath.expressions
|
|||||||
|
|
||||||
import space.kscience.kmath.operations.ExtendedField
|
import space.kscience.kmath.operations.ExtendedField
|
||||||
import space.kscience.kmath.operations.Field
|
import space.kscience.kmath.operations.Field
|
||||||
|
import space.kscience.kmath.operations.Group
|
||||||
import space.kscience.kmath.operations.Ring
|
import space.kscience.kmath.operations.Ring
|
||||||
import space.kscience.kmath.operations.Space
|
|
||||||
import kotlin.contracts.InvocationKind
|
import kotlin.contracts.InvocationKind
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a functional expression with this [Space].
|
* Creates a functional expression with this [Group].
|
||||||
*/
|
*/
|
||||||
public inline fun <T> Space<T>.spaceExpression(block: FunctionalExpressionSpace<T, Space<T>>.() -> Expression<T>): Expression<T> {
|
public inline fun <T> Group<T>.spaceExpression(block: FunctionalExpressionGroup<T, Group<T>>.() -> Expression<T>): Expression<T> {
|
||||||
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
||||||
return FunctionalExpressionSpace(this).block()
|
return FunctionalExpressionGroup(this).block()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3,6 +3,7 @@ package space.kscience.kmath.linear
|
|||||||
import space.kscience.kmath.nd.NDStructure
|
import space.kscience.kmath.nd.NDStructure
|
||||||
import space.kscience.kmath.nd.Structure2D
|
import space.kscience.kmath.nd.Structure2D
|
||||||
import space.kscience.kmath.operations.Ring
|
import space.kscience.kmath.operations.Ring
|
||||||
|
import space.kscience.kmath.operations.ScaleOperations
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
import space.kscience.kmath.structures.BufferFactory
|
import space.kscience.kmath.structures.BufferFactory
|
||||||
@ -18,15 +19,22 @@ public typealias Matrix<T> = Structure2D<T>
|
|||||||
/**
|
/**
|
||||||
* Basic implementation of Matrix space based on [NDStructure]
|
* Basic implementation of Matrix space based on [NDStructure]
|
||||||
*/
|
*/
|
||||||
public class BufferMatrixContext<T : Any, R : Ring<T>>(
|
public class BufferMatrixContext<T : Any, A>(
|
||||||
public override val elementContext: R,
|
public override val elementContext: A,
|
||||||
private val bufferFactory: BufferFactory<T>,
|
private val bufferFactory: BufferFactory<T>,
|
||||||
) : GenericMatrixContext<T, R, BufferMatrix<T>> {
|
) : GenericMatrixContext<T, A, BufferMatrix<T>> where A : Ring<T>, A : ScaleOperations<T> {
|
||||||
|
|
||||||
public override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> T): BufferMatrix<T> {
|
public override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> T): BufferMatrix<T> {
|
||||||
val buffer = bufferFactory(rows * columns) { offset -> initializer(offset / columns, offset % columns) }
|
val buffer = bufferFactory(rows * columns) { offset -> initializer(offset / columns, offset % columns) }
|
||||||
return BufferMatrix(rows, columns, buffer)
|
return BufferMatrix(rows, columns, buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun scale(a: Matrix<T>, value: Double): Matrix<T> = elementContext {
|
||||||
|
produce(a.rowNum, a.colNum) { i, j ->
|
||||||
|
a[i, j] * value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override fun point(size: Int, initializer: (Int) -> T): Point<T> = bufferFactory(size, initializer)
|
public override fun point(size: Int, initializer: (Int) -> T): Point<T> = bufferFactory(size, initializer)
|
||||||
|
|
||||||
private fun Matrix<T>.toBufferMatrix(): BufferMatrix<T> = if (this is BufferMatrix) this else {
|
private fun Matrix<T>.toBufferMatrix(): BufferMatrix<T> = if (this is BufferMatrix) this else {
|
||||||
@ -78,12 +86,12 @@ public class BufferMatrixContext<T : Any, R : Ring<T>>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun multiply(a: Matrix<T>, k: Number): BufferMatrix<T> {
|
// override fun multiply(a: Matrix<T>, k: Number): BufferMatrix<T> {
|
||||||
val aBufferMatrix = a.toBufferMatrix()
|
// val aBufferMatrix = a.toBufferMatrix()
|
||||||
return elementContext {
|
// return elementContext {
|
||||||
produce(a.rowNum, a.colNum) { i, j -> aBufferMatrix[i, j] * k.toDouble() }
|
// produce(a.rowNum, a.colNum) { i, j -> aBufferMatrix[i, j] * k.toDouble() }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
public companion object
|
public companion object
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
package space.kscience.kmath.linear
|
package space.kscience.kmath.linear
|
||||||
|
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.operations.Ring
|
import space.kscience.kmath.operations.*
|
||||||
import space.kscience.kmath.operations.SpaceOperations
|
|
||||||
import space.kscience.kmath.operations.invoke
|
|
||||||
import space.kscience.kmath.operations.sum
|
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
import space.kscience.kmath.structures.BufferFactory
|
import space.kscience.kmath.structures.BufferFactory
|
||||||
import space.kscience.kmath.structures.asSequence
|
import space.kscience.kmath.structures.asSequence
|
||||||
@ -16,7 +13,7 @@ import kotlin.reflect.KClass
|
|||||||
* @param T the type of items in the matrices.
|
* @param T the type of items in the matrices.
|
||||||
* @param M the type of operated matrices.
|
* @param M the type of operated matrices.
|
||||||
*/
|
*/
|
||||||
public interface MatrixContext<T : Any, out M : Matrix<T>> : SpaceOperations<Matrix<T>> {
|
public interface MatrixContext<T : Any, out M : Matrix<T>> : GroupOperations<Matrix<T>>, ScaleOperations<Matrix<T>> {
|
||||||
/**
|
/**
|
||||||
* Produces a matrix with this context and given dimensions.
|
* Produces a matrix with this context and given dimensions.
|
||||||
*/
|
*/
|
||||||
@ -31,7 +28,7 @@ public interface MatrixContext<T : Any, out M : Matrix<T>> : SpaceOperations<Mat
|
|||||||
public override fun binaryOperationFunction(operation: String): (left: Matrix<T>, right: Matrix<T>) -> M =
|
public override fun binaryOperationFunction(operation: String): (left: Matrix<T>, right: Matrix<T>) -> M =
|
||||||
when (operation) {
|
when (operation) {
|
||||||
"dot" -> { left, right -> left dot right }
|
"dot" -> { left, right -> left dot right }
|
||||||
else -> super.binaryOperationFunction(operation) as (Matrix<T>, Matrix<T>) -> M
|
else -> super<GroupOperations>.binaryOperationFunction(operation) as (Matrix<T>, Matrix<T>) -> M
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -87,15 +84,15 @@ public interface MatrixContext<T : Any, out M : Matrix<T>> : SpaceOperations<Mat
|
|||||||
/**
|
/**
|
||||||
* A structured matrix with custom buffer
|
* A structured matrix with custom buffer
|
||||||
*/
|
*/
|
||||||
public fun <T : Any, R : Ring<T>> buffered(
|
public fun <T : Any, A> buffered(
|
||||||
ring: R,
|
ring: A,
|
||||||
bufferFactory: BufferFactory<T> = Buffer.Companion::boxing,
|
bufferFactory: BufferFactory<T> = Buffer.Companion::boxing,
|
||||||
): GenericMatrixContext<T, R, BufferMatrix<T>> = BufferMatrixContext(ring, bufferFactory)
|
): GenericMatrixContext<T, A, BufferMatrix<T>> where A : Ring<T>, A: ScaleOperations<T> = BufferMatrixContext(ring, bufferFactory)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatic buffered matrix, unboxed if it is possible
|
* Automatic buffered matrix, unboxed if it is possible
|
||||||
*/
|
*/
|
||||||
public inline fun <reified T : Any, R : Ring<T>> auto(ring: R): GenericMatrixContext<T, R, BufferMatrix<T>> =
|
public inline fun <reified T : Any, A> auto(ring: A): GenericMatrixContext<T, A, BufferMatrix<T>> where A : Ring<T>, A: ScaleOperations<T> =
|
||||||
buffered(ring, Buffer.Companion::auto)
|
buffered(ring, Buffer.Companion::auto)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,14 +116,14 @@ public inline fun <T : Any, reified F : Any> MatrixContext<T, *>.getFeature(m: M
|
|||||||
* Partial implementation of [MatrixContext] for matrices of [Ring].
|
* Partial implementation of [MatrixContext] for matrices of [Ring].
|
||||||
*
|
*
|
||||||
* @param T the type of items in the matrices.
|
* @param T the type of items in the matrices.
|
||||||
* @param R the type of ring of matrix elements.
|
* @param A the type of ring of matrix elements.
|
||||||
* @param M the type of operated matrices.
|
* @param M the type of operated matrices.
|
||||||
*/
|
*/
|
||||||
public interface GenericMatrixContext<T : Any, R : Ring<T>, out M : Matrix<T>> : MatrixContext<T, M> {
|
public interface GenericMatrixContext<T : Any, A, out M : Matrix<T>> : MatrixContext<T, M> where A : Ring<T>, A : ScaleOperations<T>{
|
||||||
/**
|
/**
|
||||||
* The ring over matrix elements.
|
* The ring over matrix elements.
|
||||||
*/
|
*/
|
||||||
public val elementContext: R
|
public val elementContext: A
|
||||||
|
|
||||||
public override infix fun Matrix<T>.dot(other: Matrix<T>): M {
|
public override infix fun Matrix<T>.dot(other: Matrix<T>): M {
|
||||||
//TODO add typed error
|
//TODO add typed error
|
||||||
@ -167,9 +164,9 @@ public interface GenericMatrixContext<T : Any, R : Ring<T>, out M : Matrix<T>> :
|
|||||||
|
|
||||||
return produce(rowNum, colNum) { i, j -> elementContext { get(i, j) + b[i, j] } }
|
return produce(rowNum, colNum) { i, j -> elementContext { get(i, j) + b[i, j] } }
|
||||||
}
|
}
|
||||||
|
//
|
||||||
public override fun multiply(a: Matrix<T>, k: Number): M =
|
// public override fun multiply(a: Matrix<T>, k: Number): M =
|
||||||
produce(a.rowNum, a.colNum) { i, j -> elementContext { a[i, j] * k } }
|
// produce(a.rowNum, a.colNum) { i, j -> elementContext { a[i, j] * k } }
|
||||||
|
|
||||||
public override operator fun Matrix<T>.times(value: T): M =
|
public override operator fun Matrix<T>.times(value: T): M =
|
||||||
produce(rowNum, colNum) { i, j -> elementContext { get(i, j) * value } }
|
produce(rowNum, colNum) { i, j -> elementContext { get(i, j) * value } }
|
||||||
|
@ -4,6 +4,7 @@ import space.kscience.kmath.misc.UnstableKMathAPI
|
|||||||
import space.kscience.kmath.nd.Structure2D
|
import space.kscience.kmath.nd.Structure2D
|
||||||
import space.kscience.kmath.nd.getFeature
|
import space.kscience.kmath.nd.getFeature
|
||||||
import space.kscience.kmath.operations.Ring
|
import space.kscience.kmath.operations.Ring
|
||||||
|
import space.kscience.kmath.operations.ScaleOperations
|
||||||
import space.kscience.kmath.structures.asBuffer
|
import space.kscience.kmath.structures.asBuffer
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
@ -14,7 +15,7 @@ import kotlin.reflect.safeCast
|
|||||||
*
|
*
|
||||||
* @param T the type of items.
|
* @param T the type of items.
|
||||||
*/
|
*/
|
||||||
public class MatrixWrapper<T : Any> internal constructor(
|
public class MatrixWrapper<T : Any> internal constructor(
|
||||||
public val origin: Matrix<T>,
|
public val origin: Matrix<T>,
|
||||||
public val features: Set<MatrixFeature>,
|
public val features: Set<MatrixFeature>,
|
||||||
) : Matrix<T> by origin {
|
) : Matrix<T> by origin {
|
||||||
@ -73,17 +74,23 @@ public fun <T : Any> Structure2D.Companion.square(vararg elements: T): Matrix<T>
|
|||||||
/**
|
/**
|
||||||
* Diagonal matrix of ones. The matrix is virtual no actual matrix is created
|
* Diagonal matrix of ones. The matrix is virtual no actual matrix is created
|
||||||
*/
|
*/
|
||||||
public fun <T : Any, R : Ring<T>> GenericMatrixContext<T, R, *>.one(rows: Int, columns: Int): Matrix<T> =
|
public fun <T : Any, A> GenericMatrixContext<T, A, *>.one(
|
||||||
VirtualMatrix(rows, columns) { i, j ->
|
rows: Int,
|
||||||
if (i == j) elementContext.one else elementContext.zero
|
columns: Int,
|
||||||
} + UnitFeature
|
): Matrix<T> where A : Ring<T>, A : ScaleOperations<T> = VirtualMatrix(rows, columns) { i, j ->
|
||||||
|
if (i == j) elementContext.one else elementContext.zero
|
||||||
|
} + UnitFeature
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A virtual matrix of zeroes
|
* A virtual matrix of zeroes
|
||||||
*/
|
*/
|
||||||
public fun <T : Any, R : Ring<T>> GenericMatrixContext<T, R, *>.zero(rows: Int, columns: Int): Matrix<T> =
|
public fun <T : Any, A> GenericMatrixContext<T, A, *>.zero(
|
||||||
VirtualMatrix(rows, columns) { _, _ -> elementContext.zero } + ZeroFeature
|
rows: Int,
|
||||||
|
columns: Int,
|
||||||
|
): Matrix<T> where A : Ring<T>, A : ScaleOperations<T> = VirtualMatrix(rows, columns) { _, _ ->
|
||||||
|
elementContext.zero
|
||||||
|
} + ZeroFeature
|
||||||
|
|
||||||
public class TransposedFeature<T : Any>(public val original: Matrix<T>) : MatrixFeature
|
public class TransposedFeature<T : Any>(public val original: Matrix<T>) : MatrixFeature
|
||||||
|
|
||||||
@ -91,9 +98,7 @@ public class TransposedFeature<T : Any>(public val original: Matrix<T>) : Matrix
|
|||||||
* Create a virtual transposed matrix without copying anything. `A.transpose().transpose() === A`
|
* Create a virtual transposed matrix without copying anything. `A.transpose().transpose() === A`
|
||||||
*/
|
*/
|
||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
public fun <T : Any> Matrix<T>.transpose(): Matrix<T> {
|
public fun <T : Any> Matrix<T>.transpose(): Matrix<T> = getFeature<TransposedFeature<T>>()?.original ?: VirtualMatrix(
|
||||||
return getFeature<TransposedFeature<T>>()?.original ?: VirtualMatrix(
|
colNum,
|
||||||
colNum,
|
rowNum,
|
||||||
rowNum,
|
) { i, j -> get(j, i) } + TransposedFeature(this)
|
||||||
) { i, j -> get(j, i) } + TransposedFeature(this)
|
|
||||||
}
|
|
@ -1,8 +1,9 @@
|
|||||||
package space.kscience.kmath.linear
|
package space.kscience.kmath.linear
|
||||||
|
|
||||||
|
import space.kscience.kmath.operations.ScaleOperations
|
||||||
import space.kscience.kmath.structures.RealBuffer
|
import space.kscience.kmath.structures.RealBuffer
|
||||||
|
|
||||||
public object RealMatrixContext : MatrixContext<Double, BufferMatrix<Double>> {
|
public object RealMatrixContext : MatrixContext<Double, BufferMatrix<Double>>, ScaleOperations<Matrix<Double>> {
|
||||||
|
|
||||||
public override fun produce(
|
public override fun produce(
|
||||||
rows: Int,
|
rows: Int,
|
||||||
@ -21,6 +22,8 @@ public object RealMatrixContext : MatrixContext<Double, BufferMatrix<Double>> {
|
|||||||
if (i == j) 1.0 else 0.0
|
if (i == j) 1.0 else 0.0
|
||||||
} + DiagonalFeature
|
} + DiagonalFeature
|
||||||
|
|
||||||
|
override fun Matrix<Double>.unaryMinus(): Matrix<Double> = produce(rowNum, colNum) { i, j -> -get(i, j) }
|
||||||
|
|
||||||
public override infix fun Matrix<Double>.dot(other: Matrix<Double>): BufferMatrix<Double> {
|
public override infix fun Matrix<Double>.dot(other: Matrix<Double>): BufferMatrix<Double> {
|
||||||
require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" }
|
require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" }
|
||||||
val bufferMatrix = toBufferMatrix()
|
val bufferMatrix = toBufferMatrix()
|
||||||
@ -56,16 +59,23 @@ public object RealMatrixContext : MatrixContext<Double, BufferMatrix<Double>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Matrix<Double>.times(value: Double): BufferMatrix<Double> {
|
override fun scale(a: Matrix<Double>, value: Double): BufferMatrix<Double> {
|
||||||
val bufferMatrix = toBufferMatrix()
|
val bufferMatrix = a.toBufferMatrix()
|
||||||
return produce(rowNum, colNum) { i, j -> bufferMatrix[i, j] * value }
|
return produce(a.rowNum, a.colNum) { i, j -> bufferMatrix[i, j] * value }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun Matrix<Double>.times(value: Double): BufferMatrix<Double> = scale(this, value)
|
||||||
|
|
||||||
override fun multiply(a: Matrix<Double>, k: Number): BufferMatrix<Double> {
|
//
|
||||||
val aBufferMatrix = a.toBufferMatrix()
|
// override fun multiply(a: Matrix<Double>, k: Number): BufferMatrix<Double> {
|
||||||
return produce(a.rowNum, a.colNum) { i, j -> aBufferMatrix[i, j] * k.toDouble() }
|
// val aBufferMatrix = a.toBufferMatrix()
|
||||||
}
|
// return produce(a.rowNum, a.colNum) { i, j -> aBufferMatrix[i, j] * k.toDouble() }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// override fun divide(a: Matrix<Double>, k: Number): BufferMatrix<Double> {
|
||||||
|
// val aBufferMatrix = a.toBufferMatrix()
|
||||||
|
// return produce(a.rowNum, a.colNum) { i, j -> aBufferMatrix[i, j] / k.toDouble() }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
package space.kscience.kmath.linear
|
package space.kscience.kmath.linear
|
||||||
|
|
||||||
|
import space.kscience.kmath.operations.Group
|
||||||
import space.kscience.kmath.operations.RealField
|
import space.kscience.kmath.operations.RealField
|
||||||
import space.kscience.kmath.operations.Space
|
import space.kscience.kmath.operations.ScaleOperations
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
import space.kscience.kmath.structures.BufferFactory
|
import space.kscience.kmath.structures.BufferFactory
|
||||||
@ -10,21 +11,19 @@ import space.kscience.kmath.structures.BufferFactory
|
|||||||
* A linear space for vectors.
|
* A linear space for vectors.
|
||||||
* Could be used on any point-like structure
|
* Could be used on any point-like structure
|
||||||
*/
|
*/
|
||||||
public interface VectorSpace<T : Any, S : Space<T>> : Space<Point<T>> {
|
public interface VectorSpace<T : Any, A> : Group<Point<T>>, ScaleOperations<Point<T>>
|
||||||
|
where A : Group<T>, A : ScaleOperations<T> {
|
||||||
public val size: Int
|
public val size: Int
|
||||||
public val space: S
|
public val algebra: A
|
||||||
override val zero: Point<T> get() = produce { space.zero }
|
override val zero: Point<T> get() = produce { algebra.zero }
|
||||||
|
|
||||||
public fun produce(initializer: S.(Int) -> T): Point<T>
|
public fun produce(initializer: A.(Int) -> T): Point<T>
|
||||||
|
|
||||||
/**
|
override fun add(a: Point<T>, b: Point<T>): Point<T> = produce { algebra { a[it] + b[it] } }
|
||||||
* Produce a space-element of this vector space for expressions
|
|
||||||
*/
|
|
||||||
//fun produceElement(initializer: (Int) -> T): Vector<T, S>
|
|
||||||
|
|
||||||
override fun add(a: Point<T>, b: Point<T>): Point<T> = produce { space { a[it] + b[it] } }
|
override fun scale(a: Point<T>, value: Double): Point<T> = produce { algebra.scale(a[it], value) }
|
||||||
|
|
||||||
override fun multiply(a: Point<T>, k: Number): Point<T> = produce { space { a[it] * k } }
|
override fun Point<T>.unaryMinus(): Point<T> = produce { -get(it) }
|
||||||
|
|
||||||
//TODO add basis
|
//TODO add basis
|
||||||
|
|
||||||
@ -45,26 +44,29 @@ public interface VectorSpace<T : Any, S : Space<T>> : Space<Point<T>> {
|
|||||||
/**
|
/**
|
||||||
* A structured vector space with custom buffer
|
* A structured vector space with custom buffer
|
||||||
*/
|
*/
|
||||||
public fun <T : Any, S : Space<T>> buffered(
|
public fun <T : Any, A> buffered(
|
||||||
size: Int,
|
size: Int,
|
||||||
space: S,
|
space: A,
|
||||||
bufferFactory: BufferFactory<T> = Buffer.Companion::boxing,
|
bufferFactory: BufferFactory<T> = Buffer.Companion::boxing,
|
||||||
): BufferVectorSpace<T, S> = BufferVectorSpace(size, space, bufferFactory)
|
): BufferVectorSpace<T, A> where A : Group<T>, A : ScaleOperations<T> =
|
||||||
|
BufferVectorSpace(size, space, bufferFactory)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatic buffered vector, unboxed if it is possible
|
* Automatic buffered vector, unboxed if it is possible
|
||||||
*/
|
*/
|
||||||
public inline fun <reified T : Any, S : Space<T>> auto(size: Int, space: S): VectorSpace<T, S> =
|
public inline fun <reified T : Any, A> auto(
|
||||||
|
size: Int,
|
||||||
|
space: A,
|
||||||
|
): VectorSpace<T, A> where A : Group<T>, A : ScaleOperations<T> =
|
||||||
buffered(size, space, Buffer.Companion::auto)
|
buffered(size, space, Buffer.Companion::auto)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class BufferVectorSpace<T : Any, S : Space<T>>(
|
public class BufferVectorSpace<T : Any, A>(
|
||||||
override val size: Int,
|
override val size: Int,
|
||||||
override val space: S,
|
override val algebra: A,
|
||||||
public val bufferFactory: BufferFactory<T>,
|
public val bufferFactory: BufferFactory<T>,
|
||||||
) : VectorSpace<T, S> {
|
) : VectorSpace<T, A> where A : Group<T>, A : ScaleOperations<T> {
|
||||||
override fun produce(initializer: S.(Int) -> T): Buffer<T> = bufferFactory(size) { space.initializer(it) }
|
override fun produce(initializer: A.(Int) -> T): Buffer<T> = bufferFactory(size) { algebra.initializer(it) }
|
||||||
//override fun produceElement(initializer: (Int) -> T): Vector<T, S> = BufferVector(this, produce(initializer))
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package space.kscience.kmath.misc
|
package space.kscience.kmath.misc
|
||||||
|
|
||||||
import space.kscience.kmath.operations.Space
|
import space.kscience.kmath.operations.Group
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
import kotlin.jvm.JvmName
|
import kotlin.jvm.JvmName
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ public fun <T, R> List<T>.cumulative(initial: R, operation: (R, T) -> R): List<R
|
|||||||
/**
|
/**
|
||||||
* Cumulative sum with custom space
|
* Cumulative sum with custom space
|
||||||
*/
|
*/
|
||||||
public fun <T> Iterable<T>.cumulativeSum(space: Space<T>): Iterable<T> =
|
public fun <T> Iterable<T>.cumulativeSum(space: Group<T>): Iterable<T> =
|
||||||
space { cumulative(zero) { element: T, sum: T -> sum + element } }
|
space { cumulative(zero) { element: T, sum: T -> sum + element } }
|
||||||
|
|
||||||
@JvmName("cumulativeSumOfDouble")
|
@JvmName("cumulativeSumOfDouble")
|
||||||
@ -49,7 +49,7 @@ public fun Iterable<Int>.cumulativeSum(): Iterable<Int> = cumulative(0) { elemen
|
|||||||
@JvmName("cumulativeSumOfLong")
|
@JvmName("cumulativeSumOfLong")
|
||||||
public fun Iterable<Long>.cumulativeSum(): Iterable<Long> = cumulative(0L) { element, sum -> sum + element }
|
public fun Iterable<Long>.cumulativeSum(): Iterable<Long> = cumulative(0L) { element, sum -> sum + element }
|
||||||
|
|
||||||
public fun <T> Sequence<T>.cumulativeSum(space: Space<T>): Sequence<T> =
|
public fun <T> Sequence<T>.cumulativeSum(space: Group<T>): Sequence<T> =
|
||||||
space { cumulative(zero) { element: T, sum: T -> sum + element } }
|
space { cumulative(zero) { element: T, sum: T -> sum + element } }
|
||||||
|
|
||||||
@JvmName("cumulativeSumOfDouble")
|
@JvmName("cumulativeSumOfDouble")
|
||||||
@ -61,7 +61,7 @@ public fun Sequence<Int>.cumulativeSum(): Sequence<Int> = cumulative(0) { elemen
|
|||||||
@JvmName("cumulativeSumOfLong")
|
@JvmName("cumulativeSumOfLong")
|
||||||
public fun Sequence<Long>.cumulativeSum(): Sequence<Long> = cumulative(0L) { element, sum -> sum + element }
|
public fun Sequence<Long>.cumulativeSum(): Sequence<Long> = cumulative(0L) { element, sum -> sum + element }
|
||||||
|
|
||||||
public fun <T> List<T>.cumulativeSum(space: Space<T>): List<T> =
|
public fun <T> List<T>.cumulativeSum(space: Group<T>): List<T> =
|
||||||
space { cumulative(zero) { element: T, sum: T -> sum + element } }
|
space { cumulative(zero) { element: T, sum: T -> sum + element } }
|
||||||
|
|
||||||
@JvmName("cumulativeSumOfDouble")
|
@JvmName("cumulativeSumOfDouble")
|
||||||
|
@ -1,19 +1,16 @@
|
|||||||
package space.kscience.kmath.nd
|
package space.kscience.kmath.nd
|
||||||
|
|
||||||
import space.kscience.kmath.operations.Field
|
import space.kscience.kmath.operations.*
|
||||||
import space.kscience.kmath.operations.RealField
|
|
||||||
import space.kscience.kmath.operations.Ring
|
|
||||||
import space.kscience.kmath.operations.Space
|
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
import space.kscience.kmath.structures.BufferFactory
|
import space.kscience.kmath.structures.BufferFactory
|
||||||
import kotlin.contracts.InvocationKind
|
import kotlin.contracts.InvocationKind
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
|
|
||||||
public interface BufferNDAlgebra<T, C> : NDAlgebra<T, C> {
|
public interface BufferNDAlgebra<T, A : Algebra<T>> : NDAlgebra<T, A> {
|
||||||
public val strides: Strides
|
public val strides: Strides
|
||||||
public val bufferFactory: BufferFactory<T>
|
public val bufferFactory: BufferFactory<T>
|
||||||
|
|
||||||
override fun produce(initializer: C.(IntArray) -> T): NDBuffer<T> = NDBuffer(
|
override fun produce(initializer: A.(IntArray) -> T): NDBuffer<T> = NDBuffer(
|
||||||
strides,
|
strides,
|
||||||
bufferFactory(strides.linearSize) { offset ->
|
bufferFactory(strides.linearSize) { offset ->
|
||||||
elementContext.initializer(strides.index(offset))
|
elementContext.initializer(strides.index(offset))
|
||||||
@ -30,14 +27,14 @@ public interface BufferNDAlgebra<T, C> : NDAlgebra<T, C> {
|
|||||||
else -> bufferFactory(strides.linearSize) { offset -> get(strides.index(offset)) }
|
else -> bufferFactory(strides.linearSize) { offset -> get(strides.index(offset)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun NDStructure<T>.map(transform: C.(T) -> T): NDBuffer<T> {
|
override fun NDStructure<T>.map(transform: A.(T) -> T): NDBuffer<T> {
|
||||||
val buffer = bufferFactory(strides.linearSize) { offset ->
|
val buffer = bufferFactory(strides.linearSize) { offset ->
|
||||||
elementContext.transform(buffer[offset])
|
elementContext.transform(buffer[offset])
|
||||||
}
|
}
|
||||||
return NDBuffer(strides, buffer)
|
return NDBuffer(strides, buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun NDStructure<T>.mapIndexed(transform: C.(index: IntArray, T) -> T): NDBuffer<T> {
|
override fun NDStructure<T>.mapIndexed(transform: A.(index: IntArray, T) -> T): NDBuffer<T> {
|
||||||
val buffer = bufferFactory(strides.linearSize) { offset ->
|
val buffer = bufferFactory(strides.linearSize) { offset ->
|
||||||
elementContext.transform(
|
elementContext.transform(
|
||||||
strides.index(offset),
|
strides.index(offset),
|
||||||
@ -47,7 +44,7 @@ public interface BufferNDAlgebra<T, C> : NDAlgebra<T, C> {
|
|||||||
return NDBuffer(strides, buffer)
|
return NDBuffer(strides, buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun combine(a: NDStructure<T>, b: NDStructure<T>, transform: C.(T, T) -> T): NDBuffer<T> {
|
override fun combine(a: NDStructure<T>, b: NDStructure<T>, transform: A.(T, T) -> T): NDBuffer<T> {
|
||||||
val buffer = bufferFactory(strides.linearSize) { offset ->
|
val buffer = bufferFactory(strides.linearSize) { offset ->
|
||||||
elementContext.transform(a.buffer[offset], b.buffer[offset])
|
elementContext.transform(a.buffer[offset], b.buffer[offset])
|
||||||
}
|
}
|
||||||
@ -55,20 +52,21 @@ public interface BufferNDAlgebra<T, C> : NDAlgebra<T, C> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public open class BufferedNDSpace<T, R : Space<T>>(
|
public open class BufferedNDGroup<T, A : Group<T>>(
|
||||||
final override val shape: IntArray,
|
final override val shape: IntArray,
|
||||||
final override val elementContext: R,
|
final override val elementContext: A,
|
||||||
final override val bufferFactory: BufferFactory<T>,
|
final override val bufferFactory: BufferFactory<T>,
|
||||||
) : NDSpace<T, R>, BufferNDAlgebra<T, R> {
|
) : NDGroup<T, A>, BufferNDAlgebra<T, A> {
|
||||||
override val strides: Strides = DefaultStrides(shape)
|
override val strides: Strides = DefaultStrides(shape)
|
||||||
override val zero: NDBuffer<T> by lazy { produce { zero } }
|
override val zero: NDBuffer<T> by lazy { produce { zero } }
|
||||||
|
override fun NDStructure<T>.unaryMinus(): NDStructure<T> = produce { -get(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
public open class BufferedNDRing<T, R : Ring<T>>(
|
public open class BufferedNDRing<T, R : Ring<T>>(
|
||||||
shape: IntArray,
|
shape: IntArray,
|
||||||
elementContext: R,
|
elementContext: R,
|
||||||
bufferFactory: BufferFactory<T>,
|
bufferFactory: BufferFactory<T>,
|
||||||
) : BufferedNDSpace<T, R>(shape, elementContext, bufferFactory), NDRing<T, R> {
|
) : BufferedNDGroup<T, R>(shape, elementContext, bufferFactory), NDRing<T, R> {
|
||||||
override val one: NDBuffer<T> by lazy { produce { one } }
|
override val one: NDBuffer<T> by lazy { produce { one } }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,19 +74,22 @@ public open class BufferedNDField<T, R : Field<T>>(
|
|||||||
shape: IntArray,
|
shape: IntArray,
|
||||||
elementContext: R,
|
elementContext: R,
|
||||||
bufferFactory: BufferFactory<T>,
|
bufferFactory: BufferFactory<T>,
|
||||||
) : BufferedNDRing<T, R>(shape, elementContext, bufferFactory), NDField<T, R>
|
) : BufferedNDRing<T, R>(shape, elementContext, bufferFactory), NDField<T, R> {
|
||||||
|
|
||||||
|
override fun scale(a: NDStructure<T>, value: Double): NDStructure<T> = a.map { it * value }
|
||||||
|
}
|
||||||
|
|
||||||
// space factories
|
// space factories
|
||||||
public fun <T, A : Space<T>> NDAlgebra.Companion.space(
|
public fun <T, A : Group<T>> NDAlgebra.Companion.space(
|
||||||
space: A,
|
space: A,
|
||||||
bufferFactory: BufferFactory<T>,
|
bufferFactory: BufferFactory<T>,
|
||||||
vararg shape: Int,
|
vararg shape: Int,
|
||||||
): BufferedNDSpace<T, A> = BufferedNDSpace(shape, space, bufferFactory)
|
): BufferedNDGroup<T, A> = BufferedNDGroup(shape, space, bufferFactory)
|
||||||
|
|
||||||
public inline fun <T, A : Space<T>, R> A.ndSpace(
|
public inline fun <T, A : Group<T>, R> A.ndSpace(
|
||||||
noinline bufferFactory: BufferFactory<T>,
|
noinline bufferFactory: BufferFactory<T>,
|
||||||
vararg shape: Int,
|
vararg shape: Int,
|
||||||
action: BufferedNDSpace<T, A>.() -> R,
|
action: BufferedNDGroup<T, A>.() -> R,
|
||||||
): R {
|
): R {
|
||||||
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
|
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
|
||||||
return NDAlgebra.space(this, bufferFactory, *shape).run(action)
|
return NDAlgebra.space(this, bufferFactory, *shape).run(action)
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package space.kscience.kmath.nd
|
package space.kscience.kmath.nd
|
||||||
|
|
||||||
import space.kscience.kmath.operations.Field
|
import space.kscience.kmath.operations.*
|
||||||
import space.kscience.kmath.operations.Ring
|
|
||||||
import space.kscience.kmath.operations.Space
|
|
||||||
import space.kscience.kmath.structures.*
|
import space.kscience.kmath.structures.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,7 +19,7 @@ public class ShapeMismatchException(public val expected: IntArray, public val ac
|
|||||||
* @param C the type of the element context.
|
* @param C the type of the element context.
|
||||||
* @param N the type of the structure.
|
* @param N the type of the structure.
|
||||||
*/
|
*/
|
||||||
public interface NDAlgebra<T, C> {
|
public interface NDAlgebra<T, C: Algebra<T>> {
|
||||||
/**
|
/**
|
||||||
* The shape of ND-structures this algebra operates on.
|
* The shape of ND-structures this algebra operates on.
|
||||||
*/
|
*/
|
||||||
@ -33,7 +31,7 @@ public interface NDAlgebra<T, C> {
|
|||||||
public val elementContext: C
|
public val elementContext: C
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Produces a new [N] structure using given initializer function.
|
* Produces a new NDStructure using given initializer function.
|
||||||
*/
|
*/
|
||||||
public fun produce(initializer: C.(IntArray) -> T): NDStructure<T>
|
public fun produce(initializer: C.(IntArray) -> T): NDStructure<T>
|
||||||
|
|
||||||
@ -56,7 +54,7 @@ public interface NDAlgebra<T, C> {
|
|||||||
* Element-wise invocation of function working on [T] on a [NDStructure].
|
* Element-wise invocation of function working on [T] on a [NDStructure].
|
||||||
*/
|
*/
|
||||||
public operator fun Function1<T, T>.invoke(structure: NDStructure<T>): NDStructure<T> =
|
public operator fun Function1<T, T>.invoke(structure: NDStructure<T>): NDStructure<T> =
|
||||||
structure.map() { value -> this@invoke(value) }
|
structure.map { value -> this@invoke(value) }
|
||||||
|
|
||||||
public companion object
|
public companion object
|
||||||
}
|
}
|
||||||
@ -67,7 +65,7 @@ public interface NDAlgebra<T, C> {
|
|||||||
* @param structures the structures to check.
|
* @param structures the structures to check.
|
||||||
* @return the array of valid structures.
|
* @return the array of valid structures.
|
||||||
*/
|
*/
|
||||||
internal fun <T, C> NDAlgebra<T, C>.checkShape(vararg structures: NDStructure<T>): Array<out NDStructure<T>> = structures
|
internal fun <T, C: Algebra<T>> NDAlgebra<T, C>.checkShape(vararg structures: NDStructure<T>): Array<out NDStructure<T>> = structures
|
||||||
.map(NDStructure<T>::shape)
|
.map(NDStructure<T>::shape)
|
||||||
.singleOrNull { !shape.contentEquals(it) }
|
.singleOrNull { !shape.contentEquals(it) }
|
||||||
?.let<IntArray, Array<out NDStructure<T>>> { throw ShapeMismatchException(shape, it) }
|
?.let<IntArray, Array<out NDStructure<T>>> { throw ShapeMismatchException(shape, it) }
|
||||||
@ -79,7 +77,7 @@ internal fun <T, C> NDAlgebra<T, C>.checkShape(vararg structures: NDStructure<T>
|
|||||||
* @param element the structure to check.
|
* @param element the structure to check.
|
||||||
* @return the valid structure.
|
* @return the valid structure.
|
||||||
*/
|
*/
|
||||||
internal fun <T, C> NDAlgebra<T, C>.checkShape(element: NDStructure<T>): NDStructure<T> {
|
internal fun <T, C: Algebra<T>> NDAlgebra<T, C>.checkShape(element: NDStructure<T>): NDStructure<T> {
|
||||||
if (!element.shape.contentEquals(shape)) throw ShapeMismatchException(shape, element.shape)
|
if (!element.shape.contentEquals(shape)) throw ShapeMismatchException(shape, element.shape)
|
||||||
return element
|
return element
|
||||||
}
|
}
|
||||||
@ -91,7 +89,7 @@ internal fun <T, C> NDAlgebra<T, C>.checkShape(element: NDStructure<T>): NDStruc
|
|||||||
* @param N the type of ND structure.
|
* @param N the type of ND structure.
|
||||||
* @param S the type of space of structure elements.
|
* @param S the type of space of structure elements.
|
||||||
*/
|
*/
|
||||||
public interface NDSpace<T, S : Space<T>> : Space<NDStructure<T>>, NDAlgebra<T, S> {
|
public interface NDGroup<T, S : Group<T>> : Group<NDStructure<T>>, NDAlgebra<T, S> {
|
||||||
/**
|
/**
|
||||||
* Element-wise addition.
|
* Element-wise addition.
|
||||||
*
|
*
|
||||||
@ -102,14 +100,14 @@ public interface NDSpace<T, S : Space<T>> : Space<NDStructure<T>>, NDAlgebra<T,
|
|||||||
public override fun add(a: NDStructure<T>, b: NDStructure<T>): NDStructure<T> =
|
public override fun add(a: NDStructure<T>, b: NDStructure<T>): NDStructure<T> =
|
||||||
combine(a, b) { aValue, bValue -> add(aValue, bValue) }
|
combine(a, b) { aValue, bValue -> add(aValue, bValue) }
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Element-wise multiplication by scalar.
|
// * Element-wise multiplication by scalar.
|
||||||
*
|
// *
|
||||||
* @param a the multiplicand.
|
// * @param a the multiplicand.
|
||||||
* @param k the multiplier.
|
// * @param k the multiplier.
|
||||||
* @return the product.
|
// * @return the product.
|
||||||
*/
|
// */
|
||||||
public override fun multiply(a: NDStructure<T>, k: Number): NDStructure<T> = a.map() { multiply(it, k) }
|
// public override fun multiply(a: NDStructure<T>, k: Number): NDStructure<T> = a.map { multiply(it, k) }
|
||||||
|
|
||||||
// TODO move to extensions after KEEP-176
|
// TODO move to extensions after KEEP-176
|
||||||
|
|
||||||
@ -120,7 +118,7 @@ public interface NDSpace<T, S : Space<T>> : Space<NDStructure<T>>, NDAlgebra<T,
|
|||||||
* @param arg the augend.
|
* @param arg the augend.
|
||||||
* @return the sum.
|
* @return the sum.
|
||||||
*/
|
*/
|
||||||
public operator fun NDStructure<T>.plus(arg: T): NDStructure<T> = this.map() { value -> add(arg, value) }
|
public operator fun NDStructure<T>.plus(arg: T): NDStructure<T> = this.map { value -> add(arg, value) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subtracts an element from ND structure of it.
|
* Subtracts an element from ND structure of it.
|
||||||
@ -129,7 +127,7 @@ public interface NDSpace<T, S : Space<T>> : Space<NDStructure<T>>, NDAlgebra<T,
|
|||||||
* @param arg the divisor.
|
* @param arg the divisor.
|
||||||
* @return the quotient.
|
* @return the quotient.
|
||||||
*/
|
*/
|
||||||
public operator fun NDStructure<T>.minus(arg: T): NDStructure<T> = this.map() { value -> add(arg, -value) }
|
public operator fun NDStructure<T>.minus(arg: T): NDStructure<T> = this.map { value -> add(arg, -value) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an element to ND structure of it.
|
* Adds an element to ND structure of it.
|
||||||
@ -138,7 +136,7 @@ public interface NDSpace<T, S : Space<T>> : Space<NDStructure<T>>, NDAlgebra<T,
|
|||||||
* @param arg the augend.
|
* @param arg the augend.
|
||||||
* @return the sum.
|
* @return the sum.
|
||||||
*/
|
*/
|
||||||
public operator fun T.plus(arg: NDStructure<T>): NDStructure<T> = arg.map() { value -> add(this@plus, value) }
|
public operator fun T.plus(arg: NDStructure<T>): NDStructure<T> = arg.map { value -> add(this@plus, value) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subtracts an ND structure from an element of it.
|
* Subtracts an ND structure from an element of it.
|
||||||
@ -147,7 +145,7 @@ public interface NDSpace<T, S : Space<T>> : Space<NDStructure<T>>, NDAlgebra<T,
|
|||||||
* @param arg the divisor.
|
* @param arg the divisor.
|
||||||
* @return the quotient.
|
* @return the quotient.
|
||||||
*/
|
*/
|
||||||
public operator fun T.minus(arg: NDStructure<T>): NDStructure<T> = arg.map() { value -> add(-this@minus, value) }
|
public operator fun T.minus(arg: NDStructure<T>): NDStructure<T> = arg.map { value -> add(-this@minus, value) }
|
||||||
|
|
||||||
public companion object
|
public companion object
|
||||||
}
|
}
|
||||||
@ -159,7 +157,7 @@ public interface NDSpace<T, S : Space<T>> : Space<NDStructure<T>>, NDAlgebra<T,
|
|||||||
* @param N the type of ND structure.
|
* @param N the type of ND structure.
|
||||||
* @param R the type of ring of structure elements.
|
* @param R the type of ring of structure elements.
|
||||||
*/
|
*/
|
||||||
public interface NDRing<T, R : Ring<T>> : Ring<NDStructure<T>>, NDSpace<T, R> {
|
public interface NDRing<T, R : Ring<T>> : Ring<NDStructure<T>>, NDGroup<T, R> {
|
||||||
/**
|
/**
|
||||||
* Element-wise multiplication.
|
* Element-wise multiplication.
|
||||||
*
|
*
|
||||||
@ -179,7 +177,7 @@ public interface NDRing<T, R : Ring<T>> : Ring<NDStructure<T>>, NDSpace<T, R> {
|
|||||||
* @param arg the multiplier.
|
* @param arg the multiplier.
|
||||||
* @return the product.
|
* @return the product.
|
||||||
*/
|
*/
|
||||||
public operator fun NDStructure<T>.times(arg: T): NDStructure<T> = this.map() { value -> multiply(arg, value) }
|
public operator fun NDStructure<T>.times(arg: T): NDStructure<T> = this.map { value -> multiply(arg, value) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Multiplies an element by a ND structure of it.
|
* Multiplies an element by a ND structure of it.
|
||||||
@ -188,7 +186,7 @@ public interface NDRing<T, R : Ring<T>> : Ring<NDStructure<T>>, NDSpace<T, R> {
|
|||||||
* @param arg the multiplier.
|
* @param arg the multiplier.
|
||||||
* @return the product.
|
* @return the product.
|
||||||
*/
|
*/
|
||||||
public operator fun T.times(arg: NDStructure<T>): NDStructure<T> = arg.map() { value -> multiply(this@times, value) }
|
public operator fun T.times(arg: NDStructure<T>): NDStructure<T> = arg.map { value -> multiply(this@times, value) }
|
||||||
|
|
||||||
public companion object
|
public companion object
|
||||||
}
|
}
|
||||||
@ -200,7 +198,7 @@ public interface NDRing<T, R : Ring<T>> : Ring<NDStructure<T>>, NDSpace<T, R> {
|
|||||||
* @param N the type of ND structure.
|
* @param N the type of ND structure.
|
||||||
* @param F the type field of structure elements.
|
* @param F the type field of structure elements.
|
||||||
*/
|
*/
|
||||||
public interface NDField<T, F : Field<T>> : Field<NDStructure<T>>, NDRing<T, F> {
|
public interface NDField<T, F : Field<T>> : Field<NDStructure<T>>, NDRing<T, F>, ScaleOperations<NDStructure<T>> {
|
||||||
/**
|
/**
|
||||||
* Element-wise division.
|
* Element-wise division.
|
||||||
*
|
*
|
||||||
@ -219,7 +217,7 @@ public interface NDField<T, F : Field<T>> : Field<NDStructure<T>>, NDRing<T, F>
|
|||||||
* @param arg the divisor.
|
* @param arg the divisor.
|
||||||
* @return the quotient.
|
* @return the quotient.
|
||||||
*/
|
*/
|
||||||
public operator fun NDStructure<T>.div(arg: T): NDStructure<T> = this.map() { value -> divide(arg, value) }
|
public operator fun NDStructure<T>.div(arg: T): NDStructure<T> = this.map { value -> divide(arg, value) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Divides an element by an ND structure of it.
|
* Divides an element by an ND structure of it.
|
||||||
@ -228,7 +226,7 @@ public interface NDField<T, F : Field<T>> : Field<NDStructure<T>>, NDRing<T, F>
|
|||||||
* @param arg the divisor.
|
* @param arg the divisor.
|
||||||
* @return the quotient.
|
* @return the quotient.
|
||||||
*/
|
*/
|
||||||
public operator fun T.div(arg: NDStructure<T>): NDStructure<T> = arg.map() { divide(it, this@div) }
|
public operator fun T.div(arg: NDStructure<T>): NDStructure<T> = arg.map { divide(it, this@div) }
|
||||||
|
|
||||||
// @ThreadLocal
|
// @ThreadLocal
|
||||||
// public companion object {
|
// public companion object {
|
||||||
|
@ -2,8 +2,9 @@ package space.kscience.kmath.nd
|
|||||||
|
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.operations.ExtendedField
|
import space.kscience.kmath.operations.ExtendedField
|
||||||
|
import space.kscience.kmath.operations.NumbersAddOperations
|
||||||
import space.kscience.kmath.operations.RealField
|
import space.kscience.kmath.operations.RealField
|
||||||
import space.kscience.kmath.operations.RingWithNumbers
|
import space.kscience.kmath.operations.ScaleOperations
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
import space.kscience.kmath.structures.RealBuffer
|
import space.kscience.kmath.structures.RealBuffer
|
||||||
import kotlin.contracts.InvocationKind
|
import kotlin.contracts.InvocationKind
|
||||||
@ -13,7 +14,8 @@ import kotlin.contracts.contract
|
|||||||
public class RealNDField(
|
public class RealNDField(
|
||||||
shape: IntArray,
|
shape: IntArray,
|
||||||
) : BufferedNDField<Double, RealField>(shape, RealField, Buffer.Companion::real),
|
) : BufferedNDField<Double, RealField>(shape, RealField, Buffer.Companion::real),
|
||||||
RingWithNumbers<NDStructure<Double>>,
|
NumbersAddOperations<NDStructure<Double>>,
|
||||||
|
ScaleOperations<NDStructure<Double>>,
|
||||||
ExtendedField<NDStructure<Double>> {
|
ExtendedField<NDStructure<Double>> {
|
||||||
|
|
||||||
override val zero: NDBuffer<Double> by lazy { produce { zero } }
|
override val zero: NDBuffer<Double> by lazy { produce { zero } }
|
||||||
@ -75,6 +77,8 @@ public class RealNDField(
|
|||||||
return NDBuffer(strides, buffer)
|
return NDBuffer(strides, buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun scale(a: NDStructure<Double>, value: Double): NDStructure<Double> = a.map { it * value }
|
||||||
|
|
||||||
override fun power(arg: NDStructure<Double>, pow: Number): NDBuffer<Double> = arg.map { power(it, pow) }
|
override fun power(arg: NDStructure<Double>, pow: Number): NDBuffer<Double> = arg.map { power(it, pow) }
|
||||||
|
|
||||||
override fun exp(arg: NDStructure<Double>): NDBuffer<Double> = arg.map { exp(it) }
|
override fun exp(arg: NDStructure<Double>): NDBuffer<Double> = arg.map { exp(it) }
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package space.kscience.kmath.nd
|
package space.kscience.kmath.nd
|
||||||
|
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.operations.RingWithNumbers
|
import space.kscience.kmath.operations.NumbersAddOperations
|
||||||
import space.kscience.kmath.operations.ShortRing
|
import space.kscience.kmath.operations.ShortRing
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
import space.kscience.kmath.structures.ShortBuffer
|
import space.kscience.kmath.structures.ShortBuffer
|
||||||
@ -12,7 +12,7 @@ import kotlin.contracts.contract
|
|||||||
public class ShortNDRing(
|
public class ShortNDRing(
|
||||||
shape: IntArray,
|
shape: IntArray,
|
||||||
) : BufferedNDRing<Short, ShortRing>(shape, ShortRing, Buffer.Companion::auto),
|
) : BufferedNDRing<Short, ShortRing>(shape, ShortRing, Buffer.Companion::auto),
|
||||||
RingWithNumbers<NDStructure<Short>> {
|
NumbersAddOperations<NDStructure<Short>> {
|
||||||
|
|
||||||
override val zero: NDBuffer<Short> by lazy { produce { zero } }
|
override val zero: NDBuffer<Short> by lazy { produce { zero } }
|
||||||
override val one: NDBuffer<Short> by lazy { produce { one } }
|
override val one: NDBuffer<Short> by lazy { produce { one } }
|
||||||
|
@ -87,10 +87,11 @@ public interface Algebra<T> {
|
|||||||
* @param right the second argument of operation.
|
* @param right the second argument of operation.
|
||||||
* @return a result of operation.
|
* @return a result of operation.
|
||||||
*/
|
*/
|
||||||
public fun binaryOperation(operation: String, left: T, right: T): T = binaryOperationFunction(operation)(left, right)
|
public fun binaryOperation(operation: String, left: T, right: T): T =
|
||||||
|
binaryOperationFunction(operation)(left, right)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun <T: Any> Algebra<T>.bindSymbol(symbol: Symbol): T = bindSymbol(symbol.identity)
|
public fun <T : Any> Algebra<T>.bindSymbol(symbol: Symbol): T = bindSymbol(symbol.identity)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call a block with an [Algebra] as receiver.
|
* Call a block with an [Algebra] as receiver.
|
||||||
@ -104,7 +105,7 @@ public inline operator fun <A : Algebra<*>, R> A.invoke(block: A.() -> R): R = r
|
|||||||
*
|
*
|
||||||
* @param T the type of element of this semispace.
|
* @param T the type of element of this semispace.
|
||||||
*/
|
*/
|
||||||
public interface SpaceOperations<T> : Algebra<T> {
|
public interface GroupOperations<T> : Algebra<T> {
|
||||||
/**
|
/**
|
||||||
* Addition of two elements.
|
* Addition of two elements.
|
||||||
*
|
*
|
||||||
@ -114,15 +115,6 @@ public interface SpaceOperations<T> : Algebra<T> {
|
|||||||
*/
|
*/
|
||||||
public fun add(a: T, b: T): T
|
public fun add(a: T, b: T): T
|
||||||
|
|
||||||
/**
|
|
||||||
* Multiplication of element by scalar.
|
|
||||||
*
|
|
||||||
* @param a the multiplier.
|
|
||||||
* @param k the multiplicand.
|
|
||||||
* @return the produce.
|
|
||||||
*/
|
|
||||||
public fun multiply(a: T, k: Number): T
|
|
||||||
|
|
||||||
// Operations to be performed in this context. Could be moved to extensions in case of KEEP-176
|
// Operations to be performed in this context. Could be moved to extensions in case of KEEP-176
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -131,7 +123,7 @@ public interface SpaceOperations<T> : Algebra<T> {
|
|||||||
* @receiver this value.
|
* @receiver this value.
|
||||||
* @return the additive inverse of this value.
|
* @return the additive inverse of this value.
|
||||||
*/
|
*/
|
||||||
public operator fun T.unaryMinus(): T = multiply(this, -1.0)
|
public operator fun T.unaryMinus(): T
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns this value.
|
* Returns this value.
|
||||||
@ -159,34 +151,6 @@ public interface SpaceOperations<T> : Algebra<T> {
|
|||||||
*/
|
*/
|
||||||
public operator fun T.minus(b: T): T = add(this, -b)
|
public operator fun T.minus(b: T): T = add(this, -b)
|
||||||
|
|
||||||
/**
|
|
||||||
* Multiplication of this element by a scalar.
|
|
||||||
*
|
|
||||||
* @receiver the multiplier.
|
|
||||||
* @param k the multiplicand.
|
|
||||||
* @return the product.
|
|
||||||
*/
|
|
||||||
public operator fun T.times(k: Number): T = multiply(this, k)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Division of this element by scalar.
|
|
||||||
*
|
|
||||||
* @receiver the dividend.
|
|
||||||
* @param k the divisor.
|
|
||||||
* @return the quotient.
|
|
||||||
*/
|
|
||||||
@Deprecated("Dividing not allowed in a Ring")
|
|
||||||
public operator fun T.div(k: Number): T = multiply(this, 1.0 / k.toDouble())
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Multiplication of this number by element.
|
|
||||||
*
|
|
||||||
* @receiver the multiplier.
|
|
||||||
* @param b the multiplicand.
|
|
||||||
* @return the product.
|
|
||||||
*/
|
|
||||||
public operator fun Number.times(b: T): T = b * this
|
|
||||||
|
|
||||||
public override fun unaryOperationFunction(operation: String): (arg: T) -> T = when (operation) {
|
public override fun unaryOperationFunction(operation: String): (arg: T) -> T = when (operation) {
|
||||||
PLUS_OPERATION -> { arg -> +arg }
|
PLUS_OPERATION -> { arg -> +arg }
|
||||||
MINUS_OPERATION -> { arg -> -arg }
|
MINUS_OPERATION -> { arg -> -arg }
|
||||||
@ -213,12 +177,11 @@ public interface SpaceOperations<T> : Algebra<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents linear space with neutral element, i.e. algebraic structure with associative, binary operation [add] and
|
* Represents linear space with neutral element, i.e. algebraic structure with associative, binary operation [add].
|
||||||
* scalar multiplication [multiply].
|
|
||||||
*
|
*
|
||||||
* @param T the type of element of this semispace.
|
* @param T the type of element of this semispace.
|
||||||
*/
|
*/
|
||||||
public interface Space<T> : SpaceOperations<T> {
|
public interface Group<T> : GroupOperations<T> {
|
||||||
/**
|
/**
|
||||||
* The neutral element of addition.
|
* The neutral element of addition.
|
||||||
*/
|
*/
|
||||||
@ -231,7 +194,7 @@ public interface Space<T> : SpaceOperations<T> {
|
|||||||
*
|
*
|
||||||
* @param T the type of element of this semiring.
|
* @param T the type of element of this semiring.
|
||||||
*/
|
*/
|
||||||
public interface RingOperations<T> : SpaceOperations<T> {
|
public interface RingOperations<T> : GroupOperations<T> {
|
||||||
/**
|
/**
|
||||||
* Multiplies two elements.
|
* Multiplies two elements.
|
||||||
*
|
*
|
||||||
@ -267,7 +230,7 @@ public interface RingOperations<T> : SpaceOperations<T> {
|
|||||||
*
|
*
|
||||||
* @param T the type of element of this ring.
|
* @param T the type of element of this ring.
|
||||||
*/
|
*/
|
||||||
public interface Ring<T> : Space<T>, RingOperations<T> {
|
public interface Ring<T> : Group<T>, RingOperations<T> {
|
||||||
/**
|
/**
|
||||||
* neutral operation for multiplication
|
* neutral operation for multiplication
|
||||||
*/
|
*/
|
||||||
@ -318,13 +281,6 @@ public interface FieldOperations<T> : RingOperations<T> {
|
|||||||
*
|
*
|
||||||
* @param T the type of element of this semifield.
|
* @param T the type of element of this semifield.
|
||||||
*/
|
*/
|
||||||
public interface Field<T> : Ring<T>, FieldOperations<T> {
|
public interface Field<T> : Ring<T>, FieldOperations<T>, ScaleOperations<T>, NumericAlgebra<T> {
|
||||||
/**
|
override fun number(value: Number): T = scale(one, value.toDouble())
|
||||||
* Division of element by scalar.
|
}
|
||||||
*
|
|
||||||
* @receiver the dividend.
|
|
||||||
* @param b the divisor.
|
|
||||||
* @return the quotient.
|
|
||||||
*/
|
|
||||||
public operator fun Number.div(b: T): T = this * divide(one, b)
|
|
||||||
}
|
|
@ -14,24 +14,24 @@ public interface AlgebraElement<T, C : Algebra<T>> {
|
|||||||
*/
|
*/
|
||||||
public val context: C
|
public val context: C
|
||||||
}
|
}
|
||||||
|
//
|
||||||
/**
|
///**
|
||||||
* Divides this element by number.
|
// * Divides this element by number.
|
||||||
*
|
// *
|
||||||
* @param k the divisor.
|
// * @param k the divisor.
|
||||||
* @return the quotient.
|
// * @return the quotient.
|
||||||
*/
|
// */
|
||||||
public operator fun <T : AlgebraElement<T, S>, S : Space<T>> T.div(k: Number): T =
|
//public operator fun <T : AlgebraElement<T, S>, S : Space<T>> T.div(k: Number): T =
|
||||||
context.multiply(this, 1.0 / k.toDouble())
|
// context.multiply(this, 1.0 / k.toDouble())
|
||||||
|
//
|
||||||
/**
|
///**
|
||||||
* Multiplies this element by number.
|
// * Multiplies this element by number.
|
||||||
*
|
// *
|
||||||
* @param k the multiplicand.
|
// * @param k the multiplicand.
|
||||||
* @return the product.
|
// * @return the product.
|
||||||
*/
|
// */
|
||||||
public operator fun <T : AlgebraElement<T, S>, S : Space<T>> T.times(k: Number): T =
|
//public operator fun <T : AlgebraElement<T, S>, S : Space<T>> T.times(k: Number): T =
|
||||||
context.multiply(this, k.toDouble())
|
// context.multiply(this, k.toDouble())
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subtracts element from this one.
|
* Subtracts element from this one.
|
||||||
@ -39,8 +39,9 @@ public operator fun <T : AlgebraElement<T, S>, S : Space<T>> T.times(k: Number):
|
|||||||
* @param b the subtrahend.
|
* @param b the subtrahend.
|
||||||
* @return the difference.
|
* @return the difference.
|
||||||
*/
|
*/
|
||||||
public operator fun <T : AlgebraElement<T, S>, S : Space<T>> T.minus(b: T): T =
|
@UnstableKMathAPI
|
||||||
context.add(this, context.multiply(b, -1.0))
|
public operator fun <T : AlgebraElement<T, S>, S : NumbersAddOperations<T>> T.minus(b: T): T =
|
||||||
|
context.add(this, context.run { -b})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds element to this one.
|
* Adds element to this one.
|
||||||
@ -48,14 +49,14 @@ public operator fun <T : AlgebraElement<T, S>, S : Space<T>> T.minus(b: T): T =
|
|||||||
* @param b the augend.
|
* @param b the augend.
|
||||||
* @return the sum.
|
* @return the sum.
|
||||||
*/
|
*/
|
||||||
public operator fun <T : AlgebraElement<T, S>, S : Space<T>> T.plus(b: T): T =
|
public operator fun <T : AlgebraElement<T, S>, S : Group<T>> T.plus(b: T): T =
|
||||||
context.add(this, b)
|
context.add(this, b)
|
||||||
|
|
||||||
/**
|
///**
|
||||||
* Number times element
|
// * Number times element
|
||||||
*/
|
// */
|
||||||
public operator fun <T : AlgebraElement<T, S>, S : Space<T>> Number.times(element: T): T =
|
//public operator fun <T : AlgebraElement<T, S>, S : Space<T>> Number.times(element: T): T =
|
||||||
element.times(this)
|
// element.times(this)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -79,14 +80,14 @@ public operator fun <T : AlgebraElement<T, F>, F : Field<T>> T.div(b: T): T =
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The element of [Space].
|
* The element of [Group].
|
||||||
*
|
*
|
||||||
* @param T the type of space operation results.
|
* @param T the type of space operation results.
|
||||||
* @param I self type of the element. Needed for static type checking.
|
* @param I self type of the element. Needed for static type checking.
|
||||||
* @param S the type of space.
|
* @param S the type of space.
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public interface SpaceElement<T : SpaceElement<T, S>, S : Space<T>> : AlgebraElement<T, S>
|
public interface SpaceElement<T : SpaceElement<T, S>, S : Group<T>> : AlgebraElement<T, S>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The element of [Ring].
|
* The element of [Ring].
|
||||||
|
@ -21,29 +21,28 @@ public typealias TBase = ULong
|
|||||||
* @author Robert Drynkin (https://github.com/robdrynkin) and Peter Klimai (https://github.com/pklimai)
|
* @author Robert Drynkin (https://github.com/robdrynkin) and Peter Klimai (https://github.com/pklimai)
|
||||||
*/
|
*/
|
||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
public object BigIntField : Field<BigInt>, RingWithNumbers<BigInt> {
|
public object BigIntField : Field<BigInt>, NumbersAddOperations<BigInt>, ScaleOperations<BigInt> {
|
||||||
override val zero: BigInt = BigInt.ZERO
|
override val zero: BigInt = BigInt.ZERO
|
||||||
override val one: BigInt = BigInt.ONE
|
override val one: BigInt = BigInt.ONE
|
||||||
|
|
||||||
override fun add(a: BigInt, b: BigInt): BigInt = a.plus(b)
|
|
||||||
override fun number(value: Number): BigInt = value.toLong().toBigInt()
|
override fun number(value: Number): BigInt = value.toLong().toBigInt()
|
||||||
|
|
||||||
override fun multiply(a: BigInt, k: Number): BigInt = a.times(number(k))
|
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
||||||
|
override fun BigInt.unaryMinus(): BigInt = -this
|
||||||
|
override fun add(a: BigInt, b: BigInt): BigInt = a.plus(b)
|
||||||
|
override fun scale(a: BigInt, value: Double): BigInt = a.times(number(value))
|
||||||
override fun multiply(a: BigInt, b: BigInt): BigInt = a.times(b)
|
override fun multiply(a: BigInt, b: BigInt): BigInt = a.times(b)
|
||||||
|
override fun divide(a: BigInt, b: BigInt): BigInt = a.div(b)
|
||||||
|
|
||||||
public operator fun String.unaryPlus(): BigInt = this.parseBigInteger() ?: error("Can't parse $this as big integer")
|
public operator fun String.unaryPlus(): BigInt = this.parseBigInteger() ?: error("Can't parse $this as big integer")
|
||||||
|
|
||||||
public operator fun String.unaryMinus(): BigInt =
|
public operator fun String.unaryMinus(): BigInt =
|
||||||
-(this.parseBigInteger() ?: error("Can't parse $this as big integer"))
|
-(this.parseBigInteger() ?: error("Can't parse $this as big integer"))
|
||||||
|
|
||||||
override fun divide(a: BigInt, b: BigInt): BigInt = a.div(b)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BigInt internal constructor(
|
public class BigInt internal constructor(
|
||||||
private val sign: Byte,
|
private val sign: Byte,
|
||||||
private val magnitude: Magnitude
|
private val magnitude: Magnitude,
|
||||||
) : Comparable<BigInt> {
|
) : Comparable<BigInt> {
|
||||||
public override fun compareTo(other: BigInt): Int = when {
|
public override fun compareTo(other: BigInt): Int = when {
|
||||||
(sign == 0.toByte()) and (other.sign == 0.toByte()) -> 0
|
(sign == 0.toByte()) and (other.sign == 0.toByte()) -> 0
|
||||||
sign < other.sign -> -1
|
sign < other.sign -> -1
|
||||||
|
@ -81,14 +81,53 @@ public interface NumericAlgebra<T> : Algebra<T> {
|
|||||||
rightSideNumberOperationFunction(operation)(left, right)
|
rightSideNumberOperationFunction(operation)(left, right)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale by scalar operations
|
||||||
|
*/
|
||||||
|
public interface ScaleOperations<T> : Algebra<T> {
|
||||||
|
/**
|
||||||
|
* Scaling an element by a scalar.
|
||||||
|
*
|
||||||
|
* @param a the multiplier.
|
||||||
|
* @param value the multiplicand.
|
||||||
|
* @return the produce.
|
||||||
|
*/
|
||||||
|
public fun scale(a: T, value: Double): T
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiplication of this element by a scalar.
|
||||||
|
*
|
||||||
|
* @receiver the multiplier.
|
||||||
|
* @param k the multiplicand.
|
||||||
|
* @return the product.
|
||||||
|
*/
|
||||||
|
public operator fun T.times(k: Number): T = scale(this, k.toDouble())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Division of this element by scalar.
|
||||||
|
*
|
||||||
|
* @receiver the dividend.
|
||||||
|
* @param k the divisor.
|
||||||
|
* @return the quotient.
|
||||||
|
*/
|
||||||
|
public operator fun T.div(k: Number): T = scale(this, 1.0 / k.toDouble())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Multiplication of this number by element.
|
||||||
|
*
|
||||||
|
* @receiver the multiplier.
|
||||||
|
* @param b the multiplicand.
|
||||||
|
* @return the product.
|
||||||
|
*/
|
||||||
|
public operator fun Number.times(b: T): T = b * this
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A combination of [NumericAlgebra] and [Ring] that adds intrinsic simple operations on numbers like `T+1`
|
* A combination of [NumericAlgebra] and [Ring] that adds intrinsic simple operations on numbers like `T+1`
|
||||||
* TODO to be removed and replaced by extensions after multiple receivers are there
|
* TODO to be removed and replaced by extensions after multiple receivers are there
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public interface RingWithNumbers<T>: Ring<T>, NumericAlgebra<T>{
|
public interface NumbersAddOperations<T> : Group<T>, NumericAlgebra<T> {
|
||||||
public override fun number(value: Number): T = one * value
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Addition of element and scalar.
|
* Addition of element and scalar.
|
||||||
*
|
*
|
||||||
|
@ -107,111 +107,6 @@ public fun <T : AlgebraElement<T, out TrigonometricOperations<T>>> acos(arg: T):
|
|||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public fun <T : AlgebraElement<T, out TrigonometricOperations<T>>> atan(arg: T): T = arg.context.atan(arg)
|
public fun <T : AlgebraElement<T, out TrigonometricOperations<T>>> atan(arg: T): T = arg.context.atan(arg)
|
||||||
|
|
||||||
/**
|
|
||||||
* A container for hyperbolic trigonometric operations for specific type.
|
|
||||||
*
|
|
||||||
* @param T the type of element of this structure.
|
|
||||||
*/
|
|
||||||
public interface HyperbolicOperations<T> : Algebra<T> {
|
|
||||||
/**
|
|
||||||
* Computes the hyperbolic sine of [arg].
|
|
||||||
*/
|
|
||||||
public fun sinh(arg: T): T
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes the hyperbolic cosine of [arg].
|
|
||||||
*/
|
|
||||||
public fun cosh(arg: T): T
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes the hyperbolic tangent of [arg].
|
|
||||||
*/
|
|
||||||
public fun tanh(arg: T): T
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes the inverse hyperbolic sine of [arg].
|
|
||||||
*/
|
|
||||||
public fun asinh(arg: T): T
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes the inverse hyperbolic cosine of [arg].
|
|
||||||
*/
|
|
||||||
public fun acosh(arg: T): T
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes the inverse hyperbolic tangent of [arg].
|
|
||||||
*/
|
|
||||||
public fun atanh(arg: T): T
|
|
||||||
|
|
||||||
public companion object {
|
|
||||||
/**
|
|
||||||
* The identifier of hyperbolic sine.
|
|
||||||
*/
|
|
||||||
public const val SINH_OPERATION: String = "sinh"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The identifier of hyperbolic cosine.
|
|
||||||
*/
|
|
||||||
public const val COSH_OPERATION: String = "cosh"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The identifier of hyperbolic tangent.
|
|
||||||
*/
|
|
||||||
public const val TANH_OPERATION: String = "tanh"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The identifier of inverse hyperbolic sine.
|
|
||||||
*/
|
|
||||||
public const val ASINH_OPERATION: String = "asinh"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The identifier of inverse hyperbolic cosine.
|
|
||||||
*/
|
|
||||||
public const val ACOSH_OPERATION: String = "acosh"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The identifier of inverse hyperbolic tangent.
|
|
||||||
*/
|
|
||||||
public const val ATANH_OPERATION: String = "atanh"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes the hyperbolic sine of [arg].
|
|
||||||
*/
|
|
||||||
@UnstableKMathAPI
|
|
||||||
public fun <T : AlgebraElement<T, out HyperbolicOperations<T>>> sinh(arg: T): T = arg.context.sinh(arg)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes the hyperbolic cosine of [arg].
|
|
||||||
*/
|
|
||||||
@UnstableKMathAPI
|
|
||||||
public fun <T : AlgebraElement<T, out HyperbolicOperations<T>>> cosh(arg: T): T = arg.context.cosh(arg)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes the hyperbolic tangent of [arg].
|
|
||||||
*/
|
|
||||||
@UnstableKMathAPI
|
|
||||||
public fun <T : AlgebraElement<T, out HyperbolicOperations<T>>> tanh(arg: T): T = arg.context.tanh(arg)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes the inverse hyperbolic sine of [arg].
|
|
||||||
*/
|
|
||||||
@UnstableKMathAPI
|
|
||||||
public fun <T : AlgebraElement<T, out HyperbolicOperations<T>>> asinh(arg: T): T = arg.context.asinh(arg)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes the inverse hyperbolic cosine of [arg].
|
|
||||||
*/
|
|
||||||
@UnstableKMathAPI
|
|
||||||
public fun <T : AlgebraElement<T, out HyperbolicOperations<T>>> acosh(arg: T): T = arg.context.acosh(arg)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes the inverse hyperbolic tangent of [arg].
|
|
||||||
*/
|
|
||||||
@UnstableKMathAPI
|
|
||||||
public fun <T : AlgebraElement<T, out HyperbolicOperations<T>>> atanh(arg: T): T = arg.context.atanh(arg)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A context extension to include power operations based on exponentiation.
|
* A context extension to include power operations based on exponentiation.
|
||||||
*
|
*
|
||||||
@ -284,6 +179,36 @@ public interface ExponentialOperations<T> : Algebra<T> {
|
|||||||
*/
|
*/
|
||||||
public fun ln(arg: T): T
|
public fun ln(arg: T): T
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the hyperbolic sine of [arg].
|
||||||
|
*/
|
||||||
|
public fun sinh(arg: T): T
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the hyperbolic cosine of [arg].
|
||||||
|
*/
|
||||||
|
public fun cosh(arg: T): T
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the hyperbolic tangent of [arg].
|
||||||
|
*/
|
||||||
|
public fun tanh(arg: T): T
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the inverse hyperbolic sine of [arg].
|
||||||
|
*/
|
||||||
|
public fun asinh(arg: T): T
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the inverse hyperbolic cosine of [arg].
|
||||||
|
*/
|
||||||
|
public fun acosh(arg: T): T
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the inverse hyperbolic tangent of [arg].
|
||||||
|
*/
|
||||||
|
public fun atanh(arg: T): T
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
/**
|
/**
|
||||||
* The identifier of exponential function.
|
* The identifier of exponential function.
|
||||||
@ -294,6 +219,36 @@ public interface ExponentialOperations<T> : Algebra<T> {
|
|||||||
* The identifier of natural logarithm.
|
* The identifier of natural logarithm.
|
||||||
*/
|
*/
|
||||||
public const val LN_OPERATION: String = "ln"
|
public const val LN_OPERATION: String = "ln"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The identifier of hyperbolic sine.
|
||||||
|
*/
|
||||||
|
public const val SINH_OPERATION: String = "sinh"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The identifier of hyperbolic cosine.
|
||||||
|
*/
|
||||||
|
public const val COSH_OPERATION: String = "cosh"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The identifier of hyperbolic tangent.
|
||||||
|
*/
|
||||||
|
public const val TANH_OPERATION: String = "tanh"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The identifier of inverse hyperbolic sine.
|
||||||
|
*/
|
||||||
|
public const val ASINH_OPERATION: String = "asinh"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The identifier of inverse hyperbolic cosine.
|
||||||
|
*/
|
||||||
|
public const val ACOSH_OPERATION: String = "acosh"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The identifier of inverse hyperbolic tangent.
|
||||||
|
*/
|
||||||
|
public const val ATANH_OPERATION: String = "atanh"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,6 +264,43 @@ public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> exp(arg: T): T
|
|||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> ln(arg: T): T = arg.context.ln(arg)
|
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> ln(arg: T): T = arg.context.ln(arg)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the hyperbolic sine of [arg].
|
||||||
|
*/
|
||||||
|
@UnstableKMathAPI
|
||||||
|
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> sinh(arg: T): T = arg.context.sinh(arg)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the hyperbolic cosine of [arg].
|
||||||
|
*/
|
||||||
|
@UnstableKMathAPI
|
||||||
|
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> cosh(arg: T): T = arg.context.cosh(arg)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the hyperbolic tangent of [arg].
|
||||||
|
*/
|
||||||
|
@UnstableKMathAPI
|
||||||
|
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> tanh(arg: T): T = arg.context.tanh(arg)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the inverse hyperbolic sine of [arg].
|
||||||
|
*/
|
||||||
|
@UnstableKMathAPI
|
||||||
|
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> asinh(arg: T): T = arg.context.asinh(arg)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the inverse hyperbolic cosine of [arg].
|
||||||
|
*/
|
||||||
|
@UnstableKMathAPI
|
||||||
|
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> acosh(arg: T): T = arg.context.acosh(arg)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the inverse hyperbolic tangent of [arg].
|
||||||
|
*/
|
||||||
|
@UnstableKMathAPI
|
||||||
|
public fun <T : AlgebraElement<T, out ExponentialOperations<T>>> atanh(arg: T): T = arg.context.atanh(arg)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A container for norm functional on element.
|
* A container for norm functional on element.
|
||||||
*
|
*
|
||||||
|
@ -1,47 +1,49 @@
|
|||||||
package space.kscience.kmath.operations
|
package space.kscience.kmath.operations
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the sum of all elements in the iterable in this [Space].
|
* Returns the sum of all elements in the iterable in this [Group].
|
||||||
*
|
*
|
||||||
* @receiver the algebra that provides addition.
|
* @receiver the algebra that provides addition.
|
||||||
* @param data the iterable to sum up.
|
* @param data the iterable to sum up.
|
||||||
* @return the sum.
|
* @return the sum.
|
||||||
*/
|
*/
|
||||||
public fun <T> Space<T>.sum(data: Iterable<T>): T = data.fold(zero) { left, right -> add(left, right) }
|
public fun <T> Group<T>.sum(data: Iterable<T>): T = data.fold(zero) { left, right -> add(left, right) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the sum of all elements in the sequence in this [Space].
|
* Returns the sum of all elements in the sequence in this [Group].
|
||||||
*
|
*
|
||||||
* @receiver the algebra that provides addition.
|
* @receiver the algebra that provides addition.
|
||||||
* @param data the sequence to sum up.
|
* @param data the sequence to sum up.
|
||||||
* @return the sum.
|
* @return the sum.
|
||||||
*/
|
*/
|
||||||
public fun <T> Space<T>.sum(data: Sequence<T>): T = data.fold(zero) { left, right -> add(left, right) }
|
public fun <T> Group<T>.sum(data: Sequence<T>): T = data.fold(zero) { left, right -> add(left, right) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an average value of elements in the iterable in this [Space].
|
* Returns an average value of elements in the iterable in this [Group].
|
||||||
*
|
*
|
||||||
* @receiver the algebra that provides addition and division.
|
* @receiver the algebra that provides addition and division.
|
||||||
* @param data the iterable to find average.
|
* @param data the iterable to find average.
|
||||||
* @return the average value.
|
* @return the average value.
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
public fun <T> Space<T>.average(data: Iterable<T>): T = sum(data) / data.count()
|
public fun <T, S> S.average(data: Iterable<T>): T where S : Group<T>, S : ScaleOperations<T> =
|
||||||
|
sum(data) / data.count()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an average value of elements in the sequence in this [Space].
|
* Returns an average value of elements in the sequence in this [Group].
|
||||||
*
|
*
|
||||||
* @receiver the algebra that provides addition and division.
|
* @receiver the algebra that provides addition and division.
|
||||||
* @param data the sequence to find average.
|
* @param data the sequence to find average.
|
||||||
* @return the average value.
|
* @return the average value.
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
public fun <T> Space<T>.average(data: Sequence<T>): T = sum(data) / data.count()
|
public fun <T, S> S.average(data: Sequence<T>): T where S : Group<T>, S : ScaleOperations<T> =
|
||||||
|
sum(data) / data.count()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Absolute of the comparable [value]
|
* Absolute of the comparable [value]
|
||||||
*/
|
*/
|
||||||
public fun <T : Comparable<T>> Space<T>.abs(value: T): T = if (value > zero) value else -value
|
public fun <T : Comparable<T>> Group<T>.abs(value: T): T = if (value > zero) value else -value
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the sum of all elements in the iterable in provided space.
|
* Returns the sum of all elements in the iterable in provided space.
|
||||||
@ -50,7 +52,7 @@ public fun <T : Comparable<T>> Space<T>.abs(value: T): T = if (value > zero) val
|
|||||||
* @param space the algebra that provides addition.
|
* @param space the algebra that provides addition.
|
||||||
* @return the sum.
|
* @return the sum.
|
||||||
*/
|
*/
|
||||||
public fun <T> Iterable<T>.sumWith(space: Space<T>): T = space.sum(this)
|
public fun <T> Iterable<T>.sumWith(space: Group<T>): T = space.sum(this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the sum of all elements in the sequence in provided space.
|
* Returns the sum of all elements in the sequence in provided space.
|
||||||
@ -59,27 +61,29 @@ public fun <T> Iterable<T>.sumWith(space: Space<T>): T = space.sum(this)
|
|||||||
* @param space the algebra that provides addition.
|
* @param space the algebra that provides addition.
|
||||||
* @return the sum.
|
* @return the sum.
|
||||||
*/
|
*/
|
||||||
public fun <T> Sequence<T>.sumWith(space: Space<T>): T = space.sum(this)
|
public fun <T> Sequence<T>.sumWith(space: Group<T>): T = space.sum(this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an average value of elements in the iterable in this [Space].
|
* Returns an average value of elements in the iterable in this [Group].
|
||||||
*
|
*
|
||||||
* @receiver the iterable to find average.
|
* @receiver the iterable to find average.
|
||||||
* @param space the algebra that provides addition and division.
|
* @param space the algebra that provides addition and division.
|
||||||
* @return the average value.
|
* @return the average value.
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
public fun <T> Iterable<T>.averageWith(space: Space<T>): T = space.average(this)
|
public fun <T, S> Iterable<T>.averageWith(space: S): T where S : Group<T>, S : ScaleOperations<T> =
|
||||||
|
space.average(this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an average value of elements in the sequence in this [Space].
|
* Returns an average value of elements in the sequence in this [Group].
|
||||||
*
|
*
|
||||||
* @receiver the sequence to find average.
|
* @receiver the sequence to find average.
|
||||||
* @param space the algebra that provides addition and division.
|
* @param space the algebra that provides addition and division.
|
||||||
* @return the average value.
|
* @return the average value.
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
public fun <T> Sequence<T>.averageWith(space: Space<T>): T = space.average(this)
|
public fun <T, S> Sequence<T>.averageWith(space: S): T where S : Group<T>, S : ScaleOperations<T> =
|
||||||
|
space.average(this)
|
||||||
|
|
||||||
//TODO optimized power operation
|
//TODO optimized power operation
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ import kotlin.math.pow as kpow
|
|||||||
public interface ExtendedFieldOperations<T> :
|
public interface ExtendedFieldOperations<T> :
|
||||||
FieldOperations<T>,
|
FieldOperations<T>,
|
||||||
TrigonometricOperations<T>,
|
TrigonometricOperations<T>,
|
||||||
HyperbolicOperations<T>,
|
|
||||||
PowerOperations<T>,
|
PowerOperations<T>,
|
||||||
ExponentialOperations<T> {
|
ExponentialOperations<T> {
|
||||||
public override fun tan(arg: T): T = sin(arg) / cos(arg)
|
public override fun tan(arg: T): T = sin(arg) / cos(arg)
|
||||||
@ -21,15 +20,15 @@ public interface ExtendedFieldOperations<T> :
|
|||||||
TrigonometricOperations.ACOS_OPERATION -> ::acos
|
TrigonometricOperations.ACOS_OPERATION -> ::acos
|
||||||
TrigonometricOperations.ASIN_OPERATION -> ::asin
|
TrigonometricOperations.ASIN_OPERATION -> ::asin
|
||||||
TrigonometricOperations.ATAN_OPERATION -> ::atan
|
TrigonometricOperations.ATAN_OPERATION -> ::atan
|
||||||
HyperbolicOperations.COSH_OPERATION -> ::cosh
|
|
||||||
HyperbolicOperations.SINH_OPERATION -> ::sinh
|
|
||||||
HyperbolicOperations.TANH_OPERATION -> ::tanh
|
|
||||||
HyperbolicOperations.ACOSH_OPERATION -> ::acosh
|
|
||||||
HyperbolicOperations.ASINH_OPERATION -> ::asinh
|
|
||||||
HyperbolicOperations.ATANH_OPERATION -> ::atanh
|
|
||||||
PowerOperations.SQRT_OPERATION -> ::sqrt
|
PowerOperations.SQRT_OPERATION -> ::sqrt
|
||||||
ExponentialOperations.EXP_OPERATION -> ::exp
|
ExponentialOperations.EXP_OPERATION -> ::exp
|
||||||
ExponentialOperations.LN_OPERATION -> ::ln
|
ExponentialOperations.LN_OPERATION -> ::ln
|
||||||
|
ExponentialOperations.COSH_OPERATION -> ::cosh
|
||||||
|
ExponentialOperations.SINH_OPERATION -> ::sinh
|
||||||
|
ExponentialOperations.TANH_OPERATION -> ::tanh
|
||||||
|
ExponentialOperations.ACOSH_OPERATION -> ::acosh
|
||||||
|
ExponentialOperations.ASINH_OPERATION -> ::asinh
|
||||||
|
ExponentialOperations.ATANH_OPERATION -> ::atanh
|
||||||
else -> super<FieldOperations>.unaryOperationFunction(operation)
|
else -> super<FieldOperations>.unaryOperationFunction(operation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,18 +36,18 @@ public interface ExtendedFieldOperations<T> :
|
|||||||
/**
|
/**
|
||||||
* Advanced Number-like field that implements basic operations.
|
* Advanced Number-like field that implements basic operations.
|
||||||
*/
|
*/
|
||||||
public interface ExtendedField<T> : ExtendedFieldOperations<T>, Field<T>, NumericAlgebra<T> {
|
public interface ExtendedField<T> : ExtendedFieldOperations<T>, Field<T>, NumericAlgebra<T>, ScaleOperations<T> {
|
||||||
public override fun sinh(arg: T): T = (exp(arg) - exp(-arg)) / 2
|
public override fun sinh(arg: T): T = (exp(arg) - exp(-arg)) / 2.0
|
||||||
public override fun cosh(arg: T): T = (exp(arg) + exp(-arg)) / 2
|
public override fun cosh(arg: T): T = (exp(arg) + exp(-arg)) / 2.0
|
||||||
public override fun tanh(arg: T): T = (exp(arg) - exp(-arg)) / (exp(-arg) + exp(arg))
|
public override fun tanh(arg: T): T = (exp(arg) - exp(-arg)) / (exp(-arg) + exp(arg))
|
||||||
public override fun asinh(arg: T): T = ln(sqrt(arg * arg + one) + arg)
|
public override fun asinh(arg: T): T = ln(sqrt(arg * arg + one) + arg)
|
||||||
public override fun acosh(arg: T): T = ln(arg + sqrt((arg - one) * (arg + one)))
|
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
|
public override fun atanh(arg: T): T = (ln(arg + one) - ln(one - arg)) / 2.0
|
||||||
|
|
||||||
public override fun rightSideNumberOperationFunction(operation: String): (left: T, right: Number) -> T =
|
public override fun rightSideNumberOperationFunction(operation: String): (left: T, right: Number) -> T =
|
||||||
when (operation) {
|
when (operation) {
|
||||||
PowerOperations.POW_OPERATION -> ::power
|
PowerOperations.POW_OPERATION -> ::power
|
||||||
else -> super.rightSideNumberOperationFunction(operation)
|
else -> super<Field>.rightSideNumberOperationFunction(operation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,28 +55,27 @@ public interface ExtendedField<T> : ExtendedFieldOperations<T>, Field<T>, Numeri
|
|||||||
* A field for [Double] without boxing. Does not produce appropriate field element.
|
* A field for [Double] without boxing. Does not produce appropriate field element.
|
||||||
*/
|
*/
|
||||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
||||||
public object RealField : ExtendedField<Double>, Norm<Double, Double> {
|
public object RealField : ExtendedField<Double>, Norm<Double, Double>, ScaleOperations<Double> {
|
||||||
public override val zero: Double
|
public override val zero: Double = 0.0
|
||||||
get() = 0.0
|
public override val one: Double = 1.0
|
||||||
|
|
||||||
public override val one: Double
|
|
||||||
get() = 1.0
|
|
||||||
|
|
||||||
override fun number(value: Number): Double = value.toDouble()
|
override fun number(value: Number): Double = value.toDouble()
|
||||||
|
|
||||||
public override fun binaryOperationFunction(operation: String): (left: Double, right: Double) -> Double =
|
public override fun binaryOperationFunction(operation: String): (left: Double, right: Double) -> Double =
|
||||||
when (operation) {
|
when (operation) {
|
||||||
PowerOperations.POW_OPERATION -> ::power
|
PowerOperations.POW_OPERATION -> ::power
|
||||||
else -> super.binaryOperationFunction(operation)
|
else -> super<ExtendedField>.binaryOperationFunction(operation)
|
||||||
}
|
}
|
||||||
|
|
||||||
public override inline fun add(a: Double, b: Double): Double = a + b
|
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()
|
// 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 multiply(a: Double, b: Double): Double = a * b
|
||||||
|
|
||||||
public override inline fun divide(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 inline fun sin(arg: Double): Double = kotlin.math.sin(arg)
|
public override inline fun sin(arg: Double): Double = kotlin.math.sin(arg)
|
||||||
public override inline fun cos(arg: Double): Double = kotlin.math.cos(arg)
|
public override inline fun cos(arg: Double): Double = kotlin.math.cos(arg)
|
||||||
public override inline fun tan(arg: Double): Double = kotlin.math.tan(arg)
|
public override inline fun tan(arg: Double): Double = kotlin.math.tan(arg)
|
||||||
@ -110,11 +108,8 @@ public object RealField : ExtendedField<Double>, Norm<Double, Double> {
|
|||||||
*/
|
*/
|
||||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
||||||
public object FloatField : ExtendedField<Float>, Norm<Float, Float> {
|
public object FloatField : ExtendedField<Float>, Norm<Float, Float> {
|
||||||
public override val zero: Float
|
public override val zero: Float = 0.0f
|
||||||
get() = 0.0f
|
public override val one: Float = 1.0f
|
||||||
|
|
||||||
public override val one: Float
|
|
||||||
get() = 1.0f
|
|
||||||
|
|
||||||
override fun number(value: Number): Float = value.toFloat()
|
override fun number(value: Number): Float = value.toFloat()
|
||||||
|
|
||||||
@ -125,7 +120,7 @@ public object FloatField : ExtendedField<Float>, Norm<Float, Float> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override inline fun add(a: Float, b: Float): Float = a + b
|
public override inline fun add(a: Float, b: Float): Float = a + b
|
||||||
public override inline fun multiply(a: Float, k: Number): Float = a * k.toFloat()
|
override fun scale(a: Float, value: Double): Float = a * value.toFloat()
|
||||||
|
|
||||||
public override inline fun multiply(a: Float, b: Float): Float = a * b
|
public override inline fun multiply(a: Float, b: Float): Float = a * b
|
||||||
|
|
||||||
@ -170,12 +165,8 @@ public object IntRing : Ring<Int>, Norm<Int, Int>, NumericAlgebra<Int> {
|
|||||||
get() = 1
|
get() = 1
|
||||||
|
|
||||||
override fun number(value: Number): Int = value.toInt()
|
override fun number(value: Number): Int = value.toInt()
|
||||||
|
|
||||||
public override inline fun add(a: Int, b: Int): Int = a + b
|
public override inline fun add(a: Int, b: Int): Int = a + b
|
||||||
public override inline fun multiply(a: Int, k: Number): Int = k.toInt() * a
|
|
||||||
|
|
||||||
public override inline fun multiply(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)
|
public override inline fun norm(arg: Int): Int = abs(arg)
|
||||||
|
|
||||||
public override inline fun Int.unaryMinus(): Int = -this
|
public override inline fun Int.unaryMinus(): Int = -this
|
||||||
@ -196,12 +187,8 @@ public object ShortRing : Ring<Short>, Norm<Short, Short>, NumericAlgebra<Short>
|
|||||||
get() = 1
|
get() = 1
|
||||||
|
|
||||||
override fun number(value: Number): Short = value.toShort()
|
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 add(a: Short, b: Short): Short = (a + b).toShort()
|
||||||
public override inline fun multiply(a: Short, k: Number): Short = (a * k.toShort()).toShort()
|
|
||||||
|
|
||||||
public override inline fun multiply(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()
|
public override fun norm(arg: Short): Short = if (arg > 0) arg else (-arg).toShort()
|
||||||
|
|
||||||
public override inline fun Short.unaryMinus(): Short = (-this).toShort()
|
public override inline fun Short.unaryMinus(): Short = (-this).toShort()
|
||||||
@ -222,12 +209,8 @@ public object ByteRing : Ring<Byte>, Norm<Byte, Byte>, NumericAlgebra<Byte> {
|
|||||||
get() = 1
|
get() = 1
|
||||||
|
|
||||||
override fun number(value: Number): Byte = value.toByte()
|
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 add(a: Byte, b: Byte): Byte = (a + b).toByte()
|
||||||
public override inline fun multiply(a: Byte, k: Number): Byte = (a * k.toByte()).toByte()
|
|
||||||
|
|
||||||
public override inline fun multiply(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()
|
public override fun norm(arg: Byte): Byte = if (arg > 0) arg else (-arg).toByte()
|
||||||
|
|
||||||
public override inline fun Byte.unaryMinus(): Byte = (-this).toByte()
|
public override inline fun Byte.unaryMinus(): Byte = (-this).toByte()
|
||||||
@ -248,12 +231,8 @@ public object LongRing : Ring<Long>, Norm<Long, Long>, NumericAlgebra<Long> {
|
|||||||
get() = 1L
|
get() = 1L
|
||||||
|
|
||||||
override fun number(value: Number): Long = value.toLong()
|
override fun number(value: Number): Long = value.toLong()
|
||||||
|
|
||||||
public override inline fun add(a: Long, b: Long): Long = a + b
|
public override inline fun add(a: Long, b: Long): Long = a + b
|
||||||
public override inline fun multiply(a: Long, k: Number): Long = a * k.toLong()
|
|
||||||
|
|
||||||
public override inline fun multiply(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)
|
public override fun norm(arg: Long): Long = abs(arg)
|
||||||
|
|
||||||
public override inline fun Long.unaryMinus(): Long = (-this)
|
public override inline fun Long.unaryMinus(): Long = (-this)
|
||||||
|
@ -8,6 +8,12 @@ import kotlin.math.*
|
|||||||
* [ExtendedFieldOperations] over [RealBuffer].
|
* [ExtendedFieldOperations] over [RealBuffer].
|
||||||
*/
|
*/
|
||||||
public object RealBufferFieldOperations : ExtendedFieldOperations<Buffer<Double>> {
|
public object RealBufferFieldOperations : ExtendedFieldOperations<Buffer<Double>> {
|
||||||
|
override fun Buffer<Double>.unaryMinus(): RealBuffer = if (this is RealBuffer) {
|
||||||
|
RealBuffer(size) { -array[it] }
|
||||||
|
} else {
|
||||||
|
RealBuffer(size) { -get(it) }
|
||||||
|
}
|
||||||
|
|
||||||
public override fun add(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
|
public override fun add(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
|
||||||
require(b.size == a.size) {
|
require(b.size == a.size) {
|
||||||
"The size of the first buffer ${a.size} should be the same as for second one: ${b.size} "
|
"The size of the first buffer ${a.size} should be the same as for second one: ${b.size} "
|
||||||
@ -19,15 +25,24 @@ public object RealBufferFieldOperations : ExtendedFieldOperations<Buffer<Double>
|
|||||||
RealBuffer(DoubleArray(a.size) { aArray[it] + bArray[it] })
|
RealBuffer(DoubleArray(a.size) { aArray[it] + bArray[it] })
|
||||||
} else RealBuffer(DoubleArray(a.size) { a[it] + b[it] })
|
} else RealBuffer(DoubleArray(a.size) { a[it] + b[it] })
|
||||||
}
|
}
|
||||||
|
//
|
||||||
public override fun multiply(a: Buffer<Double>, k: Number): RealBuffer {
|
// public override fun multiply(a: Buffer<Double>, k: Number): RealBuffer {
|
||||||
val kValue = k.toDouble()
|
// val kValue = k.toDouble()
|
||||||
|
//
|
||||||
return if (a is RealBuffer) {
|
// return if (a is RealBuffer) {
|
||||||
val aArray = a.array
|
// val aArray = a.array
|
||||||
RealBuffer(DoubleArray(a.size) { aArray[it] * kValue })
|
// RealBuffer(DoubleArray(a.size) { aArray[it] * kValue })
|
||||||
} else RealBuffer(DoubleArray(a.size) { a[it] * kValue })
|
// } else RealBuffer(DoubleArray(a.size) { a[it] * kValue })
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
// public override fun divide(a: Buffer<Double>, 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<Double>, b: Buffer<Double>): RealBuffer {
|
public override fun multiply(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
|
||||||
require(b.size == a.size) {
|
require(b.size == a.size) {
|
||||||
@ -152,14 +167,22 @@ public class RealBufferField(public val size: Int) : ExtendedField<Buffer<Double
|
|||||||
|
|
||||||
override fun number(value: Number): Buffer<Double> = RealBuffer(size) { value.toDouble() }
|
override fun number(value: Number): Buffer<Double> = RealBuffer(size) { value.toDouble() }
|
||||||
|
|
||||||
|
override fun Buffer<Double>.unaryMinus(): Buffer<Double> = RealBufferFieldOperations.run {
|
||||||
|
-this@unaryMinus
|
||||||
|
}
|
||||||
|
|
||||||
public override fun add(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
|
public override fun add(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
|
||||||
require(a.size == size) { "The buffer size ${a.size} does not match context size $size" }
|
require(a.size == size) { "The buffer size ${a.size} does not match context size $size" }
|
||||||
return RealBufferFieldOperations.add(a, b)
|
return RealBufferFieldOperations.add(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun multiply(a: Buffer<Double>, k: Number): RealBuffer {
|
public override fun scale(a: Buffer<Double>, value: Double): RealBuffer {
|
||||||
require(a.size == size) { "The buffer size ${a.size} does not match context size $size" }
|
require(a.size == size) { "The buffer size ${a.size} does not match context size $size" }
|
||||||
return RealBufferFieldOperations.multiply(a, k)
|
|
||||||
|
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<Double>, b: Buffer<Double>): RealBuffer {
|
public override fun multiply(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
|
||||||
|
@ -11,9 +11,7 @@ class ExpressionFieldTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testExpression() {
|
fun testExpression() {
|
||||||
val context = FunctionalExpressionField(RealField)
|
val expression = FunctionalExpressionField(RealField).invoke {
|
||||||
|
|
||||||
val expression = context {
|
|
||||||
val x by binding()
|
val x by binding()
|
||||||
x * x + 2 * x + one
|
x * x + 2 * x + one
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,9 @@ import space.kscience.kmath.operations.invoke
|
|||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNotEquals
|
import kotlin.test.assertNotEquals
|
||||||
|
|
||||||
internal class FieldVerifier<T>(override val algebra: Field<T>, a: T, b: T, c: T, x: Number) :
|
internal class FieldVerifier<T, A : Field<T>>(
|
||||||
RingVerifier<T>(algebra, a, b, c, x) {
|
algebra: A, a: T, b: T, c: T, x: Number,
|
||||||
|
) : RingVerifier<T, A>(algebra, a, b, c, x) {
|
||||||
|
|
||||||
override fun verify() {
|
override fun verify() {
|
||||||
super.verify()
|
super.verify()
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package space.kscience.kmath.testutils
|
package space.kscience.kmath.testutils
|
||||||
|
|
||||||
import space.kscience.kmath.operations.Ring
|
import space.kscience.kmath.operations.Ring
|
||||||
|
import space.kscience.kmath.operations.ScaleOperations
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
internal open class RingVerifier<T>(override val algebra: Ring<T>, a: T, b: T, c: T, x: Number) :
|
internal open class RingVerifier<T, A>(algebra: A, a: T, b: T, c: T, x: Number) :
|
||||||
SpaceVerifier<T>(algebra, a, b, c, x) {
|
SpaceVerifier<T, A>(algebra, a, b, c, x) where A : Ring<T>, A : ScaleOperations<T> {
|
||||||
|
|
||||||
override fun verify() {
|
override fun verify() {
|
||||||
super.verify()
|
super.verify()
|
||||||
|
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
package space.kscience.kmath.testutils
|
package space.kscience.kmath.testutils
|
||||||
|
|
||||||
import space.kscience.kmath.operations.Space
|
import space.kscience.kmath.operations.Group
|
||||||
|
import space.kscience.kmath.operations.ScaleOperations
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNotEquals
|
import kotlin.test.assertNotEquals
|
||||||
|
|
||||||
internal open class SpaceVerifier<T>(
|
internal open class SpaceVerifier<T, out S>(
|
||||||
override val algebra: Space<T>,
|
override val algebra: S,
|
||||||
val a: T,
|
val a: T,
|
||||||
val b: T,
|
val b: T,
|
||||||
val c: T,
|
val c: T,
|
||||||
val x: Number
|
val x: Number,
|
||||||
) :
|
) : AlgebraicVerifier<T, Group<T>> where S : Group<T>, S : ScaleOperations<T> {
|
||||||
AlgebraicVerifier<T, Space<T>> {
|
|
||||||
override fun verify() {
|
override fun verify() {
|
||||||
algebra {
|
algebra {
|
||||||
assertEquals(a + b + c, a + (b + c), "Addition in $algebra is not associative.")
|
assertEquals(a + b + c, a + (b + c), "Addition in $algebra is not associative.")
|
||||||
|
@ -7,19 +7,16 @@ import java.math.MathContext
|
|||||||
/**
|
/**
|
||||||
* A field over [BigInteger].
|
* A field over [BigInteger].
|
||||||
*/
|
*/
|
||||||
public object JBigIntegerField : Field<BigInteger>, NumericAlgebra<BigInteger> {
|
public object JBigIntegerField : Ring<BigInteger>, NumericAlgebra<BigInteger> {
|
||||||
public override val zero: BigInteger
|
public override val zero: BigInteger get() = BigInteger.ZERO
|
||||||
get() = BigInteger.ZERO
|
|
||||||
|
|
||||||
public override val one: BigInteger
|
public override val one: BigInteger get() = BigInteger.ONE
|
||||||
get() = BigInteger.ONE
|
|
||||||
|
|
||||||
public override fun number(value: Number): BigInteger = BigInteger.valueOf(value.toLong())
|
public override fun number(value: Number): BigInteger = BigInteger.valueOf(value.toLong())
|
||||||
public override fun divide(a: BigInteger, b: BigInteger): BigInteger = a.div(b)
|
|
||||||
public override fun add(a: BigInteger, b: BigInteger): BigInteger = a.add(b)
|
public override fun add(a: BigInteger, b: BigInteger): BigInteger = a.add(b)
|
||||||
public override operator fun BigInteger.minus(b: BigInteger): BigInteger = subtract(b)
|
public override operator fun BigInteger.minus(b: BigInteger): BigInteger = subtract(b)
|
||||||
public override fun multiply(a: BigInteger, k: Number): BigInteger = a.multiply(k.toInt().toBigInteger())
|
|
||||||
public override fun multiply(a: BigInteger, b: BigInteger): BigInteger = a.multiply(b)
|
public override fun multiply(a: BigInteger, b: BigInteger): BigInteger = a.multiply(b)
|
||||||
|
|
||||||
public override operator fun BigInteger.unaryMinus(): BigInteger = negate()
|
public override operator fun BigInteger.unaryMinus(): BigInteger = negate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,7 +27,7 @@ public object JBigIntegerField : Field<BigInteger>, NumericAlgebra<BigInteger> {
|
|||||||
*/
|
*/
|
||||||
public abstract class JBigDecimalFieldBase internal constructor(
|
public abstract class JBigDecimalFieldBase internal constructor(
|
||||||
private val mathContext: MathContext = MathContext.DECIMAL64,
|
private val mathContext: MathContext = MathContext.DECIMAL64,
|
||||||
) : Field<BigDecimal>, PowerOperations<BigDecimal>, NumericAlgebra<BigDecimal> {
|
) : Field<BigDecimal>, PowerOperations<BigDecimal>, NumericAlgebra<BigDecimal>, ScaleOperations<BigDecimal> {
|
||||||
public override val zero: BigDecimal
|
public override val zero: BigDecimal
|
||||||
get() = BigDecimal.ZERO
|
get() = BigDecimal.ZERO
|
||||||
|
|
||||||
@ -41,8 +38,8 @@ public abstract class JBigDecimalFieldBase internal constructor(
|
|||||||
public override operator fun BigDecimal.minus(b: BigDecimal): BigDecimal = subtract(b)
|
public override operator fun BigDecimal.minus(b: BigDecimal): BigDecimal = subtract(b)
|
||||||
public override fun number(value: Number): BigDecimal = BigDecimal.valueOf(value.toDouble())
|
public override fun number(value: Number): BigDecimal = BigDecimal.valueOf(value.toDouble())
|
||||||
|
|
||||||
public override fun multiply(a: BigDecimal, k: Number): BigDecimal =
|
public override fun scale(a: BigDecimal, value: Double): BigDecimal =
|
||||||
a.multiply(k.toDouble().toBigDecimal(mathContext), mathContext)
|
a.multiply(value.toBigDecimal(mathContext), mathContext)
|
||||||
|
|
||||||
public override fun multiply(a: BigDecimal, b: BigDecimal): BigDecimal = a.multiply(b, mathContext)
|
public override fun multiply(a: BigDecimal, b: BigDecimal): BigDecimal = a.multiply(b, mathContext)
|
||||||
public override fun divide(a: BigDecimal, b: BigDecimal): BigDecimal = a.divide(b, mathContext)
|
public override fun divide(a: BigDecimal, b: BigDecimal): BigDecimal = a.divide(b, mathContext)
|
||||||
|
@ -5,16 +5,16 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.runningReduce
|
import kotlinx.coroutines.flow.runningReduce
|
||||||
import kotlinx.coroutines.flow.scan
|
import kotlinx.coroutines.flow.scan
|
||||||
import space.kscience.kmath.operations.Space
|
import space.kscience.kmath.operations.Group
|
||||||
import space.kscience.kmath.operations.SpaceOperations
|
import space.kscience.kmath.operations.GroupOperations
|
||||||
|
import space.kscience.kmath.operations.ScaleOperations
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
|
|
||||||
@ExperimentalCoroutinesApi
|
public fun <T> Flow<T>.cumulativeSum(group: GroupOperations<T>): Flow<T> =
|
||||||
public fun <T> Flow<T>.cumulativeSum(space: SpaceOperations<T>): Flow<T> =
|
group { runningReduce { sum, element -> sum + element } }
|
||||||
space { runningReduce { sum, element -> sum + element } }
|
|
||||||
|
|
||||||
@ExperimentalCoroutinesApi
|
@ExperimentalCoroutinesApi
|
||||||
public fun <T> Flow<T>.mean(space: Space<T>): Flow<T> = space {
|
public fun <T, S> Flow<T>.mean(algebra: S): Flow<T> where S : Group<T>, S : ScaleOperations<T> = algebra {
|
||||||
data class Accumulator(var sum: T, var num: Int)
|
data class Accumulator(var sum: T, var num: Int)
|
||||||
|
|
||||||
scan(Accumulator(zero, 0)) { sum, element ->
|
scan(Accumulator(zero, 0)) { sum, element ->
|
||||||
|
@ -4,13 +4,14 @@ import org.ejml.simple.SimpleMatrix
|
|||||||
import space.kscience.kmath.linear.*
|
import space.kscience.kmath.linear.*
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.nd.getFeature
|
import space.kscience.kmath.nd.getFeature
|
||||||
|
import space.kscience.kmath.operations.ScaleOperations
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents context of basic operations operating with [EjmlMatrix].
|
* Represents context of basic operations operating with [EjmlMatrix].
|
||||||
*
|
*
|
||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
public object EjmlMatrixContext : MatrixContext<Double, EjmlMatrix> {
|
public object EjmlMatrixContext : MatrixContext<Double, EjmlMatrix>, ScaleOperations<Matrix<Double>> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts this matrix to EJML one.
|
* Converts this matrix to EJML one.
|
||||||
@ -41,6 +42,9 @@ public object EjmlMatrixContext : MatrixContext<Double, EjmlMatrix> {
|
|||||||
(0 until it.numRows()).forEach { row -> it[row, 0] = initializer(row) }
|
(0 until it.numRows()).forEach { row -> it[row, 0] = initializer(row) }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
override fun Matrix<Double>.unaryMinus(): Matrix<Double> = this*(-1)
|
||||||
|
|
||||||
public override fun Matrix<Double>.dot(other: Matrix<Double>): EjmlMatrix =
|
public override fun Matrix<Double>.dot(other: Matrix<Double>): EjmlMatrix =
|
||||||
EjmlMatrix(toEjml().origin.mult(other.toEjml().origin))
|
EjmlMatrix(toEjml().origin.mult(other.toEjml().origin))
|
||||||
|
|
||||||
@ -53,8 +57,8 @@ public object EjmlMatrixContext : MatrixContext<Double, EjmlMatrix> {
|
|||||||
public override operator fun Matrix<Double>.minus(b: Matrix<Double>): EjmlMatrix =
|
public override operator fun Matrix<Double>.minus(b: Matrix<Double>): EjmlMatrix =
|
||||||
EjmlMatrix(toEjml().origin - b.toEjml().origin)
|
EjmlMatrix(toEjml().origin - b.toEjml().origin)
|
||||||
|
|
||||||
public override fun multiply(a: Matrix<Double>, k: Number): EjmlMatrix =
|
public override fun scale(a: Matrix<Double>, value: Double): EjmlMatrix =
|
||||||
produce(a.rowNum, a.colNum) { i, j -> a[i, j] * k.toDouble() }
|
produce(a.rowNum, a.colNum) { i, j -> a[i, j] * value }
|
||||||
|
|
||||||
public override operator fun Matrix<Double>.times(value: Double): EjmlMatrix =
|
public override operator fun Matrix<Double>.times(value: Double): EjmlMatrix =
|
||||||
EjmlMatrix(toEjml().origin.scale(value))
|
EjmlMatrix(toEjml().origin.scale(value))
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
package space.kscience.kmath.functions
|
package space.kscience.kmath.functions
|
||||||
|
|
||||||
|
import space.kscience.kmath.operations.Group
|
||||||
import space.kscience.kmath.operations.Ring
|
import space.kscience.kmath.operations.Ring
|
||||||
import space.kscience.kmath.operations.Space
|
import space.kscience.kmath.operations.ScaleOperations
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
import kotlin.contracts.InvocationKind
|
import kotlin.contracts.InvocationKind
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
@ -41,9 +42,15 @@ public fun <T : Any, C : Ring<T>> Polynomial<T>.asFunction(ring: C): (T) -> T =
|
|||||||
/**
|
/**
|
||||||
* An algebra for polynomials
|
* An algebra for polynomials
|
||||||
*/
|
*/
|
||||||
public class PolynomialSpace<T : Any, C : Ring<T>>(private val ring: C) : Space<Polynomial<T>> {
|
public class PolynomialSpace<T : Any, C>(
|
||||||
|
private val ring: C,
|
||||||
|
) : Group<Polynomial<T>>, ScaleOperations<Polynomial<T>> where C : Ring<T>, C : ScaleOperations<T> {
|
||||||
public override val zero: Polynomial<T> = Polynomial(emptyList())
|
public override val zero: Polynomial<T> = Polynomial(emptyList())
|
||||||
|
|
||||||
|
override fun Polynomial<T>.unaryMinus(): Polynomial<T> = with(ring) {
|
||||||
|
Polynomial(coefficients.map { -it })
|
||||||
|
}
|
||||||
|
|
||||||
public override fun add(a: Polynomial<T>, b: Polynomial<T>): Polynomial<T> {
|
public override fun add(a: Polynomial<T>, b: Polynomial<T>): Polynomial<T> {
|
||||||
val dim = max(a.coefficients.size, b.coefficients.size)
|
val dim = max(a.coefficients.size, b.coefficients.size)
|
||||||
|
|
||||||
@ -54,13 +61,13 @@ public class PolynomialSpace<T : Any, C : Ring<T>>(private val ring: C) : Space<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun multiply(a: Polynomial<T>, k: Number): Polynomial<T> =
|
public override fun scale(a: Polynomial<T>, value: Double): Polynomial<T> =
|
||||||
ring { Polynomial(List(a.coefficients.size) { index -> a.coefficients[index] * k }) }
|
ring { Polynomial(List(a.coefficients.size) { index -> a.coefficients[index] * value }) }
|
||||||
|
|
||||||
public operator fun Polynomial<T>.invoke(arg: T): T = value(ring, arg)
|
public operator fun Polynomial<T>.invoke(arg: T): T = value(ring, arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
public inline fun <T : Any, C : Ring<T>, R> C.polynomial(block: PolynomialSpace<T, C>.() -> R): R {
|
public inline fun <T : Any, C, R> C.polynomial(block: PolynomialSpace<T, C>.() -> R): R where C : Ring<T>, C : ScaleOperations<T> {
|
||||||
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
||||||
return PolynomialSpace(this).block()
|
return PolynomialSpace(this).block()
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ import space.kscience.kmath.structures.MutableBufferFactory
|
|||||||
*/
|
*/
|
||||||
public class SplineInterpolator<T : Comparable<T>>(
|
public class SplineInterpolator<T : Comparable<T>>(
|
||||||
public override val algebra: Field<T>,
|
public override val algebra: Field<T>,
|
||||||
public val bufferFactory: MutableBufferFactory<T>
|
public val bufferFactory: MutableBufferFactory<T>,
|
||||||
) : PolynomialInterpolator<T> {
|
) : PolynomialInterpolator<T> {
|
||||||
//TODO possibly optimize zeroed buffers
|
//TODO possibly optimize zeroed buffers
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package space.kscience.kmath.geometry
|
|||||||
|
|
||||||
import space.kscience.kmath.linear.Point
|
import space.kscience.kmath.linear.Point
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
|
import space.kscience.kmath.operations.ScaleOperations
|
||||||
import space.kscience.kmath.operations.SpaceElement
|
import space.kscience.kmath.operations.SpaceElement
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
@ -30,18 +31,20 @@ public fun Vector2D(x: Double, y: Double): Vector2D = Vector2DImpl(x, y)
|
|||||||
|
|
||||||
private data class Vector2DImpl(
|
private data class Vector2DImpl(
|
||||||
override val x: Double,
|
override val x: Double,
|
||||||
override val y: Double
|
override val y: Double,
|
||||||
) : Vector2D
|
) : Vector2D
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 2D Euclidean space
|
* 2D Euclidean space
|
||||||
*/
|
*/
|
||||||
public object Euclidean2DSpace : GeometrySpace<Vector2D> {
|
public object Euclidean2DSpace : GeometrySpace<Vector2D>, ScaleOperations<Vector2D> {
|
||||||
public override val zero: Vector2D by lazy { Vector2D(0.0, 0.0) }
|
public override val zero: Vector2D by lazy { Vector2D(0.0, 0.0) }
|
||||||
|
|
||||||
public fun Vector2D.norm(): Double = sqrt(x * x + y * y)
|
public fun Vector2D.norm(): Double = sqrt(x * x + y * y)
|
||||||
|
override fun Vector2D.unaryMinus(): Vector2D = Vector2D(-x, -y)
|
||||||
|
|
||||||
public override fun Vector2D.distanceTo(other: Vector2D): Double = (this - other).norm()
|
public override fun Vector2D.distanceTo(other: Vector2D): Double = (this - other).norm()
|
||||||
public override fun add(a: Vector2D, b: Vector2D): Vector2D = Vector2D(a.x + b.x, a.y + b.y)
|
public override fun add(a: Vector2D, b: Vector2D): Vector2D = Vector2D(a.x + b.x, a.y + b.y)
|
||||||
public override fun multiply(a: Vector2D, k: Number): Vector2D = Vector2D(a.x * k.toDouble(), a.y * k.toDouble())
|
public override fun scale(a: Vector2D, value: Double): Vector2D = Vector2D(a.x * value, a.y * value)
|
||||||
public override fun Vector2D.dot(other: Vector2D): Double = x * other.x + y * other.y
|
public override fun Vector2D.dot(other: Vector2D): Double = x * other.x + y * other.y
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package space.kscience.kmath.geometry
|
|||||||
|
|
||||||
import space.kscience.kmath.linear.Point
|
import space.kscience.kmath.linear.Point
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
|
import space.kscience.kmath.operations.ScaleOperations
|
||||||
import space.kscience.kmath.operations.SpaceElement
|
import space.kscience.kmath.operations.SpaceElement
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
@ -32,21 +33,22 @@ public val Vector3D.r: Double get() = Euclidean3DSpace { sqrt(norm()) }
|
|||||||
private data class Vector3DImpl(
|
private data class Vector3DImpl(
|
||||||
override val x: Double,
|
override val x: Double,
|
||||||
override val y: Double,
|
override val y: Double,
|
||||||
override val z: Double
|
override val z: Double,
|
||||||
) : Vector3D
|
) : Vector3D
|
||||||
|
|
||||||
public object Euclidean3DSpace : GeometrySpace<Vector3D> {
|
public object Euclidean3DSpace : GeometrySpace<Vector3D>, ScaleOperations<Vector3D> {
|
||||||
public override val zero: Vector3D by lazy { Vector3D(0.0, 0.0, 0.0) }
|
public override val zero: Vector3D by lazy { Vector3D(0.0, 0.0, 0.0) }
|
||||||
|
|
||||||
public fun Vector3D.norm(): Double = sqrt(x * x + y * y + z * z)
|
public fun Vector3D.norm(): Double = sqrt(x * x + y * y + z * z)
|
||||||
|
override fun Vector3D.unaryMinus(): Vector3D = Vector3D(-x, -y, -z)
|
||||||
|
|
||||||
public override fun Vector3D.distanceTo(other: Vector3D): Double = (this - other).norm()
|
public override fun Vector3D.distanceTo(other: Vector3D): Double = (this - other).norm()
|
||||||
|
|
||||||
public override fun add(a: Vector3D, b: Vector3D): Vector3D =
|
public override fun add(a: Vector3D, b: Vector3D): Vector3D =
|
||||||
Vector3D(a.x + b.x, a.y + b.y, a.z + b.z)
|
Vector3D(a.x + b.x, a.y + b.y, a.z + b.z)
|
||||||
|
|
||||||
public override fun multiply(a: Vector3D, k: Number): Vector3D =
|
public override fun scale(a: Vector3D, value: Double): Vector3D =
|
||||||
Vector3D(a.x * k.toDouble(), a.y * k.toDouble(), a.z * k.toDouble())
|
Vector3D(a.x * value, a.y * value, a.z * value)
|
||||||
|
|
||||||
public override fun Vector3D.dot(other: Vector3D): Double =
|
public override fun Vector3D.dot(other: Vector3D): Double =
|
||||||
x * other.x + y * other.y + z * other.z
|
x * other.x + y * other.y + z * other.z
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
package space.kscience.kmath.geometry
|
package space.kscience.kmath.geometry
|
||||||
|
|
||||||
import space.kscience.kmath.operations.Space
|
import space.kscience.kmath.operations.Group
|
||||||
|
import space.kscience.kmath.operations.ScaleOperations
|
||||||
|
|
||||||
public interface Vector
|
public interface Vector
|
||||||
|
|
||||||
public interface GeometrySpace<V : Vector> : Space<V> {
|
public interface GeometrySpace<V : Vector> : Group<V>, ScaleOperations<V> {
|
||||||
/**
|
/**
|
||||||
* L2 distance
|
* L2 distance
|
||||||
*/
|
*/
|
||||||
|
@ -2,8 +2,8 @@ package space.kscience.kmath.histogram
|
|||||||
|
|
||||||
import kotlinx.atomicfu.atomic
|
import kotlinx.atomicfu.atomic
|
||||||
import kotlinx.atomicfu.getAndUpdate
|
import kotlinx.atomicfu.getAndUpdate
|
||||||
|
import space.kscience.kmath.operations.Group
|
||||||
import space.kscience.kmath.operations.RealField
|
import space.kscience.kmath.operations.RealField
|
||||||
import space.kscience.kmath.operations.Space
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common representation for atomic counters
|
* Common representation for atomic counters
|
||||||
@ -36,7 +36,7 @@ public class LongCounter : Counter<Long> {
|
|||||||
override val value: Long get() = innerValue.value
|
override val value: Long get() = innerValue.value
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ObjectCounter<T : Any>(public val space: Space<T>) : Counter<T> {
|
public class ObjectCounter<T : Any>(public val space: Group<T>) : Counter<T> {
|
||||||
private val innerValue = atomic(space.zero)
|
private val innerValue = atomic(space.zero)
|
||||||
|
|
||||||
override fun add(delta: T) {
|
override fun add(delta: T) {
|
||||||
|
@ -3,10 +3,11 @@ package space.kscience.kmath.histogram
|
|||||||
import space.kscience.kmath.domains.Domain
|
import space.kscience.kmath.domains.Domain
|
||||||
import space.kscience.kmath.linear.Point
|
import space.kscience.kmath.linear.Point
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.nd.NDSpace
|
import space.kscience.kmath.nd.NDField
|
||||||
import space.kscience.kmath.nd.NDStructure
|
import space.kscience.kmath.nd.NDStructure
|
||||||
import space.kscience.kmath.nd.Strides
|
import space.kscience.kmath.nd.Strides
|
||||||
import space.kscience.kmath.operations.Space
|
import space.kscience.kmath.operations.Group
|
||||||
|
import space.kscience.kmath.operations.ScaleOperations
|
||||||
import space.kscience.kmath.operations.SpaceElement
|
import space.kscience.kmath.operations.SpaceElement
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
|
|
||||||
@ -41,10 +42,11 @@ public class IndexedHistogram<T : Comparable<T>, V : Any>(
|
|||||||
/**
|
/**
|
||||||
* A space for producing histograms with values in a NDStructure
|
* A space for producing histograms with values in a NDStructure
|
||||||
*/
|
*/
|
||||||
public interface IndexedHistogramSpace<T : Comparable<T>, V : Any> : Space<IndexedHistogram<T, V>> {
|
public interface IndexedHistogramSpace<T : Comparable<T>, V : Any>
|
||||||
|
: Group<IndexedHistogram<T, V>>, ScaleOperations<IndexedHistogram<T, V>> {
|
||||||
//public val valueSpace: Space<V>
|
//public val valueSpace: Space<V>
|
||||||
public val strides: Strides
|
public val strides: Strides
|
||||||
public val histogramValueSpace: NDSpace<V, *> //= NDAlgebra.space(valueSpace, Buffer.Companion::boxing, *shape),
|
public val histogramValueSpace: NDField<V, *> //= NDAlgebra.space(valueSpace, Buffer.Companion::boxing, *shape),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve index of the bin including given [point]
|
* Resolve index of the bin including given [point]
|
||||||
@ -63,12 +65,12 @@ public interface IndexedHistogramSpace<T : Comparable<T>, V : Any> : Space<Index
|
|||||||
override fun add(a: IndexedHistogram<T, V>, b: IndexedHistogram<T, V>): IndexedHistogram<T, V> {
|
override fun add(a: IndexedHistogram<T, V>, b: IndexedHistogram<T, V>): IndexedHistogram<T, V> {
|
||||||
require(a.context == this) { "Can't operate on a histogram produced by external space" }
|
require(a.context == this) { "Can't operate on a histogram produced by external space" }
|
||||||
require(b.context == this) { "Can't operate on a histogram produced by external space" }
|
require(b.context == this) { "Can't operate on a histogram produced by external space" }
|
||||||
return IndexedHistogram(this, histogramValueSpace.invoke { a.values + b.values })
|
return IndexedHistogram(this, histogramValueSpace { a.values + b.values })
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun multiply(a: IndexedHistogram<T, V>, k: Number): IndexedHistogram<T, V> {
|
override fun scale(a: IndexedHistogram<T, V>, value: Double): IndexedHistogram<T, V> {
|
||||||
require(a.context == this) { "Can't operate on a histogram produced by external space" }
|
require(a.context == this) { "Can't operate on a histogram produced by external space" }
|
||||||
return IndexedHistogram(this, histogramValueSpace.invoke { a.values * k })
|
return IndexedHistogram(this, histogramValueSpace { a.values * value })
|
||||||
}
|
}
|
||||||
|
|
||||||
override val zero: IndexedHistogram<T, V> get() = produce { }
|
override val zero: IndexedHistogram<T, V> get() = produce { }
|
||||||
|
@ -2,6 +2,7 @@ package space.kscience.kmath.histogram
|
|||||||
|
|
||||||
import space.kscience.kmath.domains.Domain
|
import space.kscience.kmath.domains.Domain
|
||||||
import space.kscience.kmath.domains.HyperSquareDomain
|
import space.kscience.kmath.domains.HyperSquareDomain
|
||||||
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.nd.*
|
import space.kscience.kmath.nd.*
|
||||||
import space.kscience.kmath.structures.*
|
import space.kscience.kmath.structures.*
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
@ -40,6 +41,7 @@ public class RealHistogramSpace(
|
|||||||
getIndex(it, point[it])
|
getIndex(it, point[it])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(UnstableKMathAPI::class)
|
||||||
override fun getDomain(index: IntArray): Domain<Double> {
|
override fun getDomain(index: IntArray): Domain<Double> {
|
||||||
val lowerBoundary = index.mapIndexed { axis, i ->
|
val lowerBoundary = index.mapIndexed { axis, i ->
|
||||||
when (i) {
|
when (i) {
|
||||||
@ -77,6 +79,8 @@ public class RealHistogramSpace(
|
|||||||
return IndexedHistogram(this, values)
|
return IndexedHistogram(this, values)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun IndexedHistogram<Double, Double>.unaryMinus(): IndexedHistogram<Double, Double> = this * (-1)
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
/**
|
/**
|
||||||
* Use it like
|
* Use it like
|
||||||
|
@ -2,7 +2,8 @@ package space.kscience.kmath.histogram
|
|||||||
|
|
||||||
import space.kscience.kmath.domains.UnivariateDomain
|
import space.kscience.kmath.domains.UnivariateDomain
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.operations.Space
|
import space.kscience.kmath.operations.Group
|
||||||
|
import space.kscience.kmath.operations.ScaleOperations
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
@ -36,7 +37,7 @@ public class TreeHistogram(
|
|||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class TreeHistogramSpace(
|
public class TreeHistogramSpace(
|
||||||
public val binFactory: (Double) -> UnivariateDomain,
|
public val binFactory: (Double) -> UnivariateDomain,
|
||||||
) : Space<UnivariateHistogram> {
|
) : Group<UnivariateHistogram>, ScaleOperations<UnivariateHistogram> {
|
||||||
|
|
||||||
private class BinCounter(val domain: UnivariateDomain, val counter: Counter<Double> = Counter.real()) :
|
private class BinCounter(val domain: UnivariateDomain, val counter: Counter<Double> = Counter.real()) :
|
||||||
ClosedFloatingPointRange<Double> by domain.range
|
ClosedFloatingPointRange<Double> by domain.range
|
||||||
@ -97,14 +98,14 @@ public class TreeHistogramSpace(
|
|||||||
return TreeHistogram(this, bins)
|
return TreeHistogram(this, bins)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun multiply(a: UnivariateHistogram, k: Number): UnivariateHistogram {
|
override fun scale(a: UnivariateHistogram, value: Double): UnivariateHistogram {
|
||||||
val bins = TreeMap<Double, UnivariateBin>().apply {
|
val bins = TreeMap<Double, UnivariateBin>().apply {
|
||||||
a.bins.forEach { bin ->
|
a.bins.forEach { bin ->
|
||||||
put(bin.domain.center,
|
put(bin.domain.center,
|
||||||
UnivariateBin(
|
UnivariateBin(
|
||||||
bin.domain,
|
bin.domain,
|
||||||
value = bin.value * k.toDouble(),
|
value = bin.value * value.toDouble(),
|
||||||
standardDeviation = abs(bin.standardDeviation * k.toDouble())
|
standardDeviation = abs(bin.standardDeviation * value.toDouble())
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -113,6 +114,8 @@ public class TreeHistogramSpace(
|
|||||||
return TreeHistogram(this, bins)
|
return TreeHistogram(this, bins)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun UnivariateHistogram.unaryMinus(): UnivariateHistogram = this * (-1)
|
||||||
|
|
||||||
override val zero: UnivariateHistogram = produce { }
|
override val zero: UnivariateHistogram = produce { }
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
|
@ -2,12 +2,13 @@ package space.kscience.kmath.histogram
|
|||||||
|
|
||||||
import space.kscience.kmath.domains.UnivariateDomain
|
import space.kscience.kmath.domains.UnivariateDomain
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.operations.Space
|
import space.kscience.kmath.operations.Group
|
||||||
import space.kscience.kmath.operations.SpaceElement
|
import space.kscience.kmath.operations.SpaceElement
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
import space.kscience.kmath.structures.asSequence
|
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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,6 +16,7 @@ public val UnivariateDomain.center: Double get() = (range.endInclusive - range.s
|
|||||||
* @param value The value of histogram including weighting
|
* @param value The value of histogram including weighting
|
||||||
* @param standardDeviation Standard deviation of the bin value. Zero or negative if not applicable
|
* @param standardDeviation Standard deviation of the bin value. Zero or negative if not applicable
|
||||||
*/
|
*/
|
||||||
|
@UnstableKMathAPI
|
||||||
public class UnivariateBin(
|
public class UnivariateBin(
|
||||||
public val domain: UnivariateDomain,
|
public val domain: UnivariateDomain,
|
||||||
override val value: Double,
|
override val value: Double,
|
||||||
@ -28,7 +30,7 @@ public class UnivariateBin(
|
|||||||
|
|
||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
public interface UnivariateHistogram : Histogram<Double, UnivariateBin>,
|
public interface UnivariateHistogram : Histogram<Double, UnivariateBin>,
|
||||||
SpaceElement<UnivariateHistogram, Space<UnivariateHistogram>> {
|
SpaceElement<UnivariateHistogram, Group<UnivariateHistogram>> {
|
||||||
public operator fun get(value: Double): UnivariateBin?
|
public operator fun get(value: Double): UnivariateBin?
|
||||||
public override operator fun get(point: Buffer<Double>): UnivariateBin? = get(point[0])
|
public override operator fun get(point: Buffer<Double>): UnivariateBin? = get(point[0])
|
||||||
|
|
||||||
|
@ -102,8 +102,8 @@ public fun <X : SFun<X>> MST.toSFun(): SFun<X> = when (this) {
|
|||||||
is MST.Symbolic -> toSVar()
|
is MST.Symbolic -> toSVar()
|
||||||
|
|
||||||
is MST.Unary -> when (operation) {
|
is MST.Unary -> when (operation) {
|
||||||
SpaceOperations.PLUS_OPERATION -> +value.toSFun<X>()
|
GroupOperations.PLUS_OPERATION -> +value.toSFun<X>()
|
||||||
SpaceOperations.MINUS_OPERATION -> -value.toSFun<X>()
|
GroupOperations.MINUS_OPERATION -> -value.toSFun<X>()
|
||||||
TrigonometricOperations.SIN_OPERATION -> sin(value.toSFun())
|
TrigonometricOperations.SIN_OPERATION -> sin(value.toSFun())
|
||||||
TrigonometricOperations.COS_OPERATION -> cos(value.toSFun())
|
TrigonometricOperations.COS_OPERATION -> cos(value.toSFun())
|
||||||
TrigonometricOperations.TAN_OPERATION -> tan(value.toSFun())
|
TrigonometricOperations.TAN_OPERATION -> tan(value.toSFun())
|
||||||
@ -114,8 +114,8 @@ public fun <X : SFun<X>> MST.toSFun(): SFun<X> = when (this) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
is MST.Binary -> when (operation) {
|
is MST.Binary -> when (operation) {
|
||||||
SpaceOperations.PLUS_OPERATION -> left.toSFun<X>() + right.toSFun()
|
GroupOperations.PLUS_OPERATION -> left.toSFun<X>() + right.toSFun()
|
||||||
SpaceOperations.MINUS_OPERATION -> left.toSFun<X>() - right.toSFun()
|
GroupOperations.MINUS_OPERATION -> left.toSFun<X>() - right.toSFun()
|
||||||
RingOperations.TIMES_OPERATION -> left.toSFun<X>() * right.toSFun()
|
RingOperations.TIMES_OPERATION -> left.toSFun<X>() * right.toSFun()
|
||||||
FieldOperations.DIV_OPERATION -> left.toSFun<X>() / right.toSFun()
|
FieldOperations.DIV_OPERATION -> left.toSFun<X>() / right.toSFun()
|
||||||
PowerOperations.POW_OPERATION -> left.toSFun<X>() pow (right as MST.Numeric).toSConst()
|
PowerOperations.POW_OPERATION -> left.toSFun<X>() pow (right as MST.Numeric).toSConst()
|
||||||
|
@ -20,7 +20,7 @@ internal fun NDAlgebra<*, *>.checkShape(array: INDArray): INDArray {
|
|||||||
* @param T the type of ND-structure element.
|
* @param T the type of ND-structure element.
|
||||||
* @param C the type of the element context.
|
* @param C the type of the element context.
|
||||||
*/
|
*/
|
||||||
public interface Nd4jArrayAlgebra<T, C> : NDAlgebra<T, C> {
|
public interface Nd4jArrayAlgebra<T, C : Algebra<T>> : NDAlgebra<T, C> {
|
||||||
/**
|
/**
|
||||||
* Wraps [INDArray] to [N].
|
* Wraps [INDArray] to [N].
|
||||||
*/
|
*/
|
||||||
@ -70,40 +70,27 @@ public interface Nd4jArrayAlgebra<T, C> : NDAlgebra<T, C> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents [NDSpace] over [Nd4jArrayStructure].
|
* Represents [NDGroup] over [Nd4jArrayStructure].
|
||||||
*
|
*
|
||||||
* @param T the type of the element contained in ND structure.
|
* @param T the type of the element contained in ND structure.
|
||||||
* @param S the type of space of structure elements.
|
* @param S the type of space of structure elements.
|
||||||
*/
|
*/
|
||||||
public interface Nd4jArraySpace<T, S : Space<T>> : NDSpace<T, S>, Nd4jArrayAlgebra<T, S> {
|
public interface Nd4JArrayGroup<T, S : Group<T>> : NDGroup<T, S>, Nd4jArrayAlgebra<T, S> {
|
||||||
|
|
||||||
public override val zero: Nd4jArrayStructure<T>
|
public override val zero: Nd4jArrayStructure<T>
|
||||||
get() = Nd4j.zeros(*shape).wrap()
|
get() = Nd4j.zeros(*shape).wrap()
|
||||||
|
|
||||||
public override fun add(a: NDStructure<T>, b: NDStructure<T>): Nd4jArrayStructure<T> {
|
public override fun add(a: NDStructure<T>, b: NDStructure<T>): Nd4jArrayStructure<T> =
|
||||||
return a.ndArray.add(b.ndArray).wrap()
|
a.ndArray.add(b.ndArray).wrap()
|
||||||
}
|
|
||||||
|
|
||||||
public override operator fun NDStructure<T>.minus(b: NDStructure<T>): Nd4jArrayStructure<T> {
|
public override operator fun NDStructure<T>.minus(b: NDStructure<T>): Nd4jArrayStructure<T> =
|
||||||
return ndArray.sub(b.ndArray).wrap()
|
ndArray.sub(b.ndArray).wrap()
|
||||||
}
|
|
||||||
|
|
||||||
public override operator fun NDStructure<T>.unaryMinus(): Nd4jArrayStructure<T> {
|
public override operator fun NDStructure<T>.unaryMinus(): Nd4jArrayStructure<T> =
|
||||||
return ndArray.neg().wrap()
|
ndArray.neg().wrap()
|
||||||
}
|
|
||||||
|
|
||||||
public override fun multiply(a: NDStructure<T>, k: Number): Nd4jArrayStructure<T> {
|
public fun multiply(a: NDStructure<T>, k: Number): Nd4jArrayStructure<T> =
|
||||||
return a.ndArray.mul(k).wrap()
|
a.ndArray.mul(k).wrap()
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated("Avoid using this method, underlying array get casted to Doubles")
|
|
||||||
public override operator fun NDStructure<T>.div(k: Number): Nd4jArrayStructure<T> {
|
|
||||||
return ndArray.div(k).wrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
public override operator fun NDStructure<T>.times(k: Number): Nd4jArrayStructure<T> {
|
|
||||||
return ndArray.mul(k).wrap()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,14 +100,13 @@ public interface Nd4jArraySpace<T, S : Space<T>> : NDSpace<T, S>, Nd4jArrayAlgeb
|
|||||||
* @param R the type of ring of structure elements.
|
* @param R the type of ring of structure elements.
|
||||||
*/
|
*/
|
||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
public interface Nd4jArrayRing<T, R : Ring<T>> : NDRing<T, R>, Nd4jArraySpace<T, R> {
|
public interface Nd4jArrayRing<T, R : Ring<T>> : NDRing<T, R>, Nd4JArrayGroup<T, R> {
|
||||||
|
|
||||||
public override val one: Nd4jArrayStructure<T>
|
public override val one: Nd4jArrayStructure<T>
|
||||||
get() = Nd4j.ones(*shape).wrap()
|
get() = Nd4j.ones(*shape).wrap()
|
||||||
|
|
||||||
public override fun multiply(a: NDStructure<T>, b: NDStructure<T>): Nd4jArrayStructure<T> {
|
public override fun multiply(a: NDStructure<T>, b: NDStructure<T>): Nd4jArrayStructure<T> =
|
||||||
return a.ndArray.mul(b.ndArray).wrap()
|
a.ndArray.mul(b.ndArray).wrap()
|
||||||
}
|
|
||||||
//
|
//
|
||||||
// public override operator fun Nd4jArrayStructure<T>.minus(b: Number): Nd4jArrayStructure<T> {
|
// public override operator fun Nd4jArrayStructure<T>.minus(b: Number): Nd4jArrayStructure<T> {
|
||||||
// check(this)
|
// check(this)
|
||||||
@ -180,8 +166,7 @@ public interface Nd4jArrayField<T, F : Field<T>> : NDField<T, F>, Nd4jArrayRing<
|
|||||||
public override fun divide(a: NDStructure<T>, b: NDStructure<T>): Nd4jArrayStructure<T> =
|
public override fun divide(a: NDStructure<T>, b: NDStructure<T>): Nd4jArrayStructure<T> =
|
||||||
a.ndArray.div(b.ndArray).wrap()
|
a.ndArray.div(b.ndArray).wrap()
|
||||||
|
|
||||||
public override operator fun Number.div(b: NDStructure<T>): Nd4jArrayStructure<T> = b.ndArray.rdiv(this).wrap()
|
public operator fun Number.div(b: NDStructure<T>): Nd4jArrayStructure<T> = b.ndArray.rdiv(this).wrap()
|
||||||
|
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
private val floatNd4jArrayFieldCache: ThreadLocal<MutableMap<IntArray, FloatNd4jArrayField>> =
|
private val floatNd4jArrayFieldCache: ThreadLocal<MutableMap<IntArray, FloatNd4jArrayField>> =
|
||||||
@ -218,11 +203,14 @@ public interface Nd4jArrayField<T, F : Field<T>> : NDField<T, F>, Nd4jArrayRing<
|
|||||||
* Represents [NDField] over [Nd4jArrayRealStructure].
|
* Represents [NDField] over [Nd4jArrayRealStructure].
|
||||||
*/
|
*/
|
||||||
public class RealNd4jArrayField(public override val shape: IntArray) : Nd4jArrayField<Double, RealField> {
|
public class RealNd4jArrayField(public override val shape: IntArray) : Nd4jArrayField<Double, RealField> {
|
||||||
public override val elementContext: RealField
|
public override val elementContext: RealField get() = RealField
|
||||||
get() = RealField
|
|
||||||
|
|
||||||
public override fun INDArray.wrap(): Nd4jArrayStructure<Double> = checkShape(this).asRealStructure()
|
public override fun INDArray.wrap(): Nd4jArrayStructure<Double> = checkShape(this).asRealStructure()
|
||||||
|
|
||||||
|
override fun scale(a: NDStructure<Double>, value: Double): Nd4jArrayStructure<Double> {
|
||||||
|
return a.ndArray.mul(value).wrap()
|
||||||
|
}
|
||||||
|
|
||||||
public override operator fun NDStructure<Double>.div(arg: Double): Nd4jArrayStructure<Double> {
|
public override operator fun NDStructure<Double>.div(arg: Double): Nd4jArrayStructure<Double> {
|
||||||
return ndArray.div(arg).wrap()
|
return ndArray.div(arg).wrap()
|
||||||
}
|
}
|
||||||
@ -257,29 +245,26 @@ public class FloatNd4jArrayField(public override val shape: IntArray) : Nd4jArra
|
|||||||
|
|
||||||
public override fun INDArray.wrap(): Nd4jArrayStructure<Float> = checkShape(this).asFloatStructure()
|
public override fun INDArray.wrap(): Nd4jArrayStructure<Float> = checkShape(this).asFloatStructure()
|
||||||
|
|
||||||
public override operator fun NDStructure<Float>.div(arg: Float): Nd4jArrayStructure<Float> {
|
override fun scale(a: NDStructure<Float>, value: Double): NDStructure<Float> =
|
||||||
return ndArray.div(arg).wrap()
|
a.ndArray.mul(value).wrap()
|
||||||
}
|
|
||||||
|
|
||||||
public override operator fun NDStructure<Float>.plus(arg: Float): Nd4jArrayStructure<Float> {
|
public override operator fun NDStructure<Float>.div(arg: Float): Nd4jArrayStructure<Float> =
|
||||||
return ndArray.add(arg).wrap()
|
ndArray.div(arg).wrap()
|
||||||
}
|
|
||||||
|
|
||||||
public override operator fun NDStructure<Float>.minus(arg: Float): Nd4jArrayStructure<Float> {
|
public override operator fun NDStructure<Float>.plus(arg: Float): Nd4jArrayStructure<Float> =
|
||||||
return ndArray.sub(arg).wrap()
|
ndArray.add(arg).wrap()
|
||||||
}
|
|
||||||
|
|
||||||
public override operator fun NDStructure<Float>.times(arg: Float): Nd4jArrayStructure<Float> {
|
public override operator fun NDStructure<Float>.minus(arg: Float): Nd4jArrayStructure<Float> =
|
||||||
return ndArray.mul(arg).wrap()
|
ndArray.sub(arg).wrap()
|
||||||
}
|
|
||||||
|
|
||||||
public override operator fun Float.div(arg: NDStructure<Float>): Nd4jArrayStructure<Float> {
|
public override operator fun NDStructure<Float>.times(arg: Float): Nd4jArrayStructure<Float> =
|
||||||
return arg.ndArray.rdiv(this).wrap()
|
ndArray.mul(arg).wrap()
|
||||||
}
|
|
||||||
|
|
||||||
public override operator fun Float.minus(arg: NDStructure<Float>): Nd4jArrayStructure<Float> {
|
public override operator fun Float.div(arg: NDStructure<Float>): Nd4jArrayStructure<Float> =
|
||||||
return arg.ndArray.rsub(this).wrap()
|
arg.ndArray.rdiv(this).wrap()
|
||||||
}
|
|
||||||
|
public override operator fun Float.minus(arg: NDStructure<Float>): Nd4jArrayStructure<Float> =
|
||||||
|
arg.ndArray.rsub(this).wrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -291,21 +276,17 @@ public class IntNd4jArrayRing(public override val shape: IntArray) : Nd4jArrayRi
|
|||||||
|
|
||||||
public override fun INDArray.wrap(): Nd4jArrayStructure<Int> = checkShape(this).asIntStructure()
|
public override fun INDArray.wrap(): Nd4jArrayStructure<Int> = checkShape(this).asIntStructure()
|
||||||
|
|
||||||
public override operator fun NDStructure<Int>.plus(arg: Int): Nd4jArrayStructure<Int> {
|
public override operator fun NDStructure<Int>.plus(arg: Int): Nd4jArrayStructure<Int> =
|
||||||
return ndArray.add(arg).wrap()
|
ndArray.add(arg).wrap()
|
||||||
}
|
|
||||||
|
|
||||||
public override operator fun NDStructure<Int>.minus(arg: Int): Nd4jArrayStructure<Int> {
|
public override operator fun NDStructure<Int>.minus(arg: Int): Nd4jArrayStructure<Int> =
|
||||||
return ndArray.sub(arg).wrap()
|
ndArray.sub(arg).wrap()
|
||||||
}
|
|
||||||
|
|
||||||
public override operator fun NDStructure<Int>.times(arg: Int): Nd4jArrayStructure<Int> {
|
public override operator fun NDStructure<Int>.times(arg: Int): Nd4jArrayStructure<Int> =
|
||||||
return ndArray.mul(arg).wrap()
|
ndArray.mul(arg).wrap()
|
||||||
}
|
|
||||||
|
|
||||||
public override operator fun Int.minus(arg: NDStructure<Int>): Nd4jArrayStructure<Int> {
|
public override operator fun Int.minus(arg: NDStructure<Int>): Nd4jArrayStructure<Int> =
|
||||||
return arg.ndArray.rsub(this).wrap()
|
arg.ndArray.rsub(this).wrap()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -317,19 +298,15 @@ public class LongNd4jArrayRing(public override val shape: IntArray) : Nd4jArrayR
|
|||||||
|
|
||||||
public override fun INDArray.wrap(): Nd4jArrayStructure<Long> = checkShape(this).asLongStructure()
|
public override fun INDArray.wrap(): Nd4jArrayStructure<Long> = checkShape(this).asLongStructure()
|
||||||
|
|
||||||
public override operator fun NDStructure<Long>.plus(arg: Long): Nd4jArrayStructure<Long> {
|
public override operator fun NDStructure<Long>.plus(arg: Long): Nd4jArrayStructure<Long> =
|
||||||
return ndArray.add(arg).wrap()
|
ndArray.add(arg).wrap()
|
||||||
}
|
|
||||||
|
|
||||||
public override operator fun NDStructure<Long>.minus(arg: Long): Nd4jArrayStructure<Long> {
|
public override operator fun NDStructure<Long>.minus(arg: Long): Nd4jArrayStructure<Long> =
|
||||||
return ndArray.sub(arg).wrap()
|
ndArray.sub(arg).wrap()
|
||||||
}
|
|
||||||
|
|
||||||
public override operator fun NDStructure<Long>.times(arg: Long): Nd4jArrayStructure<Long> {
|
public override operator fun NDStructure<Long>.times(arg: Long): Nd4jArrayStructure<Long> =
|
||||||
return ndArray.mul(arg).wrap()
|
ndArray.mul(arg).wrap()
|
||||||
}
|
|
||||||
|
|
||||||
public override operator fun Long.minus(arg: NDStructure<Long>): Nd4jArrayStructure<Long> {
|
public override operator fun Long.minus(arg: NDStructure<Long>): Nd4jArrayStructure<Long> =
|
||||||
return arg.ndArray.rsub(this).wrap()
|
arg.ndArray.rsub(this).wrap()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,8 @@ import space.kscience.kmath.chains.Chain
|
|||||||
import space.kscience.kmath.chains.ConstantChain
|
import space.kscience.kmath.chains.ConstantChain
|
||||||
import space.kscience.kmath.chains.map
|
import space.kscience.kmath.chains.map
|
||||||
import space.kscience.kmath.chains.zip
|
import space.kscience.kmath.chains.zip
|
||||||
import space.kscience.kmath.operations.Space
|
import space.kscience.kmath.operations.Group
|
||||||
|
import space.kscience.kmath.operations.ScaleOperations
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
|
|
||||||
public class BasicSampler<T : Any>(public val chainBuilder: (RandomGenerator) -> Chain<T>) : Sampler<T> {
|
public class BasicSampler<T : Any>(public val chainBuilder: (RandomGenerator) -> Chain<T>) : Sampler<T> {
|
||||||
@ -18,14 +19,18 @@ public class ConstantSampler<T : Any>(public val value: T) : Sampler<T> {
|
|||||||
/**
|
/**
|
||||||
* A space for samplers. Allows to perform simple operations on distributions
|
* A space for samplers. Allows to perform simple operations on distributions
|
||||||
*/
|
*/
|
||||||
public class SamplerSpace<T : Any>(public val space: Space<T>) : Space<Sampler<T>> {
|
public class SamplerSpace<T : Any, S>(public val algebra: S) : Group<Sampler<T>>,
|
||||||
public override val zero: Sampler<T> = ConstantSampler(space.zero)
|
ScaleOperations<Sampler<T>> where S : Group<T>, S : ScaleOperations<T> {
|
||||||
|
|
||||||
|
public override val zero: Sampler<T> = ConstantSampler(algebra.zero)
|
||||||
|
|
||||||
public override fun add(a: Sampler<T>, b: Sampler<T>): Sampler<T> = BasicSampler { generator ->
|
public override fun add(a: Sampler<T>, b: Sampler<T>): Sampler<T> = BasicSampler { generator ->
|
||||||
a.sample(generator).zip(b.sample(generator)) { aValue, bValue -> space { aValue + bValue } }
|
a.sample(generator).zip(b.sample(generator)) { aValue, bValue -> algebra { aValue + bValue } }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun multiply(a: Sampler<T>, k: Number): Sampler<T> = BasicSampler { generator ->
|
public override fun scale(a: Sampler<T>, value: Double): Sampler<T> = BasicSampler { generator ->
|
||||||
a.sample(generator).map { space { it * k.toDouble() } }
|
a.sample(generator).map { algebra { it * value } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun Sampler<T>.unaryMinus(): Sampler<T> = scale(this, -1.0)
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ public interface ComposableStatistic<T, I, R> : Statistic<T, R> {
|
|||||||
@ExperimentalCoroutinesApi
|
@ExperimentalCoroutinesApi
|
||||||
private fun <T, I, R> ComposableStatistic<T, I, R>.flowIntermediate(
|
private fun <T, I, R> ComposableStatistic<T, I, R>.flowIntermediate(
|
||||||
flow: Flow<Buffer<T>>,
|
flow: Flow<Buffer<T>>,
|
||||||
dispatcher: CoroutineDispatcher = Dispatchers.Default
|
dispatcher: CoroutineDispatcher = Dispatchers.Default,
|
||||||
): Flow<I> = flow
|
): Flow<I> = flow
|
||||||
.mapParallel(dispatcher) { computeIntermediate(it) }
|
.mapParallel(dispatcher) { computeIntermediate(it) }
|
||||||
.runningReduce(::composeIntermediate)
|
.runningReduce(::composeIntermediate)
|
||||||
@ -59,27 +59,31 @@ private fun <T, I, R> ComposableStatistic<T, I, R>.flowIntermediate(
|
|||||||
@ExperimentalCoroutinesApi
|
@ExperimentalCoroutinesApi
|
||||||
public fun <T, I, R> ComposableStatistic<T, I, R>.flow(
|
public fun <T, I, R> ComposableStatistic<T, I, R>.flow(
|
||||||
flow: Flow<Buffer<T>>,
|
flow: Flow<Buffer<T>>,
|
||||||
dispatcher: CoroutineDispatcher = Dispatchers.Default
|
dispatcher: CoroutineDispatcher = Dispatchers.Default,
|
||||||
): Flow<R> = flowIntermediate(flow, dispatcher).map(::toResult)
|
): Flow<R> = flowIntermediate(flow, dispatcher).map(::toResult)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Arithmetic mean
|
* Arithmetic mean
|
||||||
*/
|
*/
|
||||||
public class Mean<T>(public val space: Space<T>) : ComposableStatistic<T, Pair<T, Int>, T> {
|
public class Mean<T>(
|
||||||
|
private val space: Group<T>,
|
||||||
|
private val division: (sum: T, count: Int) -> T,
|
||||||
|
) : ComposableStatistic<T, Pair<T, Int>, T> {
|
||||||
public override suspend fun computeIntermediate(data: Buffer<T>): Pair<T, Int> =
|
public override suspend fun computeIntermediate(data: Buffer<T>): Pair<T, Int> =
|
||||||
space { sum(data.asIterable()) } to data.size
|
space { sum(data.asIterable()) } to data.size
|
||||||
|
|
||||||
public override suspend fun composeIntermediate(first: Pair<T, Int>, second: Pair<T, Int>): Pair<T, Int> =
|
public override suspend fun composeIntermediate(first: Pair<T, Int>, second: Pair<T, Int>): Pair<T, Int> =
|
||||||
space { first.first + second.first } to (first.second + second.second)
|
space { first.first + second.first } to (first.second + second.second)
|
||||||
|
|
||||||
public override suspend fun toResult(intermediate: Pair<T, Int>): T =
|
public override suspend fun toResult(intermediate: Pair<T, Int>): T = space {
|
||||||
space { intermediate.first / intermediate.second }
|
division(intermediate.first, intermediate.second)
|
||||||
|
}
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
//TODO replace with optimized version which respects overflow
|
//TODO replace with optimized version which respects overflow
|
||||||
public val real: Mean<Double> = Mean(RealField)
|
public val real: Mean<Double> = Mean(RealField) { sum, count -> sum / count }
|
||||||
public val int: Mean<Int> = Mean(IntRing)
|
public val int: Mean<Int> = Mean(IntRing) { sum, count -> sum / count }
|
||||||
public val long: Mean<Long> = Mean(LongRing)
|
public val long: Mean<Long> = Mean(LongRing) { sum, count -> sum / count }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ public final class space/kscience/kmath/viktor/ViktorBuffer : space/kscience/kma
|
|||||||
public final synthetic fun unbox-impl ()Lorg/jetbrains/bio/viktor/F64FlatArray;
|
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/RingWithNumbers {
|
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 fun <init> ([I)V
|
public fun <init> ([I)V
|
||||||
public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object;
|
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 fun acos-Q7Xurp0 (Lspace/kscience/kmath/nd/NDStructure;)Lorg/jetbrains/bio/viktor/F64Array;
|
||||||
@ -55,8 +55,6 @@ public final class space/kscience/kmath/viktor/ViktorNDField : space/kscience/km
|
|||||||
public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object;
|
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 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 fun div (DLspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure;
|
||||||
public synthetic fun div (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object;
|
|
||||||
public fun div (Ljava/lang/Number;Lspace/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/Number;)Ljava/lang/Object;
|
||||||
public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)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 synthetic fun div (Ljava/lang/Object;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure;
|
||||||
@ -68,7 +66,7 @@ public final class space/kscience/kmath/viktor/ViktorNDField : space/kscience/km
|
|||||||
public fun divide (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure;
|
public fun divide (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure;
|
||||||
public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object;
|
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-Q7Xurp0 (Lspace/kscience/kmath/nd/NDStructure;)Lorg/jetbrains/bio/viktor/F64Array;
|
||||||
public synthetic fun getElementContext ()Ljava/lang/Object;
|
public synthetic fun getElementContext ()Lspace/kscience/kmath/operations/Algebra;
|
||||||
public fun getElementContext ()Lspace/kscience/kmath/operations/RealField;
|
public fun getElementContext ()Lspace/kscience/kmath/operations/RealField;
|
||||||
public final fun getF64Buffer (Lspace/kscience/kmath/nd/NDStructure;)Lorg/jetbrains/bio/viktor/F64Array;
|
public final fun getF64Buffer (Lspace/kscience/kmath/nd/NDStructure;)Lorg/jetbrains/bio/viktor/F64Array;
|
||||||
public synthetic fun getOne ()Ljava/lang/Object;
|
public synthetic fun getOne ()Ljava/lang/Object;
|
||||||
@ -96,11 +94,8 @@ public final class space/kscience/kmath/viktor/ViktorNDField : space/kscience/km
|
|||||||
public fun minus (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)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 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 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/Number;)Ljava/lang/Object;
|
|
||||||
public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
|
public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
|
||||||
public synthetic fun multiply (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lspace/kscience/kmath/nd/NDStructure;
|
|
||||||
public fun multiply (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure;
|
public fun multiply (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure;
|
||||||
public fun multiply-s8yP2C4 (Lspace/kscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lorg/jetbrains/bio/viktor/F64Array;
|
|
||||||
public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object;
|
public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object;
|
||||||
public fun number-Q7Xurp0 (Ljava/lang/Number;)Lorg/jetbrains/bio/viktor/F64Array;
|
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 fun plus (DLspace/kscience/kmath/nd/NDStructure;)Lspace/kscience/kmath/nd/NDStructure;
|
||||||
@ -122,6 +117,8 @@ public final class space/kscience/kmath/viktor/ViktorNDField : space/kscience/km
|
|||||||
public synthetic fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
|
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 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 rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2;
|
||||||
|
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 synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object;
|
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 fun sin-Q7Xurp0 (Lspace/kscience/kmath/nd/NDStructure;)Lorg/jetbrains/bio/viktor/F64Array;
|
||||||
public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object;
|
public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object;
|
||||||
|
@ -4,8 +4,9 @@ import org.jetbrains.bio.viktor.F64Array
|
|||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.nd.*
|
import space.kscience.kmath.nd.*
|
||||||
import space.kscience.kmath.operations.ExtendedField
|
import space.kscience.kmath.operations.ExtendedField
|
||||||
|
import space.kscience.kmath.operations.NumbersAddOperations
|
||||||
import space.kscience.kmath.operations.RealField
|
import space.kscience.kmath.operations.RealField
|
||||||
import space.kscience.kmath.operations.RingWithNumbers
|
import space.kscience.kmath.operations.ScaleOperations
|
||||||
|
|
||||||
@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
||||||
public inline class ViktorNDStructure(public val f64Buffer: F64Array) : MutableNDStructure<Double> {
|
public inline class ViktorNDStructure(public val f64Buffer: F64Array) : MutableNDStructure<Double> {
|
||||||
@ -26,7 +27,8 @@ public fun F64Array.asStructure(): ViktorNDStructure = ViktorNDStructure(this)
|
|||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
||||||
public class ViktorNDField(public override val shape: IntArray) : NDField<Double, RealField>,
|
public class ViktorNDField(public override val shape: IntArray) : NDField<Double, RealField>,
|
||||||
RingWithNumbers<NDStructure<Double>>, ExtendedField<NDStructure<Double>> {
|
NumbersAddOperations<NDStructure<Double>>, ExtendedField<NDStructure<Double>>,
|
||||||
|
ScaleOperations<NDStructure<Double>> {
|
||||||
|
|
||||||
public val NDStructure<Double>.f64Buffer: F64Array
|
public val NDStructure<Double>.f64Buffer: F64Array
|
||||||
get() = when {
|
get() = when {
|
||||||
@ -38,11 +40,9 @@ public class ViktorNDField(public override val shape: IntArray) : NDField<Double
|
|||||||
else -> produce { this@f64Buffer[it] }.f64Buffer
|
else -> produce { this@f64Buffer[it] }.f64Buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
public override val zero: ViktorNDStructure
|
public override val zero: ViktorNDStructure by lazy { F64Array.full(init = 0.0, shape = shape).asStructure() }
|
||||||
get() = F64Array.full(init = 0.0, shape = shape).asStructure()
|
|
||||||
|
|
||||||
public override val one: ViktorNDStructure
|
public override val one: ViktorNDStructure by lazy { F64Array.full(init = 1.0, shape = shape).asStructure() }
|
||||||
get() = F64Array.full(init = 1.0, shape = shape).asStructure()
|
|
||||||
|
|
||||||
private val strides: Strides = DefaultStrides(shape)
|
private val strides: Strides = DefaultStrides(shape)
|
||||||
|
|
||||||
@ -55,6 +55,8 @@ public class ViktorNDField(public override val shape: IntArray) : NDField<Double
|
|||||||
}
|
}
|
||||||
}.asStructure()
|
}.asStructure()
|
||||||
|
|
||||||
|
override fun NDStructure<Double>.unaryMinus(): NDStructure<Double> = -1 * this
|
||||||
|
|
||||||
public override fun NDStructure<Double>.map(transform: RealField.(Double) -> Double): ViktorNDStructure =
|
public override fun NDStructure<Double>.map(transform: RealField.(Double) -> Double): ViktorNDStructure =
|
||||||
F64Array(*this@ViktorNDField.shape).apply {
|
F64Array(*this@ViktorNDField.shape).apply {
|
||||||
this@ViktorNDField.strides.indices().forEach { index ->
|
this@ViktorNDField.strides.indices().forEach { index ->
|
||||||
@ -83,8 +85,8 @@ public class ViktorNDField(public override val shape: IntArray) : NDField<Double
|
|||||||
public override fun add(a: NDStructure<Double>, b: NDStructure<Double>): ViktorNDStructure =
|
public override fun add(a: NDStructure<Double>, b: NDStructure<Double>): ViktorNDStructure =
|
||||||
(a.f64Buffer + b.f64Buffer).asStructure()
|
(a.f64Buffer + b.f64Buffer).asStructure()
|
||||||
|
|
||||||
public override fun multiply(a: NDStructure<Double>, k: Number): ViktorNDStructure =
|
public override fun scale(a: NDStructure<Double>, value: Double): ViktorNDStructure =
|
||||||
(a.f64Buffer * k.toDouble()).asStructure()
|
(a.f64Buffer * value.toDouble()).asStructure()
|
||||||
|
|
||||||
public override inline fun NDStructure<Double>.plus(b: NDStructure<Double>): ViktorNDStructure =
|
public override inline fun NDStructure<Double>.plus(b: NDStructure<Double>): ViktorNDStructure =
|
||||||
(f64Buffer + b.f64Buffer).asStructure()
|
(f64Buffer + b.f64Buffer).asStructure()
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
pluginManagement {
|
pluginManagement {
|
||||||
repositories {
|
repositories {
|
||||||
|
maven("https://repo.kotlin.link")
|
||||||
|
mavenLocal()
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
jcenter()
|
jcenter()
|
||||||
maven("https://repo.kotlin.link")
|
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
||||||
maven("https://dl.bintray.com/kotlin/kotlinx")
|
maven("https://dl.bintray.com/kotlin/kotlinx")
|
||||||
}
|
}
|
||||||
|
|
||||||
val toolsVersion = "0.8.1"
|
val toolsVersion = "0.9.1"
|
||||||
val kotlinVersion = "1.4.30"
|
val kotlinVersion = "1.4.31"
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("kotlinx.benchmark") version "0.2.0-dev-20"
|
id("kotlinx.benchmark") version "0.2.0-dev-20"
|
||||||
|
Loading…
Reference in New Issue
Block a user