You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@commons.apache.org by Nelson Arapé <na...@gmail.com> on 2008/08/01 20:17:46 UTC

[math] Parametric Estimation How can I use this clases to minimize functions

Hello to all,

I am interested in using a LevenbergMarquardt method in order to
minimize functions (say the classical Rosebrook banana function). I
try to use your LevenbergMarquardtEstimator to do this, but i have
problem with the EstimationProblem definition.

In my context I don't know what a measurement is. I have asumed that a
measurement is a element of the f(x) vector.
In another words:
double[] fx = function.eval(x); // each fx[i] is asumed to be a measurment

I made the problem stimation with this asumptions but I dont have the
spected results.

What I am doing wrong? My asumptions are valid? There is a way to
minimize funcions with your library?
Thank in advance
Nelson Arape

PS: My Estimation Problem -------
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.math.estimation.EstimatedParameter;
import org.apache.commons.math.estimation.SimpleEstimationProblem;
import org.apache.commons.math.estimation.WeightedMeasurement;

/**
 * Estimation problem for the minimization of the Rosenbrock function, which has
 * a global minimum at (1, 1)
 */
public class RosProblem extends SimpleEstimationProblem {
    private static final double ROSD = 105.0;
    private static final int N = 2; // Number of elements of the f(x) vector

    private EstimatedParameter[] x;
    /** Cache for easy parameter -> index lookup */
    private Map<EstimatedParameter, Integer> paramIdxCache;

    /**
     * Constructor for the RosProblem
     *
     * @param x
     *            the initial point
     */
    public RosProblem(double[] x) {
        this.x = new EstimatedParameter[x.length];
        this.paramIdxCache = new HashMap<EstimatedParameter, Integer>();

        for (int i = 0; i < x.length; i++) {
            this.x[i] = new EstimatedParameter("x" + i, x[i]);
            addParameter(this.x[i]);
            paramIdxCache.put(this.x[i], i);
        }

        for (int i = 0; i < N; i++) {
            addMeasurement(new ProblemMeasurement(i));
        }
    }

    /**
     * Get all the parameter as double array
     *
     * @return double array of the estimated parameters
     */
    public double[] getX() {
        double[] x = new double[this.x.length];
        for (int i = 0; i < x.length; i++) {
            x[i] = this.x[i].getEstimate();
        }
        return x;
    }

    /**
     * Evaluates the Rosenbrock function at <code>x</code>
     *
     * @param x
     *            the point
     * @param fx
     *            In order to avoid repeated allocations, this array will used
     *            to write the return value. If null, a new array will be
     *            created
     * @return fx Rosenbrock function at <code>x</code>
     */
    public double[] eval(double[] x, double[] fx) {
        if (fx == null) {
            fx = new double[N];
        }
        for (int i = 0; i < N; ++i) {
            double x0 = x[0];
            double x1 = x[1];
            fx[i] = ((1.0 - x0) * (1.0 - x0) + ROSD * (x1 - x0 * x0) *
(x1 - x0 * x0));
        }
        return fx;
    }

    /**
     * Evaluates the Jacobian of the Rosenbrock function at <code>x</code>
     *
     * @param x
     *            the point
     * @param jac
     *            In order to avoid repeated allocations, this matrix will used
     *            to write the return value. If null, a new matrix will be
     *            created
     * @return jac Jacobian of the Rosenbrock function at <code>x</code>
     */
    public double[][] jacf(double[] x, double[][] jac) {
        if (jac == null) {
            jac = new double[N][N];
        }
        for (int i = 0; i < N; ++i) {
            double x0 = x[0];
            double x1 = x[1];
            jac[i][0] = -2 + 2 * x0 - 4 * ROSD * (x1 - x0 * x0) * x0;
            jac[i][1] = 2 * ROSD * (x1 - x0 * x0);
        }
        return jac;
    }

    /**
     * A Measurement for estimation problem. Each Measurement correspond to each
     * element of the f(x) vector
     *
     * @author narape
     */
    private class ProblemMeasurement extends WeightedMeasurement {
        private int index; // This measure index of the f(x) vector

        public ProblemMeasurement(int i) {
            super(1.0, 0.0); // Equal weight, target value 0
            index = i;
        }

        @Override
        public double getTheoreticalValue() {
            double[] x = getX(); // get estimation Vector: x
            double[] fx = eval(x, null); // calc f(x)
            return fx[index]; // return f(x) element of this measurement
        }

        @Override
        public double getPartial(EstimatedParameter parameter) {
            double[] x = getX(); // get estimation Vector: x
            double[][] jac = jacf(x, null); // calc the Jacobian of f(x)
            Integer paramIndex = paramIdxCache.get(parameter);
            return jac[paramIndex][index];
        }
    }
}

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
For additional commands, e-mail: user-help@commons.apache.org


Re: [math] Parametric Estimation How can I use this clases to minimize functions

Posted by Luc Maisonobe <Lu...@free.fr>.
Nelson Arapé a écrit :
> Hello to all,
> 
> I am interested in using a LevenbergMarquardt method in order to
> minimize functions (say the classical Rosebrook banana function). I
> try to use your LevenbergMarquardtEstimator to do this, but i have
> problem with the EstimationProblem definition.

I'll suggest first to look at the test suite in the src/test directory.
There is a MinpackTest class which performs many tests from the minpack
suite. There is a test with the Rosenbrock function and many other
classical ones.

Take care however, this test suite is not meant to be a good example,
you will see comments in the code warning about some inefficient parts
that should be rewritten for production code.

