1 #include <../../nrnconf.h> 38 static char rcsid[] =
"svd.c,v 1.1 1997/12/04 17:55:56 hines Exp";
42 #define sgn(x) ((x) >= 0 ? 1 : -1) 58 for ( i = 0; i < d->dim; i++ )
61 d->ve[
i] = - d->ve[
i];
63 for ( j = 0; j < U->
m; j++ )
64 U->
me[i][j] = - U->
me[i][j];
71 l = 0; r = d->dim - 1;
82 while ( d->ve[++i] > v )
84 while ( i < j && d->ve[--j] < v )
89 tmp = d->ve[
i]; d->ve[
i] = d->ve[
j]; d->ve[
j] = tmp;
92 for ( k = 0; k < U->
n; k++ )
99 for ( k = 0; k < V->
n; k++ )
106 tmp = d->ve[
i]; d->ve[
i] = d->ve[r]; d->ve[r] = tmp;
108 for ( k = 0; k < U->
n; k++ )
115 for ( k = 0; k < V->
n; k++ )
123 { stack[++sp] = l; stack[++sp] = i-1; l = i+1; }
125 { stack[++sp] = i+1; stack[++sp] = r; r = i-1; }
129 r = stack[sp--]; l = stack[sp--];
146 int i_min, i_max, split;
147 Real c,
s, shift, size, z;
148 Real d_tmp, diff, t11, t12, t22, *d_ve, *f_ve;
152 if ( d->dim != f->dim + 1 )
155 if ( ( U && U->
n < n ) || ( V && V->
m < n ) )
157 if ( ( U && U->
m != U->
n ) || ( V && V->
m != V->
n ) )
163 d_ve = d->ve; f_ve = f->ve;
173 for ( i = i_min; i < n - 1; i++ )
174 if ( d_ve[i] == 0.0 || f_ve[i] == 0.0 )
176 if ( f_ve[i] != 0.0 )
179 z = f_ve[
i]; f_ve[
i] = 0.0;
180 for ( j = i; j < n-1 && z != 0.0; j++ )
182 givens(d_ve[j+1],z, &c, &s);
184 d_ve[j+1] = c*d_ve[j+1] - s*z;
188 f_ve[j+1] = c*f_ve[j+1];
196 if ( i_max <= i_min )
207 t11 = d_ve[i_max-1]*d_ve[i_max-1] +
208 (i_max > i_min+1 ? f_ve[i_max-2]*f_ve[i_max-2] : 0.0);
209 t12 = d_ve[i_max-1]*f_ve[i_max-1];
210 t22 = d_ve[i_max]*d_ve[i_max] + f_ve[i_max-1]*f_ve[i_max-1];
214 shift = t22 - t12*t12/(diff +
215 sgn(diff)*
sqrt(diff*diff+t12*t12));
218 givens(d_ve[i_min]*d_ve[i_min]-shift,
219 d_ve[i_min]*f_ve[i_min], &c, &s);
222 d_tmp = c*d_ve[i_min] + s*f_ve[i_min];
223 f_ve[i_min] = c*f_ve[i_min] - s*d_ve[i_min];
226 d_ve[i_min+1] = c*d_ve[i_min+1];
230 givens(d_ve[i_min],z, &c, &s);
231 d_ve[i_min] = c*d_ve[i_min] + s*z;
232 d_tmp = c*d_ve[i_min+1] - s*f_ve[i_min];
233 f_ve[i_min] = s*d_ve[i_min+1] + c*f_ve[i_min];
234 d_ve[i_min+1] = d_tmp;
235 if ( i_min+1 < i_max )
238 f_ve[i_min+1] = c*f_ve[i_min+1];
243 for ( i = i_min+1; i < i_max; i++ )
246 givens(f_ve[i-1],z, &c, &s);
247 f_ve[i-1] = c*f_ve[i-1] + s*z;
248 d_tmp = c*d_ve[
i] + s*f_ve[
i];
249 f_ve[
i] = c*f_ve[
i] - s*d_ve[
i];
252 d_ve[i+1] = c*d_ve[i+1];
256 givens(d_ve[i],z, &c, &s);
257 d_ve[
i] = c*d_ve[
i] + s*z;
258 d_tmp = c*d_ve[i+1] - s*f_ve[
i];
259 f_ve[
i] = c*f_ve[
i] + s*d_ve[i+1];
264 f_ve[i+1] = c*f_ve[i+1];
270 for ( i = i_min; i < i_max; i++ )
302 if ( ( U && ( U->
m != U->
n ) ) || ( V && ( V->
m != V->
n ) ) )
304 if ( ( U && U->
m !=
A->m ) || ( V && V->
m !=
A->n ) )
312 for ( k = 0; k <
A->n; k++ )
315 hhvec(tmp1,k,&beta,tmp1,&(
A->me[k][k]));
322 hhvec(tmp2,k+1,&beta,tmp2,&(
A->me[k][k+1]));
328 for ( k = 0; k <
A->m; k++ )
331 hhvec(tmp2,k,&beta,tmp2,&(
A->me[k][k]));
338 hhvec(tmp1,k+1,&beta,tmp1,&(
A->me[k+1][k]));
360 if ( ( U && ( U->
m != U->
n ) ) || ( V && ( V->
m != V->
n ) ) )
362 if ( ( U && U->
m !=
A->m ) || ( V && V->
m !=
A->n ) )
370 limit =
min(A_tmp->
m,A_tmp->
n);
372 if (f ==
VNULL && limit == 1) {
379 if ( A_tmp->
m >= A_tmp->
n )
380 for ( i = 0; i < limit; i++ )
384 f->
ve[
i] = A_tmp->
me[
i][i+1];
387 for ( i = 0; i < limit; i++ )
391 f->
ve[
i] = A_tmp->
me[i+1][
i];
395 if ( A_tmp->
m >= A_tmp->
n )
MAT * rot_rows(MAT *mat, u_int i, u_int k, double c, double s, MAT *out)
static Object ** v_resize(void *v)
static philox4x32_key_t k
int const size_t const size_t n
void givens(double x, double y, Real *c, Real *s)
MAT * hhtrcols(MAT *M, u_int i0, u_int j0, VEC *hh, double beta)
VEC * hhvec(VEC *vec, u_int i0, Real *beta, VEC *out, Real *newval)
VEC * get_row(MAT *, u_int, VEC *)
VEC * bisvd(VEC *d, VEC *f, MAT *U, MAT *V)
#define MEM_STAT_REG(var, type)
VEC * get_col(MAT *, u_int, VEC *)
#define error(err_num, fn_name)
static void fixsvd(VEC *d, MAT *U, MAT *V)
MAT * bifactor(MAT *A, MAT *U, MAT *V)
MAT * hhtrrows(MAT *M, u_int i0, u_int j0, VEC *hh, double beta)
static Object ** m_ident(void *v)
VEC * svd(MAT *A, MAT *U, MAT *V, VEC *d)