forked from kscience/kmath
Merge branch 'dev' into kotlin/1.9.20
# Conflicts: # build.gradle.kts
This commit is contained in:
commit
12a02320ec
@ -3,14 +3,21 @@
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
- Integer division algebras
|
||||
- Float32 geometries
|
||||
|
||||
### Changed
|
||||
- Default naming for algebra and buffers now uses IntXX/FloatXX notation instead of Java types.
|
||||
- Remove unnecessary inlines in basic algebras.
|
||||
- QuaternionField -> QuaternionAlgebra and does not implement `Field` anymore since it is non-commutative
|
||||
- kmath-geometry is split into `euclidean2d` and `euclidean3d`
|
||||
|
||||
### Deprecated
|
||||
|
||||
### Removed
|
||||
|
||||
### Fixed
|
||||
- Median statistics
|
||||
|
||||
### Security
|
||||
|
||||
|
@ -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]!!
|
||||
|
@ -14,7 +14,7 @@ import space.kscience.kmath.complex.ComplexField
|
||||
import space.kscience.kmath.complex.complex
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
import space.kscience.kmath.structures.Float64Buffer
|
||||
import space.kscience.kmath.structures.getDouble
|
||||
import space.kscience.kmath.structures.permute
|
||||
|
||||
@ -33,7 +33,7 @@ internal class BufferBenchmark {
|
||||
|
||||
@Benchmark
|
||||
fun doubleBufferReadWrite(blackhole: Blackhole) {
|
||||
val buffer = DoubleBuffer(size) { it.toDouble() }
|
||||
val buffer = Float64Buffer(size) { it.toDouble() }
|
||||
var res = 0.0
|
||||
(0 until size).forEach {
|
||||
res += buffer[it]
|
||||
@ -43,7 +43,7 @@ internal class BufferBenchmark {
|
||||
|
||||
@Benchmark
|
||||
fun bufferViewReadWrite(blackhole: Blackhole) {
|
||||
val buffer = DoubleBuffer(size) { it.toDouble() }.permute(reversedIndices)
|
||||
val buffer = Float64Buffer(size) { it.toDouble() }.permute(reversedIndices)
|
||||
var res = 0.0
|
||||
(0 until size).forEach {
|
||||
res += buffer[it]
|
||||
@ -53,7 +53,7 @@ internal class BufferBenchmark {
|
||||
|
||||
@Benchmark
|
||||
fun bufferViewReadWriteSpecialized(blackhole: Blackhole) {
|
||||
val buffer = DoubleBuffer(size) { it.toDouble() }.permute(reversedIndices)
|
||||
val buffer = Float64Buffer(size) { it.toDouble() }.permute(reversedIndices)
|
||||
var res = 0.0
|
||||
(0 until size).forEach {
|
||||
res += buffer.getDouble(it)
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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]!!
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import space.kscience.gradle.isInDevelopment
|
||||
import space.kscience.gradle.useApache2Licence
|
||||
import space.kscience.gradle.useSPCTeam
|
||||
|
||||
@ -14,7 +15,7 @@ allprojects {
|
||||
}
|
||||
|
||||
group = "space.kscience"
|
||||
version = "0.3.2-dev-1"
|
||||
version = "0.4.0-dev-2"
|
||||
}
|
||||
|
||||
subprojects {
|
||||
@ -63,10 +64,17 @@ ksciencePublish {
|
||||
useApache2Licence()
|
||||
useSPCTeam()
|
||||
}
|
||||
repository("spc","https://maven.sciprog.center/kscience")
|
||||
github("kmath", "SciProgCentre")
|
||||
space(
|
||||
if (isInDevelopment) {
|
||||
"https://maven.pkg.jetbrains.space/spc/p/sci/dev"
|
||||
} else {
|
||||
"https://maven.pkg.jetbrains.space/spc/p/sci/maven"
|
||||
}
|
||||
)
|
||||
sonatype("https://oss.sonatype.org")
|
||||
}
|
||||
|
||||
apiValidation.nonPublicMarkers.add("space.kscience.kmath.UnstableKMathAPI")
|
||||
|
||||
val multikVersion by extra("0.2.2")
|
||||
val multikVersion by extra("0.2.0")
|
||||
|
@ -387,9 +387,15 @@ 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.structures.Float64
|
||||
import space.kscience.kmath.structures.Float32
|
||||
import space.kscience.kmath.operations.Float64Field
|
||||
import space.kscience.kmath.operations.Float32Field
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.FloatField
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.structures.Float64Buffer
|
||||
import space.kscience.kmath.structures.Float32Buffer
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
import space.kscience.kmath.structures.FloatBuffer
|
||||
import kotlin.reflect.KClass
|
||||
@ -399,12 +405,12 @@ import kotlin.reflect.cast""")
|
||||
it.appendEjmlVector("Float", "FMatrix")
|
||||
it.appendEjmlMatrix("Double", "DMatrix")
|
||||
it.appendEjmlMatrix("Float", "FMatrix")
|
||||
it.appendEjmlLinearSpace("Double", "DoubleField", "DMatrix", "DMatrixRMaj", "DMatrixRMaj", "DDRM", "DDRM", true)
|
||||
it.appendEjmlLinearSpace("Float", "FloatField", "FMatrix", "FMatrixRMaj", "FMatrixRMaj", "FDRM", "FDRM", true)
|
||||
it.appendEjmlLinearSpace("Double", "Float64Field", "DMatrix", "DMatrixRMaj", "DMatrixRMaj", "DDRM", "DDRM", true)
|
||||
it.appendEjmlLinearSpace("Float", "Float32Field", "FMatrix", "FMatrixRMaj", "FMatrixRMaj", "FDRM", "FDRM", true)
|
||||
|
||||
it.appendEjmlLinearSpace(
|
||||
type = "Double",
|
||||
kmathAlgebra = "DoubleField",
|
||||
kmathAlgebra = "Float64Field",
|
||||
ejmlMatrixParentTypeMatrix = "DMatrix",
|
||||
ejmlMatrixType = "DMatrixSparseCSC",
|
||||
ejmlMatrixDenseType = "DMatrixRMaj",
|
||||
@ -415,7 +421,7 @@ import kotlin.reflect.cast""")
|
||||
|
||||
it.appendEjmlLinearSpace(
|
||||
type = "Float",
|
||||
kmathAlgebra = "FloatField",
|
||||
kmathAlgebra = "Float32Field",
|
||||
ejmlMatrixParentTypeMatrix = "FMatrix",
|
||||
ejmlMatrixType = "FMatrixSparseCSC",
|
||||
ejmlMatrixDenseType = "FMatrixRMaj",
|
||||
|
@ -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)
|
||||
|
@ -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> − 4 x − 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))
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -7,8 +7,8 @@ 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.structures.DoubleBuffer
|
||||
import space.kscience.kmath.operations.Float64Field
|
||||
import space.kscience.kmath.structures.Float64Buffer
|
||||
import space.kscience.plotly.Plotly
|
||||
import space.kscience.plotly.UnstablePlotlyAPI
|
||||
import space.kscience.plotly.makeFile
|
||||
@ -25,10 +25,10 @@ fun main() {
|
||||
}
|
||||
|
||||
val polynomial: PiecewisePolynomial<Double> = SplineInterpolator(
|
||||
DoubleField, ::DoubleBuffer
|
||||
Float64Field, ::Float64Buffer
|
||||
).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(),
|
||||
|
@ -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 {
|
||||
|
@ -6,7 +6,7 @@
|
||||
package space.kscience.kmath.linear
|
||||
|
||||
import space.kscience.kmath.real.*
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
import space.kscience.kmath.structures.Float64Buffer
|
||||
|
||||
fun main() {
|
||||
val x0 = DoubleVector(0.0, 0.0, 0.0)
|
||||
@ -19,9 +19,9 @@ fun main() {
|
||||
|
||||
fun ((Point<Double>) -> Double).grad(x: Point<Double>): Point<Double> {
|
||||
require(x.size == x0.size)
|
||||
return DoubleBuffer(x.size) { i ->
|
||||
return Float64Buffer(x.size) { i ->
|
||||
val h = sigma[i] / 5
|
||||
val dVector = DoubleBuffer(x.size) { if (it == i) h else 0.0 }
|
||||
val dVector = Float64Buffer(x.size) { if (it == i) h else 0.0 }
|
||||
val f1 = this(x + dVector / 2)
|
||||
val f0 = this(x - dVector / 2)
|
||||
(f1 - f0) / h
|
||||
|
@ -7,7 +7,7 @@ package space.kscience.kmath.operations
|
||||
|
||||
import space.kscience.kmath.commons.linear.CMLinearSpace
|
||||
import space.kscience.kmath.linear.matrix
|
||||
import space.kscience.kmath.nd.DoubleBufferND
|
||||
import space.kscience.kmath.nd.Float64BufferND
|
||||
import space.kscience.kmath.nd.ShapeND
|
||||
import space.kscience.kmath.nd.Structure2D
|
||||
import space.kscience.kmath.nd.ndAlgebra
|
||||
@ -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: Float64BufferND = Float64Field.ndAlgebra {
|
||||
exp(viktorStructure) + 2.0 * cmMatrix
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 } }
|
||||
|
||||
@ -32,21 +32,21 @@ class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, DoubleF
|
||||
}
|
||||
|
||||
@OptIn(PerformancePitfall::class)
|
||||
private val StructureND<Double>.buffer: DoubleBuffer
|
||||
private val StructureND<Double>.buffer: Float64Buffer
|
||||
get() = when {
|
||||
!shape.contentEquals(this@StreamDoubleFieldND.shape) -> throw ShapeMismatchException(
|
||||
this@StreamDoubleFieldND.shape,
|
||||
shape
|
||||
)
|
||||
|
||||
this is BufferND && indices == this@StreamDoubleFieldND.strides -> this.buffer as DoubleBuffer
|
||||
else -> DoubleBuffer(strides.linearSize) { offset -> get(strides.index(offset)) }
|
||||
this is BufferND && indices == this@StreamDoubleFieldND.strides -> this.buffer as Float64Buffer
|
||||
else -> Float64Buffer(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))
|
||||
|
@ -16,7 +16,7 @@ import kotlin.system.measureTimeMillis
|
||||
fun main() {
|
||||
val n = 6000
|
||||
val array = DoubleArray(n * n) { 1.0 }
|
||||
val buffer = DoubleBuffer(array)
|
||||
val buffer = Float64Buffer(array)
|
||||
val strides = ColumnStrides(ShapeND(n, n))
|
||||
val structure = BufferND(strides, buffer)
|
||||
|
||||
|
@ -32,10 +32,10 @@ fun main() {
|
||||
|
||||
println("Array mapping finished in $time2 millis")
|
||||
|
||||
val buffer = DoubleBuffer(DoubleArray(n * n) { 1.0 })
|
||||
val buffer = Float64Buffer(DoubleArray(n * n) { 1.0 })
|
||||
|
||||
val time3 = measureTimeMillis {
|
||||
val target = DoubleBuffer(DoubleArray(n * n))
|
||||
val target = Float64Buffer(DoubleArray(n * n))
|
||||
val res = array.forEachIndexed { index, value ->
|
||||
target[index] = value + 1
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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.tensors.LevenbergMarquardt.StaticLm
|
||||
|
||||
import space.kscience.kmath.nd.ShapeND
|
||||
import space.kscience.kmath.nd.as2D
|
||||
import space.kscience.kmath.nd.component1
|
||||
import space.kscience.kmath.tensors.LevenbergMarquardt.funcDifficultForLm
|
||||
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra
|
||||
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div
|
||||
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
|
||||
import space.kscience.kmath.tensors.core.LMInput
|
||||
import space.kscience.kmath.tensors.core.levenbergMarquardt
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
fun main() {
|
||||
val NData = 200
|
||||
var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D()
|
||||
for (i in 0 until NData) {
|
||||
t_example[i, 0] = t_example[i, 0] * (i + 1) - 104
|
||||
}
|
||||
|
||||
val Nparams = 15
|
||||
var p_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D()
|
||||
for (i in 0 until Nparams) {
|
||||
p_example[i, 0] = p_example[i, 0] + i - 25
|
||||
}
|
||||
|
||||
val exampleNumber = 1
|
||||
|
||||
var y_hat = funcDifficultForLm(t_example, p_example, exampleNumber)
|
||||
|
||||
var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D()
|
||||
for (i in 0 until Nparams) {
|
||||
p_init[i, 0] = (p_example[i, 0] + 0.9)
|
||||
}
|
||||
|
||||
var t = t_example
|
||||
val y_dat = y_hat
|
||||
val weight = 1.0 / Nparams * 1.0 - 0.085
|
||||
val dp = BroadcastDoubleTensorAlgebra.fromArray(
|
||||
ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 }
|
||||
).as2D()
|
||||
var p_min = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1)))
|
||||
p_min = p_min.div(1.0 / -50.0)
|
||||
val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1)))
|
||||
p_min = p_min.div(1.0 / 50.0)
|
||||
val opts = doubleArrayOf(3.0, 10000.0, 1e-6, 1e-6, 1e-6, 1e-6, 1e-2, 11.0, 9.0, 1.0)
|
||||
// val opts = doubleArrayOf(3.0, 10000.0, 1e-6, 1e-6, 1e-6, 1e-6, 1e-3, 11.0, 9.0, 1.0)
|
||||
|
||||
val inputData = LMInput(::funcDifficultForLm,
|
||||
p_init.as2D(),
|
||||
t,
|
||||
y_dat,
|
||||
weight,
|
||||
dp,
|
||||
p_min.as2D(),
|
||||
p_max.as2D(),
|
||||
opts[1].toInt(),
|
||||
doubleArrayOf(opts[2], opts[3], opts[4], opts[5]),
|
||||
doubleArrayOf(opts[6], opts[7], opts[8]),
|
||||
opts[9].toInt(),
|
||||
10,
|
||||
1)
|
||||
|
||||
val result = DoubleTensorAlgebra.levenbergMarquardt(inputData)
|
||||
|
||||
println("Parameters:")
|
||||
for (i in 0 until result.resultParameters.shape.component1()) {
|
||||
val x = (result.resultParameters[i, 0] * 10000).roundToInt() / 10000.0
|
||||
print("$x ")
|
||||
}
|
||||
println()
|
||||
|
||||
println("Y true and y received:")
|
||||
var y_hat_after = funcDifficultForLm(t_example, result.resultParameters, exampleNumber)
|
||||
for (i in 0 until y_hat.shape.component1()) {
|
||||
val x = (y_hat[i, 0] * 10000).roundToInt() / 10000.0
|
||||
val y = (y_hat_after[i, 0] * 10000).roundToInt() / 10000.0
|
||||
println("$x $y")
|
||||
}
|
||||
|
||||
println("Сhi_sq:")
|
||||
println(result.resultChiSq)
|
||||
println("Number of iterations:")
|
||||
println(result.iterations)
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.tensors.LevenbergMarquardt.StaticLm
|
||||
|
||||
import space.kscience.kmath.nd.ShapeND
|
||||
import space.kscience.kmath.nd.as2D
|
||||
import space.kscience.kmath.nd.component1
|
||||
import space.kscience.kmath.tensors.LevenbergMarquardt.funcDifficultForLm
|
||||
import space.kscience.kmath.tensors.LevenbergMarquardt.funcEasyForLm
|
||||
import space.kscience.kmath.tensors.LevenbergMarquardt.getStartDataForFuncEasy
|
||||
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
|
||||
import space.kscience.kmath.tensors.core.LMInput
|
||||
import space.kscience.kmath.tensors.core.levenbergMarquardt
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
fun main() {
|
||||
val startedData = getStartDataForFuncEasy()
|
||||
val inputData = LMInput(::funcEasyForLm,
|
||||
DoubleTensorAlgebra.ones(ShapeND(intArrayOf(4, 1))).as2D(),
|
||||
startedData.t,
|
||||
startedData.y_dat,
|
||||
startedData.weight,
|
||||
startedData.dp,
|
||||
startedData.p_min,
|
||||
startedData.p_max,
|
||||
startedData.opts[1].toInt(),
|
||||
doubleArrayOf(startedData.opts[2], startedData.opts[3], startedData.opts[4], startedData.opts[5]),
|
||||
doubleArrayOf(startedData.opts[6], startedData.opts[7], startedData.opts[8]),
|
||||
startedData.opts[9].toInt(),
|
||||
10,
|
||||
startedData.example_number)
|
||||
|
||||
val result = DoubleTensorAlgebra.levenbergMarquardt(inputData)
|
||||
|
||||
println("Parameters:")
|
||||
for (i in 0 until result.resultParameters.shape.component1()) {
|
||||
val x = (result.resultParameters[i, 0] * 10000).roundToInt() / 10000.0
|
||||
print("$x ")
|
||||
}
|
||||
println()
|
||||
|
||||
println("Y true and y received:")
|
||||
var y_hat_after = funcDifficultForLm(startedData.t, result.resultParameters, startedData.example_number)
|
||||
for (i in 0 until startedData.y_dat.shape.component1()) {
|
||||
val x = (startedData.y_dat[i, 0] * 10000).roundToInt() / 10000.0
|
||||
val y = (y_hat_after[i, 0] * 10000).roundToInt() / 10000.0
|
||||
println("$x $y")
|
||||
}
|
||||
|
||||
println("Сhi_sq:")
|
||||
println(result.resultChiSq)
|
||||
println("Number of iterations:")
|
||||
println(result.iterations)
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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.tensors.LevenbergMarquardt.StaticLm
|
||||
|
||||
import space.kscience.kmath.nd.ShapeND
|
||||
import space.kscience.kmath.nd.as2D
|
||||
import space.kscience.kmath.nd.component1
|
||||
import space.kscience.kmath.tensors.LevenbergMarquardt.funcMiddleForLm
|
||||
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra
|
||||
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div
|
||||
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
|
||||
import space.kscience.kmath.tensors.core.LMInput
|
||||
import space.kscience.kmath.tensors.core.levenbergMarquardt
|
||||
import kotlin.math.roundToInt
|
||||
fun main() {
|
||||
val NData = 100
|
||||
var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D()
|
||||
for (i in 0 until NData) {
|
||||
t_example[i, 0] = t_example[i, 0] * (i + 1)
|
||||
}
|
||||
|
||||
val Nparams = 20
|
||||
var p_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D()
|
||||
for (i in 0 until Nparams) {
|
||||
p_example[i, 0] = p_example[i, 0] + i - 25
|
||||
}
|
||||
|
||||
val exampleNumber = 1
|
||||
|
||||
var y_hat = funcMiddleForLm(t_example, p_example, exampleNumber)
|
||||
|
||||
var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D()
|
||||
for (i in 0 until Nparams) {
|
||||
p_init[i, 0] = (p_example[i, 0] + 0.9)
|
||||
}
|
||||
|
||||
var t = t_example
|
||||
val y_dat = y_hat
|
||||
val weight = 1.0
|
||||
val dp = BroadcastDoubleTensorAlgebra.fromArray(
|
||||
ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 }
|
||||
).as2D()
|
||||
var p_min = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1)))
|
||||
p_min = p_min.div(1.0 / -50.0)
|
||||
val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1)))
|
||||
p_min = p_min.div(1.0 / 50.0)
|
||||
val opts = doubleArrayOf(3.0, 7000.0, 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 11.0, 9.0, 1.0)
|
||||
|
||||
val inputData = LMInput(::funcMiddleForLm,
|
||||
p_init.as2D(),
|
||||
t,
|
||||
y_dat,
|
||||
weight,
|
||||
dp,
|
||||
p_min.as2D(),
|
||||
p_max.as2D(),
|
||||
opts[1].toInt(),
|
||||
doubleArrayOf(opts[2], opts[3], opts[4], opts[5]),
|
||||
doubleArrayOf(opts[6], opts[7], opts[8]),
|
||||
opts[9].toInt(),
|
||||
10,
|
||||
1)
|
||||
|
||||
val result = DoubleTensorAlgebra.levenbergMarquardt(inputData)
|
||||
|
||||
println("Parameters:")
|
||||
for (i in 0 until result.resultParameters.shape.component1()) {
|
||||
val x = (result.resultParameters[i, 0] * 10000).roundToInt() / 10000.0
|
||||
print("$x ")
|
||||
}
|
||||
println()
|
||||
|
||||
|
||||
var y_hat_after = funcMiddleForLm(t_example, result.resultParameters, exampleNumber)
|
||||
for (i in 0 until y_hat.shape.component1()) {
|
||||
val x = (y_hat[i, 0] * 10000).roundToInt() / 10000.0
|
||||
val y = (y_hat_after[i, 0] * 10000).roundToInt() / 10000.0
|
||||
println("$x $y")
|
||||
}
|
||||
|
||||
println("Сhi_sq:")
|
||||
println(result.resultChiSq)
|
||||
println("Number of iterations:")
|
||||
println(result.iterations)
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.tensors.LevenbergMarquardt.StreamingLm
|
||||
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.*
|
||||
import space.kscience.kmath.nd.*
|
||||
import space.kscience.kmath.tensors.LevenbergMarquardt.StartDataLm
|
||||
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.zeros
|
||||
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
|
||||
import space.kscience.kmath.tensors.core.LMInput
|
||||
import space.kscience.kmath.tensors.core.levenbergMarquardt
|
||||
import kotlin.random.Random
|
||||
import kotlin.reflect.KFunction3
|
||||
|
||||
fun streamLm(lm_func: (MutableStructure2D<Double>, MutableStructure2D<Double>, Int) -> (MutableStructure2D<Double>),
|
||||
startData: StartDataLm, launchFrequencyInMs: Long, numberOfLaunches: Int): Flow<MutableStructure2D<Double>> = flow{
|
||||
|
||||
var example_number = startData.example_number
|
||||
var p_init = startData.p_init
|
||||
var t = startData.t
|
||||
var y_dat = startData.y_dat
|
||||
val weight = startData.weight
|
||||
val dp = startData.dp
|
||||
val p_min = startData.p_min
|
||||
val p_max = startData.p_max
|
||||
val opts = startData.opts
|
||||
|
||||
var steps = numberOfLaunches
|
||||
val isEndless = (steps <= 0)
|
||||
|
||||
val inputData = LMInput(lm_func,
|
||||
p_init,
|
||||
t,
|
||||
y_dat,
|
||||
weight,
|
||||
dp,
|
||||
p_min,
|
||||
p_max,
|
||||
opts[1].toInt(),
|
||||
doubleArrayOf(opts[2], opts[3], opts[4], opts[5]),
|
||||
doubleArrayOf(opts[6], opts[7], opts[8]),
|
||||
opts[9].toInt(),
|
||||
10,
|
||||
example_number)
|
||||
|
||||
while (isEndless || steps > 0) {
|
||||
val result = DoubleTensorAlgebra.levenbergMarquardt(inputData)
|
||||
emit(result.resultParameters)
|
||||
delay(launchFrequencyInMs)
|
||||
inputData.realValues = generateNewYDat(y_dat, 0.1)
|
||||
inputData.startParameters = result.resultParameters
|
||||
if (!isEndless) steps -= 1
|
||||
}
|
||||
}
|
||||
|
||||
fun generateNewYDat(y_dat: MutableStructure2D<Double>, delta: Double): MutableStructure2D<Double>{
|
||||
val n = y_dat.shape.component1()
|
||||
val y_dat_new = zeros(ShapeND(intArrayOf(n, 1))).as2D()
|
||||
for (i in 0 until n) {
|
||||
val randomEps = Random.nextDouble(delta + delta) - delta
|
||||
y_dat_new[i, 0] = y_dat[i, 0] + randomEps
|
||||
}
|
||||
return y_dat_new
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.tensors.LevenbergMarquardt.StreamingLm
|
||||
|
||||
import space.kscience.kmath.nd.*
|
||||
import space.kscience.kmath.tensors.LevenbergMarquardt.*
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
suspend fun main(){
|
||||
val startData = getStartDataForFuncDifficult()
|
||||
// Создание потока:
|
||||
val lmFlow = streamLm(::funcDifficultForLm, startData, 0, 100)
|
||||
var initialTime = System.currentTimeMillis()
|
||||
var lastTime: Long
|
||||
val launches = mutableListOf<Long>()
|
||||
// Запуск потока
|
||||
lmFlow.collect { parameters ->
|
||||
lastTime = System.currentTimeMillis()
|
||||
launches.add(lastTime - initialTime)
|
||||
initialTime = lastTime
|
||||
for (i in 0 until parameters.shape.component1()) {
|
||||
val x = (parameters[i, 0] * 10000).roundToInt() / 10000.0
|
||||
print("$x ")
|
||||
if (i == parameters.shape.component1() - 1) println()
|
||||
}
|
||||
}
|
||||
|
||||
println("Average without first is: ${launches.subList(1, launches.size - 1).average()}")
|
||||
}
|
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* 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.tensors.LevenbergMarquardt
|
||||
|
||||
import space.kscience.kmath.nd.MutableStructure2D
|
||||
import space.kscience.kmath.nd.ShapeND
|
||||
import space.kscience.kmath.nd.as2D
|
||||
import space.kscience.kmath.nd.component1
|
||||
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra
|
||||
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div
|
||||
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
|
||||
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.max
|
||||
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.plus
|
||||
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.pow
|
||||
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.times
|
||||
import space.kscience.kmath.tensors.core.asDoubleTensor
|
||||
|
||||
public data class StartDataLm (
|
||||
var lm_matx_y_dat: MutableStructure2D<Double>,
|
||||
var example_number: Int,
|
||||
var p_init: MutableStructure2D<Double>,
|
||||
var t: MutableStructure2D<Double>,
|
||||
var y_dat: MutableStructure2D<Double>,
|
||||
var weight: Double,
|
||||
var dp: MutableStructure2D<Double>,
|
||||
var p_min: MutableStructure2D<Double>,
|
||||
var p_max: MutableStructure2D<Double>,
|
||||
var consts: MutableStructure2D<Double>,
|
||||
var opts: DoubleArray
|
||||
)
|
||||
|
||||
fun funcEasyForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int): MutableStructure2D<Double> {
|
||||
val m = t.shape.component1()
|
||||
var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1)))
|
||||
|
||||
if (exampleNumber == 1) {
|
||||
y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))).times(p[0, 0]) + t.times(p[2, 0]).times(
|
||||
DoubleTensorAlgebra.exp((t.times(-1.0 / p[3, 0])))
|
||||
)
|
||||
}
|
||||
else if (exampleNumber == 2) {
|
||||
val mt = t.max()
|
||||
y_hat = (t.times(1.0 / mt)).times(p[0, 0]) +
|
||||
(t.times(1.0 / mt)).pow(2).times(p[1, 0]) +
|
||||
(t.times(1.0 / mt)).pow(3).times(p[2, 0]) +
|
||||
(t.times(1.0 / mt)).pow(4).times(p[3, 0])
|
||||
}
|
||||
else if (exampleNumber == 3) {
|
||||
y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0])))
|
||||
.times(p[0, 0]) + DoubleTensorAlgebra.sin((t.times(1.0 / p[3, 0]))).times(p[2, 0])
|
||||
}
|
||||
|
||||
return y_hat.as2D()
|
||||
}
|
||||
|
||||
fun funcMiddleForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int): MutableStructure2D<Double> {
|
||||
val m = t.shape.component1()
|
||||
var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1)))
|
||||
|
||||
val mt = t.max()
|
||||
for(i in 0 until p.shape.component1()){
|
||||
y_hat += (t.times(1.0 / mt)).times(p[i, 0])
|
||||
}
|
||||
|
||||
for(i in 0 until 5){
|
||||
y_hat = funcEasyForLm(y_hat.as2D(), p, exampleNumber).asDoubleTensor()
|
||||
}
|
||||
|
||||
return y_hat.as2D()
|
||||
}
|
||||
|
||||
fun funcDifficultForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int): MutableStructure2D<Double> {
|
||||
val m = t.shape.component1()
|
||||
var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1)))
|
||||
|
||||
val mt = t.max()
|
||||
for(i in 0 until p.shape.component1()){
|
||||
y_hat = y_hat.plus( (t.times(1.0 / mt)).times(p[i, 0]) )
|
||||
}
|
||||
|
||||
for(i in 0 until 4){
|
||||
y_hat = funcEasyForLm((y_hat.as2D() + t).as2D(), p, exampleNumber).asDoubleTensor()
|
||||
}
|
||||
|
||||
return y_hat.as2D()
|
||||
}
|
||||
|
||||
|
||||
fun getStartDataForFuncDifficult(): StartDataLm {
|
||||
val NData = 200
|
||||
var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D()
|
||||
for (i in 0 until NData) {
|
||||
t_example[i, 0] = t_example[i, 0] * (i + 1) - 104
|
||||
}
|
||||
|
||||
val Nparams = 15
|
||||
var p_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D()
|
||||
for (i in 0 until Nparams) {
|
||||
p_example[i, 0] = p_example[i, 0] + i - 25
|
||||
}
|
||||
|
||||
val exampleNumber = 1
|
||||
|
||||
var y_hat = funcDifficultForLm(t_example, p_example, exampleNumber)
|
||||
|
||||
var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D()
|
||||
for (i in 0 until Nparams) {
|
||||
p_init[i, 0] = (p_example[i, 0] + 0.9)
|
||||
}
|
||||
|
||||
var t = t_example
|
||||
val y_dat = y_hat
|
||||
val weight = 1.0 / Nparams * 1.0 - 0.085
|
||||
val dp = BroadcastDoubleTensorAlgebra.fromArray(
|
||||
ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 }
|
||||
).as2D()
|
||||
var p_min = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1)))
|
||||
p_min = p_min.div(1.0 / -50.0)
|
||||
val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1)))
|
||||
p_min = p_min.div(1.0 / 50.0)
|
||||
val consts = BroadcastDoubleTensorAlgebra.fromArray(
|
||||
ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0)
|
||||
).as2D()
|
||||
val opts = doubleArrayOf(3.0, 10000.0, 1e-2, 1e-3, 1e-2, 1e-2, 1e-2, 11.0, 9.0, 1.0)
|
||||
|
||||
return StartDataLm(y_dat, 1, p_init, t, y_dat, weight, dp, p_min.as2D(), p_max.as2D(), consts, opts)
|
||||
}
|
||||
|
||||
fun getStartDataForFuncMiddle(): StartDataLm {
|
||||
val NData = 100
|
||||
var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D()
|
||||
for (i in 0 until NData) {
|
||||
t_example[i, 0] = t_example[i, 0] * (i + 1)
|
||||
}
|
||||
|
||||
val Nparams = 20
|
||||
var p_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D()
|
||||
for (i in 0 until Nparams) {
|
||||
p_example[i, 0] = p_example[i, 0] + i - 25
|
||||
}
|
||||
|
||||
val exampleNumber = 1
|
||||
|
||||
var y_hat = funcMiddleForLm(t_example, p_example, exampleNumber)
|
||||
|
||||
var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D()
|
||||
for (i in 0 until Nparams) {
|
||||
p_init[i, 0] = (p_example[i, 0] + 10.0)
|
||||
}
|
||||
var t = t_example
|
||||
val y_dat = y_hat
|
||||
val weight = 1.0
|
||||
val dp = BroadcastDoubleTensorAlgebra.fromArray(
|
||||
ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 }
|
||||
).as2D()
|
||||
var p_min = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1)))
|
||||
p_min = p_min.div(1.0 / -50.0)
|
||||
val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1)))
|
||||
p_min = p_min.div(1.0 / 50.0)
|
||||
val consts = BroadcastDoubleTensorAlgebra.fromArray(
|
||||
ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0)
|
||||
).as2D()
|
||||
val opts = doubleArrayOf(3.0, 10000.0, 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 11.0, 9.0, 1.0)
|
||||
|
||||
var example_number = 1
|
||||
|
||||
return StartDataLm(y_dat, example_number, p_init, t, y_dat, weight, dp, p_min.as2D(), p_max.as2D(), consts, opts)
|
||||
}
|
||||
|
||||
fun getStartDataForFuncEasy(): StartDataLm {
|
||||
val lm_matx_y_dat = doubleArrayOf(
|
||||
19.6594, 18.6096, 17.6792, 17.2747, 16.3065, 17.1458, 16.0467, 16.7023, 15.7809, 15.9807,
|
||||
14.7620, 15.1128, 16.0973, 15.1934, 15.8636, 15.4763, 15.6860, 15.1895, 15.3495, 16.6054,
|
||||
16.2247, 15.9854, 16.1421, 17.0960, 16.7769, 17.1997, 17.2767, 17.5882, 17.5378, 16.7894,
|
||||
17.7648, 18.2512, 18.1581, 16.7037, 17.8475, 17.9081, 18.3067, 17.9632, 18.2817, 19.1427,
|
||||
18.8130, 18.5658, 18.0056, 18.4607, 18.5918, 18.2544, 18.3731, 18.7511, 19.3181, 17.3066,
|
||||
17.9632, 19.0513, 18.7528, 18.2928, 18.5967, 17.8567, 17.7859, 18.4016, 18.9423, 18.4959,
|
||||
17.8000, 18.4251, 17.7829, 17.4645, 17.5221, 17.3517, 17.4637, 17.7563, 16.8471, 17.4558,
|
||||
17.7447, 17.1487, 17.3183, 16.8312, 17.7551, 17.0942, 15.6093, 16.4163, 15.3755, 16.6725,
|
||||
16.2332, 16.2316, 16.2236, 16.5361, 15.3721, 15.3347, 15.5815, 15.6319, 14.4538, 14.6044,
|
||||
14.7665, 13.3718, 15.0587, 13.8320, 14.7873, 13.6824, 14.2579, 14.2154, 13.5818, 13.8157
|
||||
)
|
||||
|
||||
var example_number = 1
|
||||
val p_init = BroadcastDoubleTensorAlgebra.fromArray(
|
||||
ShapeND(intArrayOf(4, 1)), doubleArrayOf(5.0, 2.0, 0.2, 10.0)
|
||||
).as2D()
|
||||
|
||||
var t = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(100, 1))).as2D()
|
||||
for (i in 0 until 100) {
|
||||
t[i, 0] = t[i, 0] * (i + 1)
|
||||
}
|
||||
|
||||
val y_dat = BroadcastDoubleTensorAlgebra.fromArray(
|
||||
ShapeND(intArrayOf(100, 1)), lm_matx_y_dat
|
||||
).as2D()
|
||||
|
||||
val weight = 4.0
|
||||
|
||||
val dp = BroadcastDoubleTensorAlgebra.fromArray(
|
||||
ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 }
|
||||
).as2D()
|
||||
|
||||
val p_min = BroadcastDoubleTensorAlgebra.fromArray(
|
||||
ShapeND(intArrayOf(4, 1)), doubleArrayOf(-50.0, -20.0, -2.0, -100.0)
|
||||
).as2D()
|
||||
|
||||
val p_max = BroadcastDoubleTensorAlgebra.fromArray(
|
||||
ShapeND(intArrayOf(4, 1)), doubleArrayOf(50.0, 20.0, 2.0, 100.0)
|
||||
).as2D()
|
||||
|
||||
val consts = BroadcastDoubleTensorAlgebra.fromArray(
|
||||
ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0)
|
||||
).as2D()
|
||||
|
||||
val opts = doubleArrayOf(3.0, 100.0, 1e-3, 1e-3, 1e-1, 1e-1, 1e-2, 11.0, 9.0, 1.0)
|
||||
|
||||
return StartDataLm(y_dat, example_number, p_init, t, y_dat, weight, dp, p_min, p_max, consts, opts)
|
||||
}
|
@ -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),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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() }
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,9 @@
|
||||
|
||||
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.Int8Ring
|
||||
import space.kscience.kmath.operations.pi
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
@ -17,36 +17,36 @@ 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
|
||||
fun foldNumeric() = assertEquals(
|
||||
42.toByte(),
|
||||
("42".parseMath().evaluateConstants(ByteRing) as? TypedMst.Constant<Byte> ?: fail()).value,
|
||||
("42".parseMath().evaluateConstants(Int8Ring) as? TypedMst.Constant<Byte> ?: fail()).value,
|
||||
)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -9,9 +9,9 @@ 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 space.kscience.kmath.structures.Float64Buffer
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.cast
|
||||
|
||||
@ -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()
|
||||
@ -136,7 +136,7 @@ public object CMLinearSpace : LinearSpace<Double, DoubleField> {
|
||||
override val u: Matrix<Double> by lazy { CMMatrix(sv.u) }
|
||||
override val s: Matrix<Double> by lazy { CMMatrix(sv.s) }
|
||||
override val v: Matrix<Double> by lazy { CMMatrix(sv.v) }
|
||||
override val singularValues: Point<Double> by lazy { DoubleBuffer(sv.singularValues) }
|
||||
override val singularValues: Point<Double> by lazy { Float64Buffer(sv.singularValues) }
|
||||
}
|
||||
else -> null
|
||||
}?.let(type::cast)
|
||||
|
@ -47,7 +47,7 @@ public object Transformations {
|
||||
public fun sine(
|
||||
normalization: DstNormalization = DstNormalization.STANDARD_DST_I,
|
||||
direction: TransformType = TransformType.FORWARD,
|
||||
): BufferTransform<Double, Double> = DoubleBufferTransform {
|
||||
): BufferTransform<Double, Double> = Float64BufferTransform {
|
||||
FastSineTransformer(normalization).transform(it.array, direction).asBuffer()
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ public object Transformations {
|
||||
|
||||
public fun hadamard(
|
||||
direction: TransformType = TransformType.FORWARD,
|
||||
): BufferTransform<Double, Double> = DoubleBufferTransform {
|
||||
): BufferTransform<Double, Double> = Float64BufferTransform {
|
||||
FastHadamardTransformer().transform(it.array, direction).asBuffer()
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -13,18 +13,18 @@ import space.kscience.kmath.expressions.Symbol.Companion.x
|
||||
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.Float64BufferOps.Companion.map
|
||||
import space.kscience.kmath.operations.Float64Field
|
||||
import space.kscience.kmath.optimization.*
|
||||
import space.kscience.kmath.random.RandomGenerator
|
||||
import space.kscience.kmath.stat.chiSquaredExpression
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
import space.kscience.kmath.structures.Float64Buffer
|
||||
import space.kscience.kmath.structures.asBuffer
|
||||
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)
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ internal class OptimizeTest {
|
||||
it.pow(2) + it + 1 + chain.next()
|
||||
}
|
||||
|
||||
val yErr = DoubleBuffer(x.size) { sigma }
|
||||
val yErr = Float64Buffer(x.size) { sigma }
|
||||
|
||||
val chi2 = Double.autodiff.chiSquaredExpression(
|
||||
x, y, yErr
|
||||
|
@ -122,16 +122,17 @@ public val Quaternion.reciprocal: Quaternion
|
||||
/**
|
||||
* Produce a normalized version of this quaternion
|
||||
*/
|
||||
public fun Quaternion.normalized(): Quaternion = with(QuaternionField){ this@normalized / norm(this@normalized) }
|
||||
public fun Quaternion.normalized(): Quaternion = with(QuaternionAlgebra){ this@normalized / norm(this@normalized) }
|
||||
|
||||
/**
|
||||
* A field of [Quaternion].
|
||||
*/
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
public object QuaternionField : Field<Quaternion>, Norm<Quaternion, Double>, PowerOperations<Quaternion>,
|
||||
public object QuaternionAlgebra : Group<Quaternion>, Norm<Quaternion, Double>, PowerOperations<Quaternion>,
|
||||
ExponentialOperations<Quaternion>, NumbersAddOps<Quaternion>, ScaleOperations<Quaternion> {
|
||||
|
||||
override val zero: Quaternion = Quaternion(0.0)
|
||||
override val one: Quaternion = Quaternion(1.0)
|
||||
public val one: Quaternion = Quaternion(1.0)
|
||||
|
||||
/**
|
||||
* The `i` quaternion unit.
|
||||
@ -154,14 +155,16 @@ public object QuaternionField : Field<Quaternion>, Norm<Quaternion, Double>, Pow
|
||||
override fun scale(a: Quaternion, value: Double): Quaternion =
|
||||
Quaternion(a.w * value, a.x * value, a.y * value, a.z * value)
|
||||
|
||||
override fun multiply(left: Quaternion, right: Quaternion): Quaternion = Quaternion(
|
||||
public fun multiply(left: Quaternion, right: Quaternion): Quaternion = Quaternion(
|
||||
left.w * right.w - left.x * right.x - left.y * right.y - left.z * right.z,
|
||||
left.w * right.x + left.x * right.w + left.y * right.z - left.z * right.y,
|
||||
left.w * right.y - left.x * right.z + left.y * right.w + left.z * right.x,
|
||||
left.w * right.z + left.x * right.y - left.y * right.x + left.z * right.w,
|
||||
)
|
||||
|
||||
override fun divide(left: Quaternion, right: Quaternion): Quaternion {
|
||||
public operator fun Quaternion.times(other: Quaternion): Quaternion = multiply(this, other)
|
||||
|
||||
public fun divide(left: Quaternion, right: Quaternion): Quaternion {
|
||||
val s = right.w * right.w + right.x * right.x + right.y * right.y + right.z * right.z
|
||||
|
||||
return Quaternion(
|
||||
@ -172,14 +175,17 @@ public object QuaternionField : Field<Quaternion>, Norm<Quaternion, Double>, Pow
|
||||
)
|
||||
}
|
||||
|
||||
public operator fun Quaternion.div(other: Quaternion): Quaternion = divide(this, other)
|
||||
|
||||
|
||||
override fun power(arg: Quaternion, pow: Number): Quaternion {
|
||||
if (pow is Int) return pwr(arg, pow)
|
||||
if (floor(pow.toDouble()) == pow.toDouble()) return pwr(arg, pow.toInt())
|
||||
if (pow is Int) return power(arg, pow)
|
||||
if (floor(pow.toDouble()) == pow.toDouble()) return power(arg, pow.toInt())
|
||||
return exp(pow * ln(arg))
|
||||
}
|
||||
|
||||
private fun pwr(x: Quaternion, a: Int): Quaternion = when {
|
||||
a < 0 -> -(pwr(x, -a))
|
||||
private fun power(x: Quaternion, a: Int): Quaternion = when {
|
||||
a < 0 -> -(power(x, -a))
|
||||
a == 0 -> one
|
||||
a == 1 -> x
|
||||
a == 2 -> pwr2(x)
|
||||
@ -243,14 +249,15 @@ public object QuaternionField : Field<Quaternion>, Norm<Quaternion, Double>, Pow
|
||||
return Quaternion(ln(n), th * arg.x, th * arg.y, th * arg.z)
|
||||
}
|
||||
|
||||
override operator fun Number.plus(other: Quaternion): Quaternion =
|
||||
public override operator fun Number.plus(other: Quaternion): Quaternion =
|
||||
Quaternion(toDouble() + other.w, other.x, other.y, other.z)
|
||||
|
||||
override operator fun Number.minus(other: Quaternion): Quaternion =
|
||||
public override operator fun Number.minus(other: Quaternion): Quaternion =
|
||||
Quaternion(toDouble() - other.w, -other.x, -other.y, -other.z)
|
||||
|
||||
override operator fun Quaternion.plus(other: Number): Quaternion = Quaternion(w + other.toDouble(), x, y, z)
|
||||
override operator fun Quaternion.minus(other: Number): Quaternion = Quaternion(w - other.toDouble(), x, y, z)
|
||||
public override operator fun Quaternion.plus(other: Number): Quaternion = Quaternion(w + other.toDouble(), x, y, z)
|
||||
|
||||
public override operator fun Quaternion.minus(other: Number): Quaternion = Quaternion(w - other.toDouble(), x, y, z)
|
||||
|
||||
override operator fun Number.times(arg: Quaternion): Quaternion =
|
||||
Quaternion(toDouble() * arg.w, toDouble() * arg.x, toDouble() * arg.y, toDouble() * arg.z)
|
||||
@ -275,7 +282,7 @@ public object QuaternionField : Field<Quaternion>, Norm<Quaternion, Double>, Pow
|
||||
override fun sinh(arg: Quaternion): Quaternion = (exp(arg) - exp(-arg)) / 2.0
|
||||
override fun cosh(arg: Quaternion): Quaternion = (exp(arg) + exp(-arg)) / 2.0
|
||||
override fun tanh(arg: Quaternion): Quaternion = (exp(arg) - exp(-arg)) / (exp(-arg) + exp(arg))
|
||||
override fun asinh(arg: Quaternion): Quaternion = ln(sqrt(arg * arg + one) + arg)
|
||||
override fun asinh(arg: Quaternion): Quaternion = ln(sqrt(pwr2(arg) + one) + arg)
|
||||
override fun acosh(arg: Quaternion): Quaternion = ln(arg + sqrt((arg - one) * (arg + one)))
|
||||
override fun atanh(arg: Quaternion): Quaternion = (ln(arg + one) - ln(one - arg)) / 2.0
|
||||
}
|
||||
|
@ -14,20 +14,20 @@ internal class QuaternionTest {
|
||||
|
||||
@Test
|
||||
fun testNorm() {
|
||||
assertEquals(2.0, QuaternionField.norm(Quaternion(1.0, 1.0, 1.0, 1.0)))
|
||||
assertEquals(2.0, QuaternionAlgebra.norm(Quaternion(1.0, 1.0, 1.0, 1.0)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testInverse() = QuaternionField {
|
||||
fun testInverse() = QuaternionAlgebra {
|
||||
val q = Quaternion(1.0, 2.0, -3.0, 4.0)
|
||||
assertBufferEquals(one, q * q.reciprocal, 1e-4)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAddition() {
|
||||
assertEquals(Quaternion(42, 42), QuaternionField { Quaternion(16, 16) + Quaternion(26, 26) })
|
||||
assertEquals(Quaternion(42, 16), QuaternionField { Quaternion(16, 16) + 26 })
|
||||
assertEquals(Quaternion(42, 16), QuaternionField { 26 + Quaternion(16, 16) })
|
||||
assertEquals(Quaternion(42, 42), QuaternionAlgebra { Quaternion(16, 16) + Quaternion(26, 26) })
|
||||
assertEquals(Quaternion(42, 16), QuaternionAlgebra { Quaternion(16, 16) + 26 })
|
||||
assertEquals(Quaternion(42, 16), QuaternionAlgebra { 26 + Quaternion(16, 16) })
|
||||
}
|
||||
|
||||
// @Test
|
||||
@ -39,9 +39,9 @@ internal class QuaternionTest {
|
||||
|
||||
@Test
|
||||
fun testMultiplication() {
|
||||
assertEquals(Quaternion(42, 42), QuaternionField { Quaternion(4.2, 0) * Quaternion(10, 10) })
|
||||
assertEquals(Quaternion(42, 21), QuaternionField { Quaternion(4.2, 2.1) * 10 })
|
||||
assertEquals(Quaternion(42, 21), QuaternionField { 10 * Quaternion(4.2, 2.1) })
|
||||
assertEquals(Quaternion(42, 42), QuaternionAlgebra { Quaternion(4.2, 0) * Quaternion(10, 10) })
|
||||
assertEquals(Quaternion(42, 21), QuaternionAlgebra { Quaternion(4.2, 2.1) * 10 })
|
||||
assertEquals(Quaternion(42, 21), QuaternionAlgebra { 10 * Quaternion(4.2, 2.1) })
|
||||
}
|
||||
|
||||
// @Test
|
||||
@ -53,11 +53,11 @@ internal class QuaternionTest {
|
||||
|
||||
@Test
|
||||
fun testPower() {
|
||||
assertEquals(QuaternionField.zero, QuaternionField { zero pow 2 })
|
||||
assertEquals(QuaternionField.zero, QuaternionField { zero pow 2 })
|
||||
assertEquals(QuaternionAlgebra.zero, QuaternionAlgebra { zero pow 2 })
|
||||
assertEquals(QuaternionAlgebra.zero, QuaternionAlgebra { zero pow 2 })
|
||||
|
||||
assertEquals(
|
||||
QuaternionField { i * 8 }.let { it.x.toInt() to it.w.toInt() },
|
||||
QuaternionField { Quaternion(2, 2) pow 2 }.let { it.x.toInt() to it.w.toInt() })
|
||||
QuaternionAlgebra { i * 8 }.let { it.x.toInt() to it.w.toInt() },
|
||||
QuaternionAlgebra { Quaternion(2, 2) pow 2 }.let { it.x.toInt() to it.w.toInt() })
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ public abstract class Domain1D<T : Comparable<T>>(public val range: ClosedRange<
|
||||
@UnstableKMathAPI
|
||||
public class DoubleDomain1D(
|
||||
@Suppress("CanBeParameter") public val doubleRange: ClosedFloatingPointRange<Double>,
|
||||
) : Domain1D<Double>(doubleRange), DoubleDomain {
|
||||
) : Domain1D<Double>(doubleRange), Float64Domain {
|
||||
override fun getLowerBound(num: Int): Double {
|
||||
require(num == 0)
|
||||
return range.start
|
||||
|
@ -12,7 +12,7 @@ import space.kscience.kmath.UnstableKMathAPI
|
||||
* @author Alexander Nozik
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public interface DoubleDomain : Domain<Double> {
|
||||
public interface Float64Domain : Domain<Double> {
|
||||
/**
|
||||
* Global lower edge
|
||||
* @param num axis number
|
@ -7,7 +7,7 @@ package space.kscience.kmath.domains
|
||||
import space.kscience.kmath.UnstableKMathAPI
|
||||
import space.kscience.kmath.linear.Point
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
import space.kscience.kmath.structures.Float64Buffer
|
||||
import space.kscience.kmath.structures.indices
|
||||
|
||||
/**
|
||||
@ -15,7 +15,7 @@ import space.kscience.kmath.structures.indices
|
||||
* and a [Buffer] of upper boundaries. Upper should be greater or equals than lower.
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public class HyperSquareDomain(public val lower: Buffer<Double>, public val upper: Buffer<Double>) : DoubleDomain {
|
||||
public class HyperSquareDomain(public val lower: Buffer<Double>, public val upper: Buffer<Double>) : Float64Domain {
|
||||
init {
|
||||
require(lower.size == upper.size) {
|
||||
"Domain borders size mismatch. Lower borders size is ${lower.size}, but upper borders size is ${upper.size}."
|
||||
@ -27,7 +27,7 @@ public class HyperSquareDomain(public val lower: Buffer<Double>, public val uppe
|
||||
|
||||
override val dimension: Int get() = lower.size
|
||||
|
||||
public val center: DoubleBuffer get() = DoubleBuffer(dimension) { (lower[it] + upper[it]) / 2.0 }
|
||||
public val center: Float64Buffer get() = Float64Buffer(dimension) { (lower[it] + upper[it]) / 2.0 }
|
||||
|
||||
override operator fun contains(point: Point<Double>): Boolean = point.indices.all { i ->
|
||||
point[i] in lower[i]..upper[i]
|
||||
|
@ -8,7 +8,7 @@ import space.kscience.kmath.UnstableKMathAPI
|
||||
import space.kscience.kmath.linear.Point
|
||||
|
||||
@UnstableKMathAPI
|
||||
public class UnconstrainedDomain(override val dimension: Int) : DoubleDomain {
|
||||
public class UnconstrainedDomain(override val dimension: Int) : Float64Domain {
|
||||
override operator fun contains(point: Point<Double>): Boolean = true
|
||||
|
||||
override fun getLowerBound(num: Int): Double = Double.NEGATIVE_INFINITY
|
||||
|
@ -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)
|
@ -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()
|
||||
|
@ -9,7 +9,7 @@ import space.kscience.kmath.UnstableKMathAPI
|
||||
import space.kscience.kmath.linear.Point
|
||||
import space.kscience.kmath.nd.Structure2D
|
||||
import space.kscience.kmath.structures.BufferFactory
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
import space.kscience.kmath.structures.Float64Buffer
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.jvm.JvmInline
|
||||
@ -62,8 +62,8 @@ public interface SymbolIndexer {
|
||||
public fun <T> Map<Symbol, T>.toPoint(bufferFactory: BufferFactory<T>): Point<T> =
|
||||
bufferFactory(symbols.size) { getValue(symbols[it]) }
|
||||
|
||||
public fun Map<Symbol, Double>.toPoint(): DoubleBuffer =
|
||||
DoubleBuffer(symbols.size) { getValue(symbols[it]) }
|
||||
public fun Map<Symbol, Double>.toPoint(): Float64Buffer =
|
||||
Float64Buffer(symbols.size) { getValue(symbols[it]) }
|
||||
|
||||
|
||||
public fun Map<Symbol, Double>.toDoubleArray(): DoubleArray = DoubleArray(symbols.size) { getValue(symbols[it]) }
|
||||
|
@ -7,43 +7,43 @@ 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.Float64BufferOps
|
||||
import space.kscience.kmath.operations.Float64Field
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
import space.kscience.kmath.structures.Float64Buffer
|
||||
|
||||
public object DoubleLinearSpace : LinearSpace<Double, DoubleField> {
|
||||
public object Float64LinearSpace : 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
|
||||
): Matrix<Double> = DoubleFieldOpsND.structureND(ShapeND(rows, columns)) { (i, j) ->
|
||||
DoubleField.initializer(i, j)
|
||||
initializer: Float64Field.(i: Int, j: Int) -> Double
|
||||
): Matrix<Double> = Floa64FieldOpsND.structureND(ShapeND(rows, columns)) { (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): Float64Buffer =
|
||||
Float64Buffer(size) { Float64Field.initializer(it) }
|
||||
|
||||
override fun Matrix<Double>.unaryMinus(): Matrix<Double> = DoubleFieldOpsND {
|
||||
override fun Matrix<Double>.unaryMinus(): Matrix<Double> = Floa64FieldOpsND {
|
||||
asND().map { -it }.as2D()
|
||||
}
|
||||
|
||||
override fun Matrix<Double>.plus(other: Matrix<Double>): Matrix<Double> = DoubleFieldOpsND {
|
||||
override fun Matrix<Double>.plus(other: Matrix<Double>): Matrix<Double> = Floa64FieldOpsND {
|
||||
require(shape.contentEquals(other.shape)) { "Shape mismatch on Matrix::plus. Expected $shape but found ${other.shape}" }
|
||||
asND().plus(other.asND()).as2D()
|
||||
}
|
||||
|
||||
override fun Matrix<Double>.minus(other: Matrix<Double>): Matrix<Double> = DoubleFieldOpsND {
|
||||
override fun Matrix<Double>.minus(other: Matrix<Double>): Matrix<Double> = Floa64FieldOpsND {
|
||||
require(shape.contentEquals(other.shape)) { "Shape mismatch on Matrix::minus. Expected $shape but found ${other.shape}" }
|
||||
asND().minus(other.asND()).as2D()
|
||||
}
|
||||
|
||||
// Create a continuous in-memory representation of this vector for better memory layout handling
|
||||
private fun Buffer<Double>.linearize() = if (this is DoubleBuffer) {
|
||||
private fun Buffer<Double>.linearize() = if (this is Float64Buffer) {
|
||||
this.array
|
||||
} else {
|
||||
DoubleArray(size) { get(it) }
|
||||
@ -66,10 +66,10 @@ public object DoubleLinearSpace : LinearSpace<Double, DoubleField> {
|
||||
}
|
||||
|
||||
@OptIn(PerformancePitfall::class)
|
||||
override fun Matrix<Double>.dot(vector: Point<Double>): DoubleBuffer {
|
||||
override fun Matrix<Double>.dot(vector: Point<Double>): Float64Buffer {
|
||||
require(colNum == vector.size) { "Matrix dot vector operation dimension mismatch: ($rowNum, $colNum) x (${vector.size})" }
|
||||
val rows = this@dot.rows.map { it.linearize() }
|
||||
return DoubleBuffer(rowNum) { i ->
|
||||
return Float64Buffer(rowNum) { i ->
|
||||
val r = rows[i]
|
||||
var res = 0.0
|
||||
for (j in r.indices) {
|
||||
@ -80,29 +80,29 @@ public object DoubleLinearSpace : LinearSpace<Double, DoubleField> {
|
||||
|
||||
}
|
||||
|
||||
override fun Matrix<Double>.times(value: Double): Matrix<Double> = DoubleFieldOpsND {
|
||||
override fun Matrix<Double>.times(value: Double): Matrix<Double> = Floa64FieldOpsND {
|
||||
asND().map { it * value }.as2D()
|
||||
}
|
||||
|
||||
public override fun Point<Double>.plus(other: Point<Double>): DoubleBuffer = DoubleBufferOps.run {
|
||||
public override fun Point<Double>.plus(other: Point<Double>): Float64Buffer = Float64BufferOps.run {
|
||||
this@plus + other
|
||||
}
|
||||
|
||||
public override fun Point<Double>.minus(other: Point<Double>): DoubleBuffer = DoubleBufferOps.run {
|
||||
public override fun Point<Double>.minus(other: Point<Double>): Float64Buffer = Float64BufferOps.run {
|
||||
this@minus - other
|
||||
}
|
||||
|
||||
public override fun Point<Double>.times(value: Double): DoubleBuffer = DoubleBufferOps.run {
|
||||
public override fun Point<Double>.times(value: Double): Float64Buffer = Float64BufferOps.run {
|
||||
scale(this@times, value)
|
||||
}
|
||||
|
||||
public operator fun Point<Double>.div(value: Double): DoubleBuffer = DoubleBufferOps.run {
|
||||
public operator fun Point<Double>.div(value: Double): Float64Buffer = Float64BufferOps.run {
|
||||
scale(this@div, 1.0 / value)
|
||||
}
|
||||
|
||||
public override fun Double.times(v: Point<Double>): DoubleBuffer = v * this
|
||||
public override fun Double.times(v: Point<Double>): Float64Buffer = v * this
|
||||
|
||||
|
||||
}
|
||||
|
||||
public val DoubleField.linearSpace: DoubleLinearSpace get() = DoubleLinearSpace
|
||||
public val Float64Field.linearSpace: Float64LinearSpace get() = Float64LinearSpace
|
@ -8,7 +8,7 @@ package space.kscience.kmath.linear
|
||||
import space.kscience.kmath.UnstableKMathAPI
|
||||
import space.kscience.kmath.operations.*
|
||||
import space.kscience.kmath.structures.BufferAccessor2D
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
import space.kscience.kmath.structures.Float64Buffer
|
||||
import space.kscience.kmath.structures.MutableBuffer
|
||||
import space.kscience.kmath.structures.MutableBufferFactory
|
||||
|
||||
@ -155,11 +155,11 @@ 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> =
|
||||
lup(::DoubleBuffer, matrix) { it < singularityThreshold }
|
||||
lup(::Float64Buffer, matrix) { it < singularityThreshold }
|
||||
|
||||
internal fun <T : Any> LupDecomposition<T>.solve(
|
||||
factory: MutableBufferFactory<T>,
|
||||
@ -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> =
|
||||
lupSolver(::DoubleBuffer) { it < singularityThreshold }
|
||||
public fun LinearSpace<Double, Float64Field>.lupSolver(singularityThreshold: Double = 1e-11): LinearSolver<Double> =
|
||||
lupSolver(::Float64Buffer) { it < singularityThreshold }
|
||||
|
@ -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 }
|
||||
|
||||
|
@ -8,7 +8,7 @@ package space.kscience.kmath.nd
|
||||
import space.kscience.kmath.PerformancePitfall
|
||||
import space.kscience.kmath.UnstableKMathAPI
|
||||
import space.kscience.kmath.operations.*
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
import space.kscience.kmath.structures.Float64Buffer
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.math.pow
|
||||
@ -17,9 +17,9 @@ import kotlin.math.pow as kpow
|
||||
/**
|
||||
* A simple mutable [StructureND] of doubles
|
||||
*/
|
||||
public class DoubleBufferND(
|
||||
public class Float64BufferND(
|
||||
indexes: ShapeIndexer,
|
||||
override val buffer: DoubleBuffer,
|
||||
override val buffer: Float64Buffer,
|
||||
) : MutableBufferND<Double>(indexes, buffer), MutableStructureNDOfDouble{
|
||||
override fun getDouble(index: IntArray): Double = buffer[indices.offset(index)]
|
||||
|
||||
@ -29,101 +29,101 @@ public class DoubleBufferND(
|
||||
}
|
||||
|
||||
|
||||
public sealed class DoubleFieldOpsND : BufferedFieldOpsND<Double, DoubleField>(DoubleField.bufferAlgebra),
|
||||
public sealed class Floa64FieldOpsND : BufferedFieldOpsND<Double, Float64Field>(Float64Field.bufferAlgebra),
|
||||
ScaleOperations<StructureND<Double>>, ExtendedFieldOps<StructureND<Double>> {
|
||||
|
||||
@OptIn(PerformancePitfall::class)
|
||||
override fun StructureND<Double>.toBufferND(): DoubleBufferND = when (this) {
|
||||
is DoubleBufferND -> this
|
||||
override fun StructureND<Double>.toBufferND(): Float64BufferND = when (this) {
|
||||
is Float64BufferND -> this
|
||||
else -> {
|
||||
val indexer = indexerBuilder(shape)
|
||||
DoubleBufferND(indexer, DoubleBuffer(indexer.linearSize) { offset -> get(indexer.index(offset)) })
|
||||
Float64BufferND(indexer, Float64Buffer(indexer.linearSize) { offset -> get(indexer.index(offset)) })
|
||||
}
|
||||
}
|
||||
|
||||
protected inline fun mapInline(
|
||||
arg: DoubleBufferND,
|
||||
arg: Float64BufferND,
|
||||
transform: (Double) -> Double,
|
||||
): DoubleBufferND {
|
||||
): Float64BufferND {
|
||||
val indexes = arg.indices
|
||||
val array = arg.buffer.array
|
||||
return DoubleBufferND(indexes, DoubleBuffer(indexes.linearSize) { transform(array[it]) })
|
||||
return Float64BufferND(indexes, Float64Buffer(indexes.linearSize) { transform(array[it]) })
|
||||
}
|
||||
|
||||
private inline fun zipInline(
|
||||
l: DoubleBufferND,
|
||||
r: DoubleBufferND,
|
||||
l: Float64BufferND,
|
||||
r: Float64BufferND,
|
||||
block: (l: Double, r: Double) -> Double,
|
||||
): DoubleBufferND {
|
||||
): Float64BufferND {
|
||||
require(l.indices == r.indices) { "Zip requires the same shapes, but found ${l.shape} on the left and ${r.shape} on the right" }
|
||||
val indexes = l.indices
|
||||
val lArray = l.buffer.array
|
||||
val rArray = r.buffer.array
|
||||
return DoubleBufferND(indexes, DoubleBuffer(indexes.linearSize) { block(lArray[it], rArray[it]) })
|
||||
return Float64BufferND(indexes, Float64Buffer(indexes.linearSize) { block(lArray[it], rArray[it]) })
|
||||
}
|
||||
|
||||
@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): Float64BufferND {
|
||||
val indexer = indexerBuilder(shape)
|
||||
return DoubleBufferND(
|
||||
return Float64BufferND(
|
||||
indexer,
|
||||
DoubleBuffer(indexer.linearSize) { offset ->
|
||||
Float64Buffer(indexer.linearSize) { offset ->
|
||||
elementAlgebra.initializer(indexer.index(offset))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun add(left: StructureND<Double>, right: StructureND<Double>): DoubleBufferND =
|
||||
override fun add(left: StructureND<Double>, right: StructureND<Double>): Float64BufferND =
|
||||
zipInline(left.toBufferND(), right.toBufferND()) { l, r -> l + r }
|
||||
|
||||
override fun multiply(left: StructureND<Double>, right: StructureND<Double>): DoubleBufferND =
|
||||
override fun multiply(left: StructureND<Double>, right: StructureND<Double>): Float64BufferND =
|
||||
zipInline(left.toBufferND(), right.toBufferND()) { l, r -> l * r }
|
||||
|
||||
override fun StructureND<Double>.unaryMinus(): DoubleBufferND = mapInline(toBufferND()) { -it }
|
||||
override fun StructureND<Double>.unaryMinus(): Float64BufferND = mapInline(toBufferND()) { -it }
|
||||
|
||||
override fun StructureND<Double>.div(arg: StructureND<Double>): DoubleBufferND =
|
||||
override fun StructureND<Double>.div(arg: StructureND<Double>): Float64BufferND =
|
||||
zipInline(toBufferND(), arg.toBufferND()) { l, r -> l / r }
|
||||
|
||||
override fun divide(left: StructureND<Double>, right: StructureND<Double>): DoubleBufferND =
|
||||
override fun divide(left: StructureND<Double>, right: StructureND<Double>): Float64BufferND =
|
||||
zipInline(left.toBufferND(), right.toBufferND()) { l: Double, r: Double -> l / r }
|
||||
|
||||
override fun StructureND<Double>.div(arg: Double): DoubleBufferND =
|
||||
override fun StructureND<Double>.div(arg: Double): Float64BufferND =
|
||||
mapInline(toBufferND()) { it / arg }
|
||||
|
||||
override fun Double.div(arg: StructureND<Double>): DoubleBufferND =
|
||||
override fun Double.div(arg: StructureND<Double>): Float64BufferND =
|
||||
mapInline(arg.toBufferND()) { this / it }
|
||||
|
||||
override fun StructureND<Double>.unaryPlus(): DoubleBufferND = toBufferND()
|
||||
override fun StructureND<Double>.unaryPlus(): Float64BufferND = toBufferND()
|
||||
|
||||
override fun StructureND<Double>.plus(arg: StructureND<Double>): DoubleBufferND =
|
||||
override fun StructureND<Double>.plus(arg: StructureND<Double>): Float64BufferND =
|
||||
zipInline(toBufferND(), arg.toBufferND()) { l: Double, r: Double -> l + r }
|
||||
|
||||
override fun StructureND<Double>.minus(arg: StructureND<Double>): DoubleBufferND =
|
||||
override fun StructureND<Double>.minus(arg: StructureND<Double>): Float64BufferND =
|
||||
zipInline(toBufferND(), arg.toBufferND()) { l: Double, r: Double -> l - r }
|
||||
|
||||
override fun StructureND<Double>.times(arg: StructureND<Double>): DoubleBufferND =
|
||||
override fun StructureND<Double>.times(arg: StructureND<Double>): Float64BufferND =
|
||||
zipInline(toBufferND(), arg.toBufferND()) { l: Double, r: Double -> l * r }
|
||||
|
||||
override fun StructureND<Double>.times(k: Number): DoubleBufferND =
|
||||
override fun StructureND<Double>.times(k: Number): Float64BufferND =
|
||||
mapInline(toBufferND()) { it * k.toDouble() }
|
||||
|
||||
override fun StructureND<Double>.div(k: Number): DoubleBufferND =
|
||||
override fun StructureND<Double>.div(k: Number): Float64BufferND =
|
||||
mapInline(toBufferND()) { it / k.toDouble() }
|
||||
|
||||
override fun Number.times(arg: StructureND<Double>): DoubleBufferND = arg * this
|
||||
override fun Number.times(arg: StructureND<Double>): Float64BufferND = arg * this
|
||||
|
||||
override fun StructureND<Double>.plus(arg: Double): DoubleBufferND = mapInline(toBufferND()) { it + arg }
|
||||
override fun StructureND<Double>.plus(arg: Double): Float64BufferND = mapInline(toBufferND()) { it + arg }
|
||||
|
||||
override fun StructureND<Double>.minus(arg: Double): StructureND<Double> = mapInline(toBufferND()) { it - arg }
|
||||
|
||||
@ -131,49 +131,49 @@ public sealed class DoubleFieldOpsND : BufferedFieldOpsND<Double, DoubleField>(D
|
||||
|
||||
override fun Double.minus(arg: StructureND<Double>): StructureND<Double> = mapInline(arg.toBufferND()) { this - it }
|
||||
|
||||
override fun scale(a: StructureND<Double>, value: Double): DoubleBufferND =
|
||||
override fun scale(a: StructureND<Double>, value: Double): Float64BufferND =
|
||||
mapInline(a.toBufferND()) { it * value }
|
||||
|
||||
override fun exp(arg: StructureND<Double>): DoubleBufferND =
|
||||
override fun exp(arg: StructureND<Double>): Float64BufferND =
|
||||
mapInline(arg.toBufferND()) { kotlin.math.exp(it) }
|
||||
|
||||
override fun ln(arg: StructureND<Double>): DoubleBufferND =
|
||||
override fun ln(arg: StructureND<Double>): Float64BufferND =
|
||||
mapInline(arg.toBufferND()) { kotlin.math.ln(it) }
|
||||
|
||||
override fun sin(arg: StructureND<Double>): DoubleBufferND =
|
||||
override fun sin(arg: StructureND<Double>): Float64BufferND =
|
||||
mapInline(arg.toBufferND()) { kotlin.math.sin(it) }
|
||||
|
||||
override fun cos(arg: StructureND<Double>): DoubleBufferND =
|
||||
override fun cos(arg: StructureND<Double>): Float64BufferND =
|
||||
mapInline(arg.toBufferND()) { kotlin.math.cos(it) }
|
||||
|
||||
override fun tan(arg: StructureND<Double>): DoubleBufferND =
|
||||
override fun tan(arg: StructureND<Double>): Float64BufferND =
|
||||
mapInline(arg.toBufferND()) { kotlin.math.tan(it) }
|
||||
|
||||
override fun asin(arg: StructureND<Double>): DoubleBufferND =
|
||||
override fun asin(arg: StructureND<Double>): Float64BufferND =
|
||||
mapInline(arg.toBufferND()) { kotlin.math.asin(it) }
|
||||
|
||||
override fun acos(arg: StructureND<Double>): DoubleBufferND =
|
||||
override fun acos(arg: StructureND<Double>): Float64BufferND =
|
||||
mapInline(arg.toBufferND()) { kotlin.math.acos(it) }
|
||||
|
||||
override fun atan(arg: StructureND<Double>): DoubleBufferND =
|
||||
override fun atan(arg: StructureND<Double>): Float64BufferND =
|
||||
mapInline(arg.toBufferND()) { kotlin.math.atan(it) }
|
||||
|
||||
override fun sinh(arg: StructureND<Double>): DoubleBufferND =
|
||||
override fun sinh(arg: StructureND<Double>): Float64BufferND =
|
||||
mapInline(arg.toBufferND()) { kotlin.math.sinh(it) }
|
||||
|
||||
override fun cosh(arg: StructureND<Double>): DoubleBufferND =
|
||||
override fun cosh(arg: StructureND<Double>): Float64BufferND =
|
||||
mapInline(arg.toBufferND()) { kotlin.math.cosh(it) }
|
||||
|
||||
override fun tanh(arg: StructureND<Double>): DoubleBufferND =
|
||||
override fun tanh(arg: StructureND<Double>): Float64BufferND =
|
||||
mapInline(arg.toBufferND()) { kotlin.math.tanh(it) }
|
||||
|
||||
override fun asinh(arg: StructureND<Double>): DoubleBufferND =
|
||||
override fun asinh(arg: StructureND<Double>): Float64BufferND =
|
||||
mapInline(arg.toBufferND()) { kotlin.math.asinh(it) }
|
||||
|
||||
override fun acosh(arg: StructureND<Double>): DoubleBufferND =
|
||||
override fun acosh(arg: StructureND<Double>): Float64BufferND =
|
||||
mapInline(arg.toBufferND()) { kotlin.math.acosh(it) }
|
||||
|
||||
override fun atanh(arg: StructureND<Double>): DoubleBufferND =
|
||||
override fun atanh(arg: StructureND<Double>): Float64BufferND =
|
||||
mapInline(arg.toBufferND()) { kotlin.math.atanh(it) }
|
||||
|
||||
override fun power(
|
||||
@ -185,23 +185,23 @@ public sealed class DoubleFieldOpsND : BufferedFieldOpsND<Double, DoubleField>(D
|
||||
mapInline(arg.toBufferND()) { it.pow(pow.toDouble()) }
|
||||
}
|
||||
|
||||
public companion object : DoubleFieldOpsND()
|
||||
public companion object : Floa64FieldOpsND()
|
||||
}
|
||||
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
public class DoubleFieldND(override val shape: ShapeND) :
|
||||
DoubleFieldOpsND(), FieldND<Double, DoubleField>, NumbersAddOps<StructureND<Double>>,
|
||||
public class Float64FieldND(override val shape: ShapeND) :
|
||||
Floa64FieldOpsND(), FieldND<Double, Float64Field>, NumbersAddOps<StructureND<Double>>,
|
||||
ExtendedField<StructureND<Double>> {
|
||||
|
||||
override fun power(arg: StructureND<Double>, pow: UInt): DoubleBufferND = mapInline(arg.toBufferND()) {
|
||||
override fun power(arg: StructureND<Double>, pow: UInt): Float64BufferND = mapInline(arg.toBufferND()) {
|
||||
it.kpow(pow.toInt())
|
||||
}
|
||||
|
||||
override fun power(arg: StructureND<Double>, pow: Int): DoubleBufferND = mapInline(arg.toBufferND()) {
|
||||
override fun power(arg: StructureND<Double>, pow: Int): Float64BufferND = mapInline(arg.toBufferND()) {
|
||||
it.kpow(pow)
|
||||
}
|
||||
|
||||
override fun power(arg: StructureND<Double>, pow: Number): DoubleBufferND = if (pow.isInteger()) {
|
||||
override fun power(arg: StructureND<Double>, pow: Number): Float64BufferND = if (pow.isInteger()) {
|
||||
power(arg, pow.toInt())
|
||||
} else {
|
||||
val dpow = pow.toDouble()
|
||||
@ -211,34 +211,34 @@ public class DoubleFieldND(override val shape: ShapeND) :
|
||||
}
|
||||
}
|
||||
|
||||
override fun sinh(arg: StructureND<Double>): DoubleBufferND = super<DoubleFieldOpsND>.sinh(arg)
|
||||
override fun sinh(arg: StructureND<Double>): Float64BufferND = super<Floa64FieldOpsND>.sinh(arg)
|
||||
|
||||
override fun cosh(arg: StructureND<Double>): DoubleBufferND = super<DoubleFieldOpsND>.cosh(arg)
|
||||
override fun cosh(arg: StructureND<Double>): Float64BufferND = super<Floa64FieldOpsND>.cosh(arg)
|
||||
|
||||
override fun tanh(arg: StructureND<Double>): DoubleBufferND = super<DoubleFieldOpsND>.tan(arg)
|
||||
override fun tanh(arg: StructureND<Double>): Float64BufferND = super<Floa64FieldOpsND>.tan(arg)
|
||||
|
||||
override fun asinh(arg: StructureND<Double>): DoubleBufferND = super<DoubleFieldOpsND>.asinh(arg)
|
||||
override fun asinh(arg: StructureND<Double>): Float64BufferND = super<Floa64FieldOpsND>.asinh(arg)
|
||||
|
||||
override fun acosh(arg: StructureND<Double>): DoubleBufferND = super<DoubleFieldOpsND>.acosh(arg)
|
||||
override fun acosh(arg: StructureND<Double>): Float64BufferND = super<Floa64FieldOpsND>.acosh(arg)
|
||||
|
||||
override fun atanh(arg: StructureND<Double>): DoubleBufferND = super<DoubleFieldOpsND>.atanh(arg)
|
||||
override fun atanh(arg: StructureND<Double>): Float64BufferND = super<Floa64FieldOpsND>.atanh(arg)
|
||||
|
||||
override fun number(value: Number): DoubleBufferND {
|
||||
override fun number(value: Number): Float64BufferND {
|
||||
val d = value.toDouble() // minimize conversions
|
||||
return structureND(shape) { d }
|
||||
}
|
||||
}
|
||||
|
||||
public val DoubleField.ndAlgebra: DoubleFieldOpsND get() = DoubleFieldOpsND
|
||||
public val Float64Field.ndAlgebra: Floa64FieldOpsND get() = Floa64FieldOpsND
|
||||
|
||||
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): Float64FieldND = Float64FieldND(ShapeND(shape))
|
||||
public fun Float64Field.ndAlgebra(shape: ShapeND): Float64FieldND = Float64FieldND(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: Float64FieldND.() -> R): R {
|
||||
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
|
||||
return DoubleFieldND(ShapeND(shape)).run(action)
|
||||
return Float64FieldND(ShapeND(shape)).run(action)
|
||||
}
|
@ -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 companion object : ShortRingOpsND()
|
||||
public sealed class Int16RingOpsND : BufferedRingOpsND<Short, Int16Ring>(Int16Ring.bufferAlgebra) {
|
||||
public companion object : Int16RingOpsND()
|
||||
}
|
||||
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
public class ShortRingND(
|
||||
public class Int16RingND(
|
||||
override val shape: ShapeND
|
||||
) : ShortRingOpsND(), RingND<Short, ShortRing>, NumbersAddOps<StructureND<Short>> {
|
||||
) : Int16RingOpsND(), 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: Int16RingND.() -> R): R {
|
||||
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
|
||||
return ShortRingND(ShapeND(shape)).run(action)
|
||||
return Int16RingND(ShapeND(shape)).run(action)
|
||||
}
|
@ -6,25 +6,25 @@
|
||||
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
|
||||
import space.kscience.kmath.structures.Int32Buffer
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
|
||||
public class IntBufferND(
|
||||
indexes: ShapeIndexer,
|
||||
override val buffer: IntBuffer,
|
||||
override val buffer: Int32Buffer,
|
||||
) : 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,
|
||||
IntBuffer(indexer.linearSize) { offset ->
|
||||
Int32Buffer(indexer.linearSize) { offset ->
|
||||
elementAlgebra.initializer(indexer.index(offset))
|
||||
}
|
||||
)
|
||||
@ -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)
|
||||
}
|
||||
|
@ -300,7 +300,7 @@ public interface Ring<T> : Group<T>, RingOps<T> {
|
||||
* commutative operations [add] and [multiply]; binary operation [divide] as multiplication of left operand by
|
||||
* reciprocal of right one.
|
||||
*
|
||||
* @param T the type of element of this semifield.
|
||||
* @param T the type of the semifield element.
|
||||
*/
|
||||
public interface FieldOps<T> : RingOps<T> {
|
||||
/**
|
||||
@ -336,10 +336,12 @@ public interface FieldOps<T> : RingOps<T> {
|
||||
|
||||
/**
|
||||
* Represents field i.e., algebraic structure with three operations: associative, commutative addition and
|
||||
* multiplication, and division. **This interface differs from the eponymous mathematical definition: fields in KMath
|
||||
* multiplication, and division.
|
||||
*
|
||||
* **This interface differs from the eponymous mathematical definition: fields in KMath
|
||||
* also support associative multiplication by scalar.**
|
||||
*
|
||||
* @param T the type of element of this field.
|
||||
* @param T the type of the field element.
|
||||
*/
|
||||
public interface Field<T> : Ring<T>, FieldOps<T>, ScaleOperations<T>, NumericAlgebra<T> {
|
||||
override fun number(value: Number): T = scale(one, value.toDouble())
|
||||
|
@ -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,
|
||||
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package space.kscience.kmath.operations
|
||||
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
|
||||
/**
|
||||
* [ExtendedField] over [DoubleBuffer].
|
||||
*
|
||||
* @property size the size of buffers to operate on.
|
||||
*/
|
||||
public class DoubleBufferField(public val size: Int) : ExtendedField<Buffer<Double>>, DoubleBufferOps() {
|
||||
override val zero: Buffer<Double> by lazy { DoubleBuffer(size) { 0.0 } }
|
||||
override val one: Buffer<Double> by lazy { DoubleBuffer(size) { 1.0 } }
|
||||
|
||||
override fun sinh(arg: Buffer<Double>): DoubleBuffer = super<DoubleBufferOps>.sinh(arg)
|
||||
|
||||
override fun cosh(arg: Buffer<Double>): DoubleBuffer = super<DoubleBufferOps>.cosh(arg)
|
||||
|
||||
override fun tanh(arg: Buffer<Double>): DoubleBuffer = super<DoubleBufferOps>.tanh(arg)
|
||||
|
||||
override fun asinh(arg: Buffer<Double>): DoubleBuffer = super<DoubleBufferOps>.asinh(arg)
|
||||
|
||||
override fun acosh(arg: Buffer<Double>): DoubleBuffer = super<DoubleBufferOps>.acosh(arg)
|
||||
|
||||
override fun atanh(arg: Buffer<Double>): DoubleBuffer = super<DoubleBufferOps>.atanh(arg)
|
||||
|
||||
override fun power(arg: Buffer<Double>, pow: Number): DoubleBuffer = if (pow.isInteger()) {
|
||||
arg.map { it.pow(pow.toInt()) }
|
||||
} else {
|
||||
arg.map {
|
||||
if(it<0) throw IllegalArgumentException("Negative argument $it could not be raised to the fractional power")
|
||||
it.pow(pow.toDouble())
|
||||
}
|
||||
}
|
||||
|
||||
override fun unaryOperationFunction(operation: String): (arg: Buffer<Double>) -> Buffer<Double> =
|
||||
super<ExtendedField>.unaryOperationFunction(operation)
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package space.kscience.kmath.operations
|
||||
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.Float64Buffer
|
||||
|
||||
/**
|
||||
* [ExtendedField] over [Float64Buffer].
|
||||
*
|
||||
* @property size the size of buffers to operate on.
|
||||
*/
|
||||
public class Float64BufferField(public val size: Int) : ExtendedField<Buffer<Double>>, Float64BufferOps() {
|
||||
override val zero: Buffer<Double> by lazy { Float64Buffer(size) { 0.0 } }
|
||||
override val one: Buffer<Double> by lazy { Float64Buffer(size) { 1.0 } }
|
||||
|
||||
override fun sinh(arg: Buffer<Double>): Float64Buffer = super<Float64BufferOps>.sinh(arg)
|
||||
|
||||
override fun cosh(arg: Buffer<Double>): Float64Buffer = super<Float64BufferOps>.cosh(arg)
|
||||
|
||||
override fun tanh(arg: Buffer<Double>): Float64Buffer = super<Float64BufferOps>.tanh(arg)
|
||||
|
||||
override fun asinh(arg: Buffer<Double>): Float64Buffer = super<Float64BufferOps>.asinh(arg)
|
||||
|
||||
override fun acosh(arg: Buffer<Double>): Float64Buffer = super<Float64BufferOps>.acosh(arg)
|
||||
|
||||
override fun atanh(arg: Buffer<Double>): Float64Buffer = super<Float64BufferOps>.atanh(arg)
|
||||
|
||||
override fun power(arg: Buffer<Double>, pow: Number): Float64Buffer = if (pow.isInteger()) {
|
||||
arg.map { it.pow(pow.toInt()) }
|
||||
} else {
|
||||
arg.map {
|
||||
if(it<0) throw IllegalArgumentException("Negative argument $it could not be raised to the fractional power")
|
||||
it.pow(pow.toDouble())
|
||||
}
|
||||
}
|
||||
|
||||
override fun unaryOperationFunction(operation: String): (arg: Buffer<Double>) -> Buffer<Double> =
|
||||
super<ExtendedField>.unaryOperationFunction(operation)
|
||||
}
|
@ -12,34 +12,34 @@ import kotlin.math.pow
|
||||
import kotlin.math.sqrt
|
||||
|
||||
/**
|
||||
* [ExtendedFieldOps] over [DoubleBuffer].
|
||||
* [ExtendedFieldOps] over [Float64Buffer].
|
||||
*/
|
||||
public abstract class DoubleBufferOps : BufferAlgebra<Double, DoubleField>, ExtendedFieldOps<Buffer<Double>>,
|
||||
public abstract class Float64BufferOps : 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): Float64Buffer =
|
||||
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): Float64Buffer =
|
||||
Float64Buffer(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,
|
||||
): DoubleBuffer {
|
||||
block: Float64Field.(left: Double, right: Double) -> Double,
|
||||
): Float64Buffer {
|
||||
require(size == other.size) { "Incompatible buffer sizes. left: ${size}, right: ${other.size}" }
|
||||
return DoubleBuffer(size) { DoubleField.block(getDouble(it), other.getDouble(it)) }
|
||||
return Float64Buffer(size) { Float64Field.block(getDouble(it), other.getDouble(it)) }
|
||||
}
|
||||
|
||||
override fun unaryOperationFunction(operation: String): (arg: Buffer<Double>) -> Buffer<Double> =
|
||||
@ -48,32 +48,32 @@ public abstract class DoubleBufferOps : BufferAlgebra<Double, DoubleField>, Exte
|
||||
override fun binaryOperationFunction(operation: String): (left: Buffer<Double>, right: Buffer<Double>) -> Buffer<Double> =
|
||||
super<ExtendedFieldOps>.binaryOperationFunction(operation)
|
||||
|
||||
override fun Buffer<Double>.unaryMinus(): DoubleBuffer = map { -it }
|
||||
override fun Buffer<Double>.unaryMinus(): Float64Buffer = map { -it }
|
||||
|
||||
override fun add(left: Buffer<Double>, right: Buffer<Double>): DoubleBuffer {
|
||||
override fun add(left: Buffer<Double>, right: Buffer<Double>): Float64Buffer {
|
||||
require(right.size == left.size) {
|
||||
"The size of the first buffer ${left.size} should be the same as for second one: ${right.size} "
|
||||
}
|
||||
|
||||
return if (left is DoubleBuffer && right is DoubleBuffer) {
|
||||
return if (left is Float64Buffer && right is Float64Buffer) {
|
||||
val aArray = left.array
|
||||
val bArray = right.array
|
||||
DoubleBuffer(DoubleArray(left.size) { aArray[it] + bArray[it] })
|
||||
} else DoubleBuffer(DoubleArray(left.size) { left[it] + right[it] })
|
||||
Float64Buffer(DoubleArray(left.size) { aArray[it] + bArray[it] })
|
||||
} else Float64Buffer(DoubleArray(left.size) { left[it] + right[it] })
|
||||
}
|
||||
|
||||
override fun Buffer<Double>.plus(arg: Buffer<Double>): DoubleBuffer = add(this, arg)
|
||||
override fun Buffer<Double>.plus(arg: Buffer<Double>): Float64Buffer = add(this, arg)
|
||||
|
||||
override fun Buffer<Double>.minus(arg: Buffer<Double>): DoubleBuffer {
|
||||
override fun Buffer<Double>.minus(arg: Buffer<Double>): Float64Buffer {
|
||||
require(arg.size == this.size) {
|
||||
"The size of the first buffer ${this.size} should be the same as for second one: ${arg.size} "
|
||||
}
|
||||
|
||||
return if (this is DoubleBuffer && arg is DoubleBuffer) {
|
||||
return if (this is Float64Buffer && arg is Float64Buffer) {
|
||||
val aArray = this.array
|
||||
val bArray = arg.array
|
||||
DoubleBuffer(DoubleArray(this.size) { aArray[it] - bArray[it] })
|
||||
} else DoubleBuffer(DoubleArray(this.size) { this[it] - arg[it] })
|
||||
Float64Buffer(DoubleArray(this.size) { aArray[it] - bArray[it] })
|
||||
} else Float64Buffer(DoubleArray(this.size) { this[it] - arg[it] })
|
||||
}
|
||||
|
||||
//
|
||||
@ -96,61 +96,61 @@ public abstract class DoubleBufferOps : BufferAlgebra<Double, DoubleField>, Exte
|
||||
// }
|
||||
|
||||
@UnstableKMathAPI
|
||||
override fun multiply(left: Buffer<Double>, right: Buffer<Double>): DoubleBuffer {
|
||||
override fun multiply(left: Buffer<Double>, right: Buffer<Double>): Float64Buffer {
|
||||
require(right.size == left.size) {
|
||||
"The size of the first buffer ${left.size} should be the same as for second one: ${right.size} "
|
||||
}
|
||||
|
||||
return if (left is DoubleBuffer && right is DoubleBuffer) {
|
||||
return if (left is Float64Buffer && right is Float64Buffer) {
|
||||
val aArray = left.array
|
||||
val bArray = right.array
|
||||
DoubleBuffer(DoubleArray(left.size) { aArray[it] * bArray[it] })
|
||||
} else DoubleBuffer(DoubleArray(left.size) { left[it] * right[it] })
|
||||
Float64Buffer(DoubleArray(left.size) { aArray[it] * bArray[it] })
|
||||
} else Float64Buffer(DoubleArray(left.size) { left[it] * right[it] })
|
||||
}
|
||||
|
||||
override fun divide(left: Buffer<Double>, right: Buffer<Double>): DoubleBuffer {
|
||||
override fun divide(left: Buffer<Double>, right: Buffer<Double>): Float64Buffer {
|
||||
require(right.size == left.size) {
|
||||
"The size of the first buffer ${left.size} should be the same as for second one: ${right.size} "
|
||||
}
|
||||
|
||||
return if (left is DoubleBuffer && right is DoubleBuffer) {
|
||||
return if (left is Float64Buffer && right is Float64Buffer) {
|
||||
val aArray = left.array
|
||||
val bArray = right.array
|
||||
DoubleBuffer(DoubleArray(left.size) { aArray[it] / bArray[it] })
|
||||
} else DoubleBuffer(DoubleArray(left.size) { left[it] / right[it] })
|
||||
Float64Buffer(DoubleArray(left.size) { aArray[it] / bArray[it] })
|
||||
} else Float64Buffer(DoubleArray(left.size) { left[it] / right[it] })
|
||||
}
|
||||
|
||||
override fun sin(arg: Buffer<Double>): DoubleBuffer = arg.map { sin(it) }
|
||||
override fun sin(arg: Buffer<Double>): Float64Buffer = arg.map { sin(it) }
|
||||
|
||||
override fun cos(arg: Buffer<Double>): DoubleBuffer = arg.map { cos(it) }
|
||||
override fun cos(arg: Buffer<Double>): Float64Buffer = arg.map { cos(it) }
|
||||
|
||||
override fun tan(arg: Buffer<Double>): DoubleBuffer = arg.map { tan(it) }
|
||||
override fun tan(arg: Buffer<Double>): Float64Buffer = arg.map { tan(it) }
|
||||
|
||||
override fun asin(arg: Buffer<Double>): DoubleBuffer = arg.map { asin(it) }
|
||||
override fun asin(arg: Buffer<Double>): Float64Buffer = arg.map { asin(it) }
|
||||
|
||||
override fun acos(arg: Buffer<Double>): DoubleBuffer = arg.map { acos(it) }
|
||||
override fun acos(arg: Buffer<Double>): Float64Buffer = arg.map { acos(it) }
|
||||
|
||||
override fun atan(arg: Buffer<Double>): DoubleBuffer = arg.map { atan(it) }
|
||||
override fun atan(arg: Buffer<Double>): Float64Buffer = arg.map { atan(it) }
|
||||
|
||||
override fun sinh(arg: Buffer<Double>): DoubleBuffer = arg.map { sinh(it) }
|
||||
override fun sinh(arg: Buffer<Double>): Float64Buffer = arg.map { sinh(it) }
|
||||
|
||||
override fun cosh(arg: Buffer<Double>): DoubleBuffer = arg.map { cosh(it) }
|
||||
override fun cosh(arg: Buffer<Double>): Float64Buffer = arg.map { cosh(it) }
|
||||
|
||||
override fun tanh(arg: Buffer<Double>): DoubleBuffer = arg.map { tanh(it) }
|
||||
override fun tanh(arg: Buffer<Double>): Float64Buffer = arg.map { tanh(it) }
|
||||
|
||||
override fun asinh(arg: Buffer<Double>): DoubleBuffer = arg.map { asinh(it) }
|
||||
override fun asinh(arg: Buffer<Double>): Float64Buffer = arg.map { asinh(it) }
|
||||
|
||||
override fun acosh(arg: Buffer<Double>): DoubleBuffer = arg.map { acosh(it) }
|
||||
override fun acosh(arg: Buffer<Double>): Float64Buffer = arg.map { acosh(it) }
|
||||
|
||||
override fun atanh(arg: Buffer<Double>): DoubleBuffer = arg.map { atanh(it) }
|
||||
override fun atanh(arg: Buffer<Double>): Float64Buffer = arg.map { atanh(it) }
|
||||
|
||||
override fun exp(arg: Buffer<Double>): DoubleBuffer = arg.map { exp(it) }
|
||||
override fun exp(arg: Buffer<Double>): Float64Buffer = arg.map { exp(it) }
|
||||
|
||||
override fun ln(arg: Buffer<Double>): DoubleBuffer = arg.map { ln(it) }
|
||||
override fun ln(arg: Buffer<Double>): Float64Buffer = arg.map { ln(it) }
|
||||
|
||||
override fun norm(arg: Buffer<Double>): Double = DoubleL2Norm.norm(arg)
|
||||
override fun norm(arg: Buffer<Double>): Double = Float64L2Norm.norm(arg)
|
||||
|
||||
override fun scale(a: Buffer<Double>, value: Double): DoubleBuffer = a.map { it * value }
|
||||
override fun scale(a: Buffer<Double>, value: Double): Float64Buffer = a.map { it * value }
|
||||
|
||||
override fun power(arg: Buffer<Double>, pow: Number): Buffer<Double> = if (pow is Int) {
|
||||
arg.map { it.pow(pow) }
|
||||
@ -158,37 +158,37 @@ public abstract class DoubleBufferOps : BufferAlgebra<Double, DoubleField>, Exte
|
||||
arg.map { it.pow(pow.toDouble()) }
|
||||
}
|
||||
|
||||
public companion object : DoubleBufferOps()
|
||||
public companion object : Float64BufferOps()
|
||||
}
|
||||
|
||||
public object DoubleL2Norm : Norm<Point<Double>, Double> {
|
||||
public object Float64L2Norm : Norm<Point<Double>, Double> {
|
||||
override fun norm(arg: Point<Double>): Double = sqrt(arg.fold(0.0) { acc: Double, d: Double -> acc + d.pow(2) })
|
||||
}
|
||||
|
||||
public fun DoubleBufferOps.sum(buffer: Buffer<Double>): Double = buffer.reduce(Double::plus)
|
||||
public fun Float64BufferOps.sum(buffer: Buffer<Double>): Double = buffer.reduce(Double::plus)
|
||||
|
||||
/**
|
||||
* Sum of elements using given [conversion]
|
||||
*/
|
||||
public inline fun <T> DoubleBufferOps.sumOf(buffer: Buffer<T>, conversion: (T) -> Double): Double =
|
||||
public inline fun <T> Float64BufferOps.sumOf(buffer: Buffer<T>, conversion: (T) -> Double): Double =
|
||||
buffer.fold(0.0) { acc, value -> acc + conversion(value) }
|
||||
|
||||
public fun DoubleBufferOps.average(buffer: Buffer<Double>): Double = sum(buffer) / buffer.size
|
||||
public fun Float64BufferOps.average(buffer: Buffer<Double>): Double = sum(buffer) / buffer.size
|
||||
|
||||
/**
|
||||
* Average of elements using given [conversion]
|
||||
*/
|
||||
public inline fun <T> DoubleBufferOps.averageOf(buffer: Buffer<T>, conversion: (T) -> Double): Double =
|
||||
public inline fun <T> Float64BufferOps.averageOf(buffer: Buffer<T>, conversion: (T) -> Double): Double =
|
||||
sumOf(buffer, conversion) / buffer.size
|
||||
|
||||
public fun DoubleBufferOps.dispersion(buffer: Buffer<Double>): Double {
|
||||
public fun Float64BufferOps.dispersion(buffer: Buffer<Double>): Double {
|
||||
val av = average(buffer)
|
||||
return buffer.fold(0.0) { acc, value -> acc + (value - av).pow(2) } / buffer.size
|
||||
}
|
||||
|
||||
public fun DoubleBufferOps.std(buffer: Buffer<Double>): Double = sqrt(dispersion(buffer))
|
||||
public fun Float64BufferOps.std(buffer: Buffer<Double>): Double = sqrt(dispersion(buffer))
|
||||
|
||||
public fun DoubleBufferOps.covariance(x: Buffer<Double>, y: Buffer<Double>): Double {
|
||||
public fun Float64BufferOps.covariance(x: Buffer<Double>, y: Buffer<Double>): Double {
|
||||
require(x.size == y.size) { "Expected buffers of the same size, but x.size == ${x.size} and y.size == ${y.size}" }
|
||||
val xMean = average(x)
|
||||
val yMean = average(y)
|
@ -150,7 +150,7 @@ public interface ScaleOperations<T> : Algebra<T> {
|
||||
* TODO to be removed and replaced by extensions after multiple receivers are there
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public interface NumbersAddOps<T> : RingOps<T>, NumericAlgebra<T> {
|
||||
public interface NumbersAddOps<T> : GroupOps<T>, NumericAlgebra<T> {
|
||||
/**
|
||||
* Addition of element and scalar.
|
||||
*
|
||||
@ -177,7 +177,7 @@ public interface NumbersAddOps<T> : RingOps<T>, NumericAlgebra<T> {
|
||||
public operator fun T.minus(other: Number): T = this - number(other)
|
||||
|
||||
/**
|
||||
* Subtraction of number from element.
|
||||
* Subtraction of number from the element.
|
||||
*
|
||||
* @receiver the minuend.
|
||||
* @param other the subtrahend.
|
||||
|
@ -82,9 +82,9 @@ public expect fun Number.isInteger(): Boolean
|
||||
/**
|
||||
* A context extension to include power operations based on exponentiation.
|
||||
*
|
||||
* @param T the type of element of this structure.
|
||||
* @param T the type of this structure element
|
||||
*/
|
||||
public interface PowerOperations<T> : FieldOps<T> {
|
||||
public interface PowerOperations<T>: Algebra<T> {
|
||||
|
||||
/**
|
||||
* Raises [arg] to a power if possible (negative number could not be raised to a fractional power).
|
||||
|
@ -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(::Int16Buffer)
|
||||
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(::Int32Buffer)
|
||||
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(::Int64Buffer)
|
||||
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
|
||||
}
|
@ -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.*
|
||||
@ -64,16 +63,16 @@ public interface ExtendedField<T> : ExtendedFieldOps<T>, Field<T>, NumericAlgebr
|
||||
}
|
||||
|
||||
/**
|
||||
* A field for [Double] without boxing. Does not produce appropriate field element.
|
||||
* A field for [Double] without boxing. Does not produce an appropriate field element.
|
||||
*/
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE")
|
||||
public object DoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOperations<Double> {
|
||||
override val bufferFactory: MutableBufferFactory<Double> = MutableBufferFactory(::DoubleBuffer)
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
||||
public object Float64Field : ExtendedField<Double>, Norm<Double, Double>, ScaleOperations<Double> {
|
||||
override val bufferFactory: MutableBufferFactory<Double> = MutableBufferFactory(::Float64Buffer)
|
||||
|
||||
override inline val zero: Double get() = 0.0
|
||||
override inline val one: Double get() = 1.0
|
||||
override val zero: Double get() = 0.0
|
||||
override val one: Double get() = 1.0
|
||||
|
||||
override inline fun number(value: Number): Double = value.toDouble()
|
||||
override fun number(value: Number): Double = value.toDouble()
|
||||
|
||||
override fun binaryOperationFunction(operation: String): (left: Double, right: Double) -> Double =
|
||||
when (operation) {
|
||||
@ -81,26 +80,26 @@ public object DoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOp
|
||||
else -> super<ExtendedField>.binaryOperationFunction(operation)
|
||||
}
|
||||
|
||||
override inline fun add(left: Double, right: Double): Double = left + right
|
||||
override fun add(left: Double, right: Double): Double = left + right
|
||||
|
||||
override inline fun multiply(left: Double, right: Double): Double = left * right
|
||||
override inline fun divide(left: Double, right: Double): Double = left / right
|
||||
override fun multiply(left: Double, right: Double): Double = left * right
|
||||
override fun divide(left: Double, right: Double): Double = left / right
|
||||
|
||||
override inline fun scale(a: Double, value: Double): Double = a * value
|
||||
override fun scale(a: Double, value: Double): Double = a * value
|
||||
|
||||
override inline fun sin(arg: Double): Double = kotlin.math.sin(arg)
|
||||
override inline fun cos(arg: Double): Double = kotlin.math.cos(arg)
|
||||
override inline fun tan(arg: Double): Double = kotlin.math.tan(arg)
|
||||
override inline fun acos(arg: Double): Double = kotlin.math.acos(arg)
|
||||
override inline fun asin(arg: Double): Double = kotlin.math.asin(arg)
|
||||
override inline fun atan(arg: Double): Double = kotlin.math.atan(arg)
|
||||
override fun sin(arg: Double): Double = kotlin.math.sin(arg)
|
||||
override fun cos(arg: Double): Double = kotlin.math.cos(arg)
|
||||
override fun tan(arg: Double): Double = kotlin.math.tan(arg)
|
||||
override fun acos(arg: Double): Double = kotlin.math.acos(arg)
|
||||
override fun asin(arg: Double): Double = kotlin.math.asin(arg)
|
||||
override fun atan(arg: Double): Double = kotlin.math.atan(arg)
|
||||
|
||||
override inline fun sinh(arg: Double): Double = kotlin.math.sinh(arg)
|
||||
override inline fun cosh(arg: Double): Double = kotlin.math.cosh(arg)
|
||||
override inline fun tanh(arg: Double): Double = kotlin.math.tanh(arg)
|
||||
override inline fun asinh(arg: Double): Double = kotlin.math.asinh(arg)
|
||||
override inline fun acosh(arg: Double): Double = kotlin.math.acosh(arg)
|
||||
override inline fun atanh(arg: Double): Double = kotlin.math.atanh(arg)
|
||||
override fun sinh(arg: Double): Double = kotlin.math.sinh(arg)
|
||||
override fun cosh(arg: Double): Double = kotlin.math.cosh(arg)
|
||||
override fun tanh(arg: Double): Double = kotlin.math.tanh(arg)
|
||||
override fun asinh(arg: Double): Double = kotlin.math.asinh(arg)
|
||||
override fun acosh(arg: Double): Double = kotlin.math.acosh(arg)
|
||||
override fun atanh(arg: Double): Double = kotlin.math.atanh(arg)
|
||||
|
||||
override fun sqrt(arg: Double): Double = kotlin.math.sqrt(arg)
|
||||
override fun power(arg: Double, pow: Number): Double = when {
|
||||
@ -109,29 +108,31 @@ public object DoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOp
|
||||
else -> arg.kpow(pow.toDouble())
|
||||
}
|
||||
|
||||
override inline fun exp(arg: Double): Double = kotlin.math.exp(arg)
|
||||
override inline fun ln(arg: Double): Double = kotlin.math.ln(arg)
|
||||
override fun exp(arg: Double): Double = kotlin.math.exp(arg)
|
||||
override fun ln(arg: Double): Double = kotlin.math.ln(arg)
|
||||
|
||||
override inline fun norm(arg: Double): Double = abs(arg)
|
||||
override fun norm(arg: Double): Double = abs(arg)
|
||||
|
||||
override inline fun Double.unaryMinus(): Double = -this
|
||||
override inline fun Double.plus(arg: Double): Double = this + arg
|
||||
override inline fun Double.minus(arg: Double): Double = this - arg
|
||||
override inline fun Double.times(arg: Double): Double = this * arg
|
||||
override inline fun Double.div(arg: Double): Double = this / arg
|
||||
override fun Double.unaryMinus(): Double = -this
|
||||
override fun Double.plus(arg: Double): Double = this + arg
|
||||
override fun Double.minus(arg: Double): Double = this - arg
|
||||
override fun Double.times(arg: Double): Double = this * arg
|
||||
override fun Double.div(arg: Double): Double = this / arg
|
||||
}
|
||||
|
||||
public val Double.Companion.algebra: DoubleField get() = DoubleField
|
||||
public typealias DoubleField = Float64Field
|
||||
|
||||
public val Double.Companion.algebra: Float64Field get() = Float64Field
|
||||
|
||||
/**
|
||||
* A field for [Float] without boxing. Does not produce appropriate field element.
|
||||
* A field for [Float] without boxing. Does not produce an appropriate field element.
|
||||
*/
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE")
|
||||
public object FloatField : ExtendedField<Float>, Norm<Float, Float> {
|
||||
override val bufferFactory: MutableBufferFactory<Float> = MutableBufferFactory(::FloatBuffer)
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
||||
public object Float32Field : ExtendedField<Float>, Norm<Float, Float> {
|
||||
override val bufferFactory: MutableBufferFactory<Float> = MutableBufferFactory(::Float32Buffer)
|
||||
|
||||
override inline val zero: Float get() = 0.0f
|
||||
override inline val one: Float get() = 1.0f
|
||||
override val zero: Float get() = 0.0f
|
||||
override val one: Float get() = 1.0f
|
||||
|
||||
override fun number(value: Number): Float = value.toFloat()
|
||||
|
||||
@ -141,132 +142,142 @@ public object FloatField : ExtendedField<Float>, Norm<Float, Float> {
|
||||
else -> super.binaryOperationFunction(operation)
|
||||
}
|
||||
|
||||
override inline fun add(left: Float, right: Float): Float = left + right
|
||||
override fun add(left: Float, right: Float): Float = left + right
|
||||
override fun scale(a: Float, value: Double): Float = a * value.toFloat()
|
||||
|
||||
override inline fun multiply(left: Float, right: Float): Float = left * right
|
||||
override fun multiply(left: Float, right: Float): Float = left * right
|
||||
|
||||
override inline fun divide(left: Float, right: Float): Float = left / right
|
||||
override fun divide(left: Float, right: Float): Float = left / right
|
||||
|
||||
override inline fun sin(arg: Float): Float = kotlin.math.sin(arg)
|
||||
override inline fun cos(arg: Float): Float = kotlin.math.cos(arg)
|
||||
override inline fun tan(arg: Float): Float = kotlin.math.tan(arg)
|
||||
override inline fun acos(arg: Float): Float = kotlin.math.acos(arg)
|
||||
override inline fun asin(arg: Float): Float = kotlin.math.asin(arg)
|
||||
override inline fun atan(arg: Float): Float = kotlin.math.atan(arg)
|
||||
override fun sin(arg: Float): Float = kotlin.math.sin(arg)
|
||||
override fun cos(arg: Float): Float = kotlin.math.cos(arg)
|
||||
override fun tan(arg: Float): Float = kotlin.math.tan(arg)
|
||||
override fun acos(arg: Float): Float = kotlin.math.acos(arg)
|
||||
override fun asin(arg: Float): Float = kotlin.math.asin(arg)
|
||||
override fun atan(arg: Float): Float = kotlin.math.atan(arg)
|
||||
|
||||
override inline fun sinh(arg: Float): Float = kotlin.math.sinh(arg)
|
||||
override inline fun cosh(arg: Float): Float = kotlin.math.cosh(arg)
|
||||
override inline fun tanh(arg: Float): Float = kotlin.math.tanh(arg)
|
||||
override inline fun asinh(arg: Float): Float = kotlin.math.asinh(arg)
|
||||
override inline fun acosh(arg: Float): Float = kotlin.math.acosh(arg)
|
||||
override inline fun atanh(arg: Float): Float = kotlin.math.atanh(arg)
|
||||
override fun sinh(arg: Float): Float = kotlin.math.sinh(arg)
|
||||
override fun cosh(arg: Float): Float = kotlin.math.cosh(arg)
|
||||
override fun tanh(arg: Float): Float = kotlin.math.tanh(arg)
|
||||
override fun asinh(arg: Float): Float = kotlin.math.asinh(arg)
|
||||
override fun acosh(arg: Float): Float = kotlin.math.acosh(arg)
|
||||
override fun atanh(arg: Float): Float = kotlin.math.atanh(arg)
|
||||
|
||||
override inline fun sqrt(arg: Float): Float = kotlin.math.sqrt(arg)
|
||||
override inline fun power(arg: Float, pow: Number): Float = arg.kpow(pow.toFloat())
|
||||
override fun sqrt(arg: Float): Float = kotlin.math.sqrt(arg)
|
||||
override fun power(arg: Float, pow: Number): Float = arg.kpow(pow.toFloat())
|
||||
|
||||
override inline fun exp(arg: Float): Float = kotlin.math.exp(arg)
|
||||
override inline fun ln(arg: Float): Float = kotlin.math.ln(arg)
|
||||
override fun exp(arg: Float): Float = kotlin.math.exp(arg)
|
||||
override fun ln(arg: Float): Float = kotlin.math.ln(arg)
|
||||
|
||||
override inline fun norm(arg: Float): Float = abs(arg)
|
||||
override fun norm(arg: Float): Float = abs(arg)
|
||||
|
||||
override inline fun Float.unaryMinus(): Float = -this
|
||||
override inline fun Float.plus(arg: Float): Float = this + arg
|
||||
override inline fun Float.minus(arg: Float): Float = this - arg
|
||||
override inline fun Float.times(arg: Float): Float = this * arg
|
||||
override inline fun Float.div(arg: Float): Float = this / arg
|
||||
override fun Float.unaryMinus(): Float = -this
|
||||
override fun Float.plus(arg: Float): Float = this + arg
|
||||
override fun Float.minus(arg: Float): Float = this - arg
|
||||
override fun Float.times(arg: Float): Float = this * arg
|
||||
override fun Float.div(arg: Float): Float = this / arg
|
||||
}
|
||||
|
||||
public val Float.Companion.algebra: FloatField get() = FloatField
|
||||
public typealias FloatField = Float32Field
|
||||
|
||||
public val Float.Companion.algebra: Float32Field get() = Float32Field
|
||||
|
||||
/**
|
||||
* A field for [Int] without boxing. Does not produce corresponding ring element.
|
||||
* A field for [Int] without boxing. Does not produce a corresponding ring element.
|
||||
*/
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE")
|
||||
public object IntRing : Ring<Int>, Norm<Int, Int>, NumericAlgebra<Int> {
|
||||
override val bufferFactory: MutableBufferFactory<Int> = MutableBufferFactory(::IntBuffer)
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
||||
public object Int32Ring : Ring<Int>, Norm<Int, Int>, NumericAlgebra<Int> {
|
||||
override val bufferFactory: MutableBufferFactory<Int> = MutableBufferFactory(::Int32Buffer)
|
||||
|
||||
override inline val zero: Int get() = 0
|
||||
override inline val one: Int get() = 1
|
||||
override val zero: Int get() = 0
|
||||
override val one: Int get() = 1
|
||||
|
||||
override fun number(value: Number): Int = value.toInt()
|
||||
override inline fun add(left: Int, right: Int): Int = left + right
|
||||
override inline fun multiply(left: Int, right: Int): Int = left * right
|
||||
override inline fun norm(arg: Int): Int = abs(arg)
|
||||
override 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 inline fun Int.unaryMinus(): Int = -this
|
||||
override inline fun Int.plus(arg: Int): Int = this + arg
|
||||
override inline fun Int.minus(arg: Int): Int = this - arg
|
||||
override inline fun Int.times(arg: Int): Int = this * arg
|
||||
override fun Int.unaryMinus(): Int = -this
|
||||
override fun Int.plus(arg: Int): Int = this + arg
|
||||
override fun Int.minus(arg: Int): Int = this - arg
|
||||
override fun Int.times(arg: Int): Int = this * arg
|
||||
}
|
||||
|
||||
public val Int.Companion.algebra: IntRing get() = IntRing
|
||||
public typealias IntRing = Int32Ring
|
||||
|
||||
public val Int.Companion.algebra: Int32Ring get() = Int32Ring
|
||||
|
||||
/**
|
||||
* A field for [Short] without boxing. Does not produce appropriate ring element.
|
||||
* A field for [Short] without boxing. Does not produce an appropriate ring element.
|
||||
*/
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE")
|
||||
public object ShortRing : Ring<Short>, Norm<Short, Short>, NumericAlgebra<Short> {
|
||||
override val bufferFactory: MutableBufferFactory<Short> = MutableBufferFactory(::ShortBuffer)
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
||||
public object Int16Ring : Ring<Short>, Norm<Short, Short>, NumericAlgebra<Short> {
|
||||
override val bufferFactory: MutableBufferFactory<Short> = MutableBufferFactory(::Int16Buffer)
|
||||
|
||||
override inline val zero: Short get() = 0
|
||||
override inline val one: Short get() = 1
|
||||
override val zero: Short get() = 0
|
||||
override val one: Short get() = 1
|
||||
|
||||
override fun number(value: Number): Short = value.toShort()
|
||||
override inline fun add(left: Short, right: Short): Short = (left + right).toShort()
|
||||
override inline fun multiply(left: Short, right: Short): Short = (left * right).toShort()
|
||||
override fun add(left: Short, right: Short): Short = (left + right).toShort()
|
||||
override fun multiply(left: Short, right: Short): Short = (left * right).toShort()
|
||||
override fun norm(arg: Short): Short = if (arg > 0) arg else (-arg).toShort()
|
||||
|
||||
override inline fun Short.unaryMinus(): Short = (-this).toShort()
|
||||
override inline fun Short.plus(arg: Short): Short = (this + arg).toShort()
|
||||
override inline fun Short.minus(arg: Short): Short = (this - arg).toShort()
|
||||
override inline fun Short.times(arg: Short): Short = (this * arg).toShort()
|
||||
override fun Short.unaryMinus(): Short = (-this).toShort()
|
||||
override fun Short.plus(arg: Short): Short = (this + arg).toShort()
|
||||
override fun Short.minus(arg: Short): Short = (this - arg).toShort()
|
||||
override 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.
|
||||
*/
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE")
|
||||
public object ByteRing : Ring<Byte>, Norm<Byte, Byte>, NumericAlgebra<Byte> {
|
||||
override val bufferFactory: MutableBufferFactory<Byte> = MutableBufferFactory(::ByteBuffer)
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
||||
public object Int8Ring : Ring<Byte>, Norm<Byte, Byte>, NumericAlgebra<Byte> {
|
||||
override val bufferFactory: MutableBufferFactory<Byte> = MutableBufferFactory(::Int8Buffer)
|
||||
|
||||
override inline val zero: Byte get() = 0
|
||||
override inline val one: Byte get() = 1
|
||||
override val zero: Byte get() = 0
|
||||
override val one: Byte get() = 1
|
||||
|
||||
override fun number(value: Number): Byte = value.toByte()
|
||||
override inline fun add(left: Byte, right: Byte): Byte = (left + right).toByte()
|
||||
override inline fun multiply(left: Byte, right: Byte): Byte = (left * right).toByte()
|
||||
override fun add(left: Byte, right: Byte): Byte = (left + right).toByte()
|
||||
override fun multiply(left: Byte, right: Byte): Byte = (left * right).toByte()
|
||||
override fun norm(arg: Byte): Byte = if (arg > 0) arg else (-arg).toByte()
|
||||
|
||||
override inline fun Byte.unaryMinus(): Byte = (-this).toByte()
|
||||
override inline fun Byte.plus(arg: Byte): Byte = (this + arg).toByte()
|
||||
override inline fun Byte.minus(arg: Byte): Byte = (this - arg).toByte()
|
||||
override inline fun Byte.times(arg: Byte): Byte = (this * arg).toByte()
|
||||
override fun Byte.unaryMinus(): Byte = (-this).toByte()
|
||||
override fun Byte.plus(arg: Byte): Byte = (this + arg).toByte()
|
||||
override fun Byte.minus(arg: Byte): Byte = (this - arg).toByte()
|
||||
override fun Byte.times(arg: Byte): Byte = (this * arg).toByte()
|
||||
}
|
||||
|
||||
public val Byte.Companion.algebra: ByteRing get() = ByteRing
|
||||
public typealias ByteRing = Int8Ring
|
||||
|
||||
public val Byte.Companion.algebra: Int8Ring get() = Int8Ring
|
||||
|
||||
/**
|
||||
* 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> {
|
||||
override val bufferFactory: MutableBufferFactory<Long> = MutableBufferFactory(::LongBuffer)
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
||||
public object Int64Ring : Ring<Long>, Norm<Long, Long>, NumericAlgebra<Long> {
|
||||
override val bufferFactory: MutableBufferFactory<Long> = MutableBufferFactory(::Int64Buffer)
|
||||
|
||||
override inline val zero: Long get() = 0L
|
||||
override inline val one: Long get() = 1L
|
||||
override val zero: Long get() = 0L
|
||||
override val one: Long get() = 1L
|
||||
|
||||
override fun number(value: Number): Long = value.toLong()
|
||||
override inline fun add(left: Long, right: Long): Long = left + right
|
||||
override inline fun multiply(left: Long, right: Long): Long = left * right
|
||||
override fun add(left: Long, right: Long): Long = left + right
|
||||
override fun multiply(left: Long, right: Long): Long = left * right
|
||||
override fun norm(arg: Long): Long = abs(arg)
|
||||
|
||||
override inline fun Long.unaryMinus(): Long = (-this)
|
||||
override inline fun Long.plus(arg: Long): Long = (this + arg)
|
||||
override inline fun Long.minus(arg: Long): Long = (this - arg)
|
||||
override inline fun Long.times(arg: Long): Long = (this * arg)
|
||||
override fun Long.unaryMinus(): Long = (-this)
|
||||
override fun Long.plus(arg: Long): Long = (this + arg)
|
||||
override fun Long.minus(arg: Long): Long = (this - arg)
|
||||
override 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
|
||||
|
@ -93,8 +93,8 @@ public interface Buffer<out T> : WithSize {
|
||||
List(size, initializer).asBuffer()
|
||||
|
||||
/**
|
||||
* Creates a [Buffer] of given [type]. If the type is primitive, specialized buffers are used ([IntBuffer],
|
||||
* [DoubleBuffer], etc.), [ListBuffer] is returned otherwise.
|
||||
* Creates a [Buffer] of given [type]. If the type is primitive, specialized buffers are used ([Int32Buffer],
|
||||
* [Float64Buffer], etc.), [ListBuffer] is returned otherwise.
|
||||
*
|
||||
* The [size] is specified, and each element is calculated by calling the specified [initializer] function.
|
||||
*/
|
||||
@ -110,8 +110,8 @@ public interface Buffer<out T> : WithSize {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a [Buffer] of given type [T]. If the type is primitive, specialized buffers are used ([IntBuffer],
|
||||
* [DoubleBuffer], etc.), [ListBuffer] is returned otherwise.
|
||||
* Creates a [Buffer] of given type [T]. If the type is primitive, specialized buffers are used ([Int32Buffer],
|
||||
* [Float64Buffer], etc.), [ListBuffer] is returned otherwise.
|
||||
*
|
||||
* The [size] is specified, and each element is calculated by calling the specified [initializer] function.
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -14,7 +14,7 @@ import kotlin.jvm.JvmInline
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
@JvmInline
|
||||
public value class FloatBuffer(public val array: FloatArray) : PrimitiveBuffer<Float> {
|
||||
public value class Float32Buffer(public val array: FloatArray) : PrimitiveBuffer<Float> {
|
||||
override val size: Int get() = array.size
|
||||
|
||||
override operator fun get(index: Int): Float = array[index]
|
||||
@ -26,35 +26,37 @@ public value class FloatBuffer(public val array: FloatArray) : PrimitiveBuffer<F
|
||||
override operator fun iterator(): FloatIterator = array.iterator()
|
||||
|
||||
override fun copy(): MutableBuffer<Float> =
|
||||
FloatBuffer(array.copyOf())
|
||||
Float32Buffer(array.copyOf())
|
||||
}
|
||||
|
||||
public typealias FloatBuffer = Float32Buffer
|
||||
|
||||
/**
|
||||
* Creates a new [FloatBuffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* Creates a new [Float32Buffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* [init] function.
|
||||
*
|
||||
* The function [init] is called for each array element sequentially starting from the first one.
|
||||
* It should return the value for a buffer element given its index.
|
||||
*/
|
||||
public inline fun FloatBuffer(size: Int, init: (Int) -> Float): FloatBuffer = FloatBuffer(FloatArray(size) { init(it) })
|
||||
public inline fun Float32Buffer(size: Int, init: (Int) -> Float): Float32Buffer = Float32Buffer(FloatArray(size) { init(it) })
|
||||
|
||||
/**
|
||||
* Returns a new [FloatBuffer] of given elements.
|
||||
* Returns a new [Float32Buffer] of given elements.
|
||||
*/
|
||||
public fun FloatBuffer(vararg floats: Float): FloatBuffer = FloatBuffer(floats)
|
||||
public fun Float32Buffer(vararg floats: Float): Float32Buffer = Float32Buffer(floats)
|
||||
|
||||
/**
|
||||
* Returns a new [FloatArray] containing all the elements of this [Buffer].
|
||||
*/
|
||||
public fun Buffer<Float>.toFloatArray(): FloatArray = when (this) {
|
||||
is FloatBuffer -> array.copyOf()
|
||||
is Float32Buffer -> array.copyOf()
|
||||
else -> FloatArray(size, ::get)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns [FloatBuffer] over this array.
|
||||
* Returns [Float32Buffer] over this array.
|
||||
*
|
||||
* @receiver the array.
|
||||
* @return the new buffer.
|
||||
*/
|
||||
public fun FloatArray.asBuffer(): FloatBuffer = FloatBuffer(this)
|
||||
public fun FloatArray.asBuffer(): Float32Buffer = Float32Buffer(this)
|
@ -14,7 +14,7 @@ import kotlin.jvm.JvmInline
|
||||
* @property array the underlying array.
|
||||
*/
|
||||
@JvmInline
|
||||
public value class DoubleBuffer(public val array: DoubleArray) : PrimitiveBuffer<Double> {
|
||||
public value class Float64Buffer(public val array: DoubleArray) : PrimitiveBuffer<Double> {
|
||||
override val size: Int get() = array.size
|
||||
|
||||
override operator fun get(index: Int): Double = array[index]
|
||||
@ -25,57 +25,59 @@ public value class DoubleBuffer(public val array: DoubleArray) : PrimitiveBuffer
|
||||
|
||||
override operator fun iterator(): DoubleIterator = array.iterator()
|
||||
|
||||
override fun copy(): DoubleBuffer = DoubleBuffer(array.copyOf())
|
||||
override fun copy(): Float64Buffer = Float64Buffer(array.copyOf())
|
||||
|
||||
override fun toString(): String = Buffer.toString(this)
|
||||
|
||||
public companion object {
|
||||
public fun zero(size: Int): DoubleBuffer = DoubleArray(size).asBuffer()
|
||||
public fun zero(size: Int): Float64Buffer = DoubleArray(size).asBuffer()
|
||||
}
|
||||
}
|
||||
|
||||
public typealias DoubleBuffer = Float64Buffer
|
||||
|
||||
/**
|
||||
* Creates a new [DoubleBuffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* Creates a new [Float64Buffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* [init] function.
|
||||
*
|
||||
* The function [init] is called for each array element sequentially starting from the first one.
|
||||
* It should return the value for a buffer element given its index.
|
||||
*/
|
||||
public inline fun DoubleBuffer(size: Int, init: (Int) -> Double): DoubleBuffer =
|
||||
DoubleBuffer(DoubleArray(size) { init(it) })
|
||||
public inline fun Float64Buffer(size: Int, init: (Int) -> Double): Float64Buffer =
|
||||
Float64Buffer(DoubleArray(size) { init(it) })
|
||||
|
||||
/**
|
||||
* Returns a new [DoubleBuffer] of given elements.
|
||||
* Returns a new [Float64Buffer] of given elements.
|
||||
*/
|
||||
public fun DoubleBuffer(vararg doubles: Double): DoubleBuffer = DoubleBuffer(doubles)
|
||||
public fun Float64Buffer(vararg doubles: Double): Float64Buffer = Float64Buffer(doubles)
|
||||
|
||||
/**
|
||||
* Returns a new [DoubleArray] containing all the elements of this [Buffer].
|
||||
*/
|
||||
public fun Buffer<Double>.toDoubleArray(): DoubleArray = when (this) {
|
||||
is DoubleBuffer -> array
|
||||
is Float64Buffer -> array
|
||||
else -> DoubleArray(size, ::get)
|
||||
}
|
||||
|
||||
/**
|
||||
* Represent this buffer as [DoubleBuffer]. Does not guarantee that changes in the original buffer are reflected on this buffer.
|
||||
* Represent this buffer as [Float64Buffer]. Does not guarantee that changes in the original buffer are reflected on this buffer.
|
||||
*/
|
||||
public fun Buffer<Double>.toDoubleBuffer(): DoubleBuffer = when (this) {
|
||||
is DoubleBuffer -> this
|
||||
public fun Buffer<Double>.toFloat64Buffer(): Float64Buffer = when (this) {
|
||||
is Float64Buffer -> this
|
||||
else -> DoubleArray(size, ::get).asBuffer()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns [DoubleBuffer] over this array.
|
||||
* Returns [Float64Buffer] over this array.
|
||||
*
|
||||
* @receiver the array.
|
||||
* @return the new buffer.
|
||||
*/
|
||||
public fun DoubleArray.asBuffer(): DoubleBuffer = DoubleBuffer(this)
|
||||
public fun DoubleArray.asBuffer(): Float64Buffer = Float64Buffer(this)
|
||||
|
||||
|
||||
public fun interface DoubleBufferTransform : BufferTransform<Double, Double> {
|
||||
public fun transform(arg: DoubleBuffer): DoubleBuffer
|
||||
public fun interface Float64BufferTransform : BufferTransform<Double, Double> {
|
||||
public fun transform(arg: Float64Buffer): Float64Buffer
|
||||
|
||||
override fun transform(arg: Buffer<Double>): DoubleBuffer = arg.toDoubleBuffer()
|
||||
override fun transform(arg: Buffer<Double>): Float64Buffer = arg.toFloat64Buffer()
|
||||
}
|
@ -13,7 +13,7 @@ import kotlin.jvm.JvmInline
|
||||
* @property array the underlying array.
|
||||
*/
|
||||
@JvmInline
|
||||
public value class ShortBuffer(public val array: ShortArray) : MutableBuffer<Short> {
|
||||
public value class Int16Buffer(public val array: ShortArray) : MutableBuffer<Short> {
|
||||
override val size: Int get() = array.size
|
||||
|
||||
override operator fun get(index: Int): Short = array[index]
|
||||
@ -23,35 +23,37 @@ public value class ShortBuffer(public val array: ShortArray) : MutableBuffer<Sho
|
||||
}
|
||||
|
||||
override operator fun iterator(): ShortIterator = array.iterator()
|
||||
override fun copy(): MutableBuffer<Short> = ShortBuffer(array.copyOf())
|
||||
override fun copy(): MutableBuffer<Short> = Int16Buffer(array.copyOf())
|
||||
}
|
||||
|
||||
public typealias ShortBuffer = Int16Buffer
|
||||
|
||||
/**
|
||||
* Creates a new [ShortBuffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* Creates a new [Int16Buffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* [init] function.
|
||||
*
|
||||
* The function [init] is called for each array element sequentially starting from the first one.
|
||||
* It should return the value for a buffer element given its index.
|
||||
*/
|
||||
public inline fun ShortBuffer(size: Int, init: (Int) -> Short): ShortBuffer = ShortBuffer(ShortArray(size) { init(it) })
|
||||
public inline fun Int16Buffer(size: Int, init: (Int) -> Short): Int16Buffer = Int16Buffer(ShortArray(size) { init(it) })
|
||||
|
||||
/**
|
||||
* Returns a new [ShortBuffer] of given elements.
|
||||
* Returns a new [Int16Buffer] of given elements.
|
||||
*/
|
||||
public fun ShortBuffer(vararg shorts: Short): ShortBuffer = ShortBuffer(shorts)
|
||||
public fun Int16Buffer(vararg shorts: Short): Int16Buffer = Int16Buffer(shorts)
|
||||
|
||||
/**
|
||||
* Returns a new [ShortArray] containing all the elements of this [Buffer].
|
||||
*/
|
||||
public fun Buffer<Short>.toShortArray(): ShortArray = when (this) {
|
||||
is ShortBuffer -> array.copyOf()
|
||||
is Int16Buffer -> array.copyOf()
|
||||
else -> ShortArray(size, ::get)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns [ShortBuffer] over this array.
|
||||
* Returns [Int16Buffer] over this array.
|
||||
*
|
||||
* @receiver the array.
|
||||
* @return the new buffer.
|
||||
*/
|
||||
public fun ShortArray.asBuffer(): ShortBuffer = ShortBuffer(this)
|
||||
public fun ShortArray.asBuffer(): Int16Buffer = Int16Buffer(this)
|
@ -13,7 +13,7 @@ import kotlin.jvm.JvmInline
|
||||
* @property array the underlying array.
|
||||
*/
|
||||
@JvmInline
|
||||
public value class IntBuffer(public val array: IntArray) : PrimitiveBuffer<Int> {
|
||||
public value class Int32Buffer(public val array: IntArray) : PrimitiveBuffer<Int> {
|
||||
override val size: Int get() = array.size
|
||||
|
||||
override operator fun get(index: Int): Int = array[index]
|
||||
@ -24,35 +24,37 @@ public value class IntBuffer(public val array: IntArray) : PrimitiveBuffer<Int>
|
||||
|
||||
override operator fun iterator(): IntIterator = array.iterator()
|
||||
|
||||
override fun copy(): IntBuffer = IntBuffer(array.copyOf())
|
||||
override fun copy(): Int32Buffer = Int32Buffer(array.copyOf())
|
||||
}
|
||||
|
||||
public typealias IntBuffer = Int32Buffer
|
||||
|
||||
/**
|
||||
* Creates a new [IntBuffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* Creates a new [Int32Buffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* [init] function.
|
||||
*
|
||||
* The function [init] is called for each array element sequentially starting from the first one.
|
||||
* It should return the value for a buffer element given its index.
|
||||
*/
|
||||
public inline fun IntBuffer(size: Int, init: (Int) -> Int): IntBuffer = IntBuffer(IntArray(size) { init(it) })
|
||||
public inline fun Int32Buffer(size: Int, init: (Int) -> Int): Int32Buffer = Int32Buffer(IntArray(size) { init(it) })
|
||||
|
||||
/**
|
||||
* Returns a new [IntBuffer] of given elements.
|
||||
* Returns a new [Int32Buffer] of given elements.
|
||||
*/
|
||||
public fun IntBuffer(vararg ints: Int): IntBuffer = IntBuffer(ints)
|
||||
public fun Int32Buffer(vararg ints: Int): Int32Buffer = Int32Buffer(ints)
|
||||
|
||||
/**
|
||||
* Returns a new [IntArray] containing all the elements of this [Buffer].
|
||||
*/
|
||||
public fun Buffer<Int>.toIntArray(): IntArray = when (this) {
|
||||
is IntBuffer -> array.copyOf()
|
||||
is Int32Buffer -> array.copyOf()
|
||||
else -> IntArray(size, ::get)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns [IntBuffer] over this array.
|
||||
* Returns [Int32Buffer] over this array.
|
||||
*
|
||||
* @receiver the array.
|
||||
* @return the new buffer.
|
||||
*/
|
||||
public fun IntArray.asBuffer(): IntBuffer = IntBuffer(this)
|
||||
public fun IntArray.asBuffer(): Int32Buffer = Int32Buffer(this)
|
@ -13,7 +13,7 @@ import kotlin.jvm.JvmInline
|
||||
* @property array the underlying array.
|
||||
*/
|
||||
@JvmInline
|
||||
public value class LongBuffer(public val array: LongArray) : PrimitiveBuffer<Long> {
|
||||
public value class Int64Buffer(public val array: LongArray) : PrimitiveBuffer<Long> {
|
||||
override val size: Int get() = array.size
|
||||
|
||||
override operator fun get(index: Int): Long = array[index]
|
||||
@ -25,35 +25,37 @@ public value class LongBuffer(public val array: LongArray) : PrimitiveBuffer<Lon
|
||||
override operator fun iterator(): LongIterator = array.iterator()
|
||||
|
||||
override fun copy(): MutableBuffer<Long> =
|
||||
LongBuffer(array.copyOf())
|
||||
Int64Buffer(array.copyOf())
|
||||
}
|
||||
|
||||
public typealias LongBuffer = Int64Buffer
|
||||
|
||||
/**
|
||||
* Creates a new [LongBuffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* Creates a new [Int64Buffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* [init] function.
|
||||
*
|
||||
* The function [init] is called for each array element sequentially starting from the first one.
|
||||
* It should return the value for a buffer element given its index.
|
||||
*/
|
||||
public inline fun LongBuffer(size: Int, init: (Int) -> Long): LongBuffer = LongBuffer(LongArray(size) { init(it) })
|
||||
public inline fun Int64Buffer(size: Int, init: (Int) -> Long): Int64Buffer = Int64Buffer(LongArray(size) { init(it) })
|
||||
|
||||
/**
|
||||
* Returns a new [LongBuffer] of given elements.
|
||||
* Returns a new [Int64Buffer] of given elements.
|
||||
*/
|
||||
public fun LongBuffer(vararg longs: Long): LongBuffer = LongBuffer(longs)
|
||||
public fun Int64Buffer(vararg longs: Long): Int64Buffer = Int64Buffer(longs)
|
||||
|
||||
/**
|
||||
* Returns a new [LongArray] containing all the elements of this [Buffer].
|
||||
*/
|
||||
public fun Buffer<Long>.toLongArray(): LongArray = when (this) {
|
||||
is LongBuffer -> array.copyOf()
|
||||
is Int64Buffer -> array.copyOf()
|
||||
else -> LongArray(size, ::get)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns [LongBuffer] over this array.
|
||||
* Returns [Int64Buffer] over this array.
|
||||
*
|
||||
* @receiver the array.
|
||||
* @return the new buffer.
|
||||
*/
|
||||
public fun LongArray.asBuffer(): LongBuffer = LongBuffer(this)
|
||||
public fun LongArray.asBuffer(): Int64Buffer = Int64Buffer(this)
|
@ -13,7 +13,7 @@ import kotlin.jvm.JvmInline
|
||||
* @property array the underlying array.
|
||||
*/
|
||||
@JvmInline
|
||||
public value class ByteBuffer(public val array: ByteArray) : MutableBuffer<Byte> {
|
||||
public value class Int8Buffer(public val array: ByteArray) : MutableBuffer<Byte> {
|
||||
override val size: Int get() = array.size
|
||||
|
||||
override operator fun get(index: Int): Byte = array[index]
|
||||
@ -23,35 +23,35 @@ public value class ByteBuffer(public val array: ByteArray) : MutableBuffer<Byte>
|
||||
}
|
||||
|
||||
override operator fun iterator(): ByteIterator = array.iterator()
|
||||
override fun copy(): MutableBuffer<Byte> = ByteBuffer(array.copyOf())
|
||||
override fun copy(): MutableBuffer<Byte> = Int8Buffer(array.copyOf())
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new [ByteBuffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* Creates a new [Int8Buffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* [init] function.
|
||||
*
|
||||
* The function [init] is called for each array element sequentially starting from the first one.
|
||||
* It should return the value for a buffer element given its index.
|
||||
*/
|
||||
public inline fun ByteBuffer(size: Int, init: (Int) -> Byte): ByteBuffer = ByteBuffer(ByteArray(size) { init(it) })
|
||||
public inline fun Int8Buffer(size: Int, init: (Int) -> Byte): Int8Buffer = Int8Buffer(ByteArray(size) { init(it) })
|
||||
|
||||
/**
|
||||
* Returns a new [ByteBuffer] of given elements.
|
||||
* Returns a new [Int8Buffer] of given elements.
|
||||
*/
|
||||
public fun ByteBuffer(vararg bytes: Byte): ByteBuffer = ByteBuffer(bytes)
|
||||
public fun Int8Buffer(vararg bytes: Byte): Int8Buffer = Int8Buffer(bytes)
|
||||
|
||||
/**
|
||||
* Returns a new [ByteArray] containing all the elements of this [Buffer].
|
||||
*/
|
||||
public fun Buffer<Byte>.toByteArray(): ByteArray = when (this) {
|
||||
is ByteBuffer -> array.copyOf()
|
||||
is Int8Buffer -> array.copyOf()
|
||||
else -> ByteArray(size, ::get)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns [ByteBuffer] over this array.
|
||||
* Returns [Int8Buffer] over this array.
|
||||
*
|
||||
* @receiver the array.
|
||||
* @return the new buffer.
|
||||
*/
|
||||
public fun ByteArray.asBuffer(): ByteBuffer = ByteBuffer(this)
|
||||
public fun ByteArray.asBuffer(): Int8Buffer = Int8Buffer(this)
|
@ -25,40 +25,40 @@ public interface MutableBuffer<T> : Buffer<T> {
|
||||
|
||||
public companion object {
|
||||
/**
|
||||
* Creates a [DoubleBuffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* Creates a [Float64Buffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* [initializer] function.
|
||||
*/
|
||||
public inline fun double(size: Int, initializer: (Int) -> Double): DoubleBuffer =
|
||||
DoubleBuffer(size, initializer)
|
||||
public inline fun double(size: Int, initializer: (Int) -> Double): Float64Buffer =
|
||||
Float64Buffer(size, initializer)
|
||||
|
||||
/**
|
||||
* Creates a [ShortBuffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* Creates a [Int16Buffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* [initializer] function.
|
||||
*/
|
||||
public inline fun short(size: Int, initializer: (Int) -> Short): ShortBuffer =
|
||||
ShortBuffer(size, initializer)
|
||||
public inline fun short(size: Int, initializer: (Int) -> Short): Int16Buffer =
|
||||
Int16Buffer(size, initializer)
|
||||
|
||||
/**
|
||||
* Creates a [IntBuffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* Creates a [Int32Buffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* [initializer] function.
|
||||
*/
|
||||
public inline fun int(size: Int, initializer: (Int) -> Int): IntBuffer =
|
||||
IntBuffer(size, initializer)
|
||||
public inline fun int(size: Int, initializer: (Int) -> Int): Int32Buffer =
|
||||
Int32Buffer(size, initializer)
|
||||
|
||||
/**
|
||||
* Creates a [LongBuffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* Creates a [Int64Buffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* [initializer] function.
|
||||
*/
|
||||
public inline fun long(size: Int, initializer: (Int) -> Long): LongBuffer =
|
||||
LongBuffer(size, initializer)
|
||||
public inline fun long(size: Int, initializer: (Int) -> Long): Int64Buffer =
|
||||
Int64Buffer(size, initializer)
|
||||
|
||||
|
||||
/**
|
||||
* Creates a [FloatBuffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* Creates a [Float32Buffer] with the specified [size], where each element is calculated by calling the specified
|
||||
* [initializer] function.
|
||||
*/
|
||||
public inline fun float(size: Int, initializer: (Int) -> Float): FloatBuffer =
|
||||
FloatBuffer(size, initializer)
|
||||
public inline fun float(size: Int, initializer: (Int) -> Float): Float32Buffer =
|
||||
Float32Buffer(size, initializer)
|
||||
|
||||
|
||||
/**
|
||||
@ -69,7 +69,7 @@ public interface MutableBuffer<T> : Buffer<T> {
|
||||
|
||||
/**
|
||||
* Creates a [MutableBuffer] of given [type]. If the type is primitive, specialized buffers are used
|
||||
* ([IntBuffer], [DoubleBuffer], etc.), [ListBuffer] is returned otherwise.
|
||||
* ([Int32Buffer], [Float64Buffer], etc.), [ListBuffer] is returned otherwise.
|
||||
*
|
||||
* The [size] is specified, and each element is calculated by calling the specified [initializer] function.
|
||||
*/
|
||||
@ -86,7 +86,7 @@ public interface MutableBuffer<T> : Buffer<T> {
|
||||
|
||||
/**
|
||||
* Creates a [MutableBuffer] of given type [T]. If the type is primitive, specialized buffers are used
|
||||
* ([IntBuffer], [DoubleBuffer], etc.), [ListBuffer] is returned otherwise.
|
||||
* ([Int32Buffer], [Float64Buffer], etc.), [ListBuffer] is returned otherwise.
|
||||
*
|
||||
* The [size] is specified, and each element is calculated by calling the specified [initializer] function.
|
||||
*/
|
||||
|
@ -13,7 +13,7 @@ public fun Buffer<Double>.getDouble(index: Int): Double = if (this is BufferView
|
||||
} else {
|
||||
get(index)
|
||||
}
|
||||
} else if (this is DoubleBuffer) {
|
||||
} else if (this is Float64Buffer) {
|
||||
array[index]
|
||||
} else {
|
||||
get(index)
|
||||
@ -30,7 +30,7 @@ public fun Buffer<Int>.getInt(index: Int): Int = if (this is BufferView) {
|
||||
} else {
|
||||
get(index)
|
||||
}
|
||||
} else if (this is IntBuffer) {
|
||||
} else if (this is Int32Buffer) {
|
||||
array[index]
|
||||
} else {
|
||||
get(index)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -7,7 +7,7 @@ package space.kscience.kmath.misc
|
||||
|
||||
import space.kscience.kmath.UnstableKMathAPI
|
||||
import space.kscience.kmath.misc.PermSortTest.Platform.*
|
||||
import space.kscience.kmath.structures.IntBuffer
|
||||
import space.kscience.kmath.structures.Int32Buffer
|
||||
import space.kscience.kmath.structures.asBuffer
|
||||
import kotlin.random.Random
|
||||
import kotlin.test.Test
|
||||
@ -29,7 +29,7 @@ class PermSortTest {
|
||||
*/
|
||||
@Test
|
||||
fun testOnEmptyBuffer() {
|
||||
val emptyBuffer = IntBuffer(0) {it}
|
||||
val emptyBuffer = Int32Buffer(0) {it}
|
||||
var permutations = emptyBuffer.indicesSorted()
|
||||
assertTrue(permutations.isEmpty(), "permutation on an empty buffer should return an empty result")
|
||||
permutations = emptyBuffer.indicesSortedDescending()
|
||||
@ -100,5 +100,5 @@ class PermSortTest {
|
||||
}
|
||||
}
|
||||
|
||||
private fun Random.buffer(size : Int) = IntBuffer(size) { nextInt() }
|
||||
private fun Random.buffer(size : Int) = Int32Buffer(size) { nextInt() }
|
||||
}
|
||||
|
@ -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() }
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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) } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
package space.kscience.kmath.chains
|
||||
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
import space.kscience.kmath.structures.Float64Buffer
|
||||
|
||||
/**
|
||||
* Chunked, specialized chain for double values, which supports blocking [nextBlocking] operation
|
||||
@ -15,7 +15,7 @@ public interface BlockingDoubleChain : BlockingBufferChain<Double> {
|
||||
/**
|
||||
* Returns an [DoubleArray] chunk of [size] values of [next].
|
||||
*/
|
||||
override fun nextBufferBlocking(size: Int): DoubleBuffer
|
||||
override fun nextBufferBlocking(size: Int): Float64Buffer
|
||||
|
||||
override suspend fun fork(): BlockingDoubleChain
|
||||
|
||||
@ -23,9 +23,9 @@ public interface BlockingDoubleChain : BlockingBufferChain<Double> {
|
||||
}
|
||||
|
||||
public fun BlockingDoubleChain.map(transform: (Double) -> Double): BlockingDoubleChain = object : BlockingDoubleChain {
|
||||
override fun nextBufferBlocking(size: Int): DoubleBuffer {
|
||||
override fun nextBufferBlocking(size: Int): Float64Buffer {
|
||||
val block = this@map.nextBufferBlocking(size)
|
||||
return DoubleBuffer(size) { transform(block[it]) }
|
||||
return Float64Buffer(size) { transform(block[it]) }
|
||||
}
|
||||
|
||||
override suspend fun fork(): BlockingDoubleChain = this@map.fork().map(transform)
|
||||
|
@ -5,13 +5,13 @@
|
||||
|
||||
package space.kscience.kmath.chains
|
||||
|
||||
import space.kscience.kmath.structures.IntBuffer
|
||||
import space.kscience.kmath.structures.Int32Buffer
|
||||
|
||||
/**
|
||||
* Performance optimized chain for integer values
|
||||
*/
|
||||
public interface BlockingIntChain : BlockingBufferChain<Int> {
|
||||
override fun nextBufferBlocking(size: Int): IntBuffer
|
||||
override fun nextBufferBlocking(size: Int): Int32Buffer
|
||||
|
||||
override suspend fun fork(): BlockingIntChain
|
||||
}
|
@ -16,7 +16,7 @@ import kotlinx.coroutines.flow.flow
|
||||
import space.kscience.kmath.chains.BlockingDoubleChain
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.BufferFactory
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
import space.kscience.kmath.structures.Float64Buffer
|
||||
|
||||
/**
|
||||
* Create a [Flow] from buffer
|
||||
@ -55,7 +55,7 @@ public fun <T> Flow<T>.chunked(bufferSize: Int, bufferFactory: BufferFactory<T>)
|
||||
/**
|
||||
* Specialized flow chunker for real buffer
|
||||
*/
|
||||
public fun Flow<Double>.chunked(bufferSize: Int): Flow<DoubleBuffer> = flow {
|
||||
public fun Flow<Double>.chunked(bufferSize: Int): Flow<Float64Buffer> = flow {
|
||||
require(bufferSize > 0) { "Resulting chunk size must be more than zero" }
|
||||
|
||||
if (this@chunked is BlockingDoubleChain) {
|
||||
@ -70,13 +70,13 @@ public fun Flow<Double>.chunked(bufferSize: Int): Flow<DoubleBuffer> = flow {
|
||||
counter++
|
||||
|
||||
if (counter == bufferSize) {
|
||||
val buffer = DoubleBuffer(array)
|
||||
val buffer = Float64Buffer(array)
|
||||
emit(buffer)
|
||||
counter = 0
|
||||
}
|
||||
}
|
||||
|
||||
if (counter > 0) emit(DoubleBuffer(counter) { array[it] })
|
||||
if (counter > 0) emit(Float64Buffer(counter) { array[it] })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -19,13 +19,19 @@ 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.structures.Float64
|
||||
import space.kscience.kmath.structures.Float32
|
||||
import space.kscience.kmath.operations.Float64Field
|
||||
import space.kscience.kmath.operations.Float32Field
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import space.kscience.kmath.operations.FloatField
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.structures.Float64Buffer
|
||||
import space.kscience.kmath.structures.Float32Buffer
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
import space.kscience.kmath.structures.FloatBuffer
|
||||
import kotlin.reflect.KClass
|
||||
@ -71,11 +77,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 +100,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 +109,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 +313,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 +336,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 +345,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 +549,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 +572,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 +581,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 +780,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 +803,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 +812,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) }
|
||||
})
|
||||
|
@ -7,7 +7,7 @@ package space.kscience.kmath.real
|
||||
|
||||
import space.kscience.kmath.UnstableKMathAPI
|
||||
import space.kscience.kmath.linear.Point
|
||||
import space.kscience.kmath.operations.DoubleL2Norm
|
||||
import space.kscience.kmath.operations.Float64L2Norm
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.MutableBuffer.Companion.double
|
||||
import space.kscience.kmath.structures.asBuffer
|
||||
@ -16,7 +16,6 @@ import kotlin.math.pow
|
||||
|
||||
public typealias DoubleVector = Point<Double>
|
||||
|
||||
@Suppress("FunctionName")
|
||||
public fun DoubleVector(vararg doubles: Double): DoubleVector = doubles.asBuffer()
|
||||
|
||||
/**
|
||||
@ -103,4 +102,4 @@ public fun DoubleVector.sum(): Double {
|
||||
return res
|
||||
}
|
||||
|
||||
public val DoubleVector.norm: Double get() = DoubleL2Norm.norm(this)
|
||||
public val DoubleVector.norm: Double get() = Float64L2Norm.norm(this)
|
@ -11,11 +11,11 @@ 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
|
||||
import space.kscience.kmath.structures.DoubleBuffer
|
||||
import space.kscience.kmath.structures.Float64Buffer
|
||||
import kotlin.math.pow
|
||||
|
||||
/*
|
||||
@ -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 {
|
||||
@ -130,19 +130,19 @@ public fun RealMatrix.extractColumns(columnRange: IntRange): RealMatrix =
|
||||
public fun RealMatrix.extractColumn(columnIndex: Int): RealMatrix =
|
||||
extractColumns(columnIndex..columnIndex)
|
||||
|
||||
public fun RealMatrix.sumByColumn(): DoubleBuffer = DoubleBuffer(colNum) { j ->
|
||||
public fun RealMatrix.sumByColumn(): Float64Buffer = Float64Buffer(colNum) { j ->
|
||||
columns[j].sum()
|
||||
}
|
||||
|
||||
public fun RealMatrix.minByColumn(): DoubleBuffer = DoubleBuffer(colNum) { j ->
|
||||
public fun RealMatrix.minByColumn(): Float64Buffer = Float64Buffer(colNum) { j ->
|
||||
columns[j].asIterable().minOrNull() ?: error("Cannot produce min on empty column")
|
||||
}
|
||||
|
||||
public fun RealMatrix.maxByColumn(): DoubleBuffer = DoubleBuffer(colNum) { j ->
|
||||
public fun RealMatrix.maxByColumn(): Float64Buffer = Float64Buffer(colNum) { j ->
|
||||
columns[j].asIterable().maxOrNull() ?: error("Cannot produce min on empty column")
|
||||
}
|
||||
|
||||
public fun RealMatrix.averageByColumn(): DoubleBuffer = DoubleBuffer(colNum) { j ->
|
||||
public fun RealMatrix.averageByColumn(): Float64Buffer = Float64Buffer(colNum) { j ->
|
||||
columns[j].asIterable().average()
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user