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.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))}
|
||||||
|
}
|
@ -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!!
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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 }
|
||||||
|
@ -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
|
||||||
}
|
}
|
@ -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.")
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user