N-Dimensional Rosenbrock Function in Clojure
The position of a particle is given as an n-dimensional coordinate. Example of a 5-dimensional coordinate:
(def pos0 [0.3484235400781268 0.6690042605852087 0.8423436081065802 0.5443234425830139 0.46159001581087855])
For any given coordinate X of N dimensions, we can produce a vector of adjacent pairs [[x_i x_i+1]] where i=1..N
Now, in order to get our values for [x_i x_i+1], we need to create a function to turn a sequence of values into a sequence of adjacent pairs, like so:
=> (adj_pairs ['a 'b 'c 'd 'e]) ([a b] [b c] [c d] [d e])
If you look closely, you can see that this is the equivalent of zipping a vector with its own tail. Hence:
(def zip (fn [a b] (map vector a b))) (def adj_pairs (fn [x] (zip x (cdr x))))
Applied to our random position from earlier, we get:
=> (adj_pairs pos0) ([0.3484235400781268 0.6690042605852087] [0.6690042605852087 0.8423436081065802] [0.8423436081065802 0.5443234425830139] [0.5443234425830139 0.46159001581087855])
The Rosenbrock function over two dimensions is defined as:
(def f (fn [x] (+ (pow (- 1 (car x)) 2) (pow (* 100 (- (cadr x) (pow (car x) 2))) 2))))
And we can easily extend it to n-dimensions via reduction, using our list of adjacency pairs:
(def rosenbrock (fn [x] (reduce + (map f (adj_pairs x)))))
Applied to our random position from earlier:
=> (rosenbrock pos0) 5104.192029261473
Global optima in two dimensions:
=> (rosenbrock [1 1]) 0.0
Global optima in eleven dimensions:
=> (rosenbrock [1 1 1 1 1 1 1 1 1 1 1]) 0.0












