Programme pour lire une matrice triangulaire inférieure à partir

Programme pour lire une matrice triangulaire inférieure à partir - C++ - Programmation

Marsh Posté le 07-08-2006 à 18:25:24    

Bonjour,
 
Je voudrais lire une matrice inférieure à partir d'un fichier .txt.  
La forme de la matrice en question est la suivante :

Code :
  1. 4
  2. 1.23E-02
  3. -1.24E-02 1.26E-02
  4. 1.27E-02 -1.23E-04 1.23E-03
  5. 1.27E-02 -1.23E-04 1.23E-03 1.23E-03


Le premier élément de cette matrice qui est 4 représente la dimension, le reste des éléments constituent la matrice.
N'étant pas expert en c++ je suis passé par deux codes différents mais aucun ne me donne un réusltat satisfaisant.
 
code 1 :

Code :
  1. #include "essai.h"
  2. #include <iostream>
  3. #include <fstream>
  4. #include <iomanip>
  5. using namespace std;
  6. using namespace std;
  7. int main()
  8. {
  9.   // Ouverture du fichier
  10.   ifstream fichierEntree("c:\\test1.txt", ios::in);
  11.   // Test d'ouverture du fichier
  12.     if (!fichierEntree) {
  13.         cerr << "Problème d'ouverture de fichier" << endl;
  14.         exit(1);
  15.     }
  16.     char* ligne;
  17.     int i = 0;
  18.     char * err = NULL;
  19. //double z;  
  20.     ligne = new char[10];
  21.     fichierEntree.getline(ligne, 4);
  22.     int conv1 = strtoul(ligne,0,10);
  23. ArrayLengthSpecifier dimension(conv1);
  24. cout << conv1 << endl;
  25. SymmetricMatrix covariance(dimension);
  26.     int longueur;
  27.     do
  28.   {
  29.   i = i + 1;
  30.   longueur = 9 * i + 1;
  31.   ligne = new char [longueur];//format "0.00E+00"
  32.   //donc 8 caractères; 9i=8i+ (i-1) espaces + élt nul terminal
  33.   fichierEntree.getline(ligne,longueur);
  34.   cout << ligne << endl;
  35.   
  36.   for (int j=1;j<=i;j++)
  37.  {
  38.   char temp[9];
  39.   for (int k=0;k<=7;k++)
  40.   {
  41.    temp[8]=0;
  42.    if (j==1)
  43.    temp[k] = ligne[k];
  44.    else
  45.    temp[k] = ligne[9* (j - 1) + k ];//attention dimension de 0 à n-1
  46.   }
  47.   const char* caractere=temp;
  48.   cout << caractere << endl;
  49.   covariance(i,j) = 2 * strtod(caractere, &err);
  50.   cout << covariance(i,j) << endl;
  51.   cout << covariance(j,i) << endl;
  52.  }
  53.  delete[] ligne;
  54.   }
  55.   while (!fichierEntree.eof());
  56.     fichierEntree.close();
  57. }


 
code 2 :  
 
[code]
#include "essai.h"
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <string>
 
 
 
using namespace std;
 
 
 
int main()
{
 ifstream FichierMatrice("c:\\test1.txt",ios::in);
 if (!FichierMatrice)
 {
  cerr << "Ouverture du fichier impossible" << endl;
  exit(1);
 }
 
 int val1;
 int j = 0;  
 double* valf;
 double val;
 
 FichierMatrice >> val1;
 ArrayLengthSpecifier dimension(val1);
 SymmetricMatrix covariance(dimension);
 cout << val1 << endl;  
 
 int dime = (val1*(val1+1))/2;
 valf = new double [dime];
   
 do  
 {
    i = i + 1;
 FichierMatrice >> valf[j];
 cout << valf[j] <<endl;
 //cout << valf[1]<<endl;
 //cout << covariance (1,2) <<endl;
 //cout << covariance (2,1) <<endl;
 //cout << covariance (3,2) <<endl;
 }
 while (!FichierMatrice.eof());
 
 
 return 0;
}
[code]
La classe SymmetricMatrix et la matrice covariance sont correctement définis à l'aide de la bibliothèque Newmat.
Je suis vraiment bloqué parceque je n'arrive pas à traiter le fichier de donnée. Pourriez-vous m'aider sur ce point en me conseillant laquelle des deux voies d'abord suivre puis comment écire ce code???
 
Merci d'avance

Reply

Marsh Posté le 07-08-2006 à 18:25:24   

Reply

Marsh Posté le 07-08-2006 à 19:26:27    

tu aurais pu continuer sur le même topic plutôt que d'en ouvrir un autre :o
 
que donne un truc dans ce genre là :

Code :
  1. ifstream fichierEntree("c:\\test1.txt", ios::in);
  2. int dim;
  3. fichierEntree >> dim;
  4. ArrayLengthSpecifier dimension(dim);
  5. SymmetricMatrix covariance(dimension);
  6. /* lecture de la matrice */
  7. for( int i=1 ; i<=dim ; ++i )
  8. {
  9.   for( int j=1 ; j<=i ; ++j )
  10.   {
  11.     double val;
  12.     fichierEntree >> val;
  13.     covariance(i,j) = val;
  14.   }
  15. }
  16. fichierEntree.close();
  17. /* affichage pour tester */
  18. for( int i=1 ; i<=dim ; ++i )
  19. {
  20.   for( int j=1 ; j<=dim ; ++j )
  21.   {
  22.     std::cout << setw(10) << covariance(i,j);
  23.   }
  24.   std::cout << std::endl;
  25. }


---------------
TriScale innov
Reply

Marsh Posté le 09-08-2006 à 14:56:19    

Bonjour,
Merci pour ton message, je n'ai malheureusement pas pu le lire auparavant,
Le code que tu m'a laissé marche bieb je l'ai testé.
Par contre j'aurais une petite question concercant les lignes suivantes pour les tests car j'aimerai savoir comment ça marche pour pouvoir l'exploiter plus tard :

Code :
  1. for( int i=1 ; i<=dim ; ++i )
  2. for( int j=1 ; j<=dim ; ++j )
  3. {   
  4. std::cout << setw(10) << covariance(i,j); 
  5. std::cout << std::endl;
  6. }


 
a quoi sert le setw(10)???
je voudrais utiliser ce qui sort en test dans un fichier c'est pour ça que je te pose la question, j'ai l'impression que c'est assez proche !

Reply

Marsh Posté le 09-08-2006 à 14:57:56    

Reply

Marsh Posté le 09-08-2006 à 15:19:35    

oui ok c'est l'espace entre les sorties je m'en suis aperçu quad j'ai testé je suis débutant en C++, alors excusez mon manque d'expérience.
Par contre j'ai encore deux petites questions. Je pense que la première est un peu évidente pour vous !
 
Pensez-vous que cette syntaxe est correcte pour l'écriture du résultat extrait dans un fichier (bien sûr ici il n'a subi aucun traitement, le traitement en question est le sujet de ma deuxième question, c'est juste pour voir si j'arrive à écrie sans problème).
 
Cette partie de code est à mettre juste après :

Code :
  1. fichierEntree.close();


 

Code :
  1. ofstream fichierSortie("C:\\sortie.txt",ios::in);
  2. if (!fichierSortie)
  3. {
  4.  cerr << "Création du fichier impossible" << endl;
  5.  exit(1);
  6.     }
  7. for (int i=1;i<=dim;i++)
  8. {
  9. for (int j=1;j<=i;j++)
  10. {
  11. double vals;
  12. vals << fichierSortie ;   
  13. }
  14. }
  15. fichierSortie.close();


 
Normalement ca devarit marché mais il y a un problème sur l'opérande << que je ne comprend pas!
 
Ma deuxième question porte plutôt sur le une fonction issu d'une bibliothèque mathématique la fonction est la suivante :

Code :
  1. ReturnMatrix simind(const int& nbre_noms)
  2. {
  3. //créer une matrice colonne epsilon
  4. ColumnVector epsilon;
  5. //redimensionne la matrice espsilon avec la dimension correpondante  
  6. //au nombre de titre
  7. epsilon.ReSize(nbre_noms);
  8. //générateur de loie normale
  9. for (int i=1;  i<=nbre_noms; ++i)
  10.  epsilon(i)=(double)normal_random();
  11. }
  12. epsilon.Release();
  13. return epsilon;
  14. }


 
