From 5bc627f1d414730c2b2383a179edf290f6e5a47f Mon Sep 17 00:00:00 2001 From: Gleb Minaev <43728100+lounres@users.noreply.github.com> Date: Tue, 12 Jul 2022 01:56:34 +0300 Subject: [PATCH] Rollback all breaking changes. The only breaking change now is value class. --- .../kscience/kmath/functions/Piecewise.kt | 8 ++-- .../kscience/kmath/functions/Polynomial.kt | 24 +++------- .../kmath/functions/polynomialUtil.kt | 32 ++++--------- .../kmath/integration/SplineIntegrator.kt | 3 +- .../kmath/interpolation/Interpolator.kt | 4 +- .../kmath/functions/PolynomialUtilTest.kt | 46 +++++++++---------- 6 files changed, 45 insertions(+), 72 deletions(-) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt index cfd21d552..16af7f555 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt @@ -117,16 +117,16 @@ public fun > PiecewisePolynomial( * Return a value of polynomial function with given [ring] a given [arg] or null if argument is outside piecewise * definition. */ -public fun , C : Ring> PiecewisePolynomial.substitute(ring: C, arg: T): T? = - findPiece(arg)?.substitute(ring, arg) +public fun , C : Ring> PiecewisePolynomial.value(ring: C, arg: T): T? = + findPiece(arg)?.value(ring, arg) /** * Convert this polynomial to a function returning nullable value (null if argument is outside piecewise range). */ -public fun , C : Ring> PiecewisePolynomial.asFunction(ring: C): (T) -> T? = { substitute(ring, it) } +public fun , C : Ring> PiecewisePolynomial.asFunction(ring: C): (T) -> T? = { value(ring, it) } /** * Convert this polynomial to a function using [defaultValue] for arguments outside the piecewise range. */ public fun , C : Ring> PiecewisePolynomial.asFunction(ring: C, defaultValue: T): (T) -> T = - { substitute(ring, it) ?: defaultValue } + { value(ring, it) ?: defaultValue } 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 061f556f6..bfb378cce 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 @@ -59,12 +59,12 @@ public value class Polynomial( * @param A type of provided underlying ring of constants. It's [Ring] of [C]. * @param ring underlying ring of constants of type [A]. */ -public open class PolynomialSpace>( +public open class PolynomialSpace( /** * Underlying ring of constants. Its operations on constants are inherited by local operations on constants. */ public val ring: A, -) : Ring> { +) : Ring>, ScaleOperations> where A : Ring, A : ScaleOperations { /** * Instance of zero constant (zero of the underlying ring). @@ -267,13 +267,15 @@ public open class PolynomialSpace>( override fun add(left: Polynomial, right: Polynomial): Polynomial = left + right override fun multiply(left: Polynomial, right: Polynomial): Polynomial = left * right + override fun scale(a: Polynomial, value: Double): Polynomial = + ring { Polynomial(a.coefficients.map { scale(it, value) }) } // TODO: When context receivers will be ready move all of this substitutions and invocations to utilities with // [ListPolynomialSpace] as a context receiver /** * Evaluates value of [this] polynomial on provided [argument]. */ - public inline fun Polynomial.substitute(argument: C): C = substitute(ring, argument) + public inline fun Polynomial.substitute(argument: C): C = value(ring, argument) /** * Represent [this] polynomial as a regular context-less function. @@ -283,19 +285,5 @@ public open class PolynomialSpace>( /** * Evaluates value of [this] polynomial on provided [argument]. */ - public inline operator fun Polynomial.invoke(argument: C): C = substitute(ring, argument) -} - -/** - * Space of polynomials constructed over ring. - * - * @param C the type of constants. Polynomials have them as a coefficients in their terms. - * @param A type of underlying ring of constants. It's [Ring] of [C]. - * @param ring underlying ring of constants of type [A]. - */ -public class ScalablePolynomialSpace( - ring: A, -) : PolynomialSpace(ring), ScaleOperations> where A : Ring, A : ScaleOperations { - override fun scale(a: Polynomial, value: Double): Polynomial = - ring { Polynomial(a.coefficients.map { scale(it, value) }) } + public inline operator fun Polynomial.invoke(argument: C): C = value(ring, argument) } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialUtil.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialUtil.kt index 0e1259bee..f745bf6e4 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialUtil.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialUtil.kt @@ -16,36 +16,22 @@ import kotlin.math.pow /** * Creates a [PolynomialSpace] over a received ring. */ -public inline val > A.polynomialSpace: PolynomialSpace +public inline val A.polynomialSpace: PolynomialSpace where A : Ring, A : ScaleOperations get() = PolynomialSpace(this) /** * Creates a [PolynomialSpace]'s scope over a received ring. */ // TODO: When context will be ready move [ListPolynomialSpace] and add [A] to context receivers of [block] -public inline fun , R> A.polynomialSpace(block: PolynomialSpace.() -> R): R { +public inline fun A.polynomialSpace(block: PolynomialSpace.() -> R): R where A : Ring, A : ScaleOperations { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return PolynomialSpace(this).block() } -/** - * Creates a [ScalablePolynomialSpace] over a received scalable ring. - */ -public inline val A.scalablePolynomialSpace: ScalablePolynomialSpace where A : Ring, A : ScaleOperations - get() = ScalablePolynomialSpace(this) - -/** - * Creates a [ScalablePolynomialSpace]'s scope over a received scalable ring. - */ // TODO: When context will be ready move [ListPolynomialSpace] and add [A] to context receivers of [block] -public inline fun A.scalablePolynomialSpace(block: ScalablePolynomialSpace.() -> R): R where A : Ring, A : ScaleOperations { - contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } - return ScalablePolynomialSpace(this).block() -} - /** * Evaluates value of [this] Double polynomial on provided Double argument. */ -public fun Polynomial.substitute(arg: Double): Double = +public fun Polynomial.value(arg: Double): Double = coefficients.reduceIndexedOrNull { index, acc, c -> acc + c * arg.pow(index) } ?: .0 @@ -55,7 +41,7 @@ public fun Polynomial.substitute(arg: Double): Double = * * It is an implementation of [Horner's method](https://en.wikipedia.org/wiki/Horner%27s_method). */ -public fun Polynomial.substitute(ring: Ring, arg: C): C = ring { +public fun Polynomial.value(ring: Ring, arg: C): C = ring { if (coefficients.isEmpty()) return zero var result: C = coefficients.last() for (j in coefficients.size - 2 downTo 0) { @@ -67,13 +53,13 @@ public fun Polynomial.substitute(ring: Ring, arg: C): C = ring { /** * Represent [this] polynomial as a regular context-less function. */ -public fun > Polynomial.asFunctionOver(ring: A): (C) -> C = { substitute(ring, it) } +public fun > Polynomial.asFunctionOver(ring: A): (C) -> C = { value(ring, it) } /** * Returns algebraic derivative of received polynomial. */ @UnstableKMathAPI -public fun Polynomial.derivative( +public fun Polynomial.differentiate( ring: A, ): Polynomial where A : Ring, A : NumericAlgebra = ring { Polynomial( @@ -87,7 +73,7 @@ public fun Polynomial.derivative( * Returns algebraic antiderivative of received polynomial. */ @UnstableKMathAPI -public fun Polynomial.antiderivative( +public fun Polynomial.integrate( ring: A, ): Polynomial where A : Field, A : NumericAlgebra = ring { Polynomial( @@ -106,6 +92,6 @@ public fun > Polynomial.integrate( ring: Field, range: ClosedRange, ): C { - val antiderivative = antiderivative(ring) - return ring { antiderivative.substitute(ring, range.endInclusive) - antiderivative.substitute(ring, range.start) } + val antiderivative = integrate(ring) + return ring { antiderivative.value(ring, range.endInclusive) - antiderivative.value(ring, range.start) } } \ No newline at end of file diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt index 0fcd4c6e5..eb88d9ae0 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt @@ -7,7 +7,6 @@ package space.kscience.kmath.integration import space.kscience.kmath.functions.PiecewisePolynomial import space.kscience.kmath.functions.integrate -import space.kscience.kmath.functions.antiderivative import space.kscience.kmath.interpolation.PolynomialInterpolator import space.kscience.kmath.interpolation.SplineInterpolator import space.kscience.kmath.interpolation.interpolatePolynomials @@ -24,7 +23,7 @@ import space.kscience.kmath.structures.MutableBufferFactory @OptIn(PerformancePitfall::class) @UnstableKMathAPI public fun > PiecewisePolynomial.integrate(algebra: Field): PiecewisePolynomial = - PiecewisePolynomial(pieces.map { it.first to it.second.antiderivative(algebra) }) + PiecewisePolynomial(pieces.map { it.first to it.second.integrate(algebra) }) /** * Compute definite integral of given [PiecewisePolynomial] piece by piece in a given [range] diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt index 62819be0c..2266092a3 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt @@ -10,7 +10,7 @@ package space.kscience.kmath.interpolation import space.kscience.kmath.data.XYColumnarData import space.kscience.kmath.functions.PiecewisePolynomial import space.kscience.kmath.functions.asFunction -import space.kscience.kmath.functions.substitute +import space.kscience.kmath.functions.value import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.operations.Ring import space.kscience.kmath.structures.Buffer @@ -34,7 +34,7 @@ public interface PolynomialInterpolator> : Interpolator): PiecewisePolynomial override fun interpolate(points: XYColumnarData): (T) -> T = { x -> - interpolatePolynomials(points).substitute(algebra, x) ?: getDefaultValue() + interpolatePolynomials(points).value(algebra, x) ?: getDefaultValue() } } diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialUtilTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialUtilTest.kt index 820b487b4..9d0fe4cc3 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialUtilTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialUtilTest.kt @@ -15,119 +15,119 @@ import kotlin.test.assertEquals @OptIn(UnstableKMathAPI::class) class PolynomialUtilTest { @Test - fun test_Polynomial_substitute_Double() { + fun test_Polynomial_value_Double() { assertEquals( 0.0, - Polynomial(1.0, -2.0, 1.0).substitute(1.0), + Polynomial(1.0, -2.0, 1.0).value(1.0), 0.001, "test 1" ) assertEquals( 0.0, - Polynomial(1.0, -2.0, 1.0).substitute(1.0), + Polynomial(1.0, -2.0, 1.0).value(1.0), 0.001, "test 1" ) assertEquals( 1.1931904761904761, - Polynomial(0.625, 2.6666666666666665, 0.5714285714285714, 1.5).substitute(0.2), + Polynomial(0.625, 2.6666666666666665, 0.5714285714285714, 1.5).value(0.2), 0.001, "test 2" ) assertEquals( 0.5681904761904762, - Polynomial(0.0, 2.6666666666666665, 0.5714285714285714, 1.5).substitute(0.2), + Polynomial(0.0, 2.6666666666666665, 0.5714285714285714, 1.5).value(0.2), 0.001, "test 3" ) assertEquals( 1.1811904761904761, - Polynomial(0.625, 2.6666666666666665, 0.5714285714285714, 0.0).substitute(0.2), + Polynomial(0.625, 2.6666666666666665, 0.5714285714285714, 0.0).value(0.2), 0.001, "test 4" ) assertEquals( 1.1703333333333332, - Polynomial(0.625, 2.6666666666666665, 0.0, 1.5).substitute(0.2), + Polynomial(0.625, 2.6666666666666665, 0.0, 1.5).value(0.2), 0.001, "test 5" ) } @Test - fun test_Polynomial_substitute_Constant() { + fun test_Polynomial_value_Constant() { assertEquals( Rational(0), - Polynomial(Rational(1), Rational(-2), Rational(1)).substitute(RationalField, Rational(1)), + Polynomial(Rational(1), Rational(-2), Rational(1)).value(RationalField, Rational(1)), "test 1" ) assertEquals( Rational(25057, 21000), Polynomial(Rational(5, 8), Rational(8, 3), Rational(4, 7), Rational(3, 2)) - .substitute(RationalField, Rational(1, 5)), + .value(RationalField, Rational(1, 5)), "test 2" ) assertEquals( Rational(2983, 5250), Polynomial(Rational(0), Rational(8, 3), Rational(4, 7), Rational(3, 2)) - .substitute(RationalField, Rational(1, 5)), + .value(RationalField, Rational(1, 5)), "test 3" ) assertEquals( Rational(4961, 4200), Polynomial(Rational(5, 8), Rational(8, 3), Rational(4, 7), Rational(0)) - .substitute(RationalField, Rational(1, 5)), + .value(RationalField, Rational(1, 5)), "test 4" ) assertEquals( Rational(3511, 3000), Polynomial(Rational(5, 8), Rational(8, 3), Rational(0), Rational(3, 2)) - .substitute(RationalField, Rational(1, 5)), + .value(RationalField, Rational(1, 5)), "test 5" ) } @Test - fun test_Polynomial_derivative() { + fun test_Polynomial_differentiate() { assertEquals( Polynomial(Rational(-2), Rational(2)), - Polynomial(Rational(1), Rational(-2), Rational(1)).derivative(RationalField), + Polynomial(Rational(1), Rational(-2), Rational(1)).differentiate(RationalField), "test 1" ) assertEquals( Polynomial(Rational(-8, 3), Rational(8, 9), Rational(15, 7), Rational(-20, 9)), - Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).derivative(RationalField), + Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).differentiate(RationalField), "test 2" ) assertEquals( Polynomial(Rational(0), Rational(8, 9), Rational(15, 7), Rational(-20, 9)), - Polynomial(Rational(0), Rational(0), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).derivative(RationalField), + Polynomial(Rational(0), Rational(0), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).differentiate(RationalField), "test 3" ) assertEquals( Polynomial(Rational(-8, 3), Rational(8, 9), Rational(15, 7), Rational(0)), - Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(0)).derivative(RationalField), + Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(0)).differentiate(RationalField), "test 4" ) } @Test - fun test_Polynomial_antiderivative() { + fun test_Polynomial_integrate() { assertEquals( Polynomial(Rational(0), Rational(1), Rational(-1), Rational(1, 3)), - Polynomial(Rational(1), Rational(-2), Rational(1)).antiderivative(RationalField), + Polynomial(Rational(1), Rational(-2), Rational(1)).integrate(RationalField), "test 1" ) assertEquals( Polynomial(Rational(0), Rational(1, 5), Rational(-4, 3), Rational(4, 27), Rational(5, 28), Rational(-1, 9)), - Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).antiderivative(RationalField), + Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).integrate(RationalField), "test 2" ) assertEquals( Polynomial(Rational(0), Rational(0), Rational(0), Rational(4, 27), Rational(5, 28), Rational(-1, 9)), - Polynomial(Rational(0), Rational(0), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).antiderivative(RationalField), + Polynomial(Rational(0), Rational(0), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).integrate(RationalField), "test 3" ) assertEquals( Polynomial(Rational(0), Rational(1, 5), Rational(-4, 3), Rational(4, 27), Rational(5, 28), Rational(0)), - Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(0)).antiderivative(RationalField), + Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(0)).integrate(RationalField), "test 4" ) }