Removed Any restriction on polynomials

This commit is contained in:
Alexander Nozik 2021-05-19 12:58:01 +03:00
parent ddb8917535
commit 0898285542
9 changed files with 50 additions and 19 deletions

View File

@ -32,6 +32,7 @@
- ColumnarData returns nullable column - ColumnarData returns nullable column
- MST is made sealed interface - MST is made sealed interface
- Replaced MST.Symbolic by Symbol, Symbol now implements MST - Replaced MST.Symbolic by Symbol, Symbol now implements MST
- Removed Any restriction on polynomials
### Deprecated ### Deprecated

View File

@ -5,8 +5,8 @@
package space.kscience.kmath.functions package space.kscience.kmath.functions
import space.kscience.kmath.integration.gaussIntegrator
import space.kscience.kmath.integration.integrate import space.kscience.kmath.integration.integrate
import space.kscience.kmath.integration.integrator
import space.kscience.kmath.integration.value import space.kscience.kmath.integration.value
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.DoubleField
import kotlin.math.pow import kotlin.math.pow
@ -16,7 +16,7 @@ fun main() {
val function: UnivariateFunction<Double> = { x -> 3 * x.pow(2) + 2 * x + 1 } val function: UnivariateFunction<Double> = { x -> 3 * x.pow(2) + 2 * x + 1 }
//get the result of the integration //get the result of the integration
val result = DoubleField.integrator.integrate(0.0..10.0, function = function) val result = DoubleField.gaussIntegrator.integrate(0.0..10.0, function = function)
//the value is nullable because in some cases the integration could not succeed //the value is nullable because in some cases the integration could not succeed
println(result.value) println(result.value)

View File

@ -5,8 +5,8 @@
package space.kscience.kmath.functions package space.kscience.kmath.functions
import space.kscience.kmath.integration.gaussIntegrator
import space.kscience.kmath.integration.integrate import space.kscience.kmath.integration.integrate
import space.kscience.kmath.integration.integrator
import space.kscience.kmath.integration.value import space.kscience.kmath.integration.value
import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.nd import space.kscience.kmath.nd.nd
@ -25,7 +25,7 @@ fun main(): Unit = DoubleField {
val function: (Double) -> StructureND<Double> = { x: Double -> 3 * number(x).pow(2) + 2 * diagonal(x) + 1 } val function: (Double) -> StructureND<Double> = { x: Double -> 3 * number(x).pow(2) + 2 * diagonal(x) + 1 }
//get the result of the integration //get the result of the integration
val result = integrator.integrate(0.0..10.0, function = function) val result = gaussIntegrator.integrate(0.0..10.0, function = function)
//the value is nullable because in some cases the integration could not succeed //the value is nullable because in some cases the integration could not succeed
println(result.value) println(result.value)

View File

@ -19,7 +19,7 @@ import kotlin.math.pow
* *
* @param coefficients constant is the leftmost coefficient. * @param coefficients constant is the leftmost coefficient.
*/ */
public class Polynomial<T : Any>(public val coefficients: List<T>){ public class Polynomial<T>(public val coefficients: List<T>){
override fun toString(): String = "Polynomial$coefficients" override fun toString(): String = "Polynomial$coefficients"
} }
@ -27,7 +27,7 @@ public class Polynomial<T : Any>(public val coefficients: List<T>){
* Returns a [Polynomial] instance with given [coefficients]. * Returns a [Polynomial] instance with given [coefficients].
*/ */
@Suppress("FunctionName") @Suppress("FunctionName")
public fun <T : Any> Polynomial(vararg coefficients: T): Polynomial<T> = Polynomial(coefficients.toList()) public fun <T> Polynomial(vararg coefficients: T): Polynomial<T> = Polynomial(coefficients.toList())
/** /**
* Evaluates the value of the given double polynomial for given double argument. * Evaluates the value of the given double polynomial for given double argument.
@ -38,7 +38,7 @@ public fun Polynomial<Double>.value(): Double = coefficients.reduceIndexed { ind
* Evaluates the value of the given polynomial for given argument. * Evaluates the value of the given polynomial for given argument.
* https://en.wikipedia.org/wiki/Horner%27s_method * https://en.wikipedia.org/wiki/Horner%27s_method
*/ */
public fun <T : Any, C : Ring<T>> Polynomial<T>.value(ring: C, arg: T): T = ring { public fun <T, C : Ring<T>> Polynomial<T>.value(ring: C, arg: T): T = ring {
if (coefficients.isEmpty()) return@ring zero if (coefficients.isEmpty()) return@ring zero
var result: T = coefficients.last() var result: T = coefficients.last()
for (j in coefficients.size - 2 downTo 0) { for (j in coefficients.size - 2 downTo 0) {
@ -50,7 +50,9 @@ public fun <T : Any, C : Ring<T>> Polynomial<T>.value(ring: C, arg: T): T = ring
/** /**
* Represent the polynomial as a regular context-less function. * Represent the polynomial as a regular context-less function.
*/ */
public fun <T : Any, C : Ring<T>> Polynomial<T>.asFunction(ring: C): (T) -> T = { value(ring, it) } public fun <T , C : Ring<T>> Polynomial<T>.asFunction(ring: C): (T) -> T = { value(ring, it) }
//public fun <T: Any>
/** /**
* Space of polynomials. * Space of polynomials.
@ -59,7 +61,7 @@ public fun <T : Any, C : Ring<T>> Polynomial<T>.asFunction(ring: C): (T) -> T =
* @param C the intersection of [Ring] of [T] and [ScaleOperations] of [T]. * @param C the intersection of [Ring] of [T] and [ScaleOperations] of [T].
* @param ring the [C] instance. * @param ring the [C] instance.
*/ */
public class PolynomialSpace<T : Any, C>( public class PolynomialSpace<T, C>(
private val ring: C, private val ring: C,
) : Group<Polynomial<T>>, ScaleOperations<Polynomial<T>> where C : Ring<T>, C : ScaleOperations<T> { ) : Group<Polynomial<T>>, ScaleOperations<Polynomial<T>> where C : Ring<T>, C : ScaleOperations<T> {
public override val zero: Polynomial<T> = Polynomial(emptyList()) public override val zero: Polynomial<T> = Polynomial(emptyList())
@ -87,7 +89,7 @@ public class PolynomialSpace<T : Any, C>(
public operator fun Polynomial<T>.invoke(arg: T): T = value(ring, arg) public operator fun Polynomial<T>.invoke(arg: T): T = value(ring, arg)
} }
public inline fun <T : Any, C, R> C.polynomial(block: PolynomialSpace<T, C>.() -> R): R where C : Ring<T>, C : ScaleOperations<T> { public inline fun <T, C, R> C.polynomial(block: PolynomialSpace<T, C>.() -> R): R where C : Ring<T>, C : ScaleOperations<T> {
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
return PolynomialSpace(this).block() return PolynomialSpace(this).block()
} }

View File

@ -20,6 +20,11 @@ public class UnivariateIntegrandRanges(public val ranges: List<Pair<ClosedRange<
/** /**
* A simple one-pass integrator based on Gauss rule * A simple one-pass integrator based on Gauss rule
* Following integrand features are accepted:
* [GaussIntegratorRuleFactory] - A factory for computing the Gauss integration rule. By default uses [GaussLegendreRuleFactory]
* [IntegrationRange] - the univariate range of integration. By default uses 0..1 interval.
* [IntegrandMaxCalls] - the maximum number of function calls during integration. For non-iterative rules, always uses the maximum number of points. By default uses 10 points.
* [UnivariateIntegrandRanges] - Set of ranges and number of points per range. Defaults to given [IntegrationRange] and [IntegrandMaxCalls]
*/ */
public class GaussIntegrator<T : Any>( public class GaussIntegrator<T : Any>(
public val algebra: Field<T>, public val algebra: Field<T>,
@ -73,13 +78,9 @@ public class GaussIntegrator<T : Any>(
/** /**
* Create a Gauss-Legendre integrator for this field * Create a Gauss-Legendre integrator for this field
* Following integrand features are accepted: * @see [GaussIntegrator]
* * [GaussIntegratorRuleFactory] - A factory for computing the Gauss integration rule. By default uses [GaussLegendreRuleFactory]
* * [IntegrationRange] - the univariate range of integration. By default uses 0..1 interval.
* * [IntegrandMaxCalls] - the maximum number of function calls during integration. For non-iterative rules, always uses the maximum number of points. By default uses 10 points.
* * [UnivariateIntegrandRanges] - Set of ranges and number of points per range. Defaults to given [IntegrationRange] and [IntegrandMaxCalls]
*/ */
public val <T:Any> Field<T>.integrator: GaussIntegrator<T> get() = GaussIntegrator(this) public val <T:Any> Field<T>.gaussIntegrator: GaussIntegrator<T> get() = GaussIntegrator(this)
/** /**

View File

@ -0,0 +1,17 @@
/*
* Copyright 2018-2021 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.integration
import space.kscience.kmath.operations.Ring
public class SimpsonIntegrator<T : Any>(
public val algebra: Ring<T>,
) : UnivariateIntegrator<T> {
override fun integrate(integrand: UnivariateIntegrand<T>): UnivariateIntegrand<T> {
TODO("Not yet implemented")
}
}

View File

@ -45,6 +45,16 @@ public val <T : Any> UnivariateIntegrand<T>.valueOrNull: T? get() = getFeature<I
*/ */
public val <T : Any> UnivariateIntegrand<T>.value: T get() = valueOrNull ?: error("No value in the integrand") public val <T : Any> UnivariateIntegrand<T>.value: T get() = valueOrNull ?: error("No value in the integrand")
/**
* A shortcut method to integrate a [function] with additional [features]. Range must be provided in features.
* The [function] is placed in the end position to allow passing a lambda.
*/
@UnstableKMathAPI
public fun <T: Any> UnivariateIntegrator<T>.integrate(
vararg features: IntegrandFeature,
function: (Double) -> T,
): UnivariateIntegrand<T> = integrate(UnivariateIntegrand(function, *features))
/** /**
* A shortcut method to integrate a [function] in [range] with additional [features]. * A shortcut method to integrate a [function] in [range] with additional [features].
* The [function] is placed in the end position to allow passing a lambda. * The [function] is placed in the end position to allow passing a lambda.

View File

@ -16,7 +16,7 @@ import kotlin.test.assertEquals
class GaussIntegralTest { class GaussIntegralTest {
@Test @Test
fun gaussSin() { fun gaussSin() {
val res = DoubleField.integrator.integrate(0.0..2 * PI) { x -> val res = DoubleField.gaussIntegrator.integrate(0.0..2 * PI) { x ->
sin(x) sin(x)
} }
assertEquals(0.0, res.valueOrNull!!, 1e-2) assertEquals(0.0, res.valueOrNull!!, 1e-2)
@ -24,7 +24,7 @@ class GaussIntegralTest {
@Test @Test
fun gaussUniform() { fun gaussUniform() {
val res = DoubleField.integrator.integrate(35.0..100.0) { x -> val res = DoubleField.gaussIntegrator.integrate(35.0..100.0) { x ->
if(x in 30.0..50.0){ if(x in 30.0..50.0){
1.0 1.0
} else { } else {

View File

@ -5,7 +5,7 @@ pluginManagement {
maven("https://repo.kotlin.link") maven("https://repo.kotlin.link")
} }
val toolsVersion = "0.9.7" val toolsVersion = "0.9.8"
val kotlinVersion = "1.5.0" val kotlinVersion = "1.5.0"
plugins { plugins {