Elle retourne un vecteur colonnes dont les composantes sont des variables normales générés aléatoirment. Pourtant quand j'applique cette fonction à mon code je trouve qu'elle génère toujours les mêmes variables, ce que je ne comprend pas :
voici mon code intégrale :
 

Code :
  1. //fichier main principal
  2. #include "essai.h"
  3. #include <iostream>
  4. #include <sstream>
  5. #include <fstream>
  6. #include <iomanip>
  7. #include <string>
  8. using namespace std;
  9. int main()
  10. {
  11. ifstream fichierEntree("c:\\test1.txt", ios::in);
  12. int dim;
  13. fichierEntree >> dim;
  14. ArrayLengthSpecifier dimension(dim);
  15. SymmetricMatrix covariance(dimension);
  16. /* lecture de la matrice */
  17. for( int i=1 ; i<=dim ; ++i )
  18. for( int j=1 ; j<=i ; ++j ) 
  19. {   
  20. double val;   
  21. fichierEntree >> val;   
  22. covariance(i,j) = val; 
  23. }
  24. }
  25. fichierEntree.close();
  26. //décompose la matrice de covariance suivant cholesky
  27. Matrix C;
  28. C = chol(covariance);
  29. //génère un vecteur colonne de variable normale
  30. ColumnVector E;
  31. E = simind (dim);
  32. ofstream fichierSortie("C:\\sortie.txt",ios::in);
  33. if (!fichierSortie)
  34. {
  35.  cerr << "Création du fichier impossible" << endl;
  36.  exit(1);
  37.     }
  38. for (int i=1;i<=dim;i++)
  39. {
  40. for (int j=1;j<=i;j++)
  41. {
  42. double vals;
  43. vals << fichierSortie ;   
  44. }
  45. }
  46. fichierSortie.close();


 
Merci d'avance pour votre aide

Reply

Marsh Posté le 09-08-2006 à 15:37:09    

Pour la question 1 :

iamora a écrit :

Code :
  1. ofstream fichierSortie("C:\\sortie.txt",ios::in); // si tu veux écrire dans le fichier, c'est ios::out qu'il faut mettre
  2. if (!fichierSortie)
  3. {
  4. cerr << "Création du fichier impossible" << endl;
  5. exit(1);
  6. }
  7. for (int i=1;i<=dim;i++)
  8. {
  9.   for (int j=1;j<=i;j++)
  10.   {
  11.     double vals;               // si tu n'initialise pas vals, tu vas écrire n'importe quoi dans ton fichier
  12.     vals << fichierSortie ;    // c'est dans l'autre sens qu'on écrit : monFlux << maValeurAEcrireDansLeFlux
  13.                                // comme dans : std::cout << "hello world\n"
  14.   }
  15. }
  16. fichierSortie.close();



 
Pour la question 2:
que fait la fonction normal_random() ? D'où sort elle (une bibliothèque, ou bien c'est toi qui l'as programmée) ? Quand tu dis qu'elle génère toujours la même chose, a veut dire que tu obtiens toujours le même vecteur, ou bien que toutes les composantes de ton vecteur sont égales ? Es-tu sûr de l'utiliser correctement ? habituellement, les fonctions qui génèrent des nombres pseudo-aléatoires doivent être initialisées avec une graine (sinon elles renvoient toujours la même suite de nombres)


Message édité par franceso le 09-08-2006 à 15:43:10

---------------
TriScale innov
Reply

Marsh Posté le 09-08-2006 à 15:40:43    

iamora a écrit :

oui ok c'est l'espace entre les sorties je m'en suis aperçu quad j'ai testé je suis débutant en C++, alors excusez mon manque d'expérience.


 
Tout les débutants sont excusés à partir du moment où qu'il mettent les mains dans le cambouis, la documentation et google :jap:


---------------
Töp of the plöp
Reply

Marsh Posté le 09-08-2006 à 16:08:18    

Tout d'abord merci pour la présicion de tes réponses.
 
Pour la question1 : Il me manque encore la notion d'initialiser une variable, que cela veut-il dire ?, et pourquoi ne l'a t-on pas fait lors de la lecture du fichier
 
 
Pour la question 2:
 
que fait la fonction normal_random() ? D'où sort elle (une bibliothèque, ou bien c'est toi qui l'as programmée) ?  
 
La fonction normal_random() génére aléatoirement une valeur d'une variable aléatoire. Elle est définie ci-dessus et provient de la bibliothèque newmat
 

Code :
  1. double normal_random()
  2. {
  3. return cndev(genrand_real1());
  4. }


 
genrand_real1 est défini quant à lui ci-dessus
 

Code :
  1. double genrand_real1(void)
  2. {
  3.     return genrand_int32()*(1.0/4294967295.0);
  4.     /* divided by 2^32-1 */
  5. }


 
genrand_int32 est défini quant à lui ci-dessus:

Code :
  1. unsigned long genrand_int32(void)
  2. {
  3.     unsigned long y;
  4.     static unsigned long mag01[2]={0x0UL, MATRIX_A};
  5.     /* mag01[x] = x * MATRIX_A  for x=0,1 */
  6.     if (mti >= N) { /* generate N words at one time */
  7.         int kk;
  8.         if (mti == N+1)   /* if init_genrand() has not been called, */
  9.             init_genrand(5489UL); /* a default initial seed is used */
  10.         for (kk=0;kk<N-M;kk++) {
  11.             y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
  12.             mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
  13.         }
  14.         for (;kk<N-1;kk++) {
  15.             y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
  16.             mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
  17.         }
  18.         y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
  19.         mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
  20.         mti = 0;
  21.     }
  22.     y = mt[mti++];
  23.     /* Tempering */
  24.     y ^= (y >> 11);
  25.     y ^= (y << 7) & 0x9d2c5680UL;
  26.     y ^= (y << 15) & 0xefc60000UL;
  27.     y ^= (y >> 18);
  28.     return y;
  29. }


Je crois que ces fonctions partent d'un générateur de nombre aléatoires entre 0 et 1 puis grâce à la fonction de répartition réciproque de la loi normale il permette de générer une variable aléatoire.
 
Quand tu dis qu'elle génère toujours la même chose, a veut dire que tu obtiens toujours le même vecteur, ou bien que toutes les composantes de ton vecteur sont égales ? Es-tu sûr de l'utiliser correctement ? habituellement, les fonctions qui génèrent des nombres pseudo-aléatoires doivent être initialisées avec une graine (sinon elles renvoient toujours la même suite de nombres)[/quotemsg]
 
Je veux dire par là que la composante 1 de mon vecteur est toujours la même quand je compile un nouvelle fois ce qui ne devrait pas être le cas normalement. Tout à fait d'accord au sujet de la graine j'ai pensé pareil il faut qu'elle soit intégrer dans le fonction.
Je sais qu'en VB c'est Randomize la graine mais en C++ je n'ai aucune idée???
J'espère que mon problème est un peu plus clair???

Message cité 1 fois
Message édité par iamora le 09-08-2006 à 16:14:34
Reply

Marsh Posté le 09-08-2006 à 16:32:51    

iamora a écrit :

Pour la question1 : Il me manque encore la notion d'initialiser une variable, que cela veut-il dire ?, et pourquoi ne l'a t-on pas fait lors de la lecture du fichier

lorsque tu écris

Code :
  1. double vals

tu es en train de dire à ton compilateur : "je vais utiliser à partir de maintenant une variable ne nom 'vals', de type double". Rien de plus, rien de moins. En particulier, la valeur de la variable vals est indéfinie. Lorsque à la ligne suivante, tu écris :

Code :
  1. fichierSortie << vals;

tu es en train d'écrire dans le fichier la valeur de vals, à savoir n'importe quoi.
 
Il faut que tu écrives dans la variable avant de l'utiliser. Par exemple:

