Besoin d'aide c++

sevio14 Messages postés 15 Date d'inscription mercredi 5 mai 2010 Statut Membre Dernière intervention 3 mars 2011 - 2 mars 2011 à 18:36
cs_louis14 Messages postés 793 Date d'inscription mardi 8 juillet 2003 Statut Membre Dernière intervention 10 février 2021 - 8 mars 2011 à 08:55
Quelqu'un peut-il m'aider à faire le programme de l'algorithme d'uzawa?

Voici ce que j'ai commencé à définir:


#include
#include
#include <math.h>
#include <stdlib.h>
#include <stdio.h>

using namespace std;

#define N 4
typedef double Vecteur[N];
typedef double Matrice[N][N];

// A rendre avant 7 mars avant midi

double norme(Vecteur V){
double somme=0.0;
double norm=0.0;
for(int i=0 ; i<N ; i++){
if(V[i]==0){
norm=0.0;
}
else{
somme+=V[i]*V[i];
norm=sqrt(somme);
}
}
return norm;
}

double ValAbs(double x){
if(x>0)
return x;
else
return -x;
}

void remplir_mat(Matrice A) {
for (int i=0;i<N;i++){
for (int j=0;j<N;j++){
cout<<"Entrez la composante a["<>A[i][j];
}
}
}

void remplir_vec(Vecteur b) {
for (int i=0 ; i<N ; i++){
cout<<"Entrez la composante ["<>b[i];
}
}

void affiche_vec(Vecteur b) {
for (int i=0;i<N;i++){
cout<<"["<nmax)
nmax=tab[j];
}
return nmax;
}

void gradient_conjugue(Matrice A, Vecteur b,Vecteur x,double eps){
int m=0;
Vecteur a;
Vecteur r;
Vecteur d,Ax;
double rh,rho,rho1,lambda;
bool boolean=true;
double test=pow(eps,2);

for(int i=0; i<N; i++){
x[i]=0.;
}
for(int i=0; i<N; i++){
r[i]=0.;
}
for(int i=0; i<N; i++){
a[i]=0.;
}
for(int i=0; i<N; i++){
r[i]=b[i];
}
for(int i=0 ; i<N ; i++){
d[i]=r[i];
}
rh=prod_scal(r,r);
if (rh<=test){
boolean=false;
}
while(boolean == true){
m=m+1;
prod_mat_vect(A,d,a);
rho=rh/(prod_scal(d,a));
for(int i=0;i<N;i++){
x[i]=x[i]+rho*d[i];
}
for(int i=0;i<N;i++){
r[i]=r[i]-rho*a[i];
}
rho1=prod_scal(r,r);
lambda=rho1/rh;
rh=rho1;
for(int i=0;i<N;i++){
d[i]=r[i]+lambda*d[i];
}
if (rh<=test){
boolean=false;
}
}
}


void mat_A(Matrice A){
for(int i=1 ; i <= N ; i++){
for(int j=1 ; j <= N ; j++){
if(j==i)
A[i][j]=2*(N-1);
if(j==i+1)
A[i][j]=-1*(N-1);
if(j==i-1)
A[i][j]=-1*(N-1);
else
A[i][j]=0.0;
}
}
}

void vect_F(Vecteur F){
for(int i=0;i<N;i++){
F[i]=1/(N-1);;
}
}

void mat_B(Matrice B){
for(int i=0; i<2;i++){
for(int j=0; j<N; j++){
if((i==1 && j==1) || (i==2 && j==2)){
B[i][j]=1;
}
if((i==1 && j==N) || (i==2 && j==N-1)){
B[i][j]=-1;
}
else{
B[i][j]=0.0;
}
}
}
}

main(){
Matrice A;
for(int i=1 ; i <= N ; i++){
for(int j=1 ; j <= N ; j++){
if(j==i)
A[i][j]=2*(N-1);
if(j==i+1)
A[i][j]=-1*(N-1);
if(j==i-1)
A[i][j]=-1*(N-1);
else
A[i][j]=0.0;
}
}
}


main()
{
cout<<"------------------------------------------------------------------------"<<endl;
cout<<"----------------------METHODE D'UZAWA---------------------------------- "<<endl;
cout<<"-------------------------------------------------------------------------"<<endl;
//déclaration des variables



}

7 réponses

pop70 Messages postés 181 Date d'inscription mardi 6 avril 2010 Statut Membre Dernière intervention 7 janvier 2012 10
2 mars 2011 à 21:46
Voici les premiers changements effectués :


#include 
#include <math.h>  // Ici j'ai enlevé les librairies inutiles
#define N 4
typedef double Vecteur[N];
typedef double Matrice[N][N];


