Add binding for DoubleArray

This commit is contained in:
Edwin Jakobs
2019-11-02 12:50:09 +01:00
parent 004eab4fae
commit 5546f481c3
2 changed files with 24 additions and 2 deletions

View File

@@ -11,6 +11,14 @@ fun <T : Any> modelToArray(model: T): DoubleArray {
val doubles = mutableListOf<Double>()
model::class.java.declaredFields.forEach {
when {
it.type == DoubleArray::class.java -> {
it.isAccessible = true
val da = it.get(model) as DoubleArray
for (d in da) {
doubles.add(d)
}
}
it.type == Double::class.java -> {
it.isAccessible = true
doubles.add(it.getDouble(model))
@@ -48,6 +56,15 @@ fun <T : Any> arrayToModel(data: DoubleArray, model: T) {
var index = 0
model::class.java.declaredFields.forEach {
when {
it.type == DoubleArray::class.java -> {
it.isAccessible = true
//it.setDouble(model, data[index])
val da = it.get(model) as DoubleArray
for (i in 0 until da.size) {
da[i] = data[index]
index++
}
}
it.type == Double::class.java -> {
it.isAccessible = true
it.setDouble(model, data[index])

View File

@@ -35,6 +35,7 @@ fun max(a: Double, b: Double, c: Double, d: Double, e: Double, f: Double, g: Dou
return max(max(max(max(max(max(max(a, b), c), d), e), f), g), h)
}
fun gradient(x: DoubleArray, objective: (parameters: DoubleArray) -> Double): DoubleArray {
var k = 0
val tempX = x.copyOf()
@@ -83,6 +84,7 @@ private fun add(x: Array<DoubleArray>, y: Array<DoubleArray>) = Array(x.size) {
private fun sub(x: Array<DoubleArray>, y: Array<DoubleArray>) = Array(x.size) { sub(x[it], y[it]) }
private fun mul(x: Array<DoubleArray>, y: Double) = Array(x.size) { mul(x[it], y) }
private fun mul(x: DoubleArray, y: Double) = DoubleArray(x.size) { x[it] * y }
private fun mul(x: DoubleArray, y: DoubleArray) = DoubleArray(x.size) { x[it] * y[it] }
private fun div(x: Array<DoubleArray>, y: Double) = Array(x.size) { div(x[it], y) }
private fun div(x: DoubleArray, y: Double) = DoubleArray(x.size) { x[it] / y }
private fun norm2(x: DoubleArray): Double {
@@ -96,7 +98,9 @@ fun dot(x: Array<DoubleArray>, y: DoubleArray): DoubleArray = DoubleArray(x.size
class MinimizationResult(val solution: DoubleArray, val value: Double, val gradient: DoubleArray,
val inverseHessian: Array<DoubleArray>, val iterations: Int)
fun minimize(_x0: DoubleArray, endOnLineSearch: Boolean = false, tol: Double = 1e-8, maxIterations: Int = 1000, f: (DoubleArray) -> Double): MinimizationResult {
fun minimize(_x0: DoubleArray,
weights: DoubleArray = DoubleArray(_x0.size) { 1.0 },
endOnLineSearch: Boolean = false, tol: Double = 1e-8, maxIterations: Int = 1000, f: (DoubleArray) -> Double): MinimizationResult {
val grad = { a: DoubleArray -> gradient(a, f) }
var x0 = _x0.copyOf()
var g0 = grad(x0)
@@ -175,7 +179,8 @@ fun minimize(_x0: DoubleArray, endOnLineSearch: Boolean = false, tol: Double = 1
fun <T : Any> minimizeModel(model: T, endOnLineSearch: Boolean = false, tol: Double = 1e-8, maxIterations: Int = 1000, function: (T) -> Double) {
val doubles = modelToArray(model)
val solution = minimize(doubles, endOnLineSearch, tol, maxIterations) {
val weights = DoubleArray(doubles.size) { 1.0 }
val solution = minimize(doubles, weights, endOnLineSearch, tol, maxIterations) {
arrayToModel(it, model)
function(model)
}