integrate: Jafama + KMath #357
@ -200,6 +200,12 @@ One can still use generic algebras though.
|
|||||||
> **Maturity**: PROTOTYPE
|
> **Maturity**: PROTOTYPE
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
|
* ### [kmath-jafama](kmath-jafama)
|
||||||
|
>
|
||||||
|
>
|
||||||
|
> **Maturity**: PROTOTYPE
|
||||||
|
<hr/>
|
||||||
|
|
||||||
* ### [kmath-jupyter](kmath-jupyter)
|
* ### [kmath-jupyter](kmath-jupyter)
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
|
@ -30,6 +30,7 @@ kotlin {
|
|||||||
implementation(project(":kmath-stat"))
|
implementation(project(":kmath-stat"))
|
||||||
implementation(project(":kmath-dimensions"))
|
implementation(project(":kmath-dimensions"))
|
||||||
implementation(project(":kmath-for-real"))
|
implementation(project(":kmath-for-real"))
|
||||||
|
implementation(project(":kmath-jafama"))
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-benchmark-runtime:0.3.0")
|
implementation("org.jetbrains.kotlinx:kotlinx-benchmark-runtime:0.3.0")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,7 +43,6 @@ kotlin {
|
|||||||
implementation(project(":kmath-kotlingrad"))
|
implementation(project(":kmath-kotlingrad"))
|
||||||
implementation(project(":kmath-viktor"))
|
implementation(project(":kmath-viktor"))
|
||||||
implementation("org.nd4j:nd4j-native:1.0.0-beta7")
|
implementation("org.nd4j:nd4j-native:1.0.0-beta7")
|
||||||
|
|
||||||
// uncomment if your system supports AVX2
|
// uncomment if your system supports AVX2
|
||||||
// val os = System.getProperty("os.name")
|
// val os = System.getProperty("os.name")
|
||||||
//
|
//
|
||||||
@ -95,6 +95,11 @@ benchmark {
|
|||||||
commonConfiguration()
|
commonConfiguration()
|
||||||
include("BigIntBenchmark")
|
include("BigIntBenchmark")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configurations.register("jafamaDouble") {
|
||||||
|
commonConfiguration()
|
||||||
|
include("JafamaBenchmark")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fix kotlinx-benchmarks bug
|
// Fix kotlinx-benchmarks bug
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018-2021 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.benchmarks
|
||||||
|
|
||||||
|
import kotlinx.benchmark.Blackhole
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark
|
||||||
|
import org.openjdk.jmh.annotations.Scope
|
||||||
|
import org.openjdk.jmh.annotations.State
|
||||||
|
import space.kscience.kmath.jafama.JafamaDoubleField
|
||||||
|
import space.kscience.kmath.jafama.StrictJafamaDoubleField
|
||||||
|
import space.kscience.kmath.operations.DoubleField
|
||||||
|
import space.kscience.kmath.operations.invoke
|
||||||
|
import kotlin.math.cos
|
||||||
|
import kotlin.math.exp
|
||||||
|
import kotlin.math.pow
|
||||||
|
|
||||||
|
|
||||||
|
@State(Scope.Benchmark)
|
||||||
|
internal class JafamaBenchmark {
|
||||||
|
@Benchmark
|
||||||
|
fun jafamaBench(blackhole: Blackhole) = invokeBenchmarks(jafama, blackhole)
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
fun coreBench(blackhole: Blackhole) = invokeBenchmarks(core,blackhole)
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
fun strictJafamaBench(blackhole: Blackhole) = invokeBenchmarks(strictJafama,blackhole)
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
fun kotlinMathBench(blackhole: Blackhole) = invokeBenchmarks(kotlinMath, blackhole)
|
||||||
|
|
||||||
|
private fun invokeBenchmarks(expr: Double, blackhole: Blackhole) {
|
||||||
|
blackhole.consume(expr)
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
private val x: Double = Double.MAX_VALUE
|
||||||
|
|
||||||
|
private val jafama = JafamaDoubleField{
|
||||||
|
x * power(x, 1_000_000) * exp(x) / cos(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val kotlinMath = x * x.pow(1_000_000) * exp(x) / cos(x)
|
||||||
|
|
||||||
|
private val core = DoubleField {
|
||||||
|
x * power(x, 1_000_000) * exp(x) / cos(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val strictJafama = StrictJafamaDoubleField {
|
||||||
|
x * power(x, 1_000_000) * exp(x) / cos(x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -44,6 +44,8 @@ dependencies {
|
|||||||
implementation("org.slf4j:slf4j-simple:1.7.30")
|
implementation("org.slf4j:slf4j-simple:1.7.30")
|
||||||
// plotting
|
// plotting
|
||||||
implementation("space.kscience:plotlykt-server:0.4.0")
|
implementation("space.kscience:plotlykt-server:0.4.0")
|
||||||
|
//jafama
|
||||||
|
implementation(project(":kmath-jafama"))
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin.sourceSets.all {
|
kotlin.sourceSets.all {
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018-2021 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.jafama
|
||||||
|
|
||||||
|
import net.jafama.FastMath
|
||||||
|
|
||||||
|
|
||||||
|
fun main(){
|
||||||
|
val a = JafamaDoubleField.number(2.0)
|
||||||
|
val b = StrictJafamaDoubleField.power(FastMath.E,a)
|
||||||
|
|
||||||
|
println(JafamaDoubleField.add(b,a))
|
||||||
|
println(StrictJafamaDoubleField.ln(b))
|
||||||
|
}
|
80
kmath-jafama/README.md
Normal file
80
kmath-jafama/README.md
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
# Module kmath-jafama
|
||||||
|
|
||||||
|
Jafama based implementation of DoubleField of kmath-operations.
|
||||||
|
|
||||||
|
- JafamaDoubleField : DoubleField implementation using FastMath
|
||||||
|
- StrictJafamaDoubleField - DoubleField implementation using StrictFastMath
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
Different Operations on DoubleField
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
package space.kscience.kmath.jafama
|
||||||
|
|
||||||
|
import net.jafama.FastMath
|
||||||
|
|
||||||
|
|
||||||
|
fun main(){
|
||||||
|
val a = JafamaDoubleField.number(2.0)
|
||||||
|
val b = StrictJafamaDoubleField.power(FastMath.E,a)
|
||||||
|
println(JafamaDoubleField.add(b,a))
|
||||||
|
println(StrictJafamaDoubleField.ln(b))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Benchmarks
|
||||||
|
Comparing Operations on DoubleField and JafamaDoubleField
|
||||||
|
```bash
|
||||||
|
jvm: space.kscience.kmath.benchmarks.JafamaBenchmark.coreBench
|
||||||
|
|
||||||
|
Warm-up 1: 384414358.081 ops/s
|
||||||
|
Iteration 1: 374827571.951 ops/s
|
||||||
|
Iteration 2: 479335182.332 ops/s
|
||||||
|
Iteration 3: 475483069.577 ops/s
|
||||||
|
Iteration 4: 478235949.414 ops/s
|
||||||
|
Iteration 5: 472256385.114 ops/s
|
||||||
|
|
||||||
|
456027631.678 ±(99.9%) 175106815.384 ops/s [Average]
|
||||||
|
(min, avg, max) = (374827571.951, 456027631.678, 479335182.332), stdev = 45474683.880
|
||||||
|
CI (99.9%): [280920816.294, 631134447.061] (assumes normal distribution)
|
||||||
|
|
||||||
|
jvm: space.kscience.kmath.benchmarks.JafamaBenchmark.jafamaBench
|
||||||
|
|
||||||
|
Warm-up 1: 359418665.041 ops/s
|
||||||
|
Iteration 1: 335704885.798 ops/s
|
||||||
|
Iteration 2: 427684801.542 ops/s
|
||||||
|
Iteration 3: 452193034.265 ops/s
|
||||||
|
Iteration 4: 433855064.931 ops/s
|
||||||
|
Iteration 5: 453863386.566 ops/s
|
||||||
|
|
||||||
|
420660234.620 ±(99.9%) 188028426.875 ops/s [Average]
|
||||||
|
(min, avg, max) = (335704885.798, 420660234.620, 453863386.566), stdev = 48830385.349
|
||||||
|
CI (99.9%): [232631807.746, 608688661.495] (assumes normal distribution)
|
||||||
|
|
||||||
|
jvm: space.kscience.kmath.benchmarks.JafamaBenchmark.kotlinMathBench
|
||||||
|
|
||||||
|
Warm-up 1: 371570418.113 ops/s
|
||||||
|
Iteration 1: 379281146.127 ops/s
|
||||||
|
Iteration 2: 465234403.109 ops/s
|
||||||
|
Iteration 3: 470621634.240 ops/s
|
||||||
|
Iteration 4: 467074553.006 ops/s
|
||||||
|
Iteration 5: 466424840.144 ops/s
|
||||||
|
|
||||||
|
449727315.325 ±(99.9%) 151837475.500 ops/s [Average]
|
||||||
|
(min, avg, max) = (379281146.127, 449727315.325, 470621634.240), stdev = 39431710.207
|
||||||
|
CI (99.9%): [297889839.825, 601564790.825] (assumes normal distribution)
|
||||||
|
|
||||||
|
jvm: space.kscience.kmath.benchmarks.JafamaBenchmark.strictJafamaBench
|
||||||
|
|
||||||
|
Warm-up 1: 371241281.065 ops/s
|
||||||
|
Iteration 1: 374490259.387 ops/s
|
||||||
|
Iteration 2: 464995837.424 ops/s
|
||||||
|
Iteration 3: 469788706.385 ops/s
|
||||||
|
Iteration 4: 469528470.682 ops/s
|
||||||
|
Iteration 5: 456727921.978 ops/s
|
||||||
|
|
||||||
|
447106239.171 ±(99.9%) 157629035.980 ops/s [Average]
|
||||||
|
(min, avg, max) = (374490259.387, 447106239.171, 469788706.385), stdev = 40935760.071
|
||||||
|
CI (99.9%): [289477203.192, 604735275.151] (assumes normal distribution)
|
||||||
|
```
|
20
kmath-jafama/build.gradle.kts
Normal file
20
kmath-jafama/build.gradle.kts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
plugins {
|
||||||
|
id("ru.mipt.npm.gradle.jvm")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
api(project(":kmath-core"))
|
||||||
|
api("net.jafama:jafama:2.3.2")
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
readme {
|
||||||
|
maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin.sourceSets.all {
|
||||||
|
languageSettings.useExperimentalAnnotation("space.kscience.kmath.misc.UnstableKMathAPI")
|
||||||
|
}
|
@ -0,0 +1,106 @@
|
|||||||
|
package space.kscience.kmath.jafama
|
||||||
|
|
||||||
|
import space.kscience.kmath.operations.*
|
||||||
|
import net.jafama.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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")
|
||||||
|
public object JafamaDoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOperations<Double> {
|
||||||
|
public override val zero: Double get() = 0.0
|
||||||
|
public override val one: Double get() = 1.0
|
||||||
|
|
||||||
|
public override fun number(value: Number): Double = value.toDouble()
|
||||||
|
|
||||||
|
public override fun binaryOperationFunction(operation: String): (left: Double, right: Double) -> Double =
|
||||||
|
when (operation) {
|
||||||
|
PowerOperations.POW_OPERATION -> ::power
|
||||||
|
else -> super<ExtendedField>.binaryOperationFunction(operation)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun add(a: Double, b: Double): Double = a + b
|
||||||
|
|
||||||
|
public override fun multiply(a: Double, b: Double): Double = a * b
|
||||||
|
public override fun divide(a: Double, b: Double): Double = a / b
|
||||||
|
|
||||||
|
public override fun scale(a: Double, value: Double): Double = a * value
|
||||||
|
|
||||||
|
public override fun sin(arg: Double): Double = FastMath.sin(arg)
|
||||||
|
public override fun cos(arg: Double): Double = FastMath.cos(arg)
|
||||||
|
public override fun tan(arg: Double): Double = FastMath.tan(arg)
|
||||||
|
public override fun acos(arg: Double): Double = FastMath.acos(arg)
|
||||||
|
public override fun asin(arg: Double): Double = FastMath.asin(arg)
|
||||||
|
public override fun atan(arg: Double): Double = FastMath.atan(arg)
|
||||||
|
|
||||||
|
public override fun sinh(arg: Double): Double = FastMath.sinh(arg)
|
||||||
|
public override fun cosh(arg: Double): Double = FastMath.cosh(arg)
|
||||||
|
public override fun tanh(arg: Double): Double = FastMath.tanh(arg)
|
||||||
|
public override fun asinh(arg: Double): Double = FastMath.asinh(arg)
|
||||||
|
public override fun acosh(arg: Double): Double = FastMath.acosh(arg)
|
||||||
|
public override fun atanh(arg: Double): Double = FastMath.atanh(arg)
|
||||||
|
|
||||||
|
public override fun power(arg: Double, pow: Number): Double = FastMath.pow(arg, pow.toDouble())
|
||||||
|
public override fun exp(arg: Double): Double = FastMath.exp(arg)
|
||||||
|
public override fun ln(arg: Double): Double = FastMath.log(arg)
|
||||||
|
|
||||||
|
public override fun norm(arg: Double): Double = FastMath.abs(arg)
|
||||||
|
|
||||||
|
public override fun Double.unaryMinus(): Double = -this
|
||||||
|
public override fun Double.plus(b: Double): Double = this + b
|
||||||
|
public override fun Double.minus(b: Double): Double = this - b
|
||||||
|
public override fun Double.times(b: Double): Double = this * b
|
||||||
|
public override fun Double.div(b: Double): Double = this / b
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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")
|
||||||
|
public object StrictJafamaDoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOperations<Double> {
|
||||||
|
public override val zero: Double get() = 0.0
|
||||||
|
public override val one: Double get() = 1.0
|
||||||
|
|
||||||
|
public override fun number(value: Number): Double = value.toDouble()
|
||||||
|
|
||||||
|
public override fun binaryOperationFunction(operation: String): (left: Double, right: Double) -> Double =
|
||||||
|
when (operation) {
|
||||||
|
PowerOperations.POW_OPERATION -> ::power
|
||||||
|
else -> super<ExtendedField>.binaryOperationFunction(operation)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun add(a: Double, b: Double): Double = a + b
|
||||||
|
|
||||||
|
public override fun multiply(a: Double, b: Double): Double = a * b
|
||||||
|
public override fun divide(a: Double, b: Double): Double = a / b
|
||||||
|
|
||||||
|
public override fun scale(a: Double, value: Double): Double = a * value
|
||||||
|
|
||||||
|
public override fun sin(arg: Double): Double = StrictFastMath.sin(arg)
|
||||||
|
public override fun cos(arg: Double): Double = StrictFastMath.cos(arg)
|
||||||
|
public override fun tan(arg: Double): Double = StrictFastMath.tan(arg)
|
||||||
|
public override fun acos(arg: Double): Double = StrictFastMath.acos(arg)
|
||||||
|
public override fun asin(arg: Double): Double = StrictFastMath.asin(arg)
|
||||||
|
public override fun atan(arg: Double): Double = StrictFastMath.atan(arg)
|
||||||
|
|
||||||
|
public override fun sinh(arg: Double): Double = StrictFastMath.sinh(arg)
|
||||||
|
public override fun cosh(arg: Double): Double = StrictFastMath.cosh(arg)
|
||||||
|
public override fun tanh(arg: Double): Double = StrictFastMath.tanh(arg)
|
||||||
|
public override fun asinh(arg: Double): Double = StrictFastMath.asinh(arg)
|
||||||
|
public override fun acosh(arg: Double): Double = StrictFastMath.acosh(arg)
|
||||||
|
public override fun atanh(arg: Double): Double = StrictFastMath.atanh(arg)
|
||||||
|
|
||||||
|
public override fun power(arg: Double, pow: Number): Double = StrictFastMath.pow(arg, pow.toDouble())
|
||||||
|
public override fun exp(arg: Double): Double = StrictFastMath.exp(arg)
|
||||||
|
public override fun ln(arg: Double): Double = StrictFastMath.log(arg)
|
||||||
|
|
||||||
|
public override fun norm(arg: Double): Double = StrictFastMath.abs(arg)
|
||||||
|
|
||||||
|
public override fun Double.unaryMinus(): Double = -this
|
||||||
|
public override fun Double.plus(b: Double): Double = this + b
|
||||||
|
public override fun Double.minus(b: Double): Double = this - b
|
||||||
|
public override fun Double.times(b: Double): Double = this * b
|
||||||
|
public override fun Double.div(b: Double): Double = this / b
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -43,6 +43,7 @@ include(
|
|||||||
":kmath-tensors",
|
":kmath-tensors",
|
||||||
":kmath-jupyter",
|
":kmath-jupyter",
|
||||||
":kmath-symja",
|
":kmath-symja",
|
||||||
|
":kmath-jafama",
|
||||||
":examples",
|
":examples",
|
||||||
":benchmarks"
|
":benchmarks"
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user