矩阵逆

时间:2018-12-01 23:34:00

标签: c++ arrays

直到现在,我已经开发了一个代码,可以打印用户输入的矩阵。

并尝试数学计算逆,但我无法收到适当的结果。 它通过函数获得定律,然后逐步获取新矩阵中与旧矩阵相反的每个新元素

我试图简单地做到这一点 这是我的代码 我想要执行此任务的更好算法

      #include <iostream>
     #include <stdlib.h>

       using namespace std;

     float Det (int  arr [3][3] )
      {

int res = arr[0][0]*(arr[1][1]*arr[2][2]-arr[2][1]*arr[1][2])-arr[0][1]*(arr[1][0]*arr[2][2]-arr[1][2]*arr[2][0])+arr[0][2]*(arr[1][0]*arr[2][1]-arr[1][1]*arr[2][0]);

return res ;

    }

  int main()
  {
int arr [3][3] ={{0,0,0},{0,0,0},{0,0,0}};
float inv [3][3]={{0,0,0},{0,0,0},{0,0,0}};
for(unsigned i = 0 ; i<3 ;i++)
{
    for(unsigned j= 0 ;j<3 ;j++)
    {
        cout << "Enter The Value Of The Element < " <<i+1<<" , "<<j+1<<" > :" ;
        cin >> arr [i][j] ;
    }
}
system("cls") ;
float det = Det(arr) ;

for(int i = 0 ; i < 3 ;i++)
{
    for(unsigned j = 0 ; j< 3 ; j++)
    {
        unsigned m [2]={i+1,i+2} ;
        unsigned n [2]={j+1,j+2} ;
        for(unsigned k = 0 ; k< 2 ;k++)
        {
            if(m[k]>2)
            {
                m[k]=0;
                swap(m[0],m[1]);

            }
            if(n[k]>2)
            {
                n[k]=0;
                swap(n[0],n[1]) ;

            }

        }
        inv [i][j] = arr[m[0]][n[0]]*arr[m[1]][n[1]]-arr[m[0]][n[1]]*arr[m[1]][n[0]] ;
        if((i+j)%2!=0)
        {
            inv [i] [j] = -inv[i][j] ;
        }
        inv [i] [j] = (1/det) * inv[i] [j];
    }
}
swap(inv[0][1],inv[1][0]);
swap(inv[2][1],inv[1][2]);
swap(inv[0][2],inv[2][0]);


cout << " Your Matrix is "<<endl ;
for(unsigned i = 0 ; i<3 ;i++)
{
    cout<< "     " ;
    for(unsigned j= 0 ;j<3 ;j++)
    {

        cout<< arr [i][j]<< "  " ;
    }
    cout <<endl<<endl ;
}


cout<< "DET =  "<<det <<endl ;


cout << " Your Inverse is "<<endl ;
for(unsigned i = 0 ; i<3 ;i++)
{
    cout<< "     " ;
    for(unsigned j= 0 ;j<3 ;j++)
    {

        cout<< inv [i][j]<< "  " ;
    }
    cout <<endl<<endl ;
}
  }

2 个答案:

答案 0 :(得分:0)

@MahmoudMohammad。将您的代码视为一首诗。它必须清楚,出于可读性原因而缩进并进行注释。如上面@Peter所述,除了使用平凡的高斯消除技术外,您还可以使用其他有效的方法,因为随着矩阵大小的增加,这在计算上会非常昂贵。但是,您可以通过阅读thisthis来改进代码。有关其他方法的更多信息,请参见also

答案 1 :(得分:0)

struct matris
{
    static matris matris_ans;
    int en; // {0};
    int boy;// = 0;
    int top;// = 0;
    double *p;// = NULL;


    matris();
    matris(int _boy,int _en);
    matris(double *_p,int _boy,int _en);
    matris(matris &m);     
    matris( dbl a, dbl b, dbl c,
            dbl d, dbl e, dbl f,
            dbl g, dbl h, dbl i);
    matris( dbl a, dbl b, dbl c, dbl d,
            dbl e, dbl f, dbl g, dbl h,
            dbl i, dbl j, dbl k, dbl l,
            dbl m, dbl n, dbl o, dbl p);

