You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

zrotg.c 4.7 kB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #include <math.h>
  2. #include <float.h>
  3. #include "common.h"
  4. #ifdef FUNCTION_PROFILE
  5. #include "functable.h"
  6. #endif
  7. #ifndef CBLAS
  8. void NAME(FLOAT *DA, FLOAT *DB, FLOAT *C, FLOAT *S){
  9. #else
  10. void CNAME(void *VDA, void *VDB, FLOAT *C, void *VS) {
  11. FLOAT *DA = (FLOAT*) VDA;
  12. FLOAT *DB = (FLOAT*) VDB;
  13. FLOAT *S = (FLOAT*) VS;
  14. #endif /* CBLAS */
  15. #ifdef DOUBLE
  16. long double safmin = DBL_MIN;
  17. long double rtmin = sqrt(DBL_MIN/DBL_EPSILON);
  18. #else
  19. long double safmin = FLT_MIN;
  20. long double rtmin = sqrt(FLT_MIN/FLT_EPSILON);
  21. #endif
  22. FLOAT da_r = *(DA+0);
  23. FLOAT da_i = *(DA+1);
  24. FLOAT db_r = *(DB+0);
  25. FLOAT db_i = *(DB+1);
  26. //long double r;
  27. FLOAT *r, *S1=(FLOAT *)malloc(2*sizeof(FLOAT));
  28. FLOAT *R=(FLOAT *)malloc(2*sizeof(FLOAT));
  29. long double d;
  30. FLOAT ada = da_r * da_r + da_i * da_i;
  31. FLOAT adb = db_r * db_r + db_i * db_i;
  32. FLOAT adart = sqrt( da_r * da_r + da_i * da_i);
  33. FLOAT adbrt = sqrt( db_r * db_r + db_i * db_i);
  34. PRINT_DEBUG_NAME;
  35. IDEBUG_START;
  36. FUNCTION_PROFILE_START();
  37. if (db_r == ZERO && db_i == ZERO) {
  38. *C = ONE;
  39. *(S + 0) = ZERO;
  40. *(S + 1) = ZERO;
  41. return;
  42. }
  43. long double safmax = 1./safmin;
  44. #if defined DOUBLE
  45. long double rtmax = safmax /DBL_EPSILON;
  46. #else
  47. long double rtmax = safmax /FLT_EPSILON;
  48. #endif
  49. *(S1 + 0) = *(DB + 0);
  50. *(S1 + 1) = *(DB + 1) *-1;
  51. if (da_r == ZERO && da_i == ZERO) {
  52. *C = ZERO;
  53. if (db_r == ZERO) {
  54. (*DA) = fabsl(db_i);
  55. *S = *S1 /da_r;
  56. *(S+1) = *(S1+1) /da_r;
  57. return;
  58. } else if ( db_i == ZERO) {
  59. *DA = fabsl(db_r);
  60. *S = *S1 /da_r;
  61. *(S+1) = *(S1+1) /da_r;
  62. return;
  63. } else {
  64. long double g1 = MAX( fabsl(db_r), fabsl(db_i));
  65. rtmax =sqrt(safmax/2.);
  66. if (g1 > rtmin && g1 < rtmax) { // unscaled
  67. d = sqrt(adb);
  68. *S = *S1 /d;
  69. *(S+1) = *(S1+1) /d;
  70. *DA = d ;
  71. *(DA+1) = ZERO;
  72. return;
  73. } else { // scaled algorithm
  74. long double u = MIN ( safmax, MAX ( safmin, g1));
  75. FLOAT gs_r = db_r/u;
  76. FLOAT gs_i = db_i/u;
  77. d = sqrt ( gs_r*gs_r + gs_i*gs_i);
  78. *S = gs_r / d;
  79. *(S + 1) = (gs_i * -1) / d;
  80. *DA = d * u;
  81. *(DA+1) = ZERO;
  82. return;
  83. }
  84. }
  85. } else {
  86. FLOAT f1 = MAX ( fabsl(da_r), fabsl(da_i));
  87. FLOAT g1 = MAX ( fabsl(db_r), fabsl(db_i));
  88. rtmax = sqrt(safmax / 4.);
  89. if ( f1 > rtmin && f1 < rtmax && g1 > rtmin && g1 < rtmax) { //unscaled
  90. long double h = ada + adb;
  91. double adahsq = sqrt(ada * h);
  92. if (ada >= h *safmin) {
  93. *C = sqrt(ada/h);
  94. *R = *DA / *C;
  95. *(R+1) = *(DA+1) / *(C+1);
  96. rtmax *= 2.;
  97. if ( ada > rtmin && h < rtmax) { // no risk of intermediate overflow
  98. *S = *S1 * (*DA / adahsq) - *(S1+1)* (*(DA+1)/adahsq);
  99. *(S+1) = *S1 * (*(DA+1) / adahsq) + *(S1+1) * (*DA/adahsq);
  100. } else {
  101. *S = *S1 * (*R/h) - *(S1+1) * (*(R+1)/h);
  102. *(S+1) = *S1 * (*(R+1)/h) + *(S1+1) * (*(R)/h);
  103. }
  104. } else {
  105. *C = ada / adahsq;
  106. if (*C >= safmin)
  107. *R = *DA / *C;
  108. else
  109. *R = *DA * (h / adahsq);
  110. *S = *S1 * ada / adahsq;
  111. *(S+1) = *(S1+1) * ada / adahsq;
  112. }
  113. *DA=*R;
  114. *(DA+1)=*(R+1);
  115. return;
  116. } else { // scaled
  117. FLOAT fs_r, fs_i, gs_r, gs_i;
  118. long double v,w,f2,g2,h;
  119. long double u = MIN ( safmax, MAX ( safmin, MAX(f1,g1)));
  120. gs_r = db_r/u;
  121. gs_i = db_i/u;
  122. g2 = sqrt ( gs_r*gs_r + gs_i*gs_i);
  123. if (f1 /u < rtmin) {
  124. v = MIN (safmax, MAX (safmin, f1));
  125. w = v / u;
  126. fs_r = *DA/ v;
  127. fs_i = *(DA+1) / v;
  128. f2 = sqrt ( fs_r*fs_r + fs_i*fs_i);
  129. h = f2 * w * w + g2;
  130. } else { // use same scaling for both
  131. w = 1.;
  132. fs_r = *DA/ u;
  133. fs_i = *(DA+1) / u;
  134. f2 = sqrt ( fs_r*fs_r + fs_i*fs_i);
  135. h = f2 + g2;
  136. }
  137. if ( f2 >= h * safmin) {
  138. *C = sqrt ( f2 / h );
  139. *DA = fs_r / *C;
  140. *(DA+1) = fs_i / *C;
  141. rtmax *= 2;
  142. if ( f2 > rtmin && h < rtmax) {
  143. *S = gs_r * (fs_r /sqrt(f2*h)) - gs_i * (fs_i / sqrt(f2*h));
  144. *(S+1) = gs_r * (fs_i /sqrt(f2*h)) + gs_i * -1. * (fs_r / sqrt(f2*h));
  145. } else {
  146. *S = gs_r * (*DA/h) - gs_i * (*(DA+1) / h);
  147. *(S+1) = gs_r * (*(DA+1) /h) + gs_i * -1. * (*DA / h);
  148. }
  149. } else { // intermediates might overflow
  150. d = sqrt ( f2 * h);
  151. *C = f2 /d;
  152. if (*C >= safmin) {
  153. *DA = fs_r / *C;
  154. *(DA+1) = fs_i / *C;
  155. } else {
  156. *DA = fs_r * (h / d);
  157. *(DA+1) = fs_i / (h / d);
  158. }
  159. *S = gs_r * (fs_r /d) - gs_i * (fs_i / d);
  160. *(S+1) = gs_r * (fs_i /d) + gs_i * -1. * (fs_r / d);
  161. }
  162. *C *= w;
  163. *DA *= u;
  164. *(DA+1) *= u;
  165. return;
  166. }
  167. }
  168. }