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 space.kscience.kmath.UnstableKMathAPI
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.invoke
import kotlin.math.sin
@ -84,7 +84,7 @@ class ExpressionsInterpretersBenchmark {
private val x by symbol
private const val times = 1_000_000
private val functional = DoubleField.expression {
private val functional = Float64Field.expression {
val x = bindSymbol(Symbol.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)
}
private val mst = node.toExpression(DoubleField)
private val mst = node.toExpression(Float64Field)
@OptIn(UnstableKMathAPI::class)
private val wasm = node.wasmCompileToExpression(DoubleField)
private val estree = node.estreeCompileToExpression(DoubleField)
private val wasm = node.wasmCompileToExpression(Float64Field)
private val estree = node.estreeCompileToExpression(Float64Field)
private val raw = Expression<Double> { args ->
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.linear.invoke
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.tensorflow.produceWithTF
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
@ -27,10 +27,10 @@ internal class DotBenchmark {
const val dim = 1000
//creating invertible matrix
val matrix1 = DoubleField.linearSpace.buildMatrix(dim, dim) { _, _ ->
val matrix1 = Float64Field.linearSpace.buildMatrix(dim, dim) { _, _ ->
random.nextDouble()
}
val matrix2 = DoubleField.linearSpace.buildMatrix(dim, dim) { _, _ ->
val matrix2 = Float64Field.linearSpace.buildMatrix(dim, dim) { _, _ ->
random.nextDouble()
}
@ -45,7 +45,7 @@ internal class DotBenchmark {
@Benchmark
fun tfDot(blackhole: Blackhole) {
blackhole.consume(
DoubleField.produceWithTF {
Float64Field.produceWithTF {
matrix1 dot matrix1
}
)
@ -72,7 +72,7 @@ internal class DotBenchmark {
}
@Benchmark
fun tensorDot(blackhole: Blackhole) = with(DoubleField.tensorAlgebra) {
fun tensorDot(blackhole: Blackhole) = with(Float64Field.tensorAlgebra) {
blackhole.consume(matrix1 dot matrix2)
}
@ -82,12 +82,12 @@ internal class DotBenchmark {
}
@Benchmark
fun bufferedDot(blackhole: Blackhole) = with(DoubleField.linearSpace) {
fun bufferedDot(blackhole: Blackhole) = with(Float64Field.linearSpace) {
blackhole.consume(matrix1 dot matrix2)
}
@Benchmark
fun doubleDot(blackhole: Blackhole) = with(DoubleField.linearSpace) {
fun doubleDot(blackhole: Blackhole) = with(Float64Field.linearSpace) {
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.expressions.*
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.invoke
import kotlin.math.sin
@ -100,7 +100,7 @@ internal class ExpressionsInterpretersBenchmark {
private val x by symbol
private const val times = 1_000_000
private val functional = DoubleField.expression {
private val functional = Float64Field.expression {
val x = bindSymbol(Symbol.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)
}
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 asmGeneric = node.compileToExpression(DoubleField as Algebra<Double>)
private val asmGeneric = node.compileToExpression(Float64Field as Algebra<Double>)
private val raw = Expression<Double> { args ->
val x = args[x]!!

View File

@ -11,7 +11,7 @@ import org.openjdk.jmh.annotations.Scope
import org.openjdk.jmh.annotations.State
import space.kscience.kmath.jafama.JafamaDoubleField
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 kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@ -26,7 +26,7 @@ internal class JafamaBenchmark {
@Benchmark
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

View File

@ -16,7 +16,7 @@ import org.jetbrains.kotlinx.multik.ndarray.data.DataType
import space.kscience.kmath.UnsafeKMathAPI
import space.kscience.kmath.nd.*
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.one
import space.kscience.kmath.tensors.core.tensorAlgebra
@ -86,9 +86,9 @@ internal class NDFieldBenchmark {
private const val dim = 1000
private const val n = 100
private val shape = ShapeND(dim, dim)
private val specializedField = DoubleField.ndAlgebra
private val genericField = BufferedFieldOpsND(DoubleField)
private val nd4jField = DoubleField.nd4j
private val viktorField = DoubleField.viktorAlgebra
private val specializedField = Float64Field.ndAlgebra
private val genericField = BufferedFieldOpsND(Float64Field)
private val nd4jField = Float64Field.nd4j
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.matrix
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.symEigSvd
import space.kscience.kmath.tensors.core.tensorAlgebra
@ -24,7 +24,7 @@ internal class TensorAlgebraBenchmark {
private val random = Random(12224)
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

View File

@ -14,7 +14,7 @@ import space.kscience.kmath.nd.ShapeND
import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.ndAlgebra
import space.kscience.kmath.nd.one
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.viktor.ViktorFieldND
@State(Scope.Benchmark)
@ -52,7 +52,7 @@ internal class ViktorBenchmark {
private val shape = ShapeND(dim, dim)
// automatically build context most suited for given type.
private val doubleField = DoubleField.ndAlgebra
private val doubleField = Float64Field.ndAlgebra
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.ndAlgebra
import space.kscience.kmath.nd.one
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.viktor.ViktorFieldND
@State(Scope.Benchmark)
@ -52,7 +52,7 @@ internal class ViktorLogBenchmark {
private val shape = ShapeND(dim, dim)
// automatically build context most suited for given type.
private val doubleField = DoubleField.ndAlgebra
private val doubleField = Float64Field.ndAlgebra
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.expressions.MstExtendedField
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
fun main() {
val expr = MstExtendedField {
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 xIdx = expr.indexer.indexOf(x)

View File

@ -5,12 +5,12 @@
package space.kscience.kmath.ast
import space.kscience.kmath.expressions.Symbol.Companion.x
import space.kscience.kmath.expressions.derivative
import space.kscience.kmath.expressions.invoke
import space.kscience.kmath.expressions.Symbol.Companion.x
import space.kscience.kmath.expressions.toExpression
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
@ -19,9 +19,9 @@ import space.kscience.kmath.operations.DoubleField
fun main() {
val actualDerivative = "x^2-4*x-44"
.parseMath()
.toKotlingradExpression(DoubleField)
.toKotlingradExpression(Float64Field)
.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))
}

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.invoke
import space.kscience.kmath.expressions.toExpression
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.symja.toSymjaExpression
/**
@ -19,9 +19,9 @@ import space.kscience.kmath.symja.toSymjaExpression
fun main() {
val actualDerivative = "x^2-4*x-44"
.parseMath()
.toSymjaExpression(DoubleField)
.toSymjaExpression(Float64Field)
.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))
}

View File

@ -13,7 +13,7 @@ import space.kscience.kmath.complex.algebra
import space.kscience.kmath.integration.gaussIntegrator
import space.kscience.kmath.integration.integrate
import space.kscience.kmath.integration.value
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Float64Field
import kotlin.math.pow
fun main() {
@ -21,7 +21,7 @@ fun main() {
val function: Function1D<Double> = { x -> 3 * x.pow(2) + 2 * x + 1 }
//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
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.interpolatePolynomials
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.structures.DoubleBuffer
import space.kscience.plotly.Plotly
import space.kscience.plotly.UnstablePlotlyAPI
@ -25,10 +25,10 @@ fun main() {
}
val polynomial: PiecewisePolynomial<Double> = SplineInterpolator(
DoubleField, ::DoubleBuffer
Float64Field, ::DoubleBuffer
).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(
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.splineInterpolator
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.real.map
import space.kscience.kmath.real.step
import space.kscience.plotly.Plotly
@ -28,9 +28,9 @@ fun main() {
val xs = 0.0..100.0 step 0.5
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 {
scatter {

View File

@ -15,13 +15,13 @@ import space.kscience.kmath.viktor.ViktorStructureND
import space.kscience.kmath.viktor.viktorAlgebra
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
}
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
}

View File

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

View File

@ -10,7 +10,7 @@ import kotlinx.coroutines.GlobalScope
import org.nd4j.linalg.factory.Nd4j
import space.kscience.kmath.nd.*
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.viktor.ViktorFieldND
import kotlin.contracts.InvocationKind
@ -33,15 +33,15 @@ fun main() {
// 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.
val genericField = BufferedFieldOpsND(DoubleField)
val genericField = BufferedFieldOpsND(Float64Field)
// Nd4j specialized field.
val nd4jField = DoubleField.nd4j
val nd4jField = Float64Field.nd4j
//viktor field
val viktorField = ViktorFieldND(dim, dim)
//parallel processing based on Java Streams
val parallelField = DoubleField.ndStreaming(dim, dim)
val parallelField = Float64Field.ndStreaming(dim, dim)
measureAndPrint("Boxing addition") {
genericField {

View File

@ -7,8 +7,8 @@ package space.kscience.kmath.structures
import space.kscience.kmath.PerformancePitfall
import space.kscience.kmath.nd.*
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.ExtendedField
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.NumbersAddOps
import java.util.*
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
* execution.
*/
class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, DoubleField>,
class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, Float64Field>,
NumbersAddOps<StructureND<Double>>,
ExtendedField<StructureND<Double>> {
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 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)) }
}
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 index = strides.index(offset)
DoubleField.initializer(index)
Float64Field.initializer(index)
}.toArray()
return BufferND(strides, array.asBuffer())
@ -54,18 +54,18 @@ class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, DoubleF
@OptIn(PerformancePitfall::class)
override fun StructureND<Double>.map(
transform: DoubleField.(Double) -> Double,
transform: Float64Field.(Double) -> 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())
}
@OptIn(PerformancePitfall::class)
override fun StructureND<Double>.mapIndexed(
transform: DoubleField.(index: IntArray, Double) -> Double,
transform: Float64Field.(index: IntArray, Double) -> Double,
): BufferND<Double> {
val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
DoubleField.transform(
Float64Field.transform(
strides.index(offset),
buffer.array[offset]
)
@ -78,10 +78,10 @@ class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, DoubleF
override fun zip(
left: StructureND<Double>,
right: StructureND<Double>,
transform: DoubleField.(Double, Double) -> Double,
transform: Float64Field.(Double, Double) -> Double,
): BufferND<Double> {
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()
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) }
}
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
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.buffer
import space.kscience.kmath.operations.bufferAlgebra
import space.kscience.kmath.operations.withSize
@ -17,7 +17,7 @@ inline fun <reified R : Any> MutableBuffer.Companion.same(
fun main() {
with(DoubleField.bufferAlgebra.withSize(5)) {
with(Float64Field.bufferAlgebra.withSize(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.Symbol.Companion.x
import space.kscience.kmath.expressions.interpret
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.IntRing
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.Int32Ring
import space.kscience.kmath.operations.invoke
import kotlin.test.Test
import kotlin.test.assertEquals
@ -32,8 +32,8 @@ internal class TestCompilerConsistencyWithInterpreter {
}
assertEquals(
mst.interpret(IntRing, x to 3),
mst.compile(IntRing, x to 3),
mst.interpret(Int32Ring, x to 3),
mst.compile(Int32Ring, x to 3),
)
}
@ -48,8 +48,8 @@ internal class TestCompilerConsistencyWithInterpreter {
}
assertEquals(
mst.interpret(DoubleField, x to 2.0),
mst.compile(DoubleField, x to 2.0),
mst.interpret(Float64Field, 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.Symbol.Companion.x
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 kotlin.test.Test
import kotlin.test.assertEquals
@ -16,73 +16,73 @@ import kotlin.test.assertEquals
internal class TestCompilerOperations {
@Test
fun testUnaryPlus() = runCompilerTest {
val expr = MstExtendedField { +x }.compileToExpression(DoubleField)
val expr = MstExtendedField { +x }.compileToExpression(Float64Field)
assertEquals(2.0, expr(x to 2.0))
}
@Test
fun testUnaryMinus() = runCompilerTest {
val expr = MstExtendedField { -x }.compileToExpression(DoubleField)
val expr = MstExtendedField { -x }.compileToExpression(Float64Field)
assertEquals(-2.0, expr(x to 2.0))
}
@Test
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))
}
@Test
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))
}
@Test
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))
}
@Test
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))
}
@Test
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))
}
@Test
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))
}
@Test
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))
}
@Test
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))
}
@Test
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))
}
@Test
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))
}
}

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.y
import space.kscience.kmath.expressions.invoke
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.IntRing
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.Int32Ring
import space.kscience.kmath.operations.invoke
import kotlin.test.Test
import kotlin.test.assertEquals
@ -19,25 +19,25 @@ import kotlin.test.assertFailsWith
internal class TestCompilerVariables {
@Test
fun testNoVariables() = runCompilerTest {
val expr = "0".parseMath().compileToExpression(DoubleField)
val expr = "0".parseMath().compileToExpression(Float64Field)
assertEquals(0.0, expr(), 0.0001)
}
@Test
fun testOneVariable() = runCompilerTest {
val expr = MstRing { x }.compileToExpression(IntRing)
val expr = MstRing { x }.compileToExpression(Int32Ring)
assertEquals(1, expr(x to 1))
}
@Test
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))
}
@Test
fun testUndefinedVariableFails() = runCompilerTest {
val expr = MstRing { x }.compileToExpression(IntRing)
val expr = MstRing { x }.compileToExpression(Int32Ring)
assertFailsWith<NoSuchElementException> { expr() }
}
}