Code :
  1. for( int i ...)
  2. {
  3.   for( int j ... )
  4.   {
  5.     double val;
  6.     val = covariance(i,j);
  7.     fichierSortie << val;
  8.   }
  9. }


 
Ou plus simplement, puisque ici tu n'as pas besoin d'une variable intermédiaire vals :

Code :
  1. for( int i ...)
  2. {
  3.   for( int j ... )
  4.   {
  5.     fichierSortie << covariance(i,j);
  6.   }
  7. }


 
 
 

iamora a écrit :

Pour la question 2:
Je veux dire par là que la composante 1 de mon vecteur est toujours la même quand je compile un nouvelle fois ce qui ne devrait pas être le cas normalement. Tout à fait d'accord au sujet de la graine j'ai pensé pareil il faut qu'elle soit intégrer dans le fonction.
Je sais qu'en VB c'est Randomize la graine mais en C++ je n'ai aucune idée???


D'après les commentaires de la fonction genrand_int32, l'initialisation de la graine se fait avec la fonction init_genrand.
Il n'est pas interdit de regarder la documentation de ta bibliothèque non plus. C'est là que tu trouveras toutes les informations utiles pour utiliser les fonctions qu'elle définit :o


---------------
TriScale innov
Reply

Marsh Posté le 09-08-2006 à 17:00:46    

Merci pour tes réponses efficaces!

Reply

Marsh Posté le 09-08-2006 à 17:00:46   

Reply

Marsh Posté le 09-08-2006 à 17:45:16    

En fait ce que je t'ai envoyé sur la fonction normal_random n'est pas tiré sur une bibliothèque Newmat, je viens de m'en apercevoir, je ne connais pas tellement sa proivenance. En tout cas il a l'aire de foinctionner correctement, je pense que c'est l'un de ces générateurs de nombres utilisés pour les simulations de Monté Carlo!
En tout cas voilà le code

