Feature: Polynomials and rational functions #469
@ -121,7 +121,7 @@ class ListPolynomialUtilTest {
|
|||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
@Ignore // FIXME: This tests work only for sane realisations of the substitutions. Currently, it is not.
|
@Ignore // FIXME: This tests work only for sane realisations of the substitutions. Currently, it is not.
|
||||||
// Sane algorithm for substitution p(q/r) (p, q, and r are polynomials) should make denominator r^deg(p),
|
// Sane algorithm for substitution p(q/r) (p, q, and r are polynomials) should return denominator r^deg(p),
|
||||||
// not r^(deg(p)(deg(p)+1)/2) as it is now.
|
// not r^(deg(p)(deg(p)+1)/2) as it is now.
|
||||||
fun test_Polynomial_substitute_RationalFunction() {
|
fun test_Polynomial_substitute_RationalFunction() {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
@ -589,7 +589,7 @@ class ListPolynomialUtilTest {
|
|||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
@Ignore // FIXME: This tests work only for sane realisations of the substitutions. Currently, it is not.
|
@Ignore // FIXME: This tests work only for sane realisations of the substitutions. Currently, it is not.
|
||||||
// Sane algorithm for substitution p(q/r) (p, q, and r are polynomials) should make denominator r^deg(p),
|
// Sane algorithm for substitution p(q/r) (p, q, and r are polynomials) should return denominator r^deg(p),
|
||||||
// not r^(deg(p)(deg(p)+1)/2) as it is now.
|
// not r^(deg(p)(deg(p)+1)/2) as it is now.
|
||||||
fun test_RationalFunction_substitute_RationalFunction() {
|
fun test_RationalFunction_substitute_RationalFunction() {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -41,66 +41,105 @@ class Rational {
|
|||||||
|
|
||||||
operator fun unaryPlus(): Rational = this
|
operator fun unaryPlus(): Rational = this
|
||||||
operator fun unaryMinus(): Rational = Rational(-this.numerator, this.denominator)
|
operator fun unaryMinus(): Rational = Rational(-this.numerator, this.denominator)
|
||||||
operator fun plus(other: Rational): Rational =
|
operator fun plus(other: Rational): Rational {
|
||||||
Rational(
|
val denominatorsGcd = gcd(denominator, other.denominator)
|
||||||
numerator * other.denominator + denominator * other.numerator,
|
val dividedThisDenominator = denominator / denominatorsGcd
|
||||||
denominator * other.denominator
|
val dividedOtherDenominator = other.denominator / denominatorsGcd
|
||||||
|
val numeratorCandidate = numerator * dividedOtherDenominator + dividedThisDenominator * other.numerator
|
||||||
|
val secondGcd = gcd(numeratorCandidate, denominatorsGcd)
|
||||||
|
return Rational(
|
||||||
|
numeratorCandidate / secondGcd,
|
||||||
|
dividedThisDenominator * (other.denominator / secondGcd),
|
||||||
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
|
}
|
||||||
operator fun plus(other: Int): Rational =
|
operator fun plus(other: Int): Rational =
|
||||||
Rational(
|
Rational(
|
||||||
numerator + denominator * other.toLong(),
|
numerator + denominator * other.toLong(),
|
||||||
denominator
|
denominator,
|
||||||
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
operator fun plus(other: Long): Rational =
|
operator fun plus(other: Long): Rational =
|
||||||
Rational(
|
Rational(
|
||||||
numerator + denominator * other,
|
numerator + denominator * other,
|
||||||
denominator
|
denominator,
|
||||||
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
operator fun minus(other: Rational): Rational =
|
operator fun minus(other: Rational): Rational {
|
||||||
Rational(
|
val denominatorsGcd = gcd(denominator, other.denominator)
|
||||||
numerator * other.denominator - denominator * other.numerator,
|
val dividedThisDenominator = denominator / denominatorsGcd
|
||||||
denominator * other.denominator
|
val dividedOtherDenominator = other.denominator / denominatorsGcd
|
||||||
|
val numeratorCandidate = numerator * dividedOtherDenominator - dividedThisDenominator * other.numerator
|
||||||
|
val secondGcd = gcd(numeratorCandidate, denominatorsGcd)
|
||||||
|
return Rational(
|
||||||
|
numeratorCandidate / secondGcd,
|
||||||
|
dividedThisDenominator * (other.denominator / secondGcd),
|
||||||
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
|
}
|
||||||
operator fun minus(other: Int): Rational =
|
operator fun minus(other: Int): Rational =
|
||||||
Rational(
|
Rational(
|
||||||
numerator - denominator * other.toLong(),
|
numerator - denominator * other.toLong(),
|
||||||
denominator
|
denominator,
|
||||||
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
operator fun minus(other: Long): Rational =
|
operator fun minus(other: Long): Rational =
|
||||||
Rational(
|
Rational(
|
||||||
numerator - denominator * other,
|
numerator - denominator * other,
|
||||||
denominator
|
denominator,
|
||||||
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
operator fun times(other: Rational): Rational =
|
operator fun times(other: Rational): Rational {
|
||||||
Rational(
|
val thisDenominatorAndOtherNumeratorGcd = gcd(denominator, other.numerator)
|
||||||
numerator * other.numerator,
|
val otherDenominatorAndThisNumeratorGcd = gcd(other.denominator, numerator)
|
||||||
denominator * other.denominator
|
return Rational(
|
||||||
|
(numerator / otherDenominatorAndThisNumeratorGcd) * (other.numerator / thisDenominatorAndOtherNumeratorGcd),
|
||||||
|
(denominator / thisDenominatorAndOtherNumeratorGcd) * (other.denominator / otherDenominatorAndThisNumeratorGcd),
|
||||||
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
operator fun times(other: Int): Rational =
|
}
|
||||||
Rational(
|
operator fun times(other: Int): Rational {
|
||||||
numerator * other.toLong(),
|
val other = other.toLong()
|
||||||
denominator
|
val denominatorAndOtherGcd = gcd(denominator, other)
|
||||||
|
return Rational(
|
||||||
|
numerator * (other / denominatorAndOtherGcd),
|
||||||
|
denominator / denominatorAndOtherGcd,
|
||||||
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
operator fun times(other: Long): Rational =
|
}
|
||||||
Rational(
|
operator fun times(other: Long): Rational {
|
||||||
numerator * other,
|
val denominatorAndOtherGcd = gcd(denominator, other)
|
||||||
denominator
|
return Rational(
|
||||||
|
numerator * (other / denominatorAndOtherGcd),
|
||||||
|
denominator / denominatorAndOtherGcd,
|
||||||
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
operator fun div(other: Rational): Rational =
|
}
|
||||||
Rational(
|
operator fun div(other: Rational): Rational {
|
||||||
numerator * other.denominator,
|
val denominatorsGcd = gcd(denominator, other.denominator)
|
||||||
denominator * other.numerator
|
val numeratorsGcd = gcd(numerator, other.numerator)
|
||||||
|
return Rational(
|
||||||
|
(numerator / numeratorsGcd) * (other.denominator / denominatorsGcd),
|
||||||
|
(denominator / denominatorsGcd) * (other.numerator / numeratorsGcd)
|
||||||
)
|
)
|
||||||
operator fun div(other: Int): Rational =
|
}
|
||||||
Rational(
|
operator fun div(other: Int): Rational {
|
||||||
numerator,
|
val other = other.toLong()
|
||||||
denominator * other.toLong()
|
val numeratorAndOtherGcd = gcd(numerator, other)
|
||||||
|
return Rational(
|
||||||
|
numerator / numeratorAndOtherGcd,
|
||||||
|
denominator * (other / numeratorAndOtherGcd),
|
||||||
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
operator fun div(other: Long): Rational =
|
}
|
||||||
Rational(
|
operator fun div(other: Long): Rational {
|
||||||
numerator,
|
val numeratorAndOtherGcd = gcd(numerator, other)
|
||||||
denominator * other
|
return Rational(
|
||||||
|
numerator / numeratorAndOtherGcd,
|
||||||
|
denominator * (other / numeratorAndOtherGcd),
|
||||||
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
|
}
|
||||||
override fun equals(other: Any?): Boolean =
|
override fun equals(other: Any?): Boolean =
|
||||||
when (other) {
|
when (other) {
|
||||||
is Rational -> numerator == other.numerator && denominator == other.denominator
|
is Rational -> numerator == other.numerator && denominator == other.denominator
|
||||||
|
@ -5,10 +5,44 @@
|
|||||||
|
|
||||||
package space.kscience.kmath.test.misc
|
package space.kscience.kmath.test.misc
|
||||||
|
|
||||||
|
import space.kscience.kmath.functions.NumberedPolynomial
|
||||||
|
import space.kscience.kmath.functions.NumberedRationalFunction
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
|
||||||
fun <T> assertContentEquals(expected: Map<T, Double>, actual: Map<T, Double>, absoluteTolerance: Double, message: String? = null) {
|
fun <T> assertContentEquals(expected: Map<T, Double>, actual: Map<T, Double>, absoluteTolerance: Double, message: String? = null) {
|
||||||
assertEquals(expected.keys, actual.keys, message)
|
assertEquals(expected.keys, actual.keys, message)
|
||||||
for ((key, expectedValue) in expected) assertEquals(expectedValue, actual[key]!!, absoluteTolerance, message)
|
for ((key, expectedValue) in expected) assertEquals(expectedValue, actual[key]!!, absoluteTolerance, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun assertEquals(
|
||||||
|
expected: NumberedPolynomial<Double>,
|
||||||
|
actual: NumberedPolynomial<Double>,
|
||||||
|
absoluteTolerance: Double,
|
||||||
|
message: String? = null
|
||||||
|
) = assertContentEquals(
|
||||||
|
expected.coefficients,
|
||||||
|
actual.coefficients,
|
||||||
|
absoluteTolerance,
|
||||||
|
message
|
||||||
|
)
|
||||||
|
|
||||||
|
fun assertEquals(
|
||||||
|
expected: NumberedRationalFunction<Double>,
|
||||||
|
actual: NumberedRationalFunction<Double>,
|
||||||
|
absoluteTolerance: Double,
|
||||||
|
message: String? = null
|
||||||
|
) {
|
||||||
|
assertEquals(
|
||||||
|
expected.numerator,
|
||||||
|
actual.numerator,
|
||||||
|
absoluteTolerance,
|
||||||
|
message
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
expected.denominator,
|
||||||
|
actual.denominator,
|
||||||
|
absoluteTolerance,
|
||||||
|
message
|
||||||
|
)
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user