2012-03-29 14 views
0

Ich schreibe ein Programm, das ein Array durch eine Funktion (Oberklasse) sendet, die es von einer quadratischen nxn-Matrix in eine obere hessenberg-Matrix verwandelt. Das läuft gut, aber dann muss ich das Array durch eine andere Funktion senden, mit der ich ein Problem habe. Ich muss ein Doppel gleich dem ersten Element des Arrays machen. Stattdessen wird jedoch das Doppel (mu) gleich Null gesetzt. Ich schloss mein Code untenProbleme beim Abrufen eines Indexes eines Arrays [C]


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


int idx(int r, int c, int n) 
{ 
    return r * n + c; 
} 

void transpose(double *a, int n, double *at) 
{ 
    for (int i = 0; i < n; i++) { 
     for (int j = 0; j < n; j++) { 
      at[(idx (i, j, n))] = a[(idx (j, i, n))]; 
     } 
    } 
} 

void matrix_multiplication(double *a, double *b, int n, double *combo) 
{ 

    for (int i = 0; i < n; i++) { 
     for (int j = 0; j < n; j++) { 
      combo[(idx(i, j, n))] = 0; 
      for (int k = 0; k < n; k++) { 
       combo[(idx(i, j, n))] += a[(idx(i, k, n))] * b[(idx(k, j, n))]; 
      } 
     } 
    } 

} 

void identity(double *a, int n) 
{ 
    for (int i = 0; i < n; i++) { 
      for (int j = 0; j < n; j++) { 
       if (i == j) { 
        a[(idx(i, j, n))] = 1; 
       } 
       else { 
        a[(idx(i, j, n))] = 0; 
       } 
      } 
     } 
} 

void upperhes(double *a, int n, double *u, double *b) 
{ 

    //Sets b equal to a 
    for (int i = 0; i < (n*n); i++) { 
     b[i] = a[i]; 
    } 

    //Sets u equal to the identity matrix 
    identity(u, n); 

    int times = 0; 
    for (int i = 0; i < (n-2); i++) { 
     for (int j = n-1; j > (1 + times); j--) { 
      double c, s, r; 

      r = sqrt((b[(idx(j-1,i,n))] * b[(idx(j-1,i,n))]) + (b[(idx(j,i,n))] * b[(idx(j,i,n))])); 
      if (r < 0) { 
       r = (-1 * r); 
      } 
      if (r < pow(10,-50)) { 
       c = 1; 
       s = 0; 
      } 
      else { 
       c = b[(idx(j-1, i, n))]/r; 
       s = (-1 * b[(idx(j, i, n))])/r; 
      } 

      //store takes the original values of specific points in matrix b and stores them, so the values of b can be manipulated 
      double store[6]; 

      store[0] = b[(idx(j-1, i,n))]; 
      store[1] = b[(idx(j,i,n))]; 
      store[4] = b[(idx(i,j-1,n))]; 
      store[5] = b[(idx(i,j,n))]; 


      b[(idx (j,i,n))] = (s * store[0]) + (c * store[1]); 
      b[(idx(j-1,i,n))] = (c * store[0]) + (-s * store[1]); 

      for (int k= i+1; k<n; k++) { 

       store[2] = b[(idx(j-1,k,n))]; 
       store[3] = b[(idx(j,k,n))]; 

       b[(idx(j-1,k,n))] = (c * store[2]) - (s * store[3]); 
       b[(idx(j,k,n))] = (s * store[2]) + (c * store[3]); 
      } 


      b[(idx (i, j, n))] = (s * store[4]) + (c * store[5]); 
      b[(idx (i, j-1, n))] = (c * store[4]) - (s * store[5]); 

      for (int k = i + 1; k < n; k++) { 

       store[2] = b[(idx(k, j-1, n))]; 
       store[3] = b[(idx(k, j, n))]; 

       b[idx(k, j-1, n)] = (c * store[2]) - (s * store[3]); 
       b[idx(k, j, n)] = (s * store[2]) + (c * store[3]); 
      } 


      store[0] = u[(idx(j-1, 0, n))]; 
      store[1] = u[(idx(j, 0, n))]; 

      u[idx (j, 0, n)] = (s * store[0]) + (c * store[1]); 
      u[idx(j-1, 0, n)] = (c * store[0]) + (-s * store[1]); 

      for (int k= 1; k<n; k++) { 

       store[2] = u[idx(j-1, k, n)]; 
       store[3] = u[idx(j, k, n)]; 

       u[idx(j-1, k, n)] = (c * store[2]) - (s * store[3]); 
       u[idx(j, k, n)] = (s * store[2]) + (c * store[3]); 
      } 
     } 

     times++; 

    } 

    //Sets ut equal to the transpose of u 
    double ut[n*n]; 
    transpose(u, n, ut); 

    //Multiplies u and a together. 
    double ua[(n*n)]; 
    matrix_multiplication(u, a, n, ua); 

    double b_check[(n*n)]; 
    matrix_multiplication(ua, ut, n, b_check); 

    //Prints out the matrix! 
    for(int i=0; i<n; i++){ 
     for(int j =0; j<n; j++){ 
      printf("(%+.3f)\t", b[(idx (i,j,n))]); 
     } 
     printf("\n\n"); 
    } 
    printf("\n"); 

} 

