1 #include <../../nrnconf.h> 40 static char rcsid[] =
"zschur.c,v 1.1 1997/12/04 17:56:16 hines Exp";
42 #define is_zero(z) ((z).re == 0.0 && (z).im == 0.0) 43 #define b2s(t_or_f) ((t_or_f) ? "TRUE" : "FALSE") 52 int i,
j, iter,
k, k_min, k_max, k_tmp,
n, split;
54 complex det, discrim, lambda, lambda0, lambda1,
s, sum, ztmp;
61 if (
A->m !=
A->n || ( Q && Q->m != Q->n ) )
63 if ( Q !=
ZMNULL && Q->m !=
A->m )
74 k_min = 0; A_me =
A->me;
81 for ( k = k_min; k < k_max; k++ )
93 split =
FALSE; iter = 0;
103 a00 = A_me[k_tmp][k_tmp];
104 a01 = A_me[k_tmp][k_max];
105 a10 = A_me[k_max][k_tmp];
106 a11 = A_me[k_max][k_max];
107 ztmp.
re = 0.5*(a00.
re - a11.
re);
108 ztmp.
im = 0.5*(a00.
im - a11.
im);
110 sum.
re = 0.5*(a00.
re + a11.
re);
111 sum.
im = 0.5*(a00.
im + a11.
im);
112 lambda0 =
zadd(sum,discrim);
113 lambda1 =
zsub(sum,discrim);
118 lambda.
re = lambda.
im = 0.0;
120 else if (
zabs(lambda0) >
zabs(lambda1) )
121 lambda =
zdiv(det,lambda0);
123 lambda =
zdiv(det,lambda1);
126 if ( (iter % 10) == 0 )
128 lambda.
re += iter*0.02;
129 lambda.
im += iter*0.02;
135 x =
zsub(
A->me[k_min][k_min],lambda);
136 y =
A->me[k_min+1][k_min];
139 for ( k = k_min; k <= k_max-1; k++ )
149 A->me[k+1][k-1].re =
A->me[k+1][k-1].im = 0.0;
153 if ( k <= k_max - 2 )
159 for ( k = k_min; k <= k_max-2; k++ )
162 A->me[k+2][
k].re =
A->me[k+2][
k].im = 0.0;
166 for ( k = k_min; k < k_max; k++ )
168 (
zabs(A_me[k][k])+
zabs(A_me[k+1][k+1])) )
170 A_me[k+1][
k].
re = A_me[k+1][
k].
im = 0.0;
179 for ( i = 0; i <
A->m; i++ )
180 for ( j = 0; j < i-1; j++ )
181 A_me[i][j].re = A_me[i][j].im = 0.0;
182 for ( i = 0; i <
A->m - 1; i++ )
184 (
zabs(A_me[i][i])+
zabs(A_me[i+1][i+1])) )
185 A_me[i+1][
i].
re = A_me[i+1][
i].
im = 0.0;
201 MAT *
T, *Q, *X_re, *X_im;
204 Real t11_re, t11_im, t12, t21, t22_re, t22_im;
205 Real l_re, l_im, det_re, det_im, invdet_re, invdet_im,
206 val1_re, val1_im, val2_re, val2_im,
207 tmp_val1_re, tmp_val1_im, tmp_val2_re, tmp_val2_im, **T_me;
208 Real sum, diff, discrim, magdet, norm, scale;
214 if (
T->m !=
T->n || X_re->m != X_re->n ||
215 ( Q !=
MNULL && Q->m != Q->n ) ||
216 ( X_im !=
MNULL && X_im->m != X_im->n ) )
218 if (
T->m != X_re->m ||
219 ( Q !=
MNULL &&
T->m != Q->m ) ||
220 ( X_im !=
MNULL &&
T->m != X_im->m ) )
236 if ( i+1 <
T->m &&
T->me[i+1][i] != 0.0 )
238 sum = 0.5*(T_me[
i][
i]+T_me[i+1][i+1]);
239 diff = 0.5*(T_me[
i][
i]-T_me[i+1][i+1]);
240 discrim = diff*diff + T_me[
i][i+1]*T_me[i+1][
i];
245 l_im =
sqrt(-discrim);
261 limit = ( l_im != 0.0 ) ? i+1 : i;
263 for ( j = limit+1; j <
T->m; j++ )
264 tmp1_re->
ve[j] = 0.0;
268 if ( j > 0 &&
T->me[j][j-1] != 0.0 )
271 val1_re = tmp1_re->
ve[j-1] -
272 __ip__(&(tmp1_re->
ve[j+1]),&(
T->me[j-1][j+1]),limit-j);
274 val1_im = tmp1_im->ve[j-1] -
275 __ip__(&(tmp1_im->ve[j+1]),&(
T->me[j-1][j+1]),limit-j);
277 val2_re = tmp1_re->
ve[
j] -
278 __ip__(&(tmp1_re->
ve[j+1]),&(
T->me[j][j+1]),limit-j);
280 val2_im = tmp1_im->ve[
j] -
281 __ip__(&(tmp1_im->ve[j+1]),&(
T->me[j][j+1]),limit-j);
284 t11_re = T_me[j-1][j-1] - l_re;
286 t22_re = T_me[
j][
j] - l_re;
291 scale =
fabs(T_me[j-1][j-1]) +
fabs(T_me[j][j]) +
294 det_re = t11_re*t22_re - t11_im*t22_im - t12*t21;
295 det_im = t11_re*t22_im + t11_im*t22_re;
296 magdet = det_re*det_re+det_im*det_im;
300 magdet = det_re*det_re+det_im*det_im;
302 invdet_re = det_re/magdet;
303 invdet_im = - det_im/magdet;
304 tmp_val1_re = t22_re*val1_re-t22_im*val1_im-t12*val2_re;
305 tmp_val1_im = t22_im*val1_re+t22_re*val1_im-t12*val2_im;
306 tmp_val2_re = t11_re*val2_re-t11_im*val2_im-t21*val1_re;
307 tmp_val2_im = t11_im*val2_re+t11_re*val2_im-t21*val1_im;
308 tmp1_re->
ve[j-1] = invdet_re*tmp_val1_re -
309 invdet_im*tmp_val1_im;
310 tmp1_im->ve[j-1] = invdet_im*tmp_val1_re +
311 invdet_re*tmp_val1_im;
312 tmp1_re->
ve[
j] = invdet_re*tmp_val2_re -
313 invdet_im*tmp_val2_im;
314 tmp1_im->ve[
j] = invdet_im*tmp_val2_re +
315 invdet_re*tmp_val2_im;
320 t11_re = T_me[
j][
j] - l_re;
322 magdet = t11_re*t11_re + t11_im*t11_im;
323 scale =
fabs(T_me[j][j]) +
fabs(l_re);
327 magdet = t11_re*t11_re + t11_im*t11_im;
329 invdet_re = t11_re/magdet;
330 invdet_im = - t11_im/magdet;
332 val1_re = tmp1_re->
ve[
j] -
333 __ip__(&(tmp1_re->
ve[j+1]),&(
T->me[j][j+1]),limit-j);
335 val1_im = tmp1_im->ve[
j] -
336 __ip__(&(tmp1_im->ve[j+1]),&(
T->me[j][j+1]),limit-j);
338 tmp1_re->
ve[
j] = invdet_re*val1_re - invdet_im*val1_im;
339 tmp1_im->ve[
j] = invdet_im*val1_re + invdet_re*val1_im;
345 sv_mlt(1/norm,tmp1_re,tmp1_re);
347 sv_mlt(1/norm,tmp1_im,tmp1_im);
348 mv_mlt(Q,tmp1_re,tmp2_re);
350 mv_mlt(Q,tmp1_im,tmp2_im);
355 sv_mlt(1/norm,tmp2_re,tmp2_re);
357 sv_mlt(1/norm,tmp2_im,tmp2_im);
365 sv_mlt(-1.0,tmp2_im,tmp2_im);
static Object ** v_resize(void *v)
ZMAT * zrot_rows(ZMAT *mat, int i, int k, double c, complex s, ZMAT *out)
ZMAT * zrot_cols(ZMAT *mat, int i, int k, double c, complex s, ZMAT *out)
static philox4x32_key_t k
complex zmlt(complex z1, complex z2)
complex zadd(complex z1, complex z2)
int const size_t const size_t n
ZMAT * zschur(ZMAT *A, ZMAT *Q)
ZMAT * zHfactor(ZMAT *A, ZVEC *diag)
#define set_col(mat, col, vec)
VEC * sv_mlt(double, VEC *, VEC *)
double __ip__(Real *dp1, Real *dp2, int len)
MAT * schur_vecs(MAT *T, MAT *Q, MAT *X_re, MAT *X_im)
ZVEC * zv_resize(ZVEC *x, int new_dim)
#define MEM_STAT_REG(var, type)
VEC * mv_mlt(MAT *A, VEC *b, VEC *out)
void zgivens(complex x, complex y, Real *c, complex *s)
complex zdiv(complex z1, complex z2)
#define error(err_num, fn_name)
ZMAT * zHQunpack(ZMAT *HQ, ZVEC *diag, ZMAT *Q, ZMAT *H)
complex zsub(complex z1, complex z2)