1 #include <../../nrnconf.h>
43 static char rcsid[] =
"itersym.c,v 1.1 1997/12/04 17:55:29 hines Exp";
78 ip->
B_par = (
void *)LLT;
86 if (steps) *steps = ip->
steps;
104 if (!ip->Ax || !ip->b)
106 if ( ip->x == ip->b )
111 if ( ip->eps <= 0.0 )
129 if (ip->x !=
VNULL) {
130 if (ip->x->dim != ip->b->dim)
132 ip->Ax(ip->A_par,ip->x,
p);
136 ip->x =
v_get(ip->b->dim);
137 ip->shared_x =
FALSE;
142 for ( ip->steps = 0; ip->steps <= ip->limit; ip->steps++ )
145 (ip->Bx)(ip->B_par,r,rr);
149 if (ip->info) ip->info(ip,nres,r,rr);
150 if (ip->steps == 0) ip->init_res = nres;
151 if ( ip->stop_crit(ip,nres,r,rr) )
break;
155 beta = inner/old_inner;
164 (ip->Ax)(ip->A_par,
p,
q);
195 if ( ! ip->Ax || ! ip->x || ! a || ! b )
199 if ( Q && ( Q->
n < ip->x->dim || Q->
m < ip->k ) )
225 (ip->Ax)(ip->A_par,w,
v);
227 for (
j = 0;
j < ip->k;
j++ )
247 (ip->Ax)(ip->A_par,w,tmp);
295 for (
i = 0;
i < a->
dim;
i++ )
301 mant =
frexp(mant,&tmp_expt);
306 for (
i = 0;
i < a->
dim;
i++ )
308 tmp_fctr = a->
ve[
i] - offset;
309 tmp_fctr += (tmp_fctr > 0.0 ) ? -
MACHEPS*offset :
311 mant *=
frexp(tmp_fctr,&tmp_expt);
315 mant =
frexp(mant,&tmp_expt);
320 mant =
frexp(mant,&tmp_expt);
333 Real mant, mu, tmp_fctr;
338 if ( k < 0 || k >= a->
dim )
344 for (
i = 0;
i < a->
dim;
i++ )
348 tmp_fctr = a->
ve[
i] - mu;
350 mant *=
frexp(tmp_fctr,&tmp_expt);
354 mant =
frexp(mant,&tmp_expt);
358 mant =
frexp(mant,&tmp_expt);
371 return (tmp > 0 ? 1 : tmp < 0 ? -1: 0);
385 Real beta, pb_mant, det_mant, det_mant1, det_mant2;
386 int i, pb_expt, det_expt, det_expt1, det_expt2;
390 if ( ! ip->Ax || ! ip->x )
406 pb_mant =
product(b,(
double)0.0,&pb_expt);
416 for (
i = 0;
i < a2->dim - 1;
i++ )
418 a2->ve[
i] = a->
ve[
i+1];
419 b2->ve[
i] = b->
ve[
i+1];
421 a2->ve[a2->dim-1] = a->
ve[a2->dim];
437 for (
i = 0;
i < a->
dim;
i++ )
440 det_mant2 =
product(a2,(
double)a->
ve[
i],&det_expt2);
445 if ( det_mant1 == 0.0 )
447 err_est->
ve[
i] = 0.0;
450 else if ( det_mant2 == 0.0 )
452 err_est->
ve[
i] = HUGE;
455 if ( (det_expt1 + det_expt2) % 2 )
457 det_mant =
sqrt(2.0*
fabs(det_mant1*det_mant2));
459 det_mant =
sqrt(
fabs(det_mant1*det_mant2));
460 det_expt = (det_expt1+det_expt2)/2;
462 ldexp(pb_mant/det_mant,pb_expt-det_expt));
511 if (!ip->Ax || !ip->b)
513 if ( ip->x == ip->b )
518 if ( ip->eps <= 0.0 )
536 if (ip->x !=
VNULL) {
537 if (ip->x->dim != ip->b->dim)
539 ip->Ax(ip->A_par,ip->x,
p);
543 ip->x =
v_get(ip->b->dim);
544 ip->shared_x =
FALSE;
548 if (ip->Bx) (ip->Bx)(ip->B_par,r,
p);
553 if (ip->info) ip->info(ip,nres,r,
p);
554 if ( nres == 0.0)
return ip->x;
556 for ( ip->steps = 0; ip->steps <= ip->limit; ip->steps++ )
558 ip->Ax(ip->A_par,
p,
q);
569 ip->Bx(ip->B_par,r,z);
579 if (ip->info) ip->info(ip,nres,r,z);
580 if (ip->steps == 0) ip->init_res = nres;
581 if ( ip->stop_crit(ip,nres,r,z) )
break;
#define error(err_num, fn_name)
void warning(const char *s, const char *t)
void(* Fun_info)(ITER *, double, VEC *, VEC *)
VEC *(* Fun_Ax)(void *, VEC *, VEC *)
ITER * iter_get(int lenb, int lenx)
VEC * spCHsolve(SPMAT *, VEC *, VEC *)
void iter_lanczos(ITER *ip, VEC *a, VEC *b, Real *beta2, MAT *Q)
static int dbl_cmp(Real *x, Real *y)
static double product2(VEC *a, int k, int *expt)
void iter_splanczos(SPMAT *A, int m, VEC *x0, VEC *a, VEC *b, Real *beta2, MAT *Q)
VEC * iter_splanczos2(SPMAT *A, int m, VEC *x0, VEC *evals, VEC *err_est)
VEC * iter_spcg(SPMAT *A, SPMAT *LLT, VEC *b, double eps, VEC *x, int limit, int *steps)
VEC * trieig(VEC *, VEC *, MAT *)
VEC * iter_lanczos2(ITER *ip, VEC *evals, VEC *err_est)
static double product(VEC *a, double offset, int *expt)
static Object ** v_add(void *v1)
static Object ** v_sub(void *v1)
static double v_get(void *v)
static Object ** v_resize(void *v)
static Object ** m_zero(void *v)
#define set_row(mat, row, vec)
VEC * v_mltadd(VEC *, VEC *, double, VEC *)
VEC * sv_mlt(double, VEC *, VEC *)
#define MEM_STAT_REG(var, type)
static philox4x32_key_t k
VEC * sp_mv_mlt(SPMAT *A, VEC *x, VEC *out)