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 56dad975d..4106371cc 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 @@ -5,6 +5,7 @@ package space.kscience.kmath.functions +import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.operations.* import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -40,9 +41,9 @@ internal constructor( * ) to (-6) * ) * ``` - * where `a`, `b` and `c` are corresponding [Variable] objects. + * where `a`, `b` and `c` are corresponding [Symbol] objects. */ - public val coefficients: Map, C> + public val coefficients: Map, C> ) : AbstractPolynomial { override fun toString(): String = "LabeledPolynomial$coefficients" } @@ -67,7 +68,7 @@ internal fun labeledPolynomialError(message: Any): Nothing = throw LabeledPolyno /** * Returns the same degrees description of the monomial, but without zero degrees. */ -internal fun Map.cleanUp() = filterValues { it > 0U } +internal fun Map.cleanUp() = filterValues { it > 0U } // endregion @@ -75,10 +76,10 @@ internal fun Map.cleanUp() = filterValues { it > 0U } //context(LabeledPolynomialSpace>) //@Suppress("FunctionName") -//internal fun LabeledPolynomial(coefs: Map, C>, toCheckInput: Boolean = false) : LabeledPolynomial { +//internal fun LabeledPolynomial(coefs: Map, C>, toCheckInput: Boolean = false) : LabeledPolynomial { // if (!toCheckInput) return LabeledPolynomial(coefs) // -// val fixedCoefs = mutableMapOf, C>() +// val fixedCoefs = mutableMapOf, C>() // // for (entry in coefs) { // val key = entry.key.cleanUp() @@ -93,10 +94,10 @@ internal fun Map.cleanUp() = filterValues { it > 0U } // //context(LabeledPolynomialSpace>) //@Suppress("FunctionName") -//internal fun LabeledPolynomial(pairs: Collection, C>>, toCheckInput: Boolean = false) : LabeledPolynomial { +//internal fun LabeledPolynomial(pairs: Collection, C>>, toCheckInput: Boolean = false) : LabeledPolynomial { // if (!toCheckInput) return LabeledPolynomial(pairs.toMap()) // -// val fixedCoefs = mutableMapOf, C>() +// val fixedCoefs = mutableMapOf, C>() // // for (entry in pairs) { // val key = entry.first.cleanUp() @@ -112,20 +113,20 @@ internal fun Map.cleanUp() = filterValues { it > 0U } //// TODO: Do not know how to make it without context receivers //context(LabeledPolynomialSpace>) //@Suppress("FunctionName") -//public fun LabeledPolynomial(coefs: Map, C>) : LabeledPolynomial = LabeledPolynomial(coefs, toCheckInput = true) +//public fun LabeledPolynomial(coefs: Map, C>) : LabeledPolynomial = LabeledPolynomial(coefs, toCheckInput = true) // //context(LabeledPolynomialSpace>) //@Suppress("FunctionName") -//public fun LabeledPolynomial(pairs: Collection, C>>) : LabeledPolynomial = LabeledPolynomial(pairs, toCheckInput = true) +//public fun LabeledPolynomial(pairs: Collection, C>>) : LabeledPolynomial = LabeledPolynomial(pairs, toCheckInput = true) // //context(LabeledPolynomialSpace>) //@Suppress("FunctionName") -//public fun LabeledPolynomial(vararg pairs: Pair, C>) : LabeledPolynomial = LabeledPolynomial(pairs.toList(), toCheckInput = true) +//public fun LabeledPolynomial(vararg pairs: Pair, C>) : LabeledPolynomial = LabeledPolynomial(pairs.toList(), toCheckInput = true) // //context(LabeledPolynomialSpace>) -//public fun Variable.asLabeledPolynomial() : LabeledPolynomial = LabeledPolynomial(mapOf(mapOf(this to 1u) to constantOne)) +//public fun Symbol.asLabeledPolynomial() : LabeledPolynomial = LabeledPolynomial(mapOf(mapOf(this to 1u) to constantOne)) -public fun C.asLabeledPolynomial() : LabeledPolynomial = LabeledPolynomial(mapOf(emptyMap() to this)) +public fun C.asLabeledPolynomial() : LabeledPolynomial = LabeledPolynomial(mapOf(emptyMap() to this)) // endregion @@ -140,24 +141,24 @@ public class LabeledPolynomialSpace>( public override val ring: A, ) : AbstractPolynomialSpaceOverRing, A> { - // region Variable-integer relation - public operator fun Variable.plus(other: Int): LabeledPolynomial = + // region Symbol-integer relation + public operator fun Symbol.plus(other: Int): LabeledPolynomial = if (other == 0) LabeledPolynomial(mapOf( mapOf(this@plus to 1U) to constantOne, )) else LabeledPolynomial(mapOf( mapOf(this@plus to 1U) to constantOne, - emptyMap() to constantOne * other, + emptyMap() to constantOne * other, )) - public operator fun Variable.minus(other: Int): LabeledPolynomial = + public operator fun Symbol.minus(other: Int): LabeledPolynomial = if (other == 0) LabeledPolynomial(mapOf( mapOf(this@minus to 1U) to -constantOne, )) else LabeledPolynomial(mapOf( mapOf(this@minus to 1U) to -constantOne, - emptyMap() to constantOne * other, + emptyMap() to constantOne * other, )) - public operator fun Variable.times(other: Int): LabeledPolynomial = + public operator fun Symbol.times(other: Int): LabeledPolynomial = if (other == 0) zero else LabeledPolynomial(mapOf( mapOf(this to 1U) to constantOne * other, @@ -165,23 +166,23 @@ public class LabeledPolynomialSpace>( // endregion // region Integer-variable relation - public operator fun Int.plus(other: Variable): LabeledPolynomial = + public operator fun Int.plus(other: Symbol): LabeledPolynomial = if (this == 0) LabeledPolynomial(mapOf( mapOf(other to 1U) to constantOne, )) else LabeledPolynomial(mapOf( mapOf(other to 1U) to constantOne, - emptyMap() to constantOne * this@plus, + emptyMap() to constantOne * this@plus, )) - public operator fun Int.minus(other: Variable): LabeledPolynomial = + public operator fun Int.minus(other: Symbol): LabeledPolynomial = if (this == 0) LabeledPolynomial(mapOf( mapOf(other to 1U) to -constantOne, )) else LabeledPolynomial(mapOf( mapOf(other to 1U) to -constantOne, - emptyMap() to constantOne * this@minus, + emptyMap() to constantOne * this@minus, )) - public operator fun Int.times(other: Variable): LabeledPolynomial = + public operator fun Int.times(other: Symbol): LabeledPolynomial = if (this == 0) zero else LabeledPolynomial(mapOf( mapOf(other to 1U) to constantOne * this@times, @@ -201,7 +202,7 @@ public class LabeledPolynomialSpace>( coefficients .toMutableMap() .apply { - val degs = emptyMap() + val degs = emptyMap() val result = getOrElse(degs) { constantZero } + other @@ -221,7 +222,7 @@ public class LabeledPolynomialSpace>( coefficients .toMutableMap() .apply { - val degs = emptyMap() + val degs = emptyMap() val result = getOrElse(degs) { constantZero } - other @@ -257,7 +258,7 @@ public class LabeledPolynomialSpace>( other.coefficients .toMutableMap() .apply { - val degs = emptyMap() + val degs = emptyMap() val result = this@plus + getOrElse(degs) { constantZero } @@ -277,7 +278,7 @@ public class LabeledPolynomialSpace>( other.coefficients .toMutableMap() .apply { - val degs = emptyMap() + val degs = emptyMap() val result = this@minus - getOrElse(degs) { constantZero } @@ -301,47 +302,47 @@ public class LabeledPolynomialSpace>( // endregion // region Constant-variable relation - public operator fun C.plus(other: Variable): LabeledPolynomial = + public operator fun C.plus(other: Symbol): LabeledPolynomial = if (isZero()) LabeledPolynomial(mapOf( mapOf(other to 1U) to constantOne, )) else LabeledPolynomial(mapOf( mapOf(other to 1U) to constantOne, - emptyMap() to this@plus, + emptyMap() to this@plus, )) - public operator fun C.minus(other: Variable): LabeledPolynomial = + public operator fun C.minus(other: Symbol): LabeledPolynomial = if (isZero()) LabeledPolynomial(mapOf( mapOf(other to 1U) to -constantOne, )) else LabeledPolynomial(mapOf( mapOf(other to 1U) to -constantOne, - emptyMap() to this@minus, + emptyMap() to this@minus, )) - public operator fun C.times(other: Variable): LabeledPolynomial = + public operator fun C.times(other: Symbol): LabeledPolynomial = if (isZero()) zero else LabeledPolynomial(mapOf( mapOf(other to 1U) to this@times, )) // endregion - // region Variable-constant relation - public operator fun Variable.plus(other: C): LabeledPolynomial = + // region Symbol-constant relation + public operator fun Symbol.plus(other: C): LabeledPolynomial = if (other.isZero()) LabeledPolynomial(mapOf( mapOf(this@plus to 1U) to constantOne, )) else LabeledPolynomial(mapOf( mapOf(this@plus to 1U) to constantOne, - emptyMap() to other, + emptyMap() to other, )) - public operator fun Variable.minus(other: C): LabeledPolynomial = + public operator fun Symbol.minus(other: C): LabeledPolynomial = if (other.isZero()) LabeledPolynomial(mapOf( mapOf(this@minus to 1U) to -constantOne, )) else LabeledPolynomial(mapOf( mapOf(this@minus to 1U) to -constantOne, - emptyMap() to other, + emptyMap() to other, )) - public operator fun Variable.times(other: C): LabeledPolynomial = + public operator fun Symbol.times(other: C): LabeledPolynomial = if (other.isZero()) zero else LabeledPolynomial(mapOf( mapOf(this@times to 1U) to other, @@ -355,11 +356,11 @@ public class LabeledPolynomialSpace>( override operator fun C.plus(other: LabeledPolynomial): LabeledPolynomial = if (this.isZero()) other else with(other.coefficients) { - if (isEmpty()) LabeledPolynomial(mapOf(emptyMap() to this@plus)) + if (isEmpty()) LabeledPolynomial(mapOf(emptyMap() to this@plus)) else LabeledPolynomial( toMutableMap() .apply { - val degs = emptyMap() + val degs = emptyMap() val result = this@plus + getOrElse(degs) { constantZero } @@ -374,13 +375,13 @@ public class LabeledPolynomialSpace>( override operator fun C.minus(other: LabeledPolynomial): LabeledPolynomial = if (this.isZero()) other else with(other.coefficients) { - if (isEmpty()) LabeledPolynomial(mapOf(emptyMap() to this@minus)) + if (isEmpty()) LabeledPolynomial(mapOf(emptyMap() to this@minus)) else LabeledPolynomial( toMutableMap() .apply { forEach { (degs, c) -> if(degs.isNotEmpty()) this[degs] = -c } - val degs = emptyMap() + val degs = emptyMap() val result = this@minus - getOrElse(degs) { constantZero } @@ -409,11 +410,11 @@ public class LabeledPolynomialSpace>( override operator fun LabeledPolynomial.plus(other: C): LabeledPolynomial = if (other.isZero()) this else with(coefficients) { - if (isEmpty()) LabeledPolynomial(mapOf(emptyMap() to other)) + if (isEmpty()) LabeledPolynomial(mapOf(emptyMap() to other)) else LabeledPolynomial( toMutableMap() .apply { - val degs = emptyMap() + val degs = emptyMap() val result = getOrElse(degs) { constantZero } + other @@ -428,13 +429,13 @@ public class LabeledPolynomialSpace>( override operator fun LabeledPolynomial.minus(other: C): LabeledPolynomial = if (other.isZero()) this else with(coefficients) { - if (isEmpty()) LabeledPolynomial(mapOf(emptyMap() to other)) + if (isEmpty()) LabeledPolynomial(mapOf(emptyMap() to other)) else LabeledPolynomial( toMutableMap() .apply { forEach { (degs, c) -> if(degs.isNotEmpty()) this[degs] = -c } - val degs = emptyMap() + val degs = emptyMap() val result = getOrElse(degs) { constantZero } - other @@ -456,8 +457,8 @@ public class LabeledPolynomialSpace>( ) // endregion - // region Variable-variable relation - public operator fun Variable.plus(other: Variable): LabeledPolynomial = + // region Symbol-variable relation + public operator fun Symbol.plus(other: Symbol): LabeledPolynomial = if (this == other) LabeledPolynomial(mapOf( mapOf(this to 1U) to constantOne * 2 )) @@ -465,13 +466,13 @@ public class LabeledPolynomialSpace>( mapOf(this to 1U) to constantOne, mapOf(other to 1U) to constantOne, )) - public operator fun Variable.minus(other: Variable): LabeledPolynomial = + public operator fun Symbol.minus(other: Symbol): LabeledPolynomial = if (this == other) zero else LabeledPolynomial(mapOf( mapOf(this to 1U) to constantOne, mapOf(other to 1U) to -constantOne, )) - public operator fun Variable.times(other: Variable): LabeledPolynomial = + public operator fun Symbol.times(other: Symbol): LabeledPolynomial = if (this == other) LabeledPolynomial(mapOf( mapOf(this to 2U) to constantOne )) @@ -480,8 +481,8 @@ public class LabeledPolynomialSpace>( )) // endregion - // region Variable-polynomial relation - public operator fun Variable.plus(other: LabeledPolynomial): LabeledPolynomial = + // region Symbol-polynomial relation + public operator fun Symbol.plus(other: LabeledPolynomial): LabeledPolynomial = with(other.coefficients) { if (isEmpty()) LabeledPolynomial(mapOf(mapOf(this@plus to 1u) to constantOne)) else LabeledPolynomial( @@ -496,7 +497,7 @@ public class LabeledPolynomialSpace>( } ) } - public operator fun Variable.minus(other: LabeledPolynomial): LabeledPolynomial = + public operator fun Symbol.minus(other: LabeledPolynomial): LabeledPolynomial = with(other.coefficients) { if (isEmpty()) LabeledPolynomial(mapOf(mapOf(this@minus to 1u) to constantOne)) else LabeledPolynomial( @@ -513,7 +514,7 @@ public class LabeledPolynomialSpace>( } ) } - public operator fun Variable.times(other: LabeledPolynomial): LabeledPolynomial = + public operator fun Symbol.times(other: LabeledPolynomial): LabeledPolynomial = LabeledPolynomial( other.coefficients .mapKeys { (degs, _) -> degs.toMutableMap().also{ it[this] = if (this in it) it[this]!! + 1U else 1U } } @@ -521,7 +522,7 @@ public class LabeledPolynomialSpace>( // endregion // region Polynomial-variable relation - public operator fun LabeledPolynomial.plus(other: Variable): LabeledPolynomial = + public operator fun LabeledPolynomial.plus(other: Symbol): LabeledPolynomial = with(coefficients) { if (isEmpty()) LabeledPolynomial(mapOf(mapOf(other to 1u) to constantOne)) else LabeledPolynomial( @@ -536,7 +537,7 @@ public class LabeledPolynomialSpace>( } ) } - public operator fun LabeledPolynomial.minus(other: Variable): LabeledPolynomial = + public operator fun LabeledPolynomial.minus(other: Symbol): LabeledPolynomial = with(coefficients) { if (isEmpty()) LabeledPolynomial(mapOf(mapOf(other to 1u) to constantOne)) else LabeledPolynomial( @@ -551,7 +552,7 @@ public class LabeledPolynomialSpace>( } ) } - public operator fun LabeledPolynomial.times(other: Variable): LabeledPolynomial = + public operator fun LabeledPolynomial.times(other: Symbol): LabeledPolynomial = LabeledPolynomial( coefficients .mapKeys { (degs, _) -> degs.toMutableMap().also{ it[other] = if (other in it) it[other]!! + 1U else 1U } } @@ -610,11 +611,11 @@ public class LabeledPolynomialSpace>( /** * Instance of zero polynomial (zero of the polynomial ring). */ - override val zero: LabeledPolynomial = LabeledPolynomial(mapOf(emptyMap() to constantZero)) + override val zero: LabeledPolynomial = LabeledPolynomial(mapOf(emptyMap() to constantZero)) /** * Instance of unit polynomial (unit of the polynomial ring). */ - override val one: LabeledPolynomial = LabeledPolynomial(mapOf(emptyMap() to constantOne)) + override val one: LabeledPolynomial = LabeledPolynomial(mapOf(emptyMap() to constantOne)) /** * Checks equality of the polynomials. @@ -642,7 +643,7 @@ public class LabeledPolynomialSpace>( * As consequence all values in the map are positive integers. Also, if the polynomial is constant, the map is empty. * And keys of the map is the same as in [variables]. */ - public val LabeledPolynomial.degrees: Map + public val LabeledPolynomial.degrees: Map get() = buildMap { coefficients.entries.forEach { (degs, c) -> @@ -654,7 +655,7 @@ public class LabeledPolynomialSpace>( /** * Set of all variables that appear in the polynomial in positive exponents. */ - public val LabeledPolynomial.variables: Set + public val LabeledPolynomial.variables: Set get() = buildSet { coefficients.entries.forEach { (degs, c) -> if (c.isNotZero()) addAll(degs.keys) } @@ -695,29 +696,29 @@ public class LabeledPolynomialSpace>( } // @Suppress("NOTHING_TO_INLINE") -// public inline fun LabeledPolynomial.substitute(argument: Map): LabeledPolynomial = this.substitute(ring, argument) +// public inline fun LabeledPolynomial.substitute(argument: Map): LabeledPolynomial = this.substitute(ring, argument) // @Suppress("NOTHING_TO_INLINE") // @JvmName("substitutePolynomial") -// public inline fun LabeledPolynomial.substitute(argument: Map>): LabeledPolynomial = this.substitute(ring, argument) +// public inline fun LabeledPolynomial.substitute(argument: Map>): LabeledPolynomial = this.substitute(ring, argument) // // @Suppress("NOTHING_TO_INLINE") -// public inline fun LabeledPolynomial.asFunction(): (Map) -> LabeledPolynomial = { this.substitute(ring, it) } +// public inline fun LabeledPolynomial.asFunction(): (Map) -> LabeledPolynomial = { this.substitute(ring, it) } // @Suppress("NOTHING_TO_INLINE") -// public inline fun LabeledPolynomial.asFunctionOnConstants(): (Map) -> LabeledPolynomial = { this.substitute(ring, it) } +// public inline fun LabeledPolynomial.asFunctionOnConstants(): (Map) -> LabeledPolynomial = { this.substitute(ring, it) } // @Suppress("NOTHING_TO_INLINE") -// public inline fun LabeledPolynomial.asFunctionOnPolynomials(): (Map>) -> LabeledPolynomial = { this.substitute(ring, it) } +// public inline fun LabeledPolynomial.asFunctionOnPolynomials(): (Map>) -> LabeledPolynomial = { this.substitute(ring, it) } // // @Suppress("NOTHING_TO_INLINE") -// public inline operator fun LabeledPolynomial.invoke(argument: Map): LabeledPolynomial = this.substitute(ring, argument) +// public inline operator fun LabeledPolynomial.invoke(argument: Map): LabeledPolynomial = this.substitute(ring, argument) // @Suppress("NOTHING_TO_INLINE") // @JvmName("invokePolynomial") -// public inline operator fun LabeledPolynomial.invoke(argument: Map>): LabeledPolynomial = this.substitute(ring, argument) +// public inline operator fun LabeledPolynomial.invoke(argument: Map>): LabeledPolynomial = this.substitute(ring, argument) // endregion // region Utilities // TODO: Move to region internal utilities with context receiver @JvmName("applyAndRemoveZerosInternal") - internal fun MutableMap, C>.applyAndRemoveZeros(block: MutableMap, C>.() -> Unit) : MutableMap, C> { + internal fun MutableMap, C>.applyAndRemoveZeros(block: MutableMap, C>.() -> Unit) : MutableMap, C> { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } @@ -725,10 +726,10 @@ public class LabeledPolynomialSpace>( for ((degs, c) in this) if (c.isZero()) this.remove(degs) return this } - internal fun Map, C>.applyAndRemoveZeros(block: MutableMap, C>.() -> Unit) : Map, C> = + internal fun Map, C>.applyAndRemoveZeros(block: MutableMap, C>.() -> Unit) : Map, C> = toMutableMap().applyAndRemoveZeros(block) @OptIn(ExperimentalTypeInference::class) - internal inline fun buildCoefficients(@BuilderInference builderAction: MutableMap, C>.() -> Unit): Map, C> { + internal inline fun buildCoefficients(@BuilderInference builderAction: MutableMap, C>.() -> Unit): Map, C> { contract { callsInPlace(builderAction, InvocationKind.EXACTLY_ONCE) } return buildMap { builderAction() @@ -736,7 +737,7 @@ public class LabeledPolynomialSpace>( } } @OptIn(ExperimentalTypeInference::class) - internal inline fun buildCoefficients(capacity: Int, @BuilderInference builderAction: MutableMap, C>.() -> Unit): Map, C> { + internal inline fun buildCoefficients(capacity: Int, @BuilderInference builderAction: MutableMap, C>.() -> Unit): Map, C> { contract { callsInPlace(builderAction, InvocationKind.EXACTLY_ONCE) } return buildMap(capacity) { builderAction() 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 df4441127..3077a2b82 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 @@ -5,6 +5,7 @@ package space.kscience.kmath.functions +import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.operations.Ring import space.kscience.kmath.operations.invoke @@ -62,22 +63,22 @@ internal fun labeledRationalFunctionError(message: Any): Nothing = throw Labeled // ) // TODO: Rewrite former constructors as fabrics -//constructor(numeratorCoefficients: Map, C>, denominatorCoefficients: Map, C>) : this( +//constructor(numeratorCoefficients: Map, C>, denominatorCoefficients: Map, C>) : this( //LabeledPolynomial(numeratorCoefficients), //LabeledPolynomial(denominatorCoefficients) //) // -//constructor(numeratorCoefficients: Collection, C>>, denominatorCoefficients: Collection, C>>) : this( +//constructor(numeratorCoefficients: Collection, C>>, denominatorCoefficients: Collection, C>>) : this( //LabeledPolynomial(numeratorCoefficients), //LabeledPolynomial(denominatorCoefficients) //) // //constructor(numerator: LabeledPolynomial) : this(numerator, numerator.getOne()) -//constructor(numeratorCoefficients: Map, C>) : this( +//constructor(numeratorCoefficients: Map, C>) : this( //LabeledPolynomial(numeratorCoefficients) //) // -//constructor(numeratorCoefficients: Collection, C>>) : this( +//constructor(numeratorCoefficients: Collection, C>>) : this( //LabeledPolynomial(numeratorCoefficients) //) @@ -338,11 +339,11 @@ public class LabeledRationalFunctionSpace>( * As consequence all values in the map are positive integers. Also, if the polynomial is constant, the map is empty. * And keys of the map is the same as in [variables]. */ - public val LabeledPolynomial.degrees: Map get() = polynomialRing { degrees } + public val LabeledPolynomial.degrees: Map get() = polynomialRing { degrees } /** * Set of all variables that appear in the polynomial in positive exponents. */ - public val LabeledPolynomial.variables: Set get() = polynomialRing { variables } + public val LabeledPolynomial.variables: Set get() = polynomialRing { variables } /** * Count of all variables that appear in the polynomial in positive exponents. */ @@ -353,7 +354,7 @@ public class LabeledRationalFunctionSpace>( /** * Count of all variables that appear in the polynomial in positive exponents. */ - public val LabeledRationalFunction.variables: Set + public val LabeledRationalFunction.variables: Set get() = numerator.variables union denominator.variables /** * Count of all variables that appear in the polynomial in positive exponents. @@ -381,21 +382,21 @@ public class LabeledRationalFunctionSpace>( denominator * other ) -// operator fun invoke(arg: Map): LabeledRationalFunction = +// operator fun invoke(arg: Map): LabeledRationalFunction = // LabeledRationalFunction( // numerator(arg), // denominator(arg) // ) // // @JvmName("invokeLabeledPolynomial") -// operator fun invoke(arg: Map>): LabeledRationalFunction = +// operator fun invoke(arg: Map>): LabeledRationalFunction = // LabeledRationalFunction( // numerator(arg), // denominator(arg) // ) // // @JvmName("invokeLabeledRationalFunction") -// operator fun invoke(arg: Map>): LabeledRationalFunction { +// operator fun invoke(arg: Map>): LabeledRationalFunction { // var num = numerator invokeRFTakeNumerator arg // var den = denominator invokeRFTakeNumerator arg // for (variable in variables) if (variable in arg) { @@ -410,56 +411,56 @@ public class LabeledRationalFunctionSpace>( // // override fun toString(): String = toString(emptyMap()) // -// fun toString(names: Map = emptyMap()): String = +// fun toString(names: Map = emptyMap()): String = // when (true) { // numerator.isZero() -> "0" // denominator.isOne() -> numerator.toString(names) // else -> "${numerator.toStringWithBrackets(names)}/${denominator.toStringWithBrackets(names)}" // } // -// fun toString(namer: (Variable) -> String): String = +// fun toString(namer: (Symbol) -> String): String = // when (true) { // numerator.isZero() -> "0" // denominator.isOne() -> numerator.toString(namer) // else -> "${numerator.toStringWithBrackets(namer)}/${denominator.toStringWithBrackets(namer)}" // } // -// fun toStringWithBrackets(names: Map = emptyMap()): String = +// fun toStringWithBrackets(names: Map = emptyMap()): String = // when (true) { // numerator.isZero() -> "0" // denominator.isOne() -> numerator.toStringWithBrackets(names) // else -> "(${numerator.toStringWithBrackets(names)}/${denominator.toStringWithBrackets(names)})" // } // -// fun toStringWithBrackets(namer: (Variable) -> String): String = +// fun toStringWithBrackets(namer: (Symbol) -> String): String = // when (true) { // numerator.isZero() -> "0" // denominator.isOne() -> numerator.toStringWithBrackets(namer) // else -> "(${numerator.toStringWithBrackets(namer)}/${denominator.toStringWithBrackets(namer)})" // } // -// fun toReversedString(names: Map = emptyMap()): String = +// fun toReversedString(names: Map = emptyMap()): String = // when (true) { // numerator.isZero() -> "0" // denominator.isOne() -> numerator.toReversedString(names) // else -> "${numerator.toReversedStringWithBrackets(names)}/${denominator.toReversedStringWithBrackets(names)}" // } // -// fun toReversedString(namer: (Variable) -> String): String = +// fun toReversedString(namer: (Symbol) -> String): String = // when (true) { // numerator.isZero() -> "0" // denominator.isOne() -> numerator.toReversedString(namer) // else -> "${numerator.toReversedStringWithBrackets(namer)}/${denominator.toReversedStringWithBrackets(namer)}" // } // -// fun toReversedStringWithBrackets(names: Map = emptyMap()): String = +// fun toReversedStringWithBrackets(names: Map = emptyMap()): String = // when (true) { // numerator.isZero() -> "0" // denominator.isOne() -> numerator.toReversedStringWithBrackets(names) // else -> "(${numerator.toReversedStringWithBrackets(names)}/${denominator.toReversedStringWithBrackets(names)})" // } // -// fun toReversedStringWithBrackets(namer: (Variable) -> String): String = +// fun toReversedStringWithBrackets(namer: (Symbol) -> String): String = // when (true) { // numerator.isZero() -> "0" // denominator.isOne() -> numerator.toReversedStringWithBrackets(namer) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Variable.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Variable.kt deleted file mode 100644 index 410604fd3..000000000 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Variable.kt +++ /dev/null @@ -1,38 +0,0 @@ -package space.kscience.kmath.functions - -import kotlin.reflect.KProperty - - -/** - * Represents class of labeled variables like usual - * `x`, `y`, `z`, `a`, `b`, `n`, `m`, etc. - * - * Variables does not contain any information about field (or ring, ets.) they are considered in - * and therefore about coefficient. - * - * @property name Is the label or name of variable. For `x` it is `"x"`, for `n` – `"n"`, etc. - */ -public data class Variable (val name: String) : Comparable { - /** - * Represents the variable as a string. - * - * @return Only name of the variable. - */ - override fun toString(): String = name - /** - * Compares two variables. - * Comparison is realised by comparison of variables' names. - * - * Used in [LabeledPolynomial] and [LabeledRationalFunction] to sort monomials in - * [LabeledPolynomial.toString] and [LabeledRationalFunction.toString] in lexicographic order. - * - * @see Comparable.compareTo - * @sample LabeledPolynomial.monomialComparator - * @return Only name of the variable. - */ - override fun compareTo(other: Variable): Int = name.compareTo(other.name) - - public companion object { - public operator fun getValue(thisRef: Any?, property: KProperty<*>) : Variable = Variable(property.name) - } -} \ No newline at end of file diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/labeledPolynomialUtil.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/labeledPolynomialUtil.kt index 544cca410..9408a09f2 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/labeledPolynomialUtil.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/labeledPolynomialUtil.kt @@ -5,10 +5,14 @@ package space.kscience.kmath.functions +import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.misc.UnstableKMathAPI -import space.kscience.kmath.operations.* -import kotlin.contracts.* -import kotlin.math.max +import space.kscience.kmath.operations.Field +import space.kscience.kmath.operations.Ring +import space.kscience.kmath.operations.invoke +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract // TODO: Docs @@ -31,10 +35,10 @@ import kotlin.math.max // //// endregion -//// region Variables +//// region Symbols // //context(LabeledPolynomialSpace) -//fun > power(arg: Variable, pow: UInt): LabeledPolynomial = +//fun > power(arg: Symbol, pow: UInt): LabeledPolynomial = // if (pow == 0U) one // else LabeledPolynomial(mapOf( // mapOf(arg to pow) to constantOne @@ -45,7 +49,7 @@ import kotlin.math.max //// region Polynomials // //context(LabeledPolynomialSpace) -//fun > number(value: Int): LabeledPolynomial = ring { LabeledPolynomial(mapOf(emptyMap() to number(value))) } +//fun > number(value: Int): LabeledPolynomial = ring { LabeledPolynomial(mapOf(emptyMap() to number(value))) } // //context(LabeledPolynomialSpace) //fun > multiplyWithPower(base: LabeledPolynomial, arg: LabeledPolynomial, pow: UInt): LabeledPolynomial = @@ -97,7 +101,7 @@ public inline fun , R> A.labeledPolynomial(block: LabeledPolynomi // * Consider that monomials are sorted in lexicographic order. // */ //context(LabeledPolynomialSpace) -//fun > LabeledPolynomial.represent(names: Map = emptyMap()): String = +//fun > LabeledPolynomial.represent(names: Map = emptyMap()): String = // coefficients.entries // .sortedWith { o1, o2 -> LabeledPolynomial.monomialComparator.compare(o1.key, o2.key) } // .asSequence() @@ -130,7 +134,7 @@ public inline fun , R> A.labeledPolynomial(block: LabeledPolynomi // * Consider that monomials are sorted in lexicographic order. // */ //context(LabeledPolynomialSpace) -//fun > LabeledPolynomial.represent(namer: (Variable) -> String): String = +//fun > LabeledPolynomial.represent(namer: (Symbol) -> String): String = // coefficients.entries // .sortedWith { o1, o2 -> LabeledPolynomial.monomialComparator.compare(o1.key, o2.key) } // .asSequence() @@ -163,7 +167,7 @@ public inline fun , R> A.labeledPolynomial(block: LabeledPolynomi // * Consider that monomials are sorted in lexicographic order. // */ //context(LabeledPolynomialSpace) -//fun > LabeledPolynomial.representWithBrackets(names: Map = emptyMap()): String = +//fun > LabeledPolynomial.representWithBrackets(names: Map = emptyMap()): String = // with(represent(names)) { if (coefficients.count() == 1) this else "($this)" } // ///** @@ -172,7 +176,7 @@ public inline fun , R> A.labeledPolynomial(block: LabeledPolynomi // * Consider that monomials are sorted in lexicographic order. // */ //context(LabeledPolynomialSpace) -//fun > LabeledPolynomial.representWithBrackets(namer: (Variable) -> String): String = +//fun > LabeledPolynomial.representWithBrackets(namer: (Symbol) -> String): String = // with(represent(namer)) { if (coefficients.count() == 1) this else "($this)" } // ///** @@ -180,7 +184,7 @@ public inline fun , R> A.labeledPolynomial(block: LabeledPolynomi // * Consider that monomials are sorted in **reversed** lexicographic order. // */ //context(LabeledPolynomialSpace) -//fun > LabeledPolynomial.representReversed(names: Map = emptyMap()): String = +//fun > LabeledPolynomial.representReversed(names: Map = emptyMap()): String = // coefficients.entries // .sortedWith { o1, o2 -> -LabeledPolynomial.monomialComparator.compare(o1.key, o2.key) } // .asSequence() @@ -213,7 +217,7 @@ public inline fun , R> A.labeledPolynomial(block: LabeledPolynomi // * Consider that monomials are sorted in **reversed** lexicographic order. // */ //context(LabeledPolynomialSpace) -//fun > LabeledPolynomial.representReversed(namer: (Variable) -> String): String = +//fun > LabeledPolynomial.representReversed(namer: (Symbol) -> String): String = // coefficients.entries // .sortedWith { o1, o2 -> -LabeledPolynomial.monomialComparator.compare(o1.key, o2.key) } // .asSequence() @@ -246,7 +250,7 @@ public inline fun , R> A.labeledPolynomial(block: LabeledPolynomi // * Consider that monomials are sorted in **reversed** lexicographic order. // */ //context(LabeledPolynomialSpace) -//fun > LabeledPolynomial.representReversedWithBrackets(names: Map = emptyMap()): String = +//fun > LabeledPolynomial.representReversedWithBrackets(names: Map = emptyMap()): String = // with(representReversed(names)) { if (coefficients.count() == 1) this else "($this)" } // ///** @@ -255,7 +259,7 @@ public inline fun , R> A.labeledPolynomial(block: LabeledPolynomi // * Consider that monomials are sorted in **reversed** lexicographic order. // */ //context(LabeledPolynomialSpace) -//fun > LabeledPolynomial.representReversedWithBrackets(namer: (Variable) -> String): String = +//fun > LabeledPolynomial.representReversedWithBrackets(namer: (Symbol) -> String): String = // with(representReversed(namer)) { if (coefficients.count() == 1) this else "($this)" } // //// endregion @@ -279,7 +283,7 @@ public inline fun , R> A.labeledPolynomial(block: LabeledPolynomi //// region Polynomial substitution and functional representation // -//public fun LabeledPolynomial.substitute(ring: Ring, args: Map): LabeledPolynomial = ring { +//public fun LabeledPolynomial.substitute(ring: Ring, args: Map): LabeledPolynomial = ring { // if (coefficients.isEmpty()) return this@substitute // LabeledPolynomial( // buildMap { @@ -297,7 +301,7 @@ public inline fun , R> A.labeledPolynomial(block: LabeledPolynomi //// TODO: Replace with optimisation: the [result] may be unboxed, and all operations may be performed as soon as //// possible on it //@JvmName("substitutePolynomial") -//fun LabeledPolynomial.substitute(ring: Ring, arg: Map>) : LabeledPolynomial = +//fun LabeledPolynomial.substitute(ring: Ring, arg: Map>) : LabeledPolynomial = // ring.labeledPolynomial { // if (coefficients.isEmpty()) return zero // coefficients @@ -315,10 +319,10 @@ public inline fun , R> A.labeledPolynomial(block: LabeledPolynomi // //// TODO: Substitute rational function // -//fun > LabeledPolynomial.asFunctionOver(ring: A): (Map) -> LabeledPolynomial = +//fun > LabeledPolynomial.asFunctionOver(ring: A): (Map) -> LabeledPolynomial = // { substitute(ring, it) } // -//fun > LabeledPolynomial.asPolynomialFunctionOver(ring: A): (Map>) -> LabeledPolynomial = +//fun > LabeledPolynomial.asPolynomialFunctionOver(ring: A): (Map>) -> LabeledPolynomial = // { substitute(ring, it) } // //// endregion @@ -331,7 +335,7 @@ public inline fun , R> A.labeledPolynomial(block: LabeledPolynomi @UnstableKMathAPI public fun > LabeledPolynomial.derivativeWithRespectTo( algebra: A, - variable: Variable, + variable: Symbol, ): LabeledPolynomial = algebra { LabeledPolynomial( buildMap(coefficients.size) { @@ -360,7 +364,7 @@ public fun > LabeledPolynomial.derivativeWithRespectTo( @UnstableKMathAPI public fun > LabeledPolynomial.derivativeWithRespectTo( algebra: A, - variables: Collection, + variables: Collection, ): LabeledPolynomial = algebra { val cleanedVariables = variables.toSet() if (cleanedVariables.isEmpty()) return this@derivativeWithRespectTo @@ -391,7 +395,7 @@ public fun > LabeledPolynomial.derivativeWithRespectTo( @UnstableKMathAPI public fun > LabeledPolynomial.nthDerivativeWithRespectTo( algebra: A, - variable: Variable, + variable: Symbol, order: UInt ): LabeledPolynomial = algebra { if (order == 0u) return this@nthDerivativeWithRespectTo @@ -425,7 +429,7 @@ public fun > LabeledPolynomial.nthDerivativeWithRespectTo( @UnstableKMathAPI public fun > LabeledPolynomial.nthDerivativeWithRespectTo( algebra: A, - variablesAndOrders: Map, + variablesAndOrders: Map, ): LabeledPolynomial = algebra { val filteredVariablesAndOrders = variablesAndOrders.filterValues { it != 0u } if (filteredVariablesAndOrders.isEmpty()) return this@nthDerivativeWithRespectTo @@ -462,13 +466,13 @@ public fun > LabeledPolynomial.nthDerivativeWithRespectTo( @UnstableKMathAPI public fun > LabeledPolynomial.antiderivativeWithRespectTo( algebra: A, - variable: Variable, + variable: Symbol, ): LabeledPolynomial = algebra { LabeledPolynomial( buildMap(coefficients.size) { coefficients .forEach { (degs, c) -> - val newDegs = buildMap(degs.size + 1) { + val newDegs = buildMap(degs.size + 1) { put(variable, 1u) for ((vari, deg) in degs) put(vari, deg + getOrElse(vari) { 0u }) } @@ -487,7 +491,7 @@ public fun > LabeledPolynomial.antiderivativeWithRespectTo( @UnstableKMathAPI public fun > LabeledPolynomial.antiderivativeWithRespectTo( algebra: A, - variables: Collection, + variables: Collection, ): LabeledPolynomial = algebra { val cleanedVariables = variables.toSet() if (cleanedVariables.isEmpty()) return this@antiderivativeWithRespectTo @@ -495,7 +499,7 @@ public fun > LabeledPolynomial.antiderivativeWithRespectTo( buildMap(coefficients.size) { coefficients .forEach { (degs, c) -> - val newDegs = buildMap(degs.size + 1) { + val newDegs = buildMap(degs.size + 1) { for (variable in cleanedVariables) put(variable, 1u) for ((vari, deg) in degs) put(vari, deg + getOrElse(vari) { 0u }) } @@ -514,7 +518,7 @@ public fun > LabeledPolynomial.antiderivativeWithRespectTo( @UnstableKMathAPI public fun > LabeledPolynomial.nthAntiderivativeWithRespectTo( algebra: A, - variable: Variable, + variable: Symbol, order: UInt ): LabeledPolynomial = algebra { if (order == 0u) return this@nthAntiderivativeWithRespectTo @@ -522,7 +526,7 @@ public fun > LabeledPolynomial.nthAntiderivativeWithRespectTo buildMap(coefficients.size) { coefficients .forEach { (degs, c) -> - val newDegs = buildMap(degs.size + 1) { + val newDegs = buildMap(degs.size + 1) { put(variable, order) for ((vari, deg) in degs) put(vari, deg + getOrElse(vari) { 0u }) } @@ -544,7 +548,7 @@ public fun > LabeledPolynomial.nthAntiderivativeWithRespectTo @UnstableKMathAPI public fun > LabeledPolynomial.nthAntiderivativeWithRespectTo( algebra: A, - variablesAndOrders: Map, + variablesAndOrders: Map, ): LabeledPolynomial = algebra { val filteredVariablesAndOrders = variablesAndOrders.filterValues { it != 0u } if (filteredVariablesAndOrders.isEmpty()) return this@nthAntiderivativeWithRespectTo @@ -552,7 +556,7 @@ public fun > LabeledPolynomial.nthAntiderivativeWithRespectTo buildMap(coefficients.size) { coefficients .forEach { (degs, c) -> - val newDegs = buildMap(degs.size + 1) { + val newDegs = buildMap(degs.size + 1) { for ((variable, order) in filteredVariablesAndOrders) put(variable, order) for ((vari, deg) in degs) put(vari, deg + getOrElse(vari) { 0u }) }