<T>LAPACK 0.1.2
C++ Template Linear Algebra PACKage
Loading...
Searching...
No Matches
laev2.hpp
Go to the documentation of this file.
1
3//
4// Copyright (c) 2021-2023, University of Colorado Denver. All rights reserved.
5//
6// This file is part of <T>LAPACK.
7// <T>LAPACK is free software: you can redistribute it and/or modify it under
8// the terms of the BSD 3-Clause license. See the accompanying LICENSE file.
9
10#ifndef TLAPACK_LAEV2_HH
11#define TLAPACK_LAEV2_HH
12
14
15namespace tlapack {
16
58template <TLAPACK_SCALAR T>
59void laev2(T a, T b, T c, T& s1, T& s2, T& cs, T& sn)
60{
61 // Constants
62 const T zero(0);
63 const T one(1);
64 const T two(2);
65 const T half(0.5);
66
67 // Compute the eigenvalues
68 T sm = a + c;
69 T df = a - c;
70 T adf = abs(df);
71 T tb = b + b;
72 T ab = abs(tb);
73 T acmx, acmn;
74 if (abs(a) > abs(c)) {
75 acmx = a;
76 acmn = c;
77 }
78 else {
79 acmx = c;
80 acmn = a;
81 }
82
83 T rt;
84 if (adf > ab) {
85 rt = adf * sqrt(one + square(ab / adf));
86 }
87 else if (adf < ab) {
88 rt = ab * sqrt(one + square(adf / ab));
89 }
90 else {
91 // This case includes case AB=ADF=0
92 rt = ab * sqrt(two);
93 }
94
95 int sign1;
96 if (sm < zero) {
97 s1 = half * (sm - rt);
98 sign1 = -1;
99 // Order of execution important.
100 // To get fully accurate smaller eigenvalue,
101 // next line needs to be executed in higher precision.
102 s2 = (acmx / s1) * acmn - (b / s1) * b;
103 }
104 else if (sm > zero) {
105 s1 = half * (sm + rt);
106 sign1 = 1;
107 // Order of execution important.
108 // To get fully accurate smaller eigenvalue,
109 // next line needs to be executed in higher precision.
110 s2 = (acmx / s1) * acmn - (b / s1) * b;
111 }
112 else {
113 // Includes case s1 = s2 = 0
114 s1 = half * rt;
115 s2 = -half * rt;
116 sign1 = 1;
117 }
118
119 // Compute the eigenvector
120 int sign2;
121 if (df >= zero) {
122 cs = df + rt;
123 sign2 = 1;
124 }
125 else {
126 cs = df - rt;
127 sign2 = -1;
128 }
129 T acs = abs(cs);
130 if (acs > ab) {
131 T ct = -tb / cs;
132 sn = one / sqrt(one + square(ct));
133 cs = ct * sn;
134 }
135 else {
136 if (ab == zero) {
137 cs = one;
138 sn = zero;
139 }
140 else {
141 T tn = -cs / tb;
142 cs = one / sqrt(one + square(tn));
143 sn = tn * cs;
144 }
145 }
146 if (sign1 == sign2) {
147 T tn = cs;
148 cs = -sn;
149 sn = tn;
150 }
151}
152} // namespace tlapack
153
154#endif // TLAPACK_LAEV2_HH
void laev2(T a, T b, T c, T &s1, T &s2, T &cs, T &sn)
Computes the eigenvalues and eigenvector of a real symmetric 2x2 matrix A [ a b ] [ b c ] On exit,...
Definition laev2.hpp:59
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