Eigen  5.0.1
 
Loading...
Searching...
No Matches
ConjHelper.h
1// SPDX-License-Identifier: MPL-2.0
2
3// This file is part of Eigen, a lightweight C++ template library
4// for linear algebra.
5//
6// Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
7//
8// This Source Code Form is subject to the terms of the Mozilla
9// Public License v. 2.0. If a copy of the MPL was not distributed
10// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
11
12#ifndef EIGEN_ARCH_CONJ_HELPER_H
13#define EIGEN_ARCH_CONJ_HELPER_H
14
15#define EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(PACKET_CPLX, PACKET_REAL) \
16 template <> \
17 struct conj_helper<PACKET_REAL, PACKET_CPLX, false, false> { \
18 EIGEN_STRONG_INLINE PACKET_CPLX pmadd(const PACKET_REAL& x, const PACKET_CPLX& y, const PACKET_CPLX& c) const { \
19 return padd(c, this->pmul(x, y)); \
20 } \
21 EIGEN_STRONG_INLINE PACKET_CPLX pmsub(const PACKET_REAL& x, const PACKET_CPLX& y, const PACKET_CPLX& c) const { \
22 return psub(this->pmul(x, y), c); \
23 } \
24 EIGEN_STRONG_INLINE PACKET_CPLX pmul(const PACKET_REAL& x, const PACKET_CPLX& y) const { \
25 return PACKET_CPLX(Eigen::internal::pmul<PACKET_REAL>(x, y.v)); \
26 } \
27 }; \
28 \
29 template <> \
30 struct conj_helper<PACKET_CPLX, PACKET_REAL, false, false> { \
31 EIGEN_STRONG_INLINE PACKET_CPLX pmadd(const PACKET_CPLX& x, const PACKET_REAL& y, const PACKET_CPLX& c) const { \
32 return padd(c, this->pmul(x, y)); \
33 } \
34 EIGEN_STRONG_INLINE PACKET_CPLX pmsub(const PACKET_CPLX& x, const PACKET_REAL& y, const PACKET_CPLX& c) const { \
35 return psub(this->pmul(x, y), c); \
36 } \
37 EIGEN_STRONG_INLINE PACKET_CPLX pmul(const PACKET_CPLX& x, const PACKET_REAL& y) const { \
38 return PACKET_CPLX(Eigen::internal::pmul<PACKET_REAL>(x.v, y)); \
39 } \
40 };
41
42// IWYU pragma: private
43#include "../../InternalHeaderCheck.h"
44
45namespace Eigen {
46namespace internal {
47
48template <bool Conjugate>
49struct conj_if;
50
51template <>
52struct conj_if<true> {
53 template <typename T>
54 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T operator()(const T& x) const {
55 return numext::conj(x);
56 }
57 template <typename T>
58 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T pconj(const T& x) const {
59 return internal::pconj(x);
60 }
61};
62
63template <>
64struct conj_if<false> {
65 template <typename T>
66 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& operator()(const T& x) const {
67 return x;
68 }
69 template <typename T>
70 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& pconj(const T& x) const {
71 return x;
72 }
73};
74
75// Generic Implementation, assume scalars since the packet-version is
76// specialized below.
77template <typename LhsType, typename RhsType, bool ConjLhs, bool ConjRhs>
78struct conj_helper {
79 using ResultType = typename ScalarBinaryOpTraits<LhsType, RhsType>::ReturnType;
80
81 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType pmadd(const LhsType& x, const RhsType& y,
82 const ResultType& c) const {
83 return this->pmul(x, y) + c;
84 }
85
86 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType pmsub(const LhsType& x, const RhsType& y,
87 const ResultType& c) const {
88 return this->pmul(x, y) - c;
89 }
90
91 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType pmul(const LhsType& x, const RhsType& y) const {
92 return conj_if<ConjLhs>()(x) * conj_if<ConjRhs>()(y);
93 }
94};
95
96template <typename LhsScalar, typename RhsScalar>
97struct conj_helper<LhsScalar, RhsScalar, true, true> {
98 using ResultType = typename ScalarBinaryOpTraits<LhsScalar, RhsScalar>::ReturnType;
99
100 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType pmadd(const LhsScalar& x, const RhsScalar& y,
101 const ResultType& c) const {
102 return this->pmul(x, y) + c;
103 }
104
105 // We save a conjugation by using the identity conj(a)*conj(b) = conj(a*b).
106 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ResultType pmul(const LhsScalar& x, const RhsScalar& y) const {
107 return numext::conj(x * y);
108 }
109};
110
111// Implementation with equal type, use packet operations.
112template <typename Packet, bool ConjLhs, bool ConjRhs>
113struct conj_helper<Packet, Packet, ConjLhs, ConjRhs> {
114 using ResultType = Packet;
115 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pmadd(const Packet& x, const Packet& y, const Packet& c) const {
116 return Eigen::internal::pmadd(conj_if<ConjLhs>().pconj(x), conj_if<ConjRhs>().pconj(y), c);
117 }
118
119 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pmsub(const Packet& x, const Packet& y, const Packet& c) const {
120 return Eigen::internal::pmsub(conj_if<ConjLhs>().pconj(x), conj_if<ConjRhs>().pconj(y), c);
121 }
122
123 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pmul(const Packet& x, const Packet& y) const {
124 return Eigen::internal::pmul(conj_if<ConjLhs>().pconj(x), conj_if<ConjRhs>().pconj(y));
125 }
126};
127
128template <typename Packet>
129struct conj_helper<Packet, Packet, true, true> {
130 using ResultType = Packet;
131
132 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pmadd(const Packet& x, const Packet& y, const Packet& c) const {
133 return Eigen::internal::pmadd(pconj(x), pconj(y), c);
134 }
135 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pmsub(const Packet& x, const Packet& y, const Packet& c) const {
136 return Eigen::internal::pmsub(pconj(x), pconj(y), c);
137 }
138 // We save a conjugation by using the identity conj(a)*conj(b) = conj(a*b).
139 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pmul(const Packet& x, const Packet& y) const {
140 return pconj(Eigen::internal::pmul(x, y));
141 }
142};
143
144} // namespace internal
145} // namespace Eigen
146
147#endif // EIGEN_ARCH_CONJ_HELPER_H