givens.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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. Files for matrix computations
  26. Givens operations file. Contains routines for calculating and
  27. applying givens rotations for/to vectors and also to matrices by
  28. row and by column.
  29. */
  30. /* givens.c 1.2 11/25/87 */
  31. static char rcsid[] = "$Id: givens.c,v 1.3 1995/03/27 15:41:15 des Exp $";
  32. #include <stdio.h>
  33. #include <math.h>
  34. #include "matrix.h"
  35. #include "matrix2.h"
  36. /* givens -- returns c,s parameters for Givens rotation to
  37. eliminate y in the vector [ x y ]' */
  38. #ifndef ANSI_C
  39. void givens(x,y,c,s)
  40. double x,y;
  41. Real *c,*s;
  42. #else
  43. void givens(double x, double y, Real *c, Real *s)
  44. #endif
  45. {
  46. Real norm;
  47. norm = sqrt(x*x+y*y);
  48. if ( norm == 0.0 )
  49. { *c = 1.0; *s = 0.0; } /* identity */
  50. else
  51. { *c = x/norm; *s = y/norm; }
  52. }
  53. /* rot_vec -- apply Givens rotation to x's i & k components */
  54. #ifndef ANSI_C
  55. VEC *rot_vec(x,i,k,c,s,out)
  56. VEC *x,*out;
  57. unsigned int i,k;
  58. double c,s;
  59. #else
  60. VEC *rot_vec(const VEC *x,unsigned int i,unsigned int k, double c,double s,
  61. VEC *out)
  62. #endif
  63. {
  64. Real temp;
  65. if ( x==VNULL )
  66. error(E_NULL,"rot_vec");
  67. if ( i >= x->dim || k >= x->dim )
  68. error(E_RANGE,"rot_vec");
  69. out = v_copy(x,out);
  70. /* temp = c*out->ve[i] + s*out->ve[k]; */
  71. temp = c*v_entry(out,i) + s*v_entry(out,k);
  72. /* out->ve[k] = -s*out->ve[i] + c*out->ve[k]; */
  73. v_set_val(out,k,-s*v_entry(out,i)+c*v_entry(out,k));
  74. /* out->ve[i] = temp; */
  75. v_set_val(out,i,temp);
  76. return (out);
  77. }
  78. /* rot_rows -- premultiply mat by givens rotation described by c,s */
  79. #ifndef ANSI_C
  80. MAT *rot_rows(mat,i,k,c,s,out)
  81. MAT *mat,*out;
  82. unsigned int i,k;
  83. double c,s;
  84. #else
  85. MAT *rot_rows(const MAT *mat, unsigned int i, unsigned int k,
  86. double c, double s, MAT *out)
  87. #endif
  88. {
  89. unsigned int j;
  90. Real temp;
  91. if ( mat==(MAT *)NULL )
  92. error(E_NULL,"rot_rows");
  93. if ( i >= mat->m || k >= mat->m )
  94. error(E_RANGE,"rot_rows");
  95. if ( mat != out )
  96. out = m_copy(mat,m_resize(out,mat->m,mat->n));
  97. for ( j=0; j<mat->n; j++ )
  98. {
  99. /* temp = c*out->me[i][j] + s*out->me[k][j]; */
  100. temp = c*m_entry(out,i,j) + s*m_entry(out,k,j);
  101. /* out->me[k][j] = -s*out->me[i][j] + c*out->me[k][j]; */
  102. m_set_val(out,k,j, -s*m_entry(out,i,j) + c*m_entry(out,k,j));
  103. /* out->me[i][j] = temp; */
  104. m_set_val(out,i,j, temp);
  105. }
  106. return (out);
  107. }
  108. /* rot_cols -- postmultiply mat by givens rotation described by c,s */
  109. #ifndef ANSI_C
  110. MAT *rot_cols(mat,i,k,c,s,out)
  111. MAT *mat,*out;
  112. unsigned int i,k;
  113. double c,s;
  114. #else
  115. MAT *rot_cols(const MAT *mat,unsigned int i,unsigned int k,
  116. double c, double s, MAT *out)
  117. #endif
  118. {
  119. unsigned int j;
  120. Real temp;
  121. if ( mat==(MAT *)NULL )
  122. error(E_NULL,"rot_cols");
  123. if ( i >= mat->n || k >= mat->n )
  124. error(E_RANGE,"rot_cols");
  125. if ( mat != out )
  126. out = m_copy(mat,m_resize(out,mat->m,mat->n));
  127. for ( j=0; j<mat->m; j++ )
  128. {
  129. /* temp = c*out->me[j][i] + s*out->me[j][k]; */
  130. temp = c*m_entry(out,j,i) + s*m_entry(out,j,k);
  131. /* out->me[j][k] = -s*out->me[j][i] + c*out->me[j][k]; */
  132. m_set_val(out,j,k, -s*m_entry(out,j,i) + c*m_entry(out,j,k));
  133. /* out->me[j][i] = temp; */
  134. m_set_val(out,j,i,temp);
  135. }
  136. return (out);
  137. }