Flag wert Ausgeben in do while Schleife
-
Hallo liebe Forum Member,
Ich habe ein relativ leichtes Problem (denk ich mal) aber komm momentan überhaupt nicht darauf (kein Schlaf)
Ich habe einen Code, Broyden Methode um nicht lineares Gleichungssystem zu lösen.
Der Code compiliert auch wunderbar. Nun will ich aber Flag = 1 falls bei meiner do while Schleifewhile (U > 1e-10 && count < 50);
Die beschränkung auf 50 nicht ausreicht und Flag = 0 wenn der Durchlauf erfolgreich ist.
Leider stehe ich total auf dem Schlauch. Hat jemand eine Idee und kann mir helfen?
Do while Schleife startet Zeile 40 und geht bis 100.Vielen Dank soweit.
Horn#include <math.h> #include <stdlib.h> #include "vorrueckwaertsub.c" #include "lrmp.c" /* * F Function * n Dimension * x Argument [n] (input/output) * f F(x) [n] (input/output) * W Negative inverse Jacob Approximation [n^2] (input/output) * * * Broyden: * xnew = x + W f * fnew = F(xnew) * Wnew = W - (W fnew) (s^T W) / (s^T W (fnew - f)), * where * s = xnew - x (= Wf) */ void broyden_update(void (*F)(double*, double*), int n, double* x, double* f, double** W ) { double* fnew = calloc(n, sizeof(double)); int *p = calloc(n, sizeof(int)); double* xnew = calloc(n, sizeof(double)); double* d = calloc(n, sizeof(double)); /* double** w = calloc(2, sizeof(double*)); for (int i = 0; i < 2; i++) { w[i] = calloc(2, sizeof(double)); } */ // double* stw = &fnew[n * 2]; // double* wf1 = &fnew[n * 3]; double denom, U; int i, j, count=0; do { if (count == 0) { F(x, f); } else { for(i=0; i<n;++i){ d[i]=-f[i]; } Solve ( n, W, d, p); for (j = 0; j < n; ++j) { xnew[j] = x[j]+d[j]; } F(xnew, fnew); /* for (j = 0, wij = W; j < n; ++j) { double sj = s[j]; for (i = 0; i < n; ++i, ++wij) stw[i] += sj * wij[0]; } */ for (i = 0, denom = 0.0; i < n; ++i) denom += d[i] * d[i]; /*for (j = 0, wij = W; j < n; ++j) wf1[j] += s[j] * fnew[j]; */ for (j = 0; j < n; ++j) { fnew[j] /= denom; for (i = 0; i < n; ++i) W[i][j] += fnew[i] * d[j]; } for (i = 0; i < n; ++i) x[i] = xnew[i]; } for (i = 0, U = 0.0; i < n; ++i) U += d[i] * d[i]; U = sqrt(U); FILE *h = fopen("datei.txt", "w"); if (!h) { /* FEHLER */ } fprintf(h, " k | fx | ||x^k+1-x^k|| | K-Ord | \n"); fprintf(h, "--------------------------------------------------------------------------------\n"); fprintf(h, " %d | %f | %f | %f | \n", count, f[i], U, 0.5); fflush(h); fclose(h); // printf(" %d: %.3g\n", count, tol); count++; } while (U > 1e-10 && count < 50); } #include <math.h> #include <stdio.h> void F(double* x, double* f) { f[0]=((x[0])+3)*(pow(x[1], 3)-7.0)+18; f[1]=sin(x[1]*exp(x[0])-1); } int main() { //double c = 0.01; int n = 2; double x[2] = { -0.5,1.4}; //double W[n][n]; double* f= calloc(n, sizeof(double)); double** W = calloc(2, sizeof(double*)); for (int i = 0; i < 2; i++) { W[i] = calloc(2, sizeof(double)); } // int i; W[0][0]= pow(x[1], 3)-7; W[0][1]=(3*x[0]+3)*x[1]; W[1][0]= x[1]* exp(x[0])*cos(x[1] *(exp(x[0])-1)); W[1][1]= (exp(x[0])-1)*cos(x[1] *(exp(x[0])-1)); broyden_update(F, n, x, f, W); /* for (i = 0; i < n * n; ++i) W[i] = 0.0; for (i = 0; i < n; ++i) W[i * n + i] = 1.0; */ return 0; }
-
Du möchtest also in
main
feststellen, ob die Berechnung ok ist?Dazu nimmt man meist den Rückgabewert einer Funktion. Der darf dann natürlich nicht vom Typ
void
sein.Ein return !(count < 50) nach Zeile 100 reicht dann schon aus.
In
main
musst du den Wert dann noch auswerten.
-
Vielen Dank, das hilft mir.
Was meinst du mit auswerten in der main?
Einfach printen? also etwas in der Formprintf("Erfolgreicher Durchlauf bei 0: %d", !(count < 50));
-
Vorweg:
Du hast ganz vielcalloc
aber keinfree
. -> Das gibt Speicherlecks.
Das sind grobe Fehler. Die musst du beheben.Hornschild schrieb:
Was meinst du mit auswerten in der main?
Dass
main
eine Info bekommt, dass die Schleife in broyden_update nicht ausgereicht hat,Hornschild schrieb:
Einfach printen? also etwas in der Form
printf("Erfolgreicher Durchlauf bei 0: %d", !(count < 50));
1. ist count in
main
nicht bekannt, da es eine lokale Variable in broyden_update ist.
1a. denk gar nicht erst über globale Variablen nach.2. ist !(count < 50) ein logischer Ausdruck. Der ergibt nur die Werte 0 oder 1.
Also die Werte, die du Flag geben möchtest.Du musst dir also einen Weg ausdenken, wie du diese Information aus broyden_update nach
main
bekommst.
(Tipp: wie bekommst du den Wert aussgrt
zurück oder die Speicheradresse beicallac
?)Du kannst auch einfach
printf("Erfolgreicher Durchlauf bei 0: %d", count);
in broyden_update machen.
Solch eine Funktion sollte aber nicht mit dem Nutzer kommunizieren und du hattest auch nach Flag gefragt.
-
Ach ja, ich habe die free's vergessen danke.
Könnte ich dazu dann etwa so vorgehen:int flag flag = broyden_update if (flag = 0) printf(" Erfolgreicher Durchlauf bei 0: %d \n",flag); else printf("flag = 1 \n");
-
Hornschild schrieb:
int flag flag = broyden_update // dasz das syntaktisch falsch ist, ist klar, oder? if (flag = 0) // das ist eine Zuweisung und immer false printf(" Erfolgreicher Durchlauf bei 0: %d \n",flag); else printf("flag = 1 \n");
-
Ja dagehört noch broyden_update(wert1,wert2,etc) rein.
Ich weiß aber jetzt leider nicht weiter wie ich das sonst umsetzen soll.
Geht das über die Zuweisung des Rückgabewerts?
-
Hornschild schrieb:
Geht das über die Zuweisung des Rückgabewerts?
Ja
-
Mh okay, leider scheitere ich hieran aber noch.
Ich weise also flag = broyden_update (wert1,...) zu.
Dann aber weiß ich nicht weiter wie ich dann auf flag =1 wenn es mehr als 50 count sind oder flag = 0 wenn es nicht abbricht komme.
-
Mit if und meiner ersten Antwort.
-
Ich steh auf dem Schlauch.
Ich habe also den return Wert mit !count...
Dann nehme ich flag = broyden_update(...)
Jetzt komm ich aber nicht darauf wie ich die if bedingung gestalten muss.
count ist ja eben eine lokale Variable und nutzt uns in der main nichts.
Wie kann man die if Bedingung gestalten?
-
Hornschild schrieb:
Jetzt komm ich aber nicht darauf wie ich die if bedingung gestalten muss.
Hattest du doch schon (fast)
if (flag == 0) // Achtung hier ist ein == printf("Erfolgreicher Durchlauf:\n"); else printf("flag = 1 \n");
Hornschild schrieb:
count ist ja eben eine lokale Variable und nutzt uns in der main nichts.
Dafür hast du ja den Rückgabewert, bzw. flag.
Du kannst natürlich auch count zurückgeben. (Dann sollte
main
halt wissen, dass 50 die Abbruchbedingung ist)