Skip to content

Instantly share code, notes, and snippets.

@Luiz-Monad
Created May 20, 2021 05:32
Show Gist options
  • Save Luiz-Monad/bee2b40e80eba5ccf6f0880778dbd177 to your computer and use it in GitHub Desktop.
Save Luiz-Monad/bee2b40e80eba5ccf6f0880778dbd177 to your computer and use it in GitHub Desktop.
derivative/groups in kotlin
//diferentiable mathematical group/ring
//http://breandan.net/public/masters_thesis.pdf#page=58
interface Group<X : Group<X>>
object Top : Fun<Top>()
open class Const<T : Fun<T>>(val number : Double) : Fun<T>() { override fun toString() = "$number" }
class Sum<T : Fun<T>>(val left : Fun<T>, val right : Fun<T>) : Fun<T>() { override fun toString() = "($left + $right)" }
class Prod<T : Fun<T>>(val left : Fun<T>, val right : Fun<T>) : Fun<T>() { override fun toString() = "($left * $right)" }
class Var<T : Fun<T>>(val name: String) : Fun<T>() { override val vars: Set<Var<T>> = setOf(this) ; override fun toString() = "$name" }
class Zero<T : Fun<T>> : Const<T>(0.0)
class One<T : Fun<T>> : Const<T>(1.0)
sealed class Fun<X : Fun<X>>(open val vars: Set<Var<X>> = emptySet()) : Group<Fun<X>> {
constructor(vararg fns: Fun<X>) : this(fns.flatMap { it.vars }.toSet())
operator fun invoke(): Double = when(this) {
is Top -> 0.0
is Const -> this.number
is Var -> 0.0
is Prod -> left() * right()
is Sum -> left() + right()
}
fun d(v : Var<X>) : Fun<X> = when(this) {
is Top -> One()
is Const -> Zero()
is Var -> if (v == this) One() else Zero()
is Prod -> left.d(v) * right + left * right.d(v)
is Sum -> left.d(v) + right.d(v)
}
operator fun plus(addend : Fun<X>) = Sum(this, addend)
operator fun times(multiplicand : Fun<X>) = Prod(this, multiplicand)
}
fun main() {
val x = Var<Top>("x")
val result = (Const<Top>(2.0) * Sum(x, Const(3.0)))
val dx = result.d(x)
println("2x + 3 $result") ; println("d/dx( $dx )", ) ; println("= ${dx()}")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment