Merge pull request #326 from mipt-npm/commandertvis/kotlingrad

Promote kmath-kotlingrad to experimental alongside minor documentation and API changes
This commit is contained in:
Alexander Nozik 2021-05-11 09:01:59 +03:00 committed by GitHub
commit e01ee63c03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 106 additions and 41 deletions

View File

@ -26,6 +26,7 @@
- Move MST to core - Move MST to core
- Separated benchmarks and examples - Separated benchmarks and examples
- Rewritten EJML module without ejml-simple - Rewritten EJML module without ejml-simple
- Stability of kmath-ast and kmath-kotilngrad promoted to EXPERIMENTAL.
### Deprecated ### Deprecated
@ -35,7 +36,7 @@
- `contentEquals` from Buffer. It moved to the companion. - `contentEquals` from Buffer. It moved to the companion.
- MSTExpression - MSTExpression
- Expression algebra builders - Expression algebra builders
- Comples and Quaternion no longer are elements. - Complex and Quaternion no longer are elements.
### Fixed ### Fixed
- Ring inherits RingOperations, not GroupOperations - Ring inherits RingOperations, not GroupOperations

View File

@ -207,9 +207,14 @@ One can still use generic algebras though.
<hr/> <hr/>
* ### [kmath-kotlingrad](kmath-kotlingrad) * ### [kmath-kotlingrad](kmath-kotlingrad)
> > Functions, integration and interpolation
> >
> **Maturity**: PROTOTYPE > **Maturity**: EXPERIMENTAL
>
> **Features:**
> - [differentiable-mst-expression](kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/DifferentiableMstExpression.kt) : MST based DifferentiableExpression.
> - [differentiable-mst-expression](kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/DifferentiableMstExpression.kt) : Conversions between Kotlin&nabla;'s SFun and MST
<hr/> <hr/>
* ### [kmath-memory](kmath-memory) * ### [kmath-memory](kmath-memory)

View File

