QDP++
qdp_multi.h
Go to the documentation of this file.
1// -*- C++ -*-
2
8
9#ifndef MULTI_INCLUDE
10#define MULTI_INCLUDE
11
12#include "qdp_config.h"
13namespace QDP {
14
22
24template<class T> class multi1d
25{
26public:
27 // Basic cosntructor. Null (0x0) array_pointer, no copymem, no fast memory
28 multi1d() {F=0;n1=0;copymem=false;}
29
30 // Placement constructor. Copy pointer, copymem=true
31 multi1d(T *f, int ns1) {F=f; n1=ns1;copymem=true;}
32
33 // Explicit constructor, copymem is false, fast_mem is false, call resize
34 explicit multi1d(int ns1) {copymem=false;F=0;resize(ns1);}
35 // Destructor
37 // If not created with placement, delete array
38 if (! copymem) {
39 delete[] F;
40 }
41 }
42
43
45 // Copy from s, into slow memory
46 multi1d(const multi1d& s): copymem(false), n1(s.n1), F(0)
47 {
48 resize(n1);
49
50 for(int i=0; i < n1; ++i)
51 F[i] = s.F[i];
52 }
53
55 // template type
56 void resize(int ns1) { resize(*this, ns1); }
57
58
60 int size() const {return n1;}
61 int size1() const {return n1;}
62
64
66 {
67 if (size() != s1.size()) // a simple check avoids resizing always
68 resize(s1.size());
69
70 for(int i=0; i < n1; ++i)
71 F[i] = s1.F[i];
72 return *this;
73 }
74
76 template<class T1>
77 multi1d<T>& operator=(const T1& s1)
78 {
79 if (F == 0)
80 {
81 std::cerr << "multi1d: left hand side not initialized in =" << std::endl;
82 exit(1);
83 }
84
85 for(int i=0; i < n1; ++i)
86 F[i] = s1;
87 return *this;
88 }
89
91 multi1d<T>& operator=(const T* s1)
92 {
93 if (F == 0)
94 {
95 std::cerr << "multi1d: left hand side not initialized in =" << std::endl;
96 exit(1);
97 }
98
99 for(int i=0; i < n1; ++i)
100 F[i] = s1[i];
101 return *this;
102 }
103
105
107 {
108 if (size() != s1.size())
109 {
110 std::cerr << "multi1d: Sizes incompatible in +=" << std::endl;
111 exit(1);
112 }
113
114 for(int i=0; i < n1; ++i)
115 F[i] += s1.F[i];
116 return *this;
117 }
118
120
121 multi1d<T>& operator+=(const T& s1)
122 {
123 if (F == 0)
124 {
125 std::cerr << "multi1d: left hand side not initialized in +=" << std::endl;
126 exit(1);
127 }
128
129 for(int i=0; i < n1; ++i)
130 F[i] += s1;
131 return *this;
132 }
133
135
137 {
138 if (size() != s1.size())
139 {
140 std::cerr << "multi1d: Sizes incompatible in -=" << std::endl;
141 exit(1);
142 }
143
144 for(int i=0; i < n1; ++i)
145 F[i] -= s1.F[i];
146 return *this;
147 }
148
150
151 multi1d<T>& operator-=(const T& s1)
152 {
153 if (F == 0)
154 {
155 std::cerr << "multi1d: left hand side not initialized in -=" << std::endl;
156 exit(1);
157 }
158
159 for(int i=0; i < n1; ++i)
160 F[i] -= s1;
161 return *this;
162 }
163
165
167 {
168 if (size() != s1.size())
169 {
170 std::cerr << "multi1d: Sizes incompatible in *=" << std::endl;
171 exit(1);
172 }
173
174 for(int i=0; i < n1; ++i)
175 F[i] *= s1.F[i];
176 return *this;
177 }
178
180
181 multi1d<T>& operator*=(const T& s1)
182 {
183 if (F == 0)
184 {
185 std::cerr << "multi1d: left hand side not initialized in *=" << std::endl;
186 exit(1);
187 }
188
189 for(int i=0; i < n1; ++i)
190 F[i] *= s1;
191 return *this;
192 }
193
195
197 {
198 if (size() != s1.size())
199 {
200 std::cerr << "multi1d: Sizes incompatible in /=" << std::endl;
201 exit(1);
202 }
203
204 for(int i=0; i < n1; ++i)
205 F[i] /= s1.F[i];
206 return *this;
207 }
208
210
211 multi1d<T>& operator/=(const T& s1)
212 {
213 if (F == 0)
214 {
215 std::cerr << "multi1d: left hand side not initialized in /=" << std::endl;
216 exit(1);
217 }
218
219 for(int i=0; i < n1; ++i)
220 F[i] /= s1;
221 return *this;
222 }
223
225 const T* slice() const {return F;}
226
228 T& operator()(int i) {return F[i];}
229
231 const T& operator()(int i) const {return F[i];}
232
234 T& operator[](int i) {return F[i];}
235
237 const T& operator[](int i) const {return F[i];}
238
242 inline void moveToFastMemoryHint(bool copy=false) {
243 moveToFastMemoryHint(*this, copy);
244 }
245
249 inline void revertFromFastMemoryHint(bool copy=false) {
250 revertFromFastMemoryHint(*this, copy);
251 }
252
253private:
255 template<typename I>
256 void resize(multi1d<I>& disambiguator, int ns1)
257 {
258 if(copymem) {
259 std::cerr <<"multi1d: invalid resize of a copy of memory" << std::endl;
260 exit(1);
261 }
262 delete [] F;
263 n1=ns1;
264 F = new(std::nothrow) T[n1];
265 if ( F == 0x0 ) {
266 QDP_error_exit("Unable to allocate memory in multi1d::resize(%d)\n",ns1);
267 }
268 }
269
272 template<typename I>
273 inline void moveToFastMemoryHint(multi1d<I>& disambiguator, bool copy=false) {}
274
277 template<typename I>
278 inline void revertFromFastMemoryHint(multi1d<I>& disambiguator, bool copy=false) {}
279
280 bool copymem;
281 int n1;
282 T *F;
283};
284
285
286
287//---------------------------------------------------------------
288// Comparisons/recombinations
289
291template<typename T>
292inline multi1d<T> concat(const multi1d<T>& l, const multi1d<T>& r)
293{
294 multi1d<int> nz(l.size() + r.size());
295 int j = 0;
296 for(int i=0; i < l.size(); ++i)
297 nz[j++] = l[i];
298
299 for(int i=0; i < r.size(); ++i)
300 nz[j++] = r[i];
301
302 return nz;
303}
304
306template<typename T>
307inline bool operator==(const multi1d<T>& n1, const multi1d<T>& n2)
308{
309 if (n1.size() == 0 || n1.size() != n2.size())
310 return false;
311
312 for(int i=0; i < n1.size(); ++i)
313 if (n2[i] != n1[i])
314 return false;
315
316 return true;
317}
318
320template<typename T>
321inline bool operator!=(const multi1d<T>& n1, const multi1d<T>& n2)
322{
323 return ! (n1 == n2);
324}
325
327
328template<typename T>
329inline bool operator<(const multi1d<T>& a, const multi1d<T>& b)
330{
331 int len = (a.size() < b.size()) ? a.size() : b.size();
332
333 for(int i=0; i < len; ++i)
334 {
335 if (a[i] != b[i])
336 return (a[i] < b[i]) ? true : false;
337 }
338
339 return (a.size() == b.size()) ? false : (a.size() < b.size()) ? true : false;
340}
341
343
344template<typename T>
345inline bool operator>(const multi1d<T>& a, const multi1d<T>& b)
346{
347 int len = (a.size() < b.size()) ? a.size() : b.size();
348
349 for(int i=0; i < len; ++i)
350 {
351 if (a[i] != b[i])
352 return (a[i] > b[i]) ? true : false;
353 }
354
355 return (a.size() == b.size()) ? false : (a.size() > b.size()) ? true : false;
356}
357
359
360template<typename T>
361inline bool operator<=(const multi1d<T>& a, const multi1d<T>& b)
362{
363 return (a < b) || (a == b);
364}
365
367
368template<typename T>
369inline bool operator>=(const multi1d<T>& a, const multi1d<T>& b)
370{
371 return (a > b) || (a == b);
372}
373
374
375//---------------------------------------------------------------
376// Basic math support
377//
379template< typename T>
380inline
382{
383 multi1d<T> c(a);
384 c+=b;
385 return c;
386}
387
389template< typename T>
390inline
392{
393 multi1d<T> c(a);
394 c-=b;
395 return c;
396}
397
399template< typename T>
400inline
402{
403 multi1d<T> c(a);
404 c*=b;
405 return c;
406}
407
409template< typename T>
410inline
412{
413 multi1d<T> c(a);
414 c/=b;
415 return c;
416}
417
419template< typename T>
420inline
421multi1d<T> operator+(const T& s, const multi1d<T>& a)
422{
423 multi1d<T> c(a);
424 c+=s;
425 return c;
426}
427
429template< typename T>
430inline
431multi1d<T> operator+(const multi1d<T>& a, const T& s)
432{
433 multi1d<T> c(a);
434 c+=s;
435 return c;
436}
437
439template< typename T>
440inline
441multi1d<T> operator-(const T& s, const multi1d<T>& a)
442{
443 multi1d<T> c(-a);
444 c+=s;
445 return c;
446}
447
448template< typename T>
449inline
450multi1d<T> operator-(const multi1d<T>& a, const T& s)
451{
452 multi1d<T> c(a);
453 c-=s;
454 return c;
455}
456
458template< typename T>
459inline
460multi1d<T> operator*(const T& s, const multi1d<T>& a)
461{
462 multi1d<T> c(a);
463 c*=s;
464 return c;
465}
466
468template< typename T>
469inline
470multi1d<T> operator*(const multi1d<T>& a, const T& s)
471{
472 multi1d<T> c(a);
473 c*=s;
474 return c;
475}
476
478template< typename T>
479inline
480multi1d<T> operator/(const T& s, const multi1d<T>& a)
481{
482 multi1d<T> c(a.size());
483 c = s;
484 c/= a;
485 return c;
486}
487
489template< typename T>
490inline
491multi1d<T> operator/(const multi1d<T>& a, const T& s)
492{
493 multi1d<T> c(a);
494 c/=s;
495 return c;
496}
497
499template< typename T>
500inline
502{
503 multi1d<T> c(a.size());
504 for(int i(0);i<a.size();i++)
505 {
506 T tt;
507 tt = a[i];
508 c[i] = sqrt(a[i]);
509 }
510 return c;
511}
512
514template< typename T>
515inline
517{
518 multi1d<T> c(a.size());
519 for(int i(0);i<a.size();i++)
520 {
521 T tt;
522 tt = a[i];
523 c[i] = log(a[i]);
524 }
525 return c;
526}
527
529template< typename T>
530inline
532{
533 multi1d<T> c(a.size());
534 for(int i(0);i<a.size();i++)
535 {
536 T tt;
537 tt = a[i];
538 c[i] = sin(a[i]);
539 }
540 return c;
541}
542
543
545template< typename T>
546inline
548{
549 multi1d<T> c(a.size());
550 for(int i(0);i<a.size();i++)
551 {
552 T tt;
553 tt = a[i];
554 c[i] = cos(a[i]);
555 }
556 return c;
557}
558
560template< typename T>
561inline
563{
564 multi1d<T> c(a.size());
565 for(int i(0);i<a.size();i++)
566 {
567 T tt;
568 tt = a[i];
569 c[i] = tan(a[i]);
570 }
571 return c;
572}
573
575template< typename T>
576inline
578{
579 multi1d<T> c(a.size());
580 for(int i(0);i<a.size();i++)
581 {
582 T tt;
583 tt = a[i];
584 c[i] = asin(a[i]);
585 }
586 return c;
587}
588
589
591template< typename T>
592inline
594{
595 multi1d<T> c(a.size());
596 for(int i(0);i<a.size();i++)
597 {
598 T tt;
599 tt = a[i];
600 c[i] = acos(a[i]);
601 }
602 return c;
603}
604
606template< typename T>
607inline
609{
610 multi1d<T> c(a.size());
611 for(int i(0);i<a.size();i++)
612 {
613 T tt;
614 tt = a[i];
615 c[i] = atan(a[i]);
616 }
617 return c;
618}
619
620
621
623template< typename T>
624inline
625T norm2(const multi1d<T>& a)
626{
627 T nn = a[0]*a[0]; // assumes at least 1 element
628 for(int i=1; i < a.size(); ++i)
629 nn += a[i]*a[i];
630
631 return nn;
632}
633
634
635
636
637//------------------------------------------------------------------------------------------
639template<class T> class multi2d
640{
641public:
642 multi2d() {F=0;n1=n2=sz=0;copymem=false;}
643 multi2d(T *f, int ns2, int ns1) {F=f; n1=ns1; n2=ns2; sz=n1*n2; copymem=true;}
644 explicit multi2d(int ns2, int ns1) {copymem=false;F=0;resize(ns2,ns1);}
645 ~multi2d() {if (! copymem) {delete[] F;}}
646
648 multi2d(const multi2d& s): copymem(false), n1(s.n1), n2(s.n2), sz(s.sz), F(0)
649 {
650 resize(n2,n1);
651
652 for(int i=0; i < sz; ++i)
653 F[i] = s.F[i];
654 }
655
657 void resize(int ns2, int ns1) {
658 if(copymem) {
659 std::cerr <<"multi2d: invalid resize of a copy of memory" << std::endl;
660 exit(1);
661 }
662 delete[] F;
663 n1=ns1;
664 n2=ns2;
665 sz=n1*n2;
666 F = new(std::nothrow) T[sz];
667 if( F == 0x0 ) {
668 QDP_error_exit("Unable to new memory in multi2d::resize(%d,%d)\n",ns2,ns1);
669 }
670 }
671
673 int size1() const {return n1;}
674 int size2() const {return n2;}
675
677 int nrows() const {return n2;}
678 int ncols() const {return n1;}
679
682 {
683 resize(s1.size2(), s1.size1()); // always resize
684
685 for(int i=0; i < sz; ++i)
686 F[i] = s1.F[i];
687 return *this;
688 }
689
691 template<class T1>
692 multi2d<T>& operator=(const T1& s1)
693 {
694 if (F == 0)
695 {
696 std::cerr << "multi2d: left hand side not initialized in =" << std::endl;
697 exit(1);
698 }
699
700 for(int i=0; i < sz; ++i)
701 F[i] = s1;
702 return *this;
703 }
704
706 const T* slice(int j) const {return F+n1*j;}
707
709 T& operator()(int j, int i) {return F[i+n1*j];}
710
712 const T& operator()(int j, int i) const {return F[i+n1*j];}
713
715 multi1d<T> operator[](int j) {return multi1d<T>(F+j*n1,n1);}
716
718 const multi1d<T> operator[](int j) const {return multi1d<T>(F+j*n1,n1);}
719
720private:
721 bool copymem;
722 int n1;
723 int n2;
724 int sz;
725 T *F;
726};
727
728
729
730//------------------------------------------------------------------------------------------
732template<class T> class multi3d
733{
734public:
735 multi3d() {F=0;n1=n2=n3=sz=0;copymem=false;}
736 multi3d(T *f, int ns3, int ns2, int ns1) {F=f; n1=ns1; n2=ns2; n3=ns3; sz=n1*n2*n3; copymem=true;}
737 explicit multi3d(int ns3, int ns2, int ns1) {copymem=false;F=0;resize(ns3,ns2,ns1);}
738 ~multi3d() {if (! copymem) {delete[] F;}}
739
741 multi3d(const multi3d& s): copymem(false), n1(s.n1), n2(s.n2), n3(s.n3), sz(s.sz), F(0)
742 {
743 resize(n3,n2,n1);
744
745 for(int i=0; i < sz; ++i)
746 F[i] = s.F[i];
747 }
748
750 void resize(int ns3, int ns2, int ns1)
751 {
752 if(copymem) {
753 std::cerr <<"multi3d: invalid resize of a copy of memory" << std::endl;
754 exit(1);
755 }
756
757 // Only delete if the array is not NULL. If it is NULL
758 // deleting may be bad
759 if ( F != 0x0 ) {
760 delete[] F;
761 }
762
763 n1=ns1; n2=ns2; n3=ns3; sz=n1*n2*n3; F = new(std::nothrow) T[sz];
764 if( F == 0x0 ) {
765 QDP_error_exit("Unable to new memory in multi3d::resize(%d,%d,%d)\n",ns3,ns2,ns1);
766 }
767 }
768
770 int size1() const {return n1;}
771 int size2() const {return n2;}
772 int size3() const {return n3;}
773
775 int leftSize() const {return n3;}
776 int middleSize() const {return n2;}
777 int rightSize() const {return n1;}
778
781 {
782 resize(s1.size3(), s1.size2(), s1.size1());
783
784 for(int i=0; i < sz; ++i)
785 F[i] = s1.F[i];
786 return *this;
787 }
788
790 template<class T1>
791 multi3d<T>& operator=(const T1& s1)
792 {
793 if (F == 0)
794 {
795 std::cerr << "multi3d: left hand side not initialized in =" << std::endl;
796 exit(1);
797 }
798
799 for(int i=0; i < sz; ++i)
800 F[i] = s1;
801 return *this;
802 }
803
805 const T* slice(int k, int j) const {return F+n1*(j+n2*(k));}
806
808 T& operator()(int k, int j, int i) {return F[i+n1*(j+n2*(k))];}
809
811 const T& operator()(int k, int j, int i) const {return F[i+n1*(j+n2*(k))];}
812
814 multi2d<T> operator[](int k) {return multi2d<T>(F+n1*n2*k,n2,n1);}
815
817 const multi2d<T> operator[](int k) const {return multi2d<T>(F+n1*n2*k,n2,n1);}
818
819private:
820 bool copymem;
821 int n1;
822 int n2;
823 int n3;
824 int sz;
825 T *F;
826};
827
828
829//------------------------------------------------------------------------------------------
831template<class T> class multi4d
832{
833public:
834 multi4d() {F=0;n1=n2=n3=n4=sz=0;copymem=false;}
835 multi4d(T *f, int ns4, int ns3, int ns2, int ns1) {F=f; n1=ns1; n2=ns2; n3=ns3; n4=ns4; sz=n1*n2*n3*n4; copymem=true;}
836 explicit multi4d(int ns4, int ns3, int ns2, int ns1) {copymem=false;F=0;resize(ns4,ns3,ns2,ns1);}
837 ~multi4d() {if (! copymem) {delete[] F;}}
838
840 multi4d(const multi4d& s): copymem(false), n1(s.n1), n2(s.n2), n3(s.n3), n4(s.n4), sz(s.sz), F(0)
841 {
842 resize(n4,n3,n2,n1);
843
844 for(int i=0; i < sz; ++i)
845 F[i] = s.F[i];
846 }
847
849 void resize(int ns4, int ns3, int ns2, int ns1)
850 {
851 if(copymem) {
852 std::cerr <<"multi4d: invalid resize of a copy of memory" << std::endl;
853 exit(1);
854 }
855
856 // Only delete if the array is not NULL. If it is NULL
857 // deleting may be bad
858 if ( F != 0x0 ) {
859 delete[] F;
860 }
861
862 n1=ns1; n2=ns2; n3=ns3; n4=ns4; sz=n1*n2*n3*n4; F = new(std::nothrow) T[sz];
863 if( F == 0x0 ) {
864 QDP_error_exit("Unable to new memory in multi4d::resize(%d,%d,%d,%d)\n",ns4,ns3,ns2,ns1);
865 }
866 }
867
869 int size1() const {return n1;}
870 int size2() const {return n2;}
871 int size3() const {return n3;}
872 int size4() const {return n4;}
873
876 {
877 resize(s1.size4(),s1.size3(),s1.size2(),s1.size1());
878
879 for(int i=0; i < sz; ++i)
880 F[i] = s1.F[i];
881 return *this;
882 }
883
885 template<class T1>
886 multi4d<T>& operator=(const T1& s1)
887 {
888 if (F == 0)
889 {
890 std::cerr << "multi4d: left hand side not initialized in =" << std::endl;
891 exit(1);
892 }
893
894 for(int i=0; i < sz; ++i)
895 F[i] = s1;
896 return *this;
897 }
898
900 const T* slice(int l, int k, int j) const {return F+n1*(j+n2*(k+n3*(l)));}
901
903 T& operator()(int l, int k, int j, int i) {return F[i+n1*(j+n2*(k+n3*(l)))];}
904
906 const T& operator()(int l, int k, int j, int i) const {return F[i+n1*(j+n2*(k+n3*(l)))];}
907
909 multi3d<T> operator[](int l) {return multi3d<T>(F+n1*n2*n3*l,n3,n2,n1);}
910
912 const multi3d<T> operator[](int l) const {return multi3d<T>(F+n1*n2*n3*l,n3,n2,n1);}
913
914private:
915 bool copymem;
916 int n1;
917 int n2;
918 int n3;
919 int n4;
920 int sz;
921 T *F;
922};
923
924
925//------------------------------------------------------------------------------------------
927template<class T> class multi5d
928{
929public:
930 multi5d() {F=0;n1=n2=n3=n4=n5=sz=0;copymem=false;}
931 multi5d(T *f, int ns5, int ns4, int ns3, int ns2, int ns1) {F=f; n1=ns1; n2=ns2; n3=ns3; n4=ns4; n5=ns5; sz=n1*n2*n3*n4*n5; copymem=true;}
932 explicit multi5d(int ns4, int ns3, int ns2, int ns1) {copymem=false;F=0;resize(ns4,ns3,ns2,ns1);}
933 ~multi5d() {if (! copymem) {delete[] F;}}
934
936 multi5d(const multi5d& s): copymem(false), n1(s.n1), n2(s.n2), n3(s.n3), n4(s.n4), n5(s.n5), sz(s.sz), F(0)
937 {
938 resize(n5,n4,n3,n2,n1);
939
940 for(int i=0; i < sz; ++i)
941 F[i] = s.F[i];
942 }
943
945 void resize(int ns5, int ns4, int ns3, int ns2, int ns1)
946 {
947 if(copymem) {
948 std::cerr <<"multi5d: invalid resize of a copy of memory" << std::endl;
949 exit(1);
950 }
951
952 // Only delete if the array is not NULL. If it is NULL
953 // deleting may be bad
954 if ( F != 0x0 ) {
955 delete[] F;
956 }
957
958 n1=ns1; n2=ns2; n3=ns3; n4=ns4; n5=ns5; sz=n1*n2*n3*n4*n5; F = new(std::nothrow) T[sz];
959 if( F == 0x0 ) {
960 QDP_error_exit("Unable to new memory in multi5d::resize(%d,%d,%d,%d,%d)\n",ns5,ns4,ns3,ns2,ns1);
961 }
962 }
963
965 int size1() const {return n1;}
966 int size2() const {return n2;}
967 int size3() const {return n3;}
968 int size4() const {return n4;}
969 int size5() const {return n5;}
970
973 {
974 resize(s1.size5(),s1.size4(),s1.size3(),s1.size2(),s1.size1());
975
976 for(int i=0; i < sz; ++i)
977 F[i] = s1.F[i];
978 return *this;
979 }
980
982 template<class T1>
983 multi5d<T>& operator=(const T1& s1)
984 {
985 if (F == 0)
986 {
987 std::cerr << "multi5d: left hand side not initialized in =" << std::endl;
988 exit(1);
989 }
990
991 for(int i=0; i < sz; ++i)
992 F[i] = s1;
993 return *this;
994 }
995
997 const T* slice(int m, int l, int k, int j) const{return F+n1*(j+n2*(k+n3*(l+n4*(m))));}
998
1000 T& operator()(int m, int l, int k, int j, int i) {return F[i+n1*(j+n2*(k+n3*(l+n4*(m))))];}
1001
1003 const T& operator()(int m, int l, int k, int j, int i) const {return F[i+n1*(j+n2*(k+n3*(l+n4*(m))))];}
1004
1006 multi4d<T> operator[](int m) {return multi4d<T>(F+n1*n2*n3*n4*m,n4,n3,n2,n1);}
1007
1009 const multi4d<T> operator[](int m) const {return multi4d<T>(F+n1*n2*n3*n4*m,n4,n3,n2,n1);}
1010
1011private:
1012 bool copymem;
1013 int n1;
1014 int n2;
1015 int n3;
1016 int n4;
1017 int n5;
1018 int sz;
1019 T *F;
1020};
1021
1022
1023//------------------------------------------------------------------------------------------
1025template<class T> class multiNd
1026{
1027public:
1028 multiNd() {F=0;}
1029 explicit multiNd(const multi1d<int>& _nz) {F=0;resize(_nz);}
1030 ~multiNd() {delete[] F;}
1031
1033 multiNd(const multiNd& s): nz(s.nz), sz(s.sz), F(0)
1034 {
1035 resize(nz);
1036
1037 for(int i=0; i < sz; ++i)
1038 F[i] = s.F[i];
1039 }
1040
1042 void resize(const multi1d<int>& _nz)
1043 {
1044 delete[] F;
1045 nz = _nz;
1046 sz = nz[0];
1047 for(int i=1; i < nz.size(); ++i)
1048 sz *= nz[i];
1049 F = new(std::nothrow) T[sz];
1050 if ( F==0x0 ) {
1051 std::cerr << "Unable to new memory in multiNd::resize(): sz= " << sz << " size= ";
1052 for(int i=0; i < _nz.size(); ++i) {
1053 std::cerr << " " << _nz[i];
1054 }
1055 std::cerr << std::endl;
1056 QDP_abort(1);
1057 }
1058 }
1059
1061
1062 int size(int i) const {return nz[i];}
1063
1065
1066 const multi1d<int>& size() const {return nz;}
1067
1069
1070 int numElem() const {return sz;}
1071
1074 {
1075 resize(s1.size());
1076
1077 for(int i=0; i < sz; ++i)
1078 F[i] = s1.F[i];
1079 return *this;
1080 }
1081
1083 template<class T1>
1084 multiNd<T>& operator=(const T1& s1)
1085 {
1086 if (F == 0)
1087 {
1088 std::cerr << "multiNd: left hand side not initialized in =" << std::endl;
1089 exit(1);
1090 }
1091
1092 for(int i=0; i < sz; ++i)
1093 F[i] = s1;
1094 return *this;
1095 }
1096
1098 T& operator()(int i)
1099 {
1100 if (nz.size() != 1)
1101 {
1102 std::cerr << "multiNd: improper rank of array indices" << std::endl;
1103 exit(1);
1104 }
1105
1106 return F[i];
1107 }
1108
1110 const T& operator()(int i) const
1111 {
1112 if (nz.size() != 1)
1113 {
1114 std::cerr << "multiNd: improper rank of array indices" << std::endl;
1115 exit(1);
1116 }
1117
1118 return F[i];
1119 }
1120
1122 T& operator()(int j, int i)
1123 {
1124 if (nz.size() != 2)
1125 {
1126 std::cerr << "multiNd: improper rank of array indices" << std::endl;
1127 exit(1);
1128 }
1129
1130 return F[i+nz[0]*j];
1131 }
1132
1134 const T& operator()(int j, int i) const
1135 {
1136 if (nz.size() != 2)
1137 {
1138 std::cerr << "multiNd: improper rank of array indices" << std::endl;
1139 exit(1);
1140 }
1141
1142 return F[i+nz[0]*j];
1143 }
1144
1146 T& operator()(int k, int j, int i)
1147 {
1148 if (nz.size() != 3)
1149 {
1150 std::cerr << "multiNd: improper rank of array indices" << std::endl;
1151 exit(1);
1152 }
1153
1154 return F[i+nz[0]*(j+nz[1]*(k))];
1155 }
1156
1158 const T& operator()(int k, int j, int i) const
1159 {
1160 if (nz.size() != 3)
1161 {
1162 std::cerr << "multiNd: improper rank of array indices" << std::endl;
1163 exit(1);
1164 }
1165
1166 return F[i+nz[0]*(j+nz[1]*(k))];
1167 }
1168
1170 T& operator()(int l, int k, int j, int i)
1171 {
1172 if (nz.size() != 4)
1173 {
1174 std::cerr << "multiNd: improper rank of array indices" << std::endl;
1175 exit(1);
1176 }
1177
1178 return F[i+nz[0]*(j+nz[1]*(k+nz[2]*l))];
1179 }
1180
1182 const T& operator()(int l, int k, int j, int i) const
1183 {
1184 if (nz.size() != 4)
1185 {
1186 std::cerr << "multiNd: improper rank of array indices" << std::endl;
1187 exit(1);
1188 }
1189
1190 return F[i+nz[0]*(j+nz[1]*(k+nz[2]*l))];
1191 }
1192
1195 {
1196 if (ind.size() != nz.size())
1197 {
1198 std::cerr << "multiNd: improper rank of array indices" << std::endl;
1199 exit(1);
1200 }
1201
1202 int off = ind[0];
1203 for(int i=1; i < nz.size(); ++i)
1204 off = off*nz[i] + ind[i];
1205
1206 return F[off];
1207 }
1208
1210 const T& operator[](const multi1d<int>& ind) const
1211 {
1212 if (ind.size() != nz.size())
1213 {
1214 std::cerr << "multiNd: improper rank of array indices" << std::endl;
1215 exit(1);
1216 }
1217
1218 int off = ind[0];
1219 for(int i=1; i < nz.size(); ++i)
1220 off = off*nz[i] + ind[i];
1221
1222 return F[off];
1223 }
1224
1226
1227 T& getElem(int off)
1228 {
1229 if (off < 0 || off >= sz)
1230 {
1231 std::cerr << "multiNd: index out of bounds" << std::endl;
1232 exit(1);
1233 }
1234
1235 return F[off];
1236 }
1237
1239
1240 const T& getElem(int off) const
1241 {
1242 if (off < 0 || off >= sz)
1243 {
1244 std::cerr << "multiNd: index out of bounds" << std::endl;
1245 exit(1);
1246 }
1247
1248 return F[off];
1249 }
1250
1251private:
1252 multi1d<int> nz;
1253 int sz;
1254 T *F;
1255};
1256 // end of group multi
1258
1259}
1260
1261#endif
Container for a multi-dimensional 1D array.
Definition qdp_multi.h:25
const T & operator[](int i) const
Return const ref to an element.
Definition qdp_multi.h:237
void revertFromFastMemoryHint(bool copy=false)
Definition qdp_multi.h:249
multi1d< T > & operator=(const T *s1)
Set equal to a old-style C 1-D array.
Definition qdp_multi.h:91
int size1() const
Definition qdp_multi.h:61
multi1d< T > & operator-=(const T &s1)
Subtract-replace on each element.
Definition qdp_multi.h:151
multi1d< T > & operator+=(const T &s1)
Add-replace on each element.
Definition qdp_multi.h:121
const T & operator()(int i) const
Return const ref to an element.
Definition qdp_multi.h:231
multi1d< T > & operator/=(const multi1d< T > &s1)
Divide-replace on each element.
Definition qdp_multi.h:196
multi1d< T > & operator-=(const multi1d< T > &s1)
Subtract-replace on each element.
Definition qdp_multi.h:136
void moveToFastMemoryHint(bool copy=false)
Definition qdp_multi.h:242
multi1d & operator=(const multi1d &s1)
Equal operator uses underlying = of T.
Definition qdp_multi.h:65
T & operator[](int i)
Return ref to an element.
Definition qdp_multi.h:234
multi1d< T > & operator=(const T1 &s1)
Equal operator uses underlying = of T.
Definition qdp_multi.h:77
multi1d< T > & operator+=(const multi1d< T > &s1)
Add-replace on each element.
Definition qdp_multi.h:106
multi1d(const multi1d &s)
Copy constructor.
Definition qdp_multi.h:46
int size() const
Size of array.
Definition qdp_multi.h:60
T & operator()(int i)
Return ref to an element.
Definition qdp_multi.h:228
void resize(int ns1)
Resize routine, call a templated resize, using *this to disambiguate.
Definition qdp_multi.h:56
const T * slice() const
Return ref to a column slice.
Definition qdp_multi.h:225
multi1d(T *f, int ns1)
Definition qdp_multi.h:31
multi1d< T > & operator*=(const multi1d< T > &s1)
Mult-replace on each element.
Definition qdp_multi.h:166
multi1d(int ns1)
Definition qdp_multi.h:34
multi1d< T > & operator/=(const T &s1)
Divide-replace on each element.
Definition qdp_multi.h:211
multi1d< T > & operator*=(const T &s1)
Mult-replace on each element.
Definition qdp_multi.h:181
Container for a multi-dimensional 2D array.
Definition qdp_multi.h:640
void resize(int ns2, int ns1)
Allocate mem for the array.
Definition qdp_multi.h:657
multi2d< T > & operator=(const T1 &s1)
Equal operator uses underlying = of T.
Definition qdp_multi.h:692
const T * slice(int j) const
Return ref to a row slice.
Definition qdp_multi.h:706
multi2d(const multi2d &s)
Copy constructor.
Definition qdp_multi.h:648
T & operator()(int j, int i)
Return ref to an element.
Definition qdp_multi.h:709
int size1() const
Size of array.
Definition qdp_multi.h:673
multi1d< T > operator[](int j)
Return ref to an element.
Definition qdp_multi.h:715
multi2d(int ns2, int ns1)
Definition qdp_multi.h:644
int ncols() const
Definition qdp_multi.h:678
const T & operator()(int j, int i) const
Return const ref to an element.
Definition qdp_multi.h:712
int size2() const
Definition qdp_multi.h:674
int nrows() const
Another variant on the size of the 2d array.
Definition qdp_multi.h:677
multi2d< T > & operator=(const multi2d< T > &s1)
Equal operator uses underlying = of T.
Definition qdp_multi.h:681
const multi1d< T > operator[](int j) const
Return const ref to an element.
Definition qdp_multi.h:718
multi2d(T *f, int ns2, int ns1)
Definition qdp_multi.h:643
Container for a multi-dimensional 3D array.
Definition qdp_multi.h:733
int size3() const
Definition qdp_multi.h:772
multi2d< T > operator[](int k)
Return ref to an element.
Definition qdp_multi.h:814
const T * slice(int k, int j) const
Return ref to a column slice.
Definition qdp_multi.h:805
T & operator()(int k, int j, int i)
Return ref to an element.
Definition qdp_multi.h:808
multi3d< T > & operator=(const T1 &s1)
Equal operator uses underlying = of T.
Definition qdp_multi.h:791
multi3d(const multi3d &s)
Copy constructor.
Definition qdp_multi.h:741
int leftSize() const
Another variant on the size of the 3d array.
Definition qdp_multi.h:775
int size1() const
Size of array.
Definition qdp_multi.h:770
int size2() const
Definition qdp_multi.h:771
multi3d(T *f, int ns3, int ns2, int ns1)
Definition qdp_multi.h:736
const multi2d< T > operator[](int k) const
Return const ref to an element.
Definition qdp_multi.h:817
multi3d(int ns3, int ns2, int ns1)
Definition qdp_multi.h:737
const T & operator()(int k, int j, int i) const
Return const ref to an element.
Definition qdp_multi.h:811
void resize(int ns3, int ns2, int ns1)
Allocate mem for the array.
Definition qdp_multi.h:750
multi3d< T > & operator=(const multi3d< T > &s1)
Equal operator uses underlying = of T.
Definition qdp_multi.h:780
int middleSize() const
Definition qdp_multi.h:776
int rightSize() const
Definition qdp_multi.h:777
Container for a multi-dimensional 4D array.
Definition qdp_multi.h:832
int size1() const
Size of array.
Definition qdp_multi.h:869
const T * slice(int l, int k, int j) const
Return ref to a column slice.
Definition qdp_multi.h:900
int size4() const
Definition qdp_multi.h:872
T & operator()(int l, int k, int j, int i)
Return ref to an element.
Definition qdp_multi.h:903
multi4d< T > & operator=(const multi4d< T > &s1)
Equal operator uses underlying = of T.
Definition qdp_multi.h:875
multi4d(int ns4, int ns3, int ns2, int ns1)
Definition qdp_multi.h:836
const T & operator()(int l, int k, int j, int i) const
Return const ref to an element.
Definition qdp_multi.h:906
int size3() const
Definition qdp_multi.h:871
multi4d< T > & operator=(const T1 &s1)
Equal operator uses underlying = of T.
Definition qdp_multi.h:886
const multi3d< T > operator[](int l) const
Return const ref to an element.
Definition qdp_multi.h:912
multi4d(T *f, int ns4, int ns3, int ns2, int ns1)
Definition qdp_multi.h:835
int size2() const
Definition qdp_multi.h:870
multi4d(const multi4d &s)
Copy constructor.
Definition qdp_multi.h:840
multi3d< T > operator[](int l)
Return ref to an element.
Definition qdp_multi.h:909
void resize(int ns4, int ns3, int ns2, int ns1)
Allocate mem for the array.
Definition qdp_multi.h:849
multi5d< T > & operator=(const T1 &s1)
Equal operator uses underlying = of T.
Definition qdp_multi.h:983
int size2() const
Definition qdp_multi.h:966
int size1() const
Size of array.
Definition qdp_multi.h:965
const multi4d< T > operator[](int m) const
Return const ref to an element.
Definition qdp_multi.h:1009
int size4() const
Definition qdp_multi.h:968
multi5d< T > & operator=(const multi5d< T > &s1)
Equal operator uses underlying = of T.
Definition qdp_multi.h:972
multi5d(const multi5d &s)
Copy constructor.
Definition qdp_multi.h:936
int size5() const
Definition qdp_multi.h:969
void resize(int ns5, int ns4, int ns3, int ns2, int ns1)
Allocate mem for the array.
Definition qdp_multi.h:945
const T & operator()(int m, int l, int k, int j, int i) const
Return const ref to an element.
Definition qdp_multi.h:1003
multi4d< T > operator[](int m)
Return ref to an element.
Definition qdp_multi.h:1006
multi5d(int ns4, int ns3, int ns2, int ns1)
Definition qdp_multi.h:932
T & operator()(int m, int l, int k, int j, int i)
Return ref to an element.
Definition qdp_multi.h:1000
multi5d(T *f, int ns5, int ns4, int ns3, int ns2, int ns1)
Definition qdp_multi.h:931
int size3() const
Definition qdp_multi.h:967
const T * slice(int m, int l, int k, int j) const
Return ref to a column slice.
Definition qdp_multi.h:997
const T & operator[](const multi1d< int > &ind) const
Return ref to an element via indices packed in a multi1d array.
Definition qdp_multi.h:1210
T & operator()(int k, int j, int i)
Return ref to an element.
Definition qdp_multi.h:1146
T & operator[](const multi1d< int > &ind)
Return ref to an element via indices packed in a multi1d array.
Definition qdp_multi.h:1194
void resize(const multi1d< int > &_nz)
Allocate mem for the array.
Definition qdp_multi.h:1042
T & operator()(int l, int k, int j, int i)
Return ref to an element.
Definition qdp_multi.h:1170
T & getElem(int off)
Return ref to an element with index flattened over indices.
Definition qdp_multi.h:1227
multiNd< T > & operator=(const T1 &s1)
Equal operator uses underlying = of T.
Definition qdp_multi.h:1084
T & operator()(int i)
Return ref to an element.
Definition qdp_multi.h:1098
multiNd(const multi1d< int > &_nz)
Definition qdp_multi.h:1029
const T & operator()(int l, int k, int j, int i) const
Return const ref to an element.
Definition qdp_multi.h:1182
const multi1d< int > & size() const
Size of an array containing sizes of each index.
Definition qdp_multi.h:1066
int size(int i) const
Size of i-th array index. Indices run from left to right in operator().
Definition qdp_multi.h:1062
const T & operator()(int k, int j, int i) const
Return const ref to an element.
Definition qdp_multi.h:1158
int numElem() const
Number of elements in the array.
Definition qdp_multi.h:1070
const T & getElem(int off) const
Return const-ref to an element with index flattened over indices.
Definition qdp_multi.h:1240
const T & operator()(int j, int i) const
Return const ref to an element.
Definition qdp_multi.h:1134
multiNd< T > & operator=(const multiNd< T > &s1)
Equal operator uses underlying = of T.
Definition qdp_multi.h:1073
const T & operator()(int i) const
Return const ref to an element.
Definition qdp_multi.h:1110
T & operator()(int j, int i)
Return ref to an element.
Definition qdp_multi.h:1122
multiNd(const multiNd &s)
Copy constructor.
Definition qdp_multi.h:1033
UnaryReturn< C, FnNorm2 >::Type_t norm2(const QDPType< T, C > &s1)
OScalar = norm2(trace(adj(source)*source)).
multi1d< T > concat(const multi1d< T > &l, const multi1d< T > &r)
Concatenate two Array's.
Definition qdp_multi.h:292
Yet another random number generator.
MakeReturn< BinaryNode< OpEQ, typenameCreateLeaf< QDPType< T1, C1 > >::Leaf_t, typenameCreateLeaf< QDPExpr< T2, C2 > >::Leaf_t >, typenameBinaryReturn< C1, C2, OpEQ >::Type_t >::Expression_t operator==(const QDPType< T1, C1 > &l, const QDPExpr< T2, C2 > &r)
Definition qdp.h:2812
MakeReturn< BinaryNode< OpGT, typenameCreateLeaf< QDPType< T1, C1 > >::Leaf_t, typenameCreateLeaf< QDPExpr< T2, C2 > >::Leaf_t >, typenameBinaryReturn< C1, C2, OpGT >::Type_t >::Expression_t operator>(const QDPType< T1, C1 > &l, const QDPExpr< T2, C2 > &r)
Definition qdp.h:2780
void QDP_error_exit(const char *format,...)
Simple error display and abort routine.
Definition qdp_util.cc:93
MakeReturn< BinaryNode< OpMultiply, typenameCreateLeaf< QDPType< T1, C1 > >::Leaf_t, typenameCreateLeaf< QDPExpr< T2, C2 > >::Leaf_t >, typenameBinaryReturn< C1, C2, OpMultiply >::Type_t >::Expression_t operator*(const QDPType< T1, C1 > &l, const QDPExpr< T2, C2 > &r)
Definition qdp.h:2588
MakeReturn< BinaryNode< OpAdd, typenameCreateLeaf< QDPType< T1, C1 > >::Leaf_t, typenameCreateLeaf< QDPExpr< T2, C2 > >::Leaf_t >, typenameBinaryReturn< C1, C2, OpAdd >::Type_t >::Expression_t operator+(const QDPType< T1, C1 > &l, const QDPExpr< T2, C2 > &r)
Definition qdp.h:2556
MakeReturn< UnaryNode< FnCos, typenameCreateLeaf< QDPExpr< T1, C1 > >::Leaf_t >, typenameUnaryReturn< C1, FnCos >::Type_t >::Expression_t cos(const QDPExpr< T1, C1 > &l)
Definition qdp.h:5336
MakeReturn< BinaryNode< OpSubtract, typenameCreateLeaf< QDPType< T1, C1 > >::Leaf_t, typenameCreateLeaf< QDPExpr< T2, C2 > >::Leaf_t >, typenameBinaryReturn< C1, C2, OpSubtract >::Type_t >::Expression_t operator-(const QDPType< T1, C1 > &l, const QDPExpr< T2, C2 > &r)
Definition qdp.h:2572
MakeReturn< UnaryNode< FnArcTan, typenameCreateLeaf< QDPExpr< T1, C1 > >::Leaf_t >, typenameUnaryReturn< C1, FnArcTan >::Type_t >::Expression_t atan(const QDPExpr< T1, C1 > &l)
Definition qdp.h:5310
MakeReturn< UnaryNode< FnArcSin, typenameCreateLeaf< QDPExpr< T1, C1 > >::Leaf_t >, typenameUnaryReturn< C1, FnArcSin >::Type_t >::Expression_t asin(const QDPExpr< T1, C1 > &l)
Definition qdp.h:5297
MakeReturn< BinaryNode< OpGE, typenameCreateLeaf< QDPType< T1, C1 > >::Leaf_t, typenameCreateLeaf< QDPExpr< T2, C2 > >::Leaf_t >, typenameBinaryReturn< C1, C2, OpGE >::Type_t >::Expression_t operator>=(const QDPType< T1, C1 > &l, const QDPExpr< T2, C2 > &r)
Definition qdp.h:2796
void QDP_abort(int status)
Panic button.
MakeReturn< BinaryNode< OpDivide, typenameCreateLeaf< QDPType< T1, C1 > >::Leaf_t, typenameCreateLeaf< QDPExpr< T2, C2 > >::Leaf_t >, typenameBinaryReturn< C1, C2, OpDivide >::Type_t >::Expression_t operator/(const QDPType< T1, C1 > &l, const QDPExpr< T2, C2 > &r)
Definition qdp.h:2604
MakeReturn< UnaryNode< FnSin, typenameCreateLeaf< QDPExpr< T1, C1 > >::Leaf_t >, typenameUnaryReturn< C1, FnSin >::Type_t >::Expression_t sin(const QDPExpr< T1, C1 > &l)
Definition qdp.h:5427
MakeReturn< UnaryNode< FnArcCos, typenameCreateLeaf< QDPExpr< T1, C1 > >::Leaf_t >, typenameUnaryReturn< C1, FnArcCos >::Type_t >::Expression_t acos(const QDPExpr< T1, C1 > &l)
Definition qdp.h:5284
MakeReturn< BinaryNode< OpLT, typenameCreateLeaf< QDPType< T1, C1 > >::Leaf_t, typenameCreateLeaf< QDPExpr< T2, C2 > >::Leaf_t >, typenameBinaryReturn< C1, C2, OpLT >::Type_t >::Expression_t operator<(const QDPType< T1, C1 > &l, const QDPExpr< T2, C2 > &r)
Definition qdp.h:2748
MakeReturn< BinaryNode< OpNE, typenameCreateLeaf< QDPType< T1, C1 > >::Leaf_t, typenameCreateLeaf< QDPExpr< T2, C2 > >::Leaf_t >, typenameBinaryReturn< C1, C2, OpNE >::Type_t >::Expression_t operator!=(const QDPType< T1, C1 > &l, const QDPExpr< T2, C2 > &r)
Definition qdp.h:2828
MakeReturn< UnaryNode< FnSqrt, typenameCreateLeaf< QDPExpr< T1, C1 > >::Leaf_t >, typenameUnaryReturn< C1, FnSqrt >::Type_t >::Expression_t sqrt(const QDPExpr< T1, C1 > &l)
Definition qdp.h:5453
MakeReturn< UnaryNode< FnTan, typenameCreateLeaf< QDPExpr< T1, C1 > >::Leaf_t >, typenameUnaryReturn< C1, FnTan >::Type_t >::Expression_t tan(const QDPExpr< T1, C1 > &l)
Definition qdp.h:5466
MakeReturn< BinaryNode< OpLE, typenameCreateLeaf< QDPType< T1, C1 > >::Leaf_t, typenameCreateLeaf< QDPExpr< T2, C2 > >::Leaf_t >, typenameBinaryReturn< C1, C2, OpLE >::Type_t >::Expression_t operator<=(const QDPType< T1, C1 > &l, const QDPExpr< T2, C2 > &r)
Definition qdp.h:2764
MakeReturn< UnaryNode< FnLog, typenameCreateLeaf< QDPExpr< T1, C1 > >::Leaf_t >, typenameUnaryReturn< C1, FnLog >::Type_t >::Expression_t log(const QDPExpr< T1, C1 > &l)
Definition qdp.h:5401