Matrix in Funktion übergeben.
-
Also überall n-1 in den Funktionen
sowie in der main choldc(n-1....)?
oder verstehe ich dich da falsch?
Wenn ich es so mache gibt er mir keine Fehler oder Warnungen an,
aber er gibt es als Fehler (nicht positiv definit aus) was ja nicht stimmt
-
DirkB schrieb:
Bleibt nur noch die Frage nach deiner Lieblingsfarbe!
-
Martin Subovic schrieb:
Also überall n-1 in den Funktionen
sowie in der main choldc(n-1....)?
oder verstehe ich dich da falsch?Nein!
n ist die Größe!! Beim Aufruf von choldc musst du natürlich n und nicht n-1 angeben. Die Indizes laufen von 0 bis n-1. Du scheinst aber Indizes von 1 bis n zu nutzen, was nicht richtig ist.Vergleiche:
for (i=1;i<=n;i++) for (i = 0; i < n; i++)
-
Martin Subovic schrieb:
Also überall n-1 in den Funktionen
sowie in der main choldc(n-1....)?Nein
Martin Subovic schrieb:
oder verstehe ich dich da falsch?
Ja.
An die Funktion übergibst du die Anzahl der Elemente pro Zeile/Spalte (also n (bei dir 4))In den Schleifen darf der Index das n aber nicht erreichen, da du sonst auf falsche Elemente vom Array zugreifst.*
for (i=0;i<n;i++) { // hier ist das in Ordnung for (j=i;j<=n;j++) { // Bis wohin zählt diese Schleife?
for (i=n;i>=1;i--) { //Über welchen Bereich zählt diese Schleife?
Martin Subovic schrieb:
Wenn ich es so mache gibt er mir keine Fehler oder Warnungen an,
aber er gibt es als Fehler (nicht positiv definit aus) was ja nicht stimmtDafür müsstest du ja mit den richtigen Werten rechnen * (und der Algorithmus muss auch richtig sein).
Bis jetzt hast du ja gerade erstmal die Werte richtig in die Funktion rein bekommen (wennmain
stimmt)
-
float choldc(int n, float a[n][n],float p[n]) { void nrerror(char error_text[]); int i,j,k; float sum; for (i=0;i<n;i++) { for (j=i;j<n;j++) { for (sum=a[i][j],k=i-1;k>=1;k--) sum -= a[i][k]*a[j][k]; if (i == j) { if (sum <= 0.0) nrerror("choldc failed"); p[i]=sqrt(sum); } else a[j][i]=sum/p[i]; } } return 1; } float cholsl(int n, float a[n][n], float p[n], float b[n], float x[n]) { int i,k; float sum; for (i=0;i<n;i++) { for (sum=b[i],k=i-1;k>=1;k--) sum -= a[i][k]*x[k]; x[i]=sum/p[i]; } for (i=n-1;i>=0;i--) { for (sum=x[i],k=i+1;k<n;k++) sum -= a[k][i]*x[k]; x[i]=sum/p[i]; } return 1; } int main() { int n = 4; float L; float p[n]; int zeile =4; int spalte =4; float a[4][4]={{1, -0.2, 0, 0}, {-0.2, 2, -0.3, 0}, {0, -0.3, 3, -0.4}, {0, 0, -0.4, 4}}; L = choldc(n, a, p); printf(" Untere Dreiecksmatrix L %f \n ", L); return 0; }
Also ich habe jetzt
for (i=0;i<n;i++) { // hier ist das in Ordnung for (j=i;j<=n;j++) { // Bis wohin zählt diese Schleife? // bis j<n geändert for (i=n;i>=1;i--) { //Über welchen Bereich zählt diese Schleife? //geändert zu (i=n-1;i>=0;i--)
-
Hast du die anderen Schleifen (Start-, Endwerte, Inkrement) auch gleich mal überprüft?
-
Ja ich habe soweit alles geändert dass es passen sollte in den Funktionen.
float choldc(int n, float a[n][n],float p[n]) { void nrerror(char error_text[]); int i,j,k; float sum; for (i=0;i<n;i++) { for (j=i;j<n;j++) { for (sum=a[i][j],k=i-1;k>=0;k--) sum -= a[i][k]*a[j][k]; if (i == j) { if (sum <= 0.0) nrerror("choldc failed"); p[i]=sqrt(sum); } else a[j][i]=sum/p[i]; } } return 1; } float cholsl(int n, float a[n][n], float p[n], float b[n], float x[n]) { int i,k; float sum; for (i=0;i<n;i++) { for (sum=b[i],k=i-1;k>=0;k--) sum -= a[i][k]*x[k]; x[i]=sum/p[i]; } for (i=n-1;i>=0;i--) { for (sum=x[i],k=i+1;k<n;k++) sum -= a[k][i]*x[k]; x[i]=sum/p[i]; } return 1; }
In cholsl hab ich for
sum=b[i]... k>=0
anstatt k>=1 dann in der zweiten for schleife k<n .
Irgendwas in der main passt aber noch nicht da immer noch nich positiv definit angegeben wird
int main() { int n = 4; float L; float p[n]; int zeile =4; int spalte =4; float a[4][4]={{1, -0.2, 0, 0}, {-0.2, 2, -0.3, 0}, {0, -0.3, 3, -0.4}, {0, 0, -0.4, 4}}; L = choldc(n, a, p); printf(" Untere Dreiecksmatrix L %f \n ", L); return 0; }
-
Martin Subovic schrieb:
Ja ich habe soweit alles geändert dass es passen sollte in den Funktionen.
Dann spiel mal den allerersten Durchlauf per Hand durch
Martin Subovic schrieb:
for (i=0;i<n;i++) { for (j=i;j<n;j++) { Hier ist i=0,j=i also auch 0 for (sum=a[i][j],k=i-1;k>=0;k--) Welchen Wert hat k?
Oh? Warte, da war doch was:
DirkB (in derersten Antwort) schrieb:
Die Indizes vom Array fangen immer bei 0 an.
Von wegen
Martin Subovic schrieb:
Irgendwas in der main passt aber noch nicht da immer noch nich positiv definit angegeben wird
-
Stimmt, also k>=1 belassen? aber das passt auch nicht
for (sum=a[i][j],k=i-1;k>=1;k--) sum -= a[i][k]*a[j][k];
wie könnte man das jetzt besser machen? (k=0;k<=i;k++)
gleiches problem bei der zweiten funktion erste for schleife
Ansonsten dürfte es passen.
wenn k=i-1 und k>=0 dann gibt es eine konflikt für i=0
-
Man könnte ja mal 1 Sekunde investieren und irgendeine Suchmaschine befragen:
Ich habe z.B. gerade http://web.mit.edu/~mkgray/afs/UROP/choldc.c gefunden. Von 1991. Sieht man insbesondere an der Parameterübergabe. Aber der Algorithmus ist offenbar derselbe. Schau dir mal an, wie es dort gelöst wurde.
-
Ja der Algorithmus is sehr ähnlich bzw der selbe.
Das scheint mit eingängig nun.Wie bring ich die aber vernünftig in die main bzw wie soll die main aussehen.
Wenn ich also die Funktionen nehme:#include <stdio.h> #include <math.h> #include <stdlib.h> #include "parameters.h" void choldc( matrix, np, dp ) /* Inputs */ double matrix[NMAT][NMAT]; long np; double dp[NMAT]; { /* Locals */ long i,j,k; /* Dummy variables */ double sum; /* Temp variable */ /********** ** ** ** Begin ** ** ** **********/ for( i=0; i<np; i++ ) { for( j=i; j<np; j++ ) { sum = matrix[i][j]; k = i; while ( --k >= 0 ) sum -= matrix[i][k] * matrix[j][k]; if ( i==j ) { if (sum <= 0.0) { printf("Choldc Failed! Exiting...\n"); exit(1); } else dp[i] = sqrt( sum ); } else matrix[j][i] = sum / dp[i]; } } } #include <stdio.h> #include "parameters.h" void cholsl( matrix, np, dp, b, x) /* Inputs */ double matrix[NMAT][NMAT]; long np; double dp[NMAT]; double b[NMAT]; double x[NMAT]; { /* Locals */ long i,k; /* Dummy variables */ double sum; /* Temp variable */ /********** ** ** ** Begin ** ** ** **********/ for( i=0; i<np; i++ ) { sum = b[i]; k = i; while ( --k >= 0 ) sum -= matrix[i][k] * x[k]; x[i] = sum / dp[i]; } for( i=np-1; i>=0; i-- ) { sum = x[i]; k = i; while ( ++k < np ) sum -= matrix[k][i] * x[k]; x[i] = sum / dp[i]; } }
Dann probier ich die main
int main() { void choldc( matrix, np, dp ) void cholsl( matrix, np, dp, b, x) int np = 4; float L,T; float dp[n]; float a[4][4]={{1, -0.2, 0, 0}, {-0.2, 2, -0.3, 0}, {0, -0.3, 3, -0.4}, {0, 0, -0.4, 4}}; float b[4] = {4,-1,0,0} L = choldc(matrix, np, dp); printf(" Untere Dreiecksmatrix L %f \n ", L); T = cholsl(matrix,np,dp,b,x); printf(" Lösungsvektor T %f \n ", T); return 0;
Hier habe ich Schwierigkeiten die Funktionen in der main anzuwenden und zu printen
-
Martin Subovic schrieb:
Wie bring ich die aber vernünftig in die main bzw wie soll die main aussehen.
Hier habe ich Schwierigkeiten die Funktionen in der main anzuwenden und zu printenFindest du nicht dass man dich hier nun lange genug am Händchen gehalten hat? 38 Beiträge in einem Thread, der um eine simple Funktion mit zweidimensionalem Array handelt? - Echt jetzt?!
Schau dir an wie man eine Funktion aufbaut und was ein Rückgabeparameter ist!
-
Meine Idee war auch eigentlich, dass du nicht den Code 1:1 kopierst, sondern einfach abschaust, wie es dort funktioniert und das auf deinen eigenen Code überträgst. Naja, wie auch immer.