polynomial fitting with LeastSquareProblem / CurveFitting.cpp

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

polynomial fitting with LeastSquareProblem / CurveFitting.cpp

piers august
Hi All,

I want to use the example in CurveFitting.cpp to base a polynomial fit off but can't compile it. 

I'm getting errors for the line   class CurveFittingProblem  : public LeastSquareProblem<Array,Matrix> { ...
the error is:

CurveFitting.cpp:91: error: expected template-name before ‘<’ token
CurveFitting.cpp:91: error: expected `{' before ‘<’ token
CurveFitting.cpp:91: error: expected unqualified-id before ‘<’ token

gcc version 4.1.1

Can anyone take a look  on what I've got wrong?
I have tried using the namespace qualifiers in the template inheritance but with no luck.

thanks
Piers


// C++ includes

#include <ql/quantlib.hpp>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <iomanip>
#include <cmath>

using namespace QuantLib;
using namespace std;


// personal headers
#include <ql/time/date.hpp>
#include <ql/math/array.hpp>
#include <ql/math/matrix.hpp>
#include <ql/errors.hpp>

//#include <portability.h>
#include <ql/math/optimization/leastsquare.hpp>
#include <timer.h>

/*using QuantLib::Date;
using QuantLib::Array;
using QuantLib::Math::Matrix;
using QuantLib::Math::transpose;
using QuantLib::Error;*/



inline
std::ostream& operator<< (std::ostream& os, const QuantLib::Array& v)
{
    size_t i, sz = v.size();
 
    os << "[";
    for (i=0; i<sz-1; ++i)
        os << v[i] << " ";
    os << v[sz-1]
       << "]"
       << std::endl;
 
    return os;
}

/*!
  Brace volatility term structure function
  ( similar to Nelson-Siegel function for zero rate)

  sigma(t) = (a+b*t)*exp(-c*t) + d
*/
class BraceVolatilityFunction {
  //! coefficients of the function
  double a_, b_, c_, d_;
public :
  //! Default constructor to set coeffs
  inline BraceVolatilityFunction(double a, double b, double c, double d)
    : a_(a), b_(b), c_(c), d_(d) {}
  //! Destructor
  inline ~BraceVolatilityFunction() {}

  //! operator to evaluate the function at given time to maturity
  inline double operator() (double t)
  { return (a_+b_*t)*exp(-c_*t) + d_; }

  //! First derivative with respect to a
  inline double da(double t)
  { return exp(-c_*t); }

  //! First derivative with respect to b
  inline double db(double t)
  { return t*exp(-c_*t); }

  //! First derivative with respect to c
  inline double dc(double t)
  { return -t*(a_+b_*t)*exp(-c_*t); }

  //! First derivative with respect to d
  inline double dd(double t)
  { return 1.; }
};


/*!
  Curve Fitting Problem

  It is an inverse problem
 */
class CurveFittingProblem
    : public LeastSquareProblem<Array,Matrix> {
    const Array &ttm_;
    const Array &target_;
public :
  /*!
    Default constructor : set time to maturity vector
    and target value
  */
  CurveFittingProblem(const Array& ttm, const Array& target)
      : ttm_(ttm), target_(target) {}
  //! Destructor
  virtual ~CurveFittingProblem() {}

  //! Size of the least square problem
  virtual int size() { return ttm_.size(); }

  //! return function and target values
  virtual void targetAndValue(const Array& abcd,
                              Array& target,
                              Array& fct2fit)
  {
    BraceVolatilityFunction bvf(abcd[0],abcd[1],abcd[2],abcd[3]);
    target = target_;// target values
    for (int i=0; i<ttm_.size(); ++i)
        fct2fit[i] = bvf(ttm_[i]);
  }

  //! return function, target and first derivatives values
  virtual void targetValueAndfirstDerivative(const Array& abcd,
                                             Matrix& grad_fct2fit,
                                             Array& target,
                                             Array& fct2fit)
  {
    BraceVolatilityFunction bvf(abcd[0],abcd[1],abcd[2],abcd[3]);
    target = target_;// target values
    for (int i=0; i<ttm_.size(); ++i) {
        // function value at current point abcd
        fct2fit[i] = bvf(ttm_[i]);
        /*
            matrix of first derivatives :
            the derivatives with respect to the parameter a,b,c,d
            are stored by row.
        */
        grad_fct2fit[i][0] = bvf.da(ttm_[i]);
        grad_fct2fit[i][1] = bvf.db(ttm_[i]);
        grad_fct2fit[i][2] = bvf.dc(ttm_[i]);
        grad_fct2fit[i][3] = bvf.dd(ttm_[i]);
    }

  }
};

/*
    We define here an inverse problem to show how to fit
    parametric function to data.
*/
int main()
{
    /*
        Parameter values that produce the volatility hump.
        Consider it as optimal values of the curve fitting
        problem.
    */
    double abcd_[4] = {0.147014, 0.057302, 0.249964, 0.148556 };
    Array abcd(4);
    abcd[0] = abcd_[0];
    abcd[1] = abcd_[1];
    abcd[2] = abcd_[2];
    abcd[3] = abcd_[3];

    cout << "Optimal values  : " << abcd << endl;

    // Define the target volatility function
    BraceVolatilityFunction bvf(abcd[0],abcd[1],abcd[2],abcd[3]);

    Timer t;
    t.start();
    try {
 
        double t,
            startDate = 0.0, // start date of volatilty
            endDate = 20., // end date of volatility
            period = 0.25; // period length between values (in year fraction : quarterly)

        int i, periodNumber = (int)(endDate / period); // number of period

        Array targetValue(periodNumber), timeToMaturity(periodNumber);
        // Fill target and time to maturity arrays
        for (i=0; i<periodNumber; ++i) {
            t = startDate + i*period;
            timeToMaturity[i] = t;
            targetValue[i] = bvf(t);
        }

        // Accuracy of the optimization method
        double accuracy = 1e-10;// It is the square of the accuracy
        // Maximum number of iterations
        int maxiter = 10000;

        Array initialValue(4, 0.1);
       
        // Least square optimizer
        NonLinearLeastSquare<Array > lsqnonlin(accuracy,maxiter);

        // Define the least square problem
        CurveFittingProblem cfp(timeToMaturity,    targetValue);
     
        // Set initial values
        lsqnonlin.setInitialValue(initialValue);
        // perform fitting
        Array solution = lsqnonlin.Perform(cfp);
       
        cout << endl
             << "Optimal values  : " << abcd
             << "Solution values : " << solution
             << "Solution Error  : " << (solution - abcd ) << endl;

        // save in given format
        BraceVolatilityFunction bvf2(solution[0],solution[1],solution[2],solution[3]);

        // Gnuplot format
        /*
        std::ofstream file("curve.dta");
        for (i=0; i<periodNumber; ++i) {
            t = startDate + i*period;
            file << setw(8) << t << setw(20) << bvf(t) << setw(20) << bvf2(t) << endl;
        }
        */
       
        std::ofstream file("curve.csv");
        const char separator[] = ", ";
        // CSV format
        for (i=0; i<periodNumber; ++i) {
            t = startDate + i*period;
            file << t << separator << bvf(t) << separator << bvf2(t) << endl;
        }
        file.close();

    }
    catch(Error & e)
    {
        cerr << e.what() << endl;;
    }
    t.stop();

    cout << "Ellapsed time : " << (double) t << " seconds." << endl;


    return 1;
}




Share your photos with Windows Live Photos – Free. Try it Now!
------------------------------------------------------------------------------
This SF.net email is sponsored by:
High Quality Requirements in a Collaborative Environment.
Download a free trial of Rational Requirements Composer Now!
http://p.sf.net/sfu/www-ibm-com
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users
Reply | Threaded
Open this post in threaded view
|

Re: polynomial fitting with LeastSquareProblem / CurveFitting.cpp

Bojan Nikolic

Hi Piers,

The problem is that you are mixing the example which was originally
called CurvedFitting.cpp with the current implementation of
least-square-fitting in QuantLib which is significantly different. For
example, LeastSquareProblem is not a template class and this is why
you get the first error that you do get. There are a few other
adjustments that need to be made:

* No need to define operator<<

* Need to supply a constraint for the LeastSquareProblem

* targetValueAndGradient not targetValueAndfirstDerivative

* size_t or QuantLib::Size not int

I've put the modified example that does compile and seems to work at
the following address:

http://www.bnikolic.co.uk/blog/ql-fitting-curves.html

Best,
Bojan

--
Bojan Nikolic          ||          http://www.bnikolic.co.uk

------------------------------------------------------------------------------
This SF.net email is sponsored by:
High Quality Requirements in a Collaborative Environment.
Download a free trial of Rational Requirements Composer Now!
http://p.sf.net/sfu/www-ibm-com
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users
Reply | Threaded
Open this post in threaded view
|

Re: polynomial fitting with LeastSquareProblem / CurveFitting.cpp

piers august
Thanks alot Bojan,
Seems fine,  output below.

rgds,
Piers


Optimal values  : [ 0.147014; 0.057302; 0.249964; 0.148556 ]

Optimal values  : [ 0.147014; 0.057302; 0.249964; 0.148556 ]Solution values : [ 0.147014; 0.057302; 0.249964; 0.148556 ]Solution Error  : [ -3.67345e-13; 2.74405e-13; 6.97664e-13; 1.66672e-13 ]



> To: [hidden email]
> CC: [hidden email]
> Subject: Re: [Quantlib-users] polynomial fitting with LeastSquareProblem / CurveFitting.cpp
> From: [hidden email]
> Date: Tue, 7 Apr 2009 09:09:41 +0100
>
>
> Hi Piers,
>
> The problem is that you are mixing the example which was originally
> called CurvedFitting.cpp with the current implementation of
> least-square-fitting in QuantLib which is significantly different. For
> example, LeastSquareProblem is not a template class and this is why
> you get the first error that you do get. There are a few other
> adjustments that need to be made:
>
> * No need to define operator<<
>
> * Need to supply a constraint for the LeastSquareProblem
>
> * targetValueAndGradient not targetValueAndfirstDerivative
>
> * size_t or QuantLib::Size not int
>
> I've put the modified example that does compile and seems to work at
> the following address:
>
> http://www.bnikolic.co.uk/blog/ql-fitting-curves.html
>
> Best,
> Bojan
>
> --
> Bojan Nikolic || http://www.bnikolic.co.uk


Share your photos with Windows Live Photos – Free. Try it Now!
------------------------------------------------------------------------------
This SF.net email is sponsored by:
High Quality Requirements in a Collaborative Environment.
Download a free trial of Rational Requirements Composer Now!
http://p.sf.net/sfu/www-ibm-com
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users