PSCF v1.4.0
cpu/complex.h
1#ifndef PSCF_CPU_COMPLEX_H
2#define PSCF_CPU_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/math/arithmetic.h> // built-in and standard lib types
12
13#include <fftw3.h>
14#include <complex>
15#include <iostream>
16
17namespace Pscf{
18
27
28 // Real and imaginary components of fftw_complex numbers
29
37 inline
38 double real(fftw_complex const & a)
39 { return a[0]; }
40
48 inline
49 double imag(fftw_complex const & a)
50 { return a[1]; }
51
52 // Absolute magnitude
53
61 inline
62 double abs(fftw_complex const & a)
63 { return sqrt(a[0] * a[0] + a[1] * a[1]); }
64
72 inline
73 double absSq(fftw_complex const & a)
74 { return (a[0] * a[0] + a[1] * a[1]); }
75
76 // Complex Conjugation
77
86 inline
87 void conj(fftw_complex& z, fftw_complex const & a)
88 {
89 z[0] = a[0];
90 z[1] = -a[1];
91 }
92
100 inline
101 void conj(fftw_complex& a)
102 {
103 a[0] = a[0];
104 a[1] = -a[1];
105 }
106
107 // Assignment
108
118 inline
119 void assign(fftw_complex& z, double const & a, double const & b)
120 {
121 z[0] = a;
122 z[1] = b;
123 }
124
133 inline
134 void assign(fftw_complex& z, double const & a)
135 {
136 z[0] = a;
137 z[1] = 0.0;
138 }
139
148 inline
149 void assign(fftw_complex& z, fftw_complex const & a)
150 {
151 z[0] = a[0];
152 z[1] = a[1];
153 }
154
163 inline
164 void assign(fftw_complex & z, std::complex<double> const& a)
165 {
166 z[0] = a.real();
167 z[1] = a.imag();
168 }
169
178 inline
179 void assign(std::complex<double> & z, fftw_complex const& a)
180 { z = std::complex<double>(a[0], a[1]); }
181
182 // Addition
183
193 inline
194 void add(fftw_complex& z, fftw_complex const& a, fftw_complex const& b)
195 {
196 z[0] = a[0] + b[0];
197 z[1] = a[1] + b[1];
198 }
199
209 inline
210 void add(fftw_complex& z, fftw_complex const& a, double const& b)
211 {
212 z[0] = a[0] + b;
213 z[1] = a[1];
214 }
215
224 inline
225 void addEq(fftw_complex& a, fftw_complex const& b)
226 {
227 a[0] += b[0];
228 a[1] += b[1];
229 }
230
239 inline
240 void addEq(fftw_complex& a, double const& b)
241 {
242 a[0] += b;
243 }
244
245 // Subtraction
246
256 inline
257 void sub(fftw_complex& z, fftw_complex const& a, fftw_complex const& b)
258 {
259 z[0] = a[0] - b[0];
260 z[1] = a[1] - b[1];
261 }
262
272 inline
273 void sub(fftw_complex& z, fftw_complex const& a, double const& b)
274 {
275 z[0] = a[0] - b;
276 z[1] = a[1];
277 }
278
287 inline
288 void subEq(fftw_complex & a, fftw_complex const& b)
289 {
290 a[0] -= b[0];
291 a[1] -= b[1];
292 }
293
302 inline
303 void subEq(fftw_complex & a, double const& b)
304 {
305 a[0] -= b;
306 }
307
318 inline
319 double absSqDiff(fftw_complex const& a, fftw_complex const& b)
320 {
321 fftw_complex z;
322 sub(z, a, b);
323 return absSq(z);
324 }
325
326 // Multiplication
327
337 inline
338 void mul(fftw_complex& z, fftw_complex const& a, fftw_complex const& b)
339 {
340 z[0] = a[0] * b[0] - a[1] * b[1];
341 z[1] = a[1] * b[0] + a[0] * b[1];
342 }
343
353 inline
354 void mul(fftw_complex& z, fftw_complex const& a, double const& b)
355 {
356 z[0] = a[0]*b;
357 z[1] = a[1]*b;
358 }
359
368 inline
369 void mulEq(fftw_complex & a, fftw_complex const& b)
370 {
371 double a0;
372 a0 = a[0] * b[0] - a[1] * b[1];
373 a[1] = a[1] * b[0] + a[0] * b[1];
374 a[0] = a0;
375 }
376
385 inline
386 void mulEq(fftw_complex & a, double const& b)
387 {
388 a[0] *= b;
389 a[1] *= b;
390 }
391
400 inline
401 void square(fftw_complex& z, fftw_complex const& a)
402 {
403 z[0] = a[0] * a[0] - a[1] * a[1];
404 z[1] = 2.0 * a[1] * a[0];
405 }
406
407 // Division
408
418 inline
419 void div(fftw_complex& z, fftw_complex const& a, fftw_complex const& b)
420 {
421 double bSq = b[0] * b[0] + b[1] * b[1];
422 z[0] = (a[0] * b[0] + a[1] * b[1])/bSq;
423 z[1] = (a[1] * b[0] - a[0] * b[1])/bSq;
424 }
425
435 inline
436 void div(fftw_complex& z, fftw_complex const& a, double const& b)
437 {
438 z[0] = a[0]/b;
439 z[1] = a[1]/b;
440 }
441
450 inline
451 void divEq(fftw_complex & a, fftw_complex const & b)
452 {
453 double bSq = b[0] * b[0] + b[1] * b[1];
454 double a0 = (a[0] * b[0] + a[1] * b[1])/bSq;
455 a[1] = (a[1] * b[0] - a[0] * b[1])/bSq;
456 a[0] = a0;
457 }
458
467 inline
468 void divEq(fftw_complex & a, double const & b)
469 {
470 a[0] /= b;
471 a[1] /= b;
472 }
473
474 // Inversion
475
484 inline
485 void inverse(fftw_complex& z, fftw_complex const & a)
486 {
487 double aSq = a[0] * a[0] + a[1] * a[1];
488 z[0] = a[0]/aSq;
489 z[1] = - a[1]/aSq;
490 }
491
492 // Exponentiation and logarithm
493
502 inline
503 void assignExp(fftw_complex & z, fftw_complex const & a)
504 {
505 std::complex<double> arg = std::complex<double>(a[0], a[1]);
506 std::complex<double> result = std::exp(arg);
507 z[0] = result.real();
508 z[1] = result.imag();
509 }
510
519 inline
520 void assignLog(fftw_complex & z, fftw_complex const & a)
521 {
522 std::complex<double> arg = std::complex<double>(a[0], a[1]);
523 std::complex<double> result = std::log(arg);
524 z[0] = result.real();
525 z[1] = result.imag();
526 }
527
528 // Stream IO operators
529
538 std::istream& operator >> (std::istream& is, fftw_complex & z);
539
549 std::ostream& operator << (std::ostream& os, fftw_complex const & z);
550
551} // namespace Pscf
552#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.
std::istream & operator>>(std::istream &in, Pair< Data > &pair)
Input a Pair from an istream.
Definition Pair.h:44
std::ostream & operator<<(std::ostream &out, const Pair< Data > &pair)
Output a Pair to an ostream, without line breaks.
Definition Pair.h:57