forked from kscience/kmath
Refactor integrator API.
This commit is contained in:
parent
4964fb2642
commit
6f39b38a72
@ -5,8 +5,6 @@
|
||||
|
||||
package space.kscience.kmath.functions
|
||||
|
||||
import space.kscience.kmath.integration.integrate
|
||||
import space.kscience.kmath.integration.value
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
import kotlin.math.pow
|
||||
|
||||
@ -18,5 +16,5 @@ fun main() {
|
||||
val result = DoubleField.integrate(0.0..10.0, function = function)
|
||||
|
||||
//the value is nullable because in some cases the integration could not succeed
|
||||
println(result.value)
|
||||
println(result.valueOrNull)
|
||||
}
|
@ -5,8 +5,6 @@
|
||||
|
||||
package space.kscience.kmath.functions
|
||||
|
||||
import space.kscience.kmath.integration.integrate
|
||||
import space.kscience.kmath.integration.value
|
||||
import space.kscience.kmath.nd.StructureND
|
||||
import space.kscience.kmath.nd.nd
|
||||
import space.kscience.kmath.operations.DoubleField
|
||||
@ -27,6 +25,6 @@ fun main(): Unit = DoubleField {
|
||||
val result = integrate(0.0..10.0, function = function)
|
||||
|
||||
//the value is nullable because in some cases the integration could not succeed
|
||||
println(result.value)
|
||||
println(result.valueOrNull)
|
||||
}
|
||||
}
|
@ -78,6 +78,6 @@ public class GaussRuleIntegrator(
|
||||
function: (Double) -> Double,
|
||||
): Double = GaussRuleIntegrator(numPoints, type).integrate(
|
||||
UnivariateIntegrand(function, IntegrationRange(range))
|
||||
).value!!
|
||||
).valueOrNull!!
|
||||
}
|
||||
}
|
@ -66,31 +66,25 @@ public class GaussIntegrator<T : Any>(
|
||||
return integrand + IntegrandValue(res) + IntegrandCallsPerformed(integrand.calls + points.size)
|
||||
}
|
||||
|
||||
public companion object {
|
||||
|
||||
}
|
||||
public companion object
|
||||
}
|
||||
|
||||
/**
|
||||
* Integrate [T]-valued univariate function using provided set of [IntegrandFeature]
|
||||
* Following features are evaluated:
|
||||
* Create a Gauss-Legendre integrator for this field
|
||||
* Following integrand features are accepted:
|
||||
* * [GaussIntegratorRuleFactory] - A factory for computing the Gauss integration rule. By default uses [GaussLegendreRuleFactory]
|
||||
* * [IntegrationRange] - the univariate range of integration. By default uses 0..1 interval.
|
||||
* * [IntegrandMaxCalls] - the maximum number of function calls during integration. For non-iterative rules, always uses the maximum number of points. By default uses 10 points.
|
||||
* * [UnivariateIntegrandRanges] - Set of ranges and number of points per range. Defaults to given [IntegrationRange] and [IntegrandMaxCalls]
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun <T : Any> Field<T>.integrate(
|
||||
vararg features: IntegrandFeature,
|
||||
function: (Double) -> T,
|
||||
): UnivariateIntegrand<T> = GaussIntegrator(this).integrate(UnivariateIntegrand(function, *features))
|
||||
public val <T:Any> Field<T>.integrator: GaussIntegrator<T> get() = GaussIntegrator(this)
|
||||
|
||||
|
||||
/**
|
||||
* Use [GaussIntegrator.Companion.integrate] to integrate the function in the current algebra with given [range] and [numPoints]
|
||||
* Use [integrate] to integrate the function in the current algebra with given [range] and [numPoints]
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun <T : Any> Field<T>.integrate(
|
||||
public fun <T : Any> GaussIntegrator<T>.integrate(
|
||||
range: ClosedRange<Double>,
|
||||
order: Int = 10,
|
||||
intervals: Int = 10,
|
||||
@ -104,7 +98,7 @@ public fun <T : Any> Field<T>.integrate(
|
||||
val ranges = UnivariateIntegrandRanges(
|
||||
(0 until intervals).map { i -> (rangeSize * i)..(rangeSize * (i + 1)) to order }
|
||||
)
|
||||
return GaussIntegrator(this).integrate(
|
||||
return integrate(
|
||||
UnivariateIntegrand(
|
||||
function,
|
||||
IntegrationRange(range),
|
||||
|
@ -35,37 +35,41 @@ public typealias UnivariateIntegrator<T> = Integrator<UnivariateIntegrand<T>>
|
||||
@JvmInline
|
||||
public value class IntegrationRange(public val range: ClosedRange<Double>) : IntegrandFeature
|
||||
|
||||
public val <T : Any> UnivariateIntegrand<T>.value: T? get() = getFeature<IntegrandValue<T>>()?.value
|
||||
/**
|
||||
* Value of the integrand if it is present or null
|
||||
*/
|
||||
public val <T : Any> UnivariateIntegrand<T>.valueOrNull: T? get() = getFeature<IntegrandValue<T>>()?.value
|
||||
|
||||
/**
|
||||
* Value of the integrand or error
|
||||
*/
|
||||
public val <T : Any> UnivariateIntegrand<T>.value: T get() = valueOrNull ?: error("No value in the integrand")
|
||||
|
||||
/**
|
||||
* A shortcut method to integrate a [function] in [range] with additional [features].
|
||||
* The [function] is placed in the end position to allow passing a lambda.
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun UnivariateIntegrator<Double>.integrate(
|
||||
public fun <T: Any> UnivariateIntegrator<T>.integrate(
|
||||
range: ClosedRange<Double>,
|
||||
vararg features: IntegrandFeature,
|
||||
function: (Double) -> Double,
|
||||
): Double = integrate(
|
||||
UnivariateIntegrand(function, IntegrationRange(range), *features)
|
||||
).value ?: error("Unexpected: no value after integration.")
|
||||
function: (Double) -> T,
|
||||
): UnivariateIntegrand<T> = integrate(UnivariateIntegrand(function, IntegrationRange(range), *features))
|
||||
|
||||
/**
|
||||
* A shortcut method to integrate a [function] in [range] with additional [features].
|
||||
* The [function] is placed in the end position to allow passing a lambda.
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun UnivariateIntegrator<Double>.integrate(
|
||||
public fun <T: Any> UnivariateIntegrator<T>.integrate(
|
||||
range: ClosedRange<Double>,
|
||||
featureBuilder: MutableList<IntegrandFeature>.() -> Unit = {},
|
||||
function: (Double) -> Double,
|
||||
): Double {
|
||||
function: (Double) -> T,
|
||||
): UnivariateIntegrand<T> {
|
||||
//TODO use dedicated feature builder class instead or add extensions to MutableList<IntegrandFeature>
|
||||
val features = buildList {
|
||||
featureBuilder()
|
||||
add(IntegrationRange(range))
|
||||
}
|
||||
return integrate(
|
||||
UnivariateIntegrand(function, *features.toTypedArray())
|
||||
).value ?: error("Unexpected: no value after integration.")
|
||||
return integrate(UnivariateIntegrand(function, *features.toTypedArray()))
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ class GaussIntegralTest {
|
||||
val res = DoubleField.integrate(0.0..2 * PI) { x ->
|
||||
sin(x)
|
||||
}
|
||||
assertEquals(0.0, res.value!!, 1e-2)
|
||||
assertEquals(0.0, res.valueOrNull!!, 1e-2)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -31,7 +31,7 @@ class GaussIntegralTest {
|
||||
0.0
|
||||
}
|
||||
}
|
||||
assertEquals(20.0, res.value!!, 0.5)
|
||||
assertEquals(20.0, res.valueOrNull!!, 0.5)
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user