CoDiPack  3.0.0
A Code Differentiation Package
SciComp TU Kaiserslautern
Loading...
Searching...
No Matches
allOperators.hpp
1/*
2 * CoDiPack, a Code Differentiation Package
3 *
4 * Copyright (C) 2015-2025 Chair for Scientific Computing (SciComp), University of Kaiserslautern-Landau
5 * Homepage: http://scicomp.rptu.de
6 * Contact: Prof. Nicolas R. Gauger (codi@scicomp.uni-kl.de)
7 *
8 * Lead developers: Max Sagebaum, Johannes Blühdorn (SciComp, University of Kaiserslautern-Landau)
9 *
10 * This file is part of CoDiPack (http://scicomp.rptu.de/software/codi).
11 *
12 * CoDiPack is free software: you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, either version 3 of the
15 * License, or (at your option) any later version.
16 *
17 * CoDiPack is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty
19 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * See the GNU General Public License for more details.
22 * You should have received a copy of the GNU
23 * General Public License along with CoDiPack.
24 * If not, see <http://www.gnu.org/licenses/>.
25 *
26 * For other licensing options please contact us.
27 *
28 * Authors:
29 * - SciComp, University of Kaiserslautern-Landau:
30 * - Max Sagebaum
31 * - Johannes Blühdorn
32 * - Former members:
33 * - Tim Albring
34 */
35#pragma once
36
37#include <complex>
38
39#include "../../config.h"
40#include "../../misc/macros.hpp"
41#include "../computeExpression.hpp"
42#include "../expressionInterface.hpp"
43#include "../real/allOperators.hpp"
44#include "complexPredef.hpp"
45#include "realToComplexCast.hpp"
46
48namespace codi {
49
50 template<typename T_Tape, typename T_ParallelToolbox>
51 struct ParallelActiveType;
52
53 using std::abs;
54 using std::arg;
55 using std::conj;
56 using std::imag;
57 using std::norm;
58 using std::polar;
59 using std::proj;
60 using std::real;
61
62 /*******************************************************************************/
65
66// Use the Logic from the real definition
67#define OPERATION_LOGIC OperationAdd
68#define FUNCTION operator+
69#include "binaryMixedComplexAndRealOverloads.tpp"
70
71#define OPERATION_LOGIC OperationSubstract
72#define FUNCTION operator-
73#include "binaryMixedComplexAndRealOverloads.tpp"
74
75#define OPERATION_LOGIC OperationMultiply
76#define FUNCTION operator*
77#include "binaryMixedComplexAndRealOverloads.tpp"
79#define OPERATION_LOGIC OperationDivide
80#define FUNCTION operator/
81#include "binaryMixedComplexAndRealOverloads.tpp"
82
84 /*******************************************************************************/
85 /// @name Standard math library binary operators
86 /// @{
87
89 template<typename T_ComplexReal>
90 struct OperationComplexPolar : public BinaryOperation<T_ComplexReal, OperationComplexPolar<T_ComplexReal>> {
91 public:
93 using ComplexReal = CODI_DD(T_ComplexReal, std::complex<double>);
94
95 using Real = typename ComplexReal::value_type;
96
97
98 template<typename ArgA, typename ArgB>
99 static CODI_INLINE ComplexReal primal(ArgA const& argA, ArgB const& argB) {
100 return polar(argA, argB);
101 }
102
104 template<typename Tangent, typename ArgA, typename ArgB>
105 static CODI_INLINE auto applyTangentArgA(Tangent const& tangent, ComplexReal const& result, ArgA const& argA,
106 ArgB const& argB);
107 // TODO: Implement
108
109 /// \copydoc codi::BinaryOperation::applyAdjointArgA
110 template<typename Adjoint, typename ArgA, typename ArgB>
111 static CODI_INLINE Real applyAdjointArgA(Adjoint const& adjoint, ComplexReal const& result, ArgA const& argA,
112 ArgB const& argB) {
113 CODI_UNUSED(result, argA);
114 return cos(argB) * std::real(adjoint) + sin(argB) * std::imag(adjoint);
115 }
116
118 template<typename Tangent, typename ArgA, typename ArgB>
119 static CODI_INLINE auto applyTangentArgB(Tangent const& tangent, ComplexReal const& result, ArgA const& argA,
120 ArgB const& argB);
121 // TODO: Implement
122
124 template<typename Adjoint, typename ArgA, typename ArgB>
125 static CODI_INLINE Real applyAdjointArgB(Adjoint const& adjoint, ComplexReal const& result, ArgA const& argA,
126 ArgB const& argB) {
127 CODI_UNUSED(argA, argB);
128
129 return -std::imag(result) * std::real(adjoint) + std::real(result) * std::imag(adjoint);
130 }
131
133 static CODI_INLINE std::string getMathRep() {
134 return "polar()";
135 }
136 };
137
138#define FUNCTION polar
139#define OPERATION_LOGIC OperationComplexPolar
140#include "binaryRealToComplexOverloads.tpp"
141
143 template<typename T_Real>
144 struct OperationPow<std::complex<T_Real>>
145 : public BinaryJacobianOperation<std::complex<T_Real>, OperationPow<std::complex<T_Real>>> {
146 public:
147
148 using ComplexReal = CODI_DD(std::complex<T_Real>, std::complex<double>);
149
151 template<typename ArgA, typename ArgB>
152 static CODI_INLINE ComplexReal primal(ArgA const& argA, ArgB const& argB) {
153 return pow(argA, argB);
154 }
155
157 template<typename ArgA, typename ArgB>
158 static CODI_INLINE ComplexReal gradientA(ArgA const& argA, ArgB const& argB, ComplexReal const& result) {
159 CODI_UNUSED(result);
160
161 return argB * pow(argA, argB - 1.0);
162 }
163
165 template<typename ArgA, typename ArgB>
166 static CODI_INLINE ComplexReal gradientB(ArgA const& argA, ArgB const& argB, ComplexReal const& result) {
167 CODI_UNUSED(argB);
168
169 // Complex cast for argA, since the real log for negative numbers is not defined.
170 return log(ComplexReal(argA)) * result;
171 }
172
174 static CODI_INLINE std::string getMathRep() {
175 return "pow()";
176 }
177 };
178
179#define OPERATION_LOGIC OperationPow
180#define FUNCTION pow
181#include "binaryMixedComplexAndRealOverloads.tpp"
182
184 /*******************************************************************************/
187
188#define OPERATOR ==
189#include "conditionalBinaryMixedComplexAndRealOverloads.tpp"
190
191#define OPERATOR !=
192#include "conditionalBinaryMixedComplexAndRealOverloads.tpp"
193
195 /*******************************************************************************/
198
199 // Functions handled by the real definitions:
200 // exp, log, log10, sqrt, sin, cos, tan, asin, acos, atan, sinh, cosh, tanh, asinh, acosh, atanh,
201 // Unary operators handled by the real definitions:
202 // operator+, operator-
203
205 template<typename T_Real>
206 struct OperationComplexAbs : public UnaryJacobianOperation<T_Real, OperationComplexAbs<T_Real>> {
207 public:
208
209 using Real = CODI_DD(T_Real, double);
210 using Jacobian = std::complex<Real>;
211
213 template<typename Arg>
214 static CODI_INLINE Real primal(Arg const& arg) {
215 return abs(arg);
216 }
217
219 template<typename Arg>
220 static CODI_INLINE Jacobian gradient(Arg const& arg, Real const& result) {
221 checkResult(result);
222 if (result != 0.0) {
223 return Jacobian(real(arg) / result, -imag(arg) / result);
224 } else {
225 return Jacobian(0.0);
226 }
227 }
228
230 static CODI_INLINE std::string getMathRep() {
231 return "abs";
232 }
233
234 private:
235 static CODI_INLINE void checkResult(Real const& result) {
237 if (RealTraits::getPassiveValue(result) == 0.0) {
238 CODI_EXCEPTION("Zero divisor for abs derivative.");
239 }
240 }
241 }
242 };
243
244#define FUNCTION abs
245#define OPERATION_LOGIC OperationComplexAbs
246#include "unaryComplexToRealOverloads.tpp"
247
249 template<typename T_Real>
250 struct OperationComplexArg : public UnaryJacobianOperation<T_Real, OperationComplexArg<T_Real>> {
251 public:
252
253 using Real = CODI_DD(T_Real, double);
254 using Jacobian = std::complex<Real>;
255
257 template<typename Argument>
258 static CODI_INLINE Real primal(Argument const& argument) {
259 return arg(argument);
260 }
261
263 template<typename Argument>
264 static CODI_INLINE Jacobian gradient(Argument const& argument, Real const& result) {
265 CODI_UNUSED(result);
266
267 Real divisor = real(argument) * real(argument) + imag(argument) * imag(argument);
268 checkDivisor(divisor);
269 divisor = 1.0 / divisor;
270
271 return Jacobian(-imag(argument) * divisor, -real(argument) * divisor);
272 }
273
275 static CODI_INLINE std::string getMathRep() {
276 return "arg";
277 }
278
279 private:
280 static CODI_INLINE void checkDivisor(Real const& devisor) {
282 if (RealTraits::getPassiveValue(devisor) == 0.0) {
283 CODI_EXCEPTION("Zero divisor for arg derivative.");
284 }
285 }
286 }
287 };
288
289#define FUNCTION arg
290#define OPERATION_LOGIC OperationComplexArg
291#include "unaryComplexToRealOverloads.tpp"
292
294 template<typename T_ComplexReal>
295 struct OperationComplexConj : public UnaryOperation<T_ComplexReal, OperationComplexConj<T_ComplexReal>> {
296 public:
297
298 using ComplexReal = CODI_DD(T_ComplexReal, std::complex<double>);
299
301 template<typename Arg>
302 static CODI_INLINE ComplexReal primal(Arg const& arg) {
303 return conj(arg);
304 }
305
307 template<typename Tangent, typename Arg>
308 static CODI_INLINE auto applyTangentArg(Tangent const& tangent, ComplexReal const& result, Arg const& arg) {
309 CODI_UNUSED(arg, result);
310
311 return conj(tangent);
312 }
313
315 template<typename Adjoint, typename Arg>
316 static CODI_INLINE auto applyAdjointArg(Adjoint const& adjoint, ComplexReal const& result, Arg const& arg) {
317 CODI_UNUSED(arg, result);
318
319 return conj(adjoint);
320 }
321
323 static CODI_INLINE std::string getMathRep() {
324 return "conj";
325 }
326 };
327
328#define FUNCTION conj
329#define OPERATION_LOGIC OperationComplexConj
330#include "../real/unaryOverloads.tpp"
331
333 template<typename T_Real>
334 struct OperationComplexImag : public UnaryJacobianOperation<T_Real, OperationComplexImag<T_Real>> {
335 public:
336
337 using Real = CODI_DD(T_Real, double);
338 using Jacobian = std::complex<Real>;
339
341 template<typename Arg>
342 static CODI_INLINE Real primal(Arg const& arg) {
343 return arg.imag();
344 }
345
347 template<typename Arg>
348 static CODI_INLINE Jacobian gradient(Arg const& arg, Real const& result) {
349 CODI_UNUSED(arg, result);
350
351 return Jacobian(0.0, -1.0);
352 }
353
355 static CODI_INLINE std::string getMathRep() {
356 return "imag";
357 }
358 };
359
360#define FUNCTION imag
361#define OPERATION_LOGIC OperationComplexImag
362#include "unaryComplexToRealOverloads.tpp"
363
365 template<typename T_Real>
366 struct OperationComplexNorm : public UnaryJacobianOperation<T_Real, OperationComplexNorm<T_Real>> {
367 public:
368
369 using Real = CODI_DD(T_Real, double);
370 using Jacobian = std::complex<Real>;
371
373 template<typename Arg>
374 static CODI_INLINE Real primal(Arg const& arg) {
375 return norm(arg);
376 }
377
379 template<typename Arg>
380 static CODI_INLINE Jacobian gradient(Arg const& arg, Real const& result) {
381 CODI_UNUSED(result);
382
383 return Jacobian(2.0 * real(arg), -2.0 * imag(arg));
384 }
385
387 static CODI_INLINE std::string getMathRep() {
388 return "norm";
389 }
390 };
391
392#define FUNCTION norm
393#define OPERATION_LOGIC OperationComplexNorm
394#include "unaryComplexToRealOverloads.tpp"
395
397 template<typename T_ComplexReal>
398 struct OperationComplexProj : public UnaryJacobianOperation<T_ComplexReal, OperationComplexProj<T_ComplexReal>> {
399 public:
400
401 using ComplexReal = CODI_DD(T_ComplexReal, std::complex<double>);
402 using Jacobian = double;
403
405 template<typename Arg>
406 static CODI_INLINE ComplexReal primal(Arg const& argument) {
407 return proj(argument);
408 }
409
411 template<typename Arg>
412 static CODI_INLINE Jacobian gradient(Arg const& argument, ComplexReal const& result) {
413 CODI_UNUSED(argument, result);
414
415 return 1.0;
416 }
417
419 static CODI_INLINE std::string getMathRep() {
420 return "proj";
421 }
422 };
423
424#define FUNCTION proj
425#define OPERATION_LOGIC OperationComplexProj
426#include "../real/unaryOverloads.tpp"
427
429 template<typename T_Real>
430 struct OperationComplexReal : public UnaryJacobianOperation<T_Real, OperationComplexReal<T_Real>> {
431 public:
432
433 using Real = CODI_DD(T_Real, double);
434 using Jacobian = std::complex<Real>;
435
437 template<typename Arg>
438 static CODI_INLINE Real primal(Arg const& arg) {
439 return arg.real();
440 }
441
443 template<typename Arg>
444 static CODI_INLINE Jacobian gradient(Arg const& arg, Real const& result) {
445 CODI_UNUSED(arg, result);
446
447 return Jacobian(1.0, 0.0);
448 }
449
451 static CODI_INLINE std::string getMathRep() {
452 return "real";
453 }
454 };
455
456#define FUNCTION real
457#define OPERATION_LOGIC OperationComplexReal
458#include "unaryComplexToRealOverloads.tpp"
459
461}
462
463namespace std {
465 template<typename Real>
466 bool isfinite(std::complex<Real> arg) {
467 return isfinite(arg.real()) && isfinite(arg.imag());
468 }
469
470 using codi::abs;
471 using codi::imag;
472 using codi::real;
473
474}
#define CODI_INLINE
See codi::Config::ForcedInlines.
Definition config.h:469
#define CODI_DD(Type, Default)
Abbreviation for CODI_DECLARE_DEFAULT.
Definition macros.hpp:96
bool constexpr CheckExpressionArguments
Check for invalid arguments to expressions like division by zero.
Definition config.h:146
inlinePassiveReal< Type > getPassiveValue(Type const &v)
Get the basic primal value of the type.
Definition realTraits.hpp:133
CoDiPack - Code Differentiation Package.
Definition codi.hpp:94
inlineauto log(ExpressionInterface< Real, Arg > const &arg)
Function overload for FUNCTION.
Definition unaryOperators.hpp:71
inlineauto conj(ExpressionInterface< Real, Arg > const &arg)
Function overload for FUNCTION.
Definition allOperators.hpp:71
inlineauto cos(ExpressionInterface< Real, Arg > const &arg)
Function overload for FUNCTION.
Definition unaryOperators.hpp:71
inlineauto imag(ExpressionInterface< std::complex< Real >, Arg > const &arg)
Function overload for FUNCTION.
Definition allOperators.hpp:75
inlineauto abs(ExpressionInterface< std::complex< Real >, Arg > const &arg)
Function overload for FUNCTION.
Definition allOperators.hpp:75
inlineauto real(ExpressionInterface< std::complex< Real >, Arg > const &arg)
Function overload for FUNCTION.
Definition allOperators.hpp:75
inlinevoid CODI_UNUSED(Args const &...)
Disable unused warnings for an arbitrary number of arguments.
Definition macros.hpp:54
inlineauto arg(ExpressionInterface< std::complex< Real >, Arg > const &arg)
Function overload for FUNCTION.
Definition allOperators.hpp:75
inlineauto sin(ExpressionInterface< Real, Arg > const &arg)
Function overload for FUNCTION.
Definition unaryOperators.hpp:71
inlineauto norm(ExpressionInterface< std::complex< Real >, Arg > const &arg)
Function overload for FUNCTION.
Definition allOperators.hpp:75
inlineauto pow(ExpressionInterface< std::complex< Real >, ArgA > const &argA, ExpressionInterface< Real, ArgB > const &argB)
Function overload for FUNCTION(complex, real).
Definition allOperators.hpp:92
inlineauto proj(ExpressionInterface< Real, Arg > const &arg)
Function overload for FUNCTION.
Definition allOperators.hpp:71
inlineauto polar(ExpressionInterface< Real, ArgA > const &argA, ExpressionInterface< Real, ArgB > const &argB)
Function overload for FUNCTION(real, real).
Definition allOperators.hpp:86
inlinebool isfinite(ExpressionInterface< Real, Arg > const &arg)
Function overload for isfinite.
Definition unaryOperators.hpp:787
Implements BinaryOperation for functions where the gradients can be computed and transposed.
Definition computeExpression.hpp:302
Implements ComputeOperation for two arguments.
Definition computeExpression.hpp:197
UnaryJacobianOperation implementation for complex abs.
Definition allOperators.hpp:206
static inlinestd::string getMathRep()
Get the math symbol of the operation. E.g. + for operators and pow() for functions.
Definition allOperators.hpp:230
T_Real Real
See UnaryJacobianOperation.
Definition allOperators.hpp:209
static inlineReal primal(Arg const &arg)
Definition allOperators.hpp:214
static inlineJacobian gradient(Arg const &arg, Real const &result)
Compute .
Definition allOperators.hpp:220
std::complex< Real > Jacobian
See UnaryJacobianOperation.
Definition allOperators.hpp:210
UnaryJacobianOperation implementation for complex arg.
Definition allOperators.hpp:250
static inlineJacobian gradient(Argument const &argument, Real const &result)
Compute .
Definition allOperators.hpp:264
std::complex< Real > Jacobian
See UnaryJacobianOperation.
Definition allOperators.hpp:254
static inlineReal primal(Argument const &argument)
Definition allOperators.hpp:258
static inlinestd::string getMathRep()
Get the math symbol of the operation. E.g. + for operators and pow() for functions.
Definition allOperators.hpp:275
T_Real Real
See UnaryJacobianOperation.
Definition allOperators.hpp:253
UnaryJacobianOperation implementation for complex conj.
Definition allOperators.hpp:295
static inlineauto applyTangentArg(Tangent const &tangent, ComplexReal const &result, Arg const &arg)
Definition allOperators.hpp:308
static inlineComplexReal primal(Arg const &arg)
Definition allOperators.hpp:302
static inlineauto applyAdjointArg(Adjoint const &adjoint, ComplexReal const &result, Arg const &arg)
Definition allOperators.hpp:316
static inlinestd::string getMathRep()
Get the math symbol of the operation. E.g. + for operators and pow() for functions.
Definition allOperators.hpp:323
T_ComplexReal ComplexReal
See UnaryJacobianOperation.
Definition allOperators.hpp:298
UnaryJacobianOperation implementation for complex imag.
Definition allOperators.hpp:334
std::complex< Real > Jacobian
See UnaryJacobianOperation.
Definition allOperators.hpp:338
T_Real Real
See UnaryJacobianOperation.
Definition allOperators.hpp:337
static inlineReal primal(Arg const &arg)
Definition allOperators.hpp:342
static inlinestd::string getMathRep()
Get the math symbol of the operation. E.g. + for operators and pow() for functions.
Definition allOperators.hpp:355
static inlineJacobian gradient(Arg const &arg, Real const &result)
Compute .
Definition allOperators.hpp:348
UnaryJacobianOperation implementation for complex real.
Definition allOperators.hpp:366
static inlineJacobian gradient(Arg const &arg, Real const &result)
Compute .
Definition allOperators.hpp:380
std::complex< Real > Jacobian
See UnaryJacobianOperation.
Definition allOperators.hpp:370
static inlineReal primal(Arg const &arg)
Definition allOperators.hpp:374
T_Real Real
See UnaryJacobianOperation.
Definition allOperators.hpp:369
static inlinestd::string getMathRep()
Get the math symbol of the operation. E.g. + for operators and pow() for functions.
Definition allOperators.hpp:387
BinaryJacobianOperation specialization for complex polar.
Definition allOperators.hpp:90
static inlineReal applyAdjointArgA(Adjoint const &adjoint, ComplexReal const &result, ArgA const &argA, ArgB const &argB)
Definition allOperators.hpp:111
static inlinestd::string getMathRep()
Get the math symbol of the operation. E.g. + for operators and pow() for functions.
Definition allOperators.hpp:133
T_ComplexReal ComplexReal
See OperationComplexPolar.
Definition allOperators.hpp:93
static inlineReal applyAdjointArgB(Adjoint const &adjoint, ComplexReal const &result, ArgA const &argA, ArgB const &argB)
Definition allOperators.hpp:125
static inlineauto applyTangentArgB(Tangent const &tangent, ComplexReal const &result, ArgA const &argA, ArgB const &argB)
typename ComplexReal::value_type Real
Inner type of the complex value.
Definition allOperators.hpp:95
static inlineComplexReal primal(ArgA const &argA, ArgB const &argB)
Definition allOperators.hpp:99
static inlineauto applyTangentArgA(Tangent const &tangent, ComplexReal const &result, ArgA const &argA, ArgB const &argB)
UnaryJacobianOperation implementation for complex proj.
Definition allOperators.hpp:398
static inlineComplexReal primal(Arg const &argument)
Definition allOperators.hpp:406
static inlinestd::string getMathRep()
Get the math symbol of the operation. E.g. + for operators and pow() for functions.
Definition allOperators.hpp:419
static inlineJacobian gradient(Arg const &argument, ComplexReal const &result)
Compute .
Definition allOperators.hpp:412
double Jacobian
See UnaryJacobianOperation.
Definition allOperators.hpp:402
T_ComplexReal ComplexReal
See UnaryJacobianOperation.
Definition allOperators.hpp:401
UnaryJacobianOperation implementation for complex real.
Definition allOperators.hpp:430
T_Real Real
See UnaryJacobianOperation.
Definition allOperators.hpp:433
static inlineReal primal(Arg const &arg)
Definition allOperators.hpp:438
static inlinestd::string getMathRep()
Get the math symbol of the operation. E.g. + for operators and pow() for functions.
Definition allOperators.hpp:451
static inlineJacobian gradient(Arg const &arg, Real const &result)
Compute .
Definition allOperators.hpp:444
std::complex< Real > Jacobian
See UnaryJacobianOperation.
Definition allOperators.hpp:434
static inlineComplexReal gradientA(ArgA const &argA, ArgB const &argB, ComplexReal const &result)
Compute .
Definition allOperators.hpp:158
std::complex< T_Real > ComplexReal
See BinaryJacobianOperation.
Definition allOperators.hpp:148
static inlinestd::string getMathRep()
Get the math symbol of the operation. E.g. + for operators and pow() for functions.
Definition allOperators.hpp:174
static inlineComplexReal gradientB(ArgA const &argA, ArgB const &argB, ComplexReal const &result)
Compute .
Definition allOperators.hpp:166
static inlineComplexReal primal(ArgA const &argA, ArgB const &argB)
Definition allOperators.hpp:152
BinaryJacobianOperation implementation for pow.
Definition binaryOperators.hpp:726
Represents a concrete lvalue in the CoDiPack expression tree.
Definition parallelActiveType.hpp:54
Implements UnaryOperation for functions where the gradient can be computed and transposed.
Definition computeExpression.hpp:149
Implements ComputeOperation for one argument.
Definition computeExpression.hpp:98