Finish tests generation for numbered utilities. Also:

- Optimize a bit labeled and numbered differentiation.
- Fixed bugs in numbered anti-differentiation.
This commit is contained in:
Gleb Minaev 2022-07-05 03:41:52 +03:00
parent e40977647d
commit 45ed45bd13
3 changed files with 2823 additions and 29 deletions

View File

@ -148,7 +148,7 @@ public fun <C, A : Ring<C>> LabeledPolynomial<C>.derivativeWithRespectTo(
variable: Symbol, variable: Symbol,
): LabeledPolynomial<C> = algebra { ): LabeledPolynomial<C> = algebra {
LabeledPolynomial<C>( LabeledPolynomial<C>(
buildMap(coefficients.size) { buildMap(coefficients.count { it.key.getOrElse(variable) { 0u } >= 1u }) {
coefficients coefficients
.forEach { (degs, c) -> .forEach { (degs, c) ->
if (variable !in degs) return@forEach if (variable !in degs) return@forEach
@ -179,7 +179,7 @@ public fun <C, A : Ring<C>> LabeledPolynomial<C>.nthDerivativeWithRespectTo(
): LabeledPolynomial<C> = algebra { ): LabeledPolynomial<C> = algebra {
if (order == 0u) return this@nthDerivativeWithRespectTo if (order == 0u) return this@nthDerivativeWithRespectTo
LabeledPolynomial<C>( LabeledPolynomial<C>(
buildMap(coefficients.size) { buildMap(coefficients.count { it.key.getOrElse(variable) { 0u } >= order }) {
coefficients coefficients
.forEach { (degs, c) -> .forEach { (degs, c) ->
if (degs.getOrElse(variable) { 0u } < order) return@forEach if (degs.getOrElse(variable) { 0u } < order) return@forEach
@ -213,7 +213,13 @@ public fun <C, A : Ring<C>> LabeledPolynomial<C>.nthDerivativeWithRespectTo(
val filteredVariablesAndOrders = variablesAndOrders.filterValues { it != 0u } val filteredVariablesAndOrders = variablesAndOrders.filterValues { it != 0u }
if (filteredVariablesAndOrders.isEmpty()) return this@nthDerivativeWithRespectTo if (filteredVariablesAndOrders.isEmpty()) return this@nthDerivativeWithRespectTo
LabeledPolynomial<C>( LabeledPolynomial<C>(
buildMap(coefficients.size) { buildMap(
coefficients.count {
variablesAndOrders.all { (variable, order) ->
it.key.getOrElse(variable) { 0u } >= order
}
}
) {
coefficients coefficients
.forEach { (degs, c) -> .forEach { (degs, c) ->
if (filteredVariablesAndOrders.any { (variable, order) -> degs.getOrElse(variable) { 0u } < order }) return@forEach if (filteredVariablesAndOrders.any { (variable, order) -> degs.getOrElse(variable) { 0u } < order }) return@forEach

View File

@ -352,7 +352,7 @@ public fun <C, A : Ring<C>> NumberedPolynomial<C>.derivativeWithRespectTo(
variable: Int, variable: Int,
): NumberedPolynomial<C> = ring { ): NumberedPolynomial<C> = ring {
NumberedPolynomial<C>( NumberedPolynomial<C>(
buildMap(coefficients.size) { buildMap(coefficients.count { it.key.getOrElse(variable) { 0u } >= 1u }) {
coefficients coefficients
.forEach { (degs, c) -> .forEach { (degs, c) ->
if (degs.lastIndex < variable) return@forEach if (degs.lastIndex < variable) return@forEach
@ -382,7 +382,7 @@ public fun <C, A : Ring<C>> NumberedPolynomial<C>.nthDerivativeWithRespectTo(
): NumberedPolynomial<C> = ring { ): NumberedPolynomial<C> = ring {
if (order == 0u) return this@nthDerivativeWithRespectTo if (order == 0u) return this@nthDerivativeWithRespectTo
NumberedPolynomial<C>( NumberedPolynomial<C>(
buildMap(coefficients.size) { buildMap(coefficients.count { it.key.getOrElse(variable) { 0u } >= order }) {
coefficients coefficients
.forEach { (degs, c) -> .forEach { (degs, c) ->
if (degs.lastIndex < variable) return@forEach if (degs.lastIndex < variable) return@forEach
@ -451,8 +451,8 @@ public fun <C, A : Field<C>> NumberedPolynomial<C>.antiderivativeWithRespectTo(
coefficients coefficients
.forEach { (degs, c) -> .forEach { (degs, c) ->
put( put(
List(max(variable + 1, degs.size)) { if (it != variable) degs[it] else degs[it] + 1u }, List(max(variable + 1, degs.size)) { degs.getOrElse(it) { 0u } + if (it != variable) 0u else 1u },
c / multiplyByDoubling(one, degs[variable]) c / multiplyByDoubling(one, degs.getOrElse(variable) { 0u } + 1u)
) )
} }
} }
@ -474,9 +474,9 @@ public fun <C, A : Field<C>> NumberedPolynomial<C>.nthAntiderivativeWithRespectT
coefficients coefficients
.forEach { (degs, c) -> .forEach { (degs, c) ->
put( put(
List(max(variable + 1, degs.size)) { if (it != variable) degs[it] else degs[it] + order }, List(max(variable + 1, degs.size)) { degs.getOrElse(it) { 0u } + if (it != variable) 0u else order },
degs[variable].let { deg -> degs.getOrElse(variable) { 0u }.let { deg ->
(deg downTo deg - order + 1u) (deg + 1u .. deg + order)
.fold(c) { acc, ord -> acc / multiplyByDoubling(one, ord) } .fold(c) { acc, ord -> acc / multiplyByDoubling(one, ord) }
} }
) )
@ -501,11 +501,11 @@ public fun <C, A : Field<C>> NumberedPolynomial<C>.nthAntiderivativeWithRespectT
coefficients coefficients
.forEach { (degs, c) -> .forEach { (degs, c) ->
put( put(
List(max(maxRespectedVariable + 1, degs.size)) { degs[it] + filteredVariablesAndOrders.getOrElse(it) { 0u } }, List(max(maxRespectedVariable + 1, degs.size)) { degs.getOrElse(it) { 0u } + filteredVariablesAndOrders.getOrElse(it) { 0u } },
filteredVariablesAndOrders.entries.fold(c) { acc1, (index, order) -> filteredVariablesAndOrders.entries.fold(c) { acc1, (variable, order) ->
degs[index].let { deg -> degs.getOrElse(variable) { 0u }.let { deg ->
(deg downTo deg - order + 1u) (deg + 1u .. deg + order)
.fold(acc1) { acc2, ord -> acc2 / multiplyByDoubling(one, ord) } .fold(acc1) { acc, ord -> acc / multiplyByDoubling(one, ord) }
} }
} }
) )