Apply context receivers to operator extension functions in main algebras
This commit is contained in:
parent
ff58985d78
commit
e65e1eedaa
@ -18,9 +18,10 @@ repositories {
|
||||
kotlin {
|
||||
jvm()
|
||||
|
||||
js(IR) {
|
||||
nodejs()
|
||||
}
|
||||
// Testing multi-receiver!
|
||||
// js(IR) {
|
||||
// nodejs()
|
||||
// }
|
||||
|
||||
sourceSets {
|
||||
all {
|
||||
@ -74,7 +75,8 @@ benchmark {
|
||||
// Setup configurations
|
||||
targets {
|
||||
register("jvm")
|
||||
register("js")
|
||||
// Testing multi-receiver!
|
||||
// register("js")
|
||||
}
|
||||
|
||||
fun kotlinx.benchmark.gradle.BenchmarkConfiguration.commonConfiguration() {
|
||||
@ -158,7 +160,7 @@ kotlin.sourceSets.all {
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> {
|
||||
kotlinOptions {
|
||||
jvmTarget = "11"
|
||||
freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all" + "-Xlambdas=indy"
|
||||
freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all" + "-Xlambdas=indy" + "-Xcontext-receivers"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,10 +11,7 @@ import kotlinx.benchmark.Scope
|
||||
import kotlinx.benchmark.State
|
||||
import space.kscience.kmath.asm.compileToExpression
|
||||
import space.kscience.kmath.expressions.*
|
||||
import space.kscience.kmath.operations.Algebra
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.bindSymbol
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.*
|
||||
import kotlin.math.sin
|
||||
import kotlin.random.Random
|
||||
|
||||
|
@ -11,7 +11,7 @@ allprojects {
|
||||
}
|
||||
|
||||
group = "space.kscience"
|
||||
version = "0.3.0-dev-21"
|
||||
version = "0.4.0-dev-1"
|
||||
}
|
||||
|
||||
subprojects {
|
||||
|
@ -4,4 +4,4 @@
|
||||
#
|
||||
|
||||
kotlin.code.style=official
|
||||
toolsVersion=0.11.2-kotlin-1.6.10
|
||||
toolsVersion=0.11.2-kotlin-1.6.20
|
||||
|
@ -207,7 +207,7 @@ public object EjmlLinearSpace${ops} : EjmlLinearSpace<${type}, ${kmathAlgebra},
|
||||
structure.getFeature(type)?.let { return it }
|
||||
val origin = structure.toEjml().origin
|
||||
|
||||
return when (type) {
|
||||
return type.cast(when (type) {
|
||||
${
|
||||
if (isDense)
|
||||
""" InverseMatrixFeature::class -> object : InverseMatrixFeature<${type}> {
|
||||
@ -318,8 +318,8 @@ public object EjmlLinearSpace${ops} : EjmlLinearSpace<${type}, ${kmathAlgebra},
|
||||
}"""
|
||||
}
|
||||
|
||||
else -> null
|
||||
}?.let(type::cast)
|
||||
else -> return null
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -62,10 +62,6 @@ val c2 = ComplexField { c1 - 1.0 } // Returns: Complex(re=0.0, im=2.0)
|
||||
val c3 = ComplexField { c1 - i * 2.0 }
|
||||
```
|
||||
|
||||
**Note**: In theory it is possible to add behaviors directly to the context, but as for now Kotlin does not support
|
||||
that. Watch [KT-10468](https://youtrack.jetbrains.com/issue/KT-10468) and
|
||||
[KEEP-176](https://github.com/Kotlin/KEEP/pull/176) for updates.
|
||||
|
||||
## Nested fields
|
||||
|
||||
Contexts allow one to build more complex structures. For example, it is possible to create a `Matrix` from complex
|
||||
|
@ -61,7 +61,8 @@ kotlin.sourceSets.all {
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> {
|
||||
kotlinOptions {
|
||||
jvmTarget = "11"
|
||||
freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all" + "-Xopt-in=kotlin.RequiresOptIn" + "-Xlambdas=indy"
|
||||
freeCompilerArgs =
|
||||
freeCompilerArgs + "-Xjvm-default=all" + "-Xopt-in=kotlin.RequiresOptIn" + "-Xlambdas=indy" + "-Xcontext-receivers"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,7 @@ package space.kscience.kmath.ast
|
||||
import space.kscience.kmath.asm.compileToExpression
|
||||
import space.kscience.kmath.expressions.MstExtendedField
|
||||
import space.kscience.kmath.expressions.Symbol.Companion.x
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.*
|
||||
|
||||
fun main() {
|
||||
val expr = MstExtendedField {
|
||||
|
@ -13,6 +13,8 @@ import space.kscience.kmath.distributions.NormalDistribution
|
||||
import space.kscience.kmath.expressions.chiSquaredExpression
|
||||
import space.kscience.kmath.expressions.symbol
|
||||
import space.kscience.kmath.operations.asIterable
|
||||
import space.kscience.kmath.operations.plus
|
||||
import space.kscience.kmath.operations.times
|
||||
import space.kscience.kmath.operations.toList
|
||||
import space.kscience.kmath.optimization.FunctionOptimizationTarget
|
||||
import space.kscience.kmath.optimization.optimizeWith
|
||||
|
@ -14,6 +14,8 @@ import space.kscience.kmath.expressions.Symbol
|
||||
import space.kscience.kmath.expressions.binding
|
||||
import space.kscience.kmath.expressions.symbol
|
||||
import space.kscience.kmath.operations.asIterable
|
||||
import space.kscience.kmath.operations.plus
|
||||
import space.kscience.kmath.operations.times
|
||||
import space.kscience.kmath.operations.toList
|
||||
import space.kscience.kmath.optimization.QowOptimizer
|
||||
import space.kscience.kmath.optimization.chiSquaredOrNull
|
||||
|
@ -13,6 +13,7 @@ import space.kscience.kmath.nd.structureND
|
||||
import space.kscience.kmath.nd.withNdAlgebra
|
||||
import space.kscience.kmath.operations.algebra
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.times
|
||||
|
||||
fun main(): Unit = Double.algebra {
|
||||
withNdAlgebra(2, 2) {
|
||||
@ -31,4 +32,4 @@ fun main(): Unit = Double.algebra {
|
||||
//the value is nullable because in some cases the integration could not succeed
|
||||
println(result.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ package space.kscience.kmath.operations
|
||||
|
||||
import space.kscience.kmath.commons.linear.CMLinearSpace
|
||||
import space.kscience.kmath.linear.matrix
|
||||
import space.kscience.kmath.nd.DoubleBufferND
|
||||
import space.kscience.kmath.nd.Shape
|
||||
import space.kscience.kmath.nd.Structure2D
|
||||
import space.kscience.kmath.nd.ndAlgebra
|
||||
@ -21,7 +20,7 @@ fun main() {
|
||||
|
||||
val cmMatrix: Structure2D<Double> = CMLinearSpace.matrix(2, 2)(0.0, 1.0, 0.0, 3.0)
|
||||
|
||||
val res: DoubleBufferND = DoubleField.ndAlgebra {
|
||||
val res = DoubleField.ndAlgebra {
|
||||
exp(viktorStructure) + 2.0 * cmMatrix
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,8 @@ import space.kscience.kmath.nd.ndAlgebra
|
||||
import space.kscience.kmath.nd.structureND
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.plus
|
||||
import space.kscience.kmath.operations.times
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
fun main() {
|
||||
|
@ -80,7 +80,7 @@ class StreamDoubleFieldND(override val shape: IntArray) : FieldND<Double, Double
|
||||
return BufferND(strides, array.asBuffer())
|
||||
}
|
||||
|
||||
override fun StructureND<Double>.unaryMinus(): StructureND<Double> = map { -it }
|
||||
override fun negate(arg: StructureND<Double>): StructureND<Double> = arg.map { -it }
|
||||
|
||||
override fun scale(a: StructureND<Double>, value: Double): StructureND<Double> = a.map { it * value }
|
||||
|
||||
|
@ -5,10 +5,7 @@
|
||||
|
||||
package space.kscience.kmath.structures
|
||||
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.buffer
|
||||
import space.kscience.kmath.operations.bufferAlgebra
|
||||
import space.kscience.kmath.operations.withSize
|
||||
import space.kscience.kmath.operations.*
|
||||
|
||||
inline fun <reified R : Any> MutableBuffer.Companion.same(
|
||||
n: Int,
|
||||
|
@ -5,12 +5,13 @@
|
||||
|
||||
package space.kscience.kmath.tensors
|
||||
|
||||
import space.kscience.kmath.nd.StructureND
|
||||
import space.kscience.kmath.operations.abs
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.tensors.core.DoubleTensor
|
||||
import space.kscience.kmath.operations.minus
|
||||
import space.kscience.kmath.operations.plus
|
||||
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
|
||||
|
||||
import kotlin.math.abs
|
||||
|
||||
// OLS estimator using SVD
|
||||
|
||||
fun main() {
|
||||
@ -48,14 +49,16 @@ fun main() {
|
||||
|
||||
|
||||
// inverse Sigma matrix can be restored from singular values with diagonalEmbedding function
|
||||
val sigma = diagonalEmbedding(singValues.map{ if (abs(it) < 1e-3) 0.0 else 1.0/it })
|
||||
val sigma = diagonalEmbedding(singValues.map { if (abs(it) < 1e-3) 0.0 else 1.0 / it })
|
||||
|
||||
val alphaOLS = v dot sigma dot u.transpose() dot y
|
||||
println("Estimated alpha:\n" +
|
||||
"$alphaOLS")
|
||||
println(
|
||||
"Estimated alpha:\n" +
|
||||
"$alphaOLS"
|
||||
)
|
||||
|
||||
// figure out MSE of approximation
|
||||
fun mse(yTrue: DoubleTensor, yPred: DoubleTensor): Double {
|
||||
fun mse(yTrue: StructureND<Double>, yPred: StructureND<Double>): Double {
|
||||
require(yTrue.shape.size == 1)
|
||||
require(yTrue.shape contentEquals yPred.shape)
|
||||
|
||||
|
@ -5,10 +5,11 @@
|
||||
|
||||
package space.kscience.kmath.tensors
|
||||
|
||||
import space.kscience.kmath.operations.plus
|
||||
import space.kscience.kmath.operations.times
|
||||
import space.kscience.kmath.tensors.core.tensorAlgebra
|
||||
import space.kscience.kmath.tensors.core.withBroadcast
|
||||
|
||||
|
||||
// simple PCA
|
||||
|
||||
fun main(): Unit = Double.tensorAlgebra.withBroadcast { // work in context with broadcast methods
|
||||
|
@ -5,10 +5,11 @@
|
||||
|
||||
package space.kscience.kmath.tensors
|
||||
|
||||
import space.kscience.kmath.operations.div
|
||||
import space.kscience.kmath.operations.minus
|
||||
import space.kscience.kmath.tensors.core.tensorAlgebra
|
||||
import space.kscience.kmath.tensors.core.withBroadcast
|
||||
|
||||
|
||||
// Dataset normalization
|
||||
|
||||
fun main() = Double.tensorAlgebra.withBroadcast { // work in context with broadcast methods
|
||||
|
@ -10,6 +10,8 @@ import org.jetbrains.kotlinx.multik.api.ndarray
|
||||
import space.kscience.kmath.multik.multikAlgebra
|
||||
import space.kscience.kmath.nd.one
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.minus
|
||||
import space.kscience.kmath.operations.plus
|
||||
|
||||
fun main(): Unit = with(DoubleField.multikAlgebra) {
|
||||
val a = Multik.ndarray(intArrayOf(1, 2, 3)).asType<Double>().wrap()
|
||||
|
@ -5,11 +5,9 @@
|
||||
|
||||
package space.kscience.kmath.tensors
|
||||
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra
|
||||
import space.kscience.kmath.tensors.core.DoubleTensor
|
||||
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
|
||||
import space.kscience.kmath.tensors.core.copyArray
|
||||
import space.kscience.kmath.misc.PerformancePitfall
|
||||
import space.kscience.kmath.operations.*
|
||||
import space.kscience.kmath.tensors.core.*
|
||||
import kotlin.math.sqrt
|
||||
|
||||
const val seed = 100500L
|
||||
@ -27,13 +25,10 @@ open class Activation(
|
||||
val activation: (DoubleTensor) -> DoubleTensor,
|
||||
val activationDer: (DoubleTensor) -> DoubleTensor,
|
||||
) : Layer {
|
||||
override fun forward(input: DoubleTensor): DoubleTensor {
|
||||
return activation(input)
|
||||
}
|
||||
override fun forward(input: DoubleTensor): DoubleTensor = activation(input)
|
||||
|
||||
override fun backward(input: DoubleTensor, outputError: DoubleTensor): DoubleTensor {
|
||||
return DoubleTensorAlgebra { outputError * activationDer(input) }
|
||||
}
|
||||
override fun backward(input: DoubleTensor, outputError: DoubleTensor): DoubleTensor =
|
||||
DoubleTensorAlgebra { outputError * activationDer(input) }
|
||||
}
|
||||
|
||||
fun relu(x: DoubleTensor): DoubleTensor = DoubleTensorAlgebra {
|
||||
@ -106,8 +101,8 @@ fun accuracy(yPred: DoubleTensor, yTrue: DoubleTensor): Double {
|
||||
}
|
||||
|
||||
// neural network class
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
class NeuralNetwork(private val layers: List<Layer>) {
|
||||
@OptIn(PerformancePitfall::class)
|
||||
private fun softMaxLoss(yPred: DoubleTensor, yTrue: DoubleTensor): DoubleTensor = BroadcastDoubleTensorAlgebra {
|
||||
|
||||
val onesForAnswers = yPred.zeroesLike()
|
||||
@ -174,7 +169,7 @@ class NeuralNetwork(private val layers: List<Layer>) {
|
||||
}
|
||||
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
@OptIn(PerformancePitfall::class)
|
||||
fun main() = BroadcastDoubleTensorAlgebra {
|
||||
val features = 5
|
||||
val sampleSize = 250
|
||||
|
@ -84,3 +84,8 @@ readme {
|
||||
ref = "src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt"
|
||||
) { "Extendable MST rendering" }
|
||||
}
|
||||
|
||||
// Testing multi-receiver!
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile> {
|
||||
enabled = false
|
||||
}
|
||||
|
@ -9,9 +9,7 @@ import space.kscience.kmath.expressions.MstField
|
||||
import space.kscience.kmath.expressions.MstRing
|
||||
import space.kscience.kmath.expressions.Symbol.Companion.x
|
||||
import space.kscience.kmath.expressions.interpret
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.IntRing
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.*
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
@ -8,8 +8,7 @@ package space.kscience.kmath.ast
|
||||
import space.kscience.kmath.expressions.MstExtendedField
|
||||
import space.kscience.kmath.expressions.Symbol.Companion.x
|
||||
import space.kscience.kmath.expressions.invoke
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.*
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
@ -68,7 +68,7 @@ public class DerivativeStructureField(
|
||||
|
||||
public fun DerivativeStructure.derivative(vararg symbols: Symbol): Double = derivative(symbols.toList())
|
||||
|
||||
override fun DerivativeStructure.unaryMinus(): DerivativeStructure = negate()
|
||||
override fun negate(arg: DerivativeStructure): DerivativeStructure = arg.negate()
|
||||
|
||||
override fun add(left: DerivativeStructure, right: DerivativeStructure): DerivativeStructure = left.add(right)
|
||||
|
||||
|
@ -6,6 +6,9 @@
|
||||
package space.kscience.kmath.commons.expressions
|
||||
|
||||
import space.kscience.kmath.expressions.*
|
||||
import space.kscience.kmath.operations.plus
|
||||
import space.kscience.kmath.operations.times
|
||||
import space.kscience.kmath.operations.unaryMinus
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.test.Test
|
||||
|
@ -13,7 +13,7 @@ import space.kscience.kmath.expressions.Symbol.Companion.x
|
||||
import space.kscience.kmath.expressions.Symbol.Companion.y
|
||||
import space.kscience.kmath.expressions.chiSquaredExpression
|
||||
import space.kscience.kmath.expressions.symbol
|
||||
import space.kscience.kmath.operations.map
|
||||
import space.kscience.kmath.operations.*
|
||||
import space.kscience.kmath.optimization.*
|
||||
import space.kscience.kmath.stat.RandomGenerator
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
|
@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
id("ru.mipt.npm.gradle.common")
|
||||
id("ru.mipt.npm.gradle.native")
|
||||
// id("ru.mipt.npm.gradle.native")
|
||||
}
|
||||
|
||||
kotlin.sourceSets {
|
||||
@ -29,3 +29,8 @@ readme {
|
||||
ref = "src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt"
|
||||
)
|
||||
}
|
||||
|
||||
// Testing multi-receiver!
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile> {
|
||||
enabled = false
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
package space.kscience.kmath.complex
|
||||
|
||||
import space.kscience.kmath.complex.ComplexField.plus
|
||||
import space.kscience.kmath.memory.MemoryReader
|
||||
import space.kscience.kmath.memory.MemorySpec
|
||||
import space.kscience.kmath.memory.MemoryWriter
|
||||
@ -71,14 +72,13 @@ public object ComplexField :
|
||||
*/
|
||||
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)
|
||||
|
||||
override fun add(left: Complex, right: Complex): Complex = Complex(left.re + right.re, left.im + right.im)
|
||||
// override fun multiply(a: Complex, k: Number): Complex = Complex(a.re * k.toDouble(), a.im * k.toDouble())
|
||||
override fun negate(arg: Complex): Complex = Complex(-arg.re, -arg.im)
|
||||
|
||||
override fun multiply(left: Complex, right: Complex): Complex =
|
||||
Complex(left.re * right.re - left.im * right.im, left.re * right.im + left.im * right.re)
|
||||
@ -107,8 +107,6 @@ public object ComplexField :
|
||||
}
|
||||
}
|
||||
|
||||
override operator fun Complex.div(k: Number): Complex = Complex(re / k.toDouble(), im / k.toDouble())
|
||||
|
||||
override fun sin(arg: Complex): Complex = i * (exp(-i * arg) - exp(i * arg)) / 2.0
|
||||
override fun cos(arg: Complex): Complex = (exp(-i * arg) + exp(i * arg)) / 2.0
|
||||
|
||||
@ -139,61 +137,65 @@ public object ComplexField :
|
||||
|
||||
override fun ln(arg: Complex): Complex = ln(arg.r) + i * atan2(arg.im, arg.re)
|
||||
|
||||
/**
|
||||
* Adds complex number to real one.
|
||||
*
|
||||
* @receiver the augend.
|
||||
* @param c the addend.
|
||||
* @return the sum.
|
||||
*/
|
||||
public operator fun Double.plus(c: Complex): Complex = add(this.toComplex(), c)
|
||||
|
||||
/**
|
||||
* Subtracts complex number from real one.
|
||||
*
|
||||
* @receiver the minuend.
|
||||
* @param c the subtrahend.
|
||||
* @return the difference.
|
||||
*/
|
||||
public operator fun Double.minus(c: Complex): Complex = add(this.toComplex(), -c)
|
||||
|
||||
/**
|
||||
* Adds real number to complex one.
|
||||
*
|
||||
* @receiver the augend.
|
||||
* @param d the addend.
|
||||
* @return the sum.
|
||||
*/
|
||||
public operator fun Complex.plus(d: Double): Complex = d + this
|
||||
|
||||
/**
|
||||
* Subtracts real number from complex one.
|
||||
*
|
||||
* @receiver the minuend.
|
||||
* @param d the subtrahend.
|
||||
* @return the difference.
|
||||
*/
|
||||
public operator fun Complex.minus(d: Double): Complex = add(this, -d.toComplex())
|
||||
|
||||
/**
|
||||
* Multiplies real number by complex one.
|
||||
*
|
||||
* @receiver the multiplier.
|
||||
* @param c the multiplicand.
|
||||
* @receiver the product.
|
||||
*/
|
||||
public operator fun Double.times(c: Complex): Complex = Complex(c.re * this, c.im * this)
|
||||
|
||||
override fun norm(arg: Complex): Complex = sqrt(arg.conjugate * arg)
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds complex number to real one.
|
||||
*
|
||||
* @receiver the augend.
|
||||
* @param c the addend.
|
||||
* @return the sum.
|
||||
*/
|
||||
context(ComplexField)
|
||||
public operator fun Double.plus(c: Complex): Complex = add(toComplex(), c)
|
||||
|
||||
/**
|
||||
* Adds real number to complex one.
|
||||
*
|
||||
* @receiver the augend.
|
||||
* @param d the addend.
|
||||
* @return the sum.
|
||||
*/
|
||||
context(ComplexField)
|
||||
public operator fun Complex.plus(d: Double): Complex = d + this
|
||||
|
||||
/**
|
||||
* Subtracts complex number from real one.
|
||||
*
|
||||
* @receiver the minuend.
|
||||
* @param c the subtrahend.
|
||||
* @return the difference.
|
||||
*/
|
||||
context(ComplexField)
|
||||
public operator fun Double.minus(c: Complex): Complex = add(toComplex(), -c)
|
||||
|
||||
/**
|
||||
* Subtracts real number from complex one.
|
||||
*
|
||||
* @receiver the minuend.
|
||||
* @param d the subtrahend.
|
||||
* @return the difference.
|
||||
*/
|
||||
context(ComplexField)
|
||||
public operator fun Complex.minus(d: Double): Complex = add(this, -d.toComplex())
|
||||
|
||||
/**
|
||||
* Multiplies real number by complex one.
|
||||
*
|
||||
* @receiver the multiplier.
|
||||
* @param c the multiplicand.
|
||||
* @receiver the product.
|
||||
*/
|
||||
context(ComplexField)
|
||||
public operator fun Double.times(c: Complex): Complex = Complex(c.re * this, c.im * this)
|
||||
|
||||
/**
|
||||
* Represents `double`-based complex number.
|
||||
*
|
||||
* @property re The real part.
|
||||
* @property im The imaginary part.
|
||||
*/
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
public data class Complex(val re: Double, val im: Double) {
|
||||
public constructor(re: Number, im: Number) : this(re.toDouble(), im.toDouble())
|
||||
public constructor(re: Number) : this(re.toDouble(), 0.0)
|
||||
|
@ -166,10 +166,7 @@ public object QuaternionField : Field<Quaternion>, Norm<Quaternion, Quaternion>,
|
||||
override operator fun Quaternion.plus(other: Number): Quaternion = Quaternion(w + other.toDouble(), x, y, z)
|
||||
override operator fun Quaternion.minus(other: Number): Quaternion = Quaternion(w - other.toDouble(), x, y, z)
|
||||
|
||||
override operator fun Number.times(arg: Quaternion): Quaternion =
|
||||
Quaternion(toDouble() * arg.w, toDouble() * arg.x, toDouble() * arg.y, toDouble() * arg.z)
|
||||
|
||||
override fun Quaternion.unaryMinus(): Quaternion = Quaternion(-w, -x, -y, -z)
|
||||
override fun negate(arg: Quaternion): Quaternion = Quaternion(-arg.w, -arg.x, -arg.y, -arg.z)
|
||||
override fun norm(arg: Quaternion): Quaternion = sqrt(arg.conjugate * arg)
|
||||
|
||||
override fun bindSymbolOrNull(value: String): Quaternion? = when (value) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
package space.kscience.kmath.complex
|
||||
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.*
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.abs
|
||||
import kotlin.test.Test
|
||||
|
@ -6,6 +6,8 @@
|
||||
package space.kscience.kmath.complex
|
||||
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.minus
|
||||
import space.kscience.kmath.operations.plus
|
||||
import kotlin.math.sqrt
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
@ -9,6 +9,8 @@ import space.kscience.kmath.expressions.FunctionalExpressionField
|
||||
import space.kscience.kmath.expressions.invoke
|
||||
import space.kscience.kmath.expressions.symbol
|
||||
import space.kscience.kmath.operations.bindSymbol
|
||||
import space.kscience.kmath.operations.plus
|
||||
import space.kscience.kmath.operations.times
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
package space.kscience.kmath.complex
|
||||
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.plus
|
||||
import space.kscience.kmath.operations.times
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
id("ru.mipt.npm.gradle.common")
|
||||
id("ru.mipt.npm.gradle.native")
|
||||
// id("ru.mipt.npm.gradle.native")
|
||||
// id("com.xcporter.metaview") version "0.0.5"
|
||||
}
|
||||
|
||||
@ -72,3 +72,8 @@ readme {
|
||||
ref = "src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt"
|
||||
) { "Automatic differentiation" }
|
||||
}
|
||||
|
||||
// Testing multi-receiver!
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile> {
|
||||
enabled = false
|
||||
}
|
||||
|
@ -51,8 +51,8 @@ public open class FunctionalExpressionGroup<T, out A : Group<T>>(
|
||||
) : FunctionalExpressionAlgebra<T, A>(algebra), Group<Expression<T>> {
|
||||
override val zero: Expression<T> get() = const(algebra.zero)
|
||||
|
||||
override fun Expression<T>.unaryMinus(): Expression<T> =
|
||||
unaryOperation(GroupOps.MINUS_OPERATION, this)
|
||||
override fun negate(arg: Expression<T>): Expression<T> =
|
||||
unaryOperation(GroupOps.MINUS_OPERATION, arg)
|
||||
|
||||
/**
|
||||
* Builds an Expression of addition of two another expressions.
|
||||
@ -60,26 +60,25 @@ public open class FunctionalExpressionGroup<T, out A : Group<T>>(
|
||||
override fun add(left: Expression<T>, right: Expression<T>): Expression<T> =
|
||||
binaryOperation(GroupOps.PLUS_OPERATION, left, right)
|
||||
|
||||
// /**
|
||||
// * Builds an Expression of multiplication of expression by number.
|
||||
// */
|
||||
// override fun multiply(a: Expression<T>, k: Number): Expression<T> = Expression { arguments ->
|
||||
// algebra.multiply(a.invoke(arguments), k)
|
||||
// }
|
||||
|
||||
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 T.plus(arg: Expression<T>): Expression<T> = arg + this
|
||||
public operator fun T.minus(arg: Expression<T>): Expression<T> = arg - this
|
||||
|
||||
override fun unaryOperationFunction(operation: String): (arg: Expression<T>) -> Expression<T> =
|
||||
super<FunctionalExpressionAlgebra>.unaryOperationFunction(operation)
|
||||
|
||||
override fun binaryOperationFunction(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> =
|
||||
super<FunctionalExpressionAlgebra>.binaryOperationFunction(operation)
|
||||
|
||||
}
|
||||
|
||||
context(FunctionalExpressionGroup<T, A>)
|
||||
public operator fun <T, A : Group<T>> Expression<T>.plus(arg: T): Expression<T> = this + const(arg)
|
||||
|
||||
context(FunctionalExpressionGroup<T, A>)
|
||||
public operator fun <T, A : Group<T>> Expression<T>.minus(arg: T): Expression<T> = this - const(arg)
|
||||
|
||||
context(FunctionalExpressionGroup<T, A>)
|
||||
public operator fun <T, A : Group<T>> T.plus(arg: Expression<T>): Expression<T> = arg + this
|
||||
|
||||
context(FunctionalExpressionGroup<T, A>)
|
||||
public operator fun <T, A : Group<T>> T.minus(arg: Expression<T>): Expression<T> = arg - this
|
||||
|
||||
public open class FunctionalExpressionRing<T, out A : Ring<T>>(
|
||||
algebra: A,
|
||||
) : FunctionalExpressionGroup<T, A>(algebra), Ring<Expression<T>> {
|
||||
@ -91,9 +90,6 @@ public open class FunctionalExpressionRing<T, out A : Ring<T>>(
|
||||
override fun multiply(left: Expression<T>, right: Expression<T>): Expression<T> =
|
||||
binaryOperationFunction(RingOps.TIMES_OPERATION)(left, right)
|
||||
|
||||
public operator fun Expression<T>.times(arg: T): Expression<T> = this * const(arg)
|
||||
public operator fun T.times(arg: Expression<T>): Expression<T> = arg * this
|
||||
|
||||
override fun unaryOperationFunction(operation: String): (arg: Expression<T>) -> Expression<T> =
|
||||
super<FunctionalExpressionGroup>.unaryOperationFunction(operation)
|
||||
|
||||
@ -101,6 +97,12 @@ public open class FunctionalExpressionRing<T, out A : Ring<T>>(
|
||||
super<FunctionalExpressionGroup>.binaryOperationFunction(operation)
|
||||
}
|
||||
|
||||
context(FunctionalExpressionRing<T, A>)
|
||||
public operator fun <T, A : Ring<T>> Expression<T>.times(arg: T): Expression<T> = this * const(arg)
|
||||
|
||||
context(FunctionalExpressionRing<T, A>)
|
||||
public operator fun <T, A : Ring<T>> T.times(arg: Expression<T>): Expression<T> = arg * this
|
||||
|
||||
public open class FunctionalExpressionField<T, out A : Field<T>>(
|
||||
algebra: A,
|
||||
) : FunctionalExpressionRing<T, A>(algebra), Field<Expression<T>>, ScaleOperations<Expression<T>> {
|
||||
@ -110,9 +112,6 @@ public open class FunctionalExpressionField<T, out A : Field<T>>(
|
||||
override fun divide(left: Expression<T>, right: Expression<T>): Expression<T> =
|
||||
binaryOperationFunction(FieldOps.DIV_OPERATION)(left, right)
|
||||
|
||||
public operator fun Expression<T>.div(arg: T): Expression<T> = this / const(arg)
|
||||
public operator fun T.div(arg: Expression<T>): Expression<T> = arg / this
|
||||
|
||||
override fun unaryOperationFunction(operation: String): (arg: Expression<T>) -> Expression<T> =
|
||||
super<FunctionalExpressionRing>.unaryOperationFunction(operation)
|
||||
|
||||
@ -127,6 +126,12 @@ public open class FunctionalExpressionField<T, out A : Field<T>>(
|
||||
super<FunctionalExpressionRing>.bindSymbolOrNull(value)
|
||||
}
|
||||
|
||||
context(FunctionalExpressionField<T, A>)
|
||||
public operator fun <T, A : Field<T>> Expression<T>.div(arg: T): Expression<T> = this / const(arg)
|
||||
|
||||
context(FunctionalExpressionField<T, A>)
|
||||
public operator fun <T, A : Field<T>> T.div(arg: Expression<T>): Expression<T> = arg / this
|
||||
|
||||
public open class FunctionalExpressionExtendedField<T, out A : ExtendedField<T>>(
|
||||
algebra: A,
|
||||
) : FunctionalExpressionField<T, A>(algebra), ExtendedField<Expression<T>> {
|
||||
|
@ -32,14 +32,12 @@ public object MstGroup : Group<MST>, NumericAlgebra<MST>, ScaleOperations<MST> {
|
||||
override fun number(value: Number): MST.Numeric = MstNumericAlgebra.number(value)
|
||||
override fun bindSymbolOrNull(value: String): Symbol = MstNumericAlgebra.bindSymbolOrNull(value)
|
||||
override fun add(left: MST, right: MST): MST.Binary = binaryOperationFunction(GroupOps.PLUS_OPERATION)(left, right)
|
||||
override operator fun MST.unaryPlus(): MST.Unary =
|
||||
unaryOperationFunction(GroupOps.PLUS_OPERATION)(this)
|
||||
|
||||
override operator fun MST.unaryMinus(): MST.Unary =
|
||||
unaryOperationFunction(GroupOps.MINUS_OPERATION)(this)
|
||||
override fun negate(arg: MST): MST.Unary =
|
||||
unaryOperationFunction(GroupOps.MINUS_OPERATION)(arg)
|
||||
|
||||
override operator fun MST.minus(arg: MST): MST.Binary =
|
||||
binaryOperationFunction(GroupOps.MINUS_OPERATION)(this, arg)
|
||||
override fun subtract(left: MST, right: MST): MST.Binary =
|
||||
binaryOperationFunction(GroupOps.MINUS_OPERATION)(left, right)
|
||||
|
||||
override fun scale(a: MST, value: Double): MST.Binary =
|
||||
binaryOperationFunction(RingOps.TIMES_OPERATION)(a, number(value))
|
||||
@ -70,9 +68,8 @@ public object MstRing : Ring<MST>, NumbersAddOps<MST>, ScaleOperations<MST> {
|
||||
override fun multiply(left: MST, right: MST): MST.Binary =
|
||||
binaryOperationFunction(RingOps.TIMES_OPERATION)(left, right)
|
||||
|
||||
override operator fun MST.unaryPlus(): MST.Unary = MstGroup { +this@unaryPlus }
|
||||
override operator fun MST.unaryMinus(): MST.Unary = MstGroup { -this@unaryMinus }
|
||||
override operator fun MST.minus(arg: MST): MST.Binary = MstGroup { this@minus - arg }
|
||||
override fun negate(arg: MST): MST.Unary = MstGroup.negate(arg)
|
||||
override fun subtract(left: MST, right: MST): MST.Binary = MstGroup.subtract(left, right)
|
||||
|
||||
override fun binaryOperationFunction(operation: String): (left: MST, right: MST) -> MST.Binary =
|
||||
MstGroup.binaryOperationFunction(operation)
|
||||
@ -101,9 +98,8 @@ public object MstField : Field<MST>, NumbersAddOps<MST>, ScaleOperations<MST> {
|
||||
override fun divide(left: MST, right: MST): MST.Binary =
|
||||
binaryOperationFunction(FieldOps.DIV_OPERATION)(left, right)
|
||||
|
||||
override operator fun MST.unaryPlus(): MST.Unary = MstRing { +this@unaryPlus }
|
||||
override operator fun MST.unaryMinus(): MST.Unary = MstRing { -this@unaryMinus }
|
||||
override operator fun MST.minus(arg: MST): MST.Binary = MstRing { this@minus - arg }
|
||||
override fun negate(arg: MST): MST.Unary = MstRing.negate(arg)
|
||||
override fun subtract(left: MST, right: MST): MST.Binary = MstRing.subtract(left, right)
|
||||
|
||||
override fun binaryOperationFunction(operation: String): (left: MST, right: MST) -> MST.Binary =
|
||||
MstRing.binaryOperationFunction(operation)
|
||||
@ -142,9 +138,8 @@ public object MstExtendedField : ExtendedField<MST>, NumericAlgebra<MST> {
|
||||
|
||||
override fun multiply(left: MST, right: MST): MST.Binary = MstField.multiply(left, right)
|
||||
override fun divide(left: MST, right: MST): MST.Binary = MstField.divide(left, right)
|
||||
override operator fun MST.unaryPlus(): MST.Unary = MstField { +this@unaryPlus }
|
||||
override operator fun MST.unaryMinus(): MST.Unary = MstField { -this@unaryMinus }
|
||||
override operator fun MST.minus(arg: MST): MST.Binary = MstField { this@minus - arg }
|
||||
override fun negate(arg: MST): MST.Unary = MstField.negate(arg)
|
||||
override fun subtract(left: MST, right: MST): MST.Binary = MstField.subtract(left, right)
|
||||
|
||||
override fun power(arg: MST, pow: Number): MST.Binary =
|
||||
binaryOperationFunction(PowerOperations.POW_OPERATION)(arg, number(pow))
|
||||
|
@ -163,8 +163,8 @@ public open class SimpleAutoDiffField<T : Any, F : Field<T>>(
|
||||
// derive(const { this@minus.value - one * b.toDouble() }) { z -> d += z.d }
|
||||
|
||||
|
||||
override fun AutoDiffValue<T>.unaryMinus(): AutoDiffValue<T> =
|
||||
derive(const { -value }) { z -> d -= z.d }
|
||||
override fun negate(arg: AutoDiffValue<T>): AutoDiffValue<T> =
|
||||
derive(const { -arg.value }) { z -> arg.d -= z.d }
|
||||
|
||||
// Basic math (+, -, *, /)
|
||||
|
||||
|
@ -5,8 +5,7 @@
|
||||
|
||||
package space.kscience.kmath.expressions
|
||||
|
||||
import space.kscience.kmath.operations.ExtendedField
|
||||
import space.kscience.kmath.operations.asIterable
|
||||
import space.kscience.kmath.operations.*
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.indices
|
||||
import kotlin.jvm.JvmName
|
||||
|
@ -9,9 +9,7 @@ import space.kscience.kmath.misc.PerformancePitfall
|
||||
import space.kscience.kmath.nd.DoubleFieldOpsND
|
||||
import space.kscience.kmath.nd.as2D
|
||||
import space.kscience.kmath.nd.asND
|
||||
import space.kscience.kmath.operations.DoubleBufferOps
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.*
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
|
||||
|
@ -10,10 +10,7 @@ import space.kscience.kmath.nd.MutableStructure2D
|
||||
import space.kscience.kmath.nd.Structure2D
|
||||
import space.kscience.kmath.nd.StructureFeature
|
||||
import space.kscience.kmath.nd.as1D
|
||||
import space.kscience.kmath.operations.BufferRingOps
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.Ring
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.*
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.BufferFactory
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
|
@ -89,6 +89,5 @@ public class TransposedFeature<out T : Any>(public val original: Matrix<T>) : Ma
|
||||
* Create a virtual transposed matrix without copying anything. `A.transpose().transpose() === A`
|
||||
*/
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
public fun <T : Any> Matrix<T>.transpose(): Matrix<T> = getFeature(TransposedFeature::class)?.original as? Matrix<T>
|
||||
?: VirtualMatrix(colNum, rowNum) { i, j -> get(j, i) }.withFeature(TransposedFeature(this))
|
||||
|
@ -7,6 +7,7 @@ package space.kscience.kmath.misc
|
||||
|
||||
import space.kscience.kmath.operations.Ring
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.plus
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
/**
|
||||
|
@ -127,51 +127,54 @@ public interface GroupOpsND<T, out A : GroupOps<T>> : GroupOps<StructureND<T>>,
|
||||
override fun add(left: StructureND<T>, right: StructureND<T>): StructureND<T> =
|
||||
zip(left, right) { aValue, bValue -> add(aValue, bValue) }
|
||||
|
||||
// TODO move to extensions after KEEP-176
|
||||
|
||||
/**
|
||||
* Adds an ND structure to an element of it.
|
||||
*
|
||||
* @receiver the augend.
|
||||
* @param arg the addend.
|
||||
* @return the sum.
|
||||
*/
|
||||
@OptIn(PerformancePitfall::class)
|
||||
public operator fun StructureND<T>.plus(arg: T): StructureND<T> = this.map { value -> add(arg, value) }
|
||||
|
||||
/**
|
||||
* Subtracts an element from ND structure of it.
|
||||
*
|
||||
* @receiver the dividend.
|
||||
* @param arg the divisor.
|
||||
* @return the quotient.
|
||||
*/
|
||||
@OptIn(PerformancePitfall::class)
|
||||
public operator fun StructureND<T>.minus(arg: T): StructureND<T> = this.map { value -> add(arg, -value) }
|
||||
|
||||
/**
|
||||
* Adds an element to ND structure of it.
|
||||
*
|
||||
* @receiver the augend.
|
||||
* @param arg the addend.
|
||||
* @return the sum.
|
||||
*/
|
||||
@OptIn(PerformancePitfall::class)
|
||||
public operator fun T.plus(arg: StructureND<T>): StructureND<T> = arg.map { value -> add(this@plus, value) }
|
||||
|
||||
/**
|
||||
* Subtracts an ND structure from an element of it.
|
||||
*
|
||||
* @receiver the dividend.
|
||||
* @param arg the divisor.
|
||||
* @return the quotient.
|
||||
*/
|
||||
@OptIn(PerformancePitfall::class)
|
||||
public operator fun T.minus(arg: StructureND<T>): StructureND<T> = arg.map { value -> add(-this@minus, value) }
|
||||
|
||||
public companion object
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an ND structure to an element of it.
|
||||
*
|
||||
* @receiver the augend.
|
||||
* @param arg the addend.
|
||||
* @return the sum.
|
||||
*/
|
||||
context(GroupOpsND<T, A>)
|
||||
@OptIn(PerformancePitfall::class)
|
||||
public operator fun <T, A : GroupOps<T>> StructureND<T>.plus(arg: T): StructureND<T> = this.map { value -> add(arg, value) }
|
||||
|
||||
/**
|
||||
* Subtracts an element from ND structure of it.
|
||||
*
|
||||
* @receiver the dividend.
|
||||
* @param arg the divisor.
|
||||
* @return the quotient.
|
||||
*/
|
||||
context(GroupOpsND<T, A>)
|
||||
@OptIn(PerformancePitfall::class)
|
||||
public operator fun <T, A : GroupOps<T>> StructureND<T>.minus(arg: T): StructureND<T> = this.map { value -> add(arg, -value) }
|
||||
|
||||
/**
|
||||
* Adds an element to ND structure of it.
|
||||
*
|
||||
* @receiver the augend.
|
||||
* @param arg the addend.
|
||||
* @return the sum.
|
||||
*/
|
||||
context(GroupOpsND<T, A>)
|
||||
@OptIn(PerformancePitfall::class)
|
||||
public operator fun <T, A : GroupOps<T>> T.plus(arg: StructureND<T>): StructureND<T> = arg.map { value -> add(this@plus, value) }
|
||||
|
||||
/**
|
||||
* Subtracts an ND structure from an element of it.
|
||||
*
|
||||
* @receiver the dividend.
|
||||
* @param arg the divisor.
|
||||
* @return the quotient.
|
||||
*/
|
||||
context(GroupOpsND<T, A>)
|
||||
@OptIn(PerformancePitfall::class)
|
||||
public operator fun <T, A : GroupOps<T>> T.minus(arg: StructureND<T>): StructureND<T> = arg.map { value -> add(-this@minus, value) }
|
||||
|
||||
|
||||
public interface GroupND<T, out A : Group<T>> : Group<StructureND<T>>, GroupOpsND<T, A>, WithShape {
|
||||
override val zero: StructureND<T> get() = structureND(shape) { elementAlgebra.zero }
|
||||
}
|
||||
@ -194,31 +197,34 @@ public interface RingOpsND<T, out A : RingOps<T>> : RingOps<StructureND<T>>, Gro
|
||||
override fun multiply(left: StructureND<T>, right: StructureND<T>): StructureND<T> =
|
||||
zip(left, right) { aValue, bValue -> multiply(aValue, bValue) }
|
||||
|
||||
//TODO move to extensions with context receivers
|
||||
|
||||
/**
|
||||
* Multiplies an ND structure by an element of it.
|
||||
*
|
||||
* @receiver the multiplicand.
|
||||
* @param arg the multiplier.
|
||||
* @return the product.
|
||||
*/
|
||||
@OptIn(PerformancePitfall::class)
|
||||
public operator fun StructureND<T>.times(arg: T): StructureND<T> = this.map { value -> multiply(arg, value) }
|
||||
|
||||
/**
|
||||
* Multiplies an element by a ND structure of it.
|
||||
*
|
||||
* @receiver the multiplicand.
|
||||
* @param arg the multiplier.
|
||||
* @return the product.
|
||||
*/
|
||||
@OptIn(PerformancePitfall::class)
|
||||
public operator fun T.times(arg: StructureND<T>): StructureND<T> = arg.map { value -> multiply(this@times, value) }
|
||||
|
||||
public companion object
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies an ND structure by an element of it.
|
||||
*
|
||||
* @receiver the multiplicand.
|
||||
* @param arg the multiplier.
|
||||
* @return the product.
|
||||
*/
|
||||
context(RingOpsND<T, A>)
|
||||
@OptIn(PerformancePitfall::class)
|
||||
public operator fun <T, A : RingOps<T>> StructureND<T>.times(arg: T): StructureND<T> =
|
||||
this.map { value -> multiply(arg, value) }
|
||||
|
||||
/**
|
||||
* Multiplies an element by a ND structure of it.
|
||||
*
|
||||
* @receiver the multiplicand.
|
||||
* @param arg the multiplier.
|
||||
* @return the product.
|
||||
*/
|
||||
context(RingOpsND<T, A>)
|
||||
@OptIn(PerformancePitfall::class)
|
||||
public operator fun <T, A : RingOps<T>> T.times(arg: StructureND<T>): StructureND<T> =
|
||||
arg.map { value -> multiply(this@times, value) }
|
||||
|
||||
public interface RingND<T, out A : Ring<T>> : Ring<StructureND<T>>, RingOpsND<T, A>, GroupND<T, A>, WithShape {
|
||||
override val one: StructureND<T> get() = structureND(shape) { elementAlgebra.one }
|
||||
}
|
||||
@ -245,31 +251,33 @@ public interface FieldOpsND<T, out A : Field<T>> :
|
||||
override fun divide(left: StructureND<T>, right: StructureND<T>): StructureND<T> =
|
||||
zip(left, right) { aValue, bValue -> divide(aValue, bValue) }
|
||||
|
||||
//TODO move to extensions after https://github.com/Kotlin/KEEP/blob/master/proposals/context-receivers.md
|
||||
/**
|
||||
* Divides an ND structure by an element of it.
|
||||
*
|
||||
* @receiver the dividend.
|
||||
* @param arg the divisor.
|
||||
* @return the quotient.
|
||||
*/
|
||||
@OptIn(PerformancePitfall::class)
|
||||
public operator fun StructureND<T>.div(arg: T): StructureND<T> = this.map { value -> divide(arg, value) }
|
||||
|
||||
/**
|
||||
* Divides an element by an ND structure of it.
|
||||
*
|
||||
* @receiver the dividend.
|
||||
* @param arg the divisor.
|
||||
* @return the quotient.
|
||||
*/
|
||||
@OptIn(PerformancePitfall::class)
|
||||
public operator fun T.div(arg: StructureND<T>): StructureND<T> = arg.map { divide(it, this@div) }
|
||||
|
||||
@OptIn(PerformancePitfall::class)
|
||||
override fun scale(a: StructureND<T>, value: Double): StructureND<T> = a.map { scale(it, value) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides an ND structure by an element of it.
|
||||
*
|
||||
* @receiver the dividend.
|
||||
* @param arg the divisor.
|
||||
* @return the quotient.
|
||||
*/
|
||||
context(FieldOpsND<T, A>)
|
||||
@OptIn(PerformancePitfall::class)
|
||||
public operator fun <T, A : Field<T>> StructureND<T>.div(arg: T): StructureND<T> = this.map { value -> divide(arg, value) }
|
||||
|
||||
/**
|
||||
* Divides an element by an ND structure of it.
|
||||
*
|
||||
* @receiver the dividend.
|
||||
* @param arg the divisor.
|
||||
* @return the quotient.
|
||||
*/
|
||||
context(FieldOpsND<T, A>)
|
||||
@OptIn(PerformancePitfall::class)
|
||||
public operator fun <T, A : Field<T>> T.div(arg: StructureND<T>): StructureND<T> = arg.map { divide(it, this@div) }
|
||||
|
||||
|
||||
public interface FieldND<T, out A : Field<T>> : Field<StructureND<T>>, FieldOpsND<T, A>, RingND<T, A>, WithShape {
|
||||
override val one: StructureND<T> get() = structureND(shape) { elementAlgebra.one }
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ public open class BufferedGroupNDOps<T, out A : Group<T>>(
|
||||
override val bufferAlgebra: BufferAlgebra<T, A>,
|
||||
override val indexerBuilder: (IntArray) -> ShapeIndexer = BufferAlgebraND.defaultIndexerBuilder,
|
||||
) : GroupOpsND<T, A>, BufferAlgebraND<T, A> {
|
||||
override fun StructureND<T>.unaryMinus(): StructureND<T> = map { -it }
|
||||
override fun negate(arg: StructureND<T>): StructureND<T> = arg.map { -it }
|
||||
}
|
||||
|
||||
public open class BufferedRingOpsND<T, out A : Ring<T>>(
|
||||
|
@ -76,50 +76,17 @@ public sealed class DoubleFieldOpsND : BufferedFieldOpsND<Double, DoubleField>(D
|
||||
override fun add(left: StructureND<Double>, right: StructureND<Double>): DoubleBufferND =
|
||||
zipInline(left.toBufferND(), right.toBufferND()) { l, r -> l + r }
|
||||
|
||||
override fun negate(arg: StructureND<Double>): DoubleBufferND = mapInline(arg.toBufferND()) { -it }
|
||||
|
||||
override fun subtract(left: StructureND<Double>, right: StructureND<Double>): DoubleBufferND =
|
||||
zipInline(left.toBufferND(), right.toBufferND()) { l: Double, r: Double -> l - r }
|
||||
|
||||
override fun multiply(left: StructureND<Double>, right: StructureND<Double>): DoubleBufferND =
|
||||
zipInline(left.toBufferND(), right.toBufferND()) { l, r -> l * r }
|
||||
|
||||
override fun StructureND<Double>.unaryMinus(): DoubleBufferND = mapInline(toBufferND()) { -it }
|
||||
|
||||
override fun StructureND<Double>.div(arg: StructureND<Double>): DoubleBufferND =
|
||||
zipInline(toBufferND(), arg.toBufferND()) { l, r -> l / r }
|
||||
|
||||
override fun divide(left: StructureND<Double>, right: StructureND<Double>): DoubleBufferND =
|
||||
zipInline(left.toBufferND(), right.toBufferND()) { l: Double, r: Double -> l / r }
|
||||
|
||||
override fun StructureND<Double>.div(arg: Double): DoubleBufferND =
|
||||
mapInline(toBufferND()) { it / arg }
|
||||
|
||||
override fun Double.div(arg: StructureND<Double>): DoubleBufferND =
|
||||
mapInline(arg.toBufferND()) { this / it }
|
||||
|
||||
override fun StructureND<Double>.unaryPlus(): DoubleBufferND = toBufferND()
|
||||
|
||||
override fun StructureND<Double>.plus(arg: StructureND<Double>): DoubleBufferND =
|
||||
zipInline(toBufferND(), arg.toBufferND()) { l: Double, r: Double -> l + r }
|
||||
|
||||
override fun StructureND<Double>.minus(arg: StructureND<Double>): DoubleBufferND =
|
||||
zipInline(toBufferND(), arg.toBufferND()) { l: Double, r: Double -> l - r }
|
||||
|
||||
override fun StructureND<Double>.times(arg: StructureND<Double>): DoubleBufferND =
|
||||
zipInline(toBufferND(), arg.toBufferND()) { l: Double, r: Double -> l * r }
|
||||
|
||||
override fun StructureND<Double>.times(k: Number): DoubleBufferND =
|
||||
mapInline(toBufferND()) { it * k.toDouble() }
|
||||
|
||||
override fun StructureND<Double>.div(k: Number): DoubleBufferND =
|
||||
mapInline(toBufferND()) { it / k.toDouble() }
|
||||
|
||||
override fun Number.times(arg: StructureND<Double>): DoubleBufferND = arg * this
|
||||
|
||||
override fun StructureND<Double>.plus(arg: Double): DoubleBufferND = mapInline(toBufferND()) { it + arg }
|
||||
|
||||
override fun StructureND<Double>.minus(arg: Double): StructureND<Double> = mapInline(toBufferND()) { it - arg }
|
||||
|
||||
override fun Double.plus(arg: StructureND<Double>): StructureND<Double> = arg + this
|
||||
|
||||
override fun Double.minus(arg: StructureND<Double>): StructureND<Double> = mapInline(arg.toBufferND()) { this - it }
|
||||
|
||||
override fun scale(a: StructureND<Double>, value: Double): DoubleBufferND =
|
||||
mapInline(a.toBufferND()) { it * value }
|
||||
|
||||
@ -181,7 +148,7 @@ public class DoubleFieldND(override val shape: Shape) :
|
||||
it.kpow(pow)
|
||||
}
|
||||
|
||||
override fun power(arg: StructureND<Double>, pow: Number): DoubleBufferND = if(pow.isInteger()){
|
||||
override fun power(arg: StructureND<Double>, pow: Number): DoubleBufferND = if (pow.isInteger()) {
|
||||
power(arg, pow.toInt())
|
||||
} else {
|
||||
val dpow = pow.toDouble()
|
||||
|
@ -11,6 +11,7 @@ import space.kscience.kmath.misc.Featured
|
||||
import space.kscience.kmath.misc.PerformancePitfall
|
||||
import space.kscience.kmath.operations.Ring
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.minus
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.BufferFactory
|
||||
import kotlin.jvm.JvmName
|
||||
|
@ -9,12 +9,6 @@ import space.kscience.kmath.expressions.Symbol
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.operations.Ring.Companion.optimizedPower
|
||||
|
||||
/**
|
||||
* Stub for DSL the [Algebra] is.
|
||||
*/
|
||||
@DslMarker
|
||||
public annotation class KMathContext
|
||||
|
||||
/**
|
||||
* Represents an algebraic structure.
|
||||
*
|
||||
@ -137,46 +131,26 @@ public interface GroupOps<T> : Algebra<T> {
|
||||
*/
|
||||
public fun add(left: T, right: T): T
|
||||
|
||||
// Operations to be performed in this context. Could be moved to extensions in case of KEEP-176.
|
||||
|
||||
/**
|
||||
* The negation of this element.
|
||||
*
|
||||
* @receiver this value.
|
||||
* @param arg the element.
|
||||
* @return the additive inverse of this value.
|
||||
*/
|
||||
public operator fun T.unaryMinus(): T
|
||||
|
||||
/**
|
||||
* Returns this value.
|
||||
*
|
||||
* @receiver this value.
|
||||
* @return this value.
|
||||
*/
|
||||
public operator fun T.unaryPlus(): T = this
|
||||
|
||||
/**
|
||||
* Addition of two elements.
|
||||
*
|
||||
* @receiver the augend.
|
||||
* @param arg the addend.
|
||||
* @return the sum.
|
||||
*/
|
||||
public operator fun T.plus(arg: T): T = add(this, arg)
|
||||
public fun negate(arg: T): T
|
||||
|
||||
/**
|
||||
* Subtraction of two elements.
|
||||
*
|
||||
* @receiver the minuend.
|
||||
* @param arg the subtrahend.
|
||||
* @parm left the minuend.
|
||||
* @param right the subtrahend.
|
||||
* @return the difference.
|
||||
*/
|
||||
public operator fun T.minus(arg: T): T = add(this, -arg)
|
||||
public fun subtract(left: T, right: T): T = add(left, -right)
|
||||
|
||||
// Dynamic dispatch of operations
|
||||
override fun unaryOperationFunction(operation: String): (arg: T) -> T = when (operation) {
|
||||
PLUS_OPERATION -> { arg -> +arg }
|
||||
MINUS_OPERATION -> { arg -> -arg }
|
||||
PLUS_OPERATION -> { arg -> arg }
|
||||
MINUS_OPERATION -> ::negate
|
||||
else -> super.unaryOperationFunction(operation)
|
||||
}
|
||||
|
||||
@ -199,6 +173,44 @@ public interface GroupOps<T> : Algebra<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The negation of this element.
|
||||
*
|
||||
* @receiver the element.
|
||||
* @return the additive inverse of this value.
|
||||
*/
|
||||
context(GroupOps<T>)
|
||||
public operator fun <T> T.unaryMinus(): T = negate(this)
|
||||
|
||||
/**
|
||||
* Returns this value.
|
||||
*
|
||||
* @receiver this value.
|
||||
* @return this value.
|
||||
*/
|
||||
context(GroupOps<T>)
|
||||
public operator fun <T> T.unaryPlus(): T = this
|
||||
|
||||
/**
|
||||
* Addition of two elements.
|
||||
*
|
||||
* @receiver the augend.
|
||||
* @param arg the addend.
|
||||
* @return the sum.
|
||||
*/
|
||||
context(GroupOps<T>)
|
||||
public operator fun <T> T.plus(arg: T): T = add(this, arg)
|
||||
|
||||
/**
|
||||
* Subtraction of two elements.
|
||||
*
|
||||
* @receiver the minuend.
|
||||
* @param arg the subtrahend.
|
||||
* @return the difference.
|
||||
*/
|
||||
context(GroupOps<T>)
|
||||
public operator fun <T> T.minus(arg: T): T = subtract(this, arg)
|
||||
|
||||
/**
|
||||
* Represents group i.e., algebraic structure with associative, binary operation [add].
|
||||
*
|
||||
@ -226,14 +238,6 @@ public interface RingOps<T> : GroupOps<T> {
|
||||
*/
|
||||
public fun multiply(left: T, right: T): T
|
||||
|
||||
/**
|
||||
* Multiplies this element by scalar.
|
||||
*
|
||||
* @receiver the multiplier.
|
||||
* @param arg the multiplicand.
|
||||
*/
|
||||
public operator fun T.times(arg: T): T = multiply(this, arg)
|
||||
|
||||
override fun binaryOperationFunction(operation: String): (left: T, right: T) -> T = when (operation) {
|
||||
TIMES_OPERATION -> ::multiply
|
||||
else -> super.binaryOperationFunction(operation)
|
||||
@ -247,6 +251,15 @@ public interface RingOps<T> : GroupOps<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies two elements.
|
||||
*
|
||||
* @receiver the multiplier.
|
||||
* @param arg the multiplicand.
|
||||
*/
|
||||
context(RingOps<T>)
|
||||
public operator fun <T> T.times(arg: T): T = multiply(this, arg)
|
||||
|
||||
/**
|
||||
* Represents ring i.e., algebraic structure with two associative binary operations called "addition" and
|
||||
* "multiplication" and their neutral elements.
|
||||
@ -264,7 +277,7 @@ public interface Ring<T> : Group<T>, RingOps<T> {
|
||||
*/
|
||||
public fun power(arg: T, pow: UInt): T = optimizedPower(arg, pow)
|
||||
|
||||
public companion object{
|
||||
public companion object {
|
||||
/**
|
||||
* Raises [arg] to the non-negative integer power [exponent].
|
||||
*
|
||||
@ -311,15 +324,6 @@ public interface FieldOps<T> : RingOps<T> {
|
||||
*/
|
||||
public fun divide(left: T, right: T): T
|
||||
|
||||
/**
|
||||
* Division of two elements.
|
||||
*
|
||||
* @receiver the dividend.
|
||||
* @param arg the divisor.
|
||||
* @return the quotient.
|
||||
*/
|
||||
public operator fun T.div(arg: T): T = divide(this, arg)
|
||||
|
||||
override fun binaryOperationFunction(operation: String): (left: T, right: T) -> T = when (operation) {
|
||||
DIV_OPERATION -> ::divide
|
||||
else -> super.binaryOperationFunction(operation)
|
||||
@ -333,6 +337,16 @@ public interface FieldOps<T> : RingOps<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Division of two elements.
|
||||
*
|
||||
* @receiver the dividend.
|
||||
* @param arg the divisor.
|
||||
* @return the quotient.
|
||||
*/
|
||||
context(FieldOps<T>)
|
||||
public operator fun <T> T.div(arg: T): T = divide(this, arg)
|
||||
|
||||
/**
|
||||
* Represents field i.e., algebraic structure with three operations: associative, commutative addition and
|
||||
* multiplication, and division. **This interface differs from the eponymous mathematical definition: fields in KMath
|
||||
@ -345,7 +359,7 @@ public interface Field<T> : Ring<T>, FieldOps<T>, ScaleOperations<T>, NumericAlg
|
||||
|
||||
public fun power(arg: T, pow: Int): T = optimizedPower(arg, pow)
|
||||
|
||||
public companion object{
|
||||
public companion object {
|
||||
/**
|
||||
* Raises [arg] to the integer power [exponent].
|
||||
*
|
||||
@ -358,7 +372,10 @@ public interface Field<T> : Ring<T>, FieldOps<T>, ScaleOperations<T>, NumericAlg
|
||||
* @author Iaroslav Postovalov, Evgeniy Zhelenskiy
|
||||
*/
|
||||
private fun <T> Field<T>.optimizedPower(arg: T, exponent: Int): T = when {
|
||||
exponent < 0 -> one / (this as Ring<T>).optimizedPower(arg, if (exponent == Int.MIN_VALUE) Int.MAX_VALUE.toUInt().inc() else (-exponent).toUInt())
|
||||
exponent < 0 -> one / (this as Ring<T>).optimizedPower(
|
||||
arg,
|
||||
if (exponent == Int.MIN_VALUE) Int.MAX_VALUE.toUInt().inc() else (-exponent).toUInt()
|
||||
)
|
||||
else -> (this as Ring<T>).optimizedPower(arg, exponent.toUInt())
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ public object BigIntField : Field<BigInt>, NumbersAddOps<BigInt>, ScaleOperation
|
||||
override fun number(value: Number): BigInt = value.toLong().toBigInt()
|
||||
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
||||
override fun BigInt.unaryMinus(): BigInt = -this
|
||||
override fun negate(arg: BigInt): BigInt = -arg
|
||||
override fun add(left: BigInt, right: BigInt): BigInt = left.plus(right)
|
||||
override fun scale(a: BigInt, value: Double): BigInt = a.times(number(value))
|
||||
override fun multiply(left: BigInt, right: BigInt): BigInt = left.times(right)
|
||||
|
@ -137,7 +137,7 @@ public open class BufferRingOps<T, A: Ring<T>>(
|
||||
|
||||
override fun add(left: Buffer<T>, right: Buffer<T>): Buffer<T> = zipInline(left, right) { l, r -> l + r }
|
||||
override fun multiply(left: Buffer<T>, right: Buffer<T>): Buffer<T> = zipInline(left, right) { l, r -> l * r }
|
||||
override fun Buffer<T>.unaryMinus(): Buffer<T> = map { -it }
|
||||
override fun negate(arg: Buffer<T>): Buffer<T> = arg.map { negate(it) }
|
||||
|
||||
override fun unaryOperationFunction(operation: String): (arg: Buffer<T>) -> Buffer<T> =
|
||||
super<BufferAlgebra>.unaryOperationFunction(operation)
|
||||
@ -159,7 +159,7 @@ public open class BufferFieldOps<T, A : Field<T>>(
|
||||
override fun divide(left: Buffer<T>, right: Buffer<T>): Buffer<T> = zipInline(left, right) { l, r -> l / r }
|
||||
|
||||
override fun scale(a: Buffer<T>, value: Double): Buffer<T> = a.map { scale(it, value) }
|
||||
override fun Buffer<T>.unaryMinus(): Buffer<T> = map { -it }
|
||||
override fun negate(arg: Buffer<T>): Buffer<T> = arg.map { -it }
|
||||
|
||||
override fun binaryOperationFunction(operation: String): (left: Buffer<T>, right: Buffer<T>) -> Buffer<T> =
|
||||
super<BufferRingOps>.binaryOperationFunction(operation)
|
||||
|
@ -6,7 +6,6 @@
|
||||
package space.kscience.kmath.operations
|
||||
|
||||
import space.kscience.kmath.linear.Point
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.BufferFactory
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
@ -32,8 +31,6 @@ public abstract class DoubleBufferOps : BufferAlgebra<Double, DoubleField>, Exte
|
||||
override fun binaryOperationFunction(operation: String): (left: Buffer<Double>, right: Buffer<Double>) -> Buffer<Double> =
|
||||
super<ExtendedFieldOps>.binaryOperationFunction(operation)
|
||||
|
||||
override fun Buffer<Double>.unaryMinus(): DoubleBuffer = mapInline { -it }
|
||||
|
||||
override fun add(left: Buffer<Double>, right: Buffer<Double>): DoubleBuffer {
|
||||
require(right.size == left.size) {
|
||||
"The size of the first buffer ${left.size} should be the same as for second one: ${right.size} "
|
||||
@ -46,18 +43,17 @@ public abstract class DoubleBufferOps : BufferAlgebra<Double, DoubleField>, Exte
|
||||
} else DoubleBuffer(DoubleArray(left.size) { left[it] + right[it] })
|
||||
}
|
||||
|
||||
override fun Buffer<Double>.plus(arg: Buffer<Double>): DoubleBuffer = add(this, arg)
|
||||
override fun negate(arg: Buffer<Double>): DoubleBuffer = arg.mapInline { -it }
|
||||
|
||||
override fun Buffer<Double>.minus(arg: Buffer<Double>): DoubleBuffer {
|
||||
require(arg.size == this.size) {
|
||||
"The size of the first buffer ${this.size} should be the same as for second one: ${arg.size} "
|
||||
override fun subtract(left: Buffer<Double>, right: Buffer<Double>): DoubleBuffer {
|
||||
require(left.size == right.size) {
|
||||
"The size of the first buffer ${left.size} should be the same as for second one: ${right.size} "
|
||||
}
|
||||
|
||||
return if (this is DoubleBuffer && arg is DoubleBuffer) {
|
||||
val aArray = this.array
|
||||
val bArray = arg.array
|
||||
DoubleBuffer(DoubleArray(this.size) { aArray[it] - bArray[it] })
|
||||
} else DoubleBuffer(DoubleArray(this.size) { this[it] - arg[it] })
|
||||
return if (left is DoubleBuffer && right is DoubleBuffer)
|
||||
DoubleBuffer(DoubleArray(left.size) { left.array[it] - right.array[it] })
|
||||
else
|
||||
DoubleBuffer(DoubleArray(left.size) { left[it] - right[it] })
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -116,35 +116,39 @@ public interface ScaleOperations<T> : Algebra<T> {
|
||||
* @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 arg the multiplicand.
|
||||
* @return the product.
|
||||
*/
|
||||
public operator fun Number.times(arg: T): T = arg * this
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Multiplication of this element by a scalar.
|
||||
*
|
||||
* @receiver the multiplier.
|
||||
* @param k the multiplicand.
|
||||
* @return the product.
|
||||
*/
|
||||
context(ScaleOperations<T>)
|
||||
public operator fun <T> 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.
|
||||
*/
|
||||
context(ScaleOperations<T>)
|
||||
public operator fun <T> T.div(k: Number): T = scale(this, 1.0 / k.toDouble())
|
||||
|
||||
/**
|
||||
* Multiplication of this number by element.
|
||||
*
|
||||
* @receiver the multiplier.
|
||||
* @param arg the multiplicand.
|
||||
* @return the product.
|
||||
*/
|
||||
context(ScaleOperations<T>)
|
||||
public operator fun <T> Number.times(arg: T): T = arg * this
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -68,7 +68,7 @@ public object DoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOp
|
||||
override inline val zero: Double get() = 0.0
|
||||
override inline val one: Double get() = 1.0
|
||||
|
||||
override inline fun number(value: Number): Double = value.toDouble()
|
||||
override fun number(value: Number): Double = value.toDouble()
|
||||
|
||||
override fun binaryOperationFunction(operation: String): (left: Double, right: Double) -> Double =
|
||||
when (operation) {
|
||||
@ -77,6 +77,8 @@ public object DoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOp
|
||||
}
|
||||
|
||||
override inline fun add(left: Double, right: Double): Double = left + right
|
||||
override inline fun negate(arg: Double): Double = -arg
|
||||
override inline fun subtract(left: Double, right: Double): Double = left - right
|
||||
|
||||
override inline fun multiply(left: Double, right: Double): Double = left * right
|
||||
override inline fun divide(left: Double, right: Double): Double = left / right
|
||||
@ -108,12 +110,6 @@ public object DoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOp
|
||||
override inline fun ln(arg: Double): Double = kotlin.math.ln(arg)
|
||||
|
||||
override inline fun norm(arg: Double): Double = abs(arg)
|
||||
|
||||
override inline fun Double.unaryMinus(): Double = -this
|
||||
override inline fun Double.plus(arg: Double): Double = this + arg
|
||||
override inline fun Double.minus(arg: Double): Double = this - arg
|
||||
override inline fun Double.times(arg: Double): Double = this * arg
|
||||
override inline fun Double.div(arg: Double): Double = this / arg
|
||||
}
|
||||
|
||||
public val Double.Companion.algebra: DoubleField get() = DoubleField
|
||||
@ -135,7 +131,10 @@ public object FloatField : ExtendedField<Float>, Norm<Float, Float> {
|
||||
}
|
||||
|
||||
override inline fun add(left: Float, right: Float): Float = left + right
|
||||
override fun scale(a: Float, value: Double): Float = a * value.toFloat()
|
||||
override inline fun negate(arg: Float): Float = -arg
|
||||
override inline fun subtract(left: Float, right: Float): Float = left - right
|
||||
|
||||
override inline fun scale(a: Float, value: Double): Float = a * value.toFloat()
|
||||
|
||||
override inline fun multiply(left: Float, right: Float): Float = left * right
|
||||
|
||||
@ -162,12 +161,6 @@ public object FloatField : ExtendedField<Float>, Norm<Float, Float> {
|
||||
override inline fun ln(arg: Float): Float = kotlin.math.ln(arg)
|
||||
|
||||
override inline fun norm(arg: Float): Float = abs(arg)
|
||||
|
||||
override inline fun Float.unaryMinus(): Float = -this
|
||||
override inline fun Float.plus(arg: Float): Float = this + arg
|
||||
override inline fun Float.minus(arg: Float): Float = this - arg
|
||||
override inline fun Float.times(arg: Float): Float = this * arg
|
||||
override inline fun Float.div(arg: Float): Float = this / arg
|
||||
}
|
||||
|
||||
public val Float.Companion.algebra: FloatField get() = FloatField
|
||||
@ -185,13 +178,11 @@ public object IntRing : Ring<Int>, Norm<Int, Int>, NumericAlgebra<Int> {
|
||||
|
||||
override fun number(value: Number): Int = value.toInt()
|
||||
override inline fun add(left: Int, right: Int): Int = left + right
|
||||
override inline fun negate(arg: Int): Int = -arg
|
||||
override inline fun subtract(left: Int, right: Int): Int = left - right
|
||||
|
||||
override inline fun multiply(left: Int, right: Int): Int = left * right
|
||||
override inline fun norm(arg: Int): Int = abs(arg)
|
||||
|
||||
override inline fun Int.unaryMinus(): Int = -this
|
||||
override inline fun Int.plus(arg: Int): Int = this + arg
|
||||
override inline fun Int.minus(arg: Int): Int = this - arg
|
||||
override inline fun Int.times(arg: Int): Int = this * arg
|
||||
}
|
||||
|
||||
public val Int.Companion.algebra: IntRing get() = IntRing
|
||||
@ -209,13 +200,11 @@ public object ShortRing : Ring<Short>, Norm<Short, Short>, NumericAlgebra<Short>
|
||||
|
||||
override fun number(value: Number): Short = value.toShort()
|
||||
override inline fun add(left: Short, right: Short): Short = (left + right).toShort()
|
||||
override inline fun multiply(left: Short, right: Short): Short = (left * right).toShort()
|
||||
override fun norm(arg: Short): Short = if (arg > 0) arg else (-arg).toShort()
|
||||
override inline fun negate(arg: Short): Short = (-arg).toShort()
|
||||
override inline fun subtract(left: Short, right: Short): Short = (left - right).toShort()
|
||||
|
||||
override inline fun Short.unaryMinus(): Short = (-this).toShort()
|
||||
override inline fun Short.plus(arg: Short): Short = (this + arg).toShort()
|
||||
override inline fun Short.minus(arg: Short): Short = (this - arg).toShort()
|
||||
override inline fun Short.times(arg: Short): Short = (this * arg).toShort()
|
||||
override inline fun multiply(left: Short, right: Short): Short = (left * right).toShort()
|
||||
override inline fun norm(arg: Short): Short = if (arg > 0) arg else (-arg).toShort()
|
||||
}
|
||||
|
||||
public val Short.Companion.algebra: ShortRing get() = ShortRing
|
||||
@ -233,13 +222,12 @@ public object ByteRing : Ring<Byte>, Norm<Byte, Byte>, NumericAlgebra<Byte> {
|
||||
|
||||
override fun number(value: Number): Byte = value.toByte()
|
||||
override inline fun add(left: Byte, right: Byte): Byte = (left + right).toByte()
|
||||
override inline fun multiply(left: Byte, right: Byte): Byte = (left * right).toByte()
|
||||
override fun norm(arg: Byte): Byte = if (arg > 0) arg else (-arg).toByte()
|
||||
override inline fun negate(arg: Byte): Byte = (-arg).toByte()
|
||||
override inline fun subtract(left: Byte, right: Byte): Byte = (left - right).toByte()
|
||||
|
||||
override inline fun Byte.unaryMinus(): Byte = (-this).toByte()
|
||||
override inline fun Byte.plus(arg: Byte): Byte = (this + arg).toByte()
|
||||
override inline fun Byte.minus(arg: Byte): Byte = (this - arg).toByte()
|
||||
override inline fun Byte.times(arg: Byte): Byte = (this * arg).toByte()
|
||||
override inline fun multiply(left: Byte, right: Byte): Byte = (left * right).toByte()
|
||||
|
||||
override inline fun norm(arg: Byte): Byte = if (arg > 0) arg else (-arg).toByte()
|
||||
}
|
||||
|
||||
public val Byte.Companion.algebra: ByteRing get() = ByteRing
|
||||
@ -256,14 +244,13 @@ public object LongRing : Ring<Long>, Norm<Long, Long>, NumericAlgebra<Long> {
|
||||
get() = 1L
|
||||
|
||||
override fun number(value: Number): Long = value.toLong()
|
||||
override inline fun add(left: Long, right: Long): Long = left + right
|
||||
override inline fun multiply(left: Long, right: Long): Long = left * right
|
||||
override fun norm(arg: Long): Long = abs(arg)
|
||||
|
||||
override inline fun Long.unaryMinus(): Long = (-this)
|
||||
override inline fun Long.plus(arg: Long): Long = (this + arg)
|
||||
override inline fun Long.minus(arg: Long): Long = (this - arg)
|
||||
override inline fun Long.times(arg: Long): Long = (this * arg)
|
||||
override inline fun add(left: Long, right: Long): Long = left + right
|
||||
override inline fun negate(arg: Long): Long = -arg
|
||||
override inline fun subtract(left: Long, right: Long): Long = left - right
|
||||
|
||||
override inline fun multiply(left: Long, right: Long): Long = left * right
|
||||
override inline fun norm(arg: Long): Long = abs(arg)
|
||||
}
|
||||
|
||||
public val Long.Companion.algebra: LongRing get() = LongRing
|
||||
|
@ -6,6 +6,8 @@
|
||||
package space.kscience.kmath.expressions
|
||||
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.plus
|
||||
import space.kscience.kmath.operations.times
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFails
|
||||
|
@ -7,13 +7,10 @@ package space.kscience.kmath.expressions
|
||||
|
||||
import space.kscience.kmath.expressions.Symbol.Companion.x
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.operations.BooleanAlgebra
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.*
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
||||
internal class InterpretTest {
|
||||
@Test
|
||||
fun interpretation() {
|
||||
|
@ -5,8 +5,7 @@
|
||||
|
||||
package space.kscience.kmath.expressions
|
||||
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.bindSymbol
|
||||
import space.kscience.kmath.operations.*
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.asBuffer
|
||||
import kotlin.math.E
|
||||
|
@ -10,6 +10,7 @@ import space.kscience.kmath.nd.ndAlgebra
|
||||
import space.kscience.kmath.nd.structureND
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.times
|
||||
import space.kscience.kmath.testutils.FieldVerifier
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
@ -8,10 +8,7 @@ package space.kscience.kmath.structures
|
||||
import space.kscience.kmath.linear.linearSpace
|
||||
import space.kscience.kmath.misc.PerformancePitfall
|
||||
import space.kscience.kmath.nd.*
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.Norm
|
||||
import space.kscience.kmath.operations.algebra
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.*
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.pow
|
||||
import kotlin.test.Test
|
||||
|
@ -5,8 +5,7 @@
|
||||
|
||||
package space.kscience.kmath.testutils
|
||||
|
||||
import space.kscience.kmath.operations.Field
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.*
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotEquals
|
||||
|
||||
|
@ -5,9 +5,7 @@
|
||||
|
||||
package space.kscience.kmath.testutils
|
||||
|
||||
import space.kscience.kmath.operations.Ring
|
||||
import space.kscience.kmath.operations.ScaleOperations
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
internal open class RingVerifier<T, out A>(algebra: A, a: T, b: T, c: T, x: Number) :
|
||||
|
@ -5,9 +5,7 @@
|
||||
|
||||
package space.kscience.kmath.testutils
|
||||
|
||||
import space.kscience.kmath.operations.Ring
|
||||
import space.kscience.kmath.operations.ScaleOperations
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.*
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotEquals
|
||||
|
||||
|
@ -19,10 +19,10 @@ public object JBigIntegerField : Ring<BigInteger>, NumericAlgebra<BigInteger> {
|
||||
|
||||
override fun number(value: Number): BigInteger = BigInteger.valueOf(value.toLong())
|
||||
override fun add(left: BigInteger, right: BigInteger): BigInteger = left.add(right)
|
||||
override operator fun BigInteger.minus(arg: BigInteger): BigInteger = subtract(arg)
|
||||
override fun multiply(left: BigInteger, right: BigInteger): BigInteger = left.multiply(right)
|
||||
override fun negate(arg: BigInteger): BigInteger = arg.negate()
|
||||
override fun subtract(left: BigInteger, right: BigInteger): BigInteger = left.subtract(right)
|
||||
|
||||
override operator fun BigInteger.unaryMinus(): BigInteger = negate()
|
||||
override fun multiply(left: BigInteger, right: BigInteger): BigInteger = left.multiply(right)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -40,7 +40,9 @@ public abstract class JBigDecimalFieldBase internal constructor(
|
||||
get() = BigDecimal.ONE
|
||||
|
||||
override fun add(left: BigDecimal, right: BigDecimal): BigDecimal = left.add(right)
|
||||
override operator fun BigDecimal.minus(arg: BigDecimal): BigDecimal = subtract(arg)
|
||||
override fun negate(arg: BigDecimal): BigDecimal = arg.negate(mathContext)
|
||||
override fun subtract(left: BigDecimal, right: BigDecimal): BigDecimal = left.subtract(right)
|
||||
|
||||
override fun number(value: Number): BigDecimal = BigDecimal.valueOf(value.toDouble())
|
||||
|
||||
override fun scale(a: BigDecimal, value: Double): BigDecimal =
|
||||
@ -50,7 +52,6 @@ public abstract class JBigDecimalFieldBase internal constructor(
|
||||
override fun divide(left: BigDecimal, right: BigDecimal): BigDecimal = left.divide(right, mathContext)
|
||||
override fun power(arg: BigDecimal, pow: Number): BigDecimal = arg.pow(pow.toInt(), mathContext)
|
||||
override fun sqrt(arg: BigDecimal): BigDecimal = arg.sqrt(mathContext)
|
||||
override operator fun BigDecimal.unaryMinus(): BigDecimal = negate(mathContext)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
id("ru.mipt.npm.gradle.common")
|
||||
id("ru.mipt.npm.gradle.native")
|
||||
// id("ru.mipt.npm.gradle.native")
|
||||
}
|
||||
|
||||
kotlin.sourceSets {
|
||||
@ -24,4 +24,9 @@ kotlin.sourceSets {
|
||||
|
||||
readme {
|
||||
maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL
|
||||
}
|
||||
}
|
||||
|
||||
// Testing multi-receiver!
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile> {
|
||||
enabled = false
|
||||
}
|
||||
|
@ -10,10 +10,7 @@ import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.runningReduce
|
||||
import kotlinx.coroutines.flow.scan
|
||||
import space.kscience.kmath.operations.GroupOps
|
||||
import space.kscience.kmath.operations.Ring
|
||||
import space.kscience.kmath.operations.ScaleOperations
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.*
|
||||
|
||||
public fun <T> Flow<T>.cumulativeSum(group: GroupOps<T>): Flow<T> =
|
||||
group { runningReduce { sum, element -> sum + element } }
|
||||
|
@ -39,15 +39,11 @@ public fun <T> StructureND<T>.deferred(index: IntArray): Deferred<T> =
|
||||
public suspend fun <T> StructureND<T>.await(index: IntArray): T =
|
||||
if (this is LazyStructureND<T>) await(index) else get(index)
|
||||
|
||||
/**
|
||||
* PENDING would benefit from KEEP-176
|
||||
*/
|
||||
context(CoroutineScope)
|
||||
public inline fun <T, R> StructureND<T>.mapAsyncIndexed(
|
||||
scope: CoroutineScope,
|
||||
crossinline function: suspend (T, index: IntArray) -> R,
|
||||
): LazyStructureND<R> = LazyStructureND(scope, shape) { index -> function(get(index), index) }
|
||||
): LazyStructureND<R> = LazyStructureND(this@CoroutineScope, shape) { index -> function(get(index), index) }
|
||||
|
||||
public inline fun <T, R> StructureND<T>.mapAsync(
|
||||
scope: CoroutineScope,
|
||||
crossinline function: suspend (T) -> R,
|
||||
): LazyStructureND<R> = LazyStructureND(scope, shape) { index -> function(get(index)) }
|
||||
context(CoroutineScope)
|
||||
public inline fun <T, R> StructureND<T>.mapAsync(crossinline function: suspend (T) -> R): LazyStructureND<R> =
|
||||
LazyStructureND(this@CoroutineScope, shape) { index -> function(get(index)) }
|
||||
|
@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
id("ru.mipt.npm.gradle.common")
|
||||
id("ru.mipt.npm.gradle.native")
|
||||
// id("ru.mipt.npm.gradle.native")
|
||||
}
|
||||
|
||||
description = "A proof of concept module for adding type-safe dimensions to structures"
|
||||
@ -23,3 +23,8 @@ kotlin.sourceSets {
|
||||
readme {
|
||||
maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE
|
||||
}
|
||||
|
||||
// Testing multi-receiver!
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile> {
|
||||
enabled = false
|
||||
}
|
||||
|
@ -33,10 +33,19 @@ readme {
|
||||
) { "LinearSpace implementations." }
|
||||
}
|
||||
|
||||
kotlin.sourceSets.main {
|
||||
val codegen by tasks.creating {
|
||||
ejmlCodegen(kotlin.srcDirs.first().absolutePath + "/space/kscience/kmath/ejml/_generated.kt")
|
||||
}
|
||||
kotlin.sourceSets {
|
||||
filter { it.name.contains("test", true) }
|
||||
.map(org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet::languageSettings)
|
||||
.forEach {
|
||||
it.optIn("space.kscience.kmath.misc.PerformancePitfall")
|
||||
it.optIn("space.kscience.kmath.misc.UnstableKMathAPI")
|
||||
}
|
||||
|
||||
kotlin.srcDirs(files().builtBy(codegen))
|
||||
main {
|
||||
val codegen by tasks.creating {
|
||||
ejmlCodegen(kotlin.srcDirs.first().absolutePath + "/space/kscience/kmath/ejml/_generated.kt")
|
||||
}
|
||||
|
||||
kotlin.srcDirs(files().builtBy(codegen))
|
||||
}
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, DoubleField, DMatrix
|
||||
structure.getFeature(type)?.let { return it }
|
||||
val origin = structure.toEjml().origin
|
||||
|
||||
return when (type) {
|
||||
return type.cast(when (type) {
|
||||
InverseMatrixFeature::class -> object : InverseMatrixFeature<Double> {
|
||||
override val inverse: Matrix<Double> by lazy {
|
||||
val res = origin.copy()
|
||||
@ -270,8 +270,8 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, DoubleField, DMatrix
|
||||
override val p: Matrix<Double> by lazy { lup.getRowPivot(null).wrapMatrix() }
|
||||
}
|
||||
|
||||
else -> null
|
||||
}?.let(type::cast)
|
||||
else -> return null
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -442,7 +442,7 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, FloatField, FMatrixRM
|
||||
structure.getFeature(type)?.let { return it }
|
||||
val origin = structure.toEjml().origin
|
||||
|
||||
return when (type) {
|
||||
return type.cast(when (type) {
|
||||
InverseMatrixFeature::class -> object : InverseMatrixFeature<Float> {
|
||||
override val inverse: Matrix<Float> by lazy {
|
||||
val res = origin.copy()
|
||||
@ -504,8 +504,8 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, FloatField, FMatrixRM
|
||||
override val p: Matrix<Float> by lazy { lup.getRowPivot(null).wrapMatrix() }
|
||||
}
|
||||
|
||||
else -> null
|
||||
}?.let(type::cast)
|
||||
else -> return null
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -684,7 +684,7 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, DoubleField, DMatrix
|
||||
structure.getFeature(type)?.let { return it }
|
||||
val origin = structure.toEjml().origin
|
||||
|
||||
return when (type) {
|
||||
return type.cast(when (type) {
|
||||
QRDecompositionFeature::class -> object : QRDecompositionFeature<Double> {
|
||||
private val qr by lazy {
|
||||
DecompositionFactory_DSCC.qr(FillReducing.NONE).apply { decompose(origin.copy()) }
|
||||
@ -733,8 +733,8 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, DoubleField, DMatrix
|
||||
override val determinant: Double by lazy { elementAlgebra.number(lu.computeDeterminant().real) }
|
||||
}
|
||||
|
||||
else -> null
|
||||
}?.let(type::cast)
|
||||
else -> return null
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -913,7 +913,7 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, FloatField, FMatrixSp
|
||||
structure.getFeature(type)?.let { return it }
|
||||
val origin = structure.toEjml().origin
|
||||
|
||||
return when (type) {
|
||||
return type.cast(when (type) {
|
||||
QRDecompositionFeature::class -> object : QRDecompositionFeature<Float> {
|
||||
private val qr by lazy {
|
||||
DecompositionFactory_FSCC.qr(FillReducing.NONE).apply { decompose(origin.copy()) }
|
||||
@ -962,8 +962,8 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, FloatField, FMatrixSp
|
||||
override val determinant: Float by lazy { elementAlgebra.number(lu.computeDeterminant().real) }
|
||||
}
|
||||
|
||||
else -> null
|
||||
}?.let(type::cast)
|
||||
else -> return null
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
id("ru.mipt.npm.gradle.common")
|
||||
id("ru.mipt.npm.gradle.native")
|
||||
// id("ru.mipt.npm.gradle.native")
|
||||
}
|
||||
|
||||
kotlin.sourceSets.commonMain {
|
||||
@ -40,3 +40,8 @@ readme {
|
||||
"Uniform grid generators"
|
||||
}
|
||||
}
|
||||
|
||||
// Testing multi-receiver!
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile> {
|
||||
enabled = false
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
id("ru.mipt.npm.gradle.common")
|
||||
id("ru.mipt.npm.gradle.native")
|
||||
// id("ru.mipt.npm.gradle.native")
|
||||
}
|
||||
|
||||
description = "Functions, integration and interpolation"
|
||||
@ -32,3 +32,8 @@ readme {
|
||||
"Univariate and multivariate quadratures"
|
||||
}
|
||||
}
|
||||
|
||||
// Testing multi-receiver!
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile> {
|
||||
enabled = false
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ public fun <T, A> Polynomial<T>.integrate(
|
||||
): Polynomial<T> where A : Field<T>, A : NumericAlgebra<T> = algebra {
|
||||
val integratedCoefficients = buildList(coefficients.size + 1) {
|
||||
add(zero)
|
||||
coefficients.forEachIndexed{ index, t -> add(t / (number(index) + one)) }
|
||||
coefficients.forEachIndexed { index, t -> add(t / (number(index) + one)) }
|
||||
}
|
||||
Polynomial(integratedCoefficients)
|
||||
}
|
||||
@ -100,8 +100,8 @@ public class PolynomialSpace<T, C>(
|
||||
) : Group<Polynomial<T>>, ScaleOperations<Polynomial<T>> where C : Ring<T>, C : ScaleOperations<T> {
|
||||
override val zero: Polynomial<T> = Polynomial(emptyList())
|
||||
|
||||
override fun Polynomial<T>.unaryMinus(): Polynomial<T> = ring {
|
||||
Polynomial(coefficients.map { -it })
|
||||
override fun negate(arg: Polynomial<T>): Polynomial<T> = ring {
|
||||
Polynomial(arg.coefficients.map { -it })
|
||||
}
|
||||
|
||||
override fun add(left: Polynomial<T>, right: Polynomial<T>): Polynomial<T> {
|
||||
|
@ -6,6 +6,9 @@ package space.kscience.kmath.integration
|
||||
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.operations.Field
|
||||
import space.kscience.kmath.operations.minus
|
||||
import space.kscience.kmath.operations.plus
|
||||
import space.kscience.kmath.operations.times
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.asBuffer
|
||||
import space.kscience.kmath.structures.indices
|
||||
|
@ -6,10 +6,7 @@
|
||||
package space.kscience.kmath.integration
|
||||
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.Field
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.sum
|
||||
import space.kscience.kmath.operations.*
|
||||
|
||||
/**
|
||||
* Use double pass Simpson rule integration with a fixed number of points.
|
||||
@ -60,7 +57,8 @@ public class SimpsonIntegrator<T : Any>(
|
||||
}
|
||||
|
||||
@UnstableKMathAPI
|
||||
public val <T : Any> Field<T>.simpsonIntegrator: SimpsonIntegrator<T> get() = SimpsonIntegrator(this)
|
||||
public val <T : Any> Field<T>.simpsonIntegrator: SimpsonIntegrator<T>
|
||||
get() = SimpsonIntegrator(this)
|
||||
|
||||
/**
|
||||
* Use double pass Simpson rule integration with a fixed number of points.
|
||||
|
@ -9,8 +9,7 @@ import space.kscience.kmath.data.XYColumnarData
|
||||
import space.kscience.kmath.functions.PiecewisePolynomial
|
||||
import space.kscience.kmath.functions.Polynomial
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.operations.Field
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.*
|
||||
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
internal fun <T : Comparable<T>> insureSorted(points: XYColumnarData<*, T, *>) {
|
||||
|
@ -9,9 +9,7 @@ import space.kscience.kmath.data.XYColumnarData
|
||||
import space.kscience.kmath.functions.PiecewisePolynomial
|
||||
import space.kscience.kmath.functions.Polynomial
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.Field
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.*
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
import space.kscience.kmath.structures.MutableBufferFactory
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
id("ru.mipt.npm.gradle.common")
|
||||
id("ru.mipt.npm.gradle.native")
|
||||
// id("ru.mipt.npm.gradle.native")
|
||||
}
|
||||
|
||||
kotlin.sourceSets.commonMain {
|
||||
@ -13,3 +13,8 @@ kotlin.sourceSets.commonMain {
|
||||
readme {
|
||||
maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE
|
||||
}
|
||||
|
||||
// Testing multi-receiver!
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile> {
|
||||
enabled = false
|
||||
}
|
||||
|
@ -6,12 +6,11 @@
|
||||
package space.kscience.kmath.geometry
|
||||
|
||||
import space.kscience.kmath.linear.Point
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.operations.ScaleOperations
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.minus
|
||||
import kotlin.math.sqrt
|
||||
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
public interface Vector2D : Point<Double>, Vector {
|
||||
public val x: Double
|
||||
public val y: Double
|
||||
@ -44,7 +43,7 @@ public object Euclidean2DSpace : GeometrySpace<Vector2D>, ScaleOperations<Vector
|
||||
override val zero: Vector2D by lazy { Vector2D(0.0, 0.0) }
|
||||
|
||||
public fun Vector2D.norm(): Double = sqrt(x * x + y * y)
|
||||
override fun Vector2D.unaryMinus(): Vector2D = Vector2D(-x, -y)
|
||||
override fun negate(arg: Vector2D): Vector2D = Vector2D(-arg.x, -arg.y)
|
||||
|
||||
override fun Vector2D.distanceTo(other: Vector2D): Double = (this - other).norm()
|
||||
override fun add(left: Vector2D, right: Vector2D): Vector2D = Vector2D(left.x + right.x, left.y + right.y)
|
||||
|
@ -6,12 +6,11 @@
|
||||
package space.kscience.kmath.geometry
|
||||
|
||||
import space.kscience.kmath.linear.Point
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.operations.ScaleOperations
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.minus
|
||||
import kotlin.math.sqrt
|
||||
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
public interface Vector3D : Point<Double>, Vector {
|
||||
public val x: Double
|
||||
public val y: Double
|
||||
@ -43,7 +42,7 @@ public object Euclidean3DSpace : GeometrySpace<Vector3D>, ScaleOperations<Vector
|
||||
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)
|
||||
override fun Vector3D.unaryMinus(): Vector3D = Vector3D(-x, -y, -z)
|
||||
override fun negate(arg: Vector3D): Vector3D = Vector3D(-arg.x, -arg.y, -arg.z)
|
||||
|
||||
override fun Vector3D.distanceTo(other: Vector3D): Double = (this - other).norm()
|
||||
|
||||
|
@ -5,6 +5,11 @@
|
||||
|
||||
package space.kscience.kmath.geometry
|
||||
|
||||
import space.kscience.kmath.operations.div
|
||||
import space.kscience.kmath.operations.minus
|
||||
import space.kscience.kmath.operations.plus
|
||||
import space.kscience.kmath.operations.times
|
||||
|
||||
/**
|
||||
* Project vector onto a line.
|
||||
* @param vector to project
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
package space.kscience.kmath.geometry
|
||||
|
||||
import space.kscience.kmath.operations.plus
|
||||
import space.kscience.kmath.operations.times
|
||||
import kotlin.math.sqrt
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
package space.kscience.kmath.geometry
|
||||
|
||||
import space.kscience.kmath.operations.plus
|
||||
import space.kscience.kmath.operations.times
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
package space.kscience.kmath.geometry
|
||||
|
||||
import space.kscience.kmath.operations.minus
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
package space.kscience.kmath.geometry
|
||||
|
||||
import space.kscience.kmath.operations.minus
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
id("ru.mipt.npm.gradle.common")
|
||||
id("ru.mipt.npm.gradle.native")
|
||||
// id("ru.mipt.npm.gradle.native")
|
||||
}
|
||||
|
||||
kscience {
|
||||
@ -9,6 +9,12 @@ kscience {
|
||||
}
|
||||
|
||||
kotlin.sourceSets {
|
||||
filter { it.name.contains("test", true) }
|
||||
.map(org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet::languageSettings)
|
||||
.forEach {
|
||||
it.optIn("space.kscience.kmath.misc.UnstableKMathAPI")
|
||||
}
|
||||
|
||||
commonMain {
|
||||
dependencies {
|
||||
api(project(":kmath-core"))
|
||||
@ -26,3 +32,8 @@ kotlin.sourceSets {
|
||||
readme {
|
||||
maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE
|
||||
}
|
||||
|
||||
// Testing multi-receiver!
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile> {
|
||||
enabled = false
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import kotlinx.atomicfu.atomic
|
||||
import kotlinx.atomicfu.getAndUpdate
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.Group
|
||||
import space.kscience.kmath.operations.plus
|
||||
|
||||
/**
|
||||
* Common representation for atomic counters
|
||||
@ -72,5 +73,3 @@ public class ObjectCounter<T : Any>(private val group: Group<T>) : Counter<T> {
|
||||
|
||||
override val value: T get() = innerValue.value
|
||||
}
|
||||
|
||||
|
||||
|
@ -11,9 +11,7 @@ import space.kscience.kmath.nd.DefaultStrides
|
||||
import space.kscience.kmath.nd.FieldOpsND
|
||||
import space.kscience.kmath.nd.Shape
|
||||
import space.kscience.kmath.nd.StructureND
|
||||
import space.kscience.kmath.operations.Group
|
||||
import space.kscience.kmath.operations.ScaleOperations
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.*
|
||||
|
||||
/**
|
||||
* @param T the type of the argument space
|
||||
|
@ -7,10 +7,7 @@ package space.kscience.kmath.histogram
|
||||
|
||||
import space.kscience.kmath.domains.DoubleDomain1D
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.operations.Group
|
||||
import space.kscience.kmath.operations.Ring
|
||||
import space.kscience.kmath.operations.ScaleOperations
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.*
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import kotlin.math.floor
|
||||
|
||||
@ -69,8 +66,8 @@ public class UniformHistogram1DGroup<V : Any, A>(
|
||||
)
|
||||
}
|
||||
|
||||
override fun Histogram1D<Double, V>.unaryMinus(): UniformHistogram1D<V> = valueAlgebra {
|
||||
UniformHistogram1D(this@UniformHistogram1DGroup, produceFrom(this@unaryMinus).values.mapValues { -it.value })
|
||||
override fun negate(arg: Histogram1D<Double, V>): UniformHistogram1D<V> = valueAlgebra {
|
||||
UniformHistogram1D(this@UniformHistogram1DGroup, produceFrom(arg).values.mapValues { -it.value })
|
||||
}
|
||||
|
||||
override fun scale(
|
||||
|
@ -14,6 +14,7 @@ import space.kscience.kmath.nd.*
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.Field
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.unaryMinus
|
||||
import space.kscience.kmath.structures.*
|
||||
import kotlin.math.floor
|
||||
|
||||
@ -98,8 +99,8 @@ public class UniformHistogramGroupND<V : Any, A : Field<V>>(
|
||||
return HistogramND(this, values)
|
||||
}
|
||||
|
||||
override fun HistogramND<Double, HyperSquareDomain, V>.unaryMinus(): HistogramND<Double, HyperSquareDomain, V> =
|
||||
this * (-1)
|
||||
override fun negate(arg: HistogramND<Double, HyperSquareDomain, V>): HistogramND<Double, HyperSquareDomain, V> =
|
||||
HistogramND(this, valueAlgebraND { -arg.values })
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -10,6 +10,7 @@ package space.kscience.kmath.histogram
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.nd.DefaultStrides
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.minus
|
||||
import space.kscience.kmath.real.DoubleVector
|
||||
import kotlin.random.Random
|
||||
import kotlin.test.*
|
||||
|
@ -10,6 +10,7 @@ import kotlinx.coroutines.test.runTest
|
||||
import space.kscience.kmath.distributions.NormalDistribution
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.plus
|
||||
import space.kscience.kmath.stat.RandomGenerator
|
||||
import space.kscience.kmath.stat.nextBuffer
|
||||
import kotlin.native.concurrent.ThreadLocal
|
||||
@ -36,7 +37,7 @@ internal class UniformHistogram1DTest {
|
||||
@Test
|
||||
fun rebinDown() = runTest {
|
||||
val h1 = Histogram.uniform1D(DoubleField, 0.01).produce(generator.nextDoubleBuffer(10000))
|
||||
val h2 = Histogram.uniform1D(DoubleField,0.03).produceFrom(h1)
|
||||
val h2 = Histogram.uniform1D(DoubleField, 0.03).produceFrom(h1)
|
||||
|
||||
assertEquals(10000, h2.bins.sumOf { it.binValue }.toInt())
|
||||
}
|
||||
@ -44,13 +45,13 @@ internal class UniformHistogram1DTest {
|
||||
@Test
|
||||
fun rebinUp() = runTest {
|
||||
val h1 = Histogram.uniform1D(DoubleField, 0.03).produce(generator.nextDoubleBuffer(10000))
|
||||
val h2 = Histogram.uniform1D(DoubleField,0.01).produceFrom(h1)
|
||||
val h2 = Histogram.uniform1D(DoubleField, 0.01).produceFrom(h1)
|
||||
|
||||
assertEquals(10000, h2.bins.sumOf { it.binValue }.toInt())
|
||||
}
|
||||
|
||||
@ThreadLocal
|
||||
companion object{
|
||||
companion object {
|
||||
private val generator = RandomGenerator.default(123)
|
||||
}
|
||||
}
|
@ -11,9 +11,7 @@ import space.kscience.kmath.domains.DoubleDomain1D
|
||||
import space.kscience.kmath.domains.center
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.misc.sorted
|
||||
import space.kscience.kmath.operations.Group
|
||||
import space.kscience.kmath.operations.Ring
|
||||
import space.kscience.kmath.operations.ScaleOperations
|
||||
import space.kscience.kmath.operations.*
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.first
|
||||
import space.kscience.kmath.structures.indices
|
||||
@ -123,7 +121,18 @@ public class TreeHistogramGroup<V : Any, A>(
|
||||
return TreeHistogram(bins)
|
||||
}
|
||||
|
||||
override fun TreeHistogram<V>.unaryMinus(): TreeHistogram<V> = this * (-1)
|
||||
override fun negate(arg: TreeHistogram<V>): TreeHistogram<V> {
|
||||
val bins = TreeMap<Double, Bin1D<Double, V>>().apply {
|
||||
arg.bins.forEach { bin ->
|
||||
put(
|
||||
bin.domain.center,
|
||||
Bin1D(bin.domain, valueAlgebra { -bin.binValue })
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return TreeHistogram(bins)
|
||||
}
|
||||
|
||||
override val zero: TreeHistogram<V> = produce { }
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ public object JafamaDoubleField : ExtendedField<Double>, Norm<Double, Double>, S
|
||||
}
|
||||
|
||||
override inline fun add(left: Double, right: Double): Double = left + right
|
||||
override inline fun negate(arg: Double): Double = -arg
|
||||
override inline fun subtract(left: Double, right: Double): Double = left - right
|
||||
|
||||
override inline fun multiply(left: Double, right: Double): Double = left * right
|
||||
override inline fun divide(left: Double, right: Double): Double = left / right
|
||||
@ -55,12 +57,6 @@ public object JafamaDoubleField : ExtendedField<Double>, Norm<Double, Double>, S
|
||||
override inline fun ln(arg: Double): Double = FastMath.log(arg)
|
||||
|
||||
override inline fun norm(arg: Double): Double = FastMath.abs(arg)
|
||||
|
||||
override inline fun Double.unaryMinus(): Double = -this
|
||||
override inline fun Double.plus(arg: Double): Double = this + arg
|
||||
override inline fun Double.minus(arg: Double): Double = this - arg
|
||||
override inline fun Double.times(arg: Double): Double = this * arg
|
||||
override inline fun Double.div(arg: Double): Double = this / arg
|
||||
}
|
||||
|
||||
/**
|
||||
@ -80,6 +76,8 @@ public object StrictJafamaDoubleField : ExtendedField<Double>, Norm<Double, Doub
|
||||
}
|
||||
|
||||
override inline fun add(left: Double, right: Double): Double = left + right
|
||||
override inline fun negate(arg: Double): Double = -arg
|
||||
override inline fun subtract(left: Double, right: Double): Double = left - right
|
||||
|
||||
override inline fun multiply(left: Double, right: Double): Double = left * right
|
||||
override inline fun divide(left: Double, right: Double): Double = left / right
|
||||
@ -106,10 +104,4 @@ public object StrictJafamaDoubleField : ExtendedField<Double>, Norm<Double, Doub
|
||||
override inline fun ln(arg: Double): Double = StrictFastMath.log(arg)
|
||||
|
||||
override inline fun norm(arg: Double): Double = StrictFastMath.abs(arg)
|
||||
|
||||
override inline fun Double.unaryMinus(): Double = -this
|
||||
override inline fun Double.plus(arg: Double): Double = this + arg
|
||||
override inline fun Double.minus(arg: Double): Double = this - arg
|
||||
override inline fun Double.times(arg: Double): Double = this * arg
|
||||
override inline fun Double.div(arg: Double): Double = this / arg
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ import space.kscience.kmath.misc.PerformancePitfall
|
||||
import space.kscience.kmath.nd.Structure2D
|
||||
import space.kscience.kmath.operations.asSequence
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.plus
|
||||
import space.kscience.kmath.operations.times
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
|
||||
/**
|
||||
|
@ -8,7 +8,6 @@ package space.kscience.kmath.kotlingrad
|
||||
import ai.hypergraph.kotlingrad.api.*
|
||||
import space.kscience.kmath.expressions.MST
|
||||
import space.kscience.kmath.expressions.MstExtendedField
|
||||
import space.kscience.kmath.expressions.MstExtendedField.unaryMinus
|
||||
import space.kscience.kmath.expressions.MstNumericAlgebra
|
||||
import space.kscience.kmath.expressions.Symbol
|
||||
import space.kscience.kmath.operations.*
|
||||
|
@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
id("ru.mipt.npm.gradle.common")
|
||||
id("ru.mipt.npm.gradle.native")
|
||||
// id("ru.mipt.npm.gradle.native")
|
||||
}
|
||||
|
||||
readme {
|
||||
|
@ -20,8 +20,7 @@ internal class ByteBufferMemory(
|
||||
val startOffset: Int = 0,
|
||||
override val size: Int = buffer.limit(),
|
||||
) : Memory {
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
private inline fun position(o: Int): Int = startOffset + o
|
||||
private fun position(o: Int): Int = startOffset + o
|
||||
|
||||
override fun view(offset: Int, length: Int): Memory {
|
||||
require(offset >= 0) { "offset shouldn't be negative: $offset" }
|
||||
|
@ -7,28 +7,29 @@ package space.kscience.kmath.multik
|
||||
|
||||
import org.jetbrains.kotlinx.multik.ndarray.data.DataType
|
||||
import space.kscience.kmath.nd.StructureND
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.ExponentialOperations
|
||||
import space.kscience.kmath.operations.TrigonometricOperations
|
||||
import space.kscience.kmath.operations.*
|
||||
|
||||
public object MultikDoubleAlgebra : MultikDivisionTensorAlgebra<Double, DoubleField>(),
|
||||
TrigonometricOperations<StructureND<Double>>, ExponentialOperations<StructureND<Double>> {
|
||||
override val elementAlgebra: DoubleField get() = DoubleField
|
||||
override val type: DataType get() = DataType.DoubleDataType
|
||||
|
||||
override fun sin(arg: StructureND<Double>): MultikTensor<Double> = multikMath.mathEx.sin(arg.asMultik().array).wrap()
|
||||
override fun sin(arg: StructureND<Double>): MultikTensor<Double> =
|
||||
multikMath.mathEx.sin(arg.asMultik().array).wrap()
|
||||
|
||||
override fun cos(arg: StructureND<Double>): MultikTensor<Double> = multikMath.mathEx.cos(arg.asMultik().array).wrap()
|
||||
override fun cos(arg: StructureND<Double>): MultikTensor<Double> =
|
||||
multikMath.mathEx.cos(arg.asMultik().array).wrap()
|
||||
|
||||
override fun tan(arg: StructureND<Double>): MultikTensor<Double> = sin(arg) / cos(arg)
|
||||
|
||||
override fun asin(arg: StructureND<Double>): MultikTensor<Double> = arg.map { asin(it) }
|
||||
override fun asin(arg: StructureND<Double>): MultikTensor<Double> = arg.map { asin(it) }
|
||||
|
||||
override fun acos(arg: StructureND<Double>): MultikTensor<Double> = arg.map { acos(it) }
|
||||
|
||||
override fun atan(arg: StructureND<Double>): MultikTensor<Double> = arg.map { atan(it) }
|
||||
|
||||
override fun exp(arg: StructureND<Double>): MultikTensor<Double> = multikMath.mathEx.exp(arg.asMultik().array).wrap()
|
||||
override fun exp(arg: StructureND<Double>): MultikTensor<Double> =
|
||||
multikMath.mathEx.exp(arg.asMultik().array).wrap()
|
||||
|
||||
override fun ln(arg: StructureND<Double>): MultikTensor<Double> = multikMath.mathEx.log(arg.asMultik().array).wrap()
|
||||
|
||||
@ -39,7 +40,7 @@ public object MultikDoubleAlgebra : MultikDivisionTensorAlgebra<Double, DoubleFi
|
||||
override fun tanh(arg: StructureND<Double>): MultikTensor<Double> {
|
||||
val expPlus = exp(arg)
|
||||
val expMinus = exp(-arg)
|
||||
return (expPlus - expMinus) / (expPlus + expMinus)
|
||||
return divide((expPlus - expMinus), (expPlus + expMinus))
|
||||
}
|
||||
|
||||
override fun asinh(arg: StructureND<Double>): MultikTensor<Double> = arg.map { asinh(it) }
|
||||
@ -51,4 +52,3 @@ public object MultikDoubleAlgebra : MultikDivisionTensorAlgebra<Double, DoubleFi
|
||||
|
||||
public val Double.Companion.multikAlgebra: MultikTensorAlgebra<Double, DoubleField> get() = MultikDoubleAlgebra
|
||||
public val DoubleField.multikAlgebra: MultikTensorAlgebra<Double, DoubleField> get() = MultikDoubleAlgebra
|
||||
|
||||
|
@ -50,7 +50,7 @@ private fun <T, D : Dimension> MultiArray<T, D>.asD2Array(): D2Array<T> {
|
||||
else throw ClassCastException("Cannot cast MultiArray to NDArray.")
|
||||
}
|
||||
|
||||
public abstract class MultikTensorAlgebra<T, A : Ring<T>> : TensorAlgebra<T, A>
|
||||
public abstract class MultikTensorAlgebra<T, out A : Ring<T>> : TensorAlgebra<T, A>
|
||||
where T : Number, T : Comparable<T> {
|
||||
|
||||
public abstract val type: DataType
|
||||
@ -138,14 +138,8 @@ public abstract class MultikTensorAlgebra<T, A : Ring<T>> : TensorAlgebra<T, A>
|
||||
get(intArrayOf(0))
|
||||
} else null
|
||||
|
||||
override fun T.plus(arg: StructureND<T>): MultikTensor<T> =
|
||||
arg.plus(this)
|
||||
|
||||
override fun StructureND<T>.plus(arg: T): MultikTensor<T> =
|
||||
asMultik().array.deepCopy().apply { plusAssign(arg) }.wrap()
|
||||
|
||||
override fun StructureND<T>.plus(arg: StructureND<T>): MultikTensor<T> =
|
||||
asMultik().array.plus(arg.asMultik().array).wrap()
|
||||
override fun add(left: StructureND<T>, right: StructureND<T>): MultikTensor<T> =
|
||||
left.asMultik().array.plus(right.asMultik().array).wrap()
|
||||
|
||||
override fun Tensor<T>.plusAssign(value: T) {
|
||||
if (this is MultikTensor) {
|
||||
@ -163,13 +157,8 @@ public abstract class MultikTensorAlgebra<T, A : Ring<T>> : TensorAlgebra<T, A>
|
||||
}
|
||||
}
|
||||
|
||||
override fun T.minus(arg: StructureND<T>): MultikTensor<T> = (-(arg.asMultik().array - this)).wrap()
|
||||
|
||||
override fun StructureND<T>.minus(arg: T): MultikTensor<T> =
|
||||
asMultik().array.deepCopy().apply { minusAssign(arg) }.wrap()
|
||||
|
||||
override fun StructureND<T>.minus(arg: StructureND<T>): MultikTensor<T> =
|
||||
asMultik().array.minus(arg.asMultik().array).wrap()
|
||||
override fun subtract(left: StructureND<T>, right: StructureND<T>): MultikTensor<T> =
|
||||
left.asMultik().array.minus(right.asMultik().array).wrap()
|
||||
|
||||
override fun Tensor<T>.minusAssign(value: T) {
|
||||
if (this is MultikTensor) {
|
||||
@ -187,14 +176,8 @@ public abstract class MultikTensorAlgebra<T, A : Ring<T>> : TensorAlgebra<T, A>
|
||||
}
|
||||
}
|
||||
|
||||
override fun T.times(arg: StructureND<T>): MultikTensor<T> =
|
||||
arg.asMultik().array.deepCopy().apply { timesAssign(this@times) }.wrap()
|
||||
|
||||
override fun StructureND<T>.times(arg: T): Tensor<T> =
|
||||
asMultik().array.deepCopy().apply { timesAssign(arg) }.wrap()
|
||||
|
||||
override fun StructureND<T>.times(arg: StructureND<T>): MultikTensor<T> =
|
||||
asMultik().array.times(arg.asMultik().array).wrap()
|
||||
override fun multiply(left: StructureND<T>, right: StructureND<T>): MultikTensor<T> =
|
||||
left.asMultik().array.times(right.asMultik().array).wrap()
|
||||
|
||||
override fun Tensor<T>.timesAssign(value: T) {
|
||||
if (this is MultikTensor) {
|
||||
@ -212,12 +195,11 @@ public abstract class MultikTensorAlgebra<T, A : Ring<T>> : TensorAlgebra<T, A>
|
||||
}
|
||||
}
|
||||
|
||||
override fun StructureND<T>.unaryMinus(): MultikTensor<T> =
|
||||
asMultik().array.unaryMinus().wrap()
|
||||
override fun negate(arg: StructureND<T>): MultikTensor<T> = (-arg.asMultik().array).wrap()
|
||||
|
||||
override fun Tensor<T>.get(i: Int): MultikTensor<T> = asMultik().array.mutableView(i).wrap()
|
||||
|
||||
override fun Tensor<T>.transpose(i: Int, j: Int): MultikTensor<T> = asMultik().array.transpose(i, j).wrap()
|
||||
override fun StructureND<T>.transpose(i: Int, j: Int): MultikTensor<T> = asMultik().array.transpose(i, j).wrap()
|
||||
|
||||
override fun Tensor<T>.view(shape: IntArray): MultikTensor<T> {
|
||||
require(shape.all { it > 0 })
|
||||
@ -282,16 +264,36 @@ public abstract class MultikTensorAlgebra<T, A : Ring<T>> : TensorAlgebra<T, A>
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class MultikDivisionTensorAlgebra<T, A : Field<T>>
|
||||
context(MultikTensorAlgebra<T, A>)
|
||||
public operator fun <T, A : Ring<T>> T.plus(arg: StructureND<T>): MultikTensor<T> where T : Comparable<T>, T : Number =
|
||||
arg.plus(this)
|
||||
|
||||
context(MultikTensorAlgebra<T, A>)
|
||||
public operator fun <T, A : Ring<T>> StructureND<T>.plus(arg: T): MultikTensor<T> where T : Comparable<T>, T : Number =
|
||||
asMultik().array.deepCopy().apply { plusAssign(arg) }.wrap()
|
||||
|
||||
context(MultikTensorAlgebra<T, A>)
|
||||
public operator fun <T, A : Ring<T>> T.minus(arg: StructureND<T>): MultikTensor<T> where T : Comparable<T>, T : Number =
|
||||
(-(arg.asMultik().array - this)).wrap()
|
||||
|
||||
context(MultikTensorAlgebra<T, A>)
|
||||
public operator fun <T, A : Ring<T>> StructureND<T>.minus(arg: T): MultikTensor<T> where T : Comparable<T>, T : Number =
|
||||
asMultik().array.deepCopy().apply { minusAssign(arg) }.wrap()
|
||||
|
||||
context(MultikTensorAlgebra<T, A>)
|
||||
public operator fun <T, A : Ring<T>> T.times(arg: StructureND<T>): MultikTensor<T> where T : Comparable<T>, T : Number =
|
||||
arg.asMultik().array.deepCopy().apply { timesAssign(this@times) }.wrap()
|
||||
|
||||
context(MultikTensorAlgebra<T, A>)
|
||||
public operator fun <T, A : Ring<T>> StructureND<T>.times(arg: T): Tensor<T> where T : Comparable<T>, T : Number =
|
||||
asMultik().array.deepCopy().apply { timesAssign(arg) }.wrap()
|
||||
|
||||
|
||||
public abstract class MultikDivisionTensorAlgebra<T, out A : Field<T>>
|
||||
: MultikTensorAlgebra<T, A>(), TensorPartialDivisionAlgebra<T, A> where T : Number, T : Comparable<T> {
|
||||
|
||||
override fun T.div(arg: StructureND<T>): MultikTensor<T> = arg.map { elementAlgebra.divide(this@div, it) }
|
||||
|
||||
override fun StructureND<T>.div(arg: T): MultikTensor<T> =
|
||||
asMultik().array.deepCopy().apply { divAssign(arg) }.wrap()
|
||||
|
||||
override fun StructureND<T>.div(arg: StructureND<T>): MultikTensor<T> =
|
||||
asMultik().array.div(arg.asMultik().array).wrap()
|
||||
override fun divide(left: StructureND<T>, right: StructureND<T>): MultikTensor<T> =
|
||||
left.asMultik().array.div(right.asMultik().array).wrap()
|
||||
|
||||
override fun Tensor<T>.divAssign(value: T) {
|
||||
if (this is MultikTensor) {
|
||||
@ -310,6 +312,18 @@ public abstract class MultikDivisionTensorAlgebra<T, A : Field<T>>
|
||||
}
|
||||
}
|
||||
|
||||
context(MultikDivisionTensorAlgebra<T, A>)
|
||||
public operator fun <T, A : Field<T>> StructureND<T>.div(arg: StructureND<T>): MultikTensor<T> where T : Number, T : Comparable<T> =
|
||||
divide(this, arg)
|
||||
|
||||
context(MultikDivisionTensorAlgebra<T, A>)
|
||||
public operator fun <T, A : Field<T>> T.div(arg: StructureND<T>): MultikTensor<T> where T : Number, T : Comparable<T> =
|
||||
arg.map { elementAlgebra.divide(this@div, it) }
|
||||
|
||||
context(MultikDivisionTensorAlgebra<T, A>)
|
||||
public operator fun <T, A : Field<T>> StructureND<T>.div(arg: T): MultikTensor<T> where T : Number, T : Comparable<T> =
|
||||
asMultik().array.deepCopy().apply { divAssign(arg) }.wrap()
|
||||
|
||||
public object MultikFloatAlgebra : MultikDivisionTensorAlgebra<Float, FloatField>() {
|
||||
override val elementAlgebra: FloatField get() = FloatField
|
||||
override val type: DataType get() = DataType.FloatDataType
|
||||
@ -340,4 +354,4 @@ public object MultikLongAlgebra : MultikTensorAlgebra<Long, LongRing>() {
|
||||
}
|
||||
|
||||
public val Long.Companion.multikAlgebra: MultikTensorAlgebra<Long, LongRing> get() = MultikLongAlgebra
|
||||
public val LongRing.multikAlgebra: MultikTensorAlgebra<Long, LongRing> get() = MultikLongAlgebra
|
||||
public val LongRing.multikAlgebra: MultikTensorAlgebra<Long, LongRing> get() = MultikLongAlgebra
|
||||
|
@ -45,6 +45,7 @@ public sealed interface Nd4jArrayAlgebra<T, out C : Algebra<T>> : AlgebraND<T, C
|
||||
return newStruct
|
||||
}
|
||||
|
||||
@OptIn(PerformancePitfall::class)
|
||||
override fun StructureND<T>.mapIndexed(
|
||||
transform: C.(index: IntArray, T) -> T,
|
||||
): Nd4jArrayStructure<T> {
|
||||
@ -53,6 +54,7 @@ public sealed interface Nd4jArrayAlgebra<T, out C : Algebra<T>> : AlgebraND<T, C
|
||||
return new
|
||||
}
|
||||
|
||||
@OptIn(PerformancePitfall::class)
|
||||
override fun zip(
|
||||
left: StructureND<T>,
|
||||
right: StructureND<T>,
|
||||
@ -72,15 +74,14 @@ public sealed interface Nd4jArrayAlgebra<T, out C : Algebra<T>> : AlgebraND<T, C
|
||||
* @param S the type of space of structure elements.
|
||||
*/
|
||||
public sealed interface Nd4jArrayGroupOps<T, out S : Ring<T>> : GroupOpsND<T, S>, Nd4jArrayAlgebra<T, S> {
|
||||
|
||||
override fun add(left: StructureND<T>, right: StructureND<T>): Nd4jArrayStructure<T> =
|
||||
left.ndArray.add(right.ndArray).wrap()
|
||||
|
||||
override operator fun StructureND<T>.minus(arg: StructureND<T>): Nd4jArrayStructure<T> =
|
||||
ndArray.sub(arg.ndArray).wrap()
|
||||
override fun subtract(left: StructureND<T>, right: StructureND<T>): Nd4jArrayStructure<T> =
|
||||
left.ndArray.sub(right.ndArray).wrap()
|
||||
|
||||
override operator fun StructureND<T>.unaryMinus(): Nd4jArrayStructure<T> =
|
||||
ndArray.neg().wrap()
|
||||
override fun negate(arg: StructureND<T>): Nd4jArrayStructure<T> =
|
||||
arg.ndArray.neg().wrap()
|
||||
|
||||
public fun multiply(a: StructureND<T>, k: Number): Nd4jArrayStructure<T> =
|
||||
a.ndArray.mul(k).wrap()
|
||||
@ -92,7 +93,6 @@ public sealed interface Nd4jArrayGroupOps<T, out S : Ring<T>> : GroupOpsND<T, S>
|
||||
* @param T the type of the element contained in ND structure.
|
||||
* @param R the type of ring of structure elements.
|
||||
*/
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
public sealed interface Nd4jArrayRingOps<T, out R : Ring<T>> : RingOpsND<T, R>, Nd4jArrayGroupOps<T, R> {
|
||||
|
||||
override fun multiply(left: StructureND<T>, right: StructureND<T>): Nd4jArrayStructure<T> =
|
||||
@ -201,23 +201,29 @@ public open class DoubleNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Double, Do
|
||||
|
||||
override fun scale(a: StructureND<Double>, value: Double): Nd4jArrayStructure<Double> = a.ndArray.mul(value).wrap()
|
||||
|
||||
override operator fun StructureND<Double>.div(arg: Double): Nd4jArrayStructure<Double> = ndArray.div(arg).wrap()
|
||||
|
||||
override operator fun StructureND<Double>.plus(arg: Double): Nd4jArrayStructure<Double> = ndArray.add(arg).wrap()
|
||||
|
||||
override operator fun StructureND<Double>.minus(arg: Double): Nd4jArrayStructure<Double> = ndArray.sub(arg).wrap()
|
||||
|
||||
override operator fun StructureND<Double>.times(arg: Double): Nd4jArrayStructure<Double> = ndArray.mul(arg).wrap()
|
||||
|
||||
override operator fun Double.div(arg: StructureND<Double>): Nd4jArrayStructure<Double> =
|
||||
arg.ndArray.rdiv(this).wrap()
|
||||
|
||||
override operator fun Double.minus(arg: StructureND<Double>): Nd4jArrayStructure<Double> =
|
||||
arg.ndArray.rsub(this).wrap()
|
||||
|
||||
public companion object : DoubleNd4jArrayFieldOps()
|
||||
}
|
||||
|
||||
context(DoubleNd4jArrayFieldOps)
|
||||
public operator fun StructureND<Double>.div(arg: Double): Nd4jArrayStructure<Double> = ndArray.div(arg).wrap()
|
||||
|
||||
context(DoubleNd4jArrayFieldOps)
|
||||
public operator fun StructureND<Double>.plus(arg: Double): Nd4jArrayStructure<Double> = ndArray.add(arg).wrap()
|
||||
|
||||
context(DoubleNd4jArrayFieldOps)
|
||||
public operator fun StructureND<Double>.minus(arg: Double): Nd4jArrayStructure<Double> = ndArray.sub(arg).wrap()
|
||||
|
||||
context(DoubleNd4jArrayFieldOps)
|
||||
public operator fun StructureND<Double>.times(arg: Double): Nd4jArrayStructure<Double> = ndArray.mul(arg).wrap()
|
||||
|
||||
context(DoubleNd4jArrayFieldOps)
|
||||
public operator fun Double.div(arg: StructureND<Double>): Nd4jArrayStructure<Double> =
|
||||
arg.ndArray.rdiv(this).wrap()
|
||||
|
||||
context(DoubleNd4jArrayFieldOps)
|
||||
public operator fun Double.minus(arg: StructureND<Double>): Nd4jArrayStructure<Double> =
|
||||
arg.ndArray.rsub(this).wrap()
|
||||
|
||||
public val DoubleField.nd4j: DoubleNd4jArrayFieldOps get() = DoubleNd4jArrayFieldOps
|
||||
|
||||
public class DoubleNd4jArrayField(override val shape: Shape) : DoubleNd4jArrayFieldOps(), FieldND<Double, DoubleField>
|
||||
@ -246,27 +252,33 @@ public open class FloatNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Float, Floa
|
||||
override fun scale(a: StructureND<Float>, value: Double): StructureND<Float> =
|
||||
a.ndArray.mul(value).wrap()
|
||||
|
||||
override operator fun StructureND<Float>.div(arg: Float): Nd4jArrayStructure<Float> =
|
||||
ndArray.div(arg).wrap()
|
||||
|
||||
override operator fun StructureND<Float>.plus(arg: Float): Nd4jArrayStructure<Float> =
|
||||
ndArray.add(arg).wrap()
|
||||
|
||||
override operator fun StructureND<Float>.minus(arg: Float): Nd4jArrayStructure<Float> =
|
||||
ndArray.sub(arg).wrap()
|
||||
|
||||
override operator fun StructureND<Float>.times(arg: Float): Nd4jArrayStructure<Float> =
|
||||
ndArray.mul(arg).wrap()
|
||||
|
||||
override operator fun Float.div(arg: StructureND<Float>): Nd4jArrayStructure<Float> =
|
||||
arg.ndArray.rdiv(this).wrap()
|
||||
|
||||
override operator fun Float.minus(arg: StructureND<Float>): Nd4jArrayStructure<Float> =
|
||||
arg.ndArray.rsub(this).wrap()
|
||||
|
||||
public companion object : FloatNd4jArrayFieldOps()
|
||||
}
|
||||
|
||||
context(FloatNd4jArrayFieldOps)
|
||||
public operator fun StructureND<Float>.div(arg: Float): Nd4jArrayStructure<Float> =
|
||||
ndArray.div(arg).wrap()
|
||||
|
||||
context(FloatNd4jArrayFieldOps)
|
||||
public operator fun StructureND<Float>.plus(arg: Float): Nd4jArrayStructure<Float> =
|
||||
ndArray.add(arg).wrap()
|
||||
|
||||
context(FloatNd4jArrayFieldOps)
|
||||
public operator fun StructureND<Float>.minus(arg: Float): Nd4jArrayStructure<Float> =
|
||||
ndArray.sub(arg).wrap()
|
||||
|
||||
context(FloatNd4jArrayFieldOps)
|
||||
public operator fun StructureND<Float>.times(arg: Float): Nd4jArrayStructure<Float> =
|
||||
ndArray.mul(arg).wrap()
|
||||
|
||||
context(FloatNd4jArrayFieldOps)
|
||||
public operator fun Float.div(arg: StructureND<Float>): Nd4jArrayStructure<Float> =
|
||||
arg.ndArray.rdiv(this).wrap()
|
||||
|
||||
context(FloatNd4jArrayFieldOps)
|
||||
public operator fun Float.minus(arg: StructureND<Float>): Nd4jArrayStructure<Float> =
|
||||
arg.ndArray.rsub(this).wrap()
|
||||
|
||||
public class FloatNd4jArrayField(override val shape: Shape) : FloatNd4jArrayFieldOps(), RingND<Float, FloatField>
|
||||
|
||||
public val FloatField.nd4j: FloatNd4jArrayFieldOps get() = FloatNd4jArrayFieldOps
|
||||
@ -291,21 +303,25 @@ public open class IntNd4jArrayRingOps : Nd4jArrayRingOps<Int, IntRing> {
|
||||
}
|
||||
}
|
||||
|
||||
override operator fun StructureND<Int>.plus(arg: Int): Nd4jArrayStructure<Int> =
|
||||
ndArray.add(arg).wrap()
|
||||
|
||||
override operator fun StructureND<Int>.minus(arg: Int): Nd4jArrayStructure<Int> =
|
||||
ndArray.sub(arg).wrap()
|
||||
|
||||
override operator fun StructureND<Int>.times(arg: Int): Nd4jArrayStructure<Int> =
|
||||
ndArray.mul(arg).wrap()
|
||||
|
||||
override operator fun Int.minus(arg: StructureND<Int>): Nd4jArrayStructure<Int> =
|
||||
arg.ndArray.rsub(this).wrap()
|
||||
|
||||
public companion object : IntNd4jArrayRingOps()
|
||||
}
|
||||
|
||||
context(IntNd4jArrayRingOps)
|
||||
public operator fun StructureND<Int>.plus(arg: Int): Nd4jArrayStructure<Int> =
|
||||
ndArray.add(arg).wrap()
|
||||
|
||||
context(IntNd4jArrayRingOps)
|
||||
public operator fun StructureND<Int>.minus(arg: Int): Nd4jArrayStructure<Int> =
|
||||
ndArray.sub(arg).wrap()
|
||||
|
||||
context(IntNd4jArrayRingOps)
|
||||
public operator fun StructureND<Int>.times(arg: Int): Nd4jArrayStructure<Int> =
|
||||
ndArray.mul(arg).wrap()
|
||||
|
||||
context(IntNd4jArrayRingOps)
|
||||
public operator fun Int.minus(arg: StructureND<Int>): Nd4jArrayStructure<Int> =
|
||||
arg.ndArray.rsub(this).wrap()
|
||||
|
||||
public val IntRing.nd4j: IntNd4jArrayRingOps get() = IntNd4jArrayRingOps
|
||||
|
||||
public class IntNd4jArrayRing(override val shape: Shape) : IntNd4jArrayRingOps(), RingND<Int, IntRing>
|
||||
|
@ -16,6 +16,7 @@ import space.kscience.kmath.misc.PerformancePitfall
|
||||
import space.kscience.kmath.nd.DefaultStrides
|
||||
import space.kscience.kmath.nd.Shape
|
||||
import space.kscience.kmath.nd.StructureND
|
||||
import space.kscience.kmath.operations.Algebra
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.Field
|
||||
import space.kscience.kmath.tensors.api.AnalyticTensorAlgebra
|
||||
@ -26,7 +27,7 @@ import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
|
||||
/**
|
||||
* ND4J based [TensorAlgebra] implementation.
|
||||
*/
|
||||
public sealed interface Nd4jTensorAlgebra<T : Number, A : Field<T>> : AnalyticTensorAlgebra<T, A> {
|
||||
public sealed interface Nd4jTensorAlgebra<T : Number, out A : Field<T>> : AnalyticTensorAlgebra<T, A> {
|
||||
|
||||
/**
|
||||
* Wraps [INDArray] to [Nd4jArrayStructure].
|
||||
@ -51,10 +52,8 @@ public sealed interface Nd4jTensorAlgebra<T : Number, A : Field<T>> : AnalyticTe
|
||||
return structureND(left.shape) { index -> elementAlgebra.transform(left[index], right[index]) }
|
||||
}
|
||||
|
||||
override fun T.plus(arg: StructureND<T>): Nd4jArrayStructure<T> = arg.ndArray.add(this).wrap()
|
||||
override fun StructureND<T>.plus(arg: T): Nd4jArrayStructure<T> = ndArray.add(arg).wrap()
|
||||
|
||||
override fun StructureND<T>.plus(arg: StructureND<T>): Nd4jArrayStructure<T> = ndArray.add(arg.ndArray).wrap()
|
||||
override fun add(left: StructureND<T>, right: StructureND<T>): Nd4jArrayStructure<T> =
|
||||
left.ndArray.add(right.ndArray).wrap()
|
||||
|
||||
override fun Tensor<T>.plusAssign(value: T) {
|
||||
ndArray.addi(value)
|
||||
@ -64,9 +63,8 @@ public sealed interface Nd4jTensorAlgebra<T : Number, A : Field<T>> : AnalyticTe
|
||||
ndArray.addi(arg.ndArray)
|
||||
}
|
||||
|
||||
override fun T.minus(arg: StructureND<T>): Nd4jArrayStructure<T> = arg.ndArray.rsub(this).wrap()
|
||||
override fun StructureND<T>.minus(arg: T): Nd4jArrayStructure<T> = ndArray.sub(arg).wrap()
|
||||
override fun StructureND<T>.minus(arg: StructureND<T>): Nd4jArrayStructure<T> = ndArray.sub(arg.ndArray).wrap()
|
||||
override fun subtract(left: StructureND<T>, right: StructureND<T>): Nd4jArrayStructure<T> =
|
||||
left.ndArray.sub(right.ndArray).wrap()
|
||||
|
||||
override fun Tensor<T>.minusAssign(value: T) {
|
||||
ndArray.rsubi(value)
|
||||
@ -76,12 +74,7 @@ public sealed interface Nd4jTensorAlgebra<T : Number, A : Field<T>> : AnalyticTe
|
||||
ndArray.subi(arg.ndArray)
|
||||
}
|
||||
|
||||
override fun T.times(arg: StructureND<T>): Nd4jArrayStructure<T> = arg.ndArray.mul(this).wrap()
|
||||
|
||||
override fun StructureND<T>.times(arg: T): Nd4jArrayStructure<T> =
|
||||
ndArray.mul(arg).wrap()
|
||||
|
||||
override fun StructureND<T>.times(arg: StructureND<T>): Nd4jArrayStructure<T> = ndArray.mul(arg.ndArray).wrap()
|
||||
override fun multiply(left: StructureND<T>, right: StructureND<T>): Nd4jArrayStructure<T> = left.ndArray.mul(right.ndArray).wrap()
|
||||
|
||||
override fun Tensor<T>.timesAssign(value: T) {
|
||||
ndArray.muli(value)
|
||||
@ -91,9 +84,9 @@ public sealed interface Nd4jTensorAlgebra<T : Number, A : Field<T>> : AnalyticTe
|
||||
ndArray.mmuli(arg.ndArray)
|
||||
}
|
||||
|
||||
override fun StructureND<T>.unaryMinus(): Nd4jArrayStructure<T> = ndArray.neg().wrap()
|
||||
override fun negate(arg: StructureND<T>): Nd4jArrayStructure<T> = arg.ndArray.neg().wrap()
|
||||
override fun Tensor<T>.get(i: Int): Nd4jArrayStructure<T> = ndArray.slice(i.toLong()).wrap()
|
||||
override fun Tensor<T>.transpose(i: Int, j: Int): Nd4jArrayStructure<T> = ndArray.swapAxes(i, j).wrap()
|
||||
override fun StructureND<T>.transpose(i: Int, j: Int): Nd4jArrayStructure<T> = ndArray.swapAxes(i, j).wrap()
|
||||
override fun StructureND<T>.dot(other: StructureND<T>): Nd4jArrayStructure<T> = ndArray.mmul(other.ndArray).wrap()
|
||||
|
||||
override fun StructureND<T>.min(dim: Int, keepDim: Boolean): Nd4jArrayStructure<T> =
|
||||
@ -140,9 +133,7 @@ public sealed interface Nd4jTensorAlgebra<T : Number, A : Field<T>> : AnalyticTe
|
||||
override fun StructureND<T>.std(dim: Int, keepDim: Boolean): Nd4jArrayStructure<T> =
|
||||
ndArray.std(true, keepDim, dim).wrap()
|
||||
|
||||
override fun T.div(arg: StructureND<T>): Nd4jArrayStructure<T> = arg.ndArray.rdiv(this).wrap()
|
||||
override fun StructureND<T>.div(arg: T): Nd4jArrayStructure<T> = ndArray.div(arg).wrap()
|
||||
override fun StructureND<T>.div(arg: StructureND<T>): Nd4jArrayStructure<T> = ndArray.div(arg.ndArray).wrap()
|
||||
override fun divide(left: StructureND<T>, right: StructureND<T>): Nd4jArrayStructure<T> = left.ndArray.div(right.ndArray).wrap()
|
||||
|
||||
override fun Tensor<T>.divAssign(value: T) {
|
||||
ndArray.divi(value)
|
||||
@ -160,6 +151,36 @@ public sealed interface Nd4jTensorAlgebra<T : Number, A : Field<T>> : AnalyticTe
|
||||
}
|
||||
}
|
||||
|
||||
context(Nd4jTensorAlgebra<T, C>)
|
||||
public fun <T : Number, C : Field<T>> T.plus(arg: StructureND<T>): Nd4jArrayStructure<T> = arg.ndArray.add(this).wrap()
|
||||
|
||||
context(Nd4jTensorAlgebra<T, C>)
|
||||
public fun <T : Number, C : Field<T>> StructureND<T>.plus(arg: T): Nd4jArrayStructure<T> = ndArray.add(arg).wrap()
|
||||
|
||||
context(Nd4jTensorAlgebra<T, C>)
|
||||
public fun <T : Number, C : Field<T>> T.times(arg: StructureND<T>): Nd4jArrayStructure<T> =
|
||||
arg.ndArray.mul(this).wrap()
|
||||
|
||||
context(Nd4jTensorAlgebra<T, C>)
|
||||
public fun <T : Number, C : Field<T>> StructureND<T>.times(arg: T): Nd4jArrayStructure<T> =
|
||||
ndArray.mul(arg).wrap()
|
||||
|
||||
context(Nd4jTensorAlgebra<T, C>)
|
||||
public operator fun <T : Number, C : Field<T>> T.minus(arg: StructureND<T>): Nd4jArrayStructure<T> =
|
||||
arg.ndArray.rsub(this).wrap()
|
||||
|
||||
context(Nd4jTensorAlgebra<T, C>)
|
||||
public operator fun <T:Number,C : Field<T>> StructureND<T>.minus(arg: T): Nd4jArrayStructure<T> =
|
||||
ndArray.sub(arg).wrap()
|
||||
|
||||
context(Nd4jTensorAlgebra<T, C>)
|
||||
public operator fun <T : Number, C : Field<T>> T.div(arg: StructureND<T>): Nd4jArrayStructure<T> =
|
||||
arg.ndArray.rdiv(this).wrap()
|
||||
|
||||
context(Nd4jTensorAlgebra<T, C>)
|
||||
public operator fun <T : Number, C : Field<T>> StructureND<T>.div(arg: T): Nd4jArrayStructure<T> =
|
||||
ndArray.div(arg).wrap()
|
||||
|
||||
/**
|
||||
* [Double] specialization of [Nd4jTensorAlgebra].
|
||||
*/
|
||||
|
@ -1,6 +1,6 @@
|
||||
plugins {
|
||||
id("ru.mipt.npm.gradle.mpp")
|
||||
id("ru.mipt.npm.gradle.native")
|
||||
// id("ru.mipt.npm.gradle.native")
|
||||
}
|
||||
|
||||
kscience {
|
||||
@ -22,3 +22,8 @@ kotlin.sourceSets {
|
||||
readme {
|
||||
maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL
|
||||
}
|
||||
|
||||
// Testing multi-receiver!
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile> {
|
||||
enabled = false
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user