From 08982855426eefe6ba2cf0987b1da732abba0064 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 19 May 2021 12:58:01 +0300 Subject: [PATCH] Removed Any restriction on polynomials --- CHANGELOG.md | 1 + .../space/kscience/kmath/functions/integrate.kt | 4 ++-- .../kmath/functions/matrixIntegration.kt | 4 ++-- .../kscience/kmath/functions/Polynomial.kt | 14 ++++++++------ .../kmath/integration/GaussIntegrator.kt | 13 +++++++------ .../kmath/integration/SimpsonIntegrator.kt | 17 +++++++++++++++++ .../kmath/integration/UnivariateIntegrand.kt | 10 ++++++++++ .../kmath/integration/GaussIntegralTest.kt | 4 ++-- settings.gradle.kts | 2 +- 9 files changed, 50 insertions(+), 19 deletions(-) create mode 100644 kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index acdf9899b..c5acd4660 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ - ColumnarData returns nullable column - MST is made sealed interface - Replaced MST.Symbolic by Symbol, Symbol now implements MST +- Removed Any restriction on polynomials ### Deprecated diff --git a/examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt b/examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt index 8d5349bce..f60b1ab45 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt @@ -5,8 +5,8 @@ package space.kscience.kmath.functions +import space.kscience.kmath.integration.gaussIntegrator import space.kscience.kmath.integration.integrate -import space.kscience.kmath.integration.integrator import space.kscience.kmath.integration.value import space.kscience.kmath.operations.DoubleField import kotlin.math.pow @@ -16,7 +16,7 @@ fun main() { val function: UnivariateFunction = { x -> 3 * x.pow(2) + 2 * x + 1 } //get the result of the integration - val result = DoubleField.integrator.integrate(0.0..10.0, function = function) + val result = DoubleField.gaussIntegrator.integrate(0.0..10.0, function = function) //the value is nullable because in some cases the integration could not succeed println(result.value) diff --git a/examples/src/main/kotlin/space/kscience/kmath/functions/matrixIntegration.kt b/examples/src/main/kotlin/space/kscience/kmath/functions/matrixIntegration.kt index 601a0e3c4..2619d3d74 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/functions/matrixIntegration.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/functions/matrixIntegration.kt @@ -5,8 +5,8 @@ package space.kscience.kmath.functions +import space.kscience.kmath.integration.gaussIntegrator import space.kscience.kmath.integration.integrate -import space.kscience.kmath.integration.integrator import space.kscience.kmath.integration.value import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.nd @@ -25,7 +25,7 @@ fun main(): Unit = DoubleField { val function: (Double) -> StructureND = { x: Double -> 3 * number(x).pow(2) + 2 * diagonal(x) + 1 } //get the result of the integration - val result = integrator.integrate(0.0..10.0, function = function) + val result = gaussIntegrator.integrate(0.0..10.0, function = function) //the value is nullable because in some cases the integration could not succeed println(result.value) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt index 325010f99..427a17385 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt @@ -19,7 +19,7 @@ import kotlin.math.pow * * @param coefficients constant is the leftmost coefficient. */ -public class Polynomial(public val coefficients: List){ +public class Polynomial(public val coefficients: List){ override fun toString(): String = "Polynomial$coefficients" } @@ -27,7 +27,7 @@ public class Polynomial(public val coefficients: List){ * Returns a [Polynomial] instance with given [coefficients]. */ @Suppress("FunctionName") -public fun Polynomial(vararg coefficients: T): Polynomial = Polynomial(coefficients.toList()) +public fun Polynomial(vararg coefficients: T): Polynomial = Polynomial(coefficients.toList()) /** * Evaluates the value of the given double polynomial for given double argument. @@ -38,7 +38,7 @@ public fun Polynomial.value(): Double = coefficients.reduceIndexed { ind * Evaluates the value of the given polynomial for given argument. * https://en.wikipedia.org/wiki/Horner%27s_method */ -public fun > Polynomial.value(ring: C, arg: T): T = ring { +public fun > Polynomial.value(ring: C, arg: T): T = ring { if (coefficients.isEmpty()) return@ring zero var result: T = coefficients.last() for (j in coefficients.size - 2 downTo 0) { @@ -50,7 +50,9 @@ public fun > Polynomial.value(ring: C, arg: T): T = ring /** * Represent the polynomial as a regular context-less function. */ -public fun > Polynomial.asFunction(ring: C): (T) -> T = { value(ring, it) } +public fun > Polynomial.asFunction(ring: C): (T) -> T = { value(ring, it) } + +//public fun /** * Space of polynomials. @@ -59,7 +61,7 @@ public fun > Polynomial.asFunction(ring: C): (T) -> T = * @param C the intersection of [Ring] of [T] and [ScaleOperations] of [T]. * @param ring the [C] instance. */ -public class PolynomialSpace( +public class PolynomialSpace( private val ring: C, ) : Group>, ScaleOperations> where C : Ring, C : ScaleOperations { public override val zero: Polynomial = Polynomial(emptyList()) @@ -87,7 +89,7 @@ public class PolynomialSpace( public operator fun Polynomial.invoke(arg: T): T = value(ring, arg) } -public inline fun C.polynomial(block: PolynomialSpace.() -> R): R where C : Ring, C : ScaleOperations { +public inline fun C.polynomial(block: PolynomialSpace.() -> R): R where C : Ring, C : ScaleOperations { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return PolynomialSpace(this).block() } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt index fcf47040e..26757ae68 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt @@ -20,6 +20,11 @@ public class UnivariateIntegrandRanges(public val ranges: List( public val algebra: Field, @@ -73,13 +78,9 @@ public class GaussIntegrator( /** * 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] + * @see [GaussIntegrator] */ -public val Field.integrator: GaussIntegrator get() = GaussIntegrator(this) +public val Field.gaussIntegrator: GaussIntegrator get() = GaussIntegrator(this) /** diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt new file mode 100644 index 000000000..526d4d35d --- /dev/null +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2018-2021 KMath contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package space.kscience.kmath.integration + +import space.kscience.kmath.operations.Ring + + +public class SimpsonIntegrator( + public val algebra: Ring, +) : UnivariateIntegrator { + override fun integrate(integrand: UnivariateIntegrand): UnivariateIntegrand { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt index 3cafc9782..c03cc8df0 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt @@ -45,6 +45,16 @@ public val UnivariateIntegrand.valueOrNull: T? get() = getFeature UnivariateIntegrand.value: T get() = valueOrNull ?: error("No value in the integrand") +/** + * A shortcut method to integrate a [function] with additional [features]. Range must be provided in features. + * The [function] is placed in the end position to allow passing a lambda. + */ +@UnstableKMathAPI +public fun UnivariateIntegrator.integrate( + vararg features: IntegrandFeature, + function: (Double) -> T, +): UnivariateIntegrand = integrate(UnivariateIntegrand(function, *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. diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt index 6195d0ac6..5c9241120 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt @@ -16,7 +16,7 @@ import kotlin.test.assertEquals class GaussIntegralTest { @Test fun gaussSin() { - val res = DoubleField.integrator.integrate(0.0..2 * PI) { x -> + val res = DoubleField.gaussIntegrator.integrate(0.0..2 * PI) { x -> sin(x) } assertEquals(0.0, res.valueOrNull!!, 1e-2) @@ -24,7 +24,7 @@ class GaussIntegralTest { @Test fun gaussUniform() { - val res = DoubleField.integrator.integrate(35.0..100.0) { x -> + val res = DoubleField.gaussIntegrator.integrate(35.0..100.0) { x -> if(x in 30.0..50.0){ 1.0 } else { diff --git a/settings.gradle.kts b/settings.gradle.kts index 7ebfe1f59..cc9eb4860 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,7 +5,7 @@ pluginManagement { maven("https://repo.kotlin.link") } - val toolsVersion = "0.9.7" + val toolsVersion = "0.9.8" val kotlinVersion = "1.5.0" plugins {