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