Skip to content

Commit 33797c4

Browse files
authored
Merge pull request #4143 from martin-frbg/issue4130
Update to use safe scaling algorithm from Reference-LAPACK PR 527
2 parents ee310e3 + 42909ce commit 33797c4

File tree

2 files changed

+200
-123
lines changed

2 files changed

+200
-123
lines changed

interface/rotg.c

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#include <math.h>
2+
#include <float.h>
23
#include "common.h"
34
#ifdef FUNCTION_PROFILE
45
#include "functable.h"
56
#endif
67

8+
79
#ifndef CBLAS
810

911
void NAME(FLOAT *DA, FLOAT *DB, FLOAT *C, FLOAT *S){
@@ -14,35 +16,53 @@ void CNAME(FLOAT *DA, FLOAT *DB, FLOAT *C, FLOAT *S){
1416

1517
#endif
1618

19+
#ifdef DOUBLE
20+
long double safmin = DBL_MIN;
21+
#else
22+
long double safmin = FLT_MIN;
23+
#endif
24+
1725
#if defined(__i386__) || defined(__x86_64__) || defined(__ia64__) || defined(_M_X64) || defined(_M_IX86)
1826

1927
long double da = *DA;
2028
long double db = *DB;
2129
long double c;
2230
long double s;
23-
long double r, roe, z;
31+
long double r, z;
32+
long double sigma, dascal,dbscal;
2433

2534
long double ada = fabsl(da);
2635
long double adb = fabsl(db);
27-
long double scale = ada + adb;
36+
long double maxab = MAX(ada,adb);
37+
long double safmax;
38+
long double scale;
39+
2840

2941
#ifndef CBLAS
3042
PRINT_DEBUG_NAME;
3143
#else
3244
PRINT_DEBUG_CNAME;
3345
#endif
3446

35-
roe = db;
36-
if (ada > adb) roe = da;
37-
38-
if (scale == ZERO) {
47+
if (adb == ZERO) {
3948
*C = ONE;
4049
*S = ZERO;
41-
*DA = ZERO;
4250
*DB = ZERO;
51+
} else if (ada == ZERO) {
52+
*C = ZERO;
53+
*S = ONE;
54+
*DA = *DB;
55+
*DB = ONE;
4356
} else {
44-
r = sqrt(da * da + db * db);
45-
if (roe < 0) r = -r;
57+
safmax = 1./safmin;
58+
scale = MIN(MAX(safmin,maxab), safmax);
59+
if (ada > adb)
60+
sigma = copysign(1.,da);
61+
else
62+
sigma = copysign(1.,db);
63+
dascal = da / scale;
64+
dbscal = db / scale;
65+
r = sigma * (scale * sqrt(dascal * dascal + dbscal * dbscal));
4666
c = da / r;
4767
s = db / r;
4868
z = ONE;
@@ -65,32 +85,44 @@ void CNAME(FLOAT *DA, FLOAT *DB, FLOAT *C, FLOAT *S){
6585
FLOAT db = *DB;
6686
FLOAT c = *C;
6787
FLOAT s = *S;
68-
FLOAT r, roe, z;
88+
FLOAT sigma;
89+
FLOAT r, z;
6990

7091
FLOAT ada = fabs(da);
7192
FLOAT adb = fabs(db);
72-
FLOAT scale = ada + adb;
93+
FLOAT maxab = MAX(ada,adb);
94+
long double safmax ;
95+
FLOAT scale ;
96+
97+
safmax = 1./safmin;
98+
scale = MIN(MAX(safmin,maxab), safmax);
99+
100+
if (ada > adb)
101+
sigma = copysign(1.,da);
102+
else
103+
sigma = copysign(1.,db);
73104

74105
#ifndef CBLAS
75106
PRINT_DEBUG_NAME;
76107
#else
77108
PRINT_DEBUG_CNAME;
78109
#endif
79110

80-
roe = db;
81-
if (ada > adb) roe = da;
82111

83-
if (scale == ZERO) {
112+
if (adb == ZERO) {
84113
*C = ONE;
85114
*S = ZERO;
86-
*DA = ZERO;
87115
*DB = ZERO;
116+
} else if (ada == ZERO) {
117+
*C = ZERO;
118+
*S = ONE;
119+
*DA = *DB;
120+
*DB = ONE;
88121
} else {
89122
FLOAT aa = da / scale;
90123
FLOAT bb = db / scale;
91124

92-
r = scale * sqrt(aa * aa + bb * bb);
93-
if (roe < 0) r = -r;
125+
r = sigma * scale * sqrt(aa * aa + bb * bb);
94126
c = da / r;
95127
s = db / r;
96128
z = ONE;

0 commit comments

Comments
 (0)