Skip to content
Numerical Method , home
Menu

Forum Numerical Method Optimization

Null Value when using PenaltyMethod

  1. frogman119Participant 2011-02-17 at 9:15 pm

    Hi,

    I have implemented the following code excerpt:

    …. PenaltyMethod optim = new PenaltyMethod(ConstrainedProblem, sp, 1e30, 1e-15, ConjugateGradient.class); …. Vector xmin = new DenseVector(inputarray); …. xmin = optim.search(1000, xmin); …..

    for some optimization problems it works fine, for some I get “Null” back for xmin. What’s the issue for the “Null”-cases?

    Appreciate any clues!

    Thanks & Rgds Roger

  2. RyuParticipant 2011-02-18 at 3:59 am

    Hello Roger,

    Would it be possible for you to post your code, esp., the objective function and the constraints? We will take a look at it.

    Underneah the Penalty Method, it calls an unconstrained optimizer such as Nelder-Mead. Do you get some values back when solving the unconstrained version of the problem? Does it help if you give a different initial values?

  3. frogman119Participant 2011-02-18 at 8:03 pm

    Hi,

    please find below the objective function and the constraints. I have cut out some passages (…). Please apologize the unprofessional way of coding. The array “variables” contains doubles read from a string handed over to the library. I chose the “ConjugateGradient.class” as optimization algorithm in the penalty method. For some problems the routine works fine, for some I get the null value for xmin and the code throws a null-pointer exception when running the last line “xmin = optim.search(1000, xmin);”.

    Thanks a lot for your help. rgds Roger

     ….
     public double [] variables = new double [500];
     public int finalcounter;
    ….
    
    final int fdimension = ((numberofvariables-6)/3) + 1;
    
    //here goes the function to be maximized
    RealScalarFunction f = new RealScalarFunction() {
    
                public int dimension4Domain() {
            return fdimension;
        }
        public int dimension4Range() {
            return 1;
        }
                @Override
                public double evaluate(double… x)
                {
                    double result = 0.0;
                    if ((variables[0] < 1.5) && (variables[0] > 0))
                    {
                        result = result + (variables[1] * (x[0] – variables[4]));
                        int numbertocount1 = fdimension-1;
                        for (int i=0, j=0; j
                        {
                            result += (variables[1] * variables[i+8] * (x[j+1] – variables[i+6]));
                            result += (variables[2] * (x[j+1] – variables[i+6]));
                            result -= (1 + (variables[2] * (x[j+1] – variables[i+6])))* Math.log(1 + (variables[2] * (x[j+1] – variables[i+6])));
                        }
                    }
                    if ((variables[0] > 1.6) && (variables[0] < 2.5))
                    {
                        result = result + (variables[1] * (x[0] – variables[4]));
                        int numbertocount1 = fdimension-1;
                        for (int i=0, j=0; j
                        {
                            result += (variables[1] * variables[i+8] * (x[j+1] – variables[i+6]));
                            result += (variables[2] * (x[j+1] – variables[i+6]));
                            result -= (1 + (variables[2] * (x[j+1] – variables[i+6])))* Math.log(1 + (variables[2] * (x[j+1] – variables[i+6])));
                        }
                    }
                    if (variables[0] > 2.7)
                    {
                        double g = 4 * variables[3];
                        double partresult = 0.0;
                        result = result + (g * (x[0] – variables[4]));
                        int numbertocount1 = fdimension-1;
                        for (int i=0, j=0; j
                        {
                            result += (g * variables[i+8] * (x[j+1] – variables[i+6]));
                            partresult += (x[j+1] – variables[i+6]);
                        }
                        result = result – (2 * partresult * partresult);
                    }
                    if ((variables[0] < 0) && (variables[0] > -1.5))
                    {
                        result = result + (variables[1] * (x[0] – variables[4]));
                        int numbertocount1 = fdimension-1;
                        for (int i=0, j=0; j
                        {
                            result += (variables[1] * variables[i+8] * (x[j+1] – variables[i+6]));
                            result += (variables[2] * (x[j+1] – variables[i+6]));
                            result -= (1 + (variables[2] * (x[j+1] – variables[i+6])))* Math.log(1 + (variables[2] * (x[j+1] – variables[i+6])));
                        }
                    }
                    if ((variables[0] < -1.6) && (variables[0] > -2.5))
                    {
                        result = result + (variables[1] * (x[0] – variables[4]));
                        int numbertocount1 = fdimension-1;
                        for (int i=0, j=0; j
                        {
                            result += (variables[1] * variables[i+8] * (x[j+1] – variables[i+6]));
                            result += (variables[2] * (x[j+1] – variables[i+6]));
                            result -= (1 + (variables[2] * (x[j+1] – variables[i+6])))* Math.log(1 + (variables[2] * (x[j+1] – variables[i+6])));
                        }
                    }
                    if (variables[0] < -2.7)
                    {
                        double g = 4 * variables[3];
                        double partresult = 0.0;
                        result = result + (g * (x[0] – variables[4]));
                        int numbertocount1 = fdimension-1;
                        for (int i=0, j=0; j
                        {
                            result += (g * variables[i+8] * (x[j+1] – variables[i+6]));
                            partresult += (x[j+1] – variables[i+6]);
                        }
                        result = result – (2 * partresult * partresult);
                    }
                    return -result;
                }
    };
            //here go the constraints to be satisfied
            RealScalarFunction[] test = new RealScalarFunction[fdimension];
         if (variables[0] < 0)
         {
            finalcounter = 0;
            for (int i = 0; i
            {
                finalcounter=i;
                test[finalcounter] = new RealScalarFunction(){
                    //non-negativity constraint
                    @Override
                    public int dimension4Domain() {
                        return fdimension;
                    }
                    public int dimension4Range() {
                        return 1;
                    }
                    @Override
                    public double evaluate(double… x)
                    {
                        return (-1 * x[finalcounter]);
                    }
                };
            }
        }
         if (variables[0] > 0)
         {
            finalcounter = 0;
            for (int i = 0; i
            {
                finalcounter=i;
                test[finalcounter] = new RealScalarFunction(){
                   //limitation on the negative values which can be realized
                   @Override
                    public int dimension4Domain() {
                        return fdimension;
                    }
                    public int dimension4Range() {
                        return 1;
                    }
                    @Override
                    public double evaluate(double… x)
                    {
                        return (-100000000 – (1 * x[finalcounter]));
                    }
                };
            }
        }
            RealScalarFunction c16 = new RealScalarFunction() {
                //this is a balance sheet constraint
                @Override
                public int dimension4Domain() {
            return fdimension;
        }
                @Override
        public int dimension4Range() {
            return 1;
        }
                @Override
                public double evaluate(double… x)
                {
                    double result = 0.0;
                    result = variables[5] – x[0];
                    for (int i=1, j = 7; i
                    {
                        result -= (x * variables[j]);
                    }
                    return result;
                }
    };
            //Problem formulation
            Problem ConstrainedProblem = new Problem(f, new EqualityConstraints(c16),new InequalityConstraints(test));
            PenaltyFunction a = new Courant(new EqualityConstraints(c16));
            PenaltyFunction b = new Fletcher (new InequalityConstraints(test));
            SumOfPenalties sp = new SumOfPenalties (a,b);
    PenaltyMethod optim = new PenaltyMethod(ConstrainedProblem, sp, 1e30, 1e-15, ConjugateGradient.class);
            double [] inputarray = new double[fdimension];
            inputarray[0]=variables[4];
            for (int i=1, j=6; i
            {
                inputarray=variables[j];
            }
            Vector xmin = new DenseVector(inputarray);
            xmin = optim.search(1000, xmin);
       …
    
  4. RyuParticipant 2011-02-19 at 2:57 am

    Hello Roger,

    Here is my guess.

    <br />
    //here go the constraints to be satisfied<br />
    RealScalarFunction[] test = new RealScalarFunction[fdimension];<br />
    if (variables[0] < 0)<br />
    {<br />
    ...}<br />
    if (variables[0] > 0)<br />
    {<br />
    ...<br />
    }<br />
    

    The reason why it throws a null exception may be because of the way you defined your inequality constraints. You specify only for the cases when

    if (variables[0] < 0)</code>
    

    and

    if (variables[0] > 0)
    

    but you did not specify what to do when

    if (variables[0] == 0)
    

    .

    You declare an array of [tt:2wx76rn8]RealScalarFunction[/tt:2wx76rn8] but they are all ‘null’ for when

    variables[0]
    

    is exactly 0, which is the case in your code snippet. I believe that the code is OK and it probably will work when you take care of the case when

    variables[0]
    

    is 0.

    Hope this helps.

  5. frogman119Participant 2011-02-22 at 8:41 pm

    excellent! thanks a lot. Indeed, that was the problem.

    rgds Roger