<T>LAPACK 0.1.1
C++ Template Linear Algebra PACKage
Loading...
Searching...
No Matches
rotmg.hpp
Go to the documentation of this file.
1
3//
4// Copyright (c) 2017-2021, University of Tennessee. All rights reserved.
5// Copyright (c) 2021-2023, University of Colorado Denver. All rights reserved.
6//
7// This file is part of <T>LAPACK.
8// <T>LAPACK is free software: you can redistribute it and/or modify it under
9// the terms of the BSD 3-Clause license. See the accompanying LICENSE file.
10
11#ifndef TLAPACK_BLAS_ROTMG_HH
12#define TLAPACK_BLAS_ROTMG_HH
13
15
16namespace tlapack {
17
92template <TLAPACK_REAL T,
93 enable_if_t<is_real<T>, int> = 0,
94 disable_if_allow_optblas_t<T> = 0>
95int rotmg(T& d1, T& d2, T& a, const T& b, T h[4])
96{
97 // check arguments
99
100 // Constants
101 const T zero(0);
102 const T one(1);
103 const T gam(4096);
104 const T gamsq = gam * gam;
105 const T rgamsq = one / gamsq;
106
107 int flag;
108 h[0] = zero;
109 h[1] = zero;
110 h[2] = zero;
111 h[3] = zero;
112
113 if (d1 < zero) {
114 flag = -1;
115 d1 = zero;
116 d2 = zero;
117 a = zero;
118 }
119 else {
120 const T p2 = d2 * b;
121 if (p2 == zero) {
122 flag = -2;
123 }
124 else {
125 const T p1 = d1 * a;
126 const T q2 = p2 * b;
127 const T q1 = p1 * a;
128
129 if (abs(q1) > abs(q2)) {
130 flag = zero;
131 h[1] = -b / a;
132 h[2] = p2 / p1;
133 const T u = one - h[2] * h[1];
134 if (u > zero) {
135 d1 /= u;
136 d2 /= u;
137 a *= u;
138 }
139 }
140 else if (q2 < zero) {
141 flag = -1;
142 d1 = zero;
143 d2 = zero;
144 a = zero;
145 }
146 else {
147 flag = 1;
148 h[0] = p1 / p2;
149 h[3] = a / b;
150 const T u = one + h[0] * h[3];
151 const T stemp = d2 / u;
152 d2 = d1 / u;
153 d1 = stemp;
154 a = b * u;
155 }
156
157 if (d1 != zero) {
158 while ((d1 <= rgamsq) || (d1 >= gamsq)) {
159 if (flag == 0) {
160 h[0] = one;
161 h[3] = one;
162 flag = -1;
163 }
164 else {
165 h[1] = -one;
166 h[2] = one;
167 flag = -1;
168 }
169 if (d1 <= rgamsq) {
170 d1 *= gam * gam;
171 a /= gam;
172 h[0] /= gam;
173 h[2] /= gam;
174 }
175 else {
176 d1 /= gam * gam;
177 a *= gam;
178 h[0] *= gam;
179 h[2] *= gam;
180 }
181 }
182 }
183
184 if (d2 != zero) {
185 while ((abs(d2) <= rgamsq) || (abs(d2) >= gamsq)) {
186 if (flag == 0) {
187 h[0] = one;
188 h[3] = one;
189 flag = -1;
190 }
191 else {
192 h[1] = -one;
193 h[2] = one;
194 flag = -1;
195 }
196 if (abs(d2) <= rgamsq) {
197 d2 *= gam * gam;
198 h[1] /= gam;
199 h[3] /= gam;
200 }
201 else {
202 d2 /= gam * gam;
203 h[1] *= gam;
204 h[3] *= gam;
205 }
206 }
207 }
208 }
209 }
210
211 return flag;
212}
213
214#ifdef TLAPACK_USE_LAPACKPP
215
216template <TLAPACK_REAL T,
217 enable_if_t<is_real<T>, int> = 0,
218 enable_if_allow_optblas_t<T> = 0>
219int rotmg(T& d1, T& d2, T& a, const T b, T h[4])
220{
221 T param[5];
222 ::blas::rotmg(&d1, &d2, &a, b, param);
223
224 // Collect the output
225 h[0] = param[1];
226 h[1] = param[2];
227 h[2] = param[3];
228 h[3] = param[4];
229
230 return param[0];
231}
232
233#endif
234
235} // namespace tlapack
236
237#endif // #ifndef TLAPACK_BLAS_ROTMG_HH
#define TLAPACK_REAL
Macro for tlapack::concepts::Real compatible with C++17.
Definition concepts.hpp:918
int rotmg(T &d1, T &d2, T &a, const T &b, T h[4])
Construct modified (fast) plane rotation, H, that eliminates b, such that.
Definition rotmg.hpp:95
#define tlapack_check_false(cond)
Throw an error if cond is true.
Definition exceptionHandling.hpp:113
typename traits::real_type_traits< Types..., int >::type real_type
The common real type of the list of types.
Definition scalar_type_traits.hpp:113