Code :
  1. #include "stdafx.h"
  2. #ifndef PI
  3. #define PI 3.141592653589793238462643
  4. #endif
  5. double n(const double& z)
  6. {
  7.     return (1.0/sqrt(2.0*PI))*exp(-0.5*z*z);
  8. }
  9. double N(const double& z) {
  10.     if (z >  6.0)
  11.  return 1.0; // this guards against overflow  
  12.     if (z < -6.0)
  13.  return 0.0;
  14.     double b1 =  0.31938153;
  15.     double b2 = -0.356563782;
  16.     double b3 =  1.781477937;
  17.     double b4 = -1.821255978;
  18.     double b5 =  1.330274429;
  19.     double p  =  0.2316419;
  20.     double c2 =  0.3989423;
  21.     double a=fabs(z);
  22.     double t = 1.0/(1.0+a*p);
  23.     double b = c2*exp((-z)*(z/2.0));
  24.     double n = ((((b5*t+b4)*t+b3)*t+b2)*t+b1)*t;
  25.     n = 1.0-b*n;
  26.     if ( z < 0.0 ) n = 1.0 - n;
  27.     return n;
  28. }
  29. double random_0_1(void)
  30. {
  31. return double(rand())/double(RAND_MAX);
  32. }
  33. double box_muller(void)
  34. {
  35. double U1, U2, V1, V2;
  36. double S=2;
  37. while (S>=1)
  38. {
  39.  U1 = random_0_1();
  40.  U2 = random_0_1();
  41.  V1 = 2.0*U1-1.0;
  42.  V2 = 2.0*U2-1.0;
  43.  S = (V1*V1)+(V2*V2);
  44. }
  45. double X1=V1*sqrt((-2.0*log(S))/S);
  46. return X1;
  47. }
  48. double normal_random()
  49. {
  50. return cndev(genrand_real1());
  51. }
  52. double lognormal_random(const double& S,const double& r,const double& sigma,
  53.      const double& time)
  54. {
  55. double R = (r-0.5 * (sigma*sigma) )*time;
  56. double SD = sigma * sqrt(time);
  57. return S * exp(R + SD * normal_random());
  58. }
  59. #define N 624
  60. #define M 397
  61. #define MATRIX_A 0x9908b0dfUL 
  62. #define UPPER_MASK 0x80000000UL
  63. #define LOWER_MASK 0x7fffffffUL
  64. static unsigned long mt[N];
  65. static int mti=N+1;
  66. void init_genrand(unsigned long s)
  67. {
  68.     mt[0]= s & 0xffffffffUL;
  69.     for (mti=1; mti<N; mti++) {
  70.         mt[mti] =
  71.   (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
  72.         mt[mti] &= 0xffffffffUL;
  73. }
  74. }
  75. void init_by_array(unsigned long init_key[], int key_length)
  76. {
  77.     int i, j, k;
  78.     init_genrand(19650218UL);
  79.     i=1; j=0;
  80.     k = (N>key_length ? N : key_length);
  81.     for (; k; k--) {
  82.         mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
  83.   + init_key[j] + j; /* non linear */
  84.         mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
  85.         i++; j++;
  86.         if (i>=N) { mt[0] = mt[N-1]; i=1; }
  87.         if (j>=key_length) j=0;
  88.     }
  89.     for (k=N-1; k; k--) {
  90.         mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
  91.   - i; /* non linear */
  92.         mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
  93.         i++;
  94.         if (i>=N) { mt[0] = mt[N-1]; i=1; }
  95.     }
  96.     mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
  97. }
  98. /* generates a random number on [0,0xffffffff]-interval */
  99. unsigned long genrand_int32(void)
  100. {
  101.     unsigned long y;
  102.     static unsigned long mag01[2]={0x0UL, MATRIX_A};
  103.     /* mag01[x] = x * MATRIX_A  for x=0,1 */
  104.     if (mti >= N) { /* generate N words at one time */
  105.         int kk;
  106.         if (mti == N+1)   /* if init_genrand() has not been called, */
  107.             init_genrand(5489UL); /* a default initial seed is used */
  108.         for (kk=0;kk<N-M;kk++) {
  109.             y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
  110.             mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
  111.         }
  112.         for (;kk<N-1;kk++) {
  113.             y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
  114.             mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
  115.         }
  116.         y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
  117.         mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
  118.         mti = 0;
  119.     }
  120.     y = mt[mti++];
  121.     /* Tempering */
  122.     y ^= (y >> 11);
  123.     y ^= (y << 7) & 0x9d2c5680UL;
  124.     y ^= (y << 15) & 0xefc60000UL;
  125.     y ^= (y >> 18);
  126.     return y;
  127. }
  128. /* generates a random number on [0,1]-real-interval */
  129. double genrand_real1(void)
  130. {
  131.     return genrand_int32()*(1.0/4294967295.0);
  132.     /* divided by 2^32-1 */
  133. }
  134. double cndev(double u)
  135. {
  136. static double a[4]={2.50662823884,-18.61500062529,41.39119773534,-25.44106049637};
  137. static double b[4]={-8.47351093090,23.08336743743,-21.06224101826,3.13082909833};
  138. static double c[9]={0.3374754822726147,0.9761690190917186,0.1607979714918209,0.0276438810333863,
  139.  0.0038405729373609,0.0003951896511919,0.0000321767881768,0.0000002888167364,0.0000003960315187};
  140. double x,r;
  141. x=u-0.5;
  142. if (fabs(x)<0.42)
  143. {
  144.  r=x*x;
  145.  r=x*(((a[3]*r+a[2])*r+a[1])*r+a[0])/((((b[3]*r+b[2])*r+b[1])*r+b[0])*r+1.0);
  146.  return(r);
  147. }
  148. r=u;
  149. if(x>0.0)
  150.  r=1.0-u;
  151. r=log(-log(r));
  152. r=c[0]+r*(c[1]+r*(c[2]+r*(c[3]+r*(c[4]+r*(c[5]+r*(c[6]+r*(c[7]+r*c[8])))))));
  153. if(x<0.0)
  154.  r=-r;
  155. return(r);
  156. }


 
Normalement à chaque fois que je compile je dois tomber sur une nouvelle valeur, mais là c'a à l'aire de garder la même valeur. J'ai remarqué par contre que si je mettai pour autant un :
init_genrand(n) avec n un nombre que je chose à chaque fois avant que je compile, cela change le résultat!
 

Code :
  1. ReturnMatrix simind(const int& nbre_noms)
  2. {
  3. //créer une matrice colonne epsilon
  4. ColumnVector epsilon;
  5. //redimensionne la matrice espsilon avec la dimension correpondante  
  6. //au nombre de titre
  7. epsilon.ReSize(nbre_noms);
  8. //générateur de loie normale
  9. for (int i=1;  i<=nbre_noms; ++i)
  10.  init_genrand(n)
  11.               epsilon(i)= normal_random();
  12. }


 
Décidement, c'est bien compliqué le C++

Reply

Marsh Posté le 09-08-2006 à 18:16:56    

Les méthodes aléatoires c'est pas si compliqué : ce sont en fait des suite récurentes du type
 
Un+1 = (Un^6) % un grand chiffre premier;
 
enfin mon exemple est peut être (sûrement  :D ) bidon Mais l'idée c'est que c'est une suite. Donc tu doit d'initialiser a partir d'une certaine valeur et ensuite tu obtient des nombres pseudo aléatoire. C'est pour cela que tu as toujours les même nombres : tu part du même premier terme et les autres sont calculé par récurrence a partir du premier...
 
L'idée si tu veut avoir des résultats différents a chaque exécution serait de l'initialiser a partir d'un chiffre obtenu a partir de l'horloge de l'ordi. Comme ça a chaque fois que tu exécute ton prog tu a un point de départ différent pour ta suite et donc des résultats différents.

Reply

Marsh Posté le 09-08-2006 à 18:36:41    

Amonchakai a écrit :

Les méthodes aléatoires c'est pas si compliqué : ce sont en fait des suite récurentes du type
 
Un+1 = (Un^6) % un grand chiffre premier;
 
enfin mon exemple est peut être (sûrement  :D ) bidon Mais l'idée c'est que c'est une suite. Donc tu doit d'initialiser a partir d'une certaine valeur et ensuite tu obtient des nombres pseudo aléatoire. C'est pour cela que tu as toujours les même nombres : tu part du même premier terme et les autres sont calculé par récurrence a partir du premier...
 
L'idée si tu veut avoir des résultats différents a chaque exécution serait de l'initialiser a partir d'un chiffre obtenu a partir de l'horloge de l'ordi. Comme ça a chaque fois que tu exécute ton prog tu a un point de départ différent pour ta suite et donc des résultats différents.


 
 
Merci pour ces explications,C'est plus clair maintenant.
Jstement cette fonction qui me permetterait de récuperer l'horloge de l'ordi, je pensais que c'était la fonction init_genrand(n) ais comme elle prend en argument un entier c pas possible.
Une telle fonction doit être sans argument apparamment, non?
Sauras tu quelle fonction utiliser?
Peut être qu'elle figure déjà dans le code que j'ai intégré dans mon dernier message?

Reply

Marsh Posté le 09-08-2006 à 19:17:48    

c'est justement le n de init_genrand(n) qu'on choisit généralement sur la base de l'horloge de l'ordi.
En général, j'utilise la fonction C time().
 
man 2 time


---------------
TriScale innov
Reply

Marsh Posté le 10-08-2006 à 10:44:16    

franceso a écrit :

c'est justement le n de init_genrand(n) qu'on choisit généralement sur la base de l'horloge de l'ordi.
En général, j'utilise la fonction C time().
 
Merci franseco pour ton aide, ça marche maintenant j'utiliser pour ça la fonction time() que tu m'as montré

Code :
  1. init_genrand(time(NULL));


 
En fait c'est quoi le site que tu m'as montré ???, il est un peu bizarre à quoi sert la photo et c'est quoi man??
 
man 2 time


Reply

Marsh Posté le 10-08-2006 à 10:50:34    

"man" c'est pour avoir la doc de quelque chose dans les *nix

Reply

Marsh Posté le 10-08-2006 à 10:57:32    

iamora a écrit :

En fait c'est quoi le site que tu m'as montré ???, il est un peu bizarre à quoi sert la photo et c'est quoi man??

Bah la photo, je suppose que c'est pour faire joli :spamafote:
 
"man", c'est l'abbréviation de "manuel". Il s'agit au départ d'une commande présente dans les unixoides pour donner de la documentation sur les fonctions C et les commandes que tu peux taper dans un terminal. Les pages de man sont toutes écrites de la même façon, et constituent une source centrale de documentation de référence. La plupart des pages de man sont aussi disponible sur internet sur le genre de site que je t'ai montré (donc la prochaine fois que tu te demandes comment utiliser une fonction C, tu peux essayer de taper 'man printf' (par exemple) dans google pour voir ce qui sort).


---------------
TriScale innov
Reply

Marsh Posté le 10-08-2006 à 10:59:59    

'man 3 time' plutot ?

Reply

Marsh Posté le 10-08-2006 à 11:04:54    

skelter a écrit :

'man 3 time' plutot ?


> man 3 time
No entry for time in section 3 of the manual


---------------
TriScale innov
Reply

Marsh Posté le 10-08-2006 à 11:06:36    

OK!
Merci pour ces infos les gars, ça me sera surement utile par la suite.
L'opérateur << est certes puissant dans le code que je vous ai transmis et que tu as corrigé franseco, je voudrais faire une petit changement d'affichage, mais je me rends compte que c'est impossibel :

Code :
  1. /* affichage pour tester */
  2. for( int i=1 ; i<=dim ; ++i )
  3. for( int j=1 ; j<=dim ; ++j )
  4. {   
  5. std::cout << setw(10) << covariance(i,j); 
  6. std::cout << std::endl;
  7. }


 
C'était pour afficher ma matraice de covariance, seulement  moi je ne voudrais pas d'espace au début de chaque ligne, alors je me suis dis en faisant ça :

Code :
  1. std::cout << covariance(i,j)  << setw(10);


Mais non ça ne marche pas, il le fait bien pour la première ligne mais pas pour les autres lignes qui suivent puisq'ils laissent un espace au début de chaque nouvelle ligne??
 
Peut être qu'avec l'opérateur << de sortie c'est pas possible de réaliser ce que je veux non?
 

Reply

Marsh Posté le 10-08-2006 à 11:14:28    

iamora a écrit :

Peut être qu'avec l'opérateur << de sortie c'est pas possible de réaliser ce que je veux non?

Si si, c'est possible !
Essaie de comprendre le fonctionnement des manipulateurs. En particulier, essaie de comprendre pourquoi tu as un espace en début de chaque ligne, et pourquoi ta solution ne marche pas. Si tu n'y arrives pas, on te proposera une solution, mais il est important que tu arrives à trouver les informations par toi même.
 
EDIT: Cf  le post d'Elmoricq sur les histoires de poissons et de canne à pêche

Message cité 1 fois
Message édité par franceso le 10-08-2006 à 11:16:41

---------------
TriScale innov
Reply

Marsh Posté le 10-08-2006 à 11:33:17    

franceso a écrit :

Si si, c'est possible !
Essaie de comprendre le fonctionnement des manipulateurs. En particulier, essaie de comprendre pourquoi tu as un espace en début de chaque ligne, et pourquoi ta solution ne marche pas. Si tu n'y arrives pas, on te proposera une solution, mais il est important que tu arrives à trouver les informations par toi même.
 
Pas mal l'histoire,
Mais je dois dire que tu as bien raison, j'essaierai de trouver seul !
 
EDIT: Cf  le post d'Elmoricq sur les histoires de poissons et de canne à pêche


Reply

Marsh Posté le 10-08-2006 à 11:42:59    

Code :
  1. /* affichage pour tester la matrice de cholesky */
  2. for( int i=1 ; i<=dim ; ++i )
  3. for( int j=1 ; j<=dim ; ++j )
  4. {   
  5. if (j==1)
  6. std::cout << C(i,j); 
  7. else
  8. {
  9. std::cout << setw(12) << C(i,j); 
  10.  } 
  11.     std::cout << std::endl;
  12. }


 
C'est mieux comme ça non?

Reply

Marsh Posté le 10-08-2006 à 14:45:23    

C'est effectivement l'une des solutions. Bravo !


---------------
TriScale innov
Reply

Marsh Posté le 10-08-2006 à 15:07:33    

franceso a écrit :

C'est effectivement l'une des solutions. Bravo !


Je pense que l'énigme suivante est plus diffcile et malgrès que je me suis planché la-dessus assez longtemps je bloque, je pense que j'ai besoin d'aide cette fois.
Voilà le but de mon programme est le suivant :
 
1) récupérer une matrice de variance-covariance depuis un fichier .txt  (étape faite et testée)
 
