简体   繁体   中英

Unknown error using the c++ eigen library

I am a graduate student at Florida State University studying financial mathematics. I am still a bit of a novice with C++ but I am trying to implement the Longstaff-Schwartz method for pricing of American options. Although, the algorithm in the journal is a bit daunting thus I am trying to convert the code that was written in Matlab and change it into C++. Essentially I am using the Matlab code as a guide.

I was referred by some stackexchange users to use the Eigen library which contains a good matrix class. Unfortunately the website here does not show me how to make my own function from the class. What I am stuck on is making a C++ function for the function in Matlab that does this:

Say t = 0:1/2:1 then in Matlab the output will be t = 0 0.500 1

So using the Eigen class I created a function called range to achieve the latter above. The function looks like this:

MatrixXd range(double min, double max, double N){
     MatrixXd m(N,1);
     double delta = (max-min)/N;
     for(int i = 0; i < N; i++){
         for(int j = 0; j < N; j++){
             m(i,j) = min + i*delta;
         }
     }
    return m;
}

I do not have any errors on my IDE (Ecclipse) but when I run my code and test this function I get this error message:

c:\mingw\include\c++\6.2.0\eigen\src/Core/PlainObjectBase.h:736:7: 

error: static assertion failed:



FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED

I am not sure what is wrong. Any suggestions on achieving what I am trying to do or any suggestions at all are greatly appreciated.

Taking the suggestion by Martijn Courteaux, I changed $N$ into an int now but I now receive a new error that I do not understand:

c:\mingw\include\c++\6.2.0\eigen\src/Core/Matrix.h:350:7: error: static

assertion failed: THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE

       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 3)

For sake of completeness I will post my whole code below:

#include <iostream>
#include <cmath>
#include <limits>
#include <algorithm>
#include <Eigen/Dense>
#include <Eigen/Geometry>

using namespace Eigen;
using namespace std;


double LaguerreExplicit(int R, double x); // Generates the (weighted) laguerre value
double payoff_Call(double S, double K); // Pay off of a call option
double generateGaussianNoise(double mu, double sigma); // Generates Normally distributed random numbers
double LSM(int T, double r, double sigma, double K, double S0, int N, int M, int R);
// T        Expiration time
// r        Riskless interest rate
// sigma    Volatility
// K        Strike price
// S0       Initial asset price
// N        Number of time steps
// M        Number of paths
// R        Number of basis functions

MatrixXd range(double min, double max, int N);

int main(){

    MatrixXd range(0, 1, 2);



}


double payoff_Call(double S, double K){
    double payoff;
    if((S - K) > 0)
    {
        payoff = S - K;
    }else
    {
        payoff = 0.0;
    }
    return payoff;
}

double LaguerreExplicit(int R, double x){
    double value;
    if(R==0)
    {
        value = 1;
    }
    else if(R==1)
    {
        value = 0.5*(pow(x,2) - 4.0*x + 2);
    }
    else if(R==3)
    {
        value = (1.0/6.0)*(-1*pow(x,3) + 9*pow(x,2) - 18*x + 6);
    }
    else if(R==4)
    {
        value = (1.0/24.0)*(pow(x,4) - 16*pow(x,3) + 72*pow(x,2) - 96*x + 24);
    }
    else if(R==5)
    {
        value = (1.0/120.0)*(-1*pow(x,5) + 25*pow(x,4) - 200*pow(x,3) + 600*pow(x,2) - 600*x + 120);
    }
    else if (R==6)
    {
        value = (1.0/720.0)*(pow(x,6) - 36*pow(x,5) + 450*pow(x,4) - 2400*pow(x,3) + 5400*pow(x,2) - 4320*x + 720);
    }
    else{
        cout << "Error!, R is out of range" << endl;
        value  = 0;
    }
    value = exp(-0.5*x)*value; // Weighted used in Longstaff-Scwartz
    return value;
}

double generateGaussianNoise(double mu, double sigma)
{
    const double epsilon = std::numeric_limits<double>::min();
    const double two_pi = 2.0*M_PI;

    static double z0, z1;
    static bool generate;
    generate = !generate;

    if (!generate)
       return z1 * sigma + mu;

    double u1, u2;
    do
     {
       u1 = rand() * (1.0 / RAND_MAX);
       u2 = rand() * (1.0 / RAND_MAX);
     }
    while ( u1 <= epsilon );

    z0 = sqrt(-2.0 * log(u1)) * cos(two_pi * u2);
    z1 = sqrt(-2.0 * log(u1)) * sin(two_pi * u2);
    return z0 * sigma + mu;
}

MatrixXd range(double min, double max, int N){
     MatrixXd m(N,1);
     double delta = (max-min)/N;
     for(int i = 0; i < N; i++){
         for(int j = 0; j < N; j++){
             m(i,j) = min + i*delta;
         }
     }
    return m;
}

double LSM(int T, double r, double sigma, double K, double S0, int N, int M, int R){
    double dt = T/N;
    MatrixXd m(T,1);

    return 0;

}

Here is the corrected function code that I fixed:

VectorXd range(double min, double max, int N){
    VectorXd m(N + 1);
     double delta = (max-min)/N;
     for(int i = 0; i <= N; i++){
             m(i) = min + i*delta;
     }
    return m;
}

Mistake is here:

MatrixXd range(double min, double max, double N){
     MatrixXd m(N,1);

N is a double. The arguments of MatrixXd::MatrixXd(int, int) are int .

You presumably want to make N an int .


In regard to your edit:

Second mistake is here:

MatrixXd range(0, 1, 2);

in the main() function. Not sure what you are trying to do here, but that constructor is not valid. EDIT: Ah I believe I have an idea. You are trying to call your function named range . Do this like this:

MatrixXd result = range(0.0, 1.0, 2);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM