Free Electron
VectorNf_gnu.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #if FE_VDIM<3 || FE_VDIM>4
8 #error Full SIMD Vector specialization only implemented in 3 or 4 dimensions
9 #endif
10 
11 #ifndef _MM_SHUFFLE
12 #define _MM_SHUFFLE(fp3,fp2,fp1,fp0) \
13  (((fp3) << 6) | ((fp2) << 4) | ((fp1) << 2) | (fp0))
14 #endif
15 
16 namespace fe
17 {
18 
19 //* NOTE FE_VDIM is a #define, not a real template parameter
20 
21 /**************************************************************************//**
22  @brief Fully specialized 3 or 4 component F32 vector using GNU SIMD
23 
24  @ingroup math
25 *//***************************************************************************/
26 template<>
27 class Vector<FE_VDIM,F32>
28 {
29  public:
30 
31  class Raw
32  {
33  public:
34  Raw(const Vector<FE_VDIM,F32>& vector)
35  {
36  m_array[0]=vector[0];
37  m_array[1]=vector[1];
38  m_array[2]=vector[2];
39 #if FE_VDIM>3
40  m_array[3]=vector[3];
41 #else
42  m_array[3]=0.0f;
43 #endif
44  }
45 
46  operator const F32*(void) const
47  { return m_array; }
48 
49  private:
50  F32 m_array[4];
51  };
52 
53  Vector(void)
54  {
55  v4sf_assertAlignment(m_simd);
56 
57 #if FE_VEC_CHECK_VALID
58  set4(0.0f,0.0f,0.0f,0.0f);
59 #endif
60  }
61  template<int N,typename T>
62  Vector(const Vector<N,T>& other)
63  { operator=(other); }
64  Vector(const Vector<FE_VDIM,F32>& other)
65  { operator=(other); }
66  Vector(const F32* array)
67  { operator=(array); }
68  template<typename T, typename U>
69  Vector(T x,U y)
70  { set4(x,y,0.0f,0.0f); }
71  template<typename T, typename U, typename V>
72  Vector(T x,U y,V z)
73  { set4(x,y,z,0.0f); }
74  template<typename T, typename U, typename V, typename W>
75  Vector(T x,U y,V z,W w)
76  { set4(x,y,z,w); }
77 
78  Vector<FE_VDIM,F32>& operator=(const F32* array);
79  template<typename T>
80  Vector<FE_VDIM,F32>& operator=(const Vector<3,T>& other);
81  template<typename T>
82  Vector<FE_VDIM,F32>& operator=(const Vector<2,T>& other);
83  template<typename T>
84  Vector<FE_VDIM,F32>& operator=(const Vector<1,T>& other);
85  template<int N,typename T>
86  Vector<FE_VDIM,F32>& operator=(const Vector<N,T>& other);
87  Vector<FE_VDIM,F32>& operator=(const Vector<FE_VDIM,F32>& other);
88 
89  BWORD operator==(const Vector<FE_VDIM,F32>& other);
90  BWORD operator!=(const Vector<FE_VDIM,F32>& other);
91 
92  F32 operator[](U32 index) const
93  {
94  FEASSERT(index<4);
95  checkValid();
96  return m_data[index];
97  }
98 
99  /** @brief Access internal component
100 
101  Warning, this provides internal access and should
102  be limited to immediate use only. */
103  F32& operator[](U32 index)
104  {
105  FEASSERT(index<4);
106  return m_data[index];
107  }
108 
109  template<typename T, typename U, typename V, typename W>
110  Vector<FE_VDIM,F32>& set4(T x,U y,V z,W w);
111 
112  template<typename T>
113  void get4(T array[4]);
114 
115 const Raw temp(void) const { return *this; }
116 
117  /// @internal
118 const v4sf& simd(void) const { return m_simd; }
119 
120  /// @internal
121  v4sf& simd(void) { return m_simd; }
122 
123  /// @internal
124  void checkValid(void) const
125  {
126 #if FE_VEC_CHECK_VALID
127  if(FE_INVALID_SCALAR(m_data[0]))
128  feX(e_corrupt,"Vector<N,F32>::checkValid",
129  "element 0 invalid");
130  if(FE_INVALID_SCALAR(m_data[1]))
131  feX(e_corrupt,"Vector<N,F32>::checkValid",
132  "element 1 invalid");
133  if(FE_INVALID_SCALAR(m_data[2]))
134  feX(e_corrupt,"Vector<N,F32>::checkValid",
135  "element 2 invalid");
136 #if FE_VDIM>3
137  if(FE_INVALID_SCALAR(m_data[3]))
138  feX(e_corrupt,"Vector<4,F32>::checkValid",
139  "element 3 invalid");
140 #else
141  if(m_data[3]!=0.0f)
142  feX(e_corrupt,"Vector<3,F32>::checkValid",
143  "element 3 nonzero");
144 #endif
145 #endif
146  }
147 
148  protected:
149 /*
150 const F32* data(void) const
151  { return reinterpret_cast<const F32*>(&m_simd); }
152  F32* data(void)
153  { return reinterpret_cast<F32*>(&m_simd); }
154 */
155 
156  union
157  {
158  v4sf m_simd;
159  float m_data[4];
160  };
161 };
162 
163 /** Return text describing the Vector's state
164  @relates Vector<4,F32>
165  */
166 inline String print(const Vector<FE_VDIM,F32> &rhs)
167 {
168  v4sf_assertAlignment(rhs.simd());
169  rhs.checkValid();
170 
171  String s;
172 #if FE_VDIM>3
173  s.sPrintf("[%g %g %g %g]",rhs[0],rhs[1],rhs[2],rhs[3]);
174 #else
175  s.sPrintf("[%g %g %g]",rhs[0],rhs[1],rhs[2]);
176 #endif
177  return s;
178 }
179 
180 template<typename T>
182  const Vector<3,T>& other)
183 {
184  v4sf_assertAlignment(m_simd);
185  return set4(other[0],other[1],other[2],0.0f);
186 }
187 
188 template<typename T>
190  const Vector<2,T>& other)
191 {
192  v4sf_assertAlignment(m_simd);
193  return set4(other[0],other[1],0.0f,0.0f);
194 }
195 
196 template<typename T>
198  const Vector<1,T>& other)
199 {
200  v4sf_assertAlignment(m_simd);
201  return set4(other[0],0.0f,0.0f,0.0f);
202 }
203 
204 template<int N,typename T>
206  const Vector<N,T>& other)
207 {
208  v4sf_assertAlignment(m_simd);
209  return set4(other[0],other[1],other[2],other[3]);
210 }
211 
213  const Vector<FE_VDIM,F32>& other)
214 {
215  v4sf_assertAlignment(m_simd);
216  v4sf_assertAlignment(other.m_simd);
217  other.checkValid();
218 
219  m_simd=other.m_simd;
220  checkValid();
221  return *this;
222 }
223 
224 inline Vector<FE_VDIM,F32>& Vector<FE_VDIM,F32>::operator=(const F32* array)
225 {
226  v4sf_assertAlignment(m_simd);
227 
228 // memcpy(&m_simd,array,sizeof(m_simd));
229  m_simd= __builtin_ia32_loadups(array);
230 
231 #if FE_VDIM<4
232  m_data[3]=0.0f;
233 #endif
234  checkValid();
235  return *this;
236 }
237 
238 inline BWORD Vector<FE_VDIM,F32>::operator==(const Vector<FE_VDIM,F32>& other)
239 {
240  if(this!=&other)
241  {
242  for(U32 i=0;i<FE_VDIM;i++)
243  {
244  if(m_data[i]!=other[i])
245  {
246  return false;
247  }
248  }
249  }
250  return true;
251 }
252 
253 inline BWORD Vector<FE_VDIM,F32>::operator!=(const Vector<FE_VDIM,F32>& other)
254 {
255  return !operator==(other);
256 }
257 
258 template<typename T, typename U, typename V, typename W>
259 inline Vector<FE_VDIM,F32>& Vector<FE_VDIM,F32>::set4(T x,U y,V z,W w)
260 {
261  v4sf_assertAlignment(m_simd);
262 
263  m_data[0]=x;
264  m_data[1]=y;
265  m_data[2]=z;
266 #if FE_VDIM>3
267  m_data[3]=w;
268 #else
269  m_data[3]=0.0f;
270 #endif
271  checkValid();
272  return *this;
273 }
274 
275 template<typename T>
276 inline void Vector<FE_VDIM,F32>::get4(T array[4])
277 {
278  v4sf_assertAlignment(m_simd);
279  checkValid();
280 
281  array[0]=m_data[0];
282  array[1]=m_data[1];
283  array[2]=m_data[2];
284  array[3]=m_data[3];
285 }
286 
287 /** Set components
288  @relates Vector<4,F32>
289  */
291 {
292  v4sf_assertAlignment(r.simd());
293 
294  r.set4(0.0f,0.0f,0.0f,0.0f);
295  r.checkValid();
296  return r;
297 }
298 
299 /** Set components
300  @relates Vector<4,F32>
301  */
302 template<typename T>
304 {
305  v4sf_assertAlignment(r.simd());
306 
307  r.set4(x,0.0f,0.0f,0.0f);
308  r.checkValid();
309  return r;
310 }
311 
312 /** Set components
313  @relates Vector<4,F32>
314  */
315 template<typename T, typename U>
317 {
318  v4sf_assertAlignment(r.simd());
319 
320  r.set4(x,y,0.0f,0.0f);
321  r.checkValid();
322  return r;
323 }
324 
325 /** Set components
326  @relates Vector<4,F32>
327  */
328 template<typename T, typename U, typename V>
329 inline Vector<FE_VDIM,F32> &set(Vector<FE_VDIM,F32> &r,T x,U y,V z)
330 {
331  v4sf_assertAlignment(r.simd());
332 
333  r.set4(x,y,z,0.0f);
334  r.checkValid();
335  return r;
336 }
337 
338 /** Set components
339  @relates Vector<4,F32>
340  */
341 template<typename T, typename U, typename V, typename W>
342 inline Vector<FE_VDIM,F32> &set(Vector<FE_VDIM,F32> &r,T x,U y,V z,W w)
343 {
344  v4sf_assertAlignment(r.simd());
345 
346  r.set4(x,y,z,w);
347  r.checkValid();
348  return r;
349 }
350 
351 /** Set all components to the same value
352  @relates Vector<4,F32>
353  */
354 template<typename T>
356 {
357  v4sf_assertAlignment(lhs.simd());
358 
359  lhs.set4(value,value,value,value);
360  lhs.checkValid();
361  return lhs;
362 }
363 
364 /** Set indexed component
365  @relates Vector<4,F32>
366  */
367 template<typename T>
368 inline Vector<FE_VDIM,F32> &setAt(Vector<FE_VDIM,F32> &lhs,U32 index,T value)
369 {
370  v4sf_assertAlignment(lhs.simd());
371  lhs[index]=value;
372  lhs.checkValid();
373  return lhs;
374 }
375 
376 /** Return the number of elements
377  @relates Vector<4,F32>
378  */
379 template<typename T>
380 inline U32 size(const Vector<FE_VDIM,F32> &lhs)
381 {
382  return FE_VDIM;
383 }
384 
385 /** Add to Vector in place
386  @relates Vector<4,F32>
387  */
389  const Vector<FE_VDIM,F32> &rhs)
390 {
391  v4sf_assertAlignment(lhs.simd());
392  v4sf_assertAlignment(rhs.simd());
393  lhs.checkValid();
394  rhs.checkValid();
395 
396  lhs.simd()=__builtin_ia32_addps(lhs.simd(),rhs.simd());
397  lhs.checkValid();
398  return lhs;
399 }
400 
401 /** Subtract from Vector in place
402  @relates Vector<4,F32>
403  */
405  const Vector<FE_VDIM,F32> &rhs)
406 {
407  v4sf_assertAlignment(lhs.simd());
408  v4sf_assertAlignment(rhs.simd());
409  lhs.checkValid();
410  rhs.checkValid();
411 
412  lhs.simd()=__builtin_ia32_subps(lhs.simd(),rhs.simd());
413  lhs.checkValid();
414  return lhs;
415 }
416 
417 /** Negate the Vector
418  @relates Vector<4,F32>
419  */
421 {
422  v4sf_assertAlignment(rhs.simd());
423  rhs.checkValid();
424 
426 #if FALSE
427  v4sf zero=__builtin_ia32_setzerops();
428 #else
429  v4sf zero;
430  v4sf_setSame(zero,0.0f);
431 #endif
432  v.simd()=__builtin_ia32_subps(zero,rhs.simd());
433  v.checkValid();
434  return v;
435 }
436 
437 /** Independently scale components in place
438  @relates Vector<4,F32>
439  */
441  const Vector<FE_VDIM,F32> &rhs)
442 {
443  v4sf_assertAlignment(lhs.simd());
444  v4sf_assertAlignment(rhs.simd());
445  lhs.checkValid();
446  rhs.checkValid();
447 
448  lhs.simd()=__builtin_ia32_mulps(lhs.simd(),rhs.simd());
449  lhs.checkValid();
450  return lhs;
451 }
452 
453 /** Uniformly scale components in place
454  @relates Vector<4,F32>
455  */
456 template<typename T>
458 {
459  v4sf_assertAlignment(lhs.simd());
460  lhs.checkValid();
461 
462  v4sf scale;
463  v4sf_setSame(scale,rhs);
464  lhs.simd()=__builtin_ia32_mulps(scale,lhs.simd());
465  lhs.checkValid();
466  return lhs;
467 }
468 
469 /** Return dot product
470  @relates Vector<4,F32>
471  */
472 inline F32 dot(const Vector<FE_VDIM,F32> &lhs,const Vector<FE_VDIM,F32> &rhs)
473 {
474  v4sf_assertAlignment(lhs.simd());
475  v4sf_assertAlignment(rhs.simd());
476  lhs.checkValid();
477  rhs.checkValid();
478 
479 // v4sf_log("lhs",lhs.simd());
480 // v4sf_log("rhs",rhs.simd());
481  v4sf combine=__builtin_ia32_mulps(lhs.simd(),rhs.simd());
482 #if FE_SSE<3
483 // v4sf_log("combine",combine);
484 // v4sf shift=__builtin_ia32_shufps(combine,combine,0x4E);
485  v4sf shift=__builtin_ia32_shufps(combine,combine,_MM_SHUFFLE(1,0,3,2));
486 // v4sf_log("shift",shift);
487  combine=__builtin_ia32_addps(combine,shift);
488 // v4sf_log("combine",combine);
489 // shift=__builtin_ia32_shufps(combine,combine,0x39);
490  shift=__builtin_ia32_shufps(combine,combine,_MM_SHUFFLE(0,3,2,1));
491 // v4sf_log("shift",shift);
492  combine=__builtin_ia32_addps(combine,shift);
493 // v4sf_log("combine",combine);
494 #else
495  combine=__builtin_ia32_haddps(combine,combine);
496  combine=__builtin_ia32_haddps(combine,combine);
497 #endif
498  return reinterpret_cast<F32*>(&combine)[0];
499 }
500 
501 /** Return square of the Vector length
502  @relates Vector<4,F32>
503  */
504 inline F32 magnitudeSquared(const Vector<FE_VDIM,F32> &rhs)
505 {
506  v4sf_assertAlignment(rhs.simd());
507  rhs.checkValid();
508 
509  return dot(rhs,rhs);
510 }
511 
512 /** Return the Vector length
513  @relates Vector<4,F32>
514  */
515 inline F32 magnitude(const Vector<FE_VDIM,F32> &rhs)
516 {
517  v4sf_assertAlignment(rhs.simd());
518  rhs.checkValid();
519 
520  return sqrtf(magnitudeSquared(rhs));
521 }
522 
523 /** Return sum of Vectors
524  @relates Vector<4,F32>
525  */
527  const Vector<FE_VDIM,F32> &rhs)
528 {
529  v4sf_assertAlignment(lhs.simd());
530  v4sf_assertAlignment(rhs.simd());
531  lhs.checkValid();
532  rhs.checkValid();
533 
535  v.simd()=__builtin_ia32_addps(lhs.simd(),rhs.simd());
536  v.checkValid();
537  return v;
538 }
539 
540 /** Return difference of Vectors
541  @relates Vector<4,F32>
542  */
544  const Vector<FE_VDIM,F32> &rhs)
545 {
546  v4sf_assertAlignment(lhs.simd());
547  v4sf_assertAlignment(rhs.simd());
548  lhs.checkValid();
549  rhs.checkValid();
550 
552  v.simd()=__builtin_ia32_subps(lhs.simd(),rhs.simd());
553  v.checkValid();
554  return v;
555 }
556 
557 /** Return a Vector of products of each component
558  @relates Vector<4,F32>
559  */
561  const Vector<FE_VDIM,F32> &rhs)
562 {
563  v4sf_assertAlignment(lhs.simd());
564  v4sf_assertAlignment(rhs.simd());
565  lhs.checkValid();
566  rhs.checkValid();
567 
569  v.simd()=__builtin_ia32_mulps(lhs.simd(),rhs.simd());
570  v.checkValid();
571  return v;
572 }
573 
574 /** Return a uniformly scaled Vector (pre)
575  @relates Vector<4,F32>
576  */
577 template <typename T>
578 inline
579 typename boost::enable_if<boost::is_arithmetic<T>,Vector<FE_VDIM,F32> >::type
580 operator*(const T lhs,const Vector<FE_VDIM,F32> &rhs)
581 {
582  v4sf_assertAlignment(rhs.simd());
583  rhs.checkValid();
584 
586  v4sf scale;
587  v4sf_setSame(scale,lhs);
588  v.simd()=__builtin_ia32_mulps(scale,rhs.simd());
589  v.checkValid();
590  return v;
591 }
592 
593 /** Return a uniformly scaled Vector (post)
594  @relates Vector<4,F32>
595  */
596 template<typename T>
597 inline
598 typename boost::enable_if<boost::is_arithmetic<T>,Vector<FE_VDIM,F32> >::type
599 operator*(const Vector<FE_VDIM,F32> &lhs,const T rhs)
600 {
601  v4sf_assertAlignment(lhs.simd());
602  lhs.checkValid();
603 
605  v4sf scale;
606  v4sf_setSame(scale,F32(rhs));
607  v.simd()=__builtin_ia32_mulps(scale,lhs.simd());
608  v.checkValid();
609  return v;
610 }
611 
612 /** Return the Vector direction scaled to unit length
613  @relates Vector<4,F32>
614  */
616 {
617  v4sf_assertAlignment(rhs.simd());
618  rhs.checkValid();
619 
620  F32 mag=magnitude(rhs);
621  if(mag==0.0f)
622  {
623  feX(e_unsolvable,"unit(Vector<N,F32>)",
624  "attempt to normalize zero magnitude vector");
625  }
626  return rhs*F32(1.0f/mag);
627 }
628 
629 /** Return the Vector direction scaled to unit length with zero check
630  @relates Vector<4,F32>
631  */
633 {
634  v4sf_assertAlignment(rhs.simd());
635  rhs.checkValid();
636 
637  F32 mag=magnitude(rhs);
638  if(mag>0.0f)
639  {
640  return rhs*F32(1.0f/mag);
641  }
642  return rhs;
643 }
644 
645 /** Scale Vector to unit length
646  @relates Vector<4,F32>
647  */
649 {
650  v4sf_assertAlignment(rhs.simd());
651  rhs.checkValid();
652 
653  F32 mag=magnitude(rhs);
654  if(mag==0.0f)
655  {
656  feX(e_unsolvable,"normalize",
657  "attempt to normalize zero magnitude vector");
658  }
659  return rhs*=F32(1.0f/mag);
660 }
661 
662 /** Scale Vector to unit length
663  @relates Vector<4,F32>
664  */
666 {
667  v4sf_assertAlignment(rhs.simd());
668  rhs.checkValid();
669 
670  F32 mag=magnitude(rhs);
671  if(mag>0.0f)
672  {
673  rhs*=F32(1.0f/mag);
674  }
675  return rhs;
676 }
677 
678 /** Return a cross product of Vectors
679  @relates Vector<4,F32>
680  */
682  const Vector<FE_VDIM,F32> &lhs,const Vector<FE_VDIM,F32> &rhs)
683 {
684  v4sf_assertAlignment(r.simd());
685  v4sf_assertAlignment(lhs.simd());
686  v4sf_assertAlignment(rhs.simd());
687  lhs.checkValid();
688  rhs.checkValid();
689 
690 #if FALSE
691  set(r, lhs[1] * rhs[2] - lhs[2] * rhs[1],
692  lhs[2] * rhs[0] - lhs[0] * rhs[2],
693  lhs[0] * rhs[1] - lhs[1] * rhs[0]);
694 #else
695  v4sf op1=__builtin_ia32_shufps(lhs.simd(),lhs.simd(),_MM_SHUFFLE(3,0,2,1));
696  v4sf op2=__builtin_ia32_shufps(rhs.simd(),rhs.simd(),_MM_SHUFFLE(3,1,0,2));
697  v4sf pr1=__builtin_ia32_mulps(op1,op2);
698 
699  op1=__builtin_ia32_shufps(lhs.simd(),lhs.simd(),_MM_SHUFFLE(3,1,0,2));
700  op2=__builtin_ia32_shufps(rhs.simd(),rhs.simd(),_MM_SHUFFLE(3,0,2,1));
701  v4sf pr2=__builtin_ia32_mulps(op1,op2);
702 
703  r.simd()=__builtin_ia32_subps(pr1,pr2);
704  r[3]=0.0f;
705 #endif
706  r.checkValid();
707  return r;
708 }
709 
710 /** Set the Vector as a cross product of Vectors
711  @relates Vector<4,F32>
712  */
714  const Vector<FE_VDIM,F32> &rhs)
715 {
716  v4sf_assertAlignment(lhs.simd());
717  v4sf_assertAlignment(rhs.simd());
718  lhs.checkValid();
719  rhs.checkValid();
720 
722  return cross3(v, lhs, rhs);
723 }
724 
725 #if FE_VDIM==3
726 /** Return a cross product of Vectors
727  @relates Vector<3,F32>
728  */
730  const Vector<FE_VDIM,F32> &lhs,const Vector<FE_VDIM,F32> &rhs)
731 {
732  return cross3(r,lhs,rhs);
733 }
734 
735 /** Set the Vector as a cross product of Vectors
736  @relates Vector<3,F32>
737  */
738 inline Vector<FE_VDIM,F32> cross(const Vector<FE_VDIM,F32> &lhs,
739  const Vector<FE_VDIM,F32> &rhs)
740 {
741  return cross3(lhs,rhs);
742 }
743 #endif
744 
745 /** Add with scaling
746 
747  lhs = lhs + rhs * scalar
748 
749  @relates DenseVector
750  */
751 template<typename U>
753  const Vector<FE_VDIM,F32> &rhs)
754 {
755  v4sf_assertAlignment(lhs.simd());
756  v4sf_assertAlignment(rhs.simd());
757  lhs.checkValid();
758  rhs.checkValid();
759 
760  v4sf scale;
761  v4sf_setSame(scale,scalar);
762  v4sf scaled=__builtin_ia32_mulps(scale,rhs.simd());
763  lhs.simd()=__builtin_ia32_addps(lhs.simd(),scaled);
764  lhs.checkValid();
765  return lhs;
766 }
767 
768 /** Scale then add
769 
770  lhs = lhs * scalar + rhs
771 
772  @relates DenseVector
773  */
774 template<typename U>
776  const Vector<FE_VDIM,F32> &rhs)
777 {
778  v4sf_assertAlignment(lhs.simd());
779  v4sf_assertAlignment(rhs.simd());
780  lhs.checkValid();
781  rhs.checkValid();
782 
783  v4sf scale;
784  v4sf_setSame(scale,scalar);
785  v4sf scaled=__builtin_ia32_mulps(scale,lhs.simd());
786  lhs.simd()=__builtin_ia32_addps(rhs.simd(),scaled);
787  lhs.checkValid();
788  return lhs;
789 }
790 
791 } /* namespace */
U32 size(const Vector< FE_VDIM, F32 > &lhs)
Return the number of elements.
Definition: VectorNf_gnu.h:380
Vector< FE_VDIM, F32 > & normalizeSafe(Vector< FE_VDIM, F32 > &rhs)
Scale Vector to unit length.
Definition: VectorNf_gnu.h:665
Vector< FE_VDIM, F32 > operator*(const Vector< FE_VDIM, F32 > &lhs, const Vector< FE_VDIM, F32 > &rhs)
Return a Vector of products of each component.
Definition: VectorNf_gnu.h:560
Vector< FE_VDIM, F32 > & setAll(Vector< FE_VDIM, F32 > &lhs, T value)
Set all components to the same value.
Definition: VectorNf_gnu.h:355
Vector< N, T > & scaleAndAdd(Vector< N, T > &lhs, U scalar, const Vector< N, T > &rhs)
Scale then add.
Definition: Vector.h:1126
void checkValid(void) const
Definition: VectorNf_gnu.h:124
Vector< FE_VDIM, F32 > & normalize(Vector< FE_VDIM, F32 > &rhs)
Scale Vector to unit length.
Definition: VectorNf_gnu.h:648
kernel
Definition: namespace.dox:3
boost::enable_if< boost::is_arithmetic< T >, Vector< FE_VDIM, F32 > >::type operator*(const T lhs, const Vector< FE_VDIM, F32 > &rhs)
Return a uniformly scaled Vector (pre)
Definition: VectorNf_gnu.h:580
BWORD checkValid(const T &a_value)
Definition: Vector.h:79
Vector< FE_VDIM, F32 > & operator-=(Vector< FE_VDIM, F32 > &lhs, const Vector< FE_VDIM, F32 > &rhs)
Subtract from Vector in place.
Definition: VectorNf_gnu.h:404
Vector< FE_VDIM, F32 > & operator*=(Vector< FE_VDIM, F32 > &lhs, const Vector< FE_VDIM, F32 > &rhs)
Independently scale components in place.
Definition: VectorNf_gnu.h:440
F32 dot(const Vector< FE_VDIM, F32 > &lhs, const Vector< FE_VDIM, F32 > &rhs)
Return dot product.
Definition: VectorNf_gnu.h:472
Vector< FE_VDIM, F32 > operator-(const Vector< FE_VDIM, F32 > &lhs, const Vector< FE_VDIM, F32 > &rhs)
Return difference of Vectors.
Definition: VectorNf_gnu.h:543
Dense vector - size fixed by template.
Definition: Vector.h:19
const v4sf & simd(void) const
Definition: VectorNf_gnu.h:118
T dot(const Vector< N, T > &lhs, const Vector< N, T > &rhs)
Dot (inner) product.
Definition: Vector.h:768
Vector< FE_VDIM, F32 > & operator+=(Vector< FE_VDIM, F32 > &lhs, const Vector< FE_VDIM, F32 > &rhs)
Add to Vector in place.
Definition: VectorNf_gnu.h:388
Vector< N, T > & addScaled(Vector< N, T > &lhs, U scalar, const Vector< N, T > &rhs)
Add with scaling.
Definition: Vector.h:1106
String & sPrintf(const char *fmt,...)
Populate the string in the manner of sprintf().
Definition: String.cc:529
Automatically reference-counted string container.
Definition: String.h:128
Vector< FE_VDIM, F32 > unit(const Vector< FE_VDIM, F32 > &rhs)
Return the Vector direction scaled to unit length.
Definition: VectorNf_gnu.h:615
Vector< 4, T > & cross3(Vector< 4, T > &r, const Vector< 4, T > &lhs, const Vector< 4, T > &rhs)
Return a cross product of Vectors.
Definition: Vector4.h:432
Vector< FE_VDIM, F32 > operator+(const Vector< FE_VDIM, F32 > &lhs, const Vector< FE_VDIM, F32 > &rhs)
Return sum of Vectors.
Definition: VectorNf_gnu.h:526
Vector< FE_VDIM, F32 > cross3(const Vector< FE_VDIM, F32 > &lhs, const Vector< FE_VDIM, F32 > &rhs)
Set the Vector as a cross product of Vectors.
Definition: VectorNf_gnu.h:713
T magnitude(const Vector< N, T > &rhs)
Frobenius norm operation.
Definition: Vector.h:785
Vector< FE_VDIM, F32 > & setAt(Vector< FE_VDIM, F32 > &lhs, U32 index, T value)
Set indexed component.
Definition: VectorNf_gnu.h:368
String print(const Vector< FE_VDIM, F32 > &rhs)
Return text describing the Vector&#39;s state.
Definition: VectorNf_gnu.h:166
boost::enable_if< boost::is_arithmetic< T >, Vector< FE_VDIM, F32 > >::type operator*(const Vector< FE_VDIM, F32 > &lhs, const T rhs)
Return a uniformly scaled Vector (post)
Definition: VectorNf_gnu.h:599
T magnitudeSquared(const Vector< N, T > &rhs)
Square of the length.
Definition: Vector.h:794
Fully specialized 3 or 4 component F32 vector using GNU SIMD.
Definition: VectorNf_gnu.h:27
v4sf & simd(void)
Definition: VectorNf_gnu.h:121
F32 magnitude(const Vector< FE_VDIM, F32 > &rhs)
Return the Vector length.
Definition: VectorNf_gnu.h:515
Vector< FE_VDIM, F32 > & cross3(Vector< FE_VDIM, F32 > &r, const Vector< FE_VDIM, F32 > &lhs, const Vector< FE_VDIM, F32 > &rhs)
Return a cross product of Vectors.
Definition: VectorNf_gnu.h:681
F32 magnitudeSquared(const Vector< FE_VDIM, F32 > &rhs)
Return square of the Vector length.
Definition: VectorNf_gnu.h:504
Vector< FE_VDIM, F32 > unitSafe(const Vector< FE_VDIM, F32 > &rhs)
Return the Vector direction scaled to unit length with zero check.
Definition: VectorNf_gnu.h:632
Vector< FE_VDIM, F32 > operator-(const Vector< FE_VDIM, F32 > &rhs)
Negate the Vector.
Definition: VectorNf_gnu.h:420
Vector< FE_VDIM, F32 > & operator*=(Vector< FE_VDIM, F32 > &lhs, T rhs)
Uniformly scale components in place.
Definition: VectorNf_gnu.h:457
F32 & operator[](U32 index)
Access internal component.
Definition: VectorNf_gnu.h:103