Le fichier .txt a la forme suivante:

Code :
  1. 6
  2. 3.06E-01
  3. 1.83E-02 4.42E-02
  4. 6.33E-03 2.98E-03 3.11E-02
  5. 1.88E-04 1.88E-04 1.88E-04 6.25E-04
  6. 1.29E-02 1.36E-02 -5.03E-04 1.88E-04 9.51E-02
  7. 4.49E-03 2.91E-02 6.50E-03 1.88E-04 3.05E-02 2.27E-01


 

Code :
  1. //fichier main principal
  2. #include "essai.h"
  3. #include <iostream>
  4. #include <sstream>
  5. #include <fstream>
  6. #include <iomanip>
  7. #include <string>
  8. using namespace std;
  9. int main()
  10. {
  11. ifstream fichierEntree("D:\\Documents and Settings\\AMOR\\Desktop\\VaRaction\\covariance.txt", ios::in);
  12. int dim;
  13. fichierEntree >> dim;
  14. ArrayLengthSpecifier dimension(dim);
  15. SymmetricMatrix covariance(dimension);
  16. /* lecture de la matrice */
  17. for( int i=1 ; i<=dim ; ++i )
  18. for( int j=1 ; j<=i ; ++j ) 
  19. {   
  20. double val;   
  21. fichierEntree >> val;   
  22. covariance(i,j) = val; 
  23. }
  24. }
  25. fichierEntree.close();


 
2) Traiter la matrice récupérée, cette étape se fait sous deux sous-étapes :
 
2-1) Appliquer une fonction nommée chol (cette fonction réalise la décomposition de Cholesky) Cette fonction c'est moi qui l'ai codée et elle est en annexe en à la fin de mon message (étape faite et testée)
 

Code :
  1. //décompose la matrice de covariance suivant cholesky
  2. int nbre_simul;
  3. Matrix C;
  4. C = chol(covariance);


 
2-2) étape ou je bloque:
 
2-2-1) Prendre la matrice transformée par la fonction Chol puis la multiplier par un vecteur de variable aléatoire normale généré par la fonction simind, dont mainteant tu connais la fonction:
simind : retourne à partir d'un générateur de nombre entre 0 et 1, la valeur correspondante à une variable normale
 
(étape ok)  
 
2-2-2) Mon but dans cet étape que je n'arrive pas à réaliser construire dans une matrice de dimension (nombre_simul, dim_vecteur généré) ou bien entendu la ligne i représente le produit de la matrice issue de la fonction chol par un vecteur dont les composantes sont générés aléatoirement.
Bien sur chaque ligne i représente une nouvelle simulation .
 
voici ce que j'ai codé et qui me semble être un début mais ça bloque pour des raisons que je ne comprend pas !
 
 

Code :
  1. //décompose la matrice de covariance suivant cholesky
  2. int nbre_simul;
  3. Matrix C;
  4. C = chol(covariance);
  5. //saisie du nombre de simulation
  6. cout << "Veuillez saisir le nombre de simulations souhaitees : ";
  7. cin >> nbre_simul;
  8. // définie la matrice de sortie  
  9. Matrix simul_epsilon (nbre_simul,dim);
  10.  
  11. for( int i=1 ; i<=nbre_simul ; i++ )
  12. {
  13. for( int j=0 ; j=dim ; ++j )
  14. {
  15. //génère un vecteur colonne de variable normale
  16. ColumnVector E;
  17. E = simind (dim);
  18. std::cout << E(1) << std::endl;
  19. //multiplie la matrice de cholesky par le vecteur de varibles normales (simulation d'un vecteur normale)
  20. ColumnVector epsilon_correl;
  21. epsilon_correl = C * E;
  22. std::cout << epsilon_correl(0) << std::endl;
  23.     //std::cout << epsilon_correl(2) << std::endl;
  24. simul_epsilon(i,j) = epsilon_correl(j);
  25. }
  26. }
  27. /* affichage pour tester la matrice de cholesky */
  28. for( int i=1 ; i<=dim ; ++i )
  29. for( int j=1 ; j<=dim ; ++j )
  30. {   
  31. if (j==1)
  32. std::cout << C(i,j); 
  33. else
  34.   {
  35. std::cout << " " << C(i,j); 
  36.   } 
  37.     std::cout << std::endl;
  38. }
  39. /* affichage pour tester la matrice simul_epsilon */
  40. for( int i=1 ; i<=dim ; ++i )
  41. for( int j=1 ; j<=dim ; ++j )
  42. {   
  43. if (j==1)
  44. std::cout << simul_epsilon(i,j); 
  45. else
  46.   {
  47. std::cout << " " << simul_epsilon(i,j); 
  48.   } 
  49.     std::cout << std::endl;
  50. }
  51. /* affichage pour tester la génération d'une variable normale*/
  52. //std::cout << E(1) << std::endl;  
  53. /* affichage pour tester la matrice de epsilon correl */
  54. //std::cout << epsilon_correl(1) << std::endl;  
  55. //écriture de la matrice de Cholesky transformée dans un fichier .txt  
  56. ofstream fichierSortie("C:\\Matrice de cholesky transformée.txt",ios::out);
  57. if (!fichierSortie)
  58. {
  59.  cerr << "Création du fichier impossible" << endl;
  60.  exit(1);
  61.     }
  62. for (int i=1;i<=dim;i++)
  63. for (int j=1;j<=i;j++)
  64. {   
  65. if (j==1)
  66. fichierSortie << C(i,j);
  67. else
  68.   {
  69.   fichierSortie <<  " " << C(i,j);                           
  70.   }
  71. }
  72. fichierSortie << endl;
  73. }
  74. return 0;
  75. }


 
code pour la fonction simind et chol
 

Code :
  1. // Il s'agit du fichier DLL principal.
  2. #include "stdafx.h"
  3. #include "CorrelSimul.h"
  4. ReturnMatrix chol(const SymmetricMatrix& correlation)
  5. {
  6. //renvoie la dimension de la matrice de corrélation
  7. ArrayLengthSpecifier dimension(correlation.Nrows());
  8. int dimension1 = correlation.Nrows();
  9. //initialise le test de défini positivité à faux
  10. bool test=false;
  11. //diagonalise la matrice de corrélation
  12. DiagonalMatrix D(dimension);
  13. Matrix V(dimension1,dimension1);
  14. LowerTriangularMatrix L(dimension);
  15. Matrix resultat;
  16. //renvoie les valeurs propres
  17. EigenValues(correlation,D,V);
  18. //
  19. if (D(1)<=0) test=true;
  20. if (test=false)
  21. {
  22.  L = Cholesky(correlation);
  23.  resultat=L;
  24. }
  25. else
  26. {
  27.  for (int i = 1; i <= dimension1; i++)
  28.  {
  29.   D(i)=sqrt(max(D(i),0)); /* on transforme D en D+ puis en (D+)^1/2  
  30.         pour prendre la racine carrée */
  31.  }
  32.   resultat = V*D*V.t();
  33. }
  34. D.Release();
  35. V.Release();
  36. L.Release();
  37. return resultat;
  38. }
  39. ReturnMatrix simind(const int& nbre_noms)
  40. {
  41. //créer une matrice colonne epsilon
  42. ColumnVector epsilon;
  43. //redimensionne la matrice espsilon avec la dimension correpondante  
  44. //au nombre de titre
  45. epsilon.ReSize(nbre_noms);
  46. //générateur de loie normale
  47. for (int i=1;  i<=nbre_noms; ++i)
  48.  init_genrand(time(NULL));
  49.  epsilon(i)= normal_random();
  50. }
  51. epsilon.Release();
  52. return epsilon;
  53. }


