cs_iamor
Messages postés2Date d'inscriptionjeudi 29 juin 2006StatutMembreDernière intervention11 août 2006
-
11 août 2006 à 10:44
cs_iamor
Messages postés2Date d'inscriptionjeudi 29 juin 2006StatutMembreDernière intervention11 août 2006
-
11 août 2006 à 11:31
Bonsoir, je souhaite améliorer un programme que j'ai codé pour qu'il soit plus clean, mais pour se faire j'aurai besoin d'avoir une petite aide sur la construction d'une fonction.
Le programme en question récupère à partir d'un fichier texte une matrice de covaraince, test si elle est définie positive, puis la rende définie positive dans le cas ou elle ne l'est pas.
Ensuite il la décompose suivant cholesky puis la multiplie par une vecteur de variables aléoatoires normales afin de simuler une loie normale.
Mon code est le suivant sans amélioration:
//fichier main principal
#include "essai.h"
#include
#include <sstream>
#include <fstream>
#include
#include <string>
using namespace std;
int main()
{
//initialise la graine du générateur de variable normale
init_genrand(time(NULL));
ifstream fichierEntree("D:\\Documents and Settings\\AMOR\\Desktop\\VaRaction\\covariance.txt", ios::in);
int dim;
fichierEntree >> dim;
ArrayLengthSpecifier dimension(dim);
SymmetricMatrix covariance(dimension);
/* lecture de la matrice */
for( int i=1 ; i<=dim ; ++i )
{
for( int j=1 ; j<=i ; ++j )
{
double val;
fichierEntree >> val;
covariance(i,j) = val;
}
}
fichierEntree.close();
//décompose la matrice de covariance suivant cholesky
Matrix C;
C = chol(covariance);
int nbre_simul;
ColumnVector E;
ColumnVector epsilon_correl;
//saisie du nombre de simulation
cout << "Veuillez saisir le nombre de simulations souhaitees : ";
cin >> nbre_simul;
// définie la matrice de sortie
Matrix simul_epsilon (nbre_simul,dim);
for(int i=1 ; i<=nbre_simul ; ++i )
{
E = simind(dim);
epsilon_correl = C * E;
for(int j=1 ; j<=dim ; ++j )
{
simul_epsilon(i,j) = epsilon_correl(j);
}
}
std::cout << simul_epsilon(4,4) << std::endl;
/* affichage pour tester la matrice de cholesky */
for( int i=1 ; i<=dim ; ++i )
{
for( int j=1 ; j<=dim ; ++j )
{
if (j==1)
std::cout << C(i,j);
else
{
std::cout << " " << C(i,j);
}
}
std::cout << std::endl;
}
/* affichage pour tester la matrice simul_epsilon */
for( int i=1 ; i<=nbre_simul ; ++i )
{
for( int j=1 ; j<=dim ; ++j )
{
if (j==1)
std::cout << simul_epsilon(i,j);
else
{
std::cout << " " << simul_epsilon(i,j);
}
}
std::cout << std::endl;
}
//écriture de la matrice de Cholesky transformée dans un fichier .txt
ofstream fichierSortie("C:\\Matrice de cholesky transformée.txt",ios::out);
if (!fichierSortie)
{
cerr << "Création du fichier impossible" << endl;
exit(1);
}
for (int i=1;i<=dim;i++)
{
for (int j=1;j<=i;j++)
{
if (j==1)
fichierSortie << C(i,j);
else
{
fichierSortie << " " << C(i,j);
}
}
fichierSortie << endl;
}
return 0;
}
Pour l'améliorer je construis en plus des fonction simind et chol une fonction simcor qui va se charger de faire la décomposition de cholesky puis multiplier celle-ci par le vecteur de variable aléatoire normale et cela pour n simulations.
Voilà le fichier contenant ces fonctions:
// Il s'agit du fichier DLL principal.
#include "stdafx.h"
#include "CorrelSimul.h"
ReturnMatrix chol(const SymmetricMatrix& correlation)
{
//renvoie la dimension de la matrice de corrélation
ArrayLengthSpecifier dimension(correlation.Nrows());
int dimension1 = correlation.Nrows();
//initialise le test de défini positivité à faux
bool test=false;
//diagonalise la matrice de corrélation
DiagonalMatrix D(dimension);
Matrix V(dimension1,dimension1);
LowerTriangularMatrix L(dimension);
Matrix resultat;
//renvoie les valeurs propres
EigenValues(correlation,D,V);
//
if (D(1)<=0) test=true;
if (test=false)
{
L = Cholesky(correlation);
resultat=L;
}
else
{
for (int i = 1; i <= dimension1; i++)
{
D(i)=sqrt(max(D(i),0)); /* on transforme D en D+ puis en (D+)^1/2
pour prendre la racine carrée */
}
resultat = V*D*V.t();
}
D.Release();
V.Release();
L.Release();
return resultat;
}
ReturnMatrix simind(const int& nbre_noms)
{
//créer une matrice colonne epsilon
ColumnVector epsilon;
//redimensionne la matrice espsilon avec la dimension correpondante
//au nombre de titre
epsilon.ReSize(nbre_noms);
//générateur de loie normale
for (int i=1; i<=nbre_noms; ++i)
{
epsilon(i)= normal_random();
}
epsilon.Release();
return epsilon;
}
ReturnMatrix simcor(const int& nbre_simul, const int& dim, const SymmetricMatrix& covariance)
{
//décompose la matrice de covariance suivant cholesky
Matrix C;
C = chol(covariance);
//définie le vecteur de variables aléatoires normales
ColumnVector E;
//définie le vecteur issue de la multiplication de E et C
ColumnVector epsilon_correl;
// définie la matrice de sortie
Matrix simul_epsilon (nbre_simul,dim);
for(int i=1 ; i<=nbre_simul ; ++i )
{
E = simind(dim);
epsilon_correl = C * E;
for(int j=1 ; j<=dim ; ++j )
{
simul_epsilon(i,j) = epsilon_correl(j);
}
}
C.Release();
E.Release();
epsilon_correl.Release();
simul_epsilon.Release();
return simul_epsilon;
}
Le fichier principal devient
//fichier main principal
#include "essai.h"
#include
#include <sstream>
#include <fstream>
#include
#include <string>
using namespace std;
int main()
{
//initialise la graine du générateur de variable normale
init_genrand(time(NULL));
ifstream fichierEntree("D:\\Documents and Settings\\AMOR\\Desktop\\VaRaction\\covariance.txt", ios::in);
int dim;
fichierEntree >> dim;
ArrayLengthSpecifier dimension(dim);
SymmetricMatrix covariance(dimension);
/* lecture de la matrice */
for( int i=1 ; i<=dim ; ++i )
{
for( int j=1 ; j<=i ; ++j )
{
double val;
fichierEntree >> val;
covariance(i,j) = val;
}
}
fichierEntree.close();
//saisie du nombre de simulation
int x;
cout << "Veuillez saisir le nombre de simulations souhaitees : ";
cin >> x;
//définie la matrice de sortie
//Matrix sortie(x,dim);
//sortie = simcor(x, dim, covariance);
//std::cout << sortie(4,4) << std::endl;
//écriture de la matrice de Cholesky transformée dans un fichier .txt
ofstream fichierSortie("C:\\Matrice de cholesky transformée.txt",ios::out);
if (!fichierSortie)
{
cerr << "Création du fichier impossible" << endl;
exit(1);
}
Matrix COLout;
COLout = chol(covariance);
for (int i=1;i<=dim;i++)
{
for (int j=1;j<=i;j++)
{
if (j==1)
fichierSortie << COLout(i,j);
else
{
fichierSortie << " " << COLout(i,j);
}
}
fichierSortie << endl;
}
return 0;
}
Le problème c'est que j'ai un message d'erreur qui est le suivant et dont je ne comprend pas l'origine !
essai.cpp(45) : error C2660: 'simcor'*: la fonction ne prend pas 3 arguments
L'origine du problème est mis en commentaires dans le fichier principal