2017-01-24 2 views
0

Ich bin ein Doktorand an der Florida State University, der Finanzmathematik studiert. Ich bin immer noch ein wenig Neuling mit C++, aber ich versuche, die Longstaff-Schwartz-Methode für die Preisgestaltung von amerikanischen Optionen zu implementieren. Obwohl der Algorithmus im Journal ein wenig entmutigend ist, versuche ich den Code, der in Matlab geschrieben wurde, in C++ zu konvertieren. Im Wesentlichen verwende ich den Matlab-Code als Leitfaden.Unbekannter Fehler unter Verwendung der C++ - Eigenbibliothek

Ich wurde von einigen Stackexchange-Benutzern verwiesen, die Eigenbibliothek zu verwenden, die eine gute Matrixklasse enthält. Leider zeigt mir die Webseite here nicht, wie ich meine eigene Funktion aus der Klasse machen kann. Was ich steckte auf macht eine C++ Funktion für die Funktion in Matlab, das dies tut:

Say t = 0:1/2:1 dann in Matlab wird der Ausgang t = 0 0.500 1

So mit der Eigen Klasse I eine Funktion erstellt genannt Bereich zu erreichen letzteres oben. Die Funktion sieht wie folgt aus:

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; 
} 

Ich habe keine Fehler auf meiner IDE (Ecclipse), aber wenn ich meinen Code ausführen und testen diese Funktion ich diese Fehlermeldung:

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 

Ich bin nicht sicher, was falsch ist. Irgendwelche Vorschläge, um zu erreichen, was ich versuche, oder irgendwelche Vorschläge überhaupt werden sehr geschätzt.

Unter dem Vorschlag von Martijn Courteaux, änderte ich $ N $ in eine int jetzt aber ich erhalte jetzt einen neuen Fehler, die ich nicht verstehe:

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) 

Die Vollständigkeit halber werde ich meinen ganzen Code schreiben unten:

#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; 

} 

Hier ist die korrigierte Funktionscode, 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; 
} 
+0

Ich denke, was Sie wollen, ist nur 'Eigen :: VectorXd :: LinSpaced (N + 1, min, max)' http://eigen.tuxfamily.org/dox/classEigen_1_1DenseBase.html # aaef589c1dbd7fad93f97bd3fa1b1e768 – chtz

+0

Auch wenn Sie mit Matlab Programmierung vertraut sind, wird diese [AsciiQuickReference] (http://eigen.tuxfamily.org/dox/AsciiQuickReference.txt) wahrscheinlich hilfreich sein. – chtz

Antwort

4

Mist ake ist hier:

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

N eine doppelt so hoch ist. Die Argumente von MatrixXd::MatrixXd(int, int) sind int.

Vermutlich möchten Sie N eine int machen.


In Bezug auf Ihre edit:

Zweiter Fehler ist hier:

MatrixXd range(0, 1, 2); 

in der main() Funktion. Nicht sicher, was Sie hier versuchen, aber dieser Konstruktor ist nicht gültig. EDIT: Ah ich glaube, ich habe eine Idee. Sie versuchen, Ihre Funktion mit dem Namen range aufzurufen. Tun Sie dies wie folgt aus:

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

Ich sehe, der Grund, warum ich es zu einem Doppel gemacht habe, war, weil ich ein Doppel durch ein Doppel teilen werde. Ich dachte, dass es einen Fehler geben würde, wenn ich ein Doppel und dann ein Int teilte? –

+0

Nein, das ist in Ordnung. Der Int wird vor der Division auf ein Double hochgestuft. Alle Gleitkomma + * -/Integral-Operationen funktionieren auf diese Weise. –

+0

Wenn ich N in eine int-Variable ändere, bekomme ich diesen Fehler: c: \ mingw \ include \ C++ \ 6.2.0 \ eigen \ src/Core/Matrix.h: 350: 7: Fehler: statische Assertion ist fehlgeschlagen: THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE –

Verwandte Themen