Compare commits
1 Commits
SolveFucti
...
backup-fin
| Author | SHA1 | Date | |
|---|---|---|---|
| 367021d2d5 |
@@ -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
|
||||||
|
|||||||
202
main.c
202
main.c
@@ -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("%s" 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);
|
||||||
|
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);
|
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,78 +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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector* solveJacobi(Matrix* A, Vector* b, Vector* x, double e) {
|
||||||
|
Vector* history = malloc(sizeof(Vector) * (MAX_ITERATION_STEPS + 1));
|
||||||
|
|
||||||
|
initVector(history, x->n);
|
||||||
initVector(&vectors[0], b->n);
|
memcpy(history[0].data, b->data, b->n * sizeof(double));
|
||||||
memcpy(vectors[0].data, x->data, b->n * sizeof(double));
|
double delta;
|
||||||
|
int i, j, steps = 1;
|
||||||
int vectorCount = 1;
|
double value;
|
||||||
double temp;
|
double* data;
|
||||||
double delta = 0.0;
|
|
||||||
|
|
||||||
if (method == 0){
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
delta= 0.0;
|
delta = 0.;
|
||||||
initVector(&vectors[vectorCount],b->n);
|
|
||||||
for(int i=0; i<b->n; i++){
|
|
||||||
temp=0.0;
|
|
||||||
for(int j=0; j<b->n; j++){
|
|
||||||
if(j!=i){
|
|
||||||
temp= temp+A->data[i][j]*vectors[vectorCount-1].data[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vectors[vectorCount].data[i]=(b->data[i]-temp)/A->data[i][i];
|
|
||||||
delta=fmax(fabs(vectors[vectorCount].data[i]-vectors[vectorCount-1].data[i]),delta);
|
|
||||||
}
|
|
||||||
printVector(&vectors[vectorCount]);
|
|
||||||
vectorCount++;
|
|
||||||
} while (delta > e && vectorCount < MAX_ITERATION_STEPS);
|
|
||||||
|
|
||||||
|
initVector(&history[steps], x->n);
|
||||||
|
data = history[steps].data;
|
||||||
|
|
||||||
|
for(i = 0; i < x->n; i++) {
|
||||||
|
value = b->data[i];
|
||||||
|
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]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (method ==1){
|
steps++;
|
||||||
|
} while(delta > e && steps < MAX_ITERATION_STEPS);
|
||||||
|
|
||||||
|
if(steps < MAX_ITERATION_STEPS) {
|
||||||
do{
|
history[steps].n = 0;
|
||||||
delta = 0.0;
|
|
||||||
if (vectorCount==1){
|
|
||||||
initVector(&vectors[vectorCount], b->n);
|
|
||||||
memcpy(vectors[vectorCount].data, x->data, b->n * sizeof(double));}
|
|
||||||
else {
|
|
||||||
initVector(&vectors[vectorCount], b->n);
|
|
||||||
memcpy(vectors[vectorCount].data, vectors[vectorCount-1].data, b->n * sizeof(double));}
|
|
||||||
|
|
||||||
for (int i = 0; i<b->n; i++){
|
|
||||||
temp=0.0;
|
|
||||||
for (int j=0; j<b->n; j++){
|
|
||||||
if (j!=i){
|
|
||||||
temp = temp + A->data[i][j]*vectors[vectorCount].data[j];
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vectors[vectorCount].data[i] = (b->data[i]-temp)/A->data[i][i];
|
|
||||||
delta=fmax(fabs(vectors[vectorCount].data[i]-vectors[vectorCount-1].data[i]),delta);
|
|
||||||
|
|
||||||
}
|
|
||||||
printVector(&vectors[vectorCount]);
|
|
||||||
vectorCount++;
|
|
||||||
}while(delta > e && vectorCount < MAX_ITERATION_STEPS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MAX_ITERATION_STEPS enthält die maximal zulässige Anzahl an Iterationsschritten (100)
|
return history;
|
||||||
// Die einzelnen Vektoren müssen noch mit initVector initialisiert werden
|
}
|
||||||
|
|
||||||
|
Vector* solveGaussSeidel(Matrix* A, Vector* b, Vector* x, double e) {
|
||||||
|
Vector* history = malloc(sizeof(Vector) * (MAX_ITERATION_STEPS + 1));
|
||||||
|
|
||||||
// HIER kommt der Code hin ;)
|
initVector(history, x->n);
|
||||||
|
memcpy(history[0].data, b->data, x->n * sizeof(double));
|
||||||
|
|
||||||
// on success
|
double delta;
|
||||||
// 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.
|
int i, k, steps = 1;
|
||||||
vectors[vectorCount].n=0;
|
double* data;
|
||||||
|
double value;
|
||||||
|
|
||||||
return vectors;
|
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) {
|
||||||
@@ -349,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("");
|
||||||
}
|
}
|
||||||
@@ -373,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("");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user