Tatooine
geev.h
Go to the documentation of this file.
1#ifndef TATOOINE_LAPACK_GEEV_H
2#define TATOOINE_LAPACK_GEEV_H
3//==============================================================================
4extern "C" {
5auto dgeev_(char* JOBVL, char* JOBVR, int* N, double* A, int* LDA, double* WR,
6 double* WI, double* VL, int* LDVL, double* VR, int* LDVR,
7 double* WORK, int* LWORK, int* INFO) -> void;
8
9auto sgeev_(char* JOBVL, char* JOBVR, int* N, float* A, int* LDA, float* WR,
10 float* WI, float* VL, int* LDVL, float* VR, int* LDVR, float* WORK,
11 int* LWORK, int* INFO) -> void;
12}
13//==============================================================================
15
16#include <concepts>
17#include <complex>
18#include <memory>
19//==============================================================================
20namespace tatooine::lapack {
21//==============================================================================
42//==============================================================================
43template <std::floating_point Float>
44auto geev(job JOBVL, job JOBVR, int N, Float* A, int LDA, Float* WR,
45 Float* WI, Float* VL, int LDVL, Float* VR, int LDVR, Float* WORK,
46 int LWORK) -> int {
47 auto INFO = int{};
48 if constexpr (std::same_as<Float, double>) {
49 dgeev_(reinterpret_cast<char*>(&JOBVL), reinterpret_cast<char*>(&JOBVR), &N,
50 A, &LDA, WR, WI, VL, &LDVL, VR, &LDVR, WORK, &LWORK, &INFO);
51 } else if constexpr (std::same_as<Float, float>) {
52 sgeev_(reinterpret_cast<char*>(&JOBVL), reinterpret_cast<char*>(&JOBVR), &N,
53 A, &LDA, WR, WI, VL, &LDVL, VR, &LDVR, WORK, &LWORK, &INFO);
54 }
55 return INFO;
56}
57//------------------------------------------------------------------------------
58template <std::floating_point Float>
59auto geev(job const JOBVL, job const JOBVR, int N, Float* A, int LDA, Float* WR,
60 Float* WI, Float* VL, int LDVL, Float* VR, int LDVR) -> int {
61 auto LWORK = int{-1};
62 auto WORK = std::unique_ptr<Float[]>{new Float[1]};
63 geev<Float>(JOBVL, JOBVR, N, A, LDA, WR, WI, VL, LDVL, VR, LDVR, WORK.get(),
64 LWORK);
65 LWORK = static_cast<int>(WORK[0]);
66 WORK = std::unique_ptr<Float[]>{new Float[LWORK]};
67 return geev<Float>(JOBVL, JOBVR, N, A, LDA, WR, WI, VL, LDVL, VR, LDVR,
68 WORK.get(), LWORK);
69}
70//------------------------------------------------------------------------------
71template <std::floating_point Float>
72auto geev(job JOBVL, job JOBVR, int N, Float* A, int LDA,
73 std::complex<Float>* W, Float* VL, int LDVL, Float* VR, int LDVR,
74 Float* WORK, int LWORK) -> int {
75 auto INFO = int{};
76 auto WRI = std::unique_ptr<Float[]>{new Float[N*2]};
77 if constexpr (std::same_as<Float, double>) {
78 dgeev_(reinterpret_cast<char*>(&JOBVL), reinterpret_cast<char*>(&JOBVR), &N,
79 A, &LDA, WRI.get(), WRI.get() + N, VL, &LDVL, VR, &LDVR, WORK,
80 &LWORK, &INFO);
81 } else if constexpr (std::same_as<Float, float>) {
82 sgeev_(reinterpret_cast<char*>(&JOBVL), reinterpret_cast<char*>(&JOBVR), &N,
83 A, &LDA, WRI.get(), WRI.get() + N, VL, &LDVL, VR, &LDVR, WORK,
84 &LWORK, &INFO);
85 }
86 for (int i = 0; i < N; ++i) {
87 W[i].real(WRI[i]);
88 W[i].imag(WRI[i+N]);
89 }
90 return INFO;
91}
92//------------------------------------------------------------------------------
93template <std::floating_point Float>
94auto geev(job const JOBVL, job const JOBVR, int N, Float* A, int LDA,
95 std::complex<Float>* W, Float* VL, int LDVL, Float* VR, int LDVR)
96 -> int {
97 auto LWORK = int{-1};
98 auto WORK = std::unique_ptr<Float[]>{new Float[1]};
99 geev<Float>(JOBVL, JOBVR, N, A, LDA, W, VL, LDVL, VR, LDVR, WORK.get(),
100 LWORK);
101 LWORK = static_cast<int>(WORK[0]);
102 WORK = std::unique_ptr<Float[]>{new Float[LWORK]};
103 return geev<Float>(JOBVL, JOBVR, N, A, LDA, W, VL, LDVL, VR, LDVR, WORK.get(),
104 LWORK);
105}
106//------------------------------------------------------------------------------
107template <std::floating_point Float, size_t N>
108auto geev(tensor<Float, N, N>& A, tensor<std::complex<Float>, N>& W) {
109 return geev<Float>(job::no_vec, job::no_vec, N, A.data(), N, W.data(), nullptr, N,
110 nullptr, N);
111}
112//------------------------------------------------------------------------------
113template <std::floating_point Float, size_t N>
114auto geev_left(tensor<Float, N, N>& A, tensor<std::complex<Float>, N>& W,
116 return geev<Float>(job::vec, job::no_vec, N, A.data(), N, W.data(), VL.data(), N,
117 nullptr, N);
118}
119//------------------------------------------------------------------------------
120template <std::floating_point Float, size_t N>
121auto geev_right(tensor<Float, N, N>& A, tensor<std::complex<Float>, N>& W,
123 return geev<Float>(job::no_vec, job::vec, N, A.data(), N, W.data(), nullptr, N,
124 VR.data(), N);
125}
126//------------------------------------------------------------------------------
127template <std::floating_point Float, size_t N>
128auto geev(tensor<Float, N, N>& A, tensor<std::complex<Float>, N>& W,
130 return geev<Float>(job::vec, job::vec, N, A.data(), N, W.data(), VL.data(), N,
131 VR.data(), N);
132}
133//==============================================================================
135//==============================================================================
136} // namespace tatooine::lapack
137//==============================================================================
138#endif
constexpr auto data() -> ValueType *
Definition: static_multidim_array.h:260
auto sgeev_(char *JOBVL, char *JOBVR, int *N, float *A, int *LDA, float *WR, float *WI, float *VL, int *LDVL, float *VR, int *LDVR, float *WORK, int *LWORK, int *INFO) -> void
auto dgeev_(char *JOBVL, char *JOBVR, int *N, double *A, int *LDA, double *WR, double *WI, double *VL, int *LDVL, double *VR, int *LDVR, double *WORK, int *LWORK, int *INFO) -> void
auto geev(job JOBVL, job JOBVR, int N, Float *A, int LDA, Float *WR, Float *WI, Float *VL, int LDVL, Float *VR, int LDVR, Float *WORK, int LWORK) -> int
Definition: geev.h:44
auto geev_left(tensor< Float, N, N > &A, tensor< std::complex< Float >, N > &W, tensor< Float, N, N > &VL)
Definition: geev.h:114
auto geev_right(tensor< Float, N, N > &A, tensor< std::complex< Float >, N > &W, tensor< Float, N, N > &VR)
Definition: geev.h:121
Definition: base.h:6
job
Definition: base.h:55
Definition: tensor.h:17