From 12805712d3a42092c7b4ca65c1fd2507acf2c0f3 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Mon, 24 May 2021 14:30:51 +0300 Subject: [PATCH] Integrand toString --- .../kmath/commons/integration/CMIntegrator.kt | 41 ++++++++----------- .../integration/GaussIntegratorRuleFactory.kt | 2 + .../kscience/kmath/integration/Integrand.kt | 29 ++++++++++--- .../integration/MultivariateIntegrand.kt | 8 ++-- .../kmath/integration/UnivariateIntegrand.kt | 29 +++++++++---- 5 files changed, 66 insertions(+), 43 deletions(-) diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt index 92bf86128..bcddccdc4 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt @@ -18,12 +18,6 @@ public class CMIntegrator( public val integratorBuilder: (Integrand) -> org.apache.commons.math3.analysis.integration.UnivariateIntegrator, ) : UnivariateIntegrator { - public class TargetRelativeAccuracy(public val value: Double) : IntegrandFeature - public class TargetAbsoluteAccuracy(public val value: Double) : IntegrandFeature - - public class MinIterations(public val value: Int) : IntegrandFeature - public class MaxIterations(public val value: Int) : IntegrandFeature - override fun integrate(integrand: UnivariateIntegrand): UnivariateIntegrand { val integrator = integratorBuilder(integrand) val maxCalls = integrand.getFeature()?.maxCalls ?: defaultMaxCalls @@ -45,16 +39,15 @@ public class CMIntegrator( * Create a Simpson integrator based on [SimpsonIntegrator] */ public fun simpson(defaultMaxCalls: Int = 200): CMIntegrator = CMIntegrator(defaultMaxCalls) { integrand -> - val absoluteAccuracy = integrand.getFeature()?.value + val absoluteAccuracy = integrand.getFeature()?.accuracy ?: SimpsonIntegrator.DEFAULT_ABSOLUTE_ACCURACY - val relativeAccuracy = integrand.getFeature()?.value + val relativeAccuracy = integrand.getFeature()?.accuracy ?: SimpsonIntegrator.DEFAULT_ABSOLUTE_ACCURACY - val minIterations = integrand.getFeature()?.value - ?: SimpsonIntegrator.DEFAULT_MIN_ITERATIONS_COUNT - val maxIterations = integrand.getFeature()?.value - ?: SimpsonIntegrator.SIMPSON_MAX_ITERATIONS_COUNT + val iterations = integrand.getFeature()?.range + ?: SimpsonIntegrator.DEFAULT_MIN_ITERATIONS_COUNT..SimpsonIntegrator.SIMPSON_MAX_ITERATIONS_COUNT - SimpsonIntegrator(relativeAccuracy, absoluteAccuracy, minIterations, maxIterations) + + SimpsonIntegrator(relativeAccuracy, absoluteAccuracy, iterations.first, iterations.last) } /** @@ -62,21 +55,19 @@ public class CMIntegrator( */ public fun legandre(numPoints: Int, defaultMaxCalls: Int = numPoints * 5): CMIntegrator = CMIntegrator(defaultMaxCalls) { integrand -> - val absoluteAccuracy = integrand.getFeature()?.value + val absoluteAccuracy = integrand.getFeature()?.accuracy ?: IterativeLegendreGaussIntegrator.DEFAULT_ABSOLUTE_ACCURACY - val relativeAccuracy = integrand.getFeature()?.value + val relativeAccuracy = integrand.getFeature()?.accuracy ?: IterativeLegendreGaussIntegrator.DEFAULT_ABSOLUTE_ACCURACY - val minIterations = integrand.getFeature()?.value - ?: IterativeLegendreGaussIntegrator.DEFAULT_MIN_ITERATIONS_COUNT - val maxIterations = integrand.getFeature()?.value - ?: IterativeLegendreGaussIntegrator.DEFAULT_MAX_ITERATIONS_COUNT + val iterations = integrand.getFeature()?.range + ?: IterativeLegendreGaussIntegrator.DEFAULT_MIN_ITERATIONS_COUNT..IterativeLegendreGaussIntegrator.DEFAULT_MAX_ITERATIONS_COUNT IterativeLegendreGaussIntegrator( numPoints, relativeAccuracy, absoluteAccuracy, - minIterations, - maxIterations + iterations.first, + iterations.last ) } } @@ -84,14 +75,14 @@ public class CMIntegrator( @UnstableKMathAPI public var MutableList.targetAbsoluteAccuracy: Double? - get() = filterIsInstance().lastOrNull()?.value + get() = filterIsInstance().lastOrNull()?.accuracy set(value) { - value?.let { add(CMIntegrator.TargetAbsoluteAccuracy(value)) } + value?.let { add(IntegrandAbsoluteAccuracy(value)) } } @UnstableKMathAPI public var MutableList.targetRelativeAccuracy: Double? - get() = filterIsInstance().lastOrNull()?.value + get() = filterIsInstance().lastOrNull()?.accuracy set(value) { - value?.let { add(CMIntegrator.TargetRelativeAccuracy(value)) } + value?.let { add(IntegrandRelativeAccuracy(value)) } } \ 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 133f829e3..594ca9940 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 @@ -164,4 +164,6 @@ public object GaussLegendreRuleFactory : GaussIntegratorRuleFactory { } override fun build(numPoints: Int): Pair, Buffer> = getOrBuildRule(numPoints) + + override fun toString(): String = "GaussLegendreRule" } \ No newline at end of file diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt index 1ff8e422e..f9c26e88b 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt @@ -7,22 +7,39 @@ package space.kscience.kmath.integration import kotlin.reflect.KClass -public interface IntegrandFeature +public interface IntegrandFeature { + override fun toString(): String +} public interface Integrand { + public val features: Set public fun getFeature(type: KClass): T? } public inline fun Integrand.getFeature(): T? = getFeature(T::class) -public class IntegrandValue(public val value: T) : IntegrandFeature +public class IntegrandValue(public val value: T) : IntegrandFeature { + override fun toString(): String = "Value($value)" +} -public class IntegrandRelativeAccuracy(public val accuracy: Double) : IntegrandFeature +public class IntegrandRelativeAccuracy(public val accuracy: Double) : IntegrandFeature { + override fun toString(): String = "TargetRelativeAccuracy($accuracy)" +} -public class IntegrandAbsoluteAccuracy(public val accuracy: Double) : IntegrandFeature +public class IntegrandAbsoluteAccuracy(public val accuracy: Double) : IntegrandFeature { + override fun toString(): String = "TargetAbsoluteAccuracy($accuracy)" +} -public class IntegrandCallsPerformed(public val calls: Int) : IntegrandFeature +public class IntegrandCallsPerformed(public val calls: Int) : IntegrandFeature { + override fun toString(): String = "Calls($calls)" +} public val Integrand.calls: Int get() = getFeature()?.calls ?: 0 -public class IntegrandMaxCalls(public val maxCalls: Int) : IntegrandFeature +public class IntegrandMaxCalls(public val maxCalls: Int) : IntegrandFeature { + override fun toString(): String = "MaxCalls($maxCalls)" +} + +public class IntegrandIterationsRange(public val range: IntRange) : IntegrandFeature { + override fun toString(): String = "Iterations(${range.first}..${range.last})" +} diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt index 12d0ef0a6..5ba411bf9 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt @@ -9,15 +9,17 @@ import space.kscience.kmath.linear.Point import kotlin.reflect.KClass public class MultivariateIntegrand internal constructor( - private val features: Map, IntegrandFeature>, + private val featureMap: Map, IntegrandFeature>, public val function: (Point) -> T, ) : Integrand { + override val features: Set get() = featureMap.values.toSet() + @Suppress("UNCHECKED_CAST") - override fun getFeature(type: KClass): T? = features[type] as? T + override fun getFeature(type: KClass): T? = featureMap[type] as? T public operator fun plus(pair: Pair, F>): MultivariateIntegrand = - MultivariateIntegrand(features + pair, function) + MultivariateIntegrand(featureMap + pair, function) public operator fun plus(feature: F): MultivariateIntegrand = plus(feature::class to feature) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt index 8c515065f..e265f54e8 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt @@ -8,19 +8,20 @@ package space.kscience.kmath.integration import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.DoubleBuffer -import kotlin.jvm.JvmInline import kotlin.reflect.KClass public class UnivariateIntegrand internal constructor( - private val features: Map, IntegrandFeature>, + private val featureMap: Map, IntegrandFeature>, public val function: (Double) -> T, ) : Integrand { + override val features: Set get() = featureMap.values.toSet() + @Suppress("UNCHECKED_CAST") - override fun getFeature(type: KClass): T? = features[type] as? T + override fun getFeature(type: KClass): T? = featureMap[type] as? T public operator fun plus(pair: Pair, F>): UnivariateIntegrand = - UnivariateIntegrand(features + pair, function) + UnivariateIntegrand(featureMap + pair, function) public operator fun plus(feature: F): UnivariateIntegrand = plus(feature::class to feature) @@ -34,8 +35,9 @@ public fun UnivariateIntegrand( public typealias UnivariateIntegrator = Integrator> -@JvmInline -public value class IntegrationRange(public val range: ClosedRange) : IntegrandFeature +public class IntegrationRange(public val range: ClosedRange) : IntegrandFeature { + override fun toString(): String = "Range(${range.start}..${range.endInclusive})" +} /** * Set of univariate integration ranges. First components correspond to ranges themselves, second components to number of @@ -43,10 +45,19 @@ public value class IntegrationRange(public val range: ClosedRange) : Int */ public class UnivariateIntegrandRanges(public val ranges: List, Int>>) : IntegrandFeature { public constructor(vararg pairs: Pair, Int>) : this(pairs.toList()) + + override fun toString(): String { + val rangesString = ranges.joinToString(separator = ",") { (range, points) -> + "${range.start}..${range.endInclusive} : $points" + } + return "UnivariateRanges($rangesString)" + } } public class UnivariateIntegrationNodes(public val nodes: Buffer) : IntegrandFeature { public constructor(vararg nodes: Double) : this(DoubleBuffer(nodes)) + + override fun toString(): String = "UnivariateNodes($nodes)" } @@ -65,7 +76,7 @@ public val UnivariateIntegrand.value: T get() = valueOrNull ?: erro * The [function] is placed in the end position to allow passing a lambda. */ @UnstableKMathAPI -public fun UnivariateIntegrator.integrate( +public fun UnivariateIntegrator.integrate( vararg features: IntegrandFeature, function: (Double) -> T, ): UnivariateIntegrand = integrate(UnivariateIntegrand(function, *features)) @@ -75,7 +86,7 @@ public fun UnivariateIntegrator.integrate( * The [function] is placed in the end position to allow passing a lambda. */ @UnstableKMathAPI -public fun UnivariateIntegrator.integrate( +public fun UnivariateIntegrator.integrate( range: ClosedRange, vararg features: IntegrandFeature, function: (Double) -> T, @@ -86,7 +97,7 @@ public fun UnivariateIntegrator.integrate( * The [function] is placed in the end position to allow passing a lambda. */ @UnstableKMathAPI -public fun UnivariateIntegrator.integrate( +public fun UnivariateIntegrator.integrate( range: ClosedRange, featureBuilder: MutableList.() -> Unit = {}, function: (Double) -> T,