diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/AbstractPolynomial.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/AbstractPolynomial.kt index b053ffebd..8bd8697e3 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/AbstractPolynomial.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/AbstractPolynomial.kt @@ -18,7 +18,7 @@ public interface AbstractPolynomial /** * Abstraction of ring of polynomials of type [P] over ring of constants of type [C]. * - * @param C the type of constants. Polynomials have them as a coefficients in their terms. + * @param C the type of constants. Polynomials have them as coefficients in their terms. * @param P the type of polynomials. */ @Suppress("INAPPLICABLE_JVM_NAME", "PARAMETER_NAME_CHANGED_ON_OVERRIDE") @@ -313,10 +313,12 @@ public interface AbstractPolynomialSpace> : Ring

} /** - * Abstraction of ring of polynomials of type [P] over ring of constants of type [C]. + * Abstraction of ring of polynomials of type [P] over ring of constants of type [C]. It also assumes that there is + * provided [ring] (of type [A]), that provides constant-wise operations. * - * @param C the type of constants. Polynomials have them as a coefficients in their terms. + * @param C the type of constants. Polynomials have them as coefficients in their terms. * @param P the type of polynomials. + * @param A the type of algebraic structure (precisely, of ring) provided for constants. */ @Suppress("INAPPLICABLE_JVM_NAME") public interface AbstractPolynomialSpaceOverRing, A: Ring> : AbstractPolynomialSpace { diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/AbstractRationalFunction.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/AbstractRationalFunction.kt index f8d3bb99b..685cf4ca3 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/AbstractRationalFunction.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/AbstractRationalFunction.kt @@ -20,6 +20,14 @@ public interface AbstractRationalFunction> { public operator fun component2(): P = denominator } +/** + * Abstraction of field of rational functions of type [R] with respect to polynomials of type [P] and constants of type + * [C]. + * + * @param C the type of constants. Polynomials have them as coefficients in their terms. + * @param P the type of polynomials. Rational functions have them as numerators and denominators in them. + * @param R the type of rational functions. + */ // TODO: Add support of field @Suppress("INAPPLICABLE_JVM_NAME", "PARAMETER_NAME_CHANGED_ON_OVERRIDE") public interface AbstractRationalFunctionalSpace, R: AbstractRationalFunction> : Ring { // region Constant-integer relation @@ -508,6 +516,15 @@ public interface AbstractRationalFunctionalSpace, R: // endregion } +/** + * Abstraction of field of rational functions of type [R] with respect to polynomials of type [P] and constants of type + * [C]. It also assumes that there is provided [ring] (of type [A]), that provides constant-wise operations. + * + * @param C the type of constants. Polynomials have them as coefficients in their terms. + * @param P the type of polynomials. Rational functions have them as numerators and denominators in them. + * @param R the type of rational functions. + * @param A the type of algebraic structure (precisely, of ring) provided for constants. + */ // TODO: Add support of field @Suppress("INAPPLICABLE_JVM_NAME") public interface AbstractRationalFunctionalSpaceOverRing, R: AbstractRationalFunction, A: Ring> : AbstractRationalFunctionalSpace { @@ -593,10 +610,25 @@ public interface AbstractRationalFunctionalSpaceOverRing, R: AbstractRationalFunction, A: Ring> : AbstractRationalFunctionalSpace { +public interface AbstractRationalFunctionalSpaceOverPolynomialSpace< + C, + P: AbstractPolynomial, + R: AbstractRationalFunction, + AP: AbstractPolynomialSpace, + > : AbstractRationalFunctionalSpace { - public val polynomialRing: AbstractPolynomialSpace + public val polynomialRing: AP // region Constant-integer relation /** 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 81aabb4a4..ebdaa6e26 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 @@ -384,6 +384,11 @@ public class LabeledPolynomialSpace>( // endregion // region Polynomial-integer relation + /** + * Returns sum of the polynomial and the integer represented as polynomial. + * + * The operation is equivalent to adding [other] copies of unit polynomial to [this]. + */ public override operator fun LabeledPolynomial.plus(other: Int): LabeledPolynomial = if (other == 0) this else @@ -399,6 +404,11 @@ public class LabeledPolynomialSpace>( else this[degs] = result } ) + /** + * Returns difference between the polynomial and the integer represented as polynomial. + * + * The operation is equivalent to subtraction [other] copies of unit polynomial from [this]. + */ public override operator fun LabeledPolynomial.minus(other: Int): LabeledPolynomial = if (other == 0) this else @@ -414,6 +424,11 @@ public class LabeledPolynomialSpace>( else this[degs] = result } ) + /** + * Returns product of the polynomial and the integer represented as polynomial. + * + * The operation is equivalent to sum of [other] copies of [this]. + */ public override operator fun LabeledPolynomial.times(other: Int): LabeledPolynomial = if (other == 0) zero else LabeledPolynomial( @@ -425,6 +440,11 @@ public class LabeledPolynomialSpace>( // endregion // region Integer-polynomial relation + /** + * Returns sum of the integer represented as polynomial and the polynomial. + * + * The operation is equivalent to adding [this] copies of unit polynomial to [other]. + */ public override operator fun Int.plus(other: LabeledPolynomial): LabeledPolynomial = if (this == 0) other else @@ -440,6 +460,11 @@ public class LabeledPolynomialSpace>( else this[degs] = result } ) + /** + * Returns difference between the integer represented as polynomial and the polynomial. + * + * The operation is equivalent to subtraction [this] copies of unit polynomial from [other]. + */ public override operator fun Int.minus(other: LabeledPolynomial): LabeledPolynomial = if (this == 0) other else @@ -455,6 +480,11 @@ public class LabeledPolynomialSpace>( else this[degs] = result } ) + /** + * Returns product of the integer represented as polynomial and the polynomial. + * + * The operation is equivalent to sum of [this] copies of [other]. + */ public override operator fun Int.times(other: LabeledPolynomial): LabeledPolynomial = if (this == 0) zero else LabeledPolynomial( @@ -514,6 +544,9 @@ public class LabeledPolynomialSpace>( // endregion // region Constant-polynomial relation + /** + * Returns sum of the constant represented as polynomial and the polynomial. + */ override operator fun C.plus(other: LabeledPolynomial): LabeledPolynomial = if (this.isZero()) other else with(other.coefficients) { @@ -530,6 +563,9 @@ public class LabeledPolynomialSpace>( } ) } + /** + * Returns difference between the constant represented as polynomial and the polynomial. + */ override operator fun C.minus(other: LabeledPolynomial): LabeledPolynomial = if (this.isZero()) other else with(other.coefficients) { @@ -548,6 +584,9 @@ public class LabeledPolynomialSpace>( } ) } + /** + * Returns product of the constant represented as polynomial and the polynomial. + */ override operator fun C.times(other: LabeledPolynomial): LabeledPolynomial = if (this.isZero()) zero else LabeledPolynomial( @@ -560,7 +599,7 @@ public class LabeledPolynomialSpace>( // region Polynomial-constant relation /** - * Returns sum of the polynomials. [other] is interpreted as [UnivariatePolynomial]. + * Returns sum of the constant represented as polynomial and the polynomial. */ override operator fun LabeledPolynomial.plus(other: C): LabeledPolynomial = if (other.isZero()) this @@ -579,7 +618,7 @@ public class LabeledPolynomialSpace>( ) } /** - * Returns difference of the polynomials. [other] is interpreted as [UnivariatePolynomial]. + * Returns difference between the constant represented as polynomial and the polynomial. */ override operator fun LabeledPolynomial.minus(other: C): LabeledPolynomial = if (other.isZero()) this @@ -600,7 +639,7 @@ public class LabeledPolynomialSpace>( ) } /** - * Returns product of the polynomials. [other] is interpreted as [UnivariatePolynomial]. + * Returns product of the constant represented as polynomial and the polynomial. */ override operator fun LabeledPolynomial.times(other: C): LabeledPolynomial = if (other.isZero()) zero @@ -763,10 +802,18 @@ public class LabeledPolynomialSpace>( ) } + /** + * Instance of zero polynomial (zero of the polynomial ring). + */ override val zero: LabeledPolynomial = LabeledPolynomial(mapOf(emptyMap() to constantZero)) + /** + * Instance of unit polynomial (unit of the polynomial ring). + */ override val one: LabeledPolynomial = LabeledPolynomial(mapOf(emptyMap() to constantOne)) - // TODO: Docs + /** + * Checks equality of the polynomials. + */ override infix fun LabeledPolynomial.equalsTo(other: LabeledPolynomial): Boolean = when { this === other -> true @@ -832,7 +879,10 @@ public class LabeledPolynomialSpace>( } foundAbsoluteTermAndItIsNotZero } - + /** + * If polynomial is a constant polynomial represents and returns it as constant. + * Otherwise, (when the polynomial is not constant polynomial) returns `null`. + */ override fun LabeledPolynomial.asConstantOrNull(): C? = with(coefficients) { if(isConstant()) getOrElse(emptyMap()) { constantZero } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/LabeledRationalFunction.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/LabeledRationalFunction.kt index 2bec1f3a4..df4441127 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/LabeledRationalFunction.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/LabeledRationalFunction.kt @@ -85,7 +85,12 @@ internal fun labeledRationalFunctionError(message: Any): Nothing = throw Labeled public class LabeledRationalFunctionSpace>( public val ring: A, -) : AbstractRationalFunctionalSpaceOverPolynomialSpace, LabeledRationalFunction, A> { +) : AbstractRationalFunctionalSpaceOverPolynomialSpace< + C, + LabeledPolynomial, + LabeledRationalFunction, + LabeledPolynomialSpace, + > { override val polynomialRing : LabeledPolynomialSpace = LabeledPolynomialSpace(ring) 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 de5cc5658..86c76949b 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 @@ -267,6 +267,11 @@ public open class NumberedPolynomialSpace>( public final override val ring: A, ) : AbstractPolynomialSpaceOverRing, A> { // region Polynomial-integer relation + /** + * Returns sum of the polynomial and the integer represented as polynomial. + * + * The operation is equivalent to adding [other] copies of unit polynomial to [this]. + */ public override operator fun NumberedPolynomial.plus(other: Int): NumberedPolynomial = if (other == 0) this else @@ -282,6 +287,11 @@ public open class NumberedPolynomialSpace>( else this[degs] = result } ) + /** + * Returns difference between the polynomial and the integer represented as polynomial. + * + * The operation is equivalent to subtraction [other] copies of unit polynomial from [this]. + */ public override operator fun NumberedPolynomial.minus(other: Int): NumberedPolynomial = if (other == 0) this else @@ -297,6 +307,11 @@ public open class NumberedPolynomialSpace>( else this[degs] = result } ) + /** + * Returns product of the polynomial and the integer represented as polynomial. + * + * The operation is equivalent to sum of [other] copies of [this]. + */ public override operator fun NumberedPolynomial.times(other: Int): NumberedPolynomial = if (other == 0) zero else NumberedPolynomial( @@ -308,6 +323,11 @@ public open class NumberedPolynomialSpace>( // endregion // region Integer-polynomial relation + /** + * Returns sum of the integer represented as polynomial and the polynomial. + * + * The operation is equivalent to adding [this] copies of unit polynomial to [other]. + */ public override operator fun Int.plus(other: NumberedPolynomial): NumberedPolynomial = if (this == 0) other else @@ -323,6 +343,11 @@ public open class NumberedPolynomialSpace>( else this[degs] = result } ) + /** + * Returns difference between the integer represented as polynomial and the polynomial. + * + * The operation is equivalent to subtraction [this] copies of unit polynomial from [other]. + */ public override operator fun Int.minus(other: NumberedPolynomial): NumberedPolynomial = if (this == 0) other else @@ -338,6 +363,11 @@ public open class NumberedPolynomialSpace>( else this[degs] = result } ) + /** + * Returns product of the integer represented as polynomial and the polynomial. + * + * The operation is equivalent to sum of [this] copies of [other]. + */ public override operator fun Int.times(other: NumberedPolynomial): NumberedPolynomial = if (this == 0) zero else NumberedPolynomial( @@ -349,6 +379,9 @@ public open class NumberedPolynomialSpace>( // endregion // region Constant-polynomial relation + /** + * Returns sum of the constant represented as polynomial and the polynomial. + */ override operator fun C.plus(other: NumberedPolynomial): NumberedPolynomial = if (this.isZero()) other else with(other.coefficients) { @@ -365,6 +398,9 @@ public open class NumberedPolynomialSpace>( } ) } + /** + * Returns difference between the constant represented as polynomial and the polynomial. + */ override operator fun C.minus(other: NumberedPolynomial): NumberedPolynomial = if (this.isZero()) -other else with(other.coefficients) { @@ -383,6 +419,9 @@ public open class NumberedPolynomialSpace>( } ) } + /** + * Returns product of the constant represented as polynomial and the polynomial. + */ override operator fun C.times(other: NumberedPolynomial): NumberedPolynomial = if (this.isZero()) zero else NumberedPolynomial( @@ -395,7 +434,7 @@ public open class NumberedPolynomialSpace>( // region Polynomial-constant relation /** - * Returns sum of the polynomials. [other] is interpreted as [NumberedPolynomial]. + * Returns sum of the constant represented as polynomial and the polynomial. */ override operator fun NumberedPolynomial.plus(other: C): NumberedPolynomial = if (other.isZero()) this @@ -414,7 +453,7 @@ public open class NumberedPolynomialSpace>( ) } /** - * Returns difference of the polynomials. [other] is interpreted as [NumberedPolynomial]. + * Returns difference between the constant represented as polynomial and the polynomial. */ override operator fun NumberedPolynomial.minus(other: C): NumberedPolynomial = if (other.isZero()) this @@ -433,7 +472,7 @@ public open class NumberedPolynomialSpace>( ) } /** - * Returns product of the polynomials. [other] is interpreted as [NumberedPolynomial]. + * Returns product of the constant represented as polynomial and the polynomial. */ override operator fun NumberedPolynomial.times(other: C): NumberedPolynomial = if (other.isZero()) zero @@ -496,7 +535,13 @@ public open class NumberedPolynomialSpace>( ) } + /** + * Check if the instant is zero polynomial. + */ public override fun NumberedPolynomial.isZero(): Boolean = coefficients.values.all { it.isZero() } + /** + * Check if the instant is unit polynomial. + */ public override fun NumberedPolynomial.isOne(): Boolean = with(coefficients) { var foundAbsoluteTermAndItIsOne = false @@ -509,6 +554,9 @@ public open class NumberedPolynomialSpace>( } foundAbsoluteTermAndItIsOne } + /** + * Check if the instant is minus unit polynomial. + */ public override fun NumberedPolynomial.isMinusOne(): Boolean = with(coefficients) { var foundAbsoluteTermAndItIsMinusOne = false @@ -522,7 +570,13 @@ public open class NumberedPolynomialSpace>( foundAbsoluteTermAndItIsMinusOne } + /** + * Instance of zero polynomial (zero of the polynomial ring). + */ override val zero: NumberedPolynomial = NumberedPolynomial(emptyMap()) + /** + * Instance of unit polynomial (unit of the polynomial ring). + */ override val one: NumberedPolynomial = NumberedPolynomial( mapOf( @@ -530,7 +584,9 @@ public open class NumberedPolynomialSpace>( ) ) - // TODO: Docs + /** + * Checks equality of the polynomials. + */ override infix fun NumberedPolynomial.equalsTo(other: NumberedPolynomial): Boolean = when { this === other -> true @@ -591,7 +647,10 @@ public open class NumberedPolynomialSpace>( } foundAbsoluteTermAndItIsNotZero } - + /** + * If polynomial is a constant polynomial represents and returns it as constant. + * Otherwise, (when the polynomial is not constant polynomial) returns `null`. + */ override fun NumberedPolynomial.asConstantOrNull(): C? = with(coefficients) { if(isConstant()) getOrElse(emptyList()) { constantZero } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/NumberedRationalFunction.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/NumberedRationalFunction.kt index 2053cc7f9..a81795c81 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/NumberedRationalFunction.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/NumberedRationalFunction.kt @@ -82,7 +82,12 @@ internal fun numberedRationalFunctionError(message: Any): Nothing = throw Number public class NumberedRationalFunctionSpace> ( public val ring: A, -) : AbstractRationalFunctionalSpaceOverPolynomialSpace, NumberedRationalFunction, A> { +) : AbstractRationalFunctionalSpaceOverPolynomialSpace< + C, + NumberedPolynomial, + NumberedRationalFunction, + NumberedPolynomialSpace, + > { override val polynomialRing : NumberedPolynomialSpace = NumberedPolynomialSpace(ring) 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 802ff7ea2..bdc725e63 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 @@ -68,10 +68,15 @@ public fun T.asPolynomial() : Polynomial = Polynomial(listOf(this)) */ //@Suppress("INAPPLICABLE_JVM_NAME") // TODO: KT-31420 public open class PolynomialSpace>( - public final override val ring: A, + public override val ring: A, ) : AbstractPolynomialSpaceOverRing, A> { // region Polynomial-integer relation + /** + * Returns sum of the polynomial and the integer represented as polynomial. + * + * The operation is equivalent to adding [other] copies of unit polynomial to [this]. + */ public override operator fun Polynomial.plus(other: Int): Polynomial = if (other == 0) this else @@ -89,6 +94,11 @@ public open class PolynomialSpace>( } } ) + /** + * Returns difference between the polynomial and the integer represented as polynomial. + * + * The operation is equivalent to subtraction [other] copies of unit polynomial from [this]. + */ public override operator fun Polynomial.minus(other: Int): Polynomial = if (other == 0) this else @@ -106,6 +116,11 @@ public open class PolynomialSpace>( } } ) + /** + * Returns product of the polynomial and the integer represented as polynomial. + * + * The operation is equivalent to sum of [other] copies of [this]. + */ public override operator fun Polynomial.times(other: Int): Polynomial = if (other == 0) zero else Polynomial( @@ -116,6 +131,11 @@ public open class PolynomialSpace>( // endregion // region Integer-polynomial relation + /** + * Returns sum of the integer represented as polynomial and the polynomial. + * + * The operation is equivalent to adding [this] copies of unit polynomial to [other]. + */ public override operator fun Int.plus(other: Polynomial): Polynomial = if (this == 0) other else @@ -133,6 +153,11 @@ public open class PolynomialSpace>( } } ) + /** + * Returns difference between the integer represented as polynomial and the polynomial. + * + * The operation is equivalent to subtraction [this] copies of unit polynomial from [other]. + */ public override operator fun Int.minus(other: Polynomial): Polynomial = if (this == 0) other else @@ -152,6 +177,11 @@ public open class PolynomialSpace>( } } ) + /** + * Returns product of the integer represented as polynomial and the polynomial. + * + * The operation is equivalent to sum of [this] copies of [other]. + */ public override operator fun Int.times(other: Polynomial): Polynomial = if (this == 0) zero else Polynomial( @@ -162,6 +192,9 @@ public open class PolynomialSpace>( // endregion // region Constant-polynomial relation + /** + * Returns sum of the constant represented as polynomial and the polynomial. + */ public override operator fun C.plus(other: Polynomial): Polynomial = if (this.isZero()) other else with(other.coefficients) { @@ -180,9 +213,9 @@ public open class PolynomialSpace>( } ) } -// if (degree == -1) UnivariatePolynomial(other) else UnivariatePolynomial( -// listOf(coefficients[0] + other) + coefficients.subList(1, degree + 1) -// ) + /** + * Returns difference between the constant represented as polynomial and the polynomial. + */ public override operator fun C.minus(other: Polynomial): Polynomial = if (this.isZero()) other else with(other.coefficients) { @@ -203,9 +236,9 @@ public open class PolynomialSpace>( } ) } -// if (degree == -1) UnivariatePolynomial(other) else UnivariatePolynomial( -// listOf(coefficients[0] + other) + coefficients.subList(1, degree + 1) -// ) + /** + * Returns product of the constant represented as polynomial and the polynomial. + */ public override operator fun C.times(other: Polynomial): Polynomial = if (this.isZero()) other else Polynomial( @@ -216,6 +249,9 @@ public open class PolynomialSpace>( // endregion // region Polynomial-constant relation + /** + * Returns sum of the constant represented as polynomial and the polynomial. + */ public override operator fun Polynomial.plus(other: C): Polynomial = if (other.isZero()) this else with(coefficients) { @@ -234,9 +270,9 @@ public open class PolynomialSpace>( } ) } -// if (degree == -1) UnivariatePolynomial(other) else UnivariatePolynomial( -// listOf(coefficients[0] + other) + coefficients.subList(1, degree + 1) -// ) + /** + * Returns difference between the constant represented as polynomial and the polynomial. + */ public override operator fun Polynomial.minus(other: C): Polynomial = if (other.isZero()) this else with(coefficients) { @@ -255,9 +291,9 @@ public open class PolynomialSpace>( } ) } -// if (degree == -1) UnivariatePolynomial(-other) else UnivariatePolynomial( -// listOf(coefficients[0] - other) + coefficients.subList(1, degree + 1) -// ) + /** + * Returns product of the constant represented as polynomial and the polynomial. + */ public override operator fun Polynomial.times(other: C): Polynomial = if (other.isZero()) this else Polynomial( @@ -268,8 +304,14 @@ public open class PolynomialSpace>( // endregion // region Polynomial-polynomial relation + /** + * Returns negation of the polynomial. + */ public override operator fun Polynomial.unaryMinus(): Polynomial = Polynomial(coefficients.map { -it }) + /** + * Returns sum of the polynomials. + */ public override operator fun Polynomial.plus(other: Polynomial): Polynomial = Polynomial( (0..max(degree, other.degree)) @@ -282,6 +324,9 @@ public open class PolynomialSpace>( } .ifEmpty { listOf(constantZero) } ) + /** + * Returns difference of the polynomials. + */ public override operator fun Polynomial.minus(other: Polynomial): Polynomial = Polynomial( (0..max(degree, other.degree)) @@ -294,6 +339,9 @@ public open class PolynomialSpace>( } .ifEmpty { listOf(constantZero) } ) + /** + * Returns product of the polynomials. + */ public override operator fun Polynomial.times(other: Polynomial): Polynomial { val thisDegree = degree val otherDegree = other.degree @@ -313,15 +361,39 @@ public open class PolynomialSpace>( } } + /** + * Check if the instant is zero polynomial. + */ public override fun Polynomial.isZero(): Boolean = coefficients.all { it.isZero() } + /** + * Check if the instant is unit polynomial. + */ public override fun Polynomial.isOne(): Boolean = - with(coefficients) { isNotEmpty() && asSequence().withIndex().any { (index, c) -> if (index == 0) c.isOne() else c.isZero() } } // TODO: It's better to write new methods like `anyIndexed`. But what's better way to do it? + with(coefficients) { + isNotEmpty() && + asSequence().withIndex().any { (index, c) -> if (index == 0) c.isOne() else c.isZero() } // TODO: It's better to write new methods like `anyIndexed`. But what's better way to do it? + } + /** + * Check if the instant is minus unit polynomial. + */ public override fun Polynomial.isMinusOne(): Boolean = - with(coefficients) { isNotEmpty() && asSequence().withIndex().any { (index, c) -> if (index == 0) c.isMinusOne() else c.isZero() } } // TODO: It's better to write new methods like `anyIndexed`. But what's better way to do it? + with(coefficients) { + isNotEmpty() && + asSequence().withIndex().any { (index, c) -> if (index == 0) c.isMinusOne() else c.isZero() } // TODO: It's better to write new methods like `anyIndexed`. But what's better way to do it? + } + /** + * Instance of zero polynomial (zero of the polynomial ring). + */ override val zero: Polynomial = Polynomial(emptyList()) + /** + * Instance of unit constant (unit of the underlying ring). + */ override val one: Polynomial = Polynomial(listOf(constantZero)) + /** + * Checks equality of the polynomials. + */ public override infix fun Polynomial.equalsTo(other: Polynomial): Boolean = when { this === other -> true @@ -334,9 +406,16 @@ public open class PolynomialSpace>( // endregion // region Polynomial properties - + /** + * Degree of the polynomial, [see also](https://en.wikipedia.org/wiki/Degree_of_a_polynomial). If the polynomial is + * zero, degree is -1. + */ public override val Polynomial.degree: Int get() = coefficients.indexOfLast { it != constantZero } + /** + * If polynomial is a constant polynomial represents and returns it as constant. + * Otherwise, (when the polynomial is not constant polynomial) returns `null`. + */ public override fun Polynomial.asConstantOrNull(): C? = with(coefficients) { when { @@ -345,7 +424,6 @@ public open class PolynomialSpace>( else -> first() } } - public override fun Polynomial.asConstant(): C = asConstantOrNull() ?: error("Can not represent non-constant polynomial as a constant") @Suppress("NOTHING_TO_INLINE") public inline fun Polynomial.substitute(argument: C): C = this.substitute(ring, argument) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/RationalFunction.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/RationalFunction.kt index 0842f0938..441136a64 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/RationalFunction.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/RationalFunction.kt @@ -67,7 +67,12 @@ internal fun rationalFunctionError(message: Any): Nothing = throw RationalFuncti public class RationalFunctionSpace> ( public val ring: A, -) : AbstractRationalFunctionalSpaceOverPolynomialSpace, RationalFunction, A> { +) : AbstractRationalFunctionalSpaceOverPolynomialSpace< + C, + Polynomial, + RationalFunction, + PolynomialSpace, + > { override val polynomialRing : PolynomialSpace = PolynomialSpace(ring)