TRIQS/nda 1.3.0
Multi-dimensional array library for C++
Loading...
Searching...
No Matches
eigh.hpp
Go to the documentation of this file.
1// Copyright (c) 2019--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
13#include "../basic_array.hpp"
14#include "../blas/tools.hpp"
15#include "../concepts.hpp"
16#include "../declarations.hpp"
17#include "../exceptions.hpp"
18#include "../lapack/syev.hpp"
19#include "../lapack/sygv.hpp"
20#include "../lapack/heev.hpp"
21#include "../lapack/hegv.hpp"
23#include "../macros.hpp"
26#include "../traits.hpp"
27
28#include <complex>
29#include <type_traits>
30#include <utility>
31
32namespace nda::linalg {
33
38
39 namespace detail {
40
41 // Perform the call to the LAPACK routines syev/heev for eigh_in_place and eigvalsh_in_place.
42 template <typename A>
43 auto eigh_impl(A &&a, char jobz) { // NOLINT (temporary views are allowed here)
44 // early return if the matrix is empty
45 if (a.empty()) return array<double, 1>{};
46
47 // make the call to syev/heev
48 auto lambda = array<double, 1>(a.extent(0));
49 int info = 0;
50 if constexpr (is_complex_v<get_value_t<A>>) {
51 info = nda::lapack::heev(a, lambda, jobz);
52 } else {
53 info = nda::lapack::syev(a, lambda, jobz);
54 }
55 if (info != 0) NDA_RUNTIME_ERROR << "Error in nda::linalg::detail::eigh_impl: syev/heev routine failed: info = " << info;
56
57 return lambda;
58 }
59
60 // Perform the call to the LAPACK routines sygv/hegv for eigh_in_place and eigvalsh_in_place.
61 template <typename A, typename B>
62 auto eigh_impl(A &&a, B &&b, char jobz, int itype) { // NOLINT (temporary views are allowed here)
63 // early return if the matrix is empty
64 if (a.empty()) return array<double, 1>{};
65
66 // make the call to sygv/hegv
67 auto lambda = array<double, 1>(a.extent(0));
68 int info = 0;
69 if constexpr (is_complex_v<get_value_t<A>>) {
70 info = nda::lapack::hegv(a, b, lambda, jobz, itype);
71 } else {
72 info = nda::lapack::sygv(a, b, lambda, jobz, itype);
73 }
74 if (info != 0) NDA_RUNTIME_ERROR << "Error in nda::linalg::detail::eigh_impl: sygv/hegv routine failed: info = " << info;
75
76 return lambda;
77 }
78
79 } // namespace detail
80
102 template <MemoryMatrix A>
104 auto eigh_in_place(A &&a) {
105 return detail::eigh_impl(std::forward<A>(a), 'V');
106 }
107
137 template <MemoryMatrix A, MemoryMatrix B>
140 auto eigh_in_place(A &&a, B &&b, int itype = 1) {
141 return detail::eigh_impl(std::forward<A>(a), std::forward<B>(b), 'V', itype);
142 }
143
160 template <Matrix A>
161 requires(Scalar<get_value_t<A>>)
162 auto eigh(A const &a) {
163 using value_t = std::conditional_t<is_complex_v<get_value_t<A>>, std::complex<double>, double>;
164 auto a_copy = matrix<value_t, F_layout>{a};
165 auto lambda = eigh_in_place(a_copy);
166 return std::make_pair(lambda, a_copy);
167 }
168
189 template <Matrix A, Matrix B>
191 auto eigh(A const &a, B const &b, int itype = 1) {
192 using value_t = std::conditional_t<is_complex_v<get_value_t<A>> or is_complex_v<get_value_t<B>>, std::complex<double>, double>;
193 auto a_copy = matrix<value_t, F_layout>{a};
194 auto b_copy = matrix<value_t, F_layout>{b};
195 auto lambda = eigh_in_place(a_copy, b_copy, itype);
196 return std::make_pair(lambda, a_copy);
197 }
198
219 template <MemoryMatrix A>
221 auto eigvalsh_in_place(A &&a) {
222 return detail::eigh_impl(std::forward<A>(a), 'N');
223 }
224
253 template <MemoryMatrix A, MemoryMatrix B>
256 auto eigvalsh_in_place(A &&a, B &&b, int itype = 1) {
257 return detail::eigh_impl(std::forward<A>(a), std::forward<B>(b), 'N', itype);
258 }
259
274 template <Matrix A>
275 requires(Scalar<get_value_t<A>>)
276 auto eigvalsh(A const &a) {
277 using value_t = std::conditional_t<is_complex_v<get_value_t<A>>, std::complex<double>, double>;
278 auto a_copy = matrix<value_t, F_layout>{a};
279 return eigvalsh_in_place(a_copy);
280 }
281
301 template <Matrix A, Matrix B>
303 auto eigvalsh(A const &a, B const &b, int itype = 1) {
304 using value_t = std::conditional_t<is_complex_v<get_value_t<A>> or is_complex_v<get_value_t<B>>, std::complex<double>, double>;
305 auto a_copy = matrix<value_t, F_layout>{a};
306 auto b_copy = matrix<value_t, F_layout>{b};
307 return eigvalsh_in_place(a_copy, b_copy, itype);
308 }
309
311
312} // namespace nda::linalg
Provides definitions and type traits involving the different memory address spaces supported by nda.
Provides the generic class for arrays.
Check if a given type is either an arithmetic or complex type.
Definition concepts.hpp:83
Provides concepts for the nda library.
Provides various convenient aliases and helper functions for nda::basic_array and nda::basic_array_vi...
Provides a custom runtime error class and macros to assert conditions and throw exceptions.
basic_array< ValueType, Rank, Layout, 'A', ContainerPolicy > array
Alias template of an nda::basic_array with an 'A' algebra.
basic_array< ValueType, 2, Layout, 'M', ContainerPolicy > matrix
Alias template of an nda::basic_array with rank 2 and an 'M' 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
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
int sygv(A &&a, B &&b, W &&w, char jobz='V', int itype=1)
Interface to the LAPACK sygv routine.
Definition sygv.hpp:56
int heev(A &&a, W &&w, char jobz='V')
Interface to the LAPACK heev routine.
Definition heev.hpp:50
int hegv(A &&a, B &&b, W &&w, char jobz='V', int itype=1)
Interface to the LAPACK hegv routine.
Definition hegv.hpp:59
int syev(A &&a, W &&w, char jobz='V')
Interface to the LAPACK syev routine.
Definition syev.hpp:48
auto eigh_in_place(A &&a)
Compute the eigenvalues and eigenvectors of a real symmetric or complex hermitian matrix.
Definition eigh.hpp:104
auto eigvalsh_in_place(A &&a)
Compute the eigenvalues of a real symmetric or complex hermitian matrix.
Definition eigh.hpp:221
auto eigh(A const &a)
Compute the eigenvalues and eigenvectors of a real symmetric or complex hermitian matrix.
Definition eigh.hpp:162
auto eigvalsh(A const &a)
Compute the eigenvalues of a real symmetric or complex hermitian matrix.
Definition eigh.hpp:276
static constexpr bool have_host_compatible_addr_space
Constexpr variable that is true if all given types have an address space compatible with Host.
constexpr bool is_complex_v
Constexpr variable that is true if type T is a std::complex type.
Definition traits.hpp:65
constexpr bool is_blas_lapack_v
Alias for nda::is_double_or_complex_v.
Definition traits.hpp:92
Provides a generic interface to the LAPACK heev routine.
Provides a generic interface to the LAPACK hegv routine.
Provides definitions of various layout policies.
Macros used in the nda library.
Provides functions to create and manipulate matrices, i.e. arrays/view with 'M' algebra.
Provides a generic interface to the LAPACK syev routine.
Provides a generic interface to the LAPACK sygv routine.
Provides various traits and utilities for the BLAS interface.
Provides type traits for the nda library.