Finish �

This commit is contained in:
2020-02-15 20:02:41 +01:00
parent 64b44958a0
commit 367021d2d5
4 changed files with 137 additions and 29 deletions

View File

@@ -1,3 +1,3 @@
@echo off @echo off
gcc -Wall -g -std=c99 %1.c -o %1.exe gcc -Wall -g -lm -std=c99 main.c -o main.exe
@echo on @echo on

1
build.sh Normal file
View File

@@ -0,0 +1 @@
gcc -Wall -g -std=c99 -lm main.c -o main

BIN
main Normal file

Binary file not shown.

163
main.c
View File

@@ -41,18 +41,20 @@ void flushStdin(void);
bool load(const char* filename, Matrix* A, Vector* b, Vector* x); bool load(const char* filename, Matrix* A, Vector* b, Vector* x);
Vector* solve(Method method, Matrix* A, Vector* b, Vector* x, double e); Vector* solve(Method method, Matrix* A, Vector* b, Vector* x, double e);
Vector* solveJacobi(Matrix* A, Vector* b, Vector* x, double e);
Vector* solveGaussSeidel(Matrix* A, Vector* b, Vector* x, double e);
int readMatrixLine(FILE* file, double* matrixLine, int maxCols); int readMatrixLine(FILE* file, double* matrixLine, int maxCols);
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
char filePath[MAX_FILE_PATH_LENGTH]; char filePath[MAX_FILE_PATH_LENGTH];
if(argc >= 2) { if(argc >= 2) { // If arguments specified
strncpy(filePath, argv[1], MAX_FILE_PATH_LENGTH); strncpy(filePath, argv[1], MAX_FILE_PATH_LENGTH); // use first argument as filePath
} else { } else { // Otherwise read from stdin
puts("Please enter the path of the file you'd like to open"); puts("Please enter the path of the file you'd like to open");
int result = scanf("%" STR(MAX_FILE_PATH_LENGTH) "[^\n]", filePath); int result = scanf("%" STR(MAX_FILE_PATH_LENGTH) "[^\n]", filePath);
if(result == EOF || result == 0 || filePath[0] == 0) { if(result == EOF || result == 0 || filePath[0] == 0) { // If an error occured or no text has been entered -> exit
return 0; return 0;
} }
if(result != 1) { if(result != 1) {
@@ -72,12 +74,12 @@ int main(int argc, char* argv[]) {
if(load(filePath, matrix, b, x)) { if(load(filePath, matrix, b, x)) {
// Debug outputs // Debug outputs
//puts("Data successfully loaded\nMatrix A:"); puts("Data successfully loaded\nMatrix A:");
//printMatrix(matrix); printMatrix(matrix);
//puts("Vector b:"); puts("Vector b:");
//printVector(b); printVector(b);
//puts("Vector x:"); puts("Vector x:");
//printVector(x); printVector(x);
puts("Please enter the algorithm to use:\n\t0: Jacobi (default)\n\t1: Gauss-Seidel"); puts("Please enter the algorithm to use:\n\t0: Jacobi (default)\n\t1: Gauss-Seidel");
int algorithm; int algorithm;
@@ -87,15 +89,16 @@ int main(int argc, char* argv[]) {
if(algorithm == EOF) { if(algorithm == EOF) {
goto end; goto end;
} }
if(algorithm == '0' || algorithm == '1') {
algorithm -= '0';
break;
}
if(algorithm == '\n' || algorithm == 0) { if(algorithm == '\n' || algorithm == 0) {
puts("Defaulting to Jacobi"); puts("Defaulting to Jacobi");
algorithm = 0; algorithm = 0;
break; break;
} }
flushStdin();
if(algorithm == '0' || algorithm == '1') {
algorithm -= '0';
break;
}
fputs("Please enter 0, 1 or leave empty to exit!\n", stderr); fputs("Please enter 0, 1 or leave empty to exit!\n", stderr);
} }
@@ -107,15 +110,52 @@ int main(int argc, char* argv[]) {
if(scan == EOF) { if(scan == EOF) {
goto end; goto end;
} }
flushStdin();
if(scan == 1) { if(scan == 1) {
break; break;
} }
flushStdin();
fputs("Invalid input - please enter a valid floating point number!\n", stderr); fputs("Invalid input - please enter a valid floating point number!\n", stderr);
} }
Vector* result = solve(algorithm, matrix, b, x, e); Vector* result = solve(algorithm, matrix, b, x, e);
free(result); if(result == NULL) {
fputs("Failed to run the algorithm!\n", stderr);
returnCode = 100;
} else {
int input;
while(true) {
puts("Choose what to output:\n\t0: Only the final result (default)\n\t1: All the iteration steps");
input = getchar();
if(input == '\n') {
puts("Defaulting to final result");
input = 0;
} else {
flushStdin();
}
if(input == 0 || input == '\n' || input == '0') {
puts("Showing final result:");
int i = 0;
while(result[++i].n != 0 && i < MAX_ITERATION_STEPS)
free(result[i-1].data);
printVector(&result[i-1]);
free(result[i-1].data);
break;
}
if(input == '1') {
puts("Showing all iterations:");
for(int i = 0; i < MAX_ITERATION_STEPS; i++) {
printVector(&result[i]);
if(result[i].n == 0) {
break;
}
free(result[i].data);
}
break;
}
fputs("Please enter 0, 1 or leave empty!", stderr);
};
free(result);
}
break; break;
} else { } else {
fputs("Failed to load data from file.\nEnter new file path or leave empty to exit.\n", stderr); fputs("Failed to load data from file.\nEnter new file path or leave empty to exit.\n", stderr);
@@ -253,21 +293,88 @@ void flushStdin(void) {
} }
Vector* solve(Method method, Matrix* A, Vector* b, Vector* x, double e) { Vector* solve(Method method, Matrix* A, Vector* b, Vector* x, double e) {
Vector* vectors = malloc(sizeof(Vector) * (MAX_ITERATION_STEPS + 1)); if(method == JACOBI) {
return solveJacobi(A, b, x, e);
} else {
return solveGaussSeidel(A, b, x, e);
}
}
// MAX_ITERATION_STEPS enthält die maximal zulässige Anzahl an Iterationsschritten (100) Vector* solveJacobi(Matrix* A, Vector* b, Vector* x, double e) {
// Die einzelnen Vektoren müssen noch mit initVector initialisiert werden Vector* history = malloc(sizeof(Vector) * (MAX_ITERATION_STEPS + 1));
initVector(history, x->n);
memcpy(history[0].data, b->data, b->n * sizeof(double));
double delta;
int i, j, steps = 1;
double value;
double* data;
// HIER kommt der Code hin ;) do {
delta = 0.;
// on success initVector(&history[steps], x->n);
// Sei x die Anzahl der durchgeführten Iterationschritte. Dann setzt vectors[x+1].n = 0. Damit weiß das folgende Programm wie viele Schritte getätigt wurden. data = history[steps].data;
return vectors;
// on failure for(i = 0; i < x->n; i++) {
free(vectors); value = b->data[i];
return NULL; for(j = 0; j < x->n; j++) {
if(i != j)
value -= history[steps-1].data[i] * A->data[i][j];
}
data[i] = value / A->data[i][i];
delta = fmax(delta, fabs(data[i] - history[steps - 1].data[i]));
}
steps++;
} while(delta > e && steps < MAX_ITERATION_STEPS);
if(steps < MAX_ITERATION_STEPS) {
history[steps].n = 0;
}
return history;
}
Vector* solveGaussSeidel(Matrix* A, Vector* b, Vector* x, double e) {
Vector* history = malloc(sizeof(Vector) * (MAX_ITERATION_STEPS + 1));
initVector(history, x->n);
memcpy(history[0].data, b->data, x->n * sizeof(double));
double delta;
int i, k, steps = 1;
double* data;
double value;
do {
delta = 0.;
initVector(&history[steps], x->n);
data = history[steps].data;
for(k = 0; k < x->n; k++) {
value = b->data[k];
for(i = 0; i < k; i++) {
value -= A->data[k][i] * data[i];
}
for(i = k + 1; i < x->n; i++) {
value -= A->data[k][i] * history[steps - 1].data[i];
}
data[k] = value / A->data[k][k];
delta = fmax(delta, fabs(data[k] - history[steps - 1].data[k]));
}
steps++;
} while(delta > e && steps < MAX_ITERATION_STEPS);
if(steps < MAX_ITERATION_STEPS) {
history[steps].n = 0;
}
return history;
} }
inline Matrix* createMatrix(void) { inline Matrix* createMatrix(void) {
@@ -292,7 +399,7 @@ inline void freeMatrix(Matrix* matrix) {
void printMatrix(Matrix* matrix) { void printMatrix(Matrix* matrix) {
for(int i = 0; i < matrix->n; i++) { for(int i = 0; i < matrix->n; i++) {
for(int j = 0; j < matrix->n; j++) { for(int j = 0; j < matrix->n; j++) {
printf("%lf, ", matrix->data[i][j]); printf("%le, ", matrix->data[i][j]);
} }
puts(""); puts("");
} }
@@ -316,7 +423,7 @@ inline void freeVector(Vector* vector) {
void printVector(Vector* vector) { void printVector(Vector* vector) {
for(int i = 0; i < vector->n; i++) { for(int i = 0; i < vector->n; i++) {
printf("%lf, ", vector->data[i]); printf("%le, ", vector->data[i]);
} }
puts(""); puts("");
} }