PSCF v1.4.0
VecOp.cpp
1/*
2* PSCF - Polymer Self-Consistent Field
3*
4* Copyright 2015 - 2025, The Regents of the University of Minnesota
5* Distributed under the terms of the GNU General Public License.
6*/
7
8
9#include "VecOp.h"
10#include <util/containers/Array.h>
11#include <cmath>
12
13namespace Pscf {
14namespace VecOp {
15
16 // Assignment
17
18 /*
19 * Vector-vector assignment, a[i] = b[i] (real, slice).
20 */
21 void eqV(Array<double>& a, Array<double> const & b,
22 const int beginIdA, const int beginIdB, const int n)
23 {
24 UTIL_CHECK(beginIdA >= 0);
25 UTIL_CHECK(beginIdB >= 0);
26 UTIL_CHECK(n > 0);
27 UTIL_CHECK(a.capacity() >= beginIdA + n);
28 UTIL_CHECK(b.capacity() >= beginIdB + n);
29 for (int i = 0; i < n; ++i) {
30 a[i + beginIdA] = b[i + beginIdB];
31 }
32 }
33
34 /*
35 * Vector-vector assignment, a[i] = b[i] (real).
36 */
37 void eqV(Array<double>& a, Array<double> const & b)
38 {
39 const int n = a.capacity();
40 UTIL_CHECK(n > 0);
41 UTIL_CHECK(b.capacity() >= n);
42 for (int i = 0; i < n; ++i) {
43 a[i] = b[i];
44 }
45 }
46
47 /*
48 * Vector-scalar assignment, a[i] = b (real).
49 */
50 void eqS(Array<double>& a, double b)
51 {
52 const int n = a.capacity();
53 UTIL_CHECK(n > 0);
54 for (int i = 0; i < n; ++i) {
55 a[i] = b;
56 }
57 }
58
59 // Addition
60
61 /*
62 * Vector-vector addition, a[i] = b[i] + c[i] (real).
63 */
65 Array<double> const & b, Array<double> const & c)
66 {
67 const int n = a.capacity();
68 UTIL_CHECK(n > 0);
69 UTIL_CHECK(b.capacity() >= n);
70 UTIL_CHECK(c.capacity() >= n);
71 for (int i = 0; i < n; ++i) {
72 a[i] = b[i] + c[i];
73 }
74 }
75
76 /*
77 * Vector-scalar addition, a[i] = b[i] + c (real).
78 */
79 void addVS(Array<double>& a, Array<double> const & b, double c)
80 {
81 const int n = a.capacity();
82 UTIL_CHECK(n > 0);
83 UTIL_CHECK(b.capacity() >= n);
84
85 for (int i = 0; i < n; ++i) {
86 a[i] = b[i] + c;
87 }
88 }
89
90 // Subtraction
91
92 /*
93 * Vector-vector subtraction, a[i] = b[i] - c[i] (real).
94 */
96 Array<double> const & b, Array<double> const & c)
97 {
98 const int n = a.capacity();
99 UTIL_CHECK(n > 0);
100 UTIL_CHECK(b.capacity() >= n);
101 UTIL_CHECK(c.capacity() >= n);
102 for (int i = 0; i < n; ++i) {
103 a[i] = b[i] - c[i];
104 }
105 }
106
107 /*
108 * Vector-scalar subtraction, a[i] = b[i] - c (real).
109 */
110 void subVS(Array<double>& a, Array<double> const & b, double c)
111 {
112 const int n = a.capacity();
113 UTIL_CHECK(n > 0);
114 UTIL_CHECK(b.capacity() >= n);
115 for (int i = 0; i < n; ++i) {
116 a[i] = b[i] - c;
117 }
118 }
119
120 // Multiplication
121
122 /*
123 * Vector-vector multiplication, a[i] = b[i] * c[i] (real).
124 */
126 Array<double> const & b, Array<double> const & c)
127 {
128 const int n = a.capacity();
129 UTIL_CHECK(n > 0);
130 UTIL_CHECK(b.capacity() >= n);
131 UTIL_CHECK(c.capacity() >= n);
132 for (int i = 0; i < n; ++i) {
133 a[i] = b[i] * c[i];
134 }
135 }
136
137 /*
138 * Vector-scalar multiplication, a[i] = b[i] * c (real).
139 */
140 void mulVS(Array<double>& a, Array<double> const & b, double c)
141 {
142 const int n = a.capacity();
143 UTIL_CHECK(n > 0);
144 UTIL_CHECK(b.capacity() >= n);
145 for (int i = 0; i < n; ++i) {
146 a[i] = b[i] * c;
147 }
148 }
149
150 // Division
151
152 /*
153 * Vector-vector division, a[i] = b[i] / c[i] (real).
154 */
156 Array<double> const & b, Array<double> const & c)
157 {
158 const int n = a.capacity();
159 UTIL_CHECK(n > 0);
160 UTIL_CHECK(b.capacity() >= n);
161 UTIL_CHECK(c.capacity() >= n);
162 for (int i = 0; i < n; ++i) {
163 a[i] = b[i] / c[i];
164 }
165 }
166
167 /*
168 * Vector-scalar division, a[i] = b[i] / c (real).
169 */
170 void divVS(Array<double>& a, Array<double> const & b, double c)
171 {
172 const int n = a.capacity();
173 UTIL_CHECK(n > 0);
174 UTIL_CHECK(b.capacity() >= n);
175 for (int i = 0; i < n; ++i) {
176 a[i] = b[i] / c;
177 }
178 }
179
180 /*
181 * Scalar-vector division, a[i] = b / c[i] (real).
182 */
183 void divSV(Array<double>& a, double b, Array<double> const & c)
184 {
185 const int n = a.capacity();
186 UTIL_CHECK(n > 0);
187 UTIL_CHECK(c.capacity() >= n);
188 for (int i = 0; i < n; ++i) {
189 a[i] = b/c[i];
190 }
191 }
192
193 // In-place addition
194
195 /*
196 * Vector-vector in-place addition, a[i] += b[i] (real).
197 */
199 {
200 const int n = a.capacity();
201 UTIL_CHECK(n > 0);
202 UTIL_CHECK(b.capacity() >= n);
203 for (int i = 0; i < n; ++i) {
204 a[i] += b[i];
205 }
206 }
207
208 /*
209 * Vector-scalar in-place addition, a[i] += b (real).
210 */
211 void addEqS(Array<double>& a, double b)
212 {
213 const int n = a.capacity();
214 UTIL_CHECK(n > 0);
215 for (int i = 0; i < n; ++i) {
216 a[i] += b;
217 }
218 }
219
220 // In-place subtraction
221
222 /*
223 * Vector-vector in-place subtraction, a[i] -= b[i] (real).
224 */
226 {
227 const int n = a.capacity();
228 UTIL_CHECK(n > 0);
229 UTIL_CHECK(b.capacity() >= n);
230 for (int i = 0; i < n; ++i) {
231 a[i] -= b[i];
232 }
233 }
234
235 /*
236 * Vector-scalar in-place subtraction, a[i] -= b (real).
237 */
238 void subEqS(Array<double>& a, double b)
239 {
240 const int n = a.capacity();
241 UTIL_CHECK(n > 0);
242 for (int i = 0; i < n; ++i) {
243 a[i] -= b;
244 }
245 }
246
247 // In-place multiplication
248
249 /*
250 * Vector-vector in-place multiplication, a[i] *= b[i] (real).
251 */
253 {
254 const int n = a.capacity();
255 UTIL_CHECK(n > 0);
256 UTIL_CHECK(b.capacity() >= n);
257 for (int i = 0; i < n; ++i) {
258 a[i] *= b[i];
259 }
260 }
261
262 /*
263 * Vector-scalar in-place multiplication, a[i] *= b (real).
264 */
265 void mulEqS(Array<double>& a, double b)
266 {
267 const int n = a.capacity();
268 UTIL_CHECK(n > 0);
269 for (int i = 0; i < n; ++i) {
270 a[i] *= b;
271 }
272 }
273
274 // In-place division
275
276 /*
277 * Vector-vector in-place division, a[i] /= b[i] (real).
278 */
280 {
281 const int n = a.capacity();
282 UTIL_CHECK(n > 0);
283 UTIL_CHECK(b.capacity() >= n);
284 for (int i = 0; i < n; ++i) {
285 a[i] /= b[i];
286 }
287 }
288
289 /*
290 * Vector-scalar in-place division, a[i] /= b (real).
291 */
292 void divEqS(Array<double>& a, double b)
293 {
294 const int n = a.capacity();
295 UTIL_CHECK(n > 0);
296 for (int i = 0; i < n; ++i) {
297 a[i] /= b;
298 }
299 }
300
301 // Exponentiation
302
303 /*
304 * Vector exponentiation, a[i] = exp(b[i]) (real).
305 */
306 void expV(Array<double>& a, Array<double> const & b)
307 {
308 const int n = a.capacity();
309 UTIL_CHECK(n > 0);
310 UTIL_CHECK(b.capacity() >= n);
311 for (int i = 0; i < n; ++i) {
312 a[i] = exp(b[i]);
313 }
314 }
315
316 /*
317 * Exponentiate a scaled vector, a[i] = exp(b[i]*c) (real).
318 */
319 void expVc(Array<double>& a, Array<double> const & b, const double c)
320 {
321 const int n = a.capacity();
322 UTIL_CHECK(n > 0);
323 UTIL_CHECK(b.capacity() >= n);
324 for (int i = 0; i < n; ++i) {
325 a[i] = exp(b[i]*c);
326 }
327 }
328
329 // Square
330
331 /*
332 * Vector elementwise square, a[i] = b[i]*b[i] (real).
333 */
334 void sqV(Array<double>& a, Array<double> const & b)
335 {
336 const int n = a.capacity();
337 UTIL_CHECK(n > 0);
338 UTIL_CHECK(b.capacity() >= n);
339 for (int i = 0; i < n; ++i) {
340 a[i] = b[i]*b[i];
341 }
342 }
343
344 // Absolute magnitude
345
346 /*
347 * Vector elementwise square, a[i] = b[i]*b[i] (real).
348 */
349 void absV(Array<double>& a, Array<double> const & b)
350 {
351 const int n = a.capacity();
352 UTIL_CHECK(n > 0);
353 UTIL_CHECK(b.capacity() >= n);
354 for (int i = 0; i < n; ++i) {
355 a[i] = std::abs(b[i]);
356 }
357 }
358
359 // Linear combinations (separate result)
360
361 /*
362 * Add two scaled vectors, a[i] = b1[i]*c1 + b2[2]*c2 (real).
363 */
365 Array<double> const & b1, const double c1,
366 Array<double> const & b2, const double c2)
367 {
368 const int n = a.capacity();
369 UTIL_CHECK(n > 0);
370 UTIL_CHECK(b1.capacity() >= n);
371 UTIL_CHECK(b2.capacity() >= n);
372 for (int i = 0; i < n; ++i) {
373 a[i] = b1[i]*c1 + b2[i]*c2;
374 }
375 }
376
377 /*
378 * Add a scaled vector and a scalar, a[i] = b[i]*c + s (real).
379 */
381 Array<double> const & b, const double c,
382 const double s)
383 {
384 const int n = a.capacity();
385 UTIL_CHECK(n > 0);
386 UTIL_CHECK(b.capacity() >= n);
387 for (int i = 0; i < n; ++i) {
388 a[i] = b[i]*c + s;
389 }
390 }
391
392 /*
393 * In-place add one scaled vector, a[i] += b[i]*c (real).
394 */
396 Array<double> const & b, const double c)
397 {
398 const int n = a.capacity();
399 UTIL_CHECK(n > 0);
400 UTIL_CHECK(b.capacity() >= n);
401 for (int i = 0; i < n; ++i) {
402 a[i] += b[i]*c;
403 }
404 }
405
406 /*
407 * Add 2 scaled vectors & scalar, a[i] = b1[i]*c1 + b2[i]*c2 + s (real).
408 */
410 Array<double> const & b1, const double c1,
411 Array<double> const & b2, const double c2,
412 const double s)
413 {
414 const int n = a.capacity();
415 UTIL_CHECK(n > 0);
416 UTIL_CHECK(b1.capacity() >= n);
417 UTIL_CHECK(b2.capacity() >= n);
418 for (int i = 0; i < n; ++i) {
419 a[i] = b1[i]*c1 + b2[i]*c2 + s;
420 }
421 }
422
423 /*
424 * Add 3 scaled vectors, a[i] = b1[i]*c1 + b2[i]*c2 + b3[i]*c3 (real).
425 */
427 Array<double> const & b1, const double c1,
428 Array<double> const & b2, const double c2,
429 Array<double> const & b3, const double c3)
430 {
431 const int n = a.capacity();
432 UTIL_CHECK(n > 0);
433 UTIL_CHECK(b1.capacity() >= n);
434 UTIL_CHECK(b2.capacity() >= n);
435 UTIL_CHECK(b3.capacity() >= n);
436 for (int i = 0; i < n; ++i) {
437 a[i] = b1[i]*c1 + b2[i]*c2 + b3[i]*c3;
438 }
439 }
440
441 // Pair operations (two output arrays and a shared input)
442
443 /*
444 * Vector assignment in pairs, ax[i] = b[i], x = 1, 2 (real).
445 */
447 Array<double>& a2,
448 Array<double> const & b)
449 {
450 const int n = a1.capacity();
451 UTIL_CHECK(n > 0);
452 UTIL_CHECK(a2.capacity() == n);
453 UTIL_CHECK(b.capacity() >= n);
454 for (int i = 0; i < n; ++i) {
455 a1[i] = b[i];
456 a2[i] = b[i];
457 }
458 }
459
460 /*
461 * Vector multiplication in pairs, ax[i] = bx[i] * c[i], x=1,2 (real).
462 */
464 Array<double>& a2,
465 Array<double> const & b1,
466 Array<double> const & b2,
467 Array<double> const & c)
468 {
469 const int n = a1.capacity();
470 UTIL_CHECK(n > 0);
471 UTIL_CHECK(a2.capacity() == n);
472 UTIL_CHECK(b1.capacity() >= n);
473 UTIL_CHECK(b2.capacity() >= n);
474 UTIL_CHECK(c.capacity() >= n);
475 for (int i = 0; i < n; ++i) {
476 a1[i] = b1[i]*c[i];
477 a2[i] = b2[i]*c[i];
478 }
479 }
480
481 /*
482 * In-place vector multiplication in pairs, ax[i] *= b[i], x=1,2 (real).
483 */
485 Array<double>& a2,
486 Array<double> const & b)
487 {
488 const int n = a1.capacity();
489 UTIL_CHECK(n > 0);
490 UTIL_CHECK(a2.capacity() == n);
491 UTIL_CHECK(b.capacity() >= n);
492 for (int i = 0; i < n; ++i) {
493 a1[i] *= b[i];
494 a2[i] *= b[i];
495 }
496 }
497
498} // namespace VecOp
499} // namespace Pscf
Array container class template.
Definition Array.h:40
int capacity() const
Return allocated size.
Definition Array.h:144
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition global.h:68
void divEqS(Array< double > &a, double b)
Vector-scalar in-place division, a[i] /= b.
Definition VecOp.cpp:292
void addEqV(Array< double > &a, Array< double > const &b)
Vector-vector in-place addition, a[i] += b[i] (real).
Definition VecOp.cpp:198
void divEqV(Array< double > &a, Array< double > const &b)
Vector-vector in-place division, a[i] /= b[i].
Definition VecOp.cpp:279
void addEqS(Array< double > &a, double b)
Vector-scalar in-place addition, a[i] += b (real).
Definition VecOp.cpp:211
void sqV(Array< double > &a, Array< double > const &b)
Vector element-wise square, a[i] = b[i]*b[i] (real).
Definition VecOp.cpp:334
void mulEqV(Array< double > &a, Array< double > const &b)
Vector-vector in-place multiplication, a[i] *= b[i] (real).
Definition VecOp.cpp:252
void eqV(Array< double > &a, Array< double > const &b, const int beginIdA, const int beginIdB, const int n)
Vector assignment, a[i] = b[i] (real, slice).
Definition VecOp.cpp:21
void mulEqS(Array< double > &a, double b)
Vector-scalar in-place multiplication, a[i] *= b (real).
Definition VecOp.cpp:265
void subVV(Array< double > &a, Array< double > const &b, Array< double > const &c)
Vector-vector subtraction, a[i] = b[i] - c[i] (real)
Definition VecOp.cpp:95
void absV(Array< double > &a, Array< double > const &b)
Element-wise absolute magnitude, a[i] = abs(b[i]) (real).
Definition VecOp.cpp:349
void expV(Array< double > &a, Array< double > const &b)
Vector exponentiation, a[i] = exp(b[i]) (real).
Definition VecOp.cpp:306
void divVS(Array< double > &a, Array< double > const &b, double c)
Vector-scalar division, a[i] = b[i] / c (real).
Definition VecOp.cpp:170
void expVc(Array< double > &a, Array< double > const &b, const double c)
Exponentiation a scaled vector, a[i] = exp(b[i]*c) (real).
Definition VecOp.cpp:319
void eqS(Array< double > &a, double b)
Vector assignment, a[i] = b (real).
Definition VecOp.cpp:50
void mulVV(Array< double > &a, Array< double > const &b, Array< double > const &c)
Vector-vector multiplication, a[i] = b[i] * c[i] (real).
Definition VecOp.cpp:125
void subVS(Array< double > &a, Array< double > const &b, double c)
Vector-scalar subtraction, a[i] = b[i] - c (real).
Definition VecOp.cpp:110
void subEqV(Array< double > &a, Array< double > const &b)
Vector-vector in-place subtraction, a[i] -= b[i] (real).
Definition VecOp.cpp:225
void addVV(Array< double > &a, Array< double > const &b, Array< double > const &c)
Vector-vector addition, a[i] = b[i] + c[i] (real)
Definition VecOp.cpp:64
void divSV(Array< double > &a, double b, Array< double > const &c)
Vector division, a[i] = b / c[i].
Definition VecOp.cpp:183
void addVS(Array< double > &a, Array< double > const &b, double c)
Vector-scalar addition, a[i] = b[i] + c (real).
Definition VecOp.cpp:79
void divVV(Array< double > &a, Array< double > const &b, Array< double > const &c)
Vector-vector division, a[i] = b[i] / c[i] (real).
Definition VecOp.cpp:155
void subEqS(Array< double > &a, double b)
Vector-scalar subtraction in-place, a[i] -= b (real).
Definition VecOp.cpp:238
void addEqVc(Array< double > &a, Array< double > const &b, const double c)
Add scaled vector in-place, a[i] += b[i]*c (real).
Definition VecOp.cpp:395
void mulVS(Array< double > &a, Array< double > const &b, double c)
Vector-scalar multiplication, a[i] = b[i] * c (real).
Definition VecOp.cpp:140
void mulVVPair(Array< double > &a1, Array< double > &a2, Array< double > const &b1, Array< double > const &b2, Array< double > const &c)
Vector multiplication in pairs, ax[i] = bx[i] * s[i], x=1,2.
Definition VecOp.cpp:463
void eqVPair(Array< double > &a1, Array< double > &a2, Array< double > const &b)
Vector assignment in pairs, ax[i] = b[i], x = 1, 2.
Definition VecOp.cpp:446
void mulEqVPair(Array< double > &a1, Array< double > &a2, Array< double > const &b)
In-place vector multiplication in pairs, ax[i] *= b[i], x=1,2.
Definition VecOp.cpp:484
Vector operations on GPU or CPU.
Definition VecOp.cpp:14
void addVcVcS(Array< double > &a, Array< double > const &b1, const double c1, Array< double > const &b2, const double c2, const double s)
Add scaled vectors + scalar, a[i] = b1[i]*c1 + b2[2]*c2 + s (real).
Definition VecOp.cpp:409
void addVcS(Array< double > &a, Array< double > const &b, const double c, const double s)
Add a scaled vector and a scalar, a[i] = b[i]*c + s (real).
Definition VecOp.cpp:380
void addVcVc(Array< double > &a, Array< double > const &b1, const double c1, Array< double > const &b2, const double c2)
Add two scaled vectors, a[i] = b1[i]*c1 + b2[2]*c2 (real).
Definition VecOp.cpp:364
void addVcVcVc(Array< double > &a, Array< double > const &b1, const double c1, Array< double > const &b2, const double c2, Array< double > const &b3, const double c3)
Add scaled vectors, a[i] = b1[i]*c1 + b2[i]*c2 + b3[i]*c3 (real).
Definition VecOp.cpp:426
PSCF package top-level namespace.