Fix Median statistics. Update algebra naming. Add integer fields

This commit is contained in:
Alexander Nozik 2023-08-12 10:46:43 +03:00
parent 976714475e
commit 62f1c59d73
97 changed files with 632 additions and 482 deletions

View File

@ -11,7 +11,7 @@ import kotlinx.benchmark.Scope
import kotlinx.benchmark.State import kotlinx.benchmark.State
import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.expressions.* import space.kscience.kmath.expressions.*
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.bindSymbol import space.kscience.kmath.operations.bindSymbol
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import kotlin.math.sin import kotlin.math.sin
@ -84,7 +84,7 @@ class ExpressionsInterpretersBenchmark {
private val x by symbol private val x by symbol
private const val times = 1_000_000 private const val times = 1_000_000
private val functional = DoubleField.expression { private val functional = Float64Field.expression {
val x = bindSymbol(Symbol.x) val x = bindSymbol(Symbol.x)
x * number(2.0) + 2.0 / x - 16.0 / sin(x) x * number(2.0) + 2.0 / x - 16.0 / sin(x)
} }
@ -93,10 +93,10 @@ class ExpressionsInterpretersBenchmark {
x * 2.0 + number(2.0) / x - number(16.0) / sin(x) x * 2.0 + number(2.0) / x - number(16.0) / sin(x)
} }
private val mst = node.toExpression(DoubleField) private val mst = node.toExpression(Float64Field)
@OptIn(UnstableKMathAPI::class) @OptIn(UnstableKMathAPI::class)
private val wasm = node.wasmCompileToExpression(DoubleField) private val wasm = node.wasmCompileToExpression(Float64Field)
private val estree = node.estreeCompileToExpression(DoubleField) private val estree = node.estreeCompileToExpression(Float64Field)
private val raw = Expression<Double> { args -> private val raw = Expression<Double> { args ->
val x = args[x]!! val x = args[x]!!

View File

@ -13,7 +13,7 @@ import space.kscience.kmath.commons.linear.CMLinearSpace
import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM
import space.kscience.kmath.linear.invoke import space.kscience.kmath.linear.invoke
import space.kscience.kmath.linear.linearSpace import space.kscience.kmath.linear.linearSpace
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import space.kscience.kmath.tensorflow.produceWithTF import space.kscience.kmath.tensorflow.produceWithTF
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
@ -27,10 +27,10 @@ internal class DotBenchmark {
const val dim = 1000 const val dim = 1000
//creating invertible matrix //creating invertible matrix
val matrix1 = DoubleField.linearSpace.buildMatrix(dim, dim) { _, _ -> val matrix1 = Float64Field.linearSpace.buildMatrix(dim, dim) { _, _ ->
random.nextDouble() random.nextDouble()
} }
val matrix2 = DoubleField.linearSpace.buildMatrix(dim, dim) { _, _ -> val matrix2 = Float64Field.linearSpace.buildMatrix(dim, dim) { _, _ ->
random.nextDouble() random.nextDouble()
} }
@ -45,7 +45,7 @@ internal class DotBenchmark {
@Benchmark @Benchmark
fun tfDot(blackhole: Blackhole) { fun tfDot(blackhole: Blackhole) {
blackhole.consume( blackhole.consume(
DoubleField.produceWithTF { Float64Field.produceWithTF {
matrix1 dot matrix1 matrix1 dot matrix1
} }
) )
@ -72,7 +72,7 @@ internal class DotBenchmark {
} }
@Benchmark @Benchmark
fun tensorDot(blackhole: Blackhole) = with(DoubleField.tensorAlgebra) { fun tensorDot(blackhole: Blackhole) = with(Float64Field.tensorAlgebra) {
blackhole.consume(matrix1 dot matrix2) blackhole.consume(matrix1 dot matrix2)
} }
@ -82,12 +82,12 @@ internal class DotBenchmark {
} }
@Benchmark @Benchmark
fun bufferedDot(blackhole: Blackhole) = with(DoubleField.linearSpace) { fun bufferedDot(blackhole: Blackhole) = with(Float64Field.linearSpace) {
blackhole.consume(matrix1 dot matrix2) blackhole.consume(matrix1 dot matrix2)
} }
@Benchmark @Benchmark
fun doubleDot(blackhole: Blackhole) = with(DoubleField.linearSpace) { fun doubleDot(blackhole: Blackhole) = with(Float64Field.linearSpace) {
blackhole.consume(matrix1 dot matrix2) blackhole.consume(matrix1 dot matrix2)
} }

View File

@ -12,7 +12,7 @@ import kotlinx.benchmark.State
import space.kscience.kmath.asm.compileToExpression import space.kscience.kmath.asm.compileToExpression
import space.kscience.kmath.expressions.* import space.kscience.kmath.expressions.*
import space.kscience.kmath.operations.Algebra import space.kscience.kmath.operations.Algebra
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.bindSymbol import space.kscience.kmath.operations.bindSymbol
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import kotlin.math.sin import kotlin.math.sin
@ -100,7 +100,7 @@ internal class ExpressionsInterpretersBenchmark {
private val x by symbol private val x by symbol
private const val times = 1_000_000 private const val times = 1_000_000
private val functional = DoubleField.expression { private val functional = Float64Field.expression {
val x = bindSymbol(Symbol.x) val x = bindSymbol(Symbol.x)
x * number(2.0) + 2.0 / x - 16.0 / sin(x) x * number(2.0) + 2.0 / x - 16.0 / sin(x)
} }
@ -109,12 +109,12 @@ internal class ExpressionsInterpretersBenchmark {
x * 2.0 + number(2.0) / x - number(16.0) / sin(x) x * 2.0 + number(2.0) / x - number(16.0) / sin(x)
} }
private val mst = node.toExpression(DoubleField) private val mst = node.toExpression(Float64Field)
private val asmPrimitive = node.compileToExpression(DoubleField) private val asmPrimitive = node.compileToExpression(Float64Field)
private val xIdx = asmPrimitive.indexer.indexOf(x) private val xIdx = asmPrimitive.indexer.indexOf(x)
private val asmGeneric = node.compileToExpression(DoubleField as Algebra<Double>) private val asmGeneric = node.compileToExpression(Float64Field as Algebra<Double>)
private val raw = Expression<Double> { args -> private val raw = Expression<Double> { args ->
val x = args[x]!! val x = args[x]!!

View File

@ -11,7 +11,7 @@ import org.openjdk.jmh.annotations.Scope
import org.openjdk.jmh.annotations.State import org.openjdk.jmh.annotations.State
import space.kscience.kmath.jafama.JafamaDoubleField import space.kscience.kmath.jafama.JafamaDoubleField
import space.kscience.kmath.jafama.StrictJafamaDoubleField import space.kscience.kmath.jafama.StrictJafamaDoubleField
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
@ -26,7 +26,7 @@ internal class JafamaBenchmark {
@Benchmark @Benchmark
fun core(blackhole: Blackhole) = invokeBenchmarks(blackhole) { x -> fun core(blackhole: Blackhole) = invokeBenchmarks(blackhole) { x ->
DoubleField { x * power(x, 4) * exp(x) / cos(x) + sin(x) } Float64Field { x * power(x, 4) * exp(x) / cos(x) + sin(x) }
} }
@Benchmark @Benchmark

View File

@ -16,7 +16,7 @@ import org.jetbrains.kotlinx.multik.ndarray.data.DataType
import space.kscience.kmath.UnsafeKMathAPI import space.kscience.kmath.UnsafeKMathAPI
import space.kscience.kmath.nd.* import space.kscience.kmath.nd.*
import space.kscience.kmath.nd4j.nd4j import space.kscience.kmath.nd4j.nd4j
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.tensors.core.DoubleTensor import space.kscience.kmath.tensors.core.DoubleTensor
import space.kscience.kmath.tensors.core.one import space.kscience.kmath.tensors.core.one
import space.kscience.kmath.tensors.core.tensorAlgebra import space.kscience.kmath.tensors.core.tensorAlgebra
@ -86,9 +86,9 @@ internal class NDFieldBenchmark {
private const val dim = 1000 private const val dim = 1000
private const val n = 100 private const val n = 100
private val shape = ShapeND(dim, dim) private val shape = ShapeND(dim, dim)
private val specializedField = DoubleField.ndAlgebra private val specializedField = Float64Field.ndAlgebra
private val genericField = BufferedFieldOpsND(DoubleField) private val genericField = BufferedFieldOpsND(Float64Field)
private val nd4jField = DoubleField.nd4j private val nd4jField = Float64Field.nd4j
private val viktorField = DoubleField.viktorAlgebra private val viktorField = Float64Field.viktorAlgebra
} }
} }

View File

@ -12,7 +12,7 @@ import kotlinx.benchmark.State
import space.kscience.kmath.linear.linearSpace import space.kscience.kmath.linear.linearSpace
import space.kscience.kmath.linear.matrix import space.kscience.kmath.linear.matrix
import space.kscience.kmath.linear.symmetric import space.kscience.kmath.linear.symmetric
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.tensors.core.symEigJacobi import space.kscience.kmath.tensors.core.symEigJacobi
import space.kscience.kmath.tensors.core.symEigSvd import space.kscience.kmath.tensors.core.symEigSvd
import space.kscience.kmath.tensors.core.tensorAlgebra import space.kscience.kmath.tensors.core.tensorAlgebra
@ -24,7 +24,7 @@ internal class TensorAlgebraBenchmark {
private val random = Random(12224) private val random = Random(12224)
private const val dim = 30 private const val dim = 30
private val matrix = DoubleField.linearSpace.matrix(dim, dim).symmetric { _, _ -> random.nextDouble() } private val matrix = Float64Field.linearSpace.matrix(dim, dim).symmetric { _, _ -> random.nextDouble() }
} }
@Benchmark @Benchmark

View File

@ -14,7 +14,7 @@ import space.kscience.kmath.nd.ShapeND
import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.ndAlgebra import space.kscience.kmath.nd.ndAlgebra
import space.kscience.kmath.nd.one import space.kscience.kmath.nd.one
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.viktor.ViktorFieldND import space.kscience.kmath.viktor.ViktorFieldND
@State(Scope.Benchmark) @State(Scope.Benchmark)
@ -52,7 +52,7 @@ internal class ViktorBenchmark {
private val shape = ShapeND(dim, dim) private val shape = ShapeND(dim, dim)
// automatically build context most suited for given type. // automatically build context most suited for given type.
private val doubleField = DoubleField.ndAlgebra private val doubleField = Float64Field.ndAlgebra
private val viktorField = ViktorFieldND(dim, dim) private val viktorField = ViktorFieldND(dim, dim)
} }
} }

View File

@ -13,7 +13,7 @@ import org.jetbrains.bio.viktor.F64Array
import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.ShapeND
import space.kscience.kmath.nd.ndAlgebra import space.kscience.kmath.nd.ndAlgebra
import space.kscience.kmath.nd.one import space.kscience.kmath.nd.one
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.viktor.ViktorFieldND import space.kscience.kmath.viktor.ViktorFieldND
@State(Scope.Benchmark) @State(Scope.Benchmark)
@ -52,7 +52,7 @@ internal class ViktorLogBenchmark {
private val shape = ShapeND(dim, dim) private val shape = ShapeND(dim, dim)
// automatically build context most suited for given type. // automatically build context most suited for given type.
private val doubleField = DoubleField.ndAlgebra private val doubleField = Float64Field.ndAlgebra
private val viktorField = ViktorFieldND(dim, dim) private val viktorField = ViktorFieldND(dim, dim)
} }
} }

View File

@ -8,13 +8,13 @@ package space.kscience.kmath.ast
import space.kscience.kmath.asm.compileToExpression import space.kscience.kmath.asm.compileToExpression
import space.kscience.kmath.expressions.MstExtendedField import space.kscience.kmath.expressions.MstExtendedField
import space.kscience.kmath.expressions.Symbol.Companion.x import space.kscience.kmath.expressions.Symbol.Companion.x
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
fun main() { fun main() {
val expr = MstExtendedField { val expr = MstExtendedField {
x * 2.0 + number(2.0) / x - number(16.0) + asinh(x) / sin(x) x * 2.0 + number(2.0) / x - number(16.0) + asinh(x) / sin(x)
}.compileToExpression(DoubleField) }.compileToExpression(Float64Field)
val m = DoubleArray(expr.indexer.symbols.size) val m = DoubleArray(expr.indexer.symbols.size)
val xIdx = expr.indexer.indexOf(x) val xIdx = expr.indexer.indexOf(x)

View File

@ -5,12 +5,12 @@
package space.kscience.kmath.ast package space.kscience.kmath.ast
import space.kscience.kmath.expressions.Symbol.Companion.x
import space.kscience.kmath.expressions.derivative import space.kscience.kmath.expressions.derivative
import space.kscience.kmath.expressions.invoke import space.kscience.kmath.expressions.invoke
import space.kscience.kmath.expressions.Symbol.Companion.x
import space.kscience.kmath.expressions.toExpression import space.kscience.kmath.expressions.toExpression
import space.kscience.kmath.kotlingrad.toKotlingradExpression import space.kscience.kmath.kotlingrad.toKotlingradExpression
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
/** /**
* In this example, *x<sup>2</sup> &minus; 4 x &minus; 44* function is differentiated with Kotlin, and the * In this example, *x<sup>2</sup> &minus; 4 x &minus; 44* function is differentiated with Kotlin, and the
@ -19,9 +19,9 @@ import space.kscience.kmath.operations.DoubleField
fun main() { fun main() {
val actualDerivative = "x^2-4*x-44" val actualDerivative = "x^2-4*x-44"
.parseMath() .parseMath()
.toKotlingradExpression(DoubleField) .toKotlingradExpression(Float64Field)
.derivative(x) .derivative(x)
val expectedDerivative = "2*x-4".parseMath().toExpression(DoubleField) val expectedDerivative = "2*x-4".parseMath().toExpression(Float64Field)
check(actualDerivative(x to 123.0) == expectedDerivative(x to 123.0)) check(actualDerivative(x to 123.0) == expectedDerivative(x to 123.0))
} }

View File

@ -9,7 +9,7 @@ import space.kscience.kmath.expressions.Symbol.Companion.x
import space.kscience.kmath.expressions.derivative import space.kscience.kmath.expressions.derivative
import space.kscience.kmath.expressions.invoke import space.kscience.kmath.expressions.invoke
import space.kscience.kmath.expressions.toExpression import space.kscience.kmath.expressions.toExpression
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.symja.toSymjaExpression import space.kscience.kmath.symja.toSymjaExpression
/** /**
@ -19,9 +19,9 @@ import space.kscience.kmath.symja.toSymjaExpression
fun main() { fun main() {
val actualDerivative = "x^2-4*x-44" val actualDerivative = "x^2-4*x-44"
.parseMath() .parseMath()
.toSymjaExpression(DoubleField) .toSymjaExpression(Float64Field)
.derivative(x) .derivative(x)
val expectedDerivative = "2*x-4".parseMath().toExpression(DoubleField) val expectedDerivative = "2*x-4".parseMath().toExpression(Float64Field)
check(actualDerivative(x to 123.0) == expectedDerivative(x to 123.0)) check(actualDerivative(x to 123.0) == expectedDerivative(x to 123.0))
} }

View File

@ -13,7 +13,7 @@ import space.kscience.kmath.complex.algebra
import space.kscience.kmath.integration.gaussIntegrator import space.kscience.kmath.integration.gaussIntegrator
import space.kscience.kmath.integration.integrate import space.kscience.kmath.integration.integrate
import space.kscience.kmath.integration.value import space.kscience.kmath.integration.value
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import kotlin.math.pow import kotlin.math.pow
fun main() { fun main() {
@ -21,7 +21,7 @@ fun main() {
val function: Function1D<Double> = { x -> 3 * x.pow(2) + 2 * x + 1 } val function: Function1D<Double> = { x -> 3 * x.pow(2) + 2 * x + 1 }
//get the result of the integration //get the result of the integration
val result = DoubleField.gaussIntegrator.integrate(0.0..10.0, function = function) val result = Float64Field.gaussIntegrator.integrate(0.0..10.0, function = function)
//the value is nullable because in some cases the integration could not succeed //the value is nullable because in some cases the integration could not succeed
println(result.value) println(result.value)

View File

@ -7,7 +7,7 @@ package space.kscience.kmath.functions
import space.kscience.kmath.interpolation.SplineInterpolator import space.kscience.kmath.interpolation.SplineInterpolator
import space.kscience.kmath.interpolation.interpolatePolynomials import space.kscience.kmath.interpolation.interpolatePolynomials
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.DoubleBuffer
import space.kscience.plotly.Plotly import space.kscience.plotly.Plotly
import space.kscience.plotly.UnstablePlotlyAPI import space.kscience.plotly.UnstablePlotlyAPI
@ -25,10 +25,10 @@ fun main() {
} }
val polynomial: PiecewisePolynomial<Double> = SplineInterpolator( val polynomial: PiecewisePolynomial<Double> = SplineInterpolator(
DoubleField, ::DoubleBuffer Float64Field, ::DoubleBuffer
).interpolatePolynomials(data) ).interpolatePolynomials(data)
val function = polynomial.asFunction(DoubleField, 0.0) val function = polynomial.asFunction(Float64Field, 0.0)
val cmInterpolate = org.apache.commons.math3.analysis.interpolation.SplineInterpolator().interpolate( val cmInterpolate = org.apache.commons.math3.analysis.interpolation.SplineInterpolator().interpolate(
data.map { it.first }.toDoubleArray(), data.map { it.first }.toDoubleArray(),

View File

@ -7,7 +7,7 @@ package space.kscience.kmath.functions
import space.kscience.kmath.interpolation.interpolatePolynomials import space.kscience.kmath.interpolation.interpolatePolynomials
import space.kscience.kmath.interpolation.splineInterpolator import space.kscience.kmath.interpolation.splineInterpolator
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.real.map import space.kscience.kmath.real.map
import space.kscience.kmath.real.step import space.kscience.kmath.real.step
import space.kscience.plotly.Plotly import space.kscience.plotly.Plotly
@ -28,9 +28,9 @@ fun main() {
val xs = 0.0..100.0 step 0.5 val xs = 0.0..100.0 step 0.5
val ys = xs.map(function) val ys = xs.map(function)
val polynomial: PiecewisePolynomial<Double> = DoubleField.splineInterpolator.interpolatePolynomials(xs, ys) val polynomial: PiecewisePolynomial<Double> = Float64Field.splineInterpolator.interpolatePolynomials(xs, ys)
val polyFunction = polynomial.asFunction(DoubleField, 0.0) val polyFunction = polynomial.asFunction(Float64Field, 0.0)
Plotly.plot { Plotly.plot {
scatter { scatter {

View File

@ -15,13 +15,13 @@ import space.kscience.kmath.viktor.ViktorStructureND
import space.kscience.kmath.viktor.viktorAlgebra import space.kscience.kmath.viktor.viktorAlgebra
fun main() { fun main() {
val viktorStructure: ViktorStructureND = DoubleField.viktorAlgebra.structureND(ShapeND(2, 2)) { (i, j) -> val viktorStructure: ViktorStructureND = Float64Field.viktorAlgebra.structureND(ShapeND(2, 2)) { (i, j) ->
if (i == j) 2.0 else 0.0 if (i == j) 2.0 else 0.0
} }
val cmMatrix: Structure2D<Double> = CMLinearSpace.matrix(2, 2)(0.0, 1.0, 0.0, 3.0) val cmMatrix: Structure2D<Double> = CMLinearSpace.matrix(2, 2)(0.0, 1.0, 0.0, 3.0)
val res: DoubleBufferND = DoubleField.ndAlgebra { val res: DoubleBufferND = Float64Field.ndAlgebra {
exp(viktorStructure) + 2.0 * cmMatrix exp(viktorStructure) + 2.0 * cmMatrix
} }

View File

@ -13,7 +13,7 @@ import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.as2D import space.kscience.kmath.nd.as2D
import space.kscience.kmath.nd.ndAlgebra import space.kscience.kmath.nd.ndAlgebra
import space.kscience.kmath.nd.structureND import space.kscience.kmath.nd.structureND
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import kotlin.system.measureTimeMillis import kotlin.system.measureTimeMillis
@ -21,7 +21,7 @@ fun main() {
val dim = 1000 val dim = 1000
val n = 1000 val n = 1000
val realField = DoubleField.ndAlgebra(dim, dim) val realField = Float64Field.ndAlgebra(dim, dim)
val complexField: ComplexFieldND = ComplexField.ndAlgebra(dim, dim) val complexField: ComplexFieldND = ComplexField.ndAlgebra(dim, dim)
val realTime = measureTimeMillis { val realTime = measureTimeMillis {

View File

@ -10,7 +10,7 @@ import kotlinx.coroutines.GlobalScope
import org.nd4j.linalg.factory.Nd4j import org.nd4j.linalg.factory.Nd4j
import space.kscience.kmath.nd.* import space.kscience.kmath.nd.*
import space.kscience.kmath.nd4j.nd4j import space.kscience.kmath.nd4j.nd4j
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import space.kscience.kmath.viktor.ViktorFieldND import space.kscience.kmath.viktor.ViktorFieldND
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
@ -33,15 +33,15 @@ fun main() {
// specialized nd-field for Double. It works as generic Double field as well. // specialized nd-field for Double. It works as generic Double field as well.
val doubleField = DoubleField.ndAlgebra val doubleField = Float64Field.ndAlgebra
//A generic field. It should be used for objects, not primitives. //A generic field. It should be used for objects, not primitives.
val genericField = BufferedFieldOpsND(DoubleField) val genericField = BufferedFieldOpsND(Float64Field)
// Nd4j specialized field. // Nd4j specialized field.
val nd4jField = DoubleField.nd4j val nd4jField = Float64Field.nd4j
//viktor field //viktor field
val viktorField = ViktorFieldND(dim, dim) val viktorField = ViktorFieldND(dim, dim)
//parallel processing based on Java Streams //parallel processing based on Java Streams
val parallelField = DoubleField.ndStreaming(dim, dim) val parallelField = Float64Field.ndStreaming(dim, dim)
measureAndPrint("Boxing addition") { measureAndPrint("Boxing addition") {
genericField { genericField {

View File

@ -7,8 +7,8 @@ package space.kscience.kmath.structures
import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.PerformancePitfall
import space.kscience.kmath.nd.* import space.kscience.kmath.nd.*
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.ExtendedField import space.kscience.kmath.operations.ExtendedField
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.NumbersAddOps import space.kscience.kmath.operations.NumbersAddOps
import java.util.* import java.util.*
import java.util.stream.IntStream import java.util.stream.IntStream
@ -17,12 +17,12 @@ import java.util.stream.IntStream
* A demonstration implementation of NDField over Real using Java [java.util.stream.DoubleStream] for parallel * A demonstration implementation of NDField over Real using Java [java.util.stream.DoubleStream] for parallel
* execution. * execution.
*/ */
class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, DoubleField>, class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, Float64Field>,
NumbersAddOps<StructureND<Double>>, NumbersAddOps<StructureND<Double>>,
ExtendedField<StructureND<Double>> { ExtendedField<StructureND<Double>> {
private val strides = ColumnStrides(shape) private val strides = ColumnStrides(shape)
override val elementAlgebra: DoubleField get() = DoubleField override val elementAlgebra: Float64Field get() = Float64Field
override val zero: BufferND<Double> by lazy { structureND(shape) { zero } } override val zero: BufferND<Double> by lazy { structureND(shape) { zero } }
override val one: BufferND<Double> by lazy { structureND(shape) { one } } override val one: BufferND<Double> by lazy { structureND(shape) { one } }
@ -43,10 +43,10 @@ class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, DoubleF
else -> DoubleBuffer(strides.linearSize) { offset -> get(strides.index(offset)) } else -> DoubleBuffer(strides.linearSize) { offset -> get(strides.index(offset)) }
} }
override fun structureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): BufferND<Double> { override fun structureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): BufferND<Double> {
val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset -> val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
val index = strides.index(offset) val index = strides.index(offset)
DoubleField.initializer(index) Float64Field.initializer(index)
}.toArray() }.toArray()
return BufferND(strides, array.asBuffer()) return BufferND(strides, array.asBuffer())
@ -54,18 +54,18 @@ class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, DoubleF
@OptIn(PerformancePitfall::class) @OptIn(PerformancePitfall::class)
override fun StructureND<Double>.map( override fun StructureND<Double>.map(
transform: DoubleField.(Double) -> Double, transform: Float64Field.(Double) -> Double,
): BufferND<Double> { ): BufferND<Double> {
val array = Arrays.stream(buffer.array).parallel().map { DoubleField.transform(it) }.toArray() val array = Arrays.stream(buffer.array).parallel().map { Float64Field.transform(it) }.toArray()
return BufferND(strides, array.asBuffer()) return BufferND(strides, array.asBuffer())
} }
@OptIn(PerformancePitfall::class) @OptIn(PerformancePitfall::class)
override fun StructureND<Double>.mapIndexed( override fun StructureND<Double>.mapIndexed(
transform: DoubleField.(index: IntArray, Double) -> Double, transform: Float64Field.(index: IntArray, Double) -> Double,
): BufferND<Double> { ): BufferND<Double> {
val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset -> val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
DoubleField.transform( Float64Field.transform(
strides.index(offset), strides.index(offset),
buffer.array[offset] buffer.array[offset]
) )
@ -78,10 +78,10 @@ class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, DoubleF
override fun zip( override fun zip(
left: StructureND<Double>, left: StructureND<Double>,
right: StructureND<Double>, right: StructureND<Double>,
transform: DoubleField.(Double, Double) -> Double, transform: Float64Field.(Double, Double) -> Double,
): BufferND<Double> { ): BufferND<Double> {
val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset -> val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
DoubleField.transform(left.buffer.array[offset], right.buffer.array[offset]) Float64Field.transform(left.buffer.array[offset], right.buffer.array[offset])
}.toArray() }.toArray()
return BufferND(strides, array.asBuffer()) return BufferND(strides, array.asBuffer())
} }
@ -111,4 +111,4 @@ class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, DoubleF
override fun atanh(arg: StructureND<Double>): BufferND<Double> = arg.map { atanh(it) } override fun atanh(arg: StructureND<Double>): BufferND<Double> = arg.map { atanh(it) }
} }
fun DoubleField.ndStreaming(vararg shape: Int): StreamDoubleFieldND = StreamDoubleFieldND(ShapeND(shape)) fun Float64Field.ndStreaming(vararg shape: Int): StreamDoubleFieldND = StreamDoubleFieldND(ShapeND(shape))

