From ba3c9b6d45cdb724d8f2e40d8a8e236e4dfd8b48 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Fri, 16 Apr 2021 09:47:30 +0300 Subject: [PATCH] BigIntBenchmarks. cleanup --- examples/build.gradle.kts | 8 +++++ .../kmath/benchmarks/BigIntBenchmark.kt | 32 +++++++++++++++++++ .../kscience/kmath/commons/linear/CMMatrix.kt | 4 +-- .../kmath/structures/NumberNDFieldTest.kt | 2 +- .../space/kscience/kmath/ejml/EjmlMatrix.kt | 2 +- .../kmath/integration/GaussIntegrator.kt | 20 +++++++++++- .../integration/GaussIntegratorRuleFactory.kt | 19 ++++++----- .../histogram/MultivariateHistogramTest.kt | 2 +- .../kscience/kmath/internal/InternalGamma.kt | 2 +- .../kscience/kmath/internal/InternalUtils.kt | 2 +- .../NoDerivFunctionOptimization.kt | 2 +- .../kmath/stat/RandomSourceGenerator.kt | 2 +- .../kscience/kmath/viktor/ViktorBuffer.kt | 2 +- 13 files changed, 78 insertions(+), 21 deletions(-) create mode 100644 examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts index d02e5268e..29aa1af6e 100644 --- a/examples/build.gradle.kts +++ b/examples/build.gradle.kts @@ -103,6 +103,14 @@ benchmark { iterationTimeUnit = "ms" // time unity for iterationTime, default is seconds include("MatrixInverseBenchmark") } + + configurations.register("bigInt") { + warmups = 1 // number of warmup iterations + iterations = 3 // number of iterations + iterationTime = 500 // time in seconds per iteration + iterationTimeUnit = "ms" // time unity for iterationTime, default is seconds + include("BigIntBenchmark") + } } kotlin.sourceSets.all { diff --git a/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt new file mode 100644 index 000000000..543d51bee --- /dev/null +++ b/examples/src/benchmarks/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt @@ -0,0 +1,32 @@ +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.operations.BigIntField +import space.kscience.kmath.operations.JBigIntegerField +import space.kscience.kmath.operations.invoke + +@State(Scope.Benchmark) +internal class BigIntBenchmark { + @Benchmark + fun kmAdd(blackhole: Blackhole) = BigIntField{ + blackhole.consume(one + number(Int.MAX_VALUE)) + } + + @Benchmark + fun jvmAdd(blackhole: Blackhole) = JBigIntegerField{ + blackhole.consume(one + number(Int.MAX_VALUE)) + } + + @Benchmark + fun kmMultiply(blackhole: Blackhole) = BigIntField{ + blackhole.consume(number(Int.MAX_VALUE)* number(Int.MAX_VALUE)) + } + + @Benchmark + fun jvmMultiply(blackhole: Blackhole) = JBigIntegerField{ + blackhole.consume(number(Int.MAX_VALUE)* number(Int.MAX_VALUE)) + } +} \ No newline at end of file diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt index 80929e6b9..99219c19f 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt @@ -9,14 +9,14 @@ import space.kscience.kmath.structures.DoubleBuffer import kotlin.reflect.KClass import kotlin.reflect.cast -public inline class CMMatrix(public val origin: RealMatrix) : Matrix { +public class CMMatrix(public val origin: RealMatrix) : Matrix { public override val rowNum: Int get() = origin.rowDimension public override val colNum: Int get() = origin.columnDimension public override operator fun get(i: Int, j: Int): Double = origin.getEntry(i, j) } -public inline class CMVector(public val origin: RealVector) : Point { +public class CMVector(public val origin: RealVector) : Point { public override val size: Int get() = origin.dimension public override operator fun get(index: Int): Double = origin.getEntry(index) diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt index 376415a56..01fde190f 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt @@ -70,7 +70,7 @@ class NumberNDFieldTest { object L2Norm : Norm, Double> { override fun norm(arg: StructureND): Double = - kotlin.math.sqrt(arg.elements().sumByDouble { it.second.toDouble() }) + kotlin.math.sqrt(arg.elements().sumOf { it.second.toDouble() }) } @Test diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt index 10afd6ec2..30b6dc2ee 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt @@ -9,7 +9,7 @@ import space.kscience.kmath.linear.Matrix * @property origin the underlying [SimpleMatrix]. * @author Iaroslav Postovalov */ -public inline class EjmlMatrix(public val origin: SimpleMatrix) : Matrix { +public class EjmlMatrix(public val origin: SimpleMatrix) : Matrix { public override val rowNum: Int get() = origin.numRows() public override val colNum: Int get() = origin.numCols() diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt index a4f79f542..9a950e05e 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt @@ -31,7 +31,7 @@ public class GaussIntegrator> internal constructor( init { require(points.size == weights.size) { "Inconsistent points and weights sizes" } - require(points.indices.all { i -> i == 0 || points[i] > points[i - 1] }){"Integration nodes must be sorted"} + require(points.indices.all { i -> i == 0 || points[i] > points[i - 1] }) { "Integration nodes must be sorted" } } override fun integrate(integrand: UnivariateIntegrand): UnivariateIntegrand = with(algebra) { @@ -51,6 +51,9 @@ public class GaussIntegrator> internal constructor( public companion object { + /** + * Integrate given [function] in a [range] with Gauss-Legendre quadrature with [numPoints] points. + */ public fun integrate( range: ClosedRange, numPoints: Int = 100, @@ -63,5 +66,20 @@ public class GaussIntegrator> internal constructor( UnivariateIntegrand(function, IntegrationRange(range)) ) } + +// public fun integrate( +// borders: List, +// numPoints: Int = 10, +// ruleFactory: GaussIntegratorRuleFactory = GaussLegendreDoubleRuleFactory, +// features: List = emptyList(), +// function: (Double) -> Double, +// ): UnivariateIntegrand { +// require(borders.indices.all { i -> i == 0 || borders[i] > borders[i - 1] }){"Borders are not sorted"} +// +// val (points, weights) = ruleFactory.build(numPoints, range) +// return GaussIntegrator(DoubleField, points, weights).integrate( +// UnivariateIntegrand(function, IntegrationRange(range)) +// ) +// } } } \ No newline at end of file diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt index 678e6bf0a..be7e298af 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt @@ -10,6 +10,7 @@ import kotlin.native.concurrent.ThreadLocal public interface GaussIntegratorRuleFactory { public val algebra: Field public val bufferFactory: BufferFactory + public fun build(numPoints: Int): Pair, Buffer> public companion object { @@ -20,6 +21,7 @@ public interface GaussIntegratorRuleFactory { /** * Create an integration rule by scaling existing normalized rule + * */ public fun > GaussIntegratorRuleFactory.build( numPoints: Int, @@ -45,8 +47,8 @@ public fun > GaussIntegratorRuleFactory.build( /** * Gauss integrator rule based ont Legendre polynomials. All rules are normalized to * - * The code is based on Apache Commons Math source code version 3.6.1 - * https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/analysis/integration/gauss/LegendreRuleFactory.html + * The code is based on [Apache Commons Math source code version 3.6.1](https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/analysis/integration/gauss/LegendreRuleFactory.html) + * */ @ThreadLocal public object GaussLegendreDoubleRuleFactory : GaussIntegratorRuleFactory { @@ -96,12 +98,12 @@ public object GaussLegendreDoubleRuleFactory : GaussIntegratorRuleFactory= -0.5) diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/internal/InternalUtils.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/internal/InternalUtils.kt index 832689b27..b0e4ae9f3 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/internal/InternalUtils.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/internal/InternalUtils.kt @@ -21,7 +21,7 @@ internal object InternalUtils { fun validateProbabilities(probabilities: DoubleArray?): Double { require(!(probabilities == null || probabilities.isEmpty())) { "Probabilities must not be empty." } - val sumProb = probabilities.sumByDouble { prob -> + val sumProb = probabilities.sumOf { prob -> require(!(prob < 0 || prob.isInfinite() || prob.isNaN())) { "Invalid probability: $prob" } prob } diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/NoDerivFunctionOptimization.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/NoDerivFunctionOptimization.kt index b8785dd8c..b2ff5aef4 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/NoDerivFunctionOptimization.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/NoDerivFunctionOptimization.kt @@ -40,7 +40,7 @@ public interface NoDerivFunctionOptimization : Optimization { require(y.size == yErr.size) { "Y and yErr buffer should of the same size" } return Expression { arguments -> - x.indices.sumByDouble { + x.indices.sumOf { val xValue = x[it] val yValue = y[it] val yErrValue = yErr[it] diff --git a/kmath-stat/src/jvmMain/kotlin/space/kscience/kmath/stat/RandomSourceGenerator.kt b/kmath-stat/src/jvmMain/kotlin/space/kscience/kmath/stat/RandomSourceGenerator.kt index f6a5d6605..d72f82ffd 100644 --- a/kmath-stat/src/jvmMain/kotlin/space/kscience/kmath/stat/RandomSourceGenerator.kt +++ b/kmath-stat/src/jvmMain/kotlin/space/kscience/kmath/stat/RandomSourceGenerator.kt @@ -32,7 +32,7 @@ public class RandomSourceGenerator internal constructor(public val source: Rando * * @property generator the underlying [RandomGenerator] object. */ -public inline class RandomGeneratorProvider(public val generator: RandomGenerator) : UniformRandomProvider { +public class RandomGeneratorProvider(public val generator: RandomGenerator) : UniformRandomProvider { /** * Generates a [Boolean] value. * diff --git a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt index 1592763db..9d817112d 100644 --- a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt +++ b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt @@ -4,7 +4,7 @@ import org.jetbrains.bio.viktor.F64FlatArray import space.kscience.kmath.structures.MutableBuffer @Suppress("NOTHING_TO_INLINE", "OVERRIDE_BY_INLINE") -public inline class ViktorBuffer(public val flatArray: F64FlatArray) : MutableBuffer { +public class ViktorBuffer(public val flatArray: F64FlatArray) : MutableBuffer { public override val size: Int get() = flatArray.size