@ -0,0 +1,34 @@
# Module kmath-kotlingrad
[Kotlin∇](https://github.com/breandan/kotlingrad) integration module.
- [differentiable-mst-expression](src/main/kotlin/space/kscience/kmath/kotlingrad/DifferentiableMstExpression.kt) : MST based DifferentiableExpression.
- [differentiable-mst-expression](src/main/kotlin/space/kscience/kmath/kotlingrad/DifferentiableMstExpression.kt) : Conversions between Kotlin∇'s SFun and MST
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-kotlingrad:0.3.0-dev-8`.
**Gradle:**
```gradle
repositories {
maven { url 'https://repo.kotlin.link' }
mavenCentral()
}
dependencies {
implementation 'space.kscience:kmath-kotlingrad:0.3.0-dev-8'
}
```
**Gradle Kotlin DSL:**
```kotlin
repositories {
maven("https://repo.kotlin.link")
mavenCentral()
}
dependencies {
implementation("space.kscience:kmath-kotlingrad:0.3.0-dev-8")
}
```

View File

@ -4,11 +4,27 @@ plugins {
} }
dependencies { dependencies {
api("com.github.breandan:kaliningraph:0.1.4") api("com.github.breandan:kaliningraph:0.1.6")
api("com.github.breandan:kotlingrad:0.4.5") api("com.github.breandan:kotlingrad:0.4.5")
api(project(":kmath-ast")) api(project(":kmath-ast"))
} }
readme { readme {
maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE description = "Functions, integration and interpolation"
maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL
propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md"))
feature(
"differentiable-mst-expression",
"src/main/kotlin/space/kscience/kmath/kotlingrad/DifferentiableMstExpression.kt",
) {
"MST based DifferentiableExpression."
}
feature(
"differentiable-mst-expression",
"src/main/kotlin/space/kscience/kmath/kotlingrad/DifferentiableMstExpression.kt",
) {
"Conversions between Kotlin∇'s SFun and MST"
}
} }

View File

@ -0,0 +1,7 @@
# Module kmath-kotlingrad
[Kotlin∇](https://www.htmlsymbols.xyz/unicode/U+2207) integration module.
${features}
${artifact}

View File

@ -6,6 +6,7 @@
package space.kscience.kmath.kotlingrad package space.kscience.kmath.kotlingrad
import edu.umontreal.kotlingrad.api.SFun import edu.umontreal.kotlingrad.api.SFun
import edu.umontreal.kotlingrad.api.SVar
import space.kscience.kmath.expressions.DifferentiableExpression import space.kscience.kmath.expressions.DifferentiableExpression
import space.kscience.kmath.expressions.MST import space.kscience.kmath.expressions.MST
import space.kscience.kmath.expressions.MstAlgebra import space.kscience.kmath.expressions.MstAlgebra
@ -14,20 +15,20 @@ import space.kscience.kmath.misc.Symbol
import space.kscience.kmath.operations.NumericAlgebra import space.kscience.kmath.operations.NumericAlgebra
/** /**
* Represents wrapper of [MstExpression] implementing [DifferentiableExpression]. * Represents [MST] based [DifferentiableExpression].
* *
* The principle of this API is converting the [mst] to an [SFun], differentiating it with Kotlin, then converting * The principle of this API is converting the [mst] to an [SFun], differentiating it with
* [SFun] back to [MST]. * [Kotlin](https://github.com/breandan/kotlingrad), then converting [SFun] back to [MST].
* *
* @param T the type of number. * @param T The type of number.
* @param A the [NumericAlgebra] of [T]. * @param A The [NumericAlgebra] of [T].
* @property expr the underlying [MstExpression]. * @property algebra The [A] instance.
* @property mst The [MST] node.
*/ */
public class DifferentiableMstExpression<T : Number, A : NumericAlgebra<T>>( public class DifferentiableMstExpression<T : Number, A : NumericAlgebra<T>>(
public val algebra: A, public val algebra: A,
public val mst: MST, public val mst: MST,
) : DifferentiableExpression<T, DifferentiableMstExpression<T, A>> { ) : DifferentiableExpression<T, DifferentiableMstExpression<T, A>> {
public override fun invoke(arguments: Map<Symbol, T>): T = mst.interpret(algebra, arguments) public override fun invoke(arguments: Map<Symbol, T>): T = mst.interpret(algebra, arguments)
public override fun derivativeOrNull(symbols: List<Symbol>): DifferentiableMstExpression<T, A> = public override fun derivativeOrNull(symbols: List<Symbol>): DifferentiableMstExpression<T, A> =
@ -35,7 +36,7 @@ public class DifferentiableMstExpression<T : Number, A : NumericAlgebra<T>>(
algebra, algebra,
symbols.map(Symbol::identity) symbols.map(Symbol::identity)
.map(MstAlgebra::bindSymbol) .map(MstAlgebra::bindSymbol)
.map { it.toSVar<KMathNumber<T, A>>() } .map<MST.Symbolic, SVar<KMathNumber<T, A>>>(MST.Symbolic::toSVar)
.fold(mst.toSFun(), SFun<KMathNumber<T, A>>::d) .fold(mst.toSFun(), SFun<KMathNumber<T, A>>::d)
.toMst(), .toMst(),
) )

View File

@ -5,19 +5,26 @@
package space.kscience.kmath.kotlingrad package space.kscience.kmath.kotlingrad
import edu.umontreal.kotlingrad.api.RealNumber
import edu.umontreal.kotlingrad.api.SConst import edu.umontreal.kotlingrad.api.SConst
import space.kscience.kmath.operations.NumericAlgebra import space.kscience.kmath.operations.NumericAlgebra
/** /**
* Implements [RealNumber] by delegating its functionality to [NumericAlgebra]. * Implements [SConst] by delegating its functionality to [NumericAlgebra].
* *
* @param T the type of number. * @param T The type of number.
* @param A the [NumericAlgebra] of [T]. * @param A The [NumericAlgebra] over [T].
* @property algebra the algebra. * @property algebra The algebra.
* @param value the value of this number. * @property value The value of this number.
*/ */
public class KMathNumber<T, A>(public val algebra: A, value: T) : public class KMathNumber<T, A>(public val algebra: A, public override val value: T) :
RealNumber<KMathNumber<T, A>, T>(value) where T : Number, A : NumericAlgebra<T> { SConst<KMathNumber<T, A>>(value) where T : Number, A : NumericAlgebra<T> {
public override fun wrap(number: Number): SConst<KMathNumber<T, A>> = SConst(algebra.number(number)) /**
* Returns a string representation of the [value].
*/
public override fun toString(): String = value.toString()
/**
* Wraps [Number] to [KMathNumber].
*/
public override fun wrap(number: Number): KMathNumber<T, A> = KMathNumber(algebra, algebra.number(number))
} }

View File

@ -15,16 +15,16 @@ import space.kscience.kmath.operations.*
/** /**
* Maps [SVar] to [MST.Symbolic] directly. * Maps [SVar] to [MST.Symbolic] directly.
* *
* @receiver the variable. * @receiver The variable.
* @return a node. * @returnAa node.
*/ */
public fun <X : SFun<X>> SVar<X>.toMst(): MST.Symbolic = MstAlgebra.bindSymbol(name) public fun <X : SFun<X>> SVar<X>.toMst(): MST.Symbolic = MstAlgebra.bindSymbol(name)
/** /**
* Maps [SVar] to [MST.Numeric] directly. * Maps [SVar] to [MST.Numeric] directly.
* *
* @receiver the constant. * @receiver The constant.
* @return a node. * @return A node.
*/ */
public fun <X : SFun<X>> SConst<X>.toMst(): MST.Numeric = MstAlgebra.number(doubleValue) public fun <X : SFun<X>> SConst<X>.toMst(): MST.Numeric = MstAlgebra.number(doubleValue)
@ -49,8 +49,8 @@ public fun <X : SFun<X>> SConst<X>.toMst(): MST.Numeric = MstAlgebra.number(doub
* - [VSumAll] is requested to be evaluated; * - [VSumAll] is requested to be evaluated;
* - [Derivative] is requested to be evaluated. * - [Derivative] is requested to be evaluated.
* *
* @receiver the scalar function. * @receiver The scalar function.
* @return a node. * @return A node.
*/ */
public fun <X : SFun<X>> SFun<X>.toMst(): MST = MstExtendedField { public fun <X : SFun<X>> SFun<X>.toMst(): MST = MstExtendedField {
when (this@toMst) { when (this@toMst) {
@ -74,17 +74,16 @@ public fun <X : SFun<X>> SFun<X>.toMst(): MST = MstExtendedField {
/** /**
* Maps [MST.Numeric] to [SConst] directly. * Maps [MST.Numeric] to [SConst] directly.
* *
* @receiver the node. * @receiver The node.
* @return a new constant. * @return A new constant.
*/ */
public fun <X : SFun<X>> MST.Numeric.toSConst(): SConst<X> = SConst(value) public fun <X : SFun<X>> MST.Numeric.toSConst(): SConst<X> = SConst(value)
/** /**
* Maps [MST.Symbolic] to [SVar] directly. * Maps [MST.Symbolic] to [SVar] directly.
* *
* @receiver the node. * @receiver The node.
* @param proto the prototype instance. * @return A new variable.
* @return a new variable.
*/ */
internal fun <X : SFun<X>> MST.Symbolic.toSVar(): SVar<X> = SVar(value) internal fun <X : SFun<X>> MST.Symbolic.toSVar(): SVar<X> = SVar(value)
@ -98,9 +97,8 @@ internal fun <X : SFun<X>> MST.Symbolic.toSVar(): SVar<X> = SVar(value)
* - [MST.Unary] -> [Negative], [Sine], [Cosine], [Tangent], [Power], [Log]; * - [MST.Unary] -> [Negative], [Sine], [Cosine], [Tangent], [Power], [Log];
* - [MST.Binary] -> [Sum], [Prod], [Power]. * - [MST.Binary] -> [Sum], [Prod], [Power].
* *
* @receiver the node. * @receiver The node.
* @param proto the prototype instance. * @return A scalar function.
* @return a scalar function.
*/ */
public fun <X : SFun<X>> MST.toSFun(): SFun<X> = when (this) { public fun <X : SFun<X>> MST.toSFun(): SFun<X> = when (this) {
is MST.Numeric -> toSConst() is MST.Numeric -> toSConst()

View File

@ -10,7 +10,7 @@ import space.kscience.kmath.asm.compileToExpression
import space.kscience.kmath.ast.parseMath import space.kscience.kmath.ast.parseMath
import space.kscience.kmath.expressions.MstAlgebra import space.kscience.kmath.expressions.MstAlgebra
import space.kscience.kmath.expressions.invoke import space.kscience.kmath.expressions.invoke
import space.kscience.kmath.misc.symbol import space.kscience.kmath.misc.Symbol.Companion.x
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.DoubleField
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -65,8 +65,4 @@ internal class AdaptingTests {
assertEquals(actualDerivative(x to 0.1), expectedDerivative(x to 0.1)) assertEquals(actualDerivative(x to 0.1), expectedDerivative(x to 0.1))
} }
private companion object {
private val x by symbol
}
} }