QDP++
qdp_primseed.h
Go to the documentation of this file.
1// -*- C++ -*-
2
6
7
8#ifndef QDP_PRIMSEED_H
9#define QDP_PRIMSEED_H
10
11namespace QDP {
12
13//-------------------------------------------------------------------------------------
22
23
25
33template <class T> class PSeed
34{
35public:
36 PSeed() {}
37 ~PSeed() {}
38
40 template<class T1>
41 PSeed(const PScalar<T1>& rhs)
42 {
43 assign(rhs);
44 }
45
46
48
49 template<class T1>
50 inline
51 PSeed& assign(const PScalar<T1>& rhs)
52 {
53 typedef typename InternalScalar<T1>::Type_t S;
54
55 elem(0) = rhs.elem() & S(4095);
56 elem(1) = (rhs.elem() >> S(12)) & S(4095);
57 elem(2) = (rhs.elem() >> S(24)) & S(4095);
58// elem(3) = (rhs.elem() >> S(36)) & S(2047); // This probably will never be nonzero
59 zero_rep(elem(3)); // assumes 32 bit integers
60
61 return *this;
62 }
63
65
66 template<class T1>
67 inline
69 {
70 return assign(rhs);
71 }
72
74
75 template<class T1>
76 inline
78 {
79 for(int i=0; i < 4; ++i)
80 elem(i) = rhs.elem(i);
81
82 return *this;
83 }
84
86#if defined(QDP_USE_ARRAY_INITIALIZER)
88 PSeed(const PSeed& a) : F(a.F) {}
89#else
91 PSeed(const PSeed& a)
92 {
93 for(int i=0; i < 4; ++i)
94 F[i] = a.F[i];
95 }
96#endif
97
98public:
99 T& elem(int i) {return F[i];}
100 const T& elem(int i) const {return F[i];}
101
102private:
103 T F[4];
104};
105
106
108template<class T>
109inline
110std::istream& operator>>(std::istream& s, PSeed<T>& d)
111{
112 for(int i=0; i < 4; ++i)
113 s >> d.elem(i);
114
115 return s;
116}
117
119template<class T>
120inline
122{
123 for(int i=0; i < 4; ++i)
124 s >> d.elem(i);
125
126 return s;
127}
128
130template<class T>
131inline
132std::ostream& operator<<(std::ostream& s, const PSeed<T>& d)
133{
134 s << d.elem(0) << " " << d.elem(1) << " " << d.elem(2) << " " << d.elem(3) << "\n";
135 return s;
136}
137
139template<class T>
140inline
142{
143 s << d.elem(0) << " " << d.elem(1) << " " << d.elem(2) << " " << d.elem(3) << "\n";
144 return s;
145}
146
148template<class T>
149inline
151{
152 for(int i=0; i < 4; ++i)
153 txt >> d.elem(i);
154
155 return txt;
156}
157
159template<class T>
160inline
162{
163 for(int i=0; i < 4; ++i)
164 txt << d.elem(i) << "\n";
165
166 return txt;
167}
168
169#ifdef QDP_USE_LIBXML2
171template<class T>
172inline
173XMLWriter& operator<<(XMLWriter& xml, const PSeed<T>& d)
174{
175 xml.openTag("Seed");
176
177 // Copy into another array first
178 for(int i=0; i < 4; ++i)
179 {
180 xml.openTag("elem");
181 xml << d.elem(i);
182 xml.closeTag();
183 }
184
185 xml.closeTag(); // Seed
186 return xml;
187}
188
189
191template<class T>
192inline
193void read(XMLReader& xml, const std::string& path, PSeed<T>& d)
194{
195 typedef typename PrimitiveScalar<T>::Type_t S;
196 multi1d<S> ff(4);
197
198 read(xml, path + "/Seed", ff);
199
200 for(int i=0; i < 4; ++i)
201 {
202 d.elem(i) = S(ff[i]);
203 }
204}
205
206#endif // end of group primseed
208
209//-----------------------------------------------------------------------------
210// Traits classes
211//-----------------------------------------------------------------------------
212
213// Underlying word type
214template<class T1>
215struct WordType<PSeed<T1> >
216{
217 typedef typename WordType<T1>::Type_t Type_t;
218};
219
220// Fixed Precision versions (do these even make sense? )
221
222template<class T1>
227
228template<class T1>
233
234
235// Internally used scalars
236template<class T>
240
241// Makes a primitive scalar leaving grid alone
242template<class T>
246
247// Makes a lattice scalar leaving primitive indices alone
248template<class T>
252
253
254//-----------------------------------------------------------------------------
255// Traits classes to support return types
256//-----------------------------------------------------------------------------
257
258// Assignment is different
259template<class T1, class T2 >
260struct BinaryReturn<PSeed<T1>, PSeed<T2>, OpAssign > {
262};
263
264
265
266//-----------------------------------------------------------------------------
267// Operators
268//-----------------------------------------------------------------------------
269
270// PScalar = (PSeed == PSeed)
271template<class T1, class T2>
275
276template<class T1, class T2>
278operator==(const PSeed<T1>& l, const PSeed<T2>& r)
279{
280 return
281 (l.elem(0) == r.elem(0)) &&
282 (l.elem(1) == r.elem(1)) &&
283 (l.elem(2) == r.elem(2)) &&
284 (l.elem(3) == r.elem(3));
285}
286
287
288// PScalar = (Seed != Seed)
289template<class T1, class T2>
293
294template<class T1, class T2>
296operator!=(const PSeed<T1>& l, const PSeed<T2>& r)
297{
298 return
299 (l.elem(0) != r.elem(0)) ||
300 (l.elem(1) != r.elem(1)) ||
301 (l.elem(2) != r.elem(2)) ||
302 (l.elem(3) != r.elem(3));
303}
304
305
309
310// Primitive Seeds
311
313
332template<class T1, class T2>
336
337template<class T1, class T2>
339operator*(const PSeed<T1>& s1, const PSeed<T2>& s2)
340{
343 typedef typename InternalScalar<T>::Type_t S;
344 T i0, i1, i2, i3;
345
346 /* i3 = s1(3)*s2(0) + s1(2)*s2(1) + s1(1)*s2(2) + s1(0)*s2(3) */
347 i3 = s1.elem(3) * s2.elem(0);
348 i3 += s1.elem(2) * s2.elem(1);
349 i3 += s1.elem(1) * s2.elem(2);
350 i3 += s1.elem(0) * s2.elem(3);
351
352 /* i2 = s1(2)*s2(0) + s1(1)*s2(1) + s1(0)*s2(2) */
353 i2 = s1.elem(2) * s2.elem(0);
354 i2 += s1.elem(1) * s2.elem(1);
355 i2 += s1.elem(0) * s2.elem(2);
356
357 /* i1 = s1(1)*s2(0) + s1(0)*s2(1) */
358 i1 = s1.elem(1) * s2.elem(0);
359 i1 += s1.elem(0) * s2.elem(1);
360
361 /* i0 = s1(0)*s2(0) */
362 i0 = s1.elem(0) * s2.elem(0);
363
364 /* dest(0) = mod(i0, 4096) */
365 d.elem(0) = i0 & S(4095);
366
367 /* i1 = i1 + i0/4096 */
368 i1 += i0 >> S(12);
369
370 /* dest(1) = mod(i1, 4096) */
371 d.elem(1) = i1 & S(4095);
372
373 /* i2 = i2 + i1/4096 */
374 i2 += i1 >> S(12);
375
376 /* dest(2) = mod(i2, 4096) */
377 d.elem(2) = i2 & S(4095);
378 /* i3 = i3 + i2/4096 */
379 i3 += i2 >> S(12);
380
381 /* dest(3) = mod(i3, 2048) */
382 d.elem(3) = i3 & S(2047);
383
384 return d;
385}
386
387
388template<class T1, class T2>
392
393template<class T1, class T2>
395operator|(const PSeed<T1>& l, const PSeed<T2>& r)
396{
398
399 d.elem(0) = l.elem(0) | r.elem(0);
400 d.elem(1) = l.elem(1) | r.elem(1);
401 d.elem(2) = l.elem(2) | r.elem(2);
402 d.elem(3) = l.elem(3) | r.elem(3);
403
404 return d;
405}
406
407
408
409// Mixed versions
410template<class T1, class T2>
414
415template<class T1, class T2>
417operator|(const PSeed<T1>& l, const PScalar<T2>& r)
418{
419 // Lazy implementation
420
421 PSeed<T2> d;
422 d = r;
423
424 return (l | d);
425}
426
427
428
433template<class T1, class T2>
437
438template<class T1, class T2>
440operator<<(const PSeed<T1>& s1, const PScalar<T2>& s2)
441{
444 typedef typename InternalScalar<T>::Type_t S;
445 T i0, i1, i2, i3;
446
447 i0 = s1.elem(0) << s2.elem();
448 i1 = s1.elem(1) << s2.elem();
449 i2 = s1.elem(2) << s2.elem();
450 i3 = s1.elem(3) << s2.elem();
451
452 d.elem(0) = i0 & S(4095);
453 i0 >>= S(12);
454 i1 |= i0 & S(4095);
455 d.elem(1) = i1 & S(4095);
456 i1 >>= S(12);
457 i2 |= i1 & S(4095);
458 d.elem(2) = i2 & S(4095);
459 i2 >>= S(12);
460 i3 |= i2 & S(4095);
461 d.elem(3) = i3 & S(2047);
462
463 return d;
464}
465
466
468template<class T>
472
473template<class T>
476{
478 typedef typename RealScalar<T>::Type_t S;
479
480 S twom11(1.0 / 2048.0);
481 S twom12(1.0 / 4096.0);
482 S fs1, fs2;
483
484// recast_rep(fs1, s1.elem(0));
485 fs1 = S(s1.elem(0));
486 d.elem() = twom12 * S(s1.elem(0));
487
488// recast_rep(fs1, s1.elem(1));
489 fs1 = S(s1.elem(1));
490 fs2 = fs1 + d.elem();
491 d.elem() = twom12 * fs2;
492
493// recast_rep(fs1, s1.elem(2));
494 fs1 = S(s1.elem(2));
495 fs2 = fs1 + d.elem();
496 d.elem() = twom12 * fs2;
497
498// recast_rep(fs1, s1.elem(3));
499 fs1 = S(s1.elem(3));
500 fs2 = fs1 + d.elem();
501 d.elem() = twom11 * fs2;
502
503 return d;
504}
505
506
508
509template<class T>
513
514template<class T>
516getSite(const PSeed<T>& s1, int innersite)
517{
519
520 for(int i=0; i < 4; ++i)
521 d.elem(i) = getSite(s1.elem(i), innersite);
522
523 return d;
524}
525
526
527// Functions
529template<class T>
530inline void
532{
533 for(int i=0; i < 4; ++i)
534 zero_rep(dest.elem(i));
535}
536
537
539template<class T, class T1>
540inline void
541copymask(PSeed<T>& d, const PScalar<T1>& mask, const PSeed<T>& s1)
542{
543 for(int i=0; i < 4; ++i)
544 copymask(d.elem(i),mask.elem(),s1.elem(i));
545}
546
548
549} // namespace QDP
550
551#endif
Primitive Scalar.
Primitive Seed class.
PSeed(const PSeed &a)
Deep copy constructor.
const T & elem(int i) const
PSeed & assign(const PScalar< T1 > &rhs)
PSeed = PScalar.
PSeed(const PScalar< T1 > &rhs)
construct dest = const
PSeed & operator=(const PSeed< T1 > &rhs)
PSeed = PSeed.
PSeed & operator=(const PScalar< T1 > &rhs)
PSeed = PScalar.
T & elem(int i)
StandardInputStream class.
Definition qdp_stdio.h:33
StandardOutputStream class.
Definition qdp_stdio.h:106
Text input class.
Definition qdp_io.h:42
Text output base class.
Definition qdp_io.h:203
XML reader class.
Definition qdp_xmlio.h:44
Container for a multi-dimensional 1D array.
Definition qdp_multi.h:25
TextWriter & operator<<(TextWriter &txt, const std::string &output)
Definition qdp_io.cc:283
TextReader & operator>>(TextReader &txt, std::string &input)
Definition qdp_io.cc:121
void read(BinaryReader &bin, std::string &input, size_t maxBytes)
Definition qdp_io.cc:778
void zero_rep(IScalar< T > &dest)
dest = 0
Definition qdp_inner.h:1841
void copymask(IScalar< T > &d, const IScalar< T1 > &mask, const IScalar< T > &s1)
dest = (mask) ? s1 : dest
Definition qdp_inner.h:1656
UnaryReturn< IScalar< T >, FnGetSite >::Type_t getSite(const IScalar< T > &s1, int innersite)
Definition qdp_inner.h:1605
Yet another random number generator.
MakeReturn< UnaryNode< FnSeedToFloat, typenameCreateLeaf< QDPExpr< T1, C1 > >::Leaf_t >, typenameUnaryReturn< C1, FnSeedToFloat >::Type_t >::Expression_t seedToFloat(const QDPExpr< T1, C1 > &l)
Definition qdp.h:5037
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< 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< OpBitwiseOr, typenameCreateLeaf< QDPType< T1, C1 > >::Leaf_t, typenameCreateLeaf< QDPExpr< T2, C2 > >::Leaf_t >, typenameBinaryReturn< C1, C2, OpBitwiseOr >::Type_t >::Expression_t operator|(const QDPType< T1, C1 > &l, const QDPExpr< T2, C2 > &r)
Definition qdp.h:2652
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
PSeed< typename BinaryReturn< T1, T2, OpBitwiseOr >::Type_t > Type_t
PSeed< typename BinaryReturn< T1, T2, OpLeftShift >::Type_t > Type_t
PSeed< typename BinaryReturn< T1, T2, OpBitwiseOr >::Type_t > Type_t
PScalar< typename BinaryReturn< T1, T2, OpEQ >::Type_t > Type_t
PSeed< typename BinaryReturn< T1, T2, OpMultiply >::Type_t > Type_t
PScalar< typename BinaryReturn< T1, T2, OpNE >::Type_t > Type_t
Promote< T1, T2 >::Type_t Type_t
Definition qdp.h:377
PSeed< typename DoublePrecType< T1 >::Type_t > Type_t
PScalar< typename InternalScalar< T >::Type_t > Type_t
Construct simple word type used at some level within primitives.
Definition qdp_traits.h:98
PSeed< typename LatticeScalar< T >::Type_t > Type_t
Makes a lattice scalar leaving primitive indices alone.
Definition qdp_traits.h:108
PScalar< typename PrimitiveScalar< T >::Type_t > Type_t
Makes a primitive scalar leaving grid alone.
Definition qdp_traits.h:103
Construct simple word type used at some level within primitives.
Definition qdp_traits.h:113
PSeed< typename SinglePrecType< T1 >::Type_t > Type_t
PSeed< typename UnaryReturn< T, FnGetSite >::Type_t > Type_t
PScalar< typename UnaryReturn< T, FnSeedToFloat >::Type_t > Type_t
WordType< T1 >::Type_t Type_t
Find the underlying word type of a field.
Definition qdp_traits.h:29