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 3.5 kB

7 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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. #else
  18. long double safmin = FLT_MIN;
  19. #endif
  20. #if defined(__i386__) || defined(__x86_64__) || defined(__ia64__) || defined(_M_X64) || defined(_M_IX86)
  21. long double da_r = *(DA + 0);
  22. long double da_i = *(DA + 1);
  23. long double db_r = *(DB + 0);
  24. long double db_i = *(DB + 1);
  25. long double r;
  26. long double ada = fabsl(da_r) + fabsl(da_i);
  27. long double adb = sqrt(db_r * db_r + db_i * db_i);
  28. PRINT_DEBUG_NAME;
  29. IDEBUG_START;
  30. FUNCTION_PROFILE_START();
  31. if (ada == ZERO) {
  32. *C = ZERO;
  33. *(S + 0) = ONE;
  34. *(S + 1) = ZERO;
  35. *(DA + 0) = db_r;
  36. *(DA + 1) = db_i;
  37. } else {
  38. long double alpha_r, alpha_i;
  39. long double safmax = 1./safmin;
  40. long double sigma;
  41. long double maxab = MAX(ada,adb);
  42. long double scale = MIN(MAX(safmin,maxab), safmax);
  43. long double aa_r = da_r / scale;
  44. long double aa_i = da_i / scale;
  45. long double bb_r = db_r / scale;
  46. long double bb_i = db_i / scale;
  47. if (ada > adb)
  48. sigma = copysign(1.,da_r);
  49. else
  50. sigma = copysign(1.,db_r);
  51. r = sigma * scale * sqrt(aa_r * aa_r + aa_i * aa_i + bb_r * bb_r + bb_i * bb_i);
  52. alpha_r = da_r / ada;
  53. alpha_i = da_i / ada;
  54. *(C + 0) = ada / r;
  55. *(S + 0) = (alpha_r * db_r + alpha_i *db_i) / r;
  56. *(S + 1) = (alpha_i * db_r - alpha_r *db_i) / r;
  57. *(DA + 0) = alpha_r * r;
  58. *(DA + 1) = alpha_i * r;
  59. }
  60. #else
  61. FLOAT da_r = *(DA + 0);
  62. FLOAT da_i = *(DA + 1);
  63. FLOAT db_r = *(DB + 0);
  64. FLOAT db_i = *(DB + 1);
  65. FLOAT r;
  66. FLOAT ada = fabs(da_r) + fabs(da_i);
  67. FLOAT ada = fabs(db_r) + fabs(db_i);
  68. PRINT_DEBUG_NAME;
  69. IDEBUG_START;
  70. FUNCTION_PROFILE_START();
  71. if (ada == ZERO) {
  72. *C = ZERO;
  73. *(S + 0) = ONE;
  74. *(S + 1) = ZERO;
  75. *(DA + 0) = db_r;
  76. *(DA + 1) = db_i;
  77. } else {
  78. long double safmax = 1./safmin;
  79. FLOAT scale;
  80. FLOAT aa_r, aa_i, bb_r, bb_i;
  81. FLOAT alpha_r, alpha_i;
  82. aa_r = fabs(da_r);
  83. aa_i = fabs(da_i);
  84. if (aa_i > aa_r) {
  85. aa_r = fabs(da_i);
  86. aa_i = fabs(da_r);
  87. }
  88. if (aa_r == ZERO) {
  89. ada = 0.;
  90. } else {
  91. scale = (aa_i / aa_r);
  92. ada = aa_r * sqrt(ONE + scale * scale);
  93. }
  94. bb_r = fabs(db_r);
  95. bb_i = fabs(db_i);
  96. if (bb_i > bb_r) {
  97. bb_r = fabs(bb_i);
  98. bb_i = fabs(bb_r);
  99. }
  100. if (bb_r == ZERO) {
  101. adb = 0.;
  102. } else {
  103. scale = (bb_i / bb_r);
  104. adb = bb_r * sqrt(ONE + scale * scale);
  105. }
  106. FLOAT maxab = MAX(ada,adb);
  107. scale = MIN(MAX(safmin,maxab), safmax);
  108. aa_r = da_r / scale;
  109. aa_i = da_i / scale;
  110. bb_r = db_r / scale;
  111. bb_i = db_i / scale;
  112. if (ada > adb)
  113. sigma = copysign(1.,da_r);
  114. else
  115. sigma = copysign(1.,db_r);
  116. r = sigma * scale * sqrt(aa_r * aa_r + aa_i * aa_i + bb_r * bb_r + bb_i * bb_i);
  117. alpha_r = da_r / ada;
  118. alpha_i = da_i / ada;
  119. *(C + 0) = ada / r;
  120. *(S + 0) = (alpha_r * db_r + alpha_i *db_i) / r;
  121. *(S + 1) = (alpha_i * db_r - alpha_r *db_i) / r;
  122. *(DA + 0) = alpha_r * r;
  123. *(DA + 1) = alpha_i * r;
  124. }
  125. #endif
  126. FUNCTION_PROFILE_END(4, 4, 4);
  127. IDEBUG_END;
  128. return;
  129. }