Dev #280

Merged
altavir merged 99 commits from dev into master 2021-04-16 19:45:55 +03:00
13 changed files with 78 additions and 21 deletions
Showing only changes of commit ba3c9b6d45 - Show all commits

View File

@ -103,6 +103,14 @@ benchmark {
iterationTimeUnit = "ms" // time unity for iterationTime, default is seconds iterationTimeUnit = "ms" // time unity for iterationTime, default is seconds
include("MatrixInverseBenchmark") 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 { kotlin.sourceSets.all {

View File

@ -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))
}
}

View File

@ -9,14 +9,14 @@ import space.kscience.kmath.structures.DoubleBuffer
import kotlin.reflect.KClass import kotlin.reflect.KClass
import kotlin.reflect.cast import kotlin.reflect.cast
public inline class CMMatrix(public val origin: RealMatrix) : Matrix<Double> { public class CMMatrix(public val origin: RealMatrix) : Matrix<Double> {
public override val rowNum: Int get() = origin.rowDimension public override val rowNum: Int get() = origin.rowDimension
public override val colNum: Int get() = origin.columnDimension public override val colNum: Int get() = origin.columnDimension
public override operator fun get(i: Int, j: Int): Double = origin.getEntry(i, j) public override operator fun get(i: Int, j: Int): Double = origin.getEntry(i, j)
} }
public inline class CMVector(public val origin: RealVector) : Point<Double> { public class CMVector(public val origin: RealVector) : Point<Double> {
public override val size: Int get() = origin.dimension public override val size: Int get() = origin.dimension
public override operator fun get(index: Int): Double = origin.getEntry(index) public override operator fun get(index: Int): Double = origin.getEntry(index)

View File

@ -70,7 +70,7 @@ class NumberNDFieldTest {
object L2Norm : Norm<StructureND<out Number>, Double> { object L2Norm : Norm<StructureND<out Number>, Double> {
override fun norm(arg: StructureND<out Number>): Double = override fun norm(arg: StructureND<out Number>): Double =
kotlin.math.sqrt(arg.elements().sumByDouble { it.second.toDouble() }) kotlin.math.sqrt(arg.elements().sumOf { it.second.toDouble() })
} }
@Test @Test

View File

@ -9,7 +9,7 @@ import space.kscience.kmath.linear.Matrix
* @property origin the underlying [SimpleMatrix]. * @property origin the underlying [SimpleMatrix].
* @author Iaroslav Postovalov * @author Iaroslav Postovalov
*/ */
public inline class EjmlMatrix(public val origin: SimpleMatrix) : Matrix<Double> { public class EjmlMatrix(public val origin: SimpleMatrix) : Matrix<Double> {
public override val rowNum: Int get() = origin.numRows() public override val rowNum: Int get() = origin.numRows()
public override val colNum: Int get() = origin.numCols() public override val colNum: Int get() = origin.numCols()

View File

@ -31,7 +31,7 @@ public class GaussIntegrator<T : Comparable<T>> internal constructor(
init { init {
require(points.size == weights.size) { "Inconsistent points and weights sizes" } 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<T>): UnivariateIntegrand<T> = with(algebra) { override fun integrate(integrand: UnivariateIntegrand<T>): UnivariateIntegrand<T> = with(algebra) {
@ -51,6 +51,9 @@ public class GaussIntegrator<T : Comparable<T>> internal constructor(
public companion object { public companion object {
/**
* Integrate given [function] in a [range] with Gauss-Legendre quadrature with [numPoints] points.
*/
public fun integrate( public fun integrate(
range: ClosedRange<Double>, range: ClosedRange<Double>,
numPoints: Int = 100, numPoints: Int = 100,
@ -63,5 +66,20 @@ public class GaussIntegrator<T : Comparable<T>> internal constructor(
UnivariateIntegrand(function, IntegrationRange(range)) UnivariateIntegrand(function, IntegrationRange(range))
) )
} }
// public fun integrate(
// borders: List<Double>,
// numPoints: Int = 10,
// ruleFactory: GaussIntegratorRuleFactory<Double> = GaussLegendreDoubleRuleFactory,
// features: List<IntegrandFeature> = emptyList(),
// function: (Double) -> Double,
// ): UnivariateIntegrand<Double> {
// 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))
// )
// }
} }
} }

View File

@ -10,6 +10,7 @@ import kotlin.native.concurrent.ThreadLocal
public interface GaussIntegratorRuleFactory<T : Any> { public interface GaussIntegratorRuleFactory<T : Any> {
public val algebra: Field<T> public val algebra: Field<T>
public val bufferFactory: BufferFactory<T> public val bufferFactory: BufferFactory<T>
public fun build(numPoints: Int): Pair<Buffer<T>, Buffer<T>> public fun build(numPoints: Int): Pair<Buffer<T>, Buffer<T>>
public companion object { public companion object {
@ -20,6 +21,7 @@ public interface GaussIntegratorRuleFactory<T : Any> {
/** /**
* Create an integration rule by scaling existing normalized rule * Create an integration rule by scaling existing normalized rule
*
*/ */
public fun <T : Comparable<T>> GaussIntegratorRuleFactory<T>.build( public fun <T : Comparable<T>> GaussIntegratorRuleFactory<T>.build(
numPoints: Int, numPoints: Int,
@ -45,8 +47,8 @@ public fun <T : Comparable<T>> GaussIntegratorRuleFactory<T>.build(
/** /**
* Gauss integrator rule based ont Legendre polynomials. All rules are normalized to * 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 * 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)
* https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/analysis/integration/gauss/LegendreRuleFactory.html *
*/ */
@ThreadLocal @ThreadLocal
public object GaussLegendreDoubleRuleFactory : GaussIntegratorRuleFactory<Double> { public object GaussLegendreDoubleRuleFactory : GaussIntegratorRuleFactory<Double> {
@ -96,12 +98,12 @@ public object GaussLegendreDoubleRuleFactory : GaussIntegratorRuleFactory<Double
// P[j](b) // P[j](b)
var pb = b var pb = b
for (j in 1 until numPoints) { for (j in 1 until numPoints) {
val two_j_p_1 = 2 * j + 1 val twoJP1 = 2 * j + 1
val j_p_1 = j + 1 val jP1 = j + 1
// P[j+1](a) // P[j+1](a)
val ppa = (two_j_p_1 * a * pa - j * pma) / j_p_1 val ppa = (twoJP1 * a * pa - j * pma) / jP1
// P[j+1](b) // P[j+1](b)
val ppb = (two_j_p_1 * b * pb - j * pmb) / j_p_1 val ppb = (twoJP1 * b * pb - j * pmb) / jP1
pma = pa pma = pa
pa = ppa pa = ppa
pmb = pb pmb = pb
@ -129,11 +131,8 @@ public object GaussLegendreDoubleRuleFactory : GaussIntegratorRuleFactory<Double
if (!done) { if (!done) {
if (pa * pc <= 0) { if (pa * pc <= 0) {
b = c b = c
pmb = pmc
pb = pc
} else { } else {
a = c a = c
pma = pmc
pa = pc pa = pc
} }
c = 0.5 * (a + b) c = 0.5 * (a + b)
@ -147,7 +146,7 @@ public object GaussLegendreDoubleRuleFactory : GaussIntegratorRuleFactory<Double
points[idx] = -c points[idx] = -c
weights[idx] = w weights[idx] = w
} }
// If "numberOfPoints" is odd, 0 is a root. // If "numPoints" is odd, 0 is a root.
// Note: as written, the test for oddness will work for negative // Note: as written, the test for oddness will work for negative
// integers too (although it is not necessary here), preventing // integers too (although it is not necessary here), preventing
// a FindBugs warning. // a FindBugs warning.

View File

@ -38,7 +38,7 @@ internal class MultivariateHistogramTest {
put(nextDouble(), nextDouble(), nextDouble()) put(nextDouble(), nextDouble(), nextDouble())
} }
} }
assertEquals(n, histogram.bins.sumBy { it.value.toInt() }) assertEquals(n, histogram.bins.sumOf { it.value.toInt() })
} }
@Test @Test

View File

@ -163,7 +163,7 @@ internal object InternalGamma {
} }
private fun lanczos(x: Double): Double = private fun lanczos(x: Double): Double =
(LANCZOS.size - 1 downTo 1).sumByDouble { LANCZOS[it] / (x + it) } + LANCZOS[0] (LANCZOS.size - 1 downTo 1).sumOf { LANCZOS[it] / (x + it) } + LANCZOS[0]
private fun invGamma1pm1(x: Double): Double { private fun invGamma1pm1(x: Double): Double {
require(x >= -0.5) require(x >= -0.5)

View File

@ -21,7 +21,7 @@ internal object InternalUtils {
fun validateProbabilities(probabilities: DoubleArray?): Double { fun validateProbabilities(probabilities: DoubleArray?): Double {
require(!(probabilities == null || probabilities.isEmpty())) { "Probabilities must not be empty." } 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" } require(!(prob < 0 || prob.isInfinite() || prob.isNaN())) { "Invalid probability: $prob" }
prob prob
} }

View File

@ -40,7 +40,7 @@ public interface NoDerivFunctionOptimization<T : Any> : Optimization<T> {
require(y.size == yErr.size) { "Y and yErr buffer should of the same size" } require(y.size == yErr.size) { "Y and yErr buffer should of the same size" }
return Expression { arguments -> return Expression { arguments ->
x.indices.sumByDouble { x.indices.sumOf {
val xValue = x[it] val xValue = x[it]
val yValue = y[it] val yValue = y[it]
val yErrValue = yErr[it] val yErrValue = yErr[it]

View File

@ -32,7 +32,7 @@ public class RandomSourceGenerator internal constructor(public val source: Rando
* *
* @property generator the underlying [RandomGenerator] object. * @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. * Generates a [Boolean] value.
* *

View File

@ -4,7 +4,7 @@ import org.jetbrains.bio.viktor.F64FlatArray
import space.kscience.kmath.structures.MutableBuffer import space.kscience.kmath.structures.MutableBuffer
@Suppress("NOTHING_TO_INLINE", "OVERRIDE_BY_INLINE") @Suppress("NOTHING_TO_INLINE", "OVERRIDE_BY_INLINE")
public inline class ViktorBuffer(public val flatArray: F64FlatArray) : MutableBuffer<Double> { public class ViktorBuffer(public val flatArray: F64FlatArray) : MutableBuffer<Double> {
public override val size: Int public override val size: Int
get() = flatArray.size get() = flatArray.size