Fixed bug in implementations of polynomial operations

This commit is contained in:
Gleb Minaev 2022-03-18 20:04:21 +03:00
parent ed2f14b68e
commit cdc85291bc
4 changed files with 30 additions and 33 deletions

View File

@ -211,7 +211,7 @@ public class LabeledPolynomialSpace<C, A : Ring<C>>(
else LabeledPolynomial( else LabeledPolynomial(
coefficients coefficients
.applyAndRemoveZeros { .applyAndRemoveZeros {
mapValues { (_, c) -> c * other } for (degs in keys) this[degs] = this[degs]!! * other
} }
) )
@ -265,7 +265,7 @@ public class LabeledPolynomialSpace<C, A : Ring<C>>(
else LabeledPolynomial( else LabeledPolynomial(
other.coefficients other.coefficients
.applyAndRemoveZeros { .applyAndRemoveZeros {
mapValues { (_, c) -> this@times * c } for (degs in keys) this[degs] = this@times * this[degs]!!
} }
) )
@ -361,7 +361,7 @@ public class LabeledPolynomialSpace<C, A : Ring<C>>(
else LabeledPolynomial<C>( else LabeledPolynomial<C>(
other.coefficients other.coefficients
.applyAndRemoveZeros { .applyAndRemoveZeros {
mapValues { (_, c) -> this@times * c } for (degs in keys) this[degs] = this@times * this[degs]!!
} }
) )
@ -413,7 +413,7 @@ public class LabeledPolynomialSpace<C, A : Ring<C>>(
else LabeledPolynomial<C>( else LabeledPolynomial<C>(
coefficients coefficients
.applyAndRemoveZeros { .applyAndRemoveZeros {
mapValues { (_, c) -> c * other } for (degs in keys) this[degs] = this[degs]!! * other
} }
) )
@ -525,22 +525,20 @@ public class LabeledPolynomialSpace<C, A : Ring<C>>(
*/ */
override operator fun LabeledPolynomial<C>.plus(other: LabeledPolynomial<C>): LabeledPolynomial<C> = override operator fun LabeledPolynomial<C>.plus(other: LabeledPolynomial<C>): LabeledPolynomial<C> =
LabeledPolynomial<C>( LabeledPolynomial<C>(
coefficients buildCoefficients(coefficients.size + other.coefficients.size) {
.applyAndRemoveZeros { other.coefficients.mapValuesTo(this) { it.value }
other.coefficients other.coefficients.mapValuesTo(this) { (key, value) -> if (key in this) this[key]!! + value else value }
.mapValuesTo(this) { (key, value) -> if (key in this) this[key]!! + value else value } }
}
) )
/** /**
* Returns difference of the polynomials. * Returns difference of the polynomials.
*/ */
override operator fun LabeledPolynomial<C>.minus(other: LabeledPolynomial<C>): LabeledPolynomial<C> = override operator fun LabeledPolynomial<C>.minus(other: LabeledPolynomial<C>): LabeledPolynomial<C> =
LabeledPolynomial<C>( LabeledPolynomial<C>(
coefficients buildCoefficients(coefficients.size + other.coefficients.size) {
.applyAndRemoveZeros { other.coefficients.mapValuesTo(this) { it.value }
other.coefficients other.coefficients.mapValuesTo(this) { (key, value) -> if (key in this) this[key]!! - value else -value }
.mapValuesTo(this) { (key, value) -> if (key in this) this[key]!! - value else -value } }
}
) )
/** /**
* Returns product of the polynomials. * Returns product of the polynomials.

View File

@ -163,7 +163,7 @@ public open class NumberedPolynomialSpace<C, A : Ring<C>>(
else NumberedPolynomial<C>( else NumberedPolynomial<C>(
coefficients coefficients
.applyAndRemoveZeros { .applyAndRemoveZeros {
mapValues { (_, c) -> c * other } for (degs in keys) this[degs] = this[degs]!! * other
} }
) )
@ -217,7 +217,7 @@ public open class NumberedPolynomialSpace<C, A : Ring<C>>(
else NumberedPolynomial( else NumberedPolynomial(
other.coefficients other.coefficients
.applyAndRemoveZeros { .applyAndRemoveZeros {
mapValues { (_, c) -> this@times * c } for (degs in keys) this[degs] = this@times * this[degs]!!
} }
) )
@ -269,7 +269,7 @@ public open class NumberedPolynomialSpace<C, A : Ring<C>>(
else NumberedPolynomial<C>( else NumberedPolynomial<C>(
other.coefficients other.coefficients
.applyAndRemoveZeros { .applyAndRemoveZeros {
mapValues { (_, c) -> this@times * c } for (degs in keys) this[degs] = this@times * this[degs]!!
} }
) )
@ -319,7 +319,7 @@ public open class NumberedPolynomialSpace<C, A : Ring<C>>(
else NumberedPolynomial<C>( else NumberedPolynomial<C>(
coefficients coefficients
.applyAndRemoveZeros { .applyAndRemoveZeros {
mapValues { (_, c) -> c * other } for (degs in keys) this[degs] = this[degs]!! * other
} }
) )
@ -335,22 +335,20 @@ public open class NumberedPolynomialSpace<C, A : Ring<C>>(
*/ */
override operator fun NumberedPolynomial<C>.plus(other: NumberedPolynomial<C>): NumberedPolynomial<C> = override operator fun NumberedPolynomial<C>.plus(other: NumberedPolynomial<C>): NumberedPolynomial<C> =
NumberedPolynomial<C>( NumberedPolynomial<C>(
coefficients buildCoefficients(coefficients.size + other.coefficients.size) {
.applyAndRemoveZeros { other.coefficients.mapValuesTo(this) { it.value }
other.coefficients other.coefficients.mapValuesTo(this) { (key, value) -> if (key in this) this[key]!! + value else value }
.mapValuesTo(this) { (key, value) -> if (key in this) this[key]!! + value else value } }
}
) )
/** /**
* Returns difference of the polynomials. * Returns difference of the polynomials.
*/ */
override operator fun NumberedPolynomial<C>.minus(other: NumberedPolynomial<C>): NumberedPolynomial<C> = override operator fun NumberedPolynomial<C>.minus(other: NumberedPolynomial<C>): NumberedPolynomial<C> =
NumberedPolynomial<C>( NumberedPolynomial<C>(
coefficients buildCoefficients(coefficients.size + other.coefficients.size) {
.applyAndRemoveZeros { other.coefficients.mapValuesTo(this) { it.value }
other.coefficients other.coefficients.mapValuesTo(this) { (key, value) -> if (key in this) this[key]!! - value else -value }
.mapValuesTo(this) { (key, value) -> if (key in this) this[key]!! - value else -value } }
}
) )
/** /**
* Returns product of the polynomials. * Returns product of the polynomials.

View File

@ -129,7 +129,7 @@ public open class PolynomialSpace<C, A : Ring<C>>(
else Polynomial( else Polynomial(
coefficients coefficients
.applyAndRemoveZeros { .applyAndRemoveZeros {
map { it * other } for (deg in indices) this[deg] = this[deg] * other
} }
) )
@ -189,7 +189,7 @@ public open class PolynomialSpace<C, A : Ring<C>>(
else Polynomial( else Polynomial(
other.coefficients other.coefficients
.applyAndRemoveZeros { .applyAndRemoveZeros {
map { it * this@times } for (deg in indices) this[deg] = this@times * this[deg]
} }
) )
@ -245,7 +245,7 @@ public open class PolynomialSpace<C, A : Ring<C>>(
else Polynomial( else Polynomial(
other.coefficients other.coefficients
.applyAndRemoveZeros { .applyAndRemoveZeros {
map { it * this@times } for (deg in indices) this[deg] = this@times * this[deg]
} }
) )
@ -299,7 +299,7 @@ public open class PolynomialSpace<C, A : Ring<C>>(
else Polynomial( else Polynomial(
coefficients coefficients
.applyAndRemoveZeros { .applyAndRemoveZeros {
map { it * other } for (deg in indices) this[deg] = this[deg] * other
} }
) )
@ -452,12 +452,14 @@ public open class PolynomialSpace<C, A : Ring<C>>(
} }
internal inline fun List<C>.applyAndRemoveZeros(block: MutableList<C>.() -> Unit) : List<C> = internal inline fun List<C>.applyAndRemoveZeros(block: MutableList<C>.() -> Unit) : List<C> =
toMutableList().applyAndRemoveZeros(block) toMutableList().applyAndRemoveZeros(block)
@Suppress("FunctionName")
internal inline fun MutableCoefficients(size: Int, init: (index: Int) -> C): MutableList<C> { internal inline fun MutableCoefficients(size: Int, init: (index: Int) -> C): MutableList<C> {
val list = ArrayList<C>(size) val list = ArrayList<C>(size)
repeat(size) { index -> list.add(init(index)) } repeat(size) { index -> list.add(init(index)) }
with(list) { while (elementAt(lastIndex).isZero()) removeAt(lastIndex) } with(list) { while (elementAt(lastIndex).isZero()) removeAt(lastIndex) }
return list return list
} }
@Suppress("FunctionName")
internal inline fun Coefficients(size: Int, init: (index: Int) -> C): List<C> = MutableCoefficients(size, init) internal inline fun Coefficients(size: Int, init: (index: Int) -> C): List<C> = MutableCoefficients(size, init)
@OptIn(ExperimentalTypeInference::class) @OptIn(ExperimentalTypeInference::class)
internal inline fun buildCoefficients(@BuilderInference builderAction: MutableList<C>.() -> Unit): List<C> { internal inline fun buildCoefficients(@BuilderInference builderAction: MutableList<C>.() -> Unit): List<C> {

View File

@ -96,7 +96,6 @@ internal inline fun <C> multiplyAddingTo(
target[d] += multiplicand[k] * multiplier[d - k] target[d] += multiplicand[k] * multiplier[d - k]
} }
// TODO: May be apply Horner's method too?
/** /**
* Evaluates the value of the given double polynomial for given double argument. * Evaluates the value of the given double polynomial for given double argument.
*/ */