Feature/integration #250
@ -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.SimpsonIntegrator
|
||||
import space.kscience.kmath.integration.*
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
|
||||
/**
|
||||
* Integration wrapper for Common-maths UnivariateIntegrator
|
||||
@ -18,7 +19,7 @@ public class CMIntegrator(
|
||||
public class MinIterations(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 maxCalls = integrand.getFeature<IntegrandMaxCalls>()?.maxCalls ?: defaultMaxCalls
|
||||
val remainingCalls = maxCalls - integrand.calls
|
||||
@ -74,4 +75,18 @@ 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))}
|
||||
}
|
@ -27,7 +27,7 @@ public class GaussRuleIntegrator(
|
||||
private var type: GaussRule = GaussRule.LEGANDRE,
|
||||
) : 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
|
||||
?: error("Integration range is not provided")
|
||||
val integrator: GaussIntegrator = getIntegrator(range)
|
||||
@ -87,7 +87,7 @@ public class GaussRuleIntegrator(
|
||||
numPoints: Int = 100,
|
||||
type: GaussRule = GaussRule.LEGANDRE,
|
||||
function: (Double) -> Double,
|
||||
): Double = GaussRuleIntegrator(numPoints, type).evaluate(
|
||||
): Double = GaussRuleIntegrator(numPoints, type).integrate(
|
||||
UnivariateIntegrand(function, IntegrationRange(range))
|
||||
).value!!
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ import kotlin.reflect.KClass
|
||||
public operator fun PointValuePair.component1(): DoubleArray = point
|
||||
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 {
|
||||
private val optimizationData: HashMap<KClass<out OptimizationData>, OptimizationData> = HashMap()
|
||||
private var optimizatorBuilder: (() -> MultivariateOptimizer)? = null
|
||||
|
@ -21,8 +21,8 @@ internal class IntegrationTest {
|
||||
@Test
|
||||
fun customSimpson() {
|
||||
val res = CMIntegrator.simpson().integrate(0.0..PI, function) {
|
||||
add(CMIntegrator.TargetRelativeAccuracy(1e-4))
|
||||
add(CMIntegrator.TargetAbsoluteAccuracy(1e-4))
|
||||
targetRelativeAccuracy = 1e-4
|
||||
targetAbsoluteAccuracy = 1e-4
|
||||
}
|
||||
assertTrue { abs(res - 2) < 1e-3 }
|
||||
assertTrue { abs(res - 2) > 1e-12 }
|
||||
|
@ -7,5 +7,5 @@ public interface Integrator<I: Integrand> {
|
||||
/**
|
||||
* 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
|
||||
}
|
@ -39,7 +39,7 @@ public fun UnivariateIntegrator<Double>.integrate(
|
||||
range: ClosedRange<Double>,
|
||||
vararg features: IntegrandFeature,
|
||||
function: (Double) -> Double,
|
||||
): Double = evaluate(
|
||||
): Double = integrate(
|
||||
UnivariateIntegrand(function, IntegrationRange(range), *features)
|
||||
).value ?: error("Unexpected: no value after integration.")
|
||||
|
||||
@ -58,7 +58,7 @@ public fun UnivariateIntegrator<Double>.integrate(
|
||||
featureBuilder()
|
||||
add(IntegrationRange(range))
|
||||
}
|
||||
return evaluate(
|
||||
return integrate(
|
||||
UnivariateIntegrand(function, *features.toTypedArray())
|
||||
).value ?: error("Unexpected: no value after integration.")
|
||||
}
|
Loading…
Reference in New Issue
Block a user