zhessen.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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 determining Hessenberg
  26. factorisations.
  27. Complex version
  28. */
  29. static char rcsid[] = "$Id: zhessen.c,v 1.2 1995/03/27 15:47:50 des Exp $";
  30. #include <stdio.h>
  31. #include "zmatrix.h"
  32. #include "zmatrix2.h"
  33. /* zHfactor -- compute Hessenberg factorisation in compact form.
  34. -- factorisation performed in situ
  35. -- for details of the compact form see zQRfactor.c and zmatrix2.doc */
  36. ZMAT *zHfactor(A, diag)
  37. ZMAT *A;
  38. ZVEC *diag;
  39. {
  40. STATIC ZVEC *tmp1 = ZVNULL, *w = ZVNULL;
  41. Real beta;
  42. int k, limit;
  43. if ( ! A || ! diag )
  44. error(E_NULL,"zHfactor");
  45. if ( diag->dim < A->m - 1 )
  46. error(E_SIZES,"zHfactor");
  47. if ( A->m != A->n )
  48. error(E_SQUARE,"zHfactor");
  49. limit = A->m - 1;
  50. tmp1 = zv_resize(tmp1,A->m);
  51. w = zv_resize(w, A->n);
  52. MEM_STAT_REG(tmp1,TYPE_ZVEC);
  53. MEM_STAT_REG(w, TYPE_ZVEC);
  54. for ( k = 0; k < limit; k++ )
  55. {
  56. zget_col(A,k,tmp1);
  57. zhhvec(tmp1,k+1,&beta,tmp1,&A->me[k+1][k]);
  58. diag->ve[k] = tmp1->ve[k+1];
  59. /* printf("zHfactor: k = %d, beta = %g, tmp1 =\n",k,beta);
  60. zv_output(tmp1); */
  61. _zhhtrcols(A,k+1,k+1,tmp1,beta,w);
  62. zhhtrrows(A,0 ,k+1,tmp1,beta);
  63. /* printf("# at stage k = %d, A =\n",k); zm_output(A); */
  64. }
  65. #ifdef THREADSAFE
  66. ZV_FREE(tmp1); ZV_FREE(w);
  67. #endif
  68. return (A);
  69. }
  70. /* zHQunpack -- unpack the compact representation of H and Q of a
  71. Hessenberg factorisation
  72. -- if either H or Q is NULL, then it is not unpacked
  73. -- it can be in situ with HQ == H
  74. -- returns HQ
  75. */
  76. ZMAT *zHQunpack(HQ,diag,Q,H)
  77. ZMAT *HQ, *Q, *H;
  78. ZVEC *diag;
  79. {
  80. int i, j, limit;
  81. Real beta, r_ii, tmp_val;
  82. STATIC ZVEC *tmp1 = ZVNULL, *tmp2 = ZVNULL;
  83. if ( HQ==ZMNULL || diag==ZVNULL )
  84. error(E_NULL,"zHQunpack");
  85. if ( HQ == Q || H == Q )
  86. error(E_INSITU,"zHQunpack");
  87. limit = HQ->m - 1;
  88. if ( diag->dim < limit )
  89. error(E_SIZES,"zHQunpack");
  90. if ( HQ->m != HQ->n )
  91. error(E_SQUARE,"zHQunpack");
  92. if ( Q != ZMNULL )
  93. {
  94. Q = zm_resize(Q,HQ->m,HQ->m);
  95. tmp1 = zv_resize(tmp1,H->m);
  96. tmp2 = zv_resize(tmp2,H->m);
  97. MEM_STAT_REG(tmp1,TYPE_ZVEC);
  98. MEM_STAT_REG(tmp2,TYPE_ZVEC);
  99. for ( i = 0; i < H->m; i++ )
  100. {
  101. /* tmp1 = i'th basis vector */
  102. for ( j = 0; j < H->m; j++ )
  103. tmp1->ve[j].re = tmp1->ve[j].im = 0.0;
  104. tmp1->ve[i].re = 1.0;
  105. /* apply H/h transforms in reverse order */
  106. for ( j = limit-1; j >= 0; j-- )
  107. {
  108. zget_col(HQ,j,tmp2);
  109. r_ii = zabs(tmp2->ve[j+1]);
  110. tmp2->ve[j+1] = diag->ve[j];
  111. tmp_val = (r_ii*zabs(diag->ve[j]));
  112. beta = ( tmp_val == 0.0 ) ? 0.0 : 1.0/tmp_val;
  113. /* printf("zHQunpack: j = %d, beta = %g, tmp2 =\n",
  114. j,beta);
  115. zv_output(tmp2); */
  116. zhhtrvec(tmp2,beta,j+1,tmp1,tmp1);
  117. }
  118. /* insert into Q */
  119. zset_col(Q,i,tmp1);
  120. }
  121. }
  122. if ( H != ZMNULL )
  123. {
  124. H = zm_copy(HQ,zm_resize(H,HQ->m,HQ->n));
  125. limit = H->m;
  126. for ( i = 1; i < limit; i++ )
  127. for ( j = 0; j < i-1; j++ )
  128. H->me[i][j].re = H->me[i][j].im = 0.0;
  129. }
  130. #ifdef THREADSAFE
  131. ZV_FREE(tmp1); ZV_FREE(tmp2);
  132. #endif
  133. return HQ;
  134. }