Eigenvalue decomposition API
Cosmetic change Double -> Float64
This commit is contained in:
parent
91513a1629
commit
b818a8981f
@ -201,7 +201,7 @@
|
|||||||
- Full autodiff refactoring based on `Symbol`
|
- Full autodiff refactoring based on `Symbol`
|
||||||
- `kmath-prob` renamed to `kmath-stat`
|
- `kmath-prob` renamed to `kmath-stat`
|
||||||
- Grid generators moved to `kmath-for-real`
|
- Grid generators moved to `kmath-for-real`
|
||||||
- Use `Point<Double>` instead of specialized type in `kmath-for-real`
|
- Use `Point<Float64>` instead of specialized type in `kmath-for-real`
|
||||||
- Optimized dot product for buffer matrices moved to `kmath-for-real`
|
- Optimized dot product for buffer matrices moved to `kmath-for-real`
|
||||||
- EjmlMatrix context is an object
|
- EjmlMatrix context is an object
|
||||||
- Matrix LUP `inverse` renamed to `inverseWithLup`
|
- Matrix LUP `inverse` renamed to `inverseWithLup`
|
||||||
|
@ -14,6 +14,7 @@ import space.kscience.kmath.expressions.*
|
|||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
import space.kscience.kmath.operations.bindSymbol
|
import space.kscience.kmath.operations.bindSymbol
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
import space.kscience.kmath.estree.compileToExpression as estreeCompileToExpression
|
import space.kscience.kmath.estree.compileToExpression as estreeCompileToExpression
|
||||||
@ -67,7 +68,7 @@ class ExpressionsInterpretersBenchmark {
|
|||||||
blackhole.consume(sum)
|
blackhole.consume(sum)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun invokeAndSum(expr: Expression<Double>, blackhole: Blackhole) {
|
private fun invokeAndSum(expr: Expression<Float64>, blackhole: Blackhole) {
|
||||||
val random = Random(0)
|
val random = Random(0)
|
||||||
var sum = 0.0
|
var sum = 0.0
|
||||||
val m = HashMap<Symbol, Double>()
|
val m = HashMap<Symbol, Double>()
|
||||||
@ -99,7 +100,7 @@ class ExpressionsInterpretersBenchmark {
|
|||||||
private val wasm = node.wasmCompileToExpression(Float64Field)
|
private val wasm = node.wasmCompileToExpression(Float64Field)
|
||||||
private val estree = node.estreeCompileToExpression(Float64Field)
|
private val estree = node.estreeCompileToExpression(Float64Field)
|
||||||
|
|
||||||
private val raw = Expression<Double> { args ->
|
private val raw = Expression<Float64> { args ->
|
||||||
val x = args.getValue(x)
|
val x = args.getValue(x)
|
||||||
x * 2.0 + 2.0 / x - 16.0 / sin(x)
|
x * 2.0 + 2.0 / x - 16.0 / sin(x)
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ import space.kscience.kmath.operations.Algebra
|
|||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
import space.kscience.kmath.operations.bindSymbol
|
import space.kscience.kmath.operations.bindSymbol
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
@ -83,7 +84,7 @@ internal class ExpressionsInterpretersBenchmark {
|
|||||||
blackhole.consume(sum)
|
blackhole.consume(sum)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun invokeAndSum(expr: Expression<Double>, blackhole: Blackhole) {
|
private fun invokeAndSum(expr: Expression<Float64>, blackhole: Blackhole) {
|
||||||
val random = Random(0)
|
val random = Random(0)
|
||||||
var sum = 0.0
|
var sum = 0.0
|
||||||
val m = HashMap<Symbol, Double>()
|
val m = HashMap<Symbol, Double>()
|
||||||
@ -114,9 +115,9 @@ internal class ExpressionsInterpretersBenchmark {
|
|||||||
private val asmPrimitive = node.compileToExpression(Float64Field)
|
private val asmPrimitive = node.compileToExpression(Float64Field)
|
||||||
private val xIdx = asmPrimitive.indexer.indexOf(x)
|
private val xIdx = asmPrimitive.indexer.indexOf(x)
|
||||||
|
|
||||||
private val asmGeneric = node.compileToExpression(Float64Field as Algebra<Double>)
|
private val asmGeneric = node.compileToExpression(Float64Field as Algebra<Float64>)
|
||||||
|
|
||||||
private val raw = Expression<Double> { args ->
|
private val raw = Expression<Float64> { args ->
|
||||||
val x = args[x]!!
|
val x = args[x]!!
|
||||||
x * 2.0 + 2.0 / x - 16.0 / sin(x)
|
x * 2.0 + 2.0 / x - 16.0 / sin(x)
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ import space.kscience.kmath.UnsafeKMathAPI
|
|||||||
import space.kscience.kmath.nd.*
|
import space.kscience.kmath.nd.*
|
||||||
import space.kscience.kmath.nd4j.nd4j
|
import space.kscience.kmath.nd4j.nd4j
|
||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.tensors.core.DoubleTensor
|
import space.kscience.kmath.tensors.core.DoubleTensor
|
||||||
import space.kscience.kmath.tensors.core.one
|
import space.kscience.kmath.tensors.core.one
|
||||||
import space.kscience.kmath.tensors.core.tensorAlgebra
|
import space.kscience.kmath.tensors.core.tensorAlgebra
|
||||||
@ -37,28 +38,28 @@ internal class NDFieldBenchmark {
|
|||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
fun specializedFieldAdd(blackhole: Blackhole) = with(specializedField) {
|
fun specializedFieldAdd(blackhole: Blackhole) = with(specializedField) {
|
||||||
var res: StructureND<Double> = one(shape)
|
var res: StructureND<Float64> = one(shape)
|
||||||
repeat(n) { res += 1.0 }
|
repeat(n) { res += 1.0 }
|
||||||
blackhole.consume(res)
|
blackhole.consume(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
fun boxingFieldAdd(blackhole: Blackhole) = with(genericField) {
|
fun boxingFieldAdd(blackhole: Blackhole) = with(genericField) {
|
||||||
var res: StructureND<Double> = one(shape)
|
var res: StructureND<Float64> = one(shape)
|
||||||
repeat(n) { res += 1.0 }
|
repeat(n) { res += 1.0 }
|
||||||
blackhole.consume(res)
|
blackhole.consume(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
fun multikAdd(blackhole: Blackhole) = with(multikAlgebra) {
|
fun multikAdd(blackhole: Blackhole) = with(multikAlgebra) {
|
||||||
var res: StructureND<Double> = one(shape)
|
var res: StructureND<Float64> = one(shape)
|
||||||
repeat(n) { res += 1.0 }
|
repeat(n) { res += 1.0 }
|
||||||
blackhole.consume(res)
|
blackhole.consume(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
fun viktorAdd(blackhole: Blackhole) = with(viktorField) {
|
fun viktorAdd(blackhole: Blackhole) = with(viktorField) {
|
||||||
var res: StructureND<Double> = one(shape)
|
var res: StructureND<Float64> = one(shape)
|
||||||
repeat(n) { res += 1.0 }
|
repeat(n) { res += 1.0 }
|
||||||
blackhole.consume(res)
|
blackhole.consume(res)
|
||||||
}
|
}
|
||||||
@ -87,7 +88,7 @@ internal class NDFieldBenchmark {
|
|||||||
|
|
||||||
// @Benchmark
|
// @Benchmark
|
||||||
// fun nd4jAdd(blackhole: Blackhole) = with(nd4jField) {
|
// fun nd4jAdd(blackhole: Blackhole) = with(nd4jField) {
|
||||||
// var res: StructureND<Double> = one(dim, dim)
|
// var res: StructureND<Float64> = one(dim, dim)
|
||||||
// repeat(n) { res += 1.0 }
|
// repeat(n) { res += 1.0 }
|
||||||
// blackhole.consume(res)
|
// blackhole.consume(res)
|
||||||
// }
|
// }
|
||||||
|
@ -15,6 +15,7 @@ import space.kscience.kmath.nd.StructureND
|
|||||||
import space.kscience.kmath.nd.ndAlgebra
|
import space.kscience.kmath.nd.ndAlgebra
|
||||||
import space.kscience.kmath.nd.one
|
import space.kscience.kmath.nd.one
|
||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.viktor.ViktorFieldND
|
import space.kscience.kmath.viktor.ViktorFieldND
|
||||||
|
|
||||||
@State(Scope.Benchmark)
|
@State(Scope.Benchmark)
|
||||||
@ -23,7 +24,7 @@ internal class ViktorBenchmark {
|
|||||||
@Benchmark
|
@Benchmark
|
||||||
fun doubleFieldAddition(blackhole: Blackhole) {
|
fun doubleFieldAddition(blackhole: Blackhole) {
|
||||||
with(doubleField) {
|
with(doubleField) {
|
||||||
var res: StructureND<Double> = one(shape)
|
var res: StructureND<Float64> = one(shape)
|
||||||
repeat(n) { res += 1.0 }
|
repeat(n) { res += 1.0 }
|
||||||
blackhole.consume(res)
|
blackhole.consume(res)
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ The code to run this looks like:
|
|||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
specializedField.run {
|
specializedField.run {
|
||||||
var res: NDBuffer<Double> = one
|
var res: NDBuffer<Float64> = one
|
||||||
repeat(n) {
|
repeat(n) {
|
||||||
res += 1.0
|
res += 1.0
|
||||||
}
|
}
|
||||||
@ -103,7 +103,7 @@ The boxing field produced by
|
|||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
genericField.run {
|
genericField.run {
|
||||||
var res: NDBuffer<Double> = one
|
var res: NDBuffer<Float64> = one
|
||||||
repeat(n) {
|
repeat(n) {
|
||||||
res += 1.0
|
res += 1.0
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,12 @@ import space.kscience.kmath.integration.gaussIntegrator
|
|||||||
import space.kscience.kmath.integration.integrate
|
import space.kscience.kmath.integration.integrate
|
||||||
import space.kscience.kmath.integration.value
|
import space.kscience.kmath.integration.value
|
||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
//Define a function
|
//Define a function
|
||||||
val function: Function1D<Double> = { x -> 3 * x.pow(2) + 2 * x + 1 }
|
val function: Function1D<Float64> = { x -> 3 * x.pow(2) + 2 * x + 1 }
|
||||||
|
|
||||||
//get the result of the integration
|
//get the result of the integration
|
||||||
val result = Float64Field.gaussIntegrator.integrate(0.0..10.0, function = function)
|
val result = Float64Field.gaussIntegrator.integrate(0.0..10.0, function = function)
|
||||||
|
@ -8,6 +8,7 @@ package space.kscience.kmath.functions
|
|||||||
import space.kscience.kmath.interpolation.SplineInterpolator
|
import space.kscience.kmath.interpolation.SplineInterpolator
|
||||||
import space.kscience.kmath.interpolation.interpolatePolynomials
|
import space.kscience.kmath.interpolation.interpolatePolynomials
|
||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.plotly.Plotly
|
import space.kscience.plotly.Plotly
|
||||||
import space.kscience.plotly.UnstablePlotlyAPI
|
import space.kscience.plotly.UnstablePlotlyAPI
|
||||||
import space.kscience.plotly.makeFile
|
import space.kscience.plotly.makeFile
|
||||||
@ -23,7 +24,7 @@ fun main() {
|
|||||||
x to sin(x)
|
x to sin(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
val polynomial: PiecewisePolynomial<Double> = SplineInterpolator(Float64Field).interpolatePolynomials(data)
|
val polynomial: PiecewisePolynomial<Float64> = SplineInterpolator(Float64Field).interpolatePolynomials(data)
|
||||||
|
|
||||||
val function = polynomial.asFunction(Float64Field, 0.0)
|
val function = polynomial.asFunction(Float64Field, 0.0)
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import space.kscience.kmath.interpolation.splineInterpolator
|
|||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
import space.kscience.kmath.real.map
|
import space.kscience.kmath.real.map
|
||||||
import space.kscience.kmath.real.step
|
import space.kscience.kmath.real.step
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.plotly.Plotly
|
import space.kscience.plotly.Plotly
|
||||||
import space.kscience.plotly.UnstablePlotlyAPI
|
import space.kscience.plotly.UnstablePlotlyAPI
|
||||||
import space.kscience.plotly.makeFile
|
import space.kscience.plotly.makeFile
|
||||||
@ -18,7 +19,7 @@ import space.kscience.plotly.scatter
|
|||||||
|
|
||||||
@OptIn(UnstablePlotlyAPI::class)
|
@OptIn(UnstablePlotlyAPI::class)
|
||||||
fun main() {
|
fun main() {
|
||||||
val function: Function1D<Double> = { x ->
|
val function: Function1D<Float64> = { x ->
|
||||||
if (x in 30.0..50.0) {
|
if (x in 30.0..50.0) {
|
||||||
1.0
|
1.0
|
||||||
} else {
|
} else {
|
||||||
@ -28,7 +29,7 @@ fun main() {
|
|||||||
val xs = 0.0..100.0 step 0.5
|
val xs = 0.0..100.0 step 0.5
|
||||||
val ys = xs.map(function)
|
val ys = xs.map(function)
|
||||||
|
|
||||||
val polynomial: PiecewisePolynomial<Double> = Float64Field.splineInterpolator.interpolatePolynomials(xs, ys)
|
val polynomial: PiecewisePolynomial<Float64> = Float64Field.splineInterpolator.interpolatePolynomials(xs, ys)
|
||||||
|
|
||||||
val polyFunction = polynomial.asFunction(Float64Field, 0.0)
|
val polyFunction = polynomial.asFunction(Float64Field, 0.0)
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import space.kscience.kmath.nd.StructureND
|
|||||||
import space.kscience.kmath.nd.structureND
|
import space.kscience.kmath.nd.structureND
|
||||||
import space.kscience.kmath.nd.withNdAlgebra
|
import space.kscience.kmath.nd.withNdAlgebra
|
||||||
import space.kscience.kmath.operations.algebra
|
import space.kscience.kmath.operations.algebra
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
fun main(): Unit = Double.algebra.withNdAlgebra(2, 2) {
|
fun main(): Unit = Double.algebra.withNdAlgebra(2, 2) {
|
||||||
@ -22,7 +23,7 @@ fun main(): Unit = Double.algebra.withNdAlgebra(2, 2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Define a function in a nd space
|
//Define a function in a nd space
|
||||||
val function: (Double) -> StructureND<Double> = { x: Double -> 3 * x.pow(2) + 2 * diagonal(x) + 1 }
|
val function: (Double) -> StructureND<Float64> = { x: Double -> 3 * x.pow(2) + 2 * diagonal(x) + 1 }
|
||||||
|
|
||||||
//get the result of the integration
|
//get the result of the integration
|
||||||
val result = gaussIntegrator.integrate(0.0..10.0, function = function)
|
val result = gaussIntegrator.integrate(0.0..10.0, function = function)
|
||||||
|
@ -6,18 +6,19 @@
|
|||||||
package space.kscience.kmath.linear
|
package space.kscience.kmath.linear
|
||||||
|
|
||||||
import space.kscience.kmath.real.*
|
import space.kscience.kmath.real.*
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.Float64Buffer
|
import space.kscience.kmath.structures.Float64Buffer
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
val x0 = DoubleVector(0.0, 0.0, 0.0)
|
val x0 = DoubleVector(0.0, 0.0, 0.0)
|
||||||
val sigma = DoubleVector(1.0, 1.0, 1.0)
|
val sigma = DoubleVector(1.0, 1.0, 1.0)
|
||||||
|
|
||||||
val gaussian: (Point<Double>) -> Double = { x ->
|
val gaussian: (Point<Float64>) -> Double = { x ->
|
||||||
require(x.size == x0.size)
|
require(x.size == x0.size)
|
||||||
kotlin.math.exp(-((x - x0) / sigma).square().sum())
|
kotlin.math.exp(-((x - x0) / sigma).square().sum())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ((Point<Double>) -> Double).grad(x: Point<Double>): Point<Double> {
|
fun ((Point<Float64>) -> Double).grad(x: Point<Float64>): Point<Float64> {
|
||||||
require(x.size == x0.size)
|
require(x.size == x0.size)
|
||||||
return Float64Buffer(x.size) { i ->
|
return Float64Buffer(x.size) { i ->
|
||||||
val h = sigma[i] / 5
|
val h = sigma[i] / 5
|
||||||
|
@ -11,6 +11,7 @@ import space.kscience.kmath.nd.Float64BufferND
|
|||||||
import space.kscience.kmath.nd.Structure2D
|
import space.kscience.kmath.nd.Structure2D
|
||||||
import space.kscience.kmath.nd.mutableStructureND
|
import space.kscience.kmath.nd.mutableStructureND
|
||||||
import space.kscience.kmath.nd.ndAlgebra
|
import space.kscience.kmath.nd.ndAlgebra
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.viktor.viktorAlgebra
|
import space.kscience.kmath.viktor.viktorAlgebra
|
||||||
import kotlin.collections.component1
|
import kotlin.collections.component1
|
||||||
import kotlin.collections.component2
|
import kotlin.collections.component2
|
||||||
@ -20,7 +21,7 @@ fun main() {
|
|||||||
if (i == j) 2.0 else 0.0
|
if (i == j) 2.0 else 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
val cmMatrix: Structure2D<Double> = CMLinearSpace.matrix(2, 2)(0.0, 1.0, 0.0, 3.0)
|
val cmMatrix: Structure2D<Float64> = CMLinearSpace.matrix(2, 2)(0.0, 1.0, 0.0, 3.0)
|
||||||
|
|
||||||
val res: Float64BufferND = Float64Field.ndAlgebra {
|
val res: Float64BufferND = Float64Field.ndAlgebra {
|
||||||
exp(viktorStructure) + 2.0 * cmMatrix
|
exp(viktorStructure) + 2.0 * cmMatrix
|
||||||
|
@ -14,6 +14,7 @@ import space.kscience.kmath.operations.toList
|
|||||||
import space.kscience.kmath.stat.KMComparisonResult
|
import space.kscience.kmath.stat.KMComparisonResult
|
||||||
import space.kscience.kmath.stat.ksComparisonStatistic
|
import space.kscience.kmath.stat.ksComparisonStatistic
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.slice
|
import space.kscience.kmath.structures.slice
|
||||||
import space.kscience.plotly.*
|
import space.kscience.plotly.*
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
@ -24,7 +25,7 @@ fun Double.Companion.seriesAlgebra() = Double.algebra.bufferAlgebra.seriesAlgebr
|
|||||||
fun main() = with(Double.seriesAlgebra()) {
|
fun main() = with(Double.seriesAlgebra()) {
|
||||||
|
|
||||||
|
|
||||||
fun Plot.plotSeries(name: String, buffer: Buffer<Double>) {
|
fun Plot.plotSeries(name: String, buffer: Buffer<Float64>) {
|
||||||
scatter {
|
scatter {
|
||||||
this.name = name
|
this.name = name
|
||||||
x.numbers = buffer.labels
|
x.numbers = buffer.labels
|
||||||
@ -37,10 +38,10 @@ fun main() = with(Double.seriesAlgebra()) {
|
|||||||
|
|
||||||
val s2 = s1.slice(20..50).moveTo(40)
|
val s2 = s1.slice(20..50).moveTo(40)
|
||||||
|
|
||||||
val s3: Buffer<Double> = s1.zip(s2) { l, r -> l + r } //s1 + s2
|
val s3: Buffer<Float64> = s1.zip(s2) { l, r -> l + r } //s1 + s2
|
||||||
val s4 = s3.map { ln(it) }
|
val s4 = s3.map { ln(it) }
|
||||||
|
|
||||||
val kmTest: KMComparisonResult<Double> = ksComparisonStatistic(s1, s2)
|
val kmTest: KMComparisonResult<Float64> = ksComparisonStatistic(s1, s2)
|
||||||
|
|
||||||
Plotly.page {
|
Plotly.page {
|
||||||
h1 { +"This is my plot" }
|
h1 { +"This is my plot" }
|
||||||
|
@ -6,10 +6,7 @@
|
|||||||
package space.kscience.kmath.series
|
package space.kscience.kmath.series
|
||||||
|
|
||||||
|
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.*
|
||||||
import space.kscience.kmath.structures.Float64Buffer
|
|
||||||
import space.kscience.kmath.structures.asBuffer
|
|
||||||
import space.kscience.kmath.structures.toDoubleArray
|
|
||||||
import space.kscience.plotly.*
|
import space.kscience.plotly.*
|
||||||
import space.kscience.plotly.models.Scatter
|
import space.kscience.plotly.models.Scatter
|
||||||
import space.kscience.plotly.models.ScatterMode
|
import space.kscience.plotly.models.ScatterMode
|
||||||
@ -22,7 +19,7 @@ fun main(): Unit = with(Double.seriesAlgebra()) {
|
|||||||
val arrayOfRandoms = DoubleArray(20) { random.nextDouble() }
|
val arrayOfRandoms = DoubleArray(20) { random.nextDouble() }
|
||||||
|
|
||||||
val series1: Float64Buffer = arrayOfRandoms.asBuffer()
|
val series1: Float64Buffer = arrayOfRandoms.asBuffer()
|
||||||
val series2: Series<Double> = series1.moveBy(3)
|
val series2: Series<Float64> = series1.moveBy(3)
|
||||||
|
|
||||||
val res = series2 - series1
|
val res = series2 - series1
|
||||||
|
|
||||||
@ -30,7 +27,7 @@ fun main(): Unit = with(Double.seriesAlgebra()) {
|
|||||||
|
|
||||||
println(res)
|
println(res)
|
||||||
|
|
||||||
fun Plot.series(name: String, buffer: Buffer<Double>, block: Scatter.() -> Unit = {}) {
|
fun Plot.series(name: String, buffer: Buffer<Float64>, block: Scatter.() -> Unit = {}) {
|
||||||
scatter {
|
scatter {
|
||||||
this.name = name
|
this.name = name
|
||||||
x.numbers = buffer.offsetIndices
|
x.numbers = buffer.offsetIndices
|
||||||
|
@ -37,7 +37,7 @@ private suspend fun runKMathChained(): Duration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun runCMDirect(): Duration {
|
private fun runCMDirect(): Duration {
|
||||||
val rng = RandomSource.create(RandomSource.MT, 123L)
|
val rng = RandomSource.MT.create(123L)
|
||||||
|
|
||||||
val sampler = CMGaussianSampler.of(
|
val sampler = CMGaussianSampler.of(
|
||||||
BoxMullerNormalizedGaussianSampler.of(rng),
|
BoxMullerNormalizedGaussianSampler.of(rng),
|
||||||
|
@ -10,13 +10,14 @@ import space.kscience.kmath.chains.Chain
|
|||||||
import space.kscience.kmath.chains.combineWithState
|
import space.kscience.kmath.chains.combineWithState
|
||||||
import space.kscience.kmath.distributions.NormalDistribution
|
import space.kscience.kmath.distributions.NormalDistribution
|
||||||
import space.kscience.kmath.random.RandomGenerator
|
import space.kscience.kmath.random.RandomGenerator
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
|
|
||||||
private data class AveragingChainState(var num: Int = 0, var value: Double = 0.0)
|
private data class AveragingChainState(var num: Int = 0, var value: Double = 0.0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Averaging.
|
* Averaging.
|
||||||
*/
|
*/
|
||||||
private fun Chain<Double>.mean(): Chain<Double> = combineWithState(AveragingChainState(), { it.copy() }) { chain ->
|
private fun Chain<Float64>.mean(): Chain<Float64> = combineWithState(AveragingChainState(), { it.copy() }) { chain ->
|
||||||
val next = chain.next()
|
val next = chain.next()
|
||||||
num++
|
num++
|
||||||
value += next
|
value += next
|
||||||
|
@ -26,7 +26,7 @@ fun main() {
|
|||||||
|
|
||||||
val realTime = measureTimeMillis {
|
val realTime = measureTimeMillis {
|
||||||
realField {
|
realField {
|
||||||
var res: StructureND<Double> = one
|
var res: StructureND<Float64> = one
|
||||||
repeat(n) {
|
repeat(n) {
|
||||||
res += 1.0
|
res += 1.0
|
||||||
}
|
}
|
||||||
|
@ -45,35 +45,35 @@ fun main() {
|
|||||||
|
|
||||||
measureAndPrint("Boxing addition") {
|
measureAndPrint("Boxing addition") {
|
||||||
genericField {
|
genericField {
|
||||||
var res: StructureND<Double> = one(shape)
|
var res: StructureND<Float64> = one(shape)
|
||||||
repeat(n) { res += 1.0 }
|
repeat(n) { res += 1.0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
measureAndPrint("Specialized addition") {
|
measureAndPrint("Specialized addition") {
|
||||||
doubleField {
|
doubleField {
|
||||||
var res: StructureND<Double> = one(shape)
|
var res: StructureND<Float64> = one(shape)
|
||||||
repeat(n) { res += 1.0 }
|
repeat(n) { res += 1.0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
measureAndPrint("Nd4j specialized addition") {
|
measureAndPrint("Nd4j specialized addition") {
|
||||||
nd4jField {
|
nd4jField {
|
||||||
var res: StructureND<Double> = one(shape)
|
var res: StructureND<Float64> = one(shape)
|
||||||
repeat(n) { res += 1.0 }
|
repeat(n) { res += 1.0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
measureAndPrint("Viktor addition") {
|
measureAndPrint("Viktor addition") {
|
||||||
viktorField {
|
viktorField {
|
||||||
var res: StructureND<Double> = one
|
var res: StructureND<Float64> = one
|
||||||
repeat(n) { res += 1.0 }
|
repeat(n) { res += 1.0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
measureAndPrint("Parallel stream addition") {
|
measureAndPrint("Parallel stream addition") {
|
||||||
parallelField {
|
parallelField {
|
||||||
var res: StructureND<Double> = one
|
var res: StructureND<Float64> = one
|
||||||
repeat(n) { res += 1.0 }
|
repeat(n) { res += 1.0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,21 +19,21 @@ import java.util.stream.IntStream
|
|||||||
* execution.
|
* execution.
|
||||||
*/
|
*/
|
||||||
class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, Float64Field>,
|
class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, Float64Field>,
|
||||||
NumbersAddOps<StructureND<Double>>,
|
NumbersAddOps<StructureND<Float64>>,
|
||||||
ExtendedField<StructureND<Double>> {
|
ExtendedField<StructureND<Float64>> {
|
||||||
|
|
||||||
private val strides = ColumnStrides(shape)
|
private val strides = ColumnStrides(shape)
|
||||||
override val elementAlgebra: Float64Field get() = Float64Field
|
override val elementAlgebra: Float64Field get() = Float64Field
|
||||||
override val zero: BufferND<Double> by lazy { structureND(shape) { zero } }
|
override val zero: BufferND<Float64> by lazy { structureND(shape) { zero } }
|
||||||
override val one: BufferND<Double> by lazy { structureND(shape) { one } }
|
override val one: BufferND<Float64> by lazy { structureND(shape) { one } }
|
||||||
|
|
||||||
override fun number(value: Number): BufferND<Double> {
|
override fun number(value: Number): BufferND<Float64> {
|
||||||
val d = value.toDouble() // minimize conversions
|
val d = value.toDouble() // minimize conversions
|
||||||
return structureND(shape) { d }
|
return structureND(shape) { d }
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(PerformancePitfall::class)
|
@OptIn(PerformancePitfall::class)
|
||||||
private val StructureND<Double>.buffer: Float64Buffer
|
private val StructureND<Float64>.buffer: Float64Buffer
|
||||||
get() = when {
|
get() = when {
|
||||||
shape != this@StreamDoubleFieldND.shape -> throw ShapeMismatchException(
|
shape != this@StreamDoubleFieldND.shape -> throw ShapeMismatchException(
|
||||||
this@StreamDoubleFieldND.shape,
|
this@StreamDoubleFieldND.shape,
|
||||||
@ -44,7 +44,7 @@ class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, Float64
|
|||||||
else -> Float64Buffer(strides.linearSize) { offset -> get(strides.index(offset)) }
|
else -> Float64Buffer(strides.linearSize) { offset -> get(strides.index(offset)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun structureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): BufferND<Double> {
|
override fun structureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): BufferND<Float64> {
|
||||||
val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
|
val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
|
||||||
val index = strides.index(offset)
|
val index = strides.index(offset)
|
||||||
Float64Field.initializer(index)
|
Float64Field.initializer(index)
|
||||||
@ -56,7 +56,7 @@ class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, Float64
|
|||||||
override fun mutableStructureND(
|
override fun mutableStructureND(
|
||||||
shape: ShapeND,
|
shape: ShapeND,
|
||||||
initializer: DoubleField.(IntArray) -> Double,
|
initializer: DoubleField.(IntArray) -> Double,
|
||||||
): MutableBufferND<Double> {
|
): MutableBufferND<Float64> {
|
||||||
val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
|
val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
|
||||||
val index = strides.index(offset)
|
val index = strides.index(offset)
|
||||||
DoubleField.initializer(index)
|
DoubleField.initializer(index)
|
||||||
@ -66,17 +66,17 @@ class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, Float64
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(PerformancePitfall::class)
|
@OptIn(PerformancePitfall::class)
|
||||||
override fun StructureND<Double>.map(
|
override fun StructureND<Float64>.map(
|
||||||
transform: Float64Field.(Double) -> Double,
|
transform: Float64Field.(Double) -> Double,
|
||||||
): BufferND<Double> {
|
): BufferND<Float64> {
|
||||||
val array = Arrays.stream(buffer.array).parallel().map { Float64Field.transform(it) }.toArray()
|
val array = Arrays.stream(buffer.array).parallel().map { Float64Field.transform(it) }.toArray()
|
||||||
return BufferND(strides, array.asBuffer())
|
return BufferND(strides, array.asBuffer())
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(PerformancePitfall::class)
|
@OptIn(PerformancePitfall::class)
|
||||||
override fun StructureND<Double>.mapIndexed(
|
override fun StructureND<Float64>.mapIndexed(
|
||||||
transform: Float64Field.(index: IntArray, Double) -> Double,
|
transform: Float64Field.(index: IntArray, Double) -> Double,
|
||||||
): BufferND<Double> {
|
): BufferND<Float64> {
|
||||||
val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
|
val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
|
||||||
Float64Field.transform(
|
Float64Field.transform(
|
||||||
strides.index(offset),
|
strides.index(offset),
|
||||||
@ -89,39 +89,39 @@ class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, Float64
|
|||||||
|
|
||||||
@OptIn(PerformancePitfall::class)
|
@OptIn(PerformancePitfall::class)
|
||||||
override fun zip(
|
override fun zip(
|
||||||
left: StructureND<Double>,
|
left: StructureND<Float64>,
|
||||||
right: StructureND<Double>,
|
right: StructureND<Float64>,
|
||||||
transform: Float64Field.(Double, Double) -> Double,
|
transform: Float64Field.(Double, Double) -> Double,
|
||||||
): BufferND<Double> {
|
): BufferND<Float64> {
|
||||||
val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
|
val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
|
||||||
Float64Field.transform(left.buffer.array[offset], right.buffer.array[offset])
|
Float64Field.transform(left.buffer.array[offset], right.buffer.array[offset])
|
||||||
}.toArray()
|
}.toArray()
|
||||||
return BufferND(strides, array.asBuffer())
|
return BufferND(strides, array.asBuffer())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun StructureND<Double>.unaryMinus(): StructureND<Double> = map { -it }
|
override fun StructureND<Float64>.unaryMinus(): StructureND<Float64> = map { -it }
|
||||||
|
|
||||||
override fun scale(a: StructureND<Double>, value: Double): StructureND<Double> = a.map { it * value }
|
override fun scale(a: StructureND<Float64>, value: Double): StructureND<Float64> = a.map { it * value }
|
||||||
|
|
||||||
override fun power(arg: StructureND<Double>, pow: Number): BufferND<Double> = arg.map { power(it, pow) }
|
override fun power(arg: StructureND<Float64>, pow: Number): BufferND<Float64> = arg.map { power(it, pow) }
|
||||||
|
|
||||||
override fun exp(arg: StructureND<Double>): BufferND<Double> = arg.map { exp(it) }
|
override fun exp(arg: StructureND<Float64>): BufferND<Float64> = arg.map { exp(it) }
|
||||||
|
|
||||||
override fun ln(arg: StructureND<Double>): BufferND<Double> = arg.map { ln(it) }
|
override fun ln(arg: StructureND<Float64>): BufferND<Float64> = arg.map { ln(it) }
|
||||||
|
|
||||||
override fun sin(arg: StructureND<Double>): BufferND<Double> = arg.map { sin(it) }
|
override fun sin(arg: StructureND<Float64>): BufferND<Float64> = arg.map { sin(it) }
|
||||||
override fun cos(arg: StructureND<Double>): BufferND<Double> = arg.map { cos(it) }
|
override fun cos(arg: StructureND<Float64>): BufferND<Float64> = arg.map { cos(it) }
|
||||||
override fun tan(arg: StructureND<Double>): BufferND<Double> = arg.map { tan(it) }
|
override fun tan(arg: StructureND<Float64>): BufferND<Float64> = arg.map { tan(it) }
|
||||||
override fun asin(arg: StructureND<Double>): BufferND<Double> = arg.map { asin(it) }
|
override fun asin(arg: StructureND<Float64>): BufferND<Float64> = arg.map { asin(it) }
|
||||||
override fun acos(arg: StructureND<Double>): BufferND<Double> = arg.map { acos(it) }
|
override fun acos(arg: StructureND<Float64>): BufferND<Float64> = arg.map { acos(it) }
|
||||||
override fun atan(arg: StructureND<Double>): BufferND<Double> = arg.map { atan(it) }
|
override fun atan(arg: StructureND<Float64>): BufferND<Float64> = arg.map { atan(it) }
|
||||||
|
|
||||||
override fun sinh(arg: StructureND<Double>): BufferND<Double> = arg.map { sinh(it) }
|
override fun sinh(arg: StructureND<Float64>): BufferND<Float64> = arg.map { sinh(it) }
|
||||||
override fun cosh(arg: StructureND<Double>): BufferND<Double> = arg.map { cosh(it) }
|
override fun cosh(arg: StructureND<Float64>): BufferND<Float64> = arg.map { cosh(it) }
|
||||||
override fun tanh(arg: StructureND<Double>): BufferND<Double> = arg.map { tanh(it) }
|
override fun tanh(arg: StructureND<Float64>): BufferND<Float64> = arg.map { tanh(it) }
|
||||||
override fun asinh(arg: StructureND<Double>): BufferND<Double> = arg.map { asinh(it) }
|
override fun asinh(arg: StructureND<Float64>): BufferND<Float64> = arg.map { asinh(it) }
|
||||||
override fun acosh(arg: StructureND<Double>): BufferND<Double> = arg.map { acosh(it) }
|
override fun acosh(arg: StructureND<Float64>): BufferND<Float64> = arg.map { acosh(it) }
|
||||||
override fun atanh(arg: StructureND<Double>): BufferND<Double> = arg.map { atanh(it) }
|
override fun atanh(arg: StructureND<Float64>): BufferND<Float64> = arg.map { atanh(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Float64Field.ndStreaming(vararg shape: Int): StreamDoubleFieldND = StreamDoubleFieldND(ShapeND(shape))
|
fun Float64Field.ndStreaming(vararg shape: Int): StreamDoubleFieldND = StreamDoubleFieldND(ShapeND(shape))
|
||||||
|
@ -11,7 +11,7 @@ import space.kscience.kmath.operations.algebra
|
|||||||
|
|
||||||
@OptIn(PerformancePitfall::class)
|
@OptIn(PerformancePitfall::class)
|
||||||
fun main(): Unit = with(Double.algebra.ndAlgebra) {
|
fun main(): Unit = with(Double.algebra.ndAlgebra) {
|
||||||
val structure: MutableStructure2D<Double> = mutableStructureND(ShapeND(2, 2)) { (i, j) ->
|
val structure: MutableStructure2D<Float64> = mutableStructureND(ShapeND(2, 2)) { (i, j) ->
|
||||||
i.toDouble() + j.toDouble()
|
i.toDouble() + j.toDouble()
|
||||||
}.as2D()
|
}.as2D()
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import space.kscience.kmath.nd.MutableStructure2D
|
|||||||
import space.kscience.kmath.nd.ShapeND
|
import space.kscience.kmath.nd.ShapeND
|
||||||
import space.kscience.kmath.nd.as2D
|
import space.kscience.kmath.nd.as2D
|
||||||
import space.kscience.kmath.nd.component1
|
import space.kscience.kmath.nd.component1
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.tensors.LevenbergMarquardt.StartDataLm
|
import space.kscience.kmath.tensors.LevenbergMarquardt.StartDataLm
|
||||||
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.zeros
|
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.zeros
|
||||||
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
|
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
|
||||||
@ -20,9 +21,9 @@ import space.kscience.kmath.tensors.core.levenbergMarquardt
|
|||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
fun streamLm(
|
fun streamLm(
|
||||||
lm_func: (MutableStructure2D<Double>, MutableStructure2D<Double>, Int) -> (MutableStructure2D<Double>),
|
lm_func: (MutableStructure2D<Float64>, MutableStructure2D<Float64>, Int) -> (MutableStructure2D<Float64>),
|
||||||
startData: StartDataLm, launchFrequencyInMs: Long, numberOfLaunches: Int,
|
startData: StartDataLm, launchFrequencyInMs: Long, numberOfLaunches: Int,
|
||||||
): Flow<MutableStructure2D<Double>> = flow {
|
): Flow<MutableStructure2D<Float64>> = flow {
|
||||||
|
|
||||||
var example_number = startData.example_number
|
var example_number = startData.example_number
|
||||||
var p_init = startData.p_init
|
var p_init = startData.p_init
|
||||||
@ -64,7 +65,7 @@ fun streamLm(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateNewYDat(y_dat: MutableStructure2D<Double>, delta: Double): MutableStructure2D<Double> {
|
fun generateNewYDat(y_dat: MutableStructure2D<Float64>, delta: Double): MutableStructure2D<Float64> {
|
||||||
val n = y_dat.shape.component1()
|
val n = y_dat.shape.component1()
|
||||||
val y_dat_new = zeros(ShapeND(intArrayOf(n, 1))).as2D()
|
val y_dat_new = zeros(ShapeND(intArrayOf(n, 1))).as2D()
|
||||||
for (i in 0 until n) {
|
for (i in 0 until n) {
|
||||||
|
@ -9,6 +9,7 @@ import space.kscience.kmath.nd.MutableStructure2D
|
|||||||
import space.kscience.kmath.nd.ShapeND
|
import space.kscience.kmath.nd.ShapeND
|
||||||
import space.kscience.kmath.nd.as2D
|
import space.kscience.kmath.nd.as2D
|
||||||
import space.kscience.kmath.nd.component1
|
import space.kscience.kmath.nd.component1
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra
|
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra
|
||||||
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div
|
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div
|
||||||
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
|
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
|
||||||
@ -19,24 +20,24 @@ import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.times
|
|||||||
import space.kscience.kmath.tensors.core.asDoubleTensor
|
import space.kscience.kmath.tensors.core.asDoubleTensor
|
||||||
|
|
||||||
public data class StartDataLm(
|
public data class StartDataLm(
|
||||||
var lm_matx_y_dat: MutableStructure2D<Double>,
|
var lm_matx_y_dat: MutableStructure2D<Float64>,
|
||||||
var example_number: Int,
|
var example_number: Int,
|
||||||
var p_init: MutableStructure2D<Double>,
|
var p_init: MutableStructure2D<Float64>,
|
||||||
var t: MutableStructure2D<Double>,
|
var t: MutableStructure2D<Float64>,
|
||||||
var y_dat: MutableStructure2D<Double>,
|
var y_dat: MutableStructure2D<Float64>,
|
||||||
var weight: Double,
|
var weight: Double,
|
||||||
var dp: MutableStructure2D<Double>,
|
var dp: MutableStructure2D<Float64>,
|
||||||
var p_min: MutableStructure2D<Double>,
|
var p_min: MutableStructure2D<Float64>,
|
||||||
var p_max: MutableStructure2D<Double>,
|
var p_max: MutableStructure2D<Float64>,
|
||||||
var consts: MutableStructure2D<Double>,
|
var consts: MutableStructure2D<Float64>,
|
||||||
var opts: DoubleArray,
|
var opts: DoubleArray,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun funcEasyForLm(
|
fun funcEasyForLm(
|
||||||
t: MutableStructure2D<Double>,
|
t: MutableStructure2D<Float64>,
|
||||||
p: MutableStructure2D<Double>,
|
p: MutableStructure2D<Float64>,
|
||||||
exampleNumber: Int,
|
exampleNumber: Int,
|
||||||
): MutableStructure2D<Double> {
|
): MutableStructure2D<Float64> {
|
||||||
val m = t.shape.component1()
|
val m = t.shape.component1()
|
||||||
var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1)))
|
var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1)))
|
||||||
|
|
||||||
@ -59,10 +60,10 @@ fun funcEasyForLm(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun funcMiddleForLm(
|
fun funcMiddleForLm(
|
||||||
t: MutableStructure2D<Double>,
|
t: MutableStructure2D<Float64>,
|
||||||
p: MutableStructure2D<Double>,
|
p: MutableStructure2D<Float64>,
|
||||||
exampleNumber: Int,
|
exampleNumber: Int,
|
||||||
): MutableStructure2D<Double> {
|
): MutableStructure2D<Float64> {
|
||||||
val m = t.shape.component1()
|
val m = t.shape.component1()
|
||||||
var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1)))
|
var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1)))
|
||||||
|
|
||||||
@ -79,10 +80,10 @@ fun funcMiddleForLm(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun funcDifficultForLm(
|
fun funcDifficultForLm(
|
||||||
t: MutableStructure2D<Double>,
|
t: MutableStructure2D<Float64>,
|
||||||
p: MutableStructure2D<Double>,
|
p: MutableStructure2D<Float64>,
|
||||||
exampleNumber: Int,
|
exampleNumber: Int,
|
||||||
): MutableStructure2D<Double> {
|
): MutableStructure2D<Float64> {
|
||||||
val m = t.shape.component1()
|
val m = t.shape.component1()
|
||||||
var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1)))
|
var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1)))
|
||||||
|
|
||||||
|
@ -10,12 +10,13 @@ import org.jetbrains.kotlinx.multik.api.ndarray
|
|||||||
import org.jetbrains.kotlinx.multik.default.DefaultEngine
|
import org.jetbrains.kotlinx.multik.default.DefaultEngine
|
||||||
import space.kscience.kmath.multik.MultikDoubleAlgebra
|
import space.kscience.kmath.multik.MultikDoubleAlgebra
|
||||||
import space.kscience.kmath.nd.one
|
import space.kscience.kmath.nd.one
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
|
|
||||||
|
|
||||||
val multikAlgebra = MultikDoubleAlgebra(DefaultEngine())
|
val multikAlgebra = MultikDoubleAlgebra(DefaultEngine())
|
||||||
|
|
||||||
fun main(): Unit = with(multikAlgebra) {
|
fun main(): Unit = with(multikAlgebra) {
|
||||||
val a = Multik.ndarray(intArrayOf(1, 2, 3)).asType<Double>().wrap()
|
val a = Multik.ndarray(intArrayOf(1, 2, 3)).asType<Float64>().wrap()
|
||||||
val b = Multik.ndarray(doubleArrayOf(1.0, 2.0, 3.0)).wrap()
|
val b = Multik.ndarray(doubleArrayOf(1.0, 2.0, 3.0)).wrap()
|
||||||
one(a.shape) - a + b * 3.0
|
one(a.shape) - a + b * 3.0
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import space.kscience.kmath.operations.Float64Field
|
|||||||
import space.kscience.kmath.operations.Int32Ring
|
import space.kscience.kmath.operations.Int32Ring
|
||||||
import space.kscience.kmath.operations.Int8Ring
|
import space.kscience.kmath.operations.Int8Ring
|
||||||
import space.kscience.kmath.operations.pi
|
import space.kscience.kmath.operations.pi
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.fail
|
import kotlin.test.fail
|
||||||
@ -41,7 +42,7 @@ internal class TestFolding {
|
|||||||
@Test
|
@Test
|
||||||
fun foldSymbol() = assertEquals(
|
fun foldSymbol() = assertEquals(
|
||||||
Float64Field.pi,
|
Float64Field.pi,
|
||||||
("pi".parseMath().evaluateConstants(Float64Field) as? TypedMst.Constant<Double> ?: fail()).value,
|
("pi".parseMath().evaluateConstants(Float64Field) as? TypedMst.Constant<Float64> ?: fail()).value,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -10,12 +10,13 @@ import space.kscience.kmath.expressions.MST
|
|||||||
import space.kscience.kmath.expressions.Symbol
|
import space.kscience.kmath.expressions.Symbol
|
||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
import space.kscience.kmath.operations.Int32Ring
|
import space.kscience.kmath.operations.Int32Ring
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
|
|
||||||
internal interface CompilerTestContext {
|
internal interface CompilerTestContext {
|
||||||
fun MST.compileToExpression(algebra: Int32Ring): Expression<Int>
|
fun MST.compileToExpression(algebra: Int32Ring): Expression<Int>
|
||||||
fun MST.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): 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.compile(algebra: Int32Ring, vararg arguments: Pair<Symbol, Int>): Int = compile(algebra, mapOf(*arguments))
|
||||||
fun MST.compileToExpression(algebra: Float64Field): Expression<Double>
|
fun MST.compileToExpression(algebra: Float64Field): Expression<Float64>
|
||||||
fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double
|
fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double
|
||||||
|
|
||||||
fun MST.compile(algebra: Float64Field, vararg arguments: Pair<Symbol, Double>): Double =
|
fun MST.compile(algebra: Float64Field, vararg arguments: Pair<Symbol, Double>): Double =
|
||||||
|
@ -11,6 +11,7 @@ import space.kscience.kmath.expressions.*
|
|||||||
import space.kscience.kmath.internal.binaryen.*
|
import space.kscience.kmath.internal.binaryen.*
|
||||||
import space.kscience.kmath.internal.webassembly.Instance
|
import space.kscience.kmath.internal.webassembly.Instance
|
||||||
import space.kscience.kmath.operations.*
|
import space.kscience.kmath.operations.*
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.internal.binaryen.Module as BinaryenModule
|
import space.kscience.kmath.internal.binaryen.Module as BinaryenModule
|
||||||
import space.kscience.kmath.internal.webassembly.Module as WasmModule
|
import space.kscience.kmath.internal.webassembly.Module as WasmModule
|
||||||
|
|
||||||
@ -85,13 +86,13 @@ internal sealed class WasmBuilder<T : Number, out E : Expression<T>>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
internal class DoubleWasmBuilder(target: TypedMst<Double>) :
|
internal class DoubleWasmBuilder(target: TypedMst<Float64>) :
|
||||||
WasmBuilder<Double, DoubleExpression>(f64, Float64Field, target) {
|
WasmBuilder<Double, DoubleExpression>(f64, Float64Field, target) {
|
||||||
override val instance by lazy {
|
override val instance by lazy {
|
||||||
object : DoubleExpression {
|
object : DoubleExpression {
|
||||||
override val indexer = SimpleSymbolIndexer(keys)
|
override val indexer = SimpleSymbolIndexer(keys)
|
||||||
|
|
||||||
override fun invoke(arguments: DoubleArray) = spreader(executable, arguments).unsafeCast<Double>()
|
override fun invoke(arguments: DoubleArray) = spreader(executable, arguments).unsafeCast<Float64>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +100,7 @@ internal class DoubleWasmBuilder(target: TypedMst<Double>) :
|
|||||||
|
|
||||||
override fun visitNumber(number: Number) = ctx.f64.const(number.toDouble())
|
override fun visitNumber(number: Number) = ctx.f64.const(number.toDouble())
|
||||||
|
|
||||||
override fun visitUnary(node: TypedMst.Unary<Double>): ExpressionRef = when (node.operation) {
|
override fun visitUnary(node: TypedMst.Unary<Float64>): ExpressionRef = when (node.operation) {
|
||||||
GroupOps.MINUS_OPERATION -> ctx.f64.neg(visit(node.value))
|
GroupOps.MINUS_OPERATION -> ctx.f64.neg(visit(node.value))
|
||||||
GroupOps.PLUS_OPERATION -> visit(node.value)
|
GroupOps.PLUS_OPERATION -> visit(node.value)
|
||||||
PowerOperations.SQRT_OPERATION -> ctx.f64.sqrt(visit(node.value))
|
PowerOperations.SQRT_OPERATION -> ctx.f64.sqrt(visit(node.value))
|
||||||
@ -120,7 +121,7 @@ internal class DoubleWasmBuilder(target: TypedMst<Double>) :
|
|||||||
else -> super.visitUnary(node)
|
else -> super.visitUnary(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitBinary(mst: TypedMst.Binary<Double>): ExpressionRef = when (mst.operation) {
|
override fun visitBinary(mst: TypedMst.Binary<Float64>): ExpressionRef = when (mst.operation) {
|
||||||
GroupOps.PLUS_OPERATION -> ctx.f64.add(visit(mst.left), visit(mst.right))
|
GroupOps.PLUS_OPERATION -> ctx.f64.add(visit(mst.left), visit(mst.right))
|
||||||
GroupOps.MINUS_OPERATION -> ctx.f64.sub(visit(mst.left), visit(mst.right))
|
GroupOps.MINUS_OPERATION -> ctx.f64.sub(visit(mst.left), visit(mst.right))
|
||||||
RingOps.TIMES_OPERATION -> ctx.f64.mul(visit(mst.left), visit(mst.right))
|
RingOps.TIMES_OPERATION -> ctx.f64.mul(visit(mst.left), visit(mst.right))
|
||||||
|
@ -13,6 +13,7 @@ import space.kscience.kmath.ast.evaluateConstants
|
|||||||
import space.kscience.kmath.expressions.*
|
import space.kscience.kmath.expressions.*
|
||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
import space.kscience.kmath.operations.Int32Ring
|
import space.kscience.kmath.operations.Int32Ring
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.wasm.internal.DoubleWasmBuilder
|
import space.kscience.kmath.wasm.internal.DoubleWasmBuilder
|
||||||
import space.kscience.kmath.wasm.internal.IntWasmBuilder
|
import space.kscience.kmath.wasm.internal.IntWasmBuilder
|
||||||
|
|
||||||
@ -58,7 +59,7 @@ public fun MST.compile(algebra: Int32Ring, vararg arguments: Pair<Symbol, Int>):
|
|||||||
* @author Iaroslav Postovalov
|
* @author Iaroslav Postovalov
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public fun MST.compileToExpression(algebra: Float64Field): Expression<Double> {
|
public fun MST.compileToExpression(algebra: Float64Field): Expression<Float64> {
|
||||||
val typed = evaluateConstants(algebra)
|
val typed = evaluateConstants(algebra)
|
||||||
|
|
||||||
return if (typed is TypedMst.Constant) object : DoubleExpression {
|
return if (typed is TypedMst.Constant) object : DoubleExpression {
|
||||||
|
@ -13,6 +13,7 @@ import space.kscience.kmath.expressions.MST
|
|||||||
import space.kscience.kmath.expressions.Symbol
|
import space.kscience.kmath.expressions.Symbol
|
||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
import space.kscience.kmath.operations.Int32Ring
|
import space.kscience.kmath.operations.Int32Ring
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import kotlin.contracts.InvocationKind
|
import kotlin.contracts.InvocationKind
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
import space.kscience.kmath.estree.compile as estreeCompile
|
import space.kscience.kmath.estree.compile as estreeCompile
|
||||||
@ -24,7 +25,7 @@ import space.kscience.kmath.wasm.compileToExpression as wasmCompileToExpression
|
|||||||
private object WasmCompilerTestContext : CompilerTestContext {
|
private object WasmCompilerTestContext : CompilerTestContext {
|
||||||
override fun MST.compileToExpression(algebra: Int32Ring): Expression<Int> = 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.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int = wasmCompile(algebra, arguments)
|
||||||
override fun MST.compileToExpression(algebra: Float64Field): Expression<Double> = wasmCompileToExpression(algebra)
|
override fun MST.compileToExpression(algebra: Float64Field): Expression<Float64> = wasmCompileToExpression(algebra)
|
||||||
|
|
||||||
override fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double =
|
override fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double =
|
||||||
wasmCompile(algebra, arguments)
|
wasmCompile(algebra, arguments)
|
||||||
@ -33,7 +34,7 @@ private object WasmCompilerTestContext : CompilerTestContext {
|
|||||||
private object ESTreeCompilerTestContext : CompilerTestContext {
|
private object ESTreeCompilerTestContext : CompilerTestContext {
|
||||||
override fun MST.compileToExpression(algebra: Int32Ring): Expression<Int> = 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.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int = estreeCompile(algebra, arguments)
|
||||||
override fun MST.compileToExpression(algebra: Float64Field): Expression<Double> = estreeCompileToExpression(algebra)
|
override fun MST.compileToExpression(algebra: Float64Field): Expression<Float64> = estreeCompileToExpression(algebra)
|
||||||
|
|
||||||
override fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double =
|
override fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double =
|
||||||
estreeCompile(algebra, arguments)
|
estreeCompile(algebra, arguments)
|
||||||
|
@ -15,6 +15,7 @@ import space.kscience.kmath.UnstableKMathAPI
|
|||||||
import space.kscience.kmath.ast.TypedMst
|
import space.kscience.kmath.ast.TypedMst
|
||||||
import space.kscience.kmath.expressions.*
|
import space.kscience.kmath.expressions.*
|
||||||
import space.kscience.kmath.operations.*
|
import space.kscience.kmath.operations.*
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import java.lang.invoke.MethodHandles
|
import java.lang.invoke.MethodHandles
|
||||||
import java.lang.invoke.MethodType
|
import java.lang.invoke.MethodType
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
@ -381,7 +382,7 @@ internal sealed class PrimitiveAsmBuilder<T : Number, out E : Expression<T>>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
internal class DoubleAsmBuilder(target: TypedMst<Double>) : PrimitiveAsmBuilder<Double, DoubleExpression>(
|
internal class DoubleAsmBuilder(target: TypedMst<Float64>) : PrimitiveAsmBuilder<Double, DoubleExpression>(
|
||||||
Float64Field,
|
Float64Field,
|
||||||
java.lang.Double::class.java,
|
java.lang.Double::class.java,
|
||||||
java.lang.Double.TYPE,
|
java.lang.Double.TYPE,
|
||||||
@ -410,7 +411,7 @@ internal class DoubleAsmBuilder(target: TypedMst<Double>) : PrimitiveAsmBuilder<
|
|||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun visitUnary(node: TypedMst.Unary<Double>) {
|
override fun visitUnary(node: TypedMst.Unary<Float64>) {
|
||||||
super.visitUnary(node)
|
super.visitUnary(node)
|
||||||
|
|
||||||
when (node.operation) {
|
when (node.operation) {
|
||||||
@ -435,7 +436,7 @@ internal class DoubleAsmBuilder(target: TypedMst<Double>) : PrimitiveAsmBuilder<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitBinary(node: TypedMst.Binary<Double>) {
|
override fun visitBinary(node: TypedMst.Binary<Float64>) {
|
||||||
super.visitBinary(node)
|
super.visitBinary(node)
|
||||||
|
|
||||||
when (node.operation) {
|
when (node.operation) {
|
||||||
|
@ -12,6 +12,7 @@ import space.kscience.kmath.expressions.Symbol
|
|||||||
import space.kscience.kmath.operations.Algebra
|
import space.kscience.kmath.operations.Algebra
|
||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
import space.kscience.kmath.operations.Int32Ring
|
import space.kscience.kmath.operations.Int32Ring
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.asm.compile as asmCompile
|
import space.kscience.kmath.asm.compile as asmCompile
|
||||||
import space.kscience.kmath.asm.compileToExpression as asmCompileToExpression
|
import space.kscience.kmath.asm.compileToExpression as asmCompileToExpression
|
||||||
|
|
||||||
@ -22,18 +23,18 @@ private object GenericAsmCompilerTestContext : CompilerTestContext {
|
|||||||
override fun MST.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int =
|
override fun MST.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int =
|
||||||
asmCompile(algebra as Algebra<Int>, arguments)
|
asmCompile(algebra as Algebra<Int>, arguments)
|
||||||
|
|
||||||
override fun MST.compileToExpression(algebra: Float64Field): Expression<Double> =
|
override fun MST.compileToExpression(algebra: Float64Field): Expression<Float64> =
|
||||||
asmCompileToExpression(algebra as Algebra<Double>)
|
asmCompileToExpression(algebra as Algebra<Float64>)
|
||||||
|
|
||||||
override fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double =
|
override fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double =
|
||||||
asmCompile(algebra as Algebra<Double>, arguments)
|
asmCompile(algebra as Algebra<Float64>, arguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
private object PrimitiveAsmCompilerTestContext : CompilerTestContext {
|
private object PrimitiveAsmCompilerTestContext : CompilerTestContext {
|
||||||
override fun MST.compileToExpression(algebra: Int32Ring): Expression<Int> = 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.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int = asmCompile(algebra, arguments)
|
||||||
override fun MST.compileToExpression(algebra: Float64Field): Expression<Double> = asmCompileToExpression(algebra)
|
override fun MST.compileToExpression(algebra: Float64Field): Expression<Float64> = asmCompileToExpression(algebra)
|
||||||
|
|
||||||
override fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double =
|
override fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double =
|
||||||
asmCompile(algebra, arguments)
|
asmCompile(algebra, arguments)
|
||||||
|
@ -14,6 +14,7 @@ import space.kscience.kmath.expressions.*
|
|||||||
import space.kscience.kmath.operations.DoubleField
|
import space.kscience.kmath.operations.DoubleField
|
||||||
import space.kscience.kmath.operations.ExtendedField
|
import space.kscience.kmath.operations.ExtendedField
|
||||||
import space.kscience.kmath.operations.NumbersAddOps
|
import space.kscience.kmath.operations.NumbersAddOps
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.MutableBufferFactory
|
import space.kscience.kmath.structures.MutableBufferFactory
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -132,9 +133,9 @@ public object CmDsProcessor : AutoDiffProcessor<Double, DerivativeStructure, CmD
|
|||||||
@Deprecated("Use generic DSAlgebra from the core")
|
@Deprecated("Use generic DSAlgebra from the core")
|
||||||
public class CmDsExpression(
|
public class CmDsExpression(
|
||||||
public val function: CmDsField.() -> DerivativeStructure,
|
public val function: CmDsField.() -> DerivativeStructure,
|
||||||
) : DifferentiableExpression<Double> {
|
) : DifferentiableExpression<Float64> {
|
||||||
|
|
||||||
override val type: SafeType<Double> get() = DoubleField.type
|
override val type: SafeType<Float64> get() = DoubleField.type
|
||||||
|
|
||||||
override operator fun invoke(arguments: Map<Symbol, Double>): Double =
|
override operator fun invoke(arguments: Map<Symbol, Double>): Double =
|
||||||
CmDsField(0, arguments).function().value
|
CmDsField(0, arguments).function().value
|
||||||
@ -142,7 +143,7 @@ public class CmDsExpression(
|
|||||||
/**
|
/**
|
||||||
* Get the derivative expression with given orders
|
* Get the derivative expression with given orders
|
||||||
*/
|
*/
|
||||||
override fun derivativeOrNull(symbols: List<Symbol>): Expression<Double> = Expression(type) { arguments ->
|
override fun derivativeOrNull(symbols: List<Symbol>): Expression<Float64> = Expression(type) { arguments ->
|
||||||
with(CmDsField(symbols.size, arguments)) { function().derivative(symbols) }
|
with(CmDsField(symbols.size, arguments)) { function().derivative(symbols) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ package space.kscience.kmath.commons.integration
|
|||||||
import org.apache.commons.math3.analysis.integration.gauss.GaussIntegrator
|
import org.apache.commons.math3.analysis.integration.gauss.GaussIntegrator
|
||||||
import org.apache.commons.math3.analysis.integration.gauss.GaussIntegratorFactory
|
import org.apache.commons.math3.analysis.integration.gauss.GaussIntegratorFactory
|
||||||
import space.kscience.kmath.integration.*
|
import space.kscience.kmath.integration.*
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple one-pass integrator based on Gauss rule
|
* A simple one-pass integrator based on Gauss rule
|
||||||
@ -14,9 +15,9 @@ import space.kscience.kmath.integration.*
|
|||||||
public class CMGaussRuleIntegrator(
|
public class CMGaussRuleIntegrator(
|
||||||
private val numpoints: Int,
|
private val numpoints: Int,
|
||||||
private var type: GaussRule = GaussRule.LEGENDRE,
|
private var type: GaussRule = GaussRule.LEGENDRE,
|
||||||
) : UnivariateIntegrator<Double> {
|
) : UnivariateIntegrator<Float64> {
|
||||||
|
|
||||||
override fun integrate(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> {
|
override fun integrate(integrand: UnivariateIntegrand<Float64>): UnivariateIntegrand<Float64> {
|
||||||
val range = integrand[IntegrationRange]
|
val range = integrand[IntegrationRange]
|
||||||
?: error("Integration range is not provided")
|
?: error("Integration range is not provided")
|
||||||
val integrator: GaussIntegrator = getIntegrator(range)
|
val integrator: GaussIntegrator = getIntegrator(range)
|
||||||
@ -28,7 +29,7 @@ public class CMGaussRuleIntegrator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getIntegrator(range: ClosedRange<Double>): GaussIntegrator {
|
private fun getIntegrator(range: ClosedRange<Float64>): GaussIntegrator {
|
||||||
return when (type) {
|
return when (type) {
|
||||||
GaussRule.LEGENDRE -> factory.legendre(
|
GaussRule.LEGENDRE -> factory.legendre(
|
||||||
numpoints,
|
numpoints,
|
||||||
@ -77,7 +78,7 @@ public class CMGaussRuleIntegrator(
|
|||||||
private val factory: GaussIntegratorFactory = GaussIntegratorFactory()
|
private val factory: GaussIntegratorFactory = GaussIntegratorFactory()
|
||||||
|
|
||||||
public fun integrate(
|
public fun integrate(
|
||||||
range: ClosedRange<Double>,
|
range: ClosedRange<Float64>,
|
||||||
numPoints: Int = 100,
|
numPoints: Int = 100,
|
||||||
type: GaussRule = GaussRule.LEGENDRE,
|
type: GaussRule = GaussRule.LEGENDRE,
|
||||||
function: (Double) -> Double,
|
function: (Double) -> Double,
|
||||||
|
@ -10,6 +10,7 @@ import org.apache.commons.math3.analysis.integration.SimpsonIntegrator
|
|||||||
import space.kscience.attributes.Attributes
|
import space.kscience.attributes.Attributes
|
||||||
import space.kscience.kmath.UnstableKMathAPI
|
import space.kscience.kmath.UnstableKMathAPI
|
||||||
import space.kscience.kmath.integration.*
|
import space.kscience.kmath.integration.*
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import org.apache.commons.math3.analysis.integration.UnivariateIntegrator as CMUnivariateIntegrator
|
import org.apache.commons.math3.analysis.integration.UnivariateIntegrator as CMUnivariateIntegrator
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -17,10 +18,10 @@ import org.apache.commons.math3.analysis.integration.UnivariateIntegrator as CMU
|
|||||||
*/
|
*/
|
||||||
public class CMIntegrator(
|
public class CMIntegrator(
|
||||||
private val defaultMaxCalls: Int = 200,
|
private val defaultMaxCalls: Int = 200,
|
||||||
public val integratorBuilder: (Integrand<Double>) -> CMUnivariateIntegrator,
|
public val integratorBuilder: (Integrand<Float64>) -> CMUnivariateIntegrator,
|
||||||
) : UnivariateIntegrator<Double> {
|
) : UnivariateIntegrator<Float64> {
|
||||||
|
|
||||||
override fun integrate(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> {
|
override fun integrate(integrand: UnivariateIntegrand<Float64>): UnivariateIntegrand<Float64> {
|
||||||
val integrator = integratorBuilder(integrand)
|
val integrator = integratorBuilder(integrand)
|
||||||
val maxCalls = integrand[IntegrandMaxCalls] ?: defaultMaxCalls
|
val maxCalls = integrand[IntegrandMaxCalls] ?: defaultMaxCalls
|
||||||
val remainingCalls = maxCalls - integrand.calls
|
val remainingCalls = maxCalls - integrand.calls
|
||||||
|
@ -12,6 +12,7 @@ import space.kscience.attributes.SafeType
|
|||||||
import space.kscience.kmath.UnstableKMathAPI
|
import space.kscience.kmath.UnstableKMathAPI
|
||||||
import space.kscience.kmath.linear.*
|
import space.kscience.kmath.linear.*
|
||||||
import space.kscience.kmath.linear.CholeskyDecomposition
|
import space.kscience.kmath.linear.CholeskyDecomposition
|
||||||
|
import space.kscience.kmath.linear.EigenDecomposition
|
||||||
import space.kscience.kmath.linear.QRDecomposition
|
import space.kscience.kmath.linear.QRDecomposition
|
||||||
import space.kscience.kmath.nd.Structure2D
|
import space.kscience.kmath.nd.Structure2D
|
||||||
import space.kscience.kmath.nd.StructureAttribute
|
import space.kscience.kmath.nd.StructureAttribute
|
||||||
@ -22,7 +23,7 @@ import space.kscience.kmath.structures.Float64
|
|||||||
import space.kscience.kmath.structures.IntBuffer
|
import space.kscience.kmath.structures.IntBuffer
|
||||||
import space.kscience.kmath.structures.asBuffer
|
import space.kscience.kmath.structures.asBuffer
|
||||||
|
|
||||||
public class CMMatrix(public val origin: RealMatrix) : Matrix<Double> {
|
public class CMMatrix(public val origin: RealMatrix) : Matrix<Float64> {
|
||||||
|
|
||||||
override val rowNum: Int get() = origin.rowDimension
|
override val rowNum: Int get() = origin.rowDimension
|
||||||
override val colNum: Int get() = origin.columnDimension
|
override val colNum: Int get() = origin.columnDimension
|
||||||
@ -31,12 +32,12 @@ public class CMMatrix(public val origin: RealMatrix) : Matrix<Double> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JvmInline
|
@JvmInline
|
||||||
public value class CMVector(public val origin: RealVector) : Point<Double> {
|
public value class CMVector(public val origin: RealVector) : Point<Float64> {
|
||||||
override val size: Int get() = origin.dimension
|
override val size: Int get() = origin.dimension
|
||||||
|
|
||||||
override operator fun get(index: Int): Double = origin.getEntry(index)
|
override operator fun get(index: Int): Double = origin.getEntry(index)
|
||||||
|
|
||||||
override operator fun iterator(): Iterator<Double> = origin.toArray().iterator()
|
override operator fun iterator(): Iterator<Float64> = origin.toArray().iterator()
|
||||||
|
|
||||||
override fun toString(): String = Buffer.toString(this)
|
override fun toString(): String = Buffer.toString(this)
|
||||||
}
|
}
|
||||||
@ -46,7 +47,7 @@ public fun RealVector.toPoint(): CMVector = CMVector(this)
|
|||||||
public object CMLinearSpace : LinearSpace<Double, Float64Field> {
|
public object CMLinearSpace : LinearSpace<Double, Float64Field> {
|
||||||
override val elementAlgebra: Float64Field get() = Float64Field
|
override val elementAlgebra: Float64Field get() = Float64Field
|
||||||
|
|
||||||
override val type: SafeType<Double> get() = DoubleField.type
|
override val type: SafeType<Float64> get() = DoubleField.type
|
||||||
|
|
||||||
override fun buildMatrix(
|
override fun buildMatrix(
|
||||||
rows: Int,
|
rows: Int,
|
||||||
@ -58,7 +59,7 @@ public object CMLinearSpace : LinearSpace<Double, Float64Field> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
public fun Matrix<Double>.toCM(): CMMatrix = when (val matrix = origin) {
|
public fun Matrix<Float64>.toCM(): CMMatrix = when (val matrix = origin) {
|
||||||
is CMMatrix -> matrix
|
is CMMatrix -> matrix
|
||||||
else -> {
|
else -> {
|
||||||
//TODO add feature analysis
|
//TODO add feature analysis
|
||||||
@ -67,7 +68,7 @@ public object CMLinearSpace : LinearSpace<Double, Float64Field> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun Point<Double>.toCM(): CMVector = if (this is CMVector) this else {
|
public fun Point<Float64>.toCM(): CMVector = if (this is CMVector) this else {
|
||||||
val array = DoubleArray(size) { this[it] }
|
val array = DoubleArray(size) { this[it] }
|
||||||
ArrayRealVector(array).wrap()
|
ArrayRealVector(array).wrap()
|
||||||
}
|
}
|
||||||
@ -75,40 +76,40 @@ public object CMLinearSpace : LinearSpace<Double, Float64Field> {
|
|||||||
internal fun RealMatrix.wrap(): CMMatrix = CMMatrix(this)
|
internal fun RealMatrix.wrap(): CMMatrix = CMMatrix(this)
|
||||||
internal fun RealVector.wrap(): CMVector = CMVector(this)
|
internal fun RealVector.wrap(): CMVector = CMVector(this)
|
||||||
|
|
||||||
override fun buildVector(size: Int, initializer: Float64Field.(Int) -> Double): Point<Double> =
|
override fun buildVector(size: Int, initializer: Float64Field.(Int) -> Double): Point<Float64> =
|
||||||
ArrayRealVector(DoubleArray(size) { Float64Field.initializer(it) }).wrap()
|
ArrayRealVector(DoubleArray(size) { Float64Field.initializer(it) }).wrap()
|
||||||
|
|
||||||
override fun Matrix<Double>.plus(other: Matrix<Double>): CMMatrix =
|
override fun Matrix<Float64>.plus(other: Matrix<Float64>): CMMatrix =
|
||||||
toCM().origin.add(other.toCM().origin).wrap()
|
toCM().origin.add(other.toCM().origin).wrap()
|
||||||
|
|
||||||
override fun Point<Double>.plus(other: Point<Double>): CMVector =
|
override fun Point<Float64>.plus(other: Point<Float64>): CMVector =
|
||||||
toCM().origin.add(other.toCM().origin).wrap()
|
toCM().origin.add(other.toCM().origin).wrap()
|
||||||
|
|
||||||
override fun Point<Double>.minus(other: Point<Double>): CMVector =
|
override fun Point<Float64>.minus(other: Point<Float64>): CMVector =
|
||||||
toCM().origin.subtract(other.toCM().origin).wrap()
|
toCM().origin.subtract(other.toCM().origin).wrap()
|
||||||
|
|
||||||
override fun Matrix<Double>.dot(other: Matrix<Double>): CMMatrix =
|
override fun Matrix<Float64>.dot(other: Matrix<Float64>): CMMatrix =
|
||||||
toCM().origin.multiply(other.toCM().origin).wrap()
|
toCM().origin.multiply(other.toCM().origin).wrap()
|
||||||
|
|
||||||
override fun Matrix<Double>.dot(vector: Point<Double>): CMVector =
|
override fun Matrix<Float64>.dot(vector: Point<Float64>): CMVector =
|
||||||
toCM().origin.preMultiply(vector.toCM().origin).wrap()
|
toCM().origin.preMultiply(vector.toCM().origin).wrap()
|
||||||
|
|
||||||
override operator fun Matrix<Double>.minus(other: Matrix<Double>): CMMatrix =
|
override operator fun Matrix<Float64>.minus(other: Matrix<Float64>): CMMatrix =
|
||||||
toCM().origin.subtract(other.toCM().origin).wrap()
|
toCM().origin.subtract(other.toCM().origin).wrap()
|
||||||
|
|
||||||
override operator fun Matrix<Double>.times(value: Double): CMMatrix =
|
override operator fun Matrix<Float64>.times(value: Double): CMMatrix =
|
||||||
toCM().origin.scalarMultiply(value).wrap()
|
toCM().origin.scalarMultiply(value).wrap()
|
||||||
|
|
||||||
override fun Double.times(m: Matrix<Double>): CMMatrix =
|
override fun Double.times(m: Matrix<Float64>): CMMatrix =
|
||||||
m * this
|
m * this
|
||||||
|
|
||||||
override fun Point<Double>.times(value: Double): CMVector =
|
override fun Point<Float64>.times(value: Double): CMVector =
|
||||||
toCM().origin.mapMultiply(value).wrap()
|
toCM().origin.mapMultiply(value).wrap()
|
||||||
|
|
||||||
override fun Double.times(v: Point<Double>): CMVector =
|
override fun Double.times(v: Point<Float64>): CMVector =
|
||||||
v * this
|
v * this
|
||||||
|
|
||||||
override fun <V, A : StructureAttribute<V>> computeAttribute(structure: Structure2D<Double>, attribute: A): V? {
|
override fun <V, A : StructureAttribute<V>> computeAttribute(structure: Structure2D<Float64>, attribute: A): V? {
|
||||||
|
|
||||||
val origin = structure.toCM().origin
|
val origin = structure.toCM().origin
|
||||||
|
|
||||||
@ -125,7 +126,7 @@ public object CMLinearSpace : LinearSpace<Double, Float64Field> {
|
|||||||
|
|
||||||
Cholesky -> object : CholeskyDecomposition<Float64> {
|
Cholesky -> object : CholeskyDecomposition<Float64> {
|
||||||
val cmCholesky by lazy { org.apache.commons.math3.linear.CholeskyDecomposition(origin) }
|
val cmCholesky by lazy { org.apache.commons.math3.linear.CholeskyDecomposition(origin) }
|
||||||
override val l: Matrix<Double> get() = cmCholesky.l.wrap()
|
override val l: Matrix<Float64> get() = cmCholesky.l.wrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
QR -> object : QRDecomposition<Float64> {
|
QR -> object : QRDecomposition<Float64> {
|
||||||
@ -144,6 +145,13 @@ public object CMLinearSpace : LinearSpace<Double, Float64Field> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EIG -> object : EigenDecomposition<Float64> {
|
||||||
|
val cmEigen by lazy { org.apache.commons.math3.linear.EigenDecomposition(origin) }
|
||||||
|
|
||||||
|
override val v: Matrix<Float64> get() = cmEigen.v.wrap()
|
||||||
|
override val d: Matrix<Float64> get() = cmEigen.d.wrap()
|
||||||
|
}
|
||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
@ -9,6 +9,7 @@ import org.apache.commons.math3.linear.*
|
|||||||
import space.kscience.kmath.linear.LinearSolver
|
import space.kscience.kmath.linear.LinearSolver
|
||||||
import space.kscience.kmath.linear.Matrix
|
import space.kscience.kmath.linear.Matrix
|
||||||
import space.kscience.kmath.linear.Point
|
import space.kscience.kmath.linear.Point
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
|
|
||||||
public enum class CMDecomposition {
|
public enum class CMDecomposition {
|
||||||
LUP,
|
LUP,
|
||||||
@ -19,7 +20,7 @@ public enum class CMDecomposition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun CMLinearSpace.solver(
|
private fun CMLinearSpace.solver(
|
||||||
a: Matrix<Double>,
|
a: Matrix<Float64>,
|
||||||
decomposition: CMDecomposition = CMDecomposition.LUP,
|
decomposition: CMDecomposition = CMDecomposition.LUP,
|
||||||
): DecompositionSolver = when (decomposition) {
|
): DecompositionSolver = when (decomposition) {
|
||||||
CMDecomposition.LUP -> LUDecomposition(a.toCM().origin).solver
|
CMDecomposition.LUP -> LUDecomposition(a.toCM().origin).solver
|
||||||
@ -30,31 +31,31 @@ private fun CMLinearSpace.solver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
public fun CMLinearSpace.solve(
|
public fun CMLinearSpace.solve(
|
||||||
a: Matrix<Double>,
|
a: Matrix<Float64>,
|
||||||
b: Matrix<Double>,
|
b: Matrix<Float64>,
|
||||||
decomposition: CMDecomposition = CMDecomposition.LUP,
|
decomposition: CMDecomposition = CMDecomposition.LUP,
|
||||||
): CMMatrix = solver(a, decomposition).solve(b.toCM().origin).wrap()
|
): CMMatrix = solver(a, decomposition).solve(b.toCM().origin).wrap()
|
||||||
|
|
||||||
public fun CMLinearSpace.solve(
|
public fun CMLinearSpace.solve(
|
||||||
a: Matrix<Double>,
|
a: Matrix<Float64>,
|
||||||
b: Point<Double>,
|
b: Point<Float64>,
|
||||||
decomposition: CMDecomposition = CMDecomposition.LUP,
|
decomposition: CMDecomposition = CMDecomposition.LUP,
|
||||||
): CMVector = solver(a, decomposition).solve(b.toCM().origin).toPoint()
|
): CMVector = solver(a, decomposition).solve(b.toCM().origin).toPoint()
|
||||||
|
|
||||||
public fun CMLinearSpace.inverse(
|
public fun CMLinearSpace.inverse(
|
||||||
a: Matrix<Double>,
|
a: Matrix<Float64>,
|
||||||
decomposition: CMDecomposition = CMDecomposition.LUP,
|
decomposition: CMDecomposition = CMDecomposition.LUP,
|
||||||
): CMMatrix = solver(a, decomposition).inverse.wrap()
|
): CMMatrix = solver(a, decomposition).inverse.wrap()
|
||||||
|
|
||||||
|
|
||||||
public fun CMLinearSpace.solver(decomposition: CMDecomposition): LinearSolver<Double> = object : LinearSolver<Double> {
|
public fun CMLinearSpace.solver(decomposition: CMDecomposition): LinearSolver<Float64> = object : LinearSolver<Float64> {
|
||||||
override fun solve(a: Matrix<Double>, b: Matrix<Double>): Matrix<Double> =
|
override fun solve(a: Matrix<Float64>, b: Matrix<Float64>): Matrix<Float64> =
|
||||||
solver(a, decomposition).solve(b.toCM().origin).wrap()
|
solver(a, decomposition).solve(b.toCM().origin).wrap()
|
||||||
|
|
||||||
override fun solve(a: Matrix<Double>, b: Point<Double>): Point<Double> =
|
override fun solve(a: Matrix<Float64>, b: Point<Float64>): Point<Float64> =
|
||||||
solver(a, decomposition).solve(b.toCM().origin).toPoint()
|
solver(a, decomposition).solve(b.toCM().origin).toPoint()
|
||||||
|
|
||||||
override fun inverse(matrix: Matrix<Double>): Matrix<Double> = solver(matrix, decomposition).inverse.wrap()
|
override fun inverse(matrix: Matrix<Float64>): Matrix<Float64> = solver(matrix, decomposition).inverse.wrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun CMLinearSpace.lupSolver(): LinearSolver<Double> = solver((CMDecomposition.LUP))
|
public fun CMLinearSpace.lupSolver(): LinearSolver<Float64> = solver((CMDecomposition.LUP))
|
@ -22,6 +22,7 @@ import space.kscience.kmath.expressions.SymbolIndexer
|
|||||||
import space.kscience.kmath.expressions.derivative
|
import space.kscience.kmath.expressions.derivative
|
||||||
import space.kscience.kmath.expressions.withSymbols
|
import space.kscience.kmath.expressions.withSymbols
|
||||||
import space.kscience.kmath.optimization.*
|
import space.kscience.kmath.optimization.*
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
@ -33,7 +34,7 @@ public object CMOptimizerEngine : OptimizationAttribute<() -> MultivariateOptimi
|
|||||||
/**
|
/**
|
||||||
* Specify a Commons-maths optimization engine
|
* Specify a Commons-maths optimization engine
|
||||||
*/
|
*/
|
||||||
public fun AttributesBuilder<FunctionOptimization<Double>>.cmEngine(optimizerBuilder: () -> MultivariateOptimizer) {
|
public fun AttributesBuilder<FunctionOptimization<Float64>>.cmEngine(optimizerBuilder: () -> MultivariateOptimizer) {
|
||||||
set(CMOptimizerEngine, optimizerBuilder)
|
set(CMOptimizerEngine, optimizerBuilder)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,18 +43,18 @@ public object CMOptimizerData : SetAttribute<SymbolIndexer.() -> OptimizationDat
|
|||||||
/**
|
/**
|
||||||
* Specify Commons-maths optimization data.
|
* Specify Commons-maths optimization data.
|
||||||
*/
|
*/
|
||||||
public fun AttributesBuilder<FunctionOptimization<Double>>.cmOptimizationData(data: SymbolIndexer.() -> OptimizationData) {
|
public fun AttributesBuilder<FunctionOptimization<Float64>>.cmOptimizationData(data: SymbolIndexer.() -> OptimizationData) {
|
||||||
CMOptimizerData add data
|
CMOptimizerData add data
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun AttributesBuilder<FunctionOptimization<Double>>.simplexSteps(vararg steps: Pair<Symbol, Double>) {
|
public fun AttributesBuilder<FunctionOptimization<Float64>>.simplexSteps(vararg steps: Pair<Symbol, Double>) {
|
||||||
//TODO use convergence checker from features
|
//TODO use convergence checker from features
|
||||||
cmEngine { SimplexOptimizer(CMOptimizer.defaultConvergenceChecker) }
|
cmEngine { SimplexOptimizer(CMOptimizer.defaultConvergenceChecker) }
|
||||||
cmOptimizationData { NelderMeadSimplex(mapOf(*steps).toDoubleArray()) }
|
cmOptimizationData { NelderMeadSimplex(mapOf(*steps).toDoubleArray()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
public object CMOptimizer : Optimizer<Double, FunctionOptimization<Double>> {
|
public object CMOptimizer : Optimizer<Double, FunctionOptimization<Float64>> {
|
||||||
|
|
||||||
public const val DEFAULT_RELATIVE_TOLERANCE: Double = 1e-4
|
public const val DEFAULT_RELATIVE_TOLERANCE: Double = 1e-4
|
||||||
public const val DEFAULT_ABSOLUTE_TOLERANCE: Double = 1e-4
|
public const val DEFAULT_ABSOLUTE_TOLERANCE: Double = 1e-4
|
||||||
@ -67,12 +68,12 @@ public object CMOptimizer : Optimizer<Double, FunctionOptimization<Double>> {
|
|||||||
|
|
||||||
|
|
||||||
override suspend fun optimize(
|
override suspend fun optimize(
|
||||||
problem: FunctionOptimization<Double>,
|
problem: FunctionOptimization<Float64>,
|
||||||
): FunctionOptimization<Double> {
|
): FunctionOptimization<Float64> {
|
||||||
val startPoint = problem.startPoint
|
val startPoint = problem.startPoint
|
||||||
|
|
||||||
val parameters = problem.attributes[OptimizationParameters]
|
val parameters = problem.attributes[OptimizationParameters]
|
||||||
?: problem.attributes[OptimizationStartPoint<Double>()]?.keys
|
?: problem.attributes[OptimizationStartPoint<Float64>()]?.keys
|
||||||
?: startPoint.keys
|
?: startPoint.keys
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ public fun Flow<Buffer<Complex>>.fft(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JvmName("realFFT")
|
@JvmName("realFFT")
|
||||||
public fun Flow<Buffer<Double>>.fft(
|
public fun Flow<Buffer<Float64>>.fft(
|
||||||
normalization: DftNormalization = DftNormalization.STANDARD,
|
normalization: DftNormalization = DftNormalization.STANDARD,
|
||||||
direction: TransformType = TransformType.FORWARD,
|
direction: TransformType = TransformType.FORWARD,
|
||||||
): Flow<Buffer<Complex>> {
|
): Flow<Buffer<Complex>> {
|
||||||
@ -89,7 +89,7 @@ public fun Flow<Buffer<Double>>.fft(
|
|||||||
* Process a continuous flow of real numbers in FFT splitting it in chunks of [bufferSize].
|
* Process a continuous flow of real numbers in FFT splitting it in chunks of [bufferSize].
|
||||||
*/
|
*/
|
||||||
@JvmName("realFFT")
|
@JvmName("realFFT")
|
||||||
public fun Flow<Double>.fft(
|
public fun Flow<Float64>.fft(
|
||||||
bufferSize: Int = Int.MAX_VALUE,
|
bufferSize: Int = Int.MAX_VALUE,
|
||||||
normalization: DftNormalization = DftNormalization.STANDARD,
|
normalization: DftNormalization = DftNormalization.STANDARD,
|
||||||
direction: TransformType = TransformType.FORWARD,
|
direction: TransformType = TransformType.FORWARD,
|
||||||
@ -99,4 +99,4 @@ public fun Flow<Double>.fft(
|
|||||||
* Map a complex flow into real flow by taking real part of each number
|
* Map a complex flow into real flow by taking real part of each number
|
||||||
*/
|
*/
|
||||||
@FlowPreview
|
@FlowPreview
|
||||||
public fun Flow<Complex>.real(): Flow<Double> = map { it.re }
|
public fun Flow<Complex>.real(): Flow<Float64> = map { it.re }
|
||||||
|
@ -18,6 +18,7 @@ import space.kscience.kmath.operations.Float64Field
|
|||||||
import space.kscience.kmath.optimization.*
|
import space.kscience.kmath.optimization.*
|
||||||
import space.kscience.kmath.random.RandomGenerator
|
import space.kscience.kmath.random.RandomGenerator
|
||||||
import space.kscience.kmath.stat.chiSquaredExpression
|
import space.kscience.kmath.stat.chiSquaredExpression
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.Float64Buffer
|
import space.kscience.kmath.structures.Float64Buffer
|
||||||
import space.kscience.kmath.structures.asBuffer
|
import space.kscience.kmath.structures.asBuffer
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
@ -70,7 +71,7 @@ internal class OptimizeTest {
|
|||||||
bindSymbol(a) * arg.pow(2) + bindSymbol(b) * arg + cWithDefault
|
bindSymbol(a) * arg.pow(2) + bindSymbol(b) * arg + cWithDefault
|
||||||
}
|
}
|
||||||
|
|
||||||
val result: FunctionOptimization<Double> = chi2.optimizeWith(
|
val result: FunctionOptimization<Float64> = chi2.optimizeWith(
|
||||||
CMOptimizer,
|
CMOptimizer,
|
||||||
mapOf(a to 1.5, b to 0.9, c to 1.0),
|
mapOf(a to 1.5, b to 0.9, c to 1.0),
|
||||||
) {
|
) {
|
||||||
|
@ -11,6 +11,7 @@ import space.kscience.kmath.UnstableKMathAPI
|
|||||||
import space.kscience.kmath.memory.*
|
import space.kscience.kmath.memory.*
|
||||||
import space.kscience.kmath.operations.*
|
import space.kscience.kmath.operations.*
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.MutableBuffer
|
import space.kscience.kmath.structures.MutableBuffer
|
||||||
import space.kscience.kmath.structures.MutableBufferFactory
|
import space.kscience.kmath.structures.MutableBufferFactory
|
||||||
import kotlin.math.*
|
import kotlin.math.*
|
||||||
@ -28,7 +29,7 @@ public class Quaternion(
|
|||||||
public val x: Double,
|
public val x: Double,
|
||||||
public val y: Double,
|
public val y: Double,
|
||||||
public val z: Double,
|
public val z: Double,
|
||||||
) : Buffer<Double> {
|
) : Buffer<Float64> {
|
||||||
init {
|
init {
|
||||||
require(!w.isNaN()) { "w-component of quaternion is not-a-number" }
|
require(!w.isNaN()) { "w-component of quaternion is not-a-number" }
|
||||||
require(!x.isNaN()) { "x-component of quaternion is not-a-number" }
|
require(!x.isNaN()) { "x-component of quaternion is not-a-number" }
|
||||||
@ -51,7 +52,7 @@ public class Quaternion(
|
|||||||
else -> error("Index $index out of bounds [0,3]")
|
else -> error("Index $index out of bounds [0,3]")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun iterator(): Iterator<Double> = listOf(w, x, y, z).iterator()
|
override fun iterator(): Iterator<Float64> = listOf(w, x, y, z).iterator()
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
|
@ -7,6 +7,7 @@ package space.kscience.kmath.domains
|
|||||||
|
|
||||||
import space.kscience.kmath.UnstableKMathAPI
|
import space.kscience.kmath.UnstableKMathAPI
|
||||||
import space.kscience.kmath.linear.Point
|
import space.kscience.kmath.linear.Point
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
|
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public abstract class Domain1D<T : Comparable<T>>(public val range: ClosedRange<T>) : Domain<T> {
|
public abstract class Domain1D<T : Comparable<T>>(public val range: ClosedRange<T>) : Domain<T> {
|
||||||
@ -22,8 +23,8 @@ public abstract class Domain1D<T : Comparable<T>>(public val range: ClosedRange<
|
|||||||
|
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class DoubleDomain1D(
|
public class DoubleDomain1D(
|
||||||
@Suppress("CanBeParameter") public val doubleRange: ClosedFloatingPointRange<Double>,
|
@Suppress("CanBeParameter") public val doubleRange: ClosedFloatingPointRange<Float64>,
|
||||||
) : Domain1D<Double>(doubleRange), Float64Domain {
|
) : Domain1D<Float64>(doubleRange), Float64Domain {
|
||||||
override fun getLowerBound(num: Int): Double {
|
override fun getLowerBound(num: Int): Double {
|
||||||
require(num == 0)
|
require(num == 0)
|
||||||
return range.start
|
return range.start
|
||||||
@ -55,5 +56,5 @@ public class DoubleDomain1D(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public val Domain1D<Double>.center: Double
|
public val Domain1D<Float64>.center: Double
|
||||||
get() = (range.endInclusive + range.start) / 2
|
get() = (range.endInclusive + range.start) / 2
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
package space.kscience.kmath.domains
|
package space.kscience.kmath.domains
|
||||||
|
|
||||||
import space.kscience.kmath.UnstableKMathAPI
|
import space.kscience.kmath.UnstableKMathAPI
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* n-dimensional volume
|
* n-dimensional volume
|
||||||
@ -12,7 +13,7 @@ import space.kscience.kmath.UnstableKMathAPI
|
|||||||
* @author Alexander Nozik
|
* @author Alexander Nozik
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public interface Float64Domain : Domain<Double> {
|
public interface Float64Domain : Domain<Float64> {
|
||||||
/**
|
/**
|
||||||
* Global lower edge
|
* Global lower edge
|
||||||
* @param num axis number
|
* @param num axis number
|
||||||
|
@ -7,6 +7,7 @@ package space.kscience.kmath.domains
|
|||||||
import space.kscience.kmath.UnstableKMathAPI
|
import space.kscience.kmath.UnstableKMathAPI
|
||||||
import space.kscience.kmath.linear.Point
|
import space.kscience.kmath.linear.Point
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.Float64Buffer
|
import space.kscience.kmath.structures.Float64Buffer
|
||||||
import space.kscience.kmath.structures.indices
|
import space.kscience.kmath.structures.indices
|
||||||
|
|
||||||
@ -15,7 +16,7 @@ import space.kscience.kmath.structures.indices
|
|||||||
* and a [Buffer] of upper boundaries. Upper should be greater or equals than lower.
|
* and a [Buffer] of upper boundaries. Upper should be greater or equals than lower.
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class HyperSquareDomain(public val lower: Buffer<Double>, public val upper: Buffer<Double>) : Float64Domain {
|
public class HyperSquareDomain(public val lower: Buffer<Float64>, public val upper: Buffer<Float64>) : Float64Domain {
|
||||||
init {
|
init {
|
||||||
require(lower.size == upper.size) {
|
require(lower.size == upper.size) {
|
||||||
"Domain borders size mismatch. Lower borders size is ${lower.size}, but upper borders size is ${upper.size}."
|
"Domain borders size mismatch. Lower borders size is ${lower.size}, but upper borders size is ${upper.size}."
|
||||||
@ -29,7 +30,7 @@ public class HyperSquareDomain(public val lower: Buffer<Double>, public val uppe
|
|||||||
|
|
||||||
public val center: Float64Buffer get() = Float64Buffer(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 ->
|
override operator fun contains(point: Point<Float64>): Boolean = point.indices.all { i ->
|
||||||
point[i] in lower[i]..upper[i]
|
point[i] in lower[i]..upper[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,10 +6,11 @@ package space.kscience.kmath.domains
|
|||||||
|
|
||||||
import space.kscience.kmath.UnstableKMathAPI
|
import space.kscience.kmath.UnstableKMathAPI
|
||||||
import space.kscience.kmath.linear.Point
|
import space.kscience.kmath.linear.Point
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
|
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class UnconstrainedDomain(override val dimension: Int) : Float64Domain {
|
public class UnconstrainedDomain(override val dimension: Int) : Float64Domain {
|
||||||
override operator fun contains(point: Point<Double>): Boolean = true
|
override operator fun contains(point: Point<Float64>): Boolean = true
|
||||||
|
|
||||||
override fun getLowerBound(num: Int): Double = Double.NEGATIVE_INFINITY
|
override fun getLowerBound(num: Int): Double = Double.NEGATIVE_INFINITY
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import space.kscience.kmath.operations.Algebra
|
|||||||
import space.kscience.kmath.operations.DoubleField
|
import space.kscience.kmath.operations.DoubleField
|
||||||
import space.kscience.kmath.operations.IntRing
|
import space.kscience.kmath.operations.IntRing
|
||||||
import space.kscience.kmath.operations.LongRing
|
import space.kscience.kmath.operations.LongRing
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import kotlin.jvm.JvmName
|
import kotlin.jvm.JvmName
|
||||||
import kotlin.properties.ReadOnlyProperty
|
import kotlin.properties.ReadOnlyProperty
|
||||||
|
|
||||||
@ -47,9 +48,9 @@ public inline fun <reified T> Expression(noinline block: (Map<Symbol, T>) -> T):
|
|||||||
* Specialization of [Expression] for [Double] allowing better performance because of using array.
|
* Specialization of [Expression] for [Double] allowing better performance because of using array.
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public interface DoubleExpression : Expression<Double> {
|
public interface DoubleExpression : Expression<Float64> {
|
||||||
|
|
||||||
override val type: SafeType<Double> get() = DoubleField.type
|
override val type: SafeType<Float64> get() = DoubleField.type
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The indexer of this expression's arguments that should be used to build array for [invoke].
|
* The indexer of this expression's arguments that should be used to build array for [invoke].
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
package space.kscience.kmath.expressions
|
package space.kscience.kmath.expressions
|
||||||
|
|
||||||
import space.kscience.kmath.operations.*
|
import space.kscience.kmath.operations.*
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.MutableBufferFactory
|
import space.kscience.kmath.structures.MutableBufferFactory
|
||||||
import kotlin.contracts.InvocationKind
|
import kotlin.contracts.InvocationKind
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
@ -197,5 +198,5 @@ public inline fun <T, A : ExtendedField<T>> A.expressionInExtendedField(
|
|||||||
): Expression<T> = FunctionalExpressionExtendedField(this).block()
|
): Expression<T> = FunctionalExpressionExtendedField(this).block()
|
||||||
|
|
||||||
public inline fun Float64Field.expression(
|
public inline fun Float64Field.expression(
|
||||||
block: FunctionalExpressionExtendedField<Double, Float64Field>.() -> Expression<Double>,
|
block: FunctionalExpressionExtendedField<Double, Float64Field>.() -> Expression<Float64>,
|
||||||
): Expression<Double> = FunctionalExpressionExtendedField(this).block()
|
): Expression<Float64> = FunctionalExpressionExtendedField(this).block()
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018-2024 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.linear
|
||||||
|
|
||||||
|
import space.kscience.attributes.PolymorphicAttribute
|
||||||
|
import space.kscience.attributes.safeTypeOf
|
||||||
|
|
||||||
|
public interface EigenDecomposition<T> {
|
||||||
|
/**
|
||||||
|
* Eigenvector matrix.
|
||||||
|
*/
|
||||||
|
public val v: Matrix<T>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A diagonal matrix of eigenvalues. Must have [IsDiagonal]
|
||||||
|
*/
|
||||||
|
public val d: Matrix<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EigenDecompositionAttribute<T> :
|
||||||
|
PolymorphicAttribute<EigenDecomposition<T>>(safeTypeOf()),
|
||||||
|
MatrixAttribute<EigenDecomposition<T>>
|
||||||
|
|
||||||
|
public val <T> MatrixScope<T>.EIG: EigenDecompositionAttribute<T>
|
||||||
|
get() = EigenDecompositionAttribute()
|
@ -6,12 +6,19 @@
|
|||||||
package space.kscience.kmath.linear
|
package space.kscience.kmath.linear
|
||||||
|
|
||||||
import space.kscience.kmath.PerformancePitfall
|
import space.kscience.kmath.PerformancePitfall
|
||||||
import space.kscience.kmath.nd.*
|
import space.kscience.kmath.nd.Floa64FieldOpsND
|
||||||
|
import space.kscience.kmath.nd.ShapeND
|
||||||
|
import space.kscience.kmath.nd.as2D
|
||||||
|
import space.kscience.kmath.nd.asND
|
||||||
import space.kscience.kmath.operations.Float64BufferOps
|
import space.kscience.kmath.operations.Float64BufferOps
|
||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.Float64Buffer
|
import space.kscience.kmath.structures.Float64Buffer
|
||||||
|
import kotlin.collections.component1
|
||||||
|
import kotlin.collections.component2
|
||||||
|
import kotlin.collections.map
|
||||||
|
|
||||||
public object Float64LinearSpace : LinearSpace<Double, Float64Field> {
|
public object Float64LinearSpace : LinearSpace<Double, Float64Field> {
|
||||||
|
|
||||||
@ -21,36 +28,36 @@ public object Float64LinearSpace : LinearSpace<Double, Float64Field> {
|
|||||||
rows: Int,
|
rows: Int,
|
||||||
columns: Int,
|
columns: Int,
|
||||||
initializer: Float64Field.(i: Int, j: Int) -> Double,
|
initializer: Float64Field.(i: Int, j: Int) -> Double,
|
||||||
): Matrix<Double> = Floa64FieldOpsND.structureND(ShapeND(rows, columns)) { (i, j) ->
|
): Matrix<Float64> = Floa64FieldOpsND.structureND(ShapeND(rows, columns)) { (i, j) ->
|
||||||
Float64Field.initializer(i, j)
|
Float64Field.initializer(i, j)
|
||||||
}.as2D()
|
}.as2D()
|
||||||
|
|
||||||
override fun buildVector(size: Int, initializer: Float64Field.(Int) -> Double): Float64Buffer =
|
override fun buildVector(size: Int, initializer: Float64Field.(Int) -> Double): Float64Buffer =
|
||||||
Float64Buffer(size) { Float64Field.initializer(it) }
|
Float64Buffer(size) { Float64Field.initializer(it) }
|
||||||
|
|
||||||
override fun Matrix<Double>.unaryMinus(): Matrix<Double> = Floa64FieldOpsND {
|
override fun Matrix<Float64>.unaryMinus(): Matrix<Float64> = Floa64FieldOpsND {
|
||||||
asND().map { -it }.as2D()
|
asND().map { -it }.as2D()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Matrix<Double>.plus(other: Matrix<Double>): Matrix<Double> = Floa64FieldOpsND {
|
override fun Matrix<Float64>.plus(other: Matrix<Float64>): Matrix<Float64> = Floa64FieldOpsND {
|
||||||
require(shape == other.shape) { "Shape mismatch on Matrix::plus. Expected $shape but found ${other.shape}" }
|
require(shape == other.shape) { "Shape mismatch on Matrix::plus. Expected $shape but found ${other.shape}" }
|
||||||
asND().plus(other.asND()).as2D()
|
asND().plus(other.asND()).as2D()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Matrix<Double>.minus(other: Matrix<Double>): Matrix<Double> = Floa64FieldOpsND {
|
override fun Matrix<Float64>.minus(other: Matrix<Float64>): Matrix<Float64> = Floa64FieldOpsND {
|
||||||
require(shape == other.shape) { "Shape mismatch on Matrix::minus. Expected $shape but found ${other.shape}" }
|
require(shape == other.shape) { "Shape mismatch on Matrix::minus. Expected $shape but found ${other.shape}" }
|
||||||
asND().minus(other.asND()).as2D()
|
asND().minus(other.asND()).as2D()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a continuous in-memory representation of this vector for better memory layout handling
|
// Create a continuous in-memory representation of this vector for better memory layout handling
|
||||||
private fun Buffer<Double>.linearize() = if (this is Float64Buffer) {
|
private fun Buffer<Float64>.linearize() = if (this is Float64Buffer) {
|
||||||
this.array
|
this.array
|
||||||
} else {
|
} else {
|
||||||
DoubleArray(size) { get(it) }
|
DoubleArray(size) { get(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(PerformancePitfall::class)
|
@OptIn(PerformancePitfall::class)
|
||||||
override fun Matrix<Double>.dot(other: Matrix<Double>): Matrix<Double> {
|
override fun Matrix<Float64>.dot(other: Matrix<Float64>): Matrix<Float64> {
|
||||||
require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" }
|
require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" }
|
||||||
val rows = this@dot.rows.map { it.linearize() }
|
val rows = this@dot.rows.map { it.linearize() }
|
||||||
val columns = other.columns.map { it.linearize() }
|
val columns = other.columns.map { it.linearize() }
|
||||||
@ -67,7 +74,7 @@ public object Float64LinearSpace : LinearSpace<Double, Float64Field> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(PerformancePitfall::class)
|
@OptIn(PerformancePitfall::class)
|
||||||
override fun Matrix<Double>.dot(vector: Point<Double>): Float64Buffer {
|
override fun Matrix<Float64>.dot(vector: Point<Float64>): Float64Buffer {
|
||||||
require(colNum == vector.size) { "Matrix dot vector operation dimension mismatch: ($rowNum, $colNum) x (${vector.size})" }
|
require(colNum == vector.size) { "Matrix dot vector operation dimension mismatch: ($rowNum, $colNum) x (${vector.size})" }
|
||||||
val rows = this@dot.rows.map { it.linearize() }
|
val rows = this@dot.rows.map { it.linearize() }
|
||||||
val indices = 0 until this.colNum
|
val indices = 0 until this.colNum
|
||||||
@ -82,27 +89,27 @@ public object Float64LinearSpace : LinearSpace<Double, Float64Field> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Matrix<Double>.times(value: Double): Matrix<Double> = Floa64FieldOpsND {
|
override fun Matrix<Float64>.times(value: Double): Matrix<Float64> = Floa64FieldOpsND {
|
||||||
asND().map { it * value }.as2D()
|
asND().map { it * value }.as2D()
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun Point<Double>.plus(other: Point<Double>): Float64Buffer = Float64BufferOps.run {
|
public override fun Point<Float64>.plus(other: Point<Float64>): Float64Buffer = Float64BufferOps.run {
|
||||||
this@plus + other
|
this@plus + other
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun Point<Double>.minus(other: Point<Double>): Float64Buffer = Float64BufferOps.run {
|
public override fun Point<Float64>.minus(other: Point<Float64>): Float64Buffer = Float64BufferOps.run {
|
||||||
this@minus - other
|
this@minus - other
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun Point<Double>.times(value: Double): Float64Buffer = Float64BufferOps.run {
|
public override fun Point<Float64>.times(value: Double): Float64Buffer = Float64BufferOps.run {
|
||||||
scale(this@times, value)
|
scale(this@times, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
public operator fun Point<Double>.div(value: Double): Float64Buffer = Float64BufferOps.run {
|
public operator fun Point<Float64>.div(value: Double): Float64Buffer = Float64BufferOps.run {
|
||||||
scale(this@div, 1.0 / value)
|
scale(this@div, 1.0 / value)
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun Double.times(v: Point<Double>): Float64Buffer = v * this
|
public override fun Double.times(v: Point<Float64>): Float64Buffer = v * this
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -163,9 +163,9 @@ public fun <T : Comparable<T>> Field<T>.lup(
|
|||||||
|
|
||||||
|
|
||||||
public fun Field<Float64>.lup(
|
public fun Field<Float64>.lup(
|
||||||
matrix: Matrix<Double>,
|
matrix: Matrix<Float64>,
|
||||||
singularityThreshold: Double = 1e-11,
|
singularityThreshold: Double = 1e-11,
|
||||||
): GenericLupDecomposition<Double> = lup(matrix) { it < singularityThreshold }
|
): GenericLupDecomposition<Float64> = lup(matrix) { it < singularityThreshold }
|
||||||
|
|
||||||
private fun <T> Field<T>.solve(
|
private fun <T> Field<T>.solve(
|
||||||
lup: LupDecomposition<T>,
|
lup: LupDecomposition<T>,
|
||||||
@ -235,5 +235,5 @@ public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lupSolver(
|
|||||||
override fun inverse(matrix: Matrix<T>): Matrix<T> = solve(matrix, one(matrix.rowNum, matrix.colNum))
|
override fun inverse(matrix: Matrix<T>): Matrix<T> = solve(matrix, one(matrix.rowNum, matrix.colNum))
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun LinearSpace<Double, Float64Field>.lupSolver(singularityThreshold: Double = 1e-11): LinearSolver<Double> =
|
public fun LinearSpace<Double, Float64Field>.lupSolver(singularityThreshold: Double = 1e-11): LinearSolver<Float64> =
|
||||||
lupSolver { it < singularityThreshold }
|
lupSolver { it < singularityThreshold }
|
||||||
|
@ -8,6 +8,7 @@ package space.kscience.kmath.misc
|
|||||||
import space.kscience.kmath.operations.Ring
|
import space.kscience.kmath.operations.Ring
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import kotlin.jvm.JvmName
|
import kotlin.jvm.JvmName
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,7 +48,7 @@ public fun <T> Iterable<T>.cumulativeSum(ring: Ring<T>): Iterable<T> =
|
|||||||
ring { cumulative(zero) { element: T, sum: T -> sum + element } }
|
ring { cumulative(zero) { element: T, sum: T -> sum + element } }
|
||||||
|
|
||||||
@JvmName("cumulativeSumOfDouble")
|
@JvmName("cumulativeSumOfDouble")
|
||||||
public fun Iterable<Double>.cumulativeSum(): Iterable<Double> = cumulative(0.0) { element, sum -> sum + element }
|
public fun Iterable<Float64>.cumulativeSum(): Iterable<Float64> = cumulative(0.0) { element, sum -> sum + element }
|
||||||
|
|
||||||
@JvmName("cumulativeSumOfInt")
|
@JvmName("cumulativeSumOfInt")
|
||||||
public fun Iterable<Int>.cumulativeSum(): Iterable<Int> = cumulative(0) { element, sum -> sum + element }
|
public fun Iterable<Int>.cumulativeSum(): Iterable<Int> = cumulative(0) { element, sum -> sum + element }
|
||||||
@ -59,7 +60,7 @@ public fun <T> Sequence<T>.cumulativeSum(ring: Ring<T>): Sequence<T> =
|
|||||||
ring { cumulative(zero) { element: T, sum: T -> sum + element } }
|
ring { cumulative(zero) { element: T, sum: T -> sum + element } }
|
||||||
|
|
||||||
@JvmName("cumulativeSumOfDouble")
|
@JvmName("cumulativeSumOfDouble")
|
||||||
public fun Sequence<Double>.cumulativeSum(): Sequence<Double> = cumulative(0.0) { element, sum -> sum + element }
|
public fun Sequence<Float64>.cumulativeSum(): Sequence<Float64> = cumulative(0.0) { element, sum -> sum + element }
|
||||||
|
|
||||||
@JvmName("cumulativeSumOfInt")
|
@JvmName("cumulativeSumOfInt")
|
||||||
public fun Sequence<Int>.cumulativeSum(): Sequence<Int> = cumulative(0) { element, sum -> sum + element }
|
public fun Sequence<Int>.cumulativeSum(): Sequence<Int> = cumulative(0) { element, sum -> sum + element }
|
||||||
@ -71,7 +72,7 @@ public fun <T> List<T>.cumulativeSum(group: Ring<T>): List<T> =
|
|||||||
group { cumulative(zero) { element: T, sum: T -> sum + element } }
|
group { cumulative(zero) { element: T, sum: T -> sum + element } }
|
||||||
|
|
||||||
@JvmName("cumulativeSumOfDouble")
|
@JvmName("cumulativeSumOfDouble")
|
||||||
public fun List<Double>.cumulativeSum(): List<Double> = cumulative(0.0) { element, sum -> sum + element }
|
public fun List<Float64>.cumulativeSum(): List<Float64> = cumulative(0.0) { element, sum -> sum + element }
|
||||||
|
|
||||||
@JvmName("cumulativeSumOfInt")
|
@JvmName("cumulativeSumOfInt")
|
||||||
public fun List<Int>.cumulativeSum(): List<Int> = cumulative(0) { element, sum -> sum + element }
|
public fun List<Int>.cumulativeSum(): List<Int> = cumulative(0) { element, sum -> sum + element }
|
||||||
|
@ -8,6 +8,7 @@ package space.kscience.kmath.nd
|
|||||||
import space.kscience.kmath.PerformancePitfall
|
import space.kscience.kmath.PerformancePitfall
|
||||||
import space.kscience.kmath.UnstableKMathAPI
|
import space.kscience.kmath.UnstableKMathAPI
|
||||||
import space.kscience.kmath.operations.*
|
import space.kscience.kmath.operations.*
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.Float64Buffer
|
import space.kscience.kmath.structures.Float64Buffer
|
||||||
import kotlin.contracts.InvocationKind
|
import kotlin.contracts.InvocationKind
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
@ -20,7 +21,7 @@ import kotlin.math.pow as kpow
|
|||||||
public class Float64BufferND(
|
public class Float64BufferND(
|
||||||
indexes: ShapeIndexer,
|
indexes: ShapeIndexer,
|
||||||
override val buffer: Float64Buffer,
|
override val buffer: Float64Buffer,
|
||||||
) : MutableBufferND<Double>(indexes, buffer), MutableStructureNDOfDouble {
|
) : MutableBufferND<Float64>(indexes, buffer), MutableStructureNDOfDouble {
|
||||||
|
|
||||||
override fun getDouble(index: IntArray): Double = buffer[indices.offset(index)]
|
override fun getDouble(index: IntArray): Double = buffer[indices.offset(index)]
|
||||||
|
|
||||||
@ -30,11 +31,11 @@ public class Float64BufferND(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public sealed class Floa64FieldOpsND : BufferedFieldOpsND<Double, Float64Field>(Float64Field.bufferAlgebra),
|
public sealed class Floa64FieldOpsND : BufferedFieldOpsND<Float64, Float64Field>(Float64Field.bufferAlgebra),
|
||||||
ScaleOperations<StructureND<Double>>, ExtendedFieldOps<StructureND<Double>> {
|
ScaleOperations<StructureND<Float64>>, ExtendedFieldOps<StructureND<Float64>> {
|
||||||
|
|
||||||
@OptIn(PerformancePitfall::class)
|
@OptIn(PerformancePitfall::class)
|
||||||
override fun StructureND<Double>.toBufferND(): Float64BufferND = when (this) {
|
override fun StructureND<Float64>.toBufferND(): Float64BufferND = when (this) {
|
||||||
is Float64BufferND -> this
|
is Float64BufferND -> this
|
||||||
else -> {
|
else -> {
|
||||||
val indexer = indexerBuilder(shape)
|
val indexer = indexerBuilder(shape)
|
||||||
@ -64,16 +65,16 @@ public sealed class Floa64FieldOpsND : BufferedFieldOpsND<Double, Float64Field>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(PerformancePitfall::class)
|
@OptIn(PerformancePitfall::class)
|
||||||
override fun StructureND<Double>.map(transform: Float64Field.(Double) -> Double): BufferND<Double> =
|
override fun StructureND<Float64>.map(transform: Float64Field.(Double) -> Double): BufferND<Float64> =
|
||||||
mapInline(toBufferND()) { Float64Field.transform(it) }
|
mapInline(toBufferND()) { Float64Field.transform(it) }
|
||||||
|
|
||||||
|
|
||||||
@OptIn(PerformancePitfall::class)
|
@OptIn(PerformancePitfall::class)
|
||||||
override fun zip(
|
override fun zip(
|
||||||
left: StructureND<Double>,
|
left: StructureND<Float64>,
|
||||||
right: StructureND<Double>,
|
right: StructureND<Float64>,
|
||||||
transform: Float64Field.(Double, Double) -> Double,
|
transform: Float64Field.(Double, Double) -> Double,
|
||||||
): BufferND<Double> = zipInline(left.toBufferND(), right.toBufferND()) { l, r -> Float64Field.transform(l, r) }
|
): BufferND<Float64> = zipInline(left.toBufferND(), right.toBufferND()) { l, r -> Float64Field.transform(l, r) }
|
||||||
|
|
||||||
override fun mutableStructureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): Float64BufferND {
|
override fun mutableStructureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): Float64BufferND {
|
||||||
val indexer = indexerBuilder(shape)
|
val indexer = indexerBuilder(shape)
|
||||||
@ -85,102 +86,102 @@ public sealed class Floa64FieldOpsND : BufferedFieldOpsND<Double, Float64Field>(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun add(left: StructureND<Double>, right: StructureND<Double>): Float64BufferND =
|
override fun add(left: StructureND<Float64>, right: StructureND<Float64>): Float64BufferND =
|
||||||
zipInline(left.toBufferND(), right.toBufferND()) { l, r -> l + r }
|
zipInline(left.toBufferND(), right.toBufferND()) { l, r -> l + r }
|
||||||
|
|
||||||
override fun multiply(left: StructureND<Double>, right: StructureND<Double>): Float64BufferND =
|
override fun multiply(left: StructureND<Float64>, right: StructureND<Float64>): Float64BufferND =
|
||||||
zipInline(left.toBufferND(), right.toBufferND()) { l, r -> l * r }
|
zipInline(left.toBufferND(), right.toBufferND()) { l, r -> l * r }
|
||||||
|
|
||||||
override fun StructureND<Double>.unaryMinus(): Float64BufferND = mapInline(toBufferND()) { -it }
|
override fun StructureND<Float64>.unaryMinus(): Float64BufferND = mapInline(toBufferND()) { -it }
|
||||||
|
|
||||||
override fun StructureND<Double>.div(arg: StructureND<Double>): Float64BufferND =
|
override fun StructureND<Float64>.div(arg: StructureND<Float64>): Float64BufferND =
|
||||||
zipInline(toBufferND(), arg.toBufferND()) { l, r -> l / r }
|
zipInline(toBufferND(), arg.toBufferND()) { l, r -> l / r }
|
||||||
|
|
||||||
override fun divide(left: StructureND<Double>, right: StructureND<Double>): Float64BufferND =
|
override fun divide(left: StructureND<Float64>, right: StructureND<Float64>): Float64BufferND =
|
||||||
zipInline(left.toBufferND(), right.toBufferND()) { l: Double, r: Double -> l / r }
|
zipInline(left.toBufferND(), right.toBufferND()) { l: Double, r: Double -> l / r }
|
||||||
|
|
||||||
override fun StructureND<Double>.div(arg: Double): Float64BufferND =
|
override fun StructureND<Float64>.div(arg: Double): Float64BufferND =
|
||||||
mapInline(toBufferND()) { it / arg }
|
mapInline(toBufferND()) { it / arg }
|
||||||
|
|
||||||
override fun Double.div(arg: StructureND<Double>): Float64BufferND =
|
override fun Double.div(arg: StructureND<Float64>): Float64BufferND =
|
||||||
mapInline(arg.toBufferND()) { this / it }
|
mapInline(arg.toBufferND()) { this / it }
|
||||||
|
|
||||||
override fun StructureND<Double>.unaryPlus(): Float64BufferND = toBufferND()
|
override fun StructureND<Float64>.unaryPlus(): Float64BufferND = toBufferND()
|
||||||
|
|
||||||
override fun StructureND<Double>.plus(arg: StructureND<Double>): Float64BufferND =
|
override fun StructureND<Float64>.plus(arg: StructureND<Float64>): Float64BufferND =
|
||||||
zipInline(toBufferND(), arg.toBufferND()) { l: Double, r: Double -> l + r }
|
zipInline(toBufferND(), arg.toBufferND()) { l: Double, r: Double -> l + r }
|
||||||
|
|
||||||
override fun StructureND<Double>.minus(arg: StructureND<Double>): Float64BufferND =
|
override fun StructureND<Float64>.minus(arg: StructureND<Float64>): Float64BufferND =
|
||||||
zipInline(toBufferND(), arg.toBufferND()) { l: Double, r: Double -> l - r }
|
zipInline(toBufferND(), arg.toBufferND()) { l: Double, r: Double -> l - r }
|
||||||
|
|
||||||
override fun StructureND<Double>.times(arg: StructureND<Double>): Float64BufferND =
|
override fun StructureND<Float64>.times(arg: StructureND<Float64>): Float64BufferND =
|
||||||
zipInline(toBufferND(), arg.toBufferND()) { l: Double, r: Double -> l * r }
|
zipInline(toBufferND(), arg.toBufferND()) { l: Double, r: Double -> l * r }
|
||||||
|
|
||||||
override fun StructureND<Double>.times(k: Number): Float64BufferND =
|
override fun StructureND<Float64>.times(k: Number): Float64BufferND =
|
||||||
mapInline(toBufferND()) { it * k.toDouble() }
|
mapInline(toBufferND()) { it * k.toDouble() }
|
||||||
|
|
||||||
override fun StructureND<Double>.div(k: Number): Float64BufferND =
|
override fun StructureND<Float64>.div(k: Number): Float64BufferND =
|
||||||
mapInline(toBufferND()) { it / k.toDouble() }
|
mapInline(toBufferND()) { it / k.toDouble() }
|
||||||
|
|
||||||
override fun Number.times(arg: StructureND<Double>): Float64BufferND = arg * this
|
override fun Number.times(arg: StructureND<Float64>): Float64BufferND = arg * this
|
||||||
|
|
||||||
override fun StructureND<Double>.plus(arg: Double): Float64BufferND = mapInline(toBufferND()) { it + arg }
|
override fun StructureND<Float64>.plus(arg: Double): Float64BufferND = mapInline(toBufferND()) { it + arg }
|
||||||
|
|
||||||
override fun StructureND<Double>.minus(arg: Double): StructureND<Double> = mapInline(toBufferND()) { it - arg }
|
override fun StructureND<Float64>.minus(arg: Double): StructureND<Float64> = mapInline(toBufferND()) { it - arg }
|
||||||
|
|
||||||
override fun Double.plus(arg: StructureND<Double>): StructureND<Double> = arg + this
|
override fun Double.plus(arg: StructureND<Float64>): StructureND<Float64> = arg + this
|
||||||
|
|
||||||
override fun Double.minus(arg: StructureND<Double>): StructureND<Double> = mapInline(arg.toBufferND()) { this - it }
|
override fun Double.minus(arg: StructureND<Float64>): StructureND<Float64> = mapInline(arg.toBufferND()) { this - it }
|
||||||
|
|
||||||
override fun scale(a: StructureND<Double>, value: Double): Float64BufferND =
|
override fun scale(a: StructureND<Float64>, value: Double): Float64BufferND =
|
||||||
mapInline(a.toBufferND()) { it * value }
|
mapInline(a.toBufferND()) { it * value }
|
||||||
|
|
||||||
override fun exp(arg: StructureND<Double>): Float64BufferND =
|
override fun exp(arg: StructureND<Float64>): Float64BufferND =
|
||||||
mapInline(arg.toBufferND()) { kotlin.math.exp(it) }
|
mapInline(arg.toBufferND()) { kotlin.math.exp(it) }
|
||||||
|
|
||||||
override fun ln(arg: StructureND<Double>): Float64BufferND =
|
override fun ln(arg: StructureND<Float64>): Float64BufferND =
|
||||||
mapInline(arg.toBufferND()) { kotlin.math.ln(it) }
|
mapInline(arg.toBufferND()) { kotlin.math.ln(it) }
|
||||||
|
|
||||||
override fun sin(arg: StructureND<Double>): Float64BufferND =
|
override fun sin(arg: StructureND<Float64>): Float64BufferND =
|
||||||
mapInline(arg.toBufferND()) { kotlin.math.sin(it) }
|
mapInline(arg.toBufferND()) { kotlin.math.sin(it) }
|
||||||
|
|
||||||
override fun cos(arg: StructureND<Double>): Float64BufferND =
|
override fun cos(arg: StructureND<Float64>): Float64BufferND =
|
||||||
mapInline(arg.toBufferND()) { kotlin.math.cos(it) }
|
mapInline(arg.toBufferND()) { kotlin.math.cos(it) }
|
||||||
|
|
||||||
override fun tan(arg: StructureND<Double>): Float64BufferND =
|
override fun tan(arg: StructureND<Float64>): Float64BufferND =
|
||||||
mapInline(arg.toBufferND()) { kotlin.math.tan(it) }
|
mapInline(arg.toBufferND()) { kotlin.math.tan(it) }
|
||||||
|
|
||||||
override fun asin(arg: StructureND<Double>): Float64BufferND =
|
override fun asin(arg: StructureND<Float64>): Float64BufferND =
|
||||||
mapInline(arg.toBufferND()) { kotlin.math.asin(it) }
|
mapInline(arg.toBufferND()) { kotlin.math.asin(it) }
|
||||||
|
|
||||||
override fun acos(arg: StructureND<Double>): Float64BufferND =
|
override fun acos(arg: StructureND<Float64>): Float64BufferND =
|
||||||
mapInline(arg.toBufferND()) { kotlin.math.acos(it) }
|
mapInline(arg.toBufferND()) { kotlin.math.acos(it) }
|
||||||
|
|
||||||
override fun atan(arg: StructureND<Double>): Float64BufferND =
|
override fun atan(arg: StructureND<Float64>): Float64BufferND =
|
||||||
mapInline(arg.toBufferND()) { kotlin.math.atan(it) }
|
mapInline(arg.toBufferND()) { kotlin.math.atan(it) }
|
||||||
|
|
||||||
override fun sinh(arg: StructureND<Double>): Float64BufferND =
|
override fun sinh(arg: StructureND<Float64>): Float64BufferND =
|
||||||
mapInline(arg.toBufferND()) { kotlin.math.sinh(it) }
|
mapInline(arg.toBufferND()) { kotlin.math.sinh(it) }
|
||||||
|
|
||||||
override fun cosh(arg: StructureND<Double>): Float64BufferND =
|
override fun cosh(arg: StructureND<Float64>): Float64BufferND =
|
||||||
mapInline(arg.toBufferND()) { kotlin.math.cosh(it) }
|
mapInline(arg.toBufferND()) { kotlin.math.cosh(it) }
|
||||||
|
|
||||||
override fun tanh(arg: StructureND<Double>): Float64BufferND =
|
override fun tanh(arg: StructureND<Float64>): Float64BufferND =
|
||||||
mapInline(arg.toBufferND()) { kotlin.math.tanh(it) }
|
mapInline(arg.toBufferND()) { kotlin.math.tanh(it) }
|
||||||
|
|
||||||
override fun asinh(arg: StructureND<Double>): Float64BufferND =
|
override fun asinh(arg: StructureND<Float64>): Float64BufferND =
|
||||||
mapInline(arg.toBufferND()) { kotlin.math.asinh(it) }
|
mapInline(arg.toBufferND()) { kotlin.math.asinh(it) }
|
||||||
|
|
||||||
override fun acosh(arg: StructureND<Double>): Float64BufferND =
|
override fun acosh(arg: StructureND<Float64>): Float64BufferND =
|
||||||
mapInline(arg.toBufferND()) { kotlin.math.acosh(it) }
|
mapInline(arg.toBufferND()) { kotlin.math.acosh(it) }
|
||||||
|
|
||||||
override fun atanh(arg: StructureND<Double>): Float64BufferND =
|
override fun atanh(arg: StructureND<Float64>): Float64BufferND =
|
||||||
mapInline(arg.toBufferND()) { kotlin.math.atanh(it) }
|
mapInline(arg.toBufferND()) { kotlin.math.atanh(it) }
|
||||||
|
|
||||||
override fun power(
|
override fun power(
|
||||||
arg: StructureND<Double>,
|
arg: StructureND<Float64>,
|
||||||
pow: Number,
|
pow: Number,
|
||||||
): StructureND<Double> = if (pow is Int) {
|
): StructureND<Float64> = if (pow is Int) {
|
||||||
mapInline(arg.toBufferND()) { it.pow(pow) }
|
mapInline(arg.toBufferND()) { it.pow(pow) }
|
||||||
} else {
|
} else {
|
||||||
mapInline(arg.toBufferND()) { it.pow(pow.toDouble()) }
|
mapInline(arg.toBufferND()) { it.pow(pow.toDouble()) }
|
||||||
@ -191,18 +192,18 @@ public sealed class Floa64FieldOpsND : BufferedFieldOpsND<Double, Float64Field>(
|
|||||||
|
|
||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
public class Float64FieldND(override val shape: ShapeND) :
|
public class Float64FieldND(override val shape: ShapeND) :
|
||||||
Floa64FieldOpsND(), FieldND<Double, Float64Field>, NumbersAddOps<StructureND<Double>>,
|
Floa64FieldOpsND(), FieldND<Double, Float64Field>, NumbersAddOps<StructureND<Float64>>,
|
||||||
ExtendedField<StructureND<Double>> {
|
ExtendedField<StructureND<Float64>> {
|
||||||
|
|
||||||
override fun power(arg: StructureND<Double>, pow: UInt): Float64BufferND = mapInline(arg.toBufferND()) {
|
override fun power(arg: StructureND<Float64>, pow: UInt): Float64BufferND = mapInline(arg.toBufferND()) {
|
||||||
it.kpow(pow.toInt())
|
it.kpow(pow.toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun power(arg: StructureND<Double>, pow: Int): Float64BufferND = mapInline(arg.toBufferND()) {
|
override fun power(arg: StructureND<Float64>, pow: Int): Float64BufferND = mapInline(arg.toBufferND()) {
|
||||||
it.kpow(pow)
|
it.kpow(pow)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun power(arg: StructureND<Double>, pow: Number): Float64BufferND = if (pow.isInteger()) {
|
override fun power(arg: StructureND<Float64>, pow: Number): Float64BufferND = if (pow.isInteger()) {
|
||||||
power(arg, pow.toInt())
|
power(arg, pow.toInt())
|
||||||
} else {
|
} else {
|
||||||
val dpow = pow.toDouble()
|
val dpow = pow.toDouble()
|
||||||
@ -212,17 +213,17 @@ public class Float64FieldND(override val shape: ShapeND) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun sinh(arg: StructureND<Double>): Float64BufferND = super<Floa64FieldOpsND>.sinh(arg)
|
override fun sinh(arg: StructureND<Float64>): Float64BufferND = super<Floa64FieldOpsND>.sinh(arg)
|
||||||
|
|
||||||
override fun cosh(arg: StructureND<Double>): Float64BufferND = super<Floa64FieldOpsND>.cosh(arg)
|
override fun cosh(arg: StructureND<Float64>): Float64BufferND = super<Floa64FieldOpsND>.cosh(arg)
|
||||||
|
|
||||||
override fun tanh(arg: StructureND<Double>): Float64BufferND = super<Floa64FieldOpsND>.tan(arg)
|
override fun tanh(arg: StructureND<Float64>): Float64BufferND = super<Floa64FieldOpsND>.tan(arg)
|
||||||
|
|
||||||
override fun asinh(arg: StructureND<Double>): Float64BufferND = super<Floa64FieldOpsND>.asinh(arg)
|
override fun asinh(arg: StructureND<Float64>): Float64BufferND = super<Floa64FieldOpsND>.asinh(arg)
|
||||||
|
|
||||||
override fun acosh(arg: StructureND<Double>): Float64BufferND = super<Floa64FieldOpsND>.acosh(arg)
|
override fun acosh(arg: StructureND<Float64>): Float64BufferND = super<Floa64FieldOpsND>.acosh(arg)
|
||||||
|
|
||||||
override fun atanh(arg: StructureND<Double>): Float64BufferND = super<Floa64FieldOpsND>.atanh(arg)
|
override fun atanh(arg: StructureND<Float64>): Float64BufferND = super<Floa64FieldOpsND>.atanh(arg)
|
||||||
|
|
||||||
override fun number(value: Number): Float64BufferND {
|
override fun number(value: Number): Float64BufferND {
|
||||||
val d = value.toDouble() // minimize conversions
|
val d = value.toDouble() // minimize conversions
|
||||||
|
@ -14,6 +14,7 @@ import space.kscience.kmath.linear.LinearSpace
|
|||||||
import space.kscience.kmath.operations.Ring
|
import space.kscience.kmath.operations.Ring
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
|
||||||
public interface StructureAttribute<T> : Attribute<T>
|
public interface StructureAttribute<T> : Attribute<T>
|
||||||
@ -76,8 +77,8 @@ public interface StructureND<out T> : AttributeContainer, WithShape {
|
|||||||
|
|
||||||
@PerformancePitfall
|
@PerformancePitfall
|
||||||
public fun contentEquals(
|
public fun contentEquals(
|
||||||
st1: StructureND<Double>,
|
st1: StructureND<Float64>,
|
||||||
st2: StructureND<Double>,
|
st2: StructureND<Float64>,
|
||||||
tolerance: Double = 1e-11,
|
tolerance: Double = 1e-11,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (st1 === st2) return true
|
if (st1 === st2) return true
|
||||||
@ -210,7 +211,7 @@ public fun <T : Comparable<T>> LinearSpace<T, Ring<T>>.contentEquals(
|
|||||||
@PerformancePitfall
|
@PerformancePitfall
|
||||||
public operator fun <T> StructureND<T>.get(vararg index: Int): T = get(index)
|
public operator fun <T> StructureND<T>.get(vararg index: Int): T = get(index)
|
||||||
|
|
||||||
public operator fun StructureND<Double>.get(vararg index: Int): Double = getDouble(index)
|
public operator fun StructureND<Float64>.get(vararg index: Int): Double = getDouble(index)
|
||||||
|
|
||||||
public operator fun StructureND<Int>.get(vararg index: Int): Int = getInt(index)
|
public operator fun StructureND<Int>.get(vararg index: Int): Int = getInt(index)
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ package space.kscience.kmath.nd
|
|||||||
|
|
||||||
import space.kscience.kmath.PerformancePitfall
|
import space.kscience.kmath.PerformancePitfall
|
||||||
import space.kscience.kmath.UnstableKMathAPI
|
import space.kscience.kmath.UnstableKMathAPI
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
|
|
||||||
public open class VirtualStructureND<T>(
|
public open class VirtualStructureND<T>(
|
||||||
override val shape: ShapeND,
|
override val shape: ShapeND,
|
||||||
@ -24,7 +25,7 @@ public open class VirtualStructureND<T>(
|
|||||||
public class VirtualDoubleStructureND(
|
public class VirtualDoubleStructureND(
|
||||||
shape: ShapeND,
|
shape: ShapeND,
|
||||||
producer: (IntArray) -> Double,
|
producer: (IntArray) -> Double,
|
||||||
) : VirtualStructureND<Double>(shape, producer)
|
) : VirtualStructureND<Float64>(shape, producer)
|
||||||
|
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public class VirtualIntStructureND(
|
public class VirtualIntStructureND(
|
||||||
|
@ -6,8 +6,9 @@
|
|||||||
package space.kscience.kmath.nd
|
package space.kscience.kmath.nd
|
||||||
|
|
||||||
import space.kscience.kmath.PerformancePitfall
|
import space.kscience.kmath.PerformancePitfall
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
|
|
||||||
public interface StructureNDOfDouble : StructureND<Double> {
|
public interface StructureNDOfDouble : StructureND<Float64> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Guaranteed non-blocking access to content
|
* Guaranteed non-blocking access to content
|
||||||
@ -19,10 +20,10 @@ public interface StructureNDOfDouble : StructureND<Double> {
|
|||||||
* Optimized method to access primitive without boxing if possible
|
* Optimized method to access primitive without boxing if possible
|
||||||
*/
|
*/
|
||||||
@OptIn(PerformancePitfall::class)
|
@OptIn(PerformancePitfall::class)
|
||||||
public fun StructureND<Double>.getDouble(index: IntArray): Double =
|
public fun StructureND<Float64>.getDouble(index: IntArray): Double =
|
||||||
if (this is StructureNDOfDouble) getDouble(index) else get(index)
|
if (this is StructureNDOfDouble) getDouble(index) else get(index)
|
||||||
|
|
||||||
public interface MutableStructureNDOfDouble : StructureNDOfDouble, MutableStructureND<Double> {
|
public interface MutableStructureNDOfDouble : StructureNDOfDouble, MutableStructureND<Float64> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Guaranteed non-blocking access to content
|
* Guaranteed non-blocking access to content
|
||||||
@ -31,7 +32,7 @@ public interface MutableStructureNDOfDouble : StructureNDOfDouble, MutableStruct
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(PerformancePitfall::class)
|
@OptIn(PerformancePitfall::class)
|
||||||
public fun MutableStructureND<Double>.getDouble(index: IntArray): Double =
|
public fun MutableStructureND<Float64>.getDouble(index: IntArray): Double =
|
||||||
if (this is StructureNDOfDouble) getDouble(index) else get(index)
|
if (this is StructureNDOfDouble) getDouble(index) else get(index)
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
package space.kscience.kmath.operations
|
package space.kscience.kmath.operations
|
||||||
|
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.MutableBuffer
|
import space.kscience.kmath.structures.MutableBuffer
|
||||||
import space.kscience.kmath.structures.MutableBufferFactory
|
import space.kscience.kmath.structures.MutableBufferFactory
|
||||||
|
|
||||||
@ -182,7 +183,7 @@ public fun <T, A : Field<T>> BufferFieldOps<T, A>.withSize(size: Int): BufferFie
|
|||||||
|
|
||||||
//Double buffer specialization
|
//Double buffer specialization
|
||||||
|
|
||||||
public fun BufferField<Double, *>.buffer(vararg elements: Number): Buffer<Double> {
|
public fun BufferField<Double, *>.buffer(vararg elements: Number): Buffer<Float64> {
|
||||||
require(elements.size == size) { "Expected $size elements but found ${elements.size}" }
|
require(elements.size == size) { "Expected $size elements but found ${elements.size}" }
|
||||||
return elementBufferFactory(size) { elements[it].toDouble() }
|
return elementBufferFactory(size) { elements[it].toDouble() }
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
package space.kscience.kmath.operations
|
package space.kscience.kmath.operations
|
||||||
|
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.Float64Buffer
|
import space.kscience.kmath.structures.Float64Buffer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -13,23 +14,23 @@ import space.kscience.kmath.structures.Float64Buffer
|
|||||||
*
|
*
|
||||||
* @property size the size of buffers to operate on.
|
* @property size the size of buffers to operate on.
|
||||||
*/
|
*/
|
||||||
public class Float64BufferField(public val size: Int) : ExtendedField<Buffer<Double>>, Float64BufferOps() {
|
public class Float64BufferField(public val size: Int) : ExtendedField<Buffer<Float64>>, Float64BufferOps() {
|
||||||
override val zero: Buffer<Double> by lazy { Float64Buffer(size) { 0.0 } }
|
override val zero: Buffer<Float64> by lazy { Float64Buffer(size) { 0.0 } }
|
||||||
override val one: Buffer<Double> by lazy { Float64Buffer(size) { 1.0 } }
|
override val one: Buffer<Float64> by lazy { Float64Buffer(size) { 1.0 } }
|
||||||
|
|
||||||
override fun sinh(arg: Buffer<Double>): Float64Buffer = super<Float64BufferOps>.sinh(arg)
|
override fun sinh(arg: Buffer<Float64>): Float64Buffer = super<Float64BufferOps>.sinh(arg)
|
||||||
|
|
||||||
override fun cosh(arg: Buffer<Double>): Float64Buffer = super<Float64BufferOps>.cosh(arg)
|
override fun cosh(arg: Buffer<Float64>): Float64Buffer = super<Float64BufferOps>.cosh(arg)
|
||||||
|
|
||||||
override fun tanh(arg: Buffer<Double>): Float64Buffer = super<Float64BufferOps>.tanh(arg)
|
override fun tanh(arg: Buffer<Float64>): Float64Buffer = super<Float64BufferOps>.tanh(arg)
|
||||||
|
|
||||||
override fun asinh(arg: Buffer<Double>): Float64Buffer = super<Float64BufferOps>.asinh(arg)
|
override fun asinh(arg: Buffer<Float64>): Float64Buffer = super<Float64BufferOps>.asinh(arg)
|
||||||
|
|
||||||
override fun acosh(arg: Buffer<Double>): Float64Buffer = super<Float64BufferOps>.acosh(arg)
|
override fun acosh(arg: Buffer<Float64>): Float64Buffer = super<Float64BufferOps>.acosh(arg)
|
||||||
|
|
||||||
override fun atanh(arg: Buffer<Double>): Float64Buffer = super<Float64BufferOps>.atanh(arg)
|
override fun atanh(arg: Buffer<Float64>): Float64Buffer = super<Float64BufferOps>.atanh(arg)
|
||||||
|
|
||||||
override fun power(arg: Buffer<Double>, pow: Number): Float64Buffer = if (pow.isInteger()) {
|
override fun power(arg: Buffer<Float64>, pow: Number): Float64Buffer = if (pow.isInteger()) {
|
||||||
arg.map { it.pow(pow.toInt()) }
|
arg.map { it.pow(pow.toInt()) }
|
||||||
} else {
|
} else {
|
||||||
arg.map {
|
arg.map {
|
||||||
@ -38,6 +39,6 @@ public class Float64BufferField(public val size: Int) : ExtendedField<Buffer<Dou
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun unaryOperationFunction(operation: String): (arg: Buffer<Double>) -> Buffer<Double> =
|
override fun unaryOperationFunction(operation: String): (arg: Buffer<Float64>) -> Buffer<Float64> =
|
||||||
super<ExtendedField>.unaryOperationFunction(operation)
|
super<ExtendedField>.unaryOperationFunction(operation)
|
||||||
}
|
}
|
@ -14,43 +14,43 @@ import kotlin.math.sqrt
|
|||||||
/**
|
/**
|
||||||
* [ExtendedFieldOps] over [Float64Buffer].
|
* [ExtendedFieldOps] over [Float64Buffer].
|
||||||
*/
|
*/
|
||||||
public abstract class Float64BufferOps : BufferAlgebra<Double, Float64Field>, ExtendedFieldOps<Buffer<Double>>,
|
public abstract class Float64BufferOps : BufferAlgebra<Double, Float64Field>, ExtendedFieldOps<Buffer<Float64>>,
|
||||||
Norm<Buffer<Double>, Double> {
|
Norm<Buffer<Float64>, Double> {
|
||||||
|
|
||||||
override val elementAlgebra: Float64Field get() = Float64Field
|
override val elementAlgebra: Float64Field get() = Float64Field
|
||||||
|
|
||||||
override val elementBufferFactory: MutableBufferFactory<Double> get() = elementAlgebra.bufferFactory
|
override val elementBufferFactory: MutableBufferFactory<Float64> get() = elementAlgebra.bufferFactory
|
||||||
|
|
||||||
@Suppress("OVERRIDE_BY_INLINE")
|
@Suppress("OVERRIDE_BY_INLINE")
|
||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
final override inline fun Buffer<Double>.map(block: Float64Field.(Double) -> Double): Float64Buffer =
|
final override inline fun Buffer<Float64>.map(block: Float64Field.(Double) -> Double): Float64Buffer =
|
||||||
DoubleArray(size) { Float64Field.block(getDouble(it)) }.asBuffer()
|
DoubleArray(size) { Float64Field.block(getDouble(it)) }.asBuffer()
|
||||||
|
|
||||||
|
|
||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
@Suppress("OVERRIDE_BY_INLINE")
|
@Suppress("OVERRIDE_BY_INLINE")
|
||||||
final override inline fun Buffer<Double>.mapIndexed(block: Float64Field.(index: Int, arg: Double) -> Double): Float64Buffer =
|
final override inline fun Buffer<Float64>.mapIndexed(block: Float64Field.(index: Int, arg: Double) -> Double): Float64Buffer =
|
||||||
Float64Buffer(size) { Float64Field.block(it, getDouble(it)) }
|
Float64Buffer(size) { Float64Field.block(it, getDouble(it)) }
|
||||||
|
|
||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
@Suppress("OVERRIDE_BY_INLINE")
|
@Suppress("OVERRIDE_BY_INLINE")
|
||||||
final override inline fun Buffer<Double>.zip(
|
final override inline fun Buffer<Float64>.zip(
|
||||||
other: Buffer<Double>,
|
other: Buffer<Float64>,
|
||||||
block: Float64Field.(left: Double, right: Double) -> Double,
|
block: Float64Field.(left: Double, right: Double) -> Double,
|
||||||
): Float64Buffer {
|
): Float64Buffer {
|
||||||
require(size == other.size) { "Incompatible buffer sizes. left: ${size}, right: ${other.size}" }
|
require(size == other.size) { "Incompatible buffer sizes. left: ${size}, right: ${other.size}" }
|
||||||
return Float64Buffer(size) { Float64Field.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> =
|
override fun unaryOperationFunction(operation: String): (arg: Buffer<Float64>) -> Buffer<Float64> =
|
||||||
super<ExtendedFieldOps>.unaryOperationFunction(operation)
|
super<ExtendedFieldOps>.unaryOperationFunction(operation)
|
||||||
|
|
||||||
override fun binaryOperationFunction(operation: String): (left: Buffer<Double>, right: Buffer<Double>) -> Buffer<Double> =
|
override fun binaryOperationFunction(operation: String): (left: Buffer<Float64>, right: Buffer<Float64>) -> Buffer<Float64> =
|
||||||
super<ExtendedFieldOps>.binaryOperationFunction(operation)
|
super<ExtendedFieldOps>.binaryOperationFunction(operation)
|
||||||
|
|
||||||
override fun Buffer<Double>.unaryMinus(): Float64Buffer = map { -it }
|
override fun Buffer<Float64>.unaryMinus(): Float64Buffer = map { -it }
|
||||||
|
|
||||||
override fun add(left: Buffer<Double>, right: Buffer<Double>): Float64Buffer {
|
override fun add(left: Buffer<Float64>, right: Buffer<Float64>): Float64Buffer {
|
||||||
require(right.size == left.size) {
|
require(right.size == left.size) {
|
||||||
"The size of the first buffer ${left.size} should be the same as for second one: ${right.size} "
|
"The size of the first buffer ${left.size} should be the same as for second one: ${right.size} "
|
||||||
}
|
}
|
||||||
@ -62,9 +62,9 @@ public abstract class Float64BufferOps : BufferAlgebra<Double, Float64Field>, Ex
|
|||||||
} else Float64Buffer(DoubleArray(left.size) { left[it] + right[it] })
|
} else Float64Buffer(DoubleArray(left.size) { left[it] + right[it] })
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Buffer<Double>.plus(arg: Buffer<Double>): Float64Buffer = add(this, arg)
|
override fun Buffer<Float64>.plus(arg: Buffer<Float64>): Float64Buffer = add(this, arg)
|
||||||
|
|
||||||
override fun Buffer<Double>.minus(arg: Buffer<Double>): Float64Buffer {
|
override fun Buffer<Float64>.minus(arg: Buffer<Float64>): Float64Buffer {
|
||||||
require(arg.size == this.size) {
|
require(arg.size == this.size) {
|
||||||
"The size of the first buffer ${this.size} should be the same as for second one: ${arg.size} "
|
"The size of the first buffer ${this.size} should be the same as for second one: ${arg.size} "
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ public abstract class Float64BufferOps : BufferAlgebra<Double, Float64Field>, Ex
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// override fun multiply(a: Buffer<Double>, k: Number): RealBuffer {
|
// override fun multiply(a: Buffer<Float64>, k: Number): RealBuffer {
|
||||||
// val kValue = k.toDouble()
|
// val kValue = k.toDouble()
|
||||||
//
|
//
|
||||||
// return if (a is RealBuffer) {
|
// return if (a is RealBuffer) {
|
||||||
@ -86,7 +86,7 @@ public abstract class Float64BufferOps : BufferAlgebra<Double, Float64Field>, Ex
|
|||||||
// } else RealBuffer(DoubleArray(a.size) { a[it] * kValue })
|
// } else RealBuffer(DoubleArray(a.size) { a[it] * kValue })
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// override fun divide(a: Buffer<Double>, k: Number): RealBuffer {
|
// override fun divide(a: Buffer<Float64>, k: Number): RealBuffer {
|
||||||
// val kValue = k.toDouble()
|
// val kValue = k.toDouble()
|
||||||
//
|
//
|
||||||
// return if (a is RealBuffer) {
|
// return if (a is RealBuffer) {
|
||||||
@ -96,7 +96,7 @@ public abstract class Float64BufferOps : BufferAlgebra<Double, Float64Field>, Ex
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
override fun multiply(left: Buffer<Double>, right: Buffer<Double>): Float64Buffer {
|
override fun multiply(left: Buffer<Float64>, right: Buffer<Float64>): Float64Buffer {
|
||||||
require(right.size == left.size) {
|
require(right.size == left.size) {
|
||||||
"The size of the first buffer ${left.size} should be the same as for second one: ${right.size} "
|
"The size of the first buffer ${left.size} should be the same as for second one: ${right.size} "
|
||||||
}
|
}
|
||||||
@ -108,7 +108,7 @@ public abstract class Float64BufferOps : BufferAlgebra<Double, Float64Field>, Ex
|
|||||||
} else Float64Buffer(DoubleArray(left.size) { left[it] * right[it] })
|
} else Float64Buffer(DoubleArray(left.size) { left[it] * right[it] })
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun divide(left: Buffer<Double>, right: Buffer<Double>): Float64Buffer {
|
override fun divide(left: Buffer<Float64>, right: Buffer<Float64>): Float64Buffer {
|
||||||
require(right.size == left.size) {
|
require(right.size == left.size) {
|
||||||
"The size of the first buffer ${left.size} should be the same as for second one: ${right.size} "
|
"The size of the first buffer ${left.size} should be the same as for second one: ${right.size} "
|
||||||
}
|
}
|
||||||
@ -120,39 +120,39 @@ public abstract class Float64BufferOps : BufferAlgebra<Double, Float64Field>, Ex
|
|||||||
} else Float64Buffer(DoubleArray(left.size) { left[it] / right[it] })
|
} else Float64Buffer(DoubleArray(left.size) { left[it] / right[it] })
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun sin(arg: Buffer<Double>): Float64Buffer = arg.map { sin(it) }
|
override fun sin(arg: Buffer<Float64>): Float64Buffer = arg.map { sin(it) }
|
||||||
|
|
||||||
override fun cos(arg: Buffer<Double>): Float64Buffer = arg.map { cos(it) }
|
override fun cos(arg: Buffer<Float64>): Float64Buffer = arg.map { cos(it) }
|
||||||
|
|
||||||
override fun tan(arg: Buffer<Double>): Float64Buffer = arg.map { tan(it) }
|
override fun tan(arg: Buffer<Float64>): Float64Buffer = arg.map { tan(it) }
|
||||||
|
|
||||||
override fun asin(arg: Buffer<Double>): Float64Buffer = arg.map { asin(it) }
|
override fun asin(arg: Buffer<Float64>): Float64Buffer = arg.map { asin(it) }
|
||||||
|
|
||||||
override fun acos(arg: Buffer<Double>): Float64Buffer = arg.map { acos(it) }
|
override fun acos(arg: Buffer<Float64>): Float64Buffer = arg.map { acos(it) }
|
||||||
|
|
||||||
override fun atan(arg: Buffer<Double>): Float64Buffer = arg.map { atan(it) }
|
override fun atan(arg: Buffer<Float64>): Float64Buffer = arg.map { atan(it) }
|
||||||
|
|
||||||
override fun sinh(arg: Buffer<Double>): Float64Buffer = arg.map { sinh(it) }
|
override fun sinh(arg: Buffer<Float64>): Float64Buffer = arg.map { sinh(it) }
|
||||||
|
|
||||||
override fun cosh(arg: Buffer<Double>): Float64Buffer = arg.map { cosh(it) }
|
override fun cosh(arg: Buffer<Float64>): Float64Buffer = arg.map { cosh(it) }
|
||||||
|
|
||||||
override fun tanh(arg: Buffer<Double>): Float64Buffer = arg.map { tanh(it) }
|
override fun tanh(arg: Buffer<Float64>): Float64Buffer = arg.map { tanh(it) }
|
||||||
|
|
||||||
override fun asinh(arg: Buffer<Double>): Float64Buffer = arg.map { asinh(it) }
|
override fun asinh(arg: Buffer<Float64>): Float64Buffer = arg.map { asinh(it) }
|
||||||
|
|
||||||
override fun acosh(arg: Buffer<Double>): Float64Buffer = arg.map { acosh(it) }
|
override fun acosh(arg: Buffer<Float64>): Float64Buffer = arg.map { acosh(it) }
|
||||||
|
|
||||||
override fun atanh(arg: Buffer<Double>): Float64Buffer = arg.map { atanh(it) }
|
override fun atanh(arg: Buffer<Float64>): Float64Buffer = arg.map { atanh(it) }
|
||||||
|
|
||||||
override fun exp(arg: Buffer<Double>): Float64Buffer = arg.map { exp(it) }
|
override fun exp(arg: Buffer<Float64>): Float64Buffer = arg.map { exp(it) }
|
||||||
|
|
||||||
override fun ln(arg: Buffer<Double>): Float64Buffer = arg.map { ln(it) }
|
override fun ln(arg: Buffer<Float64>): Float64Buffer = arg.map { ln(it) }
|
||||||
|
|
||||||
override fun norm(arg: Buffer<Double>): Double = Float64L2Norm.norm(arg)
|
override fun norm(arg: Buffer<Float64>): Double = Float64L2Norm.norm(arg)
|
||||||
|
|
||||||
override fun scale(a: Buffer<Double>, value: Double): Float64Buffer = a.map { it * value }
|
override fun scale(a: Buffer<Float64>, value: Double): Float64Buffer = a.map { it * value }
|
||||||
|
|
||||||
override fun power(arg: Buffer<Double>, pow: Number): Buffer<Double> = if (pow is Int) {
|
override fun power(arg: Buffer<Float64>, pow: Number): Buffer<Float64> = if (pow is Int) {
|
||||||
arg.map { it.pow(pow) }
|
arg.map { it.pow(pow) }
|
||||||
} else {
|
} else {
|
||||||
arg.map { it.pow(pow.toDouble()) }
|
arg.map { it.pow(pow.toDouble()) }
|
||||||
@ -161,11 +161,11 @@ public abstract class Float64BufferOps : BufferAlgebra<Double, Float64Field>, Ex
|
|||||||
public companion object : Float64BufferOps()
|
public companion object : Float64BufferOps()
|
||||||
}
|
}
|
||||||
|
|
||||||
public object Float64L2Norm : Norm<Point<Double>, Double> {
|
public object Float64L2Norm : Norm<Point<Float64>, Double> {
|
||||||
override fun norm(arg: Point<Double>): Double = sqrt(arg.fold(0.0) { acc: Double, d: Double -> acc + d.pow(2) })
|
override fun norm(arg: Point<Float64>): Double = sqrt(arg.fold(0.0) { acc: Double, d: Double -> acc + d.pow(2) })
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun Float64BufferOps.sum(buffer: Buffer<Double>): Double = buffer.reduce(Double::plus)
|
public fun Float64BufferOps.sum(buffer: Buffer<Float64>): Double = buffer.reduce(Double::plus)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sum of elements using given [conversion]
|
* Sum of elements using given [conversion]
|
||||||
@ -173,7 +173,7 @@ public fun Float64BufferOps.sum(buffer: Buffer<Double>): Double = buffer.reduce(
|
|||||||
public inline fun <T> Float64BufferOps.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) }
|
buffer.fold(0.0) { acc, value -> acc + conversion(value) }
|
||||||
|
|
||||||
public fun Float64BufferOps.average(buffer: Buffer<Double>): Double = sum(buffer) / buffer.size
|
public fun Float64BufferOps.average(buffer: Buffer<Float64>): Double = sum(buffer) / buffer.size
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Average of elements using given [conversion]
|
* Average of elements using given [conversion]
|
||||||
@ -181,14 +181,14 @@ public fun Float64BufferOps.average(buffer: Buffer<Double>): Double = sum(buffer
|
|||||||
public inline fun <T> Float64BufferOps.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
|
sumOf(buffer, conversion) / buffer.size
|
||||||
|
|
||||||
public fun Float64BufferOps.dispersion(buffer: Buffer<Double>): Double {
|
public fun Float64BufferOps.dispersion(buffer: Buffer<Float64>): Double {
|
||||||
val av = average(buffer)
|
val av = average(buffer)
|
||||||
return buffer.fold(0.0) { acc, value -> acc + (value - av).pow(2) } / buffer.size
|
return buffer.fold(0.0) { acc, value -> acc + (value - av).pow(2) } / buffer.size
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun Float64BufferOps.std(buffer: Buffer<Double>): Double = sqrt(dispersion(buffer))
|
public fun Float64BufferOps.std(buffer: Buffer<Float64>): Double = sqrt(dispersion(buffer))
|
||||||
|
|
||||||
public fun Float64BufferOps.covariance(x: Buffer<Double>, y: Buffer<Double>): Double {
|
public fun Float64BufferOps.covariance(x: Buffer<Float64>, y: Buffer<Float64>): Double {
|
||||||
require(x.size == y.size) { "Expected buffers of the same size, but x.size == ${x.size} and y.size == ${y.size}" }
|
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 xMean = average(x)
|
||||||
val yMean = average(y)
|
val yMean = average(y)
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
package space.kscience.kmath.operations
|
package space.kscience.kmath.operations
|
||||||
|
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.MutableBufferFactory
|
import space.kscience.kmath.structures.MutableBufferFactory
|
||||||
import kotlin.math.pow as kpow
|
import kotlin.math.pow as kpow
|
||||||
|
|
||||||
@ -66,8 +67,8 @@ public interface ExtendedField<T> : ExtendedFieldOps<T>, Field<T>, NumericAlgebr
|
|||||||
* A field for [Double] without boxing. Does not produce an appropriate field element.
|
* A field for [Double] without boxing. Does not produce an appropriate field element.
|
||||||
*/
|
*/
|
||||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
||||||
public object Float64Field : ExtendedField<Double>, Norm<Double, Double>, ScaleOperations<Double> {
|
public object Float64Field : ExtendedField<Float64>, Norm<Double, Double>, ScaleOperations<Float64> {
|
||||||
override val bufferFactory: MutableBufferFactory<Double> = MutableBufferFactory()
|
override val bufferFactory: MutableBufferFactory<Float64> = MutableBufferFactory()
|
||||||
|
|
||||||
override val zero: Double get() = 0.0
|
override val zero: Double get() = 0.0
|
||||||
override val one: Double get() = 1.0
|
override val one: Double get() = 1.0
|
||||||
|
@ -115,7 +115,7 @@ public fun <T> Buffer(
|
|||||||
size: Int,
|
size: Int,
|
||||||
initializer: (Int) -> T,
|
initializer: (Int) -> T,
|
||||||
): Buffer<T> = when (type.kType) {
|
): Buffer<T> = when (type.kType) {
|
||||||
typeOf<Double>() -> MutableBuffer.double(size) { initializer(it) as Double } as Buffer<T>
|
typeOf<Float64>() -> MutableBuffer.double(size) { initializer(it) as Double } as Buffer<T>
|
||||||
typeOf<Short>() -> MutableBuffer.short(size) { initializer(it) as Short } as Buffer<T>
|
typeOf<Short>() -> MutableBuffer.short(size) { initializer(it) as Short } as Buffer<T>
|
||||||
typeOf<Int>() -> MutableBuffer.int(size) { initializer(it) as Int } as Buffer<T>
|
typeOf<Int>() -> MutableBuffer.int(size) { initializer(it) as Int } as Buffer<T>
|
||||||
typeOf<Long>() -> MutableBuffer.long(size) { initializer(it) as Long } as Buffer<T>
|
typeOf<Long>() -> MutableBuffer.long(size) { initializer(it) as Long } as Buffer<T>
|
||||||
@ -134,7 +134,7 @@ public inline fun <reified T> Buffer(size: Int, initializer: (Int) -> T): Buffer
|
|||||||
//code duplication here because we want to inline initializers
|
//code duplication here because we want to inline initializers
|
||||||
val type = safeTypeOf<T>()
|
val type = safeTypeOf<T>()
|
||||||
return when (type.kType) {
|
return when (type.kType) {
|
||||||
typeOf<Double>() -> MutableBuffer.double(size) { initializer(it) as Double } as Buffer<T>
|
typeOf<Float64>() -> MutableBuffer.double(size) { initializer(it) as Double } as Buffer<T>
|
||||||
typeOf<Short>() -> MutableBuffer.short(size) { initializer(it) as Short } as Buffer<T>
|
typeOf<Short>() -> MutableBuffer.short(size) { initializer(it) as Short } as Buffer<T>
|
||||||
typeOf<Int>() -> MutableBuffer.int(size) { initializer(it) as Int } as Buffer<T>
|
typeOf<Int>() -> MutableBuffer.int(size) { initializer(it) as Int } as Buffer<T>
|
||||||
typeOf<Long>() -> MutableBuffer.long(size) { initializer(it) as Long } as Buffer<T>
|
typeOf<Long>() -> MutableBuffer.long(size) { initializer(it) as Long } as Buffer<T>
|
||||||
|
@ -14,7 +14,7 @@ import kotlin.jvm.JvmInline
|
|||||||
* @property array the underlying array.
|
* @property array the underlying array.
|
||||||
*/
|
*/
|
||||||
@JvmInline
|
@JvmInline
|
||||||
public value class Float64Buffer(public val array: DoubleArray) : PrimitiveBuffer<Double> {
|
public value class Float64Buffer(public val array: DoubleArray) : PrimitiveBuffer<Float64> {
|
||||||
|
|
||||||
override val size: Int get() = array.size
|
override val size: Int get() = array.size
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ public fun Float64Buffer(vararg doubles: Double): Float64Buffer = Float64Buffer(
|
|||||||
/**
|
/**
|
||||||
* Returns a new [DoubleArray] containing all the elements of this [Buffer].
|
* Returns a new [DoubleArray] containing all the elements of this [Buffer].
|
||||||
*/
|
*/
|
||||||
public fun Buffer<Double>.toDoubleArray(): DoubleArray = when (this) {
|
public fun Buffer<Float64>.toDoubleArray(): DoubleArray = when (this) {
|
||||||
is Float64Buffer -> array
|
is Float64Buffer -> array
|
||||||
else -> DoubleArray(size, ::get)
|
else -> DoubleArray(size, ::get)
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ public fun Buffer<Double>.toDoubleArray(): DoubleArray = when (this) {
|
|||||||
/**
|
/**
|
||||||
* Represent this buffer as [Float64Buffer]. 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>.toFloat64Buffer(): Float64Buffer = when (this) {
|
public fun Buffer<Float64>.toFloat64Buffer(): Float64Buffer = when (this) {
|
||||||
is Float64Buffer -> this
|
is Float64Buffer -> this
|
||||||
else -> DoubleArray(size, ::get).asBuffer()
|
else -> DoubleArray(size, ::get).asBuffer()
|
||||||
}
|
}
|
||||||
@ -79,5 +79,5 @@ public fun DoubleArray.asBuffer(): Float64Buffer = Float64Buffer(this)
|
|||||||
public fun interface Float64BufferTransform : BufferTransform<Double, Double> {
|
public fun interface Float64BufferTransform : BufferTransform<Double, Double> {
|
||||||
public fun transform(arg: Float64Buffer): Float64Buffer
|
public fun transform(arg: Float64Buffer): Float64Buffer
|
||||||
|
|
||||||
override fun transform(arg: Buffer<Double>): Float64Buffer = arg.toFloat64Buffer()
|
override fun transform(arg: Buffer<Float64>): Float64Buffer = arg.toFloat64Buffer()
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ public inline fun <T> MutableBuffer(
|
|||||||
typeOf<Int32>() -> MutableBuffer.int(size) { initializer(it) as Int32 } as MutableBuffer<T>
|
typeOf<Int32>() -> MutableBuffer.int(size) { initializer(it) as Int32 } as MutableBuffer<T>
|
||||||
typeOf<Int64>() -> MutableBuffer.long(size) { initializer(it) as Int64 } as MutableBuffer<T>
|
typeOf<Int64>() -> MutableBuffer.long(size) { initializer(it) as Int64 } as MutableBuffer<T>
|
||||||
typeOf<Float>() -> MutableBuffer.float(size) { initializer(it) as Float } as MutableBuffer<T>
|
typeOf<Float>() -> MutableBuffer.float(size) { initializer(it) as Float } as MutableBuffer<T>
|
||||||
typeOf<Double>() -> MutableBuffer.double(size) { initializer(it) as Double } as MutableBuffer<T>
|
typeOf<Float64>() -> MutableBuffer.double(size) { initializer(it) as Double } as MutableBuffer<T>
|
||||||
//TODO add unsigned types
|
//TODO add unsigned types
|
||||||
else -> MutableListBuffer(MutableList(size, initializer))
|
else -> MutableListBuffer(MutableList(size, initializer))
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import space.kscience.kmath.UnstableKMathAPI
|
|||||||
* Non-boxing access to primitive [Double]
|
* Non-boxing access to primitive [Double]
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public fun Buffer<Double>.getDouble(index: Int): Double = if (this is BufferView) {
|
public fun Buffer<Float64>.getDouble(index: Int): Double = if (this is BufferView) {
|
||||||
val originIndex = originIndex(index)
|
val originIndex = originIndex(index)
|
||||||
if (originIndex >= 0) {
|
if (originIndex >= 0) {
|
||||||
origin.getDouble(originIndex)
|
origin.getDouble(originIndex)
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
package space.kscience.kmath.expressions
|
package space.kscience.kmath.expressions
|
||||||
|
|
||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertFails
|
import kotlin.test.assertFails
|
||||||
@ -37,7 +38,7 @@ class ExpressionFieldTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun valueExpression() {
|
fun valueExpression() {
|
||||||
val expressionBuilder: FunctionalExpressionField<Double, *>.() -> Expression<Double> = {
|
val expressionBuilder: FunctionalExpressionField<Double, *>.() -> Expression<Float64> = {
|
||||||
val x by binding
|
val x by binding
|
||||||
x * x + 2 * x + one
|
x * x + 2 * x + one
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ package space.kscience.kmath.expressions
|
|||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
import space.kscience.kmath.operations.bindSymbol
|
import space.kscience.kmath.operations.bindSymbol
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.asBuffer
|
import space.kscience.kmath.structures.asBuffer
|
||||||
import kotlin.math.E
|
import kotlin.math.E
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
@ -21,18 +22,18 @@ internal class SimpleAutoDiffTest {
|
|||||||
|
|
||||||
fun dx(
|
fun dx(
|
||||||
xBinding: Pair<Symbol, Double>,
|
xBinding: Pair<Symbol, Double>,
|
||||||
body: SimpleAutoDiffField<Double, Float64Field>.(x: AutoDiffValue<Double>) -> AutoDiffValue<Double>,
|
body: SimpleAutoDiffField<Double, Float64Field>.(x: AutoDiffValue<Float64>) -> AutoDiffValue<Float64>,
|
||||||
): DerivationResult<Double> = Float64Field.simpleAutoDiff(xBinding) { body(bindSymbol(xBinding.first)) }
|
): DerivationResult<Float64> = Float64Field.simpleAutoDiff(xBinding) { body(bindSymbol(xBinding.first)) }
|
||||||
|
|
||||||
fun dxy(
|
fun dxy(
|
||||||
xBinding: Pair<Symbol, Double>,
|
xBinding: Pair<Symbol, Double>,
|
||||||
yBinding: Pair<Symbol, Double>,
|
yBinding: Pair<Symbol, Double>,
|
||||||
body: SimpleAutoDiffField<Double, Float64Field>.(x: AutoDiffValue<Double>, y: AutoDiffValue<Double>) -> AutoDiffValue<Double>,
|
body: SimpleAutoDiffField<Double, Float64Field>.(x: AutoDiffValue<Float64>, y: AutoDiffValue<Float64>) -> AutoDiffValue<Float64>,
|
||||||
): DerivationResult<Double> = Float64Field.simpleAutoDiff(xBinding, yBinding) {
|
): DerivationResult<Float64> = Float64Field.simpleAutoDiff(xBinding, yBinding) {
|
||||||
body(bindSymbol(xBinding.first), bindSymbol(yBinding.first))
|
body(bindSymbol(xBinding.first), bindSymbol(yBinding.first))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun diff(block: SimpleAutoDiffField<Double, Float64Field>.() -> AutoDiffValue<Double>): SimpleAutoDiffExpression<Double, Float64Field> {
|
fun diff(block: SimpleAutoDiffField<Double, Float64Field>.() -> AutoDiffValue<Float64>): SimpleAutoDiffExpression<Double, Float64Field> {
|
||||||
return SimpleAutoDiffExpression(Float64Field, block)
|
return SimpleAutoDiffExpression(Float64Field, block)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import space.kscience.kmath.UnstableKMathAPI
|
|||||||
import space.kscience.kmath.nd.StructureND
|
import space.kscience.kmath.nd.StructureND
|
||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
import space.kscience.kmath.operations.algebra
|
import space.kscience.kmath.operations.algebra
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
@ -38,7 +39,7 @@ class MatrixTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testMatrixExtension() = Double.algebra.linearSpace.run {
|
fun testMatrixExtension() = Double.algebra.linearSpace.run {
|
||||||
val transitionMatrix: Matrix<Double> = VirtualMatrix(6, 6) { row, col ->
|
val transitionMatrix: Matrix<Float64> = VirtualMatrix(6, 6) { row, col ->
|
||||||
when {
|
when {
|
||||||
col == 0 -> .50
|
col == 0 -> .50
|
||||||
row + 1 == col -> .50
|
row + 1 == col -> .50
|
||||||
@ -47,7 +48,7 @@ class MatrixTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
infix fun Matrix<Double>.pow(power: Int): Matrix<Double> {
|
infix fun Matrix<Float64>.pow(power: Int): Matrix<Float64> {
|
||||||
var res = this
|
var res = this
|
||||||
repeat(power - 1) {
|
repeat(power - 1) {
|
||||||
res = res dot this@pow
|
res = res dot this@pow
|
||||||
|
@ -11,6 +11,7 @@ import space.kscience.kmath.operations.Float64BufferOps
|
|||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.Float64Buffer
|
import space.kscience.kmath.structures.Float64Buffer
|
||||||
import space.kscience.kmath.structures.asBuffer
|
import space.kscience.kmath.structures.asBuffer
|
||||||
import java.util.stream.IntStream
|
import java.util.stream.IntStream
|
||||||
@ -25,7 +26,7 @@ public object Float64ParallelLinearSpace : LinearSpace<Double, Float64Field> {
|
|||||||
rows: Int,
|
rows: Int,
|
||||||
columns: Int,
|
columns: Int,
|
||||||
initializer: Float64Field.(i: Int, j: Int) -> Double,
|
initializer: Float64Field.(i: Int, j: Int) -> Double,
|
||||||
): Matrix<Double> {
|
): Matrix<Float64> {
|
||||||
val shape = ShapeND(rows, columns)
|
val shape = ShapeND(rows, columns)
|
||||||
val indexer = BufferAlgebraND.defaultIndexerBuilder(shape)
|
val indexer = BufferAlgebraND.defaultIndexerBuilder(shape)
|
||||||
|
|
||||||
@ -43,29 +44,29 @@ public object Float64ParallelLinearSpace : LinearSpace<Double, Float64Field> {
|
|||||||
override fun buildVector(size: Int, initializer: Float64Field.(Int) -> Double): Float64Buffer =
|
override fun buildVector(size: Int, initializer: Float64Field.(Int) -> Double): Float64Buffer =
|
||||||
IntStream.range(0, size).parallel().mapToDouble { Float64Field.initializer(it) }.toArray().asBuffer()
|
IntStream.range(0, size).parallel().mapToDouble { Float64Field.initializer(it) }.toArray().asBuffer()
|
||||||
|
|
||||||
override fun Matrix<Double>.unaryMinus(): Matrix<Double> = Floa64FieldOpsND {
|
override fun Matrix<Float64>.unaryMinus(): Matrix<Float64> = Floa64FieldOpsND {
|
||||||
asND().map { -it }.as2D()
|
asND().map { -it }.as2D()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Matrix<Double>.plus(other: Matrix<Double>): Matrix<Double> = Floa64FieldOpsND {
|
override fun Matrix<Float64>.plus(other: Matrix<Float64>): Matrix<Float64> = Floa64FieldOpsND {
|
||||||
require(shape == other.shape) { "Shape mismatch on Matrix::plus. Expected $shape but found ${other.shape}" }
|
require(shape == other.shape) { "Shape mismatch on Matrix::plus. Expected $shape but found ${other.shape}" }
|
||||||
asND().plus(other.asND()).as2D()
|
asND().plus(other.asND()).as2D()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Matrix<Double>.minus(other: Matrix<Double>): Matrix<Double> = Floa64FieldOpsND {
|
override fun Matrix<Float64>.minus(other: Matrix<Float64>): Matrix<Float64> = Floa64FieldOpsND {
|
||||||
require(shape == other.shape) { "Shape mismatch on Matrix::minus. Expected $shape but found ${other.shape}" }
|
require(shape == other.shape) { "Shape mismatch on Matrix::minus. Expected $shape but found ${other.shape}" }
|
||||||
asND().minus(other.asND()).as2D()
|
asND().minus(other.asND()).as2D()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a continuous in-memory representation of this vector for better memory layout handling
|
// Create a continuous in-memory representation of this vector for better memory layout handling
|
||||||
private fun Buffer<Double>.linearize() = if (this is Float64Buffer) {
|
private fun Buffer<Float64>.linearize() = if (this is Float64Buffer) {
|
||||||
this.array
|
this.array
|
||||||
} else {
|
} else {
|
||||||
DoubleArray(size) { get(it) }
|
DoubleArray(size) { get(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(PerformancePitfall::class)
|
@OptIn(PerformancePitfall::class)
|
||||||
override fun Matrix<Double>.dot(other: Matrix<Double>): Matrix<Double> {
|
override fun Matrix<Float64>.dot(other: Matrix<Float64>): Matrix<Float64> {
|
||||||
require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" }
|
require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" }
|
||||||
val rows = this@dot.rows.map { it.linearize() }
|
val rows = this@dot.rows.map { it.linearize() }
|
||||||
val columns = other.columns.map { it.linearize() }
|
val columns = other.columns.map { it.linearize() }
|
||||||
@ -82,7 +83,7 @@ public object Float64ParallelLinearSpace : LinearSpace<Double, Float64Field> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(PerformancePitfall::class)
|
@OptIn(PerformancePitfall::class)
|
||||||
override fun Matrix<Double>.dot(vector: Point<Double>): Float64Buffer {
|
override fun Matrix<Float64>.dot(vector: Point<Float64>): Float64Buffer {
|
||||||
require(colNum == vector.size) { "Matrix dot vector operation dimension mismatch: ($rowNum, $colNum) x (${vector.size})" }
|
require(colNum == vector.size) { "Matrix dot vector operation dimension mismatch: ($rowNum, $colNum) x (${vector.size})" }
|
||||||
val rows = this@dot.rows.map { it.linearize() }
|
val rows = this@dot.rows.map { it.linearize() }
|
||||||
val indices = 0 until this.colNum
|
val indices = 0 until this.colNum
|
||||||
@ -97,27 +98,27 @@ public object Float64ParallelLinearSpace : LinearSpace<Double, Float64Field> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Matrix<Double>.times(value: Double): Matrix<Double> = Floa64FieldOpsND {
|
override fun Matrix<Float64>.times(value: Double): Matrix<Float64> = Floa64FieldOpsND {
|
||||||
asND().map { it * value }.as2D()
|
asND().map { it * value }.as2D()
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun Point<Double>.plus(other: Point<Double>): Float64Buffer = Float64BufferOps.run {
|
public override fun Point<Float64>.plus(other: Point<Float64>): Float64Buffer = Float64BufferOps.run {
|
||||||
this@plus + other
|
this@plus + other
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun Point<Double>.minus(other: Point<Double>): Float64Buffer = Float64BufferOps.run {
|
public override fun Point<Float64>.minus(other: Point<Float64>): Float64Buffer = Float64BufferOps.run {
|
||||||
this@minus - other
|
this@minus - other
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun Point<Double>.times(value: Double): Float64Buffer = Float64BufferOps.run {
|
public override fun Point<Float64>.times(value: Double): Float64Buffer = Float64BufferOps.run {
|
||||||
scale(this@times, value)
|
scale(this@times, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
public operator fun Point<Double>.div(value: Double): Float64Buffer = Float64BufferOps.run {
|
public operator fun Point<Float64>.div(value: Double): Float64Buffer = Float64BufferOps.run {
|
||||||
scale(this@div, 1.0 / value)
|
scale(this@div, 1.0 / value)
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun Double.times(v: Point<Double>): Float64Buffer = v * this
|
public override fun Double.times(v: Point<Float64>): Float64Buffer = v * this
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ public fun <T> MutableBuffer.Companion.parallel(
|
|||||||
.asBuffer() as MutableBuffer<T>
|
.asBuffer() as MutableBuffer<T>
|
||||||
|
|
||||||
typeOf<Float>() -> Float32Buffer(size) { initializer(it) as Float } as MutableBuffer<T>
|
typeOf<Float>() -> Float32Buffer(size) { initializer(it) as Float } as MutableBuffer<T>
|
||||||
typeOf<Double>() -> IntStream.range(0, size).parallel().mapToDouble { initializer(it) as Float64 }.toArray()
|
typeOf<Float64>() -> IntStream.range(0, size).parallel().mapToDouble { initializer(it) as Float64 }.toArray()
|
||||||
.asBuffer() as MutableBuffer<T>
|
.asBuffer() as MutableBuffer<T>
|
||||||
//TODO add unsigned types
|
//TODO add unsigned types
|
||||||
else -> IntStream.range(0, size).parallel().mapToObj { initializer(it) }.collect(Collectors.toList<T>())
|
else -> IntStream.range(0, size).parallel().mapToObj { initializer(it) }.collect(Collectors.toList<T>())
|
||||||
|
@ -9,6 +9,7 @@ import space.kscience.kmath.PerformancePitfall
|
|||||||
import space.kscience.kmath.UnstableKMathAPI
|
import space.kscience.kmath.UnstableKMathAPI
|
||||||
import space.kscience.kmath.nd.StructureND
|
import space.kscience.kmath.nd.StructureND
|
||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
@ -37,7 +38,7 @@ class ParallelMatrixTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testMatrixExtension() = Float64Field.linearSpace.parallel {
|
fun testMatrixExtension() = Float64Field.linearSpace.parallel {
|
||||||
val transitionMatrix: Matrix<Double> = VirtualMatrix(6, 6) { row, col ->
|
val transitionMatrix: Matrix<Float64> = VirtualMatrix(6, 6) { row, col ->
|
||||||
when {
|
when {
|
||||||
col == 0 -> .50
|
col == 0 -> .50
|
||||||
row + 1 == col -> .50
|
row + 1 == col -> .50
|
||||||
@ -46,7 +47,7 @@ class ParallelMatrixTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
infix fun Matrix<Double>.pow(power: Int): Matrix<Double> {
|
infix fun Matrix<Float64>.pow(power: Int): Matrix<Float64> {
|
||||||
var res = this
|
var res = this
|
||||||
repeat(power - 1) {
|
repeat(power - 1) {
|
||||||
res = res dot this@pow
|
res = res dot this@pow
|
||||||
|
@ -5,12 +5,13 @@
|
|||||||
|
|
||||||
package space.kscience.kmath.chains
|
package space.kscience.kmath.chains
|
||||||
|
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.Float64Buffer
|
import space.kscience.kmath.structures.Float64Buffer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chunked, specialized chain for double values, which supports blocking [nextBlocking] operation
|
* Chunked, specialized chain for double values, which supports blocking [nextBlocking] operation
|
||||||
*/
|
*/
|
||||||
public interface BlockingDoubleChain : BlockingBufferChain<Double> {
|
public interface BlockingDoubleChain : BlockingBufferChain<Float64> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an [DoubleArray] chunk of [size] values of [next].
|
* Returns an [DoubleArray] chunk of [size] values of [next].
|
||||||
|
@ -17,6 +17,7 @@ import space.kscience.kmath.chains.BlockingDoubleChain
|
|||||||
import space.kscience.kmath.operations.Group
|
import space.kscience.kmath.operations.Group
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
import space.kscience.kmath.structures.BufferFactory
|
import space.kscience.kmath.structures.BufferFactory
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.Float64Buffer
|
import space.kscience.kmath.structures.Float64Buffer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,7 +57,7 @@ public fun <T> Flow<T>.chunked(bufferSize: Int, bufferFactory: BufferFactory<T>)
|
|||||||
/**
|
/**
|
||||||
* Specialized flow chunker for real buffer
|
* Specialized flow chunker for real buffer
|
||||||
*/
|
*/
|
||||||
public fun Flow<Double>.chunked(bufferSize: Int): Flow<Float64Buffer> = flow {
|
public fun Flow<Float64>.chunked(bufferSize: Int): Flow<Float64Buffer> = flow {
|
||||||
require(bufferSize > 0) { "Resulting chunk size must be more than zero" }
|
require(bufferSize > 0) { "Resulting chunk size must be more than zero" }
|
||||||
|
|
||||||
if (this@chunked is BlockingDoubleChain) {
|
if (this@chunked is BlockingDoubleChain) {
|
||||||
|
@ -5,8 +5,9 @@ plugins {
|
|||||||
val ejmlVerision = "0.43.1"
|
val ejmlVerision = "0.43.1"
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api("org.ejml:ejml-all:$ejmlVerision")
|
|
||||||
api(projects.kmathCore)
|
api(projects.kmathCore)
|
||||||
|
api(projects.kmathComplex)
|
||||||
|
api("org.ejml:ejml-all:$ejmlVerision")
|
||||||
}
|
}
|
||||||
|
|
||||||
readme {
|
readme {
|
||||||
|
@ -6,9 +6,13 @@
|
|||||||
package space.kscience.kmath.ejml
|
package space.kscience.kmath.ejml
|
||||||
|
|
||||||
import space.kscience.kmath.UnstableKMathAPI
|
import space.kscience.kmath.UnstableKMathAPI
|
||||||
import space.kscience.kmath.linear.*
|
import space.kscience.kmath.linear.Inverted
|
||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.linear.LinearSpace
|
||||||
|
import space.kscience.kmath.linear.Matrix
|
||||||
|
import space.kscience.kmath.linear.Point
|
||||||
|
import space.kscience.kmath.nd.Structure2D
|
||||||
import space.kscience.kmath.operations.Ring
|
import space.kscience.kmath.operations.Ring
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [LinearSpace] implementation specialized for a certain EJML type.
|
* [LinearSpace] implementation specialized for a certain EJML type.
|
||||||
@ -38,6 +42,6 @@ public abstract class EjmlLinearSpace<T : Any, out A : Ring<T>, out M : org.ejml
|
|||||||
public abstract override fun buildVector(size: Int, initializer: A.(Int) -> T): EjmlVector<T, M>
|
public abstract override fun buildVector(size: Int, initializer: A.(Int) -> T): EjmlVector<T, M>
|
||||||
|
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public fun EjmlMatrix<T, *>.inverted(): Matrix<Double> =
|
public fun Structure2D<T>.inverted(): Matrix<Float64> =
|
||||||
computeAttribute(this, Float64Field.linearSpace.Inverted)!!
|
computeAttribute(this, Inverted()) ?: error("Can't invert matrix")
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@ import org.ejml.dense.row.CommonOps_DDRM
|
|||||||
import org.ejml.dense.row.CommonOps_FDRM
|
import org.ejml.dense.row.CommonOps_FDRM
|
||||||
import org.ejml.dense.row.factory.DecompositionFactory_DDRM
|
import org.ejml.dense.row.factory.DecompositionFactory_DDRM
|
||||||
import org.ejml.dense.row.factory.DecompositionFactory_FDRM
|
import org.ejml.dense.row.factory.DecompositionFactory_FDRM
|
||||||
|
import org.ejml.interfaces.decomposition.EigenDecomposition_F32
|
||||||
|
import org.ejml.interfaces.decomposition.EigenDecomposition_F64
|
||||||
import org.ejml.sparse.FillReducing
|
import org.ejml.sparse.FillReducing
|
||||||
import org.ejml.sparse.csc.CommonOps_DSCC
|
import org.ejml.sparse.csc.CommonOps_DSCC
|
||||||
import org.ejml.sparse.csc.CommonOps_FSCC
|
import org.ejml.sparse.csc.CommonOps_FSCC
|
||||||
@ -19,6 +21,7 @@ import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC
|
|||||||
import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC
|
import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC
|
||||||
import space.kscience.attributes.SafeType
|
import space.kscience.attributes.SafeType
|
||||||
import space.kscience.attributes.safeTypeOf
|
import space.kscience.attributes.safeTypeOf
|
||||||
|
import space.kscience.kmath.complex.Complex
|
||||||
import space.kscience.kmath.linear.*
|
import space.kscience.kmath.linear.*
|
||||||
import space.kscience.kmath.linear.Matrix
|
import space.kscience.kmath.linear.Matrix
|
||||||
import space.kscience.kmath.nd.Structure2D
|
import space.kscience.kmath.nd.Structure2D
|
||||||
@ -27,9 +30,15 @@ import space.kscience.kmath.operations.Float32Field
|
|||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
import space.kscience.kmath.structures.Float32
|
import space.kscience.kmath.structures.Float32
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.IntBuffer
|
import space.kscience.kmath.structures.IntBuffer
|
||||||
import space.kscience.kmath.structures.asBuffer
|
import space.kscience.kmath.structures.asBuffer
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy EJML [Complex_F64] into KMath [Complex]
|
||||||
|
*/
|
||||||
|
public fun Complex_F64.toKMathComplex(): Complex = Complex(real, imaginary)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [EjmlVector] specialization for [Double].
|
* [EjmlVector] specialization for [Double].
|
||||||
*/
|
*/
|
||||||
@ -79,16 +88,16 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
*/
|
*/
|
||||||
override val elementAlgebra: Float64Field get() = Float64Field
|
override val elementAlgebra: Float64Field get() = Float64Field
|
||||||
|
|
||||||
override val type: SafeType<Double> get() = safeTypeOf()
|
override val type: SafeType<Float64> get() = safeTypeOf()
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixRMaj> = when {
|
override fun Matrix<Float64>.toEjml(): EjmlDoubleMatrix<DMatrixRMaj> = when {
|
||||||
this is EjmlDoubleMatrix<*> && origin is DMatrixRMaj -> this as EjmlDoubleMatrix<DMatrixRMaj>
|
this is EjmlDoubleMatrix<*> && origin is DMatrixRMaj -> this as EjmlDoubleMatrix<DMatrixRMaj>
|
||||||
else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) }
|
else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
override fun Point<Double>.toEjml(): EjmlDoubleVector<DMatrixRMaj> = when {
|
override fun Point<Float64>.toEjml(): EjmlDoubleVector<DMatrixRMaj> = when {
|
||||||
this is EjmlDoubleVector<*> && origin is DMatrixRMaj -> this as EjmlDoubleVector<DMatrixRMaj>
|
this is EjmlDoubleVector<*> && origin is DMatrixRMaj -> this as EjmlDoubleVector<DMatrixRMaj>
|
||||||
else -> EjmlDoubleVector(DMatrixRMaj(size, 1).also {
|
else -> EjmlDoubleVector(DMatrixRMaj(size, 1).also {
|
||||||
(0 until it.numRows).forEach { row -> it[row, 0] = get(row) }
|
(0 until it.numRows).forEach { row -> it[row, 0] = get(row) }
|
||||||
@ -115,21 +124,21 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
private fun <T : DMatrix> T.wrapMatrix() = EjmlDoubleMatrix(this)
|
private fun <T : DMatrix> T.wrapMatrix() = EjmlDoubleMatrix(this)
|
||||||
private fun <T : DMatrix> T.wrapVector() = EjmlDoubleVector(this)
|
private fun <T : DMatrix> T.wrapVector() = EjmlDoubleVector(this)
|
||||||
|
|
||||||
override fun Matrix<Double>.unaryMinus(): Matrix<Double> = this * elementAlgebra { -one }
|
override fun Matrix<Float64>.unaryMinus(): Matrix<Float64> = this * elementAlgebra { -one }
|
||||||
|
|
||||||
override fun Matrix<Double>.dot(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> {
|
override fun Matrix<Float64>.dot(other: Matrix<Float64>): EjmlDoubleMatrix<DMatrixRMaj> {
|
||||||
val out = DMatrixRMaj(1, 1)
|
val out = DMatrixRMaj(1, 1)
|
||||||
CommonOps_DDRM.mult(toEjml().origin, other.toEjml().origin, out)
|
CommonOps_DDRM.mult(toEjml().origin, other.toEjml().origin, out)
|
||||||
return out.wrapMatrix()
|
return out.wrapMatrix()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Matrix<Double>.dot(vector: Point<Double>): EjmlDoubleVector<DMatrixRMaj> {
|
override fun Matrix<Float64>.dot(vector: Point<Float64>): EjmlDoubleVector<DMatrixRMaj> {
|
||||||
val out = DMatrixRMaj(1, 1)
|
val out = DMatrixRMaj(1, 1)
|
||||||
CommonOps_DDRM.mult(toEjml().origin, vector.toEjml().origin, out)
|
CommonOps_DDRM.mult(toEjml().origin, vector.toEjml().origin, out)
|
||||||
return out.wrapVector()
|
return out.wrapVector()
|
||||||
}
|
}
|
||||||
|
|
||||||
override operator fun Matrix<Double>.minus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> {
|
override operator fun Matrix<Float64>.minus(other: Matrix<Float64>): EjmlDoubleMatrix<DMatrixRMaj> {
|
||||||
val out = DMatrixRMaj(1, 1)
|
val out = DMatrixRMaj(1, 1)
|
||||||
|
|
||||||
CommonOps_DDRM.add(
|
CommonOps_DDRM.add(
|
||||||
@ -143,19 +152,19 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
return out.wrapMatrix()
|
return out.wrapMatrix()
|
||||||
}
|
}
|
||||||
|
|
||||||
override operator fun Matrix<Double>.times(value: Double): EjmlDoubleMatrix<DMatrixRMaj> {
|
override operator fun Matrix<Float64>.times(value: Double): EjmlDoubleMatrix<DMatrixRMaj> {
|
||||||
val res = DMatrixRMaj(1, 1)
|
val res = DMatrixRMaj(1, 1)
|
||||||
CommonOps_DDRM.scale(value, toEjml().origin, res)
|
CommonOps_DDRM.scale(value, toEjml().origin, res)
|
||||||
return res.wrapMatrix()
|
return res.wrapMatrix()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Point<Double>.unaryMinus(): EjmlDoubleVector<DMatrixRMaj> {
|
override fun Point<Float64>.unaryMinus(): EjmlDoubleVector<DMatrixRMaj> {
|
||||||
val res = DMatrixRMaj(1, 1)
|
val res = DMatrixRMaj(1, 1)
|
||||||
CommonOps_DDRM.changeSign(toEjml().origin, res)
|
CommonOps_DDRM.changeSign(toEjml().origin, res)
|
||||||
return res.wrapVector()
|
return res.wrapVector()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> {
|
override fun Matrix<Float64>.plus(other: Matrix<Float64>): EjmlDoubleMatrix<DMatrixRMaj> {
|
||||||
val out = DMatrixRMaj(1, 1)
|
val out = DMatrixRMaj(1, 1)
|
||||||
|
|
||||||
CommonOps_DDRM.add(
|
CommonOps_DDRM.add(
|
||||||
@ -169,7 +178,7 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
return out.wrapMatrix()
|
return out.wrapMatrix()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Point<Double>.plus(other: Point<Double>): EjmlDoubleVector<DMatrixRMaj> {
|
override fun Point<Float64>.plus(other: Point<Float64>): EjmlDoubleVector<DMatrixRMaj> {
|
||||||
val out = DMatrixRMaj(1, 1)
|
val out = DMatrixRMaj(1, 1)
|
||||||
|
|
||||||
CommonOps_DDRM.add(
|
CommonOps_DDRM.add(
|
||||||
@ -183,7 +192,7 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
return out.wrapVector()
|
return out.wrapVector()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Point<Double>.minus(other: Point<Double>): EjmlDoubleVector<DMatrixRMaj> {
|
override fun Point<Float64>.minus(other: Point<Float64>): EjmlDoubleVector<DMatrixRMaj> {
|
||||||
val out = DMatrixRMaj(1, 1)
|
val out = DMatrixRMaj(1, 1)
|
||||||
|
|
||||||
CommonOps_DDRM.add(
|
CommonOps_DDRM.add(
|
||||||
@ -197,18 +206,18 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
return out.wrapVector()
|
return out.wrapVector()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Double.times(m: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> = m * this
|
override fun Double.times(m: Matrix<Float64>): EjmlDoubleMatrix<DMatrixRMaj> = m * this
|
||||||
|
|
||||||
override fun Point<Double>.times(value: Double): EjmlDoubleVector<DMatrixRMaj> {
|
override fun Point<Float64>.times(value: Double): EjmlDoubleVector<DMatrixRMaj> {
|
||||||
val res = DMatrixRMaj(1, 1)
|
val res = DMatrixRMaj(1, 1)
|
||||||
CommonOps_DDRM.scale(value, toEjml().origin, res)
|
CommonOps_DDRM.scale(value, toEjml().origin, res)
|
||||||
return res.wrapVector()
|
return res.wrapVector()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Double.times(v: Point<Double>): EjmlDoubleVector<DMatrixRMaj> = v * this
|
override fun Double.times(v: Point<Float64>): EjmlDoubleVector<DMatrixRMaj> = v * this
|
||||||
|
|
||||||
override fun <V, A : StructureAttribute<V>> computeAttribute(structure: Structure2D<Double>, attribute: A): V? {
|
override fun <V, A : StructureAttribute<V>> computeAttribute(structure: Structure2D<Float64>, attribute: A): V? {
|
||||||
val origin = structure.toEjml().origin
|
val origin: DMatrixRMaj = structure.toEjml().origin
|
||||||
|
|
||||||
val raw: Any? = when (attribute) {
|
val raw: Any? = when (attribute) {
|
||||||
Inverted -> {
|
Inverted -> {
|
||||||
@ -218,28 +227,28 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
}
|
}
|
||||||
|
|
||||||
Determinant -> CommonOps_DDRM.det(origin)
|
Determinant -> CommonOps_DDRM.det(origin)
|
||||||
SVD -> object : SingularValueDecomposition<Double> {
|
SVD -> object : SingularValueDecomposition<Float64> {
|
||||||
val ejmlSvd by lazy {
|
val ejmlSvd by lazy {
|
||||||
DecompositionFactory_DDRM
|
DecompositionFactory_DDRM
|
||||||
.svd(origin.numRows, origin.numCols, true, true, false)
|
.svd(origin.numRows, origin.numCols, true, true, false)
|
||||||
.apply { decompose(origin.copy()) }
|
.apply { decompose(origin.copy()) }
|
||||||
}
|
}
|
||||||
override val u: Matrix<Double> get() = ejmlSvd.getU(null, false).wrapMatrix()
|
override val u: Matrix<Float64> get() = ejmlSvd.getU(null, false).wrapMatrix()
|
||||||
|
|
||||||
override val s: Matrix<Double> get() = ejmlSvd.getW(null).wrapMatrix()
|
override val s: Matrix<Float64> get() = ejmlSvd.getW(null).wrapMatrix()
|
||||||
override val v: Matrix<Double> get() = ejmlSvd.getV(null, false).wrapMatrix()
|
override val v: Matrix<Float64> get() = ejmlSvd.getV(null, false).wrapMatrix()
|
||||||
override val singularValues: Point<Double> get() = ejmlSvd.singularValues.asBuffer()
|
override val singularValues: Point<Float64> get() = ejmlSvd.singularValues.asBuffer()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QR -> object : QRDecomposition<Double> {
|
QR -> object : QRDecomposition<Float64> {
|
||||||
val ejmlQr by lazy { DecompositionFactory_DDRM.qr().apply { decompose(origin.copy()) } }
|
val ejmlQr by lazy { DecompositionFactory_DDRM.qr().apply { decompose(origin.copy()) } }
|
||||||
override val q: Matrix<Double> get() = ejmlQr.getQ(null, false).wrapMatrix()
|
override val q: Matrix<Float64> get() = ejmlQr.getQ(null, false).wrapMatrix()
|
||||||
override val r: Matrix<Double> get() = ejmlQr.getR(null, false).wrapMatrix()
|
override val r: Matrix<Float64> get() = ejmlQr.getR(null, false).wrapMatrix()
|
||||||
}
|
}
|
||||||
|
|
||||||
Cholesky -> object : CholeskyDecomposition<Double> {
|
Cholesky -> object : CholeskyDecomposition<Float64> {
|
||||||
override val l: Matrix<Double> by lazy {
|
override val l: Matrix<Float64> by lazy {
|
||||||
val cholesky =
|
val cholesky =
|
||||||
DecompositionFactory_DDRM.chol(structure.rowNum, true).apply { decompose(origin.copy()) }
|
DecompositionFactory_DDRM.chol(structure.rowNum, true).apply { decompose(origin.copy()) }
|
||||||
|
|
||||||
@ -247,20 +256,49 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LUP -> object : LupDecomposition<Double> {
|
LUP -> object : LupDecomposition<Float64> {
|
||||||
private val lup by lazy {
|
private val lup by lazy {
|
||||||
DecompositionFactory_DDRM.lu(origin.numRows, origin.numCols).apply { decompose(origin.copy()) }
|
DecompositionFactory_DDRM.lu(origin.numRows, origin.numCols).apply { decompose(origin.copy()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override val l: Matrix<Double>
|
override val l: Matrix<Float64>
|
||||||
get() = lup.getLower(null).wrapMatrix().withAttribute(LowerTriangular)
|
get() = lup.getLower(null).wrapMatrix().withAttribute(LowerTriangular)
|
||||||
|
|
||||||
|
override val u: Matrix<Float64>
|
||||||
override val u: Matrix<Double>
|
|
||||||
get() = lup.getUpper(null).wrapMatrix().withAttribute(UpperTriangular)
|
get() = lup.getUpper(null).wrapMatrix().withAttribute(UpperTriangular)
|
||||||
|
|
||||||
override val pivot: IntBuffer get() = lup.getRowPivotV(null).asBuffer()
|
override val pivot: IntBuffer get() = lup.getRowPivotV(null).asBuffer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EIG -> {
|
||||||
|
check(origin.numCols == origin.numRows) { "Eigenvalue decomposition requires symmetric matrix" }
|
||||||
|
object : EigenDecomposition<Float64> {
|
||||||
|
val cmEigen: EigenDecomposition_F64<DMatrixRMaj> by lazy {
|
||||||
|
DecompositionFactory_DDRM.eig(origin.numRows, true).apply { decompose(origin) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override val v: Matrix<Float64> by lazy {
|
||||||
|
val eigenvectors = List(origin.numRows) { cmEigen.getEigenVector(it) }
|
||||||
|
buildMatrix(origin.numRows, origin.numCols) { row, column ->
|
||||||
|
eigenvectors[row][column]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val d: Matrix<Float64> by lazy {
|
||||||
|
val eigenvalues = List(origin.numRows) { cmEigen.getEigenvalue(it) }
|
||||||
|
|
||||||
|
buildMatrix(origin.numRows, origin.numCols) { row, column ->
|
||||||
|
when (row) {
|
||||||
|
column -> eigenvalues[row].real
|
||||||
|
column - 1 -> eigenvalues[row].imaginary
|
||||||
|
column + 1 -> -eigenvalues[row].imaginary
|
||||||
|
else -> 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,7 +313,7 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
* @param b n by p matrix.
|
* @param b n by p matrix.
|
||||||
* @return the solution for *x* that is n by p.
|
* @return the solution for *x* that is n by p.
|
||||||
*/
|
*/
|
||||||
public fun solve(a: Matrix<Double>, b: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> {
|
public fun solve(a: Matrix<Float64>, b: Matrix<Float64>): EjmlDoubleMatrix<DMatrixRMaj> {
|
||||||
val res = DMatrixRMaj(1, 1)
|
val res = DMatrixRMaj(1, 1)
|
||||||
CommonOps_DDRM.solve(DMatrixRMaj(a.toEjml().origin), DMatrixRMaj(b.toEjml().origin), res)
|
CommonOps_DDRM.solve(DMatrixRMaj(a.toEjml().origin), DMatrixRMaj(b.toEjml().origin), res)
|
||||||
return res.wrapMatrix()
|
return res.wrapMatrix()
|
||||||
@ -288,7 +326,7 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
* @param b n by p vector.
|
* @param b n by p vector.
|
||||||
* @return the solution for *x* that is n by p.
|
* @return the solution for *x* that is n by p.
|
||||||
*/
|
*/
|
||||||
public fun solve(a: Matrix<Double>, b: Point<Double>): EjmlDoubleVector<DMatrixRMaj> {
|
public fun solve(a: Matrix<Float64>, b: Point<Float64>): EjmlDoubleVector<DMatrixRMaj> {
|
||||||
val res = DMatrixRMaj(1, 1)
|
val res = DMatrixRMaj(1, 1)
|
||||||
CommonOps_DDRM.solve(DMatrixRMaj(a.toEjml().origin), DMatrixRMaj(b.toEjml().origin), res)
|
CommonOps_DDRM.solve(DMatrixRMaj(a.toEjml().origin), DMatrixRMaj(b.toEjml().origin), res)
|
||||||
return EjmlDoubleVector(res)
|
return EjmlDoubleVector(res)
|
||||||
@ -488,6 +526,35 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, Float32Field, FMatrix
|
|||||||
override val pivot: IntBuffer get() = lup.getRowPivotV(null).asBuffer()
|
override val pivot: IntBuffer get() = lup.getRowPivotV(null).asBuffer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EIG -> {
|
||||||
|
check(origin.numCols == origin.numRows) { "Eigenvalue decomposition requires symmetric matrix" }
|
||||||
|
object : EigenDecomposition<Float32> {
|
||||||
|
val cmEigen: EigenDecomposition_F32<FMatrixRMaj> by lazy {
|
||||||
|
DecompositionFactory_FDRM.eig(origin.numRows, true).apply { decompose(origin) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override val v by lazy {
|
||||||
|
val eigenvectors: List<FMatrixRMaj> = List(origin.numRows) { cmEigen.getEigenVector(it) }
|
||||||
|
buildMatrix(origin.numRows, origin.numCols) { row, column ->
|
||||||
|
eigenvectors[row][column]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val d: Matrix<Float32> by lazy {
|
||||||
|
val eigenvalues = List(origin.numRows) { cmEigen.getEigenvalue(it) }
|
||||||
|
|
||||||
|
buildMatrix(origin.numRows, origin.numCols) { row, column ->
|
||||||
|
when (row) {
|
||||||
|
column -> eigenvalues[row].real
|
||||||
|
column - 1 -> eigenvalues[row].imaginary
|
||||||
|
column + 1 -> -eigenvalues[row].imaginary
|
||||||
|
else -> 0f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -533,16 +600,16 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
*/
|
*/
|
||||||
override val elementAlgebra: Float64Field get() = Float64Field
|
override val elementAlgebra: Float64Field get() = Float64Field
|
||||||
|
|
||||||
override val type: SafeType<Double> get() = safeTypeOf()
|
override val type: SafeType<Float64> get() = safeTypeOf()
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixSparseCSC> = when {
|
override fun Matrix<Float64>.toEjml(): EjmlDoubleMatrix<DMatrixSparseCSC> = when {
|
||||||
this is EjmlDoubleMatrix<*> && origin is DMatrixSparseCSC -> this as EjmlDoubleMatrix<DMatrixSparseCSC>
|
this is EjmlDoubleMatrix<*> && origin is DMatrixSparseCSC -> this as EjmlDoubleMatrix<DMatrixSparseCSC>
|
||||||
else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) }
|
else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
override fun Point<Double>.toEjml(): EjmlDoubleVector<DMatrixSparseCSC> = when {
|
override fun Point<Float64>.toEjml(): EjmlDoubleVector<DMatrixSparseCSC> = when {
|
||||||
this is EjmlDoubleVector<*> && origin is DMatrixSparseCSC -> this as EjmlDoubleVector<DMatrixSparseCSC>
|
this is EjmlDoubleVector<*> && origin is DMatrixSparseCSC -> this as EjmlDoubleVector<DMatrixSparseCSC>
|
||||||
else -> EjmlDoubleVector(DMatrixSparseCSC(size, 1).also {
|
else -> EjmlDoubleVector(DMatrixSparseCSC(size, 1).also {
|
||||||
(0 until it.numRows).forEach { row -> it[row, 0] = get(row) }
|
(0 until it.numRows).forEach { row -> it[row, 0] = get(row) }
|
||||||
@ -569,21 +636,21 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
private fun <T : DMatrix> T.wrapMatrix() = EjmlDoubleMatrix(this)
|
private fun <T : DMatrix> T.wrapMatrix() = EjmlDoubleMatrix(this)
|
||||||
private fun <T : DMatrix> T.wrapVector() = EjmlDoubleVector(this)
|
private fun <T : DMatrix> T.wrapVector() = EjmlDoubleVector(this)
|
||||||
|
|
||||||
override fun Matrix<Double>.unaryMinus(): Matrix<Double> = this * elementAlgebra { -one }
|
override fun Matrix<Float64>.unaryMinus(): Matrix<Float64> = this * elementAlgebra { -one }
|
||||||
|
|
||||||
override fun Matrix<Double>.dot(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixSparseCSC> {
|
override fun Matrix<Float64>.dot(other: Matrix<Float64>): EjmlDoubleMatrix<DMatrixSparseCSC> {
|
||||||
val out = DMatrixSparseCSC(1, 1)
|
val out = DMatrixSparseCSC(1, 1)
|
||||||
CommonOps_DSCC.mult(toEjml().origin, other.toEjml().origin, out)
|
CommonOps_DSCC.mult(toEjml().origin, other.toEjml().origin, out)
|
||||||
return out.wrapMatrix()
|
return out.wrapMatrix()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Matrix<Double>.dot(vector: Point<Double>): EjmlDoubleVector<DMatrixSparseCSC> {
|
override fun Matrix<Float64>.dot(vector: Point<Float64>): EjmlDoubleVector<DMatrixSparseCSC> {
|
||||||
val out = DMatrixSparseCSC(1, 1)
|
val out = DMatrixSparseCSC(1, 1)
|
||||||
CommonOps_DSCC.mult(toEjml().origin, vector.toEjml().origin, out)
|
CommonOps_DSCC.mult(toEjml().origin, vector.toEjml().origin, out)
|
||||||
return out.wrapVector()
|
return out.wrapVector()
|
||||||
}
|
}
|
||||||
|
|
||||||
override operator fun Matrix<Double>.minus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixSparseCSC> {
|
override operator fun Matrix<Float64>.minus(other: Matrix<Float64>): EjmlDoubleMatrix<DMatrixSparseCSC> {
|
||||||
val out = DMatrixSparseCSC(1, 1)
|
val out = DMatrixSparseCSC(1, 1)
|
||||||
|
|
||||||
CommonOps_DSCC.add(
|
CommonOps_DSCC.add(
|
||||||
@ -599,19 +666,19 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
return out.wrapMatrix()
|
return out.wrapMatrix()
|
||||||
}
|
}
|
||||||
|
|
||||||
override operator fun Matrix<Double>.times(value: Double): EjmlDoubleMatrix<DMatrixSparseCSC> {
|
override operator fun Matrix<Float64>.times(value: Double): EjmlDoubleMatrix<DMatrixSparseCSC> {
|
||||||
val res = DMatrixSparseCSC(1, 1)
|
val res = DMatrixSparseCSC(1, 1)
|
||||||
CommonOps_DSCC.scale(value, toEjml().origin, res)
|
CommonOps_DSCC.scale(value, toEjml().origin, res)
|
||||||
return res.wrapMatrix()
|
return res.wrapMatrix()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Point<Double>.unaryMinus(): EjmlDoubleVector<DMatrixSparseCSC> {
|
override fun Point<Float64>.unaryMinus(): EjmlDoubleVector<DMatrixSparseCSC> {
|
||||||
val res = DMatrixSparseCSC(1, 1)
|
val res = DMatrixSparseCSC(1, 1)
|
||||||
CommonOps_DSCC.changeSign(toEjml().origin, res)
|
CommonOps_DSCC.changeSign(toEjml().origin, res)
|
||||||
return res.wrapVector()
|
return res.wrapVector()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixSparseCSC> {
|
override fun Matrix<Float64>.plus(other: Matrix<Float64>): EjmlDoubleMatrix<DMatrixSparseCSC> {
|
||||||
val out = DMatrixSparseCSC(1, 1)
|
val out = DMatrixSparseCSC(1, 1)
|
||||||
|
|
||||||
CommonOps_DSCC.add(
|
CommonOps_DSCC.add(
|
||||||
@ -627,7 +694,7 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
return out.wrapMatrix()
|
return out.wrapMatrix()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Point<Double>.plus(other: Point<Double>): EjmlDoubleVector<DMatrixSparseCSC> {
|
override fun Point<Float64>.plus(other: Point<Float64>): EjmlDoubleVector<DMatrixSparseCSC> {
|
||||||
val out = DMatrixSparseCSC(1, 1)
|
val out = DMatrixSparseCSC(1, 1)
|
||||||
|
|
||||||
CommonOps_DSCC.add(
|
CommonOps_DSCC.add(
|
||||||
@ -643,7 +710,7 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
return out.wrapVector()
|
return out.wrapVector()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Point<Double>.minus(other: Point<Double>): EjmlDoubleVector<DMatrixSparseCSC> {
|
override fun Point<Float64>.minus(other: Point<Float64>): EjmlDoubleVector<DMatrixSparseCSC> {
|
||||||
val out = DMatrixSparseCSC(1, 1)
|
val out = DMatrixSparseCSC(1, 1)
|
||||||
|
|
||||||
CommonOps_DSCC.add(
|
CommonOps_DSCC.add(
|
||||||
@ -659,17 +726,17 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
return out.wrapVector()
|
return out.wrapVector()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Double.times(m: Matrix<Double>): EjmlDoubleMatrix<DMatrixSparseCSC> = m * this
|
override fun Double.times(m: Matrix<Float64>): EjmlDoubleMatrix<DMatrixSparseCSC> = m * this
|
||||||
|
|
||||||
override fun Point<Double>.times(value: Double): EjmlDoubleVector<DMatrixSparseCSC> {
|
override fun Point<Float64>.times(value: Double): EjmlDoubleVector<DMatrixSparseCSC> {
|
||||||
val res = DMatrixSparseCSC(1, 1)
|
val res = DMatrixSparseCSC(1, 1)
|
||||||
CommonOps_DSCC.scale(value, toEjml().origin, res)
|
CommonOps_DSCC.scale(value, toEjml().origin, res)
|
||||||
return res.wrapVector()
|
return res.wrapVector()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Double.times(v: Point<Double>): EjmlDoubleVector<DMatrixSparseCSC> = v * this
|
override fun Double.times(v: Point<Float64>): EjmlDoubleVector<DMatrixSparseCSC> = v * this
|
||||||
|
|
||||||
override fun <V, A : StructureAttribute<V>> computeAttribute(structure: Structure2D<Double>, attribute: A): V? {
|
override fun <V, A : StructureAttribute<V>> computeAttribute(structure: Structure2D<Float64>, attribute: A): V? {
|
||||||
val origin = structure.toEjml().origin
|
val origin = structure.toEjml().origin
|
||||||
|
|
||||||
val raw: Any? = when (attribute) {
|
val raw: Any? = when (attribute) {
|
||||||
@ -681,16 +748,16 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
|
|
||||||
Determinant -> CommonOps_DSCC.det(origin)
|
Determinant -> CommonOps_DSCC.det(origin)
|
||||||
|
|
||||||
QR -> object : QRDecomposition<Double> {
|
QR -> object : QRDecomposition<Float64> {
|
||||||
val ejmlQr by lazy {
|
val ejmlQr by lazy {
|
||||||
DecompositionFactory_DSCC.qr(FillReducing.NONE).apply { decompose(origin.copy()) }
|
DecompositionFactory_DSCC.qr(FillReducing.NONE).apply { decompose(origin.copy()) }
|
||||||
}
|
}
|
||||||
override val q: Matrix<Double> get() = ejmlQr.getQ(null, false).wrapMatrix()
|
override val q: Matrix<Float64> get() = ejmlQr.getQ(null, false).wrapMatrix()
|
||||||
override val r: Matrix<Double> get() = ejmlQr.getR(null, false).wrapMatrix()
|
override val r: Matrix<Float64> get() = ejmlQr.getR(null, false).wrapMatrix()
|
||||||
}
|
}
|
||||||
|
|
||||||
Cholesky -> object : CholeskyDecomposition<Double> {
|
Cholesky -> object : CholeskyDecomposition<Float64> {
|
||||||
override val l: Matrix<Double> by lazy {
|
override val l: Matrix<Float64> by lazy {
|
||||||
val cholesky =
|
val cholesky =
|
||||||
DecompositionFactory_DSCC.cholesky().apply { decompose(origin.copy()) }
|
DecompositionFactory_DSCC.cholesky().apply { decompose(origin.copy()) }
|
||||||
|
|
||||||
@ -698,16 +765,16 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LUP -> object : LupDecomposition<Double> {
|
LUP -> object : LupDecomposition<Float64> {
|
||||||
private val lup by lazy {
|
private val lup by lazy {
|
||||||
DecompositionFactory_DSCC.lu(FillReducing.NONE).apply { decompose(origin.copy()) }
|
DecompositionFactory_DSCC.lu(FillReducing.NONE).apply { decompose(origin.copy()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override val l: Matrix<Double>
|
override val l: Matrix<Float64>
|
||||||
get() = lup.getLower(null).wrapMatrix().withAttribute(LowerTriangular)
|
get() = lup.getLower(null).wrapMatrix().withAttribute(LowerTriangular)
|
||||||
|
|
||||||
|
|
||||||
override val u: Matrix<Double>
|
override val u: Matrix<Float64>
|
||||||
get() = lup.getUpper(null).wrapMatrix().withAttribute(UpperTriangular)
|
get() = lup.getUpper(null).wrapMatrix().withAttribute(UpperTriangular)
|
||||||
override val pivot: IntBuffer get() = lup.getRowPivotV(null).asBuffer()
|
override val pivot: IntBuffer get() = lup.getRowPivotV(null).asBuffer()
|
||||||
}
|
}
|
||||||
@ -726,7 +793,7 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
* @param b n by p matrix.
|
* @param b n by p matrix.
|
||||||
* @return the solution for *x* that is n by p.
|
* @return the solution for *x* that is n by p.
|
||||||
*/
|
*/
|
||||||
public fun solve(a: Matrix<Double>, b: Matrix<Double>): EjmlDoubleMatrix<DMatrixSparseCSC> {
|
public fun solve(a: Matrix<Float64>, b: Matrix<Float64>): EjmlDoubleMatrix<DMatrixSparseCSC> {
|
||||||
val res = DMatrixSparseCSC(1, 1)
|
val res = DMatrixSparseCSC(1, 1)
|
||||||
CommonOps_DSCC.solve(DMatrixSparseCSC(a.toEjml().origin), DMatrixSparseCSC(b.toEjml().origin), res)
|
CommonOps_DSCC.solve(DMatrixSparseCSC(a.toEjml().origin), DMatrixSparseCSC(b.toEjml().origin), res)
|
||||||
return res.wrapMatrix()
|
return res.wrapMatrix()
|
||||||
@ -739,7 +806,7 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri
|
|||||||
* @param b n by p vector.
|
* @param b n by p vector.
|
||||||
* @return the solution for *x* that is n by p.
|
* @return the solution for *x* that is n by p.
|
||||||
*/
|
*/
|
||||||
public fun solve(a: Matrix<Double>, b: Point<Double>): EjmlDoubleVector<DMatrixSparseCSC> {
|
public fun solve(a: Matrix<Float64>, b: Point<Float64>): EjmlDoubleVector<DMatrixSparseCSC> {
|
||||||
val res = DMatrixSparseCSC(1, 1)
|
val res = DMatrixSparseCSC(1, 1)
|
||||||
CommonOps_DSCC.solve(DMatrixSparseCSC(a.toEjml().origin), DMatrixSparseCSC(b.toEjml().origin), res)
|
CommonOps_DSCC.solve(DMatrixSparseCSC(a.toEjml().origin), DMatrixSparseCSC(b.toEjml().origin), res)
|
||||||
return EjmlDoubleVector(res)
|
return EjmlDoubleVector(res)
|
||||||
|
@ -17,6 +17,7 @@ import space.kscience.kmath.linear.*
|
|||||||
import space.kscience.kmath.nd.StructureND
|
import space.kscience.kmath.nd.StructureND
|
||||||
import space.kscience.kmath.nd.toArray
|
import space.kscience.kmath.nd.toArray
|
||||||
import space.kscience.kmath.operations.algebra
|
import space.kscience.kmath.operations.algebra
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
import kotlin.random.asJavaRandom
|
import kotlin.random.asJavaRandom
|
||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
@ -63,7 +64,7 @@ internal class EjmlMatrixTest {
|
|||||||
val w = EjmlDoubleMatrix(m)
|
val w = EjmlDoubleMatrix(m)
|
||||||
val det: Double = w.getOrComputeAttribute(Determinant) ?: fail()
|
val det: Double = w.getOrComputeAttribute(Determinant) ?: fail()
|
||||||
assertEquals(CommonOps_DDRM.det(m), det)
|
assertEquals(CommonOps_DDRM.det(m), det)
|
||||||
val lup: LupDecomposition<Double> = w.getOrComputeAttribute(LUP) ?: fail()
|
val lup: LupDecomposition<Float64> = w.getOrComputeAttribute(LUP) ?: fail()
|
||||||
|
|
||||||
val ludecompositionF64 = DecompositionFactory_DDRM.lu(m.numRows, m.numCols)
|
val ludecompositionF64 = DecompositionFactory_DDRM.lu(m.numRows, m.numCols)
|
||||||
.also { it.decompose(m.copy()) }
|
.also { it.decompose(m.copy()) }
|
||||||
@ -104,4 +105,11 @@ internal class EjmlMatrixTest {
|
|||||||
|
|
||||||
assertTrue { StructureND.contentEquals(one(dim, dim), res, 1e-3) }
|
assertTrue { StructureND.contentEquals(one(dim, dim), res, 1e-3) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun eigenValueDecomposition() = EjmlLinearSpaceDDRM {
|
||||||
|
val matrix = EjmlDoubleMatrix(randomMatrix)
|
||||||
|
val eigen = matrix.getOrComputeAttribute(EIG) ?: fail()
|
||||||
|
assertMatrixEquals(matrix, eigen.v dot eigen.d dot eigen.v.transposed())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,13 @@ import space.kscience.kmath.UnstableKMathAPI
|
|||||||
import space.kscience.kmath.linear.Point
|
import space.kscience.kmath.linear.Point
|
||||||
import space.kscience.kmath.operations.Float64L2Norm
|
import space.kscience.kmath.operations.Float64L2Norm
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.MutableBuffer.Companion.double
|
import space.kscience.kmath.structures.MutableBuffer.Companion.double
|
||||||
import space.kscience.kmath.structures.asBuffer
|
import space.kscience.kmath.structures.asBuffer
|
||||||
import space.kscience.kmath.structures.indices
|
import space.kscience.kmath.structures.indices
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
public typealias DoubleVector = Point<Double>
|
public typealias DoubleVector = Point<Float64>
|
||||||
|
|
||||||
public fun DoubleVector(vararg doubles: Double): DoubleVector = doubles.asBuffer()
|
public fun DoubleVector(vararg doubles: Double): DoubleVector = doubles.asBuffer()
|
||||||
|
|
||||||
@ -41,7 +42,7 @@ public operator fun DoubleVector.plus(number: Number): DoubleVector = map { it +
|
|||||||
|
|
||||||
public operator fun Number.plus(vector: DoubleVector): DoubleVector = vector + this
|
public operator fun Number.plus(vector: DoubleVector): DoubleVector = vector + this
|
||||||
|
|
||||||
public operator fun DoubleVector.unaryMinus(): Buffer<Double> = map { -it }
|
public operator fun DoubleVector.unaryMinus(): Buffer<Float64> = map { -it }
|
||||||
|
|
||||||
public operator fun DoubleVector.minus(other: DoubleVector): DoubleVector {
|
public operator fun DoubleVector.minus(other: DoubleVector): DoubleVector {
|
||||||
require(size == other.size) { "Vector size $size expected but ${other.size} found" }
|
require(size == other.size) { "Vector size $size expected but ${other.size} found" }
|
||||||
|
@ -15,6 +15,7 @@ import space.kscience.kmath.operations.Float64Field
|
|||||||
import space.kscience.kmath.operations.algebra
|
import space.kscience.kmath.operations.algebra
|
||||||
import space.kscience.kmath.operations.asIterable
|
import space.kscience.kmath.operations.asIterable
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.Float64Buffer
|
import space.kscience.kmath.structures.Float64Buffer
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ import kotlin.math.pow
|
|||||||
* Functions that help create a real (Double) matrix
|
* Functions that help create a real (Double) matrix
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public typealias RealMatrix = Matrix<Double>
|
public typealias RealMatrix = Matrix<Float64>
|
||||||
|
|
||||||
public fun realMatrix(rowNum: Int, colNum: Int, initializer: Float64Field.(i: Int, j: Int) -> Double): RealMatrix =
|
public fun realMatrix(rowNum: Int, colNum: Int, initializer: Float64Field.(i: Int, j: Int) -> Double): RealMatrix =
|
||||||
Double.algebra.linearSpace.buildMatrix(rowNum, colNum, initializer)
|
Double.algebra.linearSpace.buildMatrix(rowNum, colNum, initializer)
|
||||||
@ -114,7 +115,7 @@ public operator fun RealMatrix.minus(other: RealMatrix): RealMatrix =
|
|||||||
* Operations on columns
|
* Operations on columns
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public inline fun RealMatrix.appendColumn(crossinline mapper: (Buffer<Double>) -> Double): RealMatrix =
|
public inline fun RealMatrix.appendColumn(crossinline mapper: (Buffer<Float64>) -> Double): RealMatrix =
|
||||||
Double.algebra.linearSpace.buildMatrix(rowNum, colNum + 1) { row, col ->
|
Double.algebra.linearSpace.buildMatrix(rowNum, colNum + 1) { row, col ->
|
||||||
if (col < colNum)
|
if (col < colNum)
|
||||||
get(row, col)
|
get(row, col)
|
||||||
|
@ -8,11 +8,12 @@ package space.kscience.kmath.real
|
|||||||
import space.kscience.kmath.linear.Matrix
|
import space.kscience.kmath.linear.Matrix
|
||||||
import space.kscience.kmath.linear.linearSpace
|
import space.kscience.kmath.linear.linearSpace
|
||||||
import space.kscience.kmath.operations.algebra
|
import space.kscience.kmath.operations.algebra
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optimized dot product for real matrices
|
* Optimized dot product for real matrices
|
||||||
*/
|
*/
|
||||||
public infix fun Matrix<Double>.dot(other: Matrix<Double>): Matrix<Double> = Double.algebra.linearSpace.run {
|
public infix fun Matrix<Float64>.dot(other: Matrix<Float64>): Matrix<Float64> = Double.algebra.linearSpace.run {
|
||||||
this@dot dot other
|
this@dot dot other
|
||||||
}
|
}
|
@ -7,16 +7,17 @@ package space.kscience.kmath.real
|
|||||||
|
|
||||||
import space.kscience.kmath.UnstableKMathAPI
|
import space.kscience.kmath.UnstableKMathAPI
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.Float64Buffer
|
import space.kscience.kmath.structures.Float64Buffer
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
|
|
||||||
public val ClosedFloatingPointRange<Double>.length: Double get() = endInclusive - start
|
public val ClosedFloatingPointRange<Float64>.length: Double get() = endInclusive - start
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Buffer-based grid with equally distributed [numberOfPoints] points. The range could be increasing or decreasing.
|
* Create a Buffer-based grid with equally distributed [numberOfPoints] points. The range could be increasing or decreasing.
|
||||||
* If range has a zero size, then the buffer consisting of [numberOfPoints] equal values is returned.
|
* If range has a zero size, then the buffer consisting of [numberOfPoints] equal values is returned.
|
||||||
*/
|
*/
|
||||||
public fun Buffer.Companion.fromRange(range: ClosedFloatingPointRange<Double>, numberOfPoints: Int): Float64Buffer {
|
public fun Buffer.Companion.fromRange(range: ClosedFloatingPointRange<Float64>, numberOfPoints: Int): Float64Buffer {
|
||||||
require(numberOfPoints >= 2) { "Number of points in grid must be more than 1" }
|
require(numberOfPoints >= 2) { "Number of points in grid must be more than 1" }
|
||||||
val normalizedRange = when {
|
val normalizedRange = when {
|
||||||
range.endInclusive > range.start -> range
|
range.endInclusive > range.start -> range
|
||||||
@ -31,7 +32,7 @@ public fun Buffer.Companion.fromRange(range: ClosedFloatingPointRange<Double>, n
|
|||||||
* Create a Buffer-based grid with equally distributed points with a fixed [step]. The range could be increasing or decreasing.
|
* Create a Buffer-based grid with equally distributed points with a fixed [step]. The range could be increasing or decreasing.
|
||||||
* If the step is larger than the range size, single point is returned.
|
* If the step is larger than the range size, single point is returned.
|
||||||
*/
|
*/
|
||||||
public fun Buffer.Companion.withFixedStep(range: ClosedFloatingPointRange<Double>, step: Double): Float64Buffer {
|
public fun Buffer.Companion.withFixedStep(range: ClosedFloatingPointRange<Float64>, step: Double): Float64Buffer {
|
||||||
require(step > 0) { "The grid step must be positive" }
|
require(step > 0) { "The grid step must be positive" }
|
||||||
val normalizedRange = when {
|
val normalizedRange = when {
|
||||||
range.endInclusive > range.start -> range
|
range.endInclusive > range.start -> range
|
||||||
@ -51,4 +52,4 @@ public fun Buffer.Companion.withFixedStep(range: ClosedFloatingPointRange<Double
|
|||||||
* If step is negative, the same goes from upper boundary downwards
|
* If step is negative, the same goes from upper boundary downwards
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public infix fun ClosedFloatingPointRange<Double>.step(step: Double): Float64Buffer = Buffer.withFixedStep(this, step)
|
public infix fun ClosedFloatingPointRange<Float64>.step(step: Double): Float64Buffer = Buffer.withFixedStep(this, step)
|
@ -7,12 +7,13 @@ package space.kscience.kmath.real
|
|||||||
|
|
||||||
import space.kscience.kmath.nd.BufferND
|
import space.kscience.kmath.nd.BufferND
|
||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.Float64Buffer
|
import space.kscience.kmath.structures.Float64Buffer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map one [BufferND] using function without indices.
|
* Map one [BufferND] using function without indices.
|
||||||
*/
|
*/
|
||||||
public inline fun BufferND<Double>.mapInline(crossinline transform: Float64Field.(Double) -> Double): BufferND<Double> {
|
public inline fun BufferND<Float64>.mapInline(crossinline transform: Float64Field.(Double) -> Double): BufferND<Float64> {
|
||||||
val array = DoubleArray(indices.linearSize) { offset -> Float64Field.transform(buffer[offset]) }
|
val array = DoubleArray(indices.linearSize) { offset -> Float64Field.transform(buffer[offset]) }
|
||||||
return BufferND(indices, Float64Buffer(array))
|
return BufferND(indices, Float64Buffer(array))
|
||||||
}
|
}
|
||||||
@ -20,7 +21,7 @@ public inline fun BufferND<Double>.mapInline(crossinline transform: Float64Field
|
|||||||
/**
|
/**
|
||||||
* Element by element application of any operation on elements to the whole array. Just like in numpy.
|
* Element by element application of any operation on elements to the whole array. Just like in numpy.
|
||||||
*/
|
*/
|
||||||
public operator fun Function1<Double, Double>.invoke(elementND: BufferND<Double>): BufferND<Double> =
|
public operator fun Function1<Double, Double>.invoke(elementND: BufferND<Float64>): BufferND<Float64> =
|
||||||
elementND.mapInline { this@invoke(it) }
|
elementND.mapInline { this@invoke(it) }
|
||||||
|
|
||||||
/* plus and minus */
|
/* plus and minus */
|
||||||
@ -28,9 +29,9 @@ public operator fun Function1<Double, Double>.invoke(elementND: BufferND<Double>
|
|||||||
/**
|
/**
|
||||||
* Summation operation for [BufferND] and single element
|
* Summation operation for [BufferND] and single element
|
||||||
*/
|
*/
|
||||||
public operator fun BufferND<Double>.plus(arg: Double): BufferND<Double> = mapInline { it + arg }
|
public operator fun BufferND<Float64>.plus(arg: Double): BufferND<Float64> = mapInline { it + arg }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subtraction operation between [BufferND] and single element
|
* Subtraction operation between [BufferND] and single element
|
||||||
*/
|
*/
|
||||||
public operator fun BufferND<Double>.minus(arg: Double): BufferND<Double> = mapInline { it - arg }
|
public operator fun BufferND<Float64>.minus(arg: Double): BufferND<Float64> = mapInline { it - arg }
|
@ -170,7 +170,7 @@ internal class DoubleMatrixTest {
|
|||||||
assertEquals(matrix1.average(), 1.375)
|
assertEquals(matrix1.average(), 1.375)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fun printMatrix(m: Matrix<Double>) {
|
// fun printMatrix(m: Matrix<Float64>) {
|
||||||
// for (row in 0 until m.shape[0]) {
|
// for (row in 0 until m.shape[0]) {
|
||||||
// for (col in 0 until m.shape[1]) {
|
// for (col in 0 until m.shape[1]) {
|
||||||
// print(m[row, col])
|
// print(m[row, col])
|
||||||
|
@ -7,6 +7,7 @@ package space.kscience.kmath.functions
|
|||||||
|
|
||||||
import space.kscience.kmath.UnstableKMathAPI
|
import space.kscience.kmath.UnstableKMathAPI
|
||||||
import space.kscience.kmath.operations.*
|
import space.kscience.kmath.operations.*
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import kotlin.contracts.InvocationKind
|
import kotlin.contracts.InvocationKind
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
@ -31,7 +32,7 @@ public inline fun <C, A, R> A.polynomialSpace(block: PolynomialSpace<C, A>.() ->
|
|||||||
/**
|
/**
|
||||||
* Evaluates value of [this] Double polynomial on provided Double argument.
|
* Evaluates value of [this] Double polynomial on provided Double argument.
|
||||||
*/
|
*/
|
||||||
public fun Polynomial<Double>.value(arg: Double): Double =
|
public fun Polynomial<Float64>.value(arg: Double): Double =
|
||||||
coefficients.reduceIndexedOrNull { index, acc, c ->
|
coefficients.reduceIndexedOrNull { index, acc, c ->
|
||||||
acc + c * arg.pow(index)
|
acc + c * arg.pow(index)
|
||||||
} ?: .0
|
} ?: .0
|
||||||
|
@ -8,6 +8,7 @@ import space.kscience.attributes.AttributesBuilder
|
|||||||
import space.kscience.kmath.UnstableKMathAPI
|
import space.kscience.kmath.UnstableKMathAPI
|
||||||
import space.kscience.kmath.operations.Field
|
import space.kscience.kmath.operations.Field
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.asBuffer
|
import space.kscience.kmath.structures.asBuffer
|
||||||
import space.kscience.kmath.structures.indices
|
import space.kscience.kmath.structures.indices
|
||||||
|
|
||||||
@ -27,7 +28,7 @@ public class GaussIntegrator<T : Any>(
|
|||||||
public val algebra: Field<T>,
|
public val algebra: Field<T>,
|
||||||
) : UnivariateIntegrator<T> {
|
) : UnivariateIntegrator<T> {
|
||||||
|
|
||||||
private fun buildRule(integrand: UnivariateIntegrand<T>): Pair<Buffer<Double>, Buffer<Double>> {
|
private fun buildRule(integrand: UnivariateIntegrand<T>): Pair<Buffer<Float64>, Buffer<Float64>> {
|
||||||
val factory = integrand[GaussIntegratorRuleFactory] ?: GaussLegendreRuleFactory
|
val factory = integrand[GaussIntegratorRuleFactory] ?: GaussLegendreRuleFactory
|
||||||
val predefinedRanges = integrand[UnivariateIntegrandRanges]
|
val predefinedRanges = integrand[UnivariateIntegrandRanges]
|
||||||
if (predefinedRanges == null || predefinedRanges.ranges.isEmpty()) {
|
if (predefinedRanges == null || predefinedRanges.ranges.isEmpty()) {
|
||||||
@ -89,7 +90,7 @@ public val <T : Any> Field<T>.gaussIntegrator: GaussIntegrator<T> get() = GaussI
|
|||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public inline fun <reified T : Any> GaussIntegrator<T>.integrate(
|
public inline fun <reified T : Any> GaussIntegrator<T>.integrate(
|
||||||
range: ClosedRange<Double>,
|
range: ClosedRange<Float64>,
|
||||||
order: Int = 10,
|
order: Int = 10,
|
||||||
intervals: Int = 10,
|
intervals: Int = 10,
|
||||||
noinline attributesBuilder: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit = {},
|
noinline attributesBuilder: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit = {},
|
||||||
|
@ -8,16 +8,17 @@ package space.kscience.kmath.integration
|
|||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
import space.kscience.kmath.operations.mapToBuffer
|
import space.kscience.kmath.operations.mapToBuffer
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.Float64Buffer
|
import space.kscience.kmath.structures.Float64Buffer
|
||||||
import space.kscience.kmath.structures.asBuffer
|
import space.kscience.kmath.structures.asBuffer
|
||||||
import kotlin.math.ulp
|
import kotlin.math.ulp
|
||||||
import kotlin.native.concurrent.ThreadLocal
|
import kotlin.native.concurrent.ThreadLocal
|
||||||
|
|
||||||
public interface GaussIntegratorRuleFactory {
|
public interface GaussIntegratorRuleFactory {
|
||||||
public fun build(numPoints: Int): Pair<Buffer<Double>, Buffer<Double>>
|
public fun build(numPoints: Int): Pair<Buffer<Float64>, Buffer<Float64>>
|
||||||
|
|
||||||
public companion object : IntegrandAttribute<GaussIntegratorRuleFactory> {
|
public companion object : IntegrandAttribute<GaussIntegratorRuleFactory> {
|
||||||
public fun double(numPoints: Int, range: ClosedRange<Double>): Pair<Buffer<Double>, Buffer<Double>> =
|
public fun double(numPoints: Int, range: ClosedRange<Float64>): Pair<Buffer<Float64>, Buffer<Float64>> =
|
||||||
GaussLegendreRuleFactory.build(numPoints, range)
|
GaussLegendreRuleFactory.build(numPoints, range)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -28,9 +29,9 @@ public interface GaussIntegratorRuleFactory {
|
|||||||
*/
|
*/
|
||||||
public fun GaussIntegratorRuleFactory.build(
|
public fun GaussIntegratorRuleFactory.build(
|
||||||
numPoints: Int,
|
numPoints: Int,
|
||||||
range: ClosedRange<Double>,
|
range: ClosedRange<Float64>,
|
||||||
): Pair<Buffer<Double>, Buffer<Double>> {
|
): Pair<Buffer<Float64>, Buffer<Float64>> {
|
||||||
val normalized: Pair<Buffer<Double>, Buffer<Double>> = build(numPoints)
|
val normalized: Pair<Buffer<Float64>, Buffer<Float64>> = build(numPoints)
|
||||||
val length = range.endInclusive - range.start
|
val length = range.endInclusive - range.start
|
||||||
|
|
||||||
val points = normalized.first.mapToBuffer(Float64Field.bufferFactory) {
|
val points = normalized.first.mapToBuffer(Float64Field.bufferFactory) {
|
||||||
@ -55,13 +56,13 @@ public fun GaussIntegratorRuleFactory.build(
|
|||||||
@ThreadLocal
|
@ThreadLocal
|
||||||
public object GaussLegendreRuleFactory : GaussIntegratorRuleFactory {
|
public object GaussLegendreRuleFactory : GaussIntegratorRuleFactory {
|
||||||
|
|
||||||
private val cache = HashMap<Int, Pair<Buffer<Double>, Buffer<Double>>>()
|
private val cache = HashMap<Int, Pair<Buffer<Float64>, Buffer<Float64>>>()
|
||||||
|
|
||||||
private fun getOrBuildRule(numPoints: Int): Pair<Buffer<Double>, Buffer<Double>> =
|
private fun getOrBuildRule(numPoints: Int): Pair<Buffer<Float64>, Buffer<Float64>> =
|
||||||
cache.getOrPut(numPoints) { buildRule(numPoints) }
|
cache.getOrPut(numPoints) { buildRule(numPoints) }
|
||||||
|
|
||||||
|
|
||||||
private fun buildRule(numPoints: Int): Pair<Buffer<Double>, Buffer<Double>> {
|
private fun buildRule(numPoints: Int): Pair<Buffer<Float64>, Buffer<Float64>> {
|
||||||
if (numPoints == 1) {
|
if (numPoints == 1) {
|
||||||
// Break recursion.
|
// Break recursion.
|
||||||
return Pair(
|
return Pair(
|
||||||
@ -73,7 +74,7 @@ public object GaussLegendreRuleFactory : GaussIntegratorRuleFactory {
|
|||||||
// Get previous rule.
|
// Get previous rule.
|
||||||
// If it has not been computed, yet it will trigger a recursive call
|
// If it has not been computed, yet it will trigger a recursive call
|
||||||
// to this method.
|
// to this method.
|
||||||
val previousPoints: Buffer<Double> = getOrBuildRule(numPoints - 1).first
|
val previousPoints: Buffer<Float64> = getOrBuildRule(numPoints - 1).first
|
||||||
|
|
||||||
// Compute next rule.
|
// Compute next rule.
|
||||||
val points = DoubleArray(numPoints)
|
val points = DoubleArray(numPoints)
|
||||||
@ -162,7 +163,7 @@ public object GaussLegendreRuleFactory : GaussIntegratorRuleFactory {
|
|||||||
return Pair(points.asBuffer(), weights.asBuffer())
|
return Pair(points.asBuffer(), weights.asBuffer())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun build(numPoints: Int): Pair<Buffer<Double>, Buffer<Double>> = getOrBuildRule(numPoints)
|
override fun build(numPoints: Int): Pair<Buffer<Float64>, Buffer<Float64>> = getOrBuildRule(numPoints)
|
||||||
|
|
||||||
override fun toString(): String = "GaussLegendreRule"
|
override fun toString(): String = "GaussLegendreRule"
|
||||||
}
|
}
|
@ -6,6 +6,7 @@
|
|||||||
package space.kscience.kmath.integration
|
package space.kscience.kmath.integration
|
||||||
|
|
||||||
import space.kscience.attributes.*
|
import space.kscience.attributes.*
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
|
|
||||||
public interface IntegrandAttribute<T> : Attribute<T>
|
public interface IntegrandAttribute<T> : Attribute<T>
|
||||||
|
|
||||||
@ -44,9 +45,9 @@ public inline val <reified T : Any> Integrand<T>.valueOrNull: T? get() = attribu
|
|||||||
*/
|
*/
|
||||||
public inline val <reified T : Any> Integrand<T>.value: T get() = valueOrNull ?: error("No value in the integrand")
|
public inline val <reified T : Any> Integrand<T>.value: T get() = valueOrNull ?: error("No value in the integrand")
|
||||||
|
|
||||||
public object IntegrandRelativeAccuracy : IntegrandAttribute<Double>
|
public object IntegrandRelativeAccuracy : IntegrandAttribute<Float64>
|
||||||
|
|
||||||
public object IntegrandAbsoluteAccuracy : IntegrandAttribute<Double>
|
public object IntegrandAbsoluteAccuracy : IntegrandAttribute<Float64>
|
||||||
|
|
||||||
public object IntegrandCallsPerformed : IntegrandAttribute<Int>
|
public object IntegrandCallsPerformed : IntegrandAttribute<Int>
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import space.kscience.kmath.operations.Field
|
|||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
import space.kscience.kmath.operations.sum
|
import space.kscience.kmath.operations.sum
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use double pass Simpson rule integration with a fixed number of points.
|
* Use double pass Simpson rule integration with a fixed number of points.
|
||||||
@ -24,7 +25,7 @@ public class SimpsonIntegrator<T : Any>(
|
|||||||
) : UnivariateIntegrator<T> {
|
) : UnivariateIntegrator<T> {
|
||||||
|
|
||||||
private fun integrateRange(
|
private fun integrateRange(
|
||||||
integrand: UnivariateIntegrand<T>, range: ClosedRange<Double>, numPoints: Int,
|
integrand: UnivariateIntegrand<T>, range: ClosedRange<Float64>, numPoints: Int,
|
||||||
): T = algebra {
|
): T = algebra {
|
||||||
val h: Double = (range.endInclusive - range.start) / (numPoints - 1)
|
val h: Double = (range.endInclusive - range.start) / (numPoints - 1)
|
||||||
val values: List<T> = List(numPoints) { i ->
|
val values: List<T> = List(numPoints) { i ->
|
||||||
@ -75,9 +76,9 @@ public val <T : Any> Field<T>.simpsonIntegrator: SimpsonIntegrator<T> get() = Si
|
|||||||
* * [IntegrandMaxCalls]—the maximum number of function calls during integration. For non-iterative rules, always uses
|
* * [IntegrandMaxCalls]—the maximum number of function calls during integration. For non-iterative rules, always uses
|
||||||
* the maximum number of points. By default, uses 10 points.
|
* the maximum number of points. By default, uses 10 points.
|
||||||
*/
|
*/
|
||||||
public object DoubleSimpsonIntegrator : UnivariateIntegrator<Double> {
|
public object DoubleSimpsonIntegrator : UnivariateIntegrator<Float64> {
|
||||||
private fun integrateRange(
|
private fun integrateRange(
|
||||||
integrand: UnivariateIntegrand<Double>, range: ClosedRange<Double>, numPoints: Int,
|
integrand: UnivariateIntegrand<Float64>, range: ClosedRange<Float64>, numPoints: Int,
|
||||||
): Double {
|
): Double {
|
||||||
val h: Double = (range.endInclusive - range.start) / (numPoints - 1)
|
val h: Double = (range.endInclusive - range.start) / (numPoints - 1)
|
||||||
val values = DoubleArray(numPoints) { i ->
|
val values = DoubleArray(numPoints) { i ->
|
||||||
@ -96,7 +97,7 @@ public object DoubleSimpsonIntegrator : UnivariateIntegrator<Double> {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun integrate(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> {
|
override fun integrate(integrand: UnivariateIntegrand<Float64>): UnivariateIntegrand<Float64> {
|
||||||
val ranges = integrand[UnivariateIntegrandRanges]
|
val ranges = integrand[UnivariateIntegrandRanges]
|
||||||
return if (ranges != null) {
|
return if (ranges != null) {
|
||||||
val res = ranges.ranges.sumOf { integrateRange(integrand, it.first, it.second) }
|
val res = ranges.ranges.sumOf { integrateRange(integrand, it.first, it.second) }
|
||||||
|
@ -14,6 +14,7 @@ import space.kscience.kmath.interpolation.SplineInterpolator
|
|||||||
import space.kscience.kmath.interpolation.interpolatePolynomials
|
import space.kscience.kmath.interpolation.interpolatePolynomials
|
||||||
import space.kscience.kmath.operations.*
|
import space.kscience.kmath.operations.*
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.Float64Buffer
|
import space.kscience.kmath.structures.Float64Buffer
|
||||||
import space.kscience.kmath.structures.MutableBufferFactory
|
import space.kscience.kmath.structures.MutableBufferFactory
|
||||||
|
|
||||||
@ -59,7 +60,7 @@ public class SplineIntegrator<T : Comparable<T>>(
|
|||||||
|
|
||||||
val interpolator: PolynomialInterpolator<T> = SplineInterpolator(algebra, bufferFactory)
|
val interpolator: PolynomialInterpolator<T> = SplineInterpolator(algebra, bufferFactory)
|
||||||
|
|
||||||
val nodes: Buffer<Double> = integrand[UnivariateIntegrationNodes] ?: run {
|
val nodes: Buffer<Float64> = integrand[UnivariateIntegrationNodes] ?: run {
|
||||||
val numPoints = integrand[IntegrandMaxCalls] ?: 100
|
val numPoints = integrand[IntegrandMaxCalls] ?: 100
|
||||||
val step = (range.endInclusive - range.start) / (numPoints - 1)
|
val step = (range.endInclusive - range.start) / (numPoints - 1)
|
||||||
Float64Buffer(numPoints) { i -> range.start + i * step }
|
Float64Buffer(numPoints) { i -> range.start + i * step }
|
||||||
@ -85,12 +86,12 @@ public class SplineIntegrator<T : Comparable<T>>(
|
|||||||
* uses the maximum number of points. By default, uses 10 points.
|
* uses the maximum number of points. By default, uses 10 points.
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public object DoubleSplineIntegrator : UnivariateIntegrator<Double> {
|
public object DoubleSplineIntegrator : UnivariateIntegrator<Float64> {
|
||||||
override fun integrate(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> {
|
override fun integrate(integrand: UnivariateIntegrand<Float64>): UnivariateIntegrand<Float64> {
|
||||||
val range = integrand[IntegrationRange] ?: 0.0..1.0
|
val range = integrand[IntegrationRange] ?: 0.0..1.0
|
||||||
val interpolator: PolynomialInterpolator<Double> = SplineInterpolator(Float64Field, Float64Field.bufferFactory)
|
val interpolator: PolynomialInterpolator<Float64> = SplineInterpolator(Float64Field, Float64Field.bufferFactory)
|
||||||
|
|
||||||
val nodes: Buffer<Double> = integrand[UnivariateIntegrationNodes] ?: run {
|
val nodes: Buffer<Float64> = integrand[UnivariateIntegrationNodes] ?: run {
|
||||||
val numPoints = integrand[IntegrandMaxCalls] ?: 100
|
val numPoints = integrand[IntegrandMaxCalls] ?: 100
|
||||||
val step = (range.endInclusive - range.start) / (numPoints - 1)
|
val step = (range.endInclusive - range.start) / (numPoints - 1)
|
||||||
Float64Buffer(numPoints) { i -> range.start + i * step }
|
Float64Buffer(numPoints) { i -> range.start + i * step }
|
||||||
@ -108,5 +109,5 @@ public object DoubleSplineIntegrator : UnivariateIntegrator<Double> {
|
|||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public inline val Float64Field.splineIntegrator: UnivariateIntegrator<Double>
|
public inline val Float64Field.splineIntegrator: UnivariateIntegrator<Float64>
|
||||||
get() = DoubleSplineIntegrator
|
get() = DoubleSplineIntegrator
|
@ -8,6 +8,7 @@ package space.kscience.kmath.integration
|
|||||||
import space.kscience.attributes.*
|
import space.kscience.attributes.*
|
||||||
import space.kscience.kmath.UnstableKMathAPI
|
import space.kscience.kmath.UnstableKMathAPI
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.Float64Buffer
|
import space.kscience.kmath.structures.Float64Buffer
|
||||||
|
|
||||||
public class UnivariateIntegrand<T>(
|
public class UnivariateIntegrand<T>(
|
||||||
@ -36,15 +37,15 @@ public inline fun <reified T : Any> UnivariateIntegrand(
|
|||||||
|
|
||||||
public typealias UnivariateIntegrator<T> = Integrator<T, UnivariateIntegrand<T>>
|
public typealias UnivariateIntegrator<T> = Integrator<T, UnivariateIntegrand<T>>
|
||||||
|
|
||||||
public object IntegrationRange : IntegrandAttribute<ClosedRange<Double>>
|
public object IntegrationRange : IntegrandAttribute<ClosedRange<Float64>>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of univariate integration ranges. First components correspond to the ranges themselves, second components to
|
* Set of univariate integration ranges. First components correspond to the ranges themselves, second components to
|
||||||
* the number of integration nodes per range.
|
* the number of integration nodes per range.
|
||||||
*/
|
*/
|
||||||
public class UnivariateIntegrandRanges(public val ranges: List<Pair<ClosedRange<Double>, Int>>) {
|
public class UnivariateIntegrandRanges(public val ranges: List<Pair<ClosedRange<Float64>, Int>>) {
|
||||||
public constructor(vararg pairs: Pair<ClosedRange<Double>, Int>) : this(pairs.toList())
|
public constructor(vararg pairs: Pair<ClosedRange<Float64>, Int>) : this(pairs.toList())
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
val rangesString = ranges.joinToString(separator = ",") { (range, points) ->
|
val rangesString = ranges.joinToString(separator = ",") { (range, points) ->
|
||||||
@ -56,7 +57,7 @@ public class UnivariateIntegrandRanges(public val ranges: List<Pair<ClosedRange<
|
|||||||
public companion object : IntegrandAttribute<UnivariateIntegrandRanges>
|
public companion object : IntegrandAttribute<UnivariateIntegrandRanges>
|
||||||
}
|
}
|
||||||
|
|
||||||
public object UnivariateIntegrationNodes : IntegrandAttribute<Buffer<Double>>
|
public object UnivariateIntegrationNodes : IntegrandAttribute<Buffer<Float64>>
|
||||||
|
|
||||||
public fun AttributesBuilder<UnivariateIntegrand<*>>.integrationNodes(vararg nodes: Double) {
|
public fun AttributesBuilder<UnivariateIntegrand<*>>.integrationNodes(vararg nodes: Double) {
|
||||||
UnivariateIntegrationNodes(Float64Buffer(nodes))
|
UnivariateIntegrationNodes(Float64Buffer(nodes))
|
||||||
@ -78,7 +79,7 @@ public inline fun <reified T : Any> UnivariateIntegrator<T>.integrate(
|
|||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public inline fun <reified T : Any> UnivariateIntegrator<T>.integrate(
|
public inline fun <reified T : Any> UnivariateIntegrator<T>.integrate(
|
||||||
range: ClosedRange<Double>,
|
range: ClosedRange<Float64>,
|
||||||
noinline attributeBuilder: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit = {},
|
noinline attributeBuilder: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit = {},
|
||||||
noinline function: (Double) -> T,
|
noinline function: (Double) -> T,
|
||||||
): UnivariateIntegrand<T> {
|
): UnivariateIntegrand<T> {
|
||||||
|
@ -12,6 +12,7 @@ import space.kscience.kmath.functions.Polynomial
|
|||||||
import space.kscience.kmath.operations.Field
|
import space.kscience.kmath.operations.Field
|
||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.MutableBufferFactory
|
import space.kscience.kmath.structures.MutableBufferFactory
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,5 +79,5 @@ public fun <T : Comparable<T>> Field<T>.splineInterpolator(
|
|||||||
bufferFactory: MutableBufferFactory<T>,
|
bufferFactory: MutableBufferFactory<T>,
|
||||||
): SplineInterpolator<T> = SplineInterpolator(this, bufferFactory)
|
): SplineInterpolator<T> = SplineInterpolator(this, bufferFactory)
|
||||||
|
|
||||||
public val Float64Field.splineInterpolator: SplineInterpolator<Double>
|
public val Float64Field.splineInterpolator: SplineInterpolator<Float64>
|
||||||
get() = SplineInterpolator(this, bufferFactory)
|
get() = SplineInterpolator(this, bufferFactory)
|
@ -19,7 +19,7 @@ internal class LinearInterpolatorTest {
|
|||||||
3.0 to 4.0
|
3.0 to 4.0
|
||||||
)
|
)
|
||||||
|
|
||||||
//val polynomial: PiecewisePolynomial<Double> = DoubleField.linearInterpolator.interpolatePolynomials(data)
|
//val polynomial: PiecewisePolynomial<Float64> = DoubleField.linearInterpolator.interpolatePolynomials(data)
|
||||||
val function = Float64Field.linearInterpolator.interpolate(data)
|
val function = Float64Field.linearInterpolator.interpolate(data)
|
||||||
assertEquals(null, function(-1.0))
|
assertEquals(null, function(-1.0))
|
||||||
assertEquals(0.5, function(0.5))
|
assertEquals(0.5, function(0.5))
|
||||||
|
@ -19,7 +19,7 @@ internal class SplineInterpolatorTest {
|
|||||||
x to sin(x)
|
x to sin(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
//val polynomial: PiecewisePolynomial<Double> = DoubleField.splineInterpolator.interpolatePolynomials(data)
|
//val polynomial: PiecewisePolynomial<Float64> = DoubleField.splineInterpolator.interpolatePolynomials(data)
|
||||||
|
|
||||||
val function = Float64Field.splineInterpolator.interpolate(data, Double.NaN)
|
val function = Float64Field.splineInterpolator.interpolate(data, Double.NaN)
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ public val Circle2D<*>.circumference: Double get() = radius * 2 * PI
|
|||||||
public data class Float64Circle2D(
|
public data class Float64Circle2D(
|
||||||
@Serializable(Float64Space2D.VectorSerializer::class) override val center: Float64Vector2D,
|
@Serializable(Float64Space2D.VectorSerializer::class) override val center: Float64Vector2D,
|
||||||
override val radius: Float64,
|
override val radius: Float64,
|
||||||
) : Circle2D<Double>
|
) : Circle2D<Float64>
|
||||||
|
|
||||||
public fun Circle2D(center: Vector2D<Float64>, radius: Double): Float64Circle2D = Float64Circle2D(
|
public fun Circle2D(center: Vector2D<Float64>, radius: Double): Float64Circle2D = Float64Circle2D(
|
||||||
center as? Float64Vector2D ?: Float64Vector2D(center.x, center.y),
|
center as? Float64Vector2D ?: Float64Vector2D(center.x, center.y),
|
||||||
|
@ -113,7 +113,7 @@ public object Float64Space3D : GeometrySpace<Vector3D<Float64>, Double> {
|
|||||||
/**
|
/**
|
||||||
* Vector product with the right basis
|
* Vector product with the right basis
|
||||||
*/
|
*/
|
||||||
public infix fun Vector3D<Float64>.cross(other: Vector3D<Float64>): Vector3D<Double> = vectorProduct(this, other)
|
public infix fun Vector3D<Float64>.cross(other: Vector3D<Float64>): Vector3D<Float64> = vectorProduct(this, other)
|
||||||
|
|
||||||
public val xAxis: Float64Vector3D = vector(1.0, 0.0, 0.0)
|
public val xAxis: Float64Vector3D = vector(1.0, 0.0, 0.0)
|
||||||
public val yAxis: Float64Vector3D = vector(0.0, 1.0, 0.0)
|
public val yAxis: Float64Vector3D = vector(0.0, 1.0, 0.0)
|
||||||
|
@ -90,7 +90,7 @@ public fun Float64Space3D.rotate(
|
|||||||
/**
|
/**
|
||||||
* Rotate a [Float64] vector in 3D space with a rotation matrix
|
* Rotate a [Float64] vector in 3D space with a rotation matrix
|
||||||
*/
|
*/
|
||||||
public fun Float64Space3D.rotate(vector: Float64Vector3D, matrix: Matrix<Double>): Vector3D<Float64> {
|
public fun Float64Space3D.rotate(vector: Float64Vector3D, matrix: Matrix<Float64>): Vector3D<Float64> {
|
||||||
require(matrix.colNum == 3 && matrix.rowNum == 3) { "Square 3x3 rotation matrix is required" }
|
require(matrix.colNum == 3 && matrix.rowNum == 3) { "Square 3x3 rotation matrix is required" }
|
||||||
return with(linearSpace) { (matrix dot vector).asVector3D() }
|
return with(linearSpace) { (matrix dot vector).asVector3D() }
|
||||||
}
|
}
|
||||||
@ -101,7 +101,7 @@ public fun Float64Space3D.rotate(vector: Float64Vector3D, matrix: Matrix<Double>
|
|||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
public fun Quaternion.toRotationMatrix(
|
public fun Quaternion.toRotationMatrix(
|
||||||
linearSpace: LinearSpace<Double, *> = Float64Field.linearSpace,
|
linearSpace: LinearSpace<Double, *> = Float64Field.linearSpace,
|
||||||
): Matrix<Double> {
|
): Matrix<Float64> {
|
||||||
val s = QuaternionAlgebra.norm(this).pow(-2)
|
val s = QuaternionAlgebra.norm(this).pow(-2)
|
||||||
return linearSpace.matrix(3, 3)(
|
return linearSpace.matrix(3, 3)(
|
||||||
1.0 - 2 * s * (y * y + z * z), 2 * s * (x * y - z * w), 2 * s * (x * z + y * w),
|
1.0 - 2 * s * (y * y + z * z), 2 * s * (x * y - z * w), 2 * s * (x * z + y * w),
|
||||||
@ -115,7 +115,7 @@ public fun Quaternion.toRotationMatrix(
|
|||||||
*
|
*
|
||||||
* taken from https://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/
|
* taken from https://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/
|
||||||
*/
|
*/
|
||||||
public fun Quaternion.Companion.fromRotationMatrix(matrix: Matrix<Double>): Quaternion {
|
public fun Quaternion.Companion.fromRotationMatrix(matrix: Matrix<Float64>): Quaternion {
|
||||||
require(matrix.colNum == 3 && matrix.rowNum == 3) { "Rotation matrix should be 3x3 but is ${matrix.rowNum}x${matrix.colNum}" }
|
require(matrix.colNum == 3 && matrix.rowNum == 3) { "Rotation matrix should be 3x3 but is ${matrix.rowNum}x${matrix.colNum}" }
|
||||||
val trace = matrix[0, 0] + matrix[1, 1] + matrix[2, 2]
|
val trace = matrix[0, 0] + matrix[1, 1] + matrix[2, 2]
|
||||||
|
|
||||||
@ -256,7 +256,7 @@ public fun Quaternion.Companion.fromEuler(
|
|||||||
* Based on https://github.com/mrdoob/three.js/blob/master/src/math/Euler.js
|
* Based on https://github.com/mrdoob/three.js/blob/master/src/math/Euler.js
|
||||||
*/
|
*/
|
||||||
public fun AngleVector.Companion.fromRotationMatrix(
|
public fun AngleVector.Companion.fromRotationMatrix(
|
||||||
matrix: Matrix<Double>,
|
matrix: Matrix<Float64>,
|
||||||
rotationOrder: RotationOrder,
|
rotationOrder: RotationOrder,
|
||||||
gimbaldLockThreshold: Double = 0.9999999,
|
gimbaldLockThreshold: Double = 0.9999999,
|
||||||
): AngleVector = when (rotationOrder) {
|
): AngleVector = when (rotationOrder) {
|
||||||
|
@ -9,15 +9,15 @@ import space.kscience.kmath.structures.Float64
|
|||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
fun ClosedRange<Double>.generateList(step: Double): List<Double> = generateSequence(start) { previous ->
|
fun ClosedRange<Float64>.generateList(step: Double): List<Float64> = generateSequence(start) { previous ->
|
||||||
if (previous == Double.POSITIVE_INFINITY) return@generateSequence null
|
if (previous == Double.POSITIVE_INFINITY) return@generateSequence null
|
||||||
val next = previous + step
|
val next = previous + step
|
||||||
if (next > endInclusive) null else next
|
if (next > endInclusive) null else next
|
||||||
}.toList()
|
}.toList()
|
||||||
|
|
||||||
fun grid(
|
fun grid(
|
||||||
xRange: ClosedRange<Double>,
|
xRange: ClosedRange<Float64>,
|
||||||
yRange: ClosedRange<Double>,
|
yRange: ClosedRange<Float64>,
|
||||||
step: Double,
|
step: Double,
|
||||||
): List<Pair<Double, Double>> {
|
): List<Pair<Double, Double>> {
|
||||||
val xs = xRange.generateList(step)
|
val xs = xRange.generateList(step)
|
||||||
|
@ -9,6 +9,7 @@ import kotlinx.atomicfu.atomic
|
|||||||
import kotlinx.atomicfu.getAndUpdate
|
import kotlinx.atomicfu.getAndUpdate
|
||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
import space.kscience.kmath.operations.Group
|
import space.kscience.kmath.operations.Group
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common representation for atomic counters
|
* Common representation for atomic counters
|
||||||
@ -18,7 +19,7 @@ public interface Counter<T : Any> {
|
|||||||
public val value: T
|
public val value: T
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
public fun ofDouble(): ObjectCounter<Double> = ObjectCounter(Float64Field)
|
public fun ofDouble(): ObjectCounter<Float64> = ObjectCounter(Float64Field)
|
||||||
public fun <T : Any> of(group: Group<T>): ObjectCounter<T> = ObjectCounter(group)
|
public fun <T : Any> of(group: Group<T>): ObjectCounter<T> = ObjectCounter(group)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import space.kscience.kmath.domains.center
|
|||||||
import space.kscience.kmath.linear.Point
|
import space.kscience.kmath.linear.Point
|
||||||
import space.kscience.kmath.operations.asSequence
|
import space.kscience.kmath.operations.asSequence
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,7 +50,7 @@ public interface Histogram1DBuilder<in T : Any, V : Any> : HistogramBuilder<T, V
|
|||||||
}
|
}
|
||||||
|
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public fun Histogram1DBuilder<Double, *>.fill(items: Iterable<Double>): Unit =
|
public fun Histogram1DBuilder<Double, *>.fill(items: Iterable<Float64>): Unit =
|
||||||
items.forEach(this::putValue)
|
items.forEach(this::putValue)
|
||||||
|
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@ -12,6 +12,7 @@ import space.kscience.kmath.operations.Ring
|
|||||||
import space.kscience.kmath.operations.ScaleOperations
|
import space.kscience.kmath.operations.ScaleOperations
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.MutableBufferFactory
|
import space.kscience.kmath.structures.MutableBufferFactory
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
|
|
||||||
@ -137,7 +138,7 @@ public fun <V : Any, A> Histogram.Companion.uniform1D(
|
|||||||
|
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public fun <V : Any> UniformHistogram1DGroup<V, *>.produce(
|
public fun <V : Any> UniformHistogram1DGroup<V, *>.produce(
|
||||||
buffer: Buffer<Double>,
|
buffer: Buffer<Float64>,
|
||||||
): UniformHistogram1D<V> = produce { fill(buffer) }
|
): UniformHistogram1D<V> = produce { fill(buffer) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,8 +24,8 @@ public typealias HyperSquareBin<V> = DomainBin<Double, HyperSquareDomain, V>
|
|||||||
*/
|
*/
|
||||||
public class UniformHistogramGroupND<V : Any, A : Field<V>>(
|
public class UniformHistogramGroupND<V : Any, A : Field<V>>(
|
||||||
override val valueAlgebraND: FieldOpsND<V, A>,
|
override val valueAlgebraND: FieldOpsND<V, A>,
|
||||||
private val lower: Buffer<Double>,
|
private val lower: Buffer<Float64>,
|
||||||
private val upper: Buffer<Double>,
|
private val upper: Buffer<Float64>,
|
||||||
private val binNums: IntArray = IntArray(lower.size) { 20 },
|
private val binNums: IntArray = IntArray(lower.size) { 20 },
|
||||||
private val valueBufferFactory: BufferFactory<V> = valueAlgebraND.elementAlgebra.bufferFactory,
|
private val valueBufferFactory: BufferFactory<V> = valueAlgebraND.elementAlgebra.bufferFactory,
|
||||||
) : HistogramGroupND<Double, HyperSquareDomain, V> {
|
) : HistogramGroupND<Double, HyperSquareDomain, V> {
|
||||||
@ -54,7 +54,7 @@ public class UniformHistogramGroupND<V : Any, A : Field<V>>(
|
|||||||
else -> floor((value - lower[axis]) / binSize[axis]).toInt()
|
else -> floor((value - lower[axis]) / binSize[axis]).toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getIndexOrNull(point: Buffer<Double>): IntArray = IntArray(dimension) {
|
override fun getIndexOrNull(point: Buffer<Float64>): IntArray = IntArray(dimension) {
|
||||||
getIndex(it, point[it])
|
getIndex(it, point[it])
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ public class UniformHistogramGroupND<V : Any, A : Field<V>>(
|
|||||||
val hBuilder = object : HistogramBuilder<Double, V> {
|
val hBuilder = object : HistogramBuilder<Double, V> {
|
||||||
override val defaultValue: V get() = valueAlgebraND.elementAlgebra.one
|
override val defaultValue: V get() = valueAlgebraND.elementAlgebra.one
|
||||||
|
|
||||||
override fun putValue(point: Point<Double>, value: V) = with(valueAlgebraND.elementAlgebra) {
|
override fun putValue(point: Point<Float64>, value: V) = with(valueAlgebraND.elementAlgebra) {
|
||||||
val index = getIndexOrNull(point)
|
val index = getIndexOrNull(point)
|
||||||
ndCounter[index].add(value)
|
ndCounter[index].add(value)
|
||||||
}
|
}
|
||||||
@ -120,17 +120,17 @@ public class UniformHistogramGroupND<V : Any, A : Field<V>>(
|
|||||||
*/
|
*/
|
||||||
public fun <V : Any, A : Field<V>> Histogram.Companion.uniformNDFromRanges(
|
public fun <V : Any, A : Field<V>> Histogram.Companion.uniformNDFromRanges(
|
||||||
valueAlgebraND: FieldOpsND<V, A>,
|
valueAlgebraND: FieldOpsND<V, A>,
|
||||||
vararg ranges: ClosedFloatingPointRange<Double>,
|
vararg ranges: ClosedFloatingPointRange<Float64>,
|
||||||
bufferFactory: BufferFactory<V> = valueAlgebraND.elementAlgebra.bufferFactory,
|
bufferFactory: BufferFactory<V> = valueAlgebraND.elementAlgebra.bufferFactory,
|
||||||
): UniformHistogramGroupND<V, A> = UniformHistogramGroupND(
|
): UniformHistogramGroupND<V, A> = UniformHistogramGroupND(
|
||||||
valueAlgebraND,
|
valueAlgebraND,
|
||||||
ranges.map(ClosedFloatingPointRange<Double>::start).asBuffer(),
|
ranges.map(ClosedFloatingPointRange<Float64>::start).asBuffer(),
|
||||||
ranges.map(ClosedFloatingPointRange<Double>::endInclusive).asBuffer(),
|
ranges.map(ClosedFloatingPointRange<Float64>::endInclusive).asBuffer(),
|
||||||
valueBufferFactory = bufferFactory
|
valueBufferFactory = bufferFactory
|
||||||
)
|
)
|
||||||
|
|
||||||
public fun Histogram.Companion.uniformDoubleNDFromRanges(
|
public fun Histogram.Companion.uniformDoubleNDFromRanges(
|
||||||
vararg ranges: ClosedFloatingPointRange<Double>,
|
vararg ranges: ClosedFloatingPointRange<Float64>,
|
||||||
): UniformHistogramGroupND<Double, Float64Field> = uniformNDFromRanges(Floa64FieldOpsND, *ranges)
|
): UniformHistogramGroupND<Double, Float64Field> = uniformNDFromRanges(Floa64FieldOpsND, *ranges)
|
||||||
|
|
||||||
|
|
||||||
@ -145,22 +145,22 @@ public fun Histogram.Companion.uniformDoubleNDFromRanges(
|
|||||||
*/
|
*/
|
||||||
public fun <V : Any, A : Field<V>> Histogram.Companion.uniformNDFromRanges(
|
public fun <V : Any, A : Field<V>> Histogram.Companion.uniformNDFromRanges(
|
||||||
valueAlgebraND: FieldOpsND<V, A>,
|
valueAlgebraND: FieldOpsND<V, A>,
|
||||||
vararg ranges: Pair<ClosedFloatingPointRange<Double>, Int>,
|
vararg ranges: Pair<ClosedFloatingPointRange<Float64>, Int>,
|
||||||
bufferFactory: BufferFactory<V> = valueAlgebraND.elementAlgebra.bufferFactory,
|
bufferFactory: BufferFactory<V> = valueAlgebraND.elementAlgebra.bufferFactory,
|
||||||
): UniformHistogramGroupND<V, A> = UniformHistogramGroupND(
|
): UniformHistogramGroupND<V, A> = UniformHistogramGroupND(
|
||||||
valueAlgebraND,
|
valueAlgebraND,
|
||||||
ranges
|
ranges
|
||||||
.map(Pair<ClosedFloatingPointRange<Double>, Int>::first)
|
.map(Pair<ClosedFloatingPointRange<Float64>, Int>::first)
|
||||||
.map(ClosedFloatingPointRange<Double>::start)
|
.map(ClosedFloatingPointRange<Float64>::start)
|
||||||
.asBuffer(),
|
.asBuffer(),
|
||||||
ranges
|
ranges
|
||||||
.map(Pair<ClosedFloatingPointRange<Double>, Int>::first)
|
.map(Pair<ClosedFloatingPointRange<Float64>, Int>::first)
|
||||||
.map(ClosedFloatingPointRange<Double>::endInclusive)
|
.map(ClosedFloatingPointRange<Float64>::endInclusive)
|
||||||
.asBuffer(),
|
.asBuffer(),
|
||||||
ranges.map(Pair<ClosedFloatingPointRange<Double>, Int>::second).toIntArray(),
|
ranges.map(Pair<ClosedFloatingPointRange<Float64>, Int>::second).toIntArray(),
|
||||||
valueBufferFactory = bufferFactory
|
valueBufferFactory = bufferFactory
|
||||||
)
|
)
|
||||||
|
|
||||||
public fun Histogram.Companion.uniformDoubleNDFromRanges(
|
public fun Histogram.Companion.uniformDoubleNDFromRanges(
|
||||||
vararg ranges: Pair<ClosedFloatingPointRange<Double>, Int>,
|
vararg ranges: Pair<ClosedFloatingPointRange<Float64>, Int>,
|
||||||
): UniformHistogramGroupND<Double, Float64Field> = uniformNDFromRanges(Floa64FieldOpsND, *ranges)
|
): UniformHistogramGroupND<Double, Float64Field> = uniformNDFromRanges(Floa64FieldOpsND, *ranges)
|
@ -17,7 +17,7 @@ import space.kscience.kmath.operations.ScaleOperations
|
|||||||
import space.kscience.kmath.structures.*
|
import space.kscience.kmath.structures.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
private fun <B : ClosedRange<Double>> TreeMap<Double, B>.getBin(value: Double): B? {
|
private fun <B : ClosedRange<Float64>> TreeMap<Double, B>.getBin(value: Double): B? {
|
||||||
// check ceiling entry and return it if it is what needed
|
// check ceiling entry and return it if it is what needed
|
||||||
val ceil = ceilingEntry(value)?.value
|
val ceil = ceilingEntry(value)?.value
|
||||||
if (ceil != null && value in ceil) return ceil
|
if (ceil != null && value in ceil) return ceil
|
||||||
@ -53,7 +53,7 @@ public class TreeHistogramGroup<V : Any, A>(
|
|||||||
override val bufferFactory: MutableBufferFactory<TreeHistogram<V>> = MutableBufferFactory()
|
override val bufferFactory: MutableBufferFactory<TreeHistogram<V>> = MutableBufferFactory()
|
||||||
|
|
||||||
internal inner class DomainCounter(val domain: DoubleDomain1D, val counter: Counter<V> = Counter.of(valueAlgebra)) :
|
internal inner class DomainCounter(val domain: DoubleDomain1D, val counter: Counter<V> = Counter.of(valueAlgebra)) :
|
||||||
ClosedRange<Double> by domain.range
|
ClosedRange<Float64> by domain.range
|
||||||
|
|
||||||
@PublishedApi
|
@PublishedApi
|
||||||
internal inner class TreeHistogramBuilder : Histogram1DBuilder<Double, V> {
|
internal inner class TreeHistogramBuilder : Histogram1DBuilder<Double, V> {
|
||||||
@ -153,7 +153,7 @@ public class TreeHistogramGroup<V : Any, A>(
|
|||||||
*/
|
*/
|
||||||
public fun <V : Any, A> Histogram.Companion.custom1D(
|
public fun <V : Any, A> Histogram.Companion.custom1D(
|
||||||
valueAlgebra: A,
|
valueAlgebra: A,
|
||||||
borders: Buffer<Double>,
|
borders: Buffer<Float64>,
|
||||||
): TreeHistogramGroup<V, A> where A : Ring<V>, A : ScaleOperations<V> {
|
): TreeHistogramGroup<V, A> where A : Ring<V>, A : ScaleOperations<V> {
|
||||||
val sorted = borders.sorted()
|
val sorted = borders.sorted()
|
||||||
|
|
||||||
|
@ -8,15 +8,16 @@ package space.kscience.kmath.jafama
|
|||||||
import net.jafama.FastMath
|
import net.jafama.FastMath
|
||||||
import net.jafama.StrictFastMath
|
import net.jafama.StrictFastMath
|
||||||
import space.kscience.kmath.operations.*
|
import space.kscience.kmath.operations.*
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
import space.kscience.kmath.structures.MutableBufferFactory
|
import space.kscience.kmath.structures.MutableBufferFactory
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A field for [Double] (using FastMath) without boxing. Does not produce appropriate field element.
|
* A field for [Double] (using FastMath) without boxing. Does not produce appropriate field element.
|
||||||
*/
|
*/
|
||||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
||||||
public object JafamaDoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOperations<Double> {
|
public object JafamaDoubleField : ExtendedField<Float64>, Norm<Double, Double>, ScaleOperations<Float64> {
|
||||||
|
|
||||||
override val bufferFactory: MutableBufferFactory<Double> get() = DoubleField.bufferFactory
|
override val bufferFactory: MutableBufferFactory<Float64> get() = DoubleField.bufferFactory
|
||||||
|
|
||||||
override inline val zero: Double get() = 0.0
|
override inline val zero: Double get() = 0.0
|
||||||
override inline val one: Double get() = 1.0
|
override inline val one: Double get() = 1.0
|
||||||
@ -68,9 +69,9 @@ public object JafamaDoubleField : ExtendedField<Double>, Norm<Double, Double>, S
|
|||||||
* A field for [Double] (using StrictMath) without boxing. Does not produce appropriate field element.
|
* A field for [Double] (using StrictMath) without boxing. Does not produce appropriate field element.
|
||||||
*/
|
*/
|
||||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
||||||
public object StrictJafamaDoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOperations<Double> {
|
public object StrictJafamaDoubleField : ExtendedField<Float64>, Norm<Double, Double>, ScaleOperations<Float64> {
|
||||||
|
|
||||||
override val bufferFactory: MutableBufferFactory<Double> get() = DoubleField.bufferFactory
|
override val bufferFactory: MutableBufferFactory<Float64> get() = DoubleField.bufferFactory
|
||||||
|
|
||||||
override inline val zero: Double get() = 0.0
|
override inline val zero: Double get() = 0.0
|
||||||
override inline val one: Double get() = 1.0
|
override inline val one: Double get() = 1.0
|
||||||
|
@ -14,56 +14,57 @@ import space.kscience.kmath.nd.StructureND
|
|||||||
import space.kscience.kmath.operations.ExponentialOperations
|
import space.kscience.kmath.operations.ExponentialOperations
|
||||||
import space.kscience.kmath.operations.Float64Field
|
import space.kscience.kmath.operations.Float64Field
|
||||||
import space.kscience.kmath.operations.TrigonometricOperations
|
import space.kscience.kmath.operations.TrigonometricOperations
|
||||||
|
import space.kscience.kmath.structures.Float64
|
||||||
|
|
||||||
public class MultikDoubleAlgebra(
|
public class MultikDoubleAlgebra(
|
||||||
multikEngine: Engine,
|
multikEngine: Engine,
|
||||||
) : MultikDivisionTensorAlgebra<Double, Float64Field>(multikEngine),
|
) : MultikDivisionTensorAlgebra<Double, Float64Field>(multikEngine),
|
||||||
TrigonometricOperations<StructureND<Double>>, ExponentialOperations<StructureND<Double>> {
|
TrigonometricOperations<StructureND<Float64>>, ExponentialOperations<StructureND<Float64>> {
|
||||||
override val elementAlgebra: Float64Field get() = Float64Field
|
override val elementAlgebra: Float64Field get() = Float64Field
|
||||||
override val dataType: DataType get() = DataType.DoubleDataType
|
override val dataType: DataType get() = DataType.DoubleDataType
|
||||||
|
|
||||||
override fun sin(arg: StructureND<Double>): MultikTensor<Double> =
|
override fun sin(arg: StructureND<Float64>): MultikTensor<Float64> =
|
||||||
multikMath.mathEx.sin(arg.asMultik().array).wrap()
|
multikMath.mathEx.sin(arg.asMultik().array).wrap()
|
||||||
|
|
||||||
override fun cos(arg: StructureND<Double>): MultikTensor<Double> =
|
override fun cos(arg: StructureND<Float64>): MultikTensor<Float64> =
|
||||||
multikMath.mathEx.cos(arg.asMultik().array).wrap()
|
multikMath.mathEx.cos(arg.asMultik().array).wrap()
|
||||||
|
|
||||||
override fun tan(arg: StructureND<Double>): MultikTensor<Double> = sin(arg) / cos(arg)
|
override fun tan(arg: StructureND<Float64>): MultikTensor<Float64> = sin(arg) / cos(arg)
|
||||||
|
|
||||||
@PerformancePitfall
|
@PerformancePitfall
|
||||||
override fun asin(arg: StructureND<Double>): MultikTensor<Double> = arg.map { asin(it) }
|
override fun asin(arg: StructureND<Float64>): MultikTensor<Float64> = arg.map { asin(it) }
|
||||||
|
|
||||||
@PerformancePitfall
|
@PerformancePitfall
|
||||||
override fun acos(arg: StructureND<Double>): MultikTensor<Double> = arg.map { acos(it) }
|
override fun acos(arg: StructureND<Float64>): MultikTensor<Float64> = arg.map { acos(it) }
|
||||||
|
|
||||||
@PerformancePitfall
|
@PerformancePitfall
|
||||||
override fun atan(arg: StructureND<Double>): MultikTensor<Double> = arg.map { atan(it) }
|
override fun atan(arg: StructureND<Float64>): MultikTensor<Float64> = arg.map { atan(it) }
|
||||||
|
|
||||||
override fun exp(arg: StructureND<Double>): MultikTensor<Double> =
|
override fun exp(arg: StructureND<Float64>): MultikTensor<Float64> =
|
||||||
multikMath.mathEx.exp(arg.asMultik().array).wrap()
|
multikMath.mathEx.exp(arg.asMultik().array).wrap()
|
||||||
|
|
||||||
override fun ln(arg: StructureND<Double>): MultikTensor<Double> = multikMath.mathEx.log(arg.asMultik().array).wrap()
|
override fun ln(arg: StructureND<Float64>): MultikTensor<Float64> = multikMath.mathEx.log(arg.asMultik().array).wrap()
|
||||||
|
|
||||||
override fun sinh(arg: StructureND<Double>): MultikTensor<Double> = (exp(arg) - exp(-arg)) / 2.0
|
override fun sinh(arg: StructureND<Float64>): MultikTensor<Float64> = (exp(arg) - exp(-arg)) / 2.0
|
||||||
|
|
||||||
override fun cosh(arg: StructureND<Double>): MultikTensor<Double> = (exp(arg) + exp(-arg)) / 2.0
|
override fun cosh(arg: StructureND<Float64>): MultikTensor<Float64> = (exp(arg) + exp(-arg)) / 2.0
|
||||||
|
|
||||||
override fun tanh(arg: StructureND<Double>): MultikTensor<Double> {
|
override fun tanh(arg: StructureND<Float64>): MultikTensor<Float64> {
|
||||||
val expPlus = exp(arg)
|
val expPlus = exp(arg)
|
||||||
val expMinus = exp(-arg)
|
val expMinus = exp(-arg)
|
||||||
return (expPlus - expMinus) / (expPlus + expMinus)
|
return (expPlus - expMinus) / (expPlus + expMinus)
|
||||||
}
|
}
|
||||||
|
|
||||||
@PerformancePitfall
|
@PerformancePitfall
|
||||||
override fun asinh(arg: StructureND<Double>): MultikTensor<Double> = arg.map { asinh(it) }
|
override fun asinh(arg: StructureND<Float64>): MultikTensor<Float64> = arg.map { asinh(it) }
|
||||||
|
|
||||||
@PerformancePitfall
|
@PerformancePitfall
|
||||||
override fun acosh(arg: StructureND<Double>): MultikTensor<Double> = arg.map { acosh(it) }
|
override fun acosh(arg: StructureND<Float64>): MultikTensor<Float64> = arg.map { acosh(it) }
|
||||||
|
|
||||||
@PerformancePitfall
|
@PerformancePitfall
|
||||||
override fun atanh(arg: StructureND<Double>): MultikTensor<Double> = arg.map { atanh(it) }
|
override fun atanh(arg: StructureND<Float64>): MultikTensor<Float64> = arg.map { atanh(it) }
|
||||||
|
|
||||||
override fun scalar(value: Double): MultikTensor<Double> = Multik.ndarrayOf(value).wrap()
|
override fun scalar(value: Double): MultikTensor<Float64> = Multik.ndarrayOf(value).wrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
//public val Double.Companion.multikAlgebra: MultikTensorAlgebra<Double, DoubleField> get() = MultikDoubleAlgebra
|
//public val Double.Companion.multikAlgebra: MultikTensorAlgebra<Double, DoubleField> get() = MultikDoubleAlgebra
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user