View File

@ -5,7 +5,7 @@
package space.kscience.kmath.structures package space.kscience.kmath.structures
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.buffer import space.kscience.kmath.operations.buffer
import space.kscience.kmath.operations.bufferAlgebra import space.kscience.kmath.operations.bufferAlgebra
import space.kscience.kmath.operations.withSize import space.kscience.kmath.operations.withSize
@ -17,7 +17,7 @@ inline fun <reified R : Any> MutableBuffer.Companion.same(
fun main() { fun main() {
with(DoubleField.bufferAlgebra.withSize(5)) { with(Float64Field.bufferAlgebra.withSize(5)) {
println(number(2.0) + buffer(1, 2, 3, 4, 5)) println(number(2.0) + buffer(1, 2, 3, 4, 5))
} }
} }

View File

@ -9,8 +9,8 @@ import space.kscience.kmath.expressions.MstField
import space.kscience.kmath.expressions.MstRing import space.kscience.kmath.expressions.MstRing
import space.kscience.kmath.expressions.Symbol.Companion.x import space.kscience.kmath.expressions.Symbol.Companion.x
import space.kscience.kmath.expressions.interpret import space.kscience.kmath.expressions.interpret
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.IntRing import space.kscience.kmath.operations.Int32Ring
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -32,8 +32,8 @@ internal class TestCompilerConsistencyWithInterpreter {
} }
assertEquals( assertEquals(
mst.interpret(IntRing, x to 3), mst.interpret(Int32Ring, x to 3),
mst.compile(IntRing, x to 3), mst.compile(Int32Ring, x to 3),
) )
} }
@ -48,8 +48,8 @@ internal class TestCompilerConsistencyWithInterpreter {
} }
assertEquals( assertEquals(
mst.interpret(DoubleField, x to 2.0), mst.interpret(Float64Field, x to 2.0),
mst.compile(DoubleField, x to 2.0), mst.compile(Float64Field, x to 2.0),
) )
} }
} }

View File

@ -8,7 +8,7 @@ package space.kscience.kmath.ast
import space.kscience.kmath.expressions.MstExtendedField import space.kscience.kmath.expressions.MstExtendedField
import space.kscience.kmath.expressions.Symbol.Companion.x import space.kscience.kmath.expressions.Symbol.Companion.x
import space.kscience.kmath.expressions.invoke import space.kscience.kmath.expressions.invoke
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -16,73 +16,73 @@ import kotlin.test.assertEquals
internal class TestCompilerOperations { internal class TestCompilerOperations {
@Test @Test
fun testUnaryPlus() = runCompilerTest { fun testUnaryPlus() = runCompilerTest {
val expr = MstExtendedField { +x }.compileToExpression(DoubleField) val expr = MstExtendedField { +x }.compileToExpression(Float64Field)
assertEquals(2.0, expr(x to 2.0)) assertEquals(2.0, expr(x to 2.0))
} }
@Test @Test
fun testUnaryMinus() = runCompilerTest { fun testUnaryMinus() = runCompilerTest {
val expr = MstExtendedField { -x }.compileToExpression(DoubleField) val expr = MstExtendedField { -x }.compileToExpression(Float64Field)
assertEquals(-2.0, expr(x to 2.0)) assertEquals(-2.0, expr(x to 2.0))
} }
@Test @Test
fun testAdd() = runCompilerTest { fun testAdd() = runCompilerTest {
val expr = MstExtendedField { x + x }.compileToExpression(DoubleField) val expr = MstExtendedField { x + x }.compileToExpression(Float64Field)
assertEquals(4.0, expr(x to 2.0)) assertEquals(4.0, expr(x to 2.0))
} }
@Test @Test
fun testSine() = runCompilerTest { fun testSine() = runCompilerTest {
val expr = MstExtendedField { sin(x) }.compileToExpression(DoubleField) val expr = MstExtendedField { sin(x) }.compileToExpression(Float64Field)
assertEquals(0.0, expr(x to 0.0)) assertEquals(0.0, expr(x to 0.0))
} }
@Test @Test
fun testCosine() = runCompilerTest { fun testCosine() = runCompilerTest {
val expr = MstExtendedField { cos(x) }.compileToExpression(DoubleField) val expr = MstExtendedField { cos(x) }.compileToExpression(Float64Field)
assertEquals(1.0, expr(x to 0.0)) assertEquals(1.0, expr(x to 0.0))
} }
@Test @Test
fun testTangent() = runCompilerTest { fun testTangent() = runCompilerTest {
val expr = MstExtendedField { tan(x) }.compileToExpression(DoubleField) val expr = MstExtendedField { tan(x) }.compileToExpression(Float64Field)
assertEquals(0.0, expr(x to 0.0)) assertEquals(0.0, expr(x to 0.0))
} }
@Test @Test
fun testArcSine() = runCompilerTest { fun testArcSine() = runCompilerTest {
val expr = MstExtendedField { asin(x) }.compileToExpression(DoubleField) val expr = MstExtendedField { asin(x) }.compileToExpression(Float64Field)
assertEquals(0.0, expr(x to 0.0)) assertEquals(0.0, expr(x to 0.0))
} }
@Test @Test
fun testArcCosine() = runCompilerTest { fun testArcCosine() = runCompilerTest {
val expr = MstExtendedField { acos(x) }.compileToExpression(DoubleField) val expr = MstExtendedField { acos(x) }.compileToExpression(Float64Field)
assertEquals(0.0, expr(x to 1.0)) assertEquals(0.0, expr(x to 1.0))
} }
@Test @Test
fun testAreaHyperbolicSine() = runCompilerTest { fun testAreaHyperbolicSine() = runCompilerTest {
val expr = MstExtendedField { asinh(x) }.compileToExpression(DoubleField) val expr = MstExtendedField { asinh(x) }.compileToExpression(Float64Field)
assertEquals(0.0, expr(x to 0.0)) assertEquals(0.0, expr(x to 0.0))
} }
@Test @Test
fun testSubtract() = runCompilerTest { fun testSubtract() = runCompilerTest {
val expr = MstExtendedField { x - x }.compileToExpression(DoubleField) val expr = MstExtendedField { x - x }.compileToExpression(Float64Field)
assertEquals(0.0, expr(x to 2.0)) assertEquals(0.0, expr(x to 2.0))
} }
@Test @Test
fun testDivide() = runCompilerTest { fun testDivide() = runCompilerTest {
val expr = MstExtendedField { x / x }.compileToExpression(DoubleField) val expr = MstExtendedField { x / x }.compileToExpression(Float64Field)
assertEquals(1.0, expr(x to 2.0)) assertEquals(1.0, expr(x to 2.0))
} }
@Test @Test
fun testPower() = runCompilerTest { fun testPower() = runCompilerTest {
val expr = MstExtendedField { x pow 2 }.compileToExpression(DoubleField) val expr = MstExtendedField { x pow 2 }.compileToExpression(Float64Field)
assertEquals(4.0, expr(x to 2.0)) assertEquals(4.0, expr(x to 2.0))
} }
} }

View File

@ -9,8 +9,8 @@ import space.kscience.kmath.expressions.MstRing
import space.kscience.kmath.expressions.Symbol.Companion.x import space.kscience.kmath.expressions.Symbol.Companion.x
import space.kscience.kmath.expressions.Symbol.Companion.y import space.kscience.kmath.expressions.Symbol.Companion.y
import space.kscience.kmath.expressions.invoke import space.kscience.kmath.expressions.invoke
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.IntRing import space.kscience.kmath.operations.Int32Ring
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -19,25 +19,25 @@ import kotlin.test.assertFailsWith
internal class TestCompilerVariables { internal class TestCompilerVariables {
@Test @Test
fun testNoVariables() = runCompilerTest { fun testNoVariables() = runCompilerTest {
val expr = "0".parseMath().compileToExpression(DoubleField) val expr = "0".parseMath().compileToExpression(Float64Field)
assertEquals(0.0, expr(), 0.0001) assertEquals(0.0, expr(), 0.0001)
} }
@Test @Test
fun testOneVariable() = runCompilerTest { fun testOneVariable() = runCompilerTest {
val expr = MstRing { x }.compileToExpression(IntRing) val expr = MstRing { x }.compileToExpression(Int32Ring)
assertEquals(1, expr(x to 1)) assertEquals(1, expr(x to 1))
} }
@Test @Test
fun testTwoVariables() = runCompilerTest { fun testTwoVariables() = runCompilerTest {
val expr = "y+x/y+x".parseMath().compileToExpression(DoubleField) val expr = "y+x/y+x".parseMath().compileToExpression(Float64Field)
assertEquals(8.0, expr(x to 4.0, y to 2.0)) assertEquals(8.0, expr(x to 4.0, y to 2.0))
} }
@Test @Test
fun testUndefinedVariableFails() = runCompilerTest { fun testUndefinedVariableFails() = runCompilerTest {
val expr = MstRing { x }.compileToExpression(IntRing) val expr = MstRing { x }.compileToExpression(Int32Ring)
assertFailsWith<NoSuchElementException> { expr() } assertFailsWith<NoSuchElementException> { expr() }
} }
} }

View File

@ -6,8 +6,8 @@
package space.kscience.kmath.ast package space.kscience.kmath.ast
import space.kscience.kmath.operations.ByteRing import space.kscience.kmath.operations.ByteRing
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.IntRing import space.kscience.kmath.operations.Int32Ring
import space.kscience.kmath.operations.pi import space.kscience.kmath.operations.pi
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -17,31 +17,31 @@ internal class TestFolding {
@Test @Test
fun foldUnary() = assertEquals( fun foldUnary() = assertEquals(
-1, -1,
("-(1)".parseMath().evaluateConstants(IntRing) as? TypedMst.Constant<Int> ?: fail()).value, ("-(1)".parseMath().evaluateConstants(Int32Ring) as? TypedMst.Constant<Int> ?: fail()).value,
) )
@Test @Test
fun foldDeepUnary() = assertEquals( fun foldDeepUnary() = assertEquals(
1, 1,
("-(-(1))".parseMath().evaluateConstants(IntRing) as? TypedMst.Constant<Int> ?: fail()).value, ("-(-(1))".parseMath().evaluateConstants(Int32Ring) as? TypedMst.Constant<Int> ?: fail()).value,
) )
@Test @Test
fun foldBinary() = assertEquals( fun foldBinary() = assertEquals(
2, 2,
("1*2".parseMath().evaluateConstants(IntRing) as? TypedMst.Constant<Int> ?: fail()).value, ("1*2".parseMath().evaluateConstants(Int32Ring) as? TypedMst.Constant<Int> ?: fail()).value,
) )
@Test @Test
fun foldDeepBinary() = assertEquals( fun foldDeepBinary() = assertEquals(
10, 10,
("1*2*5".parseMath().evaluateConstants(IntRing) as? TypedMst.Constant<Int> ?: fail()).value, ("1*2*5".parseMath().evaluateConstants(Int32Ring) as? TypedMst.Constant<Int> ?: fail()).value,
) )
@Test @Test
fun foldSymbol() = assertEquals( fun foldSymbol() = assertEquals(
DoubleField.pi, Float64Field.pi,
("pi".parseMath().evaluateConstants(DoubleField) as? TypedMst.Constant<Double> ?: fail()).value, ("pi".parseMath().evaluateConstants(Float64Field) as? TypedMst.Constant<Double> ?: fail()).value,
) )
@Test @Test

View File

@ -9,7 +9,7 @@ import space.kscience.kmath.complex.Complex
import space.kscience.kmath.complex.ComplexField import space.kscience.kmath.complex.ComplexField
import space.kscience.kmath.expressions.interpret import space.kscience.kmath.expressions.interpret
import space.kscience.kmath.operations.Algebra import space.kscience.kmath.operations.Algebra
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -32,7 +32,7 @@ internal class TestParser {
@Test @Test
fun evaluateMstUnary() { fun evaluateMstUnary() {
val mst = "sin(0)".parseMath() val mst = "sin(0)".parseMath()
val res = mst.interpret(DoubleField) val res = mst.interpret(Float64Field)
assertEquals(0.0, res) assertEquals(0.0, res)
} }

View File

@ -6,7 +6,7 @@
package space.kscience.kmath.ast package space.kscience.kmath.ast
import space.kscience.kmath.expressions.interpret import space.kscience.kmath.expressions.interpret
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -36,6 +36,6 @@ internal class TestParserPrecedence {
fun test8(): Unit = assertEquals(18.0, "2*2^3+2".parseMath().interpret(f)) fun test8(): Unit = assertEquals(18.0, "2*2^3+2".parseMath().interpret(f))
private companion object { private companion object {
private val f = DoubleField private val f = Float64Field
} }
} }

View File

@ -8,17 +8,17 @@ package space.kscience.kmath.ast
import space.kscience.kmath.expressions.Expression import space.kscience.kmath.expressions.Expression
import space.kscience.kmath.expressions.MST import space.kscience.kmath.expressions.MST
import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.expressions.Symbol
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.IntRing import space.kscience.kmath.operations.Int32Ring
internal interface CompilerTestContext { internal interface CompilerTestContext {
fun MST.compileToExpression(algebra: IntRing): Expression<Int> fun MST.compileToExpression(algebra: Int32Ring): Expression<Int>
fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int fun MST.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int
fun MST.compile(algebra: IntRing, vararg arguments: Pair<Symbol, Int>): Int = compile(algebra, mapOf(*arguments)) fun MST.compile(algebra: Int32Ring, vararg arguments: Pair<Symbol, Int>): Int = compile(algebra, mapOf(*arguments))
fun MST.compileToExpression(algebra: DoubleField): Expression<Double> fun MST.compileToExpression(algebra: Float64Field): Expression<Double>
fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double
fun MST.compile(algebra: DoubleField, vararg arguments: Pair<Symbol, Double>): Double = fun MST.compile(algebra: Float64Field, vararg arguments: Pair<Symbol, Double>): Double =
compile(algebra, mapOf(*arguments)) compile(algebra, mapOf(*arguments))
} }

View File

@ -86,7 +86,7 @@ internal sealed class WasmBuilder<T : Number, out E : Expression<T>>(
@UnstableKMathAPI @UnstableKMathAPI
internal class DoubleWasmBuilder(target: TypedMst<Double>) : internal class DoubleWasmBuilder(target: TypedMst<Double>) :
WasmBuilder<Double, DoubleExpression>(f64, DoubleField, target) { WasmBuilder<Double, DoubleExpression>(f64, Float64Field, target) {
override val instance by lazy { override val instance by lazy {
object : DoubleExpression { object : DoubleExpression {
override val indexer = SimpleSymbolIndexer(keys) override val indexer = SimpleSymbolIndexer(keys)
@ -131,7 +131,7 @@ internal class DoubleWasmBuilder(target: TypedMst<Double>) :
} }
@UnstableKMathAPI @UnstableKMathAPI
internal class IntWasmBuilder(target: TypedMst<Int>) : WasmBuilder<Int, IntExpression>(i32, IntRing, target) { internal class IntWasmBuilder(target: TypedMst<Int>) : WasmBuilder<Int, IntExpression>(i32, Int32Ring, target) {
override val instance by lazy { override val instance by lazy {
object : IntExpression { object : IntExpression {
override val indexer = SimpleSymbolIndexer(keys) override val indexer = SimpleSymbolIndexer(keys)

View File

@ -11,8 +11,8 @@ import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.ast.TypedMst import space.kscience.kmath.ast.TypedMst
import space.kscience.kmath.ast.evaluateConstants import space.kscience.kmath.ast.evaluateConstants
import space.kscience.kmath.expressions.* import space.kscience.kmath.expressions.*
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.IntRing import space.kscience.kmath.operations.Int32Ring
import space.kscience.kmath.wasm.internal.DoubleWasmBuilder import space.kscience.kmath.wasm.internal.DoubleWasmBuilder
import space.kscience.kmath.wasm.internal.IntWasmBuilder import space.kscience.kmath.wasm.internal.IntWasmBuilder
@ -22,7 +22,7 @@ import space.kscience.kmath.wasm.internal.IntWasmBuilder
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun MST.compileToExpression(algebra: IntRing): IntExpression { public fun MST.compileToExpression(algebra: Int32Ring): IntExpression {
val typed = evaluateConstants(algebra) val typed = evaluateConstants(algebra)
return if (typed is TypedMst.Constant) object : IntExpression { return if (typed is TypedMst.Constant) object : IntExpression {
@ -39,7 +39,7 @@ public fun MST.compileToExpression(algebra: IntRing): IntExpression {
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = public fun MST.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int =
compileToExpression(algebra)(arguments) compileToExpression(algebra)(arguments)
@ -49,7 +49,7 @@ public fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int =
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun MST.compile(algebra: IntRing, vararg arguments: Pair<Symbol, Int>): Int = public fun MST.compile(algebra: Int32Ring, vararg arguments: Pair<Symbol, Int>): Int =
compileToExpression(algebra)(*arguments) compileToExpression(algebra)(*arguments)
/** /**
@ -58,7 +58,7 @@ public fun MST.compile(algebra: IntRing, vararg arguments: Pair<Symbol, Int>): I
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun MST.compileToExpression(algebra: DoubleField): Expression<Double> { public fun MST.compileToExpression(algebra: Float64Field): Expression<Double> {
val typed = evaluateConstants(algebra) val typed = evaluateConstants(algebra)
return if (typed is TypedMst.Constant) object : DoubleExpression { return if (typed is TypedMst.Constant) object : DoubleExpression {
@ -76,7 +76,7 @@ public fun MST.compileToExpression(algebra: DoubleField): Expression<Double> {
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double = public fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double =
compileToExpression(algebra)(arguments) compileToExpression(algebra)(arguments)
@ -86,5 +86,5 @@ public fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Do
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun MST.compile(algebra: DoubleField, vararg arguments: Pair<Symbol, Double>): Double = public fun MST.compile(algebra: Float64Field, vararg arguments: Pair<Symbol, Double>): Double =
compileToExpression(algebra)(*arguments) compileToExpression(algebra)(*arguments)

View File

@ -11,8 +11,8 @@ import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.expressions.Expression import space.kscience.kmath.expressions.Expression
import space.kscience.kmath.expressions.MST import space.kscience.kmath.expressions.MST
import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.expressions.Symbol
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.IntRing import space.kscience.kmath.operations.Int32Ring
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
import space.kscience.kmath.estree.compile as estreeCompile import space.kscience.kmath.estree.compile as estreeCompile
@ -21,20 +21,20 @@ import space.kscience.kmath.wasm.compile as wasmCompile
import space.kscience.kmath.wasm.compileToExpression as wasmCompileToExpression import space.kscience.kmath.wasm.compileToExpression as wasmCompileToExpression
private object WasmCompilerTestContext : CompilerTestContext { private object WasmCompilerTestContext : CompilerTestContext {
override fun MST.compileToExpression(algebra: IntRing): Expression<Int> = wasmCompileToExpression(algebra) override fun MST.compileToExpression(algebra: Int32Ring): Expression<Int> = wasmCompileToExpression(algebra)
override fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = wasmCompile(algebra, arguments) override fun MST.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int = wasmCompile(algebra, arguments)
override fun MST.compileToExpression(algebra: DoubleField): Expression<Double> = wasmCompileToExpression(algebra) override fun MST.compileToExpression(algebra: Float64Field): Expression<Double> = wasmCompileToExpression(algebra)
override fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double = override fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double =
wasmCompile(algebra, arguments) wasmCompile(algebra, arguments)
} }
private object ESTreeCompilerTestContext : CompilerTestContext { private object ESTreeCompilerTestContext : CompilerTestContext {
override fun MST.compileToExpression(algebra: IntRing): Expression<Int> = estreeCompileToExpression(algebra) override fun MST.compileToExpression(algebra: Int32Ring): Expression<Int> = estreeCompileToExpression(algebra)
override fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = estreeCompile(algebra, arguments) override fun MST.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int = estreeCompile(algebra, arguments)
override fun MST.compileToExpression(algebra: DoubleField): Expression<Double> = estreeCompileToExpression(algebra) override fun MST.compileToExpression(algebra: Float64Field): Expression<Double> = estreeCompileToExpression(algebra)
override fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double = override fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double =
estreeCompile(algebra, arguments) estreeCompile(algebra, arguments)
} }

View File

@ -10,8 +10,8 @@ import space.kscience.kmath.expressions.MstExtendedField
import space.kscience.kmath.expressions.MstRing import space.kscience.kmath.expressions.MstRing
import space.kscience.kmath.expressions.invoke import space.kscience.kmath.expressions.invoke
import space.kscience.kmath.expressions.symbol import space.kscience.kmath.expressions.symbol
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.IntRing import space.kscience.kmath.operations.Int32Ring
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -20,20 +20,20 @@ import kotlin.test.assertEquals
internal class TestWasmSpecific { internal class TestWasmSpecific {
@Test @Test
fun int() { fun int() {
val res = MstRing { number(100000000) + number(10000000) }.compile(IntRing) val res = MstRing { number(100000000) + number(10000000) }.compile(Int32Ring)
assertEquals(110000000, res) assertEquals(110000000, res)
} }
@Test @Test
fun real() { fun real() {
val res = MstExtendedField { number(100000000) + number(2).pow(10) }.compile(DoubleField) val res = MstExtendedField { number(100000000) + number(2).pow(10) }.compile(Float64Field)
assertEquals(100001024.0, res) assertEquals(100001024.0, res)
} }
@Test @Test
fun argsPassing() { fun argsPassing() {
val res = MstExtendedField { y + x.pow(10) }.compile( val res = MstExtendedField { y + x.pow(10) }.compile(
DoubleField, Float64Field,
x to 2.0, x to 2.0,
y to 100000000.0, y to 100000000.0,
) )
@ -43,7 +43,7 @@ internal class TestWasmSpecific {
@Test @Test
fun powFunction() { fun powFunction() {
val expr = MstExtendedField { x.pow(1.0 / 6.0) }.compileToExpression(DoubleField) val expr = MstExtendedField { x.pow(1.0 / 6.0) }.compileToExpression(Float64Field)
assertEquals(0.9730585187140817, expr(x to 0.8488554755054833)) assertEquals(0.9730585187140817, expr(x to 0.8488554755054833))
} }

View File

@ -13,9 +13,9 @@ import space.kscience.kmath.ast.TypedMst
import space.kscience.kmath.ast.evaluateConstants import space.kscience.kmath.ast.evaluateConstants
import space.kscience.kmath.expressions.* import space.kscience.kmath.expressions.*
import space.kscience.kmath.operations.Algebra import space.kscience.kmath.operations.Algebra
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.IntRing import space.kscience.kmath.operations.Int32Ring
import space.kscience.kmath.operations.LongRing import space.kscience.kmath.operations.Int64Ring
/** /**
* Compiles given MST to an Expression using AST compiler. * Compiles given MST to an Expression using AST compiler.
@ -91,7 +91,7 @@ public inline fun <reified T : Any> MST.compile(algebra: Algebra<T>, vararg argu
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun MST.compileToExpression(algebra: IntRing): IntExpression { public fun MST.compileToExpression(algebra: Int32Ring): IntExpression {
val typed = evaluateConstants(algebra) val typed = evaluateConstants(algebra)
return if (typed is TypedMst.Constant) object : IntExpression { return if (typed is TypedMst.Constant) object : IntExpression {
@ -108,7 +108,7 @@ public fun MST.compileToExpression(algebra: IntRing): IntExpression {
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = public fun MST.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int =
compileToExpression(algebra)(arguments) compileToExpression(algebra)(arguments)
/** /**
@ -117,7 +117,7 @@ public fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int =
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun MST.compile(algebra: IntRing, vararg arguments: Pair<Symbol, Int>): Int = public fun MST.compile(algebra: Int32Ring, vararg arguments: Pair<Symbol, Int>): Int =
compileToExpression(algebra)(*arguments) compileToExpression(algebra)(*arguments)
@ -127,7 +127,7 @@ public fun MST.compile(algebra: IntRing, vararg arguments: Pair<Symbol, Int>): I
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun MST.compileToExpression(algebra: LongRing): LongExpression { public fun MST.compileToExpression(algebra: Int64Ring): LongExpression {
val typed = evaluateConstants(algebra) val typed = evaluateConstants(algebra)
return if (typed is TypedMst.Constant<Long>) object : LongExpression { return if (typed is TypedMst.Constant<Long>) object : LongExpression {
@ -144,7 +144,7 @@ public fun MST.compileToExpression(algebra: LongRing): LongExpression {
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun MST.compile(algebra: LongRing, arguments: Map<Symbol, Long>): Long = public fun MST.compile(algebra: Int64Ring, arguments: Map<Symbol, Long>): Long =
compileToExpression(algebra)(arguments) compileToExpression(algebra)(arguments)
@ -154,7 +154,7 @@ public fun MST.compile(algebra: LongRing, arguments: Map<Symbol, Long>): Long =
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun MST.compile(algebra: LongRing, vararg arguments: Pair<Symbol, Long>): Long = public fun MST.compile(algebra: Int64Ring, vararg arguments: Pair<Symbol, Long>): Long =
compileToExpression(algebra)(*arguments) compileToExpression(algebra)(*arguments)
@ -164,7 +164,7 @@ public fun MST.compile(algebra: LongRing, vararg arguments: Pair<Symbol, Long>):
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun MST.compileToExpression(algebra: DoubleField): DoubleExpression { public fun MST.compileToExpression(algebra: Float64Field): DoubleExpression {
val typed = evaluateConstants(algebra) val typed = evaluateConstants(algebra)
return if (typed is TypedMst.Constant) object : DoubleExpression { return if (typed is TypedMst.Constant) object : DoubleExpression {
@ -182,7 +182,7 @@ public fun MST.compileToExpression(algebra: DoubleField): DoubleExpression {
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double = public fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double =
compileToExpression(algebra)(arguments) compileToExpression(algebra)(arguments)
/** /**
@ -191,5 +191,5 @@ public fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Do
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun MST.compile(algebra: DoubleField, vararg arguments: Pair<Symbol, Double>): Double = public fun MST.compile(algebra: Float64Field, vararg arguments: Pair<Symbol, Double>): Double =
compileToExpression(algebra)(*arguments) compileToExpression(algebra)(*arguments)

View File

@ -382,7 +382,7 @@ internal sealed class PrimitiveAsmBuilder<T : Number, out E : Expression<T>>(
@UnstableKMathAPI @UnstableKMathAPI
internal class DoubleAsmBuilder(target: TypedMst<Double>) : PrimitiveAsmBuilder<Double, DoubleExpression>( internal class DoubleAsmBuilder(target: TypedMst<Double>) : PrimitiveAsmBuilder<Double, DoubleExpression>(
DoubleField, Float64Field,
java.lang.Double::class.java, java.lang.Double::class.java,
java.lang.Double.TYPE, java.lang.Double.TYPE,
DoubleExpression::class.java, DoubleExpression::class.java,
@ -457,7 +457,7 @@ internal class DoubleAsmBuilder(target: TypedMst<Double>) : PrimitiveAsmBuilder<
@UnstableKMathAPI @UnstableKMathAPI
internal class IntAsmBuilder(target: TypedMst<Int>) : internal class IntAsmBuilder(target: TypedMst<Int>) :
PrimitiveAsmBuilder<Int, IntExpression>( PrimitiveAsmBuilder<Int, IntExpression>(
IntRing, Int32Ring,
Integer::class.java, Integer::class.java,
Integer.TYPE, Integer.TYPE,
IntExpression::class.java, IntExpression::class.java,
@ -487,7 +487,7 @@ internal class IntAsmBuilder(target: TypedMst<Int>) :
@UnstableKMathAPI @UnstableKMathAPI
internal class LongAsmBuilder(target: TypedMst<Long>) : PrimitiveAsmBuilder<Long, LongExpression>( internal class LongAsmBuilder(target: TypedMst<Long>) : PrimitiveAsmBuilder<Long, LongExpression>(
LongRing, Int64Ring,
java.lang.Long::class.java, java.lang.Long::class.java,
java.lang.Long.TYPE, java.lang.Long.TYPE,
LongExpression::class.java, LongExpression::class.java,

View File

@ -10,34 +10,34 @@ import space.kscience.kmath.expressions.Expression
import space.kscience.kmath.expressions.MST import space.kscience.kmath.expressions.MST
import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.expressions.Symbol
import space.kscience.kmath.operations.Algebra import space.kscience.kmath.operations.Algebra
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.IntRing import space.kscience.kmath.operations.Int32Ring
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
import space.kscience.kmath.asm.compile as asmCompile import space.kscience.kmath.asm.compile as asmCompile
import space.kscience.kmath.asm.compileToExpression as asmCompileToExpression import space.kscience.kmath.asm.compileToExpression as asmCompileToExpression
private object GenericAsmCompilerTestContext : CompilerTestContext { private object GenericAsmCompilerTestContext : CompilerTestContext {
override fun MST.compileToExpression(algebra: IntRing): Expression<Int> = override fun MST.compileToExpression(algebra: Int32Ring): Expression<Int> =
asmCompileToExpression(algebra as Algebra<Int>) asmCompileToExpression(algebra as Algebra<Int>)
override fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = override fun MST.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int =
asmCompile(algebra as Algebra<Int>, arguments) asmCompile(algebra as Algebra<Int>, arguments)
override fun MST.compileToExpression(algebra: DoubleField): Expression<Double> = override fun MST.compileToExpression(algebra: Float64Field): Expression<Double> =
asmCompileToExpression(algebra as Algebra<Double>) asmCompileToExpression(algebra as Algebra<Double>)
override fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double = override fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double =
asmCompile(algebra as Algebra<Double>, arguments) asmCompile(algebra as Algebra<Double>, arguments)
} }
@OptIn(UnstableKMathAPI::class) @OptIn(UnstableKMathAPI::class)
private object PrimitiveAsmCompilerTestContext : CompilerTestContext { private object PrimitiveAsmCompilerTestContext : CompilerTestContext {
override fun MST.compileToExpression(algebra: IntRing): Expression<Int> = asmCompileToExpression(algebra) override fun MST.compileToExpression(algebra: Int32Ring): Expression<Int> = asmCompileToExpression(algebra)
override fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = asmCompile(algebra, arguments) override fun MST.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int = asmCompile(algebra, arguments)
override fun MST.compileToExpression(algebra: DoubleField): Expression<Double> = asmCompileToExpression(algebra) override fun MST.compileToExpression(algebra: Float64Field): Expression<Double> = asmCompileToExpression(algebra)
override fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double = override fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double =
asmCompile(algebra, arguments) asmCompile(algebra, arguments)
} }

View File

@ -9,7 +9,7 @@ import org.apache.commons.math3.linear.*
import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.linear.* import space.kscience.kmath.linear.*
import space.kscience.kmath.nd.StructureFeature import space.kscience.kmath.nd.StructureFeature
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.Buffer
import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.DoubleBuffer
import kotlin.reflect.KClass import kotlin.reflect.KClass
@ -35,15 +35,15 @@ public value class CMVector(public val origin: RealVector) : Point<Double> {
public fun RealVector.toPoint(): CMVector = CMVector(this) public fun RealVector.toPoint(): CMVector = CMVector(this)
public object CMLinearSpace : LinearSpace<Double, DoubleField> { public object CMLinearSpace : LinearSpace<Double, Float64Field> {
override val elementAlgebra: DoubleField get() = DoubleField override val elementAlgebra: Float64Field get() = Float64Field
override fun buildMatrix( override fun buildMatrix(
rows: Int, rows: Int,
columns: Int, columns: Int,
initializer: DoubleField.(i: Int, j: Int) -> Double, initializer: Float64Field.(i: Int, j: Int) -> Double,
): CMMatrix { ): CMMatrix {
val array = Array(rows) { i -> DoubleArray(columns) { j -> DoubleField.initializer(i, j) } } val array = Array(rows) { i -> DoubleArray(columns) { j -> Float64Field.initializer(i, j) } }
return CMMatrix(Array2DRowRealMatrix(array)) return CMMatrix(Array2DRowRealMatrix(array))
} }
@ -65,8 +65,8 @@ public object CMLinearSpace : LinearSpace<Double, DoubleField> {
internal fun RealMatrix.wrap(): CMMatrix = CMMatrix(this) internal fun RealMatrix.wrap(): CMMatrix = CMMatrix(this)
internal fun RealVector.wrap(): CMVector = CMVector(this) internal fun RealVector.wrap(): CMVector = CMVector(this)
override fun buildVector(size: Int, initializer: DoubleField.(Int) -> Double): Point<Double> = override fun buildVector(size: Int, initializer: Float64Field.(Int) -> Double): Point<Double> =
ArrayRealVector(DoubleArray(size) { DoubleField.initializer(it) }).wrap() ArrayRealVector(DoubleArray(size) { Float64Field.initializer(it) }).wrap()
override fun Matrix<Double>.plus(other: Matrix<Double>): CMMatrix = override fun Matrix<Double>.plus(other: Matrix<Double>): CMMatrix =
toCM().origin.add(other.toCM().origin).wrap() toCM().origin.add(other.toCM().origin).wrap()

View File

@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test
import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.integration.integrate import space.kscience.kmath.integration.integrate
import space.kscience.kmath.integration.value import space.kscience.kmath.integration.value
import space.kscience.kmath.operations.DoubleField.sin import space.kscience.kmath.operations.Float64Field.sin
import kotlin.math.PI import kotlin.math.PI
import kotlin.math.abs import kotlin.math.abs
import kotlin.test.assertTrue import kotlin.test.assertTrue

View File

@ -14,7 +14,7 @@ import space.kscience.kmath.expressions.Symbol.Companion.y
import space.kscience.kmath.expressions.autodiff import space.kscience.kmath.expressions.autodiff
import space.kscience.kmath.expressions.symbol import space.kscience.kmath.expressions.symbol
import space.kscience.kmath.operations.DoubleBufferOps.Companion.map import space.kscience.kmath.operations.DoubleBufferOps.Companion.map
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.optimization.* import space.kscience.kmath.optimization.*
import space.kscience.kmath.random.RandomGenerator import space.kscience.kmath.random.RandomGenerator
import space.kscience.kmath.stat.chiSquaredExpression import space.kscience.kmath.stat.chiSquaredExpression
@ -24,7 +24,7 @@ import kotlin.test.Test
@OptIn(UnstableKMathAPI::class) @OptIn(UnstableKMathAPI::class)
internal class OptimizeTest { internal class OptimizeTest {
val normal = DSFieldExpression(DoubleField) { val normal = DSFieldExpression(Float64Field) {
exp(-bindSymbol(x).pow(2) / 2) + exp(-bindSymbol(y).pow(2) / 2) exp(-bindSymbol(x).pow(2) / 2) + exp(-bindSymbol(y).pow(2) / 2)
} }

View File

@ -464,4 +464,4 @@ public class DSFieldProcessor<T, A : ExtendedField<T>>(
} }
@UnstableKMathAPI @UnstableKMathAPI
public val Double.Companion.autodiff: DSFieldProcessor<Double, DoubleField> get() = DSFieldProcessor(DoubleField) public val Double.Companion.autodiff: DSFieldProcessor<Double, Float64Field> get() = DSFieldProcessor(Float64Field)

View File

@ -191,6 +191,6 @@ public inline fun <T, A : ExtendedField<T>> A.expressionInExtendedField(
block: FunctionalExpressionExtendedField<T, A>.() -> Expression<T>, block: FunctionalExpressionExtendedField<T, A>.() -> Expression<T>,
): Expression<T> = FunctionalExpressionExtendedField(this).block() ): Expression<T> = FunctionalExpressionExtendedField(this).block()
public inline fun DoubleField.expression( public inline fun Float64Field.expression(
block: FunctionalExpressionExtendedField<Double, DoubleField>.() -> Expression<Double>, block: FunctionalExpressionExtendedField<Double, Float64Field>.() -> Expression<Double>,
): Expression<Double> = FunctionalExpressionExtendedField(this).block() ): Expression<Double> = FunctionalExpressionExtendedField(this).block()

View File

@ -8,25 +8,25 @@ package space.kscience.kmath.linear
import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.PerformancePitfall
import space.kscience.kmath.nd.* import space.kscience.kmath.nd.*
import space.kscience.kmath.operations.DoubleBufferOps import space.kscience.kmath.operations.DoubleBufferOps
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.Buffer
import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.DoubleBuffer
public object DoubleLinearSpace : LinearSpace<Double, DoubleField> { public object DoubleLinearSpace : LinearSpace<Double, Float64Field> {
override val elementAlgebra: DoubleField get() = DoubleField override val elementAlgebra: Float64Field get() = Float64Field
override fun buildMatrix( override fun buildMatrix(
rows: Int, rows: Int,
columns: Int, columns: Int,
initializer: DoubleField.(i: Int, j: Int) -> Double initializer: Float64Field.(i: Int, j: Int) -> Double
): Matrix<Double> = DoubleFieldOpsND.structureND(ShapeND(rows, columns)) { (i, j) -> ): Matrix<Double> = DoubleFieldOpsND.structureND(ShapeND(rows, columns)) { (i, j) ->
DoubleField.initializer(i, j) Float64Field.initializer(i, j)
}.as2D() }.as2D()
override fun buildVector(size: Int, initializer: DoubleField.(Int) -> Double): DoubleBuffer = override fun buildVector(size: Int, initializer: Float64Field.(Int) -> Double): DoubleBuffer =
DoubleBuffer(size) { DoubleField.initializer(it) } DoubleBuffer(size) { Float64Field.initializer(it) }
override fun Matrix<Double>.unaryMinus(): Matrix<Double> = DoubleFieldOpsND { override fun Matrix<Double>.unaryMinus(): Matrix<Double> = DoubleFieldOpsND {
asND().map { -it }.as2D() asND().map { -it }.as2D()
@ -105,4 +105,4 @@ public object DoubleLinearSpace : LinearSpace<Double, DoubleField> {
} }
public val DoubleField.linearSpace: DoubleLinearSpace get() = DoubleLinearSpace public val Float64Field.linearSpace: DoubleLinearSpace get() = DoubleLinearSpace

View File

@ -155,7 +155,7 @@ public inline fun <reified T : Comparable<T>> LinearSpace<T, Field<T>>.lup(
noinline checkSingular: (T) -> Boolean, noinline checkSingular: (T) -> Boolean,
): LupDecomposition<T> = lup(MutableBuffer.Companion::auto, matrix, checkSingular) ): LupDecomposition<T> = lup(MutableBuffer.Companion::auto, matrix, checkSingular)
public fun LinearSpace<Double, DoubleField>.lup( public fun LinearSpace<Double, Float64Field>.lup(
matrix: Matrix<Double>, matrix: Matrix<Double>,
singularityThreshold: Double = 1e-11, singularityThreshold: Double = 1e-11,
): LupDecomposition<Double> = ): LupDecomposition<Double> =
@ -226,5 +226,5 @@ public fun <T : Comparable<T>, F : Field<T>> LinearSpace<T, F>.lupSolver(
override fun inverse(matrix: Matrix<T>): Matrix<T> = solve(matrix, one(matrix.rowNum, matrix.colNum)) override fun inverse(matrix: Matrix<T>): Matrix<T> = solve(matrix, one(matrix.rowNum, matrix.colNum))
} }
public fun LinearSpace<Double, DoubleField>.lupSolver(singularityThreshold: Double = 1e-11): LinearSolver<Double> = public fun LinearSpace<Double, Float64Field>.lupSolver(singularityThreshold: Double = 1e-11): LinearSolver<Double> =
lupSolver(::DoubleBuffer) { it < singularityThreshold } lupSolver(::DoubleBuffer) { it < singularityThreshold }

View File

@ -65,6 +65,15 @@ public fun <V, C : Comparable<C>> Buffer<V>.sortedByDescending(selector: (V) ->
public fun <V> Buffer<V>.indicesSortedWith(comparator: Comparator<V>): IntArray = public fun <V> Buffer<V>.indicesSortedWith(comparator: Comparator<V>): IntArray =
permSortIndicesWith { i1, i2 -> comparator.compare(get(i1), get(i2)) } permSortIndicesWith { i1, i2 -> comparator.compare(get(i1), get(i2)) }
/**
* Create virtual zero-copy buffer with elements sorted by [comparator]
*/
@OptIn(UnstableKMathAPI::class)
public fun <V> Buffer<V>.sortedWith(comparator: Comparator<V>): Buffer<V> {
val permutations = indicesSortedWith(comparator)
return VirtualBuffer(size) { this[permutations[it]] }
}
private fun <V> Buffer<V>.permSortIndicesWith(comparator: Comparator<Int>): IntArray { private fun <V> Buffer<V>.permSortIndicesWith(comparator: Comparator<Int>): IntArray {
if (size < 2) return IntArray(size) { 0 } if (size < 2) return IntArray(size) { 0 }

View File

@ -29,7 +29,7 @@ public class DoubleBufferND(
} }
public sealed class DoubleFieldOpsND : BufferedFieldOpsND<Double, DoubleField>(DoubleField.bufferAlgebra), public sealed class DoubleFieldOpsND : BufferedFieldOpsND<Double, Float64Field>(Float64Field.bufferAlgebra),
ScaleOperations<StructureND<Double>>, ExtendedFieldOps<StructureND<Double>> { ScaleOperations<StructureND<Double>>, ExtendedFieldOps<StructureND<Double>> {
@OptIn(PerformancePitfall::class) @OptIn(PerformancePitfall::class)
@ -63,18 +63,18 @@ public sealed class DoubleFieldOpsND : BufferedFieldOpsND<Double, DoubleField>(D
} }
@OptIn(PerformancePitfall::class) @OptIn(PerformancePitfall::class)
override fun StructureND<Double>.map(transform: DoubleField.(Double) -> Double): BufferND<Double> = override fun StructureND<Double>.map(transform: Float64Field.(Double) -> Double): BufferND<Double> =
mapInline(toBufferND()) { DoubleField.transform(it) } mapInline(toBufferND()) { Float64Field.transform(it) }
@OptIn(PerformancePitfall::class) @OptIn(PerformancePitfall::class)
override fun zip( override fun zip(
left: StructureND<Double>, left: StructureND<Double>,
right: StructureND<Double>, right: StructureND<Double>,
transform: DoubleField.(Double, Double) -> Double, transform: Float64Field.(Double, Double) -> Double,
): BufferND<Double> = zipInline(left.toBufferND(), right.toBufferND()) { l, r -> DoubleField.transform(l, r) } ): BufferND<Double> = zipInline(left.toBufferND(), right.toBufferND()) { l, r -> Float64Field.transform(l, r) }
override fun structureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): DoubleBufferND { override fun structureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): DoubleBufferND {
val indexer = indexerBuilder(shape) val indexer = indexerBuilder(shape)
return DoubleBufferND( return DoubleBufferND(
indexer, indexer,
@ -190,7 +190,7 @@ public sealed class DoubleFieldOpsND : BufferedFieldOpsND<Double, DoubleField>(D
@OptIn(UnstableKMathAPI::class) @OptIn(UnstableKMathAPI::class)
public class DoubleFieldND(override val shape: ShapeND) : public class DoubleFieldND(override val shape: ShapeND) :
DoubleFieldOpsND(), FieldND<Double, DoubleField>, NumbersAddOps<StructureND<Double>>, DoubleFieldOpsND(), FieldND<Double, Float64Field>, NumbersAddOps<StructureND<Double>>,
ExtendedField<StructureND<Double>> { ExtendedField<StructureND<Double>> {
override fun power(arg: StructureND<Double>, pow: UInt): DoubleBufferND = mapInline(arg.toBufferND()) { override fun power(arg: StructureND<Double>, pow: UInt): DoubleBufferND = mapInline(arg.toBufferND()) {
@ -229,16 +229,16 @@ public class DoubleFieldND(override val shape: ShapeND) :
} }
} }
public val DoubleField.ndAlgebra: DoubleFieldOpsND get() = DoubleFieldOpsND public val Float64Field.ndAlgebra: DoubleFieldOpsND get() = DoubleFieldOpsND
public fun DoubleField.ndAlgebra(vararg shape: Int): DoubleFieldND = DoubleFieldND(ShapeND(shape)) public fun Float64Field.ndAlgebra(vararg shape: Int): DoubleFieldND = DoubleFieldND(ShapeND(shape))
public fun DoubleField.ndAlgebra(shape: ShapeND): DoubleFieldND = DoubleFieldND(shape) public fun Float64Field.ndAlgebra(shape: ShapeND): DoubleFieldND = DoubleFieldND(shape)
/** /**
* Produce a context for n-dimensional operations inside this real field * Produce a context for n-dimensional operations inside this real field
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public inline fun <R> DoubleField.withNdAlgebra(vararg shape: Int, action: DoubleFieldND.() -> R): R { public inline fun <R> Float64Field.withNdAlgebra(vararg shape: Int, action: DoubleFieldND.() -> R): R {
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
return DoubleFieldND(ShapeND(shape)).run(action) return DoubleFieldND(ShapeND(shape)).run(action)
} }

View File

@ -6,7 +6,7 @@
package space.kscience.kmath.nd package space.kscience.kmath.nd
import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.operations.IntRing import space.kscience.kmath.operations.Int32Ring
import space.kscience.kmath.operations.NumbersAddOps import space.kscience.kmath.operations.NumbersAddOps
import space.kscience.kmath.operations.bufferAlgebra import space.kscience.kmath.operations.bufferAlgebra
import space.kscience.kmath.structures.IntBuffer import space.kscience.kmath.structures.IntBuffer
@ -18,9 +18,9 @@ public class IntBufferND(
override val buffer: IntBuffer, override val buffer: IntBuffer,
) : MutableBufferND<Int>(indexes, buffer) ) : MutableBufferND<Int>(indexes, buffer)
public sealed class IntRingOpsND : BufferedRingOpsND<Int, IntRing>(IntRing.bufferAlgebra) { public sealed class IntRingOpsND : BufferedRingOpsND<Int, Int32Ring>(Int32Ring.bufferAlgebra) {
override fun structureND(shape: ShapeND, initializer: IntRing.(IntArray) -> Int): IntBufferND { override fun structureND(shape: ShapeND, initializer: Int32Ring.(IntArray) -> Int): IntBufferND {
val indexer = indexerBuilder(shape) val indexer = indexerBuilder(shape)
return IntBufferND( return IntBufferND(
indexer, indexer,
@ -36,7 +36,7 @@ public sealed class IntRingOpsND : BufferedRingOpsND<Int, IntRing>(IntRing.buffe
@OptIn(UnstableKMathAPI::class) @OptIn(UnstableKMathAPI::class)
public class IntRingND( public class IntRingND(
override val shape: ShapeND override val shape: ShapeND
) : IntRingOpsND(), RingND<Int, IntRing>, NumbersAddOps<StructureND<Int>> { ) : IntRingOpsND(), RingND<Int, Int32Ring>, NumbersAddOps<StructureND<Int>> {
override fun number(value: Number): BufferND<Int> { override fun number(value: Number): BufferND<Int> {
val int = value.toInt() // minimize conversions val int = value.toInt() // minimize conversions
@ -44,7 +44,7 @@ public class IntRingND(
} }
} }
public inline fun <R> IntRing.withNdAlgebra(vararg shape: Int, action: IntRingND.() -> R): R { public inline fun <R> Int32Ring.withNdAlgebra(vararg shape: Int, action: IntRingND.() -> R): R {
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
return IntRingND(ShapeND(shape)).run(action) return IntRingND(ShapeND(shape)).run(action)
} }

View File

@ -6,20 +6,20 @@
package space.kscience.kmath.nd package space.kscience.kmath.nd
import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.operations.Int16Ring
import space.kscience.kmath.operations.NumbersAddOps import space.kscience.kmath.operations.NumbersAddOps
import space.kscience.kmath.operations.ShortRing
import space.kscience.kmath.operations.bufferAlgebra import space.kscience.kmath.operations.bufferAlgebra
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
public sealed class ShortRingOpsND : BufferedRingOpsND<Short, ShortRing>(ShortRing.bufferAlgebra) { public sealed class ShortRingOpsND : BufferedRingOpsND<Short, Int16Ring>(Int16Ring.bufferAlgebra) {
public companion object : ShortRingOpsND() public companion object : ShortRingOpsND()
} }
@OptIn(UnstableKMathAPI::class) @OptIn(UnstableKMathAPI::class)
public class ShortRingND( public class ShortRingND(
override val shape: ShapeND override val shape: ShapeND
) : ShortRingOpsND(), RingND<Short, ShortRing>, NumbersAddOps<StructureND<Short>> { ) : ShortRingOpsND(), RingND<Short, Int16Ring>, NumbersAddOps<StructureND<Short>> {
override fun number(value: Number): BufferND<Short> { override fun number(value: Number): BufferND<Short> {
val short val short
@ -28,7 +28,7 @@ public class ShortRingND(
} }
} }
public inline fun <R> ShortRing.withNdAlgebra(vararg shape: Int, action: ShortRingND.() -> R): R { public inline fun <R> Int16Ring.withNdAlgebra(vararg shape: Int, action: ShortRingND.() -> R): R {
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
return ShortRingND(ShapeND(shape)).run(action) return ShortRingND(ShapeND(shape)).run(action)
} }

View File

@ -142,11 +142,11 @@ public open class BufferRingOps<T, A : Ring<T>>(
super<BufferAlgebra>.binaryOperationFunction(operation) super<BufferAlgebra>.binaryOperationFunction(operation)
} }
public val IntRing.bufferAlgebra: BufferRingOps<Int, IntRing> public val Int32Ring.bufferAlgebra: BufferRingOps<Int, Int32Ring>
get() = BufferRingOps(IntRing) get() = BufferRingOps(Int32Ring)
public val ShortRing.bufferAlgebra: BufferRingOps<Short, ShortRing> public val Int16Ring.bufferAlgebra: BufferRingOps<Short, Int16Ring>
get() = BufferRingOps(ShortRing) get() = BufferRingOps(Int16Ring)
public open class BufferFieldOps<T, A : Field<T>>( public open class BufferFieldOps<T, A : Field<T>>(
elementAlgebra: A, elementAlgebra: A,

View File

@ -14,32 +14,32 @@ import kotlin.math.sqrt
/** /**
* [ExtendedFieldOps] over [DoubleBuffer]. * [ExtendedFieldOps] over [DoubleBuffer].
*/ */
public abstract class DoubleBufferOps : BufferAlgebra<Double, DoubleField>, ExtendedFieldOps<Buffer<Double>>, public abstract class DoubleBufferOps : BufferAlgebra<Double, Float64Field>, ExtendedFieldOps<Buffer<Double>>,
Norm<Buffer<Double>, Double> { Norm<Buffer<Double>, Double> {
override val elementAlgebra: DoubleField get() = DoubleField override val elementAlgebra: Float64Field get() = Float64Field
override val elementBufferFactory: MutableBufferFactory<Double> get() = elementAlgebra.bufferFactory override val elementBufferFactory: MutableBufferFactory<Double> get() = elementAlgebra.bufferFactory
@Suppress("OVERRIDE_BY_INLINE") @Suppress("OVERRIDE_BY_INLINE")
@OptIn(UnstableKMathAPI::class) @OptIn(UnstableKMathAPI::class)
final override inline fun Buffer<Double>.map(block: DoubleField.(Double) -> Double): DoubleBuffer = final override inline fun Buffer<Double>.map(block: Float64Field.(Double) -> Double): DoubleBuffer =
DoubleArray(size) { DoubleField.block(getDouble(it)) }.asBuffer() DoubleArray(size) { Float64Field.block(getDouble(it)) }.asBuffer()
@OptIn(UnstableKMathAPI::class) @OptIn(UnstableKMathAPI::class)
@Suppress("OVERRIDE_BY_INLINE") @Suppress("OVERRIDE_BY_INLINE")
final override inline fun Buffer<Double>.mapIndexed(block: DoubleField.(index: Int, arg: Double) -> Double): DoubleBuffer = final override inline fun Buffer<Double>.mapIndexed(block: Float64Field.(index: Int, arg: Double) -> Double): DoubleBuffer =
DoubleBuffer(size) { DoubleField.block(it, getDouble(it)) } DoubleBuffer(size) { Float64Field.block(it, getDouble(it)) }
@OptIn(UnstableKMathAPI::class) @OptIn(UnstableKMathAPI::class)
@Suppress("OVERRIDE_BY_INLINE") @Suppress("OVERRIDE_BY_INLINE")
final override inline fun Buffer<Double>.zip( final override inline fun Buffer<Double>.zip(
other: Buffer<Double>, other: Buffer<Double>,
block: DoubleField.(left: Double, right: Double) -> Double, block: Float64Field.(left: Double, right: Double) -> Double,
): DoubleBuffer { ): DoubleBuffer {
require(size == other.size) { "Incompatible buffer sizes. left: ${size}, right: ${other.size}" } require(size == other.size) { "Incompatible buffer sizes. left: ${size}, right: ${other.size}" }
return DoubleBuffer(size) { DoubleField.block(getDouble(it), other.getDouble(it)) } return DoubleBuffer(size) { Float64Field.block(getDouble(it), other.getDouble(it)) }
} }
override fun unaryOperationFunction(operation: String): (arg: Buffer<Double>) -> Buffer<Double> = override fun unaryOperationFunction(operation: String): (arg: Buffer<Double>) -> Buffer<Double> =

View File

@ -0,0 +1,85 @@
/*
* Copyright 2018-2023 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.operations
import space.kscience.kmath.operations.Int16Field.div
import space.kscience.kmath.operations.Int32Field.div
import space.kscience.kmath.operations.Int64Field.div
import space.kscience.kmath.structures.*
import kotlin.math.roundToInt
import kotlin.math.roundToLong
/**
* A [Int16] field with integer division and scale. The division operation is done according to [Short.div] rules.
*
* Scaling is done according to [Double.roundToInt] rules.
*
* All results are converted to Int16.
*/
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
public object Int16Field : Field<Int16>, Norm<Int16, Int16>, NumericAlgebra<Int16> {
override val bufferFactory: MutableBufferFactory<Int16> = MutableBufferFactory(::ShortBuffer)
override val zero: Int16 get() = 0
override val one: Int16 get() = 1
override fun number(value: Number): Int16 = value.toShort()
override fun add(left: Int16, right: Int16): Int16 = (left + right).toShort()
override fun multiply(left: Int16, right: Int16): Int16 = (left * right).toShort()
override fun norm(arg: Int16): Int16 = abs(arg)
override fun scale(a: Int16, value: Double): Int16 = (a*value).roundToInt().toShort()
override fun divide(left: Int16, right: Int16): Int16 = (left / right).toShort()
override fun Int16.unaryMinus(): Int16 = (-this).toShort()
}
/**
* A [Int32] field with integer division and scale. The division operation is done according to [Int.div] rules.
*
* Scaling is done according to [Double.roundToInt] rules.
*/
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
public object Int32Field : Field<Int32>, Norm<Int32, Int32>, NumericAlgebra<Int32> {
override val bufferFactory: MutableBufferFactory<Int> = MutableBufferFactory(::IntBuffer)
override val zero: Int get() = 0
override val one: Int get() = 1
override fun number(value: Number): Int = value.toInt()
override fun add(left: Int, right: Int): Int = left + right
override fun multiply(left: Int, right: Int): Int = left * right
override fun norm(arg: Int): Int = abs(arg)
override fun scale(a: Int, value: Double): Int = (a*value).roundToInt()
override fun divide(left: Int, right: Int): Int = left / right
override fun Int.unaryMinus(): Int = -this
}
/**
* A [Int64] field with integer division and scale. The division operation is done according to [Long.div] rules.
*
* Scaling is done according to [Double.roundToLong] rules.
*/
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
public object Int64Field : Field<Int64>, Norm<Int64, Int64>, NumericAlgebra<Int64> {
override val bufferFactory: MutableBufferFactory<Int64> = MutableBufferFactory(::LongBuffer)
override val zero: Int64 get() = 0L
override val one: Int64 get() = 1L
override fun number(value: Number): Int64 = value.toLong()
override fun add(left: Int64, right: Int64): Int64 = left + right
override fun multiply(left: Int64, right: Int64): Int64 = left * right
override fun norm(arg: Int64): Int64 = abs(arg)
override fun scale(a: Int64, value: Double): Int64 = (a*value).roundToLong()
override fun divide(left: Int64, right: Int64): Int64 = left / right
override fun Int64.unaryMinus(): Int64 = -this
}

View File

@ -2,7 +2,6 @@
* Copyright 2018-2022 KMath contributors. * Copyright 2018-2022 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@file:Suppress("NOTHING_TO_INLINE")
package space.kscience.kmath.operations package space.kscience.kmath.operations
import space.kscience.kmath.structures.* import space.kscience.kmath.structures.*
@ -67,7 +66,7 @@ public interface ExtendedField<T> : ExtendedFieldOps<T>, Field<T>, NumericAlgebr
* A field for [Double] without boxing. Does not produce appropriate field element. * A field for [Double] without boxing. Does not produce appropriate field element.
*/ */
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE") @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE")
public object DoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOperations<Double> { public object Float64Field : ExtendedField<Double>, Norm<Double, Double>, ScaleOperations<Double> {
override val bufferFactory: MutableBufferFactory<Double> = MutableBufferFactory(::DoubleBuffer) override val bufferFactory: MutableBufferFactory<Double> = MutableBufferFactory(::DoubleBuffer)
override inline val zero: Double get() = 0.0 override inline val zero: Double get() = 0.0
@ -121,13 +120,15 @@ public object DoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOp
override inline fun Double.div(arg: Double): Double = this / arg override inline fun Double.div(arg: Double): Double = this / arg
} }
public val Double.Companion.algebra: DoubleField get() = DoubleField public typealias DoubleField = Float64Field
public val Double.Companion.algebra: Float64Field get() = Float64Field
/** /**
* A field for [Float] without boxing. Does not produce appropriate field element. * A field for [Float] without boxing. Does not produce appropriate field element.
*/ */
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE") @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE")
public object FloatField : ExtendedField<Float>, Norm<Float, Float> { public object Float32Field : ExtendedField<Float>, Norm<Float, Float> {
override val bufferFactory: MutableBufferFactory<Float> = MutableBufferFactory(::FloatBuffer) override val bufferFactory: MutableBufferFactory<Float> = MutableBufferFactory(::FloatBuffer)
override inline val zero: Float get() = 0.0f override inline val zero: Float get() = 0.0f
@ -177,13 +178,15 @@ public object FloatField : ExtendedField<Float>, Norm<Float, Float> {
override inline fun Float.div(arg: Float): Float = this / arg override inline fun Float.div(arg: Float): Float = this / arg
} }
public val Float.Companion.algebra: FloatField get() = FloatField public typealias FloatField = Float32Field
public val Float.Companion.algebra: Float32Field get() = Float32Field
/** /**
* A field for [Int] without boxing. Does not produce corresponding ring element. * A field for [Int] without boxing. Does not produce corresponding ring element.
*/ */
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE") @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE")
public object IntRing : Ring<Int>, Norm<Int, Int>, NumericAlgebra<Int> { public object Int32Ring : Ring<Int>, Norm<Int, Int>, NumericAlgebra<Int> {
override val bufferFactory: MutableBufferFactory<Int> = MutableBufferFactory(::IntBuffer) override val bufferFactory: MutableBufferFactory<Int> = MutableBufferFactory(::IntBuffer)
override inline val zero: Int get() = 0 override inline val zero: Int get() = 0
@ -200,13 +203,15 @@ public object IntRing : Ring<Int>, Norm<Int, Int>, NumericAlgebra<Int> {
override inline fun Int.times(arg: Int): Int = this * arg override inline fun Int.times(arg: Int): Int = this * arg
} }
public val Int.Companion.algebra: IntRing get() = IntRing public typealias IntRing = Int32Ring
public val Int.Companion.algebra: Int32Ring get() = Int32Ring
/** /**
* A field for [Short] without boxing. Does not produce appropriate ring element. * A field for [Short] without boxing. Does not produce appropriate ring element.
*/ */
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE") @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE")
public object ShortRing : Ring<Short>, Norm<Short, Short>, NumericAlgebra<Short> { public object Int16Ring : Ring<Short>, Norm<Short, Short>, NumericAlgebra<Short> {
override val bufferFactory: MutableBufferFactory<Short> = MutableBufferFactory(::ShortBuffer) override val bufferFactory: MutableBufferFactory<Short> = MutableBufferFactory(::ShortBuffer)
override inline val zero: Short get() = 0 override inline val zero: Short get() = 0
@ -223,7 +228,9 @@ public object ShortRing : Ring<Short>, Norm<Short, Short>, NumericAlgebra<Short>
override inline fun Short.times(arg: Short): Short = (this * arg).toShort() override inline fun Short.times(arg: Short): Short = (this * arg).toShort()
} }
public val Short.Companion.algebra: ShortRing get() = ShortRing public typealias ShortRing = Int16Ring
public val Short.Companion.algebra: Int16Ring get() = Int16Ring
/** /**
* A field for [Byte] without boxing. Does not produce appropriate ring element. * A field for [Byte] without boxing. Does not produce appropriate ring element.
@ -249,10 +256,10 @@ public object ByteRing : Ring<Byte>, Norm<Byte, Byte>, NumericAlgebra<Byte> {
public val Byte.Companion.algebra: ByteRing get() = ByteRing public val Byte.Companion.algebra: ByteRing get() = ByteRing
/** /**
* A field for [Double] without boxing. Does not produce appropriate ring element. * A field for [Double] without boxing. Does not produce an appropriate ring element.
*/ */
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE") @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE")
public object LongRing : Ring<Long>, Norm<Long, Long>, NumericAlgebra<Long> { public object Int64Ring : Ring<Long>, Norm<Long, Long>, NumericAlgebra<Long> {
override val bufferFactory: MutableBufferFactory<Long> = MutableBufferFactory(::LongBuffer) override val bufferFactory: MutableBufferFactory<Long> = MutableBufferFactory(::LongBuffer)
override inline val zero: Long get() = 0L override inline val zero: Long get() = 0L
@ -269,4 +276,6 @@ public object LongRing : Ring<Long>, Norm<Long, Long>, NumericAlgebra<Long> {
override inline fun Long.times(arg: Long): Long = (this * arg) override inline fun Long.times(arg: Long): Long = (this * arg)
} }
public val Long.Companion.algebra: LongRing get() = LongRing public typealias LongRing = Int64Ring
public val Long.Companion.algebra: Int64Ring get() = Int64Ring

View File

@ -96,6 +96,12 @@ public fun <T> Buffer<T>.slice(range: IntRange): BufferView<T> = if (this is Buf
) )
} }
/**
* Dynamically create a range from the initial range
*/
@UnstableKMathAPI
public inline fun <T> Buffer<T>.slice(rangeBuilder: IntRange.() -> IntRange): BufferView<T> = slice(rangeBuilder(indices))
/** /**
* Resize original buffer to a given range using given [range], filling additional segments with [defaultValue]. * Resize original buffer to a given range using given [range], filling additional segments with [defaultValue].
* Range left border could be negative to designate adding new blank segment to the beginning of the buffer * Range left border could be negative to designate adding new blank segment to the beginning of the buffer

View File

@ -8,7 +8,7 @@
package space.kscience.kmath.expressions package space.kscience.kmath.expressions
import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
import kotlin.test.Test import kotlin.test.Test
@ -18,10 +18,10 @@ import kotlin.test.assertFails
internal inline fun diff( internal inline fun diff(
order: Int, order: Int,
vararg parameters: Pair<Symbol, Double>, vararg parameters: Pair<Symbol, Double>,
block: DSField<Double, DoubleField>.() -> Unit, block: DSField<Double, Float64Field>.() -> Unit,
) { ) {
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
DSField(DoubleField, order, mapOf(*parameters)).block() DSField(Float64Field, order, mapOf(*parameters)).block()
} }
internal class DSTest { internal class DSTest {
@ -44,7 +44,7 @@ internal class DSTest {
@Test @Test
fun dsExpressionTest() { fun dsExpressionTest() {
val f = DSFieldExpression(DoubleField) { val f = DSFieldExpression(Float64Field) {
val x by binding val x by binding
val y by binding val y by binding
x.pow(2) + 2 * x * y + y.pow(2) + 1 x.pow(2) + 2 * x * y + y.pow(2) + 1

View File

@ -5,7 +5,7 @@
package space.kscience.kmath.expressions package space.kscience.kmath.expressions
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFails import kotlin.test.assertFails
@ -15,7 +15,7 @@ class ExpressionFieldTest {
@Test @Test
fun testExpression() { fun testExpression() {
val expression = with(FunctionalExpressionField(DoubleField)) { val expression = with(FunctionalExpressionField(Float64Field)) {
val x by binding val x by binding
x * x + 2 * x + one x * x + 2 * x + one
} }
@ -31,7 +31,7 @@ class ExpressionFieldTest {
return x * x + 2 * x + one return x * x + 2 * x + one
} }
val expression = FunctionalExpressionField(DoubleField).expression() val expression = FunctionalExpressionField(Float64Field).expression()
assertEquals(expression(x to 1.0), 4.0) assertEquals(expression(x to 1.0), 4.0)
} }
@ -42,7 +42,7 @@ class ExpressionFieldTest {
x * x + 2 * x + one x * x + 2 * x + one
} }
val expression = FunctionalExpressionField(DoubleField).expressionBuilder() val expression = FunctionalExpressionField(Float64Field).expressionBuilder()
assertEquals(expression(x to 1.0), 4.0) assertEquals(expression(x to 1.0), 4.0)
} }
} }

View File

@ -8,7 +8,7 @@ package space.kscience.kmath.expressions
import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.expressions.Symbol.Companion.x import space.kscience.kmath.expressions.Symbol.Companion.x
import space.kscience.kmath.operations.BooleanAlgebra import space.kscience.kmath.operations.BooleanAlgebra
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -19,7 +19,7 @@ internal class InterpretTest {
fun interpretation() { fun interpretation() {
val expr = MstField { val expr = MstField {
x * 2.0 + number(2.0) / x - 16.0 x * 2.0 + number(2.0) / x - 16.0
}.toExpression(DoubleField) }.toExpression(Float64Field)
assertEquals(-10.69, expr(x to 2.2), 0.02) assertEquals(-10.69, expr(x to 2.2), 0.02)
} }

View File

@ -5,7 +5,7 @@
package space.kscience.kmath.expressions package space.kscience.kmath.expressions
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.bindSymbol import space.kscience.kmath.operations.bindSymbol
import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.Buffer
import space.kscience.kmath.structures.asBuffer import space.kscience.kmath.structures.asBuffer
@ -21,19 +21,19 @@ internal class SimpleAutoDiffTest {
fun dx( fun dx(
xBinding: Pair<Symbol, Double>, xBinding: Pair<Symbol, Double>,
body: SimpleAutoDiffField<Double, DoubleField>.(x: AutoDiffValue<Double>) -> AutoDiffValue<Double>, body: SimpleAutoDiffField<Double, Float64Field>.(x: AutoDiffValue<Double>) -> AutoDiffValue<Double>,
): DerivationResult<Double> = DoubleField.simpleAutoDiff(xBinding) { body(bindSymbol(xBinding.first)) } ): DerivationResult<Double> = Float64Field.simpleAutoDiff(xBinding) { body(bindSymbol(xBinding.first)) }
fun dxy( fun dxy(
xBinding: Pair<Symbol, Double>, xBinding: Pair<Symbol, Double>,
yBinding: Pair<Symbol, Double>, yBinding: Pair<Symbol, Double>,
body: SimpleAutoDiffField<Double, DoubleField>.(x: AutoDiffValue<Double>, y: AutoDiffValue<Double>) -> AutoDiffValue<Double>, body: SimpleAutoDiffField<Double, Float64Field>.(x: AutoDiffValue<Double>, y: AutoDiffValue<Double>) -> AutoDiffValue<Double>,
): DerivationResult<Double> = DoubleField.simpleAutoDiff(xBinding, yBinding) { ): DerivationResult<Double> = Float64Field.simpleAutoDiff(xBinding, yBinding) {
body(bindSymbol(xBinding.first), bindSymbol(yBinding.first)) body(bindSymbol(xBinding.first), bindSymbol(yBinding.first))
} }
fun diff(block: SimpleAutoDiffField<Double, DoubleField>.() -> AutoDiffValue<Double>): SimpleAutoDiffExpression<Double, DoubleField> { fun diff(block: SimpleAutoDiffField<Double, Float64Field>.() -> AutoDiffValue<Double>): SimpleAutoDiffExpression<Double, Float64Field> {
return SimpleAutoDiffExpression(DoubleField, block) return SimpleAutoDiffExpression(Float64Field, block)
} }
val x by symbol val x by symbol
@ -42,7 +42,7 @@ internal class SimpleAutoDiffTest {
@Test @Test
fun testPlusX2() { fun testPlusX2() {
val y = DoubleField.simpleAutoDiff(x to 3.0) { val y = Float64Field.simpleAutoDiff(x to 3.0) {
// diff w.r.t this x at 3 // diff w.r.t this x at 3
val x = bindSymbol(x) val x = bindSymbol(x)
x + x x + x
@ -65,7 +65,7 @@ internal class SimpleAutoDiffTest {
@Test @Test
fun testPlus() { fun testPlus() {
// two variables // two variables
val z = DoubleField.simpleAutoDiff(x to 2.0, y to 3.0) { val z = Float64Field.simpleAutoDiff(x to 2.0, y to 3.0) {
val x = bindSymbol(x) val x = bindSymbol(x)
val y = bindSymbol(y) val y = bindSymbol(y)
x + y x + y
@ -78,7 +78,7 @@ internal class SimpleAutoDiffTest {
@Test @Test
fun testMinus() { fun testMinus() {
// two variables // two variables
val z = DoubleField.simpleAutoDiff(x to 7.0, y to 3.0) { val z = Float64Field.simpleAutoDiff(x to 7.0, y to 3.0) {
val x = bindSymbol(x) val x = bindSymbol(x)
val y = bindSymbol(y) val y = bindSymbol(y)

View File

@ -5,14 +5,14 @@
package space.kscience.kmath.nd package space.kscience.kmath.nd
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
class NdOperationsTest { class NdOperationsTest {
@Test @Test
fun roll() { fun roll() {
val structure = DoubleField.ndAlgebra.structureND(5, 5) { index -> val structure = Float64Field.ndAlgebra.structureND(5, 5) { index ->
index.sumOf { it.toDouble() } index.sumOf { it.toDouble() }
} }

View File

@ -11,16 +11,16 @@ import kotlin.test.assertEquals
internal class DoubleFieldTest { internal class DoubleFieldTest {
@Test @Test
fun verify() = FieldVerifier(DoubleField, 42.0, 66.0, 2.0, 5).verify() fun verify() = FieldVerifier(Float64Field, 42.0, 66.0, 2.0, 5).verify()
@Test @Test
fun testSqrt() { fun testSqrt() {
val sqrt = DoubleField { sqrt(25 * one) } val sqrt = Float64Field { sqrt(25 * one) }
assertEquals(5.0, sqrt) assertEquals(5.0, sqrt)
} }
@Test @Test
fun testPow() = DoubleField { fun testPow() = Float64Field {
val num = 5 * one val num = 5 * one
assertEquals(5.0, power(num, 1), 0.01) assertEquals(5.0, power(num, 1), 0.01)
assertEquals(25.0, power(num, 2), 0.01) assertEquals(25.0, power(num, 2), 0.01)

View File

@ -8,7 +8,7 @@ package space.kscience.kmath.structures
import space.kscience.kmath.nd.get import space.kscience.kmath.nd.get
import space.kscience.kmath.nd.ndAlgebra import space.kscience.kmath.nd.ndAlgebra
import space.kscience.kmath.nd.structureND import space.kscience.kmath.nd.structureND
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import space.kscience.kmath.testutils.FieldVerifier import space.kscience.kmath.testutils.FieldVerifier
import kotlin.test.Test import kotlin.test.Test
@ -17,12 +17,12 @@ import kotlin.test.assertEquals
internal class NDFieldTest { internal class NDFieldTest {
@Test @Test
fun verify() { fun verify() {
(DoubleField.ndAlgebra(12, 32)) { FieldVerifier(this, one + 3, one - 23, one * 12, 6.66) } (Float64Field.ndAlgebra(12, 32)) { FieldVerifier(this, one + 3, one - 23, one * 12, 6.66) }
} }
@Test @Test
fun testStrides() { fun testStrides() {
val ndArray = DoubleField.ndAlgebra.structureND(10, 10) { (it[0] + it[1]).toDouble() } val ndArray = Float64Field.ndAlgebra.structureND(10, 10) { (it[0] + it[1]).toDouble() }
assertEquals(ndArray[5, 5], 10.0) assertEquals(ndArray[5, 5], 10.0)
} }
} }

View File

@ -11,7 +11,7 @@ import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.get import space.kscience.kmath.nd.get
import space.kscience.kmath.nd.ndAlgebra import space.kscience.kmath.nd.ndAlgebra
import space.kscience.kmath.nd.structureND import space.kscience.kmath.nd.structureND
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.Norm import space.kscience.kmath.operations.Norm
import space.kscience.kmath.operations.algebra import space.kscience.kmath.operations.algebra
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
@ -25,7 +25,7 @@ import kotlin.test.assertEquals
@OptIn(PerformancePitfall::class) @OptIn(PerformancePitfall::class)
@Suppress("UNUSED_VARIABLE") @Suppress("UNUSED_VARIABLE")
class NumberNDFieldTest { class NumberNDFieldTest {
val algebra = DoubleField.ndAlgebra val algebra = Float64Field.ndAlgebra
val array1 = algebra.structureND(3, 3) { (i, j) -> (i + j).toDouble() } val array1 = algebra.structureND(3, 3) { (i, j) -> (i + j).toDouble() }
val array2 = algebra.structureND(3, 3) { (i, j) -> (i - j).toDouble() } val array2 = algebra.structureND(3, 3) { (i, j) -> (i - j).toDouble() }
@ -94,7 +94,7 @@ class NumberNDFieldTest {
@Test @Test
fun testInternalContext() { fun testInternalContext() {
algebra { algebra {
(DoubleField.ndAlgebra(array1.shape)) { with(L2Norm) { 1 + norm(array1) + exp(array2) } } (Float64Field.ndAlgebra(array1.shape)) { with(L2Norm) { 1 + norm(array1) + exp(array2) } }
} }
} }
} }

View File

@ -8,7 +8,7 @@ package space.kscience.kmath.dimensions
import space.kscience.kmath.linear.* import space.kscience.kmath.linear.*
import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.ShapeND
import space.kscience.kmath.nd.Structure2D import space.kscience.kmath.nd.Structure2D
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.Ring import space.kscience.kmath.operations.Ring
import space.kscience.kmath.operations.algebra import space.kscience.kmath.operations.algebra
import kotlin.jvm.JvmInline import kotlin.jvm.JvmInline
@ -150,7 +150,7 @@ public value class DMatrixContext<T : Any, out A : Ring<T>>(public val context:
context.run { (this@transpose as Matrix<T>).transpose() }.coerce() context.run { (this@transpose as Matrix<T>).transpose() }.coerce()
public companion object { public companion object {
public val real: DMatrixContext<Double, DoubleField> = DMatrixContext(Double.algebra.linearSpace) public val real: DMatrixContext<Double, Float64Field> = DMatrixContext(Double.algebra.linearSpace)
} }
} }
@ -158,12 +158,12 @@ public value class DMatrixContext<T : Any, out A : Ring<T>>(public val context:
/** /**
* A square unit matrix * A square unit matrix
*/ */
public inline fun <reified D : Dimension> DMatrixContext<Double, DoubleField>.one(): DMatrix<Double, D, D> = public inline fun <reified D : Dimension> DMatrixContext<Double, Float64Field>.one(): DMatrix<Double, D, D> =
produce { i, j -> produce { i, j ->
if (i == j) 1.0 else 0.0 if (i == j) 1.0 else 0.0
} }
public inline fun <reified R : Dimension, reified C : Dimension> DMatrixContext<Double, DoubleField>.zero(): DMatrix<Double, R, C> = public inline fun <reified R : Dimension, reified C : Dimension> DMatrixContext<Double, Float64Field>.zero(): DMatrix<Double, R, C> =
produce { _, _ -> produce { _, _ ->
0.0 0.0
} }

View File

@ -19,12 +19,12 @@ import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC
import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC
import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC
import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC
import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.linear.* import space.kscience.kmath.linear.*
import space.kscience.kmath.linear.Matrix import space.kscience.kmath.linear.Matrix
import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.nd.StructureFeature import space.kscience.kmath.nd.StructureFeature
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float32Field
import space.kscience.kmath.operations.FloatField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.DoubleBuffer
import space.kscience.kmath.structures.FloatBuffer import space.kscience.kmath.structures.FloatBuffer
@ -71,11 +71,11 @@ public class EjmlFloatMatrix<out M : FMatrix>(override val origin: M) : EjmlMatr
* [EjmlLinearSpace] implementation based on [CommonOps_DDRM], [DecompositionFactory_DDRM] operations and * [EjmlLinearSpace] implementation based on [CommonOps_DDRM], [DecompositionFactory_DDRM] operations and
* [DMatrixRMaj] matrices. * [DMatrixRMaj] matrices.
*/ */
public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, DoubleField, DMatrixRMaj>() { public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatrixRMaj>() {
/** /**
* The [DoubleField] reference. * The [Float64Field] reference.
*/ */
override val elementAlgebra: DoubleField get() = DoubleField override val elementAlgebra: Float64Field get() = Float64Field
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixRMaj> = when { override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixRMaj> = when {
@ -94,7 +94,7 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, DoubleField, DMatrix
override fun buildMatrix( override fun buildMatrix(
rows: Int, rows: Int,
columns: Int, columns: Int,
initializer: DoubleField.(i: Int, j: Int) -> Double, initializer: Float64Field.(i: Int, j: Int) -> Double,
): EjmlDoubleMatrix<DMatrixRMaj> = DMatrixRMaj(rows, columns).also { ): EjmlDoubleMatrix<DMatrixRMaj> = DMatrixRMaj(rows, columns).also {
(0 until rows).forEach { row -> (0 until rows).forEach { row ->
(0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) } (0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) }
@ -103,7 +103,7 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, DoubleField, DMatrix
override fun buildVector( override fun buildVector(
size: Int, size: Int,
initializer: DoubleField.(Int) -> Double, initializer: Float64Field.(Int) -> Double,
): EjmlDoubleVector<DMatrixRMaj> = EjmlDoubleVector(DMatrixRMaj(size, 1).also { ): EjmlDoubleVector<DMatrixRMaj> = EjmlDoubleVector(DMatrixRMaj(size, 1).also {
(0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) } (0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) }
}) })
@ -307,11 +307,11 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, DoubleField, DMatrix
* [EjmlLinearSpace] implementation based on [CommonOps_FDRM], [DecompositionFactory_FDRM] operations and * [EjmlLinearSpace] implementation based on [CommonOps_FDRM], [DecompositionFactory_FDRM] operations and
* [FMatrixRMaj] matrices. * [FMatrixRMaj] matrices.
*/ */
public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, FloatField, FMatrixRMaj>() { public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, Float32Field, FMatrixRMaj>() {
/** /**
* The [FloatField] reference. * The [Float32Field] reference.
*/ */
override val elementAlgebra: FloatField get() = FloatField override val elementAlgebra: Float32Field get() = Float32Field
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
override fun Matrix<Float>.toEjml(): EjmlFloatMatrix<FMatrixRMaj> = when { override fun Matrix<Float>.toEjml(): EjmlFloatMatrix<FMatrixRMaj> = when {
@ -330,7 +330,7 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, FloatField, FMatrixRM
override fun buildMatrix( override fun buildMatrix(
rows: Int, rows: Int,
columns: Int, columns: Int,
initializer: FloatField.(i: Int, j: Int) -> Float, initializer: Float32Field.(i: Int, j: Int) -> Float,
): EjmlFloatMatrix<FMatrixRMaj> = FMatrixRMaj(rows, columns).also { ): EjmlFloatMatrix<FMatrixRMaj> = FMatrixRMaj(rows, columns).also {
(0 until rows).forEach { row -> (0 until rows).forEach { row ->
(0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) } (0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) }
@ -339,7 +339,7 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, FloatField, FMatrixRM
override fun buildVector( override fun buildVector(
size: Int, size: Int,
initializer: FloatField.(Int) -> Float, initializer: Float32Field.(Int) -> Float,
): EjmlFloatVector<FMatrixRMaj> = EjmlFloatVector(FMatrixRMaj(size, 1).also { ): EjmlFloatVector<FMatrixRMaj> = EjmlFloatVector(FMatrixRMaj(size, 1).also {
(0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) } (0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) }
}) })
@ -543,11 +543,11 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, FloatField, FMatrixRM
* [EjmlLinearSpace] implementation based on [CommonOps_DSCC], [DecompositionFactory_DSCC] operations and * [EjmlLinearSpace] implementation based on [CommonOps_DSCC], [DecompositionFactory_DSCC] operations and
* [DMatrixSparseCSC] matrices. * [DMatrixSparseCSC] matrices.
*/ */
public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, DoubleField, DMatrixSparseCSC>() { public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatrixSparseCSC>() {
/** /**
* The [DoubleField] reference. * The [Float64Field] reference.
*/ */
override val elementAlgebra: DoubleField get() = DoubleField override val elementAlgebra: Float64Field get() = Float64Field
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixSparseCSC> = when { override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixSparseCSC> = when {
@ -566,7 +566,7 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, DoubleField, DMatrix
override fun buildMatrix( override fun buildMatrix(
rows: Int, rows: Int,
columns: Int, columns: Int,
initializer: DoubleField.(i: Int, j: Int) -> Double, initializer: Float64Field.(i: Int, j: Int) -> Double,
): EjmlDoubleMatrix<DMatrixSparseCSC> = DMatrixSparseCSC(rows, columns).also { ): EjmlDoubleMatrix<DMatrixSparseCSC> = DMatrixSparseCSC(rows, columns).also {
(0 until rows).forEach { row -> (0 until rows).forEach { row ->
(0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) } (0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) }
@ -575,7 +575,7 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, DoubleField, DMatrix
override fun buildVector( override fun buildVector(
size: Int, size: Int,
initializer: DoubleField.(Int) -> Double, initializer: Float64Field.(Int) -> Double,
): EjmlDoubleVector<DMatrixSparseCSC> = EjmlDoubleVector(DMatrixSparseCSC(size, 1).also { ): EjmlDoubleVector<DMatrixSparseCSC> = EjmlDoubleVector(DMatrixSparseCSC(size, 1).also {
(0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) } (0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) }
}) })
@ -774,11 +774,11 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, DoubleField, DMatrix
* [EjmlLinearSpace] implementation based on [CommonOps_FSCC], [DecompositionFactory_FSCC] operations and * [EjmlLinearSpace] implementation based on [CommonOps_FSCC], [DecompositionFactory_FSCC] operations and
* [FMatrixSparseCSC] matrices. * [FMatrixSparseCSC] matrices.
*/ */
public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, FloatField, FMatrixSparseCSC>() { public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, Float32Field, FMatrixSparseCSC>() {
/** /**
* The [FloatField] reference. * The [Float32Field] reference.
*/ */
override val elementAlgebra: FloatField get() = FloatField override val elementAlgebra: Float32Field get() = Float32Field
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
override fun Matrix<Float>.toEjml(): EjmlFloatMatrix<FMatrixSparseCSC> = when { override fun Matrix<Float>.toEjml(): EjmlFloatMatrix<FMatrixSparseCSC> = when {
@ -797,7 +797,7 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, FloatField, FMatrixSp
override fun buildMatrix( override fun buildMatrix(
rows: Int, rows: Int,
columns: Int, columns: Int,
initializer: FloatField.(i: Int, j: Int) -> Float, initializer: Float32Field.(i: Int, j: Int) -> Float,
): EjmlFloatMatrix<FMatrixSparseCSC> = FMatrixSparseCSC(rows, columns).also { ): EjmlFloatMatrix<FMatrixSparseCSC> = FMatrixSparseCSC(rows, columns).also {
(0 until rows).forEach { row -> (0 until rows).forEach { row ->
(0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) } (0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) }
@ -806,7 +806,7 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, FloatField, FMatrixSp
override fun buildVector( override fun buildVector(
size: Int, size: Int,
initializer: FloatField.(Int) -> Float, initializer: Float32Field.(Int) -> Float,
): EjmlFloatVector<FMatrixSparseCSC> = EjmlFloatVector(FMatrixSparseCSC(size, 1).also { ): EjmlFloatVector<FMatrixSparseCSC> = EjmlFloatVector(FMatrixSparseCSC(size, 1).also {
(0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) } (0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) }
}) })

View File

@ -11,7 +11,7 @@ package space.kscience.kmath.real
import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.PerformancePitfall
import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.linear.* import space.kscience.kmath.linear.*
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.algebra import space.kscience.kmath.operations.algebra
import space.kscience.kmath.operations.asIterable import space.kscience.kmath.operations.asIterable
import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.Buffer
@ -32,11 +32,11 @@ import kotlin.math.pow
public typealias RealMatrix = Matrix<Double> public typealias RealMatrix = Matrix<Double>
public fun realMatrix(rowNum: Int, colNum: Int, initializer: DoubleField.(i: Int, j: Int) -> Double): RealMatrix = public fun realMatrix(rowNum: Int, colNum: Int, initializer: Float64Field.(i: Int, j: Int) -> Double): RealMatrix =
Double.algebra.linearSpace.buildMatrix(rowNum, colNum, initializer) Double.algebra.linearSpace.buildMatrix(rowNum, colNum, initializer)
@OptIn(UnstableKMathAPI::class) @OptIn(UnstableKMathAPI::class)
public fun realMatrix(rowNum: Int, colNum: Int): MatrixBuilder<Double, DoubleField> = public fun realMatrix(rowNum: Int, colNum: Int): MatrixBuilder<Double, Float64Field> =
Double.algebra.linearSpace.matrix(rowNum, colNum) Double.algebra.linearSpace.matrix(rowNum, colNum)
public fun Array<DoubleArray>.toMatrix(): RealMatrix { public fun Array<DoubleArray>.toMatrix(): RealMatrix {

View File

@ -6,14 +6,14 @@
package space.kscience.kmath.real package space.kscience.kmath.real
import space.kscience.kmath.nd.BufferND import space.kscience.kmath.nd.BufferND
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.DoubleBuffer
/** /**
* Map one [BufferND] using function without indices. * Map one [BufferND] using function without indices.
*/ */
public inline fun BufferND<Double>.mapInline(crossinline transform: DoubleField.(Double) -> Double): BufferND<Double> { public inline fun BufferND<Double>.mapInline(crossinline transform: Float64Field.(Double) -> Double): BufferND<Double> {
val array = DoubleArray(indices.linearSize) { offset -> DoubleField.transform(buffer[offset]) } val array = DoubleArray(indices.linearSize) { offset -> Float64Field.transform(buffer[offset]) }
return BufferND(indices, DoubleBuffer(array)) return BufferND(indices, DoubleBuffer(array))
} }

View File

@ -6,8 +6,8 @@
package space.kscience.kmath.integration package space.kscience.kmath.integration
import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Field import space.kscience.kmath.operations.Field
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import space.kscience.kmath.operations.sum import space.kscience.kmath.operations.sum
@ -105,4 +105,4 @@ public object DoubleSimpsonIntegrator : UnivariateIntegrator<Double> {
} }
} }
public val DoubleField.simpsonIntegrator: DoubleSimpsonIntegrator get() = DoubleSimpsonIntegrator public val Float64Field.simpsonIntegrator: DoubleSimpsonIntegrator get() = DoubleSimpsonIntegrator

View File

@ -85,7 +85,7 @@ public class SplineIntegrator<T : Comparable<T>>(
public object DoubleSplineIntegrator : UnivariateIntegrator<Double> { public object DoubleSplineIntegrator : UnivariateIntegrator<Double> {
override fun process(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> { override fun process(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> {
val range = integrand.getFeature<IntegrationRange>()?.range ?: 0.0..1.0 val range = integrand.getFeature<IntegrationRange>()?.range ?: 0.0..1.0
val interpolator: PolynomialInterpolator<Double> = SplineInterpolator(DoubleField, ::DoubleBuffer) val interpolator: PolynomialInterpolator<Double> = SplineInterpolator(Float64Field, ::DoubleBuffer)
val nodes: Buffer<Double> = integrand.getFeature<UnivariateIntegrationNodes>()?.nodes ?: run { val nodes: Buffer<Double> = integrand.getFeature<UnivariateIntegrationNodes>()?.nodes ?: run {
val numPoints = integrand.getFeature<IntegrandMaxCalls>()?.maxCalls ?: 100 val numPoints = integrand.getFeature<IntegrandMaxCalls>()?.maxCalls ?: 100
@ -95,12 +95,12 @@ public object DoubleSplineIntegrator : UnivariateIntegrator<Double> {
val values = nodes.mapToBuffer(::DoubleBuffer) { integrand.function(it) } val values = nodes.mapToBuffer(::DoubleBuffer) { integrand.function(it) }
val polynomials = interpolator.interpolatePolynomials(nodes, values) val polynomials = interpolator.interpolatePolynomials(nodes, values)
val res = polynomials.integrate(DoubleField, range) val res = polynomials.integrate(Float64Field, range)
return integrand + IntegrandValue(res) + IntegrandCallsPerformed(integrand.calls + nodes.size) return integrand + IntegrandValue(res) + IntegrandCallsPerformed(integrand.calls + nodes.size)
} }
} }
@Suppress("unused") @Suppress("unused")
@UnstableKMathAPI @UnstableKMathAPI
public inline val DoubleField.splineIntegrator: UnivariateIntegrator<Double> public inline val Float64Field.splineIntegrator: UnivariateIntegrator<Double>
get() = DoubleSplineIntegrator get() = DoubleSplineIntegrator

View File

@ -9,8 +9,8 @@ import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.data.XYColumnarData import space.kscience.kmath.data.XYColumnarData
import space.kscience.kmath.functions.PiecewisePolynomial import space.kscience.kmath.functions.PiecewisePolynomial
import space.kscience.kmath.functions.Polynomial import space.kscience.kmath.functions.Polynomial
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Field import space.kscience.kmath.operations.Field
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.DoubleBuffer
import space.kscience.kmath.structures.MutableBufferFactory import space.kscience.kmath.structures.MutableBufferFactory
@ -79,5 +79,5 @@ public fun <T : Comparable<T>> Field<T>.splineInterpolator(
bufferFactory: MutableBufferFactory<T>, bufferFactory: MutableBufferFactory<T>,
): SplineInterpolator<T> = SplineInterpolator(this, bufferFactory) ): SplineInterpolator<T> = SplineInterpolator(this, bufferFactory)
public val DoubleField.splineInterpolator: SplineInterpolator<Double> public val Float64Field.splineInterpolator: SplineInterpolator<Double>
get() = SplineInterpolator(this, ::DoubleBuffer) get() = SplineInterpolator(this, ::DoubleBuffer)

View File

@ -6,7 +6,7 @@
package space.kscience.kmath.integration package space.kscience.kmath.integration
import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import kotlin.math.PI import kotlin.math.PI
import kotlin.math.sin import kotlin.math.sin
import kotlin.test.Test import kotlin.test.Test
@ -16,7 +16,7 @@ import kotlin.test.assertEquals
class GaussIntegralTest { class GaussIntegralTest {
@Test @Test
fun gaussSin() { fun gaussSin() {
val res = DoubleField.gaussIntegrator.integrate(0.0..2 * PI) { x -> val res = Float64Field.gaussIntegrator.integrate(0.0..2 * PI) { x ->
sin(x) sin(x)
} }
assertEquals(0.0, res.value, 1e-2) assertEquals(0.0, res.value, 1e-2)
@ -24,7 +24,7 @@ class GaussIntegralTest {
@Test @Test
fun gaussUniform() { fun gaussUniform() {
val res = DoubleField.gaussIntegrator.integrate(35.0..100.0) { x -> val res = Float64Field.gaussIntegrator.integrate(35.0..100.0) { x ->
if(x in 30.0..50.0){ if(x in 30.0..50.0){
1.0 1.0
} else { } else {

View File

@ -6,7 +6,7 @@
package space.kscience.kmath.integration package space.kscience.kmath.integration
import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import kotlin.math.PI import kotlin.math.PI
import kotlin.math.sin import kotlin.math.sin
import kotlin.test.Test import kotlin.test.Test
@ -16,7 +16,7 @@ import kotlin.test.assertEquals
class SimpsonIntegralTest { class SimpsonIntegralTest {
@Test @Test
fun gaussSin() { fun gaussSin() {
val res = DoubleField.simpsonIntegrator.integrate(0.0..2 * PI, IntegrandMaxCalls(5)) { x -> val res = Float64Field.simpsonIntegrator.integrate(0.0..2 * PI, IntegrandMaxCalls(5)) { x ->
sin(x) sin(x)
} }
assertEquals(0.0, res.value, 1e-2) assertEquals(0.0, res.value, 1e-2)
@ -24,7 +24,7 @@ class SimpsonIntegralTest {
@Test @Test
fun gaussUniform() { fun gaussUniform() {
val res = DoubleField.simpsonIntegrator.integrate(35.0..100.0, IntegrandMaxCalls(20)) { x -> val res = Float64Field.simpsonIntegrator.integrate(35.0..100.0, IntegrandMaxCalls(20)) { x ->
if (x in 30.0..50.0) { if (x in 30.0..50.0) {
1.0 1.0
} else { } else {

View File

@ -8,7 +8,7 @@ package space.kscience.kmath.integration
import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.functions.Polynomial import space.kscience.kmath.functions.Polynomial
import space.kscience.kmath.functions.integrate import space.kscience.kmath.functions.integrate
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import kotlin.math.PI import kotlin.math.PI
import kotlin.math.sin import kotlin.math.sin
import kotlin.test.Test import kotlin.test.Test
@ -20,13 +20,13 @@ class SplineIntegralTest {
@Test @Test
fun integratePolynomial(){ fun integratePolynomial(){
val polynomial = Polynomial(1.0, 2.0, 3.0) val polynomial = Polynomial(1.0, 2.0, 3.0)
val integral = polynomial.integrate(DoubleField,1.0..2.0) val integral = polynomial.integrate(Float64Field,1.0..2.0)
assertEquals(11.0, integral, 0.001) assertEquals(11.0, integral, 0.001)
} }
@Test @Test
fun gaussSin() { fun gaussSin() {
val res = DoubleField.splineIntegrator.integrate(0.0..2 * PI, IntegrandMaxCalls(5)) { x -> val res = Float64Field.splineIntegrator.integrate(0.0..2 * PI, IntegrandMaxCalls(5)) { x ->
sin(x) sin(x)
} }
assertEquals(0.0, res.value, 1e-2) assertEquals(0.0, res.value, 1e-2)
@ -34,7 +34,7 @@ class SplineIntegralTest {
@Test @Test
fun gaussUniform() { fun gaussUniform() {
val res = DoubleField.splineIntegrator.integrate(35.0..100.0, IntegrandMaxCalls(20)) { x -> val res = Float64Field.splineIntegrator.integrate(35.0..100.0, IntegrandMaxCalls(20)) { x ->
if(x in 30.0..50.0){ if(x in 30.0..50.0){
1.0 1.0
} else { } else {

View File

@ -5,7 +5,7 @@
package space.kscience.kmath.interpolation package space.kscience.kmath.interpolation
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -20,7 +20,7 @@ internal class LinearInterpolatorTest {
) )
//val polynomial: PiecewisePolynomial<Double> = DoubleField.linearInterpolator.interpolatePolynomials(data) //val polynomial: PiecewisePolynomial<Double> = DoubleField.linearInterpolator.interpolatePolynomials(data)
val function = DoubleField.linearInterpolator.interpolate(data) val function = Float64Field.linearInterpolator.interpolate(data)
assertEquals(null, function(-1.0)) assertEquals(null, function(-1.0))
assertEquals(0.5, function(0.5)) assertEquals(0.5, function(0.5))
assertEquals(2.0, function(1.5)) assertEquals(2.0, function(1.5))

View File

@ -5,7 +5,7 @@
package space.kscience.kmath.interpolation package space.kscience.kmath.interpolation
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import kotlin.math.PI import kotlin.math.PI
import kotlin.math.sin import kotlin.math.sin
import kotlin.test.Test import kotlin.test.Test
@ -21,7 +21,7 @@ internal class SplineInterpolatorTest {
//val polynomial: PiecewisePolynomial<Double> = DoubleField.splineInterpolator.interpolatePolynomials(data) //val polynomial: PiecewisePolynomial<Double> = DoubleField.splineInterpolator.interpolatePolynomials(data)
val function = DoubleField.splineInterpolator.interpolate(data, Double.NaN) val function = Float64Field.splineInterpolator.interpolate(data, Double.NaN)
assertEquals(Double.NaN, function(-1.0)) assertEquals(Double.NaN, function(-1.0))
assertEquals(sin(0.5), function(0.5), 0.1) assertEquals(sin(0.5), function(0.5), 0.1)

View File

@ -14,7 +14,7 @@ import space.kscience.kmath.linear.LinearSpace
import space.kscience.kmath.linear.Matrix import space.kscience.kmath.linear.Matrix
import space.kscience.kmath.linear.linearSpace import space.kscience.kmath.linear.linearSpace
import space.kscience.kmath.linear.matrix import space.kscience.kmath.linear.matrix
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import kotlin.math.pow import kotlin.math.pow
import kotlin.math.sqrt import kotlin.math.sqrt
@ -66,7 +66,7 @@ public fun Euclidean3DSpace.rotate(vector: DoubleVector3D, composition: Quaterni
public fun Euclidean3DSpace.rotate(vector: DoubleVector3D, matrix: Matrix<Double>): DoubleVector3D { public fun Euclidean3DSpace.rotate(vector: DoubleVector3D, matrix: Matrix<Double>): DoubleVector3D {
require(matrix.colNum == 3 && matrix.rowNum == 3) { "Square 3x3 rotation matrix is required" } require(matrix.colNum == 3 && matrix.rowNum == 3) { "Square 3x3 rotation matrix is required" }
return with(DoubleField.linearSpace) { matrix.dot(vector).asVector3D() } return with(Float64Field.linearSpace) { matrix.dot(vector).asVector3D() }
} }
/** /**
@ -74,7 +74,7 @@ public fun Euclidean3DSpace.rotate(vector: DoubleVector3D, matrix: Matrix<Double
*/ */
@OptIn(UnstableKMathAPI::class) @OptIn(UnstableKMathAPI::class)
public fun Quaternion.toRotationMatrix( public fun Quaternion.toRotationMatrix(
linearSpace: LinearSpace<Double, *> = DoubleField.linearSpace, linearSpace: LinearSpace<Double, *> = Float64Field.linearSpace,
): Matrix<Double> { ): Matrix<Double> {
val s = QuaternionField.norm(this).pow(-2) val s = QuaternionField.norm(this).pow(-2)
return linearSpace.matrix(3, 3)( return linearSpace.matrix(3, 3)(

View File

@ -7,7 +7,7 @@ package space.kscience.kmath.histogram
import kotlinx.atomicfu.atomic import kotlinx.atomicfu.atomic
import kotlinx.atomicfu.getAndUpdate import kotlinx.atomicfu.getAndUpdate
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.Group import space.kscience.kmath.operations.Group
/** /**
@ -18,7 +18,7 @@ public interface Counter<T : Any> {
public val value: T public val value: T
public companion object { public companion object {
public fun ofDouble(): ObjectCounter<Double> = ObjectCounter(DoubleField) public fun ofDouble(): ObjectCounter<Double> = ObjectCounter(Float64Field)
public fun <T: Any> of(group: Group<T>): ObjectCounter<T> = ObjectCounter(group) public fun <T: Any> of(group: Group<T>): ObjectCounter<T> = ObjectCounter(group)
} }
} }

View File

@ -128,7 +128,7 @@ public fun <V : Any, A : Field<V>> Histogram.Companion.uniformNDFromRanges(
public fun Histogram.Companion.uniformDoubleNDFromRanges( public fun Histogram.Companion.uniformDoubleNDFromRanges(
vararg ranges: ClosedFloatingPointRange<Double>, vararg ranges: ClosedFloatingPointRange<Double>,
): UniformHistogramGroupND<Double, DoubleField> = ): UniformHistogramGroupND<Double, Float64Field> =
uniformNDFromRanges(DoubleFieldOpsND, *ranges, bufferFactory = ::DoubleBuffer) uniformNDFromRanges(DoubleFieldOpsND, *ranges, bufferFactory = ::DoubleBuffer)
@ -163,5 +163,5 @@ public fun <V : Any, A : Field<V>> Histogram.Companion.uniformNDFromRanges(
public fun Histogram.Companion.uniformDoubleNDFromRanges( public fun Histogram.Companion.uniformDoubleNDFromRanges(
vararg ranges: Pair<ClosedFloatingPointRange<Double>, Int>, vararg ranges: Pair<ClosedFloatingPointRange<Double>, Int>,
): UniformHistogramGroupND<Double, DoubleField> = ): UniformHistogramGroupND<Double, Float64Field> =
uniformNDFromRanges(DoubleFieldOpsND, *ranges, bufferFactory = ::DoubleBuffer) uniformNDFromRanges(DoubleFieldOpsND, *ranges, bufferFactory = ::DoubleBuffer)

View File

@ -9,7 +9,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.distributions.NormalDistribution import space.kscience.kmath.distributions.NormalDistribution
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.random.RandomGenerator import space.kscience.kmath.random.RandomGenerator
import space.kscience.kmath.stat.nextBuffer import space.kscience.kmath.stat.nextBuffer
import kotlin.native.concurrent.ThreadLocal import kotlin.native.concurrent.ThreadLocal
@ -22,7 +22,7 @@ internal class UniformHistogram1DTest {
@Test @Test
fun normal() = runTest { fun normal() = runTest {
val distribution = NormalDistribution(0.0, 1.0) val distribution = NormalDistribution(0.0, 1.0)
with(Histogram.uniform1D(DoubleField, 0.1)) { with(Histogram.uniform1D(Float64Field, 0.1)) {
val h1 = produce(distribution.nextBuffer(generator, 10000)) val h1 = produce(distribution.nextBuffer(generator, 10000))
val h2 = produce(distribution.nextBuffer(generator, 50000)) val h2 = produce(distribution.nextBuffer(generator, 50000))
@ -35,16 +35,16 @@ internal class UniformHistogram1DTest {
@Test @Test
fun rebinDown() = runTest { fun rebinDown() = runTest {
val h1 = Histogram.uniform1D(DoubleField, 0.01).produce(generator.nextDoubleBuffer(10000)) val h1 = Histogram.uniform1D(Float64Field, 0.01).produce(generator.nextDoubleBuffer(10000))
val h2 = Histogram.uniform1D(DoubleField, 0.03).produceFrom(h1) val h2 = Histogram.uniform1D(Float64Field, 0.03).produceFrom(h1)
assertEquals(10000, h2.bins.sumOf { it.binValue }.toInt()) assertEquals(10000, h2.bins.sumOf { it.binValue }.toInt())
} }
@Test @Test
fun rebinUp() = runTest { fun rebinUp() = runTest {
val h1 = Histogram.uniform1D(DoubleField, 0.03).produce(generator.nextDoubleBuffer(10000)) val h1 = Histogram.uniform1D(Float64Field, 0.03).produce(generator.nextDoubleBuffer(10000))
val h2 = Histogram.uniform1D(DoubleField, 0.01).produceFrom(h1) val h2 = Histogram.uniform1D(Float64Field, 0.01).produceFrom(h1)
assertEquals(10000, h2.bins.sumOf { it.binValue }.toInt()) assertEquals(10000, h2.bins.sumOf { it.binValue }.toInt())
} }

View File

@ -7,7 +7,7 @@ package space.kscience.kmath.histogram
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.real.step import space.kscience.kmath.real.step
import kotlin.random.Random import kotlin.random.Random
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -19,7 +19,7 @@ class TreeHistogramTest {
@Test @Test
fun normalFill() { fun normalFill() {
val random = Random(123) val random = Random(123)
val histogram = Histogram.custom1D(DoubleField, 0.0..1.0 step 0.1).produce { val histogram = Histogram.custom1D(Float64Field, 0.0..1.0 step 0.1).produce {
repeat(100_000) { repeat(100_000) {
putValue(random.nextDouble()) putValue(random.nextDouble())
} }

View File

@ -12,7 +12,7 @@ import space.kscience.kmath.ast.parseMath
import space.kscience.kmath.expressions.MstNumericAlgebra import space.kscience.kmath.expressions.MstNumericAlgebra
import space.kscience.kmath.expressions.Symbol.Companion.x import space.kscience.kmath.expressions.Symbol.Companion.x
import space.kscience.kmath.expressions.invoke import space.kscience.kmath.expressions.invoke
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
@ -22,8 +22,8 @@ import kotlin.test.fail
internal class AdaptingTests { internal class AdaptingTests {
@Test @Test
fun symbol() { fun symbol() {
assertEquals(x.identity, x.toSVar<KMathNumber<Double, DoubleField>>().name) assertEquals(x.identity, x.toSVar<KMathNumber<Double, Float64Field>>().name)
val c2 = "kitten".parseMath().toSFun<KMathNumber<Double, DoubleField>>() val c2 = "kitten".parseMath().toSFun<KMathNumber<Double, Float64Field>>()
if (c2 is SVar<*>) assertTrue(c2.name == "kitten") else fail() if (c2 is SVar<*>) assertTrue(c2.name == "kitten") else fail()
} }
@ -31,15 +31,15 @@ internal class AdaptingTests {
fun number() { fun number() {
val c1 = MstNumericAlgebra.number(12354324) val c1 = MstNumericAlgebra.number(12354324)
assertTrue(c1.toSConst<DReal>().doubleValue == 12354324.0) assertTrue(c1.toSConst<DReal>().doubleValue == 12354324.0)
val c2 = "0.234".parseMath().toSFun<KMathNumber<Double, DoubleField>>() val c2 = "0.234".parseMath().toSFun<KMathNumber<Double, Float64Field>>()
if (c2 is SConst<*>) assertTrue(c2.doubleValue == 0.234) else fail() if (c2 is SConst<*>) assertTrue(c2.doubleValue == 0.234) else fail()
val c3 = "1e-3".parseMath().toSFun<KMathNumber<Double, DoubleField>>() val c3 = "1e-3".parseMath().toSFun<KMathNumber<Double, Float64Field>>()
if (c3 is SConst<*>) assertEquals(0.001, c3.value) else fail() if (c3 is SConst<*>) assertEquals(0.001, c3.value) else fail()
} }
@Test @Test
fun simpleFunctionShape() { fun simpleFunctionShape() {
val linear = "2*x+16".parseMath().toSFun<KMathNumber<Double, DoubleField>>() val linear = "2*x+16".parseMath().toSFun<KMathNumber<Double, Float64Field>>()
if (linear !is Sum<*>) fail() if (linear !is Sum<*>) fail()
if (linear.left !is Prod<*>) fail() if (linear.left !is Prod<*>) fail()
if (linear.right !is SConst<*>) fail() if (linear.right !is SConst<*>) fail()
@ -47,22 +47,22 @@ internal class AdaptingTests {
@Test @Test
fun simpleFunctionDerivative() { fun simpleFunctionDerivative() {
val xSVar = x.toSVar<KMathNumber<Double, DoubleField>>() val xSVar = x.toSVar<KMathNumber<Double, Float64Field>>()
val quadratic = "x^2-4*x-44".parseMath().toSFun<KMathNumber<Double, DoubleField>>() val quadratic = "x^2-4*x-44".parseMath().toSFun<KMathNumber<Double, Float64Field>>()
val actualDerivative = quadratic.d(xSVar).toMst().compileToExpression(DoubleField) val actualDerivative = quadratic.d(xSVar).toMst().compileToExpression(Float64Field)
val expectedDerivative = "2*x-4".parseMath().compileToExpression(DoubleField) val expectedDerivative = "2*x-4".parseMath().compileToExpression(Float64Field)
assertEquals(actualDerivative(x to 123.0), expectedDerivative(x to 123.0)) assertEquals(actualDerivative(x to 123.0), expectedDerivative(x to 123.0))
} }
@Test @Test
fun moreComplexDerivative() { fun moreComplexDerivative() {
val xSVar = x.toSVar<KMathNumber<Double, DoubleField>>() val xSVar = x.toSVar<KMathNumber<Double, Float64Field>>()
val composition = "-sqrt(sin(x^2)-cos(x)^2-16*x)".parseMath().toSFun<KMathNumber<Double, DoubleField>>() val composition = "-sqrt(sin(x^2)-cos(x)^2-16*x)".parseMath().toSFun<KMathNumber<Double, Float64Field>>()
val actualDerivative = composition.d(xSVar).toMst().compileToExpression(DoubleField) val actualDerivative = composition.d(xSVar).toMst().compileToExpression(Float64Field)
val expectedDerivative = "-(2*x*cos(x^2)+2*sin(x)*cos(x)-16)/(2*sqrt(sin(x^2)-16*x-cos(x)^2))" val expectedDerivative = "-(2*x*cos(x^2)+2*sin(x)*cos(x)-16)/(2*sqrt(sin(x^2)-16*x-cos(x)^2))"
.parseMath() .parseMath()
.compileToExpression(DoubleField) .compileToExpression(Float64Field)
assertEquals(actualDerivative(x to -0.1), expectedDerivative(x to -0.1)) assertEquals(actualDerivative(x to -0.1), expectedDerivative(x to -0.1))
} }

View File

@ -11,15 +11,15 @@ import org.jetbrains.kotlinx.multik.api.ndarrayOf
import org.jetbrains.kotlinx.multik.ndarray.data.DataType import org.jetbrains.kotlinx.multik.ndarray.data.DataType
import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.PerformancePitfall
import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.ExponentialOperations import space.kscience.kmath.operations.ExponentialOperations
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.TrigonometricOperations import space.kscience.kmath.operations.TrigonometricOperations
public class MultikDoubleAlgebra( public class MultikDoubleAlgebra(
multikEngine: Engine multikEngine: Engine
) : MultikDivisionTensorAlgebra<Double, DoubleField>(multikEngine), ) : MultikDivisionTensorAlgebra<Double, Float64Field>(multikEngine),
TrigonometricOperations<StructureND<Double>>, ExponentialOperations<StructureND<Double>> { TrigonometricOperations<StructureND<Double>>, ExponentialOperations<StructureND<Double>> {
override val elementAlgebra: DoubleField get() = DoubleField override val elementAlgebra: Float64Field get() = Float64Field
override val type: DataType get() = DataType.DoubleDataType 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()

View File

@ -9,12 +9,12 @@ import org.jetbrains.kotlinx.multik.api.Engine
import org.jetbrains.kotlinx.multik.api.Multik import org.jetbrains.kotlinx.multik.api.Multik
import org.jetbrains.kotlinx.multik.api.ndarrayOf import org.jetbrains.kotlinx.multik.api.ndarrayOf
import org.jetbrains.kotlinx.multik.ndarray.data.DataType import org.jetbrains.kotlinx.multik.ndarray.data.DataType
import space.kscience.kmath.operations.FloatField import space.kscience.kmath.operations.Float32Field
public class MultikFloatAlgebra( public class MultikFloatAlgebra(
multikEngine: Engine multikEngine: Engine
) : MultikDivisionTensorAlgebra<Float, FloatField>(multikEngine) { ) : MultikDivisionTensorAlgebra<Float, Float32Field>(multikEngine) {
override val elementAlgebra: FloatField get() = FloatField override val elementAlgebra: Float32Field get() = Float32Field
override val type: DataType get() = DataType.FloatDataType override val type: DataType get() = DataType.FloatDataType
override fun scalar(value: Float): MultikTensor<Float> = Multik.ndarrayOf(value).wrap() override fun scalar(value: Float): MultikTensor<Float> = Multik.ndarrayOf(value).wrap()

View File

@ -9,12 +9,12 @@ import org.jetbrains.kotlinx.multik.api.Engine
import org.jetbrains.kotlinx.multik.api.Multik import org.jetbrains.kotlinx.multik.api.Multik
import org.jetbrains.kotlinx.multik.api.ndarrayOf import org.jetbrains.kotlinx.multik.api.ndarrayOf
import org.jetbrains.kotlinx.multik.ndarray.data.DataType import org.jetbrains.kotlinx.multik.ndarray.data.DataType
import space.kscience.kmath.operations.IntRing import space.kscience.kmath.operations.Int32Ring
public class MultikIntAlgebra( public class MultikIntAlgebra(
multikEngine: Engine multikEngine: Engine
) : MultikTensorAlgebra<Int, IntRing>(multikEngine) { ) : MultikTensorAlgebra<Int, Int32Ring>(multikEngine) {
override val elementAlgebra: IntRing get() = IntRing override val elementAlgebra: Int32Ring get() = Int32Ring
override val type: DataType get() = DataType.IntDataType override val type: DataType get() = DataType.IntDataType
override fun scalar(value: Int): MultikTensor<Int> = Multik.ndarrayOf(value).wrap() override fun scalar(value: Int): MultikTensor<Int> = Multik.ndarrayOf(value).wrap()
} }

View File

@ -9,12 +9,12 @@ import org.jetbrains.kotlinx.multik.api.Engine
import org.jetbrains.kotlinx.multik.api.Multik import org.jetbrains.kotlinx.multik.api.Multik
import org.jetbrains.kotlinx.multik.api.ndarrayOf import org.jetbrains.kotlinx.multik.api.ndarrayOf
import org.jetbrains.kotlinx.multik.ndarray.data.DataType import org.jetbrains.kotlinx.multik.ndarray.data.DataType
import space.kscience.kmath.operations.LongRing import space.kscience.kmath.operations.Int64Ring
public class MultikLongAlgebra( public class MultikLongAlgebra(
multikEngine: Engine multikEngine: Engine
) : MultikTensorAlgebra<Long, LongRing>(multikEngine) { ) : MultikTensorAlgebra<Long, Int64Ring>(multikEngine) {
override val elementAlgebra: LongRing get() = LongRing override val elementAlgebra: Int64Ring get() = Int64Ring
override val type: DataType get() = DataType.LongDataType override val type: DataType get() = DataType.LongDataType
override fun scalar(value: Long): MultikTensor<Long> = Multik.ndarrayOf(value).wrap() override fun scalar(value: Long): MultikTensor<Long> = Multik.ndarrayOf(value).wrap()

View File

@ -9,12 +9,12 @@ import org.jetbrains.kotlinx.multik.api.Engine
import org.jetbrains.kotlinx.multik.api.Multik import org.jetbrains.kotlinx.multik.api.Multik
import org.jetbrains.kotlinx.multik.api.ndarrayOf import org.jetbrains.kotlinx.multik.api.ndarrayOf
import org.jetbrains.kotlinx.multik.ndarray.data.DataType import org.jetbrains.kotlinx.multik.ndarray.data.DataType
import space.kscience.kmath.operations.ShortRing import space.kscience.kmath.operations.Int16Ring
public class MultikShortAlgebra( public class MultikShortAlgebra(
multikEngine: Engine multikEngine: Engine
) : MultikTensorAlgebra<Short, ShortRing>(multikEngine) { ) : MultikTensorAlgebra<Short, Int16Ring>(multikEngine) {
override val elementAlgebra: ShortRing get() = ShortRing override val elementAlgebra: Int16Ring get() = Int16Ring
override val type: DataType get() = DataType.ShortDataType override val type: DataType get() = DataType.ShortDataType
override fun scalar(value: Short): MultikTensor<Short> = Multik.ndarrayOf(value).wrap() override fun scalar(value: Short): MultikTensor<Short> = Multik.ndarrayOf(value).wrap()
} }

View File

@ -10,7 +10,7 @@ import space.kscience.kmath.PerformancePitfall
import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.ShapeND
import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.one import space.kscience.kmath.nd.one
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
import space.kscience.kmath.tensors.core.randomNormal import space.kscience.kmath.tensors.core.randomNormal
import space.kscience.kmath.tensors.core.tensorAlgebra import space.kscience.kmath.tensors.core.tensorAlgebra
@ -37,7 +37,7 @@ internal class MultikNDTest {
tensor1 dot tensor2 tensor1 dot tensor2
} }
val defaultResult = with(DoubleField.tensorAlgebra) { val defaultResult = with(Float64Field.tensorAlgebra) {
tensor1 dot tensor2 tensor1 dot tensor2
} }

View File

@ -124,7 +124,7 @@ public sealed interface Nd4jArrayRingOps<T, out R : Ring<T>> : RingOpsND<T, R>,
*/ */
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
public inline fun <reified T : Number> auto(): Nd4jArrayRingOps<T, Ring<T>> = when { public inline fun <reified T : Number> auto(): Nd4jArrayRingOps<T, Ring<T>> = when {
T::class == Int::class -> IntRing.nd4j as Nd4jArrayRingOps<T, Ring<T>> T::class == Int::class -> Int32Ring.nd4j as Nd4jArrayRingOps<T, Ring<T>>
else -> throw UnsupportedOperationException("This factory method only supports Long type.") else -> throw UnsupportedOperationException("This factory method only supports Long type.")
} }
} }
@ -149,8 +149,8 @@ public sealed interface Nd4jArrayField<T, out F : Field<T>> : FieldOpsND<T, F>,
*/ */
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
public inline fun <reified T : Any> auto(): Nd4jArrayField<T, Field<T>> = when { public inline fun <reified T : Any> auto(): Nd4jArrayField<T, Field<T>> = when {
T::class == Float::class -> FloatField.nd4j as Nd4jArrayField<T, Field<T>> T::class == Float::class -> Float32Field.nd4j as Nd4jArrayField<T, Field<T>>
T::class == Double::class -> DoubleField.nd4j as Nd4jArrayField<T, Field<T>> T::class == Double::class -> Float64Field.nd4j as Nd4jArrayField<T, Field<T>>
else -> throw UnsupportedOperationException("This factory method only supports Float and Double types.") else -> throw UnsupportedOperationException("This factory method only supports Float and Double types.")
} }
} }
@ -190,8 +190,8 @@ public sealed interface Nd4jArrayExtendedFieldOps<T, out F : ExtendedField<T>> :
/** /**
* Represents [FieldND] over [Nd4jArrayDoubleStructure]. * Represents [FieldND] over [Nd4jArrayDoubleStructure].
*/ */
public open class DoubleNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Double, DoubleField> { public open class DoubleNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Double, Float64Field> {
override val elementAlgebra: DoubleField get() = DoubleField override val elementAlgebra: Float64Field get() = Float64Field
override fun INDArray.wrap(): Nd4jArrayStructure<Double> = asDoubleStructure() override fun INDArray.wrap(): Nd4jArrayStructure<Double> = asDoubleStructure()
@ -223,19 +223,19 @@ public open class DoubleNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Double, Do
public companion object : DoubleNd4jArrayFieldOps() public companion object : DoubleNd4jArrayFieldOps()
} }
public val DoubleField.nd4j: DoubleNd4jArrayFieldOps get() = DoubleNd4jArrayFieldOps public val Float64Field.nd4j: DoubleNd4jArrayFieldOps get() = DoubleNd4jArrayFieldOps
public class DoubleNd4jArrayField(override val shape: ShapeND) : DoubleNd4jArrayFieldOps(), FieldND<Double, DoubleField> public class DoubleNd4jArrayField(override val shape: ShapeND) : DoubleNd4jArrayFieldOps(), FieldND<Double, Float64Field>
public fun DoubleField.nd4j(shapeFirst: Int, vararg shapeRest: Int): DoubleNd4jArrayField = public fun Float64Field.nd4j(shapeFirst: Int, vararg shapeRest: Int): DoubleNd4jArrayField =
DoubleNd4jArrayField(ShapeND(shapeFirst, * shapeRest)) DoubleNd4jArrayField(ShapeND(shapeFirst, * shapeRest))
/** /**
* Represents [FieldND] over [Nd4jArrayStructure] of [Float]. * Represents [FieldND] over [Nd4jArrayStructure] of [Float].
*/ */
public open class FloatNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Float, FloatField> { public open class FloatNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Float, Float32Field> {
override val elementAlgebra: FloatField get() = FloatField override val elementAlgebra: Float32Field get() = Float32Field
override fun INDArray.wrap(): Nd4jArrayStructure<Float> = asFloatStructure() override fun INDArray.wrap(): Nd4jArrayStructure<Float> = asFloatStructure()
@ -272,18 +272,18 @@ public open class FloatNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Float, Floa
public companion object : FloatNd4jArrayFieldOps() public companion object : FloatNd4jArrayFieldOps()
} }
public class FloatNd4jArrayField(override val shape: ShapeND) : FloatNd4jArrayFieldOps(), RingND<Float, FloatField> public class FloatNd4jArrayField(override val shape: ShapeND) : FloatNd4jArrayFieldOps(), RingND<Float, Float32Field>
public val FloatField.nd4j: FloatNd4jArrayFieldOps get() = FloatNd4jArrayFieldOps public val Float32Field.nd4j: FloatNd4jArrayFieldOps get() = FloatNd4jArrayFieldOps
public fun FloatField.nd4j(shapeFirst: Int, vararg shapeRest: Int): FloatNd4jArrayField = public fun Float32Field.nd4j(shapeFirst: Int, vararg shapeRest: Int): FloatNd4jArrayField =
FloatNd4jArrayField(ShapeND(shapeFirst, * shapeRest)) FloatNd4jArrayField(ShapeND(shapeFirst, * shapeRest))
/** /**
* Represents [RingND] over [Nd4jArrayIntStructure]. * Represents [RingND] over [Nd4jArrayIntStructure].
*/ */
public open class IntNd4jArrayRingOps : Nd4jArrayRingOps<Int, IntRing> { public open class IntNd4jArrayRingOps : Nd4jArrayRingOps<Int, Int32Ring> {
override val elementAlgebra: IntRing get() = IntRing override val elementAlgebra: Int32Ring get() = Int32Ring
override fun INDArray.wrap(): Nd4jArrayStructure<Int> = asIntStructure() override fun INDArray.wrap(): Nd4jArrayStructure<Int> = asIntStructure()
@ -311,9 +311,9 @@ public open class IntNd4jArrayRingOps : Nd4jArrayRingOps<Int, IntRing> {
public companion object : IntNd4jArrayRingOps() public companion object : IntNd4jArrayRingOps()
} }
public val IntRing.nd4j: IntNd4jArrayRingOps get() = IntNd4jArrayRingOps public val Int32Ring.nd4j: IntNd4jArrayRingOps get() = IntNd4jArrayRingOps
public class IntNd4jArrayRing(override val shape: ShapeND) : IntNd4jArrayRingOps(), RingND<Int, IntRing> public class IntNd4jArrayRing(override val shape: ShapeND) : IntNd4jArrayRingOps(), RingND<Int, Int32Ring>
public fun IntRing.nd4j(shapeFirst: Int, vararg shapeRest: Int): IntNd4jArrayRing = public fun Int32Ring.nd4j(shapeFirst: Int, vararg shapeRest: Int): IntNd4jArrayRing =
IntNd4jArrayRing(ShapeND(shapeFirst, * shapeRest)) IntNd4jArrayRing(ShapeND(shapeFirst, * shapeRest))

View File

@ -15,8 +15,8 @@ import org.nd4j.linalg.ops.transforms.Transforms
import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.PerformancePitfall
import space.kscience.kmath.UnsafeKMathAPI import space.kscience.kmath.UnsafeKMathAPI
import space.kscience.kmath.nd.* import space.kscience.kmath.nd.*
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Field import space.kscience.kmath.operations.Field
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.tensors.api.AnalyticTensorAlgebra import space.kscience.kmath.tensors.api.AnalyticTensorAlgebra
import space.kscience.kmath.tensors.api.Tensor import space.kscience.kmath.tensors.api.Tensor
import space.kscience.kmath.tensors.api.TensorAlgebra import space.kscience.kmath.tensors.api.TensorAlgebra
@ -171,14 +171,14 @@ public sealed interface Nd4jTensorAlgebra<T : Number, A : Field<T>> : AnalyticTe
/** /**
* [Double] specialization of [Nd4jTensorAlgebra]. * [Double] specialization of [Nd4jTensorAlgebra].
*/ */
public object DoubleNd4jTensorAlgebra : Nd4jTensorAlgebra<Double, DoubleField> { public object DoubleNd4jTensorAlgebra : Nd4jTensorAlgebra<Double, Float64Field> {
override val elementAlgebra: DoubleField get() = DoubleField override val elementAlgebra: Float64Field get() = Float64Field
override fun INDArray.wrap(): Nd4jArrayStructure<Double> = asDoubleStructure() override fun INDArray.wrap(): Nd4jArrayStructure<Double> = asDoubleStructure()
@OptIn(UnsafeKMathAPI::class) @OptIn(UnsafeKMathAPI::class)
override fun structureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): Nd4jArrayStructure<Double> { override fun structureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): Nd4jArrayStructure<Double> {
val array: INDArray = Nd4j.zeros(*shape.asArray()) val array: INDArray = Nd4j.zeros(*shape.asArray())
val indices = ColumnStrides(shape) val indices = ColumnStrides(shape)
indices.asSequence().forEach { index -> indices.asSequence().forEach { index ->

View File

@ -10,8 +10,8 @@ import space.kscience.kmath.PerformancePitfall
import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.one import space.kscience.kmath.nd.one
import space.kscience.kmath.nd.structureND import space.kscience.kmath.nd.structureND
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.IntRing import space.kscience.kmath.operations.Int32Ring
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import kotlin.math.PI import kotlin.math.PI
import kotlin.test.Test import kotlin.test.Test
@ -23,7 +23,7 @@ import kotlin.test.fail
internal class Nd4jArrayAlgebraTest { internal class Nd4jArrayAlgebraTest {
@Test @Test
fun testProduce() { fun testProduce() {
val res = DoubleField.nd4j.structureND(2, 2) { it.sum().toDouble() } val res = Float64Field.nd4j.structureND(2, 2) { it.sum().toDouble() }
val expected = (Nd4j.create(2, 2) ?: fail()).asDoubleStructure() val expected = (Nd4j.create(2, 2) ?: fail()).asDoubleStructure()
expected[intArrayOf(0, 0)] = 0.0 expected[intArrayOf(0, 0)] = 0.0
expected[intArrayOf(0, 1)] = 1.0 expected[intArrayOf(0, 1)] = 1.0
@ -34,7 +34,7 @@ internal class Nd4jArrayAlgebraTest {
@Test @Test
fun testMap() { fun testMap() {
val res = IntRing.nd4j { val res = Int32Ring.nd4j {
one(2, 2).map { it + it * 2 } one(2, 2).map { it + it * 2 }
} }
val expected = (Nd4j.create(2, 2) ?: fail()).asIntStructure() val expected = (Nd4j.create(2, 2) ?: fail()).asIntStructure()
@ -47,7 +47,7 @@ internal class Nd4jArrayAlgebraTest {
@Test @Test
fun testAdd() { fun testAdd() {
val res = IntRing.nd4j { one(2, 2) + 25 } val res = Int32Ring.nd4j { one(2, 2) + 25 }
val expected = (Nd4j.create(2, 2) ?: fail()).asIntStructure() val expected = (Nd4j.create(2, 2) ?: fail()).asIntStructure()
expected[intArrayOf(0, 0)] = 26 expected[intArrayOf(0, 0)] = 26
expected[intArrayOf(0, 1)] = 26 expected[intArrayOf(0, 1)] = 26
@ -57,7 +57,7 @@ internal class Nd4jArrayAlgebraTest {
} }
@Test @Test
fun testSin() = DoubleField.nd4j{ fun testSin() = Float64Field.nd4j{
val initial = structureND(2, 2) { (i, j) -> if (i == j) PI / 2 else 0.0 } val initial = structureND(2, 2) { (i, j) -> if (i == j) PI / 2 else 0.0 }
val transformed = sin(initial) val transformed = sin(initial)
val expected = structureND(2, 2) { (i, j) -> if (i == j) 1.0 else 0.0 } val expected = structureND(2, 2) { (i, j) -> if (i == j) 1.0 else 0.0 }

View File

@ -9,8 +9,8 @@ import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.expressions.* import space.kscience.kmath.expressions.*
import space.kscience.kmath.linear.* import space.kscience.kmath.linear.*
import space.kscience.kmath.misc.log import space.kscience.kmath.misc.log
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.DoubleL2Norm import space.kscience.kmath.operations.DoubleL2Norm
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.algebra import space.kscience.kmath.operations.algebra
import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.DoubleBuffer
import kotlin.math.abs import kotlin.math.abs
@ -32,7 +32,7 @@ public class QowRuns(public val runs: Int) : OptimizationFeature {
@UnstableKMathAPI @UnstableKMathAPI
public object QowOptimizer : Optimizer<Double, XYFit> { public object QowOptimizer : Optimizer<Double, XYFit> {
private val linearSpace: LinearSpace<Double, DoubleField> = Double.algebra.linearSpace private val linearSpace: LinearSpace<Double, Float64Field> = Double.algebra.linearSpace
private val solver: LinearSolver<Double> = linearSpace.lupSolver() private val solver: LinearSolver<Double> = linearSpace.lupSolver()
@OptIn(UnstableKMathAPI::class) @OptIn(UnstableKMathAPI::class)

View File

@ -6,7 +6,7 @@
package space.kscience.kmath.distributions package space.kscience.kmath.distributions
import space.kscience.kmath.chains.Chain import space.kscience.kmath.chains.Chain
import space.kscience.kmath.operations.DoubleField.pow import space.kscience.kmath.operations.Float64Field.pow
import space.kscience.kmath.random.RandomGenerator import space.kscience.kmath.random.RandomGenerator
import space.kscience.kmath.samplers.GaussianSampler import space.kscience.kmath.samplers.GaussianSampler
import space.kscience.kmath.samplers.InternalErf import space.kscience.kmath.samplers.InternalErf

View File

@ -6,7 +6,7 @@
package space.kscience.kmath.series package space.kscience.kmath.series
import space.kscience.kmath.distributions.NormalDistribution import space.kscience.kmath.distributions.NormalDistribution
import space.kscience.kmath.operations.DoubleField.pow import space.kscience.kmath.operations.Float64Field.pow
import space.kscience.kmath.operations.fold import space.kscience.kmath.operations.fold
import kotlin.math.absoluteValue import kotlin.math.absoluteValue

View File

@ -13,21 +13,20 @@ import space.kscience.kmath.structures.indices
* Arithmetic mean * Arithmetic mean
*/ */
public class Mean<T>( public class Mean<T>(
private val group: Ring<T>, private val field: Field<T>
private val division: (sum: T, count: Int) -> T,
) : ComposableStatistic<T, Pair<T, Int>, T>, BlockingStatistic<T, T> { ) : ComposableStatistic<T, Pair<T, Int>, T>, BlockingStatistic<T, T> {
override fun evaluateBlocking(data: Buffer<T>): T = group { override fun evaluateBlocking(data: Buffer<T>): T = with(field) {
var res = zero var res = zero
for (i in data.indices) { for (i in data.indices) {
res += data[i] res += data[i]
} }
division(res, data.size) res / data.size
} }
override suspend fun evaluate(data: Buffer<T>): T = super<ComposableStatistic>.evaluate(data) override suspend fun evaluate(data: Buffer<T>): T = super<ComposableStatistic>.evaluate(data)
override suspend fun computeIntermediate(data: Buffer<T>): Pair<T, Int> = group { override suspend fun computeIntermediate(data: Buffer<T>): Pair<T, Int> = with(field) {
var res = zero var res = zero
for (i in data.indices) { for (i in data.indices) {
res += data[i] res += data[i]
@ -36,32 +35,23 @@ public class Mean<T>(
} }
override suspend fun composeIntermediate(first: Pair<T, Int>, second: Pair<T, Int>): Pair<T, Int> = override suspend fun composeIntermediate(first: Pair<T, Int>, second: Pair<T, Int>): Pair<T, Int> =
group { first.first + second.first } to (first.second + second.second) with(field) { first.first + second.first } to (first.second + second.second)
override suspend fun toResult(intermediate: Pair<T, Int>): T = group { override suspend fun toResult(intermediate: Pair<T, Int>): T = with(field) {
division(intermediate.first, intermediate.second) intermediate.first/ intermediate.second
} }
public companion object { public companion object {
@Deprecated("Use Double.mean instead") public fun evaluate(buffer: Buffer<Double>): Double = Float64Field.mean.evaluateBlocking(buffer)
public val double: Mean<Double> = Mean(DoubleField) { sum, count -> sum / count } public fun evaluate(buffer: Buffer<Int>): Int = Int32Ring.mean.evaluateBlocking(buffer)
public fun evaluate(buffer: Buffer<Long>): Long = Int64Ring.mean.evaluateBlocking(buffer)
@Deprecated("Use Int.mean instead")
public val int: Mean<Int> = Mean(IntRing) { sum, count -> sum / count }
@Deprecated("Use Long.mean instead")
public val long: Mean<Long> = Mean(LongRing) { sum, count -> sum / count }
public fun evaluate(buffer: Buffer<Double>): Double = DoubleField.mean.evaluateBlocking(buffer)
public fun evaluate(buffer: Buffer<Int>): Int = IntRing.mean.evaluateBlocking(buffer)
public fun evaluate(buffer: Buffer<Long>): Long = LongRing.mean.evaluateBlocking(buffer)
} }
} }
//TODO replace with optimized version which respects overflow //TODO replace with optimized version which respects overflow
public val DoubleField.mean: Mean<Double> get() = Mean(DoubleField) { sum, count -> sum / count } public val Float64Field.mean: Mean<Double> get() = Mean(Float64Field)
public val IntRing.mean: Mean<Int> get() = Mean(IntRing) { sum, count -> sum / count } public val Int32Ring.mean: Mean<Int> get() = Mean(Int32Field)
public val LongRing.mean: Mean<Long> get() = Mean(LongRing) { sum, count -> sum / count } public val Int64Ring.mean: Mean<Long> get() = Mean(Int64Field)

View File

@ -5,17 +5,34 @@
package space.kscience.kmath.stat package space.kscience.kmath.stat
import space.kscience.kmath.operations.asSequence import space.kscience.kmath.misc.sortedWith
import space.kscience.kmath.operations.*
import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.Buffer
/** /**
* Non-composable median * Non-composable median
*/ */
public class Median<T>(private val comparator: Comparator<T>) : BlockingStatistic<T, T> { public class Median<T>(private val field: Field<T>, private val comparator: Comparator<T>) : BlockingStatistic<T, T> {
override fun evaluateBlocking(data: Buffer<T>): T =
data.asSequence().sortedWith(comparator).toList()[data.size / 2] //TODO check if this is correct override fun evaluateBlocking(data: Buffer<T>): T = when {
data.size == 0 -> error("Can't compute median of an empty buffer")
data.size == 1 -> data[0]
data.size % 2 == 0 -> with(field) {
val sorted = data.sortedWith(comparator)
(sorted[data.size / 2 - 1] + sorted[data.size / 2]) / 2
}
else -> data.sortedWith(comparator)[(data.size - 1) / 2]
}
public companion object { public companion object {
public val real: Median<Double> = Median { a: Double, b: Double -> a.compareTo(b) }
public fun evaluate(buffer: Buffer<Double>): Double = Float64Field.mean.evaluateBlocking(buffer)
public fun evaluate(buffer: Buffer<Int>): Int = Int32Ring.mean.evaluateBlocking(buffer)
public fun evaluate(buffer: Buffer<Long>): Long = Int64Ring.mean.evaluateBlocking(buffer)
} }
} }
public val Float64Field.median: Median<Double> get() = Median(Float64Field) { a, b -> a.compareTo(b) }
public val Int32Ring.median: Median<Int> get() = Median(Int32Field) { a, b -> a.compareTo(b) }
public val Int64Ring.median: Median<Long> get() = Median(Int64Field) { a, b -> a.compareTo(b) }

View File

@ -15,7 +15,7 @@ import space.kscience.kmath.coroutines.mapParallel
import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.Buffer
/** /**
* A function, that transforms a buffer of random quantities to some resulting value * A function that transforms a buffer of random quantities to some resulting value
*/ */
public fun interface Statistic<in T, out R> { public fun interface Statistic<in T, out R> {
public suspend fun evaluate(data: Buffer<T>): R public suspend fun evaluate(data: Buffer<T>): R
@ -67,7 +67,7 @@ private fun <T, I, R> ComposableStatistic<T, I, R>.flowIntermediate(
/** /**
* Perform a streaming statistical analysis on a chunked data. The computation of inner representation is done in parallel * Perform a streaming statistical analysis on chunked data. The computation of inner representation is done in parallel
* if [dispatcher] allows it. * if [dispatcher] allows it.
* *
* The resulting flow contains values that include the whole previous statistics, not only the last chunk. * The resulting flow contains values that include the whole previous statistics, not only the last chunk.

View File

@ -0,0 +1,31 @@
/*
* Copyright 2018-2023 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.stat
import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.random.RandomGenerator
import space.kscience.kmath.structures.slice
import kotlin.test.Test
import kotlin.test.assertEquals
@OptIn(UnstableKMathAPI::class)
class TestBasicStatistics {
companion object {
val float64Sample = RandomGenerator.default(123).nextDoubleBuffer(100)
}
@Test
fun medianFloat64() {
assertEquals(0.508, Float64Field.median(float64Sample), 0.0005)
assertEquals(0.5055, Float64Field.median(float64Sample.slice { 0..<last }), 0.0005)
}
@Test
fun meanFloat64() {
assertEquals(0.488, Float64Field.mean(float64Sample), 0.0002)
}
}

View File

@ -9,7 +9,7 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.last import kotlinx.coroutines.flow.last
import kotlinx.coroutines.flow.take import kotlinx.coroutines.flow.take
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.random.RandomGenerator import space.kscience.kmath.random.RandomGenerator
import space.kscience.kmath.random.chain import space.kscience.kmath.random.chain
import space.kscience.kmath.streaming.chunked import space.kscience.kmath.streaming.chunked
@ -29,20 +29,20 @@ internal class StatisticTest {
@Test @Test
fun singleBlockingMean() { fun singleBlockingMean() {
val first = runBlocking { chunked.first() } val first = runBlocking { chunked.first() }
val res = DoubleField.mean(first) val res = Float64Field.mean(first)
assertEquals(0.5, res, 1e-1) assertEquals(0.5, res, 1e-1)
} }
@Test @Test
fun singleSuspendMean() = runBlocking { fun singleSuspendMean() = runBlocking {
val first = runBlocking { chunked.first() } val first = runBlocking { chunked.first() }
val res = DoubleField.mean(first) val res = Float64Field.mean(first)
assertEquals(0.5, res, 1e-1) assertEquals(0.5, res, 1e-1)
} }
@Test @Test
fun parallelMean() = runBlocking { fun parallelMean() = runBlocking {
val average = DoubleField.mean val average = Float64Field.mean
.flow(chunked) //create a flow from evaluated results .flow(chunked) //create a flow from evaluated results
.take(100) // Take 100 data chunks from the source and accumulate them .take(100) // Take 100 data chunks from the source and accumulate them
.last() //get 1e5 data samples average .last() //get 1e5 data samples average

View File

@ -16,7 +16,7 @@ import space.kscience.kmath.expressions.Symbol
import space.kscience.kmath.nd.ColumnStrides import space.kscience.kmath.nd.ColumnStrides
import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.ShapeND
import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.PowerOperations import space.kscience.kmath.operations.PowerOperations
public class DoubleTensorFlowOutput( public class DoubleTensorFlowOutput(
@ -32,13 +32,13 @@ internal fun ShapeND.toLongArray(): LongArray = LongArray(size) { get(it).toLong
public class DoubleTensorFlowAlgebra internal constructor( public class DoubleTensorFlowAlgebra internal constructor(
graph: Graph, graph: Graph,
) : TensorFlowAlgebra<Double, TFloat64, DoubleField>(graph), PowerOperations<StructureND<Double>> { ) : TensorFlowAlgebra<Double, TFloat64, Float64Field>(graph), PowerOperations<StructureND<Double>> {
override val elementAlgebra: DoubleField get() = DoubleField override val elementAlgebra: Float64Field get() = Float64Field
override fun structureND( override fun structureND(
shape: ShapeND, shape: ShapeND,
initializer: DoubleField.(IntArray) -> Double, initializer: Float64Field.(IntArray) -> Double,
): StructureND<Double> { ): StructureND<Double> {
val res = TFloat64.tensorOf(org.tensorflow.ndarray.Shape.of(*shape.toLongArray())) { array -> val res = TFloat64.tensorOf(org.tensorflow.ndarray.Shape.of(*shape.toLongArray())) { array ->
ColumnStrides(shape).forEach { index -> ColumnStrides(shape).forEach { index ->
@ -83,7 +83,7 @@ public class DoubleTensorFlowAlgebra internal constructor(
* The resulting tensor is available outside of scope * The resulting tensor is available outside of scope
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun DoubleField.produceWithTF( public fun Float64Field.produceWithTF(
block: DoubleTensorFlowAlgebra.() -> StructureND<Double>, block: DoubleTensorFlowAlgebra.() -> StructureND<Double>,
): StructureND<Double> = Graph().use { graph -> ): StructureND<Double> = Graph().use { graph ->
val scope = DoubleTensorFlowAlgebra(graph) val scope = DoubleTensorFlowAlgebra(graph)
@ -96,7 +96,7 @@ public fun DoubleField.produceWithTF(
* The resulting tensors are available outside of scope * The resulting tensors are available outside of scope
*/ */
@OptIn(UnstableKMathAPI::class) @OptIn(UnstableKMathAPI::class)
public fun DoubleField.produceMapWithTF( public fun Float64Field.produceMapWithTF(
block: DoubleTensorFlowAlgebra.() -> Map<Symbol, StructureND<Double>>, block: DoubleTensorFlowAlgebra.() -> Map<Symbol, StructureND<Double>>,
): Map<Symbol, StructureND<Double>> = Graph().use { graph -> ): Map<Symbol, StructureND<Double>> = Graph().use { graph ->
val scope = DoubleTensorFlowAlgebra(graph) val scope = DoubleTensorFlowAlgebra(graph)

View File

@ -10,7 +10,7 @@ import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.ShapeND
import space.kscience.kmath.nd.get import space.kscience.kmath.nd.get
import space.kscience.kmath.nd.structureND import space.kscience.kmath.nd.structureND
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.sum import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.sum
import space.kscience.kmath.tensors.core.randomNormal import space.kscience.kmath.tensors.core.randomNormal
@ -20,7 +20,7 @@ import kotlin.test.assertEquals
class DoubleTensorFlowOps { class DoubleTensorFlowOps {
@Test @Test
fun basicOps() { fun basicOps() {
val res = DoubleField.produceWithTF { val res = Float64Field.produceWithTF {
val initial = structureND(2, 2) { 1.0 } val initial = structureND(2, 2) { 1.0 }
initial + (initial * 2.0) initial + (initial * 2.0)
@ -36,14 +36,14 @@ class DoubleTensorFlowOps {
val tensor1 = DoubleTensorAlgebra.randomNormal(shape = ShapeND(dim, dim), 12224) val tensor1 = DoubleTensorAlgebra.randomNormal(shape = ShapeND(dim, dim), 12224)
val tensor2 = DoubleTensorAlgebra.randomNormal(shape = ShapeND(dim, dim), 12225) val tensor2 = DoubleTensorAlgebra.randomNormal(shape = ShapeND(dim, dim), 12225)
DoubleField.produceWithTF { Float64Field.produceWithTF {
tensor1 dot tensor2 tensor1 dot tensor2
}.sum() }.sum()
} }
@Test @Test
fun extensionOps(){ fun extensionOps(){
val res = DoubleField.produceWithTF { val res = Float64Field.produceWithTF {
val i = structureND(2, 2) { 0.5 } val i = structureND(2, 2) { 0.5 }
sin(i).pow(2) + cos(i).pow(2) sin(i).pow(2) + cos(i).pow(2)

View File

@ -11,25 +11,28 @@ package space.kscience.kmath.tensors.core
import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.PerformancePitfall
import space.kscience.kmath.nd.* import space.kscience.kmath.nd.*
import space.kscience.kmath.operations.DoubleBufferOps import space.kscience.kmath.operations.DoubleBufferOps
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.structures.* import space.kscience.kmath.structures.*
import space.kscience.kmath.tensors.api.AnalyticTensorAlgebra import space.kscience.kmath.tensors.api.AnalyticTensorAlgebra
import space.kscience.kmath.tensors.api.LinearOpsTensorAlgebra import space.kscience.kmath.tensors.api.LinearOpsTensorAlgebra
import space.kscience.kmath.tensors.api.Tensor import space.kscience.kmath.tensors.api.Tensor
import space.kscience.kmath.tensors.core.internal.* import space.kscience.kmath.tensors.core.internal.*
import kotlin.math.* import kotlin.math.abs
import kotlin.math.ceil
import kotlin.math.floor
import kotlin.math.sqrt
/** /**
* Implementation of basic operations over double tensors and basic algebra operations on them. * Implementation of basic operations over double tensors and basic algebra operations on them.
*/ */
@OptIn(PerformancePitfall::class) @OptIn(PerformancePitfall::class)
public open class DoubleTensorAlgebra : public open class DoubleTensorAlgebra :
AnalyticTensorAlgebra<Double, DoubleField>, AnalyticTensorAlgebra<Double, Float64Field>,
LinearOpsTensorAlgebra<Double, DoubleField> { LinearOpsTensorAlgebra<Double, Float64Field> {
public companion object : DoubleTensorAlgebra() public companion object : DoubleTensorAlgebra()
override val elementAlgebra: DoubleField get() = DoubleField override val elementAlgebra: Float64Field get() = Float64Field
public val bufferAlgebra: DoubleBufferOps get() = DoubleBufferOps public val bufferAlgebra: DoubleBufferOps get() = DoubleBufferOps
@ -41,10 +44,10 @@ public open class DoubleTensorAlgebra :
* @return the resulting tensor after applying the function. * @return the resulting tensor after applying the function.
*/ */
@Suppress("OVERRIDE_BY_INLINE") @Suppress("OVERRIDE_BY_INLINE")
final override inline fun StructureND<Double>.map(transform: DoubleField.(Double) -> Double): DoubleTensor { final override inline fun StructureND<Double>.map(transform: Float64Field.(Double) -> Double): DoubleTensor {
val tensor = asDoubleTensor() val tensor = asDoubleTensor()
//TODO remove additional copy //TODO remove additional copy
val array = DoubleBuffer(tensor.source.size) { DoubleField.transform(tensor.source[it]) } val array = DoubleBuffer(tensor.source.size) { Float64Field.transform(tensor.source[it]) }
return DoubleTensor( return DoubleTensor(
tensor.shape, tensor.shape,
array, array,
@ -59,12 +62,12 @@ public open class DoubleTensorAlgebra :
} }
} }
public inline fun Tensor<Double>.mapIndexedInPlace(operation: DoubleField.(IntArray, Double) -> Double) { public inline fun Tensor<Double>.mapIndexedInPlace(operation: Float64Field.(IntArray, Double) -> Double) {
indices.forEach { set(it, DoubleField.operation(it, get(it))) } indices.forEach { set(it, Float64Field.operation(it, get(it))) }
} }
@Suppress("OVERRIDE_BY_INLINE") @Suppress("OVERRIDE_BY_INLINE")
final override inline fun StructureND<Double>.mapIndexed(transform: DoubleField.(index: IntArray, Double) -> Double): DoubleTensor { final override inline fun StructureND<Double>.mapIndexed(transform: Float64Field.(index: IntArray, Double) -> Double): DoubleTensor {
return copyToTensor().apply { mapIndexedInPlace(transform) } return copyToTensor().apply { mapIndexedInPlace(transform) }
} }
@ -73,14 +76,14 @@ public open class DoubleTensorAlgebra :
final override inline fun zip( final override inline fun zip(
left: StructureND<Double>, left: StructureND<Double>,
right: StructureND<Double>, right: StructureND<Double>,
transform: DoubleField.(Double, Double) -> Double, transform: Float64Field.(Double, Double) -> Double,
): DoubleTensor { ): DoubleTensor {
checkShapesCompatible(left, right) checkShapesCompatible(left, right)
val leftTensor = left.asDoubleTensor() val leftTensor = left.asDoubleTensor()
val rightTensor = right.asDoubleTensor() val rightTensor = right.asDoubleTensor()
val buffer = DoubleBuffer(leftTensor.source.size) { val buffer = DoubleBuffer(leftTensor.source.size) {
DoubleField.transform(leftTensor.source[it], rightTensor.source[it]) Float64Field.transform(leftTensor.source[it], rightTensor.source[it])
} }
return DoubleTensor(leftTensor.shape, buffer) return DoubleTensor(leftTensor.shape, buffer)
} }
@ -124,9 +127,9 @@ public open class DoubleTensorAlgebra :
* @param initializer mapping tensor indices to values. * @param initializer mapping tensor indices to values.
* @return tensor with the [shape] shape and data generated by the [initializer]. * @return tensor with the [shape] shape and data generated by the [initializer].
*/ */
override fun structureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): DoubleTensor = fromArray( override fun structureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): DoubleTensor = fromArray(
shape, shape,
RowStrides(shape).asSequence().map { DoubleField.initializer(it) }.toMutableList().toDoubleArray() RowStrides(shape).asSequence().map { Float64Field.initializer(it) }.toMutableList().toDoubleArray()
) )
override fun Tensor<Double>.getTensor(i: Int): DoubleTensor { override fun Tensor<Double>.getTensor(i: Int): DoubleTensor {
@ -717,4 +720,4 @@ public open class DoubleTensorAlgebra :
} }
public val Double.Companion.tensorAlgebra: DoubleTensorAlgebra get() = DoubleTensorAlgebra public val Double.Companion.tensorAlgebra: DoubleTensorAlgebra get() = DoubleTensorAlgebra
public val DoubleField.tensorAlgebra: DoubleTensorAlgebra get() = DoubleTensorAlgebra public val Float64Field.tensorAlgebra: DoubleTensorAlgebra get() = DoubleTensorAlgebra

View File

@ -10,7 +10,7 @@ package space.kscience.kmath.tensors.core
import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.PerformancePitfall
import space.kscience.kmath.nd.* import space.kscience.kmath.nd.*
import space.kscience.kmath.operations.IntRing import space.kscience.kmath.operations.Int32Ring
import space.kscience.kmath.structures.* import space.kscience.kmath.structures.*
import space.kscience.kmath.tensors.api.* import space.kscience.kmath.tensors.api.*
import space.kscience.kmath.tensors.core.internal.* import space.kscience.kmath.tensors.core.internal.*
@ -19,12 +19,12 @@ import kotlin.math.*
/** /**
* Implementation of basic operations over double tensors and basic algebra operations on them. * Implementation of basic operations over double tensors and basic algebra operations on them.
*/ */
public open class IntTensorAlgebra : TensorAlgebra<Int, IntRing> { public open class IntTensorAlgebra : TensorAlgebra<Int, Int32Ring> {
public companion object : IntTensorAlgebra() public companion object : IntTensorAlgebra()
override val elementAlgebra: IntRing get() = IntRing override val elementAlgebra: Int32Ring get() = Int32Ring
/** /**
@ -34,10 +34,10 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, IntRing> {
* @return the resulting tensor after applying the function. * @return the resulting tensor after applying the function.
*/ */
@Suppress("OVERRIDE_BY_INLINE") @Suppress("OVERRIDE_BY_INLINE")
final override inline fun StructureND<Int>.map(transform: IntRing.(Int) -> Int): IntTensor { final override inline fun StructureND<Int>.map(transform: Int32Ring.(Int) -> Int): IntTensor {
val tensor = this.asIntTensor() val tensor = this.asIntTensor()
//TODO remove additional copy //TODO remove additional copy
val array = IntBuffer(tensor.source.size) { IntRing.transform(tensor.source[it]) } val array = IntBuffer(tensor.source.size) { Int32Ring.transform(tensor.source[it]) }
return IntTensor( return IntTensor(
tensor.shape, tensor.shape,
array, array,
@ -57,11 +57,11 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, IntRing> {
} }
@Suppress("OVERRIDE_BY_INLINE") @Suppress("OVERRIDE_BY_INLINE")
final override inline fun StructureND<Int>.mapIndexed(transform: IntRing.(index: IntArray, Int) -> Int): IntTensor { final override inline fun StructureND<Int>.mapIndexed(transform: Int32Ring.(index: IntArray, Int) -> Int): IntTensor {
val tensor = this.asIntTensor() val tensor = this.asIntTensor()
//TODO remove additional copy //TODO remove additional copy
val buffer = IntBuffer(tensor.source.size) { val buffer = IntBuffer(tensor.source.size) {
IntRing.transform(tensor.indices.index(it), tensor.source[it]) Int32Ring.transform(tensor.indices.index(it), tensor.source[it])
} }
return IntTensor(tensor.shape, buffer) return IntTensor(tensor.shape, buffer)
} }
@ -70,14 +70,14 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, IntRing> {
final override inline fun zip( final override inline fun zip(
left: StructureND<Int>, left: StructureND<Int>,
right: StructureND<Int>, right: StructureND<Int>,
transform: IntRing.(Int, Int) -> Int, transform: Int32Ring.(Int, Int) -> Int,
): IntTensor { ): IntTensor {
checkShapesCompatible(left, right) checkShapesCompatible(left, right)
val leftTensor = left.asIntTensor() val leftTensor = left.asIntTensor()
val rightTensor = right.asIntTensor() val rightTensor = right.asIntTensor()
val buffer = IntBuffer(leftTensor.source.size) { val buffer = IntBuffer(leftTensor.source.size) {
IntRing.transform(leftTensor.source[it], rightTensor.source[it]) Int32Ring.transform(leftTensor.source[it], rightTensor.source[it])
} }
return IntTensor(leftTensor.shape, buffer) return IntTensor(leftTensor.shape, buffer)
} }
@ -118,9 +118,9 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, IntRing> {
* @param initializer mapping tensor indices to values. * @param initializer mapping tensor indices to values.
* @return tensor with the [shape] shape and data generated by the [initializer]. * @return tensor with the [shape] shape and data generated by the [initializer].
*/ */
override fun structureND(shape: ShapeND, initializer: IntRing.(IntArray) -> Int): IntTensor = fromArray( override fun structureND(shape: ShapeND, initializer: Int32Ring.(IntArray) -> Int): IntTensor = fromArray(
shape, shape,
RowStrides(shape).asSequence().map { IntRing.initializer(it) }.toMutableList().toIntArray() RowStrides(shape).asSequence().map { Int32Ring.initializer(it) }.toMutableList().toIntArray()
) )
override fun Tensor<Int>.getTensor(i: Int): IntTensor { override fun Tensor<Int>.getTensor(i: Int): IntTensor {
@ -462,6 +462,6 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, IntRing> {
} }
public val Int.Companion.tensorAlgebra: IntTensorAlgebra get() = IntTensorAlgebra public val Int.Companion.tensorAlgebra: IntTensorAlgebra get() = IntTensorAlgebra
public val IntRing.tensorAlgebra: IntTensorAlgebra get() = IntTensorAlgebra public val Int32Ring.tensorAlgebra: IntTensorAlgebra get() = IntTensorAlgebra

View File

@ -12,15 +12,15 @@ import space.kscience.kmath.PerformancePitfall
import space.kscience.kmath.UnsafeKMathAPI import space.kscience.kmath.UnsafeKMathAPI
import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.nd.* import space.kscience.kmath.nd.*
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.ExtendedFieldOps import space.kscience.kmath.operations.ExtendedFieldOps
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.NumbersAddOps import space.kscience.kmath.operations.NumbersAddOps
import space.kscience.kmath.operations.PowerOperations import space.kscience.kmath.operations.PowerOperations
@OptIn(UnstableKMathAPI::class, PerformancePitfall::class) @OptIn(UnstableKMathAPI::class, PerformancePitfall::class)
@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") @Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
public open class ViktorFieldOpsND : public open class ViktorFieldOpsND :
FieldOpsND<Double, DoubleField>, FieldOpsND<Double, Float64Field>,
ExtendedFieldOps<StructureND<Double>>, ExtendedFieldOps<StructureND<Double>>,
PowerOperations<StructureND<Double>> { PowerOperations<StructureND<Double>> {
@ -30,13 +30,13 @@ public open class ViktorFieldOpsND :
else -> structureND(shape) { this@f64Buffer[it] }.f64Buffer else -> structureND(shape) { this@f64Buffer[it] }.f64Buffer
} }
override val elementAlgebra: DoubleField get() = DoubleField override val elementAlgebra: Float64Field get() = Float64Field
@OptIn(UnsafeKMathAPI::class) @OptIn(UnsafeKMathAPI::class)
override fun structureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): ViktorStructureND = override fun structureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): ViktorStructureND =
F64Array(*shape.asArray()).apply { F64Array(*shape.asArray()).apply {
ColumnStrides(shape).asSequence().forEach { index -> ColumnStrides(shape).asSequence().forEach { index ->
set(value = DoubleField.initializer(index), indices = index) set(value = Float64Field.initializer(index), indices = index)
} }
}.asStructure() }.asStructure()
@ -44,20 +44,20 @@ public open class ViktorFieldOpsND :
@OptIn(UnsafeKMathAPI::class) @OptIn(UnsafeKMathAPI::class)
@PerformancePitfall @PerformancePitfall
override fun StructureND<Double>.map(transform: DoubleField.(Double) -> Double): ViktorStructureND = override fun StructureND<Double>.map(transform: Float64Field.(Double) -> Double): ViktorStructureND =
F64Array(*shape.asArray()).apply { F64Array(*shape.asArray()).apply {
ColumnStrides(ShapeND(shape)).asSequence().forEach { index -> ColumnStrides(ShapeND(shape)).asSequence().forEach { index ->
set(value = DoubleField.transform(this@map[index]), indices = index) set(value = Float64Field.transform(this@map[index]), indices = index)
} }
}.asStructure() }.asStructure()
@OptIn(UnsafeKMathAPI::class) @OptIn(UnsafeKMathAPI::class)
@PerformancePitfall @PerformancePitfall
override fun StructureND<Double>.mapIndexed( override fun StructureND<Double>.mapIndexed(
transform: DoubleField.(index: IntArray, Double) -> Double, transform: Float64Field.(index: IntArray, Double) -> Double,
): ViktorStructureND = F64Array(*shape.asArray()).apply { ): ViktorStructureND = F64Array(*shape.asArray()).apply {
ColumnStrides(ShapeND(shape)).asSequence().forEach { index -> ColumnStrides(ShapeND(shape)).asSequence().forEach { index ->
set(value = DoubleField.transform(index, this@mapIndexed[index]), indices = index) set(value = Float64Field.transform(index, this@mapIndexed[index]), indices = index)
} }
}.asStructure() }.asStructure()
@ -66,12 +66,12 @@ public open class ViktorFieldOpsND :
override fun zip( override fun zip(
left: StructureND<Double>, left: StructureND<Double>,
right: StructureND<Double>, right: StructureND<Double>,
transform: DoubleField.(Double, Double) -> Double, transform: Float64Field.(Double, Double) -> Double,
): ViktorStructureND { ): ViktorStructureND {
require(left.shape.contentEquals(right.shape)) require(left.shape.contentEquals(right.shape))
return F64Array(*left.shape.asArray()).apply { return F64Array(*left.shape.asArray()).apply {
ColumnStrides(left.shape).asSequence().forEach { index -> ColumnStrides(left.shape).asSequence().forEach { index ->
set(value = DoubleField.transform(left[index], right[index]), indices = index) set(value = Float64Field.transform(left[index], right[index]), indices = index)
} }
}.asStructure() }.asStructure()
} }
@ -120,12 +120,12 @@ public open class ViktorFieldOpsND :
public companion object : ViktorFieldOpsND() public companion object : ViktorFieldOpsND()
} }
public val DoubleField.viktorAlgebra: ViktorFieldOpsND get() = ViktorFieldOpsND public val Float64Field.viktorAlgebra: ViktorFieldOpsND get() = ViktorFieldOpsND
@OptIn(UnstableKMathAPI::class) @OptIn(UnstableKMathAPI::class)
public open class ViktorFieldND( public open class ViktorFieldND(
private val shapeAsArray: IntArray, private val shapeAsArray: IntArray,
) : ViktorFieldOpsND(), FieldND<Double, DoubleField>, NumbersAddOps<StructureND<Double>> { ) : ViktorFieldOpsND(), FieldND<Double, Float64Field>, NumbersAddOps<StructureND<Double>> {
override val shape: ShapeND = ShapeND(shapeAsArray) override val shape: ShapeND = ShapeND(shapeAsArray)
@ -137,6 +137,6 @@ public open class ViktorFieldND(
F64Array.full(init = value.toDouble(), shape = shapeAsArray).asStructure() F64Array.full(init = value.toDouble(), shape = shapeAsArray).asStructure()
} }
public fun DoubleField.viktorAlgebra(vararg shape: Int): ViktorFieldND = ViktorFieldND(shape) public fun Float64Field.viktorAlgebra(vararg shape: Int): ViktorFieldND = ViktorFieldND(shape)
public fun ViktorFieldND(vararg shape: Int): ViktorFieldND = ViktorFieldND(shape) public fun ViktorFieldND(vararg shape: Int): ViktorFieldND = ViktorFieldND(shape)