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

View File

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

View File

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

View File

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

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
*/
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>,
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.")
}