Message édité par iamora le 10-08-2006 à 15:47:48
Reply

Marsh Posté le 10-08-2006 à 15:51:58    

plusieurs remarques :
 
1- il faut initialiser la graine de ton générateur alatoire une seule fois au début du programme (par exemple dans la fonction main()).
 
2- dans chol(), je ne vois pas trop l'intéret de la variable booléenne temporaire test
 
3- tu devrais faire une fonction qui affiche une matrice, plutôt que de faire du copier/coller de code
 
4- tel quel, ton code ne doit sûrement pas compiler : la variable E est locale à la boucle du haut, mais tu demandes de l'afficher en dehors de cette boucle
 
5- tu as à mon avis un gros problème dans ta première double boucle : tel que tu es en train de le faire, tu génères un nouveau vecteur aléatoire pour chaque couple (i,j), ce qui veut dire qu'au final tu auras généré dim x nbre_simul vecteurs alatoires. Ceci ne semble pas cohérent avec le fait que chaque vecteur aléatoire est censé reprsenter une simulation.
D'après ce que j'ai compris (arrête moi si je me trompe), C est la transformation de Choleski de la matrice correlation. Donc C est de dimension dim.
Une 'simulation' est modélisée par un produit entre la matrice C et un vecteur E de dim variables alatoires indpendantes et identiquement distribues selon une loi normale. Le résultat d'une simulation epsilon_correl est donc un vecteur de dimension dim.
Tu ranges tes nbre_simul résultats de simulation en lignes dans une matrice simul_epsilon, qui est donc de dimension (nbre_simul, dim)
 
Dans ce cas, ta première double boucle devrait s'écrire :

Code :
  1. ColumnVector E;
  2. ColumnVector epsilon_correl;
  3. for(int i=1 ; i<=nbre_simul ; ++i )
  4. {
  5.   E = imind(dim);
  6.   epsilon_correl = C * E; 
  7.   for(int j=1 ; j<=dim ; ++j )
  8.   {
  9.     simul_epsilon(i,j) = epsilon_correl(j);
  10.   }
  11. }


 
6- tu as un problème dans les dimensions de tes matrices utilisées pour l'affichage


---------------
TriScale innov
Reply

Marsh Posté le 10-08-2006 à 16:23:03    

[quotemsg=1423777,26,383694]plusieurs remarques :
 
Merci, encore une fois tes indications sont trés clairs, et j'ajouterai que tu connais trés bien le sujet.  
Pour le point 5, de ton précédent message, je n'avais pas fait attention effectivement mais j'ai bien redimensionner ma matrice.
Après l'application de tes conseils voilà le code que j'obtiens et qui marche!
 

Code :
  1. //fichier main principal
  2. #include "essai.h"
  3. #include <iostream>
  4. #include <sstream>
  5. #include <fstream>
  6. #include <iomanip>
  7. #include <string>
  8. using namespace std;
  9. int main()
  10. {
  11. //initialise la graine du générateur de variable normale  
  12. init_genrand(time(NULL));
  13. ifstream fichierEntree("D:\\Documents and Settings\\AMOR\\Desktop\\VaRaction\\covariance.txt", ios::in);
  14. int dim;
  15. fichierEntree >> dim;
  16. ArrayLengthSpecifier dimension(dim);
  17. SymmetricMatrix covariance(dimension);
  18. /* lecture de la matrice */
  19. for( int i=1 ; i<=dim ; ++i )
  20. for( int j=1 ; j<=i ; ++j ) 
  21. {   
  22. double val;   
  23. fichierEntree >> val;   
  24. covariance(i,j) = val; 
  25. }
  26. }
  27. fichierEntree.close();
  28. //décompose la matrice de covariance suivant cholesky
  29. Matrix C;
  30. C = chol(covariance);
  31. int nbre_simul;
  32. ColumnVector E;
  33. ColumnVector epsilon_correl;
  34. //saisie du nombre de simulation
  35. cout << "Veuillez saisir le nombre de simulations souhaitees : ";
  36. cin >> nbre_simul;
  37. // définie la matrice de sortie  
  38. Matrix simul_epsilon (nbre_simul,dim);
  39. for(int i=1 ; i<=nbre_simul ; ++i )
  40. E = simind(dim); 
  41. epsilon_correl = C * E;   
  42. for(int j=1 ; j<=dim ; ++j )
  43. {   
  44. simul_epsilon(i,j) = epsilon_correl(j); 
  45. }
  46. }
  47. std::cout << simul_epsilon(4,4) << std::endl;
  48. /* affichage pour tester la matrice de cholesky */
  49. for( int i=1 ; i<=dim ; ++i )
  50. for( int j=1 ; j<=dim ; ++j )
  51. {   
  52. if (j==1)
  53. std::cout << C(i,j); 
  54. else
  55.   {
  56. std::cout << " " << C(i,j); 
  57.   } 
  58.     std::cout << std::endl;
  59. }
  60. /* affichage pour tester la matrice simul_epsilon */
  61. for( int i=1 ; i<=nbre_simul ; ++i )
  62. for( int j=1 ; j<=dim ; ++j )
  63. {   
  64. if (j==1)
  65. std::cout << simul_epsilon(i,j); 
  66. else
  67.   {
  68. std::cout << " " << simul_epsilon(i,j); 
  69.   } 
  70.     std::cout << std::endl;
  71. }
  72. //écriture de la matrice de Cholesky transformée dans un fichier .txt  
  73. ofstream fichierSortie("C:\\Matrice de cholesky transformée.txt",ios::out);
  74. if (!fichierSortie)
  75. {
  76.  cerr << "Création du fichier impossible" << endl;
  77.  exit(1);
  78.     }
  79. for (int i=1;i<=dim;i++)
  80. for (int j=1;j<=i;j++)
  81. {   
  82. if (j==1)
  83. fichierSortie << C(i,j);
  84. else
  85.   {
  86.   fichierSortie <<  " " << C(i,j);                           
  87.   }
  88. }
  89. fichierSortie << endl;
  90. }
  91. return 0;
  92. }


 
Cependant comme tu commence à me donner goût à la rigueur en C++ je suis tout à fait d'accord avec toi pour representer les choses dans une fonction comme réalisée pour chol et simind.
J'arrange cette fonction et si tu n'y voi pas d'incovénient je te la montre pour me dire si c'est ok???


Message édité par iamora le 10-08-2006 à 17:39:14
Reply

Marsh Posté le 10-08-2006 à 16:54:02    

Voilà la fonction que j'ai composé !
Elle s'apelle simcor, je te fournis tout mon fichier ou sont définies mes fonctions
 