/* Là j'enlève le "using namespace std",
il faut mettre "std::" devant tous les cin, cout et endl ; c'est mieux
*/
double norme(Vecteur V)
{

//...


int main()
{
    Matrice A;
    for (int i=1 ; i < N ; i++) // juste < N et pas <= N
    {

 /* idem, sinon le programme se crash en tentant d&#8217;accéder à des éléments qui ne sont pas alloués : */

        for (int j=1 ; j < N ; j++)
        {
            if (j==i)
                A[i][j]=2*(N-1);
            else if (j==i+1)    /*Ici je change les "if" en "else if", c'est plus sûr, 
car si j ou i venait à être modifié dans la condition précédente, 
celle-ci ou une autre risquerait de s'executer aussi.
De plus le else à la fin ne s'appliquait avant qu'au "if" le précédent,
et je suis pas convaincu que se soit ce que tu veuilles faire. */
                A[i][j]=-1*(N-1);
            else if (j==i-1)
                A[i][j]=-1*(N-1);
            else
                A[i][j]=0.0;
        }
    }

// Là comme il n'y a plus using namespace on rajoute les std::
    std::cout<<"------------------------------------------------------------------------"<<std::endl;
    std::cout<<"----------------------METHODE D'UZAWA---------------------------------- "<<std::endl;
    std::cout<<"-------------------------------------------------------------------------"<<std::endl;



}


Pour le using namespace, tu peux aller jeter un coup d’œil ici, c'est le site de CptPingu, son article est vraiment bien et explique plein de choses.

Bonne chance,
Pop70
0
sevio14 Messages postés 15 Date d'inscription mercredi 5 mai 2010 Statut Membre Dernière intervention 3 mars 2011
3 mars 2011 à 08:45
J'ai fait le programme sur scilab et je voudrai le réécrire en c++:

N=4;
h = (1/(N-1));
A = zeros(N,N);

for i = 1:N
for j = 1:N

if (j==i) then
A(i,j)=2;
end
if (j== i+1) then A(i,j)=-1; end
if (j== i-1) then A(i,j)=-1; end

end;
end;
disp ('afficher la matrice', A);
A = (1/h)*A;
F=h*ones(N,1)
B=zeros(2,N);
B(1,1)=1;
B(2,2)=1;
B(1,N)=-1;
B(2,N-1)=-1;


T=zeros(1,N+2);


k=zeros(N+2,N+2);
k=[A,B';B,[0 0;0 0]]
T=[F;0;0]
S=linsolve(k,-T)

rho=10^(-3);
eps=10^(-6);
u=rand(zeros(N,1));
p=rand(zeros(2,1));
nmax=10000
function[p1,u1,n]=Uzawa(u,p,A,B,F,nmax,eps,rho)
p1=p;
for n=1:nmax
d=F-B'*p1;
u=inv (A)*d;
p2=p1+rho*B*u;
if (norm(p2-p1))<eps then
return
end
p1=p2
end
u1=u
endfunction

[p1,u1,n]=Uzawa(u,p,A,B,F,nmax,eps,rho);


mprintf('la solution 1 est \n')
p1
mprintf('la solution 2 est \n')
u1
0
pop70 Messages postés 181 Date d'inscription mardi 6 avril 2010 Statut Membre Dernière intervention 7 janvier 2012 10
3 mars 2011 à 11:23
Je connais pas le scilab, donc pour traduire ça en C++ ça va à peu près sauf à des endroits comme :
F=h*ones(N,1)
->Ca veut dire "faire un tableau de taille [N * h ; 1]" qu'on remplit de 1, ou faire un tableau de taille [N; 1] qu'on remplit de 1 * h ?


-Que doit faire la fonction linsolve ?
S=linsolve(k,-T)


et aussi à quoi doivent ressembler les matrices k et T quand on les déclare comme ça ?
k=[A,B';B,[0 0;0 0]]
T=[F;0;0]


genre T = F en [0;0] ?


Voila, sinon le reste c’est bon, il me manque juste ça pour pouvoir te donner une traduction à peu près correcte.


C++dialement,

Pop70
0
sevio14 Messages postés 15 Date d'inscription mercredi 5 mai 2010 Statut Membre Dernière intervention 3 mars 2011
3 mars 2011 à 14:14
F c'est un vecteur:
F =

0.25
0.25
0.25
0.25
0.25


S =

0.15625
0.25
0.28125
0.25
0.15625
- 5.126D-16
2.951D-16

k =

8. - 4. 0. 0. 0. 1. 0.
- 4. 8. - 4. 0. 0. 0. 1.
0. - 4. 8. - 4. 0. 0. 0.
0. 0. - 4. 8. - 4. 0. - 1.
0. 0. 0. - 4. 8. - 1. 0.
1. 0. 0. 0. - 1. 0. 0.
0. 1. 0. - 1. 0. 0. 0.


T =

0.25
0.25
0.25
0.25
0.25
0.
0.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
sevio14 Messages postés 15 Date d'inscription mercredi 5 mai 2010 Statut Membre Dernière intervention 3 mars 2011
3 mars 2011 à 14:17
ceux sont des matrices
0
pop70 Messages postés 181 Date d'inscription mardi 6 avril 2010 Statut Membre Dernière intervention 7 janvier 2012 10
3 mars 2011 à 16:21
Voilà, pour ma part je ne pourrait pas en faire plus, y'a encore plein de trucs que j'ai pas compris sur le scilab, mais bon voilà quand même un début.

Le code C++ est changé ligne par ligne, j'ai laissé le code de départ en commentaire en vert, à coté.

#include 
#include <math.h>

int main (int argc,char **argv)
{

    const int N=4;  // N =  4;

    double h (1/(N-1));  // h (1/(N-1)) soit 1/3;
    double A[N][N] = {0};  // A = zeros(N,N);

    for (int i 0; i < N; i++ ) //for i 1:N
    {
        for (int j 0; j < N; j++) //for j 1:N
        {
            if (j == i) //if (j==i) then
            {
                A[i][j] = 2; // A(i,j)=2;
            } //end
            else if (j == (i+1)) // if (j== i+1)
            {
                A[i][j] = - 1; //then A(i,j)=-1; end
            }
            else if (j == (i-1)) //if (j== i-1)
            {
                A[i][j] = -1; //   then A(i,j)=-1; end
            }
        } //end;
    }//end;

//******disp ('afficher la matrice', A); ******/
    std::cout << "`\nMatrice A : \n";
    for (int y = 0; y < N; y++)
    {
        for (int x = 0; x < N; x++)
        {
            std::cout << A[x][y] << " - ";
        }
        std::cout << std::endl;
    }
//********************************************/



//***** A =  (1/h)*A ; *****/
    for (int y = 0; y < N; y++)
    {
        for (int x = 0; x < N; x++)
        {
            A[x][y] *= (1/h);
        }
    }
//***************************/



    double F[N] = {h}; //F=h*ones(N,1)

    double B[2][N] = {0}; //B=zeros(2,N);
    B[0][0] = 1; //B(1,1)=1;
    B[1][1] =1; //B(2,2)=1;
    B[0][N - 1] = -1; //B(1,N)=-1;
    B[1][N-2] = -1; //B(2,N-1)=-1;


    double T[N+1] = {0}; //T=zeros(1,N+2);

    double k[N+2][N+2] = {0}; //k=zeros(N+2,N+2);
// ? // k=[A,B';B,[0 0;0 0]]

//*****T=[F;0;0]*****/
    for (int z = 0; z < N - 2; z ++)
    {
        T[z] = h;
    }
//*********************/
// ? // S=linsolve(k,-T)

    double rho = pow(10,-3); //rho=10^(-3);
    double eps = pow(10, -6); //eps=10^(-6);
    double u[N] = {rand()};  // u=rand(zeros(N,1));
    double p[2] = {rand()}; // p=rand(zeros(2,1));
    int nmmax = 10000; //nmax=10000

// ? // function[p1,u1,n]=Uzawa(u,p,A,B,F,nmax,eps,rho)

//******p1=p;*****/
    double p1[2];
    for (int z = 0; z < N;z++)
    {
        p1[z] = p[z];
    }
//********/


    for (int n = 1; n < nmmax; n++) //for n=1:nmax
    {
        double d[N];

//*****d=F-B'*p1; ***/
        for (int z = 0; z < N; z++)
        {
            d[z] = F[z] - B[0][z]; // ?
        }
//*******************/


//********u=inv (A)*d;*****/
        for (int z = 0; z < N; z++)
        {
            u[z] = (1 / (A[z][z])) * d[z]; // ?
        }
//**************************/

        double p2[2];

        //******p2=p1+rho*B*u;****/
        for (int z = 0; z < 2; z++)
        {
            p2[z] = p1[z] + rho * B[0][z] * u[z];
        }
//***************/

        if (sizeof(p2) - sizeof(p1) < eps)  //if (norm(p2-p1))<eps then
        {
            return 0; //return
        } //end
//******p1=p2;*****/
        double p1[2];
        for (int z = 0; z < N;z++)
        {
            p1[z] = p2[z];
        }
//********/

    }//end

//*****u1=u****/
    double u1[N];
    for (int z = 0; z < N;z++)
    {
        u1[z] = u[z];
    }
//*******/

//endfunction

//[p1,u1,n]=Uzawa(u,p,A,B,F,nmax,eps,rho); ?


    std::cout << "La solution 1 est p1" << p1 << "\n"; //mprintf('la solution 1 est \n') p1
    std::cout << "La solution 2 est p1" << u1 << "\n";  //mprintf('la solution 2 est \n') u1

    return 0;
}


Y'a sûrement des calculs qui sont pas bon, mais après c'est juste histoire de modifier "qu'est-ce qu'on calcul avec quoi"...
Sinon y'a des fonctions comme Uzawa() qu'y n'ont pas d'équivalent direct, même dans l'espace standard .
Y va falloir la ré-implémenter totalement je pense.


Bonne chance et bon courage !


C++dialement,

Pop70
0
cs_louis14 Messages postés 793 Date d'inscription mardi 8 juillet 2003 Statut Membre Dernière intervention 10 février 2021 8
8 mars 2011 à 08:55
Bonjour,
Il faut télécharger les sources de Scilab pour obtenir le code des fonctions particulières ou au moins s'en inspirer.


louis
0
Rejoignez-nous