Initial commit and implement data input
This commit is contained in:
231
main.c
Normal file
231
main.c
Normal file
@@ -0,0 +1,231 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#define MAX_MATRIX_SIZE 500
|
||||
#define MAX_MATRIX_IN_FILE_SIZE MAX_MATRIX_SIZE + 2
|
||||
|
||||
typedef struct {
|
||||
int n;
|
||||
double **data;
|
||||
} Matrix;
|
||||
Matrix* createMatrix(void);
|
||||
void freeMatrix(Matrix* matrix);
|
||||
void createMatrixRows(Matrix* matrix, int rows);
|
||||
void printMatrix(Matrix* matrix);
|
||||
|
||||
typedef struct {
|
||||
int n;
|
||||
double *data;
|
||||
} Vector;
|
||||
Vector* createVector(void);
|
||||
void initVector(Vector* vector, int size);
|
||||
void freeVector(Vector* vector);
|
||||
void printVector(Vector* vector);
|
||||
|
||||
typedef enum {
|
||||
JACOBI = 0, GAUSS_SEIDEL = 1
|
||||
} Method;
|
||||
|
||||
bool load(const char* filename, Matrix* A, Vector* b, Vector* x);
|
||||
void solve(Method method, Matrix* A, Vector* b, Vector* x, double e);
|
||||
|
||||
int readMatrixLine(FILE* file, double* matrixLine, int maxCols);
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
Matrix* matrix = createMatrix();
|
||||
Vector* b = createVector();
|
||||
Vector* x = createVector();
|
||||
|
||||
puts("Allocated ram");
|
||||
int returnCode = 0;
|
||||
|
||||
if(argc != 2) {
|
||||
puts("Program should be called with 1 argument specifying the file to load from\n");
|
||||
returnCode = 1;
|
||||
} else {
|
||||
if(load(argv[1], matrix, b, x)) {
|
||||
puts("Data successfully loaded\nMatrix A:");
|
||||
printMatrix(matrix);
|
||||
puts("Vector b:");
|
||||
printVector(b);
|
||||
puts("Vector x:");
|
||||
printVector(x);
|
||||
} else {
|
||||
puts("Failed to load data from file");
|
||||
returnCode = 2;
|
||||
}
|
||||
}
|
||||
|
||||
freeMatrix(matrix);
|
||||
freeVector(b);
|
||||
freeVector(x);
|
||||
|
||||
printf("\nReturning with code %i\n", returnCode);
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
|
||||
bool load(const char* filename, Matrix* matrix, Vector* b, Vector* x) {
|
||||
FILE* file = fopen(filename, "r");
|
||||
if(file == NULL) {
|
||||
printf("Failed to open file \"%s\"\n", filename);
|
||||
return false;
|
||||
} else {
|
||||
double* firstLineBuffer = malloc(sizeof(double) * (MAX_MATRIX_IN_FILE_SIZE));
|
||||
|
||||
int colsInFile = readMatrixLine(file, firstLineBuffer, MAX_MATRIX_IN_FILE_SIZE);
|
||||
|
||||
if(colsInFile == -1) {
|
||||
puts("Unexpected input on line 0");
|
||||
|
||||
free(firstLineBuffer);
|
||||
goto failure;
|
||||
} else if(colsInFile == -2) {
|
||||
printf("Exceeded maximum matrix size of %i\n", MAX_MATRIX_SIZE);
|
||||
|
||||
free(firstLineBuffer);
|
||||
goto failure;
|
||||
} else {
|
||||
// success
|
||||
int cols = colsInFile - 1;
|
||||
initVector(b, cols);
|
||||
initVector(x, cols);
|
||||
|
||||
b->data[0] = firstLineBuffer[cols];
|
||||
createMatrixRows(matrix, cols);
|
||||
matrix->data[0] = firstLineBuffer;
|
||||
|
||||
int colsInLine;
|
||||
for(int i = 1; i < cols; i++) {
|
||||
matrix->data[i] = malloc(sizeof(double) * (colsInFile));
|
||||
colsInLine = readMatrixLine(file, matrix->data[i], colsInFile);
|
||||
if(colsInLine < 0) {
|
||||
if(i == cols - 1) {
|
||||
printf("Optional parameters are being used\n");
|
||||
|
||||
// Matrix is one smaller than assumed
|
||||
cols--;
|
||||
b->n--;
|
||||
x->n--;
|
||||
matrix->n--;
|
||||
free(matrix->data[i]);
|
||||
|
||||
x->data[0] = 0.4;
|
||||
|
||||
// Copy b to x
|
||||
memcpy(x->data, b->data, b->n * sizeof(double));
|
||||
|
||||
// extract b
|
||||
for(int j = 0; j < cols; j++) {
|
||||
b->data[j] = matrix->data[j][cols];
|
||||
}
|
||||
goto success;
|
||||
} else {
|
||||
printf("Line %i contains illegal formatting - please fix!\n", i);
|
||||
goto failure;
|
||||
}
|
||||
} else if(colsInLine != colsInFile) {
|
||||
printf("Illegal line length found in line %i\n", i);
|
||||
goto failure;
|
||||
} else {
|
||||
b->data[i] = matrix->data[i][cols];
|
||||
}
|
||||
}
|
||||
// successful but with no optional parameter
|
||||
|
||||
// initialize vector x with zeros
|
||||
memset(x->data, 0, cols * sizeof(double));
|
||||
|
||||
}
|
||||
}
|
||||
success:
|
||||
fclose(file);
|
||||
return true;
|
||||
|
||||
failure:
|
||||
fclose(file);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int readMatrixLine(FILE* file, double* matrixLine, int maxCols) {
|
||||
char nextChar = 0;
|
||||
int col = 0;
|
||||
double buffer;
|
||||
|
||||
while(true) {
|
||||
if(fscanf(file, "%lf", &buffer) != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
matrixLine[col] = buffer;
|
||||
|
||||
col++;
|
||||
if(col > maxCols) {
|
||||
return -2;
|
||||
}
|
||||
nextChar = fgetc(file);
|
||||
if(nextChar == EOF || nextChar == '\n') break;
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
void solve(Method method, Matrix* A, Vector* b, Vector* x, double e) {
|
||||
|
||||
}
|
||||
|
||||
inline Matrix* createMatrix(void) {
|
||||
Matrix* matrix = malloc(sizeof(Matrix));
|
||||
matrix->n = 0;
|
||||
return matrix;
|
||||
}
|
||||
|
||||
inline void createMatrixRows(Matrix* matrix, int rows) {
|
||||
matrix->n = rows;
|
||||
matrix->data = malloc(sizeof(double*) * rows);
|
||||
}
|
||||
|
||||
inline void freeMatrix(Matrix* matrix) {
|
||||
for(int i = 0; i < matrix->n; i++) {
|
||||
free(matrix->data[i]);
|
||||
}
|
||||
free(matrix->data);
|
||||
free(matrix);
|
||||
}
|
||||
|
||||
void printMatrix(Matrix* matrix) {
|
||||
for(int i = 0; i < matrix->n; i++) {
|
||||
for(int j = 0; j < matrix->n; j++) {
|
||||
printf("%lf, ", matrix->data[i][j]);
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
}
|
||||
|
||||
inline Vector* createVector(void) {
|
||||
Vector* vector = malloc(sizeof(Vector));
|
||||
vector->n = 0;
|
||||
return vector;
|
||||
}
|
||||
|
||||
inline void initVector(Vector* vector, int size) {
|
||||
vector->n = size;
|
||||
vector->data = malloc(sizeof(double) * size);
|
||||
}
|
||||
|
||||
inline void freeVector(Vector* vector) {
|
||||
free(vector->data);
|
||||
free(vector);
|
||||
}
|
||||
|
||||
void printVector(Vector* vector) {
|
||||
for(int i = 0; i < vector->n; i++) {
|
||||
printf("%lf, ", vector->data[i]);
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
Reference in New Issue
Block a user