Code :
  1. // Il s'agit du fichier DLL principal.
  2. #include "stdafx.h"
  3. #include "CorrelSimul.h"
  4. ReturnMatrix chol(const SymmetricMatrix& correlation)
  5. {
  6. //renvoie la dimension de la matrice de corrélation
  7. ArrayLengthSpecifier dimension(correlation.Nrows());
  8. int dimension1 = correlation.Nrows();
  9. //initialise le test de défini positivité à faux
  10. bool test=false;
  11. //diagonalise la matrice de corrélation
  12. DiagonalMatrix D(dimension);
  13. Matrix V(dimension1,dimension1);
  14. LowerTriangularMatrix L(dimension);
  15. Matrix resultat;
  16. //renvoie les valeurs propres
  17. EigenValues(correlation,D,V);
  18. //
  19. if (D(1)<=0) test=true;
  20. if (test=false)
  21. {
  22.  L = Cholesky(correlation);
  23.  resultat=L;
  24. }
  25. else
  26. {
  27.  for (int i = 1; i <= dimension1; i++)
  28.  {
  29.   D(i)=sqrt(max(D(i),0)); /* on transforme D en D+ puis en (D+)^1/2  
  30.         pour prendre la racine carrée */
  31.  }
  32.   resultat = V*D*V.t();
  33. }
  34. D.Release();
  35. V.Release();
  36. L.Release();
  37. return resultat;
  38. }
  39. ReturnMatrix simind(const int& nbre_noms)
  40. {
  41. //créer une matrice colonne epsilon
  42. ColumnVector epsilon;
  43. //redimensionne la matrice espsilon avec la dimension correpondante  
  44. //au nombre de titre
  45. epsilon.ReSize(nbre_noms);
  46. //générateur de loie normale
  47. for (int i=1;  i<=nbre_noms; ++i)
  48.  epsilon(i)= normal_random();
  49. }
  50. epsilon.Release();
  51. return epsilon;
  52. }
  53. ReturnMatrix simcor(const int& nbre_simul, const int& dim, const SymmetricMatrix& covariance)
  54. {
  55. //décompose la matrice de covariance suivant cholesky
  56. Matrix C;
  57. C = chol(covariance);
  58. //définie le vecteur de variables aléatoires normales
  59. ColumnVector E;
  60. //définie le vecteur issue de la multiplication de E et C
  61. ColumnVector epsilon_correl;
  62. // définie la matrice de sortie  
  63. Matrix simul_epsilon (nbre_simul,dim);
  64. for(int i=1 ; i<=nbre_simul ; ++i )
  65. E = simind(dim); 
  66. epsilon_correl = C * E;   
  67. for(int j=1 ; j<=dim ; ++j )
  68. {   
  69. simul_epsilon(i,j) = epsilon_correl(j); 
  70. }
  71. }
  72. C.Release();
  73. E.Release();
  74. epsilon_correl.Release();
  75. simul_epsilon.Release();
  76. return simul_epsilon;
  77. }


 
Puis voilà mon fichier principal ou j'utilise la fonction  
 

Code :
  1. //fichier main principal
  2. #include "essai.h"
  3. #include <iostream>
  4. #include <sstream>
  5. #include <fstream>
  6. #include <iomanip>
  7. #include <string>
  8. using namespace std;
  9. int main()
  10. {
  11. //initialise la graine du générateur de variable normale  
  12. init_genrand(time(NULL));
  13. ifstream fichierEntree("D:\\Documents and Settings\\AMOR\\Desktop\\VaRaction\\covariance.txt", ios::in);
  14. int dim;
  15. fichierEntree >> dim;
  16. ArrayLengthSpecifier dimension(dim);
  17. SymmetricMatrix covariance(dimension);
  18. /* lecture de la matrice */
  19. for( int i=1 ; i<=dim ; ++i )
  20. for( int j=1 ; j<=i ; ++j ) 
  21. {   
  22. double val;   
  23. fichierEntree >> val;   
  24. covariance(i,j) = val; 
  25. }
  26. }
  27. fichierEntree.close();
  28. //saisie du nombre de simulation
  29. int x;
  30. cout << "Veuillez saisir le nombre de simulations souhaitees : ";
  31. cin >> x;
  32. //définie la matrice de sortie
  33. Matrix sortie;
  34. sortie = simcor(x, dim, covariance);
  35. std::cout << sortie(4,4) << std::endl;
  36. return 0;
  37. }


 
Normalement ça devrait marcher, mais j'ai un message d'erreur le compilateur me dit que  

Code :
  1. essai.cpp(43) : error C2660: 'simcor' : la fonction ne prend pas 3 arguments


 
Ce que je trouve bizarre puisque j'ai bien définie une fonction à trois arguments???


Message édité par iamora le 11-08-2006 à 10:37:39
Reply

Marsh Posté le 11-08-2006 à 10:56:42    

Oui, ce que tu as écrit me semble pas mal. Tu devrais peut-être encapsuler le code d'input de la matrice dans une fonction : ça rendrait les choses plus claires et plus llisibles.
 
Concernant ton erreur de compilation, tu n'as pas de messages de warnings autour de ton erreur ? As-tu défini les prototypes de tes fonctions dans un fichier d'en-tête ? As-tu inclus le fichier d'en-tête en question dans ton programme principal ?


---------------
TriScale innov
Reply

Marsh Posté le 11-08-2006 à 11:05:57    

franceso a écrit :

Oui, ce que tu as écrit me semble pas mal.  
Bonjour,  
 
Tu devrais peut-être encapsuler le code d'input de la matrice dans une fonction : ça rendrait les choses plus claires et plus llisibles.
 
