diff --git a/Makefile b/Makefile index 69a2d55..363fb2b 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CC = gcc CFLAGS = -Wall -g -Wshadow -pedantic LDFLAGS = -lm -OBJFILES = main.o functions.o determinant.o inverse.o read.o calculate.o +OBJFILES = main.o processing.o matrix.o TARGET = freelab all: $(TARGET) diff --git a/calculate.c b/calculate.c deleted file mode 100644 index e430d64..0000000 --- a/calculate.c +++ /dev/null @@ -1,97 +0,0 @@ -#include "functions.h" - -void calculate(struct m *matrix, int nop, int id, char *op){ - - int i; - - for(i=0; i < nop; i++){ - /*Transpose the matrices */ - if(op[i] == 't' || op[i] == 'T') - transpose(&matrix[0]); - - else if(op[i]=='d'){ - matrix[i].data[0] = determinant(matrix[i].row, &matrix[i]); - matrix[i].row = 1; - matrix[i].col = 1; - } - - if(op[i] == 'i'){ - if(matrix[0].row != matrix[0].col) - printf("Error: You can only calculate the inverse of square matrices\n"); - inverse(matrix[0].row, &matrix[0]); - } - } - - for(i=0; i <= nop; i+=2) - { - if (op[i] == '+' && op[i+1] == '?'){ - struct m tmp = add(&matrix[i],&matrix[i+1],+1); - free(matrix[i+1].data); - matrix[i+1] = tmp; - break; - } - - else if(op[i] == '*' && op[i+1] == '?'){ - if (matrix[i].row == 1 && matrix[i].col == 1) - scalar_product(matrix[i].data[0], &matrix[i+1]); //Multiplication of Scalar per matrix - else{ - struct m tmp = multiply(&matrix[i], &matrix[i+1]); - free(matrix[i+1].data); - matrix[i+1] = tmp; - } - break; - } - - else if (op[i] == '-' && op[i+1] == '?'){ - struct m tmp = add(&matrix[i],&matrix[i+1],-1); - free(matrix[i+1].data); - matrix[i+1] = tmp; - break; - } - - else if(op[i] == '*' && op[i+1] == '+'){ - if (matrix[i].row == 1 && matrix[i].col == 1) - scalar_product(matrix[i].data[0],&matrix[i+1]); //Multiplication of Scalar per matrix - else{ - matrix[i+1] = multiply(&matrix[i],&matrix[i+1]); - matrix[i+2] = add(&matrix[i+1],&matrix[i+2],+1); - } - } - - else if (op[i] == '+' && op[i+1] == '*'){ - struct m tmp = multiply(&matrix[i+1], &matrix[i+2]); - free(matrix[i+1].data); - matrix[i+1] = tmp; - - tmp = add(&matrix[i],&matrix[i+1],+1); - free(matrix[i+2].data); - matrix[i+2] = tmp; - } - - else if (op[i] == '+' && op[i+1] == '+'){ - struct m tmp = add(&matrix[i],&matrix[i+1],+1); - free(matrix[i+1].data); - matrix[i+1] = tmp; - - tmp = add(&matrix[i],&matrix[i+2],+1); - free(matrix[i+2].data); - matrix[i+2] = tmp; - } - - else if (op[i] == '-' && op[i+1] == '*'){ - struct m tmp = multiply(&matrix[i+1], &matrix[i+2]); - free(matrix[i+1].data); - matrix[i+1] = tmp; - - tmp = add(&matrix[i],&matrix[i+1],-1); - free(matrix[i+2].data); - matrix[i+2] = tmp; - } - } - - printf("=\n"); - print_matrix(&matrix[id]); /*Print the result */ - for(i=0; i <= id; i++) - free(matrix[i].data); - free(matrix); -} diff --git a/determinant.c b/determinant.c deleted file mode 100644 index 306bf00..0000000 --- a/determinant.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include "functions.h" - -double determinant(size_t n, struct m *A) -{ - size_t i,j,i_count,j_count, count=0; - - double det = 0; - - if(n < 1) - { - printf("Error\n"); - exit(1); - } - - else if(n==1) return A->data[0]; - - else if(n==2) return (A->data[0]* A->data[1 * A->col + 1] - A->data[0 + 1] * A->data[1*A->col + 0]); - - else{ - struct m C; - - C.row = A->row-1; - C.col = A->col-1; - - C.data = malloc(sizeof(double) * (A->row-1) * (A->col-1)); - - for(count=0; count < n; count++) - { - //Creating array of Minors - i_count = 0; - for(i = 1; i < n; i++) - { - j_count=0; - for(j = 0; j < n; j++) - { - if(j == count) - continue; // don't copy the minor column element - C.data[i_count * C.col + j_count] = A->data[i * A->col + j]; - j_count++; - } - i_count++; - } - det += pow(-1, count) * A->data[count] * determinant(n-1,&C);//Recursive call - } - free(C.data); - return det; - } -} diff --git a/freelab b/freelab deleted file mode 100644 index 36aab66..0000000 Binary files a/freelab and /dev/null differ diff --git a/functions.c b/functions.c deleted file mode 100644 index b62b04b..0000000 --- a/functions.c +++ /dev/null @@ -1,98 +0,0 @@ -#include -#include -#include -#include -#include "functions.h" - -struct m multiply(const struct m *A, const struct m *B) -{ - size_t i, j, k; - struct m C; - C.data = malloc(sizeof(double) * A->row * B->col); - - C.row = A->row; - C.col = B->col; - - for (i=0; i< C.row; i++) - for (j=0; j < C.col; j++) - C.data[i * C.col + j] = 0; - - // Multiplying matrix A and B and storing in C. - for(i = 0; i < A->row; ++i) - for(j = 0; j < B->col; ++j) - for(k=0; k < A->col; ++k) - C.data[i * C.col + j] += A->data[i * A->col + k] * B->data[k * B->col + j]; - - return C; -} - -struct m add(const struct m *A, const struct m *B, double n) -{ - if ( (A->row != B->row) || (A->col != B->col) ){ - printf("Error: You can't sum up matrix of different dimension\n"); - exit(1); - } - - size_t i, j; - - struct m C; - C.data = malloc(sizeof(double) * A->row * B->col); - C.row = A->row; - C.col = A->col; - - for (i=0; i< C.row; i++) - for (j=0; j < C.col; j++) - C.data[i * C.col + j] = A->data[i * A->col + j] + n *B->data[i * B->col + j]; - - return C; -} - -void f(double x) -{ - double i,f= modf(x,&i); - - if(f<.00001) - printf("%.f ",i); - - else printf("%f ",x); -} - -/*printing a Matrix*/ - -void print_matrix(struct m *A){ - - size_t i,j; - - double *tmp = A->data; - - for(i=0; i < A->row; i++){ - for(j=0; j < A->col; j++){ - f(*(tmp++)); - } - putchar('\n'); - } -} - -void scalar_product(double scalar, struct m *B) -{ - size_t i,j; - - for(i=0; i < B->row; i++) - for(j=0; j < B->col; j++) - B->data[i * B->col + j] = scalar * B->data[i * B->col + j]; -} - -void transpose(struct m *A) -{ - struct m C; - C.data = malloc(sizeof(double) * A->row * A->col); - - C.row = A->col; - C.col = A->row; - - size_t i, j; - for (i = 0; i < C.row; i++) - for (j = 0; j < C.col; j++) - C.data[i * C.col + j] = A->data[j * A->col + i]; - *A = C; -} diff --git a/functions.h b/functions.h deleted file mode 100644 index 551eaa2..0000000 --- a/functions.h +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include - -#define MAXNOP 20 /*Max number of operations allowed */ - -struct m{ - size_t row; - size_t col; - double *data; -}; - -struct m add(const struct m *A, const struct m *B, double n); -struct m multiply(const struct m *A, const struct m *B); -void f(double x); -void print_matrix(struct m *A); -void transpose(struct m *A); -double determinant(size_t n, struct m *A); -void scalar_product(double scalar, struct m *B); -void inverse(size_t n, struct m *A); -void read_file(int maxc, FILE *fp); -void calculate(struct m *matrix, int nop, int id, char op[MAXNOP]); diff --git a/inverse.c b/inverse.c deleted file mode 100644 index cc8e3d2..0000000 --- a/inverse.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include "functions.h" - -/*Calculate the inverse of a matrix */ - -void inverse(size_t n, struct m *A) -{ - double det; - if( (det = determinant(n, A)) == 0 ){ - printf("The matrix is singular\n"); - exit(1); - } - - size_t i,j,i_count,j_count, count=0; - - struct m C; /*The Adjoint matrix */ - C.data = malloc(sizeof(double) * n * n); - - C.row = n; - C.col = n; - double Rdata[(n-1)*(n-1)]; // remaining data values - struct m R = { n-1, n-1, Rdata }; // matrix structure for them - for (count = 0; count < n*n; count++) // Create n*n Matrix of Minors - { - int row = count/n, col = count%n; - for (i_count = i = 0; i < n; i++) - if (i != row) // don't copy the current row - { - for (j_count = j = 0; j < n; j++) - if (j != col) // don't copy the current column - Rdata[i_count*R.col+j_count++] = A->data[i*A->col+j]; - i_count++; - } - // transpose by swapping row and column - C.data[col*C.col+row] = pow(-1, (row&1) ^ (col&1)) * determinant(n-1, &R) / det; - } - *A=C; -} diff --git a/main.c b/main.c index 236c90b..e99523b 100644 --- a/main.c +++ b/main.c @@ -21,20 +21,44 @@ * USA */ +#include "processing.h" + +#include #include #include -#include -#include -#include "functions.h" - -int main(int argc, char *argv[]){ - - FILE *file = argc > 1 ? fopen(argv[1], "rb") : stdin; - - /*define max dimension of a matrix */ - int maxc = argc>2?atoi(argv[2])*atoi(argv[2]):100; - - read_file(maxc, file); - +#include + +#define DEFAULT_FILE stdin +#define DEFAULT_DIMENSION 100 + +int main(int argc, char *argv[]) +{ + + FILE *file = DEFAULT_FILE; + int maxc = DEFAULT_DIMENSION; + + if (argc > 1) { + file = fopen(argv[1], "rb"); + if (file == NULL) { + fprintf(stderr, "Could not open input file %s: %s\n", + argv[1], strerror(errno)); + return 1; + } + } + + if (argc > 2) { + int tmp; + + tmp = atoi(argv[2]); + if (tmp == 0) { + fprintf(stderr, "Wrong dimension %s\n", argv[2]); + fclose(file); + return 1; + } + maxc = tmp; + } + + read_file(maxc, file); + return 0; } diff --git a/matrix.c b/matrix.c new file mode 100644 index 0000000..df910b2 --- /dev/null +++ b/matrix.c @@ -0,0 +1,226 @@ +#include "matrix.h" + +#include +#include +#include + +static double determinant_int(const struct m *A) +{ + size_t i, j, i_count, j_count, count; + double det = 0; + double t; + struct m *C; + size_t n = matrix_rows(A); + + if (n < 1) { + fprintf(stderr, "Error, matrix size < 1\n"); + exit(1); + } + + if (n == 1) + return matrix_get(A, 0, 0); + + if (n == 2) { + t = matrix_get(A, 0, 0) * matrix_get(A, 1, 1) + - matrix_get(A, 0, 1) * matrix_get(A, 1, 0); + return t; + } + + C = matrix_new(matrix_cols(A) - 1, matrix_rows(A) - 1); + + for (count = 0; count < n; count++) { + /* Creating array of Minors */ + i_count = 0; + for (i = 1; i < n; i++) { + j_count = 0; + for (j = 0; j < n; j++) { + if (j == count) + /* don't copy the minor column element */ + continue; + + t = matrix_get(A, i, j); + matrix_set(C, i_count, j_count, t); + j_count++; + } + i_count++; + } + det += pow(-1, count) * matrix_get(A, 0, count) * determinant_int(C); /* Recursive call */ + } + matrix_free(C); + return det; +} + +struct m *inverse(const struct m *A) +{ + double det; + size_t n = matrix_rows(A); + struct m *C; /*The Adjoint matrix */ + struct m *R; + size_t i, j, i_count, j_count, count; + int row; + int col; + double t; + + det = determinant_int(A); + if (det == 0) { + fprintf(stderr, "The matrix is singular\n"); + exit(1); + } + + C = matrix_new(n, n); + R = matrix_new(n - 1, n - 1); + /* Create n*n Matrix of Minors */ + for (count = 0; count < n * n; count++) { + row = count / n; + col = count % n; + + for (i_count = i = 0; i < n; i++) { + /* don't copy the current row */ + if (i != row) { + for (j_count = j = 0; j < n; j++) { + /* don't copy the current column */ + if (j != col) { + t = matrix_get(A, i, j); + matrix_set(R, i_count, j_count++, t); + } + } + i_count++; + } + } + /* transpose by swapping row and column */ + t = pow(-1, (row & 1) ^ (col & 1)) * determinant_int(R) / det; + matrix_set(C, col, row, t); + } + + matrix_free(R); + return C; +} + +struct m *determinant(const struct m *A) +{ + double t; + + t = determinant_int(A); + return matrix_new_data(1, 1, &t); +} + +struct m *multiply(const struct m *A, const struct m *B) +{ + size_t i, j, k; + struct m *C; + size_t row, col; + double t1, t2; + + row = matrix_rows(A); + col = matrix_cols(B); + + C = matrix_new(col, row); + + /* Multiplying matrix A and B and storing in C */ + for (i = 0; i < row; ++i) + for (j = 0; j < col; ++j) + for (k = 0; k < matrix_cols(A); ++k) { + + t1 = matrix_get(A, i, k) * matrix_get(B, k, j); + t2 = matrix_get(C, i, j); + matrix_set(C, i, j, t1 + t2); + } + + return C; +} + +struct m *add(const struct m *A, const struct m *B, double n) +{ + size_t i, j; + struct m *C; + size_t col, row; + double t; + + if (!matrix_is_same_size(A, B)) { + fprintf(stderr, + "Error: You can't sum up matrix of different dimension\n"); + exit(1); + } + + col = matrix_cols(A); + row = matrix_rows(A); + + C = matrix_new(col, row); + + for (i = 0; i < row; i++) { + for (j = 0; j < col; j++) { + t = matrix_get(A, i, j) + (n * matrix_get(B, i, j)); + matrix_set(C, i, j, t); + } + } + + return C; +} + +static void print_elem(double x) +{ + double i, f = modf(x, &i); + + if (f < .00001) + printf("%.f ", i); + else + printf("%f ", x); +} + +void print_matrix(const struct m *A) +{ + size_t i, j; + size_t row = matrix_rows(A); + size_t col = matrix_cols(A); + + for (i = 0; i < row; i++) { + for (j = 0; j < col; j++) { + print_elem(matrix_get(A, i, j)); + } + putchar('\n'); + } +} + +struct m *scalar_product(const struct m *A, double scalar) +{ + size_t i, j; + double t; + struct m *R; + size_t row, col; + + row = matrix_rows(A); + col = matrix_cols(A); + + R = matrix_new(row, col); + + for (i = 0; i < row; i++) { + for (j = 0; j < col; j++) { + t = scalar * matrix_get(A, i, j); + matrix_set(R, i, j, t); + } + } + return R; +} + +struct m *transpose(const struct m *A) +{ + struct m *C; + size_t i, j; + size_t row, col; + double t; + + /* transpose, so opposite order */ + row = matrix_cols(A); + col = matrix_rows(A); + + C = matrix_new(row, col); + + for (i = 0; i < row; i++) { + for (j = 0; j < col; j++) { + t = matrix_get(A, j, i); + matrix_set(C, i, j, t); + } + } + + return C; +} diff --git a/matrix.h b/matrix.h new file mode 100644 index 0000000..4b3320c --- /dev/null +++ b/matrix.h @@ -0,0 +1,97 @@ +#ifndef _MATRIXLAB_MATRIX_H_ +#define _MATRIXLAB_MATRIX_H_ + +#include +#include +#include + +struct m { + size_t row; + size_t col; + double data[]; +}; + +static inline struct m *matrix_new(size_t r, size_t c) +{ + struct m *M; + size_t data_size = sizeof(M->data[0]) * r * c; + + M = malloc(sizeof(*M) + data_size); + if (M == NULL) + abort(); + + memset(M->data, 0, data_size); + + M->row = r; + M->col = c; + + return M; +} + +static inline struct m *matrix_new_data(size_t r, size_t c, double *data) +{ + struct m *M; + + M = matrix_new(r, c); + memcpy(M->data, data, sizeof(*M->data) * r * c); + return M; +} + +static inline void matrix_free(struct m *M) +{ + if (M == NULL) + return; + free(M); +} + +static inline size_t matrix_rows(const struct m *M) +{ + return M->row; +} + +static inline size_t matrix_cols(const struct m *M) +{ + return M->col; +} + +static inline double matrix_get(const struct m *M, size_t r, size_t c) +{ + if (r >= M->row || c >= M->col) + abort(); + + return M->data[r * M->col + c]; +} + +static inline void matrix_set(struct m *M, size_t r, size_t c, double v) +{ + if (r >= M->row || c >= M->col) + abort(); + + M->data[r * M->col + c] = v; +} + +static inline bool matrix_is_square(const struct m *M) +{ + return M->row == M->col; +} + +static inline bool matrix_is_same_size(const struct m *M1, + const struct m *M2) +{ + return (M1->row == M2->row) && (M1->col == M2->col); +} + +static inline bool matrix_is_scalar(const struct m *M) +{ + return M->col == 1 && M->row == 1; +} + +struct m *add(const struct m *A, const struct m *B, double n); +struct m *multiply(const struct m *A, const struct m *B); +void print_matrix(const struct m *A); +struct m *transpose(const struct m *A); +struct m *determinant(const struct m *A); +struct m *scalar_product(const struct m *A, double scalar); +struct m *inverse(const struct m *A); + +#endif /* _MATRIXLAB_MATRIX_H_ */ diff --git a/processing.c b/processing.c new file mode 100644 index 0000000..b62f2c7 --- /dev/null +++ b/processing.c @@ -0,0 +1,310 @@ +#include "matrix.h" + +#include +#include +#include +#include + +#define MAXNOP 20 /* Max number of operations allowed */ +#define MAXNMATR 40 /* Max number of matrices */ +#define MAXLINE 500 /* Max lenght of a line */ + +#define IN_PLACE(op, elem, ...) do { \ + tmp = op(elem, ## __VA_ARGS__); \ + matrix_free(elem); \ + elem = tmp; \ + } while (0) + +static void calculate(struct m *matrix[], int nop, int id, char *op) +{ + + int i; + struct m *tmp; + + for (i = 0; i < nop; i++) { + /*Transpose the matrices */ + if (op[i] == 't' || op[i] == 'T') + IN_PLACE(transpose, matrix[0]); + + else if (op[i] == 'd') { + IN_PLACE(determinant, matrix[i]); + } + + if (op[i] == 'i') { + if (matrix_is_square(matrix[0])) { + fprintf(stderr, + "Error: You can only calculate the inverse of square matrices\n"); + abort(); + } + IN_PLACE(inverse, matrix[0]); + } + } + + for (i = 0; i <= nop; i += 2) { + if (op[i] == '+' && op[i + 1] == '?') { + tmp = add(matrix[i], matrix[i + 1], +1); + matrix_free(matrix[i + 1]); + matrix[i + 1] = tmp; + break; + } + + else if (op[i] == '*' && op[i + 1] == '?') { + if (matrix_is_scalar(matrix[i])) + /* Multiplication of Scalar per matrix */ + IN_PLACE(scalar_product, + matrix[i + 1], + matrix_get(matrix[i], 0, 0)); + else { + tmp = multiply(matrix[i], matrix[i + 1]); + matrix_free(matrix[i + 1]); + matrix[i + 1] = tmp; + } + break; + } + + else if (op[i] == '-' && op[i + 1] == '?') { + tmp = add(matrix[i], matrix[i + 1], -1); + matrix_free(matrix[i + 1]); + matrix[i + 1] = tmp; + break; + } + + else if (op[i] == '*' && op[i + 1] == '+') { + if (matrix_is_scalar(matrix[i])) + /* Multiplication of Scalar per matrix */ + IN_PLACE(scalar_product, + matrix[i + 1], + matrix_get(matrix[i], 0, 0)); + else { + tmp = matrix[i + 1]; + matrix[i + 1] = multiply(matrix[i], matrix[i + 1]); + matrix_free(tmp); + + tmp = matrix[i + 2]; + matrix[i + 2] = add(matrix[i + 1], matrix[i + 2], +1); + matrix_free(tmp); + } + } + + else if (op[i] == '+' && op[i + 1] == '*') { + tmp = multiply(matrix[i + 1], matrix[i + 2]); + matrix_free(matrix[i + 1]); + matrix[i + 1] = tmp; + + tmp = add(matrix[i], matrix[i + 1], +1); + matrix_free(matrix[i + 2]); + matrix[i + 2] = tmp; + } + + else if (op[i] == '+' && op[i + 1] == '+') { + tmp = add(matrix[i], matrix[i + 1], +1); + matrix_free(matrix[i + 1]); + matrix[i + 1] = tmp; + + tmp = add(matrix[i], matrix[i + 2], +1); + matrix_free(matrix[i + 2]); + matrix[i + 2] = tmp; + } + + else if (op[i] == '-' && op[i + 1] == '*') { + tmp = multiply(matrix[i + 1], matrix[i + 2]); + matrix_free(matrix[i + 1]); + matrix[i + 1] = tmp; + + tmp = add(matrix[i], matrix[i + 1], -1); + matrix_free(matrix[i + 2]); + matrix[i + 2] = tmp; + } + } + + printf("=\n"); + print_matrix(matrix[id]); /*Print the result */ +} + +static void print_task(struct m *matrix[], size_t id, char *op) +{ + size_t i; + + for (i = 0; i <= id; i++) { + + if (op[i] == 'd') { + printf("det\n"); + print_matrix(matrix[i]); + continue; + } + + if (op[i] == '*' || op[i] == '-' || op[i] == '+') { + print_matrix(matrix[i]); + if (i > 0 && + (op[i - 1] == 'i' || op[i - 1] == 'T' || op[i - 1] == 't')) + continue; + else + printf("%c\n", op[i]); + continue; + } + + if (op[i] == 't' || op[i] == 'T') { + print_matrix(matrix[i]); + printf("^T\n"); + if (op[i + 1] != '?') + printf("%c\n", op[i + 1]); + continue; + } + + if (op[i] == 'i') { + print_matrix(matrix[i]); + printf("^-1\n"); /* matrix inverse operation */ + if (op[i + 1] != '?') + printf("%c\n", op[i + 1]); + continue; + } + + if (op[i] == '?') { + print_matrix(matrix[i]); + } + } +} + +struct matrix_state { + double *buf; + size_t row; + size_t col; + size_t pos; + bool started; /* matrix parsing started */ +}; + + +static void matrix_parse_init(struct matrix_state *s, int maxc) +{ + s->started = false; + s->buf = malloc(sizeof(*s->buf) * maxc); + if (s->buf == NULL) + abort(); +} + +static void matrix_parse_row(struct matrix_state *s, char *str) +{ + size_t off = 0; + int n; + + /* read numbers in a line into s->buf */ + while (sscanf(str + off, "%lf%n", &s->buf[s->pos], &n) == 1) { + s->pos++; + if (s->row == 0) + s->col++; + off += n; + } + + s->row++; +} + +static void matrix_parse_start(struct matrix_state *s, char *str) +{ + s->row = 0; + s->col = 0; + s->pos = 0; + s->started = true; +} + +static void matrix_parse_line(struct matrix_state *s, char *str) +{ + if (!s->started) + matrix_parse_start(s, str); + matrix_parse_row(s, str); +} + +static bool matrix_parse_end(struct matrix_state *s, struct m **M) +{ + struct m *m; + + if (!s->started) + return false; + + m = matrix_new_data(s->row, s->col, s->buf); + s->started = false; + *M = m; + return true; +} + +static bool matrix_parse_end_all(struct matrix_state *s, struct m **M) +{ + bool rc; + + rc = matrix_parse_end(s, M); + free(s->buf); + + return rc; +} + +static bool is_operator_line(char *buf) +{ + return !isdigit(*buf) && buf[1] == '\n'; +} + +void read_file(int maxc, FILE *fp) +{ + struct m *matrix[MAXNMATR]; + int id; /* id of a matrix */ + int nop = 0; /* No of operators */ + int i; + char buf[MAXLINE]; /* to store each lines of file */ + char op[MAXNOP]; + struct matrix_state parse_state; + struct m *tmp; + + memset(matrix, 0, sizeof(matrix)); + memset(op, '?', sizeof(op)); + + matrix_parse_init(&parse_state, maxc); + id = 0; + + while (fgets(buf, MAXLINE, fp)) { + if (id >= MAXNMATR) { + fprintf(stderr, "Too much matrices, max is %d\n", MAXNMATR); + abort(); + } + + if (strcmp(buf, "^-1\n") == 0) { + op[nop++] = 'i'; /* matrix inverse operation */ + continue; + } + + if (strcmp(buf, "^T\n") == 0 || strcmp(buf, "^t\n") == 0) { + op[nop++] = 't'; /* matrix inverse operation */ + continue; + } + + if (strcmp(buf, "det\n") == 0) { + op[nop++] = 'd'; /* determinant operation */ + continue; + } + + if (!is_operator_line(buf)) { + matrix_parse_line(&parse_state, buf); + } else { + if (matrix_parse_end(&parse_state, &tmp)) + matrix[id++] = tmp; + + op[nop++] = *buf; + continue; + } + + } /* end of while fgets cycle */ + + fclose(fp); + + if (matrix_parse_end_all(&parse_state, &tmp)) + matrix[id] = tmp; + + if (nop == 0) { + fprintf(stderr, "Nothing to do\n"); + exit(1); + } + + print_task(matrix, id, op); + + calculate(matrix, nop, id, op); + + for (i = 0; i <= id; i++) + matrix_free(matrix[i]); +} diff --git a/processing.h b/processing.h new file mode 100644 index 0000000..8cb51b9 --- /dev/null +++ b/processing.h @@ -0,0 +1,8 @@ +#ifndef _MATRIXLAB_PROCESSING_H_ +#define _MATRIXLAB_PROCESSING_H_ + +#include + +void read_file(int maxc, FILE *fp); + +#endif /* _MATRIXLAB_PROCESSING_H_ */ diff --git a/read.c b/read.c deleted file mode 100644 index 71fbc1a..0000000 --- a/read.c +++ /dev/null @@ -1,127 +0,0 @@ -#include "functions.h" -#include -#include - -#define MAXNOP 20 /*Max number of operations allowed */ -#define MAXNMATR 40 /*Max number of matrices */ -#define MAXLINE 500 /*Max lenght of a line */ - -void read_file(int maxc, FILE *fp) -{ - struct m *matrix; - int id = 0; /* id of a matrix */ - size_t ncol,nrow; /* No of columns of a matrix*/ - ncol = nrow = 0; - int nop = 0; /*No of operators*/ - int off = 0; - int i; - int n; - double *d; - char buf[MAXLINE]; /*to store each lines of file */ - char *p = buf; - char op[MAXNOP]; - - for (i=0; i < MAXNOP; i++) - op[i]='?'; - - if (!(matrix = malloc(MAXNMATR*sizeof *(matrix)))) { - perror ("malloc-matrix"); - exit(1); - } - - /*Read file line by line */ - while (fgets (buf, MAXLINE, fp)){ - - if (nrow == 0){ - /* allocate/validate max no. of matrix */ - d = matrix[id].data = malloc(sizeof(double) * maxc); - } - - if (strcmp(buf, "^-1\n") == 0){ - op[nop++] = 'i'; /* matrix inverse operation */ - continue; - } - - if (strcmp(buf, "^T\n") == 0 || strcmp(buf, "^t\n") == 0){ - op[nop++] = 't'; /* matrix inverse operation */ - continue; - } - - else if (strcmp(buf, "det\n") == 0){ - op[nop++] = 'd'; /* determinant operation */ - continue; - } - - /*check if line contains operator */ - else if ( (!isdigit(*buf) && buf[1] =='\n')) - { - op[nop++] = *buf; - matrix[id].col = ncol; - matrix[id].row = nrow; - nrow = ncol = 0; - id++; - continue; - } - - else /* read integers in a line into d */ - { - while (sscanf (p + off, "%lf%n", d, &n) == 1) { - d++; - if(nrow == 0) - ncol++; - off += n; - } - nrow++; - off = 0; - } - } /*end of while fgets cycle */ - - fclose(fp); - - /*Assign last matrix No of columns and rows */ - matrix[id].col = ncol; - matrix[id].row = nrow; - - if (nop == 0){ - printf("Nothing to do\n"); - exit(1); - } - - /*Printing the matrices and operations */ - for(i=0; i <= id; i++){ - - if(op[i] == 'd'){ - printf("det\n"); - print_matrix(&matrix[i]); - } - - else if (op[i] == '*' || op[i] == '-' || op[i] =='+') - { - print_matrix(&matrix[i]); - if(op[i-1] == 'i' || op[i-1] == 'T' || op[i-1] == 't') - continue; - else - printf("%c\n", op[i]); - } - - else if (op[i] == 't' || op[i] == 'T'){ - print_matrix(&matrix[i]); - printf("^T\n"); - if(op[i+1] != '?') - printf("%c\n",op[i+1]); - } - - else if (op[i] == 'i'){ - print_matrix(&matrix[i]); - printf("^-1\n"); /* matrix inverse operation */ - if(op[i+1] != '?') - printf("%c\n",op[i+1]); - } - - else if(op[i] == '?'){ - print_matrix(&matrix[i]); - } - } - - calculate(matrix, nop, id, op); -}