TRIQS/nda 1.3.0
Multi-dimensional array library for C++
Loading...
Searching...
No Matches
geev.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 "../concepts.hpp"
17#include "../declarations.hpp"
18#include "../macros.hpp"
20#include "../traits.hpp"
21
22#include <cmath>
23#include <complex>
24#include <concepts>
25
26namespace nda::lapack {
27
68 template <MemoryMatrix A, MemoryVector WR, MemoryVector WI, MemoryMatrix VL, MemoryMatrix VR>
69 requires(mem::have_host_compatible_addr_space<A, WR, WI, VL, VR> and std::same_as<double, get_value_t<A>>
71 int geev(A &&a, WR &&wr, WI &&wi, VL &&vl, VR &&vr, char jobvl = 'N', char jobvr = 'V') { // NOLINT (temporary views are allowed here)
72 static_assert(has_F_layout<A>, "Error in nda::lapack::geev: A must have Fortran layout");
73 static_assert(has_F_layout<VL>, "Error in nda::lapack::geev: VL must have Fortran layout");
74 static_assert(has_F_layout<VR>, "Error in nda::lapack::geev: VR must have Fortran layout");
75
76 // check the dimensions of the input/output arrays/views
77 auto const [m, n] = a.shape();
78 EXPECTS(m == n);
81
82 // check parameters
83 EXPECTS(jobvl == 'V' or jobvl == 'N');
84 EXPECTS(jobvr == 'V' or jobvr == 'N');
85
86 // resize eigenvector matrices if needed
87 int ldvl = 1;
88 int ldvr = 1;
89 if (jobvl == 'V') {
90 resize_or_check_if_view(vl, {n, n});
91 ldvl = get_ld(vl);
92 }
93 if (jobvr == 'V') {
94 resize_or_check_if_view(vr, {n, n});
95 ldvr = get_ld(vr);
96 }
97
98 // arrays/views must be LAPACK compatible
99 EXPECTS(a.indexmap().min_stride() == 1);
100 EXPECTS(wr.indexmap().min_stride() == 1);
101 EXPECTS(wi.indexmap().min_stride() == 1);
102 EXPECTS(jobvl == 'N' or vl.indexmap().min_stride() == 1);
103 EXPECTS(jobvr == 'N' or vr.indexmap().min_stride() == 1);
104
105 // first call to get the optimal buffer size
106 double tmp_lwork{};
107 int info = 0;
108 lapack::f77::geev(jobvl, jobvr, n, a.data(), get_ld(a), wr.data(), wi.data(), vl.data(), ldvl, vr.data(), ldvr, &tmp_lwork, -1, info);
109 int lwork = static_cast<int>(std::ceil(tmp_lwork));
110
111 // allocate work buffer and perform actual library call
112 array<double, 1> work(lwork);
113 lapack::f77::geev(jobvl, jobvr, n, a.data(), get_ld(a), wr.data(), wi.data(), vl.data(), ldvl, vr.data(), ldvr, work.data(), lwork, info);
114
115 return info;
116 }
117
151 template <MemoryMatrix A, MemoryVector W, MemoryMatrix VL, MemoryMatrix VR>
152 requires(mem::have_host_compatible_addr_space<A, W, VL, VR> and std::same_as<std::complex<double>, get_value_t<A>>
154 int geev(A &&a, W &&w, VL &&vl, VR &&vr, char jobvl = 'N', char jobvr = 'V') { // NOLINT (temporary views are allowed here)
155 static_assert(has_F_layout<A>, "Error in nda::lapack::geev: A must have Fortran layout");
156 static_assert(has_F_layout<VL>, "Error in nda::lapack::geev: VL must have Fortran layout");
157 static_assert(has_F_layout<VR>, "Error in nda::lapack::geev: VR must have Fortran layout");
158
159 // check the dimensions of the input/output arrays/views
160 auto const [m, n] = a.shape();
161 EXPECTS(m == n);
163
164 // check parameters
165 EXPECTS(jobvl == 'V' or jobvl == 'N');
166 EXPECTS(jobvr == 'V' or jobvr == 'N');
167
168 // resize eigenvector matrices if needed
169 int ldvl = 1;
170 int ldvr = 1;
171 if (jobvl == 'V') {
172 resize_or_check_if_view(vl, {n, n});
173 ldvl = get_ld(vl);
174 }
175 if (jobvr == 'V') {
176 resize_or_check_if_view(vr, {n, n});
177 ldvr = get_ld(vr);
178 }
179
180 // arrays/views must be LAPACK compatible
181 EXPECTS(a.indexmap().min_stride() == 1);
182 EXPECTS(w.indexmap().min_stride() == 1);
183 EXPECTS(jobvl == 'N' or vl.indexmap().min_stride() == 1);
184 EXPECTS(jobvr == 'N' or vr.indexmap().min_stride() == 1);
185
186 // first call to get the optimal buffer size
187 array<double, 1> rwork(2 * n);
188 std::complex<double> tmp_lwork{};
189 int info = 0;
190 lapack::f77::geev(jobvl, jobvr, n, a.data(), get_ld(a), w.data(), vl.data(), ldvl, vr.data(), ldvr, &tmp_lwork, -1, rwork.data(), info);
191 int lwork = static_cast<int>(std::ceil(std::real(tmp_lwork)));
192
193 // allocate work buffer and perform actual library call
194 array<std::complex<double>, 1> work(lwork);
195 lapack::f77::geev(jobvl, jobvr, n, a.data(), get_ld(a), w.data(), vl.data(), ldvl, vr.data(), ldvr, work.data(), lwork, rwork.data(), info);
196
197 return info;
198 }
199
200} // 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.
ValueType const * data() const noexcept
Get a pointer to the actual data (in general this is not the beginning of the memory block for a view...
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.
basic_array< ValueType, Rank, Layout, 'A', ContainerPolicy > array
Alias template of an nda::basic_array with an 'A' algebra.
constexpr bool have_same_value_type_v
Constexpr variable that is true if all types in As have the same value type as A0.
Definition traits.hpp:186
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:182
int geev(A &&a, WR &&wr, WI &&wi, VL &&vl, VR &&vr, char jobvl='N', char jobvr='V')
Interface to the LAPACK geev routine for real matrices.
Definition geev.hpp:71
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.
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:122
static constexpr bool has_F_layout
Constexpr variable that is true if the given nda::Array type has nda::F_layout.
Definition tools.hpp:73
Macros used in the nda library.
Provides type traits for the nda library.