/*
 Copyright (C) 2009 Ueli Hofstetter

 This source code is release under the BSD License.

 This file is part of JQuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://jquantlib.org/

 JQuantLib is free software: you can redistribute it and/or modify it
 under the terms of the JQuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 . The license is also available online at
 .

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.

 JQuantLib is based on QuantLib. http://quantlib.org/
 When applicable, the original copyright notice follows this notice.
 */

/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
 Copyright (C) 2006 Ferdinando Ametrano
 Copyright (C) 2001, 2002, 2003 Nicolas Di Cesare

 This file is part of QuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://quantlib.org/

 QuantLib is free software: you can redistribute it and/or modify it
 under the terms of the QuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 . The license is also available online at
 .

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.
*/

/*! \file conjugategradient.hpp
    \brief Conjugate gradient optimization method
*/
package org.jquantlib.math.optimization;

import org.jquantlib.math.matrixutilities.Array;
import org.jquantlib.math.optimization.EndCriteria.Type;

//! Multi-dimensional Conjugate Gradient class.
/*! User has to provide line-search method and
    optimization end criteria.
    Search direction \f$ d_i = - f'(x_i) + c_i*d_{i-1} \f$
    where \f$ c_i = ||f'(x_i)||^2/||f'(x_{i-1})||^2 \f$
    and \f$ d_1 = - f'(x_1) \f$
*/

public class ConjugateGradient extends LineSearchBasedMethod {

    public ConjugateGradient(){
        throw new UnsupportedOperationException("Work in progress");
    }


    public ConjugateGradient(final LineSearch lineSearch) {
        if (System.getProperty("EXPERIMENTAL") == null) {
            throw new UnsupportedOperationException("Work in progress");
        }
        if(lineSearch == null){

        }
    }

    /*! Multi-dimensional Conjugate Gradient
    (Fletcher-Reeves-Polak-Ribiere algorithm
    adapted from Numerical Recipes in C, 2nd edition).
     */
    @Override
    public Type minimize(final Problem P, final EndCriteria endCriteria) {
        final EndCriteria.Type ecType = EndCriteria.Type.None;
        P.reset();
        Array x_ = P.currentValue();
        int iterationNumber_ = 0;
        final int stationaryStateIterationNumber_ = 0;
        lineSearch_.setSearchDirection(new Array(x_.size()));

        boolean done = false;

        // function and squared norm of gradient values;
        double fold, gold2;
        final double c;
        final double normdiff;
        // clssical inital value for line-search step
        final double t = 1.0;
        // Set gradient g at the size of the optimization problem search direction.
        final int sz = lineSearch_.searchDirection().size();
        Array g = new Array(sz); Array d = new Array(sz); final Array sddiff = new Array(sz);
        // Initialize cost function and gradient g
        P.setFunctionValue(P.valueAndGradient(g, x_));
        lineSearch_.setSearchDirection(g.mul(-1));
        P.setGradientNormValue(g.dotProduct(g));
        // Loop over iterations
        do{
            // Linesearch
            // FIXME: what are we doing here?
            //t = (*lineSearch_)(P, ecType, endCriteria, t);
            // don't throw: it can fail just because maxIterations exceeded
            //QL_REQUIRE(lineSearch_->succeed(), "line-search failed!");
            if (lineSearch_.succeed_)
            {
                // Updates
                d = lineSearch_.searchDirection();
                // New point
                x_ = lineSearch_.lastX();
                // New function value
                fold = P.functionValue();
                P.setFunctionValue(lineSearch_.lastFunctionValue());
                // New gradient and search direction vectors
                g = lineSearch_.lastGradient();
                // orthogonalization coef
                gold2 = P.gradientNormValue();
                P.setGradientNormValue(lineSearch_.lastGradientNormNorm2());
                //c = P.gradientNormValue() / gold2;
                // conjugate gradient search direction
                //sddiff = (-g + c * d) - lineSearch_->searchDirection();
                //normdiff = std::sqrt(DotProduct(sddiff, sddiff));
                //lineSearch_->searchDirection() = -g + c * d;
                // End criteria
                /* FIXME: This part will be remove in later versions of Quantlib --> to be reviewd!!
                done = endCriteria(iterationNumber_,
                                   stationaryStateIterationNumber_,
                                   true,  //FIXME: it should be in the problem
                                   fold,
                                   Math.sqrt(gold2),
                                   P.functionValue(),
                                   Math.sqrt(P.gradientNormValue()),
                                   ecType
                                   // FIXME: it's never been used! ???
                                   // , normdiff
                                   );*/
                // Increase interation number"
                ++iterationNumber_;
            } else {
                done=true;
            }
        } while (!done);
        P.setCurrentValue(x_);
        return ecType;
        }
    }


 

Ads help maintain this website.