PSCF v1.4.0
cuda/complex.h
1#ifndef PSCF_CUDA_COMPLEX_H
2#define PSCF_CUDA_COMPLEX_H
3
4/*
5* PSCF - Polymer Self-Consistent Field
6*
7* Copyright 2015 - 2025, The Regents of the University of Minnesota
8* Distributed under the terms of the GNU General Public License.
9*/
10
11#include <pscf/cuda/cudaTypes.h>
12#include <pscf/math/arithmetic.h>
13#include <complex>
14
15namespace Pscf {
16
25
26 /*
27 * Types cudaComplex and cudaReal are defined in pscf/cuda/cudaTypes.h
28 * (in the Prdc::Cuda namespace) as aliases for cufft complex and
29 * real types. They may be either single or double precision.
30 */
31
32 // Real and imaginary components
33
41 inline
43 { return a.x; }
44
52 inline
54 { return a.y; }
55
56 // Absolute magnitude
57
65 inline
67 { return sqrt(a.x * a.x + a.y * a.y); }
68
76 inline
78 { return (a.x * a.x + a.y * a.y); }
79
80 // Complex Conjugation
81
90 inline
91 void conj(cudaComplex& z, cudaComplex const& a)
92 {
93 z.x = a.x;
94 z.y = -a.y;
95 }
96
104 inline
106 {
107 a.x = a.x;
108 a.y = -a.y;
109 }
110
111 // Assignment
112
122 inline
123 void assign(cudaComplex& z, cudaReal const& a, cudaReal const& b)
124 {
125 z.x = a;
126 z.y = b;
127 }
128
137 inline
138 void assign(cudaComplex& z, cudaReal const& a)
139 {
140 z.x = a;
141 z.y = 0;
142 }
143
152 inline
153 void assign(cudaComplex& z, cudaComplex const& a)
154 {
155 z.x = a.x;
156 z.y = a.y;
157 }
158
167 inline
169 std::complex<cudaReal> const& a)
170 {
171 z.x = a.real();
172 z.y = a.imag();
173 }
174
183 inline
184 void assign(std::complex<cudaReal> & z,
185 cudaComplex const& a)
186 { z = std::complex<cudaReal>(a.x, a.y); }
187
188 // Addition
189
199 inline
200 void add(cudaComplex& z, cudaComplex const& a,
201 cudaComplex const& b)
202 {
203 z.x = a.x + b.x;
204 z.y = a.y + b.y;
205 }
206
216 inline
217 void add(cudaComplex& z, cudaComplex const& a,
218 cudaReal const& b)
219 {
220 z.x = a.x + b;
221 z.y = a.y;
222 }
223
232 inline
233 void addEq(cudaComplex& a, cudaComplex const& b)
234 {
235 a.x += b.x;
236 a.y += b.y;
237 }
238
247 inline
248 void addEq(cudaComplex& a, cudaReal const& b)
249 {
250 a.x += b;
251 }
252
253 // Subtraction
254
264 inline
265 void sub(cudaComplex& z, cudaComplex const& a,
266 cudaComplex const& b)
267 {
268 z.x = a.x - b.x;
269 z.y = a.y - b.y;
270 }
271
281 inline
282 void sub(cudaComplex& z, cudaComplex const& a,
283 cudaReal const& b)
284 {
285 z.x = a.x - b;
286 z.y = a.y;
287 }
288
297 inline
298 void subEq(cudaComplex & a, cudaComplex const& b)
299 {
300 a.x -= b.x;
301 a.y -= b.y;
302 }
303
312 inline
313 void subEq(cudaComplex & a, cudaReal const& b)
314 {
315 a.x -= b;
316 }
317
328 inline
330 cudaComplex const& b)
331 {
332 cudaComplex z;
333 sub(z, a, b);
334 return absSq(z);
335 }
336
337 // Multiplication
338
348 inline
349 void mul(cudaComplex& z, cudaComplex const& a,
350 cudaComplex const& b)
351 {
352 z.x = a.x * b.x - a.y * b.y;
353 z.y = a.y * b.x + a.x * b.y;
354 }
355
365 inline
366 void mul(cudaComplex& z, cudaComplex const& a,
367 cudaReal const& b)
368 {
369 z.x = a.x*b;
370 z.y = a.y*b;
371 }
372
381 inline
382 void mulEq(cudaComplex & a, cudaComplex const& b)
383 {
384 cudaReal a0;
385 a0 = a.x * b.x - a.y * b.y;
386 a.y = a.y * b.x + a.x * b.y;
387 a.x = a0;
388 }
389
398 inline
399 void mulEq(cudaComplex & a, cudaReal const& b)
400 {
401 a.x *= b;
402 a.y *= b;
403 }
404
413 inline
414 void square(cudaComplex& z, cudaComplex const& a)
415 {
416 z.x = a.x * a.x - a.y * a.y;
417 z.y = 2.0 * a.y * a.x;
418 }
419
420 // Division
421
431 inline
432 void div(cudaComplex& z, cudaComplex const& a,
433 cudaComplex const& b)
434 {
435 cudaReal bSq = b.x * b.x + b.y * b.y;
436 z.x = (a.x * b.x + a.y * b.y) / bSq;
437 z.y = (a.y * b.x - a.x * b.y) / bSq;
438 }
439
449 inline
450 void div(cudaComplex& z, cudaComplex const& a,
451 cudaReal const& b)
452 {
453 z.x = a.x / b;
454 z.y = a.y / b;
455 }
456
465 inline
466 void divEq(cudaComplex & a, cudaComplex const & b)
467 {
468 cudaReal bSq = b.x * b.x + b.y * b.y;
469 cudaReal a0 = (a.x * b.x + a.y * b.y)/bSq;
470 a.y = (a.y * b.x - a.x * b.y)/bSq;
471 a.x = a0;
472 }
473
482 inline
483 void divEq(cudaComplex & a, cudaReal const& b)
484 {
485 a.x /= b;
486 a.y /= b;
487 }
488
489 // Inversion
490
499 inline
501 cudaComplex const & a)
502 {
503 cudaReal aSq = a.x * a.x + a.y * a.y;
504 z.x = a.x/aSq;
505 z.y = - a.y/aSq;
506 }
507
508 // Exponentiation and logarithm
509
518 inline
520 cudaComplex const & a)
521 {
522 std::complex<cudaReal> arg
523 = std::complex<cudaReal>(a.x, a.y);
524 std::complex<cudaReal> result = std::exp(arg);
525 z.x = result.real();
526 z.y = result.imag();
527 }
528
537 inline
539 cudaComplex const & a)
540 {
541 std::complex<cudaReal> arg
542 = std::complex<cudaReal>(a.x, a.y);
543 std::complex<cudaReal> result = std::log(arg);
544 z.x = result.real();
545 z.y = result.imag();
546 }
547
548 // Pseudo-constructor
549
550 /*
551 * Pseudo-constructor function for cudaComplex.
552 *
553 * \ingroup Pscf_Cuda_Complex_Module
554 *
555 * \param x real part (in)
556 * \param y imaginary part (in)
557 */
558 __host__ __device__ static inline
559 cudaComplex makeComplex(cudaReal x, cudaReal y)
560 {
561 cudaComplex result;
562 result.x = x;
563 result.y = y;
564 return result;
565 }
566
567} // namespace Pscf
568#endif
void mulEq(fftw_complex &a, fftw_complex const &b)
In-place multiplication of two complex number, a *= b.
double absSq(fftw_complex const &a)
Return square of absolute magnitude of an fftw_complex number.
Definition cpu/complex.h:73
void addEq(fftw_complex &a, fftw_complex const &b)
In-place addition of fftw_complex numbers, a += b.
void square(fftw_complex &z, fftw_complex const &a)
Complex square of an fftw_complex number, z = a * a.
void div(fftw_complex &z, fftw_complex const &a, fftw_complex const &b)
Division of fftw_complex numbers, z = a / b .
void inverse(fftw_complex &z, fftw_complex const &a)
Inversion of an fftw_complex number, z = 1 / a .
double imag(fftw_complex const &a)
Return the imaginary part of an fftw_complex number.
Definition cpu/complex.h:49
void conj(fftw_complex &z, fftw_complex const &a)
Complex conjugate of an fftw_complex, z = a^*.
Definition cpu/complex.h:87
void assignExp(fftw_complex &z, fftw_complex const &a)
Exponentation of a ffts_complex variable, z = exp(a).
void add(fftw_complex &z, fftw_complex const &a, fftw_complex const &b)
Addition of fftw_complex numbers, z = a + b.
void sub(fftw_complex &z, fftw_complex const &a, fftw_complex const &b)
Subtraction of fftw_complex numbers, z = a - b.
double absSqDiff(fftw_complex const &a, fftw_complex const &b)
Return square of the absolute magnitude of a complex difference.
void subEq(fftw_complex &a, fftw_complex const &b)
In-place subtraction of fftw_complex numbers, a -= b.
void assign(fftw_complex &z, double const &a, double const &b)
Create an fftw_complex from real and imaginary parts, z = a + ib.
void mul(fftw_complex &z, fftw_complex const &a, fftw_complex const &b)
Multiplication of fftw_complex numbers, z = a * b.
double real(fftw_complex const &a)
Return the real part of an fftw_complex number.
Definition cpu/complex.h:38
void divEq(fftw_complex &a, fftw_complex const &b)
In-place division of fftw_complex numbers, a /= b.
double abs(fftw_complex const &a)
Return absolute magnitude of an fftw_complex number.
Definition cpu/complex.h:62
void assignLog(fftw_complex &z, fftw_complex const &a)
Logarithm of an fftw_complex variable, z = log(a).
PSCF package top-level namespace.
cufftDoubleComplex cudaComplex
Complex number type used in CPU code that uses FFTW.
Definition cudaTypes.h:22
cufftDoubleReal cudaReal
Real number type used in CPU code that uses FFTW.
Definition cudaTypes.h:35