Feature: Polynomials and rational functions #469

Merged
lounres merged 132 commits from feature/polynomials into dev 2022-07-28 18:04:06 +03:00
3 changed files with 3780 additions and 26 deletions
Showing only changes of commit 102e83b478 - Show all commits

View File

@ -262,12 +262,14 @@ public fun <C> NumberedRationalFunction<C>.substitute(ring: Ring<C>, args: Buffe
numerator.substitute(ring, args) / denominator.substitute(ring, args) numerator.substitute(ring, args) / denominator.substitute(ring, args)
} }
internal const val fullSubstitutionExceptionMessage: String = "Fully substituting buffer should cover all variables of the polynomial."
/** /**
* Substitutes provided Double arguments [args] into [this] Double polynomial. * Substitutes provided Double arguments [args] into [this] Double polynomial.
*/ */
public fun NumberedPolynomial<Double>.substituteFully(args: Buffer<Double>): Double = Double.algebra { public fun NumberedPolynomial<Double>.substituteFully(args: Buffer<Double>): Double = Double.algebra {
val lastSubstitutionVariable = args.size - 1 val lastSubstitutionVariable = args.size - 1
require(coefficients.keys.all { it.lastIndex <= lastSubstitutionVariable }) { "Fully substituting buffer should cover all variables of the polynomial." } require(coefficients.keys.all { it.lastIndex <= lastSubstitutionVariable }) { fullSubstitutionExceptionMessage }
coefficients.entries.fold(.0) { acc, (degs, c) -> coefficients.entries.fold(.0) { acc, (degs, c) ->
acc + degs.foldIndexed(c) { variable, product, deg -> acc + degs.foldIndexed(c) { variable, product, deg ->
if (deg == 0u) product else product * args[variable].pow(deg.toInt()) if (deg == 0u) product else product * args[variable].pow(deg.toInt())
@ -280,7 +282,7 @@ public fun NumberedPolynomial<Double>.substituteFully(args: Buffer<Double>): Dou
*/ */
public fun <C> NumberedPolynomial<C>.substituteFully(ring: Ring<C>, args: Buffer<C>): C = ring { public fun <C> NumberedPolynomial<C>.substituteFully(ring: Ring<C>, args: Buffer<C>): C = ring {
val lastSubstitutionVariable = args.size - 1 val lastSubstitutionVariable = args.size - 1
require(coefficients.keys.all { it.lastIndex <= lastSubstitutionVariable }) { "Fully substituting buffer should cover all variables of the polynomial." } require(coefficients.keys.all { it.lastIndex <= lastSubstitutionVariable }) { fullSubstitutionExceptionMessage }
coefficients.entries.fold(zero) { acc, (degs, c) -> coefficients.entries.fold(zero) { acc, (degs, c) ->
acc + degs.foldIndexed(c) { variable, product, deg -> acc + degs.foldIndexed(c) { variable, product, deg ->
if (deg == 0u) product else product * power(args[variable], deg) if (deg == 0u) product else product * power(args[variable], deg)

View File

@ -8,6 +8,7 @@ package space.kscience.kmath.test.misc
import space.kscience.kmath.functions.NumberedPolynomial import space.kscience.kmath.functions.NumberedPolynomial
import space.kscience.kmath.functions.NumberedRationalFunction import space.kscience.kmath.functions.NumberedRationalFunction
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
fun <T> assertContentEquals(expected: Map<T, Double>, actual: Map<T, Double>, absoluteTolerance: Double, message: String? = null) { fun <T> assertContentEquals(expected: Map<T, Double>, actual: Map<T, Double>, absoluteTolerance: Double, message: String? = null) {
@ -45,4 +46,15 @@ fun assertEquals(
absoluteTolerance, absoluteTolerance,
message message
) )
} }
inline fun <reified T : Throwable> assertFailsWithTypeAndMessage(
expectedMessage: String? = null,
assertionMessage: String? = null,
block: () -> Unit
) =
assertEquals(
expectedMessage,
assertFailsWith(T::class, assertionMessage, block).message,
assertionMessage
)