C++ mpi module for stochmagnet_main Package
OMP_ValField.h
1 #ifndef OMP_ValField_H
2 #define OMP_ValField_H
3 
4 #include "CORE_Field.h"
5 
6 //corresponding array header
7 #include "OMP_ValArray.h"
8 
15 template <typename T,typename K,K D>
16 class OMP_ValField : public CORE_Field<T,K,D,OMP_ValArray<T>,OMP_ValField<T,K,D>> {
17 
18 private:
19 
20  //This class type
21  typedef OMP_ValField<T,K,D> Self;
22 
23 
24  // CONSTRUCTORS
25 public:
29  }
30 
31 
32 
33  // DESTRUCTORS
36  virtual ~OMP_ValField() {
37  }
38 
39 
40 private:
41 
42 
43 
44 
45  //MEMORY
46  //=====
47 public:
55  virtual tMemSize getMemorySize() const override {
56  return sizeof(*this)+this->getContentsMemorySize();
57  }
58 
59  //allocation methods
60  //===================
61 
62 public:
66  static inline CORE_UniquePointer<Self> New() {
67  return CORE_UniquePointer<Self>(new Self(),CORE_Object::Delete());
68  }
69 
70 
71 
72 
73  //accessor operators
74  //====================
75 
76 
77  //accessor iterator
78  //=================
79 
80 
81  //accessor methods
82  //=================
83 
84 
85  //assignment operators
86  //====================
90  inline Self& operator=(const T& v) {
91  copy(v);
92  return *this;
93  }
97  inline Self& operator=(const std::initializer_list<T>& values) {
98  copy(values);
99  return *this;
100  }
104  inline Self& operator=(std::initializer_list<T>&& values) {
105  copy(values);
106  return *this;
107  }
108 
109 
115  template<size_t N,typename Q>
116  inline Self& operator=(const std::array<Q,N>& values) {
117  copy(values);
118  return *this;
119 
120  }
121 
126  template<typename Q>
127  inline Self& operator=(const std::valarray<Q>& values) {
128  copy(values);
129  return *this;
130  }
131 
136  template<typename Q>
137  inline Self& operator=(const std::vector<Q>& values) {
138  copy(values);
139  return *this;
140  }
141 
145  inline Self& operator=(const Self& values) {
146  copy(values);
147  return *this;
148  }
152  inline Self& operator=(Self&& values) {
153  copy(values);
154  return *this;
155  }
156 
163  template<typename Q,class S1,class I1>
164  inline Self& operator=(const CORE_Field<Q,K,D,S1,I1>& values) {
165  copy(values);
166  return *this;
167  }
174  template<typename Q,class S1,class I1>
176  copy(values);
177  return *this;
178  }
179 
180 
181  //initializers methods
182  //====================
183 
184 
189  template<typename Q>
190  inline void initialize(const std::array<Q,D>& a) {
191 
192  //begin iterator of a
193  auto iA=a.cbegin();
194 
195  //begin iterator on this values
196  auto iV=this->sbegin();
197 
198  //number of elements
199  tInteger n=this->getElementsNumber();
200 
201  OMP_PARALLEL_SHARED((n,iA,iV)) {
202 
203  // thread id
204  tInteger threadId=OMP_GET_THREAD_ID();
205  //threads number
206  tInteger nThreads=OMP_GET_THREADS_NUMBER();
207 
208  //start index
209  tInteger start=threadId*n/nThreads;
210 
211  //end index
212  tInteger end=(threadId+1)*n/nThreads;
213 
214  //compute Vi:=Vi/norm
215  auto F=[&iA](auto& Vi) {
216  //compute Vi:=Vi/norm
217  auto Vid=&Vi;
218  std::for_each_n(iA,D,[&Vid](const auto& Aid){(*Vid)=Aid;Vid++;});
219 
220  //return the value
221  return Vi;
222  };
223 
224  //apply the function F
225  std::transform(iV+start,iV+end,
226  iV+start,F);
227  }
228  }
229 
230 
231 
232 
233 
234 
235  //compound assignement operators (+=,-=,*=,/=,^=...)
236  //===================================================
237  //arithmetic type compound operators
238  //====================================
242  inline Self& operator+=(const T& v) {
243  this->getStorage()+=v;
244  return (*this);
245  }
249  inline Self& operator-=(const T& v) {
250  this->getStorage()-=v;
251  return (*this);
252 
253  }
254 
258  inline Self& operator*=(const T& v) {
259  this->getStorage()*=v;
260  return (*this);
261 
262  }
266  inline Self& operator/=(const T& v) {
267  this->getStorage()/=v;
268  return (*this);
269  }
270 
271  //integer type compond operators
272  //===============================
276  inline Self& operator%=(const T& v) requires functions_type::isIntegerType<T>{
277  this->getStorage()%=v;
278  return (*this);
279  }
280 
284  inline Self& operator&=(const T& v) requires functions_type::isIntegerType<T>{
285  this->getStorage()&=v;
286  return (*this);
287  }
288 
292  inline Self& operator|=(const T& v) requires functions_type::isIntegerType<T>{
293  this->getStorage()|=v;
294  return (*this);
295  }
296 
300  inline Self& operator^=(const T& v) requires functions_type::isIntegerType<T> {
301  this->getStorage()^=v;
302  return (*this);
303  }
307  inline Self& operator<<=(const T& v) requires functions_type::isIntegerType<T> {
308  this->getStorage()<<=v;
309  return (*this);
310  }
311 
315  inline Self& operator>>=(const T& v) requires functions_type::isIntegerType<T> {
316  this->getStorage()>>=v;
317  return (*this);
318  }
319 
320  //class type compound operatos
321  //=============================
322 
329  template<class Q,class S,class I>
330  inline Self& operator+=(const CORE_Field<Q,K,D,S,I>& X) {
331  this->getStorage()+=X.getStorage();
332  return (*this);
333  }
340  template<class Q,class S,class I>
342  this->getStorage()-=X.getStorage();
343  return (*this);
344  }
351  template<class Q,class S,class I>
353  //T=F(T,V)
354  this->getStorage()*=X.getStorage();
355  return (*this);
356  }
363  template<class Q,class S,class I>
365  this->getStorage()/=X.getStorage();
366  return (*this);
367  }
368 
369 
370  //transform methods
371  //=================
372 
373 
374 
380  template<typename LambdaFct>
381  static inline void ElementsTransform(LambdaFct&& F,
382  Self& X) {
383 
384  //number of elements
385  tIndex n=X.getElementsNumber();
386 
387 
388  //get the const begin iterator of X
389  auto iX=X.sbegin();
390 
391 
392  //init the random data
393  OMP_PARALLEL_SHARED((n,iX,F)) {//begin parallel section
394 
395  // thread id
396  tInteger threadId=OMP_GET_THREAD_ID();
397  //threads number
398  tInteger nThreads=OMP_GET_THREADS_NUMBER();
399 
400  tInteger start=threadId*n/nThreads;
401  tInteger end=(threadId+1)*n/nThreads;
402 
403 
404  std::transform(iX+start,iX+end,
405  iX+start,F);
406 
407 
408  }//end parallel section
409 
410 
411  }
412 
413 
418  template<typename LambdaFct>
419  inline void elementsTransform(LambdaFct&& F) {
420  this->ElementsTransform(F,(*this));
421  }
422 
423 
424 
429  inline void normalize() {
430 
431  //error to detect null
432  T eps=std::numeric_limits<T>::epsilon();
433 
434 
435  //number of elements
436  tIndex n=this->getElementsNumber();
437 
438 
439  //get the const begin iterator of X
440  auto iV=this->sbegin();
441 
442 
443  //init the random data
444  OMP_PARALLEL_SHARED((n,iV,eps)) {//begin parallel section
445 
446  // thread id
447  tInteger threadId=OMP_GET_THREAD_ID();
448  //threads number
449  tInteger nThreads=OMP_GET_THREADS_NUMBER();
450  //start index
451  tInteger start=threadId*n/nThreads;
452  //end index
453  tInteger end=(threadId+1)*n/nThreads;
454 
455  T norm=0;
456  //compute Vi:=Vi/norm
457  auto F=[&norm,&eps](auto& Vi) {
458  //compute Norm2
459  norm=0;
460  std::for_each_n(&Vi,D,[&norm](const auto& Vid){
461  norm+=Vid*Vid;
462  });
463 
464  //compute invers of norm
465  if (norm>eps) {
466  norm=1./sqrt(norm);
467  }
468 
469  //compute Vi:=Vi/norm
470  std::for_each_n(&Vi,D,[&norm](auto& Vid){Vid*=norm;});
471 
472  //return the value
473  return Vi;
474  };
475  std::transform(iV+start,iV+end,
476  iV+start,F);
477 
478  }//end parallel section
479 
480  }
481 
482 
483  //Data consistency
484  //=================
485 
486 
487  //transform methods
488  //==================
489 
490 
491  //algebric methods
492  //================
493 
494 
495 
500  template<class I>
501  inline void mod2(CORE_Array<T,I>& X) const {
502 
503 
504  //number of elements
505  tIndex n=this->getElementsNumber();
506 
507  //resize x
508  X.setSize(n);
509 
510  //get the const begin iterator of this
511  auto iV=this->csbegin();
512 
513  //get the begin iterator of X
514  auto iX=X.begin();
515 
516 
517  //init the random data
518  OMP_PARALLEL_SHARED((n,iX,iV)) {//begin parallel section
519 
520 
521  // thread id
522  tInteger threadId=OMP_GET_THREAD_ID();
523  //threads number
524  tInteger nThreads=OMP_GET_THREADS_NUMBER();
525  //start index
526  tInteger start=threadId*n/nThreads;
527  //end index
528  tInteger end=(threadId+1)*n/nThreads;
529 
530  T norm2;
531  std::transform(iV+start,iV+end,
532  iX+start,[&norm2](const auto& Vi) {
533  //compute sum_d=0^D-1 Vid^2
534  norm2=0;
535  std::for_each_n(&Vi,D,[&norm2](const auto& Vid) {norm2+=Vid*Vid;});
536  return norm2;
537  });
538 
539 
540  }//end parallel section
541  }//end method
542 
543 
552  template<class Q,class S1,class I1>
553  inline T& scalarProduct(const CORE_Field<Q,K,D,S1,I1>& X,T& s) const {
554  return this->getStorage().scalarProduct(X.getStorage(),s);
555  }
556 
566  template<class Q,class S1,class I1>
567  inline T& scalarProduct(const std::valarray<Q>& weights,const CORE_Field<Q,K,D,S1,I1>& X,T& s) const {
568 
569  //number of elements
570  tIndex n=this->getElementsNumber();
571 
572  //s=sum_i Xi Yi
573  s=0;
574 
575  if (weights.size()==0) {
577  }
578 
579  //increment of W
580  tBoolean incW=(weights.size()>1);
581  //values of W
582  const tReal *Ws=&weights[0];
583 
584  //values of this
585  const T* Ys=this->getValues();
586 
587  //values of X
588  const Q* Xs=X.getValues();
589 
590  //increment on X
591  tBoolean incXs=(X.getElementsNumber()>1);
592 
593  OMP_PARALLEL_SHARED_REDUCTION((n,incW,Ws,Ys,Xs,incXs),
594  (+:s)) {//begin parallel section
595 
596 
597  // thread id
598  tInteger threadId=OMP_GET_THREAD_ID();
599  // threads number
600  tInteger nThreads=OMP_GET_THREADS_NUMBER();
601 
602  //start idnex of the loop
603  tIndex start=threadId*n/nThreads;
604 
605  //end index oft the loop
606  tIndex end=(threadId+1)*n/nThreads;;
607 
608  //start iterator on X
609  const Q* iX=Xs;iX+=incXs*start*D;
610  const Q* iXd=null;//iterator on d-coordinate
611  //start iterator on Y
612  const T* iY=Ys;iY+=start*D;
613  //end iterator on Y
614  const T* iYe=Ys;iYe+=end*D;
615  //end iterator on Yfor element
616  const T* iYd=null;
617 
618  //begin weight iterator
619  const Q* iW=Ws;iW+=start*incW;
620 
621  //s=wi <X^i.Y^i>_d
622  s=0;
623  while (iY!=iYe) {//loop on elements
624 
625  iYd=iY+D;
626  iXd=iX;
627  while(iY!=iYd) {//loop on <X^i,Y^i>
628  s+=(*iW)*(*iXd)*(*iY);
629  iY++;
630  iXd++;
631  }//end loop on <X^i,Y^i>
632 
633  //weight of next elemnt
634  iW+=incW;
635  iX+=incXs*D;
636  }//end loop on element
637 
638  }//end parallel loop
639 
640  return s;
641  }
642 
643 
644 
645 
646 };
647 
648 
649 
650 #ifndef DIMENSION_TYPE
651 #define DIMENSION_TYPE
652 typedef tUCInt tDimension;//d in [0,256[
653 #endif
654 
656 
657 
658 
659 #endif
this class describes an array of values T of dynamical size with algebrical operators and I is an imp...
Definition: CORE_Array.h:91
auto begin()
return begin iterator for writing
Definition: CORE_Collection.h:155
void setSize(const tIndex &n)
set the size of the container
Definition: CORE_Collection.h:104
this class describes an field. A field is composed by
Definition: CORE_Field.h:49
virtual tMemSize getContentsMemorySize() const override
return the memory size of the included associations
Definition: CORE_Field.h:102
void copy(const tIndex &n, const Q *vs)
initialize the field to the values of pointer of size n
Definition: CORE_Field.h:447
const T * getValues() const
get the values of the array for reading
Definition: CORE_Field.h:323
auto sbegin()
return begin stride iterator for writing
Definition: CORE_Field.h:276
tIndex getElementsNumber() const
return the number values of the container
Definition: CORE_Field.h:135
auto end()
return end iterator for writing
Definition: CORE_Field.h:242
constexpr auto csbegin() const
return begin N-stride const iterator for writing
Definition: CORE_Field.h:289
const OMP_ValArray< T > & getStorage() const
get the storage
Definition: CORE_Field.h:336
class Free introduced for deleting a smart pointer
Definition: CORE_Object.h:113
this class describes a standart arithmetic array type implemented with a std::valarray object of type...
Definition: OMP_ValArray.h:19
this class describes a standart arithmetic array type implemented with a std::valarray object
Definition: OMP_ValField.h:16
Self & operator-=(const CORE_Field< Q, K, D, S, I > &X)
array sub operator
Definition: OMP_ValField.h:341
void elementsTransform(LambdaFct &&F)
apply the transform element with the lambda function Xid = F(Xid)
Definition: OMP_ValField.h:419
virtual ~OMP_ValField()
destroy an array of T*
Definition: OMP_ValField.h:36
Self & operator%=(const T &v) requires functions_type
modulo operator
Definition: OMP_ValField.h:276
Self & operator*=(const CORE_Field< Q, K, D, S, I > &X)
array multiply operator
Definition: OMP_ValField.h:352
Self & operator=(Self &&values)
build an array by a copy of values
Definition: OMP_ValField.h:152
OMP_ValField()
build an array of T*
Definition: OMP_ValField.h:28
Self & operator=(const CORE_Field< Q, K, D, S1, I1 > &values)
build an array by a copy of values
Definition: OMP_ValField.h:164
T & scalarProduct(const CORE_Field< Q, K, D, S1, I1 > &X, T &s) const
return the weight scalar product
Definition: OMP_ValField.h:553
void mod2(CORE_Array< T, I > &X) const
return the norm2 array per exch element
Definition: OMP_ValField.h:501
Self & operator=(const std::vector< Q > &values)
build an array by a copy of values
Definition: OMP_ValField.h:137
Self & operator/=(const CORE_Field< Q, K, D, S, I > &X)
array divisor operator
Definition: OMP_ValField.h:364
Self & operator/=(const T &v)
divisor operator
Definition: OMP_ValField.h:266
void initialize(const std::array< Q, D > &a)
copy at element elemnt the array of size D
Definition: OMP_ValField.h:190
static CORE_UniquePointer< Self > New()
return a new unique pointer of this
Definition: OMP_ValField.h:66
Self & operator=(const std::initializer_list< T > &values)
build an array by a copy of values
Definition: OMP_ValField.h:97
virtual tMemSize getMemorySize() const override
return the memory size of the class
Definition: OMP_ValField.h:55
static void ElementsTransform(LambdaFct &&F, Self &X)
apply the transform element with the lambda function Ri = F(Xi)
Definition: OMP_ValField.h:381
Self & operator=(CORE_Field< Q, K, D, S1, I1 > &&values)
build an array by a copy of values
Definition: OMP_ValField.h:175
Self & operator=(const T &v)
fill the values of the array with v
Definition: OMP_ValField.h:90
T & scalarProduct(const std::valarray< Q > &weights, const CORE_Field< Q, K, D, S1, I1 > &X, T &s) const
return the weight scalar product
Definition: OMP_ValField.h:567
Self & operator+=(const T &v)
add operator
Definition: OMP_ValField.h:242
Self & operator=(const std::valarray< Q > &values)
build an array by a copy of values
Definition: OMP_ValField.h:127
Self & operator=(std::initializer_list< T > &&values)
build an array by a copy of values
Definition: OMP_ValField.h:104
Self & operator=(const std::array< Q, N > &values)
build an array by a copy of values
Definition: OMP_ValField.h:116
Self & operator-=(const T &v)
sub operator
Definition: OMP_ValField.h:249
void normalize()
normalize all the elements of the field return false if the method is not compatible with the floatin...
Definition: OMP_ValField.h:429
Self & operator*=(const T &v)
multiplicator operator
Definition: OMP_ValField.h:258
Self & operator=(const Self &values)
build an array by a copy of values
Definition: OMP_ValField.h:145