<T>LAPACK 0.1.1
C++ Template Linear Algebra PACKage
Loading...
Searching...
No Matches
lahqr_schur22.hpp
Go to the documentation of this file.
1
5//
6// Copyright (c) 2021-2023, University of Colorado Denver. All rights reserved.
7//
8// This file is part of <T>LAPACK.
9// <T>LAPACK is free software: you can redistribute it and/or modify it under
10// the terms of the BSD 3-Clause license. See the accompanying LICENSE file.
11
12#ifndef TLAPACK_LAHQR_SCHUR22_HH
13#define TLAPACK_LAHQR_SCHUR22_HH
14
18
19namespace tlapack {
20
43template <TLAPACK_REAL T>
44void lahqr_schur22(T& a,
45 T& b,
46 T& c,
47 T& d,
50 T& cs,
51 T& sn)
52{
53 const T zero(0);
54 const T half(0.5);
55 const T one(1);
56 const T multpl(4);
57
58 const T eps = ulp<T>();
59 const T safmin = safe_min<T>();
60 const T safmn2 = pow(2, T((int)(log2(safmin / eps)) / 2));
61 const T safmx2 = one / safmn2;
62
63 if (c == zero) {
64 // c is zero, the matrix is already in Schur form.
65 cs = one;
66 sn = zero;
67 }
68 else if (b == zero) {
69 // b is zero, swapping rows and columns results in Schur form.
70 cs = zero;
71 sn = one;
72 const T temp = d;
73 d = a;
74 a = temp;
75 b = -c;
76 c = zero;
77 }
78 else if ((a - d) == zero and sgn(b) != sgn(c)) {
79 cs = one;
80 sn = zero;
81 }
82 else {
83 T temp = a - d;
84 T p = half * temp;
85 const T bcmax = max(abs(b), abs(c));
86 const T bcmin = min(abs(b), abs(c)) * T(sgn(b) * sgn(c));
87 T scale = max(abs(p), bcmax);
88 T z = (p / scale) * p + (bcmax / scale) * bcmin;
89 // if z is positive, we should have real eigenvalues
90 // however, is z is very small, but positive, we postpone the decision
91 if (z >= multpl * eps) {
92 // Real eigenvalues.
93
94 // Compute a and d.
95 z = p + T(sgn(p)) * sqrt(scale) * sqrt(z);
96 a = d + z;
97 d = d - (bcmax / z) * bcmin;
98 // Compute b and the rotation matrix
99 const T tau = lapy2(c, z);
100 cs = z / tau;
101 sn = c / tau;
102 b = b - c;
103 c = zero;
104 }
105 else {
106 // Complex eigenvalues, or real (almost) equal eigenvalues.
107
108 // Make diagonal elements equal.
109 T sigma = b + c;
110 for (int count = 0; count < 20; ++count) {
111 scale = max(abs(temp), abs(sigma));
112 if (scale >= safmx2) {
113 sigma = sigma * safmn2;
114 temp = temp * safmn2;
115 continue;
116 }
117 if (scale <= safmn2) {
118 sigma = sigma * safmx2;
119 temp = temp * safmx2;
120 continue;
121 }
122 break;
123 }
124 p = half * temp;
125 T tau = lapy2(sigma, temp);
126 cs = sqrt(half * (one + abs(sigma) / tau));
127 sn = -(p / (tau * cs)) * T(sgn(sigma));
128 //
129 // Compute [aa bb] = [a b][cs -sn]
130 // [cc dd] = [c d][sn cs]
131 //
132 const T aa = a * cs + b * sn;
133 const T bb = -a * sn + b * cs;
134 const T cc = c * cs + d * sn;
135 const T dd = -c * sn + d * cs;
136 //
137 // Compute [a b] = [ cs sn][aa bb]
138 // [c d] = [-sn cs][cc dd]
139 //
140 a = aa * cs + cc * sn;
141 b = bb * cs + dd * sn;
142 c = -aa * sn + cc * cs;
143 d = -bb * sn + dd * cs;
144
145 temp = half * (a + d);
146 a = temp;
147 d = temp;
148
149 if (c != zero) {
150 if (b != zero) {
151 if (sgn(b) == sgn(c)) {
152 // Real eigenvalues: reduce to upper triangular form
153 const T sab = sqrt(abs(b));
154 const T sac = sqrt(abs(c));
155 p = (c > T(0)) ? sab * sac : -sab * sac;
156 tau = one / sqrt(abs(b + c));
157 a = temp + p;
158 d = temp - p;
159 b = b - c;
160 c = zero;
161 const T cs1 = sab * tau;
162 const T sn1 = sac * tau;
163 temp = cs * cs1 - sn * sn1;
164 sn = cs * sn1 + sn * cs1;
165 cs = temp;
166 }
167 }
168 }
169 }
170 }
171 // Store eigenvalues in s1 and s2
172 if (c != zero) {
173 const T temp = sqrt(abs(b)) * sqrt(abs(c));
174 s1 = complex_type<T>(a, temp);
176 }
177 else {
178 s1 = a;
179 s2 = d;
180 }
181}
182
183} // namespace tlapack
184
185#endif // TLAPACK_LAHQR_SCHUR22_HH
constexpr int sgn(const T &val)
Type-safe sgn function.
Definition utils.hpp:109
real_type< TX, TY > lapy2(const TX &x, const TY &y)
Finds , taking care not to cause unnecessary overflow.
Definition lapy2.hpp:32
void lahqr_schur22(T &a, T &b, T &c, T &d, complex_type< T > &s1, complex_type< T > &s2, T &cs, T &sn)
Computes the Schur factorization of a 2x2 matrix A.
Definition lahqr_schur22.hpp:44
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