Avatar billede lbs Nybegynder
01. december 2000 - 00:49 Der er 15 kommentarer og
1 løsning

invertering af matrice

Okay her er et mat spørgsmål

Jeg har ringe indsigt i matematik og har brug for en algoritme som inverterer en matrice.

lad os sige at den skal ligge i et 2-dimensionelt array.

Sproget behøver sådan set ikke at være c/c++, bare det er let forsåeligt
Avatar billede stigc Nybegynder
01. december 2000 - 00:52 #1
Jeg kan addtion og multiplikation,, men hvad er det inverte til en matrix?

Avatar billede lbs Nybegynder
01. december 2000 - 01:00 #2
hmm
ja jeg er også selv i tvivl
men hvis jeg har min matrix


[a b]
[c d]

og skal finde den inverse

så skal man noget i den her retning

[a b 1 0]
[c d 0 1]


og så laver man noget trylleri gauss-jordan eliminerin eller noget i den stil, 2 år siden jeg har haft om det, så man ender op med

[1 0 v x]
[0 1 z y]

og  så er

[v x]
[z y]

den inverterede..

det virker simpelt, men den hersens gauss-jordan virker som om det er sådan noget man gør med føling.. det er selvfølgelig fordi jeg ikke fatter den rigigt :)

Avatar billede stigc Nybegynder
01. december 2000 - 01:01 #3
Avatar billede stigc Nybegynder
01. december 2000 - 01:07 #4
Er der ikke noget med en matrix kan have en invers der ganget med sig selv giver en \"identititet\" matrix
Avatar billede stigc Nybegynder
01. december 2000 - 01:10 #5
åhhhh nu kommer det hele til mig igen, nu når jeg sider og blader i min gamle matematik bog! Det har jeg sgu\' engang været til eksamen i! Det kræver faktisk lidt menneskeligt overblik engang i mellem (noget med at prøve sig frem) så jeg tror den er rigtig svær at implementere! Hvad skal du bruge det til?
Avatar billede stigc Nybegynder
01. december 2000 - 01:13 #6
Det er noget med at lave nogen reduceringer på en matrix, for at komme frem til \"identity\" matrixen. Disse reduceringer køres så samme vej på \"identity\" matrixen, som så ender op med at blive til den inverse!

Reduceringerne skal man gætte sig frem til......

Ikke nemt at programmere!

held og lykke  :)
Avatar billede lbs Nybegynder
01. december 2000 - 01:13 #7
nope det var præcist det jeg tænkte..
hmm der må være en nem måde, jeg er på røven hvis man ikke kan :)
Avatar billede lbs Nybegynder
01. december 2000 - 01:15 #8
jeg skal bruge det til et grafikprojekt, vi skal beregne lys, og vi har to koordinatsystemer..
jeg skal regne baglæns for at kunne beregne nogle normaler som er nødvendige for lysberegningen
Avatar billede devia Nybegynder
01. december 2000 - 01:40 #9
Prøv engang med følgende:

double det(matrixptr); - Finder determinanten
int minv(matrixptr, matrixptr); - Inverterer matricen (kalder selv det();



/* Matrix structure */
typedef struct
{
  int rows;
  int cols;
  double *block;
} matrix,*matrixptr;


/* Find Determinant of matrix m */
double det(matrixptr m)
{
  double p1,p2,p3,d;
  int i,j,k;
  if (m->cols!=m->rows)
  {
    fprintf(stderr,\"\\ndet error - matrix must be square\");
    return(0.0);
  }
  d=0;
  for (i=0;i<m->cols;i++)
  {
    p1=p2=1.0;
    p3=*(m->block+i);
    k=i;
    for (j=1;j<m->cols;j++)
    {
      k=(k+1)%m->cols;
      p1*= *(m->block+j*m->cols+k);
      p2*= *(m->block+(m->cols-j)*m->cols+k);
    }
    p3*=(p1-p2);
    d+=p3;
  }
  return(d);
}


/* Invert matrix sm and put result in dm */
int minv(matrixptr sm, matrixptr dm)
{
  int i,j,k,l;
  int nrow,ncol;
  double *d;

  if (sm->rows!=dm->rows||sm->cols!=dm->cols)
  {
    fprintf(stderr,\"\\nminv error - matrices must be same size\");
    return(1);
  }
  if (det(sm)==0.0)
  {
    fprintf(stderr,\"\\nminv error - matrix is singular\");
    return 1;
  }
  d=(double *)(malloc(sizeof(double)*sm->rows*(sm->cols+1)));
  if (d==(double *)NULL)
  {
    fprintf(stderr,\"\\nminv error - insufficient memory\");
    return(1);
  }
  for (i=0;i<sm->rows;i++)
  {
    nrow=i-1;
    ncol=i-1;
    for (j=0;j<sm->rows;j++)
    {
      nrow=(nrow+1)%sm->rows;
      if (j==0)
        *(d+j*(sm->cols+1)+sm->cols)=1;
      else
        *(d+j*(sm->cols+1)+sm->cols)=0;
        for (k=0;k<sm->cols;k++)
        {
          ncol=(ncol+1)%sm->cols;
          *(d+j*(sm->cols+1)+k)=*(sm->block+nrow*sm->cols+ncol);
        }
    }
    if (nsolve(sm->rows,d))
    {
      fprintf(stderr,\"\\nminv error - cannot use nsolve on row %u\",i);
      free((char *)d);
      return 1;
    }
    else
    {
      nrow=i-1;
      for (j=0;j<sm->rows;j++)
      {
        nrow=(nrow+1)%sm->rows;
        *(dm->block+nrow*sm->cols+i)=*(d+j*(sm->cols+1)+sm->cols);
      }
    }
  }
  free((char *)d);
  return 0;
}
Avatar billede devia Nybegynder
01. december 2000 - 01:50 #10
Mangler måske lige et eksempel på hvorledes matrix structuren kan initialiseres:

/* Opret først matrix */
double b4x4A[4][4]=
{
  6,1,6,6,
  1,6,6,0,
  0,3,2,1,
  8,6,1,9
};

/* Og udfyld så matrix strukturen */
matrix m4x4A={4,4,&b4x4A[0][0]};

Avatar billede lbs Nybegynder
01. december 2000 - 01:55 #11
Det ser rigtigt godt ud, men du bruger en funktion nsolve..
som du ikke har angive?
Avatar billede lbs Nybegynder
01. december 2000 - 01:59 #12
devia, det ser ud som om du har styr på det, hvis du kan forklare hvad nsolve gør (og hvor jeg finder den=) er pointsne dine
Avatar billede devia Nybegynder
01. december 2000 - 13:08 #13
ups... den glemte jeg lige ;-)

/* Solve equation in N unknowns */
int nsolve(int rows, double data)
{
  int i,j,k;
  int cols;
  double dtemp;

  cols=rows+1;
  for (i=0;i<rows;i++)
  {
    for (j=i;j<rows&&*(data+j*cols+j)==0.0;j++);
    if (*(data+j*cols+j)==0.0)
    {
      fprintf(stderr,\"\\nnsolve error - singular matrix\");
      return 1;
    }
    if (j!=i)
    {
      for (k=0;k<cols;k++)
      {
        dtemp=*(data+i*cols+k);
        *(data+i*cols+k)=*(data+j*cols+k);
        *(data+j*cols+k)=dtemp;
      }
    }
    for (j=cols-1;j>=0;j--)
    {
      *(data+i*cols+j) /= *(data+i*cols+i);
    }
    for (j=i+1;j<rows;j++)
    {
      for (k=cols-1;k>=i;k--)
        *(data+j*cols+k)-=*(data+j*cols+i) * *(data+i*cols+k);
    }
  }
  for (i=rows-2;i>=0;i--)
  {
    for (j=cols-2;j>i;j--)
    {
      *(data+i*cols+cols-1)-= \\
      *(data+i*cols+j) * *(data+j*cols+cols-1);
      *(data+i*cols+j)=0;
    }
  }
  return 0;
}
Avatar billede lbs Nybegynder
01. december 2000 - 15:13 #14
jeg har ikke tid til at teste den, men jeg kigger på det i eftermiddag.
Avatar billede lbs Nybegynder
01. december 2000 - 23:09 #15
ehm gauss jordan eliminering eller hvad det nu hedder var ca tusind gange nemmere, og meget meget mindre beregnings tung.
Foley, vores store grafik-guru skriver at man kun bruger determinant metoden som du beskriver ovenfor med matricer på 3x3 eller mindre... mine var 4x4, jeg har klaret det på den hårde måde.

Men tak alligevel
Avatar billede moykal Nybegynder
02. december 2000 - 09:12 #16
Mht. denne form for beregninger, så bør man altså anvende de mere stabile beregninger såsom LU-dekomposition etc. Og dette har været standard software igennem årtier. Undersøg for god ordens skyld LAPack (Fortran pakke - den absolut mest anvendte ... CLAPack (www.netlib.org) er en portering til C). Hvis du vil have noget af det nyere C++ baserede software så check BLITZ... bygger på expression templates, hvilket er noget af det hotteste og hurtigste du kan få idag. En masse guf på www.oonumerics.org.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester