BLAS++ 2024.05.31
BLAS C++ API
Loading...
Searching...
No Matches
rotmg.hh
1// Copyright (c) 2017-2023, University of Tennessee. All rights reserved.
2// SPDX-License-Identifier: BSD-3-Clause
3// This program is free software: you can redistribute it and/or modify it under
4// the terms of the BSD 3-Clause license. See the accompanying LICENSE file.
5
6#ifndef BLAS_ROTMG_HH
7#define BLAS_ROTMG_HH
8
9#include "blas/util.hh"
10
11#include <limits>
12
13namespace blas {
14
15// =============================================================================
97
98template <typename T>
99void rotmg(
100 T *d1,
101 T *d2,
102 T *a,
103 T b,
104 T param[5] )
105{
106 using std::abs;
107
108 // Constants
109 const T zero = 0;
110 const T one = 1;
111 const T gam = 4096;
112 const T gamsq = gam*gam;
113 const T rgamsq = one/gamsq;
114
115 T& x1 = *a;
116 T& y1 = b;
117
118 T h11 = zero;
119 T h12 = zero;
120 T h21 = zero;
121 T h22 = zero;
122
123 if (*d1 < zero) {
124 param[0] = -1;
125 *d1 = zero;
126 *d2 = zero;
127 x1 = zero;
128 }
129 else {
130 T p2 = (*d2)*y1;
131 if (p2 == zero) {
132 param[0] = -2;
133 return;
134 }
135
136 T p1 = (*d1)*x1;
137 T q2 = p2*y1;
138 T q1 = p1*x1;
139
140 if (abs(q1) > abs(q2)) {
141 param[0] = zero;
142 h21 = -y1/x1;
143 h12 = p2/p1;
144 T u = one - h12*h21;
145 if (u > zero) {
146 *d1 /= u;
147 *d2 /= u;
148 x1 *= u;
149 }
150 }
151 else if (q2 < zero) {
152 param[0] = -1;
153 *d1 = zero;
154 *d2 = zero;
155 x1 = zero;
156 }
157 else {
158 param[0] = 1;
159 h11 = p1/p2;
160 h22 = x1/y1;
161 T u = one + h11*h22;
162 T stemp = *d2/u;
163 *d2 = *d1/u;
164 *d1 = stemp;
165 x1 = y1*u;
166 }
167
168 if (*d1 != zero) {
169 while ((*d1 <= rgamsq) || (*d1 >= gamsq)) {
170 if (param[0] == 0) {
171 h11 = one;
172 h22 = one;
173 param[0] = -1;
174 }
175 else {
176 h21 = -one;
177 h12 = one;
178 param[0] = -1;
179 }
180 if (*d1 <= rgamsq) {
181 *d1 *= gam*gam;
182 x1 /= gam;
183 h11 /= gam;
184 h12 /= gam;
185 }
186 else {
187 *d1 /= gam*gam;
188 x1 *= gam;
189 h11 *= gam;
190 h12 *= gam;
191 }
192 }
193 }
194
195 if (*d2 != zero) {
196 while ((abs(*d2) <= rgamsq) || (abs(*d2) >= gamsq)) {
197 if (param[0] == 0) {
198 h11=one;
199 h22=one;
200 param[0]=-1;
201 }
202 else {
203 h21=-one;
204 h12=one;
205 param[0]=-1;
206 }
207 if (abs(*d2) <= rgamsq) {
208 *d2 *= gam*gam;
209 h21 /= gam;
210 h22 /= gam;
211 }
212 else {
213 *d2 /= gam*gam;
214 h21 *= gam;
215 h22 *= gam;
216 }
217 }
218 }
219 }
220
221 if (param[0] < 0) {
222 param[1] = h11;
223 param[2] = h21;
224 param[3] = h12;
225 param[4] = h22;
226 }
227 else if (param[0] == 0) {
228 param[2] = h21;
229 param[3] = h12;
230 }
231 else {
232 param[1] = h11;
233 param[4] = h22;
234 }
235}
236
237} // namespace blas
238
239#endif // #ifndef BLAS_ROTMG_HH
void rotmg(T *d1, T *d2, T *a, T b, T param[5])
Construct modified (fast) plane rotation, H, that eliminates b, such that.
Definition rotmg.hh:99