#include "nr.h" #include "nrutil.h" #include #include #include #include #include #include "matutil.h" void try_gaussj(JMatrixData *data) { printf("gauss-jordan method:\n"); fflush(stdout); fflush(stderr); gaussj(data->a, data->m, data->b, 1); print_matrix(data->m, 1, data->b); } void try_lu(JMatrixData *data) { printf("LU Decomposition:\n"); int *indx = calloc(data->m + 1, sizeof(int)); float *d = calloc(data->m + 1, sizeof(float)); ludcmp(data->a, data->m, indx, d); print_matrix(data->m, data->n, data->a); printf("index: "); print_vector_int(data->m, indx); printf("solution x: "); float *b = calloc(data->m + 1, sizeof(float)); int i; for (i = 1; i <= data->m; i++) { b[i] = data->b[i][1]; } lubksb(data->a, data->m, indx, b); print_vector_float(data->m, b); free(indx); free(d); free(b); } void try_svd(JMatrixData *data) { int i; printf("Singular Value Decompoisition:\n"); fflush(stdout); fflush(stderr); float *w = calloc(data->m + 1, sizeof(float)); float **v = new_matrix(data->m, data->n); svdcmp(data->a, data->m, data->n, w, v); printf("U:\n"); print_matrix(data->m, data->n, data->a); printf("w: "); print_vector_float(data->m, w); printf("S:\n"); float **s = new_diagonal(data->m, w); print_matrix(data->m, data->n, s); printf("V:\n"); print_matrix(data->m, data->n, v); printf("\n"); float **t1 = matmul(data->m, data->m, data->m, data->a, s); float **vt = mattranspose(data->m, data->n, v); float **t2 = matmul(data->m, data->n, data->m, t1, vt); printf("Orig = U * S * V^T\n"); print_matrix(data->m, data->n, t2); printf("we want to get x by using x = V * (S^-1 * (U^T * b)):\n"); printf("x:\n"); float **invS = new_matrix(data->m, data->m); for (i = 1; i <= data->m; i++) { invS[i][i] = 1 / w[i]; } float **UT = mattranspose(data->m, data->n, data->a); float **l1 = matmul(data->m, data->m, 1, UT, data->b); float **l2 = matmul(data->m, data->m, 1, invS, l1); float **l3 = matmul(data->m, data->m, 1, v, l2); print_matrix(data->m, 1, l3); simple_free_matrix(data->m, data->n, v); simple_free_matrix(data->m, data->m, vt); simple_free_matrix(data->m, data->m, s); simple_free_matrix(data->m, data->n, t1); simple_free_matrix(data->m, data->n, t2); simple_free_matrix(data->m, data->m, invS); simple_free_matrix(data->m, data->m, UT); simple_free_matrix(data->m, 1, l1); simple_free_matrix(data->m, 1, l2); simple_free_matrix(data->m, 1, l3); free(w); } void try_det_inv(JMatrixData *data) { int m = data->m; float det = matdet(m, data->a); printf("det: %f\n", det); if (det < 1e-6) { printf("There is no inverse matrix, because det ~ 0.0f\n"); } else { float **inv = matinv(m, data->a); printf("inv:\n"); print_matrix(m, m, inv); simple_free_matrix(m, m, inv); } } void try_mprove(JMatrixData *data) { printf("mprove method:\n"); fflush(stdout); fflush(stderr); float **a = new_matrix(data->m, data->m); copy_matrix(data->m, data->m, data->a, a); int *indx = calloc(data->m + 1, sizeof(int)); float *d = malloc(sizeof(float)); ludcmp(a, data->m, indx, d); float *x_init = calloc(data->m + 1, sizeof(float)); float *b = calloc(data->m + 1, sizeof(float)); int i; for (i = 1; i <= data->m; i++) { x_init[i] = data->b[i][1]; b[i] = data->b[i][1]; } lubksb(a, data->m, indx, x_init); float *x = calloc(data->m + 1, sizeof(float)); for (i = 1; i <= data->m; i++) { x[i] = x_init[i]; } printf("x_init: "); print_vector_float(data->m, x_init); mprove(data->a, a, data->m, indx, b, x); printf("x using mprove: "); print_vector_float(data->m, x); free(x); free(x_init); free(indx); free(d); simple_free_matrix(data->m, data->m, a); } void processMatrix(JMatrixData *data) { printf("-----------------------------\n"); printf("matrix data A:\n"); print_matrix(data->m, data->n, data->a); printf("matrix data b:\n"); print_matrix(data->m, 1, data->b); printf("-----------------------------\n"); fflush(stdout); fflush(stderr); pid_t pid = fork(); if (pid < 0) { printf("process 실행 실패\n"); return; } else if (pid == 0) { printf("created process for gauss-jordan method\n"); printf("-----------------------------\n"); JMatrixData *copied = new_jmatdata(data->m, data->n); copy_jmatdata(data, copied); try_gaussj(copied); free_jmatdata(copied); printf("-----------------------------\n"); exit(0); } wait(NULL); fflush(stdout); fflush(stderr); pid = fork(); if (pid < 0) { printf("process 실행 실패\n"); return; } else if (pid == 0) { printf("created process for LU Decomposition\n"); printf("-----------------------------\n"); fflush(stdout); fflush(stderr); JMatrixData *copied = new_jmatdata(data->m, data->n); copy_jmatdata(data, copied); try_lu(copied); free_jmatdata(copied); printf("-----------------------------\n"); exit(0); } wait(NULL); fflush(stdout); fflush(stderr); pid = fork(); if (pid < 0) { printf("process 실행 실패\n"); return; } else if (pid == 0) { printf("created process for Singular Value Decomposition\n"); printf("-----------------------------\n"); fflush(stdout); fflush(stderr); JMatrixData *copied = new_jmatdata(data->m, data->n); copy_jmatdata(data, copied); try_svd(copied); free_jmatdata(copied); printf("-----------------------------\n"); exit(0); } wait(NULL); fflush(stdout); fflush(stderr); pid = fork(); if (pid < 0) { printf("process 실행 실패\n"); return; } else if (pid == 0) { printf("created process for LUDecomp with mprove\n"); printf("-----------------------------\n"); fflush(stdout); fflush(stderr); JMatrixData *copied = new_jmatdata(data->m, data->n); copy_jmatdata(data, copied); try_mprove(copied); free_jmatdata(copied); printf("-----------------------------\n"); exit(0); } wait(NULL); fflush(stdout); fflush(stderr); printf("last we want to get det and inv of A:\n"); pid = fork(); if (pid < 0) { printf("process 실행 실패\n"); return; } else if (pid == 0) { printf("created process for det and inv\n"); printf("-----------------------------\n"); fflush(stdout); fflush(stderr); JMatrixData *copied = new_jmatdata(data->m, data->n); copy_jmatdata(data, copied); try_det_inv(copied); free_jmatdata(copied); printf("-----------------------------\n"); exit(0); } wait(NULL); fflush(stdout); fflush(stderr); } JMatrixData *readDataFrom(char *filename) { FILE *fp = fopen(filename, "r"); if (fp == NULL) { printf("Error opening file"); exit(1); } int m, n; fscanf(fp, "%d", &m); fscanf(fp, "%d", &n); JMatrixData *data = new_jmatdata(m, n); int i, j; for (i = 1; i <= data->m; i++) { for (j = 1; j <= data->n; j++) { fscanf(fp, "%f", &data->a[i][j]); } } for (i = 1; i <= data->m; i++) { fscanf(fp, "%f", &data->b[i][1]); } fclose(fp); return data; } int main() { int m, n; int i, j; const char *filenames[] = { "lineq1.dat", "lineq2.dat", "lineq3.dat"}; pid_t pid; for (i = 0; i < 3; i++) { pid = fork(); fflush(stdout); fflush(stderr); if (pid < 0) { printf("process 실행 실패\n"); return 2; } else if (pid == 0) { printf("=================================\n"); printf("data from %s:\n", filenames[i]); JMatrixData *data = readDataFrom(filenames[i]); processMatrix(data); printf("end for %s\n", filenames[i]); exit(0); } wait(NULL); } fflush(stdout); fflush(stderr); printf("=======================================\n"); printf("===============< Report >==============\n"); printf("=======================================\n"); printf("# 1. discuss three method.\n"); printf("In terms of the accuracy of the solution,\nthere is no noticable difference between three methods.(at 1e-6)\n"); printf("But `gaussj` method is unstable when there are many solutions.\n"); printf("In terms of stability, svdcmp is the most stable\nbecause the solution can always come out (because it is, by definition, expressed as matmul).\n"); printf("I could not feel it in this example\nbut I think svd is the slowest for that; matmul is too expensive.\n"); printf("so I think that LUdcmp is balanced:\nNot as unstable as gaussj, not as expensive as svdcmp.\n"); printf("# 2. mprove\n"); printf("`mprove` is a method of increasing the accuracy of the solution\nby using an iterative method using the alud and initial solution obtained by `ludcmp`.\n"); printf("The accuracy of the LU can be compensated using this method,\nso the LUdcmp is getting more useful.\n"); printf("# 3. det and inv\n"); printf("Without first example, we can get inverse matrix with gaussj.\n"); printf("We can also get determinants using cofactor expansion with recursive method.\n"); printf("=======================================\n"); printf("=============< End Report >============\n"); printf("=======================================\n"); return 0; }