1 #include <../../nrnconf.h> 38 static char rcsid[] =
"symmeig.c,v 1.1 1997/12/04 17:55:57 hines Exp";
42 #define SQRT2 1.4142135623730949 43 #define sgn(x) ( (x) >= 0 ? 1 : -1 ) 53 int i, i_min, i_max,
n, split;
55 Real b_sqr, bk, ak1, bk1, ak2, bk2, z;
56 Real c, c2, cs,
s, s2, d, mu;
60 if ( a->dim != b->dim + 1 || ( Q && Q->
m != a->dim ) )
62 if ( Q && Q->
m != Q->
n )
66 a_ve = a->ve; b_ve = b->ve;
74 for ( i = i_min; i < n-1; i++ )
92 d = (a_ve[i_max-1] - a_ve[i_max])/2;
93 b_sqr = b_ve[i_max-1]*b_ve[i_max-1];
94 mu = a_ve[i_max] - b_sqr/(d +
sgn(d)*
sqrt(d*d+b_sqr));
98 givens(a_ve[i_min]-mu,b_ve[i_min],&c,&s);
102 { c2 = c*
c; s2 = 1-c2; }
104 { s2 = s*
s; c2 = 1-s2; }
106 ak1 = c2*a_ve[i_min]+s2*a_ve[i_min+1]-2*cs*b_ve[i_min];
107 bk1 = cs*(a_ve[i_min]-a_ve[i_min+1]) +
109 ak2 = s2*a_ve[i_min]+c2*a_ve[i_min+1]+2*cs*b_ve[i_min];
110 bk2 = ( i_min < i_max-1 ) ? c*b_ve[i_min+1] : 0.0;
111 z = ( i_min < i_max-1 ) ? -s*b_ve[i_min+1] : 0.0;
115 if ( i_min < i_max-1 )
123 for ( i = i_min+1; i < i_max; i++ )
126 givens(b_ve[i-1],z,&c,&s);
132 { c2 = c*
c; s2 = 1-c2; }
134 { s2 = s*
s; c2 = 1-s2; }
136 bk = c*b_ve[i-1] - s*z;
137 ak1 = c2*a_ve[
i]+s2*a_ve[i+1]-2*cs*b_ve[
i];
138 bk1 = cs*(a_ve[
i]-a_ve[i+1]) +
140 ak2 = s2*a_ve[
i]+c2*a_ve[i+1]+2*cs*b_ve[
i];
141 bk2 = ( i+1 < i_max ) ? c*b_ve[i+1] : 0.0;
142 z = ( i+1 < i_max ) ? -s*b_ve[i+1] : 0.0;
143 a_ve[
i] = ak1; a_ve[i+1] = ak2;
156 for ( i = i_min; i < i_max; i++ )
159 { b_ve[
i] = 0.0; split =
TRUE; }
186 if ( ! out || out->
dim !=
A->m )
203 for ( i = 0; i <
A->m - 1; i++ )
206 b->
ve[
i] = tmp->
me[
i][i+1];
VEC * trieig(VEC *a, VEC *b, MAT *Q)
MAT * Hfactor(MAT *A, VEC *diag, VEC *beta)
static Object ** v_resize(void *v)
MAT * rot_cols(MAT *mat, u_int i, u_int k, double c, double s, MAT *out)
VEC * symmeig(MAT *A, MAT *Q, VEC *out)
MAT * makeHQ(MAT *H, VEC *diag, VEC *beta, MAT *Qout)
int const size_t const size_t n
void givens(double x, double y, Real *c, Real *s)
static Object ** m_resize(void *v)
#define MEM_STAT_REG(var, type)
#define error(err_num, fn_name)