io.rtron.math.analysis.function.univariate.pure.PolynomialFunction.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rtron-math Show documentation
Show all versions of rtron-math Show documentation
Component 'rtron-math' of rtron.
The newest version!
/*
* Copyright 2019-2022 Chair of Geoinformatics, Technical University of Munich
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.rtron.math.analysis.function.univariate.pure
import com.github.kittinunf.result.Result
import io.rtron.math.analysis.function.univariate.UnivariateFunction
import io.rtron.math.range.BoundType
import io.rtron.math.range.Range
import org.apache.commons.math3.analysis.polynomials.PolynomialFunction as CMPolynomialFunction
fun CMPolynomialFunction.toPolynomialFunction() = PolynomialFunction(this.coefficients)
/**
* Polynomial function of form f(x) = c[0] + c[1]*x + c[2]*x^2 + ... + c\[N]*x^N.
*
* @param coefficients coefficients for f(x), whereby coefficients[0] corresponds to c0
* @param domain domain for which the polynomial function is defined
*/
data class PolynomialFunction(
val coefficients: DoubleArray,
override val domain: Range = Range.all()
) : UnivariateFunction() {
// Properties and Initializers
init {
require(coefficients.isNotEmpty()) { "At least one coefficient must be given." }
require(coefficients.all { it.isFinite() }) { "All coefficients must be finite." }
}
/** adapted polynomial of Apache Commons Math */
private val _polynomialFunction by lazy { CMPolynomialFunction(coefficients) }
/** degree of the polynomial function */
val degree by lazy { _polynomialFunction.degree() }
/** derivative of this polynomial function */
private val polynomialDerivative by lazy { _polynomialFunction.polynomialDerivative().toPolynomialFunction() }
// Secondary Constructors
constructor(coefficients: List) : this(coefficients.toDoubleArray())
// Methods
override fun valueUnbounded(x: Double): Result =
Result.success(_polynomialFunction.value(x))
override fun slopeUnbounded(x: Double): Result =
polynomialDerivative.valueUnbounded(x)
/**
* Returns the calculated value of f(x), if [x] is within the function's domain. Otherwise null is returned.
*/
fun valueOrNull(x: Double): Double? =
when (x) {
in domain -> _polynomialFunction.value(x)
else -> null
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as PolynomialFunction
if (!coefficients.contentEquals(other.coefficients)) return false
return true
}
override fun hashCode(): Int {
return coefficients.contentHashCode()
}
// Conversions
override fun toString(): String {
return "PolynomialFunction(polynomialFunction=$_polynomialFunction)"
}
companion object {
/**
* Build a polynomial function with providing its length, which is used to construct the domain [0, [length]
*
* @param coefficients the polynomial's coefficients
* @param length the length of the domain [0, length]
* @param upperBoundType open or closed upper bound type
*/
fun of(coefficients: DoubleArray, length: Double, upperBoundType: BoundType = BoundType.OPEN):
PolynomialFunction {
require(length > 0.0) { "Length must be greater than zero." }
return when {
length.isFinite() -> PolynomialFunction(coefficients, Range.closedX(0.0, length, upperBoundType))
length == Double.POSITIVE_INFINITY -> PolynomialFunction(coefficients, Range.atLeast(0.0))
else -> throw IllegalArgumentException("Unknown length state")
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy