From 2f9e5043577d798f1330c20da497bb44eb66c617 Mon Sep 17 00:00:00 2001 From: Gleb Minaev <43728100+lounres@users.noreply.github.com> Date: Tue, 22 Mar 2022 13:58:29 +0300 Subject: [PATCH] Added division to RFs' Spaces. Added conversion to polynomial and RFs' spaces. Added requirements for RFs' denominators' changes for case of non-integral domain. Added requirements for non-zero divisor to RFs' divisions. --- .../kmath/functions/LabeledPolynomial.kt | 11 +- .../functions/LabeledRationalFunction.kt | 18 -- .../kmath/functions/ListPolynomial.kt | 13 +- .../kmath/functions/ListRationalFunction.kt | 24 -- .../kmath/functions/NumberedPolynomial.kt | 11 +- .../kscience/kmath/functions/Polynomial.kt | 17 ++ .../kmath/functions/RationalFunction.kt | 217 +++++++++++++++++- 7 files changed, 250 insertions(+), 61 deletions(-) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/LabeledPolynomial.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/LabeledPolynomial.kt index 3b4971d9c..e0b92a712 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/LabeledPolynomial.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/LabeledPolynomial.kt @@ -273,9 +273,7 @@ public class LabeledPolynomialSpace>( /** * Converts the integer [value] to polynomial. */ - public override fun number(value: Int): LabeledPolynomial = - if (value == 0) zero - else LabeledPolynomial(mapOf(emptyMap() to constantNumber(value))) + public override fun number(value: Int): LabeledPolynomial = number(constantNumber(value)) public operator fun C.plus(other: Symbol): LabeledPolynomial = if (isZero()) LabeledPolynomial(mapOf( @@ -425,6 +423,13 @@ public class LabeledPolynomialSpace>( } ) + /** + * Converts the constant [value] to polynomial. + */ + public override fun number(value: C): LabeledPolynomial = + if (value == 0) zero + else LabeledPolynomial(mapOf(emptyMap() to value)) + public operator fun Symbol.plus(other: Symbol): LabeledPolynomial = if (this == other) LabeledPolynomial(mapOf( mapOf(this to 1U) to constantOne * 2 diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/LabeledRationalFunction.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/LabeledRationalFunction.kt index f347f9191..735e04a48 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/LabeledRationalFunction.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/LabeledRationalFunction.kt @@ -144,24 +144,6 @@ public class LabeledRationalFunctionSpace>( // TODO: Разобрать - public operator fun LabeledRationalFunction.div(other: LabeledRationalFunction): LabeledRationalFunction = - LabeledRationalFunction( - numerator * other.denominator, - denominator * other.numerator - ) - - public operator fun LabeledRationalFunction.div(other: LabeledPolynomial): LabeledRationalFunction = - LabeledRationalFunction( - numerator, - denominator * other - ) - - public operator fun LabeledRationalFunction.div(other: C): LabeledRationalFunction = - LabeledRationalFunction( - numerator, - denominator * other - ) - // operator fun invoke(arg: Map): LabeledRationalFunction = // LabeledRationalFunction( // numerator(arg), diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/ListPolynomial.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/ListPolynomial.kt index f886ca19f..90e9cde69 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/ListPolynomial.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/ListPolynomial.kt @@ -66,7 +66,7 @@ public fun ListPolynomial(coefficients: List, reverse: Boolean = false): public fun ListPolynomial(vararg coefficients: C, reverse: Boolean = false): ListPolynomial = ListPolynomial(with(coefficients) { if (reverse) reversed() else toList() }) -public fun C.asPolynomial() : ListPolynomial = ListPolynomial(listOf(this)) +public fun C.asListPolynomial() : ListPolynomial = ListPolynomial(listOf(this)) /** * Space of univariate polynomials constructed over ring. @@ -199,9 +199,7 @@ public open class ListPolynomialSpace>( /** * Converts the integer [value] to polynomial. */ - public override fun number(value: Int): ListPolynomial = - if (value == 0) zero - else ListPolynomial(constantNumber(value)) + public override fun number(value: Int): ListPolynomial = number(constantNumber(value)) /** * Returns sum of the constant represented as polynomial and the polynomial. @@ -313,6 +311,13 @@ public open class ListPolynomialSpace>( } ) + /** + * Converts the constant [value] to polynomial. + */ + public override fun number(value: C): ListPolynomial = + if (value.isZero()) zero + else ListPolynomial(value) + /** * Returns negation of the polynomial. */ diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/ListRationalFunction.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/ListRationalFunction.kt index 50ddd3118..8bd925c46 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/ListRationalFunction.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/ListRationalFunction.kt @@ -70,30 +70,6 @@ public class ListRationalFunctionSpace> ( // TODO: Разобрать - public operator fun ListRationalFunction.div(other: ListRationalFunction): ListRationalFunction = - ListRationalFunction( - numerator * other.denominator, - denominator * other.numerator - ) - - public operator fun ListRationalFunction.div(other: ListPolynomial): ListRationalFunction = - ListRationalFunction( - numerator, - denominator * other - ) - - public operator fun ListRationalFunction.div(other: C): ListRationalFunction = - ListRationalFunction( - numerator, - denominator * other - ) - - public operator fun ListRationalFunction.div(other: Int): ListRationalFunction = - ListRationalFunction( - numerator, - denominator * other - ) - // operator fun invoke(arg: UnivariatePolynomial): RationalFunction = // RationalFunction( // numerator(arg), 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 387b6841d..1f37a1c2b 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 @@ -225,9 +225,7 @@ public open class NumberedPolynomialSpace>( /** * Converts the integer [value] to polynomial. */ - public override fun number(value: Int): NumberedPolynomial = - if (value == 0) zero - else NumberedPolynomial(mapOf(emptyList() to constantNumber(value))) + public override fun number(value: Int): NumberedPolynomial = number(constantNumber(value)) /** * Returns sum of the constant represented as polynomial and the polynomial. @@ -331,6 +329,13 @@ public open class NumberedPolynomialSpace>( } ) + /** + * Converts the constant [value] to polynomial. + */ + public override fun number(value: C): NumberedPolynomial = + if (value == 0) zero + else NumberedPolynomial(mapOf(emptyList() to value)) + /** * Returns negation of the polynomial. */ 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 dc46c868a..f8d7d5a36 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 @@ -65,6 +65,10 @@ public interface PolynomialSpace> : Ring

