Nektar++
Vmath.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: Vmath.cpp
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description: Collection of templated functions for vector mathematics
32//
33///////////////////////////////////////////////////////////////////////////////
34
36
37namespace Vmath
38{
39
40/***************** Math routines ***************/
41
42/// \brief Fill a vector with a constant value
43template <class T> void Fill(int n, const T alpha, T *x, const int incx)
44{
45 while (n--)
46 {
47 *x = alpha;
48 x += incx;
49 }
50}
51
52template LIB_UTILITIES_EXPORT void Fill(int n, const Nektar::NekDouble alpha,
53 Nektar::NekDouble *x, const int incx);
54template LIB_UTILITIES_EXPORT void Fill(int n, const Nektar::NekSingle alpha,
55 Nektar::NekSingle *x, const int incx);
56
57#define IM1 2147483563
58#define IM2 2147483399
59#define AM (1.0 / IM1)
60#define IMM1 (IM1 - 1)
61#define IA1 40014
62#define IA2 40692
63#define IQ1 53668
64#define IQ2 52774
65#define IR1 12211
66#define IR2 3791
67#define NTAB 32
68#define NDIV (1 + IMM1 / NTAB)
69#define EPS 1.2e-7
70#define RNMX (1.0 - EPS)
71
72/// \brief Generates a number from ~Normal(0,1)
73template <class T> T ran2(long *idum)
74/* ------------------------------------------------------------------------- *
75 * Ran2 from NR 2e. Returns a uniform random deviate between 0.0 &
76 * 1.0 (exclusive of endpoints). Call with idum a negative integer to
77 * initialize; thereafter, do not alter idum between successive
78 * deviates in a sequence. RNMX should approximate the largest
79 * floating value that is less than 1.
80 * ------------------------------------------------------------------------- */
81{
82 int j;
83 long k;
84 static long idum2 = 123456789;
85 static long iy = 0;
86 static long iv[NTAB];
87 T temp;
88
89 if (*idum <= 0)
90 {
91 if (-(*idum) < 1)
92 *idum = 1;
93 else
94 *idum = -(*idum);
95 idum2 = (*idum);
96 for (j = NTAB + 7; j >= 0; j--)
97 {
98 k = (*idum) / IQ1;
99 *idum = IA1 * (*idum - k * IQ1) - k * IR1;
100 if (*idum < 0)
101 *idum += IM1;
102 if (j < NTAB)
103 iv[j] = *idum;
104 }
105 iy = iv[0];
106 }
107
108 k = (*idum) / IQ1;
109 *idum = IA1 * (*idum - k * IQ1) - k * IR1;
110 if (*idum < 0)
111 *idum += IM1;
112
113 k = idum2 / IQ2;
114 idum2 = IA2 * (idum2 - k * IQ2) - k * IR2;
115 if (idum2 < 0)
116 idum2 += IM2;
117
118 j = iy / NDIV;
119 iy = iv[j] - idum2;
120 iv[j] = *idum;
121 if (iy < 1)
122 iy += IMM1;
123
124 if ((temp = AM * iy) > RNMX)
125 return RNMX;
126 else
127 return temp;
128}
129
130#undef IM1
131#undef IM2
132#undef AM
133#undef IMM1
134#undef IA1
135#undef IA2
136#undef IQ1
137#undef IQ2
138#undef IR1
139#undef IR2
140#undef NTAB
141#undef NDIV
142#undef EPS
143#undef RNMX
144
145#ifdef NEKTAR_USE_THREAD_SAFETY
146static boost::mutex mutex;
147#endif
149template LIB_UTILITIES_EXPORT Nektar::NekSingle ran2(long *idum);
150
151/// \brief Fills a vector with white noise.
152template <class T>
153void FillWhiteNoise(int n, const T eps, T *x, const int incx, int outseed)
154{
155#ifdef NEKTAR_USE_THREAD_SAFETY
156 // Protect the static vars here and in ran2
157 boost::mutex::scoped_lock l(mutex);
158#endif
159
160 // Define static variables for generating random numbers
161 static int iset = 0;
162 static T gset;
163 static long seed = 0;
164
165 // Bypass seed if outseed was specified
166 if (outseed != 9999)
167 {
168 seed = long(outseed);
169 }
170
171 while (n--)
172 {
173 T fac, rsq, v1, v2;
174
175 if (iset == 0)
176 {
177 do
178 {
179 v1 = 2.0 * ran2<T>(&seed) - 1.0;
180 v2 = 2.0 * ran2<T>(&seed) - 1.0;
181 rsq = v1 * v1 + v2 * v2;
182 } while (rsq >= 1.0 || rsq == 0.0);
183 fac = sqrt(-2.0 * log(rsq) / rsq);
184 gset = v1 * fac;
185 iset = 1;
186 *x = eps * v2 * fac;
187 }
188 else
189 {
190 iset = 0;
191 *x = eps * gset;
192 }
193 x += incx;
194 }
195}
197 const Nektar::NekDouble eps,
199 const int incx, int outseed);
201 const Nektar::NekSingle eps,
203 const int incx, int outseed);
204
205/// \brief Multiply vector z = x*y
206template <class T>
207void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z,
208 const int incz)
209{
210 ++n;
211 if (incx == 1 && incy == 1 && incz == 1)
212 {
213 while (--n)
214 {
215 *z = (*x) * (*y);
216 ++x;
217 ++y;
218 ++z;
219 }
220 }
221 else
222 {
223 while (--n)
224 {
225 *z = (*x) * (*y);
226 x += incx;
227 y += incy;
228 z += incz;
229 }
230 }
231}
232template LIB_UTILITIES_EXPORT void Vmul(int n, const Nektar::NekDouble *x,
233 const int incx,
234 const Nektar::NekDouble *y,
235 const int incy, Nektar::NekDouble *z,
236 const int incz);
237template LIB_UTILITIES_EXPORT void Vmul(int n, const Nektar::NekSingle *x,
238 const int incx,
239 const Nektar::NekSingle *y,
240 const int incy, Nektar::NekSingle *z,
241 const int incz);
242
243/// \brief Scalar multiply y = alpha*x
244template <class T>
245void Smul(int n, const T alpha, const T *x, const int incx, T *y,
246 const int incy)
247{
248 ++n;
249 if (incx == 1 && incy == 1)
250 {
251 while (--n)
252 {
253 *y = alpha * (*x);
254 ++x;
255 ++y;
256 }
257 }
258 else
259 {
260 while (--n)
261 {
262 *y = alpha * (*x);
263 x += incx;
264 y += incy;
265 }
266 }
267}
268
269template LIB_UTILITIES_EXPORT void Smul(int n, const Nektar::NekDouble alpha,
270 const Nektar::NekDouble *x,
271 const int incx, Nektar::NekDouble *y,
272 const int incy);
273template LIB_UTILITIES_EXPORT void Smul(int n, const Nektar::NekSingle alpha,
274 const Nektar::NekSingle *x,
275 const int incx, Nektar::NekSingle *y,
276 const int incy);
277
278/// \brief Multiply vector z = x/y
279template <class T>
280void Vdiv(int n, const T *x, const int incx, const T *y, const int incy, T *z,
281 const int incz)
282{
283 ++n;
284 if (incx == 1 && incy == 1)
285 {
286 while (--n)
287 {
288 *z = (*x) / (*y);
289 ++x;
290 ++y;
291 ++z;
292 }
293 }
294 else
295 {
296 while (--n)
297 {
298 *z = (*x) / (*y);
299 x += incx;
300 y += incy;
301 z += incz;
302 }
303 }
304}
305
306template LIB_UTILITIES_EXPORT void Vdiv(int n, const Nektar::NekDouble *x,
307 const int incx,
308 const Nektar::NekDouble *y,
309 const int incy, Nektar::NekDouble *z,
310 const int incz);
311template LIB_UTILITIES_EXPORT void Vdiv(int n, const Nektar::NekSingle *x,
312 const int incx,
313 const Nektar::NekSingle *y,
314 const int incy, Nektar::NekSingle *z,
315 const int incz);
316
317/// \brief Scalar multiply y = alpha/x
318template <class T>
319void Sdiv(int n, const T alpha, const T *x, const int incx, T *y,
320 const int incy)
321{
322 ++n;
323 if (incx == 1 && incy == 1)
324 {
325 while (--n)
326 {
327 *y = alpha / (*x);
328 ++x;
329 ++y;
330 }
331 }
332 else
333 {
334 while (--n)
335 {
336 *y = alpha / (*x);
337 x += incx;
338 y += incy;
339 }
340 }
341}
342
343template LIB_UTILITIES_EXPORT void Sdiv(int n, const Nektar::NekDouble alpha,
344 const Nektar::NekDouble *x,
345 const int incx, Nektar::NekDouble *y,
346 const int incy);
347template LIB_UTILITIES_EXPORT void Sdiv(int n, const Nektar::NekSingle alpha,
348 const Nektar::NekSingle *x,
349 const int incx, Nektar::NekSingle *y,
350 const int incy);
351
352/// \brief Add vector z = x+y
353template <class T>
354void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z,
355 const int incz)
356{
357 while (n--)
358 {
359 *z = (*x) + (*y);
360 x += incx;
361 y += incy;
362 z += incz;
363 }
364}
365
366template LIB_UTILITIES_EXPORT void Vadd(int n, const Nektar::NekDouble *x,
367 const int incx,
368 const Nektar::NekDouble *y,
369 const int incy, Nektar::NekDouble *z,
370 const int incz);
371template LIB_UTILITIES_EXPORT void Vadd(int n, const Nektar::NekSingle *x,
372 const int incx,
373 const Nektar::NekSingle *y,
374 const int incy, Nektar::NekSingle *z,
375 const int incz);
376
377/// \brief Add scalar y = alpha + x
378template <class T>
379void Sadd(int n, const T alpha, const T *x, const int incx, T *y,
380 const int incy)
381{
382 ++n;
383 if (incx == 1 && incy == 1)
384 {
385 while (--n)
386 {
387 *y = alpha + (*x);
388 ++x;
389 ++y;
390 }
391 }
392 else
393 {
394 while (--n)
395 {
396 *y = alpha + (*x);
397 x += incx;
398 y += incy;
399 }
400 }
401}
402
403template LIB_UTILITIES_EXPORT void Sadd(int n, const Nektar::NekDouble alpha,
404 const Nektar::NekDouble *x,
405 const int incx, Nektar::NekDouble *y,
406 const int incy);
407template LIB_UTILITIES_EXPORT void Sadd(int n, const Nektar::NekSingle alpha,
408 const Nektar::NekSingle *x,
409 const int incx, Nektar::NekSingle *y,
410 const int incy);
411
412/// \brief Subtract vector z = x-y
413template <class T>
414void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z,
415 const int incz)
416{
417 ++n;
418 if (incx == 1 && incy == 1 && incz == 1)
419 {
420 while (--n)
421 {
422 *z = (*x) - (*y);
423 ++x;
424 ++y;
425 ++z;
426 }
427 }
428 else
429 {
430 while (--n)
431 {
432 *z = (*x) - (*y);
433 x += incx;
434 y += incy;
435 z += incz;
436 }
437 }
438}
439
440template LIB_UTILITIES_EXPORT void Vsub(int n, const Nektar::NekDouble *x,
441 const int incx,
442 const Nektar::NekDouble *y,
443 const int incy, Nektar::NekDouble *z,
444 const int incz);
445template LIB_UTILITIES_EXPORT void Vsub(int n, const Nektar::NekSingle *x,
446 const int incx,
447 const Nektar::NekSingle *y,
448 const int incy, Nektar::NekSingle *z,
449 const int incz);
450
451/// \brief Substract vector y = alpha - x
452template <class T>
453void Ssub(int n, const T alpha, const T *x, const int incx, T *y,
454 const int incy)
455{
456 ++n;
457 if (incx == 1 && incy == 1)
458 {
459 while (--n)
460 {
461 *y = alpha - (*x);
462 ++x;
463 ++y;
464 }
465 }
466 else
467 {
468 while (--n)
469 {
470 *y = alpha - (*x);
471 x += incx;
472 y += incy;
473 }
474 }
475}
476
477template LIB_UTILITIES_EXPORT void Ssub(int n, const Nektar::NekDouble alpha,
478 const Nektar::NekDouble *x,
479 const int incx, Nektar::NekDouble *y,
480 const int incy);
481template LIB_UTILITIES_EXPORT void Ssub(int n, const Nektar::NekSingle alpha,
482 const Nektar::NekSingle *x,
483 const int incx, Nektar::NekSingle *y,
484 const int incy);
485
486/// \brief Zero vector
487template <class T> void Zero(int n, T *x, const int incx)
488{
489 if (incx == 1)
490 {
491 std::memset(x, '\0', n * sizeof(T));
492 }
493 else
494 {
495 T zero = 0;
496 ++n;
497 while (--n)
498 {
499 *x = zero;
500 x += incx;
501 }
502 }
503}
504
506 const int incx);
508 const int incx);
509template LIB_UTILITIES_EXPORT void Zero(int n, int *x, const int incx);
510template LIB_UTILITIES_EXPORT void Zero(int n, long *x, const int incx);
511
512/// \brief Negate x = -x
513template <class T> void Neg(int n, T *x, const int incx)
514{
515 while (n--)
516 {
517 *x = -(*x);
518 x += incx;
519 }
520}
521
523 const int incx);
525 const int incx);
526
527/// \brief sqrt y = sqrt(x)
528template <class T>
529void Vsqrt(int n, const T *x, const int incx, T *y, const int incy)
530{
531 while (n--)
532 {
533 *y = sqrt(*x);
534 x += incx;
535 y += incy;
536 }
537}
538
539template LIB_UTILITIES_EXPORT void Vsqrt(int n, const Nektar::NekDouble *x,
540 const int incx, Nektar::NekDouble *y,
541 const int incy);
542template LIB_UTILITIES_EXPORT void Vsqrt(int n, const Nektar::NekSingle *x,
543 const int incx, Nektar::NekSingle *y,
544 const int incy);
545
546/// \brief vabs: y = |x|
547template <class T>
548void Vabs(int n, const T *x, const int incx, T *y, const int incy)
549{
550 while (n--)
551 {
552 *y = (*x > 0) ? *x : -(*x);
553 x += incx;
554 y += incy;
555 }
556}
557
558template LIB_UTILITIES_EXPORT void Vabs(int n, const Nektar::NekDouble *x,
559 const int incx, Nektar::NekDouble *y,
560 const int incy);
561template LIB_UTILITIES_EXPORT void Vabs(int n, const Nektar::NekSingle *x,
562 const int incx, Nektar::NekSingle *y,
563 const int incy);
564
565/********** Triad routines ***********************/
566
567/// \brief vvtvp (vector times vector plus vector): z = w*x + y
568template <class T>
569void Vvtvp(int n, const T *w, const int incw, const T *x, const int incx,
570 const T *y, const int incy, T *z, const int incz)
571{
572 while (n--)
573 {
574 *z = (*w) * (*x) + (*y);
575 w += incw;
576 x += incx;
577 y += incy;
578 z += incz;
579 }
580}
581
583 int n, const Nektar::NekDouble *w, const int incw,
584 const Nektar::NekDouble *x, const int incx, const Nektar::NekDouble *y,
585 const int incy, Nektar::NekDouble *z, const int incz);
587 int n, const Nektar::NekSingle *w, const int incw,
588 const Nektar::NekSingle *x, const int incx, const Nektar::NekSingle *y,
589 const int incy, Nektar::NekSingle *z, const int incz);
590
591/// \brief vvtvm (vector times vector minus vector): z = w*x - y
592template <class T>
593void Vvtvm(int n, const T *w, const int incw, const T *x, const int incx,
594 const T *y, const int incy, T *z, const int incz)
595{
596 while (n--)
597 {
598 *z = (*w) * (*x) - (*y);
599 w += incw;
600 x += incx;
601 y += incy;
602 z += incz;
603 }
604}
605
607 int n, const Nektar::NekDouble *w, const int incw,
608 const Nektar::NekDouble *x, const int incx, const Nektar::NekDouble *y,
609 const int incy, Nektar::NekDouble *z, const int incz);
611 int n, const Nektar::NekSingle *w, const int incw,
612 const Nektar::NekSingle *x, const int incx, const Nektar::NekSingle *y,
613 const int incy, Nektar::NekSingle *z, const int incz);
614
615/// \brief svtvp (scalar times vector plus vector): z = alpha*x + y
616template <class T>
617LIB_UTILITIES_EXPORT void Svtvp(int n, const T alpha, const T *x,
618 const int incx, const T *y, const int incy,
619 T *z, const int incz)
620{
621 ++n;
622 if (incx == 1 && incy == 1 && incz == 1)
623 {
624 while (--n)
625 {
626 *z = alpha * (*x) + (*y);
627 ++x;
628 ++y;
629 ++z;
630 }
631 }
632 else
633 {
634 while (--n)
635 {
636 *z = alpha * (*x) + (*y);
637 x += incx;
638 y += incy;
639 z += incz;
640 }
641 }
642}
643
644template LIB_UTILITIES_EXPORT void Svtvp(int n, const Nektar::NekDouble alpha,
645 const Nektar::NekDouble *x,
646 const int incx,
647 const Nektar::NekDouble *y,
648 const int incy, Nektar::NekDouble *z,
649 const int incz);
650template LIB_UTILITIES_EXPORT void Svtvp(int n, const Nektar::NekSingle alpha,
651 const Nektar::NekSingle *x,
652 const int incx,
653 const Nektar::NekSingle *y,
654 const int incy, Nektar::NekSingle *z,
655 const int incz);
656
657/// \brief svtvm (scalar times vector minus vector): z = alpha*x - y
658template <class T>
659void Svtvm(int n, const T alpha, const T *x, const int incx, const T *y,
660 const int incy, T *z, const int incz)
661{
662 while (n--)
663 {
664 *z = alpha * (*x) - (*y);
665 x += incx;
666 y += incy;
667 z += incz;
668 }
669}
670
671template LIB_UTILITIES_EXPORT void Svtvm(int n, const Nektar::NekDouble alpha,
672 const Nektar::NekDouble *x,
673 const int incx,
674 const Nektar::NekDouble *y,
675 const int incy, Nektar::NekDouble *z,
676 const int incz);
677template LIB_UTILITIES_EXPORT void Svtvm(int n, const Nektar::NekSingle alpha,
678 const Nektar::NekSingle *x,
679 const int incx,
680 const Nektar::NekSingle *y,
681 const int incy, Nektar::NekSingle *z,
682 const int incz);
683
684/// \brief vvtvvtp (vector times vector plus vector times vector):
685// z = v*w + x*y
686template <class T>
687void Vvtvvtp(int n, const T *v, int incv, const T *w, int incw, const T *x,
688 int incx, const T *y, int incy, T *z, int incz)
689{
690 while (n--)
691 {
692 *z = (*v) * (*w) + (*x) * (*y);
693 v += incv;
694 w += incw;
695 x += incx;
696 y += incy;
697 z += incz;
698 }
699}
700template LIB_UTILITIES_EXPORT void Vvtvvtp(int n, const Nektar::NekDouble *v,
701 int incv, const Nektar::NekDouble *w,
702 int incw, const Nektar::NekDouble *x,
703 int incx, const Nektar::NekDouble *y,
704 int incy, Nektar::NekDouble *z,
705 int incz);
706template LIB_UTILITIES_EXPORT void Vvtvvtp(int n, const Nektar::NekSingle *v,
707 int incv, const Nektar::NekSingle *w,
708 int incw, const Nektar::NekSingle *x,
709 int incx, const Nektar::NekSingle *y,
710 int incy, Nektar::NekSingle *z,
711 int incz);
712
713/// \brief vvtvvtm (vector times vector minus vector times vector):
714// z = v*w - x*y
715template <class T>
716void Vvtvvtm(int n, const T *v, int incv, const T *w, int incw, const T *x,
717 int incx, const T *y, int incy, T *z, int incz)
718{
719 while (n--)
720 {
721 *z = (*v) * (*w) - (*x) * (*y);
722 v += incv;
723 w += incw;
724 x += incx;
725 y += incy;
726 z += incz;
727 }
728}
729
730template LIB_UTILITIES_EXPORT void Vvtvvtm(int n, const Nektar::NekDouble *v,
731 int incv, const Nektar::NekDouble *w,
732 int incw, const Nektar::NekDouble *x,
733 int incx, const Nektar::NekDouble *y,
734 int incy, Nektar::NekDouble *z,
735 int incz);
736template LIB_UTILITIES_EXPORT void Vvtvvtm(int n, const Nektar::NekSingle *v,
737 int incv, const Nektar::NekSingle *w,
738 int incw, const Nektar::NekSingle *x,
739 int incx, const Nektar::NekSingle *y,
740 int incy, Nektar::NekSingle *z,
741 int incz);
742
743/// \brief svtvvtp (scalar times vector plus scalar times vector):
744// z = alpha*x + beta*y
745template <class T>
746void Svtsvtp(int n, const T alpha, const T *x, int incx, const T beta,
747 const T *y, int incy, T *z, int incz)
748{
749 while (n--)
750 {
751 *z = alpha * (*x) + beta * (*y);
752 x += incx;
753 y += incy;
754 z += incz;
755 }
756}
757
758template LIB_UTILITIES_EXPORT void Svtsvtp(int n, const Nektar::NekDouble alpha,
759 const Nektar::NekDouble *x, int incx,
761 const Nektar::NekDouble *y, int incy,
762 Nektar::NekDouble *z, int incz);
763template LIB_UTILITIES_EXPORT void Svtsvtp(int n, const Nektar::NekSingle alpha,
764 const Nektar::NekSingle *x, int incx,
766 const Nektar::NekSingle *y, int incy,
767 Nektar::NekSingle *z, int incz);
768
769/// \brief Vstvpp (scalar times vector plus vector plus vector):
770// z = alpha*w + x*y
771template <class T>
772void Vstvpp(int n, const T alpha, const T *v, int incv, const T *w, int incw,
773 const T *x, int incx, T *z, int incz)
774{
775 while (n--)
776 {
777 *z = alpha * (*v) + (*w) + (*x);
778 v += incv;
779 w += incw;
780 x += incx;
781 z += incz;
782 }
783}
784
785template LIB_UTILITIES_EXPORT void Vstvpp(int n, const Nektar::NekDouble alpha,
786 const Nektar::NekDouble *v, int incv,
787 const Nektar::NekDouble *w, int incw,
788 const Nektar::NekDouble *x, int incx,
789 Nektar::NekDouble *z, int incz);
790template LIB_UTILITIES_EXPORT void Vstvpp(int n, const Nektar::NekSingle alpha,
791 const Nektar::NekSingle *v, int incv,
792 const Nektar::NekSingle *w, int incw,
793 const Nektar::NekSingle *x, int incx,
794 Nektar::NekSingle *z, int incz);
795
796/************ Misc routine from Veclib (and extras) ************/
797
798/// \brief Gather vector z[i] = sign[i]*x[y[i]]
799template <class T>
800void Gathr(int n, const T *sign, const T *x, const int *y, T *z)
801{
802 while (n--)
803 {
804 *z++ = *(sign++) * (*(x + *y++));
805 }
806 return;
807}
808
810 const Nektar::NekDouble *x,
811 const int *y, Nektar::NekDouble *z);
813 const Nektar::NekSingle *x,
814 const int *y, Nektar::NekSingle *z);
815
816/// \brief Scatter vector z[y[i]] = x[i]
817template <class T> void Scatr(int n, const T *x, const int *y, T *z)
818{
819 while (n--)
820 {
821 *(z + *(y++)) = *(x++);
822 }
823}
824
825template LIB_UTILITIES_EXPORT void Scatr(int n, const Nektar::NekDouble *x,
826 const int *y, Nektar::NekDouble *z);
827template LIB_UTILITIES_EXPORT void Scatr(int n, const Nektar::NekSingle *x,
828 const int *y, Nektar::NekSingle *z);
829
830/// \brief Scatter vector z[y[i]] = sign[i]*x[i]
831template <class T>
832void Scatr(int n, const T *sign, const T *x, const int *y, T *z)
833{
834 while (n--)
835 {
836 if (*sign)
837 {
838 *(z + *(y++)) = *(sign++) * (*(x++));
839 }
840 else
841 {
842 x++;
843 y++;
844 sign++;
845 }
846 }
847}
848
850 const Nektar::NekDouble *x,
851 const int *y, Nektar::NekDouble *z);
853 const Nektar::NekSingle *x,
854 const int *y, Nektar::NekSingle *z);
855
856/// \brief Assemble z[y[i]] += x[i]; z should be zero'd first
857template <class T> void Assmb(int n, const T *x, const int *y, T *z)
858{
859 while (n--)
860 {
861 *(z + *(y++)) += *(x++);
862 }
863}
864
865template LIB_UTILITIES_EXPORT void Assmb(int n, const Nektar::NekDouble *x,
866 const int *y, Nektar::NekDouble *z);
867template LIB_UTILITIES_EXPORT void Assmb(int n, const Nektar::NekSingle *x,
868 const int *y, Nektar::NekSingle *z);
869
870/// \brief Assemble z[y[i]] += sign[i]*x[i]; z should be zero'd first
871template <class T>
872void Assmb(int n, const T *sign, const T *x, const int *y, T *z)
873{
874 while (n--)
875 {
876 *(z + *(y++)) += *(sign++) * (*(x++));
877 }
878}
879
881 const Nektar::NekDouble *x,
882 const int *y, Nektar::NekDouble *z);
884 const Nektar::NekSingle *x,
885 const int *y, Nektar::NekSingle *z);
886
887/************* Reduction routines *****************/
888
889/// \brief Subtract return sum(x)
890template <class T> T Vsum(int n, const T *x, const int incx)
891{
892
893 T sum = 0;
894
895 while (n--)
896 {
897 sum += (*x);
898 x += incx;
899 }
900
901 return sum;
902}
903
905 const Nektar::NekDouble *x,
906 const int incx);
908 const Nektar::NekSingle *x,
909 const int incx);
910template LIB_UTILITIES_EXPORT int Vsum(int n, const int *x, const int incx);
911
912/// \brief Return the index of the maximum element in x
913template <class T> int Imax(int n, const T *x, const int incx)
914{
915
916 int i, indx = (n > 0) ? 0 : -1;
917 T xmax = *x;
918
919 for (i = 0; i < n; i++)
920 {
921 if (*x > xmax)
922 {
923 xmax = *x;
924 indx = i;
925 }
926 x += incx;
927 }
928
929 return indx;
930}
931
932template LIB_UTILITIES_EXPORT int Imax(int n, const Nektar::NekDouble *x,
933 const int incx);
934template LIB_UTILITIES_EXPORT int Imax(int n, const Nektar::NekSingle *x,
935 const int incx);
936template LIB_UTILITIES_EXPORT int Imax(int n, const int *x, const int incx);
937
938/// \brief Return the maximum element in x -- called vmax to avoid
939/// conflict with max
940template <class T> T Vmax(int n, const T *x, const int incx)
941{
942
943 T xmax = *x;
944
945 while (n--)
946 {
947 if (*x > xmax)
948 {
949 xmax = *x;
950 }
951 x += incx;
952 }
953
954 return xmax;
955}
956
958 const Nektar::NekDouble *x,
959 const int incx);
961 const Nektar::NekSingle *x,
962 const int incx);
963template LIB_UTILITIES_EXPORT int Vmax(int n, const int *x, const int incx);
964
965/// \brief Return the index of the maximum absolute element in x
966template <class T> int Iamax(int n, const T *x, const int incx)
967{
968
969 int i, indx = (n > 0) ? 0 : -1;
970 T xmax = *x;
971 T xm;
972
973 for (i = 0; i < n; i++)
974 {
975 xm = (*x > 0) ? *x : -*x;
976 if (xm > xmax)
977 {
978 xmax = xm;
979 indx = i;
980 }
981 x += incx;
982 }
983
984 return indx;
985}
986
987template LIB_UTILITIES_EXPORT int Iamax(int n, const Nektar::NekDouble *x,
988 const int incx);
989template LIB_UTILITIES_EXPORT int Iamax(int n, const Nektar::NekSingle *x,
990 const int incx);
991
992/// \brief Return the maximum absolute element in x
993/// called vamax to avoid conflict with max
994template <class T> T Vamax(int n, const T *x, const int incx)
995{
996
997 T xmax = *x;
998 T xm;
999
1000 while (n--)
1001 {
1002 xm = (*x > 0) ? *x : -*x;
1003 if (xm > xmax)
1004 {
1005 xmax = xm;
1006 }
1007 x += incx;
1008 }
1009 return xmax;
1010}
1011
1013 int n, const Nektar::NekDouble *x, const int incx);
1015 int n, const Nektar::NekSingle *x, const int incx);
1016
1017/// \brief Return the index of the minimum element in x
1018template <class T> int Imin(int n, const T *x, const int incx)
1019{
1020
1021 int i, indx = (n > 0) ? 0 : -1;
1022 T xmin = *x;
1023
1024 for (i = 0; i < n; i++)
1025 {
1026 if (*x < xmin)
1027 {
1028 xmin = *x;
1029 indx = i;
1030 }
1031 x += incx;
1032 }
1033
1034 return indx;
1035}
1036
1037template LIB_UTILITIES_EXPORT int Imin(int n, const Nektar::NekDouble *x,
1038 const int incx);
1039template LIB_UTILITIES_EXPORT int Imin(int n, const Nektar::NekSingle *x,
1040 const int incx);
1041template LIB_UTILITIES_EXPORT int Imin(int n, const int *x, const int incx);
1042
1043/// \brief Return the minimum element in x - called vmin to avoid
1044/// conflict with min
1045template <class T> T Vmin(int n, const T *x, const int incx)
1046{
1047
1048 T xmin = *x;
1049
1050 while (n--)
1051 {
1052 if (*x < xmin)
1053 {
1054 xmin = *x;
1055 }
1056 x += incx;
1057 }
1058
1059 return xmin;
1060}
1061
1063 const Nektar::NekDouble *x,
1064 const int incx);
1066 const Nektar::NekSingle *x,
1067 const int incx);
1068template LIB_UTILITIES_EXPORT int Vmin(int n, const int *x, const int incx);
1069
1070/// \brief Return number of NaN elements of x
1071template <class T> int Nnan(int n, const T *x, const int incx)
1072{
1073
1074 int nNan = 0;
1075
1076 while (n--)
1077 {
1078 if (*x != *x)
1079 {
1080 nNan++;
1081 }
1082 x += incx;
1083 }
1084
1085 return nNan;
1086}
1087
1088template LIB_UTILITIES_EXPORT int Nnan(int n, const Nektar::NekDouble *x,
1089 const int incx);
1090template LIB_UTILITIES_EXPORT int Nnan(int n, const Nektar::NekSingle *x,
1091 const int incx);
1092template LIB_UTILITIES_EXPORT int Nnan(int n, const int *x, const int incx);
1093
1094/// \brief dot (vector times vector): z = w*x
1095template <class T> T Dot(int n, const T *w, const T *x)
1096{
1097 T sum = 0;
1098
1099 while (n--)
1100 {
1101 sum += (*w) * (*x);
1102 ++w;
1103 ++x;
1104 }
1105 return sum;
1106}
1107
1109 const Nektar::NekDouble *w,
1110 const Nektar::NekDouble *x);
1112 const Nektar::NekSingle *w,
1113 const Nektar::NekSingle *x);
1114
1115/// \brief dot (vector times vector): z = w*x
1116template <class T>
1117T Dot(int n, const T *w, const int incw, const T *x, const int incx)
1118{
1119 T sum = 0;
1120
1121 while (n--)
1122 {
1123 sum += (*w) * (*x);
1124 w += incw;
1125 x += incx;
1126 }
1127 return sum;
1128}
1129
1131 const Nektar::NekDouble *w,
1132 const int incw,
1133 const Nektar::NekDouble *x,
1134 const int incx);
1136 const Nektar::NekSingle *w,
1137 const int incw,
1138 const Nektar::NekSingle *x,
1139 const int incx);
1140
1141/// \brief dot2 (vector times vector times vector): z = w*x*y
1142template <class T> T Dot2(int n, const T *w, const T *x, const int *y)
1143{
1144 T sum = 0;
1145
1146 while (n--)
1147 {
1148 sum += (*y == 1 ? (*w) * (*x) : 0);
1149 ++w;
1150 ++x;
1151 ++y;
1152 }
1153 return sum;
1154}
1155
1157 const Nektar::NekDouble *w,
1158 const Nektar::NekDouble *x,
1159 const int *y);
1161 const Nektar::NekSingle *w,
1162 const Nektar::NekSingle *x,
1163 const int *y);
1164
1165/// \brief dot2 (vector times vector times vector): z = w*x*y
1166template <class T>
1167T Dot2(int n, const T *w, const int incw, const T *x, const int incx,
1168 const int *y, const int incy)
1169{
1170 T sum = 0;
1171
1172 while (n--)
1173 {
1174 sum += (*y == 1 ? (*w) * (*x) : 0.0);
1175 w += incw;
1176 x += incx;
1177 y += incy;
1178 }
1179 return sum;
1180}
1181
1183 int n, const Nektar::NekDouble *w, const int incw,
1184 const Nektar::NekDouble *x, const int incx, const int *y, const int incy);
1186 int n, const Nektar::NekSingle *w, const int incw,
1187 const Nektar::NekSingle *x, const int incx, const int *y, const int incy);
1188
1189// \brief copy one vector to another
1190template <typename T>
1191void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
1192{
1193 if (incx == 1 && incy == 1)
1194 {
1195 memcpy(y, x, n * sizeof(T));
1196 }
1197 else
1198 {
1199 while (n--)
1200 {
1201 *y = *x;
1202 x += incx;
1203 y += incy;
1204 }
1205 }
1206}
1207
1208template LIB_UTILITIES_EXPORT void Vcopy(int n, const int *x, const int incx,
1209 int *y, const int incy);
1210template LIB_UTILITIES_EXPORT void Vcopy(int n, const unsigned int *x,
1211 const int incx, unsigned int *y,
1212 const int incy);
1213template LIB_UTILITIES_EXPORT void Vcopy(int n, const Nektar::NekDouble *x,
1214 const int incx, Nektar::NekDouble *y,
1215 const int incy);
1216template LIB_UTILITIES_EXPORT void Vcopy(int n, const Nektar::NekSingle *x,
1217 const int incx, Nektar::NekSingle *y,
1218 const int incy);
1219
1220// \brief reverse the ordering of vector to another
1221template <class T>
1222void Reverse(int n, const T *x, const int incx, T *y, const int incy)
1223{
1224 int i;
1225 T store;
1226
1227 // Perform element by element swaps in case x and y reference the same
1228 // array.
1229 int nloop = n / 2;
1230
1231 // copy value in case of n is odd number
1232 y[nloop] = x[nloop];
1233
1234 const T *x_end = x + (n - 1) * incx;
1235 T *y_end = y + (n - 1) * incy;
1236 for (i = 0; i < nloop; ++i)
1237 {
1238 store = *x_end;
1239 *y_end = *x;
1240 *y = store;
1241 x += incx;
1242 y += incy;
1243 x_end -= incx;
1244 y_end -= incy;
1245 }
1246}
1247
1248template LIB_UTILITIES_EXPORT void Reverse(int n, const Nektar::NekDouble *x,
1249 const int incx, Nektar::NekDouble *y,
1250 const int incy);
1251template LIB_UTILITIES_EXPORT void Reverse(int n, const Nektar::NekSingle *x,
1252 const int incx, Nektar::NekSingle *y,
1253 const int incy);
1254} // namespace Vmath
#define LIB_UTILITIES_EXPORT
#define sign(a, b)
return the sign(b)*a
Definition: Polylib.cpp:49
#define NTAB
Definition: Vmath.cpp:67
#define IA2
Definition: Vmath.cpp:62
#define IR2
Definition: Vmath.cpp:66
#define NDIV
Definition: Vmath.cpp:68
#define IA1
Definition: Vmath.cpp:61
#define IM1
Definition: Vmath.cpp:57
#define IR1
Definition: Vmath.cpp:65
#define IMM1
Definition: Vmath.cpp:60
#define IQ1
Definition: Vmath.cpp:63
#define RNMX
Definition: Vmath.cpp:70
#define IQ2
Definition: Vmath.cpp:64
#define AM
Definition: Vmath.cpp:59
#define IM2
Definition: Vmath.cpp:58
@ beta
Gauss Radau pinned at x=-1,.
Definition: PointsType.h:61
std::vector< double > w(NPUPPER)
std::vector< double > z(NPUPPER)
double NekDouble
Definition: Vmath.cpp:38
void Vsqrt(int n, const T *x, const int incx, T *y, const int incy)
sqrt y = sqrt(x)
Definition: Vmath.cpp:529
void Ssub(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Substract vector y = alpha - x.
Definition: Vmath.cpp:453
void Svtsvtp(int n, const T alpha, const T *x, int incx, const T beta, const T *y, int incy, T *z, int incz)
svtvvtp (scalar times vector plus scalar times vector):
Definition: Vmath.cpp:746
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
Definition: Vmath.cpp:207
void Svtvp(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
svtvp (scalar times vector plus vector): z = alpha*x + y
Definition: Vmath.cpp:617
void Vabs(int n, const T *x, const int incx, T *y, const int incy)
vabs: y = |x|
Definition: Vmath.cpp:548
T Dot2(int n, const T *w, const T *x, const int *y)
dot2 (vector times vector times vector): z = w*x*y
Definition: Vmath.cpp:1142
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition: Vmath.cpp:513
T Vmin(int n, const T *x, const int incx)
Return the minimum element in x - called vmin to avoid conflict with min.
Definition: Vmath.cpp:1045
void Vvtvp(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvp (vector times vector plus vector): z = w*x + y
Definition: Vmath.cpp:569
T Vsum(int n, const T *x, const int incx)
Subtract return sum(x)
Definition: Vmath.cpp:890
void Scatr(int n, const T *x, const int *y, T *z)
Scatter vector z[y[i]] = x[i].
Definition: Vmath.cpp:817
T Dot(int n, const T *w, const T *x)
dot (vector times vector): z = w*x
Definition: Vmath.cpp:1095
void Gathr(int n, const T *sign, const T *x, const int *y, T *z)
Gather vector z[i] = sign[i]*x[y[i]].
Definition: Vmath.cpp:800
void Assmb(int n, const T *x, const int *y, T *z)
Assemble z[y[i]] += x[i]; z should be zero'd first.
Definition: Vmath.cpp:857
void Svtvm(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
svtvm (scalar times vector minus vector): z = alpha*x - y
Definition: Vmath.cpp:659
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
Definition: Vmath.cpp:354
void Vvtvm(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvm (vector times vector minus vector): z = w*x - y
Definition: Vmath.cpp:593
void Vvtvvtm(int n, const T *v, int incv, const T *w, int incw, const T *x, int incx, const T *y, int incy, T *z, int incz)
vvtvvtm (vector times vector minus vector times vector):
Definition: Vmath.cpp:716
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
Definition: Vmath.cpp:245
void Sdiv(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha/x.
Definition: Vmath.cpp:319
int Imax(int n, const T *x, const int incx)
Return the index of the maximum element in x.
Definition: Vmath.cpp:913
void Vdiv(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x/y.
Definition: Vmath.cpp:280
int Imin(int n, const T *x, const int incx)
Return the index of the minimum element in x.
Definition: Vmath.cpp:1018
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:487
void Fill(int n, const T alpha, T *x, const int incx)
Fill a vector with a constant value.
Definition: Vmath.cpp:43
T ran2(long *idum)
Generates a number from ~Normal(0,1)
Definition: Vmath.cpp:73
void Vstvpp(int n, const T alpha, const T *v, int incv, const T *w, int incw, const T *x, int incx, T *z, int incz)
Vstvpp (scalar times vector plus vector plus vector):
Definition: Vmath.cpp:772
void FillWhiteNoise(int n, const T eps, T *x, const int incx, int outseed)
Fills a vector with white noise.
Definition: Vmath.cpp:153
int Nnan(int n, const T *x, const int incx)
Return number of NaN elements of x.
Definition: Vmath.cpp:1071
T Vamax(int n, const T *x, const int incx)
Return the maximum absolute element in x called vamax to avoid conflict with max.
Definition: Vmath.cpp:994
void Sadd(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Add scalar y = alpha + x.
Definition: Vmath.cpp:379
void Reverse(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1222
T Vmax(int n, const T *x, const int incx)
Return the maximum element in x – called vmax to avoid conflict with max.
Definition: Vmath.cpp:940
void Vvtvvtp(int n, const T *v, int incv, const T *w, int incw, const T *x, int incx, const T *y, int incy, T *z, int incz)
vvtvvtp (vector times vector plus vector times vector):
Definition: Vmath.cpp:687
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1191
void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Subtract vector z = x-y.
Definition: Vmath.cpp:414
int Iamax(int n, const T *x, const int incx)
Return the index of the maximum absolute element in x.
Definition: Vmath.cpp:966
scalarT< T > log(scalarT< T > in)
Definition: scalar.hpp:303
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294