void two_through_five(double *b, int n, double *eigenvalues, int total) 
{ 

    for (int times = 0; times < 100; times++){ 

     double mu = b[0]; 

     .......... 
    } 
} 

void qr_symmetric(double *a, int n, double *b) 
{ 

    //Creates a tridiagonal matrix by using a method that creates upper Hessenberg matrices on a symmetrical matrix a. 
    double u[n * n]; 
    upperhes(a, n, u, b); 

    //Creates an array to store the eigenvalues 
    double eigenvalues[n]; 

    two_through_five(b, n, eigenvalues, n); 
    for (int i = 0; i < n; i++) { 
     printf("%d\t", eigenvalues[n]); 
    } 
    printf("\n"); 

} 

int main(void) 
{ 
    int n; 
    n = 4; 
    double a[(n*n)]; 
    a[0] = 1; 
    a[1] = 2; 
    a[2] = 3; 
    a[3] = 4; 
    a[4] = 2; 
    a[5] = 6; 
    a[6] = 7; 
    a[7] = 8; 
    a[8] = 3; 
    a[9] = 7; 
    a[10] = 11; 
    a[11] = 15; 
    a[12] = 4; 
    a[13] = 8; 
    a[14] = 15; 
    a[15] = 16; 
    double b[n * n]; 
    qr_symmetric(a, n, b); 
    return 0; 
} 
+1

Der Code, den Sie gepostet haben, ist nicht die Ursache dafür, warum Sie in mu null erhalten. Es besteht die Möglichkeit, dass es sich um etwas in Ihrer Funktion "eleves()" handelt, aber Sie müssen ein kurzes, kompilierbares vollständiges Beispiel Ihres Problems veröffentlichen. – tinman

+0

@tinman Ich postete den Rest meines Codes, damit mein Problem mehr Sinn ergibt. Upperhess hat einige Bugs, scheint aber mit einer symmetrischen Matrix zu funktionieren, von der ich sicher bin, dass meine Eingabe stimmt. – GoodLuckGanesh

Antwort

0

Ihr Code shoud arbeiten. Zum Beispiel funktioniert das für mich:

void two_through_five(double *b, int n, double *eigenvalues, int total) 
{ 
    int times; 
    for (times = 0; times < 100; times++) 
    { 
     double mu = b[0]; 
     printf("%f\n", mu); 
    } 
} 

int main() 
{ 

    int n = 18; 
    int i =0; 

    double * b = malloc(n*sizeof(double)); 

    for(i=0; i<n;i++) b[i] = 15.0; 

    double eigenvalues[n]; 

    two_through_five(b, n, eigenvalues, n); 

    return 0; 
} 

Outupts:

15.000000 
15.000000 
15.000000 
15.000000 
15.000000 
15.000000 
15.000000 
15.000000 
15.000000 
... 

Also mein quedtion ist, sind Sie sicher, b [0] nicht 0?

+0

Ich postete den Rest meines Codes. Wenn ich es so führe, sollte b [0] gleich 1.000 sein. – GoodLuckGanesh

+0

versuchen, den Wert von b [0] kurz vor dem Aufruf von two_through_five() und dann printf ("% f \ n", mu) zu drucken; innerhalb von twow_through_five. Vielleicht gibt es etwas, das seinen Wert verändert. Denn wenn mein Code funktioniert, sollte auch dein Code funktionieren. Halten uns auf dem Laufenden! – nay

+0

Ich habe gerade mein Problem erkannt. Wann immer ich Dinge zum Testen ausgedruckt habe, habe ich printf ("% d", b [0]) oder printf ("% d", mu) verwendet, was nicht funktionieren würde. Es funktioniert definitiv! Vielen Dank! – GoodLuckGanesh

Verwandte Themen