Feature: Polynomials and rational functions #469

Merged
lounres merged 132 commits from feature/polynomials into dev 2022-07-28 18:04:06 +03:00
3 changed files with 40 additions and 40 deletions
Showing only changes of commit 4ea29c82c5 - Show all commits

View File

@ -107,8 +107,8 @@ fun numberedPolynomialsExample() {
// Also there is DSL for constructing NumberedPolynomials: // Also there is DSL for constructing NumberedPolynomials:
val polynomial5: NumberedPolynomial<Int> = NumberedPolynomialDSL1 { val polynomial5: NumberedPolynomial<Int> = NumberedPolynomialDSL1 {
3 {} 3 {}
5 { 2 inPowerOf 1u } 5 { 1 inPowerOf 1u }
-7 with { 1 pow 2u; 3 pow 1u } -7 with { 0 pow 2u; 2 pow 1u }
// `pow` and `inPowerOf` are the same // `pow` and `inPowerOf` are the same
// `with` is omittable // `with` is omittable
} }

View File

@ -265,7 +265,7 @@ public inline fun <C> C.asLabeledPolynomial() : LabeledPolynomial<C> = LabeledPo
* For example, polynomial \(5 a^2 c^3 - 6 b\) can be described as * For example, polynomial \(5 a^2 c^3 - 6 b\) can be described as
* ``` * ```
* Int.algebra { * Int.algebra {
* val numberedPolynomial : NumberedPolynomial<Int> = NumberedPolynomial { * val labeledPolynomial : LabeledPolynomial<Int> = LabeledPolynomialDSL1 {
* 5 { a inPowerOf 2u; c inPowerOf 3u } // 5 a^2 c^3 + * 5 { a inPowerOf 2u; c inPowerOf 3u } // 5 a^2 c^3 +
* (-6) { b inPowerOf 1u } // (-6) b^1 * (-6) { b inPowerOf 1u } // (-6) b^1
* } * }
@ -339,18 +339,18 @@ public class DSL1LabeledPolynomialBuilder<C>(
/** /**
* Initial capacity of coefficients map. * Initial capacity of coefficients map.
*/ */
initialCapacity: Int = 0 initialCapacity: Int? = null
) { ) {
/** /**
* Coefficients storage. Any declaration of any monomial updates the storage. * Coefficients storage. Any declaration of any monomial updates the storage.
* Afterward the storage will be used as a resulting coefficients map. * Afterward the storage will be used as a resulting coefficients map.
*/ */
private val coefficients: MutableMap<Map<Symbol, UInt>, C> = LinkedHashMap(initialCapacity) private val coefficients: MutableMap<Map<Symbol, UInt>, C> = if (initialCapacity != null) LinkedHashMap(initialCapacity) else LinkedHashMap()
/** /**
* Builds the resulting coefficients map. * Builds the resulting coefficients map.
* *
* In fact, it just returns [coefficients] as regular coefficients map of type `Map<List<UInt>, C>`. * In fact, it just returns [coefficients] as regular coefficients map of type `Map<Map<Symbol, UInt>, C>`.
*/ */
@PublishedApi @PublishedApi
internal fun build(): LabeledPolynomial<C> = LabeledPolynomial<C>(coefficients) internal fun build(): LabeledPolynomial<C> = LabeledPolynomial<C>(coefficients)
@ -386,12 +386,12 @@ public class DSL1LabeledPolynomialBuilder<C>(
///** ///**
// * Creates [LabeledPolynomial] with lambda [block] in context of [this] ring of constants. // * Creates [LabeledPolynomial] with lambda [block] in context of [this] ring of constants.
// * // *
// * For example, polynomial \(5 x_1^2 x_3^3 - 6 x_2\) can be described as // * For example, polynomial \(5 a^2 c^3 - 6 b\) can be described as
// * ``` // * ```
// * Int.algebra { // * Int.algebra {
// * val LabeledPolynomial : LabeledPolynomial<Int> = LabeledPolynomial { // * val labeledPolynomial : LabeledPolynomial<Int> = LabeledPolynomialDSL1 {
// * 5 { 1 inPowerOf 2u; 3 inPowerOf 3u } // 5 x_1^2 x_3^3 + // * 5 { a inPowerOf 2u; c inPowerOf 3u } // 5 a^2 c^3 +
// * (-6) { 2 inPowerOf 1u } // (-6) x_2^1 // * (-6) { b inPowerOf 1u } // (-6) b^1
// * } // * }
// * } // * }
// * ``` // * ```
@ -402,39 +402,39 @@ public class DSL1LabeledPolynomialBuilder<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.LabeledPolynomialDSL1(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? = null, 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.
* *
* For example, polynomial \(5 x_1^2 x_3^3 - 6 x_2\) can be described as * For example, polynomial \(5 a^2 c^3 - 6 b\) can be described as
* ``` * ```
* Int.algebra { * Int.algebra {
* val LabeledPolynomial : LabeledPolynomial<Int> = LabeledPolynomial { * val labeledPolynomial : LabeledPolynomial<Int> = LabeledPolynomialDSL1 {
* 5 { 1 inPowerOf 2u; 3 inPowerOf 3u } // 5 x_1^2 x_3^3 + * 5 { a inPowerOf 2u; c inPowerOf 3u } // 5 a^2 c^3 +
* (-6) { 2 inPowerOf 1u } // (-6) x_2^1 * (-6) { b inPowerOf 1u } // (-6) b^1
* } * }
* } * }
* ``` * ```
* @usesMathJax * @usesMathJax
*/ */
@UnstableKMathAPI @UnstableKMathAPI
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() public inline fun <C, A: Ring<C>> LabeledPolynomialSpace<C, A>.LabeledPolynomialDSL1(initialCapacity: Int? = null, 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.
* *
* For example, polynomial \(5 x_1^2 x_3^3 - 6 x_2\) can be described as * For example, polynomial \(5 a^2 c^3 - 6 b\) can be described as
* `` * ```
* Int.algebra { * Int.algebra {
* val LabeledPolynomial : LabeledPolynomial<Int> = LabeledPolynomial { * val labeledPolynomial : LabeledPolynomial<Int> = LabeledPolynomialDSL1 {
* 5 { 1 inPowerOf 2u; 3 inPowerOf 3u } // 5 x_1^2 x_3^3 + * 5 { a inPowerOf 2u; c inPowerOf 3u } // 5 a^2 c^3 +
* (-6) { 2 inPowerOf 1u } // (-6) x_2^1 * (-6) { b inPowerOf 1u } // (-6) b^1
* } * }
* } * }
* ``` * ```
* @usesMathJax * @usesMathJax
*/ */
@UnstableKMathAPI @UnstableKMathAPI
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() public inline fun <C, A: Ring<C>> LabeledRationalFunctionSpace<C, A>.LabeledPolynomialDSL1(initialCapacity: Int? = null, 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

@ -243,12 +243,12 @@ public inline fun <C> C.asNumberedPolynomial() : NumberedPolynomial<C> = Numbere
/** /**
* Marks DSL that allows to more simply create [NumberedPolynomial]s with good performance. * Marks DSL that allows to more simply create [NumberedPolynomial]s with good performance.
* *
* For example, polynomial \(5 x_1^2 x_3^3 - 6 x_2\) can be described as * For example, polynomial \(5 x_0^2 x_2^3 - 6 x_1\) can be described as
* ``` * ```
* Int.algebra { * Int.algebra {
* val numberedPolynomial : NumberedPolynomial<Int> = NumberedPolynomial { * val numberedPolynomial : NumberedPolynomial<Int> = NumberedPolynomial {
* 5 { 1 inPowerOf 2u; 3 inPowerOf 3u } // 5 x_1^2 x_3^3 + * 5 { 0 inPowerOf 2u; 2 inPowerOf 3u } // 5 x_0^2 x_2^3 +
* (-6) { 2 inPowerOf 1u } // (-6) x_2^1 * (-6) { 1 inPowerOf 1u } // (-6) x_1^1
* } * }
* } * }
* ``` * ```
@ -285,7 +285,7 @@ public class DSL1NumberedPolynomialTermSignatureBuilder {
*/ */
public infix fun Int.inPowerOf(deg: UInt) { public infix fun Int.inPowerOf(deg: UInt) {
if (deg == 0u) return if (deg == 0u) return
val index = this - 1 val index = this
if (index > signature.lastIndex) { if (index > signature.lastIndex) {
signature.addAll(List(index - signature.lastIndex - 1) { 0u }) signature.addAll(List(index - signature.lastIndex - 1) { 0u })
signature.add(deg) signature.add(deg)
@ -326,13 +326,13 @@ public class DSL1NumberedPolynomialBuilder<C>(
/** /**
* Initial capacity of coefficients map. * Initial capacity of coefficients map.
*/ */
initialCapacity: Int = 0 initialCapacity: Int? = null
) { ) {
/** /**
* Coefficients storage. Any declaration of any monomial updates the storage. * Coefficients storage. Any declaration of any monomial updates the storage.
* Afterward the storage will be used as a resulting coefficients map. * Afterward the storage will be used as a resulting coefficients map.
*/ */
private val coefficients: MutableMap<List<UInt>, C> = LinkedHashMap(initialCapacity) private val coefficients: MutableMap<List<UInt>, C> = if (initialCapacity != null) LinkedHashMap(initialCapacity) else LinkedHashMap()
/** /**
* Builds the resulting coefficients map. * Builds the resulting coefficients map.
@ -373,12 +373,12 @@ public class DSL1NumberedPolynomialBuilder<C>(
///** ///**
// * Creates [NumberedPolynomial] with lambda [block] in context of [this] ring of constants. // * Creates [NumberedPolynomial] with lambda [block] in context of [this] ring of constants.
// * // *
// * For example, polynomial \(5 x_1^2 x_3^3 - 6 x_2\) can be described as // * For example, polynomial \(5 x_0^2 x_2^3 - 6 x_1\) can be described as
// * ``` // * ```
// * Int.algebra { // * Int.algebra {
// * val numberedPolynomial : NumberedPolynomial<Int> = NumberedPolynomial { // * val numberedPolynomial : NumberedPolynomial<Int> = NumberedPolynomial {
// * 5 { 1 inPowerOf 2u; 3 inPowerOf 3u } // 5 x_1^2 x_3^3 + // * 5 { 0 inPowerOf 2u; 2 inPowerOf 3u } // 5 x_0^2 x_2^3 +
// * (-6) { 2 inPowerOf 1u } // (-6) x_2^1 // * (-6) { 1 inPowerOf 1u } // (-6) x_1^1
// * } // * }
// * } // * }
// * ``` // * ```
@ -389,39 +389,39 @@ public class DSL1NumberedPolynomialBuilder<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.NumberedPolynomialDSL1(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? = null, 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.
* *
* For example, polynomial \(5 x_1^2 x_3^3 - 6 x_2\) can be described as * For example, polynomial \(5 x_0^2 x_2^3 - 6 x_1\) can be described as
* ``` * ```
* Int.algebra { * Int.algebra {
* val numberedPolynomial : NumberedPolynomial<Int> = NumberedPolynomial { * val numberedPolynomial : NumberedPolynomial<Int> = NumberedPolynomial {
* 5 { 1 inPowerOf 2u; 3 inPowerOf 3u } // 5 x_1^2 x_3^3 + * 5 { 0 inPowerOf 2u; 2 inPowerOf 3u } // 5 x_0^2 x_2^3 +
* (-6) { 2 inPowerOf 1u } // (-6) x_2^1 * (-6) { 1 inPowerOf 1u } // (-6) x_1^1
* } * }
* } * }
* ``` * ```
* @usesMathJax * @usesMathJax
*/ */
@UnstableKMathAPI @UnstableKMathAPI
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() public inline fun <C, A: Ring<C>> NumberedPolynomialSpace<C, A>.NumberedPolynomialDSL1(initialCapacity: Int? = null, 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.
* *
* For example, polynomial \(5 x_1^2 x_3^3 - 6 x_2\) can be described as * For example, polynomial \(5 x_0^2 x_2^3 - 6 x_1\) can be described as
* ``` * ```
* Int.algebra { * Int.algebra {
* val numberedPolynomial : NumberedPolynomial<Int> = NumberedPolynomial { * val numberedPolynomial : NumberedPolynomial<Int> = NumberedPolynomial {
* 5 { 1 inPowerOf 2u; 3 inPowerOf 3u } // 5 x_1^2 x_3^3 + * 5 { 0 inPowerOf 2u; 2 inPowerOf 3u } // 5 x_0^2 x_2^3 +
* (-6) { 2 inPowerOf 1u } // (-6) x_2^1 * (-6) { 1 inPowerOf 1u } // (-6) x_1^1
* } * }
* } * }
* ``` * ```
* @usesMathJax * @usesMathJax
*/ */
@UnstableKMathAPI @UnstableKMathAPI
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() public inline fun <C, A: Ring<C>> NumberedRationalFunctionSpace<C, A>.NumberedPolynomialDSL1(initialCapacity: Int? = null, 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