Feature: Polynomials and rational functions #469
@ -121,7 +121,7 @@ class ListPolynomialUtilTest {
|
||||
}
|
||||
@Test
|
||||
@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.
|
||||
fun test_Polynomial_substitute_RationalFunction() {
|
||||
assertEquals(
|
||||
@ -589,7 +589,7 @@ class ListPolynomialUtilTest {
|
||||
}
|
||||
@Test
|
||||
@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.
|
||||
fun test_RationalFunction_substitute_RationalFunction() {
|
||||
assertEquals(
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -41,66 +41,105 @@ class Rational {
|
||||
|
||||
operator fun unaryPlus(): Rational = this
|
||||
operator fun unaryMinus(): Rational = Rational(-this.numerator, this.denominator)
|
||||
operator fun plus(other: Rational): Rational =
|
||||
Rational(
|
||||
numerator * other.denominator + denominator * other.numerator,
|
||||
denominator * other.denominator
|
||||
operator fun plus(other: Rational): Rational {
|
||||
val denominatorsGcd = gcd(denominator, other.denominator)
|
||||
val dividedThisDenominator = denominator / denominatorsGcd
|
||||
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 =
|
||||
Rational(
|
||||
numerator + denominator * other.toLong(),
|
||||
denominator
|
||||
denominator,
|
||||
toCheckInput = false
|
||||
)
|
||||
operator fun plus(other: Long): Rational =
|
||||
Rational(
|
||||
numerator + denominator * other,
|
||||
denominator
|
||||
denominator,
|
||||
toCheckInput = false
|
||||
)
|
||||
operator fun minus(other: Rational): Rational =
|
||||
Rational(
|
||||
numerator * other.denominator - denominator * other.numerator,
|
||||
denominator * other.denominator
|
||||
operator fun minus(other: Rational): Rational {
|
||||
val denominatorsGcd = gcd(denominator, other.denominator)
|
||||
val dividedThisDenominator = denominator / denominatorsGcd
|
||||
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 =
|
||||
Rational(
|
||||
numerator - denominator * other.toLong(),
|
||||
denominator
|
||||
denominator,
|
||||
toCheckInput = false
|
||||
)
|
||||
operator fun minus(other: Long): Rational =
|
||||
Rational(
|
||||
numerator - denominator * other,
|
||||
denominator
|
||||
denominator,
|
||||
toCheckInput = false
|
||||
)
|
||||
operator fun times(other: Rational): Rational =
|
||||
Rational(
|
||||
numerator * other.numerator,
|
||||
denominator * other.denominator
|
||||
operator fun times(other: Rational): Rational {
|
||||
val thisDenominatorAndOtherNumeratorGcd = gcd(denominator, other.numerator)
|
||||
val otherDenominatorAndThisNumeratorGcd = gcd(other.denominator, numerator)
|
||||
return Rational(
|
||||
(numerator / otherDenominatorAndThisNumeratorGcd) * (other.numerator / thisDenominatorAndOtherNumeratorGcd),
|
||||
(denominator / thisDenominatorAndOtherNumeratorGcd) * (other.denominator / otherDenominatorAndThisNumeratorGcd),
|
||||
toCheckInput = false
|
||||
)
|
||||
operator fun times(other: Int): Rational =
|
||||
Rational(
|
||||
numerator * other.toLong(),
|
||||
denominator
|
||||
}
|
||||
operator fun times(other: Int): Rational {
|
||||
val other = other.toLong()
|
||||
val denominatorAndOtherGcd = gcd(denominator, other)
|
||||
return Rational(
|
||||
numerator * (other / denominatorAndOtherGcd),
|
||||
denominator / denominatorAndOtherGcd,
|
||||
toCheckInput = false
|
||||
)
|
||||
operator fun times(other: Long): Rational =
|
||||
Rational(
|
||||
numerator * other,
|
||||
denominator
|
||||
}
|
||||
operator fun times(other: Long): Rational {
|
||||
val denominatorAndOtherGcd = gcd(denominator, other)
|
||||
return Rational(
|
||||
numerator * (other / denominatorAndOtherGcd),
|
||||
denominator / denominatorAndOtherGcd,
|
||||
toCheckInput = false
|
||||
)
|
||||
operator fun div(other: Rational): Rational =
|
||||
Rational(
|
||||
numerator * other.denominator,
|
||||
denominator * other.numerator
|
||||
}
|
||||
operator fun div(other: Rational): Rational {
|
||||
val denominatorsGcd = gcd(denominator, other.denominator)
|
||||
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(
|
||||
numerator,
|
||||
denominator * other.toLong()
|
||||
}
|
||||
operator fun div(other: Int): Rational {
|
||||
val other = other.toLong()
|
||||
val numeratorAndOtherGcd = gcd(numerator, other)
|
||||
return Rational(
|
||||
numerator / numeratorAndOtherGcd,
|
||||
denominator * (other / numeratorAndOtherGcd),
|
||||
toCheckInput = false
|
||||
)
|
||||
operator fun div(other: Long): Rational =
|
||||
Rational(
|
||||
numerator,
|
||||
denominator * other
|
||||
}
|
||||
operator fun div(other: Long): Rational {
|
||||
val numeratorAndOtherGcd = gcd(numerator, other)
|
||||
return Rational(
|
||||
numerator / numeratorAndOtherGcd,
|
||||
denominator * (other / numeratorAndOtherGcd),
|
||||
toCheckInput = false
|
||||
)
|
||||
}
|
||||
override fun equals(other: Any?): Boolean =
|
||||
when (other) {
|
||||
is Rational -> numerator == other.numerator && denominator == other.denominator
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
package space.kscience.kmath.test.misc
|
||||
|
||||
import space.kscience.kmath.functions.NumberedPolynomial
|
||||
import space.kscience.kmath.functions.NumberedRationalFunction
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
||||
@ -12,3 +14,35 @@ fun <T> assertContentEquals(expected: Map<T, Double>, actual: Map<T, Double>, ab
|
||||
assertEquals(expected.keys, actual.keys, 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