    ~matris();

    matris& operator = (matris &m);
    matris  operator + (matris &m) ;
    matris  operator * (matris &m) ;

    double& operator () (int _boy, int _en);
    double* operator [] (int kk);

    double   al(int _boy, int _en);
    double &koy(int _boy, int _en);

    void degistir(int _boy,int _en);
    void degistir(double *_p,int _boy,int _en);
    void reset();
    void sifir();
    void birim();
    void yaz_konsola();
    void yaz_dosyaya(char *isim );
    void yaz_resme(char *isim);
    matris trn();

    friend void matris_copy(matris *m1, matris *m2);                //m2 yi m1 e kopyalar
    friend void matris_topla(matris *m1, matris *m2, matris *m3);   //m1=m2+m3
    friend void matris_carp(matris *m1, matris *m2, matris *m3);    //m1=m2*m3
    friend void matris_ident(matris *m1, int say);                  //matrisi birim matris yapar
    friend void matris_trn(matris *m1);                             //matrisi ters çevirir
    friend matris matris_trn(matris &m1);                           //
    friend void matris_inverse(matris *a, matris *m);               //matrisin inversini alır

    static void test1();


};

//MATRIS
matris  matris::matris_ans;
        matris::matris()// :en(0),boy(0),p(0),top(0)
{
    en=0;   boy=0;  p=0;    top=0;
}  
        matris::matris(int _boy,int _en)//  :en(_en),boy(_boy)
{
    en=_en; boy=_boy;   top=_en*_boy;
    p=new double[top];

    for(int i=0;i<top;i++) p[i]=0;
}  
        matris::matris(double *_p,int _boy,int _en)
{
    en=_en; boy=_boy;   top=en*boy;
    p=new double[top];
    for(int i=0;i<top;i++)  p[i]=_p[i];
}  

        matris::matris(matris &m)
{
    boy=m.boy;
    en =m.en;
    top=m.top;
    p=new double[top];
    for(int i=0;i<top;i++) p[i]=m.p[i];
}  
        matris::~matris()
{
    delete p;
}
        matris::matris( dbl a, dbl b, dbl c,
                        dbl d, dbl e, dbl f,
                        dbl g, dbl h, dbl i)
{
    en =3;  boy=3;  top=en*boy;
    p = new double[top] {a, b, c, d, e, f, g, h, i};
}
        matris::matris( dbl a, dbl b, dbl c, dbl d,
                        dbl e, dbl f, dbl g, dbl h,
                        dbl i, dbl j, dbl k, dbl l,
                        dbl m, dbl n, dbl o, dbl p)
{
    en =4;
    boy=4;
    top=en*boy;
    this->p = new double[top]
    {a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p};

}  
double  matris::al(int _boy, int _en)
{
    return p[_boy*en+_en];
}
double& matris::koy(int _boy, int _en)
{
    return p[_boy*en + _en];
}
double& matris::operator () (int _boy, int _en)
{
    return p[_boy*en + _en];
}

