int matrix_unit() { // allocate matrix_t m; m.n_rows = UNIT_MATRIX_N_ROWS; m.n_cols = UNIT_MATRIX_N_COLS; malloc_matrix(&m); // write size_t row, col; for(row = 0; row < m.n_rows; row++) for(col = 0; col < m.n_cols; col++) m.t[row][col] = col + m.n_cols*row; // read for(row = 0; row < m.n_rows; row++) for(col = 0; col < m.n_cols; col++) ASSERT(m.t[row][col] == col + m.n_cols*row, "matrix read/write test"); // free free_matrix(&m); // success return EXIT_SUCCESS; }
void transform_matrix(double **matrix1, double **matrix2) { double **cpy; cpy = malloc_matrix(4, 4); matrix_multiply(matrix1, matrix2, cpy); copy_matrix(matrix1, cpy); free_matrix(cpy, 4); }
int main(int argc, char *argv[]) { FILE *fp = stdin, *fp_eigen = NULL; int i, j, k, n = PRICOMP_ORDER, leng = LENG, total = -1; BOOL out_evecFlg = FALSE, out_evalFlg = FALSE; double sum; double *buf = NULL; double *mean = NULL, **var = NULL; double eps = EPS; int itemax = ITEMAX; double **e_vec = NULL, *e_val = NULL; /* eigenvector and eigenvalue */ double *cont_rate = NULL; /* contribution rate */ double jacobi_conv; float_list *top, *cur, *prev, *tmpf, *tmpff; if ((cmnd = strrchr(argv[0], '/')) == NULL) cmnd = argv[0]; else cmnd++; while (--argc) if ((**++argv) == '-') { switch (*(*argv + 1)) { case 'l': leng = atoi(*++argv); --argc; break; case 'n': n = atoi(*++argv); --argc; break; case 'e': eps = atof(*++argv); --argc; break; case 'i': itemax = atoi(*++argv); --argc; break; case 'v': out_evecFlg = TRUE; break; case 'V': out_evalFlg = TRUE; fp_eigen = getfp(*++argv, "wb"); --argc; break; case 'h': usage(EXIT_SUCCESS); default: fprintf(stderr, "%s : Invalid option '%s'!\n", cmnd, *argv); usage(EXIT_FAILURE); } } else fp = getfp(*argv, "rb"); if (n > leng) { fprintf(stderr, "\n %s (Error) output number of pricipal component" " must be less than length of vector.\n", cmnd); usage(EXIT_FAILURE); } /* -- Count number of input vectors and read -- */ buf = dgetmem(leng); top = prev = (float_list *) malloc(sizeof(float_list)); top->f = fgetmem(leng); total = 0; prev->next = NULL; while (freadf(buf, sizeof(*buf), leng, fp) == leng) { cur = (float_list *) malloc(sizeof(float_list)); cur->f = fgetmem(leng); for (i = 0; i < leng; i++) { cur->f[i] = (float) buf[i]; } total++; prev->next = cur; cur->next = NULL; prev = cur; } free(buf); buf = dgetmem(total * leng); for (i = 0, tmpf = top->next; tmpf != NULL; i++, tmpf = tmpff) { for (j = 0; j < leng; j++) { buf[i * leng + j] = tmpf->f[j]; } tmpff = tmpf->next; free(tmpf->f); free(tmpf); } free(top); /* PCA */ /* allocate memory for mean vectors and covariance matrix */ mean = dgetmem(leng); var = malloc_matrix(leng); /* calculate mean vector */ for (i = 0; i < leng; i++) { for (j = 0, sum = 0.0; j < total; j++) sum += buf[i + j * leng]; mean[i] = sum / total; } /* calculate cov. mat. */ for (i = 0; i < leng; i++) { for (j = 0; j < leng; j++) { sum = 0.0; for (k = 0; k < total; k++) sum += (buf[i + k * leng] - mean[i]) * (buf[j + k * leng] - mean[j]); var[i][j] = sum / total; } } /* allocate memory for eigenvector and eigenvalue */ e_vec = malloc_matrix(leng); e_val = dgetmem(leng); /* calculate eig.vec. and eig.val. with jacobi method */ if ((jacobi_conv = jacobi(var, leng, eps, e_val, e_vec, itemax)) == -1) { fprintf(stderr, "Error : matrix is not symmetric.\n"); exit(EXIT_FAILURE); } else if (jacobi_conv == -2) { fprintf(stderr, "Error : loop in jacobi method reached %d times.\n", itemax); exit(EXIT_FAILURE); } /* allocate memory for contribution rate of each eigenvalue */ cont_rate = dgetmem(leng); /* calculate contribution rate of each eigenvalue */ for (j = 0; j < leng; j++) { sum = 0.0; for (i = 0; i < leng; i++) sum += e_val[i]; cont_rate[j] = e_val[j] / sum; } /* end of PCA */ /* output mean vector and eigen vectors */ if (out_evecFlg == TRUE) { fwritef(mean, sizeof(*mean), leng, stdout); for (i = 0; i < n; i++) fwritef(e_vec[i], sizeof(*(e_vec[i])), leng, stdout); } /* output eigen values and contribution ratio */ if (out_evalFlg == TRUE) { for (i = 0; i < n; i++) { fwritef(e_val + i, sizeof(*e_val), 1, fp_eigen); fwritef(cont_rate + i, sizeof(*cont_rate), 1, fp_eigen); } fclose(fp_eigen); } return EXIT_SUCCESS; }
int jacobi(double **m, int n, double eps, double *e_val, double **e_vec, int itemax) { int i, j, k; int count; int ret; double **a; double max_e; int r = 0, c = 0; double a1, a2, a3; double co, si; double w1, w2; double t1, ta; double tmp; for (i = 0; i < n; i++) { for (j = i + 1; j < n; j++) { if (m[i][j] != m[j][i]) { return -1; } } } if ((a = malloc_matrix(n)) == NULL) { fprintf(stderr, "Error : Can't malloc at jacobi in %s\n", cmnd); exit(EXIT_FAILURE); } for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { a[i][j] = m[i][j]; } } for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { e_vec[i][j] = (i == j) ? 1.0 : 0.0; } } count = 0; while (1) { max_e = 0.0; for (i = 0; i < n; i++) { for (j = i + 1; j < n; j++) { if (max_e < fabs(a[i][j])) { max_e = fabs(a[i][j]); r = i; c = j; } } } if (max_e <= eps) { ret = count; break; } if (count >= itemax) { ret = -2; break; } a1 = a[r][r]; a2 = a[c][c]; a3 = a[r][c]; t1 = fabs(a1 - a2); ta = 2.0 * a3 / (t1 + sqrt(t1 * t1 + 4.0 * a3 * a3)); co = sqrt(1.0 / (ta * ta + 1.0)); si = ta * co; if (a1 < a2) si = -si; for (i = 0; i < n; i++) { w1 = e_vec[i][r]; w2 = e_vec[i][c]; e_vec[i][r] = w1 * co + w2 * si; e_vec[i][c] = -w1 * si + w2 * co; if (i == r || i == c) continue; w1 = a[i][r]; w2 = a[i][c]; a[i][r] = w1 * co + w2 * si; a[i][c] = -w1 * si + w2 * co; a[r][i] = a[i][r]; a[c][i] = a[i][c]; } a[r][r] = a1 * co * co + a2 * si * si + 2.0 * a3 * co * si; a[c][c] = a1 + a2 - a[r][r]; a[r][c] = 0.0; a[c][r] = 0.0; count++; } for (i = 0; i < n; i++) { e_val[i] = a[i][i]; } for (i = 0; i < n; i++) { for (j = i + 1; j < n; j++) { tmp = e_vec[i][j]; e_vec[i][j] = e_vec[j][i]; e_vec[j][i] = tmp; } } for (i = 0; i < n; i++) { for (j = n - 2; j >= i; j--) { if (e_val[j] < e_val[j + 1]) { tmp = e_val[j]; e_val[j] = e_val[j + 1]; e_val[j + 1] = tmp; for (k = 0; k < n; k++) { tmp = e_vec[j][k]; e_vec[j][k] = e_vec[j + 1][k]; e_vec[j + 1][k] = tmp; } } } } free(a[0]); free(a); return (ret); }
int main (int argc, char* argv[]) { int n; double *b; Cel *A = NULL; FILE *input; char opt; /* Tratamento da entrada */ if(argc < 2) { error(NO_OPTION); } else { opt = argv[1][0]; switch(opt) { case '1': n = MATRIX_TEST_SIZE; A = malloc_matrix(n); b = malloc_vector(n); build_test_matrix(A,0.01,n); build_test_vector(b,n); conjugate_gradient(A,b,n); free_matrix(n,A); free(b); break; case '2': n = MATRIX_TEST_SIZE; A = malloc_matrix(n); b = malloc_vector(n); build_test_matrix(A,0.05,n); build_test_vector(b,n); conjugate_gradient(A,b,n); free_matrix(n,A); free(b); break; case '3': n = MATRIX_TEST_SIZE; A = malloc_matrix(n); b = malloc_vector(n); build_test_matrix(A,0.1,n); build_test_vector(b,n); conjugate_gradient(A,b,n); free_matrix(n,A); free(b); break; case '4': n = MATRIX_TEST_SIZE; A = malloc_matrix(n); b = malloc_vector(n); build_test_matrix(A,0.3,n); build_test_vector(b,n); conjugate_gradient(A,b,n); free_matrix(n,A); free(b); break; case 'r': if(argc < 3) error(NO_FILE); else { input = fopen(argv[2],"r"); if(input == NULL) error(OPENING_FILE); n = read_dimension(input); A = malloc_matrix(n); b = malloc_vector(n); read_matrix_system(input,n,A,b); fclose(input); conjugate_gradient(A,b,n); free_matrix(n,A); print_vector(n,b); free(b); break; } default: printf("Opcao nao reconhecida\n"); exit(EXIT_FAILURE); } } return 1; }