Je ne sais pas ce que veux dire le terme encapsuler un code (je suis encore débutant, j'apprend sur le tas...)
 
Concernant ton erreur de compilation, tu n'as pas de messages de warnings autour de ton erreur ?  
Non pas de warning, la seule erreure que j'ai est celle que je t'ai envoyé !
 
As-tu défini les prototypes de tes fonctions dans un fichier d'en-tête ?
Encore une fois et je suis désolén mais je ne comprend pas ce que sont les prototypes de fonction??, est ce les includes???
 
As-tu inclus le fichier d'en-tête en question dans ton programme principal ?


 
En fait voici mon fichier d'en-tête précompilé stadfx.h, je ne sais pas si il faut mettre la dedans comme mis en commentaire les fonctions que j'ai codé dans le fichier correl_simul.cpp.
Mais apparament non puisque ça marche sans ??
 

Code :
  1. // stdafx.h : Fichier Include pour les fichiers Include système standard,
  2. // ou les fichiers Include spécifiques aux projets qui sont utilisés fréquemment,
  3. // et sont rarement modifiés
  4. #define WINVER 0x400
  5. #pragma once
  6. #include <Afx.h>
  7. #include <afxdisp.h>
  8. #include <afxwin.h>
  9. #include <algorithm>
  10. #include <numeric>
  11. #include <fstream>
  12. #include <vector>
  13. #include <time.h>
  14. #include <math.h>
  15. #include <iostream>
  16. #include <tchar.h>
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <vector>
  21. #include "newmat\NEWMATAP.h"
  22. #include "newmat\NEWMAT.h"
  23. #include "newmat\myexcept.h"
  24. using namespace std;
  25. void init_genrand(unsigned long s);
  26. void init_by_array(unsigned long init_key[], int key_length);
  27. unsigned long genrand_int32(void);
  28. double genrand_real1(void);
  29. double random_0_1(void);
  30. double cndev(double u);
  31. double N(const double& z);
  32. double normal_random();
  33. double box_muller();
  34. double n(const double& z);
  35. double lognormal_random();
  36. /*ReturnMatrix cholesky (const SymmetricMatrix& S);*/
  37. //ReturnMatrix simind(const int& nbre_noms)
  38. /*ReturnMatrix simcor(const int& nbre_simul, const int& dim, const SymmetricMatrix& covariance);*/


 
 

Reply

Marsh Posté le 11-08-2006 à 11:15:50    

Je ne sais pas trop comment marchent les headers précompilés (je suppose que tu es sous VC++ ou quelque chose du genre ?). Essaie peut-être de te documenter dans ce sens la...
 
Sinon, que contiennent tes headers "essai.h" et "CorrelSimul.h" ?


---------------
TriScale innov
Reply

Marsh Posté le 11-08-2006 à 11:25:27    

Ne fait pas attention au début de ce message,regarde la fin c'est peut être la raison de mon erreur,
 
 
 

franceso a écrit :

Je ne sais pas trop comment marchent les headers précompilés (je suppose que tu es sous VC++ ou quelque chose du genre ?). Essaie peut-être de te documenter dans ce sens la...
 
Sinon, que contiennent tes headers "essai.h" et "CorrelSimul.h" ?


OK
Je suis sous Visualstudio.net 2003.
Je suis en mode release et dans les proporiétés de mon projet sous entêtes précompilés je compile avec l'option :  
Générer automatiquement (/YX)
Normalement ça ne devrait pas posé mon problème .
Un ami me dit que c'est peut être du au fait que ma fonction est définie avec un ReturnMatrix et que j'initialise sortie à Matrix dans le fichier priniicpal, mais je doute que ça soit la raison puisqu'avant ça marchait pour la fonction chol définie avec ReturnMatrix et renvoyant un resultat dans le fichier principal dans une variable déclarée comme Matrix
Matrix C;
C = chol(covariance);
 
En tout cas voilà le fichier "essai.h"  
 

Code :
  1. #include "stdafx.h"
  2. #include "CorrelSimul.h"


 
et le fichier correlsimul.h

Code :
  1. // CorrelSimul.h
  2. //Specifies that the file will be included (opened) only once by the compiler in a build.  
  3. //This can reduce build times as the compiler will not open and read the file
  4. //after the first #include of the module.
  5. //#pragma once
  6. //using namespace System
  7. //namespace CorrelSimul
  8. // public __gc class Class1
  9. // {
  10.  // TODO : ajoutez ici vos méthodes pour cette classe.
  11. // };
  12. ReturnMatrix chol(const SymmetricMatrix& correlation);
  13. ReturnMatrix simind(const int& nbre_noms);
  14. ReturnMatrix simcor(const int& nbre_noms, const double& rho);
  15. ReturnMatrix spreads(const Matrix& lambda, const ColumnVector& T, const Matrix& r, const ColumnVector& sigma, const ColumnVector& defaut,
  16.      const ColumnVector& x, const double& correlation, const int& nbre_noms,const int& no_steps);


 
Ah oui je ne l'ai pas changé la fdéfinition de ma focntion dans le fichier correlsimul.h, erreur de débutant je la change et je tiens au courant  
 
[code]


Message édité par iamora le 11-08-2006 à 11:26:57
Reply

Marsh Posté le 11-08-2006 à 11:28:23    


C'était ça l'erreur, la preuve que je ne maitrise pas du tout encore le c++.
Merci pour tes réflexions ça m'a mis sur la voie  
 

Reply

Marsh Posté le 11-08-2006 à 11:41:53    

on est tous passés par là. C'est les erreurs les plus bêtes qui prennent parfois le plus de temps à corriger.
 
De rien


---------------
TriScale innov
Reply

Marsh Posté le 11-08-2006 à 11:53:56    

Franseco, t'es de l'ensta?
Si c'est le cas je peux te demander ton avis sur une question purement technique en mathématiques?
SI ça risque de te gêner t'as qu'à me le dire!

Reply

Marsh Posté le 11-08-2006 à 12:02:48    

iamora a écrit :

Franseco, t'es de l'ensta?
Oui
 
Si c'est le cas je peux te demander ton avis sur une question purement technique en mathématiques?
Tu peux toujours demander... je ne garantis rien sur la réponse !
 
SI ça risque de te gêner t'as qu'à me le dire!
Pas de prob



---------------
TriScale innov
Reply

Marsh Posté le 11-08-2006 à 12:05:29    


Donc voilà  
 
Je voudrais comme tu le sais simuler en C++ un vecteur de variables aléatoires normales. Pour cela la méthode conseillée est de générer un vecteur colonne de variables normales, que je noterai [epsilon] puis de le multiplier par la matrice de "Cholesky" qui est une matrice issue de la décomposition de Cholesky de la matrice de variance covariance :
 
[var-covar]=[chol]*[chol]t
 
[var-covar]: est la matrice de variance-covariance
[chol]: est la matrice de Cholesky
[chol]t: est la transposée de la matrice de Cholesky
 
Le problème est que pour que cette décomposition soit juste, il faut que [var-covar] soit définie positive or ce n'est pas toujours mon cas.
Mon objectif est donc de trouver une méthode qui puisse forcer la matrice [var-covar] à devenir une matrice symétrique définie positive.
Pour cela j'ai pensé à diagonaliser [var-covar] puis à remplacer toutes les valeurs propres négatives par des 0 :
 
[var-covar] = [v]-1*[d]*[v]
ou [d] est une matrice diagonale dont les valeurs>0
 
ensuite je prends la racine des éléments de [d], donc diag[di]=di^(1/2).
Puis je dis que la matrice de Cholesky est la suivante  
chol = [v]-1*[d]^(1/2)*[v].
 
Je voudrais savoir si mon raisonnemment est correct, car j'ai un doute sur la validité de ma méthode.

Reply

Marsh Posté le 11-08-2006 à 13:30:34    

Salut !
Bon j'avoue tout de suite je n'y connait rien en matrice de variance-covaiance et Cholesky. Aussi j'ai été voir Google et j'ai trouvé ça :
http://fr.wikipedia.org/wiki/Matri [...] covariance
 
je sais pas si ce qui est dit dans Wikipedia est juste mais visiblement y'a un soucis : Ils disent que la matrice de variance-covariance est Symétrique positive. Donc y'a comme un soucis si tu trouve des Valeurs propre négatives...  :??:  
Ensuite ces valeurs propre (négatives...) tu veut les remplacer par des 0. Déja là tu rend ta matrice positive et PAS définie positive (tes valeurs propre doivent être strictement positive...) donc faudrait les remplacer par un nombre positif != de zéro... Mais moi ce qui me turlupine c'est qu'est-ce qui te donne le doit de changer ta matrice comme ça... Si tu change ses valeurs propre elle n'aurra plus rien a voir avec celle initiale (surtout qu'après tu va la multiplier par les matrices diagonalisantes...) Je sais pas ce que ça va donner sûrement qqch qui n'a rien a voir avec tes résultats initiaux...
 
Et puis juste par curiosité tu fait comment pour trouver les valeurs propres... Moi je chercherai les racines du polynôme caractéristique... Mais c'est du calcul formel : ça se fait bien a la main mais pour le faire faire a un ordinateur... (avec Maple Ok... mais sinon...)
 
[edit] J'espère que tu prend pas mal ma remarque, je veut pas répondre méchament c'est juste que je comprend pas bien ce que tu veut faire  :)  Et si j'ai dit un bêtise excuse moi  :D

Reply

Marsh Posté le 11-08-2006 à 13:59:26    

Amonchakai a écrit :

je sais pas si ce qui est dit dans Wikipedia est juste mais visiblement y'a un soucis : Ils disent que la matrice de variance-covariance est Symétrique positive. Donc y'a comme un soucis si tu trouve des Valeurs propre négatives...  :??:
Ensuite ces valeurs propre (négatives...) tu veut les remplacer par des 0. Déja là tu rend ta matrice positive et PAS définie positive (tes valeurs propre doivent être strictement positive...) donc faudrait les remplacer par un nombre positif != de zéro... Mais moi ce qui me turlupine c'est qu'est-ce qui te donne le doit de changer ta matrice comme ça... Si tu change ses valeurs propre elle n'aurra plus rien a voir avec celle initiale (surtout qu'après tu va la multiplier par les matrices diagonalisantes...) Je sais pas ce que ça va donner sûrement qqch qui n'a rien a voir avec tes résultats initiaux...


+1
c'est ce qui me paraît être la plus grande faille dans le raisonnement. Tu ne peux pas comme ça décider de changer ta matrice pour qu'elle vérifie les propriétés dont tu as besoin.
 
Il y a aussi un autre problème dans les dernières lignes : à mon avis tu ne peux pas te passer de calculer la décomposition de choleski de ta matrice "transformée". Ton histoire à base de "racine carrée" de la matrice diagonale ne marche pas à mon avis (il suffit de calculer le C x Ct avec l'expression que tu proposes pour voir qu'on ne retombe pas sur la matrice de départ)
 
 

Amonchakai a écrit :

Et puis juste par curiosité tu fait comment pour trouver les valeurs propres... Moi je chercherai les racines du polynôme caractéristique... Mais c'est du calcul formel : ça se fait bien a la main mais pour le faire faire a un ordinateur... (avec Maple Ok... mais sinon...)

Il existe plein de méthodes numériques pour déterminer des valeurs approchées des valeurs propres d'une matrice (par exemple l'algorithme de Jacobi pour les matrices symétriques)


Message édité par franceso le 11-08-2006 à 14:00:08

---------------
TriScale innov
Reply

Marsh Posté le 11-08-2006 à 14:06:43    

Citation :


Il existe plein de méthodes numériques pour déterminer des valeurs approchées des valeurs propres d'une matrice (par exemple l'algorithme de Jacobi pour les matrices symétriques)


 
ha tien je connais pas.... Merci pour l'info je vais voir ça pour ma culture.... :)

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed