Youssef Shoaib [MOD]
04/30/2025, 9:29 AMAutoCloseScope
can do reverse-mode automatic differentiation:
interface AD<Num> {
val Double.num: Num
val Int.num: Num get() = toDouble().num
operator fun Num.plus(other: Num): Num
operator fun Num.times(other: Num): Num
fun exp(x: Num): Num
}
data class NumB(val value: Double, var d: Double)
fun backwardsAutoClose(x: Double, prog: AD<NumB>.(NumB) -> NumB): Double {
val input = NumB(x, 0.0)
autoCloseScope {
val res = object : AD<NumB> {
override val Double.num: NumB get() = NumB(this, 0.0)
override fun NumB.plus(other: NumB) = NumB(value + other.value, 0.0).also { z ->
onClose {
this.d += z.d
other.d += z.d
}
}
override fun NumB.times(other: NumB) = NumB(value * other.value, 0.0).also { z ->
onClose {
d += other.value * z.d
other.d += value * z.d
}
}
override fun exp(x: NumB): NumB {
val xExp = mathExp(x.value)
val z = NumB(xExp, 0.0)
onClose { x.d += xExp * z.d }
return z
}
}.prog(input)
res.d += 1
}
return input.d
}