From 86553e9f35aa5891b89bdcd187ff348dcc9955fb Mon Sep 17 00:00:00 2001 From: Gleb Minaev <43728100+lounres@users.noreply.github.com> Date: Thu, 17 Mar 2022 16:28:41 +0300 Subject: [PATCH] Added utilities. Rewrote polynomial-in-polynomial substitution --- .../kmath/functions/polynomialUtil.kt | 55 ++++++++++++++++--- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialUtil.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialUtil.kt index a0c11b0a8..c624380be 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialUtil.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialUtil.kt @@ -49,6 +49,41 @@ public inline fun A.scalablePolynomial(block: ScalablePolynomialSpace< return ScalablePolynomialSpace(this).block() } +@Suppress("NOTHING_TO_INLINE") +internal inline fun iadd( + ring: Ring, + augend: MutableList, + addend: List, + degree: Int +) = ring { + for (deg in 0 .. degree) augend[deg] += addend[deg] +} + +@Suppress("NOTHING_TO_INLINE") +internal inline fun addTo( + ring: Ring, + augend: List, + addend: List, + degree: Int, + target: MutableList +) = ring { + for (deg in 0 .. degree) target[deg] = augend[deg] + addend[deg] +} + +@Suppress("NOTHING_TO_INLINE") +internal inline fun multiplyAddingTo( + ring: Ring, + multiplicand: List, + multiplicandDegree: Int, + multiplier: List, + multiplierDegree: Int, + target: MutableList +) = ring { + for (d in 0 .. multiplicandDegree + multiplierDegree) + for (k in max(0, d - multiplierDegree)..min(multiplicandDegree, d)) + 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. @@ -80,19 +115,21 @@ public fun Polynomial.substitute(ring: Ring, arg: Polynomial) : Pol val argDegree = arg.degree if (argDegree == -1) return coefficients[0].asPolynomial() val constantZero = constantZero - val resultCoefs: MutableList = MutableList(thisDegree + argDegree + 1) { constantZero } - val resultCoefsUpdate: MutableList = MutableList(thisDegree + argDegree + 1) { constantZero } + val resultCoefs: MutableList = MutableList(thisDegree * argDegree + 1) { constantZero } + val resultCoefsUpdate: MutableList = MutableList(thisDegree * argDegree + 1) { constantZero } var resultDegree = 0 for (deg in thisDegree downTo 0) { resultCoefsUpdate[0] = coefficients[deg] - for (updateDeg in 0 .. resultDegree + argDegree) { - var newC = resultCoefsUpdate[updateDeg] - for (deg1 in max(0, updateDeg - argDegree)..min(resultDegree, updateDeg)) - newC += resultCoefs[deg1] * arg.coefficients[updateDeg - deg1] - resultCoefsUpdate[updateDeg] = newC - } + multiplyAddingTo( + ring=ring, + multiplicand = resultCoefs, + multiplicandDegree = resultDegree, + multiplier = arg.coefficients, + multiplierDegree = argDegree, + target = resultCoefsUpdate + ) resultDegree += argDegree - for (updateDeg in 0 .. resultDegree + argDegree) { + for (updateDeg in 0 .. resultDegree) { resultCoefs[updateDeg] = resultCoefsUpdate[updateDeg] resultCoefsUpdate[updateDeg] = constantZero }