Feature/integration #250

Merged
altavir merged 4 commits from feature/integration into dev 2021-03-16 20:44:42 +03:00
6 changed files with 25 additions and 10 deletions
Showing only changes of commit 105b84b87c - Show all commits

View File

@ -3,6 +3,7 @@ package space.kscience.kmath.commons.integration
import org.apache.commons.math3.analysis.integration.IterativeLegendreGaussIntegrator import org.apache.commons.math3.analysis.integration.IterativeLegendreGaussIntegrator
import org.apache.commons.math3.analysis.integration.SimpsonIntegrator import org.apache.commons.math3.analysis.integration.SimpsonIntegrator
import space.kscience.kmath.integration.* import space.kscience.kmath.integration.*
import space.kscience.kmath.misc.UnstableKMathAPI
/** /**
* Integration wrapper for Common-maths UnivariateIntegrator * Integration wrapper for Common-maths UnivariateIntegrator
@ -18,7 +19,7 @@ public class CMIntegrator(
public class MinIterations(public val value: Int) : IntegrandFeature public class MinIterations(public val value: Int) : IntegrandFeature
public class MaxIterations(public val value: Int) : IntegrandFeature public class MaxIterations(public val value: Int) : IntegrandFeature
override fun evaluate(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> { override fun integrate(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> {
val integrator = integratorBuilder(integrand) val integrator = integratorBuilder(integrand)
val maxCalls = integrand.getFeature<IntegrandMaxCalls>()?.maxCalls ?: defaultMaxCalls val maxCalls = integrand.getFeature<IntegrandMaxCalls>()?.maxCalls ?: defaultMaxCalls
val remainingCalls = maxCalls - integrand.calls val remainingCalls = maxCalls - integrand.calls
@ -75,3 +76,17 @@ public class CMIntegrator(
} }
} }
} }
@UnstableKMathAPI
public var MutableList<IntegrandFeature>.targetAbsoluteAccuracy: Double?
get() = filterIsInstance<CMIntegrator.TargetAbsoluteAccuracy>().lastOrNull()?.value
set(value){
value?.let { add(CMIntegrator.TargetAbsoluteAccuracy(value))}
}
@UnstableKMathAPI
public var MutableList<IntegrandFeature>.targetRelativeAccuracy: Double?
get() = filterIsInstance<CMIntegrator.TargetRelativeAccuracy>().lastOrNull()?.value
set(value){
value?.let { add(CMIntegrator.TargetRelativeAccuracy(value))}
}

View File

@ -27,7 +27,7 @@ public class GaussRuleIntegrator(
private var type: GaussRule = GaussRule.LEGANDRE, private var type: GaussRule = GaussRule.LEGANDRE,
) : UnivariateIntegrator<Double> { ) : UnivariateIntegrator<Double> {
override fun evaluate(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> { override fun integrate(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> {
val range = integrand.getFeature<IntegrationRange<Double>>()?.range val range = integrand.getFeature<IntegrationRange<Double>>()?.range
?: error("Integration range is not provided") ?: error("Integration range is not provided")
val integrator: GaussIntegrator = getIntegrator(range) val integrator: GaussIntegrator = getIntegrator(range)
@ -87,7 +87,7 @@ public class GaussRuleIntegrator(
numPoints: Int = 100, numPoints: Int = 100,
type: GaussRule = GaussRule.LEGANDRE, type: GaussRule = GaussRule.LEGANDRE,
function: (Double) -> Double, function: (Double) -> Double,
): Double = GaussRuleIntegrator(numPoints, type).evaluate( ): Double = GaussRuleIntegrator(numPoints, type).integrate(
UnivariateIntegrand(function, IntegrationRange(range)) UnivariateIntegrand(function, IntegrationRange(range))
).value!! ).value!!
} }

View File

@ -19,7 +19,7 @@ import kotlin.reflect.KClass
public operator fun PointValuePair.component1(): DoubleArray = point public operator fun PointValuePair.component1(): DoubleArray = point
public operator fun PointValuePair.component2(): Double = value public operator fun PointValuePair.component2(): Double = value
public class CMOptimizationProblem(override val symbols: List<Symbol>, ) : public class CMOptimizationProblem(override val symbols: List<Symbol>) :
OptimizationProblem<Double>, SymbolIndexer, OptimizationFeature { OptimizationProblem<Double>, SymbolIndexer, OptimizationFeature {
private val optimizationData: HashMap<KClass<out OptimizationData>, OptimizationData> = HashMap() private val optimizationData: HashMap<KClass<out OptimizationData>, OptimizationData> = HashMap()
private var optimizatorBuilder: (() -> MultivariateOptimizer)? = null private var optimizatorBuilder: (() -> MultivariateOptimizer)? = null

View File

@ -21,8 +21,8 @@ internal class IntegrationTest {
@Test @Test
fun customSimpson() { fun customSimpson() {
val res = CMIntegrator.simpson().integrate(0.0..PI, function) { val res = CMIntegrator.simpson().integrate(0.0..PI, function) {
add(CMIntegrator.TargetRelativeAccuracy(1e-4)) targetRelativeAccuracy = 1e-4
add(CMIntegrator.TargetAbsoluteAccuracy(1e-4)) targetAbsoluteAccuracy = 1e-4
} }
assertTrue { abs(res - 2) < 1e-3 } assertTrue { abs(res - 2) < 1e-3 }
assertTrue { abs(res - 2) > 1e-12 } assertTrue { abs(res - 2) > 1e-12 }

View File

@ -7,5 +7,5 @@ public interface Integrator<I: Integrand> {
/** /**
* Run one integration pass and return a new [Integrand] with a new set of features * Run one integration pass and return a new [Integrand] with a new set of features
*/ */
public fun evaluate(integrand: I): I public fun integrate(integrand: I): I
} }

View File

@ -39,7 +39,7 @@ public fun UnivariateIntegrator<Double>.integrate(
range: ClosedRange<Double>, range: ClosedRange<Double>,
vararg features: IntegrandFeature, vararg features: IntegrandFeature,
function: (Double) -> Double, function: (Double) -> Double,
): Double = evaluate( ): Double = integrate(
UnivariateIntegrand(function, IntegrationRange(range), *features) UnivariateIntegrand(function, IntegrationRange(range), *features)
).value ?: error("Unexpected: no value after integration.") ).value ?: error("Unexpected: no value after integration.")
@ -58,7 +58,7 @@ public fun UnivariateIntegrator<Double>.integrate(
featureBuilder() featureBuilder()
add(IntegrationRange(range)) add(IntegrationRange(range))
} }
return evaluate( return integrate(
UnivariateIntegrand(function, *features.toTypedArray()) UnivariateIntegrand(function, *features.toTypedArray())
).value ?: error("Unexpected: no value after integration.") ).value ?: error("Unexpected: no value after integration.")
} }