# Polynomial f(x, y) = 5 x^2 - 6x y + 5 y^2
fun <- function(x) {
    5 * x[1]^2 - 6 * x[1] * x[1] + 5 * x[2]^2
}
# Update, df(x, y)/dx = 0  =>  x = 6 y / 10 for y fixed
# The same the other way arround
update <- function(x, i) {
    (6 / 10) * if (i == 1) x[2] else x[1]
}
# call with initial values (x, y) = (-0.5, -1)
stopifnot(all.equal(
    ICU(fun, update, c(-0.5, -1)),
    c(0, 0) # known minimum
))

# Same problem as above but with a list of parameters
fun <- function(params) {
    5 * params$x^2 - 6 * params$x * params$x + 5 * params$y^2
}
# Update, df(x, y)/dx = 0  =>  x = 6 y / 10 for y fixed
# The same the other way arround
update <- function(params, i) {
    (6 / 10) * if (i == 1) params$y else params$x
}
# and a callback
callback <- function(iter, params) {
    cat(sprintf("%3d - fun(%7.4f, %7.4f) = %6.4f\n",
        iter, params$x, params$y, fun(params)))
}
# call with initial values (x, y) = (-0.5, -1)
ICU(fun, update, list(x = -0.5, y = -1), callback = callback)