{ * Converts the integer [value] to constant. */ public fun constantNumber(value: Int): C = constantOne * value + /** + * Converts the integer to constant. + */ + public fun Int.asConstant(): C = constantNumber(this) /** * Returns sum of the polynomial and the integer represented as polynomial. @@ -108,6 +112,10 @@ public interface PolynomialSpace> : Ring

{ * Converts the integer [value] to polynomial. */ public fun number(value: Int): P = one * value + /** + * Converts the integer to polynomial. + */ + public fun Int.asPolynomial(): P = number(this) /** * Returns the same constant. @@ -206,6 +214,15 @@ public interface PolynomialSpace> : Ring

{ */ public operator fun P.times(other: C): P + /** + * Converts the constant [value] to polynomial. + */ + public fun number(value: C): P = one * value + /** + * Converts the constant to polynomial. + */ + public fun C.asPolynomial(): P = number(this) + /** * Returns the same polynomial. */ diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/RationalFunction.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/RationalFunction.kt index 724d88963..90e3bdbb1 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/RationalFunction.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/RationalFunction.kt @@ -72,6 +72,10 @@ public interface RationalFunctionalSpace, R: RationalFunctio * Converts the integer [value] to constant. */ public fun constantNumber(value: Int): C = constantOne * value + /** + * Converts the integer to constant. + */ + public fun Int.asConstant(): C = constantNumber(this) /** * Returns sum of the constant and the integer represented as polynomial. @@ -115,6 +119,10 @@ public interface RationalFunctionalSpace, R: RationalFunctio * Converts the integer [value] to polynomial. */ public fun polynomialNumber(value: Int): P = polynomialOne * value + /** + * Converts the integer to polynomial. + */ + public fun Int.asPolynomial(): P = polynomialNumber(this) /** * Returns sum of the rational function and the integer represented as rational function. @@ -134,6 +142,13 @@ public interface RationalFunctionalSpace, R: RationalFunctio * The operation is equivalent to sum of [other] copies of [this]. */ public operator fun R.times(other: Int): R = multiplyBySquaring(this, other) + /** + * Returns quotient of the rational function and the integer represented as rational function. + * + * The operation is equivalent to creating a new rational function by preserving numerator of [this] and + * multiplication denominator of [this] to [other]. + */ + public operator fun R.div(other: Int): R = this / multiplyBySquaring(one, other) /** * Returns sum of the integer represented as rational function and the rational function. @@ -153,11 +168,22 @@ public interface RationalFunctionalSpace, R: RationalFunctio * The operation is equivalent to sum of [this] copies of [other]. */ public operator fun Int.times(other: R): R = multiplyBySquaring(other, this) + /** + * Returns quotient of the integer represented as rational function and the rational function. + * + * The operation is equivalent to creating a new rational function which numerator is [this] times denominator of + * [other] and which denominator is [other]'s numerator. + */ + public operator fun Int.div(other: R): R = multiplyBySquaring(one / other, this) /** * Converts the integer [value] to rational function. */ public fun number(value: Int): R = one * value + /** + * Converts the integer to rational function. + */ + public fun Int.asRationalFunction(): R = number(this) /** * Returns the same constant. @@ -256,6 +282,15 @@ public interface RationalFunctionalSpace, R: RationalFunctio */ public operator fun P.times(other: C): P + /** + * Converts the constant [value] to polynomial. + */ + public fun polynomialNumber(value: C): P = polynomialOne * value + /** + * Converts the constant to polynomial. + */ + public fun C.asPolynomial(): P = polynomialNumber(this) + /** * Returns the same polynomial. */ @@ -276,6 +311,10 @@ public interface RationalFunctionalSpace, R: RationalFunctio * Returns product of the polynomials. */ public operator fun P.times(other: P): P + /** + * Returns quotient of the polynomials as rational function. + */ + public operator fun P.div(other: P): R /** * Raises [arg] to the integer power [exponent]. */ @@ -336,19 +375,36 @@ public interface RationalFunctionalSpace, R: RationalFunctio * Returns product of the constant represented as polynomial and the rational function. */ public operator fun C.times(other: R): R + /** + * Returns quotient of the constant represented as polynomial and the rational function. + */ + public operator fun C.div(other: R): R /** - * Returns sum of the constant represented as rational function and the rational function. + * Returns sum of the rational function and the constant represented as rational function. */ public operator fun R.plus(other: C): R /** - * Returns difference between the constant represented as rational function and the rational function. + * Returns difference between the rational function and the constant represented as rational function. */ public operator fun R.minus(other: C): R /** - * Returns product of the constant represented as rational function and the rational function. + * Returns product of the rational function and the constant represented as rational function. */ public operator fun R.times(other: C): R + /** + * Returns quotient of the rational function and the constant represented as rational function. + */ + public operator fun R.div(other: C): R + + /** + * Converts the constant [value] to rational function. + */ + public fun number(value: C): R = one * value + /** + * Converts the constant to rational function. + */ + public fun C.asRationalFunction(): R = number(this) /** * Returns sum of the polynomial represented as rational function and the rational function. @@ -362,19 +418,36 @@ public interface RationalFunctionalSpace, R: RationalFunctio * Returns product of the polynomial represented as polynomial and the rational function. */ public operator fun P.times(other: R): R + /** + * Returns quotient of the polynomial represented as polynomial and the rational function. + */ + public operator fun P.div(other: R): R /** - * Returns sum of the polynomial represented as rational function and the rational function. + * Returns sum of the rational function and the polynomial represented as rational function. */ public operator fun R.plus(other: P): R /** - * Returns difference between the polynomial represented as rational function and the rational function. + * Returns difference between the rational function and the polynomial represented as rational function. */ public operator fun R.minus(other: P): R /** - * Returns product of the polynomial represented as rational function and the rational function. + * Returns product of the rational function and the polynomial represented as rational function. */ public operator fun R.times(other: P): R + /** + * Returns quotient of the rational function and the polynomial represented as rational function. + */ + public operator fun R.div(other: P): R + + /** + * Converts the polynomial [value] to rational function. + */ + public fun number(value: P): R = one * value + /** + * Converts the polynomial to rational function. + */ + public fun P.asRationalFunction(): R = number(this) /** * Returns the same rational function. @@ -396,6 +469,10 @@ public interface RationalFunctionalSpace, R: RationalFunctio * Returns product of the rational functions. */ public override operator fun R.times(other: R): R + /** + * Returns quotient of the rational functions. + */ + public operator fun R.div(other: R): R /** * Raises [arg] to the integer power [exponent]. */ @@ -649,6 +726,15 @@ public interface RationalFunctionalSpaceOverPolynomialSpace< */ public override operator fun Int.times(other: C): C = polynomialRing { this@times * other } + /** + * Converts the integer [value] to constant. + */ + public override fun constantNumber(value: Int): C = polynomialRing { constantNumber(value) } + /** + * Converts the integer to constant. + */ + override fun Int.asConstant(): C = polynomialRing { asConstant() } + /** * Returns sum of the constant and the integer represented as polynomial. * @@ -691,6 +777,10 @@ public interface RationalFunctionalSpaceOverPolynomialSpace< * Converts the integer [value] to polynomial. */ public override fun polynomialNumber(value: Int): P = polynomialRing { number(value) } + /** + * Converts the integer to polynomial. + */ + public override fun Int.asPolynomial(): P = polynomialRing { asPolynomial() } /** * Returns the same constant. @@ -783,6 +873,15 @@ public interface RationalFunctionalSpaceOverPolynomialSpace< */ public override operator fun P.times(other: C): P = polynomialRing { this@times * other } + /** + * Converts the constant [value] to polynomial. + */ + public override fun polynomialNumber(value: C): P = polynomialRing { number(value) } + /** + * Converts the constant to polynomial. + */ + public override fun C.asPolynomial(): P = polynomialRing { asPolynomial() } + /** * Returns the same polynomial. */ @@ -933,6 +1032,19 @@ public abstract class PolynomialSpaceOfFractions< denominator ) + public override operator fun R.div(other: Int): R { + val otherAsConstant = constantNumber(other) + require(otherAsConstant.isNotZero()) { "/ by zero." } + return constructRationalFunction( + numerator, + (denominator * other).also { + check(it.isNotZero()) { + "Got zero denominator during division of rational functions to constant. It means underlying ring of polynomials is not integral domain." + } + } + ) + } + /** * Returns sum of the integer represented as rational function and the rational function. * @@ -964,11 +1076,24 @@ public abstract class PolynomialSpaceOfFractions< other.denominator ) + public override operator fun Int.div(other: R): R { + require(other.numerator.isNotZero()) { "/ by zero." } + return constructRationalFunction( + this * other.denominator, + other.numerator + ) + } + /** * Converts the integer [value] to rational function. */ public override fun number(value: Int): R = constructRationalFunction(polynomialNumber(value)) + /** + * Returns quotient of the polynomials as rational function. + */ + public override operator fun P.div(other: P): R = constructRationalFunction(this, other) + /** * Returns sum of the constant represented as rational function and the rational function. */ @@ -994,6 +1119,14 @@ public abstract class PolynomialSpaceOfFractions< other.denominator ) + public override operator fun C.div(other: R): R { + require(other.numerator.isNotZero()) { "/ by zero." } + return constructRationalFunction( + this * other.denominator, + other.numerator + ) + } + /** * Returns sum of the constant represented as rational function and the rational function. */ @@ -1019,6 +1152,23 @@ public abstract class PolynomialSpaceOfFractions< denominator ) + public override operator fun R.div(other: C): R { + require(other.isNotZero()) { "/ by zero." } + return constructRationalFunction( + numerator, + (denominator * other).also { + check(it.isNotZero()) { + "Got zero denominator during division of rational functions to constant. It means underlying ring of polynomials is not integral domain." + } + } + ) + } + + /** + * Converts the constant [value] to rational function. + */ + public override fun number(value: C): R = constructRationalFunction(polynomialNumber(value)) + /** * Returns sum of the polynomial represented as rational function and the rational function. */ @@ -1044,6 +1194,14 @@ public abstract class PolynomialSpaceOfFractions< other.denominator ) + public override operator fun P.div(other: R): R { + require(other.numerator.isNotZero()) { "/ by zero." } + return constructRationalFunction( + this * other.denominator, + other.numerator + ) + } + /** * Returns sum of the polynomial represented as rational function and the rational function. */ @@ -1069,6 +1227,23 @@ public abstract class PolynomialSpaceOfFractions< denominator ) + public override operator fun R.div(other: P): R { + require(other.isNotZero()) { "/ by zero." } + return constructRationalFunction( + numerator, + (denominator * other).also { + require(it.isNotZero()) { + "Got zero denominator during division of rational functions to polynomial. It means underlying ring of polynomials is not integral domain." + } + } + ) + } + + /** + * Converts the polynomial [value] to rational function. + */ + public override fun number(value: P): R = constructRationalFunction(value) + /** * Returns negation of the rational function. */ @@ -1079,7 +1254,11 @@ public abstract class PolynomialSpaceOfFractions< public override operator fun R.plus(other: R): R = constructRationalFunction( numerator * other.denominator + denominator * other.numerator, - denominator * other.denominator + (denominator * other.denominator).also { + check(it.isNotZero()) { + "Got zero denominator during addition of rational functions. It means underlying ring of polynomials is not integral domain." + } + } ) /** * Returns difference of the rational functions. @@ -1087,7 +1266,11 @@ public abstract class PolynomialSpaceOfFractions< public override operator fun R.minus(other: R): R = constructRationalFunction( numerator * other.denominator - denominator * other.numerator, - denominator * other.denominator + (denominator * other.denominator).also { + check(it.isNotZero()) { + "Got zero denominator during subtraction of rational functions. It means underlying ring of polynomials is not integral domain." + } + } ) /** * Returns product of the rational functions. @@ -1095,9 +1278,25 @@ public abstract class PolynomialSpaceOfFractions< public override operator fun R.times(other: R): R = constructRationalFunction( numerator * other.numerator, - denominator * other.denominator + (denominator * other.denominator).also { + check(it.isNotZero()) { + "Got zero denominator during multiplication of rational functions. It means underlying ring of polynomials is not integral domain." + } + } ) + public override operator fun R.div(other: R): R { + require(other.isNotZero()) { "/ by zero." } + return constructRationalFunction( + numerator * other.denominator, + (denominator * other.numerator).also { + check(it.isNotZero()) { + "Got zero denominator during division of rational functions. It means underlying ring of polynomials is not integral domain." + } + } + ) + } + /** * Instance of zero rational function (zero of the rational functions ring). */