Feature: Polynomials and rational functions #469

Merged
lounres merged 132 commits from feature/polynomials into dev 2022-07-28 18:04:06 +03:00
2 changed files with 171 additions and 36 deletions
Showing only changes of commit ebd7f799ad - Show all commits

View File

@ -545,62 +545,169 @@ public fun <C, A : Ring<C>> NumberedPolynomial<C>.asPolynomialFunctionOver(ring:
* Returns algebraic derivative of received polynomial. * Returns algebraic derivative of received polynomial.
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun <C, A> NumberedPolynomial<C>.derivativeBy( public fun <C, A : Ring<C>> NumberedPolynomial<C>.derivativeWithRespectTo(
algebra: A, algebra: A,
variable: Int, variable: Int,
): Polynomial<C> where A : Ring<C>, A : NumericAlgebra<C> = algebra { ): NumberedPolynomial<C> = algebra {
TODO() NumberedPolynomial<C>(
buildMap(coefficients.size) {
coefficients.forEach { (degs, c) ->
put(
degs.mapIndexed { index, deg ->
when {
index != variable -> deg
deg > 0u -> deg - 1u
else -> return@forEach
}
},
optimizedMultiply(c, degs.getOrElse(variable) { 1u }.toInt())
)
}
}
)
}
/**
* Returns algebraic derivative of received polynomial.
*/ // TODO: This one does not work!!!
@UnstableKMathAPI
public fun <C, A : Ring<C>> NumberedPolynomial<C>.derivativeWithRespectTo(
algebra: A,
variables: IntArray,
): NumberedPolynomial<C> = algebra {
NumberedPolynomial<C>(
buildMap(coefficients.size) {
coefficients.forEach { (degs, c) ->
put(
degs.mapIndexed { index, deg ->
when {
index !in variables -> deg
deg > 0u -> deg - 1u
else -> return@forEach
}
},
optimizedMultiply(c, variables.fold(1u) { acc, variable -> acc * degs.getOrElse(variable) { 1u } }.toInt())
)
}
}
)
}
/**
* Returns algebraic derivative of received polynomial.
*/ // TODO: This one does not work!!!
@UnstableKMathAPI
public fun <C, A : Ring<C>> NumberedPolynomial<C>.derivativeWithRespectTo(
algebra: A,
variables: Collection<Int>,
): NumberedPolynomial<C> = algebra {
NumberedPolynomial<C>(
buildMap(coefficients.size) {
coefficients.forEach { (degs, c) ->
put(
degs.mapIndexed { index, deg ->
when {
index !in variables -> deg
deg > 0u -> deg - 1u
else -> return@forEach
}
},
optimizedMultiply(c, variables.fold(1u) { acc, variable -> acc * degs.getOrElse(variable) { 1u } }.toInt())
)
}
}
)
} }
/** /**
* Returns algebraic derivative of received polynomial. * Returns algebraic derivative of received polynomial.
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun <C, A> NumberedPolynomial<C>.derivativeBy( public fun <C, A : Ring<C>> NumberedPolynomial<C>.nthDerivativeWithRespectTo(
algebra: A,
variables: IntArray,
): Polynomial<C> where A : Ring<C>, A : NumericAlgebra<C> = algebra {
TODO()
}
/**
* Returns algebraic derivative of received polynomial.
*/
@UnstableKMathAPI
public fun <C, A> NumberedPolynomial<C>.derivativeBy(
algebra: A,
variables: Collection<Int>,
): Polynomial<C> where A : Ring<C>, A : NumericAlgebra<C> = derivativeBy(algebra, variables.toIntArray())
/**
* Create a polynomial witch represents indefinite integral version of this polynomial
*/
@UnstableKMathAPI
public fun <C, A> NumberedPolynomial<C>.antiderivativeBy(
algebra: A, algebra: A,
variable: Int, variable: Int,
): Polynomial<C> where A : Field<C>, A : NumericAlgebra<C> = algebra { order: UInt
TODO() ): NumberedPolynomial<C> = algebra {
NumberedPolynomial<C>(
buildMap(coefficients.size) {
coefficients.forEach { (degs, c) ->
put(
degs.mapIndexed { index, deg ->
when {
index != variable -> deg
deg >= order -> deg - order
else -> return@forEach
}
},
degs.getOrElse(variable) { 1u }.toInt().let {
(0u until order).fold(c) { acc, ord ->
optimizedMultiply(acc, ord.toInt())
}
}
)
}
}
)
} }
/** /**
* Create a polynomial witch represents indefinite integral version of this polynomial * Returns algebraic antiderivative of received polynomial.
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun <C, A> NumberedPolynomial<C>.antiderivativeBy( public fun <C, A : Field<C>> NumberedPolynomial<C>.antiderivativeWithRespectTo(
algebra: A,
variable: Int,
): NumberedPolynomial<C> = algebra {
NumberedPolynomial<C>(
buildMap(coefficients.size) {
coefficients.forEach { (degs, c) ->
put(
degs.mapIndexed { index, deg -> if(index != variable) deg else deg + 1u },
c / optimizedMultiply(one, degs.getOrElse(variable) { 1u }.toInt())
)
}
}
)
}
/**
* Returns algebraic antiderivative of received polynomial.
*/ // TODO: This one does not work!!!
@UnstableKMathAPI
public fun <C, A : Field<C>> NumberedPolynomial<C>.antiderivativeWithRespectTo(
algebra: A, algebra: A,
variables: IntArray, variables: IntArray,
): Polynomial<C> where A : Field<C>, A : NumericAlgebra<C> = algebra { ): NumberedPolynomial<C> = algebra {
TODO() NumberedPolynomial<C>(
buildMap(coefficients.size) {
coefficients.forEach { (degs, c) ->
put(
degs.mapIndexed { index, deg -> if(index !in variables) deg else deg + 1u },
c / optimizedMultiply(one, variables.fold(1u) { acc, variable -> acc * degs.getOrElse(variable) { 1u } }.toInt())
)
}
}
)
} }
/** /**
* Create a polynomial witch represents indefinite integral version of this polynomial * Returns algebraic antiderivative of received polynomial.
*/ */ // TODO: This one does not work!!!
@UnstableKMathAPI @UnstableKMathAPI
public fun <C, A> NumberedPolynomial<C>.antiderivativeBy( public fun <C, A : Field<C>> NumberedPolynomial<C>.antiderivativeWithRespectTo(
algebra: A, algebra: A,
variables: Collection<Int>, variables: Collection<Int>,
): Polynomial<C> where A : Field<C>, A : NumericAlgebra<C> = antiderivativeBy(algebra, variables.toIntArray()) ): NumberedPolynomial<C> = algebra {
NumberedPolynomial<C>(
buildMap(coefficients.size) {
coefficients.forEach { (degs, c) ->
put(
degs.mapIndexed { index, deg -> if(index !in variables) deg else deg + 1u },
c / optimizedMultiply(one, variables.fold(1u) { acc, variable -> acc * degs.getOrElse(variable) { 1u } }.toInt())
)
}
}
)
}
// endregion // endregion

