// // functions for Cholesky Solver // DllExport struct Solver_tag * CreaterCholeskySolver (int n, int nnz, int *rowIndex, int *colIndex, double *value) { int rc; char* options[] = {"taucs.factor.LLT=true", NULL}; //char* options[] = {"taucs.factor.LLT=true", "taucs.factor.droptol=1e-2", "taucs.solve.cg=true", NULL}; struct Solver_tag * s = (struct Solver_tag*) malloc(sizeof(struct Solver_tag)); if (s == NULL) return NULL; s->n = n; s->matrix = NULL; s->factorization = NULL; //open log file //taucs_logfile("c:/log2.txt"); // create matrix s->matrix = taucs_ccs_create(n, n, nnz, TAUCS_DOUBLE|TAUCS_LOWER|TAUCS_SYMMETRIC); if (s->matrix == NULL) return NULL; // copy elements to matrix memcpy(s->matrix->rowind, rowIndex, sizeof(int) * nnz); memcpy(s->matrix->values.d, value, sizeof(double) * nnz); memcpy(s->matrix->colptr, colIndex, sizeof(int) * (n+1)); // factor matrix rc = taucs_linsolve(s->matrix, &s->factorization, 0, NULL, NULL, options, NULL); if (rc != TAUCS_SUCCESS) { FreeSolver(s); return NULL; } //taucs_logfile("none"); return s; }
bool SolveNormalEquation(const taucs_ccs_matrix * A, const taucsType * b, taucsType * x) { taucs_ccs_matrix * ATmat = MatrixTranspose(A); if (! ATmat) { return false; } taucs_ccs_matrix * ATAmat = Mul2NonSymmMatSymmResult(ATmat,A); taucsType * rhs = new taucsType[A->n]; MulNonSymmMatrixVector(ATmat, b, rhs); // solve the system int rc = taucs_linsolve(ATAmat, NULL, 1, x, rhs, SIVANfactor, SIVANopt_arg); taucs_ccs_free(ATmat); taucs_ccs_free(ATAmat); delete[] rhs; if (rc != TAUCS_SUCCESS) { return false; } else { return true; } }
DllExport double SolveEx( struct Solver_tag * sp, double *x, int xIndex, double *b, int bIndex ) { int rc = -1; char* options [] = {"taucs.factor=false", NULL}; struct Solver_tag * s = (struct Solver_tag *) sp; double time = taucs_ctime(); rc = taucs_linsolve(s->matrix, &s->factorization, 1, x + xIndex, b + bIndex, options, NULL); time = taucs_ctime() - time; //return time; if (rc != TAUCS_SUCCESS) return rc; return 0; }
DllExport int Solve( struct Solver_tag * sp, double *x, double *b ) { int rc; char* options [] = {"taucs.factor=false", NULL}; //char* options [] = {"taucs.factor=false", "taucs.solve.cg=true", NULL}; struct Solver_tag * s = (struct Solver_tag *) sp; void * F = NULL; if (s->matrix == NULL || s->factorization == NULL) return -1; rc = taucs_linsolve(s->matrix, &s->factorization, 1, x, b, options, NULL); if (rc != TAUCS_SUCCESS) return rc; return 0; }
DllExport int SolveCG(void * sp, double *x, double *b) { int rc; char* options [] = {"taucs.solve.cg=true", NULL}; struct Solver_tag * s = (struct Solver_tag *) sp; void * F = NULL; if (s->matrix == NULL || s->factorization == NULL) return -1; //open log file taucs_logfile("c:/log.txt"); rc = taucs_linsolve(s->matrix, &F, 1, x, b, options, NULL); if (rc != TAUCS_SUCCESS) return rc; taucs_logfile("none"); return 0; }
DllExport int FreeSolver( struct Solver_tag * sp ) { struct Solver_tag * s = (struct Solver_tag *)sp; int rc = 0; if (sp == NULL) { return 0; } if (s->matrix != NULL) { taucs_ccs_free(s->matrix); s->matrix = NULL; } if (s->factorization != NULL) { rc = taucs_linsolve(NULL, &s->factorization, 0, NULL, NULL, NULL, NULL); s->factorization = NULL; } return rc; }
int main(int argc, char* argv[]) { double start; int rc; int i,j; taucs_ccs_matrix* A = NULL; void* X; void* B; void* Y; void* Z; void* opt_arg[] = { NULL }; double opt_nrhs = 1.0; char* opt_ijv = NULL; char* opt_ijv_zero = NULL; char* opt_hb = NULL; char* opt_bin = NULL; char* opt_log = "stdout"; double opt_3d = -1.0; double opt_2d = -1.0; char* opt_2d_type = "dirichlet"; int opt_3d_rand = 0;/*not random*/ double opt_3d_small = -1.0;/*regular*/ double opt_shift = 0.0; int opt_sreal = 0; int opt_dreal = 0; int opt_scomplex = 0; int opt_dcomplex = 0; int datatype = TAUCS_DOUBLE; int opt_all1rhs = 0; double rerr; for (i=0; argv[i]; i++) { int understood = FALSE; understood |= taucs_getopt_boolean(argv[i],opt_arg,"taucs_run.sreal",&opt_sreal); understood |= taucs_getopt_boolean(argv[i],opt_arg,"taucs_run.dreal",&opt_dreal); understood |= taucs_getopt_boolean(argv[i],opt_arg,"taucs_run.scomplex",&opt_scomplex); understood |= taucs_getopt_boolean(argv[i],opt_arg,"taucs_run.dcomplex",&opt_dcomplex); understood |= taucs_getopt_string(argv[i],opt_arg,"taucs_run.ijv",&opt_ijv); understood |= taucs_getopt_string(argv[i],opt_arg,"taucs_run.ijvz",&opt_ijv_zero); understood |= taucs_getopt_string(argv[i],opt_arg,"taucs_run.hb", &opt_hb ); understood |= taucs_getopt_string(argv[i],opt_arg,"taucs_run.bin", &opt_bin ); understood |= taucs_getopt_string(argv[i],opt_arg,"taucs_run.log",&opt_log); understood |= taucs_getopt_double(argv[i],opt_arg,"taucs_run.mesh3d",&opt_3d); understood |= taucs_getopt_boolean(argv[i],opt_arg,"taucs_run.mesh3d.rand",&opt_3d_rand); understood |= taucs_getopt_double(argv[i],opt_arg,"taucs_run.mesh3d.small",&opt_3d_small); understood |= taucs_getopt_double(argv[i],opt_arg,"taucs_run.mesh2d",&opt_2d); understood |= taucs_getopt_string(argv[i],opt_arg,"taucs_run.mesh2d.type",&opt_2d_type); understood |= taucs_getopt_double(argv[i],opt_arg,"taucs_run.shift",&opt_shift); understood |= taucs_getopt_double(argv[i],opt_arg,"taucs_run.nrhs",&opt_nrhs); understood |= taucs_getopt_string(argv[i],opt_arg,"taucs_run.params",&gl_parameters); understood |= taucs_getopt_boolean(argv[i],opt_arg,"taucs_run.all1rhs",&opt_all1rhs); if (!understood) taucs_printf("taucs_run: illegal option [%s]\n", argv[i]); } if (opt_sreal ) datatype = TAUCS_SINGLE; if (opt_dreal ) datatype = TAUCS_DOUBLE; if (opt_scomplex) datatype = TAUCS_SCOMPLEX; if (opt_dcomplex) datatype = TAUCS_DCOMPLEX; taucs_logfile(opt_log); if (opt_3d > 0) { if ( opt_3d_small > 0 ) { A = taucs_ccs_generate_mesh3d_random((int)opt_3d_small,(int)opt_3d,(int)opt_3d,opt_3d_rand); } A = taucs_ccs_generate_mesh3d_random((int)opt_3d,(int)opt_3d,(int)opt_3d,opt_3d_rand); if (!A) { taucs_printf("Matrix generation failed\n"); return 1; } datatype = TAUCS_DOUBLE; } if (opt_2d > 0) { A = taucs_ccs_generate_mesh2d((int)opt_2d,opt_2d_type); if (!A) { taucs_printf("Matrix generation failed\n"); return 1; } datatype = TAUCS_DOUBLE; } if (opt_ijv) { switch (datatype) { case TAUCS_SINGLE: A = taucs_ccs_read_ijv (opt_ijv,TAUCS_SYMMETRIC | TAUCS_SINGLE); break; break; case TAUCS_DOUBLE: A = taucs_ccs_read_ijv (opt_ijv,TAUCS_SYMMETRIC | TAUCS_DOUBLE); break; break; case TAUCS_SCOMPLEX: A = taucs_ccs_read_ijv (opt_ijv,TAUCS_HERMITIAN | TAUCS_SCOMPLEX); break; break; case TAUCS_DCOMPLEX: A = taucs_ccs_read_ijv (opt_ijv,TAUCS_HERMITIAN | TAUCS_DCOMPLEX); break; break; default: taucs_printf("taucs_run: incorrect datatype\n"); return 1; break; } } if (opt_ijv_zero) { switch (datatype) { case TAUCS_SINGLE: A = taucs_ccs_read_ijv_zero_based (opt_ijv_zero,TAUCS_SYMMETRIC | TAUCS_SINGLE); break; break; case TAUCS_DOUBLE: A = taucs_ccs_read_ijv_zero_based (opt_ijv_zero,TAUCS_SYMMETRIC | TAUCS_DOUBLE); break; break; case TAUCS_SCOMPLEX: A = taucs_ccs_read_ijv_zero_based(opt_ijv_zero,TAUCS_HERMITIAN | TAUCS_SCOMPLEX); break; break; case TAUCS_DCOMPLEX: A = taucs_ccs_read_ijv_zero_based(opt_ijv_zero,TAUCS_HERMITIAN | TAUCS_DCOMPLEX); break; break; default: taucs_printf("taucs_run: incorrect datatype\n"); return 1; break; } } if (opt_hb) { switch (datatype) { case TAUCS_SINGLE: A = taucs_ccs_read_hb (opt_hb, TAUCS_SINGLE); break; break; case TAUCS_DOUBLE: A = taucs_ccs_read_hb (opt_hb, TAUCS_DOUBLE); break; break; case TAUCS_SCOMPLEX: A = taucs_ccs_read_hb (opt_hb, TAUCS_SCOMPLEX); break; break; case TAUCS_DCOMPLEX: A = taucs_ccs_read_hb (opt_hb, TAUCS_DCOMPLEX); break; break; default: taucs_printf("taucs_run: incorrect datatype\n"); return 1; break; } datatype = A->flags; } if (opt_bin) { A = taucs_ccs_read_binary(opt_bin); } if (!A) { taucs_printf("taucs_run: there is no matrix!\n"); return 1; } if (opt_shift) { int i,j; int ip; if (datatype & TAUCS_DOUBLE) { for (j=0; j<A->n; j++) { int found = 0; for (ip = (A->colptr)[j]; ip < (A->colptr)[j+1]; ip++) { i = (A->rowind)[ip]; if (i == j) { (A->values.d)[ip] += opt_shift; found = 1; break; } } if (!found) { taucs_printf("taucs_run: the matrix is missing a diagonal element so I can't shift\n"); return 1; } } } else { taucs_printf("taucs_run: shift only works on double-precision matrices\n"); return 1; } } taucs_printf("taucs_run: matrix dimentions %d by %d with %d nonzeros\n", A->m, A->n, (A->colptr)[ A->n ]); X = taucs_vec_create((A->n)*(int)opt_nrhs,A->flags); B = taucs_vec_create((A->m)*(int)opt_nrhs,A->flags); Y = taucs_vec_create((A->n)*(int)opt_nrhs,A->flags); Z = taucs_vec_create((A->m)*(int)opt_nrhs,A->flags); if (!X || !B || !Y || !Z) { taucs_printf("taucs_run: vector allocation failed\n"); return 1; } if (!opt_all1rhs) { for(j=0;j<(int)opt_nrhs;j++) { for(i=0; i<A->n; i++) { #ifdef TAUCS_SINGLE_IN_BUILD if (datatype & TAUCS_SINGLE) ((taucs_single*)X)[i+j*(A->n)]=(taucs_single) ((double)rand()/(double)RAND_MAX); #endif #ifdef TAUCS_DOUBLE_IN_BUILD if (datatype & TAUCS_DOUBLE) //((taucs_double*)X)[i+j*(A->n)]=(taucs_double) ((double)rand()/(double)RAND_MAX); ((taucs_double*)X)[i+j*(A->n)]=0.1 + i * 0.01; #endif #ifdef TAUCS_SCOMPLEX_IN_BUILD if (datatype & TAUCS_SCOMPLEX) { taucs_single cre,cim; cre = (taucs_single) ((double)rand()/(double)RAND_MAX); cim = (taucs_single) ((double)rand()/(double)RAND_MAX); ((taucs_scomplex*)X)[i+j*(A->n)] = taucs_ccomplex_create(cre,cim); } #endif #ifdef TAUCS_DCOMPLEX_IN_BUILD if (datatype & TAUCS_DCOMPLEX) { taucs_single zre,zim; zre = (taucs_double) ((double)rand()/(double)RAND_MAX); zim = (taucs_double) ((double)rand()/(double)RAND_MAX); ((taucs_dcomplex*)X)[i+j*(A->n)] = taucs_zcomplex_create(zre,zim); } #endif } } taucs_ccs_times_vec_many(A,X,B,(int)opt_nrhs); } else { for(j=0;j<(int)opt_nrhs;j++) { for(i=0; i<A->m; i++) { #ifdef TAUCS_SINGLE_IN_BUILD if (datatype & TAUCS_SINGLE) ((taucs_single*)B)[i+j*(A->m)]= 1.0; #endif #ifdef TAUCS_DOUBLE_IN_BUILD if (datatype & TAUCS_DOUBLE) ((taucs_double*)B)[i+j*(A->m)]= 1.0; #endif #ifdef TAUCS_SCOMPLEX_IN_BUILD if (datatype & TAUCS_SCOMPLEX) { taucs_single cre,cim; cre = 1.0; cim = 0.0; ((taucs_scomplex*)B)[i+j*(A->m)] = taucs_ccomplex_create(cre,cim); } #endif #ifdef TAUCS_DCOMPLEX_IN_BUILD if (datatype & TAUCS_DCOMPLEX) { taucs_single zre,zim; zre = 1.0; zim = 0.0; ((taucs_dcomplex*)B)[i+j*(A->m)] = taucs_zcomplex_create(zre,zim); } #endif } } } start = taucs_wtime(); rc = taucs_linsolve(A,NULL,(int)opt_nrhs,Y,B,argv,opt_arg); taucs_printf("total solve time is %.2e sec\n", taucs_wtime() - start); if (!opt_all1rhs && opt_nrhs == 1) { taucs_vec_axpby_many(A->n,A->flags,1.0,X,-1.0,Y,Z,(int)opt_nrhs); rerr = taucs_vec_norm2(A->n, A->flags,Z) / taucs_vec_norm2(A->n, A->flags, X); taucs_printf("relative 2-norm of error is %.2e\n", rerr); } rnorm_many(A,Y,B,Z,(int)opt_nrhs); if (opt_nrhs == 1) { double xnorm = taucs_vec_norm2(A->n,A->flags,Y); taucs_printf("2-norm of x is %.2e\n", xnorm); } // Silencing valgrind if (X) taucs_vec_free(A->flags,X); if (B) taucs_vec_free(A->flags,B); if (Y) taucs_vec_free(A->flags,Y); if (Z) taucs_vec_free(A->flags,Z); taucs_ccs_free(A); return 0; }
int main(int argc, char* argv[]) { int rc; int i; taucs_ccs_matrix* A = NULL; void* X; void* B; void* Y; void* Z; void* opt_arg[] = { NULL }; char* opt_ijv = NULL; char* opt_hb = NULL; char* opt_log = "stdout"; double opt_3d = -1.0; double opt_2d = -1.0; char* opt_2d_type = "dirichlet"; int opt_sreal = 0; int opt_dreal = 0; int opt_scomplex = 0; int opt_dcomplex = 0; int datatype = TAUCS_DOUBLE; for (i=0; argv[i]; i++) { int understood = FALSE; understood |= taucs_getopt_boolean(argv[i],opt_arg,"taucs_run.sreal",&opt_sreal); understood |= taucs_getopt_boolean(argv[i],opt_arg,"taucs_run.dreal",&opt_dreal); understood |= taucs_getopt_boolean(argv[i],opt_arg,"taucs_run.scomplex",&opt_scomplex); understood |= taucs_getopt_boolean(argv[i],opt_arg,"taucs_run.dcomplex",&opt_dcomplex); understood |= taucs_getopt_string(argv[i],opt_arg,"taucs_run.ijv",&opt_ijv); understood |= taucs_getopt_string(argv[i],opt_arg,"taucs_run.hb", &opt_hb ); understood |= taucs_getopt_string(argv[i],opt_arg,"taucs_run.log",&opt_log); understood |= taucs_getopt_double(argv[i],opt_arg,"taucs_run.mesh3d",&opt_3d); understood |= taucs_getopt_double(argv[i],opt_arg,"taucs_run.mesh2d",&opt_2d); understood |= taucs_getopt_string(argv[i],opt_arg,"taucs_run.mesh2d.type",&opt_2d_type); if (!understood) taucs_printf("taucs_run: illegal option [%s]\n", argv[i]); } if (opt_sreal ) datatype = TAUCS_SINGLE; if (opt_dreal ) datatype = TAUCS_DOUBLE; if (opt_scomplex) datatype = TAUCS_SCOMPLEX; if (opt_dcomplex) datatype = TAUCS_DCOMPLEX; taucs_logfile(opt_log); if (opt_3d > 0) { A = taucs_ccs_generate_mesh3d((int)opt_3d,(int)opt_3d,(int)opt_3d); if (!A) { taucs_printf("Matrix generation failed\n"); return 1; } datatype = TAUCS_DOUBLE; } if (opt_2d > 0) { A = taucs_ccs_generate_mesh2d((int)opt_2d,opt_2d_type); if (!A) { taucs_printf("Matrix generation failed\n"); return 1; } datatype = TAUCS_DOUBLE; } if (opt_ijv) { switch (datatype) { case TAUCS_SINGLE: A = taucs_ccs_read_ijv (opt_ijv,TAUCS_SYMMETRIC | TAUCS_SINGLE); break; break; case TAUCS_DOUBLE: A = taucs_ccs_read_ijv (opt_ijv,TAUCS_SYMMETRIC | TAUCS_DOUBLE); break; break; case TAUCS_SCOMPLEX: A = taucs_ccs_read_ijv (opt_ijv,TAUCS_HERMITIAN | TAUCS_SCOMPLEX); break; break; case TAUCS_DCOMPLEX: A = taucs_ccs_read_ijv (opt_ijv,TAUCS_HERMITIAN | TAUCS_DCOMPLEX); break; break; default: taucs_printf("taucs_run: incorrect datatype\n"); return 1; break; } } if (opt_hb) { switch (datatype) { case TAUCS_SINGLE: A = taucs_ccs_read_hb (opt_hb, TAUCS_SINGLE); break; break; case TAUCS_DOUBLE: A = taucs_ccs_read_hb (opt_hb, TAUCS_DOUBLE); break; break; case TAUCS_SCOMPLEX: A = taucs_ccs_read_hb (opt_hb, TAUCS_SCOMPLEX); break; break; case TAUCS_DCOMPLEX: A = taucs_ccs_read_hb (opt_hb, TAUCS_DCOMPLEX); break; break; default: taucs_printf("taucs_run: incorrect datatype\n"); return 1; break; } datatype = A->flags; } if (!A) { taucs_printf("taucs_run: there is no matrix!\n"); return 1; } X = taucs_vec_create(A->n,A->flags); B = taucs_vec_create(A->n,A->flags); Y = taucs_vec_create(A->n,A->flags); Z = taucs_vec_create(A->n,A->flags); if (!X || !B || !Y || !Z) { taucs_printf("taucs_run: vector allocation failed\n"); return 1; } for(i=0; i<A->n; i++) { if (datatype & TAUCS_SINGLE) ((taucs_single*)X)[i]=(taucs_single) ((double)rand()/(double)RAND_MAX); if (datatype & TAUCS_DOUBLE) ((taucs_double*)X)[i]=(taucs_double) ((double)rand()/(double)RAND_MAX); if (datatype & TAUCS_SCOMPLEX) { taucs_single cre,cim; cre = (taucs_single) ((double)rand()/(double)RAND_MAX); cim = (taucs_single) ((double)rand()/(double)RAND_MAX); ((taucs_scomplex*)X)[i] = taucs_ccomplex_create(cre,cim); } if (datatype & TAUCS_DCOMPLEX) { taucs_single zre,zim; zre = (taucs_double) ((double)rand()/(double)RAND_MAX); zim = (taucs_double) ((double)rand()/(double)RAND_MAX); ((taucs_dcomplex*)X)[i] = taucs_zcomplex_create(zre,zim); } } taucs_ccs_times_vec(A,X,B); rc = taucs_linsolve(A,NULL,1,Y,B,argv,opt_arg); rnorm(A,Y,B,Z); return 0; }