forked from kscience/kmath
[WIP] refactor features to attributes
This commit is contained in:
parent
9da14089e0
commit
dd3d38490a
@ -7,8 +7,10 @@ package space.kscience.attributes
|
||||
|
||||
/**
|
||||
* A safe builder for [Attributes]
|
||||
*
|
||||
* @param O type marker of an owner object, for which these attributes are made
|
||||
*/
|
||||
public class AttributesBuilder internal constructor(private val map: MutableMap<Attribute<*>, Any>) {
|
||||
public class TypedAttributesBuilder<in O> internal constructor(private val map: MutableMap<Attribute<*>, Any>) {
|
||||
|
||||
public constructor() : this(mutableMapOf())
|
||||
|
||||
@ -47,6 +49,8 @@ public class AttributesBuilder internal constructor(private val map: MutableMap<
|
||||
public fun build(): Attributes = Attributes(map)
|
||||
}
|
||||
|
||||
public typealias AttributesBuilder = TypedAttributesBuilder<Any?>
|
||||
|
||||
public fun AttributesBuilder(
|
||||
attributes: Attributes,
|
||||
): AttributesBuilder = AttributesBuilder(attributes.content.toMutableMap())
|
||||
|
@ -6,7 +6,7 @@ kotlin.code.style=official
|
||||
kotlin.mpp.stability.nowarn=true
|
||||
kotlin.native.ignoreDisabledTargets=true
|
||||
|
||||
toolsVersion=0.14.9-kotlin-1.8.20
|
||||
toolsVersion=0.14.9-kotlin-1.9.0
|
||||
|
||||
org.gradle.parallel=true
|
||||
org.gradle.workers.max=4
|
||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
@ -22,7 +22,7 @@ public class CMGaussRuleIntegrator(
|
||||
val integrator: GaussIntegrator = getIntegrator(range)
|
||||
//TODO check performance
|
||||
val res: Double = integrator.integrate(integrand.function)
|
||||
return integrand.modify {
|
||||
return integrand.withAttributes {
|
||||
IntegrandValue(res)
|
||||
IntegrandCallsPerformed(integrand.calls + numpoints)
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ public class CMIntegrator(
|
||||
val range = integrand[IntegrationRange] ?: error("Integration range is not provided")
|
||||
val res = integrator.integrate(remainingCalls, integrand.function, range.start, range.endInclusive)
|
||||
|
||||
return integrand.modify {
|
||||
return integrand.withAttributes {
|
||||
value(res)
|
||||
IntegrandAbsoluteAccuracy(integrator.absoluteAccuracy)
|
||||
IntegrandRelativeAccuracy(integrator.relativeAccuracy)
|
||||
|
@ -4,7 +4,7 @@
|
||||
*/
|
||||
package space.kscience.kmath.integration
|
||||
|
||||
import space.kscience.attributes.AttributesBuilder
|
||||
import space.kscience.attributes.TypedAttributesBuilder
|
||||
import space.kscience.kmath.UnstableKMathAPI
|
||||
import space.kscience.kmath.operations.Field
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
@ -57,7 +57,7 @@ public class GaussIntegrator<T : Any>(
|
||||
override fun process(integrand: UnivariateIntegrand<T>): UnivariateIntegrand<T> = with(algebra) {
|
||||
val f = integrand.function
|
||||
val (points, weights) = buildRule(integrand)
|
||||
var res = zero
|
||||
var res: T = zero
|
||||
var c = zero
|
||||
for (i in points.indices) {
|
||||
val x = points[i]
|
||||
@ -67,7 +67,7 @@ public class GaussIntegrator<T : Any>(
|
||||
c = t - res - y
|
||||
res = t
|
||||
}
|
||||
return integrand.modify {
|
||||
return integrand.withAttributes {
|
||||
value(res)
|
||||
IntegrandCallsPerformed(integrand.calls + points.size)
|
||||
}
|
||||
@ -88,12 +88,12 @@ public val <T : Any> Field<T>.gaussIntegrator: GaussIntegrator<T> get() = GaussI
|
||||
* Integrate using [intervals] segments with Gauss-Legendre rule of [order] order.
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun <T : Any> GaussIntegrator<T>.integrate(
|
||||
public inline fun <reified T : Any> GaussIntegrator<T>.integrate(
|
||||
range: ClosedRange<Double>,
|
||||
order: Int = 10,
|
||||
intervals: Int = 10,
|
||||
attributesBuilder: AttributesBuilder.() -> Unit,
|
||||
function: (Double) -> T,
|
||||
attributesBuilder: TypedAttributesBuilder<UnivariateIntegrand<T>>.() -> Unit,
|
||||
noinline function: (Double) -> T,
|
||||
): UnivariateIntegrand<T> {
|
||||
require(range.endInclusive > range.start) { "The range upper bound should be higher than lower bound" }
|
||||
require(order > 1) { "The order of polynomial must be more than 1" }
|
||||
@ -103,7 +103,7 @@ public fun <T : Any> GaussIntegrator<T>.integrate(
|
||||
(0 until intervals).map { i -> (range.start + rangeSize * i)..(range.start + rangeSize * (i + 1)) to order }
|
||||
)
|
||||
return process(
|
||||
UnivariateIntegrand(
|
||||
UnivariateIntegrand<T>(
|
||||
attributeBuilder = {
|
||||
IntegrationRange(range)
|
||||
GaussIntegratorRuleFactory(GaussLegendreRuleFactory)
|
||||
|
@ -5,10 +5,7 @@
|
||||
|
||||
package space.kscience.kmath.integration
|
||||
|
||||
import space.kscience.attributes.Attribute
|
||||
import space.kscience.attributes.AttributeContainer
|
||||
import space.kscience.attributes.AttributesBuilder
|
||||
import space.kscience.attributes.SafeType
|
||||
import space.kscience.attributes.*
|
||||
|
||||
public interface IntegrandAttribute<T> : Attribute<T>
|
||||
|
||||
@ -16,9 +13,10 @@ public interface Integrand<T> : AttributeContainer {
|
||||
|
||||
public val type: SafeType<T>
|
||||
|
||||
public fun modify(block: AttributesBuilder.() -> Unit): Integrand<T>
|
||||
|
||||
public fun <A : Any> withAttribute(attribute: Attribute<A>, value: A): Integrand<T>
|
||||
/**
|
||||
* Create a copy of this integrand with a new set of attributes
|
||||
*/
|
||||
public fun withAttributes(attributes: Attributes): Integrand<T>
|
||||
|
||||
public companion object
|
||||
}
|
||||
@ -32,7 +30,7 @@ public sealed class IntegrandValue<T> private constructor(): IntegrandAttribute<
|
||||
}
|
||||
}
|
||||
|
||||
public fun <T> AttributesBuilder.value(value: T) {
|
||||
public fun <T> TypedAttributesBuilder<Integrand<T>>.value(value: T) {
|
||||
IntegrandValue.forType<T>().invoke(value)
|
||||
}
|
||||
|
||||
|
@ -14,14 +14,21 @@ public class MultivariateIntegrand<T>(
|
||||
public val function: (Point<T>) -> T,
|
||||
) : Integrand<T> {
|
||||
|
||||
override fun modify(block: AttributesBuilder.() -> Unit): MultivariateIntegrand<T> =
|
||||
MultivariateIntegrand(type, attributes.modify(block), function)
|
||||
override fun withAttributes(attributes: Attributes): MultivariateIntegrand<T> =
|
||||
MultivariateIntegrand(type, attributes, function)
|
||||
|
||||
override fun <A : Any> withAttribute(attribute: Attribute<A>, value: A): MultivariateIntegrand<T> =
|
||||
MultivariateIntegrand(type, attributes.withAttribute(attribute, value), function)
|
||||
}
|
||||
|
||||
public fun <T, A : Any> MultivariateIntegrand<T>.withAttribute(
|
||||
attribute: Attribute<A>,
|
||||
value: A,
|
||||
): MultivariateIntegrand<T> = withAttributes(attributes.withAttribute(attribute, value))
|
||||
|
||||
public fun <T> MultivariateIntegrand<T>.withAttributes(
|
||||
block: TypedAttributesBuilder<MultivariateIntegrand<T>>.() -> Unit,
|
||||
): MultivariateIntegrand<T> = withAttributes(attributes.modify(block))
|
||||
|
||||
public inline fun <reified T : Any> MultivariateIntegrand(
|
||||
attributeBuilder: AttributesBuilder.() -> Unit,
|
||||
attributeBuilder: TypedAttributesBuilder<MultivariateIntegrand<T>>.() -> Unit,
|
||||
noinline function: (Point<T>) -> T,
|
||||
): MultivariateIntegrand<T> = MultivariateIntegrand(safeTypeOf<T>(), Attributes(attributeBuilder), function)
|
||||
|
@ -48,7 +48,7 @@ public class SimpsonIntegrator<T : Any>(
|
||||
val ranges = integrand[UnivariateIntegrandRanges]
|
||||
return if (ranges != null) {
|
||||
val res = algebra.sum(ranges.ranges.map { integrateRange(integrand, it.first, it.second) })
|
||||
integrand.modify {
|
||||
integrand.withAttributes {
|
||||
value(res)
|
||||
IntegrandCallsPerformed(integrand.calls + ranges.ranges.sumOf { it.second })
|
||||
}
|
||||
@ -57,7 +57,7 @@ public class SimpsonIntegrator<T : Any>(
|
||||
require(numPoints >= 4) { "Simpson integrator requires at least 4 nodes" }
|
||||
val range = integrand[IntegrationRange] ?: 0.0..1.0
|
||||
val res = integrateRange(integrand, range, numPoints)
|
||||
integrand.modify {
|
||||
integrand.withAttributes {
|
||||
value(res)
|
||||
IntegrandCallsPerformed(integrand.calls + numPoints)
|
||||
}
|
||||
@ -100,7 +100,7 @@ public object DoubleSimpsonIntegrator : UnivariateIntegrator<Double> {
|
||||
val ranges = integrand[UnivariateIntegrandRanges]
|
||||
return if (ranges != null) {
|
||||
val res = ranges.ranges.sumOf { integrateRange(integrand, it.first, it.second) }
|
||||
integrand.modify {
|
||||
integrand.withAttributes {
|
||||
value(res)
|
||||
IntegrandCallsPerformed(integrand.calls + ranges.ranges.sumOf { it.second })
|
||||
}
|
||||
@ -109,7 +109,7 @@ public object DoubleSimpsonIntegrator : UnivariateIntegrator<Double> {
|
||||
require(numPoints >= 4) { "Simpson integrator requires at least 4 nodes" }
|
||||
val range = integrand[IntegrationRange] ?: 0.0..1.0
|
||||
val res = integrateRange(integrand, range, numPoints)
|
||||
integrand.modify {
|
||||
integrand.withAttributes {
|
||||
value(res)
|
||||
IntegrandCallsPerformed(integrand.calls + numPoints)
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ public class SplineIntegrator<T : Comparable<T>>(
|
||||
values
|
||||
)
|
||||
val res = polynomials.integrate(algebra, number(range.start)..number(range.endInclusive))
|
||||
integrand.modify {
|
||||
integrand.withAttributes {
|
||||
value(res)
|
||||
IntegrandCallsPerformed(integrand.calls + nodes.size)
|
||||
}
|
||||
@ -99,7 +99,7 @@ public object DoubleSplineIntegrator : UnivariateIntegrator<Double> {
|
||||
val values = nodes.mapToBuffer(::Float64Buffer) { integrand.function(it) }
|
||||
val polynomials = interpolator.interpolatePolynomials(nodes, values)
|
||||
val res = polynomials.integrate(Float64Field, range)
|
||||
return integrand.modify {
|
||||
return integrand.withAttributes {
|
||||
value(res)
|
||||
IntegrandCallsPerformed(integrand.calls + nodes.size)
|
||||
}
|
||||
|
@ -16,15 +16,21 @@ public class UnivariateIntegrand<T>(
|
||||
public val function: (Double) -> T,
|
||||
) : Integrand<T> {
|
||||
|
||||
override fun <A : Any> withAttribute(attribute: Attribute<A>, value: A): UnivariateIntegrand<T> =
|
||||
UnivariateIntegrand(type, attributes.withAttribute(attribute, value), function)
|
||||
|
||||
override fun modify(block: AttributesBuilder.() -> Unit): UnivariateIntegrand<T> =
|
||||
UnivariateIntegrand(type, attributes.modify(block), function)
|
||||
override fun withAttributes(attributes: Attributes): UnivariateIntegrand<T> =
|
||||
UnivariateIntegrand(type, attributes, function)
|
||||
}
|
||||
|
||||
public fun <T, A : Any> UnivariateIntegrand<T>.withAttribute(
|
||||
attribute: Attribute<A>,
|
||||
value: A,
|
||||
): UnivariateIntegrand<T> = withAttributes(attributes.withAttribute(attribute, value))
|
||||
|
||||
public fun <T> UnivariateIntegrand<T>.withAttributes(
|
||||
block: TypedAttributesBuilder<UnivariateIntegrand<T>>.() -> Unit,
|
||||
): UnivariateIntegrand<T> = withAttributes(attributes.modify(block))
|
||||
|
||||
public inline fun <reified T : Any> UnivariateIntegrand(
|
||||
attributeBuilder: AttributesBuilder.() -> Unit,
|
||||
attributeBuilder: TypedAttributesBuilder<UnivariateIntegrand<T>>.() -> Unit,
|
||||
noinline function: (Double) -> T,
|
||||
): UnivariateIntegrand<T> = UnivariateIntegrand(safeTypeOf(), Attributes(attributeBuilder), function)
|
||||
|
||||
@ -52,7 +58,7 @@ public class UnivariateIntegrandRanges(public val ranges: List<Pair<ClosedRange<
|
||||
|
||||
public object UnivariateIntegrationNodes : IntegrandAttribute<Buffer<Double>>
|
||||
|
||||
public fun AttributesBuilder.integrationNodes(vararg nodes: Double) {
|
||||
public fun TypedAttributesBuilder<UnivariateIntegrand<*>>.integrationNodes(vararg nodes: Double) {
|
||||
UnivariateIntegrationNodes(Float64Buffer(nodes))
|
||||
}
|
||||
|
||||
@ -62,7 +68,7 @@ public fun AttributesBuilder.integrationNodes(vararg nodes: Double) {
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public inline fun <reified T : Any> UnivariateIntegrator<T>.integrate(
|
||||
attributesBuilder: AttributesBuilder.() -> Unit,
|
||||
attributesBuilder: TypedAttributesBuilder<UnivariateIntegrand<T>>.() -> Unit,
|
||||
noinline function: (Double) -> T,
|
||||
): UnivariateIntegrand<T> = process(UnivariateIntegrand(attributesBuilder, function))
|
||||
|
||||
@ -73,7 +79,7 @@ public inline fun <reified T : Any> UnivariateIntegrator<T>.integrate(
|
||||
@UnstableKMathAPI
|
||||
public inline fun <reified T : Any> UnivariateIntegrator<T>.integrate(
|
||||
range: ClosedRange<Double>,
|
||||
attributeBuilder: AttributesBuilder.() -> Unit = {},
|
||||
attributeBuilder: TypedAttributesBuilder<UnivariateIntegrand<T>>.() -> Unit = {},
|
||||
noinline function: (Double) -> T,
|
||||
): UnivariateIntegrand<T> {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user