fix final main.c matutil.c matutil.h and add hw3.txt and README.md
This commit is contained in:
252
hws/hw3/main.c
252
hws/hw3/main.c
@@ -4,52 +4,160 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "matutil.h"
|
||||
|
||||
void try_gaussj(JMatrixData* data) {
|
||||
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) {
|
||||
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));
|
||||
|
||||
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("d: ");
|
||||
print_vector_float(data->m, d);
|
||||
|
||||
printf("solution:\n");
|
||||
float * b = calloc(data->m + 1, sizeof(float));
|
||||
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);
|
||||
for (i = 1; i <= data->m; i++) {
|
||||
printf("%6.2f ", b[i]);
|
||||
}
|
||||
print_vector_float(data->m, b);
|
||||
free(indx);
|
||||
free(d);
|
||||
|
||||
free(b);
|
||||
}
|
||||
|
||||
void processMatrix(JMatrixData* data) {
|
||||
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");
|
||||
@@ -57,7 +165,7 @@ void processMatrix(JMatrixData* data) {
|
||||
} else if (pid == 0) {
|
||||
printf("created process for gauss-jordan method\n");
|
||||
printf("-----------------------------\n");
|
||||
JMatrixData* copied = new_jmatdata(data->m, data->n);
|
||||
JMatrixData *copied = new_jmatdata(data->m, data->n);
|
||||
copy_jmatdata(data, copied);
|
||||
try_gaussj(copied);
|
||||
free_jmatdata(copied);
|
||||
@@ -66,6 +174,9 @@ void processMatrix(JMatrixData* data) {
|
||||
}
|
||||
|
||||
wait(NULL);
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
printf("process 실행 실패\n");
|
||||
@@ -73,18 +184,88 @@ void processMatrix(JMatrixData* data) {
|
||||
} else if (pid == 0) {
|
||||
printf("created process for LU Decomposition\n");
|
||||
printf("-----------------------------\n");
|
||||
JMatrixData* copied = new_jmatdata(data->m, data->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) {
|
||||
JMatrixData *readDataFrom(char *filename) {
|
||||
FILE *fp = fopen(filename, "r");
|
||||
|
||||
if (fp == NULL) {
|
||||
@@ -96,7 +277,7 @@ JMatrixData*readDataFrom(char *filename) {
|
||||
fscanf(fp, "%d", &m);
|
||||
fscanf(fp, "%d", &n);
|
||||
|
||||
JMatrixData*data = new_jmatdata(m, n);
|
||||
JMatrixData *data = new_jmatdata(m, n);
|
||||
|
||||
int i, j;
|
||||
for (i = 1; i <= data->m; i++) {
|
||||
@@ -117,19 +298,20 @@ 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]);
|
||||
JMatrixData *data = readDataFrom(filenames[i]);
|
||||
processMatrix(data);
|
||||
printf("end for %s\n", filenames[i]);
|
||||
exit(0);
|
||||
@@ -137,9 +319,27 @@ int main() {
|
||||
wait(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
printf("end\n");
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user