Matrix in Funktion übergeben.



  • Es soll natürlich
    a[0][0] bis a[3][3] gehen

    ich habe zeile und spalte initialisiert und dann die matrix definiert

    zeile 16: error: expected expression before ']' token
    ich weiß leider nicht was er hier will.



  • Martin Subovic schrieb:

    Es soll natürlich
    a[0][0] bis a[3][3] gehen

    ich habe zeile und spalte initialisiert und dann die matrix definiert

    Die Initialisierung bei der Definition aus deinem Eröffnungspost war vollkommen in Ordnung.

    Martin Subovic schrieb:

    zeile 16: error: expected expression before ']' token
    ich weiß leider nicht was er hier will.

    Nein, der Compiler weiß nicht, was du da willst!
    Was willst du da?

    p ist ein float (Zeile 2). [] werden aber bei Arrays/Zeigern verwendet um auf einzelne Elemente des Arrays zuzugreifen.

    Deine Funktion erwartet da einen Zeiger/Adresse. Das ist p aber nicht.

    Und meine Definiton von choldc (mit dem VLA) funktioniert nur, wenn n vor dem Array angegeben wird.

    Du solltest nochmal den ganzen aktuellen Code zeigen.



  • ja sollte row and column sein.
    aber Zeile/Spalte ist wohl bessere Wahl



  • Also die Funktion

    void choldc (int n, float a[n][n] ,float p[])
    {
        void nrerror(char error_text[]);
        int i,j,k;
        float sum;
    
        for (i=0;i<=n-1;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];
            }
        }
    }
    

    Dann main
    [code]
    int main() {

    float p,L;
    int n=4;
    float a[n][n]=
    {3,-2,0,0
    -2,3,6,0
    0,6,3,-2
    0,0,-2,3
    };

    float b [n+1]= {4,-1,0,0};

    L = choldc(a, n, p[]);
    printf(" Untere Dreiecksmatrix L %\n ", L);

    return 0;
    }
    [code]

    Also ich will die Funktion choldc mit der Matrix füttern.
    p ist ja eigentlich ein Array von der Funktion in dem ich Diagonalelemente speichere.
    Ich denke mal ich sollte p nicht als float p geben im code



  • Verzeihung,
    Main

    Dann main

    int main() {
    
    float p,L;
    int n=4;
    float a[n][n]=
    {3,-2,0,0
    -2,3,6,0
    0,6,3,-2
    0,0,-2,3
    };
    
    float b [n+1]= {4,-1,0,0};
    
    L = choldc(a, n, p[]);
    printf(" Untere Dreiecksmatrix L %\n ", L);
    
    return 0;
    }
    

    Also ich will die Funktion choldc mit der Matrix füttern.
    p ist ja eigentlich ein Array von der Funktion in dem ich Diagonalelemente speichere.
    Ich denke mal ich sollte p nicht als float p geben im code



  • Zur Funktion:
    Zeile 1: Was bedeutet das void am Anfang?
    Zeile 3: Funktionen werder eher nicht innerhalb von anderen Funktionen deklariert oder definiert. Das passiert außerhalb.
    Zeile 7: statt i<=n-1 schreibt man in C i<n. Dann sieht man gleich, da man (meist) bei 0 anfängt, dass es n Durchläufe sind.

    Zu main:
    Zeile 7: Du solltest die Zeilen nochmal Klammern {{3,-2,0,0},{-2,3,6,0}, ...
    Zeile 13: warum hat p ein Elment mehr als a Diagonalelement?
    Zeile 17: muss eine Warnung geben. Das hat was mit Zeile 1 der Funktion zu tun:
    Zeile 18: printf muss über den Formatstring wissen, welcher Art die weitern Paramter sind. Ein einzelnes % reicht da nicht.



  • ich weiß jetzt nicht, was du da machst, aber

    L = choldc(a, n, p[]);
    

    was hast du da eigentlich mit dem p vor? das ist doch komplett (in jeder hinsicht) falsch.
    ich benutze aus "bequemlichkeitsgründen" eigentlich immer pauschal (einfach-, doppel-, dreifach-, n-fach-) zeiger, aber wenn du arrays übergeben willst, machst du das z.b. so

    void funk(float array1d[], float array2d[2][], float array3d[3][2][])
    {
    }
    
    int main()
    {
    float array1d[1];
    float array2d[2][1];
    float array3d[3][2][1];
    
    funk(array1d, array2d, array3d);
    }
    

    die angabe der größen ist deshalb erforderlich, weil der compiler (warum auch immer) bei array2d und array3d nicht erkennen kann, wie groß die arrays eigentlich sind, das heißt, als faustregel kannst du dir merken, dass arrays eine vorher festgelegte und unveränderliche größe haben und du ansonsten lieber zeiger mit malloc verwenden und die größe des reservierten speichers dann an die funktion übergeben solltest.

    außerdem wird das programm nicht langsamer wenn du dir angewöhnst, namen wie

    float meine_matrix_5_mal_5[5][5];
    int breite_meiner_matrix;
    int hoehe_meiner_matrix;
    long long int maximale_laenge_der_namen_meiner_variablen_um_die_uebersichtlichkeit_zu_wahren;
    

    zu verwenden. du hast da zwar mehr schreibarbeit, aber man muss nicht ewig rätseln, was die variable bedeuten soll.



  • @wade

    Das P[]kommt von der cholesky zerlegung (erste Funktion) und speichert die Diagonaleinträge. Es wird also in der Funktion gebraucht.
    Bei deinem Beispiel sind die Zahlen in den Arrays nur beispiele? ebenso wie die [1] die du dann als größe vorgibst?

    @DirkB
    Ich habe die nrerror funktion außerhalb definiert und verwende sie jetzt nur in dieser Funktion

    Ich nehme an du meinst b[]. das ist ein Tippfehler. Es ist b[n]

    also %f statt % in der printfunktion (zeile 18)

    Ich sehe leider nicht warum dass eine Warnung geben muss.



  • Ps:
    es sollte float statt void sein da void keinen Rückgabewert liefert. dies ist als Warnung bei mir im Compiler



  • Wade1234 schrieb:

    void funk(float array1d[], float array2d[2][], float array3d[3][2][])
    

    Das ist natürlich Quatsch. Hebe dir dein Helfersyndrom für andere Zwecke auf, aber nicht in einem C Forum.



  • Martin Subovic schrieb:

    Bei deinem Beispiel sind die Zahlen in den Arrays nur beispiele?

    ja die zahlen sind willkürlich gewählt, trotzdem musst du bei übergabe von mehrdimensionalen arrays alle bis auf die letzte dimension in der parameterliste angeben.



  • Wade1234 schrieb:

    Martin Subovic schrieb:

    Bei deinem Beispiel sind die Zahlen in den Arrays nur beispiele?

    ja die zahlen sind willkürlich gewählt, trotzdem musst du bei übergabe von mehrdimensionalen arrays alle bis auf die letzte dimension in der parameterliste angeben.

    Das ist FALSCH!
    FALSCH!
    FALSCH!

    Du kannst die erste Dimension (vom Bezeichner aus gesehen) weglassen.

    Dann bist du aber immer noch in den anderen Dimension begrenzt.

    Das kannst du mit VLA umgehen.
    Als Parameter bei Funktion sind VLA genau richtig. (Wenn du variable Arrays brauchst)



  • ich dachte immer, variable arrays wären so unglaublich schlecht, nur was für deppen, ewig langsam, etc.? 🙄

    ja die erste dimension ist doch die ganz rechts und bei meinem lesestil dann eben die letzte. 😕


  • Mod

    Wade1234 schrieb:

    ich dachte immer, variable arrays wären so unglaublich schlecht, nur was für deppen, ewig langsam, etc.? 🙄

    Du musst verstehen, warum, dann verstehst du auch, warum die Art und Weise, wie VLAs hier meistens benutzt werden (so in dieser Art:

    puts("Wie viele Werte wollen Sie eingeben?");
    scanf("%i", anzahl_werte);
    double werte[anzahl_werte];
    

    ) der absolute Deppenschrott sind, der dem Programmierer die Kontrolle über seine eigenen Datenstrukturen entzieht, wohingegen das, was DirkB hier zeigt, das ist, wofür VLAs vorgesehen und perfekt geeignet sind.

    Von 'langsam' hat gewiss nie jemand etwas gesagt, der irgendeine Ahnung vom Thema hat.

    ja die erste dimension ist doch die ganz rechts und bei meinem lesestil dann eben die letzte. 😕

    Dann sprich lieber von 'innen' und 'außen'. Kommt es dir denn nicht konfus vor, wenn dein Verständnis von 'erste' die 'letzte' ist?



  • Wade1234 schrieb:

    ich dachte immer, variable arrays wären so unglaublich schlecht, nur was für deppen, ewig langsam, etc.? 🙄

    Es gibt das schon einen Unterschied, ob du die als Funktionsparamter nutzt oder das Array damit definierst.

    Wade1234 schrieb:

    ja die erste dimension ist doch die ganz rechts und bei meinem lesestil dann eben die letzte. 😕

    Um von Array[0][0] nach Array[1][0] zu kommen, musst der Compiler die Anzahl der Elemente beim rechten Indedx wissen.
    (Die Reihenfolge der Elemente im Speicher ist vom Standard vorgegeben)

    Ein 2D-Array ist ein Array von einem Array

    cdecl.org schrieb:

    char feld[5][3];

    declare feld as array 5 of array 3 of char

    https://cdecl.org/?q=char+feld%5B5%5D%5B3%5D%3B



  • Hier mal mein Code soweit. Er läuft aber spuckt immer die error Meldung aus.

    void nrerror(char error_text[])
    /* Numerical Recipes standard error handler */
    {
    	fprintf(stderr,"Numerical Recipes run-time error...\n");
    	fprintf(stderr,"%s\n",error_text);
    	fprintf(stderr,"...now exiting to system...\n");
    	exit(1);
    }
    
    float choldc(float **a, int n ,float p[])
    {
    	void nrerror(char error_text[]);
    	int i,j,k;
    	float sum;
    
    	for (i=1;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(float **a, int n, float p[], float b[], float x[])
    {
    	int i,k;
    	float sum;
    
    	for (i=1;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;i>=1;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;
        int *p;
        int zeile =4;
        int spalte =4;
        float a[zeile][spalte];
    
    a[1][1]=3;   a[1][2]= -2; a[1][3]=0;     a[1][4]=0;
    a[2][1]= -2; a[2][2]=3;   a[2][3]= 6;    a[2][4]=0;
    a[3][1]=0;   a[3][2]=6;   a[3][3]=3;     a[3][4]= -2;
    a[4][1]=0;   a[4][2]=0;   a[4][3]= -2;   a[4][4]=3;
    
        L = choldc(a, n, p);
        printf(" Untere Dreiecksmatrix L %\n ", L);
    
        return 0;
    
    }
    

    Okay da die matrix nicht positiv definit ist das klar.
    Für

    int main() {
    
        int n = 4;
        float L;
        int *p;
        int zeile =4;
        int spalte =4;
        float a[zeile][spalte];
    
    a[1][1]=1;   a[1][2]= -0.2; a[1][3]=0;     a[1][4]=0;
    a[2][1]= -0.2; a[2][2]=2;   a[2][3]= -0.3;    a[2][4]=0;
    a[3][1]=0;   a[3][2]= -0.3;   a[3][3]=3;     a[3][4]= -0.4;
    a[4][1]=0;   a[4][2]=0;   a[4][3]= -0.4;   a[4][4]=4;
    
        L = choldc(a, n, p);
        printf(" Untere Dreiecksmatrix L %\n ", L);
    
        return 0;
    

    Aber gibts auch die Fehlermeldung und diese matrix ist positiv definit



  • Martin Subovic schrieb:

    Hier mal mein Code soweit. Er läuft aber spuckt immer die error Meldung aus.

    Was unterscheidet diesen Code vom Eröffnungspost?
    Da sind noch alle Fehler drin.



  • Nichts da es ein copy paste Fehler war. Entschuldigung

    void nrerror(char error_text[])
    /* Numerical Recipes standard error handler */
    {
    	fprintf(stderr,"Numerical Recipes run-time error...\n");
    	fprintf(stderr,"%s\n",error_text);
    	fprintf(stderr,"...now exiting to system...\n");
    	exit(1);
    }
    
    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;i>=1;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[zeile][spalte];
    
    a[1][1]=3;   a[1][2]= -2; a[1][3]=0;     a[1][4]=0;
    a[2][1]= -2; a[2][2]=3;   a[2][3]= 6;    a[2][4]=0;
    a[3][1]=0;   a[3][2]=6;   a[3][3]=3;     a[3][4]= -2;
    a[4][1]=0;   a[4][2]=0;   a[4][3]= -2;   a[4][4]=3;
    
        L = choldc(n, a, p);
        printf(" Untere Dreiecksmatrix L %f \n ", L);
    
        return 0;
    
    }
    


  • main ist immer noch falsch.

    Wenn du ein Array als feld[4] definierst, dann darf als Index (beim Zugriff) nie die 4 (oder ein größerer Wert) auftauchen.
    https://youtu.be/FFAbhi6xnCo?t=1m30s

    Diesen Fehler machst du auch in den Funktionen (Schleifengrenzen)

    Du kannst dir ja mal zum Debuggen die Elemente, die gerade bearbeitet werden, mit den Indizes ausgeben.
    Das geht mit printf (ist etwas Schreibarbeit) oder mit dem Debugger (dafür ist der da).



  • 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


Anmelden zum Antworten