From 1f9d8d34f5f0476b4ea553bdd2c99a7406d30f61 Mon Sep 17 00:00:00 2001 From: Gleb Minaev <43728100+lounres@users.noreply.github.com> Date: Tue, 15 Mar 2022 20:18:39 +0300 Subject: [PATCH] Tried to add constructors and/or fabrics for polynomials --- .../kmath/functions/LabeledPolynomial.kt | 247 ++---------------- .../kmath/functions/NumberedPolynomial.kt | 223 +++++----------- .../kscience/kmath/functions/Polynomial.kt | 27 +- 3 files changed, 122 insertions(+), 375 deletions(-) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/LabeledPolynomial.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/LabeledPolynomial.kt index ebdaa6e26..56dad975d 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/LabeledPolynomial.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/LabeledPolynomial.kt @@ -73,254 +73,59 @@ internal fun Map.cleanUp() = filterValues { it > 0U } // region Constructors and converters -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from keys of received -// * map, sums up proportional monomials, removes aero monomials, and if result is zero map adds only element in it. -// * -// * @param pairs Collection of pairs that represent monomials. -// * @param toCheckInput If it's `true` cleaning of [coefficients] is executed otherwise it is not. -// * -// * @throws LabeledPolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(A) -//internal fun > LabeledPolynomial(coefs: Map, C>, toCheckInput: Boolean = true): LabeledPolynomial { -// if (!toCheckInput) return LabeledPolynomial(coefs) +//context(LabeledPolynomialSpace>) +//@Suppress("FunctionName") +//internal fun LabeledPolynomial(coefs: Map, C>, toCheckInput: Boolean = false) : LabeledPolynomial { +// if (!toCheckInput) return LabeledPolynomial(coefs) // -// // Map for cleaned coefficients. // val fixedCoefs = mutableMapOf, C>() // -// // Cleaning the degrees, summing monomials of the same degrees. // for (entry in coefs) { // val key = entry.key.cleanUp() // val value = entry.value // fixedCoefs[key] = if (key in fixedCoefs) fixedCoefs[key]!! + value else value // } // -// // Removing zero monomials. -// return LabeledPolynomial( -// fixedCoefs -// .filter { it.value.isNotZero() } +// return LabeledPolynomial( +// fixedCoefs.filterValues { it.isNotZero() } // ) //} -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from keys of received -// * map, sums up proportional monomials, removes aero monomials, and if result is zero map adds only element in it. -// * -// * @param pairs Collection of pairs that represent monomials. -// * @param toCheckInput If it's `true` cleaning of [coefficients] is executed otherwise it is not. -// * -// * @throws LabeledPolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(A) -//internal fun > LabeledPolynomial(pairs: Collection, C>>, toCheckInput: Boolean): LabeledPolynomial { -// if (!toCheckInput) return LabeledPolynomial(pairs.toMap()) // -// // Map for cleaned coefficients. +//context(LabeledPolynomialSpace>) +//@Suppress("FunctionName") +//internal fun LabeledPolynomial(pairs: Collection, C>>, toCheckInput: Boolean = false) : LabeledPolynomial { +// if (!toCheckInput) return LabeledPolynomial(pairs.toMap()) +// // val fixedCoefs = mutableMapOf, C>() // -// // Cleaning the degrees, summing monomials of the same degrees. // for (entry in pairs) { // val key = entry.first.cleanUp() // val value = entry.second // fixedCoefs[key] = if (key in fixedCoefs) fixedCoefs[key]!! + value else value // } // -// // Removing zero monomials. -// return LabeledPolynomial( +// return LabeledPolynomial( // fixedCoefs.filterValues { it.isNotZero() } // ) //} -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from keys of received -// * map, sums up proportional monomials, removes aero monomials, and if result is zero map adds only element in it. -// * -// * @param pairs Collection of pairs that represents monomials. -// * @param toCheckInput If it's `true` cleaning of [coefficients] is executed otherwise it is not. -// * -// * @throws LabeledPolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(A) -//internal fun > LabeledPolynomial(vararg pairs: Pair, C>, toCheckInput: Boolean): LabeledPolynomial { -// if (!toCheckInput) return LabeledPolynomial(pairs.toMap()) // -// // Map for cleaned coefficients. -// val fixedCoefs = mutableMapOf, C>() +//// TODO: Do not know how to make it without context receivers +//context(LabeledPolynomialSpace>) +//@Suppress("FunctionName") +//public fun LabeledPolynomial(coefs: Map, C>) : LabeledPolynomial = LabeledPolynomial(coefs, toCheckInput = true) // -// // Cleaning the degrees, summing monomials of the same degrees. -// for (entry in pairs) { -// val key = entry.first.cleanUp() -// val value = entry.second -// fixedCoefs[key] = if (key in fixedCoefs) fixedCoefs[key]!! + value else value -// } +//context(LabeledPolynomialSpace>) +//@Suppress("FunctionName") +//public fun LabeledPolynomial(pairs: Collection, C>>) : LabeledPolynomial = LabeledPolynomial(pairs, toCheckInput = true) // -// // Removing zero monomials. -// return LabeledPolynomial( -// fixedCoefs.filterValues { it.isNotZero() } -// ) -//} -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from keys of received -// * map, sums up proportional monomials, removes aero monomials, and if result is zero map adds only element in it. -// * -// * @param coefs Coefficients of the instants. -// * -// * @throws LabeledPolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(A) -//fun > LabeledPolynomial(coefs: Map, C>): LabeledPolynomial = LabeledPolynomial(coefs, toCheckInput = true) -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from keys of received -// * map, sums up proportional monomials, removes aero monomials, and if result is zero map adds only element in it. -// * -// * @param pairs Collection of pairs that represents monomials. -// * -// * @throws LabeledPolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(A) -//fun > LabeledPolynomial(pairs: Collection, C>>): LabeledPolynomial = LabeledPolynomial(pairs, toCheckInput = true) -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from keys of received -// * map, sums up proportional monomials, removes aero monomials, and if result is zero map adds only element in it. -// * -// * @param pairs Collection of pairs that represents monomials. -// * -// * @throws LabeledPolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(A) -//fun > LabeledPolynomial(vararg pairs: Pair, C>): LabeledPolynomial = LabeledPolynomial(*pairs, toCheckInput = true) -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from keys of received -// * map, sums up proportional monomials, removes aero monomials, and if result is zero map adds only element in it. -// * -// * @param pairs Collection of pairs that represent monomials. -// * @param toCheckInput If it's `true` cleaning of [coefficients] is executed otherwise it is not. -// * -// * @throws LabeledPolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(LabeledPolynomialSpace) -//internal fun > LabeledPolynomial(coefs: Map, C>, toCheckInput: Boolean = true): LabeledPolynomial { -// if (!toCheckInput) return LabeledPolynomial(coefs) +//context(LabeledPolynomialSpace>) +//@Suppress("FunctionName") +//public fun LabeledPolynomial(vararg pairs: Pair, C>) : LabeledPolynomial = LabeledPolynomial(pairs.toList(), toCheckInput = true) // -// // Map for cleaned coefficients. -// val fixedCoefs = mutableMapOf, C>() -// -// // Cleaning the degrees, summing monomials of the same degrees. -// for (entry in coefs) { -// val key = entry.key.cleanUp() -// val value = entry.value -// fixedCoefs[key] = if (key in fixedCoefs) fixedCoefs[key]!! + value else value -// } -// -// // Removing zero monomials. -// return LabeledPolynomial( -// fixedCoefs -// .filter { it.value.isNotZero() } -// ) -//} -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from keys of received -// * map, sums up proportional monomials, removes aero monomials, and if result is zero map adds only element in it. -// * -// * @param pairs Collection of pairs that represent monomials. -// * @param toCheckInput If it's `true` cleaning of [coefficients] is executed otherwise it is not. -// * -// * @throws LabeledPolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(LabeledPolynomialSpace) -//internal fun > LabeledPolynomial(pairs: Collection, C>>, toCheckInput: Boolean): LabeledPolynomial { -// if (!toCheckInput) return LabeledPolynomial(pairs.toMap()) -// -// // Map for cleaned coefficients. -// val fixedCoefs = mutableMapOf, C>() -// -// // Cleaning the degrees, summing monomials of the same degrees. -// for (entry in pairs) { -// val key = entry.first.cleanUp() -// val value = entry.second -// fixedCoefs[key] = if (key in fixedCoefs) fixedCoefs[key]!! + value else value -// } -// -// // Removing zero monomials. -// return LabeledPolynomial( -// fixedCoefs.filterValues { it.isNotZero() } -// ) -//} -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from keys of received -// * map, sums up proportional monomials, removes aero monomials, and if result is zero map adds only element in it. -// * -// * @param pairs Collection of pairs that represents monomials. -// * @param toCheckInput If it's `true` cleaning of [coefficients] is executed otherwise it is not. -// * -// * @throws LabeledPolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(LabeledPolynomialSpace) -//internal fun > LabeledPolynomial(vararg pairs: Pair, C>, toCheckInput: Boolean): LabeledPolynomial { -// if (!toCheckInput) return LabeledPolynomial(pairs.toMap()) -// -// // Map for cleaned coefficients. -// val fixedCoefs = mutableMapOf, C>() -// -// // Cleaning the degrees, summing monomials of the same degrees. -// for (entry in pairs) { -// val key = entry.first.cleanUp() -// val value = entry.second -// fixedCoefs[key] = if (key in fixedCoefs) fixedCoefs[key]!! + value else value -// } -// -// // Removing zero monomials. -// return LabeledPolynomial( -// fixedCoefs.filterValues { it.isNotZero() } -// ) -//} -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from keys of received -// * map, sums up proportional monomials, removes aero monomials, and if result is zero map adds only element in it. -// * -// * @param coefs Coefficients of the instants. -// * -// * @throws LabeledPolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(LabeledPolynomialSpace) -//fun > LabeledPolynomial(coefs: Map, C>): LabeledPolynomial = LabeledPolynomial(coefs, toCheckInput = true) -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from keys of received -// * map, sums up proportional monomials, removes aero monomials, and if result is zero map adds only element in it. -// * -// * @param pairs Collection of pairs that represents monomials. -// * -// * @throws LabeledPolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(LabeledPolynomialSpace) -//fun > LabeledPolynomial(pairs: Collection, C>>): LabeledPolynomial = LabeledPolynomial(pairs, toCheckInput = true) -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from keys of received -// * map, sums up proportional monomials, removes aero monomials, and if result is zero map adds only element in it. -// * -// * @param pairs Collection of pairs that represents monomials. -// * -// * @throws LabeledPolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(LabeledPolynomialSpace) -//fun > LabeledPolynomial(vararg pairs: Pair, C>): LabeledPolynomial = LabeledPolynomial(*pairs, toCheckInput = true) -// -//fun C.asLabeledPolynomial() : LabeledPolynomial = LabeledPolynomial(mapOf(emptyMap() to this)) -// -//context(A) -//fun > Variable.asLabeledPolynomial() : LabeledPolynomial = LabeledPolynomial(mapOf(mapOf(this to 1U) to one)) -// -//context(LabeledPolynomialSpace) -//fun > Variable.asLabeledPolynomial() : LabeledPolynomial = LabeledPolynomial(mapOf(mapOf(this to 1U) to constantOne)) -// -//context(A) -//fun > Variable.asLabeledPolynomial(c: C) : LabeledPolynomial = -// if(c.isZero()) LabeledPolynomial(emptyMap()) -// else LabeledPolynomial(mapOf(mapOf(this to 1U) to c)) -// -//context(LabeledPolynomialSpace) -//fun > Variable.asLabeledPolynomial(c: C) : LabeledPolynomial = -// if(c.isZero()) zero -// else LabeledPolynomial(mapOf(mapOf(this to 1U) to c)) +//context(LabeledPolynomialSpace>) +//public fun Variable.asLabeledPolynomial() : LabeledPolynomial = LabeledPolynomial(mapOf(mapOf(this to 1u) to constantOne)) + +public fun C.asLabeledPolynomial() : LabeledPolynomial = LabeledPolynomial(mapOf(emptyMap() to this)) // endregion diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/NumberedPolynomial.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/NumberedPolynomial.kt index 86c76949b..a1033fcc4 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/NumberedPolynomial.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/NumberedPolynomial.kt @@ -72,100 +72,10 @@ internal fun List.cleanUp() = subList(0, indexOfLast { it != 0U } + 1) // endregion // region Constructors and converters -// Waiting for context receivers :( TODO: Replace with context receivers when they will be available -//context(A) +//context(NumberedPolynomialSpace>) //@Suppress("FunctionName") -//internal fun > NumberedPolynomial(coefs: Map, C>, toCheckInput: Boolean): NumberedPolynomial { -// if (!toCheckInput) return NumberedPolynomial(coefs) -// -// val fixedCoefs = mutableMapOf, C>() -// -// for (entry in coefs) { -// val key = entry.key.cleanUp() -// val value = entry.value -// fixedCoefs[key] = if (key in fixedCoefs) fixedCoefs[key]!! + value else value -// } -// -// return NumberedPolynomial( -// fixedCoefs -// .filter { it.value.isNotZero() } -// ) -//} -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from end of received -// * lists, sums up proportional monomials, removes zero monomials, and if result is empty map adds only element in it. -// * -// * @param pairs Collection of pairs that represent monomials. -// * @param toCheckInput If it's `true` cleaning of [coefficients] is executed otherwise it is not. -// * -// * @throws PolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(A) -//@Suppress("FunctionName") -//internal fun > NumberedPolynomial(pairs: Collection, C>>, toCheckInput: Boolean): NumberedPolynomial { -// if (!toCheckInput) return NumberedPolynomial(pairs.toMap()) -// -// val fixedCoefs = mutableMapOf, C>() -// -// for (entry in pairs) { -// val key = entry.first.cleanUp() -// val value = entry.second -// fixedCoefs[key] = if (key in fixedCoefs) fixedCoefs[key]!! + value else value -// } -// -// return NumberedPolynomial( -// fixedCoefs -// .filter { it.value.isNotZero() } -// ) -//} -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from end of received -// * lists, sums up proportional monomials, removes zero monomials, and if result is empty map adds only element in it. -// * -// * @param pairs Collection of pairs that represent monomials. -// * @param toCheckInput If it's `true` cleaning of [coefficients] is executed otherwise it is not. -// * -// * @throws PolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(A) -//@Suppress("FunctionName") -//internal fun > NumberedPolynomial(vararg pairs: Pair, C>, toCheckInput: Boolean): NumberedPolynomial = -// NumberedPolynomial(pairs.toMap(), toCheckInput) -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from end of received -// * lists, sums up proportional monomials, removes zero monomials, and if result is empty map adds only element in it. -// * -// * @param coefs Coefficients of the instants. -// * -// * @throws PolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(A) -//public fun > NumberedPolynomial(coefs: Map, C>) = NumberedPolynomial(coefs, toCheckInput = true) -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from end of received -// * lists, sums up proportional monomials, removes zero monomials, and if result is empty map adds only element in it. -// * -// * @param pairs Collection of pairs that represent monomials. -// * -// * @throws PolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(A) -//public fun > NumberedPolynomial(pairs: Collection, C>>) = NumberedPolynomial(pairs, toCheckInput = true) -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from end of received -// * lists, sums up proportional monomials, removes zero monomials, and if result is empty map adds only element in it. -// * -// * @param pairs Collection of pairs that represent monomials. -// * -// * @throws PolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(A) -//public fun > NumberedPolynomial(vararg pairs: Pair, C>) = NumberedPolynomial(*pairs, toCheckInput = true) -// -//context(NumberedPolynomialSpace) -//@Suppress("FunctionName") -//internal fun > NumberedPolynomial(coefs: Map, C>, toCheckInput: Boolean): NumberedPolynomial { +//internal fun NumberedPolynomial(coefs: Map, C>, toCheckInput: Boolean = false) : NumberedPolynomial { // if (!toCheckInput) return NumberedPolynomial(coefs) // // val fixedCoefs = mutableMapOf, C>() @@ -176,23 +86,14 @@ internal fun List.cleanUp() = subList(0, indexOfLast { it != 0U } + 1) // fixedCoefs[key] = if (key in fixedCoefs) fixedCoefs[key]!! + value else value // } // -// return NumberedPolynomial( -// fixedCoefs -// .filter { it.value.isNotZero() } +// return NumberedPolynomial( +// fixedCoefs.filterValues { it.isNotZero() } // ) //} -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from end of received -// * lists, sums up proportional monomials, removes zero monomials, and if result is empty map adds only element in it. -// * -// * @param pairs Collection of pairs that represent monomials. -// * @param toCheckInput If it's `true` cleaning of [coefficients] is executed otherwise it is not. -// * -// * @throws PolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(NumberedPolynomialSpace) +// +//context(NumberedPolynomialSpace>) //@Suppress("FunctionName") -//internal fun > NumberedPolynomial(pairs: Collection, C>>, toCheckInput: Boolean): NumberedPolynomial { +//internal fun NumberedPolynomial(pairs: Collection, C>>, toCheckInput: Boolean = false) : NumberedPolynomial { // if (!toCheckInput) return NumberedPolynomial(pairs.toMap()) // // val fixedCoefs = mutableMapOf, C>() @@ -203,56 +104,25 @@ internal fun List.cleanUp() = subList(0, indexOfLast { it != 0U } + 1) // fixedCoefs[key] = if (key in fixedCoefs) fixedCoefs[key]!! + value else value // } // -// return NumberedPolynomial( -// fixedCoefs -// .filter { it.value.isNotZero() } +// return NumberedPolynomial( +// fixedCoefs.filterValues { it.isNotZero() } // ) //} -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from end of received -// * lists, sums up proportional monomials, removes zero monomials, and if result is empty map adds only element in it. -// * -// * @param pairs Collection of pairs that represent monomials. -// * @param toCheckInput If it's `true` cleaning of [coefficients] is executed otherwise it is not. -// * -// * @throws PolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(NumberedPolynomialSpace) +// +//// TODO: Do not know how to make it without context receivers +//context(NumberedPolynomialSpace>) //@Suppress("FunctionName") -//internal fun > NumberedPolynomial(vararg pairs: Pair, C>, toCheckInput: Boolean): NumberedPolynomial = -// NumberedPolynomial(pairs.toList(), toCheckInput) -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from end of received -// * lists, sums up proportional monomials, removes zero monomials, and if result is empty map adds only element in it. -// * -// * @param coefs Coefficients of the instants. -// * -// * @throws PolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(NumberedPolynomialSpace) -//public fun > NumberedPolynomial(coefs: Map, C>) = NumberedPolynomial(coefs, toCheckInput = true) -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from end of received -// * lists, sums up proportional monomials, removes zero monomials, and if result is empty map adds only element in it. -// * -// * @param pairs Collection of pairs that represent monomials. -// * -// * @throws PolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(NumberedPolynomialSpace) -//public fun > NumberedPolynomial(pairs: Collection, C>>) = NumberedPolynomial(pairs, toCheckInput = true) -///** -// * Gets the coefficients in format of [coefficients] field and cleans it: removes zero degrees from end of received -// * lists, sums up proportional monomials, removes zero monomials, and if result is empty map adds only element in it. -// * -// * @param pairs Collection of pairs that represent monomials. -// * -// * @throws PolynomialError If no coefficient received or if any of degrees in any monomial is negative. -// */ -//context(NumberedPolynomialSpace) -//public fun > NumberedPolynomial(vararg pairs: Pair, C>) = NumberedPolynomial(*pairs, toCheckInput = true) +//public fun NumberedPolynomial(coefs: Map, C>) : NumberedPolynomial = NumberedPolynomial(coefs, toCheckInput = true) +// +//context(NumberedPolynomialSpace>) +//@Suppress("FunctionName") +//public fun NumberedPolynomial(pairs: Collection, C>>) : NumberedPolynomial = NumberedPolynomial(pairs, toCheckInput = true) +// +//context(NumberedPolynomialSpace>) +//@Suppress("FunctionName") +//public fun NumberedPolynomial(vararg pairs: Pair, C>) : NumberedPolynomial = NumberedPolynomial(pairs.toList(), toCheckInput = true) -public fun > C.asNumberedPolynomial() : NumberedPolynomial = NumberedPolynomial(mapOf(emptyList() to this)) +public fun C.asNumberedPolynomial() : NumberedPolynomial = NumberedPolynomial(mapOf(emptyList() to this)) // endregion @@ -314,7 +184,7 @@ public open class NumberedPolynomialSpace>( */ public override operator fun NumberedPolynomial.times(other: Int): NumberedPolynomial = if (other == 0) zero - else NumberedPolynomial( + else NumberedPolynomial( coefficients .applyAndRemoveZeros { mapValues { (_, c) -> c * other } @@ -707,4 +577,51 @@ public open class NumberedPolynomialSpace>( } } // endregion + + // region Constructors and converters + + @Suppress("FunctionName") + internal fun NumberedPolynomial(coefs: Map, C>, toCheckInput: Boolean = false) : NumberedPolynomial { + if (!toCheckInput) return NumberedPolynomial(coefs) + + val fixedCoefs = mutableMapOf, C>() + + for (entry in coefs) { + val key = entry.key.cleanUp() + val value = entry.value + fixedCoefs[key] = if (key in fixedCoefs) fixedCoefs[key]!! + value else value + } + + return NumberedPolynomial( + fixedCoefs.filterValues { it.isNotZero() } + ) + } + + @Suppress("FunctionName") + internal fun NumberedPolynomial(pairs: Collection, C>>, toCheckInput: Boolean = false) : NumberedPolynomial { + if (!toCheckInput) return NumberedPolynomial(pairs.toMap()) + + val fixedCoefs = mutableMapOf, C>() + + for (entry in pairs) { + val key = entry.first.cleanUp() + val value = entry.second + fixedCoefs[key] = if (key in fixedCoefs) fixedCoefs[key]!! + value else value + } + + return NumberedPolynomial( + fixedCoefs.filterValues { it.isNotZero() } + ) + } + + @Suppress("FunctionName") + public fun NumberedPolynomial(coefs: Map, C>) : NumberedPolynomial = NumberedPolynomial(coefs, toCheckInput = true) + + @Suppress("FunctionName") + public fun NumberedPolynomial(pairs: Collection, C>>) : NumberedPolynomial = NumberedPolynomial(pairs, toCheckInput = true) + + @Suppress("FunctionName") + public fun NumberedPolynomial(vararg pairs: Pair, C>) : NumberedPolynomial = NumberedPolynomial(pairs.toList(), toCheckInput = true) + + // endregion } \ No newline at end of file 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 1ac413818..2f7976da6 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 @@ -14,7 +14,32 @@ import kotlin.math.min * * @param coefficients constant is the leftmost coefficient. */ -public data class Polynomial(public val coefficients: List) : AbstractPolynomial { +public data class Polynomial( + /** + * List that collects coefficients of the polynomial. Every monomial `a x^d` is represented as a coefficients + * `a` placed into the list with index `d`. For example coefficients of polynomial `5 x^2 - 6` can be represented as + * ``` + * listOf( + * -6, // -6 + + * 0, // 0 x + + * 5, // 5 x^2 + * ) + * ``` + * and also as + * ``` + * listOf( + * -6, // -6 + + * 0, // 0 x + + * 5, // 5 x^2 + * 0, // 0 x^3 + * 0, // 0 x^4 + * ) + * ``` + * It is recommended not to put extra zeros at end of the list (as for `0x^3` and `0x^4` in the example), but is not + * prohibited. + */ + public val coefficients: List +) : AbstractPolynomial { override fun toString(): String = "Polynomial$coefficients" }