View File

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

View File

@ -9,7 +9,7 @@ import space.kscience.kmath.complex.Complex
import space.kscience.kmath.complex.ComplexField
import space.kscience.kmath.expressions.interpret
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.assertEquals
@ -32,7 +32,7 @@ internal class TestParser {
@Test
fun evaluateMstUnary() {
val mst = "sin(0)".parseMath()
val res = mst.interpret(DoubleField)
val res = mst.interpret(Float64Field)
assertEquals(0.0, res)
}

View File

@ -6,7 +6,7 @@
package space.kscience.kmath.ast
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.assertEquals
@ -36,6 +36,6 @@ internal class TestParserPrecedence {
fun test8(): Unit = assertEquals(18.0, "2*2^3+2".parseMath().interpret(f))
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.MST
import space.kscience.kmath.expressions.Symbol
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.IntRing
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.Int32Ring
internal interface CompilerTestContext {
fun MST.compileToExpression(algebra: IntRing): Expression<Int>
fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int
fun MST.compile(algebra: IntRing, vararg arguments: Pair<Symbol, Int>): Int = compile(algebra, mapOf(*arguments))
fun MST.compileToExpression(algebra: DoubleField): Expression<Double>
fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double
fun MST.compileToExpression(algebra: Int32Ring): Expression<Int>
fun MST.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int
fun MST.compile(algebra: Int32Ring, vararg arguments: Pair<Symbol, Int>): Int = compile(algebra, mapOf(*arguments))
fun MST.compileToExpression(algebra: Float64Field): Expression<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))
}

View File

