1 #include <../../nrnconf.h> 43 static char rcsid[] =
"iternsym.c,v 1.1 1997/12/04 17:55:27 hines Exp";
64 Real alpha, beta, nres, rho, old_rho, sigma, inner;
68 if (!ip->Ax || !ip->b || !r0)
74 if ( r0->
dim != ip->b->dim )
77 if ( ip->eps <= 0.0 ) ip->eps =
MACHEPS;
97 if (ip->x->dim != ip->b->dim)
99 ip->Ax(ip->A_par,ip->x,v);
102 (ip->Bx)(ip->B_par,v,r);
104 else v_sub(ip->b,v,r);
107 ip->x =
v_get(ip->b->dim);
108 ip->shared_x =
FALSE;
109 if (ip->Bx) (ip->Bx)(ip->B_par,ip->b,r);
117 for (ip->steps = 0; ip->steps <= ip->limit; ip->steps++) {
121 if (ip->steps == 0) ip->init_res = nres;
123 if (ip->info) ip->info(ip,nres,r,
VNULL);
124 if ( ip->stop_crit(ip,nres,r,
VNULL) )
break;
127 if ( old_rho == 0.0 )
134 (ip->Ax)(ip->A_par,p,q);
136 (ip->Bx)(ip->B_par,q,z);
148 (ip->Ax)(ip->A_par,v,u);
150 (ip->Bx)(ip->B_par,u,z);
222 Real rho, rho_bar, rho_max, theta, nres;
226 if ( ! ip || ! ip->b || !ip->Ax || !ip->ATx )
228 if ( ip->x == ip->b )
230 if (!ip->stop_crit || !ip->x)
233 if ( ip->eps <= 0.0 ) ip->eps =
MACHEPS;
248 if (ip->x !=
VNULL) {
249 ip->Ax(ip->A_par,ip->x,u);
253 ip->x =
v_get(ip->b->dim);
254 ip->shared_x =
FALSE;
259 if ( beta == 0.0 )
return ip->x;
262 (ip->ATx)(ip->AT_par,u,v);
264 if ( alpha == 0.0 )
return ip->x;
272 for (ip->steps = 0; ip->steps <= ip->limit; ip->steps++) {
275 (ip->Ax)(ip->A_par,v,tmp);
282 (ip->ATx)(ip->AT_par,u,tmp);
287 rho =
sqrt(rho_bar*rho_bar+beta*beta);
303 nres =
fabs(phi_bar*alpha*c)*rho_max;
305 if (ip->info) ip->info(ip,nres,w,
VNULL);
306 if (ip->steps == 0) ip->init_res = nres;
307 if ( ip->stop_crit(ip,nres,w,
VNULL) )
break;
360 if ( ! ip->Ax || ! Q || ! ip->x )
364 if ( Q->
n != ip->x->dim || Q->
m != ip->k )
392 for ( i = 0; i < ip->k; i++ )
395 u = (ip->Ax)(ip->A_par,&v,u);
396 for (j = 0; j <=
i; j++) {
412 for (j = 0; j <=
i; j++) {
457 if ( ! ip->Ax || ! Q || ! ip->x )
461 if ( Q->
n != ip->x->dim || Q->
m != ip->k )
484 for ( i = 0; i < ip->k; i++ )
487 u = (ip->Ax)(ip->A_par,&v,u);
488 for (j = 0; j <=
i; j++) {
562 for (j=0; j <=
i; j++) {
565 ip->Ax(ip->A_par,&vt,&vt1);
570 for (j=0; j <
i; j++)
571 R1->
me[i+1][j] = 0.0;
572 R1->
me[i+1][i] = h_val;
574 for (j = 0; j <=
i; j++) {
581 printf(
" %d. ||Q*A*Q^T - H|| = %g [cf. MACHEPS = %g]\n",
588 for (j=0; j <=
i; j++)
612 if ( ! ip->Ax || ! ip->b )
614 if ( ! ip->stop_crit )
618 if (ip->x !=
VNULL && ip->x->dim != ip->b->dim)
620 if (ip->eps <= 0.0) ip->eps =
MACHEPS;
639 if (ip->x ==
VNULL) {
640 ip->x =
v_get(ip->b->dim);
641 ip->shared_x =
FALSE;
653 for (ip->steps = 0; ip->steps < ip->limit; ) {
657 ip->Ax(ip->A_par,ip->x,u);
662 (ip->Bx)(ip->B_par,u,z);
667 if (ip->steps == 0) {
684 for ( i = 0; i < ip->k && ip->steps < ip->limit; i++ ) {
687 (ip->Ax)(ip->A_par,&v,u);
690 (ip->Bx)(ip->B_par,u,z);
697 for (j = 0; j <=
i; j++) {
705 r->ve[i+1] = nres =
v_norm2(&v1);
707 for (j = 0; j <
i; j++)
708 rot_vec(r,j,j+1,givc->ve[j],givs->
ve[j],r);
718 for (j = 0; j <=
i; j++) {
725 for (j = 0; j <
i; j++)
726 rot_vec(r,j,j+1,givc->ve[j],givs->
ve[j],r);
736 r->ve[i+1] =
sqrt(nres);
742 for (j = 0; j <
i; j++)
743 rot_vec(r,j,j+1,givc->ve[j],givs->
ve[j],r);
744 givens(r->ve[i],r->ve[i+1],&givc->ve[i],&givs->
ve[i]);
745 rot_vec(r,i,i+1,givc->ve[i],givs->
ve[i],r);
746 rot_vec(rhs,i,i+1,givc->ve[i],givs->
ve[i],rhs);
750 nres =
fabs((
double) rhs->ve[i+1]);
760 if (i >= ip->k) i = ip->k - 1;
772 for (j = 0; j <=
i; j++) {
852 for (k=1; k <=
i; k++)
853 for (j=1; j <=
i; j++) {
858 for (j=1; j <=
i; j++)
865 ip->Ax(ip->A_par,ip->x,r);
869 ip->Bx(ip->B_par,r,r1);
875 for (j = 1; j <=
i; j++) {
880 printf(
" ! (mgcr:) max_j (r,Ap_j) = %g\n",sm);
907 if (! ip->Ax || ! ip->b || ! ip->stop_crit)
912 if ( ip->x && ip->x->dim != ip->b->dim)
914 if (ip->eps <= 0.0) ip->eps =
MACHEPS;
940 ip->x =
v_get(ip->b->dim);
941 ip->shared_x =
FALSE;
950 for (ip->steps = 0; ip->steps < ip->limit; ) {
951 (*ip->Ax)(ip->A_par,ip->x,As);
957 (*ip->Bx)(ip->B_par,As,z);
966 if (ip->steps == 0) {
968 if (ip->info) (*ip->info)(ip,nres,As,rr);
969 ip->init_res =
fabs(nres);
982 for (i = 0; i < ip->k && ip->steps < ip->limit; i++) {
986 (*ip->Ax)(ip->A_par,&v,As);
989 (*ip->Bx)(ip->B_par,As,z);
996 for (j = 0; j <= i-1; j++) {
1007 if ( nres <= MACHEPS*ip->
init_res) {
1020 for (j = 0; j <= i-1; j++) {
1026 for (j = 0; j <= i-1; j++)
1027 nres -= beta->
ve[j]*beta->
ve[j];
1044 for (j = 0; j <= i-1; j++)
1045 alpha->
ve[i] -= beta->
ve[j]*alpha->
ve[j];
1046 alpha->
ve[i] /= beta->
ve[i];
1062 nres = alpha->
ve[
i]/dd;
1066 nres = 1.0 - nres*nres;
1068 nres =
sqrt((
double) -nres);
1069 if (ip->info) (*ip->info)(ip,-dd*nres,
VNULL,
VNULL);
1072 dd *=
sqrt((
double) nres);
1075 if (ip->info) (*ip->info)(ip,dd,
VNULL,
VNULL);
1084 if (i >= ip->k) i = ip->k - 1;
1089 Usolve(H,alpha,alpha,0.0);
1091 for (j = 0; j <=
i; j++) {
1154 Real alpha, beta, inner, old_inner, nres;
1159 if (!ip->Ax || ! ip->ATx || !ip->b)
1161 if ( ip->x == ip->b )
1166 if ( ip->eps <= 0.0 ) ip->eps =
MACHEPS;
1180 if (ip->x->dim != ip->b->dim)
1182 ip->Ax(ip->A_par,ip->x,p);
1186 ip->x =
v_get(ip->b->dim);
1187 ip->shared_x =
FALSE;
1192 (ip->Bx)(ip->B_par,rr1,p);
1195 (ip->ATx)(ip->AT_par,rr1,r);
1199 for ( ip->steps = 0; ip->steps <= ip->limit; ip->steps++ )
1203 (ip->Bx)(ip->B_par,r,z);
1209 if (ip->info) ip->info(ip,nres,r,rr1);
1210 if (ip->steps == 0) ip->init_res = nres;
1211 if ( ip->stop_crit(ip,nres,r,rr1) )
break;
1215 beta = inner/old_inner;
1224 (ip->Ax)(ip->A_par,p,q);
1226 (ip->Bx)(ip->B_par,q,z);
1227 (ip->ATx)(ip->AT_par,z,q);
1231 (ip->ATx)(ip->AT_par,q,z);
MAT * mmtr_mlt(MAT *A, MAT *B, MAT *OUT)
MAT * rot_rows(MAT *mat, u_int i, u_int k, double c, double s, MAT *out)
double max(double a, double b)
VEC * iter_gmres(ITER *ip)
VEC * iter_splsqr(SPMAT *A, VEC *b, double tol, VEC *x, int limit, int *steps)
VEC * iter_lsqr(ITER *ip)
static Object ** v_resize(void *v)
#define m_set_val(A, i, j, val)
static void test_gmres(ITER *ip, int i, MAT *Q, MAT *R, VEC *givc, VEC *givs, double h_val)
double m_norm_inf(MAT *A)
static philox4x32_key_t k
MAT * iter_sparnoldi(SPMAT *A, VEC *x0, int m, Real *h_rem, MAT *Q, MAT *H)
ITER * iter_get(int lenb, int lenx)
VEC * iter_spgmres(SPMAT *A, SPMAT *B, VEC *b, double tol, VEC *x, int k, int limit, int *steps)
static double done(void *v)
static Object ** v_sub(void *v1)
VEC * iter_spmgcr(SPMAT *A, SPMAT *B, VEC *b, double tol, VEC *x, int k, int limit, int *steps)
int const size_t const size_t n
void givens(double x, double y, Real *c, Real *s)
VEC *(* Fun_Ax)(void *, VEC *, VEC *)
VEC * v_mltadd(VEC *, VEC *, double, VEC *)
#define set_col(mat, col, vec)
VEC * iter_cgne(ITER *ip)
VEC * sv_mlt(double, VEC *, VEC *)
VEC * spCHsolve(SPMAT *, VEC *, VEC *)
VEC * sp_mv_mlt(SPMAT *A, VEC *x, VEC *out)
static double v_get(void *v)
VEC * Usolve(MAT *A, VEC *b, VEC *x, double diag_val)
VEC * iter_mgcr(ITER *ip)
VEC * rot_vec(VEC *x, u_int i, u_int k, double c, double s, VEC *out)
VEC * iter_cgs(ITER *ip, VEC *r0)
MAT * iter_arnoldi_iref(ITER *ip, Real *h_rem, MAT *Q, MAT *H)
static Object ** v_add(void *v1)
static Object ** m_resize(void *v)
#define MEM_STAT_REG(var, type)
static Object ** m_zero(void *v)
#define error(err_num, fn_name)
void(* Fun_info)(ITER *, double, VEC *, VEC *)
VEC * iter_spcgs(SPMAT *A, SPMAT *B, VEC *b, VEC *r0, double tol, VEC *x, int limit, int *steps)
MAT * iter_arnoldi(ITER *ip, Real *h_rem, MAT *Q, MAT *H)
VEC * iter_spcgne(SPMAT *A, SPMAT *B, VEC *b, double eps, VEC *x, int limit, int *steps)
MAT * m_sub(MAT *mat1, MAT *mat2, MAT *out)
static void test_mgcr(ITER *ip, int i, MAT *Q, MAT *R)
VEC * sp_vm_mlt(SPMAT *A, VEC *x, VEC *out)