void    matris::degistir(int _boy,int _en)
{
    if (en == _en && boy == _boy)
    {
        for (int i = 0; i < top; i++)   p[i] = 0;
        return;
    }
    en=_en; boy=_boy;   top=en*boy;
    if (p) delete p;
    p=new double[top];
    for(int i=0;i<top;i++)  p[i]=0;
}
void    matris::degistir(double *_p,int _boy,int _en)
{
    if(en == _en)   // (en=_en && boy==_boy)
    if(boy == _boy)
    {
        memcpy(p, _p, top * sizeof(double));
        return;
    }


    en=_en;
    boy=_boy;
    top=en*boy;
    if (p) delete p;//[] gerek yok heralde
    p=new double[top];
    for(int i=0;i<top;i++) p[i]=_p[i];
} 
void    matris::reset()
{
    if (p) delete p;
    memset(this, 0, sizeof(*this));
}
void    matris::sifir()
{
    if(p)   memset(p, 0, en*boy * sizeof(double));
}
void    matris::birim()
{
    sifir();
    for (int i = 0; i < en; i++)
        p[i + i * en] = 1;

}
void    matris::yaz_konsola()
{
    printf("matris(%4d,%4d)=\n",boy,en);

    for(int j=0;j<boy;j++)
    {
        for(int i=0;i<en ;i++)
            printf("%9.2g ",p[j*en+i]);
        printf("\n");
    }
    printf("\n");
}
void    matris::yaz_dosyaya(char *_dosya_ismi)
{
    FILE *yaz;
    yaz = fopen(_dosya_ismi, "w");
    fprintf(yaz,"matris(%4d,%4d)\n",boy,en);

    for(int j=0;j<boy;j++)
    {
        for (int i = 0; i < en; i++)
            if (p[j*en + i])
                    fprintf(yaz, "a");//    fprintf(yaz, "%12.4g ", p[j*en + i]);
            else    fprintf(yaz, " ");
        fprintf(yaz,"\n");
    }


    fprintf(yaz,"\n");
    fclose(yaz);

}
void    matris::yaz_resme(char *_dosya_ismi)
{
    resim r(boy, en);

    resim::renk byz = { 255,255,255,255 },
                gri = { 128,128,128,128 };

    for (int j = 0; j < boy; j++)
    {
        for (int i = 0; i < en; i++)
            if (p[j*en + i])
                    r[j][i] = byz;
            else    r[j][i] = gri;
    }


    r.kaydet(_dosya_ismi);

}
matris& matris::operator = (matris &m)
{
    degistir(m.p, m.boy, m.en);
    return *this;
}
matris  matris::operator + (matris &m)
{

    matris_ans.degistir(boy,en);

    for(int i=0;i<top;i++)
        matris_ans.p[i]=p[i]+m.p[i];

    return matris_ans;
}
matris  matris::operator * (matris &m)
{
    matris_ans.degistir(boy, m.en);


    int _boy=boy;
    int _en=m.en;
    int _say=en;

    for(int i=0; i<_boy; i++)
    for(int j=0; j<_en;  j++)
    for(int k=0; k<_say; k++)
    {
        matris_ans[i][j] += (*this)[i][k] * m[k][j];
    }

    return matris_ans;//kopya döndür 
}  
double* matris::operator [] (int kk)
{
    return p + en * kk;// (&p[en*kk]);
}
matris  matris::trn()
{
    matris a(en,boy);
    for(int i=0;i<boy;i++)
    for(int j=0;j<en;j++)
        a.koy(j,i)=al(i,j);//m1 i ters çevirip a ya koy
    return a;
}  