View File

@ -109,11 +109,23 @@ public fun <C, A : Ring<C>> Polynomial<C>.asPolynomialFunctionOver(ring: A): (Po
public fun <C, A> Polynomial<C>.derivative( public fun <C, A> Polynomial<C>.derivative(
algebra: A, algebra: A,
): Polynomial<C> where A : Ring<C>, A : NumericAlgebra<C> = algebra { ): Polynomial<C> where A : Ring<C>, A : NumericAlgebra<C> = algebra {
Polynomial(coefficients.drop(1).mapIndexed { index, t -> number(index) * t }) Polynomial(coefficients.drop(1).mapIndexed { index, c -> number(index) * c })
} }
/** /**
* Create a polynomial witch represents indefinite integral version of this polynomial * Returns algebraic derivative of received polynomial.
*/
@UnstableKMathAPI
public fun <C, A> Polynomial<C>.nthDerivative(
algebra: A,
order: UInt,
): Polynomial<C> where A : Ring<C>, A : NumericAlgebra<C> = algebra {
TODO()
Polynomial(coefficients.drop(order.toInt()).mapIndexed { index, c -> number(index) * c })
}
/**
* Returns algebraic antiderivative of received polynomial.
*/ */
@UnstableKMathAPI @UnstableKMathAPI
public fun <C, A> Polynomial<C>.antiderivative( public fun <C, A> Polynomial<C>.antiderivative(
@ -126,6 +138,22 @@ public fun <C, A> Polynomial<C>.antiderivative(
Polynomial(integratedCoefficients) Polynomial(integratedCoefficients)
} }
/**
* Returns algebraic antiderivative of received polynomial.
*/
@UnstableKMathAPI
public fun <C, A> Polynomial<C>.nthAntiderivative(
algebra: A,
order: UInt,
): Polynomial<C> where A : Field<C>, A : NumericAlgebra<C> = algebra {
TODO()
val integratedCoefficients = buildList(coefficients.size + 1) {
add(zero)
coefficients.forEachIndexed{ index, t -> add(t / number(index + 1)) }
}
Polynomial(integratedCoefficients)
}
/** /**
* Compute a definite integral of a given polynomial in a [range] * Compute a definite integral of a given polynomial in a [range]
*/ */