Rosenbrock’s banana function

Rosenbrock’s banana function is a famous test case for optimization software. It’s called the banana function because of its curved contours.

The definition of the function is

f(x, y) = (1 - x)^2 + 100(y - x^2)^2

The function has a global minimum at (1, 1). If an optimization method starts at the point (−1.2, 1), it has to find its way to the other side of a flat, curved valley to find the optimal point.

Rosenbrock’s banana function is just one of the canonical test functions in the paper “Testing Unconstrained Optimization Software” by Moré, Garbow, and Hillstrom in ACM Transactions on Mathematical Software Vol. 7, No. 1, March 1981, pp 17-41. The starting point (−1.2, 1) mentioned above comes from the starting point required in that paper.

I mentioned a while back that I was trying out Python alternatives for tasks I have done in Mathematica. I tried making contour plots with Python using matplotlib. This was challenging to figure out. The plots did not look very good, though I imagine I could have made satisfactory plots if I had explored the options. Instead, I fired up Mathematica and produced the plot above easily using the following code.

Banana[x_, y_] := (1 - x)^2 + 100 (y - x*x)^2
ContourPlot[Banana[x, y], {x, -1.5, 1.5}, {y, 0.7, 2.0}]

7 thoughts on “Rosenbrock’s banana function

  1. John, don’t give up on Python! In SAGE, that will be something like

    x,y = var(‘x,y’)
    banana(x,y) = (1 – x)^2 + 100*(y – x*x)^2
    contour_plot(banana(x,y),(x,-1.5, 1.5), (y, 0.7, 2.0),cmap=’pink’)

  2. And in matplotlib it’s something like

    from pylab import mgrid, contourf, cm, show
    f = lambda x,y: (1 - x)**2 + 100*(y - x**2)**2
    x,y = mgrid[-1.5:1.5:50j, 0.7:2:50j]
    contourf(x, y, f(x,y), cmap=cm.Purples_r)

  3. +1 for Sage, and it’s even easier than Sergey makes it look; since variables get automatically recognized in a function definition, you can skip the line

    x, y = var('x,y')

    and go straight to

    banana(x, y) = (1 - x)^2 + 100(y - x * x)^2

    The “cmap” option in contour_plot is optional as well.

  4. Sorry to post again, but Sage also handles the optimization question nicely; using the “minimize” command, which can use a couple of different algorithms to find the minimum of a function:

    sage: minimize(banana, [-1.2, 1], algorithm='powell')
    Optimization terminated successfully.
    Current function value: 0.000000
    Iterations: 23
    Function evaluations: 665
    (1.0, 1.0)

    If I had left the “algorithm” option blank, I think it would have used Broyden-Fletcher-Goldfarb-Shannon. This algorithm yielded a slightly different answer.

  5. Hi John.
    Jon Harrop (Flying Frog) wrote about gradient and used banana to illustrate; no plot though.

    And the following defines the famous Rosenbrock “banana” function that is notoriously difficult to minimize due to its curvature around the minimum:

    > let rosenbrock (xs: vector) =
    let x, y = xs.[0], xs.[1]
    pown (1.0 – x) 2 + 100.0 * pown (y – pown x 2) 2;;
    val rosenbrock : vector -> floatThe minimum at (1, 1) may be found quickly and easily using the functions defined above as follows:

    > let xs =
    vector[0.0; 0.0]
    |> gradientDescent rosenbrock (grad rosenbrock);;
    val xs : Vector = vector [|0.9977180571; 0.99543389|]

  6. There is a very simple algorithm that is competitive with current genetic and ES algorithms.
    I have some example code here:
    Well it is an ES algorithm but it uses a multi-scale approach. It is similar to Continuous Gray Code optimization. A few other people have come up with basically the same idea in the past.
    I also have some code on the Walsh Hadamard transform you may peruse if you wish:
    But I have to say that some ideas in that are only joyful playing.

Comments are closed.