@ -86,7 +86,7 @@ internal sealed class WasmBuilder<T : Number, out E : Expression<T>>(
@UnstableKMathAPI
internal class DoubleWasmBuilder(target: TypedMst<Double>) :
WasmBuilder<Double, DoubleExpression>(f64, DoubleField, target) {
WasmBuilder<Double, DoubleExpression>(f64, Float64Field, target) {
override val instance by lazy {
object : DoubleExpression {
override val indexer = SimpleSymbolIndexer(keys)
@ -131,7 +131,7 @@ internal class DoubleWasmBuilder(target: TypedMst<Double>) :
}
@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 {
object : IntExpression {
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.evaluateConstants
import space.kscience.kmath.expressions.*
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.IntRing
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.Int32Ring
import space.kscience.kmath.wasm.internal.DoubleWasmBuilder
import space.kscience.kmath.wasm.internal.IntWasmBuilder
@ -22,7 +22,7 @@ import space.kscience.kmath.wasm.internal.IntWasmBuilder
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public fun MST.compileToExpression(algebra: IntRing): IntExpression {
public fun MST.compileToExpression(algebra: Int32Ring): IntExpression {
val typed = evaluateConstants(algebra)
return if (typed is TypedMst.Constant) object : IntExpression {
@ -39,7 +39,7 @@ public fun MST.compileToExpression(algebra: IntRing): IntExpression {
* @author Iaroslav Postovalov
*/
@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)
@ -49,7 +49,7 @@ public fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int =
* @author Iaroslav Postovalov
*/
@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)
/**
@ -58,7 +58,7 @@ public fun MST.compile(algebra: IntRing, vararg arguments: Pair<Symbol, Int>): I
* @author Iaroslav Postovalov
*/
@UnstableKMathAPI
public fun MST.compileToExpression(algebra: DoubleField): Expression<Double> {
public fun MST.compileToExpression(algebra: Float64Field): Expression<Double> {
val typed = evaluateConstants(algebra)
return if (typed is TypedMst.Constant) object : DoubleExpression {
@ -76,7 +76,7 @@ public fun MST.compileToExpression(algebra: DoubleField): Expression<Double> {
* @author Iaroslav Postovalov
*/
@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)
@ -86,5 +86,5 @@ public fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Do
* @author Iaroslav Postovalov
*/
@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)

View File

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

View File

@ -10,8 +10,8 @@ import space.kscience.kmath.expressions.MstExtendedField
import space.kscience.kmath.expressions.MstRing
import space.kscience.kmath.expressions.invoke
import space.kscience.kmath.expressions.symbol
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.IntRing
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.Int32Ring
import space.kscience.kmath.operations.invoke
import kotlin.test.Test
import kotlin.test.assertEquals
@ -20,20 +20,20 @@ import kotlin.test.assertEquals
internal class TestWasmSpecific {
@Test
fun int() {
val res = MstRing { number(100000000) + number(10000000) }.compile(IntRing)
val res = MstRing { number(100000000) + number(10000000) }.compile(Int32Ring)
assertEquals(110000000, res)
}
@Test
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)
}
@Test
fun argsPassing() {
val res = MstExtendedField { y + x.pow(10) }.compile(
DoubleField,
Float64Field,
x to 2.0,
y to 100000000.0,
)
@ -43,7 +43,7 @@ internal class TestWasmSpecific {
@Test
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))
}

View File

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

View File

@ -382,7 +382,7 @@ internal sealed class PrimitiveAsmBuilder<T : Number, out E : Expression<T>>(
@UnstableKMathAPI
internal class DoubleAsmBuilder(target: TypedMst<Double>) : PrimitiveAsmBuilder<Double, DoubleExpression>(
DoubleField,
Float64Field,
java.lang.Double::class.java,
java.lang.Double.TYPE,
DoubleExpression::class.java,
@ -457,7 +457,7 @@ internal class DoubleAsmBuilder(target: TypedMst<Double>) : PrimitiveAsmBuilder<
@UnstableKMathAPI
internal class IntAsmBuilder(target: TypedMst<Int>) :
PrimitiveAsmBuilder<Int, IntExpression>(
IntRing,
Int32Ring,
Integer::class.java,
Integer.TYPE,
IntExpression::class.java,
@ -487,7 +487,7 @@ internal class IntAsmBuilder(target: TypedMst<Int>) :
@UnstableKMathAPI
internal class LongAsmBuilder(target: TypedMst<Long>) : PrimitiveAsmBuilder<Long, LongExpression>(
LongRing,
Int64Ring,
java.lang.Long::class.java,
java.lang.Long.TYPE,
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.Symbol
import space.kscience.kmath.operations.Algebra
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.IntRing
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.Int32Ring
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
import space.kscience.kmath.asm.compile as asmCompile
import space.kscience.kmath.asm.compileToExpression as asmCompileToExpression
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>)
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)
override fun MST.compileToExpression(algebra: DoubleField): Expression<Double> =
override fun MST.compileToExpression(algebra: Float64Field): Expression<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)
}
@OptIn(UnstableKMathAPI::class)
private object PrimitiveAsmCompilerTestContext : CompilerTestContext {
override fun MST.compileToExpression(algebra: IntRing): Expression<Int> = asmCompileToExpression(algebra)
override fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = asmCompile(algebra, arguments)
override fun MST.compileToExpression(algebra: DoubleField): Expression<Double> = asmCompileToExpression(algebra)
override fun MST.compileToExpression(algebra: Int32Ring): Expression<Int> = asmCompileToExpression(algebra)
override fun MST.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int = asmCompile(algebra, arguments)
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)
}

View File

@ -9,7 +9,7 @@ import org.apache.commons.math3.linear.*
import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.linear.*
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.DoubleBuffer
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 object CMLinearSpace : LinearSpace<Double, DoubleField> {
override val elementAlgebra: DoubleField get() = DoubleField
public object CMLinearSpace : LinearSpace<Double, Float64Field> {
override val elementAlgebra: Float64Field get() = Float64Field
override fun buildMatrix(
rows: Int,
columns: Int,
initializer: DoubleField.(i: Int, j: Int) -> Double,
initializer: Float64Field.(i: Int, j: Int) -> Double,
): 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))
}
@ -65,8 +65,8 @@ public object CMLinearSpace : LinearSpace<Double, DoubleField> {
internal fun RealMatrix.wrap(): CMMatrix = CMMatrix(this)
internal fun RealVector.wrap(): CMVector = CMVector(this)
override fun buildVector(size: Int, initializer: DoubleField.(Int) -> Double): Point<Double> =
ArrayRealVector(DoubleArray(size) { DoubleField.initializer(it) }).wrap()
override fun buildVector(size: Int, initializer: Float64Field.(Int) -> Double): Point<Double> =
ArrayRealVector(DoubleArray(size) { Float64Field.initializer(it) }).wrap()
override fun Matrix<Double>.plus(other: Matrix<Double>): CMMatrix =
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.integration.integrate
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.abs
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.symbol
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.random.RandomGenerator
import space.kscience.kmath.stat.chiSquaredExpression
@ -24,7 +24,7 @@ import kotlin.test.Test
@OptIn(UnstableKMathAPI::class)
internal class OptimizeTest {
val normal = DSFieldExpression(DoubleField) {
val normal = DSFieldExpression(Float64Field) {
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
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>,
): Expression<T> = FunctionalExpressionExtendedField(this).block()
public inline fun DoubleField.expression(
block: FunctionalExpressionExtendedField<Double, DoubleField>.() -> Expression<Double>,
public inline fun Float64Field.expression(
block: FunctionalExpressionExtendedField<Double, Float64Field>.() -> Expression<Double>,
): 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.nd.*
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.structures.Buffer
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(
rows: 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) ->
DoubleField.initializer(i, j)
Float64Field.initializer(i, j)
}.as2D()
override fun buildVector(size: Int, initializer: DoubleField.(Int) -> Double): DoubleBuffer =
DoubleBuffer(size) { DoubleField.initializer(it) }
override fun buildVector(size: Int, initializer: Float64Field.(Int) -> Double): DoubleBuffer =
DoubleBuffer(size) { Float64Field.initializer(it) }
override fun Matrix<Double>.unaryMinus(): Matrix<Double> = DoubleFieldOpsND {
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,
): LupDecomposition<T> = lup(MutableBuffer.Companion::auto, matrix, checkSingular)
public fun LinearSpace<Double, DoubleField>.lup(
public fun LinearSpace<Double, Float64Field>.lup(
matrix: Matrix<Double>,
singularityThreshold: Double = 1e-11,
): 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))
}
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 }

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 =
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 {
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>> {
@OptIn(PerformancePitfall::class)
@ -63,18 +63,18 @@ public sealed class DoubleFieldOpsND : BufferedFieldOpsND<Double, DoubleField>(D
}
@OptIn(PerformancePitfall::class)
override fun StructureND<Double>.map(transform: DoubleField.(Double) -> Double): BufferND<Double> =
mapInline(toBufferND()) { DoubleField.transform(it) }
override fun StructureND<Double>.map(transform: Float64Field.(Double) -> Double): BufferND<Double> =
mapInline(toBufferND()) { Float64Field.transform(it) }
@OptIn(PerformancePitfall::class)
override fun zip(
left: StructureND<Double>,
right: StructureND<Double>,
transform: DoubleField.(Double, Double) -> Double,
): BufferND<Double> = zipInline(left.toBufferND(), right.toBufferND()) { l, r -> DoubleField.transform(l, r) }
transform: Float64Field.(Double, Double) -> Double,
): 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)
return DoubleBufferND(
indexer,
@ -190,7 +190,7 @@ public sealed class DoubleFieldOpsND : BufferedFieldOpsND<Double, DoubleField>(D
@OptIn(UnstableKMathAPI::class)
public class DoubleFieldND(override val shape: ShapeND) :
DoubleFieldOpsND(), FieldND<Double, DoubleField>, NumbersAddOps<StructureND<Double>>,
DoubleFieldOpsND(), FieldND<Double, Float64Field>, NumbersAddOps<StructureND<Double>>,
ExtendedField<StructureND<Double>> {
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 DoubleField.ndAlgebra(shape: ShapeND): DoubleFieldND = DoubleFieldND(shape)
public fun Float64Field.ndAlgebra(vararg shape: Int): DoubleFieldND = DoubleFieldND(ShapeND(shape))
public fun Float64Field.ndAlgebra(shape: ShapeND): DoubleFieldND = DoubleFieldND(shape)
/**
* Produce a context for n-dimensional operations inside this real field
*/
@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) }
return DoubleFieldND(ShapeND(shape)).run(action)
}

View File

@ -6,7 +6,7 @@
package space.kscience.kmath.nd
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.bufferAlgebra
import space.kscience.kmath.structures.IntBuffer
@ -18,9 +18,9 @@ public class IntBufferND(
override val buffer: IntBuffer,
) : 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)
return IntBufferND(
indexer,
@ -36,7 +36,7 @@ public sealed class IntRingOpsND : BufferedRingOpsND<Int, IntRing>(IntRing.buffe
@OptIn(UnstableKMathAPI::class)
public class IntRingND(
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> {
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) }
return IntRingND(ShapeND(shape)).run(action)
}

View File

@ -6,20 +6,20 @@
package space.kscience.kmath.nd
import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.operations.Int16Ring
import space.kscience.kmath.operations.NumbersAddOps
import space.kscience.kmath.operations.ShortRing
import space.kscience.kmath.operations.bufferAlgebra
import kotlin.contracts.InvocationKind
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()
}
@OptIn(UnstableKMathAPI::class)
public class ShortRingND(
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> {
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) }
return ShortRingND(ShapeND(shape)).run(action)
}

View File

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

View File

@ -14,32 +14,32 @@ import kotlin.math.sqrt
/**
* [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> {
override val elementAlgebra: DoubleField get() = DoubleField
override val elementAlgebra: Float64Field get() = Float64Field
override val elementBufferFactory: MutableBufferFactory<Double> get() = elementAlgebra.bufferFactory
@Suppress("OVERRIDE_BY_INLINE")
@OptIn(UnstableKMathAPI::class)
final override inline fun Buffer<Double>.map(block: DoubleField.(Double) -> Double): DoubleBuffer =
DoubleArray(size) { DoubleField.block(getDouble(it)) }.asBuffer()
final override inline fun Buffer<Double>.map(block: Float64Field.(Double) -> Double): DoubleBuffer =
DoubleArray(size) { Float64Field.block(getDouble(it)) }.asBuffer()
@OptIn(UnstableKMathAPI::class)
@Suppress("OVERRIDE_BY_INLINE")
final override inline fun Buffer<Double>.mapIndexed(block: DoubleField.(index: Int, arg: Double) -> Double): DoubleBuffer =
DoubleBuffer(size) { DoubleField.block(it, getDouble(it)) }
final override inline fun Buffer<Double>.mapIndexed(block: Float64Field.(index: Int, arg: Double) -> Double): DoubleBuffer =
DoubleBuffer(size) { Float64Field.block(it, getDouble(it)) }
@OptIn(UnstableKMathAPI::class)
@Suppress("OVERRIDE_BY_INLINE")
final override inline fun Buffer<Double>.zip(
other: Buffer<Double>,
block: DoubleField.(left: Double, right: Double) -> Double,
block: Float64Field.(left: Double, right: Double) -> Double,
): DoubleBuffer {
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> =

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.
* 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
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.
*/
@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 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
}
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.
*/
@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 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
}
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.
*/
@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 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
}
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.
*/
@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 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()
}
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.
@ -249,10 +256,10 @@ public object ByteRing : Ring<Byte>, Norm<Byte, Byte>, NumericAlgebra<Byte> {
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")
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 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)
}
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].
* 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
import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Float64Field
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
import kotlin.test.Test
@ -18,10 +18,10 @@ import kotlin.test.assertFails
internal inline fun diff(
order: Int,
vararg parameters: Pair<Symbol, Double>,
block: DSField<Double, DoubleField>.() -> Unit,
block: DSField<Double, Float64Field>.() -> Unit,
) {
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
DSField(DoubleField, order, mapOf(*parameters)).block()
DSField(Float64Field, order, mapOf(*parameters)).block()
}
internal class DSTest {
@ -44,7 +44,7 @@ internal class DSTest {
@Test
fun dsExpressionTest() {
val f = DSFieldExpression(DoubleField) {
val f = DSFieldExpression(Float64Field) {
val x by binding
val y by binding
x.pow(2) + 2 * x * y + y.pow(2) + 1

View File

@ -5,7 +5,7 @@
package space.kscience.kmath.expressions
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Float64Field
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFails
@ -15,7 +15,7 @@ class ExpressionFieldTest {
@Test
fun testExpression() {
val expression = with(FunctionalExpressionField(DoubleField)) {
val expression = with(FunctionalExpressionField(Float64Field)) {
val x by binding
x * x + 2 * x + one
}
@ -31,7 +31,7 @@ class ExpressionFieldTest {
return x * x + 2 * x + one
}
val expression = FunctionalExpressionField(DoubleField).expression()
val expression = FunctionalExpressionField(Float64Field).expression()
assertEquals(expression(x to 1.0), 4.0)
}
@ -42,7 +42,7 @@ class ExpressionFieldTest {
x * x + 2 * x + one
}
val expression = FunctionalExpressionField(DoubleField).expressionBuilder()
val expression = FunctionalExpressionField(Float64Field).expressionBuilder()
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.expressions.Symbol.Companion.x
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 kotlin.test.Test
import kotlin.test.assertEquals
@ -19,7 +19,7 @@ internal class InterpretTest {
fun interpretation() {
val expr = MstField {
x * 2.0 + number(2.0) / x - 16.0
}.toExpression(DoubleField)
}.toExpression(Float64Field)
assertEquals(-10.69, expr(x to 2.2), 0.02)
}

View File

@ -5,7 +5,7 @@
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.structures.Buffer
import space.kscience.kmath.structures.asBuffer
@ -21,19 +21,19 @@ internal class SimpleAutoDiffTest {
fun dx(
xBinding: Pair<Symbol, Double>,
body: SimpleAutoDiffField<Double, DoubleField>.(x: AutoDiffValue<Double>) -> AutoDiffValue<Double>,
): DerivationResult<Double> = DoubleField.simpleAutoDiff(xBinding) { body(bindSymbol(xBinding.first)) }
body: SimpleAutoDiffField<Double, Float64Field>.(x: AutoDiffValue<Double>) -> AutoDiffValue<Double>,
): DerivationResult<Double> = Float64Field.simpleAutoDiff(xBinding) { body(bindSymbol(xBinding.first)) }
fun dxy(
xBinding: Pair<Symbol, Double>,
yBinding: Pair<Symbol, Double>,
body: SimpleAutoDiffField<Double, DoubleField>.(x: AutoDiffValue<Double>, y: AutoDiffValue<Double>) -> AutoDiffValue<Double>,
): DerivationResult<Double> = DoubleField.simpleAutoDiff(xBinding, yBinding) {
body: SimpleAutoDiffField<Double, Float64Field>.(x: AutoDiffValue<Double>, y: AutoDiffValue<Double>) -> AutoDiffValue<Double>,
): DerivationResult<Double> = Float64Field.simpleAutoDiff(xBinding, yBinding) {
body(bindSymbol(xBinding.first), bindSymbol(yBinding.first))
}
fun diff(block: SimpleAutoDiffField<Double, DoubleField>.() -> AutoDiffValue<Double>): SimpleAutoDiffExpression<Double, DoubleField> {
return SimpleAutoDiffExpression(DoubleField, block)
fun diff(block: SimpleAutoDiffField<Double, Float64Field>.() -> AutoDiffValue<Double>): SimpleAutoDiffExpression<Double, Float64Field> {
return SimpleAutoDiffExpression(Float64Field, block)
}
val x by symbol
@ -42,7 +42,7 @@ internal class SimpleAutoDiffTest {
@Test
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
val x = bindSymbol(x)
x + x
@ -65,7 +65,7 @@ internal class SimpleAutoDiffTest {
@Test
fun testPlus() {
// 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 y = bindSymbol(y)
x + y
@ -78,7 +78,7 @@ internal class SimpleAutoDiffTest {
@Test
fun testMinus() {
// 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 y = bindSymbol(y)

View File

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

View File

@ -11,16 +11,16 @@ import kotlin.test.assertEquals
internal class DoubleFieldTest {
@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
fun testSqrt() {
val sqrt = DoubleField { sqrt(25 * one) }
val sqrt = Float64Field { sqrt(25 * one) }
assertEquals(5.0, sqrt)
}
@Test
fun testPow() = DoubleField {
fun testPow() = Float64Field {
val num = 5 * one
assertEquals(5.0, power(num, 1), 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.ndAlgebra
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.testutils.FieldVerifier
import kotlin.test.Test
@ -17,12 +17,12 @@ import kotlin.test.assertEquals
internal class NDFieldTest {
@Test
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
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)
}
}

View File

@ -11,7 +11,7 @@ import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.get
import space.kscience.kmath.nd.ndAlgebra
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.algebra
import space.kscience.kmath.operations.invoke
@ -25,7 +25,7 @@ import kotlin.test.assertEquals
@OptIn(PerformancePitfall::class)
@Suppress("UNUSED_VARIABLE")
class NumberNDFieldTest {
val algebra = DoubleField.ndAlgebra
val algebra = Float64Field.ndAlgebra
val array1 = 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
fun testInternalContext() {
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.nd.ShapeND
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.algebra
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()
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
*/
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 ->
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 { _, _ ->
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.LinearSolverFactory_DSCC
import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC
import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.linear.*
import space.kscience.kmath.linear.Matrix
import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.nd.StructureFeature
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.FloatField
import space.kscience.kmath.operations.Float32Field
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.invoke
import space.kscience.kmath.structures.DoubleBuffer
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
* [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")
override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixRMaj> = when {
@ -94,7 +94,7 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, DoubleField, DMatrix
override fun buildMatrix(
rows: Int,
columns: Int,
initializer: DoubleField.(i: Int, j: Int) -> Double,
initializer: Float64Field.(i: Int, j: Int) -> Double,
): EjmlDoubleMatrix<DMatrixRMaj> = DMatrixRMaj(rows, columns).also {
(0 until rows).forEach { row ->
(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(
size: Int,
initializer: DoubleField.(Int) -> Double,
initializer: Float64Field.(Int) -> Double,
): EjmlDoubleVector<DMatrixRMaj> = EjmlDoubleVector(DMatrixRMaj(size, 1).also {
(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
* [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")
override fun Matrix<Float>.toEjml(): EjmlFloatMatrix<FMatrixRMaj> = when {
@ -330,7 +330,7 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, FloatField, FMatrixRM
override fun buildMatrix(
rows: Int,
columns: Int,
initializer: FloatField.(i: Int, j: Int) -> Float,
initializer: Float32Field.(i: Int, j: Int) -> Float,
): EjmlFloatMatrix<FMatrixRMaj> = FMatrixRMaj(rows, columns).also {
(0 until rows).forEach { row ->
(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(
size: Int,
initializer: FloatField.(Int) -> Float,
initializer: Float32Field.(Int) -> Float,
): EjmlFloatVector<FMatrixRMaj> = EjmlFloatVector(FMatrixRMaj(size, 1).also {
(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
* [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")
override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixSparseCSC> = when {
@ -566,7 +566,7 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, DoubleField, DMatrix
override fun buildMatrix(
rows: Int,
columns: Int,
initializer: DoubleField.(i: Int, j: Int) -> Double,
initializer: Float64Field.(i: Int, j: Int) -> Double,
): EjmlDoubleMatrix<DMatrixSparseCSC> = DMatrixSparseCSC(rows, columns).also {
(0 until rows).forEach { row ->
(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(
size: Int,
initializer: DoubleField.(Int) -> Double,
initializer: Float64Field.(Int) -> Double,
): EjmlDoubleVector<DMatrixSparseCSC> = EjmlDoubleVector(DMatrixSparseCSC(size, 1).also {
(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
* [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")
override fun Matrix<Float>.toEjml(): EjmlFloatMatrix<FMatrixSparseCSC> = when {
@ -797,7 +797,7 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, FloatField, FMatrixSp
override fun buildMatrix(
rows: Int,
columns: Int,
initializer: FloatField.(i: Int, j: Int) -> Float,
initializer: Float32Field.(i: Int, j: Int) -> Float,
): EjmlFloatMatrix<FMatrixSparseCSC> = FMatrixSparseCSC(rows, columns).also {
(0 until rows).forEach { row ->
(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(
size: Int,
initializer: FloatField.(Int) -> Float,
initializer: Float32Field.(Int) -> Float,
): EjmlFloatVector<FMatrixSparseCSC> = EjmlFloatVector(FMatrixSparseCSC(size, 1).also {
(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.UnstableKMathAPI
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.asIterable
import space.kscience.kmath.structures.Buffer
@ -32,11 +32,11 @@ import kotlin.math.pow
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)
@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)
public fun Array<DoubleArray>.toMatrix(): RealMatrix {

View File

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

View File

@ -6,8 +6,8 @@
package space.kscience.kmath.integration
import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Field
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.invoke
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> {
override fun process(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> {
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 numPoints = integrand.getFeature<IntegrandMaxCalls>()?.maxCalls ?: 100
@ -95,12 +95,12 @@ public object DoubleSplineIntegrator : UnivariateIntegrator<Double> {
val values = nodes.mapToBuffer(::DoubleBuffer) { integrand.function(it) }
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)
}
}
@Suppress("unused")
@UnstableKMathAPI
public inline val DoubleField.splineIntegrator: UnivariateIntegrator<Double>
public inline val Float64Field.splineIntegrator: UnivariateIntegrator<Double>
get() = DoubleSplineIntegrator

View File

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

View File

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

View File

@ -6,7 +6,7 @@
package space.kscience.kmath.integration
import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Float64Field
import kotlin.math.PI
import kotlin.math.sin
import kotlin.test.Test
@ -16,7 +16,7 @@ import kotlin.test.assertEquals
class SimpsonIntegralTest {
@Test
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)
}
assertEquals(0.0, res.value, 1e-2)
@ -24,7 +24,7 @@ class SimpsonIntegralTest {
@Test
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) {
1.0
} else {

View File

@ -8,7 +8,7 @@ package space.kscience.kmath.integration
import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.functions.Polynomial
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.sin
import kotlin.test.Test
@ -20,13 +20,13 @@ class SplineIntegralTest {
@Test
fun integratePolynomial(){
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)
}
@Test
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)
}
assertEquals(0.0, res.value, 1e-2)
@ -34,7 +34,7 @@ class SplineIntegralTest {
@Test
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){
1.0
} else {

View File

@ -5,7 +5,7 @@
package space.kscience.kmath.interpolation
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Float64Field
import kotlin.test.Test
import kotlin.test.assertEquals
@ -20,7 +20,7 @@ internal class LinearInterpolatorTest {
)
//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(0.5, function(0.5))
assertEquals(2.0, function(1.5))

View File

@ -5,7 +5,7 @@
package space.kscience.kmath.interpolation
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Float64Field
import kotlin.math.PI
import kotlin.math.sin
import kotlin.test.Test
@ -21,7 +21,7 @@ internal class SplineInterpolatorTest {
//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(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.linearSpace
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.sqrt
@ -66,7 +66,7 @@ public fun Euclidean3DSpace.rotate(vector: DoubleVector3D, composition: Quaterni
public fun Euclidean3DSpace.rotate(vector: DoubleVector3D, matrix: Matrix<Double>): DoubleVector3D {
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)
public fun Quaternion.toRotationMatrix(
linearSpace: LinearSpace<Double, *> = DoubleField.linearSpace,
linearSpace: LinearSpace<Double, *> = Float64Field.linearSpace,
): Matrix<Double> {
val s = QuaternionField.norm(this).pow(-2)
return linearSpace.matrix(3, 3)(

View File

@ -7,7 +7,7 @@ package space.kscience.kmath.histogram
import kotlinx.atomicfu.atomic
import kotlinx.atomicfu.getAndUpdate
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.Group
/**
@ -18,7 +18,7 @@ public interface Counter<T : Any> {
public val value: T
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)
}
}

View File

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

View File

@ -9,7 +9,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import space.kscience.kmath.UnstableKMathAPI
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.stat.nextBuffer
import kotlin.native.concurrent.ThreadLocal
@ -22,7 +22,7 @@ internal class UniformHistogram1DTest {
@Test
fun normal() = runTest {
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 h2 = produce(distribution.nextBuffer(generator, 50000))
@ -35,16 +35,16 @@ internal class UniformHistogram1DTest {
@Test
fun rebinDown() = runTest {
val h1 = Histogram.uniform1D(DoubleField, 0.01).produce(generator.nextDoubleBuffer(10000))
val h2 = Histogram.uniform1D(DoubleField, 0.03).produceFrom(h1)
val h1 = Histogram.uniform1D(Float64Field, 0.01).produce(generator.nextDoubleBuffer(10000))
val h2 = Histogram.uniform1D(Float64Field, 0.03).produceFrom(h1)
assertEquals(10000, h2.bins.sumOf { it.binValue }.toInt())
}
@Test
fun rebinUp() = runTest {
val h1 = Histogram.uniform1D(DoubleField, 0.03).produce(generator.nextDoubleBuffer(10000))
val h2 = Histogram.uniform1D(DoubleField, 0.01).produceFrom(h1)
val h1 = Histogram.uniform1D(Float64Field, 0.03).produce(generator.nextDoubleBuffer(10000))
val h2 = Histogram.uniform1D(Float64Field, 0.01).produceFrom(h1)
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 space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.real.step
import kotlin.random.Random
import kotlin.test.assertEquals
@ -19,7 +19,7 @@ class TreeHistogramTest {
@Test
fun normalFill() {
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) {
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.Symbol.Companion.x
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.assertEquals
import kotlin.test.assertTrue
@ -22,8 +22,8 @@ import kotlin.test.fail
internal class AdaptingTests {
@Test
fun symbol() {
assertEquals(x.identity, x.toSVar<KMathNumber<Double, DoubleField>>().name)
val c2 = "kitten".parseMath().toSFun<KMathNumber<Double, DoubleField>>()
assertEquals(x.identity, x.toSVar<KMathNumber<Double, Float64Field>>().name)
val c2 = "kitten".parseMath().toSFun<KMathNumber<Double, Float64Field>>()
if (c2 is SVar<*>) assertTrue(c2.name == "kitten") else fail()
}
@ -31,15 +31,15 @@ internal class AdaptingTests {
fun number() {
val c1 = MstNumericAlgebra.number(12354324)
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()
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()
}
@Test
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.left !is Prod<*>) fail()
if (linear.right !is SConst<*>) fail()
@ -47,22 +47,22 @@ internal class AdaptingTests {
@Test
fun simpleFunctionDerivative() {
val xSVar = x.toSVar<KMathNumber<Double, DoubleField>>()
val quadratic = "x^2-4*x-44".parseMath().toSFun<KMathNumber<Double, DoubleField>>()
val actualDerivative = quadratic.d(xSVar).toMst().compileToExpression(DoubleField)
val expectedDerivative = "2*x-4".parseMath().compileToExpression(DoubleField)
val xSVar = x.toSVar<KMathNumber<Double, Float64Field>>()
val quadratic = "x^2-4*x-44".parseMath().toSFun<KMathNumber<Double, Float64Field>>()
val actualDerivative = quadratic.d(xSVar).toMst().compileToExpression(Float64Field)
val expectedDerivative = "2*x-4".parseMath().compileToExpression(Float64Field)
assertEquals(actualDerivative(x to 123.0), expectedDerivative(x to 123.0))
}
@Test
fun moreComplexDerivative() {
val xSVar = x.toSVar<KMathNumber<Double, DoubleField>>()
val composition = "-sqrt(sin(x^2)-cos(x)^2-16*x)".parseMath().toSFun<KMathNumber<Double, DoubleField>>()
val actualDerivative = composition.d(xSVar).toMst().compileToExpression(DoubleField)
val xSVar = x.toSVar<KMathNumber<Double, Float64Field>>()
val composition = "-sqrt(sin(x^2)-cos(x)^2-16*x)".parseMath().toSFun<KMathNumber<Double, Float64Field>>()
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))"
.parseMath()
.compileToExpression(DoubleField)
.compileToExpression(Float64Field)
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 space.kscience.kmath.PerformancePitfall
import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.ExponentialOperations
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.TrigonometricOperations
public class MultikDoubleAlgebra(
multikEngine: Engine
) : MultikDivisionTensorAlgebra<Double, DoubleField>(multikEngine),
) : MultikDivisionTensorAlgebra<Double, Float64Field>(multikEngine),
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 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.ndarrayOf
import org.jetbrains.kotlinx.multik.ndarray.data.DataType
import space.kscience.kmath.operations.FloatField
import space.kscience.kmath.operations.Float32Field
public class MultikFloatAlgebra(
multikEngine: Engine
) : MultikDivisionTensorAlgebra<Float, FloatField>(multikEngine) {
override val elementAlgebra: FloatField get() = FloatField
) : MultikDivisionTensorAlgebra<Float, Float32Field>(multikEngine) {
override val elementAlgebra: Float32Field get() = Float32Field
override val type: DataType get() = DataType.FloatDataType
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.ndarrayOf
import org.jetbrains.kotlinx.multik.ndarray.data.DataType
import space.kscience.kmath.operations.IntRing
import space.kscience.kmath.operations.Int32Ring
public class MultikIntAlgebra(
multikEngine: Engine
) : MultikTensorAlgebra<Int, IntRing>(multikEngine) {
override val elementAlgebra: IntRing get() = IntRing
) : MultikTensorAlgebra<Int, Int32Ring>(multikEngine) {
override val elementAlgebra: Int32Ring get() = Int32Ring
override val type: DataType get() = DataType.IntDataType
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.ndarrayOf
import org.jetbrains.kotlinx.multik.ndarray.data.DataType
import space.kscience.kmath.operations.LongRing
import space.kscience.kmath.operations.Int64Ring
public class MultikLongAlgebra(
multikEngine: Engine
) : MultikTensorAlgebra<Long, LongRing>(multikEngine) {
override val elementAlgebra: LongRing get() = LongRing
) : MultikTensorAlgebra<Long, Int64Ring>(multikEngine) {
override val elementAlgebra: Int64Ring get() = Int64Ring
override val type: DataType get() = DataType.LongDataType
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.ndarrayOf
import org.jetbrains.kotlinx.multik.ndarray.data.DataType
import space.kscience.kmath.operations.ShortRing
import space.kscience.kmath.operations.Int16Ring
public class MultikShortAlgebra(
multikEngine: Engine
) : MultikTensorAlgebra<Short, ShortRing>(multikEngine) {
override val elementAlgebra: ShortRing get() = ShortRing
) : MultikTensorAlgebra<Short, Int16Ring>(multikEngine) {
override val elementAlgebra: Int16Ring get() = Int16Ring
override val type: DataType get() = DataType.ShortDataType
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.StructureND
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.randomNormal
import space.kscience.kmath.tensors.core.tensorAlgebra
@ -37,7 +37,7 @@ internal class MultikNDTest {
tensor1 dot tensor2
}
val defaultResult = with(DoubleField.tensorAlgebra) {
val defaultResult = with(Float64Field.tensorAlgebra) {
tensor1 dot tensor2
}

View File

@ -124,7 +124,7 @@ public sealed interface Nd4jArrayRingOps<T, out R : Ring<T>> : RingOpsND<T, R>,
*/
@Suppress("UNCHECKED_CAST")
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.")
}
}
@ -149,8 +149,8 @@ public sealed interface Nd4jArrayField<T, out F : Field<T>> : FieldOpsND<T, F>,
*/
@Suppress("UNCHECKED_CAST")
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 == Double::class -> DoubleField.nd4j as Nd4jArrayField<T, Field<T>>
T::class == Float::class -> Float32Field.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.")
}
}
@ -190,8 +190,8 @@ public sealed interface Nd4jArrayExtendedFieldOps<T, out F : ExtendedField<T>> :
/**
* Represents [FieldND] over [Nd4jArrayDoubleStructure].
*/
public open class DoubleNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Double, DoubleField> {
override val elementAlgebra: DoubleField get() = DoubleField
public open class DoubleNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Double, Float64Field> {
override val elementAlgebra: Float64Field get() = Float64Field
override fun INDArray.wrap(): Nd4jArrayStructure<Double> = asDoubleStructure()
@ -223,19 +223,19 @@ public open class DoubleNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Double, Do
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))
/**
* Represents [FieldND] over [Nd4jArrayStructure] of [Float].
*/
public open class FloatNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Float, FloatField> {
override val elementAlgebra: FloatField get() = FloatField
public open class FloatNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Float, Float32Field> {
override val elementAlgebra: Float32Field get() = Float32Field
override fun INDArray.wrap(): Nd4jArrayStructure<Float> = asFloatStructure()
@ -272,18 +272,18 @@ public open class FloatNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Float, Floa
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))
/**
* Represents [RingND] over [Nd4jArrayIntStructure].
*/
public open class IntNd4jArrayRingOps : Nd4jArrayRingOps<Int, IntRing> {
override val elementAlgebra: IntRing get() = IntRing
public open class IntNd4jArrayRingOps : Nd4jArrayRingOps<Int, Int32Ring> {
override val elementAlgebra: Int32Ring get() = Int32Ring
override fun INDArray.wrap(): Nd4jArrayStructure<Int> = asIntStructure()
@ -311,9 +311,9 @@ public open class IntNd4jArrayRingOps : Nd4jArrayRingOps<Int, IntRing> {
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))

View File

@ -15,8 +15,8 @@ import org.nd4j.linalg.ops.transforms.Transforms
import space.kscience.kmath.PerformancePitfall
import space.kscience.kmath.UnsafeKMathAPI
import space.kscience.kmath.nd.*
import space.kscience.kmath.operations.DoubleField
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.Tensor
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].
*/
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()
@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 indices = ColumnStrides(shape)
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.one
import space.kscience.kmath.nd.structureND
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.IntRing
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.Int32Ring
import space.kscience.kmath.operations.invoke
import kotlin.math.PI
import kotlin.test.Test
@ -23,7 +23,7 @@ import kotlin.test.fail
internal class Nd4jArrayAlgebraTest {
@Test
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()
expected[intArrayOf(0, 0)] = 0.0
expected[intArrayOf(0, 1)] = 1.0
@ -34,7 +34,7 @@ internal class Nd4jArrayAlgebraTest {
@Test
fun testMap() {
val res = IntRing.nd4j {
val res = Int32Ring.nd4j {
one(2, 2).map { it + it * 2 }
}
val expected = (Nd4j.create(2, 2) ?: fail()).asIntStructure()
@ -47,7 +47,7 @@ internal class Nd4jArrayAlgebraTest {
@Test
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()
expected[intArrayOf(0, 0)] = 26
expected[intArrayOf(0, 1)] = 26
@ -57,7 +57,7 @@ internal class Nd4jArrayAlgebraTest {
}
@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 transformed = sin(initial)
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.linear.*
import space.kscience.kmath.misc.log
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.DoubleL2Norm
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.algebra
import space.kscience.kmath.structures.DoubleBuffer
import kotlin.math.abs
@ -32,7 +32,7 @@ public class QowRuns(public val runs: Int) : OptimizationFeature {
@UnstableKMathAPI
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()
@OptIn(UnstableKMathAPI::class)

View File

@ -6,7 +6,7 @@
package space.kscience.kmath.distributions
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.samplers.GaussianSampler
import space.kscience.kmath.samplers.InternalErf

View File

@ -6,7 +6,7 @@
package space.kscience.kmath.series
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 kotlin.math.absoluteValue

View File

@ -13,21 +13,20 @@ import space.kscience.kmath.structures.indices
* Arithmetic mean
*/
public class Mean<T>(
private val group: Ring<T>,
private val division: (sum: T, count: Int) -> T,
private val field: Field<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
for (i in data.indices) {
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 computeIntermediate(data: Buffer<T>): Pair<T, Int> = group {
override suspend fun computeIntermediate(data: Buffer<T>): Pair<T, Int> = with(field) {
var res = zero
for (i in data.indices) {
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> =
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 {
division(intermediate.first, intermediate.second)
override suspend fun toResult(intermediate: Pair<T, Int>): T = with(field) {
intermediate.first/ intermediate.second
}
public companion object {
@Deprecated("Use Double.mean instead")
public val double: Mean<Double> = Mean(DoubleField) { sum, count -> sum / count }
@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)
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)
}
}
//TODO replace with optimized version which respects overflow
public val DoubleField.mean: Mean<Double> get() = Mean(DoubleField) { sum, count -> sum / count }
public val IntRing.mean: Mean<Int> get() = Mean(IntRing) { sum, count -> sum / count }
public val LongRing.mean: Mean<Long> get() = Mean(LongRing) { sum, count -> sum / count }
public val Float64Field.mean: Mean<Double> get() = Mean(Float64Field)
public val Int32Ring.mean: Mean<Int> get() = Mean(Int32Field)
public val Int64Ring.mean: Mean<Long> get() = Mean(Int64Field)

View File

@ -5,17 +5,34 @@
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
/**
* Non-composable median
*/
public class Median<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
public class Median<T>(private val field: Field<T>, private val comparator: Comparator<T>) : BlockingStatistic<T, T> {
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 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
/**
* 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 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.
*
* 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.take
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.chain
import space.kscience.kmath.streaming.chunked
@ -29,20 +29,20 @@ internal class StatisticTest {
@Test
fun singleBlockingMean() {
val first = runBlocking { chunked.first() }
val res = DoubleField.mean(first)
val res = Float64Field.mean(first)
assertEquals(0.5, res, 1e-1)
}
@Test
fun singleSuspendMean() = runBlocking {
val first = runBlocking { chunked.first() }
val res = DoubleField.mean(first)
val res = Float64Field.mean(first)
assertEquals(0.5, res, 1e-1)
}
@Test
fun parallelMean() = runBlocking {
val average = DoubleField.mean
val average = Float64Field.mean
.flow(chunked) //create a flow from evaluated results
.take(100) // Take 100 data chunks from the source and accumulate them
.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.ShapeND
import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.PowerOperations
public class DoubleTensorFlowOutput(
@ -32,13 +32,13 @@ internal fun ShapeND.toLongArray(): LongArray = LongArray(size) { get(it).toLong
public class DoubleTensorFlowAlgebra internal constructor(
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(
shape: ShapeND,
initializer: DoubleField.(IntArray) -> Double,
initializer: Float64Field.(IntArray) -> Double,
): StructureND<Double> {
val res = TFloat64.tensorOf(org.tensorflow.ndarray.Shape.of(*shape.toLongArray())) { array ->
ColumnStrides(shape).forEach { index ->
@ -83,7 +83,7 @@ public class DoubleTensorFlowAlgebra internal constructor(
* The resulting tensor is available outside of scope
*/
@UnstableKMathAPI
public fun DoubleField.produceWithTF(
public fun Float64Field.produceWithTF(
block: DoubleTensorFlowAlgebra.() -> StructureND<Double>,
): StructureND<Double> = Graph().use { graph ->
val scope = DoubleTensorFlowAlgebra(graph)
@ -96,7 +96,7 @@ public fun DoubleField.produceWithTF(
* The resulting tensors are available outside of scope
*/
@OptIn(UnstableKMathAPI::class)
public fun DoubleField.produceMapWithTF(
public fun Float64Field.produceMapWithTF(
block: DoubleTensorFlowAlgebra.() -> Map<Symbol, StructureND<Double>>,
): Map<Symbol, StructureND<Double>> = Graph().use { 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.get
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.Companion.sum
import space.kscience.kmath.tensors.core.randomNormal
@ -20,7 +20,7 @@ import kotlin.test.assertEquals
class DoubleTensorFlowOps {
@Test
fun basicOps() {
val res = DoubleField.produceWithTF {
val res = Float64Field.produceWithTF {
val initial = structureND(2, 2) { 1.0 }
initial + (initial * 2.0)
@ -36,14 +36,14 @@ class DoubleTensorFlowOps {
val tensor1 = DoubleTensorAlgebra.randomNormal(shape = ShapeND(dim, dim), 12224)
val tensor2 = DoubleTensorAlgebra.randomNormal(shape = ShapeND(dim, dim), 12225)
DoubleField.produceWithTF {
Float64Field.produceWithTF {
tensor1 dot tensor2
}.sum()
}
@Test
fun extensionOps(){
val res = DoubleField.produceWithTF {
val res = Float64Field.produceWithTF {
val i = structureND(2, 2) { 0.5 }
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.nd.*
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.tensors.api.AnalyticTensorAlgebra
import space.kscience.kmath.tensors.api.LinearOpsTensorAlgebra
import space.kscience.kmath.tensors.api.Tensor
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.
*/
@OptIn(PerformancePitfall::class)
public open class DoubleTensorAlgebra :
AnalyticTensorAlgebra<Double, DoubleField>,
LinearOpsTensorAlgebra<Double, DoubleField> {
AnalyticTensorAlgebra<Double, Float64Field>,
LinearOpsTensorAlgebra<Double, Float64Field> {
public companion object : DoubleTensorAlgebra()
override val elementAlgebra: DoubleField get() = DoubleField
override val elementAlgebra: Float64Field get() = Float64Field
public val bufferAlgebra: DoubleBufferOps get() = DoubleBufferOps
@ -41,10 +44,10 @@ public open class DoubleTensorAlgebra :
* @return the resulting tensor after applying the function.
*/
@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()
//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(
tensor.shape,
array,
@ -59,12 +62,12 @@ public open class DoubleTensorAlgebra :
}
}
public inline fun Tensor<Double>.mapIndexedInPlace(operation: DoubleField.(IntArray, Double) -> Double) {
indices.forEach { set(it, DoubleField.operation(it, get(it))) }
public inline fun Tensor<Double>.mapIndexedInPlace(operation: Float64Field.(IntArray, Double) -> Double) {
indices.forEach { set(it, Float64Field.operation(it, get(it))) }
}
@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) }
}
@ -73,14 +76,14 @@ public open class DoubleTensorAlgebra :
final override inline fun zip(
left: StructureND<Double>,
right: StructureND<Double>,
transform: DoubleField.(Double, Double) -> Double,
transform: Float64Field.(Double, Double) -> Double,
): DoubleTensor {
checkShapesCompatible(left, right)
val leftTensor = left.asDoubleTensor()
val rightTensor = right.asDoubleTensor()
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)
}
@ -124,9 +127,9 @@ public open class DoubleTensorAlgebra :
* @param initializer mapping tensor indices to values.
* @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,
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 {
@ -717,4 +720,4 @@ public open class 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.nd.*
import space.kscience.kmath.operations.IntRing
import space.kscience.kmath.operations.Int32Ring
import space.kscience.kmath.structures.*
import space.kscience.kmath.tensors.api.*
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.
*/
public open class IntTensorAlgebra : TensorAlgebra<Int, IntRing> {
public open class IntTensorAlgebra : TensorAlgebra<Int, Int32Ring> {
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.
*/
@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()
//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(
tensor.shape,
array,
@ -57,11 +57,11 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, IntRing> {
}
@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()
//TODO remove additional copy
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)
}
@ -70,14 +70,14 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, IntRing> {
final override inline fun zip(
left: StructureND<Int>,
right: StructureND<Int>,
transform: IntRing.(Int, Int) -> Int,
transform: Int32Ring.(Int, Int) -> Int,
): IntTensor {
checkShapesCompatible(left, right)
val leftTensor = left.asIntTensor()
val rightTensor = right.asIntTensor()
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)
}
@ -118,9 +118,9 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, IntRing> {
* @param initializer mapping tensor indices to values.
* @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,
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 {
@ -462,6 +462,6 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, IntRing> {
}
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.UnstableKMathAPI
import space.kscience.kmath.nd.*
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.ExtendedFieldOps
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.NumbersAddOps
import space.kscience.kmath.operations.PowerOperations
@OptIn(UnstableKMathAPI::class, PerformancePitfall::class)
@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
public open class ViktorFieldOpsND :
FieldOpsND<Double, DoubleField>,
FieldOpsND<Double, Float64Field>,
ExtendedFieldOps<StructureND<Double>>,
PowerOperations<StructureND<Double>> {
@ -30,13 +30,13 @@ public open class ViktorFieldOpsND :
else -> structureND(shape) { this@f64Buffer[it] }.f64Buffer
}
override val elementAlgebra: DoubleField get() = DoubleField
override val elementAlgebra: Float64Field get() = Float64Field
@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 {
ColumnStrides(shape).asSequence().forEach { index ->
set(value = DoubleField.initializer(index), indices = index)
set(value = Float64Field.initializer(index), indices = index)
}
}.asStructure()
@ -44,20 +44,20 @@ public open class ViktorFieldOpsND :
@OptIn(UnsafeKMathAPI::class)
@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 {
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()
@OptIn(UnsafeKMathAPI::class)
@PerformancePitfall
override fun StructureND<Double>.mapIndexed(
transform: DoubleField.(index: IntArray, Double) -> Double,
transform: Float64Field.(index: IntArray, Double) -> Double,
): ViktorStructureND = F64Array(*shape.asArray()).apply {
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()
@ -66,12 +66,12 @@ public open class ViktorFieldOpsND :
override fun zip(
left: StructureND<Double>,
right: StructureND<Double>,
transform: DoubleField.(Double, Double) -> Double,
transform: Float64Field.(Double, Double) -> Double,
): ViktorStructureND {
require(left.shape.contentEquals(right.shape))
return F64Array(*left.shape.asArray()).apply {
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()
}
@ -120,12 +120,12 @@ public open class ViktorFieldOpsND :
public companion object : ViktorFieldOpsND()
}
public val DoubleField.viktorAlgebra: ViktorFieldOpsND get() = ViktorFieldOpsND
public val Float64Field.viktorAlgebra: ViktorFieldOpsND get() = ViktorFieldOpsND
@OptIn(UnstableKMathAPI::class)
public open class ViktorFieldND(
private val shapeAsArray: IntArray,
) : ViktorFieldOpsND(), FieldND<Double, DoubleField>, NumbersAddOps<StructureND<Double>> {
) : ViktorFieldOpsND(), FieldND<Double, Float64Field>, NumbersAddOps<StructureND<Double>> {
override val shape: ShapeND = ShapeND(shapeAsArray)
@ -137,6 +137,6 @@ public open class ViktorFieldND(
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)