> 
> In my context I don't know what a measurement is. I have asumed that a
> measurement is a element of the f(x) vector.
> In another words:
> double[] fx = function.eval(x); // each fx[i] is asumed to be a measurment

You can do this. A measurement is basically the thing you want to
minimize. For a classical minimum finding problem, you can use f(x).
Measurements are more general, though, and they can be used for other
kind of estimation problems.

> 
> I made the problem stimation with this asumptions but I dont have the
> spected results.
> 
> What I am doing wrong? My asumptions are valid? There is a way to
> minimize funcions with your library?

Yes, it is possible. It is not really obvious because it is more
general, and perhap too general. I will try to improve documentation and
perhaps write tutorials about that.

There is also an open issue to redesign both the estimation and the
optimization packages (see
http://issues.apache.org/jira/browse/MATH-177). They are not user friendly.

Luc

> Thank in advance
> Nelson Arape
> 
> PS: My Estimation Problem -------
> import java.util.HashMap;
> import java.util.Map;
> 
> import org.apache.commons.math.estimation.EstimatedParameter;
> import org.apache.commons.math.estimation.SimpleEstimationProblem;
> import org.apache.commons.math.estimation.WeightedMeasurement;
> 
> /**
>  * Estimation problem for the minimization of the Rosenbrock function, which has
>  * a global minimum at (1, 1)
>  */
> public class RosProblem extends SimpleEstimationProblem {
>     private static final double ROSD = 105.0;
>     private static final int N = 2; // Number of elements of the f(x) vector
> 
>     private EstimatedParameter[] x;
>     /** Cache for easy parameter -> index lookup */
>     private Map<EstimatedParameter, Integer> paramIdxCache;
> 
>     /**
>      * Constructor for the RosProblem
>      *
>      * @param x
>      *            the initial point
>      */
>     public RosProblem(double[] x) {
>         this.x = new EstimatedParameter[x.length];
>         this.paramIdxCache = new HashMap<EstimatedParameter, Integer>();
> 
>         for (int i = 0; i < x.length; i++) {
>             this.x[i] = new EstimatedParameter("x" + i, x[i]);
>             addParameter(this.x[i]);
>             paramIdxCache.put(this.x[i], i);
>         }
> 
>         for (int i = 0; i < N; i++) {
>             addMeasurement(new ProblemMeasurement(i));
>         }
>     }
> 
>     /**
>      * Get all the parameter as double array
>      *
>      * @return double array of the estimated parameters
>      */
>     public double[] getX() {
>         double[] x = new double[this.x.length];
>         for (int i = 0; i < x.length; i++) {
>             x[i] = this.x[i].getEstimate();
>         }
>         return x;
>     }
> 
>     /**
>      * Evaluates the Rosenbrock function at <code>x</code>
>      *
>      * @param x
>      *            the point
>      * @param fx
>      *            In order to avoid repeated allocations, this array will used
>      *            to write the return value. If null, a new array will be
>      *            created
>      * @return fx Rosenbrock function at <code>x</code>
>      */
>     public double[] eval(double[] x, double[] fx) {
>         if (fx == null) {
>             fx = new double[N];
>         }
>         for (int i = 0; i < N; ++i) {
>             double x0 = x[0];
>             double x1 = x[1];
>             fx[i] = ((1.0 - x0) * (1.0 - x0) + ROSD * (x1 - x0 * x0) *
> (x1 - x0 * x0));
>         }
>         return fx;
>     }
> 
>     /**
>      * Evaluates the Jacobian of the Rosenbrock function at <code>x</code>
>      *
>      * @param x
>      *            the point
>      * @param jac
>      *            In order to avoid repeated allocations, this matrix will used
>      *            to write the return value. If null, a new matrix will be
>      *            created
>      * @return jac Jacobian of the Rosenbrock function at <code>x</code>
>      */
>     public double[][] jacf(double[] x, double[][] jac) {
>         if (jac == null) {
>             jac = new double[N][N];
>         }
>         for (int i = 0; i < N; ++i) {
>             double x0 = x[0];
>             double x1 = x[1];
>             jac[i][0] = -2 + 2 * x0 - 4 * ROSD * (x1 - x0 * x0) * x0;
>             jac[i][1] = 2 * ROSD * (x1 - x0 * x0);
>         }
>         return jac;
>     }
> 
>     /**
>      * A Measurement for estimation problem. Each Measurement correspond to each
>      * element of the f(x) vector
>      *
>      * @author narape
>      */
>     private class ProblemMeasurement extends WeightedMeasurement {
>         private int index; // This measure index of the f(x) vector
> 
>         public ProblemMeasurement(int i) {
>             super(1.0, 0.0); // Equal weight, target value 0
>             index = i;
>         }
> 
>         @Override
>         public double getTheoreticalValue() {
>             double[] x = getX(); // get estimation Vector: x
>             double[] fx = eval(x, null); // calc f(x)
>             return fx[index]; // return f(x) element of this measurement
>         }
> 
>         @Override
>         public double getPartial(EstimatedParameter parameter) {
>             double[] x = getX(); // get estimation Vector: x
>             double[][] jac = jacf(x, null); // calc the Jacobian of f(x)
>             Integer paramIndex = paramIdxCache.get(parameter);
>             return jac[paramIndex][index];
>         }
>     }
> }
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
> For additional commands, e-mail: user-help@commons.apache.org
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
For additional commands, e-mail: user-help@commons.apache.org