TRIQS/nda 2.0.0
Multi-dimensional array library for C++
Loading...
Searching...
No Matches
ggev.hpp
Go to the documentation of this file.
1// Copyright (c) 2024--present, The Simons Foundation
2// This file is part of TRIQS/nda and is licensed under the Apache License, Version 2.0.
3// SPDX-License-Identifier: Apache-2.0
4// See LICENSE in the root of this distribution for details.
5
10
11#pragma once
12
14#include "../basic_array.hpp"
16#include "../blas/tools.hpp"
17#include "../concepts.hpp"
18#include "../declarations.hpp"
19#include "../macros.hpp"
21#include "../traits.hpp"
22
23#include <cmath>
24#include <complex>
25#include <concepts>
26
27namespace nda::lapack {
28
89 template <BlasArrayReal<2> A, BlasArrayFor<A, 2> B, BlasArrayFor<A, 1> AR, BlasArrayFor<A, 1> AI, BlasArrayFor<A, 1> B2, BlasArrayFor<A, 2> VL,
90 BlasArrayFor<A, 2> VR, BlasArrayFor<A, 1> W1 = vector_value_t<A>>
92 int ggev(A &&a, B &&b, AR &&alphar, AI &&alphai, B2 &&beta, VL &&vl, VR &&vr, char jobvl = 'N', char jobvr = 'V', // NOLINT
93 W1 &&work = vector_value_t<A>{}) { // NOLINT
94 // check the dimensions of the input/output arrays/views
95 auto const [m, n] = a.shape();
96 EXPECTS(m == n);
97 EXPECTS(b.shape() == a.shape());
98 resize_or_check_if_view(alphar, {n});
99 resize_or_check_if_view(alphai, {n});
100 resize_or_check_if_view(beta, {n});
101
102 // check other input parameters for consistency
103 EXPECTS(jobvl == 'V' or jobvl == 'N');
104 EXPECTS(jobvr == 'V' or jobvr == 'N');
105
106 // resize eigenvector matrices if needed
107 int ldvl = 1;
108 int ldvr = 1;
109 if (jobvl == 'V') {
110 resize_or_check_if_view(vl, {n, n});
111 ldvl = get_ld(vl);
112 }
113 if (jobvr == 'V') {
114 resize_or_check_if_view(vr, {n, n});
115 ldvr = get_ld(vr);
116 }
117
118 // arrays/views must be LAPACK compatible
119 EXPECTS(a.indexmap().min_stride() == 1);
120 EXPECTS(b.indexmap().min_stride() == 1);
121 EXPECTS(alphar.indexmap().min_stride() == 1);
122 EXPECTS(alphai.indexmap().min_stride() == 1);
123 EXPECTS(beta.indexmap().min_stride() == 1);
124 EXPECTS(jobvl == 'N' or vl.indexmap().min_stride() == 1);
125 EXPECTS(jobvr == 'N' or vr.indexmap().min_stride() == 1);
126
127 // first call to get the optimal buffer size
128 auto tmp_lwork = get_value_t<A>{};
129 int info = 0;
130 lapack::f77::ggev(jobvl, jobvr, n, a.data(), get_ld(a), b.data(), get_ld(b), alphar.data(), alphai.data(), beta.data(), vl.data(), ldvl,
131 vr.data(), ldvr, &tmp_lwork, -1, info);
132 int lwork = static_cast<int>(std::ceil(tmp_lwork));
133
134 // resize/check work buffer
135 resize_or_check_work_buffer(work, lwork);
136
137 // perform actual library call
138 lapack::f77::ggev(jobvl, jobvr, n, a.data(), get_ld(a), b.data(), get_ld(b), alphar.data(), alphai.data(), beta.data(), vl.data(), ldvl,
139 vr.data(), ldvr, work.data(), lwork, info);
140
141 return info;
142 }
143
199 template <BlasArrayCplx<2> A, BlasArrayFor<A, 2> B, BlasArrayFor<A, 1> A2, BlasArrayFor<A, 1> B2, BlasArrayFor<A, 2> VL, BlasArrayFor<A, 2> VR,
200 BlasArrayFor<A, 1> W1 = vector_value_t<A>, BlasArrayRealFor<A, 1> W2 = vector_fp_t<A>>
202 int ggev(A &&a, B &&b, A2 &&alpha, B2 &&beta, VL &&vl, VR &&vr, char jobvl = 'N', char jobvr = 'V', // NOLINT
203 W1 &&work = vector_value_t<A>{}, W2 &&rwork = vector_fp_t<A>{}) { // NOLINT
204 // check the dimensions of the input/output arrays/views
205 auto const [m, n] = a.shape();
206 EXPECTS(m == n);
207 EXPECTS(b.shape() == a.shape());
208 resize_or_check_if_view(alpha, {n});
209 resize_or_check_if_view(beta, {n});
210 resize_or_check_work_buffer(rwork, 8 * n);
211
212 // check parameters
213 EXPECTS(jobvl == 'V' or jobvl == 'N');
214 EXPECTS(jobvr == 'V' or jobvr == 'N');
215
216 // resize eigenvector matrices if needed
217 int ldvl = 1;
218 int ldvr = 1;
219 if (jobvl == 'V') {
220 resize_or_check_if_view(vl, {n, n});
221 ldvl = get_ld(vl);
222 }
223 if (jobvr == 'V') {
224 resize_or_check_if_view(vr, {n, n});
225 ldvr = get_ld(vr);
226 }
227
228 // arrays/views must be LAPACK compatible
229 EXPECTS(a.indexmap().min_stride() == 1);
230 EXPECTS(b.indexmap().min_stride() == 1);
231 EXPECTS(alpha.indexmap().min_stride() == 1);
232 EXPECTS(beta.indexmap().min_stride() == 1);
233 EXPECTS(jobvl == 'N' or vl.indexmap().min_stride() == 1);
234 EXPECTS(jobvr == 'N' or vr.indexmap().min_stride() == 1);
235
236 // first call to get the optimal buffer size
237 auto tmp_lwork = get_value_t<A>{};
238 int info = 0;
239 lapack::f77::ggev(jobvl, jobvr, n, a.data(), get_ld(a), b.data(), get_ld(b), alpha.data(), beta.data(), vl.data(), ldvl, vr.data(), ldvr,
240 &tmp_lwork, -1, rwork.data(), info);
241 int lwork = static_cast<int>(std::ceil(std::real(tmp_lwork)));
242
243 // resize/check work buffer
244 resize_or_check_work_buffer(work, lwork);
245
246 // perform actual library call
247 lapack::f77::ggev(jobvl, jobvr, n, a.data(), get_ld(a), b.data(), get_ld(b), alpha.data(), beta.data(), vl.data(), ldvl, vr.data(), ldvr,
248 work.data(), lwork, rwork.data(), info);
249
250 return info;
251 }
252
253} // namespace nda::lapack
Provides definitions and type traits involving the different memory address spaces supported by nda.
Provides the generic class for arrays.
Provides basic functions to create and manipulate arrays and views.
Provides various traits and utilities for the BLAS interface.
Provides concepts for the nda library.
Provides various convenient aliases and helper functions for nda::basic_array and nda::basic_array_vi...
void resize_or_check_if_view(A &a, std::array< long, A::rank > const &sha)
Resize a given regular array to the given shape or check if a given view as the correct shape.
std::decay_t< decltype(get_first_element(std::declval< A const >()))> get_value_t
Get the value type of an array/view or a scalar type.
Definition traits.hpp:212
int get_ld(A const &a)
Get the leading dimension of an nda::MemoryArray with rank 1 or 2 for BLAS/LAPACK calls.
Definition tools.hpp:128
void resize_or_check_work_buffer(A &a, long min_size)
Resize or check the size of a 1D array/view.
Definition tools.hpp:207
vector< get_value_t< A >, heap< mem::get_addr_space< A > > > vector_value_t
Alias for an nda::vector with the same value type and address space as the given type.
Definition tools.hpp:161
vector< get_fp_t< A >, heap< mem::get_addr_space< A > > > vector_fp_t
Alias for an nda::vector with the same address space as the given type and its value type determined ...
Definition tools.hpp:170
static constexpr bool has_F_layout
Constexpr variable that is true if all given nda::Array types have nda::F_layout.
Definition tools.hpp:79
int ggev(A &&a, B &&b, AR &&alphar, AI &&alphai, B2 &&beta, VL &&vl, VR &&vr, char jobvl='N', char jobvr='V', W1 &&work=vector_value_t< A >{})
Interface to the LAPACK ggev routine for real matrices.
Definition ggev.hpp:92
static constexpr bool have_host_compatible_addr_space
Constexpr variable that is true if all given types have an address space compatible with Host.
Provides a C++ interface for various LAPACK routines.
Macros used in the nda library.
Provides type traits for the nda library.