From 90a7c4d901d6383b2de5326b0fa852f27bc47320 Mon Sep 17 00:00:00 2001 From: Gleb Minaev <43728100+lounres@users.noreply.github.com> Date: Sat, 19 Mar 2022 18:08:43 +0300 Subject: [PATCH] Simplified use of Rational (current BigInt are hard to use and actually useless). Added tests, fixed bug. --- .../kmath/functions/NumberedPolynomial.kt | 8 +- .../kscience/kmath/functions/Polynomial.kt | 2 +- .../kmath/functions/PolynomialTest.kt | 225 +++++++++-- .../kscience/kmath/test/misc/Rational.kt | 348 +++--------------- .../test/misc/RationalWithMemorization.kt | 42 +-- .../space/kscience/kmath/test/misc/misc.kt | 17 +- 6 files changed, 268 insertions(+), 374 deletions(-) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/NumberedPolynomial.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/NumberedPolynomial.kt index 88349f003..c05bc30ec 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/NumberedPolynomial.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/NumberedPolynomial.kt @@ -246,7 +246,7 @@ public open class NumberedPolynomialSpace>( override operator fun C.minus(other: NumberedPolynomial): NumberedPolynomial = if (this.isZero()) -other else with(other.coefficients) { - if (isEmpty()) NumberedPolynomial(mapOf(listOf() to this@minus)) + if (isEmpty()) NumberedPolynomial(mapOf(emptyList() to this@minus)) else NumberedPolynomial( toMutableMap() .apply { @@ -279,7 +279,7 @@ public open class NumberedPolynomialSpace>( override operator fun NumberedPolynomial.plus(other: C): NumberedPolynomial = if (other.isZero()) this else with(coefficients) { - if (isEmpty()) NumberedPolynomial(mapOf(listOf() to other)) + if (isEmpty()) NumberedPolynomial(mapOf(emptyList() to other)) else NumberedPolynomial( toMutableMap() .apply { @@ -298,7 +298,7 @@ public open class NumberedPolynomialSpace>( override operator fun NumberedPolynomial.minus(other: C): NumberedPolynomial = if (other.isZero()) this else with(coefficients) { - if (isEmpty()) NumberedPolynomial(mapOf(listOf() to other)) + if (isEmpty()) NumberedPolynomial(mapOf(emptyList() to other)) else NumberedPolynomial( toMutableMap() .apply { @@ -416,7 +416,7 @@ public open class NumberedPolynomialSpace>( override val one: NumberedPolynomial = NumberedPolynomial( mapOf( - listOf() to constantOne // 1 * x_1^0 * x_2^0 * ... + emptyList() to constantOne // 1 * x_1^0 * x_2^0 * ... ) ) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt index 3f0d073b3..722566f5d 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt @@ -276,7 +276,7 @@ public open class PolynomialSpace>( public override operator fun Polynomial.minus(other: C): Polynomial = if (other.isZero()) this else with(coefficients) { - if (isEmpty()) Polynomial(listOf(other)) + if (isEmpty()) Polynomial(listOf(-other)) else Polynomial( toMutableList() .apply { diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialTest.kt index 9e3dea615..e2970d953 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialTest.kt @@ -5,16 +5,173 @@ package space.kscience.kmath.functions -import space.kscience.kmath.operations.BigInt import space.kscience.kmath.operations.algebra -import space.kscience.kmath.operations.toBigInt import space.kscience.kmath.test.misc.Rational import space.kscience.kmath.test.misc.RationalField -import space.kscience.kmath.test.misc.gcd import kotlin.test.Test import kotlin.test.assertEquals 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() + 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() + 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() - 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() - 2, + "test 7" + ) + } + } + @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(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(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(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(2), + "test 7" + ) + } + } @Test fun test_Polynomial_Polynomial_plus() { RationalField.polynomial { @@ -48,35 +205,39 @@ class PolynomialTest { ) } } -// @Test -// fun test_Polynomial_Polynomial_minus() { -// RationalField.polynomial { -// assertEquals( -// Polynomial(Rational(1, 2), Rational(3, 5), Rational(-2)) + -// Polynomial(Rational(3), Rational(7, 8), Rational(1, 9)), -// Polynomial(Rational(7, 2), Rational(59, 40), Rational(-17, 9)), -// "test 1" -// ) -// assertEquals( -// Polynomial(Rational(1, 2), Rational(3, 5)) + -// Polynomial(Rational(3), Rational(7, 8), Rational(1, 9)), -// Polynomial(Rational(7, 2), Rational(59, 40), Rational(1, 9)), -// "test 2" -// ) -// assertEquals( -// Polynomial(Rational(1, 2), Rational(3, 5), Rational(0), Rational(0)) + -// Polynomial(Rational(3), Rational(7, 8), Rational(1, 9)), -// Polynomial(Rational(7, 2), Rational(59, 40), Rational(1, 9)), -// "test 3" -// ) -// assertEquals( -// Polynomial(Rational(1, 2), Rational(-3, 5), Rational(7, 3)) + -// Polynomial(Rational(3), Rational(3, 5), Rational(-7, 3)), -// Polynomial(Rational(7, 2)), -// "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 simple_polynomial_test() { val polynomial : Polynomial diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/test/misc/Rational.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/test/misc/Rational.kt index fad13f88a..842e354db 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/test/misc/Rational.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/test/misc/Rational.kt @@ -6,54 +6,23 @@ package space.kscience.kmath.test.misc import space.kscience.kmath.misc.UnstableKMathAPI -import space.kscience.kmath.operations.BigInt import space.kscience.kmath.operations.Field import space.kscience.kmath.operations.NumbersAddOps -import space.kscience.kmath.operations.toBigInt -import space.kscience.kmath.operations.BigInt.Companion.ZERO as I0 -import space.kscience.kmath.operations.BigInt.Companion.ONE as I1 -/** - * The class represents rational numbers. - * - * Instances contain [numerator] and [denominator] represented as [Long]. - * - * Also [numerator] and [denominator] are coprime and [denominator] is positive. - * - * @author [Gleb Minaev](https://github.com/lounres) - */ -public class Rational: Comparable { - public companion object { - /** - * Constant containing the zero (the additive identity) of the [Rational] field. - */ - public val ZERO: Rational = Rational(I0) - /** - * Constant containing the one (the multiplicative identity) of the [Rational] field. - */ - public val ONE: Rational = Rational(I1) +class Rational { + companion object { + val ZERO: Rational = Rational(0L) + val ONE: Rational = Rational(1L) } - /** - * Numerator of the fraction. It's stored as non-negative coprime with [denominator] integer. - */ - public val numerator: BigInt - /** - * Denominator of the fraction. It's stored as non-zero coprime with [numerator] integer. - */ - public val denominator: BigInt + val numerator: Long + val denominator: Long - /** - * If [toCheckInput] is `true` before assigning values to [Rational.numerator] and [Rational.denominator] makes them coprime and makes - * denominator positive. Otherwise, just assigns the values. - * - * @throws ArithmeticException If denominator is zero. - */ - internal constructor(numerator: BigInt, denominator: BigInt, toCheckInput: Boolean = true) { + internal constructor(numerator: Long, denominator: Long, toCheckInput: Boolean = true) { if (toCheckInput) { - if (denominator == I0) throw ArithmeticException("/ by zero") + if (denominator == 0L) throw ArithmeticException("/ by zero") - val greatestCommonDivider = gcd(numerator, denominator).let { if (denominator < I0) -it else it } + val greatestCommonDivider = gcd(numerator, denominator).let { if (denominator < 0L) -it else it } this.numerator = numerator / greatestCommonDivider this.denominator = denominator / greatestCommonDivider @@ -63,303 +32,86 @@ public class Rational: Comparable { } } - /** - * Before assigning values to [Rational.numerator] and [Rational.denominator] makes them coprime and makes - * denominator positive. - * - * @throws ArithmeticException If denominator is zero. - */ - public constructor(numerator: BigInt, denominator: BigInt) : this(numerator, denominator, true) - public constructor(numerator: Int, denominator: BigInt) : this(numerator.toBigInt(), denominator, true) - public constructor(numerator: Long, denominator: BigInt) : this(numerator.toBigInt(), denominator, true) - public constructor(numerator: BigInt, denominator: Int) : this(numerator, denominator.toBigInt(), true) - public constructor(numerator: BigInt, denominator: Long) : this(numerator, denominator.toBigInt(), true) - public constructor(numerator: Int, denominator: Int) : this(numerator.toBigInt(), denominator.toBigInt(), true) - public constructor(numerator: Int, denominator: Long) : this(numerator.toBigInt(), denominator.toBigInt(), true) - public constructor(numerator: Long, denominator: Int) : this(numerator.toBigInt(), denominator.toBigInt(), true) - public constructor(numerator: Long, denominator: Long) : this(numerator.toBigInt(), denominator.toBigInt(), true) - public constructor(numerator: BigInt) : this(numerator, I1, false) - public constructor(numerator: Int) : this(numerator.toBigInt(), I1, false) - public constructor(numerator: Long) : this(numerator.toBigInt(), I1, false) + constructor(numerator: Int, denominator: Int) : this(numerator.toLong(), denominator.toLong(), true) + constructor(numerator: Int, denominator: Long) : this(numerator.toLong(), denominator, true) + constructor(numerator: Long, denominator: Int) : this(numerator, denominator.toLong(), true) + constructor(numerator: Long, denominator: Long) : this(numerator, denominator, true) + constructor(numerator: Int) : this(numerator.toLong(), 1L, false) + constructor(numerator: Long) : this(numerator, 1L, false) - /** - * Returns the same instant. - */ - public operator fun unaryPlus(): Rational = this - - /** - * Returns negation of the instant of [Rational] field. - */ - public operator fun unaryMinus(): Rational = Rational(-this.numerator, this.denominator) - - /** - * Returns sum of the instants of [Rational] field. - */ - public operator fun plus(other: Rational): 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 ) - - /** - * Returns sum of the instants of [Rational] field. [other] is represented as [Rational]. - */ - public operator fun plus(other: BigInt): Rational = + operator fun plus(other: Int): Rational = + Rational( + numerator + denominator * other.toLong(), + denominator + ) + operator fun plus(other: Long): Rational = Rational( numerator + denominator * other, denominator ) - - /** - * Returns sum of the instants of [Rational] field. [other] is represented as [Rational]. - */ - public operator fun plus(other: Int): Rational = - Rational( - numerator + denominator * other.toBigInt(), - denominator - ) - - /** - * Returns sum of the instants of [Rational] field. [other] is represented as [Rational]. - */ - public operator fun plus(other: Long): Rational = - Rational( - numerator + denominator * other.toBigInt(), - denominator - ) - - /** - * Returns difference of the instants of [Rational] field. - */ - public operator fun minus(other: Rational): Rational = + operator fun minus(other: Rational): Rational = Rational( numerator * other.denominator - denominator * other.numerator, denominator * other.denominator ) - - /** - * Returns difference of the instants of [Rational] field. [other] is represented as [Rational]. - */ - public operator fun minus(other: BigInt): Rational = + operator fun minus(other: Int): Rational = + Rational( + numerator - denominator * other.toLong(), + denominator + ) + operator fun minus(other: Long): Rational = Rational( numerator - denominator * other, denominator ) - - /** - * Returns difference of the instants of [Rational] field. [other] is represented as [Rational]. - */ - public operator fun minus(other: Int): Rational = - Rational( - numerator - denominator * other.toBigInt(), - denominator - ) - - /** - * Returns difference of the instants of [Rational] field. [other] is represented as [Rational]. - */ - public operator fun minus(other: Long): Rational = - Rational( - numerator - denominator * other.toBigInt(), - denominator - ) - - /** - * Returns product of the instants of [Rational] field. - */ - public operator fun times(other: Rational): Rational = + operator fun times(other: Rational): Rational = Rational( numerator * other.numerator, denominator * other.denominator ) - - /** - * Returns product of the instants of [Rational] field. [other] is represented as [Rational]. - */ - public operator fun times(other: BigInt): Rational = + operator fun times(other: Int): Rational = + Rational( + numerator * other.toLong(), + denominator + ) + operator fun times(other: Long): Rational = Rational( numerator * other, denominator ) - - /** - * Returns product of the instants of [Rational] field. [other] is represented as [Rational]. - */ - public operator fun times(other: Int): Rational = - Rational( - numerator * other.toBigInt(), - denominator - ) - - /** - * Returns product of the instants of [Rational] field. [other] is represented as [Rational]. - */ - public operator fun times(other: Long): Rational = - Rational( - numerator * other.toBigInt(), - denominator - ) - - /** - * Returns quotient of the instants of [Rational] field. - * - * @throws ArithmeticException if [other] is the zero of the field it can't be a divisor. - */ - public operator fun div(other: Rational): Rational = + operator fun div(other: Rational): Rational = Rational( numerator * other.denominator, denominator * other.numerator ) - - /** - * Returns quotient of the instants of [Rational] field. [other] is represented as [Rational]. - * - * @throws ArithmeticException if [other] is the zero of the field it can't be a divisor. - */ - public operator fun div(other: BigInt): Rational = + operator fun div(other: Int): Rational = + Rational( + numerator, + denominator * other.toLong() + ) + operator fun div(other: Long): Rational = Rational( numerator, denominator * other ) - - /** - * Returns quotient of the instants of [Rational] field. [other] is represented as [Rational]. - * - * @throws ArithmeticException if [other] is the zero of the field it can't be a divisor. - */ - public operator fun div(other: Int): Rational = - Rational( - numerator, - denominator * other.toBigInt() - ) - - /** - * Returns quotient of the instants of [Rational] field. [other] is represented as [Rational]. - * - * @throws ArithmeticException if [other] is the zero of the field it can't be a divisor. - */ - public operator fun div(other: Long): Rational = - Rational( - numerator, - denominator * other.toBigInt() - ) - - /** - * Returns reminder from integral division. - * - * @throws ArithmeticException if [other] is the zero of the field it can't be a divisor. - */ - public operator fun rem(other: Rational): Rational = - Rational( - (numerator * other.denominator) % (denominator * other.numerator), - denominator * other.denominator - ) - - /** - * Returns reminder from integral division. - * - * @throws ArithmeticException if [other] is the zero of the field it can't be a divisor. - */ - public operator fun rem(other: BigInt): Rational = - Rational( - numerator % denominator * other, - denominator * other - ) - - /** - * Returns reminder from integral division. - * - * @throws ArithmeticException if [other] is the zero of the field it can't be a divisor. - */ - public operator fun rem(other: Int): Rational = - Rational( - numerator % denominator * other.toBigInt(), - denominator * other.toBigInt() - ) - - /** - * Returns reminder from integral division. - * - * @throws ArithmeticException if [other] is the zero of the field it can't be a divisor. - */ - public operator fun rem(other: Long): Rational = - Rational( - numerator % denominator * other.toBigInt(), - denominator * other.toBigInt() - ) - - /** - * Checks equality of the instance to [other]. - * - * [BigInt], [Int] and [Long] values are also checked as Rational ones. - */ override fun equals(other: Any?): Boolean = when (other) { is Rational -> numerator == other.numerator && denominator == other.denominator - is BigInt -> numerator == other && denominator == I1 - is Int -> numerator == other && denominator == I1 - is Long -> numerator == other && denominator == I1 + is Int -> numerator == other && denominator == 1L + is Long -> numerator == other && denominator == 1L else -> false } - /** - * Compares the instance to [other] as [Comparable.compareTo]. - * - * @see Comparable.compareTo - */ - override operator fun compareTo(other: Rational): Int = (numerator * other.denominator).compareTo(other.numerator * denominator) + override fun hashCode(): Int = 31 * numerator.hashCode() + denominator.hashCode() - /** - * Compares the instance to [other] as [Comparable.compareTo]. - * - * [Integer] values are also checked as Rational ones. - * - * @see Comparable.compareTo - */ - public operator fun compareTo(other: BigInt): Int = (numerator).compareTo(denominator * other) - - /** - * Compares the instance to [other] as [Comparable.compareTo]. - * - * [Int] values are also checked as Rational ones. - * - * @see Comparable.compareTo - */ - public operator fun compareTo(other: Int): Int = (numerator).compareTo(denominator * other.toBigInt()) - - /** - * Compares the instance to [other] as [Comparable.compareTo]. - * - * [Long] values are also checked as Rational ones. - * - * @see Comparable.compareTo - */ - public operator fun compareTo(other: Long): Int = (numerator).compareTo(denominator * other.toBigInt()) - - public override fun hashCode(): Int = 31 * numerator.hashCode() + denominator.hashCode() - -// /** Creates a range from this value to the specified [other] value. */ -// operator fun rangeTo(other: JBInt) = ClosedRationalRange(this, other.toRational()) -// /** Creates a range from this value to the specified [other] value. */ -// operator fun rangeTo(other: Rational) = ClosedRationalRange(this, other) -// /** Creates a range from this value to the specified [other] value. */ -// operator fun rangeTo(other: Int) = ClosedRationalRange(this, other.toRational()) -// /** Creates a range from this value to the specified [other] value. */ -// operator fun rangeTo(other: Long) = ClosedRationalRange(this, other.toRational()) - - public fun toRational(): Rational = this - - public fun toBigInt(): BigInt = numerator / denominator - -// public fun toInt(): Int = (numerator / denominator).toInt() -// -// public fun toLong(): Long = (numerator / denominator).toLong() -// -// public fun toDouble(): Double = (numerator.toDouble() / denominator.toDouble()) -// -// public fun toFloat(): Float = (numerator.toFloat() / denominator.toFloat()) - - public override fun toString(): String = if (denominator == I1) "$numerator" else "$numerator/$denominator" + override fun toString(): String = if (denominator == 1L) "$numerator" else "$numerator/$denominator" } @@ -368,7 +120,7 @@ public class Rational: Comparable { */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") @OptIn(UnstableKMathAPI::class) -public object RationalField : Field, NumbersAddOps { +object RationalField : Field, NumbersAddOps { override inline val zero: Rational get() = Rational.ZERO override inline val one: Rational get() = Rational.ONE diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/test/misc/RationalWithMemorization.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/test/misc/RationalWithMemorization.kt index 6aa5ecc09..05d9115fa 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/test/misc/RationalWithMemorization.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/test/misc/RationalWithMemorization.kt @@ -12,7 +12,7 @@ class RationalWithMemorization private constructor( val value: Rational, override val memory : OperationsMemory ): WithMemorization { - public companion object { + companion object { /** * Constant containing the zero (the additive identity) of the [Rational] field. */ @@ -22,48 +22,42 @@ class RationalWithMemorization private constructor( */ public val ONE: RationalWithMemorization = RationalWithMemorization(Rational.ONE, object : Endpoint {}) } - public constructor(numerator: BigInt, denominator: BigInt) : this(Rational(numerator, denominator), object : Endpoint {}) - public constructor(numerator: Int, denominator: BigInt) : this(Rational(numerator, denominator), object : Endpoint {}) - public constructor(numerator: Long, denominator: BigInt) : this(Rational(numerator, denominator), object : Endpoint {}) - public constructor(numerator: BigInt, denominator: Int) : this(Rational(numerator, denominator), object : Endpoint {}) - public constructor(numerator: BigInt, denominator: Long) : this(Rational(numerator, denominator), object : Endpoint {}) - public constructor(numerator: Int, denominator: Int) : this(Rational(numerator, denominator), object : Endpoint {}) - public constructor(numerator: Int, denominator: Long) : this(Rational(numerator, denominator), object : Endpoint {}) - public constructor(numerator: Long, denominator: Int) : this(Rational(numerator, denominator), object : Endpoint {}) - public constructor(numerator: Long, denominator: Long) : this(Rational(numerator, denominator), object : Endpoint {}) - public constructor(numerator: BigInt) : this(Rational(numerator), object : Endpoint {}) - public constructor(numerator: Int) : this(Rational(numerator), object : Endpoint {}) - public constructor(numerator: Long) : this(Rational(numerator), object : Endpoint {}) + constructor(numerator: Int, denominator: Int) : this(Rational(numerator, denominator), object : Endpoint {}) + constructor(numerator: Int, denominator: Long) : this(Rational(numerator, denominator), object : Endpoint {}) + constructor(numerator: Long, denominator: Int) : this(Rational(numerator, denominator), object : Endpoint {}) + constructor(numerator: Long, denominator: Long) : this(Rational(numerator, denominator), object : Endpoint {}) + constructor(numerator: Int) : this(Rational(numerator), object : Endpoint {}) + constructor(numerator: Long) : this(Rational(numerator), object : Endpoint {}) - public operator fun unaryPlus(): RationalWithMemorization = this - public operator fun unaryMinus(): RationalWithMemorization = RationalWithMemorization( + operator fun unaryPlus(): RationalWithMemorization = this + operator fun unaryMinus(): RationalWithMemorization = RationalWithMemorization( -value, object : Negation { override val negated: OperationsMemory = memory } ) - public operator fun plus(other: RationalWithMemorization): RationalWithMemorization = RationalWithMemorization( + operator fun plus(other: RationalWithMemorization): RationalWithMemorization = RationalWithMemorization( value + other.value, object : Sum { override val augend: OperationsMemory = memory override val addend: OperationsMemory = other.memory } ) - public operator fun minus(other: RationalWithMemorization): RationalWithMemorization = RationalWithMemorization( + operator fun minus(other: RationalWithMemorization): RationalWithMemorization = RationalWithMemorization( value - other.value, object : Difference { override val minuend: OperationsMemory = memory override val subtrahend: OperationsMemory = other.memory } ) - public operator fun times(other: RationalWithMemorization): RationalWithMemorization = RationalWithMemorization( + operator fun times(other: RationalWithMemorization): RationalWithMemorization = RationalWithMemorization( value * other.value, object : Product { override val multiplicand: OperationsMemory = memory override val multiplier: OperationsMemory = other.memory } ) - public operator fun div(other: RationalWithMemorization): RationalWithMemorization = RationalWithMemorization( + operator fun div(other: RationalWithMemorization): RationalWithMemorization = RationalWithMemorization( value / other.value, object : Quotient { override val dividend: OperationsMemory = memory @@ -71,16 +65,16 @@ class RationalWithMemorization private constructor( } ) - public override fun equals(other: Any?): Boolean = + override fun equals(other: Any?): Boolean = other is RationalWithMemorization && value == other.value - public override fun hashCode(): Int = value.hashCode() + override fun hashCode(): Int = value.hashCode() - public override fun toString(): String = value.toString() + override fun toString(): String = value.toString() } @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") -public object RationalWithMemorizationRing : Ring { +object RationalWithMemorizationRing : Ring { override inline val zero: RationalWithMemorization get() = RationalWithMemorization.ZERO override inline val one: RationalWithMemorization get() = RationalWithMemorization.ONE @@ -94,7 +88,7 @@ public object RationalWithMemorizationRing : Ring { } @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") -public object RationalWithMemorizationField : Field { +object RationalWithMemorizationField : Field { override inline val zero: RationalWithMemorization get() = RationalWithMemorization.ZERO override inline val one: RationalWithMemorization get() = RationalWithMemorization.ONE diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/test/misc/misc.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/test/misc/misc.kt index eab29842c..2eb421024 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/test/misc/misc.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/test/misc/misc.kt @@ -5,21 +5,8 @@ package space.kscience.kmath.test.misc -import space.kscience.kmath.operations.* -import space.kscience.kmath.operations.BigInt.Companion.ZERO as I0 +import kotlin.math.abs // TODO: Move to corresponding module "kmath-number-theory" -/** - * Computes [Greatest Common Divisor](https://en.wikipedia.org/wiki/Greatest_common_divisor) of [a] and [b]. - * - * It's computed by [Euclidean algorithm](https://en.wikipedia.org/wiki/Greatest_common_divisor#Euclidean_algorithm). - * Hence, its time complexity is $$O(\log(a+b))$$ (see [Wolfram MathWorld](https://mathworld.wolfram.com/EuclideanAlgorithm.html)). - */ -public tailrec fun gcd(a: BigInt, b: BigInt): BigInt = if (a == I0) abs(b) else gcd(b % a, a) - -/** - * Computes [Greatest Common Divisor](https://en.wikipedia.org/wiki/Greatest_common_divisor) of the [values]. - */ -public fun gcd(vararg values: BigInt): BigInt = values.reduce(::gcd) -public fun gcd(values: Iterable): BigInt = values.reduce(::gcd) \ No newline at end of file +tailrec fun gcd(a: Long, b: Long): Long = if (a == 0L) abs(b) else gcd(b % a, a) \ No newline at end of file