void addeval_A(field alpha, void *matrix, pcavector x, pavector y) { struct _eval_A *eval = (struct _eval_A *) matrix; field beta; beta = -I * alpha * eval->eta; switch (eval->KMtype) { case AMATRIX: addeval_amatrix_avector(alpha, (pamatrix) eval->KM, x, y); break; case HMATRIX: addeval_hmatrix_avector(alpha, (phmatrix) eval->KM, x, y); break; case H2MATRIX: addeval_h2matrix_avector(alpha, (ph2matrix) eval->KM, x, y); break; default: printf("ERROR: unknown matrix type!\n"); abort(); break; } switch (eval->Vtype) { case AMATRIX: addeval_amatrix_avector(beta, (pamatrix) eval->V, x, y); break; case HMATRIX: addeval_hmatrix_avector(beta, (phmatrix) eval->V, x, y); break; case H2MATRIX: addeval_h2matrix_avector(beta, (ph2matrix) eval->V, x, y); break; default: printf("ERROR: unknown matrix type!\n"); abort(); break; } }
void mvm_hmatrix_avector(phmatrix hm, char trans, pcavector x, pavector y) { int rsons = hm->rsons; int csons = hm->csons; if(hm->f) { addeval_amatrix_avector(1.0, hm->f, h2_col_major, trans, x, 1.0, y); } else if (hm->r) { addeval_rkmatrix_avector(1.0, hm->r, trans, x, 1.0, y); } else { assert(hm->r==NULL && hm->f==NULL); if (h2_ntrans == trans) { int xoffset = 0; for (int j=0;j<csons;++j) { pavector xsub = new_sub_avector(x, hm->son[j*rsons]->cc->size, xoffset); int yoffset = 0; for (int i=0;i<hm->rsons;++i) { pavector ysub = new_sub_avector(y, hm->son[i]->rc->size, yoffset); mvm_hmatrix_avector(hm->son[i+j*rsons], trans, xsub, ysub); yoffset += hm->son[i]->rc->size; uninit_avector(ysub); } assert(yoffset == hm->rc->size); xoffset += hm->son[j*rsons]->cc->size; uninit_avector(xsub); } assert(xoffset == hm->cc->size); } else { int xoffset = 0; for (int i=0;i<rsons;++i) { pavector xsub = new_sub_avector(x, hm->son[i]->rc->size, xoffset); int yoffset = 0; for (int j=0;j<csons;++j) { pavector ysub = new_sub_avector(y, hm->son[j*rsons]->cc->size, yoffset); mvm_hmatrix_avector(hm->son[i+j*rsons], trans, xsub, ysub); yoffset += hm->son[j*rsons]->cc->size; uninit_avector(ysub); } assert(yoffset == hm->cc->size); xoffset += hm->son[i]->rc->size; uninit_avector(xsub); } assert(xoffset == hm->rc->size); } } }
static void check_triangularsolve(bool lower, bool unit, bool atrans, pcamatrix a, bool xtrans) { uint n = a->rows; amatrix xtmp, btmp; pamatrix x, b; avector xvtmp, bvtmp; pavector xv, bv; real error; assert(n == a->cols); /* * amatrix */ x = init_amatrix(&xtmp, n, n); random_amatrix(x); b = init_zero_amatrix(&btmp, n, n); if (xtrans) addmul_amatrix(1.0, false, x, !atrans, a, b); else addmul_amatrix(1.0, atrans, a, false, x, b); triangularsolve_amatrix(lower, unit, atrans, a, xtrans, b); add_amatrix(-1.0, false, x, b); error = norm2_amatrix(b) / norm2_amatrix(x); (void) printf("Checking amatrix triangularsolve\n" " (lower=%s, unit=%s, atrans=%s, xtrans=%s)\n" " Accuracy %g, %sokay\n", (lower ? "tr" : "fl"), (unit ? "tr" : "fl"), (atrans ? "tr" : "fl"), (xtrans ? "tr" : "fl"), error, (IS_IN_RANGE(0.0, error, 1.0e-14) ? "" : " NOT ")); if (!IS_IN_RANGE(0.0, error, 1.0e-14)) problems++; copy_amatrix(false, x, b); triangulareval_amatrix(lower, unit, atrans, a, xtrans, b); triangularsolve_amatrix(lower, unit, atrans, a, xtrans, b); add_amatrix(-1.0, false, x, b); error = norm2_amatrix(b) / norm2_amatrix(x); (void) printf("Checking amatrix triangulareval/triangularsolve\n" " (lower=%s, unit=%s, atrans=%s, xtrans=%s):\n" " Accuracy %g, %sokay\n", (lower ? "tr" : "fl"), (unit ? "tr" : "fl"), (atrans ? "tr" : "fl"), (xtrans ? "tr" : "fl"), error, (IS_IN_RANGE(0.0, error, 1.0e-14) ? "" : " NOT ")); if (!IS_IN_RANGE(0.0, error, 1.0e-14)) problems++; /* * avector */ xv = init_avector(&xvtmp, n); random_avector(xv); bv = init_avector(&bvtmp, n); clear_avector(bv); if (atrans) { addevaltrans_amatrix_avector(1.0, a, xv, bv); } else { addeval_amatrix_avector(1.0, a, xv, bv); } triangularsolve_amatrix_avector(lower, unit, atrans, a, bv); add_avector(-1.0, xv, bv); error = norm2_avector(bv) / norm2_avector(xv); (void) printf("Checking avector triangularsolve\n" " (lower=%s, unit=%s, atrans=%s)\n" " Accuracy %g, %sokay\n", (lower ? "tr" : "fl"), (unit ? "tr" : "fl"), (atrans ? "tr" : "fl"), error, (IS_IN_RANGE(0.0, error, 1.0e-14) ? "" : " NOT ")); if (!IS_IN_RANGE(0.0, error, 1.0e-14)) problems++; copy_avector(xv, bv); triangulareval_amatrix_avector(lower, unit, atrans, a, bv); triangularsolve_amatrix_avector(lower, unit, atrans, a, bv); add_avector(-1.0, xv, bv); error = norm2_avector(bv) / norm2_avector(xv); (void) printf("Checking avector triangulareval/triangularsolve\n" " (lower=%s, unit=%s, atrans=%s):\n" " Accuracy %g, %sokay\n", (lower ? "tr" : "fl"), (unit ? "tr" : "fl"), (atrans ? "tr" : "fl"), error, (IS_IN_RANGE(0.0, error, 1.0e-14) ? "" : " NOT ")); if (!IS_IN_RANGE(0.0, error, 1.0e-14)) problems++; uninit_amatrix(b); uninit_amatrix(x); uninit_avector(bv); uninit_avector(xv); }
void fastaddeval_hmatrix_avector(field alpha, phmatrix hm, char trans, pcavector x, field beta, pavector y) { pavector newy = new_avector(y->dim); mvm_hmatrix_avector(hm, trans, x, newy); add_avec(alpha, newy, beta, y); /* for (int i=0;i<y->dim;i++) { y->v[i] = alpha * newy->v[i] + beta *y->v[i]; } */ #if 0 if (hm->f) { addeval_amatrix_avector(alpha, hm->f, h2_col_major, trans, x, 0, y); } else if (hm->r) { addeval_rkmatrix_avector(alpha, hm->r, trans, x, 0, y); } else { assert(hm->r==NULL && hm->f==NULL); int yoffset = 0; if (CblasNoTrans == trans) { for (int i=0;i<hm->rsons;i++) { pavector ysub = new_sub_avector(y, hm->son[i]->rc->size, yoffset); pavector ytemp = new_avector(hm->son[i]->rc->size); int xoffset = 0; for (int j=0;j<hm->csons;j++) { pavector xsub = new_sub_avector((pavector)x, hm->son[j*hm->rsons+i]->cc->size, xoffset); fastaddeval_hmatrix_avector(alpha, hm->son[j*hm->rsons+i], trans, xsub, beta, ytemp); add_avec(alpha, ytemp, 1, ysub); xoffset += hm->son[j*hm->rsons+i]->cc->size; uninit_avector(xsub); // in urgent need to be optimized } yoffset += hm->son[i]->rc->size; uninit_avector(ysub); uninit_avector(ytemp); //free(ysub); } } else if (CblasTrans == trans || CblasConjTrans == trans) { for (int i=0;i<hm->csons;i++) { pavector ysub = new_sub_avector(y, hm->son[i*hm->rsons]->cc->size, yoffset); pavector ytemp = new_avector(hm->son[i*hm->rsons]->cc->size); int xoffset = 0; for (int j=0;j<hm->rsons;j++) { pavector xsub = new_sub_avector((pavector)x, hm->son[i*hm->rsons+j]->rc->size, xoffset); fastaddeval_hmatrix_avector(alpha, hm->son[i*hm->rsons+j], trans, xsub, beta, ytemp); add_avec(alpha, ytemp, 1, ysub); xoffset += hm->son[i*hm->rsons+j]->rc->size; uninit_avector(xsub); } yoffset += hm->son[i*hm->rsons]->cc->size; uninit_avector(ysub); uninit_avector(ytemp); } } else { cout<<"Error! Clarify the Trans Type\n"<<endl; } } #endif }