<T>LAPACK 0.1.1
C++ Template Linear Algebra PACKage
Loading...
Searching...
No Matches
lascl.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_LASCL_HH
13#define TLAPACK_LASCL_HH
14
17
18namespace tlapack {
19
53template <TLAPACK_UPLO uplo_t,
54 TLAPACK_MATRIX matrix_t,
55 TLAPACK_REAL a_type,
56 TLAPACK_REAL b_type,
57 enable_if_t<(
58 /* Requires: */
59 is_real<a_type> && is_real<b_type>),
60 int> = 0>
61int lascl(uplo_t uplo, const b_type& b, const a_type& a, matrix_t& A)
62{
63 // data traits
64 using idx_t = size_type<matrix_t>;
66
67 // constants
68 const idx_t m = nrows(A);
69 const idx_t n = ncols(A);
70
71 // constants
73 const real_t big = safe_max<real_t>();
74
75 // check arguments
77 (uplo != Uplo::General) && (uplo != Uplo::UpperHessenberg) &&
78 (uplo != Uplo::LowerHessenberg) && (uplo != Uplo::Upper) &&
79 (uplo != Uplo::Lower) && (uplo != Uplo::StrictUpper) &&
80 (uplo != Uplo::StrictLower));
81 tlapack_check_false((b == b_type(0)) || isnan(b));
83
84 // quick return
85 if (m <= 0 || n <= 0) return 0;
86
87 bool done = false;
88 real_t a_ = a, b_ = b;
89 while (!done) {
90 real_t c, a1, b1 = b * small;
91 if (b1 == b_) {
92 // b is not finite:
93 // c is a correctly signed zero if a is finite,
94 // c is NaN otherwise.
95 c = a_ / b_;
96 done = true;
97 }
98 else { // b is finite
99 a1 = a_ / big;
100 if (a1 == a_) {
101 // a is either 0 or an infinity number:
102 // in both cases, c = a serves as the correct multiplication
103 // factor.
104 c = a_;
105 done = true;
106 }
107 else if ((abs(b1) > abs(a_)) && (a_ != real_t(0))) {
108 // a is a non-zero finite number and abs(a/b) < small:
109 // Set c = small as the multiplication factor,
110 // Multiply b by the small factor.
111 c = small;
112 done = false;
113 b_ = b1;
114 }
115 else if (abs(a1) > abs(b_)) {
116 // abs(a/b) > big:
117 // Set c = big as the multiplication factor,
118 // Divide a by the big factor.
119 c = big;
120 done = false;
121 a_ = a1;
122 }
123 else {
124 // small <= abs(a/b) <= big:
125 // Set c = a/b as the multiplication factor.
126 c = a_ / b_;
127 done = true;
128 }
129 }
130
131 if (uplo == Uplo::UpperHessenberg) {
132 for (idx_t j = 0; j < n; ++j)
133 for (idx_t i = 0; i < ((j < m) ? j + 2 : m); ++i)
134 A(i, j) *= c;
135 }
136 else if (uplo == Uplo::Upper) {
137 for (idx_t j = 0; j < n; ++j)
138 for (idx_t i = 0; i < ((j < m) ? j + 1 : m); ++i)
139 A(i, j) *= c;
140 }
141 else if (uplo == Uplo::StrictUpper) {
142 for (idx_t j = 0; j < n; ++j)
143 for (idx_t i = 0; i < ((j < m) ? j : m); ++i)
144 A(i, j) *= c;
145 }
146 else if (uplo == Uplo::LowerHessenberg) {
147 for (idx_t j = 0; j < n; ++j)
148 for (idx_t i = ((j > 1) ? j - 1 : 0); i < m; ++i)
149 A(i, j) *= c;
150 }
151 else if (uplo == Uplo::Lower) {
152 for (idx_t j = 0; j < n; ++j)
153 for (idx_t i = j; i < m; ++i)
154 A(i, j) *= c;
155 }
156 else if (uplo == Uplo::StrictLower) {
157 for (idx_t j = 0; j < n; ++j)
158 for (idx_t i = j + 1; i < m; ++i)
159 A(i, j) *= c;
160 }
161 else // if ( uplo == Uplo::General )
162 {
163 for (idx_t j = 0; j < n; ++j)
164 for (idx_t i = 0; i < m; ++i)
165 A(i, j) *= c;
166 }
167 }
168
169 return 0;
170}
171
187template <TLAPACK_MATRIX matrix_t,
188 TLAPACK_REAL a_type,
189 TLAPACK_REAL b_type,
190 enable_if_t<(
191 /* Requires: */
192 is_real<a_type> && is_real<b_type>),
193 int> = 0>
195{
196 // data traits
197 using idx_t = size_type<matrix_t>;
199
200 // constants
201 const idx_t m = nrows(A);
202 const idx_t n = ncols(A);
203 const idx_t kl = accessType.lower_bandwidth;
204 const idx_t ku = accessType.upper_bandwidth;
205
206 // constants
207 const real_t small = safe_min<real_t>();
208 const real_t big = safe_max<real_t>();
209
210 // check arguments
211 tlapack_check_false((kl < 0) || (kl >= m) || (ku < 0) || (ku >= n));
212 tlapack_check_false((b == b_type(0)) || isnan(b));
214
215 // quick return
216 if (m <= 0 || n <= 0) return 0;
217
218 bool done = false;
219 real_t a_ = a, b_ = b;
220 while (!done) {
221 real_t c, a1, b1 = b * small;
222 if (b1 == b_) {
223 // b is not finite:
224 // c is a correctly signed zero if a is finite,
225 // c is NaN otherwise.
226 c = a_ / b_;
227 done = true;
228 }
229 else { // b is finite
230 a1 = a_ / big;
231 if (a1 == a_) {
232 // a is either 0 or an infinity number:
233 // in both cases, c = a serves as the correct multiplication
234 // factor.
235 c = a_;
236 done = true;
237 }
238 else if ((abs(b1) > abs(a_)) && (a_ != real_t(0))) {
239 // a is a non-zero finite number and abs(a/b) < small:
240 // Set c = small as the multiplication factor,
241 // Multiply b by the small factor.
242 c = small;
243 done = false;
244 b_ = b1;
245 }
246 else if (abs(a1) > abs(b_)) {
247 // abs(a/b) > big:
248 // Set c = big as the multiplication factor,
249 // Divide a by the big factor.
250 c = big;
251 done = false;
252 a_ = a1;
253 }
254 else {
255 // small <= abs(a/b) <= big:
256 // Set c = a/b as the multiplication factor.
257 c = a_ / b_;
258 done = true;
259 }
260 }
261
262 for (idx_t j = 0; j < n; ++j)
263 for (idx_t i = ((j >= ku) ? (j - ku) : 0); i < min(m, j + kl + 1);
264 ++i)
265 A(i, j) *= c;
266 }
267
268 return 0;
269}
270
271} // namespace tlapack
272
273#endif // TLAPACK_LASCL_HH
constexpr bool isnan(const T &x) noexcept
Extends std::isnan() to complex numbers.
Definition utils.hpp:125
#define TLAPACK_UPLO
Macro for tlapack::concepts::Uplo compatible with C++17.
Definition concepts.hpp:942
#define TLAPACK_MATRIX
Macro for tlapack::concepts::Matrix compatible with C++17.
Definition concepts.hpp:896
#define TLAPACK_REAL
Macro for tlapack::concepts::Real compatible with C++17.
Definition concepts.hpp:918
int lascl(uplo_t uplo, const b_type &b, const a_type &a, matrix_t &A)
Multiplies a matrix A by the real scalar a/b.
Definition lascl.hpp:61
#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
Band access.
Definition types.hpp:427