void    matris_copy(matris *m1,matris *m2)
{
    //eski sitil
    m1->degistir(m2->boy,m2->en);
    memcpy(m1->p,  m2->p,  m2->top*sizeof(double));//m2 nin belleğini m1 e kopyala
}
void    matris_topla(matris *m1,matris *m2,matris *m3)
{
    m1->degistir(m2->boy,m2->en);
    int top=m3->top;
    for(int i=0;i<top;i++)
        m1->p[i]=m2->p[i]+m3->p[i]; 
}  
void    matris_carp(matris *m1,matris *m2,matris *m3)
{
    int say=m2->en;
    int boy=m2->boy;
    int en=m3->en;
    m1->degistir(boy,en);

    for(int i=0;  i<boy;  i++)
    for(int j=0;  j<en;   j++)
    for(int k=0;  k<say;  k++)
        m1->koy(i,j) += m2->al(i,k) * m3->al(k,j); 

}  
void    matris_ident(matris *m1,int say)
{
    if (m1->en == say && m1->boy == say)
    {
        //m1->sifir();
        if (m1->p)  memset(m1->p, 0, say*say * sizeof(double));
        for (int i = 0; i < say; i++)  m1->koy(i, i) = 1;
        return;
    }
    m1->degistir(say,say);
    for(int i=0;i<say;i++)  m1->koy(i,i)=1;

}  
void    matris_trn(matris *m1)
{
    matris *a=new matris(m1->en,m1->boy);;//en boy ters yeni a matrisi
    for(int i=0;i<m1->boy;i++)
    for(int j=0;j<m1->en;j++)
        a->koy(j,i)=m1->al(i,j);//m1 i ters çevirip a ya koy
    matris_copy(m1,a); //a yı m1 e kopyala
    delete a;

}  
matris  matris_trn(matris &m1)
{
    matris a(m1.en,m1.boy);
    for(int i=0;i<m1.boy;i++)
    for(int j=0;j<m1.en;j++)
            a.koy(j,i)=m1.al(i,j);//m1 i ters çevirip a ya koy
    return a;//kopya döndür ama silinecek

}  
void    matris_inverse(matris *a,matris *m)//m matrisinin inversini a matrisine koy
{
    int boy=m->boy;
    int en=m->en;
    matris_ident(a,boy);//a matrisini birim matris yapalım


    for(int i=0;i<en;i++)//sütunları dön
    {


        for(int j=0;j<boy;j++)//satırları dön
        {               
            int k;//dolu satırın yeri
            for(k=i;k<boy;k++)//dolu satırı bul i den itibaren
            {
                if(m->al(k,i)==0) continue;//sıfırsa atla  i hangi en sütünundayız o                        
                break;//sıfır değil demek bu bana lazım k dolu satırım
            }

            //dolu satırı köşeye koy
            double temp;
            for(int t=0;t<en;t++)//matrisin i==j satırlarını doluyla değişelim
            {
                temp=m->al(i,t);    m->koy(i,t) = m->al(k,t);   m->koy(k,t)=temp;  //m matrisi
                temp=a->al(i,t);    a->koy(i,t) = a->al(k,t);   a->koy(k,t)=temp;  //a matrisi
            }

            //dolu satırı 1 yap
            double kk=m->al(i,i);
            for(int t=0;t<en;t++)
            {
                m->koy(i,t)=m->al(i,t)/kk;  //m matrisi
                a->koy(i,t)=a->al(i,t)/kk;  //a matrisi
            }
            break;
        }


        for(int j=0;j<boy;j++)//diğer satırları 0 yap
        {
            if(m->al(j,i)==0) continue;//zaten sıfırmış gerek yok
            if(j==i) continue;         //bu satırı geç 
            double kk=m->al(j,i);
            for(int t=0;t<en;t++)
            {
                m->koy(j,t)-=m->al(i,t)*kk; //m matrisi
                a->koy(j,t)-=a->al(i,t)*kk; //a matrisi
            }
        }


    }

}
void    matris::test1()
{
    printf("<<<<<<<<<<hesap_matris()\n");

    double pp[] = { 0,0,1,9,
                    5,0,9,0,
                    2,7,0,5,
                    0,3,0,6 };
    matris mat_b(pp, 4, 4);

    mat_b.yaz_konsola();

    matris mat_c;
    matris_inverse(&mat_c, &mat_b);
    mat_b.yaz_konsola();
    mat_c.yaz_konsola();


    memcpy(mat_b.p, pp, 16 * sizeof(double));

    //1000*1000 luk matris yapıp inversini al
    matris mat_k;
    matris_ident(&mat_k, 5);
    for (int i = 0; i < 25; i++)
        mat_k.p[i] = sin(double(i));

    mat_k.yaz_konsola();
    matris_inverse(&mat_c, &mat_k);
    mat_c.yaz_konsola();
    mat_k.yaz_konsola();

    /*
    matris_inverse(&mat_k, &mat_c);
    mat_k.yaz_konsola();
    matris_inverse(&mat_c, &mat_k);
    mat_c.yaz_konsola();
    */



    matris m(
        0, 0, 1, 9,
        5, 0, 9, 0,
        2, 7, 0, 5,
        0, 3, 0, 6), m3=m;
    m3 = m * m + m;
    /*
    m.yaz_konsola();
    m3.yaz_konsola();
    */





}