Feature: Polynomials and rational functions #469
@ -1,389 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2018-2021 KMath contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package space.kscience.kmath.functions
|
|
||||||
|
|
||||||
import space.kscience.kmath.operations.*
|
|
||||||
import kotlin.js.JsName
|
|
||||||
import kotlin.jvm.JvmName
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstraction of polynomials.
|
|
||||||
*/
|
|
||||||
public interface AbstractPolynomial<C>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 coefficients in their terms.
|
|
||||||
* @param P the type of polynomials.
|
|
||||||
*/
|
|
||||||
@Suppress("INAPPLICABLE_JVM_NAME", "PARAMETER_NAME_CHANGED_ON_OVERRIDE")
|
|
||||||
public interface AbstractPolynomialSpace<C, P: AbstractPolynomial<C>> : Ring<P> {
|
|
||||||
/**
|
|
||||||
* Returns sum of the constant and the integer represented as constant (member of underlying ring).
|
|
||||||
*
|
|
||||||
* The operation is equivalent to adding [other] copies of unit of underlying ring to [this].
|
|
||||||
*/
|
|
||||||
public operator fun C.plus(other: Int): C
|
|
||||||
/**
|
|
||||||
* Returns difference between the constant and the integer represented as constant (member of underlying ring).
|
|
||||||
*
|
|
||||||
* The operation is equivalent to subtraction [other] copies of unit of underlying ring from [this].
|
|
||||||
*/
|
|
||||||
public operator fun C.minus(other: Int): C
|
|
||||||
/**
|
|
||||||
* Returns product of the constant and the integer represented as constant (member of underlying ring).
|
|
||||||
*
|
|
||||||
* The operation is equivalent to sum of [other] copies of [this].
|
|
||||||
*/
|
|
||||||
public operator fun C.times(other: Int): C
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns sum of the integer represented as constant (member of underlying ring) and the constant.
|
|
||||||
*
|
|
||||||
* The operation is equivalent to adding [this] copies of unit of underlying ring to [other].
|
|
||||||
*/
|
|
||||||
public operator fun Int.plus(other: C): C
|
|
||||||
/**
|
|
||||||
* Returns difference between the integer represented as constant (member of underlying ring) and the constant.
|
|
||||||
*
|
|
||||||
* The operation is equivalent to subtraction [this] copies of unit of underlying ring from [other].
|
|
||||||
*/
|
|
||||||
public operator fun Int.minus(other: C): C
|
|
||||||
/**
|
|
||||||
* Returns product of the integer represented as constant (member of underlying ring) and the constant.
|
|
||||||
*
|
|
||||||
* The operation is equivalent to sum of [this] copies of [other].
|
|
||||||
*/
|
|
||||||
public operator fun Int.times(other: C): C
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 operator fun P.plus(other: Int): P = addMultipliedBySquaring(this, one, other)
|
|
||||||
/**
|
|
||||||
* 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 operator fun P.minus(other: Int): P = addMultipliedBySquaring(this, one, -other)
|
|
||||||
/**
|
|
||||||
* Returns product of the polynomial and the integer represented as polynomial.
|
|
||||||
*
|
|
||||||
* The operation is equivalent to sum of [other] copies of [this].
|
|
||||||
*/
|
|
||||||
public operator fun P.times(other: Int): P = multiplyBySquaring(this, other)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 operator fun Int.plus(other: P): P = addMultipliedBySquaring(other, one, this)
|
|
||||||
/**
|
|
||||||
* 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 operator fun Int.minus(other: P): P = addMultipliedBySquaring(-other, one, this)
|
|
||||||
/**
|
|
||||||
* Returns product of the integer represented as polynomial and the polynomial.
|
|
||||||
*
|
|
||||||
* The operation is equivalent to sum of [this] copies of [other].
|
|
||||||
*/
|
|
||||||
public operator fun Int.times(other: P): P = multiplyBySquaring(other, this)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the same constant.
|
|
||||||
*/
|
|
||||||
@JvmName("constantUnaryPlus")
|
|
||||||
@JsName("constantUnaryPlus")
|
|
||||||
public operator fun C.unaryPlus(): C = this
|
|
||||||
/**
|
|
||||||
* Returns negation of the constant.
|
|
||||||
*/
|
|
||||||
@JvmName("constantUnaryMinus")
|
|
||||||
@JsName("constantUnaryMinus")
|
|
||||||
public operator fun C.unaryMinus(): C
|
|
||||||
/**
|
|
||||||
* Returns sum of the constants.
|
|
||||||
*/
|
|
||||||
@JvmName("constantPlus")
|
|
||||||
@JsName("constantPlus")
|
|
||||||
public operator fun C.plus(other: C): C
|
|
||||||
/**
|
|
||||||
* Returns difference of the constants.
|
|
||||||
*/
|
|
||||||
@JvmName("constantMinus")
|
|
||||||
@JsName("constantMinus")
|
|
||||||
public operator fun C.minus(other: C): C
|
|
||||||
/**
|
|
||||||
* Returns product of the constants.
|
|
||||||
*/
|
|
||||||
@JvmName("constantTimes")
|
|
||||||
@JsName("constantTimes")
|
|
||||||
public operator fun C.times(other: C): C
|
|
||||||
/**
|
|
||||||
* Raises [arg] to the integer power [exponent].
|
|
||||||
*/
|
|
||||||
@JvmName("constantPower")
|
|
||||||
@JsName("constantPower")
|
|
||||||
public fun power(arg: C, exponent: UInt) : C
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the instant is zero constant.
|
|
||||||
*/
|
|
||||||
public fun C.isZero(): Boolean = this == constantZero
|
|
||||||
/**
|
|
||||||
* Check if the instant is NOT zero constant.
|
|
||||||
*/
|
|
||||||
public fun C.isNotZero(): Boolean = !isZero()
|
|
||||||
/**
|
|
||||||
* Check if the instant is unit constant.
|
|
||||||
*/
|
|
||||||
public fun C.isOne(): Boolean = this == constantOne
|
|
||||||
/**
|
|
||||||
* Check if the instant is NOT unit constant.
|
|
||||||
*/
|
|
||||||
public fun C.isNotOne(): Boolean = !isOne()
|
|
||||||
/**
|
|
||||||
* Check if the instant is minus unit constant.
|
|
||||||
*/
|
|
||||||
public fun C.isMinusOne(): Boolean = this == -constantOne
|
|
||||||
/**
|
|
||||||
* Check if the instant is NOT minus unit constant.
|
|
||||||
*/
|
|
||||||
public fun C.isNotMinusOne(): Boolean = !isMinusOne()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instance of zero constant (zero of the underlying ring).
|
|
||||||
*/
|
|
||||||
public val constantZero: C
|
|
||||||
/**
|
|
||||||
* Instance of unit constant (unit of the underlying ring).
|
|
||||||
*/
|
|
||||||
public val constantOne: C
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns sum of the constant represented as polynomial and the polynomial.
|
|
||||||
*/
|
|
||||||
public operator fun C.plus(other: P): P
|
|
||||||
/**
|
|
||||||
* Returns difference between the constant represented as polynomial and the polynomial.
|
|
||||||
*/
|
|
||||||
public operator fun C.minus(other: P): P
|
|
||||||
/**
|
|
||||||
* Returns product of the constant represented as polynomial and the polynomial.
|
|
||||||
*/
|
|
||||||
public operator fun C.times(other: P): P
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns sum of the constant represented as polynomial and the polynomial.
|
|
||||||
*/
|
|
||||||
public operator fun P.plus(other: C): P
|
|
||||||
/**
|
|
||||||
* Returns difference between the constant represented as polynomial and the polynomial.
|
|
||||||
*/
|
|
||||||
public operator fun P.minus(other: C): P
|
|
||||||
/**
|
|
||||||
* Returns product of the constant represented as polynomial and the polynomial.
|
|
||||||
*/
|
|
||||||
public operator fun P.times(other: C): P
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the same polynomial.
|
|
||||||
*/
|
|
||||||
public override operator fun P.unaryPlus(): P = this
|
|
||||||
/**
|
|
||||||
* Returns negation of the polynomial.
|
|
||||||
*/
|
|
||||||
public override operator fun P.unaryMinus(): P
|
|
||||||
/**
|
|
||||||
* Returns sum of the polynomials.
|
|
||||||
*/
|
|
||||||
public override operator fun P.plus(other: P): P
|
|
||||||
/**
|
|
||||||
* Returns difference of the polynomials.
|
|
||||||
*/
|
|
||||||
public override operator fun P.minus(other: P): P
|
|
||||||
/**
|
|
||||||
* Returns product of the polynomials.
|
|
||||||
*/
|
|
||||||
public override operator fun P.times(other: P): P
|
|
||||||
/**
|
|
||||||
* Raises [arg] to the integer power [exponent].
|
|
||||||
*/
|
|
||||||
public override fun power(arg: P, exponent: UInt) : P = exponentiationBySquaring(arg, exponent)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the instant is zero polynomial.
|
|
||||||
*/
|
|
||||||
public fun P.isZero(): Boolean = this equalsTo zero
|
|
||||||
/**
|
|
||||||
* Check if the instant is NOT zero polynomial.
|
|
||||||
*/
|
|
||||||
public fun P.isNotZero(): Boolean = !isZero()
|
|
||||||
/**
|
|
||||||
* Check if the instant is unit polynomial.
|
|
||||||
*/
|
|
||||||
public fun P.isOne(): Boolean = this equalsTo one
|
|
||||||
/**
|
|
||||||
* Check if the instant is NOT unit polynomial.
|
|
||||||
*/
|
|
||||||
public fun P.isNotOne(): Boolean = !isOne()
|
|
||||||
/**
|
|
||||||
* Check if the instant is minus unit polynomial.
|
|
||||||
*/
|
|
||||||
public fun P.isMinusOne(): Boolean = this equalsTo -one
|
|
||||||
/**
|
|
||||||
* Check if the instant is NOT minus unit polynomial.
|
|
||||||
*/
|
|
||||||
public fun P.isNotMinusOne(): Boolean = !isMinusOne()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instance of zero polynomial (zero of the polynomial ring).
|
|
||||||
*/
|
|
||||||
public override val zero: P
|
|
||||||
/**
|
|
||||||
* Instance of unit polynomial (unit of the polynomial ring).
|
|
||||||
*/
|
|
||||||
public override val one: P
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks equality of the polynomials.
|
|
||||||
*/
|
|
||||||
public infix fun P.equalsTo(other: P): Boolean
|
|
||||||
/**
|
|
||||||
* Checks NOT equality of the polynomials.
|
|
||||||
*/
|
|
||||||
public infix fun P.notEqualsTo(other: P): Boolean = !(this equalsTo other)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Degree of the polynomial, [see also](https://en.wikipedia.org/wiki/Degree_of_a_polynomial). If the polynomial is
|
|
||||||
* zero, degree is -1.
|
|
||||||
*/
|
|
||||||
public val P.degree: Int
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the instant is constant polynomial (of degree no more than 0) over considered ring.
|
|
||||||
*/
|
|
||||||
public fun P.isConstant(): Boolean = degree <= 0
|
|
||||||
/**
|
|
||||||
* Checks if the instant is **not** constant polynomial (of degree no more than 0) over considered ring.
|
|
||||||
*/
|
|
||||||
public fun P.isNotConstant(): Boolean = !isConstant()
|
|
||||||
/**
|
|
||||||
* Checks if the instant is constant non-zero polynomial (of degree no more than 0) over considered ring.
|
|
||||||
*/
|
|
||||||
public fun P.isNonZeroConstant(): Boolean = degree == 0
|
|
||||||
/**
|
|
||||||
* Checks if the instant is **not** constant non-zero polynomial (of degree no more than 0) over considered ring.
|
|
||||||
*/
|
|
||||||
public fun P.isNotNonZeroConstant(): Boolean = !isNonZeroConstant()
|
|
||||||
/**
|
|
||||||
* If polynomial is a constant polynomial represents and returns it as constant.
|
|
||||||
* Otherwise, (when the polynomial is not constant polynomial) returns `null`.
|
|
||||||
*/
|
|
||||||
public fun P.asConstantOrNull(): C?
|
|
||||||
/**
|
|
||||||
* If polynomial is a constant polynomial represents and returns it as constant.
|
|
||||||
* Otherwise, (when the polynomial is not constant polynomial) raises corresponding exception.
|
|
||||||
*/
|
|
||||||
public fun P.asConstant(): C = requireNotNull(asConstantOrNull()) { "Can not represent non-constant polynomial as a constant" }
|
|
||||||
|
|
||||||
override fun add(left: P, right: P): P = left + right
|
|
||||||
override fun multiply(left: P, right: P): P = left * right
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 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<C, P: AbstractPolynomial<C>, A: Ring<C>> : AbstractPolynomialSpace<C, P> {
|
|
||||||
|
|
||||||
public val ring: A
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns sum of the constant and the integer represented as constant (member of underlying ring).
|
|
||||||
*
|
|
||||||
* The operation is equivalent to adding [other] copies of unit of underlying ring to [this].
|
|
||||||
*/
|
|
||||||
public override operator fun C.plus(other: Int): C = ring { addMultipliedBySquaring(this@plus, one, other) }
|
|
||||||
/**
|
|
||||||
* Returns difference between the constant and the integer represented as constant (member of underlying ring).
|
|
||||||
*
|
|
||||||
* The operation is equivalent to subtraction [other] copies of unit of underlying ring from [this].
|
|
||||||
*/
|
|
||||||
public override operator fun C.minus(other: Int): C = ring { addMultipliedBySquaring(this@minus, one, -other) }
|
|
||||||
/**
|
|
||||||
* Returns product of the constant and the integer represented as constant (member of underlying ring).
|
|
||||||
*
|
|
||||||
* The operation is equivalent to sum of [other] copies of [this].
|
|
||||||
*/
|
|
||||||
public override operator fun C.times(other: Int): C = ring { multiplyBySquaring(this@times, other) }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns sum of the integer represented as constant (member of underlying ring) and the constant.
|
|
||||||
*
|
|
||||||
* The operation is equivalent to adding [this] copies of unit of underlying ring to [other].
|
|
||||||
*/
|
|
||||||
public override operator fun Int.plus(other: C): C = ring { addMultipliedBySquaring(other, one, this@plus) }
|
|
||||||
/**
|
|
||||||
* Returns difference between the integer represented as constant (member of underlying ring) and the constant.
|
|
||||||
*
|
|
||||||
* The operation is equivalent to subtraction [this] copies of unit of underlying ring from [other].
|
|
||||||
*/
|
|
||||||
public override operator fun Int.minus(other: C): C = ring { addMultipliedBySquaring(-other, one, this@minus) }
|
|
||||||
/**
|
|
||||||
* Returns product of the integer represented as constant (member of underlying ring) and the constant.
|
|
||||||
*
|
|
||||||
* The operation is equivalent to sum of [this] copies of [other].
|
|
||||||
*/
|
|
||||||
public override operator fun Int.times(other: C): C = ring { multiplyBySquaring(other, this@times) }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns negation of the constant.
|
|
||||||
*/
|
|
||||||
@JvmName("constantUnaryMinus")
|
|
||||||
public override operator fun C.unaryMinus(): C = ring { -this@unaryMinus }
|
|
||||||
/**
|
|
||||||
* Returns sum of the constants.
|
|
||||||
*/
|
|
||||||
@JvmName("constantPlus")
|
|
||||||
public override operator fun C.plus(other: C): C = ring { this@plus + other }
|
|
||||||
/**
|
|
||||||
* Returns difference of the constants.
|
|
||||||
*/
|
|
||||||
@JvmName("constantMinus")
|
|
||||||
public override operator fun C.minus(other: C): C = ring { this@minus - other }
|
|
||||||
/**
|
|
||||||
* Returns product of the constants.
|
|
||||||
*/
|
|
||||||
@JvmName("constantTimes")
|
|
||||||
public override operator fun C.times(other: C): C = ring { this@times * other }
|
|
||||||
/**
|
|
||||||
* Raises [arg] to the integer power [exponent].
|
|
||||||
*/
|
|
||||||
@JvmName("constantPower")
|
|
||||||
override fun power(arg: C, exponent: UInt): C = ring { power(arg, exponent) }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instance of zero constant (zero of the underlying ring).
|
|
||||||
*/
|
|
||||||
public override val constantZero: C get() = ring.zero
|
|
||||||
/**
|
|
||||||
* Instance of unit constant (unit of the underlying ring).
|
|
||||||
*/
|
|
||||||
public override val constantOne: C get() = ring.one
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -44,7 +44,7 @@ internal constructor(
|
|||||||
* where `a`, `b` and `c` are corresponding [Symbol] objects.
|
* where `a`, `b` and `c` are corresponding [Symbol] objects.
|
||||||
*/
|
*/
|
||||||
public val coefficients: Map<Map<Symbol, UInt>, C>
|
public val coefficients: Map<Map<Symbol, UInt>, C>
|
||||||
) : AbstractPolynomial<C> {
|
) : Polynomial<C> {
|
||||||
override fun toString(): String = "LabeledPolynomial$coefficients"
|
override fun toString(): String = "LabeledPolynomial$coefficients"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ public fun <C> C.asLabeledPolynomial() : LabeledPolynomial<C> = LabeledPolynomia
|
|||||||
*/
|
*/
|
||||||
public class LabeledPolynomialSpace<C, A : Ring<C>>(
|
public class LabeledPolynomialSpace<C, A : Ring<C>>(
|
||||||
public override val ring: A,
|
public override val ring: A,
|
||||||
) : AbstractPolynomialSpaceOverRing<C, LabeledPolynomial<C>, A> {
|
) : PolynomialSpaceOverRing<C, LabeledPolynomial<C>, A> {
|
||||||
public operator fun Symbol.plus(other: Int): LabeledPolynomial<C> =
|
public operator fun Symbol.plus(other: Int): LabeledPolynomial<C> =
|
||||||
if (other == 0) LabeledPolynomial<C>(mapOf(
|
if (other == 0) LabeledPolynomial<C>(mapOf(
|
||||||
mapOf(this@plus to 1U) to constantOne,
|
mapOf(this@plus to 1U) to constantOne,
|
||||||
|
@ -13,7 +13,7 @@ import space.kscience.kmath.operations.invoke
|
|||||||
public class LabeledRationalFunction<C>(
|
public class LabeledRationalFunction<C>(
|
||||||
public override val numerator: LabeledPolynomial<C>,
|
public override val numerator: LabeledPolynomial<C>,
|
||||||
public override val denominator: LabeledPolynomial<C>
|
public override val denominator: LabeledPolynomial<C>
|
||||||
) : AbstractRationalFunction<C, LabeledPolynomial<C>> {
|
) : RationalFunction<C, LabeledPolynomial<C>> {
|
||||||
override fun toString(): String = "LabeledRationalFunction${numerator.coefficients}/${denominator.coefficients}"
|
override fun toString(): String = "LabeledRationalFunction${numerator.coefficients}/${denominator.coefficients}"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ public class LabeledRationalFunction<C>(
|
|||||||
public class LabeledRationalFunctionSpace<C, A: Ring<C>>(
|
public class LabeledRationalFunctionSpace<C, A: Ring<C>>(
|
||||||
public val ring: A,
|
public val ring: A,
|
||||||
) :
|
) :
|
||||||
AbstractRationalFunctionalSpaceOverPolynomialSpace<
|
RationalFunctionalSpaceOverPolynomialSpace<
|
||||||
C,
|
C,
|
||||||
LabeledPolynomial<C>,
|
LabeledPolynomial<C>,
|
||||||
LabeledRationalFunction<C>,
|
LabeledRationalFunction<C>,
|
||||||
|
@ -0,0 +1,491 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018-2021 KMath contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package space.kscience.kmath.functions
|
||||||
|
|
||||||
|
import space.kscience.kmath.operations.*
|
||||||
|
import kotlin.contracts.InvocationKind
|
||||||
|
import kotlin.contracts.contract
|
||||||
|
import kotlin.experimental.ExperimentalTypeInference
|
||||||
|
import kotlin.jvm.JvmName
|
||||||
|
import kotlin.math.max
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Polynomial model without fixation on specific context they are applied to.
|
||||||
|
*
|
||||||
|
* @param coefficients constant is the leftmost coefficient.
|
||||||
|
*/
|
||||||
|
public data class ListPolynomial<C>(
|
||||||
|
/**
|
||||||
|
* 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<C>
|
||||||
|
) : Polynomial<C> {
|
||||||
|
override fun toString(): String = "Polynomial$coefficients"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a [ListPolynomial] instance with given [coefficients]. The collection of coefficients will be reversed if
|
||||||
|
* [reverse] parameter is true.
|
||||||
|
*/
|
||||||
|
@Suppress("FunctionName")
|
||||||
|
public fun <C> ListPolynomial(coefficients: List<C>, reverse: Boolean = false): ListPolynomial<C> =
|
||||||
|
ListPolynomial(with(coefficients) { if (reverse) reversed() else this })
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a [ListPolynomial] instance with given [coefficients]. The collection of coefficients will be reversed if
|
||||||
|
* [reverse] parameter is true.
|
||||||
|
*/
|
||||||
|
@Suppress("FunctionName")
|
||||||
|
public fun <C> ListPolynomial(vararg coefficients: C, reverse: Boolean = false): ListPolynomial<C> =
|
||||||
|
ListPolynomial(with(coefficients) { if (reverse) reversed() else toList() })
|
||||||
|
|
||||||
|
public fun <C> C.asPolynomial() : ListPolynomial<C> = ListPolynomial(listOf(this))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Space of univariate polynomials constructed over ring.
|
||||||
|
*
|
||||||
|
* @param C the type of constants. Polynomials have them as a coefficients in their terms.
|
||||||
|
* @param A type of underlying ring of constants. It's [Ring] of [C].
|
||||||
|
* @param ring underlying ring of constants of type [A].
|
||||||
|
*/
|
||||||
|
public open class ListPolynomialSpace<C, A : Ring<C>>(
|
||||||
|
public override val ring: A,
|
||||||
|
) : PolynomialSpaceOverRing<C, ListPolynomial<C>, A> {
|
||||||
|
/**
|
||||||
|
* 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 ListPolynomial<C>.plus(other: Int): ListPolynomial<C> =
|
||||||
|
if (other == 0) this
|
||||||
|
else
|
||||||
|
ListPolynomial(
|
||||||
|
coefficients
|
||||||
|
.toMutableList()
|
||||||
|
.apply {
|
||||||
|
val result = getOrElse(0) { constantZero } + other
|
||||||
|
val isResultZero = result.isZero()
|
||||||
|
|
||||||
|
when {
|
||||||
|
size == 0 && !isResultZero -> add(result)
|
||||||
|
size > 1 || !isResultZero -> this[0] = result
|
||||||
|
else -> clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
/**
|
||||||
|
* 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 ListPolynomial<C>.minus(other: Int): ListPolynomial<C> =
|
||||||
|
if (other == 0) this
|
||||||
|
else
|
||||||
|
ListPolynomial(
|
||||||
|
coefficients
|
||||||
|
.toMutableList()
|
||||||
|
.apply {
|
||||||
|
val result = getOrElse(0) { constantZero } - other
|
||||||
|
val isResultZero = result.isZero()
|
||||||
|
|
||||||
|
when {
|
||||||
|
size == 0 && !isResultZero -> add(result)
|
||||||
|
size > 1 || !isResultZero -> this[0] = result
|
||||||
|
else -> clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
/**
|
||||||
|
* 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 ListPolynomial<C>.times(other: Int): ListPolynomial<C> =
|
||||||
|
if (other == 0) zero
|
||||||
|
else ListPolynomial(
|
||||||
|
coefficients
|
||||||
|
.applyAndRemoveZeros {
|
||||||
|
for (deg in indices) this[deg] = this[deg] * other
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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: ListPolynomial<C>): ListPolynomial<C> =
|
||||||
|
if (this == 0) other
|
||||||
|
else
|
||||||
|
ListPolynomial(
|
||||||
|
other.coefficients
|
||||||
|
.toMutableList()
|
||||||
|
.apply {
|
||||||
|
val result = this@plus + getOrElse(0) { constantZero }
|
||||||
|
val isResultZero = result.isZero()
|
||||||
|
|
||||||
|
when {
|
||||||
|
size == 0 && !isResultZero -> add(result)
|
||||||
|
size > 1 || !isResultZero -> this[0] = result
|
||||||
|
else -> clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
/**
|
||||||
|
* 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: ListPolynomial<C>): ListPolynomial<C> =
|
||||||
|
if (this == 0) other
|
||||||
|
else
|
||||||
|
ListPolynomial(
|
||||||
|
other.coefficients
|
||||||
|
.toMutableList()
|
||||||
|
.apply {
|
||||||
|
forEachIndexed { index, c -> if (index != 0) this[index] = -c }
|
||||||
|
|
||||||
|
val result = this@minus - getOrElse(0) { constantZero }
|
||||||
|
val isResultZero = result.isZero()
|
||||||
|
|
||||||
|
when {
|
||||||
|
size == 0 && !isResultZero -> add(result)
|
||||||
|
size > 1 || !isResultZero -> this[0] = result
|
||||||
|
else -> clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
/**
|
||||||
|
* 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: ListPolynomial<C>): ListPolynomial<C> =
|
||||||
|
if (this == 0) zero
|
||||||
|
else ListPolynomial(
|
||||||
|
other.coefficients
|
||||||
|
.applyAndRemoveZeros {
|
||||||
|
for (deg in indices) this[deg] = this@times * this[deg]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns sum of the constant represented as polynomial and the polynomial.
|
||||||
|
*/
|
||||||
|
public override operator fun C.plus(other: ListPolynomial<C>): ListPolynomial<C> =
|
||||||
|
if (this.isZero()) other
|
||||||
|
else with(other.coefficients) {
|
||||||
|
if (isEmpty()) ListPolynomial(listOf(this@plus))
|
||||||
|
else ListPolynomial(
|
||||||
|
toMutableList()
|
||||||
|
.apply {
|
||||||
|
val result = if (size == 0) this@plus else this@plus + get(0)
|
||||||
|
val isResultZero = result.isZero()
|
||||||
|
|
||||||
|
when {
|
||||||
|
size == 0 && !isResultZero -> add(result)
|
||||||
|
size > 1 || !isResultZero -> this[0] = result
|
||||||
|
else -> clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns difference between the constant represented as polynomial and the polynomial.
|
||||||
|
*/
|
||||||
|
public override operator fun C.minus(other: ListPolynomial<C>): ListPolynomial<C> =
|
||||||
|
if (this.isZero()) other
|
||||||
|
else with(other.coefficients) {
|
||||||
|
if (isEmpty()) ListPolynomial(listOf(this@minus))
|
||||||
|
else ListPolynomial(
|
||||||
|
toMutableList()
|
||||||
|
.apply {
|
||||||
|
forEachIndexed { index, c -> if (index != 0) this[index] = -c }
|
||||||
|
|
||||||
|
val result = if (size == 0) this@minus else this@minus - get(0)
|
||||||
|
val isResultZero = result.isZero()
|
||||||
|
|
||||||
|
when {
|
||||||
|
size == 0 && !isResultZero -> add(result)
|
||||||
|
size > 1 || !isResultZero -> this[0] = result
|
||||||
|
else -> clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns product of the constant represented as polynomial and the polynomial.
|
||||||
|
*/
|
||||||
|
public override operator fun C.times(other: ListPolynomial<C>): ListPolynomial<C> =
|
||||||
|
if (this.isZero()) other
|
||||||
|
else ListPolynomial(
|
||||||
|
other.coefficients
|
||||||
|
.applyAndRemoveZeros {
|
||||||
|
for (deg in indices) this[deg] = this@times * this[deg]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns sum of the constant represented as polynomial and the polynomial.
|
||||||
|
*/
|
||||||
|
public override operator fun ListPolynomial<C>.plus(other: C): ListPolynomial<C> =
|
||||||
|
if (other.isZero()) this
|
||||||
|
else with(coefficients) {
|
||||||
|
if (isEmpty()) ListPolynomial(listOf(other))
|
||||||
|
else ListPolynomial(
|
||||||
|
toMutableList()
|
||||||
|
.apply {
|
||||||
|
val result = if (size == 0) other else get(0) + other
|
||||||
|
val isResultZero = result.isZero()
|
||||||
|
|
||||||
|
when {
|
||||||
|
size == 0 && !isResultZero -> add(result)
|
||||||
|
size > 1 || !isResultZero -> this[0] = result
|
||||||
|
else -> clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns difference between the constant represented as polynomial and the polynomial.
|
||||||
|
*/
|
||||||
|
public override operator fun ListPolynomial<C>.minus(other: C): ListPolynomial<C> =
|
||||||
|
if (other.isZero()) this
|
||||||
|
else with(coefficients) {
|
||||||
|
if (isEmpty()) ListPolynomial(listOf(-other))
|
||||||
|
else ListPolynomial(
|
||||||
|
toMutableList()
|
||||||
|
.apply {
|
||||||
|
val result = if (size == 0) other else get(0) - other
|
||||||
|
val isResultZero = result.isZero()
|
||||||
|
|
||||||
|
when {
|
||||||
|
size == 0 && !isResultZero -> add(result)
|
||||||
|
size > 1 || !isResultZero -> this[0] = result
|
||||||
|
else -> clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns product of the constant represented as polynomial and the polynomial.
|
||||||
|
*/
|
||||||
|
public override operator fun ListPolynomial<C>.times(other: C): ListPolynomial<C> =
|
||||||
|
if (other.isZero()) this
|
||||||
|
else ListPolynomial(
|
||||||
|
coefficients
|
||||||
|
.applyAndRemoveZeros {
|
||||||
|
for (deg in indices) this[deg] = this[deg] * other
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns negation of the polynomial.
|
||||||
|
*/
|
||||||
|
public override operator fun ListPolynomial<C>.unaryMinus(): ListPolynomial<C> =
|
||||||
|
ListPolynomial(coefficients.map { -it })
|
||||||
|
/**
|
||||||
|
* Returns sum of the polynomials.
|
||||||
|
*/
|
||||||
|
public override operator fun ListPolynomial<C>.plus(other: ListPolynomial<C>): ListPolynomial<C> {
|
||||||
|
val thisDegree = degree
|
||||||
|
val otherDegree = other.degree
|
||||||
|
return ListPolynomial(
|
||||||
|
Coefficients(max(thisDegree, otherDegree) + 1) {
|
||||||
|
when {
|
||||||
|
it > thisDegree -> other.coefficients[it]
|
||||||
|
it > otherDegree -> coefficients[it]
|
||||||
|
else -> coefficients[it] + other.coefficients[it]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns difference of the polynomials.
|
||||||
|
*/
|
||||||
|
public override operator fun ListPolynomial<C>.minus(other: ListPolynomial<C>): ListPolynomial<C> {
|
||||||
|
val thisDegree = degree
|
||||||
|
val otherDegree = other.degree
|
||||||
|
return ListPolynomial(
|
||||||
|
Coefficients(max(thisDegree, otherDegree) + 1) {
|
||||||
|
when {
|
||||||
|
it > thisDegree -> -other.coefficients[it]
|
||||||
|
it > otherDegree -> coefficients[it]
|
||||||
|
else -> coefficients[it] - other.coefficients[it]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns product of the polynomials.
|
||||||
|
*/
|
||||||
|
public override operator fun ListPolynomial<C>.times(other: ListPolynomial<C>): ListPolynomial<C> {
|
||||||
|
val thisDegree = degree
|
||||||
|
val otherDegree = other.degree
|
||||||
|
return when {
|
||||||
|
thisDegree == -1 -> zero
|
||||||
|
otherDegree == -1 -> zero
|
||||||
|
else ->
|
||||||
|
ListPolynomial(
|
||||||
|
Coefficients(thisDegree + otherDegree + 1) { d ->
|
||||||
|
(max(0, d - otherDegree)..min(thisDegree, d))
|
||||||
|
.map { coefficients[it] * other.coefficients[d - it] }
|
||||||
|
.reduce { acc, rational -> acc + rational }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the instant is zero polynomial.
|
||||||
|
*/
|
||||||
|
public override fun ListPolynomial<C>.isZero(): Boolean = coefficients.all { it.isZero() }
|
||||||
|
/**
|
||||||
|
* Check if the instant is unit polynomial.
|
||||||
|
*/
|
||||||
|
public override fun ListPolynomial<C>.isOne(): Boolean =
|
||||||
|
with(coefficients) {
|
||||||
|
isNotEmpty() && withIndex().all { (index, c) -> if (index == 0) c.isOne() else c.isZero() }
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Check if the instant is minus unit polynomial.
|
||||||
|
*/
|
||||||
|
public override fun ListPolynomial<C>.isMinusOne(): Boolean =
|
||||||
|
with(coefficients) {
|
||||||
|
isNotEmpty() && withIndex().all { (index, c) -> if (index == 0) c.isMinusOne() else c.isZero() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of zero polynomial (zero of the polynomial ring).
|
||||||
|
*/
|
||||||
|
override val zero: ListPolynomial<C> = ListPolynomial(emptyList())
|
||||||
|
/**
|
||||||
|
* Instance of unit constant (unit of the underlying ring).
|
||||||
|
*/
|
||||||
|
override val one: ListPolynomial<C> = ListPolynomial(listOf(constantOne))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks equality of the polynomials.
|
||||||
|
*/
|
||||||
|
public override infix fun ListPolynomial<C>.equalsTo(other: ListPolynomial<C>): Boolean =
|
||||||
|
when {
|
||||||
|
this === other -> true
|
||||||
|
this.degree == other.degree -> (0..degree).all { coefficients[it] == other.coefficients[it] }
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 ListPolynomial<C>.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 ListPolynomial<C>.asConstantOrNull(): C? =
|
||||||
|
with(coefficients) {
|
||||||
|
when {
|
||||||
|
isEmpty() -> constantZero
|
||||||
|
withIndex().all { (index, c) -> index == 0 || c.isZero() } -> first()
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
public inline fun ListPolynomial<C>.substitute(argument: C): C = this.substitute(ring, argument)
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
public inline fun ListPolynomial<C>.substitute(argument: ListPolynomial<C>): ListPolynomial<C> = this.substitute(ring, argument)
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
public inline fun ListPolynomial<C>.asFunction(): (C) -> C = { this.substitute(ring, it) }
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
public inline fun ListPolynomial<C>.asFunctionOnConstants(): (C) -> C = { this.substitute(ring, it) }
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
public inline fun ListPolynomial<C>.asFunctionOnPolynomials(): (ListPolynomial<C>) -> ListPolynomial<C> = { this.substitute(ring, it) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluates the polynomial for the given value [argument].
|
||||||
|
*/
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
public inline operator fun ListPolynomial<C>.invoke(argument: C): C = this.substitute(ring, argument)
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
public inline operator fun ListPolynomial<C>.invoke(argument: ListPolynomial<C>): ListPolynomial<C> = this.substitute(ring, argument)
|
||||||
|
|
||||||
|
// TODO: Move to other internal utilities with context receiver
|
||||||
|
@JvmName("applyAndRemoveZerosInternal")
|
||||||
|
internal inline fun MutableList<C>.applyAndRemoveZeros(block: MutableList<C>.() -> Unit) : MutableList<C> {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
block()
|
||||||
|
while (isNotEmpty() && elementAt(lastIndex).isZero()) removeAt(lastIndex)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
internal inline fun List<C>.applyAndRemoveZeros(block: MutableList<C>.() -> Unit) : List<C> =
|
||||||
|
toMutableList().applyAndRemoveZeros(block)
|
||||||
|
@Suppress("FunctionName")
|
||||||
|
internal inline fun MutableCoefficients(size: Int, init: (index: Int) -> C): MutableList<C> {
|
||||||
|
val list = ArrayList<C>(size)
|
||||||
|
repeat(size) { index -> list.add(init(index)) }
|
||||||
|
with(list) { while (isNotEmpty() && elementAt(lastIndex).isZero()) removeAt(lastIndex) }
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
@Suppress("FunctionName")
|
||||||
|
internal inline fun Coefficients(size: Int, init: (index: Int) -> C): List<C> = MutableCoefficients(size, init)
|
||||||
|
@OptIn(ExperimentalTypeInference::class)
|
||||||
|
internal inline fun buildCoefficients(@BuilderInference builderAction: MutableList<C>.() -> Unit): List<C> {
|
||||||
|
contract { callsInPlace(builderAction, InvocationKind.EXACTLY_ONCE) }
|
||||||
|
return buildList {
|
||||||
|
builderAction()
|
||||||
|
while (isNotEmpty() && elementAt(lastIndex).isZero()) removeAt(lastIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@OptIn(ExperimentalTypeInference::class)
|
||||||
|
internal inline fun buildCoefficients(capacity: Int, @BuilderInference builderAction: MutableList<C>.() -> Unit): List<C> {
|
||||||
|
contract { callsInPlace(builderAction, InvocationKind.EXACTLY_ONCE) }
|
||||||
|
return buildList(capacity) {
|
||||||
|
builderAction()
|
||||||
|
while (isNotEmpty() && elementAt(lastIndex).isZero()) removeAt(lastIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Space of polynomials constructed over ring.
|
||||||
|
*
|
||||||
|
* @param C the type of constants. Polynomials have them as a coefficients in their terms.
|
||||||
|
* @param A type of underlying ring of constants. It's [Ring] of [C].
|
||||||
|
* @param ring underlying ring of constants of type [A].
|
||||||
|
*/
|
||||||
|
public class ScalableListPolynomialSpace<C, A>(
|
||||||
|
ring: A,
|
||||||
|
) : ListPolynomialSpace<C, A>(ring), ScaleOperations<ListPolynomial<C>> where A : Ring<C>, A : ScaleOperations<C> {
|
||||||
|
override fun scale(a: ListPolynomial<C>, value: Double): ListPolynomial<C> =
|
||||||
|
ring { ListPolynomial(a.coefficients.map { scale(it, value) }) }
|
||||||
|
}
|
@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018-2021 KMath contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package space.kscience.kmath.functions
|
||||||
|
|
||||||
|
import space.kscience.kmath.operations.Ring
|
||||||
|
|
||||||
|
|
||||||
|
public data class ListRationalFunction<C> internal constructor (
|
||||||
|
public override val numerator: ListPolynomial<C>,
|
||||||
|
public override val denominator: ListPolynomial<C>
|
||||||
|
) : RationalFunction<C, ListPolynomial<C>> {
|
||||||
|
override fun toString(): String = "RationalFunction${numerator.coefficients}/${denominator.coefficients}"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Waiting for context receivers :( TODO: Replace with context receivers when they will be available
|
||||||
|
|
||||||
|
//context(RationalFunctionSpace<C, A>)
|
||||||
|
//@Suppress("FunctionName")
|
||||||
|
//internal fun <C, A: Ring<C>> RationalFunction(numerator: Polynomial<C>, denominator: Polynomial<C>): RationalFunction<C> =
|
||||||
|
// if (denominator.isZero()) throw ArithmeticException("/ by zero")
|
||||||
|
// else RationalFunction<C>(numerator, denominator)
|
||||||
|
//context(RationalFunctionSpace<C, A>)
|
||||||
|
//@Suppress("FunctionName")
|
||||||
|
//public fun <C, A: Ring<C>> RationalFunction(numeratorCoefficients: List<C>, denominatorCoefficients: List<C>, reverse: Boolean = false): RationalFunction<C> =
|
||||||
|
// RationalFunction<C>(
|
||||||
|
// Polynomial( with(numeratorCoefficients) { if (reverse) reversed() else this } ),
|
||||||
|
// Polynomial( with(denominatorCoefficients) { if (reverse) reversed() else this } ).also { if (it.isZero()) }
|
||||||
|
// )
|
||||||
|
//context(RationalFunctionSpace<C, A>)
|
||||||
|
//@Suppress("FunctionName")
|
||||||
|
//public fun <C, A: Ring<C>> RationalFunction(numerator: Polynomial<C>): RationalFunction<C> =
|
||||||
|
// RationalFunction(numerator, onePolynomial)
|
||||||
|
//context(RationalFunctionSpace<C, A>)
|
||||||
|
//@Suppress("FunctionName")
|
||||||
|
//public fun <C, A: Ring<C>> RationalFunction(numeratorCoefficients: List<C>, reverse: Boolean = false): RationalFunction<C> =
|
||||||
|
// RationalFunction(
|
||||||
|
// Polynomial( with(numeratorCoefficients) { if (reverse) reversed() else this } )
|
||||||
|
// )
|
||||||
|
|
||||||
|
public class ListRationalFunctionSpace<C, A : Ring<C>> (
|
||||||
|
public val ring: A,
|
||||||
|
) :
|
||||||
|
RationalFunctionalSpaceOverPolynomialSpace<
|
||||||
|
C,
|
||||||
|
ListPolynomial<C>,
|
||||||
|
ListRationalFunction<C>,
|
||||||
|
ListPolynomialSpace<C, A>,
|
||||||
|
>,
|
||||||
|
PolynomialSpaceOfFractions<
|
||||||
|
C,
|
||||||
|
ListPolynomial<C>,
|
||||||
|
ListRationalFunction<C>,
|
||||||
|
>() {
|
||||||
|
|
||||||
|
override val polynomialRing : ListPolynomialSpace<C, A> = ListPolynomialSpace(ring)
|
||||||
|
override fun constructRationalFunction(numerator: ListPolynomial<C>, denominator: ListPolynomial<C>): ListRationalFunction<C> =
|
||||||
|
ListRationalFunction(numerator, denominator)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of zero rational function (zero of the rational functions ring).
|
||||||
|
*/
|
||||||
|
public override val zero: ListRationalFunction<C> = ListRationalFunction(polynomialZero, polynomialOne)
|
||||||
|
/**
|
||||||
|
* Instance of unit polynomial (unit of the rational functions ring).
|
||||||
|
*/
|
||||||
|
public override val one: ListRationalFunction<C> = ListRationalFunction(polynomialOne, polynomialOne)
|
||||||
|
|
||||||
|
// TODO: Разобрать
|
||||||
|
|
||||||
|
public operator fun ListRationalFunction<C>.div(other: ListRationalFunction<C>): ListRationalFunction<C> =
|
||||||
|
ListRationalFunction(
|
||||||
|
numerator * other.denominator,
|
||||||
|
denominator * other.numerator
|
||||||
|
)
|
||||||
|
|
||||||
|
public operator fun ListRationalFunction<C>.div(other: ListPolynomial<C>): ListRationalFunction<C> =
|
||||||
|
ListRationalFunction(
|
||||||
|
numerator,
|
||||||
|
denominator * other
|
||||||
|
)
|
||||||
|
|
||||||
|
public operator fun ListRationalFunction<C>.div(other: C): ListRationalFunction<C> =
|
||||||
|
ListRationalFunction(
|
||||||
|
numerator,
|
||||||
|
denominator * other
|
||||||
|
)
|
||||||
|
|
||||||
|
public operator fun ListRationalFunction<C>.div(other: Int): ListRationalFunction<C> =
|
||||||
|
ListRationalFunction(
|
||||||
|
numerator,
|
||||||
|
denominator * other
|
||||||
|
)
|
||||||
|
|
||||||
|
// operator fun invoke(arg: UnivariatePolynomial<T>): RationalFunction<T> =
|
||||||
|
// RationalFunction(
|
||||||
|
// numerator(arg),
|
||||||
|
// denominator(arg)
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// operator fun invoke(arg: RationalFunction<T>): RationalFunction<T> {
|
||||||
|
// val num = numerator invokeRFTakeNumerator arg
|
||||||
|
// val den = denominator invokeRFTakeNumerator arg
|
||||||
|
// val degreeDif = numeratorDegree - denominatorDegree
|
||||||
|
// return if (degreeDif > 0)
|
||||||
|
// RationalFunction(
|
||||||
|
// num,
|
||||||
|
// multiplyByPower(den, arg.denominator, degreeDif)
|
||||||
|
// )
|
||||||
|
// else
|
||||||
|
// RationalFunction(
|
||||||
|
// multiplyByPower(num, arg.denominator, -degreeDif),
|
||||||
|
// den
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// override fun toString(): String = toString(UnivariatePolynomial.variableName)
|
||||||
|
//
|
||||||
|
// fun toString(withVariableName: String = UnivariatePolynomial.variableName): String =
|
||||||
|
// when(true) {
|
||||||
|
// numerator.isZero() -> "0"
|
||||||
|
// denominator.isOne() -> numerator.toString(withVariableName)
|
||||||
|
// else -> "${numerator.toStringWithBrackets(withVariableName)}/${denominator.toStringWithBrackets(withVariableName)}"
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fun toStringWithBrackets(withVariableName: String = UnivariatePolynomial.variableName): String =
|
||||||
|
// when(true) {
|
||||||
|
// numerator.isZero() -> "0"
|
||||||
|
// denominator.isOne() -> numerator.toStringWithBrackets(withVariableName)
|
||||||
|
// else -> "(${numerator.toStringWithBrackets(withVariableName)}/${denominator.toStringWithBrackets(withVariableName)})"
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fun toReversedString(withVariableName: String = UnivariatePolynomial.variableName): String =
|
||||||
|
// when(true) {
|
||||||
|
// numerator.isZero() -> "0"
|
||||||
|
// denominator.isOne() -> numerator.toReversedString(withVariableName)
|
||||||
|
// else -> "${numerator.toReversedStringWithBrackets(withVariableName)}/${denominator.toReversedStringWithBrackets(withVariableName)}"
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fun toReversedStringWithBrackets(withVariableName: String = UnivariatePolynomial.variableName): String =
|
||||||
|
// when(true) {
|
||||||
|
// numerator.isZero() -> "0"
|
||||||
|
// denominator.isOne() -> numerator.toReversedStringWithBrackets(withVariableName)
|
||||||
|
// else -> "(${numerator.toReversedStringWithBrackets(withVariableName)}/${denominator.toReversedStringWithBrackets(withVariableName)})"
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fun removeZeros() =
|
||||||
|
// RationalFunction(
|
||||||
|
// numerator.removeZeros(),
|
||||||
|
// denominator.removeZeros()
|
||||||
|
// )
|
||||||
|
}
|
@ -43,7 +43,7 @@ internal constructor(
|
|||||||
* contain any zeros on end, but can contain zeros on start or anywhere in middle.
|
* contain any zeros on end, but can contain zeros on start or anywhere in middle.
|
||||||
*/
|
*/
|
||||||
public val coefficients: Map<List<UInt>, C>
|
public val coefficients: Map<List<UInt>, C>
|
||||||
) : AbstractPolynomial<C> {
|
) : Polynomial<C> {
|
||||||
override fun toString(): String = "NumberedPolynomial$coefficients"
|
override fun toString(): String = "NumberedPolynomial$coefficients"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +112,7 @@ public fun <C> C.asNumberedPolynomial() : NumberedPolynomial<C> = NumberedPolyno
|
|||||||
*/
|
*/
|
||||||
public open class NumberedPolynomialSpace<C, A : Ring<C>>(
|
public open class NumberedPolynomialSpace<C, A : Ring<C>>(
|
||||||
public final override val ring: A,
|
public final override val ring: A,
|
||||||
) : AbstractPolynomialSpaceOverRing<C, NumberedPolynomial<C>, A> {
|
) : PolynomialSpaceOverRing<C, NumberedPolynomial<C>, A> {
|
||||||
/**
|
/**
|
||||||
* Returns sum of the polynomial and the integer represented as polynomial.
|
* Returns sum of the polynomial and the integer represented as polynomial.
|
||||||
*
|
*
|
||||||
|
@ -12,7 +12,7 @@ import kotlin.math.max
|
|||||||
public class NumberedRationalFunction<C> internal constructor(
|
public class NumberedRationalFunction<C> internal constructor(
|
||||||
public override val numerator: NumberedPolynomial<C>,
|
public override val numerator: NumberedPolynomial<C>,
|
||||||
public override val denominator: NumberedPolynomial<C>
|
public override val denominator: NumberedPolynomial<C>
|
||||||
) : AbstractRationalFunction<C, NumberedPolynomial<C>> {
|
) : RationalFunction<C, NumberedPolynomial<C>> {
|
||||||
override fun toString(): String = "NumberedRationalFunction${numerator.coefficients}/${denominator.coefficients}"
|
override fun toString(): String = "NumberedRationalFunction${numerator.coefficients}/${denominator.coefficients}"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ public class NumberedRationalFunction<C> internal constructor(
|
|||||||
public class NumberedRationalFunctionSpace<C, A: Ring<C>> (
|
public class NumberedRationalFunctionSpace<C, A: Ring<C>> (
|
||||||
public val ring: A,
|
public val ring: A,
|
||||||
) :
|
) :
|
||||||
AbstractRationalFunctionalSpaceOverPolynomialSpace<
|
RationalFunctionalSpaceOverPolynomialSpace<
|
||||||
C,
|
C,
|
||||||
NumberedPolynomial<C>,
|
NumberedPolynomial<C>,
|
||||||
NumberedRationalFunction<C>,
|
NumberedRationalFunction<C>,
|
||||||
|
@ -27,10 +27,10 @@ public fun interface Piecewise<in T, out R> {
|
|||||||
* @property pieces An ordered list of range-polynomial pairs. The list does not in general guarantee that there are no
|
* @property pieces An ordered list of range-polynomial pairs. The list does not in general guarantee that there are no
|
||||||
* "holes" in it.
|
* "holes" in it.
|
||||||
*/
|
*/
|
||||||
public interface PiecewisePolynomial<T : Comparable<T>> : Piecewise<T, Polynomial<T>> {
|
public interface PiecewisePolynomial<T : Comparable<T>> : Piecewise<T, ListPolynomial<T>> {
|
||||||
public val pieces: Collection<Pair<ClosedRange<T>, Polynomial<T>>>
|
public val pieces: Collection<Pair<ClosedRange<T>, ListPolynomial<T>>>
|
||||||
|
|
||||||
override fun findPiece(arg: T): Polynomial<T>?
|
override fun findPiece(arg: T): ListPolynomial<T>?
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,11 +38,11 @@ public interface PiecewisePolynomial<T : Comparable<T>> : Piecewise<T, Polynomia
|
|||||||
*/
|
*/
|
||||||
@PerformancePitfall("findPiece method of resulting piecewise is slow")
|
@PerformancePitfall("findPiece method of resulting piecewise is slow")
|
||||||
public fun <T : Comparable<T>> PiecewisePolynomial(
|
public fun <T : Comparable<T>> PiecewisePolynomial(
|
||||||
pieces: Collection<Pair<ClosedRange<T>, Polynomial<T>>>,
|
pieces: Collection<Pair<ClosedRange<T>, ListPolynomial<T>>>,
|
||||||
): PiecewisePolynomial<T> = object : PiecewisePolynomial<T> {
|
): PiecewisePolynomial<T> = object : PiecewisePolynomial<T> {
|
||||||
override val pieces: Collection<Pair<ClosedRange<T>, Polynomial<T>>> = pieces
|
override val pieces: Collection<Pair<ClosedRange<T>, ListPolynomial<T>>> = pieces
|
||||||
|
|
||||||
override fun findPiece(arg: T): Polynomial<T>? = pieces.firstOrNull { arg in it.first }?.second
|
override fun findPiece(arg: T): ListPolynomial<T>? = pieces.firstOrNull { arg in it.first }?.second
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,10 +50,10 @@ public fun <T : Comparable<T>> PiecewisePolynomial(
|
|||||||
* The pieces search is logarithmic.
|
* The pieces search is logarithmic.
|
||||||
*/
|
*/
|
||||||
private class OrderedPiecewisePolynomial<T : Comparable<T>>(
|
private class OrderedPiecewisePolynomial<T : Comparable<T>>(
|
||||||
override val pieces: List<Pair<ClosedRange<T>, Polynomial<T>>>,
|
override val pieces: List<Pair<ClosedRange<T>, ListPolynomial<T>>>,
|
||||||
) : PiecewisePolynomial<T> {
|
) : PiecewisePolynomial<T> {
|
||||||
|
|
||||||
override fun findPiece(arg: T): Polynomial<T>? {
|
override fun findPiece(arg: T): ListPolynomial<T>? {
|
||||||
val index = pieces.binarySearch { (range, _) ->
|
val index = pieces.binarySearch { (range, _) ->
|
||||||
when {
|
when {
|
||||||
arg >= range.endInclusive -> -1
|
arg >= range.endInclusive -> -1
|
||||||
@ -74,7 +74,7 @@ private class OrderedPiecewisePolynomial<T : Comparable<T>>(
|
|||||||
*/
|
*/
|
||||||
public class PiecewiseBuilder<T : Comparable<T>>(delimiter: T) {
|
public class PiecewiseBuilder<T : Comparable<T>>(delimiter: T) {
|
||||||
private val delimiters: MutableList<T> = arrayListOf(delimiter)
|
private val delimiters: MutableList<T> = arrayListOf(delimiter)
|
||||||
private val pieces: MutableList<Polynomial<T>> = arrayListOf()
|
private val pieces: MutableList<ListPolynomial<T>> = arrayListOf()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dynamically adds a piece to the right side (beyond maximum argument value of previous piece)
|
* Dynamically adds a piece to the right side (beyond maximum argument value of previous piece)
|
||||||
@ -82,7 +82,7 @@ public class PiecewiseBuilder<T : Comparable<T>>(delimiter: T) {
|
|||||||
* @param right new rightmost position. If is less than current rightmost position, an error is thrown.
|
* @param right new rightmost position. If is less than current rightmost position, an error is thrown.
|
||||||
* @param piece the sub-function.
|
* @param piece the sub-function.
|
||||||
*/
|
*/
|
||||||
public fun putRight(right: T, piece: Polynomial<T>) {
|
public fun putRight(right: T, piece: ListPolynomial<T>) {
|
||||||
require(right > delimiters.last()) { "New delimiter should be to the right of old one" }
|
require(right > delimiters.last()) { "New delimiter should be to the right of old one" }
|
||||||
delimiters += right
|
delimiters += right
|
||||||
pieces += piece
|
pieces += piece
|
||||||
@ -94,7 +94,7 @@ public class PiecewiseBuilder<T : Comparable<T>>(delimiter: T) {
|
|||||||
* @param left the new leftmost position. If is less than current rightmost position, an error is thrown.
|
* @param left the new leftmost position. If is less than current rightmost position, an error is thrown.
|
||||||
* @param piece the sub-function.
|
* @param piece the sub-function.
|
||||||
*/
|
*/
|
||||||
public fun putLeft(left: T, piece: Polynomial<T>) {
|
public fun putLeft(left: T, piece: ListPolynomial<T>) {
|
||||||
require(left < delimiters.first()) { "New delimiter should be to the left of old one" }
|
require(left < delimiters.first()) { "New delimiter should be to the left of old one" }
|
||||||
delimiters.add(0, left)
|
delimiters.add(0, left)
|
||||||
pieces.add(0, piece)
|
pieces.add(0, piece)
|
||||||
|
@ -6,486 +6,384 @@
|
|||||||
package space.kscience.kmath.functions
|
package space.kscience.kmath.functions
|
||||||
|
|
||||||
import space.kscience.kmath.operations.*
|
import space.kscience.kmath.operations.*
|
||||||
import kotlin.contracts.InvocationKind
|
import kotlin.js.JsName
|
||||||
import kotlin.contracts.contract
|
|
||||||
import kotlin.experimental.ExperimentalTypeInference
|
|
||||||
import kotlin.jvm.JvmName
|
import kotlin.jvm.JvmName
|
||||||
import kotlin.math.max
|
|
||||||
import kotlin.math.min
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Polynomial model without fixation on specific context they are applied to.
|
* Abstraction of polynomials.
|
||||||
*
|
|
||||||
* @param coefficients constant is the leftmost coefficient.
|
|
||||||
*/
|
*/
|
||||||
public data class Polynomial<C>(
|
public interface Polynomial<C>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 coefficients in their terms.
|
||||||
|
* @param P the type of polynomials.
|
||||||
|
*/
|
||||||
|
@Suppress("INAPPLICABLE_JVM_NAME", "PARAMETER_NAME_CHANGED_ON_OVERRIDE")
|
||||||
|
public interface PolynomialSpace<C, P: Polynomial<C>> : Ring<P> {
|
||||||
/**
|
/**
|
||||||
* List that collects coefficients of the polynomial. Every monomial `a x^d` is represented as a coefficients
|
* Returns sum of the constant and the integer represented as constant (member of underlying ring).
|
||||||
* `a` placed into the list with index `d`. For example coefficients of polynomial `5 x^2 - 6` can be represented as
|
*
|
||||||
* ```
|
* The operation is equivalent to adding [other] copies of unit of underlying ring to [this].
|
||||||
* 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<C>
|
public operator fun C.plus(other: Int): C
|
||||||
) : AbstractPolynomial<C> {
|
/**
|
||||||
override fun toString(): String = "Polynomial$coefficients"
|
* Returns difference between the constant and the integer represented as constant (member of underlying ring).
|
||||||
}
|
*
|
||||||
|
* The operation is equivalent to subtraction [other] copies of unit of underlying ring from [this].
|
||||||
|
*/
|
||||||
|
public operator fun C.minus(other: Int): C
|
||||||
|
/**
|
||||||
|
* Returns product of the constant and the integer represented as constant (member of underlying ring).
|
||||||
|
*
|
||||||
|
* The operation is equivalent to sum of [other] copies of [this].
|
||||||
|
*/
|
||||||
|
public operator fun C.times(other: Int): C
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a [Polynomial] instance with given [coefficients]. The collection of coefficients will be reversed if
|
* Returns sum of the integer represented as constant (member of underlying ring) and the constant.
|
||||||
* [reverse] parameter is true.
|
*
|
||||||
*/
|
* The operation is equivalent to adding [this] copies of unit of underlying ring to [other].
|
||||||
@Suppress("FunctionName")
|
*/
|
||||||
public fun <C> Polynomial(coefficients: List<C>, reverse: Boolean = false): Polynomial<C> =
|
public operator fun Int.plus(other: C): C
|
||||||
Polynomial(with(coefficients) { if (reverse) reversed() else this })
|
/**
|
||||||
|
* Returns difference between the integer represented as constant (member of underlying ring) and the constant.
|
||||||
|
*
|
||||||
|
* The operation is equivalent to subtraction [this] copies of unit of underlying ring from [other].
|
||||||
|
*/
|
||||||
|
public operator fun Int.minus(other: C): C
|
||||||
|
/**
|
||||||
|
* Returns product of the integer represented as constant (member of underlying ring) and the constant.
|
||||||
|
*
|
||||||
|
* The operation is equivalent to sum of [this] copies of [other].
|
||||||
|
*/
|
||||||
|
public operator fun Int.times(other: C): C
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a [Polynomial] instance with given [coefficients]. The collection of coefficients will be reversed if
|
|
||||||
* [reverse] parameter is true.
|
|
||||||
*/
|
|
||||||
@Suppress("FunctionName")
|
|
||||||
public fun <C> Polynomial(vararg coefficients: C, reverse: Boolean = false): Polynomial<C> =
|
|
||||||
Polynomial(with(coefficients) { if (reverse) reversed() else toList() })
|
|
||||||
|
|
||||||
public fun <C> C.asPolynomial() : Polynomial<C> = Polynomial(listOf(this))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Space of univariate polynomials constructed over ring.
|
|
||||||
*
|
|
||||||
* @param C the type of constants. Polynomials have them as a coefficients in their terms.
|
|
||||||
* @param A type of underlying ring of constants. It's [Ring] of [C].
|
|
||||||
* @param ring underlying ring of constants of type [A].
|
|
||||||
*/
|
|
||||||
public open class PolynomialSpace<C, A : Ring<C>>(
|
|
||||||
public override val ring: A,
|
|
||||||
) : AbstractPolynomialSpaceOverRing<C, Polynomial<C>, A> {
|
|
||||||
/**
|
/**
|
||||||
* Returns sum of the polynomial and the integer represented as polynomial.
|
* Returns sum of the polynomial and the integer represented as polynomial.
|
||||||
*
|
*
|
||||||
* The operation is equivalent to adding [other] copies of unit polynomial to [this].
|
* The operation is equivalent to adding [other] copies of unit polynomial to [this].
|
||||||
*/
|
*/
|
||||||
public override operator fun Polynomial<C>.plus(other: Int): Polynomial<C> =
|
public operator fun P.plus(other: Int): P = addMultipliedBySquaring(this, one, other)
|
||||||
if (other == 0) this
|
|
||||||
else
|
|
||||||
Polynomial(
|
|
||||||
coefficients
|
|
||||||
.toMutableList()
|
|
||||||
.apply {
|
|
||||||
val result = getOrElse(0) { constantZero } + other
|
|
||||||
val isResultZero = result.isZero()
|
|
||||||
|
|
||||||
when {
|
|
||||||
size == 0 && !isResultZero -> add(result)
|
|
||||||
size > 1 || !isResultZero -> this[0] = result
|
|
||||||
else -> clear()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
/**
|
/**
|
||||||
* Returns difference between the polynomial and the integer represented as polynomial.
|
* Returns difference between the polynomial and the integer represented as polynomial.
|
||||||
*
|
*
|
||||||
* The operation is equivalent to subtraction [other] copies of unit polynomial from [this].
|
* The operation is equivalent to subtraction [other] copies of unit polynomial from [this].
|
||||||
*/
|
*/
|
||||||
public override operator fun Polynomial<C>.minus(other: Int): Polynomial<C> =
|
public operator fun P.minus(other: Int): P = addMultipliedBySquaring(this, one, -other)
|
||||||
if (other == 0) this
|
|
||||||
else
|
|
||||||
Polynomial(
|
|
||||||
coefficients
|
|
||||||
.toMutableList()
|
|
||||||
.apply {
|
|
||||||
val result = getOrElse(0) { constantZero } - other
|
|
||||||
val isResultZero = result.isZero()
|
|
||||||
|
|
||||||
when {
|
|
||||||
size == 0 && !isResultZero -> add(result)
|
|
||||||
size > 1 || !isResultZero -> this[0] = result
|
|
||||||
else -> clear()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
/**
|
/**
|
||||||
* Returns product of the polynomial and the integer represented as polynomial.
|
* Returns product of the polynomial and the integer represented as polynomial.
|
||||||
*
|
*
|
||||||
* The operation is equivalent to sum of [other] copies of [this].
|
* The operation is equivalent to sum of [other] copies of [this].
|
||||||
*/
|
*/
|
||||||
public override operator fun Polynomial<C>.times(other: Int): Polynomial<C> =
|
public operator fun P.times(other: Int): P = multiplyBySquaring(this, other)
|
||||||
if (other == 0) zero
|
|
||||||
else Polynomial(
|
|
||||||
coefficients
|
|
||||||
.applyAndRemoveZeros {
|
|
||||||
for (deg in indices) this[deg] = this[deg] * other
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns sum of the integer represented as polynomial and the polynomial.
|
* Returns sum of the integer represented as polynomial and the polynomial.
|
||||||
*
|
*
|
||||||
* The operation is equivalent to adding [this] copies of unit polynomial to [other].
|
* The operation is equivalent to adding [this] copies of unit polynomial to [other].
|
||||||
*/
|
*/
|
||||||
public override operator fun Int.plus(other: Polynomial<C>): Polynomial<C> =
|
public operator fun Int.plus(other: P): P = addMultipliedBySquaring(other, one, this)
|
||||||
if (this == 0) other
|
|
||||||
else
|
|
||||||
Polynomial(
|
|
||||||
other.coefficients
|
|
||||||
.toMutableList()
|
|
||||||
.apply {
|
|
||||||
val result = this@plus + getOrElse(0) { constantZero }
|
|
||||||
val isResultZero = result.isZero()
|
|
||||||
|
|
||||||
when {
|
|
||||||
size == 0 && !isResultZero -> add(result)
|
|
||||||
size > 1 || !isResultZero -> this[0] = result
|
|
||||||
else -> clear()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
/**
|
/**
|
||||||
* Returns difference between the integer represented as polynomial and the polynomial.
|
* Returns difference between the integer represented as polynomial and the polynomial.
|
||||||
*
|
*
|
||||||
* The operation is equivalent to subtraction [this] copies of unit polynomial from [other].
|
* The operation is equivalent to subtraction [this] copies of unit polynomial from [other].
|
||||||
*/
|
*/
|
||||||
public override operator fun Int.minus(other: Polynomial<C>): Polynomial<C> =
|
public operator fun Int.minus(other: P): P = addMultipliedBySquaring(-other, one, this)
|
||||||
if (this == 0) other
|
|
||||||
else
|
|
||||||
Polynomial(
|
|
||||||
other.coefficients
|
|
||||||
.toMutableList()
|
|
||||||
.apply {
|
|
||||||
forEachIndexed { index, c -> if (index != 0) this[index] = -c }
|
|
||||||
|
|
||||||
val result = this@minus - getOrElse(0) { constantZero }
|
|
||||||
val isResultZero = result.isZero()
|
|
||||||
|
|
||||||
when {
|
|
||||||
size == 0 && !isResultZero -> add(result)
|
|
||||||
size > 1 || !isResultZero -> this[0] = result
|
|
||||||
else -> clear()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
/**
|
/**
|
||||||
* Returns product of the integer represented as polynomial and the polynomial.
|
* Returns product of the integer represented as polynomial and the polynomial.
|
||||||
*
|
*
|
||||||
* The operation is equivalent to sum of [this] copies of [other].
|
* The operation is equivalent to sum of [this] copies of [other].
|
||||||
*/
|
*/
|
||||||
public override operator fun Int.times(other: Polynomial<C>): Polynomial<C> =
|
public operator fun Int.times(other: P): P = multiplyBySquaring(other, this)
|
||||||
if (this == 0) zero
|
|
||||||
else Polynomial(
|
/**
|
||||||
other.coefficients
|
* Returns the same constant.
|
||||||
.applyAndRemoveZeros {
|
*/
|
||||||
for (deg in indices) this[deg] = this@times * this[deg]
|
@JvmName("constantUnaryPlus")
|
||||||
}
|
@JsName("constantUnaryPlus")
|
||||||
)
|
public operator fun C.unaryPlus(): C = this
|
||||||
|
/**
|
||||||
|
* Returns negation of the constant.
|
||||||
|
*/
|
||||||
|
@JvmName("constantUnaryMinus")
|
||||||
|
@JsName("constantUnaryMinus")
|
||||||
|
public operator fun C.unaryMinus(): C
|
||||||
|
/**
|
||||||
|
* Returns sum of the constants.
|
||||||
|
*/
|
||||||
|
@JvmName("constantPlus")
|
||||||
|
@JsName("constantPlus")
|
||||||
|
public operator fun C.plus(other: C): C
|
||||||
|
/**
|
||||||
|
* Returns difference of the constants.
|
||||||
|
*/
|
||||||
|
@JvmName("constantMinus")
|
||||||
|
@JsName("constantMinus")
|
||||||
|
public operator fun C.minus(other: C): C
|
||||||
|
/**
|
||||||
|
* Returns product of the constants.
|
||||||
|
*/
|
||||||
|
@JvmName("constantTimes")
|
||||||
|
@JsName("constantTimes")
|
||||||
|
public operator fun C.times(other: C): C
|
||||||
|
/**
|
||||||
|
* Raises [arg] to the integer power [exponent].
|
||||||
|
*/
|
||||||
|
@JvmName("constantPower")
|
||||||
|
@JsName("constantPower")
|
||||||
|
public fun power(arg: C, exponent: UInt) : C
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the instant is zero constant.
|
||||||
|
*/
|
||||||
|
public fun C.isZero(): Boolean = this == constantZero
|
||||||
|
/**
|
||||||
|
* Check if the instant is NOT zero constant.
|
||||||
|
*/
|
||||||
|
public fun C.isNotZero(): Boolean = !isZero()
|
||||||
|
/**
|
||||||
|
* Check if the instant is unit constant.
|
||||||
|
*/
|
||||||
|
public fun C.isOne(): Boolean = this == constantOne
|
||||||
|
/**
|
||||||
|
* Check if the instant is NOT unit constant.
|
||||||
|
*/
|
||||||
|
public fun C.isNotOne(): Boolean = !isOne()
|
||||||
|
/**
|
||||||
|
* Check if the instant is minus unit constant.
|
||||||
|
*/
|
||||||
|
public fun C.isMinusOne(): Boolean = this == -constantOne
|
||||||
|
/**
|
||||||
|
* Check if the instant is NOT minus unit constant.
|
||||||
|
*/
|
||||||
|
public fun C.isNotMinusOne(): Boolean = !isMinusOne()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of zero constant (zero of the underlying ring).
|
||||||
|
*/
|
||||||
|
public val constantZero: C
|
||||||
|
/**
|
||||||
|
* Instance of unit constant (unit of the underlying ring).
|
||||||
|
*/
|
||||||
|
public val constantOne: C
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns sum of the constant represented as polynomial and the polynomial.
|
* Returns sum of the constant represented as polynomial and the polynomial.
|
||||||
*/
|
*/
|
||||||
public override operator fun C.plus(other: Polynomial<C>): Polynomial<C> =
|
public operator fun C.plus(other: P): P
|
||||||
if (this.isZero()) other
|
|
||||||
else with(other.coefficients) {
|
|
||||||
if (isEmpty()) Polynomial(listOf(this@plus))
|
|
||||||
else Polynomial(
|
|
||||||
toMutableList()
|
|
||||||
.apply {
|
|
||||||
val result = if (size == 0) this@plus else this@plus + get(0)
|
|
||||||
val isResultZero = result.isZero()
|
|
||||||
|
|
||||||
when {
|
|
||||||
size == 0 && !isResultZero -> add(result)
|
|
||||||
size > 1 || !isResultZero -> this[0] = result
|
|
||||||
else -> clear()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Returns difference between the constant represented as polynomial and the polynomial.
|
* Returns difference between the constant represented as polynomial and the polynomial.
|
||||||
*/
|
*/
|
||||||
public override operator fun C.minus(other: Polynomial<C>): Polynomial<C> =
|
public operator fun C.minus(other: P): P
|
||||||
if (this.isZero()) other
|
|
||||||
else with(other.coefficients) {
|
|
||||||
if (isEmpty()) Polynomial(listOf(this@minus))
|
|
||||||
else Polynomial(
|
|
||||||
toMutableList()
|
|
||||||
.apply {
|
|
||||||
forEachIndexed { index, c -> if (index != 0) this[index] = -c }
|
|
||||||
|
|
||||||
val result = if (size == 0) this@minus else this@minus - get(0)
|
|
||||||
val isResultZero = result.isZero()
|
|
||||||
|
|
||||||
when {
|
|
||||||
size == 0 && !isResultZero -> add(result)
|
|
||||||
size > 1 || !isResultZero -> this[0] = result
|
|
||||||
else -> clear()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Returns product of the constant represented as polynomial and the polynomial.
|
* Returns product of the constant represented as polynomial and the polynomial.
|
||||||
*/
|
*/
|
||||||
public override operator fun C.times(other: Polynomial<C>): Polynomial<C> =
|
public operator fun C.times(other: P): P
|
||||||
if (this.isZero()) other
|
|
||||||
else Polynomial(
|
|
||||||
other.coefficients
|
|
||||||
.applyAndRemoveZeros {
|
|
||||||
for (deg in indices) this[deg] = this@times * this[deg]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns sum of the constant represented as polynomial and the polynomial.
|
* Returns sum of the constant represented as polynomial and the polynomial.
|
||||||
*/
|
*/
|
||||||
public override operator fun Polynomial<C>.plus(other: C): Polynomial<C> =
|
public operator fun P.plus(other: C): P
|
||||||
if (other.isZero()) this
|
|
||||||
else with(coefficients) {
|
|
||||||
if (isEmpty()) Polynomial(listOf(other))
|
|
||||||
else Polynomial(
|
|
||||||
toMutableList()
|
|
||||||
.apply {
|
|
||||||
val result = if (size == 0) other else get(0) + other
|
|
||||||
val isResultZero = result.isZero()
|
|
||||||
|
|
||||||
when {
|
|
||||||
size == 0 && !isResultZero -> add(result)
|
|
||||||
size > 1 || !isResultZero -> this[0] = result
|
|
||||||
else -> clear()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Returns difference between the constant represented as polynomial and the polynomial.
|
* Returns difference between the constant represented as polynomial and the polynomial.
|
||||||
*/
|
*/
|
||||||
public override operator fun Polynomial<C>.minus(other: C): Polynomial<C> =
|
public operator fun P.minus(other: C): P
|
||||||
if (other.isZero()) this
|
|
||||||
else with(coefficients) {
|
|
||||||
if (isEmpty()) Polynomial(listOf(-other))
|
|
||||||
else Polynomial(
|
|
||||||
toMutableList()
|
|
||||||
.apply {
|
|
||||||
val result = if (size == 0) other else get(0) - other
|
|
||||||
val isResultZero = result.isZero()
|
|
||||||
|
|
||||||
when {
|
|
||||||
size == 0 && !isResultZero -> add(result)
|
|
||||||
size > 1 || !isResultZero -> this[0] = result
|
|
||||||
else -> clear()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Returns product of the constant represented as polynomial and the polynomial.
|
* Returns product of the constant represented as polynomial and the polynomial.
|
||||||
*/
|
*/
|
||||||
public override operator fun Polynomial<C>.times(other: C): Polynomial<C> =
|
public operator fun P.times(other: C): P
|
||||||
if (other.isZero()) this
|
|
||||||
else Polynomial(
|
|
||||||
coefficients
|
|
||||||
.applyAndRemoveZeros {
|
|
||||||
for (deg in indices) this[deg] = this[deg] * other
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the same polynomial.
|
||||||
|
*/
|
||||||
|
public override operator fun P.unaryPlus(): P = this
|
||||||
/**
|
/**
|
||||||
* Returns negation of the polynomial.
|
* Returns negation of the polynomial.
|
||||||
*/
|
*/
|
||||||
public override operator fun Polynomial<C>.unaryMinus(): Polynomial<C> =
|
public override operator fun P.unaryMinus(): P
|
||||||
Polynomial(coefficients.map { -it })
|
|
||||||
/**
|
/**
|
||||||
* Returns sum of the polynomials.
|
* Returns sum of the polynomials.
|
||||||
*/
|
*/
|
||||||
public override operator fun Polynomial<C>.plus(other: Polynomial<C>): Polynomial<C> {
|
public override operator fun P.plus(other: P): P
|
||||||
val thisDegree = degree
|
|
||||||
val otherDegree = other.degree
|
|
||||||
return Polynomial(
|
|
||||||
Coefficients(max(thisDegree, otherDegree) + 1) {
|
|
||||||
when {
|
|
||||||
it > thisDegree -> other.coefficients[it]
|
|
||||||
it > otherDegree -> coefficients[it]
|
|
||||||
else -> coefficients[it] + other.coefficients[it]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Returns difference of the polynomials.
|
* Returns difference of the polynomials.
|
||||||
*/
|
*/
|
||||||
public override operator fun Polynomial<C>.minus(other: Polynomial<C>): Polynomial<C> {
|
public override operator fun P.minus(other: P): P
|
||||||
val thisDegree = degree
|
|
||||||
val otherDegree = other.degree
|
|
||||||
return Polynomial(
|
|
||||||
Coefficients(max(thisDegree, otherDegree) + 1) {
|
|
||||||
when {
|
|
||||||
it > thisDegree -> -other.coefficients[it]
|
|
||||||
it > otherDegree -> coefficients[it]
|
|
||||||
else -> coefficients[it] - other.coefficients[it]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Returns product of the polynomials.
|
* Returns product of the polynomials.
|
||||||
*/
|
*/
|
||||||
public override operator fun Polynomial<C>.times(other: Polynomial<C>): Polynomial<C> {
|
public override operator fun P.times(other: P): P
|
||||||
val thisDegree = degree
|
/**
|
||||||
val otherDegree = other.degree
|
* Raises [arg] to the integer power [exponent].
|
||||||
return when {
|
*/
|
||||||
thisDegree == -1 -> zero
|
public override fun power(arg: P, exponent: UInt) : P = exponentiationBySquaring(arg, exponent)
|
||||||
otherDegree == -1 -> zero
|
|
||||||
else ->
|
|
||||||
Polynomial(
|
|
||||||
Coefficients(thisDegree + otherDegree + 1) { d ->
|
|
||||||
(max(0, d - otherDegree)..min(thisDegree, d))
|
|
||||||
.map { coefficients[it] * other.coefficients[d - it] }
|
|
||||||
.reduce { acc, rational -> acc + rational }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the instant is zero polynomial.
|
* Check if the instant is zero polynomial.
|
||||||
*/
|
*/
|
||||||
public override fun Polynomial<C>.isZero(): Boolean = coefficients.all { it.isZero() }
|
public fun P.isZero(): Boolean = this equalsTo zero
|
||||||
|
/**
|
||||||
|
* Check if the instant is NOT zero polynomial.
|
||||||
|
*/
|
||||||
|
public fun P.isNotZero(): Boolean = !isZero()
|
||||||
/**
|
/**
|
||||||
* Check if the instant is unit polynomial.
|
* Check if the instant is unit polynomial.
|
||||||
*/
|
*/
|
||||||
public override fun Polynomial<C>.isOne(): Boolean =
|
public fun P.isOne(): Boolean = this equalsTo one
|
||||||
with(coefficients) {
|
/**
|
||||||
isNotEmpty() && withIndex().all { (index, c) -> if (index == 0) c.isOne() else c.isZero() }
|
* Check if the instant is NOT unit polynomial.
|
||||||
}
|
*/
|
||||||
|
public fun P.isNotOne(): Boolean = !isOne()
|
||||||
/**
|
/**
|
||||||
* Check if the instant is minus unit polynomial.
|
* Check if the instant is minus unit polynomial.
|
||||||
*/
|
*/
|
||||||
public override fun Polynomial<C>.isMinusOne(): Boolean =
|
public fun P.isMinusOne(): Boolean = this equalsTo -one
|
||||||
with(coefficients) {
|
/**
|
||||||
isNotEmpty() && withIndex().all { (index, c) -> if (index == 0) c.isMinusOne() else c.isZero() }
|
* Check if the instant is NOT minus unit polynomial.
|
||||||
}
|
*/
|
||||||
|
public fun P.isNotMinusOne(): Boolean = !isMinusOne()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instance of zero polynomial (zero of the polynomial ring).
|
* Instance of zero polynomial (zero of the polynomial ring).
|
||||||
*/
|
*/
|
||||||
override val zero: Polynomial<C> = Polynomial(emptyList())
|
public override val zero: P
|
||||||
/**
|
/**
|
||||||
* Instance of unit constant (unit of the underlying ring).
|
* Instance of unit polynomial (unit of the polynomial ring).
|
||||||
*/
|
*/
|
||||||
override val one: Polynomial<C> = Polynomial(listOf(constantOne))
|
public override val one: P
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks equality of the polynomials.
|
* Checks equality of the polynomials.
|
||||||
*/
|
*/
|
||||||
public override infix fun Polynomial<C>.equalsTo(other: Polynomial<C>): Boolean =
|
public infix fun P.equalsTo(other: P): Boolean
|
||||||
when {
|
/**
|
||||||
this === other -> true
|
* Checks NOT equality of the polynomials.
|
||||||
this.degree == other.degree -> (0..degree).all { coefficients[it] == other.coefficients[it] }
|
*/
|
||||||
else -> false
|
public infix fun P.notEqualsTo(other: P): Boolean = !(this equalsTo other)
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Degree of the polynomial, [see also](https://en.wikipedia.org/wiki/Degree_of_a_polynomial). If the polynomial is
|
* Degree of the polynomial, [see also](https://en.wikipedia.org/wiki/Degree_of_a_polynomial). If the polynomial is
|
||||||
* zero, degree is -1.
|
* zero, degree is -1.
|
||||||
*/
|
*/
|
||||||
public override val Polynomial<C>.degree: Int get() = coefficients.indexOfLast { it != constantZero }
|
public val P.degree: Int
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the instant is constant polynomial (of degree no more than 0) over considered ring.
|
||||||
|
*/
|
||||||
|
public fun P.isConstant(): Boolean = degree <= 0
|
||||||
|
/**
|
||||||
|
* Checks if the instant is **not** constant polynomial (of degree no more than 0) over considered ring.
|
||||||
|
*/
|
||||||
|
public fun P.isNotConstant(): Boolean = !isConstant()
|
||||||
|
/**
|
||||||
|
* Checks if the instant is constant non-zero polynomial (of degree no more than 0) over considered ring.
|
||||||
|
*/
|
||||||
|
public fun P.isNonZeroConstant(): Boolean = degree == 0
|
||||||
|
/**
|
||||||
|
* Checks if the instant is **not** constant non-zero polynomial (of degree no more than 0) over considered ring.
|
||||||
|
*/
|
||||||
|
public fun P.isNotNonZeroConstant(): Boolean = !isNonZeroConstant()
|
||||||
/**
|
/**
|
||||||
* If polynomial is a constant polynomial represents and returns it as constant.
|
* If polynomial is a constant polynomial represents and returns it as constant.
|
||||||
* Otherwise, (when the polynomial is not constant polynomial) returns `null`.
|
* Otherwise, (when the polynomial is not constant polynomial) returns `null`.
|
||||||
*/
|
*/
|
||||||
public override fun Polynomial<C>.asConstantOrNull(): C? =
|
public fun P.asConstantOrNull(): C?
|
||||||
with(coefficients) {
|
|
||||||
when {
|
|
||||||
isEmpty() -> constantZero
|
|
||||||
withIndex().all { (index, c) -> index == 0 || c.isZero() } -> first()
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
public inline fun Polynomial<C>.substitute(argument: C): C = this.substitute(ring, argument)
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
public inline fun Polynomial<C>.substitute(argument: Polynomial<C>): Polynomial<C> = this.substitute(ring, argument)
|
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
public inline fun Polynomial<C>.asFunction(): (C) -> C = { this.substitute(ring, it) }
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
public inline fun Polynomial<C>.asFunctionOnConstants(): (C) -> C = { this.substitute(ring, it) }
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
public inline fun Polynomial<C>.asFunctionOnPolynomials(): (Polynomial<C>) -> Polynomial<C> = { this.substitute(ring, it) }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluates the polynomial for the given value [argument].
|
* If polynomial is a constant polynomial represents and returns it as constant.
|
||||||
|
* Otherwise, (when the polynomial is not constant polynomial) raises corresponding exception.
|
||||||
*/
|
*/
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
public fun P.asConstant(): C = requireNotNull(asConstantOrNull()) { "Can not represent non-constant polynomial as a constant" }
|
||||||
public inline operator fun Polynomial<C>.invoke(argument: C): C = this.substitute(ring, argument)
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
|
||||||
public inline operator fun Polynomial<C>.invoke(argument: Polynomial<C>): Polynomial<C> = this.substitute(ring, argument)
|
|
||||||
|
|
||||||
// TODO: Move to other internal utilities with context receiver
|
override fun add(left: P, right: P): P = left + right
|
||||||
@JvmName("applyAndRemoveZerosInternal")
|
override fun multiply(left: P, right: P): P = left * right
|
||||||
internal inline fun MutableList<C>.applyAndRemoveZeros(block: MutableList<C>.() -> Unit) : MutableList<C> {
|
|
||||||
contract {
|
|
||||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
|
||||||
}
|
|
||||||
block()
|
|
||||||
while (isNotEmpty() && elementAt(lastIndex).isZero()) removeAt(lastIndex)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
internal inline fun List<C>.applyAndRemoveZeros(block: MutableList<C>.() -> Unit) : List<C> =
|
|
||||||
toMutableList().applyAndRemoveZeros(block)
|
|
||||||
@Suppress("FunctionName")
|
|
||||||
internal inline fun MutableCoefficients(size: Int, init: (index: Int) -> C): MutableList<C> {
|
|
||||||
val list = ArrayList<C>(size)
|
|
||||||
repeat(size) { index -> list.add(init(index)) }
|
|
||||||
with(list) { while (isNotEmpty() && elementAt(lastIndex).isZero()) removeAt(lastIndex) }
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
@Suppress("FunctionName")
|
|
||||||
internal inline fun Coefficients(size: Int, init: (index: Int) -> C): List<C> = MutableCoefficients(size, init)
|
|
||||||
@OptIn(ExperimentalTypeInference::class)
|
|
||||||
internal inline fun buildCoefficients(@BuilderInference builderAction: MutableList<C>.() -> Unit): List<C> {
|
|
||||||
contract { callsInPlace(builderAction, InvocationKind.EXACTLY_ONCE) }
|
|
||||||
return buildList {
|
|
||||||
builderAction()
|
|
||||||
while (isNotEmpty() && elementAt(lastIndex).isZero()) removeAt(lastIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@OptIn(ExperimentalTypeInference::class)
|
|
||||||
internal inline fun buildCoefficients(capacity: Int, @BuilderInference builderAction: MutableList<C>.() -> Unit): List<C> {
|
|
||||||
contract { callsInPlace(builderAction, InvocationKind.EXACTLY_ONCE) }
|
|
||||||
return buildList(capacity) {
|
|
||||||
builderAction()
|
|
||||||
while (isNotEmpty() && elementAt(lastIndex).isZero()) removeAt(lastIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Space of polynomials constructed over ring.
|
* 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 A type of underlying ring of constants. It's [Ring] of [C].
|
* @param P the type of polynomials.
|
||||||
* @param ring underlying ring of constants of type [A].
|
* @param A the type of algebraic structure (precisely, of ring) provided for constants.
|
||||||
*/
|
*/
|
||||||
public class ScalablePolynomialSpace<C, A>(
|
@Suppress("INAPPLICABLE_JVM_NAME")
|
||||||
ring: A,
|
public interface PolynomialSpaceOverRing<C, P: Polynomial<C>, A: Ring<C>> : PolynomialSpace<C, P> {
|
||||||
) : PolynomialSpace<C, A>(ring), ScaleOperations<Polynomial<C>> where A : Ring<C>, A : ScaleOperations<C> {
|
|
||||||
override fun scale(a: Polynomial<C>, value: Double): Polynomial<C> =
|
public val ring: A
|
||||||
ring { Polynomial(a.coefficients.map { scale(it, value) }) }
|
|
||||||
}
|
/**
|
||||||
|
* Returns sum of the constant and the integer represented as constant (member of underlying ring).
|
||||||
|
*
|
||||||
|
* The operation is equivalent to adding [other] copies of unit of underlying ring to [this].
|
||||||
|
*/
|
||||||
|
public override operator fun C.plus(other: Int): C = ring { addMultipliedBySquaring(this@plus, one, other) }
|
||||||
|
/**
|
||||||
|
* Returns difference between the constant and the integer represented as constant (member of underlying ring).
|
||||||
|
*
|
||||||
|
* The operation is equivalent to subtraction [other] copies of unit of underlying ring from [this].
|
||||||
|
*/
|
||||||
|
public override operator fun C.minus(other: Int): C = ring { addMultipliedBySquaring(this@minus, one, -other) }
|
||||||
|
/**
|
||||||
|
* Returns product of the constant and the integer represented as constant (member of underlying ring).
|
||||||
|
*
|
||||||
|
* The operation is equivalent to sum of [other] copies of [this].
|
||||||
|
*/
|
||||||
|
public override operator fun C.times(other: Int): C = ring { multiplyBySquaring(this@times, other) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns sum of the integer represented as constant (member of underlying ring) and the constant.
|
||||||
|
*
|
||||||
|
* The operation is equivalent to adding [this] copies of unit of underlying ring to [other].
|
||||||
|
*/
|
||||||
|
public override operator fun Int.plus(other: C): C = ring { addMultipliedBySquaring(other, one, this@plus) }
|
||||||
|
/**
|
||||||
|
* Returns difference between the integer represented as constant (member of underlying ring) and the constant.
|
||||||
|
*
|
||||||
|
* The operation is equivalent to subtraction [this] copies of unit of underlying ring from [other].
|
||||||
|
*/
|
||||||
|
public override operator fun Int.minus(other: C): C = ring { addMultipliedBySquaring(-other, one, this@minus) }
|
||||||
|
/**
|
||||||
|
* Returns product of the integer represented as constant (member of underlying ring) and the constant.
|
||||||
|
*
|
||||||
|
* The operation is equivalent to sum of [this] copies of [other].
|
||||||
|
*/
|
||||||
|
public override operator fun Int.times(other: C): C = ring { multiplyBySquaring(other, this@times) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns negation of the constant.
|
||||||
|
*/
|
||||||
|
@JvmName("constantUnaryMinus")
|
||||||
|
public override operator fun C.unaryMinus(): C = ring { -this@unaryMinus }
|
||||||
|
/**
|
||||||
|
* Returns sum of the constants.
|
||||||
|
*/
|
||||||
|
@JvmName("constantPlus")
|
||||||
|
public override operator fun C.plus(other: C): C = ring { this@plus + other }
|
||||||
|
/**
|
||||||
|
* Returns difference of the constants.
|
||||||
|
*/
|
||||||
|
@JvmName("constantMinus")
|
||||||
|
public override operator fun C.minus(other: C): C = ring { this@minus - other }
|
||||||
|
/**
|
||||||
|
* Returns product of the constants.
|
||||||
|
*/
|
||||||
|
@JvmName("constantTimes")
|
||||||
|
public override operator fun C.times(other: C): C = ring { this@times * other }
|
||||||
|
/**
|
||||||
|
* Raises [arg] to the integer power [exponent].
|
||||||
|
*/
|
||||||
|
@JvmName("constantPower")
|
||||||
|
override fun power(arg: C, exponent: UInt): C = ring { power(arg, exponent) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of zero constant (zero of the underlying ring).
|
||||||
|
*/
|
||||||
|
public override val constantZero: C get() = ring.zero
|
||||||
|
/**
|
||||||
|
* Instance of unit constant (unit of the underlying ring).
|
||||||
|
*/
|
||||||
|
public override val constantOne: C get() = ring.one
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,7 @@ public fun <C, A : Ring<C>> A.labeledRationalFunction(): LabeledRationalFunction
|
|||||||
LabeledRationalFunctionSpace(this)
|
LabeledRationalFunctionSpace(this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a [RationalFunctionSpace]'s scope over a received ring.
|
* Creates a [LabeledRationalFunctionSpace]'s scope over a received ring.
|
||||||
*/
|
*/
|
||||||
public inline fun <C, A : Ring<C>, R> A.labeledRationalFunction(block: LabeledRationalFunctionSpace<C, A>.() -> R): R {
|
public inline fun <C, A : Ring<C>, R> A.labeledRationalFunction(block: LabeledRationalFunctionSpace<C, A>.() -> R): R {
|
||||||
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
||||||
|
@ -22,31 +22,31 @@ import kotlin.math.pow
|
|||||||
// if (degree > -1) Polynomial(coefficients.subList(0, degree + 1)) else zero
|
// if (degree > -1) Polynomial(coefficients.subList(0, degree + 1)) else zero
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a [PolynomialSpace] over a received ring.
|
* Creates a [ListPolynomialSpace] over a received ring.
|
||||||
*/
|
*/
|
||||||
public fun <C, A : Ring<C>> A.polynomial(): PolynomialSpace<C, A> =
|
public fun <C, A : Ring<C>> A.listPolynomial(): ListPolynomialSpace<C, A> =
|
||||||
PolynomialSpace(this)
|
ListPolynomialSpace(this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a [PolynomialSpace]'s scope over a received ring.
|
* Creates a [ListPolynomialSpace]'s scope over a received ring.
|
||||||
*/
|
*/
|
||||||
public inline fun <C, A : Ring<C>, R> A.polynomial(block: PolynomialSpace<C, A>.() -> R): R {
|
public inline fun <C, A : Ring<C>, R> A.listPolynomial(block: ListPolynomialSpace<C, A>.() -> R): R {
|
||||||
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
||||||
return PolynomialSpace(this).block()
|
return ListPolynomialSpace(this).block()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a [ScalablePolynomialSpace] over a received scalable ring.
|
* Creates a [ScalableListPolynomialSpace] over a received scalable ring.
|
||||||
*/
|
*/
|
||||||
public fun <C, A> A.scalablePolynomial(): ScalablePolynomialSpace<C, A> where A : Ring<C>, A : ScaleOperations<C> =
|
public fun <C, A> A.scalableListPolynomial(): ScalableListPolynomialSpace<C, A> where A : Ring<C>, A : ScaleOperations<C> =
|
||||||
ScalablePolynomialSpace(this)
|
ScalableListPolynomialSpace(this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a [ScalablePolynomialSpace]'s scope over a received scalable ring.
|
* Creates a [ScalableListPolynomialSpace]'s scope over a received scalable ring.
|
||||||
*/
|
*/
|
||||||
public inline fun <C, A, R> A.scalablePolynomial(block: ScalablePolynomialSpace<C, A>.() -> R): R where A : Ring<C>, A : ScaleOperations<C> {
|
public inline fun <C, A, R> A.scalableListPolynomial(block: ScalableListPolynomialSpace<C, A>.() -> R): R where A : Ring<C>, A : ScaleOperations<C> {
|
||||||
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
||||||
return ScalablePolynomialSpace(this).block()
|
return ScalableListPolynomialSpace(this).block()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
@ -99,7 +99,7 @@ internal inline fun <C> multiplyAddingTo(
|
|||||||
/**
|
/**
|
||||||
* Evaluates the value of the given double polynomial for given double argument.
|
* Evaluates the value of the given double polynomial for given double argument.
|
||||||
*/
|
*/
|
||||||
public fun Polynomial<Double>.substitute(arg: Double): Double =
|
public fun ListPolynomial<Double>.substitute(arg: Double): Double =
|
||||||
coefficients.reduceIndexedOrNull { index, acc, c ->
|
coefficients.reduceIndexedOrNull { index, acc, c ->
|
||||||
acc + c * arg.pow(index)
|
acc + c * arg.pow(index)
|
||||||
} ?: .0
|
} ?: .0
|
||||||
@ -109,7 +109,7 @@ public fun Polynomial<Double>.substitute(arg: Double): Double =
|
|||||||
*
|
*
|
||||||
* It is an implementation of [Horner's method](https://en.wikipedia.org/wiki/Horner%27s_method).
|
* It is an implementation of [Horner's method](https://en.wikipedia.org/wiki/Horner%27s_method).
|
||||||
*/
|
*/
|
||||||
public fun <C> Polynomial<C>.substitute(ring: Ring<C>, arg: C): C = ring {
|
public fun <C> ListPolynomial<C>.substitute(ring: Ring<C>, arg: C): C = ring {
|
||||||
if (coefficients.isEmpty()) return@ring zero
|
if (coefficients.isEmpty()) return@ring zero
|
||||||
var result: C = coefficients.last()
|
var result: C = coefficients.last()
|
||||||
for (j in coefficients.size - 2 downTo 0) {
|
for (j in coefficients.size - 2 downTo 0) {
|
||||||
@ -118,11 +118,11 @@ public fun <C> Polynomial<C>.substitute(ring: Ring<C>, arg: C): C = ring {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun <C> Polynomial<C>.substitute(ring: Ring<C>, arg: Polynomial<C>) : Polynomial<C> = ring {
|
public fun <C> ListPolynomial<C>.substitute(ring: Ring<C>, arg: ListPolynomial<C>) : ListPolynomial<C> = ring {
|
||||||
if (coefficients.isEmpty()) return Polynomial(emptyList())
|
if (coefficients.isEmpty()) return ListPolynomial(emptyList())
|
||||||
|
|
||||||
val thisDegree = coefficients.indexOfLast { it != zero }
|
val thisDegree = coefficients.indexOfLast { it != zero }
|
||||||
if (thisDegree == -1) return Polynomial(emptyList())
|
if (thisDegree == -1) return ListPolynomial(emptyList())
|
||||||
val argDegree = arg.coefficients.indexOfLast { it != zero }
|
val argDegree = arg.coefficients.indexOfLast { it != zero }
|
||||||
if (argDegree == -1) return coefficients[0].asPolynomial()
|
if (argDegree == -1) return coefficients[0].asPolynomial()
|
||||||
val constantZero = zero
|
val constantZero = zero
|
||||||
@ -145,27 +145,27 @@ public fun <C> Polynomial<C>.substitute(ring: Ring<C>, arg: Polynomial<C>) : Pol
|
|||||||
}
|
}
|
||||||
|
|
||||||
with(resultCoefs) { while (isNotEmpty() && elementAt(lastIndex) == constantZero) removeAt(lastIndex) }
|
with(resultCoefs) { while (isNotEmpty() && elementAt(lastIndex) == constantZero) removeAt(lastIndex) }
|
||||||
return Polynomial<C>(resultCoefs)
|
return ListPolynomial<C>(resultCoefs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represent the polynomial as a regular context-less function.
|
* Represent the polynomial as a regular context-less function.
|
||||||
*/
|
*/
|
||||||
public fun <C, A : Ring<C>> Polynomial<C>.asFunction(ring: A): (C) -> C = { substitute(ring, it) }
|
public fun <C, A : Ring<C>> ListPolynomial<C>.asFunction(ring: A): (C) -> C = { substitute(ring, it) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represent the polynomial as a regular context-less function.
|
* Represent the polynomial as a regular context-less function.
|
||||||
*/
|
*/
|
||||||
public fun <C, A : Ring<C>> Polynomial<C>.asPolynomialFunctionOver(ring: A): (Polynomial<C>) -> Polynomial<C> = { substitute(ring, it) }
|
public fun <C, A : Ring<C>> ListPolynomial<C>.asPolynomialFunctionOver(ring: A): (ListPolynomial<C>) -> ListPolynomial<C> = { substitute(ring, it) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns algebraic derivative of received polynomial.
|
* Returns algebraic derivative of received polynomial.
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public fun <C, A> Polynomial<C>.derivative(
|
public fun <C, A> ListPolynomial<C>.derivative(
|
||||||
algebra: A,
|
algebra: A,
|
||||||
): Polynomial<C> where A : Ring<C>, A : NumericAlgebra<C> = algebra {
|
): ListPolynomial<C> where A : Ring<C>, A : NumericAlgebra<C> = algebra {
|
||||||
Polynomial(
|
ListPolynomial(
|
||||||
buildList(max(0, coefficients.size - 1)) {
|
buildList(max(0, coefficients.size - 1)) {
|
||||||
for (deg in 1 .. coefficients.lastIndex) add(number(deg) * coefficients[deg])
|
for (deg in 1 .. coefficients.lastIndex) add(number(deg) * coefficients[deg])
|
||||||
while (isNotEmpty() && elementAt(lastIndex) == algebra.zero) removeAt(lastIndex)
|
while (isNotEmpty() && elementAt(lastIndex) == algebra.zero) removeAt(lastIndex)
|
||||||
@ -177,12 +177,12 @@ public fun <C, A> Polynomial<C>.derivative(
|
|||||||
* Returns algebraic derivative of received polynomial.
|
* Returns algebraic derivative of received polynomial.
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public fun <C, A> Polynomial<C>.nthDerivative(
|
public fun <C, A> ListPolynomial<C>.nthDerivative(
|
||||||
algebra: A,
|
algebra: A,
|
||||||
order: Int,
|
order: Int,
|
||||||
): Polynomial<C> where A : Ring<C>, A : NumericAlgebra<C> = algebra {
|
): ListPolynomial<C> where A : Ring<C>, A : NumericAlgebra<C> = algebra {
|
||||||
require(order >= 0) { "Order of derivative must be non-negative" }
|
require(order >= 0) { "Order of derivative must be non-negative" }
|
||||||
Polynomial(
|
ListPolynomial(
|
||||||
buildList(max(0, coefficients.size - order)) {
|
buildList(max(0, coefficients.size - order)) {
|
||||||
for (deg in order.. coefficients.lastIndex)
|
for (deg in order.. coefficients.lastIndex)
|
||||||
add((deg - order + 1 .. deg).fold(coefficients[deg]) { acc, d -> acc * number(d) })
|
add((deg - order + 1 .. deg).fold(coefficients[deg]) { acc, d -> acc * number(d) })
|
||||||
@ -195,10 +195,10 @@ public fun <C, A> Polynomial<C>.nthDerivative(
|
|||||||
* Returns algebraic antiderivative of received polynomial.
|
* Returns algebraic antiderivative of received polynomial.
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public fun <C, A> Polynomial<C>.antiderivative(
|
public fun <C, A> ListPolynomial<C>.antiderivative(
|
||||||
algebra: A,
|
algebra: A,
|
||||||
): Polynomial<C> where A : Field<C>, A : NumericAlgebra<C> = algebra {
|
): ListPolynomial<C> where A : Field<C>, A : NumericAlgebra<C> = algebra {
|
||||||
Polynomial(
|
ListPolynomial(
|
||||||
buildList(coefficients.size + 1) {
|
buildList(coefficients.size + 1) {
|
||||||
add(zero)
|
add(zero)
|
||||||
coefficients.mapIndexedTo(this) { index, t -> t / number(index + 1) }
|
coefficients.mapIndexedTo(this) { index, t -> t / number(index + 1) }
|
||||||
@ -211,12 +211,12 @@ public fun <C, A> Polynomial<C>.antiderivative(
|
|||||||
* Returns algebraic antiderivative of received polynomial.
|
* Returns algebraic antiderivative of received polynomial.
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public fun <C, A> Polynomial<C>.nthAntiderivative(
|
public fun <C, A> ListPolynomial<C>.nthAntiderivative(
|
||||||
algebra: A,
|
algebra: A,
|
||||||
order: Int,
|
order: Int,
|
||||||
): Polynomial<C> where A : Field<C>, A : NumericAlgebra<C> = algebra {
|
): ListPolynomial<C> where A : Field<C>, A : NumericAlgebra<C> = algebra {
|
||||||
require(order >= 0) { "Order of antiderivative must be non-negative" }
|
require(order >= 0) { "Order of antiderivative must be non-negative" }
|
||||||
Polynomial(
|
ListPolynomial(
|
||||||
buildList(coefficients.size + order) {
|
buildList(coefficients.size + order) {
|
||||||
repeat(order) { add(zero) }
|
repeat(order) { add(zero) }
|
||||||
coefficients.mapIndexedTo(this) { index, c -> (1..order).fold(c) { acc, i -> acc / number(index + i) } }
|
coefficients.mapIndexedTo(this) { index, c -> (1..order).fold(c) { acc, i -> acc / number(index + i) } }
|
||||||
@ -229,7 +229,7 @@ public fun <C, A> Polynomial<C>.nthAntiderivative(
|
|||||||
* Compute a definite integral of a given polynomial in a [range]
|
* Compute a definite integral of a given polynomial in a [range]
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public fun <C : Comparable<C>> Polynomial<C>.integrate(
|
public fun <C : Comparable<C>> ListPolynomial<C>.integrate(
|
||||||
algebra: Field<C>,
|
algebra: Field<C>,
|
||||||
range: ClosedRange<C>,
|
range: ClosedRange<C>,
|
||||||
): C = algebra {
|
): C = algebra {
|
@ -14,23 +14,23 @@ import kotlin.math.max
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a [RationalFunctionSpace] over a received ring.
|
* Creates a [ListRationalFunctionSpace] over a received ring.
|
||||||
*/
|
*/
|
||||||
public fun <C, A : Ring<C>> A.rationalFunction(): RationalFunctionSpace<C, A> =
|
public fun <C, A : Ring<C>> A.listRationalFunction(): ListRationalFunctionSpace<C, A> =
|
||||||
RationalFunctionSpace(this)
|
ListRationalFunctionSpace(this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a [RationalFunctionSpace]'s scope over a received ring.
|
* Creates a [ListRationalFunctionSpace]'s scope over a received ring.
|
||||||
*/
|
*/
|
||||||
public inline fun <C, A : Ring<C>, R> A.rationalFunction(block: RationalFunctionSpace<C, A>.() -> R): R {
|
public inline fun <C, A : Ring<C>, R> A.listRationalFunction(block: ListRationalFunctionSpace<C, A>.() -> R): R {
|
||||||
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
||||||
return RationalFunctionSpace(this).block()
|
return ListRationalFunctionSpace(this).block()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluates the value of the given double polynomial for given double argument.
|
* Evaluates the value of the given double polynomial for given double argument.
|
||||||
*/
|
*/
|
||||||
public fun RationalFunction<Double>.substitute(arg: Double): Double =
|
public fun ListRationalFunction<Double>.substitute(arg: Double): Double =
|
||||||
numerator.substitute(arg) / denominator.substitute(arg)
|
numerator.substitute(arg) / denominator.substitute(arg)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,7 +38,7 @@ public fun RationalFunction<Double>.substitute(arg: Double): Double =
|
|||||||
*
|
*
|
||||||
* It is an implementation of [Horner's method](https://en.wikipedia.org/wiki/Horner%27s_method).
|
* It is an implementation of [Horner's method](https://en.wikipedia.org/wiki/Horner%27s_method).
|
||||||
*/
|
*/
|
||||||
public fun <C> RationalFunction<C>.substitute(ring: Field<C>, arg: C): C = ring {
|
public fun <C> ListRationalFunction<C>.substitute(ring: Field<C>, arg: C): C = ring {
|
||||||
numerator.substitute(ring, arg) / denominator.substitute(ring, arg)
|
numerator.substitute(ring, arg) / denominator.substitute(ring, arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,13 +50,13 @@ public fun <C> RationalFunction<C>.substitute(ring: Field<C>, arg: C): C = ring
|
|||||||
* ```
|
* ```
|
||||||
* is returned.
|
* is returned.
|
||||||
*
|
*
|
||||||
* Used in [Polynomial.substitute] and [RationalFunction.substitute] for performance optimisation.
|
* Used in [ListPolynomial.substitute] and [ListRationalFunction.substitute] for performance optimisation.
|
||||||
*/ // TODO: Дописать
|
*/ // TODO: Дописать
|
||||||
internal fun <C> Polynomial<C>.substituteRationalFunctionTakeNumerator(ring: Ring<C>, arg: RationalFunction<C>): Polynomial<C> = ring {
|
internal fun <C> ListPolynomial<C>.substituteRationalFunctionTakeNumerator(ring: Ring<C>, arg: ListRationalFunction<C>): ListPolynomial<C> = ring {
|
||||||
if (coefficients.isEmpty()) return Polynomial(emptyList())
|
if (coefficients.isEmpty()) return ListPolynomial(emptyList())
|
||||||
|
|
||||||
val thisDegree = coefficients.indexOfLast { it != zero }
|
val thisDegree = coefficients.indexOfLast { it != zero }
|
||||||
if (thisDegree == -1) return Polynomial(emptyList())
|
if (thisDegree == -1) return ListPolynomial(emptyList())
|
||||||
val thisDegreeLog2 = 31 - thisDegree.countLeadingZeroBits()
|
val thisDegreeLog2 = 31 - thisDegree.countLeadingZeroBits()
|
||||||
val numeratorDegree = arg.numerator.coefficients.indexOfLast { it != zero }
|
val numeratorDegree = arg.numerator.coefficients.indexOfLast { it != zero }
|
||||||
val denominatorDegree = arg.denominator.coefficients.indexOfLast { it != zero }
|
val denominatorDegree = arg.denominator.coefficients.indexOfLast { it != zero }
|
||||||
@ -189,7 +189,7 @@ internal fun <C> Polynomial<C>.substituteRationalFunctionTakeNumerator(ring: Rin
|
|||||||
return levelResultCoefs
|
return levelResultCoefs
|
||||||
}
|
}
|
||||||
|
|
||||||
return Polynomial(
|
return ListPolynomial(
|
||||||
processLevelEdged(
|
processLevelEdged(
|
||||||
level = thisDegreeLog2,
|
level = thisDegreeLog2,
|
||||||
start = 0,
|
start = 0,
|
@ -17,7 +17,7 @@ public fun <C, A : Ring<C>> A.numberedRationalFunction(): NumberedRationalFuncti
|
|||||||
NumberedRationalFunctionSpace(this)
|
NumberedRationalFunctionSpace(this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a [RationalFunctionSpace]'s scope over a received ring.
|
* Creates a [NumberedRationalFunctionSpace]'s scope over a received ring.
|
||||||
*/
|
*/
|
||||||
public inline fun <C, A : Ring<C>, R> A.numberedRationalFunction(block: NumberedRationalFunctionSpace<C, A>.() -> R): R {
|
public inline fun <C, A : Ring<C>, R> A.numberedRationalFunction(block: NumberedRationalFunctionSpace<C, A>.() -> R): R {
|
||||||
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
||||||
|
@ -7,7 +7,7 @@ package space.kscience.kmath.interpolation
|
|||||||
|
|
||||||
import space.kscience.kmath.data.XYColumnarData
|
import space.kscience.kmath.data.XYColumnarData
|
||||||
import space.kscience.kmath.functions.PiecewisePolynomial
|
import space.kscience.kmath.functions.PiecewisePolynomial
|
||||||
import space.kscience.kmath.functions.Polynomial
|
import space.kscience.kmath.functions.ListPolynomial
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.operations.Field
|
import space.kscience.kmath.operations.Field
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
@ -32,7 +32,7 @@ public class LinearInterpolator<T : Comparable<T>>(override val algebra: Field<T
|
|||||||
for (i in 0 until points.size - 1) {
|
for (i in 0 until points.size - 1) {
|
||||||
val slope = (points.y[i + 1] - points.y[i]) / (points.x[i + 1] - points.x[i])
|
val slope = (points.y[i + 1] - points.y[i]) / (points.x[i + 1] - points.x[i])
|
||||||
val const = points.y[i] - slope * points.x[i]
|
val const = points.y[i] - slope * points.x[i]
|
||||||
val polynomial = Polynomial(const, slope)
|
val polynomial = ListPolynomial(const, slope)
|
||||||
putRight(points.x[i + 1], polynomial)
|
putRight(points.x[i + 1], polynomial)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ package space.kscience.kmath.interpolation
|
|||||||
|
|
||||||
import space.kscience.kmath.data.XYColumnarData
|
import space.kscience.kmath.data.XYColumnarData
|
||||||
import space.kscience.kmath.functions.PiecewisePolynomial
|
import space.kscience.kmath.functions.PiecewisePolynomial
|
||||||
import space.kscience.kmath.functions.Polynomial
|
import space.kscience.kmath.functions.ListPolynomial
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.operations.DoubleField
|
import space.kscience.kmath.operations.DoubleField
|
||||||
import space.kscience.kmath.operations.Field
|
import space.kscience.kmath.operations.Field
|
||||||
@ -61,7 +61,7 @@ public class SplineInterpolator<T : Comparable<T>>(
|
|||||||
val x02 = x0 * x0
|
val x02 = x0 * x0
|
||||||
val x03 = x02 * x0
|
val x03 = x02 * x0
|
||||||
//Shift coefficients to represent absolute polynomial instead of one with an offset
|
//Shift coefficients to represent absolute polynomial instead of one with an offset
|
||||||
val polynomial = Polynomial(
|
val polynomial = ListPolynomial(
|
||||||
a - b * x0 + c * x02 - d * x03,
|
a - b * x0 + c * x02 - d * x03,
|
||||||
b - 2 * c * x0 + 3 * d * x02,
|
b - 2 * c * x0 + 3 * d * x02,
|
||||||
c - 3 * d * x0,
|
c - 3 * d * x0,
|
||||||
|
@ -0,0 +1,705 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018-2021 KMath contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package space.kscience.kmath.functions
|
||||||
|
|
||||||
|
import space.kscience.kmath.test.misc.*
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
|
||||||
|
class ListPolynomialTest {
|
||||||
|
@Test
|
||||||
|
fun test_Polynomial_Int_plus() {
|
||||||
|
RationalField.listPolynomial {
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-22, 9), Rational(-8, 9), Rational(-8, 7)),
|
||||||
|
ListPolynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)) + -3,
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(0), Rational(0)),
|
||||||
|
ListPolynomial(Rational(-2), Rational(0), Rational(0), Rational(0)) + 2,
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
ListPolynomial(Rational(-2)) + 2,
|
||||||
|
"test 3"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
ListPolynomial<Rational>() + 0,
|
||||||
|
"test 4"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-1), Rational(0), Rational(0), Rational(0)),
|
||||||
|
ListPolynomial(Rational(-2), Rational(0), Rational(0), Rational(0)) + 1,
|
||||||
|
"test 5"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-1)),
|
||||||
|
ListPolynomial(Rational(-2)) + 1,
|
||||||
|
"test 6"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(2)),
|
||||||
|
ListPolynomial<Rational>() + 2,
|
||||||
|
"test 7"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Polynomial_Int_minus() {
|
||||||
|
RationalField.listPolynomial {
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(32, 9), Rational(-8, 9), Rational(-8, 7)),
|
||||||
|
ListPolynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)) - -3,
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(0), Rational(0)),
|
||||||
|
ListPolynomial(Rational(2), Rational(0), Rational(0), Rational(0)) - 2,
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
ListPolynomial(Rational(2)) - 2,
|
||||||
|
"test 3"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
ListPolynomial<Rational>() - 0,
|
||||||
|
"test 4"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(1), Rational(0), Rational(0), Rational(0)),
|
||||||
|
ListPolynomial(Rational(2), Rational(0), Rational(0), Rational(0)) - 1,
|
||||||
|
"test 5"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(1)),
|
||||||
|
ListPolynomial(Rational(2)) - 1,
|
||||||
|
"test 6"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-2)),
|
||||||
|
ListPolynomial<Rational>() - 2,
|
||||||
|
"test 7"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Polynomial_Int_times() {
|
||||||
|
IntModuloRing(35).listPolynomial {
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(34, 2, 1, 20, 2),
|
||||||
|
ListPolynomial(22, 26, 13, 15, 26) * 27,
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
ListPolynomial(7, 0, 49, 21, 14) * 15,
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Int_Polynomial_plus() {
|
||||||
|
RationalField.listPolynomial {
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-22, 9), Rational(-8, 9), Rational(-8, 7)),
|
||||||
|
-3 + ListPolynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(0), Rational(0)),
|
||||||
|
2 + ListPolynomial(Rational(-2), Rational(0), Rational(0), Rational(0)),
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
2 + ListPolynomial(Rational(-2)),
|
||||||
|
"test 3"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
0 + ListPolynomial(),
|
||||||
|
"test 4"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-1), Rational(0), Rational(0), Rational(0)),
|
||||||
|
1 + ListPolynomial(Rational(-2), Rational(0), Rational(0), Rational(0)),
|
||||||
|
"test 5"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-1)),
|
||||||
|
1 + ListPolynomial(Rational(-2)),
|
||||||
|
"test 6"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(2)),
|
||||||
|
2 + ListPolynomial(),
|
||||||
|
"test 7"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Int_Polynomial_minus() {
|
||||||
|
RationalField.listPolynomial {
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(32, 9), Rational(-8, 9), Rational(-8, 7)),
|
||||||
|
3 - ListPolynomial(Rational(-5, 9), Rational(8, 9), Rational(8, 7)),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(0), Rational(0)),
|
||||||
|
-2 - ListPolynomial(Rational(-2), Rational(0), Rational(0), Rational(0)),
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
-2 - ListPolynomial(Rational(-2)),
|
||||||
|
"test 3"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
0 - ListPolynomial(),
|
||||||
|
"test 4"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(1), Rational(0), Rational(0), Rational(0)),
|
||||||
|
-1 - ListPolynomial(Rational(-2), Rational(0), Rational(0), Rational(0)),
|
||||||
|
"test 5"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(1)),
|
||||||
|
-1 - ListPolynomial(Rational(-2)),
|
||||||
|
"test 6"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-2)),
|
||||||
|
-2 - ListPolynomial(),
|
||||||
|
"test 7"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Int_Polynomial_times() {
|
||||||
|
IntModuloRing(35).listPolynomial {
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(34, 2, 1, 20, 2),
|
||||||
|
27 * ListPolynomial(22, 26, 13, 15, 26),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
15 * ListPolynomial(7, 0, 49, 21, 14),
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Polynomial_Constant_plus() {
|
||||||
|
RationalField.listPolynomial {
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-22, 9), Rational(-8, 9), Rational(-8, 7)),
|
||||||
|
ListPolynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)) + Rational(-3),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(0), Rational(0)),
|
||||||
|
ListPolynomial(Rational(-2), Rational(0), Rational(0), Rational(0)) + Rational(2),
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
ListPolynomial(Rational(-2)) + Rational(2),
|
||||||
|
"test 3"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
ListPolynomial<Rational>() + Rational(0),
|
||||||
|
"test 4"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-1), Rational(0), Rational(0), Rational(0)),
|
||||||
|
ListPolynomial(Rational(-2), Rational(0), Rational(0), Rational(0)) + Rational(1),
|
||||||
|
"test 5"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-1)),
|
||||||
|
ListPolynomial(Rational(-2)) + Rational(1),
|
||||||
|
"test 6"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(2)),
|
||||||
|
ListPolynomial<Rational>() + Rational(2),
|
||||||
|
"test 7"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Polynomial_Constant_minus() {
|
||||||
|
RationalField.listPolynomial {
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(32, 9), Rational(-8, 9), Rational(-8, 7)),
|
||||||
|
ListPolynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)) - Rational(-3),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(0), Rational(0)),
|
||||||
|
ListPolynomial(Rational(2), Rational(0), Rational(0), Rational(0)) - Rational(2),
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
ListPolynomial(Rational(2)) - Rational(2),
|
||||||
|
"test 3"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
ListPolynomial<Rational>() - Rational(0),
|
||||||
|
"test 4"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(1), Rational(0), Rational(0), Rational(0)),
|
||||||
|
ListPolynomial(Rational(2), Rational(0), Rational(0), Rational(0)) - Rational(1),
|
||||||
|
"test 5"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(1)),
|
||||||
|
ListPolynomial(Rational(2)) - Rational(1),
|
||||||
|
"test 6"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-2)),
|
||||||
|
ListPolynomial<Rational>() - Rational(2),
|
||||||
|
"test 7"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Polynomial_Constant_times() {
|
||||||
|
IntModuloRing(35).listPolynomial {
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(34, 2, 1, 20, 2),
|
||||||
|
ListPolynomial(22, 26, 13, 15, 26) * number(27),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
ListPolynomial(7, 0, 49, 21, 14) * number(15),
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Constant_Polynomial_plus() {
|
||||||
|
RationalField.listPolynomial {
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-22, 9), Rational(-8, 9), Rational(-8, 7)),
|
||||||
|
Rational(-3) + ListPolynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(0), Rational(0)),
|
||||||
|
Rational(2) + ListPolynomial(Rational(-2), Rational(0), Rational(0), Rational(0)),
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
Rational(2) + ListPolynomial(Rational(-2)),
|
||||||
|
"test 3"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
Rational(0) + ListPolynomial(),
|
||||||
|
"test 4"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-1), Rational(0), Rational(0), Rational(0)),
|
||||||
|
Rational(1) + ListPolynomial(Rational(-2), Rational(0), Rational(0), Rational(0)),
|
||||||
|
"test 5"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-1)),
|
||||||
|
Rational(1) + ListPolynomial(Rational(-2)),
|
||||||
|
"test 6"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(2)),
|
||||||
|
Rational(2) + ListPolynomial(),
|
||||||
|
"test 7"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Constant_Polynomial_minus() {
|
||||||
|
RationalField.listPolynomial {
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(32, 9), Rational(-8, 9), Rational(-8, 7)),
|
||||||
|
Rational(3) - ListPolynomial(Rational(-5, 9), Rational(8, 9), Rational(8, 7)),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(0), Rational(0)),
|
||||||
|
Rational(-2) - ListPolynomial(Rational(-2), Rational(0), Rational(0), Rational(0)),
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
Rational(-2) - ListPolynomial(Rational(-2)),
|
||||||
|
"test 3"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
Rational(0) - ListPolynomial(),
|
||||||
|
"test 4"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(1), Rational(0), Rational(0), Rational(0)),
|
||||||
|
Rational(-1) - ListPolynomial(Rational(-2), Rational(0), Rational(0), Rational(0)),
|
||||||
|
"test 5"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(1)),
|
||||||
|
Rational(-1) - ListPolynomial(Rational(-2)),
|
||||||
|
"test 6"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-2)),
|
||||||
|
Rational(-2) - ListPolynomial(),
|
||||||
|
"test 7"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Constant_Polynomial_times() {
|
||||||
|
IntModuloRing(35).listPolynomial {
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(34, 2, 1, 20, 2),
|
||||||
|
27 * ListPolynomial(22, 26, 13, 15, 26),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
15 * ListPolynomial(7, 0, 49, 21, 14),
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Polynomial_unaryMinus() {
|
||||||
|
RationalField.listPolynomial {
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-5, 9), Rational(8, 9), Rational(8, 7)),
|
||||||
|
-ListPolynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-5, 9), Rational(8, 9), Rational(8, 7), Rational(0), Rational(0)),
|
||||||
|
-ListPolynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7), Rational(0), Rational(0)),
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Polynomial_Polynomial_plus() {
|
||||||
|
RationalField.listPolynomial {
|
||||||
|
// (5/9 - 8/9 x - 8/7 x^2) + (-5/7 + 5/1 x + 5/8 x^2) ?= -10/63 + 37/9 x - 29/56 x^2
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-10, 63), Rational(37, 9), Rational(-29, 56)),
|
||||||
|
ListPolynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)) +
|
||||||
|
ListPolynomial(Rational(-5, 7), Rational(5, 1), Rational(5, 8)),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
// (-2/9 - 8/3 x) + (0 + 9/4 x + 2/4 x^2) ?= -2/9 - 5/12 x + 2/4 x^2
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-2, 9), Rational(-5, 12), Rational(2, 4)),
|
||||||
|
ListPolynomial(Rational(-2, 9), Rational(-8, 3)) +
|
||||||
|
ListPolynomial(Rational(0), Rational(9, 4), Rational(2, 4)),
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
// (-4/7 - 2/6 x + 0 x^2 + 0 x^3) + (-6/3 - 7/2 x + 2/3 x^2) ?= -18/7 - 23/6 x + 2/3 x^2
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-18, 7), Rational(-23, 6), Rational(2, 3)),
|
||||||
|
ListPolynomial(Rational(-4, 7), Rational(-2, 6), Rational(0), Rational(0)) +
|
||||||
|
ListPolynomial(Rational(-6, 3), Rational(-7, 2), Rational(2, 3)),
|
||||||
|
"test 3"
|
||||||
|
)
|
||||||
|
// (-2/4 - 6/9 x - 4/9 x^2) + (2/4 + 6/9 x + 4/9 x^2) ?= 0
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
ListPolynomial(Rational(-2, 4), Rational(-6, 9), Rational(-4, 9)) +
|
||||||
|
ListPolynomial(Rational(2, 4), Rational(6, 9), Rational(4, 9)),
|
||||||
|
"test 4"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Polynomial_Polynomial_minus() {
|
||||||
|
RationalField.listPolynomial {
|
||||||
|
// (5/9 - 8/9 x - 8/7 x^2) - (-5/7 + 5/1 x + 5/8 x^2) ?= 80/63 - 53/9 x - 99/56 x^2
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(80, 63), Rational(-53, 9), Rational(-99, 56)),
|
||||||
|
ListPolynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)) -
|
||||||
|
ListPolynomial(Rational(-5, 7), Rational(5, 1), Rational(5, 8)),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
// (-2/9 - 8/3 x) - (0 + 9/4 x + 2/4 x^2) ?= -2/9 - 59/12 x - 2/4 x^2
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-2, 9), Rational(-59, 12), Rational(-2, 4)),
|
||||||
|
ListPolynomial(Rational(-2, 9), Rational(-8, 3)) -
|
||||||
|
ListPolynomial(Rational(0), Rational(9, 4), Rational(2, 4)),
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
// (-4/7 - 2/6 x + 0 x^2 + 0 x^3) - (-6/3 - 7/2 x + 2/3 x^2) ?= 10/7 + 19/6 x - 2/3 x^2
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(10, 7), Rational(19, 6), Rational(-2, 3)),
|
||||||
|
ListPolynomial(Rational(-4, 7), Rational(-2, 6), Rational(0), Rational(0)) -
|
||||||
|
ListPolynomial(Rational(-6, 3), Rational(-7, 2), Rational(2, 3)),
|
||||||
|
"test 3"
|
||||||
|
)
|
||||||
|
// (-2/4 - 6/9 x - 4/9 x^2) - (-2/4 - 6/9 x - 4/9 x^2) ?= 0
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
ListPolynomial(Rational(-2, 4), Rational(-6, 9), Rational(-4, 9)) -
|
||||||
|
ListPolynomial(Rational(-2, 4), Rational(-6, 9), Rational(-4, 9)),
|
||||||
|
"test 4"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Polynomial_Polynomial_times() {
|
||||||
|
IntModuloRing(35).listPolynomial {
|
||||||
|
// (1 + x + x^2) * (1 - x + x^2) ?= 1 + x^2 + x^4
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(1, 0, 1, 0, 1),
|
||||||
|
ListPolynomial(1, -1, 1) * ListPolynomial(1, 1, 1),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
// Spoiler: 5 * 7 = 0
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
ListPolynomial(5, -25, 10) * ListPolynomial(21, 14, -7),
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Polynomial_isZero() {
|
||||||
|
RationalField.listPolynomial {
|
||||||
|
assertTrue("test 1") { ListPolynomial<Rational>().isZero() }
|
||||||
|
assertTrue("test 2") { ListPolynomial<Rational>(Rational(0)).isZero() }
|
||||||
|
assertTrue("test 3") { ListPolynomial<Rational>(Rational(0), Rational(0)).isZero() }
|
||||||
|
assertTrue("test 4") { ListPolynomial<Rational>(Rational(0), Rational(0), Rational(0))
|
||||||
|
.isZero() }
|
||||||
|
assertFalse("test 5") { ListPolynomial<Rational>(Rational(3, 5)).isZero() }
|
||||||
|
assertFalse("test 6") { ListPolynomial<Rational>(Rational(3, 5), Rational(0))
|
||||||
|
.isZero() }
|
||||||
|
assertFalse("test 7") { ListPolynomial<Rational>(Rational(0), Rational(3, 5), Rational(0))
|
||||||
|
.isZero() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Polynomial_isOne() {
|
||||||
|
RationalField.listPolynomial {
|
||||||
|
assertFalse("test 1") { ListPolynomial<Rational>().isOne() }
|
||||||
|
assertFalse("test 2") { ListPolynomial(Rational(0)).isOne() }
|
||||||
|
assertFalse("test 3") { ListPolynomial(Rational(0), Rational(0)).isOne() }
|
||||||
|
assertFalse("test 4") { ListPolynomial(Rational(0), Rational(0), Rational(0))
|
||||||
|
.isOne() }
|
||||||
|
assertFalse("test 5") { ListPolynomial(Rational(3, 5)).isOne() }
|
||||||
|
assertTrue("test 6") { ListPolynomial(Rational(5, 5)).isOne() }
|
||||||
|
assertFalse("test 7") { ListPolynomial(Rational(3, 5), Rational(0)).isOne() }
|
||||||
|
assertTrue("test 8") { ListPolynomial(Rational(3, 3), Rational(0)).isOne() }
|
||||||
|
assertFalse("test 9") { ListPolynomial(Rational(0), Rational(3, 5), Rational(0))
|
||||||
|
.isOne() }
|
||||||
|
assertFalse("test 10") { ListPolynomial(Rational(0), Rational(5, 5), Rational(0))
|
||||||
|
.isOne() }
|
||||||
|
assertFalse("test 11") { ListPolynomial(Rational(1), Rational(3, 5), Rational(0))
|
||||||
|
.isOne() }
|
||||||
|
assertFalse("test 12") { ListPolynomial(Rational(1), Rational(5, 5), Rational(0))
|
||||||
|
.isOne() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Polynomial_isMinusOne() {
|
||||||
|
RationalField.listPolynomial {
|
||||||
|
assertFalse("test 1") { ListPolynomial<Rational>().isMinusOne() }
|
||||||
|
assertFalse("test 2") { ListPolynomial(Rational(0)).isMinusOne() }
|
||||||
|
assertFalse("test 3") { ListPolynomial(Rational(0), Rational(0)).isMinusOne() }
|
||||||
|
assertFalse("test 4") { ListPolynomial(Rational(0), Rational(0), Rational(0))
|
||||||
|
.isMinusOne() }
|
||||||
|
assertFalse("test 5") { ListPolynomial(Rational(3, 5)).isMinusOne() }
|
||||||
|
assertTrue("test 6") { ListPolynomial(Rational(-5, 5)).isMinusOne() }
|
||||||
|
assertFalse("test 7") { ListPolynomial(Rational(3, 5), Rational(0)).isMinusOne() }
|
||||||
|
assertTrue("test 8") { ListPolynomial(Rational(-3, 3), Rational(0)).isMinusOne() }
|
||||||
|
assertFalse("test 9") { ListPolynomial(Rational(0), Rational(3, 5), Rational(0))
|
||||||
|
.isMinusOne() }
|
||||||
|
assertFalse("test 10") { ListPolynomial(Rational(0), Rational(5, -5), Rational(0))
|
||||||
|
.isMinusOne() }
|
||||||
|
assertFalse("test 11") { ListPolynomial(Rational(-1), Rational(3, 5), Rational(0))
|
||||||
|
.isMinusOne() }
|
||||||
|
assertFalse("test 12") { ListPolynomial(Rational(-1), Rational(5, -5), Rational(0))
|
||||||
|
.isMinusOne() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Polynomial_Polynomial_equalsTo() {
|
||||||
|
RationalField.listPolynomial {
|
||||||
|
assertTrue("test 1") {
|
||||||
|
ListPolynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)) equalsTo
|
||||||
|
ListPolynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7))
|
||||||
|
}
|
||||||
|
assertTrue("test 2") {
|
||||||
|
ListPolynomial(Rational(5, 9), Rational(0), Rational(-8, 7)) equalsTo
|
||||||
|
ListPolynomial(Rational(5, 9), Rational(0), Rational(-8, 7))
|
||||||
|
}
|
||||||
|
assertTrue("test 3") {
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(-8, 7), Rational(0), Rational(0)) equalsTo
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(-8, 7))
|
||||||
|
}
|
||||||
|
assertFalse("test 4") {
|
||||||
|
ListPolynomial(Rational(5, 9), Rational(5, 7), Rational(-8, 7)) equalsTo
|
||||||
|
ListPolynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7))
|
||||||
|
}
|
||||||
|
assertFalse("test 5") {
|
||||||
|
ListPolynomial(Rational(8, 3), Rational(0), Rational(-8, 7)) equalsTo
|
||||||
|
ListPolynomial(Rational(5, 9), Rational(0), Rational(-8, 7))
|
||||||
|
}
|
||||||
|
assertFalse("test 6") {
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(-8, 7), Rational(0), Rational(0)) equalsTo
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(8, 7))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Polynomial_degree() {
|
||||||
|
RationalField.listPolynomial {
|
||||||
|
assertEquals(
|
||||||
|
2,
|
||||||
|
ListPolynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)).degree,
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
-1,
|
||||||
|
ListPolynomial<Rational>().degree,
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
-1,
|
||||||
|
ListPolynomial(Rational(0)).degree,
|
||||||
|
"test 3"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
-1,
|
||||||
|
ListPolynomial(Rational(0), Rational(0)).degree,
|
||||||
|
"test 4"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
-1,
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(0)).degree,
|
||||||
|
"test 5"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
0,
|
||||||
|
ListPolynomial(Rational(5, 9)).degree,
|
||||||
|
"test 6"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
0,
|
||||||
|
ListPolynomial(Rational(5, 9), Rational(0)).degree,
|
||||||
|
"test 7"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
0,
|
||||||
|
ListPolynomial(Rational(5, 9), Rational(0), Rational(0)).degree,
|
||||||
|
"test 8"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
2,
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(-8, 7)).degree,
|
||||||
|
"test 9"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
2,
|
||||||
|
ListPolynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7), Rational(0), Rational(0)).degree,
|
||||||
|
"test 10"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
2,
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(-8, 7), Rational(0), Rational(0)).degree,
|
||||||
|
"test 11"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_Polynomial_asConstantOrNull() {
|
||||||
|
RationalField.listPolynomial {
|
||||||
|
assertEquals(
|
||||||
|
Rational(0),
|
||||||
|
ListPolynomial<Rational>().asConstantOrNull(),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
Rational(0),
|
||||||
|
ListPolynomial(Rational(0)).asConstantOrNull(),
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
Rational(0),
|
||||||
|
ListPolynomial(Rational(0), Rational(0)).asConstantOrNull(),
|
||||||
|
"test 3"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
Rational(0),
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(0)).asConstantOrNull(),
|
||||||
|
"test 4"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
Rational(-7, 9),
|
||||||
|
ListPolynomial(Rational(-7, 9)).asConstantOrNull(),
|
||||||
|
"test 5"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
Rational(-7, 9),
|
||||||
|
ListPolynomial(Rational(-7, 9), Rational(0)).asConstantOrNull(),
|
||||||
|
"test 6"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
Rational(-7, 9),
|
||||||
|
ListPolynomial(Rational(-7, 9), Rational(0), Rational(0)).asConstantOrNull(),
|
||||||
|
"test 7"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
null,
|
||||||
|
ListPolynomial(Rational(0), Rational(-7, 9)).asConstantOrNull(),
|
||||||
|
"test 8"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
null,
|
||||||
|
ListPolynomial(Rational(0), Rational(-7, 9), Rational(0)).asConstantOrNull(),
|
||||||
|
"test 9"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
null,
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(-7, 9)).asConstantOrNull(),
|
||||||
|
"test 10"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
null,
|
||||||
|
ListPolynomial(Rational(4, 15), Rational(0), Rational(-7, 9)).asConstantOrNull(),
|
||||||
|
"test 11"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
null,
|
||||||
|
ListPolynomial(Rational(4, 15), Rational(0), Rational(-7, 9), Rational(0))
|
||||||
|
.asConstantOrNull(),
|
||||||
|
"test 12"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,229 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018-2021 KMath contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package space.kscience.kmath.functions
|
||||||
|
|
||||||
|
import space.kscience.kmath.test.misc.Rational
|
||||||
|
import space.kscience.kmath.test.misc.RationalField
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertFailsWith
|
||||||
|
|
||||||
|
|
||||||
|
class ListPolynomialUtilTest {
|
||||||
|
@Test
|
||||||
|
fun test_substitute_Double() {
|
||||||
|
val polynomial = ListPolynomial(1.0, -2.0, 1.0)
|
||||||
|
assertEquals(0.0, polynomial.substitute(1.0), 0.001)
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_substitute_Constant() {
|
||||||
|
assertEquals(
|
||||||
|
Rational(0),
|
||||||
|
ListPolynomial(Rational(1), Rational(-2), Rational(1)).substitute(RationalField, Rational(1)),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
Rational(25057, 21000),
|
||||||
|
ListPolynomial(Rational(5,8), Rational(8, 3), Rational(4, 7), Rational(3, 2))
|
||||||
|
.substitute(RationalField, Rational(1, 5)),
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
Rational(2983, 5250),
|
||||||
|
ListPolynomial(Rational(0), Rational(8, 3), Rational(4, 7), Rational(3, 2))
|
||||||
|
.substitute(RationalField, Rational(1, 5)),
|
||||||
|
"test 3"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
Rational(4961, 4200),
|
||||||
|
ListPolynomial(Rational(5,8), Rational(8, 3), Rational(4, 7), Rational(0))
|
||||||
|
.substitute(RationalField, Rational(1, 5)),
|
||||||
|
"test 4"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
Rational(3511, 3000),
|
||||||
|
ListPolynomial(Rational(5,8), Rational(8, 3), Rational(0), Rational(3, 2))
|
||||||
|
.substitute(RationalField, Rational(1, 5)),
|
||||||
|
"test 5"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_substitute_Polynomial() {
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
ListPolynomial(Rational(1), Rational(-2), Rational(1)).substitute(RationalField, ListPolynomial(Rational(1))),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(709, 378), Rational(155, 252), Rational(19, 525), Rational(2, 875)),
|
||||||
|
ListPolynomial(Rational(1, 7), Rational(9, 4), Rational(1, 3), Rational(2, 7))
|
||||||
|
.substitute(RationalField, ListPolynomial(Rational(6, 9), Rational(1, 5))),
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(655, 378), Rational(155, 252), Rational(19, 525), Rational(2, 875)),
|
||||||
|
ListPolynomial(Rational(0), Rational(9, 4), Rational(1, 3), Rational(2, 7))
|
||||||
|
.substitute(RationalField, ListPolynomial(Rational(6, 9), Rational(1, 5))),
|
||||||
|
"test 3"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(677, 378), Rational(97, 180), Rational(1, 75)),
|
||||||
|
ListPolynomial(Rational(1, 7), Rational(9, 4), Rational(1, 3), Rational(0))
|
||||||
|
.substitute(RationalField, ListPolynomial(Rational(6, 9), Rational(1, 5))),
|
||||||
|
"test 4"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(653, 378), Rational(221, 420), Rational(4, 175), Rational(2, 875)),
|
||||||
|
ListPolynomial(Rational(1, 7), Rational(9, 4), Rational(0), Rational(2, 7))
|
||||||
|
.substitute(RationalField, ListPolynomial(Rational(6, 9), Rational(1, 5))),
|
||||||
|
"test 5"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(89, 54)),
|
||||||
|
ListPolynomial(Rational(0), Rational(9, 4), Rational(1, 3), Rational(0))
|
||||||
|
.substitute(RationalField, ListPolynomial(Rational(6, 9), Rational(0))),
|
||||||
|
"test 6"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_derivative() {
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-2), Rational(2)),
|
||||||
|
ListPolynomial(Rational(1), Rational(-2), Rational(1)).derivative(RationalField),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-8, 3), Rational(8, 9), Rational(15, 7), Rational(-20, 9)),
|
||||||
|
ListPolynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).derivative(RationalField),
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(8, 9), Rational(15, 7), Rational(-20, 9)),
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).derivative(RationalField),
|
||||||
|
"test 3"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-8, 3), Rational(8, 9), Rational(15, 7)),
|
||||||
|
ListPolynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(0)).derivative(RationalField),
|
||||||
|
"test 4"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_nthDerivative() {
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(-2), Rational(2)),
|
||||||
|
ListPolynomial(Rational(1), Rational(-2), Rational(1)).nthDerivative(RationalField, 1),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertFailsWith<IllegalArgumentException>("test2") {
|
||||||
|
ListPolynomial(Rational(1), Rational(-2), Rational(1)).nthDerivative(RationalField, -1)
|
||||||
|
}
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(1), Rational(-2), Rational(1)),
|
||||||
|
ListPolynomial(Rational(1), Rational(-2), Rational(1)).nthDerivative(RationalField, 0),
|
||||||
|
"test 3"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(2)),
|
||||||
|
ListPolynomial(Rational(1), Rational(-2), Rational(1)).nthDerivative(RationalField, 2),
|
||||||
|
"test 4"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
ListPolynomial(Rational(1), Rational(-2), Rational(1)).nthDerivative(RationalField, 3),
|
||||||
|
"test 5"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(),
|
||||||
|
ListPolynomial(Rational(1), Rational(-2), Rational(1)).nthDerivative(RationalField, 4),
|
||||||
|
"test 6"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(8, 9), Rational(30, 7), Rational(-20, 3)),
|
||||||
|
ListPolynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).nthDerivative(RationalField, 2),
|
||||||
|
"test 7"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(8, 9), Rational(30, 7), Rational(-20, 3)),
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).nthDerivative(RationalField, 2),
|
||||||
|
"test 8"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(8, 9), Rational(30, 7)),
|
||||||
|
ListPolynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(0)).nthDerivative(RationalField, 2),
|
||||||
|
"test 9"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_antiderivative() {
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(1), Rational(-1), Rational(1, 3)),
|
||||||
|
ListPolynomial(Rational(1), Rational(-2), Rational(1)).antiderivative(RationalField),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(1, 5), Rational(-4, 3), Rational(4, 27), Rational(5, 28), Rational(-1, 9)),
|
||||||
|
ListPolynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).antiderivative(RationalField),
|
||||||
|
"test 2"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(0), Rational(4, 27), Rational(5, 28), Rational(-1, 9)),
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).antiderivative(RationalField),
|
||||||
|
"test 3"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(1, 5), Rational(-4, 3), Rational(4, 27), Rational(5, 28)),
|
||||||
|
ListPolynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(0)).antiderivative(RationalField),
|
||||||
|
"test 4"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun test_nthAntiderivative() {
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(1), Rational(-1), Rational(1, 3)),
|
||||||
|
ListPolynomial(Rational(1), Rational(-2), Rational(1)).nthAntiderivative(RationalField, 1),
|
||||||
|
"test 1"
|
||||||
|
)
|
||||||
|
assertFailsWith<IllegalArgumentException>("test2") {
|
||||||
|
ListPolynomial(Rational(1), Rational(-2), Rational(1)).nthAntiderivative(RationalField, -1)
|
||||||
|
}
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(1), Rational(-2), Rational(1)),
|
||||||
|
ListPolynomial(Rational(1), Rational(-2), Rational(1)).nthAntiderivative(RationalField, 0),
|
||||||
|
"test 3"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(1, 2), Rational(-1, 3), Rational(1, 12)),
|
||||||
|
ListPolynomial(Rational(1), Rational(-2), Rational(1)).nthAntiderivative(RationalField, 2),
|
||||||
|
"test 4"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(0), Rational(1, 6), Rational(-1, 12), Rational(1, 60)),
|
||||||
|
ListPolynomial(Rational(1), Rational(-2), Rational(1)).nthAntiderivative(RationalField, 3),
|
||||||
|
"test 5"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(0), Rational(0), Rational(1, 24), Rational(-1, 60), Rational(1, 360)),
|
||||||
|
ListPolynomial(Rational(1), Rational(-2), Rational(1)).nthAntiderivative(RationalField, 4),
|
||||||
|
"test 6"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(1, 10), Rational(-4, 9), Rational(1, 27), Rational(1, 28), Rational(-1, 54)),
|
||||||
|
ListPolynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).nthAntiderivative(RationalField, 2),
|
||||||
|
"test 7"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(0), Rational(0), Rational(1, 27), Rational(1, 28), Rational(-1, 54)),
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).nthAntiderivative(RationalField, 2),
|
||||||
|
"test 8"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
ListPolynomial(Rational(0), Rational(0), Rational(1, 10), Rational(-4, 9), Rational(1, 27), Rational(1, 28)),
|
||||||
|
ListPolynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(0)).nthAntiderivative(RationalField, 2),
|
||||||
|
"test 9"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -1,691 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2018-2021 KMath contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package space.kscience.kmath.functions
|
|
||||||
|
|
||||||
import space.kscience.kmath.test.misc.*
|
|
||||||
import kotlin.test.*
|
|
||||||
|
|
||||||
|
|
||||||
class PolynomialTest {
|
|
||||||
@Test
|
|
||||||
fun test_Polynomial_Int_plus() {
|
|
||||||
RationalField.polynomial {
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-22, 9), Rational(-8, 9), Rational(-8, 7)),
|
|
||||||
Polynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)) + -3,
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(0), Rational(0)),
|
|
||||||
Polynomial(Rational(-2), Rational(0), Rational(0), Rational(0)) + 2,
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Polynomial(Rational(-2)) + 2,
|
|
||||||
"test 3"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Polynomial<Rational>() + 0,
|
|
||||||
"test 4"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-1), Rational(0), Rational(0), Rational(0)),
|
|
||||||
Polynomial(Rational(-2), Rational(0), Rational(0), Rational(0)) + 1,
|
|
||||||
"test 5"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-1)),
|
|
||||||
Polynomial(Rational(-2)) + 1,
|
|
||||||
"test 6"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(2)),
|
|
||||||
Polynomial<Rational>() + 2,
|
|
||||||
"test 7"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Polynomial_Int_minus() {
|
|
||||||
RationalField.polynomial {
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(32, 9), Rational(-8, 9), Rational(-8, 7)),
|
|
||||||
Polynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)) - -3,
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(0), Rational(0)),
|
|
||||||
Polynomial(Rational(2), Rational(0), Rational(0), Rational(0)) - 2,
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Polynomial(Rational(2)) - 2,
|
|
||||||
"test 3"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Polynomial<Rational>() - 0,
|
|
||||||
"test 4"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(1), Rational(0), Rational(0), Rational(0)),
|
|
||||||
Polynomial(Rational(2), Rational(0), Rational(0), Rational(0)) - 1,
|
|
||||||
"test 5"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(1)),
|
|
||||||
Polynomial(Rational(2)) - 1,
|
|
||||||
"test 6"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-2)),
|
|
||||||
Polynomial<Rational>() - 2,
|
|
||||||
"test 7"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Polynomial_Int_times() {
|
|
||||||
IntModuloRing(35).polynomial {
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(34, 2, 1, 20, 2),
|
|
||||||
Polynomial(22, 26, 13, 15, 26) * 27,
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Polynomial(7, 0, 49, 21, 14) * 15,
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Int_Polynomial_plus() {
|
|
||||||
RationalField.polynomial {
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-22, 9), Rational(-8, 9), Rational(-8, 7)),
|
|
||||||
-3 + Polynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(0), Rational(0)),
|
|
||||||
2 + Polynomial(Rational(-2), Rational(0), Rational(0), Rational(0)),
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
2 + Polynomial(Rational(-2)),
|
|
||||||
"test 3"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
0 + Polynomial(),
|
|
||||||
"test 4"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-1), Rational(0), Rational(0), Rational(0)),
|
|
||||||
1 + Polynomial(Rational(-2), Rational(0), Rational(0), Rational(0)),
|
|
||||||
"test 5"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-1)),
|
|
||||||
1 + Polynomial(Rational(-2)),
|
|
||||||
"test 6"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(2)),
|
|
||||||
2 + Polynomial(),
|
|
||||||
"test 7"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Int_Polynomial_minus() {
|
|
||||||
RationalField.polynomial {
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(32, 9), Rational(-8, 9), Rational(-8, 7)),
|
|
||||||
3 - Polynomial(Rational(-5, 9), Rational(8, 9), Rational(8, 7)),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(0), Rational(0)),
|
|
||||||
-2 - Polynomial(Rational(-2), Rational(0), Rational(0), Rational(0)),
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
-2 - Polynomial(Rational(-2)),
|
|
||||||
"test 3"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
0 - Polynomial(),
|
|
||||||
"test 4"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(1), Rational(0), Rational(0), Rational(0)),
|
|
||||||
-1 - Polynomial(Rational(-2), Rational(0), Rational(0), Rational(0)),
|
|
||||||
"test 5"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(1)),
|
|
||||||
-1 - Polynomial(Rational(-2)),
|
|
||||||
"test 6"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-2)),
|
|
||||||
-2 - Polynomial(),
|
|
||||||
"test 7"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Int_Polynomial_times() {
|
|
||||||
IntModuloRing(35).polynomial {
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(34, 2, 1, 20, 2),
|
|
||||||
27 * Polynomial(22, 26, 13, 15, 26),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
15 * Polynomial(7, 0, 49, 21, 14),
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Polynomial_Constant_plus() {
|
|
||||||
RationalField.polynomial {
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-22, 9), Rational(-8, 9), Rational(-8, 7)),
|
|
||||||
Polynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)) + Rational(-3),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(0), Rational(0)),
|
|
||||||
Polynomial(Rational(-2), Rational(0), Rational(0), Rational(0)) + Rational(2),
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Polynomial(Rational(-2)) + Rational(2),
|
|
||||||
"test 3"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Polynomial<Rational>() + Rational(0),
|
|
||||||
"test 4"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-1), Rational(0), Rational(0), Rational(0)),
|
|
||||||
Polynomial(Rational(-2), Rational(0), Rational(0), Rational(0)) + Rational(1),
|
|
||||||
"test 5"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-1)),
|
|
||||||
Polynomial(Rational(-2)) + Rational(1),
|
|
||||||
"test 6"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(2)),
|
|
||||||
Polynomial<Rational>() + Rational(2),
|
|
||||||
"test 7"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Polynomial_Constant_minus() {
|
|
||||||
RationalField.polynomial {
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(32, 9), Rational(-8, 9), Rational(-8, 7)),
|
|
||||||
Polynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)) - Rational(-3),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(0), Rational(0)),
|
|
||||||
Polynomial(Rational(2), Rational(0), Rational(0), Rational(0)) - Rational(2),
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Polynomial(Rational(2)) - Rational(2),
|
|
||||||
"test 3"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Polynomial<Rational>() - Rational(0),
|
|
||||||
"test 4"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(1), Rational(0), Rational(0), Rational(0)),
|
|
||||||
Polynomial(Rational(2), Rational(0), Rational(0), Rational(0)) - Rational(1),
|
|
||||||
"test 5"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(1)),
|
|
||||||
Polynomial(Rational(2)) - Rational(1),
|
|
||||||
"test 6"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-2)),
|
|
||||||
Polynomial<Rational>() - Rational(2),
|
|
||||||
"test 7"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Polynomial_Constant_times() {
|
|
||||||
IntModuloRing(35).polynomial {
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(34, 2, 1, 20, 2),
|
|
||||||
Polynomial(22, 26, 13, 15, 26) * number(27),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Polynomial(7, 0, 49, 21, 14) * number(15),
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Constant_Polynomial_plus() {
|
|
||||||
RationalField.polynomial {
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-22, 9), Rational(-8, 9), Rational(-8, 7)),
|
|
||||||
Rational(-3) + Polynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(0), Rational(0)),
|
|
||||||
Rational(2) + Polynomial(Rational(-2), Rational(0), Rational(0), Rational(0)),
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Rational(2) + Polynomial(Rational(-2)),
|
|
||||||
"test 3"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Rational(0) + Polynomial(),
|
|
||||||
"test 4"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-1), Rational(0), Rational(0), Rational(0)),
|
|
||||||
Rational(1) + Polynomial(Rational(-2), Rational(0), Rational(0), Rational(0)),
|
|
||||||
"test 5"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-1)),
|
|
||||||
Rational(1) + Polynomial(Rational(-2)),
|
|
||||||
"test 6"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(2)),
|
|
||||||
Rational(2) + Polynomial(),
|
|
||||||
"test 7"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Constant_Polynomial_minus() {
|
|
||||||
RationalField.polynomial {
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(32, 9), Rational(-8, 9), Rational(-8, 7)),
|
|
||||||
Rational(3) - Polynomial(Rational(-5, 9), Rational(8, 9), Rational(8, 7)),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(0), Rational(0)),
|
|
||||||
Rational(-2) - Polynomial(Rational(-2), Rational(0), Rational(0), Rational(0)),
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Rational(-2) - Polynomial(Rational(-2)),
|
|
||||||
"test 3"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Rational(0) - Polynomial(),
|
|
||||||
"test 4"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(1), Rational(0), Rational(0), Rational(0)),
|
|
||||||
Rational(-1) - Polynomial(Rational(-2), Rational(0), Rational(0), Rational(0)),
|
|
||||||
"test 5"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(1)),
|
|
||||||
Rational(-1) - Polynomial(Rational(-2)),
|
|
||||||
"test 6"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-2)),
|
|
||||||
Rational(-2) - Polynomial(),
|
|
||||||
"test 7"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Constant_Polynomial_times() {
|
|
||||||
IntModuloRing(35).polynomial {
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(34, 2, 1, 20, 2),
|
|
||||||
27 * Polynomial(22, 26, 13, 15, 26),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
15 * Polynomial(7, 0, 49, 21, 14),
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Polynomial_unaryMinus() {
|
|
||||||
RationalField.polynomial {
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-5, 9), Rational(8, 9), Rational(8, 7)),
|
|
||||||
-Polynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-5, 9), Rational(8, 9), Rational(8, 7), Rational(0), Rational(0)),
|
|
||||||
-Polynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7), Rational(0), Rational(0)),
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Polynomial_Polynomial_plus() {
|
|
||||||
RationalField.polynomial {
|
|
||||||
// (5/9 - 8/9 x - 8/7 x^2) + (-5/7 + 5/1 x + 5/8 x^2) ?= -10/63 + 37/9 x - 29/56 x^2
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-10, 63), Rational(37, 9), Rational(-29, 56)),
|
|
||||||
Polynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)) +
|
|
||||||
Polynomial(Rational(-5, 7), Rational(5, 1), Rational(5, 8)),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
// (-2/9 - 8/3 x) + (0 + 9/4 x + 2/4 x^2) ?= -2/9 - 5/12 x + 2/4 x^2
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-2, 9), Rational(-5, 12), Rational(2, 4)),
|
|
||||||
Polynomial(Rational(-2, 9), Rational(-8, 3)) +
|
|
||||||
Polynomial(Rational(0), Rational(9, 4), Rational(2, 4)),
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
// (-4/7 - 2/6 x + 0 x^2 + 0 x^3) + (-6/3 - 7/2 x + 2/3 x^2) ?= -18/7 - 23/6 x + 2/3 x^2
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-18, 7), Rational(-23, 6), Rational(2, 3)),
|
|
||||||
Polynomial(Rational(-4, 7), Rational(-2, 6), Rational(0), Rational(0)) +
|
|
||||||
Polynomial(Rational(-6, 3), Rational(-7, 2), Rational(2, 3)),
|
|
||||||
"test 3"
|
|
||||||
)
|
|
||||||
// (-2/4 - 6/9 x - 4/9 x^2) + (2/4 + 6/9 x + 4/9 x^2) ?= 0
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Polynomial(Rational(-2, 4), Rational(-6, 9), Rational(-4, 9)) +
|
|
||||||
Polynomial(Rational(2, 4), Rational(6, 9), Rational(4, 9)),
|
|
||||||
"test 4"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Polynomial_Polynomial_minus() {
|
|
||||||
RationalField.polynomial {
|
|
||||||
// (5/9 - 8/9 x - 8/7 x^2) - (-5/7 + 5/1 x + 5/8 x^2) ?= 80/63 - 53/9 x - 99/56 x^2
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(80, 63), Rational(-53, 9), Rational(-99, 56)),
|
|
||||||
Polynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)) -
|
|
||||||
Polynomial(Rational(-5, 7), Rational(5, 1), Rational(5, 8)),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
// (-2/9 - 8/3 x) - (0 + 9/4 x + 2/4 x^2) ?= -2/9 - 59/12 x - 2/4 x^2
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-2, 9), Rational(-59, 12), Rational(-2, 4)),
|
|
||||||
Polynomial(Rational(-2, 9), Rational(-8, 3)) -
|
|
||||||
Polynomial(Rational(0), Rational(9, 4), Rational(2, 4)),
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
// (-4/7 - 2/6 x + 0 x^2 + 0 x^3) - (-6/3 - 7/2 x + 2/3 x^2) ?= 10/7 + 19/6 x - 2/3 x^2
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(10, 7), Rational(19, 6), Rational(-2, 3)),
|
|
||||||
Polynomial(Rational(-4, 7), Rational(-2, 6), Rational(0), Rational(0)) -
|
|
||||||
Polynomial(Rational(-6, 3), Rational(-7, 2), Rational(2, 3)),
|
|
||||||
"test 3"
|
|
||||||
)
|
|
||||||
// (-2/4 - 6/9 x - 4/9 x^2) - (-2/4 - 6/9 x - 4/9 x^2) ?= 0
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Polynomial(Rational(-2, 4), Rational(-6, 9), Rational(-4, 9)) -
|
|
||||||
Polynomial(Rational(-2, 4), Rational(-6, 9), Rational(-4, 9)),
|
|
||||||
"test 4"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Polynomial_Polynomial_times() {
|
|
||||||
IntModuloRing(35).polynomial {
|
|
||||||
// (1 + x + x^2) * (1 - x + x^2) ?= 1 + x^2 + x^4
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(1, 0, 1, 0, 1),
|
|
||||||
Polynomial(1, -1, 1) * Polynomial(1, 1, 1),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
// Spoiler: 5 * 7 = 0
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Polynomial(5, -25, 10) * Polynomial(21, 14, -7),
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Polynomial_isZero() {
|
|
||||||
RationalField.polynomial {
|
|
||||||
assertTrue("test 1") { Polynomial<Rational>().isZero() }
|
|
||||||
assertTrue("test 2") { Polynomial<Rational>(Rational(0)).isZero() }
|
|
||||||
assertTrue("test 3") { Polynomial<Rational>(Rational(0), Rational(0)).isZero() }
|
|
||||||
assertTrue("test 4") { Polynomial<Rational>(Rational(0), Rational(0), Rational(0)).isZero() }
|
|
||||||
assertFalse("test 5") { Polynomial<Rational>(Rational(3, 5)).isZero() }
|
|
||||||
assertFalse("test 6") { Polynomial<Rational>(Rational(3, 5), Rational(0)).isZero() }
|
|
||||||
assertFalse("test 7") { Polynomial<Rational>(Rational(0), Rational(3, 5), Rational(0)).isZero() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Polynomial_isOne() {
|
|
||||||
RationalField.polynomial {
|
|
||||||
assertFalse("test 1") { Polynomial<Rational>().isOne() }
|
|
||||||
assertFalse("test 2") { Polynomial(Rational(0)).isOne() }
|
|
||||||
assertFalse("test 3") { Polynomial(Rational(0), Rational(0)).isOne() }
|
|
||||||
assertFalse("test 4") { Polynomial(Rational(0), Rational(0), Rational(0)).isOne() }
|
|
||||||
assertFalse("test 5") { Polynomial(Rational(3, 5)).isOne() }
|
|
||||||
assertTrue("test 6") { Polynomial(Rational(5, 5)).isOne() }
|
|
||||||
assertFalse("test 7") { Polynomial(Rational(3, 5), Rational(0)).isOne() }
|
|
||||||
assertTrue("test 8") { Polynomial(Rational(3, 3), Rational(0)).isOne() }
|
|
||||||
assertFalse("test 9") { Polynomial(Rational(0), Rational(3, 5), Rational(0)).isOne() }
|
|
||||||
assertFalse("test 10") { Polynomial(Rational(0), Rational(5, 5), Rational(0)).isOne() }
|
|
||||||
assertFalse("test 11") { Polynomial(Rational(1), Rational(3, 5), Rational(0)).isOne() }
|
|
||||||
assertFalse("test 12") { Polynomial(Rational(1), Rational(5, 5), Rational(0)).isOne() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Polynomial_isMinusOne() {
|
|
||||||
RationalField.polynomial {
|
|
||||||
assertFalse("test 1") { Polynomial<Rational>().isMinusOne() }
|
|
||||||
assertFalse("test 2") { Polynomial(Rational(0)).isMinusOne() }
|
|
||||||
assertFalse("test 3") { Polynomial(Rational(0), Rational(0)).isMinusOne() }
|
|
||||||
assertFalse("test 4") { Polynomial(Rational(0), Rational(0), Rational(0)).isMinusOne() }
|
|
||||||
assertFalse("test 5") { Polynomial(Rational(3, 5)).isMinusOne() }
|
|
||||||
assertTrue("test 6") { Polynomial(Rational(-5, 5)).isMinusOne() }
|
|
||||||
assertFalse("test 7") { Polynomial(Rational(3, 5), Rational(0)).isMinusOne() }
|
|
||||||
assertTrue("test 8") { Polynomial(Rational(-3, 3), Rational(0)).isMinusOne() }
|
|
||||||
assertFalse("test 9") { Polynomial(Rational(0), Rational(3, 5), Rational(0)).isMinusOne() }
|
|
||||||
assertFalse("test 10") { Polynomial(Rational(0), Rational(5, -5), Rational(0)).isMinusOne() }
|
|
||||||
assertFalse("test 11") { Polynomial(Rational(-1), Rational(3, 5), Rational(0)).isMinusOne() }
|
|
||||||
assertFalse("test 12") { Polynomial(Rational(-1), Rational(5, -5), Rational(0)).isMinusOne() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Polynomial_equalsTo() {
|
|
||||||
RationalField.polynomial {
|
|
||||||
assertTrue("test 1") {
|
|
||||||
Polynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)) equalsTo
|
|
||||||
Polynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7))
|
|
||||||
}
|
|
||||||
assertTrue("test 2") {
|
|
||||||
Polynomial(Rational(5, 9), Rational(0), Rational(-8, 7)) equalsTo
|
|
||||||
Polynomial(Rational(5, 9), Rational(0), Rational(-8, 7))
|
|
||||||
}
|
|
||||||
assertTrue("test 3") {
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(-8, 7), Rational(0), Rational(0)) equalsTo
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(-8, 7))
|
|
||||||
}
|
|
||||||
assertFalse("test 4") {
|
|
||||||
Polynomial(Rational(5, 9), Rational(5, 7), Rational(-8, 7)) equalsTo
|
|
||||||
Polynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7))
|
|
||||||
}
|
|
||||||
assertFalse("test 5") {
|
|
||||||
Polynomial(Rational(8, 3), Rational(0), Rational(-8, 7)) equalsTo
|
|
||||||
Polynomial(Rational(5, 9), Rational(0), Rational(-8, 7))
|
|
||||||
}
|
|
||||||
assertFalse("test 6") {
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(-8, 7), Rational(0), Rational(0)) equalsTo
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(8, 7))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Polynomial_degree() {
|
|
||||||
RationalField.polynomial {
|
|
||||||
assertEquals(
|
|
||||||
2,
|
|
||||||
Polynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7)).degree,
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
-1,
|
|
||||||
Polynomial<Rational>().degree,
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
-1,
|
|
||||||
Polynomial(Rational(0)).degree,
|
|
||||||
"test 3"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
-1,
|
|
||||||
Polynomial(Rational(0), Rational(0)).degree,
|
|
||||||
"test 4"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
-1,
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(0)).degree,
|
|
||||||
"test 5"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
0,
|
|
||||||
Polynomial(Rational(5, 9)).degree,
|
|
||||||
"test 6"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
0,
|
|
||||||
Polynomial(Rational(5, 9), Rational(0)).degree,
|
|
||||||
"test 7"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
0,
|
|
||||||
Polynomial(Rational(5, 9), Rational(0), Rational(0)).degree,
|
|
||||||
"test 8"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
2,
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(-8, 7)).degree,
|
|
||||||
"test 9"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
2,
|
|
||||||
Polynomial(Rational(5, 9), Rational(-8, 9), Rational(-8, 7), Rational(0), Rational(0)).degree,
|
|
||||||
"test 10"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
2,
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(-8, 7), Rational(0), Rational(0)).degree,
|
|
||||||
"test 11"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_Polynomial_asConstantOrNull() {
|
|
||||||
RationalField.polynomial {
|
|
||||||
assertEquals(
|
|
||||||
Rational(0),
|
|
||||||
Polynomial<Rational>().asConstantOrNull(),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Rational(0),
|
|
||||||
Polynomial(Rational(0)).asConstantOrNull(),
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Rational(0),
|
|
||||||
Polynomial(Rational(0), Rational(0)).asConstantOrNull(),
|
|
||||||
"test 3"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Rational(0),
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(0)).asConstantOrNull(),
|
|
||||||
"test 4"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Rational(-7, 9),
|
|
||||||
Polynomial(Rational(-7, 9)).asConstantOrNull(),
|
|
||||||
"test 5"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Rational(-7, 9),
|
|
||||||
Polynomial(Rational(-7, 9), Rational(0)).asConstantOrNull(),
|
|
||||||
"test 6"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Rational(-7, 9),
|
|
||||||
Polynomial(Rational(-7, 9), Rational(0), Rational(0)).asConstantOrNull(),
|
|
||||||
"test 7"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
null,
|
|
||||||
Polynomial(Rational(0), Rational(-7, 9)).asConstantOrNull(),
|
|
||||||
"test 8"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
null,
|
|
||||||
Polynomial(Rational(0), Rational(-7, 9), Rational(0)).asConstantOrNull(),
|
|
||||||
"test 9"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
null,
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(-7, 9)).asConstantOrNull(),
|
|
||||||
"test 10"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
null,
|
|
||||||
Polynomial(Rational(4, 15), Rational(0), Rational(-7, 9)).asConstantOrNull(),
|
|
||||||
"test 11"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
null,
|
|
||||||
Polynomial(Rational(4, 15), Rational(0), Rational(-7, 9), Rational(0)).asConstantOrNull(),
|
|
||||||
"test 12"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,229 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2018-2021 KMath contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package space.kscience.kmath.functions
|
|
||||||
|
|
||||||
import space.kscience.kmath.test.misc.Rational
|
|
||||||
import space.kscience.kmath.test.misc.RationalField
|
|
||||||
import kotlin.test.Test
|
|
||||||
import kotlin.test.assertEquals
|
|
||||||
import kotlin.test.assertFailsWith
|
|
||||||
|
|
||||||
|
|
||||||
class PolynomialUtilTest {
|
|
||||||
@Test
|
|
||||||
fun test_substitute_Double() {
|
|
||||||
val polynomial = Polynomial(1.0, -2.0, 1.0)
|
|
||||||
assertEquals(0.0, polynomial.substitute(1.0), 0.001)
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_substitute_Constant() {
|
|
||||||
assertEquals(
|
|
||||||
Rational(0),
|
|
||||||
Polynomial(Rational(1), Rational(-2), Rational(1)).substitute(RationalField, Rational(1)),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Rational(25057, 21000),
|
|
||||||
Polynomial(Rational(5,8), Rational(8, 3), Rational(4, 7), Rational(3, 2))
|
|
||||||
.substitute(RationalField, Rational(1, 5)),
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Rational(2983, 5250),
|
|
||||||
Polynomial(Rational(0), Rational(8, 3), Rational(4, 7), Rational(3, 2))
|
|
||||||
.substitute(RationalField, Rational(1, 5)),
|
|
||||||
"test 3"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Rational(4961, 4200),
|
|
||||||
Polynomial(Rational(5,8), Rational(8, 3), Rational(4, 7), Rational(0))
|
|
||||||
.substitute(RationalField, Rational(1, 5)),
|
|
||||||
"test 4"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Rational(3511, 3000),
|
|
||||||
Polynomial(Rational(5,8), Rational(8, 3), Rational(0), Rational(3, 2))
|
|
||||||
.substitute(RationalField, Rational(1, 5)),
|
|
||||||
"test 5"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_substitute_Polynomial() {
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Polynomial(Rational(1), Rational(-2), Rational(1)).substitute(RationalField, Polynomial(Rational(1))),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(709, 378), Rational(155, 252), Rational(19, 525), Rational(2, 875)),
|
|
||||||
Polynomial(Rational(1, 7), Rational(9, 4), Rational(1, 3), Rational(2, 7))
|
|
||||||
.substitute(RationalField, Polynomial(Rational(6, 9), Rational(1, 5))),
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(655, 378), Rational(155, 252), Rational(19, 525), Rational(2, 875)),
|
|
||||||
Polynomial(Rational(0), Rational(9, 4), Rational(1, 3), Rational(2, 7))
|
|
||||||
.substitute(RationalField, Polynomial(Rational(6, 9), Rational(1, 5))),
|
|
||||||
"test 3"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(677, 378), Rational(97, 180), Rational(1, 75)),
|
|
||||||
Polynomial(Rational(1, 7), Rational(9, 4), Rational(1, 3), Rational(0))
|
|
||||||
.substitute(RationalField, Polynomial(Rational(6, 9), Rational(1, 5))),
|
|
||||||
"test 4"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(653, 378), Rational(221, 420), Rational(4, 175), Rational(2, 875)),
|
|
||||||
Polynomial(Rational(1, 7), Rational(9, 4), Rational(0), Rational(2, 7))
|
|
||||||
.substitute(RationalField, Polynomial(Rational(6, 9), Rational(1, 5))),
|
|
||||||
"test 5"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(89, 54)),
|
|
||||||
Polynomial(Rational(0), Rational(9, 4), Rational(1, 3), Rational(0))
|
|
||||||
.substitute(RationalField, Polynomial(Rational(6, 9), Rational(0))),
|
|
||||||
"test 6"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_derivative() {
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-2), Rational(2)),
|
|
||||||
Polynomial(Rational(1), Rational(-2), Rational(1)).derivative(RationalField),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-8, 3), Rational(8, 9), Rational(15, 7), Rational(-20, 9)),
|
|
||||||
Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).derivative(RationalField),
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(8, 9), Rational(15, 7), Rational(-20, 9)),
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).derivative(RationalField),
|
|
||||||
"test 3"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-8, 3), Rational(8, 9), Rational(15, 7)),
|
|
||||||
Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(0)).derivative(RationalField),
|
|
||||||
"test 4"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_nthDerivative() {
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(-2), Rational(2)),
|
|
||||||
Polynomial(Rational(1), Rational(-2), Rational(1)).nthDerivative(RationalField, 1),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertFailsWith<IllegalArgumentException>("test2") {
|
|
||||||
Polynomial(Rational(1), Rational(-2), Rational(1)).nthDerivative(RationalField, -1)
|
|
||||||
}
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(1), Rational(-2), Rational(1)),
|
|
||||||
Polynomial(Rational(1), Rational(-2), Rational(1)).nthDerivative(RationalField, 0),
|
|
||||||
"test 3"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(2)),
|
|
||||||
Polynomial(Rational(1), Rational(-2), Rational(1)).nthDerivative(RationalField, 2),
|
|
||||||
"test 4"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Polynomial(Rational(1), Rational(-2), Rational(1)).nthDerivative(RationalField, 3),
|
|
||||||
"test 5"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(),
|
|
||||||
Polynomial(Rational(1), Rational(-2), Rational(1)).nthDerivative(RationalField, 4),
|
|
||||||
"test 6"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(8, 9), Rational(30, 7), Rational(-20, 3)),
|
|
||||||
Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).nthDerivative(RationalField, 2),
|
|
||||||
"test 7"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(8, 9), Rational(30, 7), Rational(-20, 3)),
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).nthDerivative(RationalField, 2),
|
|
||||||
"test 8"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(8, 9), Rational(30, 7)),
|
|
||||||
Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(0)).nthDerivative(RationalField, 2),
|
|
||||||
"test 9"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_antiderivative() {
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(1), Rational(-1), Rational(1, 3)),
|
|
||||||
Polynomial(Rational(1), Rational(-2), Rational(1)).antiderivative(RationalField),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(1, 5), Rational(-4, 3), Rational(4, 27), Rational(5, 28), Rational(-1, 9)),
|
|
||||||
Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).antiderivative(RationalField),
|
|
||||||
"test 2"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(0), Rational(4, 27), Rational(5, 28), Rational(-1, 9)),
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).antiderivative(RationalField),
|
|
||||||
"test 3"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(1, 5), Rational(-4, 3), Rational(4, 27), Rational(5, 28)),
|
|
||||||
Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(0)).antiderivative(RationalField),
|
|
||||||
"test 4"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@Test
|
|
||||||
fun test_nthAntiderivative() {
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(1), Rational(-1), Rational(1, 3)),
|
|
||||||
Polynomial(Rational(1), Rational(-2), Rational(1)).nthAntiderivative(RationalField, 1),
|
|
||||||
"test 1"
|
|
||||||
)
|
|
||||||
assertFailsWith<IllegalArgumentException>("test2") {
|
|
||||||
Polynomial(Rational(1), Rational(-2), Rational(1)).nthAntiderivative(RationalField, -1)
|
|
||||||
}
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(1), Rational(-2), Rational(1)),
|
|
||||||
Polynomial(Rational(1), Rational(-2), Rational(1)).nthAntiderivative(RationalField, 0),
|
|
||||||
"test 3"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(1, 2), Rational(-1, 3), Rational(1, 12)),
|
|
||||||
Polynomial(Rational(1), Rational(-2), Rational(1)).nthAntiderivative(RationalField, 2),
|
|
||||||
"test 4"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(0), Rational(1, 6), Rational(-1, 12), Rational(1, 60)),
|
|
||||||
Polynomial(Rational(1), Rational(-2), Rational(1)).nthAntiderivative(RationalField, 3),
|
|
||||||
"test 5"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(0), Rational(0), Rational(1, 24), Rational(-1, 60), Rational(1, 360)),
|
|
||||||
Polynomial(Rational(1), Rational(-2), Rational(1)).nthAntiderivative(RationalField, 4),
|
|
||||||
"test 6"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(1, 10), Rational(-4, 9), Rational(1, 27), Rational(1, 28), Rational(-1, 54)),
|
|
||||||
Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).nthAntiderivative(RationalField, 2),
|
|
||||||
"test 7"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(0), Rational(0), Rational(1, 27), Rational(1, 28), Rational(-1, 54)),
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).nthAntiderivative(RationalField, 2),
|
|
||||||
"test 8"
|
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
Polynomial(Rational(0), Rational(0), Rational(1, 10), Rational(-4, 9), Rational(1, 27), Rational(1, 28)),
|
|
||||||
Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(0)).nthAntiderivative(RationalField, 2),
|
|
||||||
"test 9"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
package space.kscience.kmath.integration
|
package space.kscience.kmath.integration
|
||||||
|
|
||||||
import space.kscience.kmath.functions.Polynomial
|
import space.kscience.kmath.functions.ListPolynomial
|
||||||
import space.kscience.kmath.functions.integrate
|
import space.kscience.kmath.functions.integrate
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.operations.DoubleField
|
import space.kscience.kmath.operations.DoubleField
|
||||||
@ -19,7 +19,7 @@ class SplineIntegralTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun integratePolynomial(){
|
fun integratePolynomial(){
|
||||||
val polynomial = Polynomial(1.0, 2.0, 3.0)
|
val polynomial = ListPolynomial(1.0, 2.0, 3.0)
|
||||||
val integral = polynomial.integrate(DoubleField,1.0..2.0)
|
val integral = polynomial.integrate(DoubleField,1.0..2.0)
|
||||||
assertEquals(11.0, integral, 0.001)
|
assertEquals(11.0, integral, 0.001)
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
package space.kscience.kmath.test.misc
|
package space.kscience.kmath.test.misc
|
||||||
|
|
||||||
import space.kscience.kmath.functions.Polynomial
|
import space.kscience.kmath.functions.ListPolynomial
|
||||||
import space.kscience.kmath.functions.PolynomialSpace
|
import space.kscience.kmath.functions.ListPolynomialSpace
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.operations.Ring
|
import space.kscience.kmath.operations.Ring
|
||||||
|
|
||||||
@ -134,9 +134,9 @@ class IntModuloRing : Ring<IntModulo> {
|
|||||||
inline fun IntModulo.div(arg: IntModulo): IntModulo = this / arg
|
inline fun IntModulo.div(arg: IntModulo): IntModulo = this / arg
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PolynomialSpace<IntModulo, IntModuloRing>.number(arg: Int) = IntModulo(arg, ring.modulus, toCheckInput = false)
|
fun ListPolynomialSpace<IntModulo, IntModuloRing>.number(arg: Int) = IntModulo(arg, ring.modulus, toCheckInput = false)
|
||||||
|
|
||||||
fun PolynomialSpace<IntModulo, IntModuloRing>.Polynomial(vararg coefs: Int): Polynomial<IntModulo> =
|
fun ListPolynomialSpace<IntModulo, IntModuloRing>.ListPolynomial(vararg coefs: Int): ListPolynomial<IntModulo> =
|
||||||
Polynomial(coefs.map { IntModulo(it, ring.modulus) })
|
ListPolynomial(coefs.map { IntModulo(it, ring.modulus) })
|
||||||
fun IntModuloRing.Polynomial(vararg coefs: Int): Polynomial<IntModulo> =
|
fun IntModuloRing.ListPolynomial(vararg coefs: Int): ListPolynomial<IntModulo> =
|
||||||
Polynomial(coefs.map { IntModulo(it, modulus) })
|
ListPolynomial(coefs.map { IntModulo(it, modulus) })
|
Loading…
Reference in New Issue
Block a user