OSDN Git Service

new file: Integration/Tomography/Makefile.recent
[eos/hostdependX86LINUX64.git] / hostdepend / X86MAC64 / util / X86MAC64 / cuda / samples / 5_Simulations / smokeParticles / nvVector.h
1 /*
2  * Copyright 1993-2013 NVIDIA Corporation.  All rights reserved.
3  *
4  * Please refer to the NVIDIA end user license agreement (EULA) associated
5  * with this source code for terms and conditions that govern your use of
6  * this software. Any use, reproduction, disclosure, or distribution of
7  * this software and related documentation outside the terms of the EULA
8  * is strictly prohibited.
9  *
10  */
11
12 //
13 // Template math library for common 3D functionality
14 //
15 // nvVector.h - 2-vector, 3-vector, and 4-vector templates and utilities
16 //
17 // This code is in part deriver from glh, a cross platform glut helper library.
18 // The copyright for glh follows this notice.
19 //
20 // Copyright (c) NVIDIA Corporation. All rights reserved.
21 ////////////////////////////////////////////////////////////////////////////////
22
23 /*
24     Copyright (c) 2000 Cass Everitt
25     Copyright (c) 2000 NVIDIA Corporation
26     All rights reserved.
27
28     Redistribution and use in source and binary forms, with or
29     without modification, are permitted provided that the following
30     conditions are met:
31
32      * Redistributions of source code must retain the above
33        copyright notice, this list of conditions and the following
34        disclaimer.
35
36      * Redistributions in binary form must reproduce the above
37        copyright notice, this list of conditions and the following
38        disclaimer in the documentation and/or other materials
39        provided with the distribution.
40
41      * The names of contributors to this software may not be used
42        to endorse or promote products derived from this software
43        without specific prior written permission.
44
45        THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
46        ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
47        LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
48        FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
49        REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
50        INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
51        BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52        LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
53        CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54        LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
55        ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
56        POSSIBILITY OF SUCH DAMAGE.
57
58
59     Cass Everitt - cass@r3.nu
60 */
61 #ifndef NV_VECTOR_H
62 #define NV_VECTOR_H
63
64 namespace nv
65 {
66
67     template <class T> class vec2;
68     template <class T> class vec3;
69     template <class T> class vec4;
70
71     //////////////////////////////////////////////////////////////////////
72     //
73     // vec2 - template class for 2-tuple vector
74     //
75     //////////////////////////////////////////////////////////////////////
76     template <class T>
77     class vec2
78     {
79         public:
80
81             typedef T value_type;
82             int size() const
83             {
84                 return 2;
85             }
86
87             ////////////////////////////////////////////////////////
88             //
89             //  Constructors
90             //
91             ////////////////////////////////////////////////////////
92
93             // Default/scalar constructor
94             vec2(const T &t = T())
95             {
96                 for (int i = 0; i < size(); i++)
97                 {
98                     _array[i] = t;
99                 }
100             }
101
102             // Construct from array
103             vec2(const T *tp)
104             {
105                 for (int i = 0; i < size(); i++)
106                 {
107                     _array[i] = tp[i];
108                 }
109             }
110
111             // Construct from explicit values
112             vec2(const T v0, const T v1)
113             {
114                 x = v0;
115                 y = v1;
116             }
117
118             explicit vec2(const vec3<T> &u)
119             {
120                 for (int i = 0; i < size(); i++)
121                 {
122                     _array[i] = u._array[i];
123                 }
124             }
125
126             explicit vec2(const vec4<T> &u)
127             {
128                 for (int i = 0; i < size(); i++)
129                 {
130                     _array[i] = u._array[i];
131                 }
132             }
133
134             const T *get_value() const
135             {
136                 return _array;
137             }
138
139             vec2<T> &set_value(const T *rhs)
140             {
141                 for (int i = 0; i < size(); i++)
142                 {
143                     _array[i] = rhs[i];
144                 }
145
146                 return *this;
147             }
148
149             // indexing operators
150             T &operator [](int i)
151             {
152                 return _array[i];
153             }
154
155             const T &operator [](int i) const
156             {
157                 return _array[i];
158             }
159
160             // type-cast operators
161             operator T *()
162             {
163                 return _array;
164             }
165
166             operator const T *() const
167             {
168                 return _array;
169             }
170
171             ////////////////////////////////////////////////////////
172             //
173             //  Math operators
174             //
175             ////////////////////////////////////////////////////////
176
177             // scalar multiply assign
178             friend vec2<T> &operator *= (vec2<T> &lhs, T d)
179             {
180                 for (int i = 0; i < lhs.size(); i++)
181                 {
182                     lhs._array[i] *= d;
183                 }
184
185                 return lhs;
186             }
187
188             // component-wise vector multiply assign
189             friend vec2<T> &operator *= (vec2<T> &lhs, const vec2<T> &rhs)
190             {
191                 for (int i = 0; i < lhs.size(); i++)
192                 {
193                     lhs._array[i] *= rhs[i];
194                 }
195
196                 return lhs;
197             }
198
199             // scalar divide assign
200             friend vec2<T> &operator /= (vec2<T> &lhs, T d)
201             {
202                 if (d == 0)
203                 {
204                     return lhs;
205                 }
206
207                 for (int i = 0; i < lhs.size(); i++)
208                 {
209                     lhs._array[i] /= d;
210                 }
211
212                 return lhs;
213             }
214
215             // component-wise vector divide assign
216             friend vec2<T> &operator /= (vec2<T> &lhs, const vec2<T> &rhs)
217             {
218                 for (int i = 0; i < lhs.size(); i++)
219                 {
220                     lhs._array[i] /= rhs._array[i];
221                 }
222
223                 return lhs;
224             }
225
226             // component-wise vector add assign
227             friend vec2<T> &operator += (vec2<T> &lhs, const vec2<T> &rhs)
228             {
229                 for (int i = 0; i < lhs.size(); i++)
230                 {
231                     lhs._array[i] += rhs._array[i];
232                 }
233
234                 return lhs;
235             }
236
237             // component-wise vector subtract assign
238             friend vec2<T> &operator -= (vec2<T> &lhs, const vec2<T> &rhs)
239             {
240                 for (int i = 0; i < lhs.size(); i++)
241                 {
242                     lhs._array[i] -= rhs._array[i];
243                 }
244
245                 return lhs;
246             }
247
248             // unary negate
249             friend vec2<T> operator - (const vec2<T> &rhs)
250             {
251                 vec2<T> rv;
252
253                 for (int i = 0; i < rhs.size(); i++)
254                 {
255                     rv._array[i] = -rhs._array[i];
256                 }
257
258                 return rv;
259             }
260
261             // vector add
262             friend vec2<T> operator + (const vec2<T> &lhs, const vec2<T> &rhs)
263             {
264                 vec2<T> rt(lhs);
265                 return rt += rhs;
266             }
267
268             // vector subtract
269             friend vec2<T> operator - (const vec2<T> &lhs, const vec2<T> &rhs)
270             {
271                 vec2<T> rt(lhs);
272                 return rt -= rhs;
273             }
274
275             // scalar multiply
276             friend vec2<T> operator * (const vec2<T> &lhs, T rhs)
277             {
278                 vec2<T> rt(lhs);
279                 return rt *= rhs;
280             }
281
282             // scalar multiply
283             friend vec2<T> operator * (T lhs, const vec2<T> &rhs)
284             {
285                 vec2<T> rt(lhs);
286                 return rt *= rhs;
287             }
288
289             // vector component-wise multiply
290             friend vec2<T> operator * (const vec2<T> &lhs, const vec2<T> &rhs)
291             {
292                 vec2<T> rt(lhs);
293                 return rt *= rhs;
294             }
295
296             // scalar multiply
297             friend vec2<T> operator / (const vec2<T> &lhs, T rhs)
298             {
299                 vec2<T> rt(lhs);
300                 return rt /= rhs;
301             }
302
303             // vector component-wise multiply
304             friend vec2<T> operator / (const vec2<T> &lhs, const vec2<T> &rhs)
305             {
306                 vec2<T> rt(lhs);
307                 return rt /= rhs;
308             }
309
310             ////////////////////////////////////////////////////////
311             //
312             //  Comparison operators
313             //
314             ////////////////////////////////////////////////////////
315
316             // equality
317             friend bool operator == (const vec2<T> &lhs, const vec2<T> &rhs)
318             {
319                 bool r = true;
320
321                 for (int i = 0; i < lhs.size(); i++)
322                 {
323                     r &= lhs._array[i] == rhs._array[i];
324                 }
325
326                 return r;
327             }
328
329             // inequality
330             friend bool operator != (const vec2<T> &lhs, const vec2<T> &rhs)
331             {
332                 bool r = true;
333
334                 for (int i = 0; i < lhs.size(); i++)
335                 {
336                     r &= lhs._array[i] != rhs._array[i];
337                 }
338
339                 return r;
340             }
341
342             //data intentionally left public to allow vec2.x
343             union
344             {
345                 struct
346                 {
347                     T x,y;          // standard names for components
348                 };
349                 struct
350                 {
351                     T s,t;          // standard names for components
352                 };
353                 T _array[2];     // array access
354             };
355     };
356
357     //////////////////////////////////////////////////////////////////////
358     //
359     // vec3 - template class for 3-tuple vector
360     //
361     //////////////////////////////////////////////////////////////////////
362     template <class T>
363     class vec3
364     {
365         public:
366
367             typedef T value_type;
368             int size() const
369             {
370                 return 3;
371             }
372
373             ////////////////////////////////////////////////////////
374             //
375             //  Constructors
376             //
377             ////////////////////////////////////////////////////////
378
379             // Default/scalar constructor
380             vec3(const T &t = T())
381             {
382                 for (int i = 0; i < size(); i++)
383                 {
384                     _array[i] = t;
385                 }
386             }
387
388             // Construct from array
389             vec3(const T *tp)
390             {
391                 for (int i = 0; i < size(); i++)
392                 {
393                     _array[i] = tp[i];
394                 }
395             }
396
397             // Construct from explicit values
398             vec3(const T v0, const T v1, const T v2)
399             {
400                 x = v0;
401                 y = v1;
402                 z = v2;
403             }
404
405             explicit vec3(const vec4<T> &u)
406             {
407                 for (int i = 0; i < size(); i++)
408                 {
409                     _array[i] = u._array[i];
410                 }
411             }
412
413             explicit vec3(const vec2<T> &u, T v0)
414             {
415                 x = u.x;
416                 y = u.y;
417                 z = v0;
418             }
419
420             const T *get_value() const
421             {
422                 return _array;
423             }
424
425             vec3<T> &set_value(const T *rhs)
426             {
427                 for (int i = 0; i < size(); i++)
428                 {
429                     _array[i] = rhs[i];
430                 }
431
432                 return *this;
433             }
434
435             // indexing operators
436             T &operator [](int i)
437             {
438                 return _array[i];
439             }
440
441             const T &operator [](int i) const
442             {
443                 return _array[i];
444             }
445
446             // type-cast operators
447             operator T *()
448             {
449                 return _array;
450             }
451
452             operator const T *() const
453             {
454                 return _array;
455             }
456
457             ////////////////////////////////////////////////////////
458             //
459             //  Math operators
460             //
461             ////////////////////////////////////////////////////////
462
463             // scalar multiply assign
464             friend vec3<T> &operator *= (vec3<T> &lhs, T d)
465             {
466                 for (int i = 0; i < lhs.size(); i++)
467                 {
468                     lhs._array[i] *= d;
469                 }
470
471                 return lhs;
472             }
473
474             // component-wise vector multiply assign
475             friend vec3<T> &operator *= (vec3<T> &lhs, const vec3<T> &rhs)
476             {
477                 for (int i = 0; i < lhs.size(); i++)
478                 {
479                     lhs._array[i] *= rhs[i];
480                 }
481
482                 return lhs;
483             }
484
485             // scalar divide assign
486             friend vec3<T> &operator /= (vec3<T> &lhs, T d)
487             {
488                 if (d == 0)
489                 {
490                     return lhs;
491                 }
492
493                 for (int i = 0; i < lhs.size(); i++)
494                 {
495                     lhs._array[i] /= d;
496                 }
497
498                 return lhs;
499             }
500
501             // component-wise vector divide assign
502             friend vec3<T> &operator /= (vec3<T> &lhs, const vec3<T> &rhs)
503             {
504                 for (int i = 0; i < lhs.size(); i++)
505                 {
506                     lhs._array[i] /= rhs._array[i];
507                 }
508
509                 return lhs;
510             }
511
512             // component-wise vector add assign
513             friend vec3<T> &operator += (vec3<T> &lhs, const vec3<T> &rhs)
514             {
515                 for (int i = 0; i < lhs.size(); i++)
516                 {
517                     lhs._array[i] += rhs._array[i];
518                 }
519
520                 return lhs;
521             }
522
523             // component-wise vector subtract assign
524             friend vec3<T> &operator -= (vec3<T> &lhs, const vec3<T> &rhs)
525             {
526                 for (int i = 0; i < lhs.size(); i++)
527                 {
528                     lhs._array[i] -= rhs._array[i];
529                 }
530
531                 return lhs;
532             }
533
534             // unary negate
535             friend vec3<T> operator - (const vec3<T> &rhs)
536             {
537                 vec3<T> rv;
538
539                 for (int i = 0; i < rhs.size(); i++)
540                 {
541                     rv._array[i] = -rhs._array[i];
542                 }
543
544                 return rv;
545             }
546
547             // vector add
548             friend vec3<T> operator + (const vec3<T> &lhs, const vec3<T> &rhs)
549             {
550                 vec3<T> rt(lhs);
551                 return rt += rhs;
552             }
553
554             // vector subtract
555             friend vec3<T> operator - (const vec3<T> &lhs, const vec3<T> &rhs)
556             {
557                 vec3<T> rt(lhs);
558                 return rt -= rhs;
559             }
560
561             // scalar multiply
562             friend vec3<T> operator * (const vec3<T> &lhs, T rhs)
563             {
564                 vec3<T> rt(lhs);
565                 return rt *= rhs;
566             }
567
568             // scalar multiply
569             friend vec3<T> operator * (T lhs, const vec3<T> &rhs)
570             {
571                 vec3<T> rt(lhs);
572                 return rt *= rhs;
573             }
574
575             // vector component-wise multiply
576             friend vec3<T> operator * (const vec3<T> &lhs, const vec3<T> &rhs)
577             {
578                 vec3<T> rt(lhs);
579                 return rt *= rhs;
580             }
581
582             // scalar multiply
583             friend vec3<T> operator / (const vec3<T> &lhs, T rhs)
584             {
585                 vec3<T> rt(lhs);
586                 return rt /= rhs;
587             }
588
589             // vector component-wise multiply
590             friend vec3<T> operator / (const vec3<T> &lhs, const vec3<T> &rhs)
591             {
592                 vec3<T> rt(lhs);
593                 return rt /= rhs;
594             }
595
596             ////////////////////////////////////////////////////////
597             //
598             //  Comparison operators
599             //
600             ////////////////////////////////////////////////////////
601
602             // equality
603             friend bool operator == (const vec3<T> &lhs, const vec3<T> &rhs)
604             {
605                 bool r = true;
606
607                 for (int i = 0; i < lhs.size(); i++)
608                 {
609                     r &= lhs._array[i] == rhs._array[i];
610                 }
611
612                 return r;
613             }
614
615             // inequality
616             friend bool operator != (const vec3<T> &lhs, const vec3<T> &rhs)
617             {
618                 bool r = true;
619
620                 for (int i = 0; i < lhs.size(); i++)
621                 {
622                     r &= lhs._array[i] != rhs._array[i];
623                 }
624
625                 return r;
626             }
627
628             ////////////////////////////////////////////////////////////////////////////////
629             //
630             // dimension specific operations
631             //
632             ////////////////////////////////////////////////////////////////////////////////
633
634             // cross product
635             friend vec3<T> cross(const vec3<T> &lhs, const vec3<T> &rhs)
636             {
637                 vec3<T> r;
638
639                 r.x = lhs.y * rhs.z - lhs.z * rhs.y;
640                 r.y = lhs.z * rhs.x - lhs.x * rhs.z;
641                 r.z = lhs.x * rhs.y - lhs.y * rhs.x;
642
643                 return r;
644             }
645
646             //data intentionally left public to allow vec2.x
647             union
648             {
649                 struct
650                 {
651                     T x, y, z;          // standard names for components
652                 };
653                 struct
654                 {
655                     T s, t, r;          // standard names for components
656                 };
657                 T _array[3];     // array access
658             };
659     };
660
661     //////////////////////////////////////////////////////////////////////
662     //
663     // vec4 - template class for 4-tuple vector
664     //
665     //////////////////////////////////////////////////////////////////////
666     template <class T>
667     class vec4
668     {
669         public:
670
671             typedef T value_type;
672             int size() const
673             {
674                 return 4;
675             }
676
677             ////////////////////////////////////////////////////////
678             //
679             //  Constructors
680             //
681             ////////////////////////////////////////////////////////
682
683             // Default/scalar constructor
684             vec4(const T &t = T())
685             {
686                 for (int i = 0; i < size(); i++)
687                 {
688                     _array[i] = t;
689                 }
690             }
691
692             // Construct from array
693             vec4(const T *tp)
694             {
695                 for (int i = 0; i < size(); i++)
696                 {
697                     _array[i] = tp[i];
698                 }
699             }
700
701             // Construct from explicit values
702             vec4(const T v0, const T v1, const T v2, const T v3)
703             {
704                 x = v0;
705                 y = v1;
706                 z = v2;
707                 w = v3;
708             }
709
710             explicit vec4(const vec3<T> &u, T v0)
711             {
712                 x = u.x;
713                 y = u.y;
714                 z = u.z;
715                 w = v0;
716             }
717
718             explicit vec4(const vec2<T> &u, T v0, T v1)
719             {
720                 x = u.x;
721                 y = u.y;
722                 z = v0;
723                 w = v1;
724             }
725
726             const T *get_value() const
727             {
728                 return _array;
729             }
730
731             vec4<T> &set_value(const T *rhs)
732             {
733                 for (int i = 0; i < size(); i++)
734                 {
735                     _array[i] = rhs[i];
736                 }
737
738                 return *this;
739             }
740
741             // indexing operators
742             T &operator [](int i)
743             {
744                 return _array[i];
745             }
746
747             const T &operator [](int i) const
748             {
749                 return _array[i];
750             }
751
752             // type-cast operators
753             operator T *()
754             {
755                 return _array;
756             }
757
758             operator const T *() const
759             {
760                 return _array;
761             }
762
763             ////////////////////////////////////////////////////////
764             //
765             //  Math operators
766             //
767             ////////////////////////////////////////////////////////
768
769             // scalar multiply assign
770             friend vec4<T> &operator *= (vec4<T> &lhs, T d)
771             {
772                 for (int i = 0; i < lhs.size(); i++)
773                 {
774                     lhs._array[i] *= d;
775                 }
776
777                 return lhs;
778             }
779
780             // component-wise vector multiply assign
781             friend vec4<T> &operator *= (vec4<T> &lhs, const vec4<T> &rhs)
782             {
783                 for (int i = 0; i < lhs.size(); i++)
784                 {
785                     lhs._array[i] *= rhs[i];
786                 }
787
788                 return lhs;
789             }
790
791             // scalar divide assign
792             friend vec4<T> &operator /= (vec4<T> &lhs, T d)
793             {
794                 if (d == 0)
795                 {
796                     return lhs;
797                 }
798
799                 for (int i = 0; i < lhs.size(); i++)
800                 {
801                     lhs._array[i] /= d;
802                 }
803
804                 return lhs;
805             }
806
807             // component-wise vector divide assign
808             friend vec4<T> &operator /= (vec4<T> &lhs, const vec4<T> &rhs)
809             {
810                 for (int i = 0; i < lhs.size(); i++)
811                 {
812                     lhs._array[i] /= rhs._array[i];
813                 }
814
815                 return lhs;
816             }
817
818             // component-wise vector add assign
819             friend vec4<T> &operator += (vec4<T> &lhs, const vec4<T> &rhs)
820             {
821                 for (int i = 0; i < lhs.size(); i++)
822                 {
823                     lhs._array[i] += rhs._array[i];
824                 }
825
826                 return lhs;
827             }
828
829             // component-wise vector subtract assign
830             friend vec4<T> &operator -= (vec4<T> &lhs, const vec4<T> &rhs)
831             {
832                 for (int i = 0; i < lhs.size(); i++)
833                 {
834                     lhs._array[i] -= rhs._array[i];
835                 }
836
837                 return lhs;
838             }
839
840             // unary negate
841             friend vec4<T> operator - (const vec4<T> &rhs)
842             {
843                 vec4<T> rv;
844
845                 for (int i = 0; i < rhs.size(); i++)
846                 {
847                     rv._array[i] = -rhs._array[i];
848                 }
849
850                 return rv;
851             }
852
853             // vector add
854             friend vec4<T> operator + (const vec4<T> &lhs, const vec4<T> &rhs)
855             {
856                 vec4<T> rt(lhs);
857                 return rt += rhs;
858             }
859
860             // vector subtract
861             friend vec4<T> operator - (const vec4<T> &lhs, const vec4<T> &rhs)
862             {
863                 vec4<T> rt(lhs);
864                 return rt -= rhs;
865             }
866
867             // scalar multiply
868             friend vec4<T> operator * (const vec4<T> &lhs, T rhs)
869             {
870                 vec4<T> rt(lhs);
871                 return rt *= rhs;
872             }
873
874             // scalar multiply
875             friend vec4<T> operator * (T lhs, const vec4<T> &rhs)
876             {
877                 vec4<T> rt(lhs);
878                 return rt *= rhs;
879             }
880
881             // vector component-wise multiply
882             friend vec4<T> operator * (const vec4<T> &lhs, const vec4<T> &rhs)
883             {
884                 vec4<T> rt(lhs);
885                 return rt *= rhs;
886             }
887
888             // scalar multiply
889             friend vec4<T> operator / (const vec4<T> &lhs, T rhs)
890             {
891                 vec4<T> rt(lhs);
892                 return rt /= rhs;
893             }
894
895             // vector component-wise multiply
896             friend vec4<T> operator / (const vec4<T> &lhs, const vec4<T> &rhs)
897             {
898                 vec4<T> rt(lhs);
899                 return rt /= rhs;
900             }
901
902             ////////////////////////////////////////////////////////
903             //
904             //  Comparison operators
905             //
906             ////////////////////////////////////////////////////////
907
908             // equality
909             friend bool operator == (const vec4<T> &lhs, const vec4<T> &rhs)
910             {
911                 bool r = true;
912
913                 for (int i = 0; i < lhs.size(); i++)
914                 {
915                     r &= lhs._array[i] == rhs._array[i];
916                 }
917
918                 return r;
919             }
920
921             // inequality
922             friend bool operator != (const vec4<T> &lhs, const vec4<T> &rhs)
923             {
924                 bool r = true;
925
926                 for (int i = 0; i < lhs.size(); i++)
927                 {
928                     r &= lhs._array[i] != rhs._array[i];
929                 }
930
931                 return r;
932             }
933
934             //data intentionally left public to allow vec2.x
935             union
936             {
937                 struct
938                 {
939                     T x, y, z, w;          // standard names for components
940                 };
941                 struct
942                 {
943                     T s, t, r, q;          // standard names for components
944                 };
945                 T _array[4];     // array access
946             };
947     };
948
949     ////////////////////////////////////////////////////////////////////////////////
950     //
951     // Generic vector operations
952     //
953     ////////////////////////////////////////////////////////////////////////////////
954
955     // compute the dot product of two vectors
956     template<class T>
957     inline typename T::value_type dot(const T &lhs, const T &rhs)
958     {
959         typename T::value_type r = 0;
960
961         for (int i = 0; i < lhs.size(); i++)
962         {
963             r += lhs._array[i] * rhs._array[i];
964         }
965
966         return r;
967     }
968
969     // return the length of the provided vector
970     template< class T>
971     inline typename T::value_type length(const T &vec)
972     {
973         typename T::value_type r = 0;
974
975         for (int i = 0; i < vec.size(); i++)
976         {
977             r += vec._array[i]*vec._array[i];
978         }
979
980         return typename T::value_type(sqrt(r));
981     }
982
983     // return the squared norm
984     template< class T>
985     inline typename T::value_type square_norm(const T &vec)
986     {
987         typename T::value_type r = 0;
988
989         for (int i = 0; i < vec.size(); i++)
990         {
991             r += vec._array[i]*vec._array[i];
992         }
993
994         return r;
995     }
996
997     // return the normalized version of the vector
998     template< class T>
999     inline T normalize(const T &vec)
1000     {
1001         typename T::value_type sum(0);
1002         T r;
1003
1004         for (int i = 0; i < vec.size(); i++)
1005         {
1006             sum += vec._array[i] * vec._array[i];
1007         }
1008
1009         sum = typename T::value_type(sqrt(sum));
1010
1011         if (sum > 0)
1012             for (int i = 0; i < vec.size(); i++)
1013             {
1014                 r._array[i] = vec._array[i] / sum;
1015             }
1016
1017         return r;
1018     }
1019
1020     // In VC8 : min and max are already defined by a #define...
1021 #ifdef min
1022 #undef min
1023 #endif
1024 #ifdef max
1025 #undef max
1026 #endif
1027     //componentwise min
1028     template< class T>
1029     inline T min(const T &lhs, const T &rhs)
1030     {
1031         T rt;
1032
1033         for (int i = 0; i < lhs.size(); i++)
1034         {
1035             rt._array[i] = std::min(lhs._array[i], rhs._array[i]);
1036         }
1037
1038         return rt;
1039     }
1040
1041     // componentwise max
1042     template< class T>
1043     inline T max(const T &lhs, const T &rhs)
1044     {
1045         T rt;
1046
1047         for (int i = 0; i < lhs.size(); i++)
1048         {
1049             rt._array[i] = std::max(lhs._array[i], rhs._array[i]);
1050         }
1051
1052         return rt;
1053     }
1054
1055
1056 };
1057
1058 #endif