svd.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. /**************************************************************************
  2. **
  3. ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved.
  4. **
  5. ** Meschach Library
  6. **
  7. ** This Meschach Library is provided "as is" without any express
  8. ** or implied warranty of any kind with respect to this software.
  9. ** In particular the authors shall not be liable for any direct,
  10. ** indirect, special, incidental or consequential damages arising
  11. ** in any way from use of the software.
  12. **
  13. ** Everyone is granted permission to copy, modify and redistribute this
  14. ** Meschach Library, provided:
  15. ** 1. All copies contain this copyright notice.
  16. ** 2. All modified copies shall carry a notice stating who
  17. ** made the last modification and the date of such modification.
  18. ** 3. No charge is made for this software or works derived from it.
  19. ** This clause shall not be construed as constraining other software
  20. ** distributed on the same medium as this software, nor is a
  21. ** distribution fee considered a charge.
  22. **
  23. ***************************************************************************/
  24. /*
  25. File containing routines for computing the SVD of matrices
  26. */
  27. #include <stdio.h>
  28. #include <math.h>
  29. #include "matrix.h"
  30. #include "matrix2.h"
  31. static char rcsid[] = "$Id: svd.c,v 1.7 1995/09/08 14:45:43 des Exp $";
  32. #define sgn(x) ((x) >= 0 ? 1 : -1)
  33. #define MAX_STACK 100
  34. /* fixsvd -- fix minor details about SVD
  35. -- make singular values non-negative
  36. -- sort singular values in decreasing order
  37. -- variables as for bisvd()
  38. -- no argument checking */
  39. #ifndef ANSI_C
  40. static void fixsvd(d,U,V)
  41. VEC *d;
  42. MAT *U, *V;
  43. #else
  44. static void fixsvd(VEC *d, MAT *U, MAT *V)
  45. #endif
  46. {
  47. int i, j, k, l, r, stack[MAX_STACK], sp;
  48. Real tmp, v;
  49. /* make singular values non-negative */
  50. for ( i = 0; i < d->dim; i++ )
  51. if ( d->ve[i] < 0.0 )
  52. {
  53. d->ve[i] = - d->ve[i];
  54. if ( U != MNULL )
  55. for ( j = 0; j < U->m; j++ )
  56. U->me[i][j] = - U->me[i][j];
  57. }
  58. /* sort singular values */
  59. /* nonrecursive implementation of quicksort due to R.Sedgewick,
  60. "Algorithms in C", p. 122 (1990) */
  61. sp = -1;
  62. l = 0; r = d->dim - 1;
  63. for ( ; ; )
  64. {
  65. while ( r > l )
  66. {
  67. /* i = partition(d->ve,l,r) */
  68. v = d->ve[r];
  69. i = l - 1; j = r;
  70. for ( ; ; )
  71. { /* inequalities are "backwards" for **decreasing** order */
  72. while ( d->ve[++i] > v )
  73. ;
  74. while ( d->ve[--j] < v )
  75. ;
  76. if ( i >= j )
  77. break;
  78. /* swap entries in d->ve */
  79. tmp = d->ve[i]; d->ve[i] = d->ve[j]; d->ve[j] = tmp;
  80. /* swap rows of U & V as well */
  81. if ( U != MNULL )
  82. for ( k = 0; k < U->n; k++ )
  83. {
  84. tmp = U->me[i][k];
  85. U->me[i][k] = U->me[j][k];
  86. U->me[j][k] = tmp;
  87. }
  88. if ( V != MNULL )
  89. for ( k = 0; k < V->n; k++ )
  90. {
  91. tmp = V->me[i][k];
  92. V->me[i][k] = V->me[j][k];
  93. V->me[j][k] = tmp;
  94. }
  95. }
  96. tmp = d->ve[i]; d->ve[i] = d->ve[r]; d->ve[r] = tmp;
  97. if ( U != MNULL )
  98. for ( k = 0; k < U->n; k++ )
  99. {
  100. tmp = U->me[i][k];
  101. U->me[i][k] = U->me[r][k];
  102. U->me[r][k] = tmp;
  103. }
  104. if ( V != MNULL )
  105. for ( k = 0; k < V->n; k++ )
  106. {
  107. tmp = V->me[i][k];
  108. V->me[i][k] = V->me[r][k];
  109. V->me[r][k] = tmp;
  110. }
  111. /* end i = partition(...) */
  112. if ( i - l > r - i )
  113. { stack[++sp] = l; stack[++sp] = i-1; l = i+1; }
  114. else
  115. { stack[++sp] = i+1; stack[++sp] = r; r = i-1; }
  116. }
  117. if ( sp < 0 )
  118. break;
  119. r = stack[sp--]; l = stack[sp--];
  120. }
  121. }
  122. /* bisvd -- svd of a bidiagonal m x n matrix represented by d (diagonal) and
  123. f (super-diagonals)
  124. -- returns with d set to the singular values, f zeroed
  125. -- if U, V non-NULL, the orthogonal operations are accumulated
  126. in U, V; if U, V == I on entry, then SVD == U^T.A.V
  127. where A is initial matrix
  128. -- returns d on exit */
  129. #ifndef ANSI_C
  130. VEC *bisvd(d,f,U,V)
  131. VEC *d, *f;
  132. MAT *U, *V;
  133. #else
  134. VEC *bisvd(VEC *d, VEC *f, MAT *U, MAT *V)
  135. #endif
  136. {
  137. int i, j, n;
  138. int i_min, i_max, split;
  139. Real c, s, shift, size, z;
  140. Real d_tmp, diff, t11, t12, t22, *d_ve, *f_ve;
  141. if ( ! d || ! f )
  142. error(E_NULL,"bisvd");
  143. if ( d->dim != f->dim + 1 )
  144. error(E_SIZES,"bisvd");
  145. n = d->dim;
  146. if ( ( U && U->n < n ) || ( V && V->m < n ) )
  147. error(E_SIZES,"bisvd");
  148. if ( ( U && U->m != U->n ) || ( V && V->m != V->n ) )
  149. error(E_SQUARE,"bisvd");
  150. if ( n == 1 )
  151. {
  152. if ( d->ve[0] < 0.0 )
  153. {
  154. d->ve[0] = - d->ve[0];
  155. if ( U != MNULL )
  156. sm_mlt(-1.0,U,U);
  157. }
  158. return d;
  159. }
  160. d_ve = d->ve; f_ve = f->ve;
  161. size = v_norm_inf(d) + v_norm_inf(f);
  162. i_min = 0;
  163. while ( i_min < n ) /* outer while loop */
  164. {
  165. /* find i_max to suit;
  166. submatrix i_min..i_max should be irreducible */
  167. i_max = n - 1;
  168. for ( i = i_min; i < n - 1; i++ )
  169. if ( d_ve[i] == 0.0 || f_ve[i] == 0.0 )
  170. { i_max = i;
  171. if ( f_ve[i] != 0.0 )
  172. {
  173. /* have to ``chase'' f[i] element out of matrix */
  174. z = f_ve[i]; f_ve[i] = 0.0;
  175. for ( j = i; j < n-1 && z != 0.0; j++ )
  176. {
  177. givens(d_ve[j+1],z, &c, &s);
  178. s = -s;
  179. d_ve[j+1] = c*d_ve[j+1] - s*z;
  180. if ( j+1 < n-1 )
  181. {
  182. z = s*f_ve[j+1];
  183. f_ve[j+1] = c*f_ve[j+1];
  184. }
  185. if ( U )
  186. rot_rows(U,i,j+1,c,s,U);
  187. }
  188. }
  189. break;
  190. }
  191. if ( i_max <= i_min )
  192. {
  193. i_min = i_max + 1;
  194. continue;
  195. }
  196. /* printf("bisvd: i_min = %d, i_max = %d\n",i_min,i_max); */
  197. split = FALSE;
  198. while ( ! split )
  199. {
  200. /* compute shift */
  201. t11 = d_ve[i_max-1]*d_ve[i_max-1] +
  202. (i_max > i_min+1 ? f_ve[i_max-2]*f_ve[i_max-2] : 0.0);
  203. t12 = d_ve[i_max-1]*f_ve[i_max-1];
  204. t22 = d_ve[i_max]*d_ve[i_max] + f_ve[i_max-1]*f_ve[i_max-1];
  205. /* use e-val of [[t11,t12],[t12,t22]] matrix
  206. closest to t22 */
  207. diff = (t11-t22)/2;
  208. shift = t22 - t12*t12/(diff +
  209. sgn(diff)*sqrt(diff*diff+t12*t12));
  210. /* initial Givens' rotation */
  211. givens(d_ve[i_min]*d_ve[i_min]-shift,
  212. d_ve[i_min]*f_ve[i_min], &c, &s);
  213. /* do initial Givens' rotations */
  214. d_tmp = c*d_ve[i_min] + s*f_ve[i_min];
  215. f_ve[i_min] = c*f_ve[i_min] - s*d_ve[i_min];
  216. d_ve[i_min] = d_tmp;
  217. z = s*d_ve[i_min+1];
  218. d_ve[i_min+1] = c*d_ve[i_min+1];
  219. if ( V )
  220. rot_rows(V,i_min,i_min+1,c,s,V);
  221. /* 2nd Givens' rotation */
  222. givens(d_ve[i_min],z, &c, &s);
  223. d_ve[i_min] = c*d_ve[i_min] + s*z;
  224. d_tmp = c*d_ve[i_min+1] - s*f_ve[i_min];
  225. f_ve[i_min] = s*d_ve[i_min+1] + c*f_ve[i_min];
  226. d_ve[i_min+1] = d_tmp;
  227. if ( i_min+1 < i_max )
  228. {
  229. z = s*f_ve[i_min+1];
  230. f_ve[i_min+1] = c*f_ve[i_min+1];
  231. }
  232. if ( U )
  233. rot_rows(U,i_min,i_min+1,c,s,U);
  234. for ( i = i_min+1; i < i_max; i++ )
  235. {
  236. /* get Givens' rotation for zeroing z */
  237. givens(f_ve[i-1],z, &c, &s);
  238. f_ve[i-1] = c*f_ve[i-1] + s*z;
  239. d_tmp = c*d_ve[i] + s*f_ve[i];
  240. f_ve[i] = c*f_ve[i] - s*d_ve[i];
  241. d_ve[i] = d_tmp;
  242. z = s*d_ve[i+1];
  243. d_ve[i+1] = c*d_ve[i+1];
  244. if ( V )
  245. rot_rows(V,i,i+1,c,s,V);
  246. /* get 2nd Givens' rotation */
  247. givens(d_ve[i],z, &c, &s);
  248. d_ve[i] = c*d_ve[i] + s*z;
  249. d_tmp = c*d_ve[i+1] - s*f_ve[i];
  250. f_ve[i] = c*f_ve[i] + s*d_ve[i+1];
  251. d_ve[i+1] = d_tmp;
  252. if ( i+1 < i_max )
  253. {
  254. z = s*f_ve[i+1];
  255. f_ve[i+1] = c*f_ve[i+1];
  256. }
  257. if ( U )
  258. rot_rows(U,i,i+1,c,s,U);
  259. }
  260. /* should matrix be split? */
  261. for ( i = i_min; i < i_max; i++ )
  262. if ( fabs(f_ve[i]) <
  263. MACHEPS*(fabs(d_ve[i])+fabs(d_ve[i+1])) )
  264. {
  265. split = TRUE;
  266. f_ve[i] = 0.0;
  267. }
  268. else if ( fabs(d_ve[i]) < MACHEPS*size )
  269. {
  270. split = TRUE;
  271. d_ve[i] = 0.0;
  272. }
  273. /* printf("bisvd: d =\n"); v_output(d); */
  274. /* printf("bisvd: f = \n"); v_output(f); */
  275. }
  276. }
  277. fixsvd(d,U,V);
  278. return d;
  279. }
  280. /* bifactor -- perform preliminary factorisation for bisvd
  281. -- updates U and/or V, which ever is not NULL */
  282. #ifndef ANSI_C
  283. MAT *bifactor(A,U,V)
  284. MAT *A, *U, *V;
  285. #else
  286. MAT *bifactor(MAT *A, MAT *U, MAT *V)
  287. #endif
  288. {
  289. int k;
  290. STATIC VEC *tmp1=VNULL, *tmp2=VNULL, *w=VNULL;
  291. Real beta;
  292. if ( ! A )
  293. error(E_NULL,"bifactor");
  294. if ( ( U && ( U->m != U->n ) ) || ( V && ( V->m != V->n ) ) )
  295. error(E_SQUARE,"bifactor");
  296. if ( ( U && U->m != A->m ) || ( V && V->m != A->n ) )
  297. error(E_SIZES,"bifactor");
  298. tmp1 = v_resize(tmp1,A->m);
  299. tmp2 = v_resize(tmp2,A->n);
  300. w = v_resize(w, max(A->m,A->n));
  301. MEM_STAT_REG(tmp1,TYPE_VEC);
  302. MEM_STAT_REG(tmp2,TYPE_VEC);
  303. MEM_STAT_REG(w, TYPE_VEC);
  304. if ( A->m >= A->n )
  305. for ( k = 0; k < A->n; k++ )
  306. {
  307. get_col(A,k,tmp1);
  308. hhvec(tmp1,k,&beta,tmp1,&(A->me[k][k]));
  309. _hhtrcols(A,k,k+1,tmp1,beta,w);
  310. if ( U )
  311. _hhtrcols(U,k,0,tmp1,beta,w);
  312. if ( k+1 >= A->n )
  313. continue;
  314. get_row(A,k,tmp2);
  315. hhvec(tmp2,k+1,&beta,tmp2,&(A->me[k][k+1]));
  316. hhtrrows(A,k+1,k+1,tmp2,beta);
  317. if ( V )
  318. _hhtrcols(V,k+1,0,tmp2,beta,w);
  319. }
  320. else
  321. for ( k = 0; k < A->m; k++ )
  322. {
  323. get_row(A,k,tmp2);
  324. hhvec(tmp2,k,&beta,tmp2,&(A->me[k][k]));
  325. hhtrrows(A,k+1,k,tmp2,beta);
  326. if ( V )
  327. _hhtrcols(V,k,0,tmp2,beta,w);
  328. if ( k+1 >= A->m )
  329. continue;
  330. get_col(A,k,tmp1);
  331. hhvec(tmp1,k+1,&beta,tmp1,&(A->me[k+1][k]));
  332. _hhtrcols(A,k+1,k+1,tmp1,beta,w);
  333. if ( U )
  334. _hhtrcols(U,k+1,0,tmp1,beta,w);
  335. }
  336. #ifdef THREADSAFE
  337. V_FREE(tmp1); V_FREE(tmp2);
  338. #endif
  339. return A;
  340. }
  341. /* svd -- returns vector of singular values in d
  342. -- also updates U and/or V, if one or the other is non-NULL
  343. -- destroys A */
  344. #ifndef ANSI_C
  345. VEC *svd(A,U,V,d)
  346. MAT *A, *U, *V;
  347. VEC *d;
  348. #else
  349. VEC *svd(MAT *A, MAT *U, MAT *V, VEC *d)
  350. #endif
  351. {
  352. STATIC VEC *f=VNULL;
  353. int i, limit;
  354. MAT *A_tmp;
  355. if ( ! A )
  356. error(E_NULL,"svd");
  357. if ( ( U && ( U->m != U->n ) ) || ( V && ( V->m != V->n ) ) )
  358. error(E_SQUARE,"svd");
  359. if ( ( U && U->m != A->m ) || ( V && V->m != A->n ) )
  360. error(E_SIZES,"svd");
  361. A_tmp = m_copy(A,MNULL);
  362. if ( U != MNULL )
  363. m_ident(U);
  364. if ( V != MNULL )
  365. m_ident(V);
  366. limit = min(A_tmp->m,A_tmp->n);
  367. d = v_resize(d,limit);
  368. f = v_resize(f,limit-1);
  369. MEM_STAT_REG(f,TYPE_VEC);
  370. bifactor(A_tmp,U,V);
  371. if ( A_tmp->m >= A_tmp->n )
  372. for ( i = 0; i < limit; i++ )
  373. {
  374. d->ve[i] = A_tmp->me[i][i];
  375. if ( i+1 < limit )
  376. f->ve[i] = A_tmp->me[i][i+1];
  377. }
  378. else
  379. for ( i = 0; i < limit; i++ )
  380. {
  381. d->ve[i] = A_tmp->me[i][i];
  382. if ( i+1 < limit )
  383. f->ve[i] = A_tmp->me[i+1][i];
  384. }
  385. if ( A_tmp->m >= A_tmp->n )
  386. bisvd(d,f,U,V);
  387. else
  388. bisvd(d,f,V,U);
  389. M_FREE(A_tmp);
  390. #ifdef THREADSAFE
  391. V_FREE(f);
  392. #endif
  393. return d;
  394. }