hessen.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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. */
  28. static char rcsid[] = "$Id: hessen.c,v 1.2 1994/01/13 05:36:24 des Exp $";
  29. #include <stdio.h>
  30. #include "matrix.h"
  31. #include "matrix2.h"
  32. /* Hfactor -- compute Hessenberg factorisation in compact form.
  33. -- factorisation performed in situ
  34. -- for details of the compact form see QRfactor.c and matrix2.doc */
  35. #ifndef ANSI_C
  36. MAT *Hfactor(A, diag, beta)
  37. MAT *A;
  38. VEC *diag, *beta;
  39. #else
  40. MAT *Hfactor(MAT *A, VEC *diag, VEC *beta)
  41. #endif
  42. {
  43. STATIC VEC *hh = VNULL, *w = VNULL;
  44. int k, limit;
  45. if ( ! A || ! diag || ! beta )
  46. error(E_NULL,"Hfactor");
  47. if ( diag->dim < A->m - 1 || beta->dim < A->m - 1 )
  48. error(E_SIZES,"Hfactor");
  49. if ( A->m != A->n )
  50. error(E_SQUARE,"Hfactor");
  51. limit = A->m - 1;
  52. hh = v_resize(hh,A->m);
  53. w = v_resize(w,A->n);
  54. MEM_STAT_REG(hh,TYPE_VEC);
  55. MEM_STAT_REG(w, TYPE_VEC);
  56. for ( k = 0; k < limit; k++ )
  57. {
  58. /* compute the Householder vector hh */
  59. get_col(A,(unsigned int)k,hh);
  60. /* printf("the %d'th column = "); v_output(hh); */
  61. hhvec(hh,k+1,&beta->ve[k],hh,&A->me[k+1][k]);
  62. /* diag->ve[k] = hh->ve[k+1]; */
  63. v_set_val(diag,k,v_entry(hh,k+1));
  64. /* printf("H/h vector = "); v_output(hh); */
  65. /* printf("from the %d'th entry\n",k+1); */
  66. /* printf("beta = %g\n",beta->ve[k]); */
  67. /* apply Householder operation symmetrically to A */
  68. _hhtrcols(A,k+1,k+1,hh,v_entry(beta,k),w);
  69. hhtrrows(A,0 ,k+1,hh,v_entry(beta,k));
  70. /* printf("A = "); m_output(A); */
  71. }
  72. #ifdef THREADSAFE
  73. V_FREE(hh); V_FREE(w);
  74. #endif
  75. return (A);
  76. }
  77. /* makeHQ -- construct the Hessenberg orthogonalising matrix Q;
  78. -- i.e. Hess M = Q.M.Q' */
  79. #ifndef ANSI_C
  80. MAT *makeHQ(H, diag, beta, Qout)
  81. MAT *H, *Qout;
  82. VEC *diag, *beta;
  83. #else
  84. MAT *makeHQ(MAT *H, VEC *diag, VEC *beta, MAT *Qout)
  85. #endif
  86. {
  87. int i, j, limit;
  88. STATIC VEC *tmp1 = VNULL, *tmp2 = VNULL;
  89. if ( H==(MAT *)NULL || diag==(VEC *)NULL || beta==(VEC *)NULL )
  90. error(E_NULL,"makeHQ");
  91. limit = H->m - 1;
  92. if ( diag->dim < limit || beta->dim < limit )
  93. error(E_SIZES,"makeHQ");
  94. if ( H->m != H->n )
  95. error(E_SQUARE,"makeHQ");
  96. Qout = m_resize(Qout,H->m,H->m);
  97. tmp1 = v_resize(tmp1,H->m);
  98. tmp2 = v_resize(tmp2,H->m);
  99. MEM_STAT_REG(tmp1,TYPE_VEC);
  100. MEM_STAT_REG(tmp2,TYPE_VEC);
  101. for ( i = 0; i < H->m; i++ )
  102. {
  103. /* tmp1 = i'th basis vector */
  104. for ( j = 0; j < H->m; j++ )
  105. /* tmp1->ve[j] = 0.0; */
  106. v_set_val(tmp1,j,0.0);
  107. /* tmp1->ve[i] = 1.0; */
  108. v_set_val(tmp1,i,1.0);
  109. /* apply H/h transforms in reverse order */
  110. for ( j = limit-1; j >= 0; j-- )
  111. {
  112. get_col(H,(unsigned int)j,tmp2);
  113. /* tmp2->ve[j+1] = diag->ve[j]; */
  114. v_set_val(tmp2,j+1,v_entry(diag,j));
  115. hhtrvec(tmp2,beta->ve[j],j+1,tmp1,tmp1);
  116. }
  117. /* insert into Qout */
  118. set_col(Qout,(unsigned int)i,tmp1);
  119. }
  120. #ifdef THREADSAFE
  121. V_FREE(tmp1); V_FREE(tmp2);
  122. #endif
  123. return (Qout);
  124. }
  125. /* makeH -- construct actual Hessenberg matrix */
  126. #ifndef ANSI_C
  127. MAT *makeH(H,Hout)
  128. MAT *H, *Hout;
  129. #else
  130. MAT *makeH(const MAT *H, MAT *Hout)
  131. #endif
  132. {
  133. int i, j, limit;
  134. if ( H==(MAT *)NULL )
  135. error(E_NULL,"makeH");
  136. if ( H->m != H->n )
  137. error(E_SQUARE,"makeH");
  138. Hout = m_resize(Hout,H->m,H->m);
  139. Hout = m_copy(H,Hout);
  140. limit = H->m;
  141. for ( i = 1; i < limit; i++ )
  142. for ( j = 0; j < i-1; j++ )
  143. /* Hout->me[i][j] = 0.0;*/
  144. m_set_val(Hout,i,j,0.0);
  145. return (Hout);
  146. }