Feature: Polynomials and rational functions #469

Merged
lounres merged 132 commits from feature/polynomials into dev 2022-07-28 18:04:06 +03:00
5 changed files with 1270 additions and 1277 deletions
Showing only changes of commit 5834fad938 - Show all commits

View File

@ -8,6 +8,7 @@ package space.kscience.kmath.functions
import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.expressions.Symbol
import space.kscience.kmath.expressions.symbol import space.kscience.kmath.expressions.symbol
import space.kscience.kmath.operations.algebra import space.kscience.kmath.operations.algebra
import space.kscience.kmath.operations.invoke
/** /**
@ -102,7 +103,7 @@ fun numberedPolynomialsExample() {
numberedPolynomialSpace { numberedPolynomialSpace {
// Also there is DSL for constructing NumberedPolynomials: // Also there is DSL for constructing NumberedPolynomials:
val polynomial5: NumberedPolynomial<Int> = NumberedPolynomial { val polynomial5: NumberedPolynomial<Int> = NumberedPolynomialDSL1 {
3 {} 3 {}
5 { 2 inPowerOf 1u } 5 { 2 inPowerOf 1u }
-7 with { 1 pow 2u; 3 pow 1u } -7 with { 1 pow 2u; 3 pow 1u }
@ -116,7 +117,7 @@ fun numberedPolynomialsExample() {
} }
} }
val polynomial6: NumberedPolynomial<Int> = with(Int.algebra) { val polynomial6: NumberedPolynomial<Int> = Int.algebra {
NumberedPolynomial( NumberedPolynomial(
listOf<UInt>() to 7, listOf<UInt>() to 7,
listOf(0u, 1u) to -5, listOf(0u, 1u) to -5,
@ -127,28 +128,28 @@ fun numberedPolynomialsExample() {
// For every ring there can be provided a polynomial ring: // For every ring there can be provided a polynomial ring:
Int.algebra.numberedPolynomialSpace { Int.algebra.numberedPolynomialSpace {
println( println(
-polynomial6 == NumberedPolynomial { -polynomial6 == NumberedPolynomial(
(-7) {} listOf<UInt>() to -7,
5 { 2 pow 1u } listOf(0u, 1u) to 5,
0 { 1 pow 2u; 3 pow 1u } listOf(2u, 0u, 1u) to 0,
(-4) { 4 pow 4u } listOf(0u, 0u, 0u, 4u) to (-4),
} )
) // true ) // true
println( println(
polynomial1 + polynomial6 == NumberedPolynomial { polynomial1 + polynomial6 == NumberedPolynomial(
10 {} listOf<UInt>() to 10,
0 { 2 pow 1u } listOf(0u, 1u) to 0,
(-7) { 1 pow 2u; 3 pow 1u } listOf(2u, 0u, 1u) to -7,
4 { 4 pow 4u } listOf(0u, 0u, 0u, 4u) to 4,
} )
) // true ) // true
println( println(
polynomial1 - polynomial6 == NumberedPolynomial { polynomial1 - polynomial6 == NumberedPolynomial(
(-4) {} listOf<UInt>() to -4,
10 { 2 pow 1u } listOf(0u, 1u) to 10,
(-7) { 1 pow 2u; 3 pow 1u } listOf(2u, 0u, 1u) to -7,
(-4) { 4 pow 4u } listOf(0u, 0u, 0u, 4u) to -4,
} )
) // true ) // true
polynomial1 * polynomial6 // Multiplication works too polynomial1 * polynomial6 // Multiplication works too
@ -156,14 +157,14 @@ fun numberedPolynomialsExample() {
Double.algebra.numberedPolynomialSpace { Double.algebra.numberedPolynomialSpace {
// You can even write // You can even write
val x_1: NumberedPolynomial<Double> = NumberedPolynomial { 1.0 { 1 pow 1u } } val x_1: NumberedPolynomial<Double> = NumberedPolynomial(listOf(1u) to 1.0)
val x_2: NumberedPolynomial<Double> = NumberedPolynomial { 1.0 { 2 pow 1u } } val x_2: NumberedPolynomial<Double> = NumberedPolynomial(listOf(0u, 1u) to 1.0)
val x_3: NumberedPolynomial<Double> = NumberedPolynomial { 1.0 { 3 pow 1u } } val x_3: NumberedPolynomial<Double> = NumberedPolynomial(listOf(0u, 0u, 1u) to 1.0)
val polynomial7: NumberedPolynomial<Double> = NumberedPolynomial { val polynomial7: NumberedPolynomial<Double> = NumberedPolynomial(
3.0 {} listOf<UInt>() to 3.0,
5.0 { 2 pow 1u } listOf(0u, 1u) to 5.0,
(-7.0) { 1 pow 2u; 3 pow 1u } listOf(2u, 0u, 1u) to -7.0,
} )
Double.algebra.listPolynomialSpace { Double.algebra.listPolynomialSpace {
println(3 + 5 * x_2 - 7 * x_1 * x_1 * x_3 == polynomial7) println(3 + 5 * x_2 - 7 * x_1 * x_1 * x_3 == polynomial7)
println(3.0 + 5.0 * x_2 - 7.0 * x_1 * x_1 * x_3 == polynomial7) println(3.0 + 5.0 * x_2 - 7.0 * x_1 * x_1 * x_3 == polynomial7)
@ -171,49 +172,49 @@ fun numberedPolynomialsExample() {
} }
Int.algebra.numberedPolynomialSpace { Int.algebra.numberedPolynomialSpace {
val x_4: NumberedPolynomial<Int> = NumberedPolynomial { 1 { 4 pow 1u } } val x_4: NumberedPolynomial<Int> = NumberedPolynomial(listOf(0u, 0u, 0u, 4u) to 1)
// Also there are some utilities for polynomials: // Also there are some utilities for polynomials:
println(polynomial1.substitute(mapOf(0 to 1, 1 to -2, 2 to -1)) == 0.asNumberedPolynomial()) // true, println(polynomial1.substitute(mapOf(0 to 1, 1 to -2, 2 to -1)) == 0.asNumberedPolynomial()) // true,
// because it's substitution x_1 -> 1, x_2 -> -2, x_3 -> -1, // because it's substitution x_1 -> 1, x_2 -> -2, x_3 -> -1,
// so 3 + 5 x_2 - 7 x_1^2 x_3 = 3 + 5 * (-2) - 7 * 1^2 * (-1) = 3 - 10 + 7 = 0 // so 3 + 5 x_2 - 7 x_1^2 x_3 = 3 + 5 * (-2) - 7 * 1^2 * (-1) = 3 - 10 + 7 = 0
println( println(
polynomial1.substitute(mapOf(1 to x_4)) == NumberedPolynomial { polynomial1.substitute(mapOf(1 to x_4)) == NumberedPolynomial(
3 {} listOf<UInt>() to 3,
5 { 4 pow 1u } listOf(0u, 1u) to 5,
(-7) { 1 pow 2u; 3 pow 1u } listOf(2u, 0u, 1u) to -7,
} )
) // true, because it's substitution x_2 -> x_4, so result is 3 + 5 x_4 - 7 x_1^2 x_3 ) // true, because it's substitution x_2 -> x_4, so result is 3 + 5 x_4 - 7 x_1^2 x_3
println( println(
polynomial1.derivativeWithRespectTo(Int.algebra, 1) == polynomial1.derivativeWithRespectTo(Int.algebra, 1) ==
NumberedPolynomial { 5 {} } NumberedPolynomial(listOf<UInt>() to 5)
) // true, d/dx_2 (3 + 5 x_2 - 7 x_1^2 x_3) = 5 ) // true, d/dx_2 (3 + 5 x_2 - 7 x_1^2 x_3) = 5
} }
// Lastly, there are rational functions and some other utilities: // Lastly, there are rational functions and some other utilities:
Double.algebra.numberedRationalFunctionSpace { Double.algebra.numberedRationalFunctionSpace {
val rationalFunction1: NumberedRationalFunction<Double> = NumberedRationalFunction( val rationalFunction1: NumberedRationalFunction<Double> = NumberedRationalFunction(
NumberedPolynomial { NumberedPolynomial(
2.0 {} listOf<UInt>() to 2.0,
(-3.0) { 1 pow 1u } listOf(1u) to -3.0,
1.0 { 1 pow 2u } listOf(2u) to 1.0,
}, ),
NumberedPolynomial { NumberedPolynomial(
3.0 {} listOf<UInt>() to 3.0,
(-1.0) { 1 pow 1u } listOf(1u) to -1.0,
} )
) )
// It's just (2 - 3x + x^2)/(3 - x) where x = x_1 // It's just (2 - 3x + x^2)/(3 - x) where x = x_1
val rationalFunction2: NumberedRationalFunction<Double> = NumberedRationalFunction( val rationalFunction2: NumberedRationalFunction<Double> = NumberedRationalFunction(
NumberedPolynomial { NumberedPolynomial(
5.0 {} listOf<UInt>() to 5.0,
(-4.0) { 1 pow 1u } listOf(1u) to -4.0,
1.0 { 1 pow 2u } listOf(2u) to 1.0,
}, ),
NumberedPolynomial { NumberedPolynomial(
3.0 {} listOf<UInt>() to 3.0,
(-1.0) { 1 pow 1u } listOf(1u) to -1.0,
} )
) )
// It's just (5 - 4x + x^2)/(3 - x) where x = x_1 // It's just (5 - 4x + x^2)/(3 - x) where x = x_1
@ -267,7 +268,7 @@ fun labeledPolynomialsExample() {
labeledPolynomialSpace { labeledPolynomialSpace {
// Also there is DSL for constructing NumberedPolynomials: // Also there is DSL for constructing NumberedPolynomials:
val polynomial5: LabeledPolynomial<Int> = LabeledPolynomial { val polynomial5: LabeledPolynomial<Int> = LabeledPolynomialDSL1 {
3 {} 3 {}
5 { y inPowerOf 1u } 5 { y inPowerOf 1u }
-7 with { x pow 2u; z pow 1u } -7 with { x pow 2u; z pow 1u }
@ -281,7 +282,7 @@ fun labeledPolynomialsExample() {
} }
} }
val polynomial6: LabeledPolynomial<Int> = with(Int.algebra) { val polynomial6: LabeledPolynomial<Int> = Int.algebra {
LabeledPolynomial( LabeledPolynomial(
mapOf<Symbol, UInt>() to 7, mapOf<Symbol, UInt>() to 7,
mapOf(y to 1u) to -5, mapOf(y to 1u) to -5,
@ -292,28 +293,28 @@ fun labeledPolynomialsExample() {
// For every ring there can be provided a polynomial ring: // For every ring there can be provided a polynomial ring:
Int.algebra.labeledPolynomialSpace { Int.algebra.labeledPolynomialSpace {
println( println(
-polynomial6 == LabeledPolynomial { -polynomial6 == LabeledPolynomial(
(-7) {} mapOf<Symbol, UInt>() to -7,
5 { y pow 1u } mapOf(y to 1u) to 5,
0 { x pow 2u; z pow 1u } mapOf(x to 2u, z to 1u) to 0,
(-4) { t pow 4u } mapOf(t to 4u) to -4,
} )
) // true ) // true
println( println(
polynomial1 + polynomial6 == LabeledPolynomial { polynomial1 + polynomial6 == LabeledPolynomial(
10 {} mapOf<Symbol, UInt>() to 10,
0 { y pow 1u } mapOf(y to 1u) to 0,
(-7) { x pow 2u; z pow 1u } mapOf(x to 2u, z to 1u) to -7,
4 { t pow 4u } mapOf(t to 4u) to 4,
} )
) // true ) // true
println( println(
polynomial1 - polynomial6 == LabeledPolynomial { polynomial1 - polynomial6 == LabeledPolynomial(
(-4) {} mapOf<Symbol, UInt>() to -4,
10 { y pow 1u } mapOf(y to 1u) to 10,
(-7) { x pow 2u; z pow 1u } mapOf(x to 2u, z to 1u) to -7,
(-4) { t pow 4u } mapOf(t to 4u) to -4,
} )
) // true ) // true
polynomial1 * polynomial6 // Multiplication works too polynomial1 * polynomial6 // Multiplication works too
@ -321,11 +322,11 @@ fun labeledPolynomialsExample() {
Double.algebra.labeledPolynomialSpace { Double.algebra.labeledPolynomialSpace {
// You can even write // You can even write
val polynomial7: LabeledPolynomial<Double> = LabeledPolynomial { val polynomial7: LabeledPolynomial<Double> = LabeledPolynomial(
3.0 {} mapOf<Symbol, UInt>() to 3.0,
5.0 { y pow 1u } mapOf(y to 1u) to 5.0,
(-7.0) { x pow 2u; z pow 1u } mapOf(x to 2u, z to 1u) to -7.0,
} )
Double.algebra.listPolynomialSpace { Double.algebra.listPolynomialSpace {
println(3 + 5 * y - 7 * x * x * z == polynomial7) println(3 + 5 * y - 7 * x * x * z == polynomial7)
println(3.0 + 5.0 * y - 7.0 * x * x * z == polynomial7) println(3.0 + 5.0 * y - 7.0 * x * x * z == polynomial7)
@ -338,42 +339,42 @@ fun labeledPolynomialsExample() {
// because it's substitution x -> 1, y -> -2, z -> -1, // because it's substitution x -> 1, y -> -2, z -> -1,
// so 3 + 5 y - 7 x^2 z = 3 + 5 * (-2) - 7 * 1^2 * (-1) = 3 - 10 + 7 = 0 // so 3 + 5 y - 7 x^2 z = 3 + 5 * (-2) - 7 * 1^2 * (-1) = 3 - 10 + 7 = 0
println( println(
polynomial1.substitute(mapOf(y to t.asPolynomial())) == LabeledPolynomial { polynomial1.substitute(mapOf(y to t.asPolynomial())) == LabeledPolynomial(
3 {} mapOf<Symbol, UInt>() to 3,
5 { t pow 1u } mapOf(t to 1u) to 5,
(-7) { x pow 2u; z pow 1u } mapOf(x to 2u, z to 1u) to -7,
} )
) // true, because it's substitution y -> t, so result is 3 + 5 t - 7 x^2 z ) // true, because it's substitution y -> t, so result is 3 + 5 t - 7 x^2 z
println( println(
polynomial1.derivativeWithRespectTo(Int.algebra, y) == LabeledPolynomial { 5 {} } polynomial1.derivativeWithRespectTo(Int.algebra, y) == LabeledPolynomial(mapOf<Symbol, UInt>() to 5)
) // true, d/dy (3 + 5 y - 7 x^2 z) = 5 ) // true, d/dy (3 + 5 y - 7 x^2 z) = 5
} }
// Lastly, there are rational functions and some other utilities: // Lastly, there are rational functions and some other utilities:
Double.algebra.labeledRationalFunctionSpace { Double.algebra.labeledRationalFunctionSpace {
val rationalFunction1: LabeledRationalFunction<Double> = LabeledRationalFunction( val rationalFunction1: LabeledRationalFunction<Double> = LabeledRationalFunction(
LabeledPolynomial { LabeledPolynomial(
2.0 {} mapOf<Symbol, UInt>() to 2.0,
(-3.0) { x pow 1u } mapOf(x to 1u) to -3.0,
1.0 { x pow 2u } mapOf(x to 2u) to 1.0,
}, ),
LabeledPolynomial { LabeledPolynomial(
3.0 {} mapOf<Symbol, UInt>() to 3.0,
(-1.0) { x pow 1u } mapOf(x to 1u) to -1.0,
} )
) )
// It's just (2 - 3x + x^2)/(3 - x) // It's just (2 - 3x + x^2)/(3 - x)
val rationalFunction2: LabeledRationalFunction<Double> = LabeledRationalFunction( val rationalFunction2: LabeledRationalFunction<Double> = LabeledRationalFunction(
LabeledPolynomial { LabeledPolynomial(
5.0 {} mapOf<Symbol, UInt>() to 5.0,
(-4.0) { x pow 1u } mapOf(x to 1u) to -4.0,
1.0 { x pow 2u } mapOf(x to 2u) to 1.0,
}, ),
LabeledPolynomial { LabeledPolynomial(
3.0 {} mapOf<Symbol, UInt>() to 3.0,
(-1.0) { x pow 1u } mapOf(x to 1u) to -1.0,
} )
) )
// It's just (5 - 4x + x^2)/(3 - x) // It's just (5 - 4x + x^2)/(3 - x)

View File

@ -274,14 +274,14 @@ public inline fun <C> C.asLabeledPolynomial() : LabeledPolynomial<C> = LabeledPo
*/ */
@DslMarker @DslMarker
@UnstableKMathAPI @UnstableKMathAPI
internal annotation class LabeledPolynomialConstructorDSL internal annotation class LabeledPolynomialConstructorDSL1
/** /**
* Builder of [LabeledPolynomial] signature. It should be used as an implicit context for lambdas that describe term signature. * Builder of [LabeledPolynomial] signature. It should be used as an implicit context for lambdas that describe term signature.
*/ */
@UnstableKMathAPI @UnstableKMathAPI
@LabeledPolynomialConstructorDSL @LabeledPolynomialConstructorDSL1
public class LabeledPolynomialTermSignatureBuilder { public class DSL1LabeledPolynomialTermSignatureBuilder {
/** /**
* Signature storage. Any declaration of any variable's power updates the storage by increasing corresponding value. * Signature storage. Any declaration of any variable's power updates the storage by increasing corresponding value.
* Afterward the storage will be used as a resulting signature. * Afterward the storage will be used as a resulting signature.
@ -302,7 +302,7 @@ public class LabeledPolynomialTermSignatureBuilder {
* Declaring another power of the same variable will increase its degree by received degree. * Declaring another power of the same variable will increase its degree by received degree.
*/ */
public infix fun Symbol.inPowerOf(deg: UInt) { public infix fun Symbol.inPowerOf(deg: UInt) {
signature[this] = deg signature[this] = signature.getOrElse(this) { 0u } + deg
} }
/** /**
* Declares power of [this] variable of degree [deg]. * Declares power of [this] variable of degree [deg].
@ -328,7 +328,8 @@ public class LabeledPolynomialTermSignatureBuilder {
* Builder of [LabeledPolynomial]. It should be used as an implicit context for lambdas that describe [LabeledPolynomial]. * Builder of [LabeledPolynomial]. It should be used as an implicit context for lambdas that describe [LabeledPolynomial].
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public class LabeledPolynomialBuilder<C>( @LabeledPolynomialConstructorDSL1
public class DSL1LabeledPolynomialBuilder<C>(
/** /**
* Summation operation that will be used to sum coefficients of monomials of same signatures. * Summation operation that will be used to sum coefficients of monomials of same signatures.
*/ */
@ -367,15 +368,15 @@ public class LabeledPolynomialBuilder<C>(
* Declaring another monomial with the same signature will add [this] coefficient to existing one. If the sum of such * Declaring another monomial with the same signature will add [this] coefficient to existing one. If the sum of such
* coefficients is zero at any moment the monomial won't be removed but will be left as it is. * coefficients is zero at any moment the monomial won't be removed but will be left as it is.
*/ */
public inline infix fun C.with(noinline block: LabeledPolynomialTermSignatureBuilder.() -> Unit): Unit = this.invoke(block) public inline infix fun C.with(noinline block: DSL1LabeledPolynomialTermSignatureBuilder.() -> Unit): Unit = this.invoke(block)
/** /**
* Declares monomial with [this] coefficient and signature constructed by [block]. * Declares monomial with [this] coefficient and signature constructed by [block].
* *
* Declaring another monomial with the same signature will add [this] coefficient to existing one. If the sum of such * Declaring another monomial with the same signature will add [this] coefficient to existing one. If the sum of such
* coefficients is zero at any moment the monomial won't be removed but will be left as it is. * coefficients is zero at any moment the monomial won't be removed but will be left as it is.
*/ */
public inline operator fun C.invoke(block: LabeledPolynomialTermSignatureBuilder.() -> Unit): Unit = public inline operator fun C.invoke(block: DSL1LabeledPolynomialTermSignatureBuilder.() -> Unit): Unit =
this with LabeledPolynomialTermSignatureBuilder().apply(block).build() this with DSL1LabeledPolynomialTermSignatureBuilder().apply(block).build()
} }
// Waiting for context receivers :( FIXME: Replace with context receivers when they will be available // Waiting for context receivers :( FIXME: Replace with context receivers when they will be available
@ -398,7 +399,7 @@ public class LabeledPolynomialBuilder<C>(
// 2. Union types are implemented. Then all three functions should be rewritten // 2. Union types are implemented. Then all three functions should be rewritten
// as one with single union type as a (context) receiver. // as one with single union type as a (context) receiver.
//@UnstableKMathAPI //@UnstableKMathAPI
//public inline fun <C, A: Ring<C>> A.LabeledPolynomial(initialCapacity: Int = 0, block: LabeledPolynomialBuilder<C>.() -> Unit) : LabeledPolynomial<C> = LabeledPolynomialBuilder(::add, initialCapacity).apply(block).build() //public inline fun <C, A: Ring<C>> A.LabeledPolynomialDSL1(initialCapacity: Int = 0, block: LabeledPolynomialBuilder<C>.() -> Unit) : LabeledPolynomial<C> = LabeledPolynomialBuilder(::add, initialCapacity).apply(block).build()
/** /**
* Creates [LabeledPolynomial] with lambda [block] in context of [this] ring of [LabeledPolynomial]s. * Creates [LabeledPolynomial] with lambda [block] in context of [this] ring of [LabeledPolynomial]s.
* *
@ -413,7 +414,7 @@ public class LabeledPolynomialBuilder<C>(
* ``` * ```
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public inline fun <C, A: Ring<C>> LabeledPolynomialSpace<C, A>.LabeledPolynomial(initialCapacity: Int = 0, block: LabeledPolynomialBuilder<C>.() -> Unit) : LabeledPolynomial<C> = LabeledPolynomialBuilder({ left: C, right: C -> left + right }, initialCapacity).apply(block).build() public inline fun <C, A: Ring<C>> LabeledPolynomialSpace<C, A>.LabeledPolynomialDSL1(initialCapacity: Int = 0, block: DSL1LabeledPolynomialBuilder<C>.() -> Unit) : LabeledPolynomial<C> = DSL1LabeledPolynomialBuilder({ left: C, right: C -> left + right }, initialCapacity).apply(block).build()
/** /**
* Creates [LabeledPolynomial] with lambda [block] in context of [this] field of [LabeledRationalFunction]s. * Creates [LabeledPolynomial] with lambda [block] in context of [this] field of [LabeledRationalFunction]s.
* *
@ -428,7 +429,7 @@ public inline fun <C, A: Ring<C>> LabeledPolynomialSpace<C, A>.LabeledPolynomial
* ``` * ```
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public inline fun <C, A: Ring<C>> LabeledRationalFunctionSpace<C, A>.LabeledPolynomial(initialCapacity: Int = 0, block: LabeledPolynomialBuilder<C>.() -> Unit) : LabeledPolynomial<C> = LabeledPolynomialBuilder({ left: C, right: C -> left + right }, initialCapacity).apply(block).build() public inline fun <C, A: Ring<C>> LabeledRationalFunctionSpace<C, A>.LabeledPolynomialDSL1(initialCapacity: Int = 0, block: DSL1LabeledPolynomialBuilder<C>.() -> Unit) : LabeledPolynomial<C> = DSL1LabeledPolynomialBuilder({ left: C, right: C -> left + right }, initialCapacity).apply(block).build()
// Waiting for context receivers :( FIXME: Replace with context receivers when they will be available // Waiting for context receivers :( FIXME: Replace with context receivers when they will be available

View File

@ -255,14 +255,14 @@ public inline fun <C> C.asNumberedPolynomial() : NumberedPolynomial<C> = Numbere
*/ */
@DslMarker @DslMarker
@UnstableKMathAPI @UnstableKMathAPI
internal annotation class NumberedPolynomialConstructorDSL internal annotation class NumberedPolynomialConstructorDSL1
/** /**
* Builder of [NumberedPolynomial] signature. It should be used as an implicit context for lambdas that describe term signature. * Builder of [NumberedPolynomial] signature. It should be used as an implicit context for lambdas that describe term signature.
*/ */
@UnstableKMathAPI @UnstableKMathAPI
@NumberedPolynomialConstructorDSL @NumberedPolynomialConstructorDSL1
public class NumberedPolynomialTermSignatureBuilder { public class DSL1NumberedPolynomialTermSignatureBuilder {
/** /**
* Signature storage. Any declaration of any variable's power updates the storage by increasing corresponding value. * Signature storage. Any declaration of any variable's power updates the storage by increasing corresponding value.
* Afterward the storage will be used as a resulting signature. * Afterward the storage will be used as a resulting signature.
@ -316,8 +316,8 @@ public class NumberedPolynomialTermSignatureBuilder {
* Builder of [NumberedPolynomial]. It should be used as an implicit context for lambdas that describe [NumberedPolynomial]. * Builder of [NumberedPolynomial]. It should be used as an implicit context for lambdas that describe [NumberedPolynomial].
*/ */
@UnstableKMathAPI @UnstableKMathAPI
@NumberedPolynomialConstructorDSL @NumberedPolynomialConstructorDSL1
public class NumberedPolynomialBuilder<C>( public class DSL1NumberedPolynomialBuilder<C>(
/** /**
* Summation operation that will be used to sum coefficients of monomials of same signatures. * Summation operation that will be used to sum coefficients of monomials of same signatures.
*/ */
@ -356,15 +356,15 @@ public class NumberedPolynomialBuilder<C>(
* Declaring another monomial with the same signature will add [this] coefficient to existing one. If the sum of such * Declaring another monomial with the same signature will add [this] coefficient to existing one. If the sum of such
* coefficients is zero at any moment the monomial won't be removed but will be left as it is. * coefficients is zero at any moment the monomial won't be removed but will be left as it is.
*/ */
public inline infix fun C.with(noinline block: NumberedPolynomialTermSignatureBuilder.() -> Unit): Unit = this.invoke(block) public inline infix fun C.with(noinline block: DSL1NumberedPolynomialTermSignatureBuilder.() -> Unit): Unit = this.invoke(block)
/** /**
* Declares monomial with [this] coefficient and signature constructed by [block]. * Declares monomial with [this] coefficient and signature constructed by [block].
* *
* Declaring another monomial with the same signature will add [this] coefficient to existing one. If the sum of such * Declaring another monomial with the same signature will add [this] coefficient to existing one. If the sum of such
* coefficients is zero at any moment the monomial won't be removed but will be left as it is. * coefficients is zero at any moment the monomial won't be removed but will be left as it is.
*/ */
public inline operator fun C.invoke(block: NumberedPolynomialTermSignatureBuilder.() -> Unit): Unit = public inline operator fun C.invoke(block: DSL1NumberedPolynomialTermSignatureBuilder.() -> Unit): Unit =
this with NumberedPolynomialTermSignatureBuilder().apply(block).build() this with DSL1NumberedPolynomialTermSignatureBuilder().apply(block).build()
} }
// Waiting for context receivers :( FIXME: Replace with context receivers when they will be available // Waiting for context receivers :( FIXME: Replace with context receivers when they will be available
@ -387,7 +387,7 @@ public class NumberedPolynomialBuilder<C>(
// 2. Union types are implemented. Then all three functions should be rewritten // 2. Union types are implemented. Then all three functions should be rewritten
// as one with single union type as a (context) receiver. // as one with single union type as a (context) receiver.
//@UnstableKMathAPI //@UnstableKMathAPI
//public inline fun <C, A: Ring<C>> A.NumberedPolynomial(initialCapacity: Int = 0, block: NumberedPolynomialBuilder<C>.() -> Unit) : NumberedPolynomial<C> = NumberedPolynomialBuilder(::add, initialCapacity).apply(block).build() //public inline fun <C, A: Ring<C>> A.NumberedPolynomialDSL1(initialCapacity: Int = 0, block: NumberedPolynomialBuilder<C>.() -> Unit) : NumberedPolynomial<C> = NumberedPolynomialBuilder(::add, initialCapacity).apply(block).build()
/** /**
* Creates [NumberedPolynomial] with lambda [block] in context of [this] ring of [NumberedPolynomial]s. * Creates [NumberedPolynomial] with lambda [block] in context of [this] ring of [NumberedPolynomial]s.
* *
@ -402,7 +402,7 @@ public class NumberedPolynomialBuilder<C>(
* ``` * ```
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public inline fun <C, A: Ring<C>> NumberedPolynomialSpace<C, A>.NumberedPolynomial(initialCapacity: Int = 0, block: NumberedPolynomialBuilder<C>.() -> Unit) : NumberedPolynomial<C> = NumberedPolynomialBuilder({ left: C, right: C -> left + right }, initialCapacity).apply(block).build() public inline fun <C, A: Ring<C>> NumberedPolynomialSpace<C, A>.NumberedPolynomialDSL1(initialCapacity: Int = 0, block: DSL1NumberedPolynomialBuilder<C>.() -> Unit) : NumberedPolynomial<C> = DSL1NumberedPolynomialBuilder({ left: C, right: C -> left + right }, initialCapacity).apply(block).build()
/** /**
* Creates [NumberedPolynomial] with lambda [block] in context of [this] field of [NumberedRationalFunction]s. * Creates [NumberedPolynomial] with lambda [block] in context of [this] field of [NumberedRationalFunction]s.
* *
@ -417,7 +417,7 @@ public inline fun <C, A: Ring<C>> NumberedPolynomialSpace<C, A>.NumberedPolynomi
* ``` * ```
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public inline fun <C, A: Ring<C>> NumberedRationalFunctionSpace<C, A>.NumberedPolynomial(initialCapacity: Int = 0, block: NumberedPolynomialBuilder<C>.() -> Unit) : NumberedPolynomial<C> = NumberedPolynomialBuilder({ left: C, right: C -> left + right }, initialCapacity).apply(block).build() public inline fun <C, A: Ring<C>> NumberedRationalFunctionSpace<C, A>.NumberedPolynomialDSL1(initialCapacity: Int = 0, block: DSL1NumberedPolynomialBuilder<C>.() -> Unit) : NumberedPolynomial<C> = DSL1NumberedPolynomialBuilder({ left: C, right: C -> left + right }, initialCapacity).apply(block).build()
// Waiting for context receivers :( FIXME: Replace with context receivers when they will be available // Waiting for context receivers :( FIXME: Replace with context receivers when they will be available

View File

@ -15,14 +15,14 @@ import kotlin.test.assertEquals
class NumberedConstructorsTest { class NumberedConstructorsTest {
@Test @Test
@UnstableKMathAPI @UnstableKMathAPI
fun testBuilder() { fun testDSL1() {
assertEquals( assertEquals(
NumberedPolynomialAsIs( NumberedPolynomialAsIs(
listOf(2u, 0u, 3u) to 5, listOf(2u, 0u, 3u) to 5,
listOf(0u, 1u) to -6, listOf(0u, 1u) to -6,
), ),
Int.algebra.numberedPolynomialSpace { Int.algebra.numberedPolynomialSpace {
NumberedPolynomial { NumberedPolynomialDSL1 {
5 { 1 pow 2u; 3 pow 3u } 5 { 1 pow 2u; 3 pow 3u }
(-6) { 2 pow 1u } (-6) { 2 pow 1u }
} }
@ -34,7 +34,7 @@ class NumberedConstructorsTest {
listOf<UInt>() to -1, listOf<UInt>() to -1,
), ),
Int.algebra.numberedPolynomialSpace { Int.algebra.numberedPolynomialSpace {
NumberedPolynomial { NumberedPolynomialDSL1 {
5 { } 5 { }
(-6) { } (-6) { }
} }
@ -46,7 +46,7 @@ class NumberedConstructorsTest {
listOf(2u) to -1, listOf(2u) to -1,
), ),
Int.algebra.numberedPolynomialSpace { Int.algebra.numberedPolynomialSpace {
NumberedPolynomial { NumberedPolynomialDSL1 {
5 { 1 pow 1u; 1 pow 1u } 5 { 1 pow 1u; 1 pow 1u }
(-6) { 1 pow 2u } (-6) { 1 pow 2u }
} }
@ -58,7 +58,7 @@ class NumberedConstructorsTest {
listOf(2u) to -1, listOf(2u) to -1,
), ),
Int.algebra.numberedPolynomialSpace { Int.algebra.numberedPolynomialSpace {
NumberedPolynomial { NumberedPolynomialDSL1 {
5 { 1 pow 1u; 1 pow 1u } 5 { 1 pow 1u; 1 pow 1u }
(-6) { 1 pow 2u; 3 pow 0u } (-6) { 1 pow 2u; 3 pow 0u }
} }