const version of loopover and grouploopoevr in tensor class
This commit is contained in:
parent
cd09d93c27
commit
3baced9adb
97
tensor.cc
97
tensor.cc
@ -376,6 +376,7 @@ calcsize();
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
void loopingroups(Tensor<T> &t, int ngroup, int igroup, T **p, SUPERINDEX &I, void (*callback)(const SUPERINDEX &, T *))
|
||||
{
|
||||
@ -441,14 +442,78 @@ loopingroups(*this,ss,sh->number-1,&pp,I,callback);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
void constloopingroups(const Tensor<T> &t, int ngroup, int igroup, const T **p, SUPERINDEX &I, void (*callback)(const SUPERINDEX &, const T *))
|
||||
{
|
||||
LA_index istart,iend;
|
||||
const indexgroup *sh = &t.shape[ngroup];
|
||||
switch(sh->symmetry)
|
||||
{
|
||||
case 0:
|
||||
istart= sh->offset;
|
||||
iend= sh->offset+sh->range-1;
|
||||
break;
|
||||
case 1:
|
||||
istart= sh->offset;
|
||||
if(igroup==sh->number-1) iend= sh->offset+sh->range-1;
|
||||
else iend = I[ngroup][igroup+1];
|
||||
break;
|
||||
case -1:
|
||||
istart= sh->offset + igroup;
|
||||
if(igroup==sh->number-1) iend= sh->offset+sh->range-1;
|
||||
else iend = I[ngroup][igroup+1]-1;
|
||||
break;
|
||||
}
|
||||
|
||||
for(LA_index i = istart; i<=iend; ++i)
|
||||
{
|
||||
I[ngroup][igroup]=i;
|
||||
if(ngroup==0 && igroup==0)
|
||||
{
|
||||
int sign;
|
||||
//std::cout <<"TEST "<<t.index(&sign,I)<<" ";
|
||||
(*callback)(I,(*p)++);
|
||||
}
|
||||
else
|
||||
{
|
||||
int newigroup= igroup-1;
|
||||
int newngroup=ngroup;
|
||||
if(newigroup<0)
|
||||
{
|
||||
--newngroup;
|
||||
const indexgroup *sh2 = &(* const_cast<const NRVec<indexgroup> *>(&t.shape))[newngroup];
|
||||
newigroup=sh2->number-1;
|
||||
}
|
||||
constloopingroups(t,newngroup,newigroup,p,I,callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
void Tensor<T>::constloopover(void (*callback)(const SUPERINDEX &, const T *)) const
|
||||
{
|
||||
SUPERINDEX I(shape.size());
|
||||
for(int i=0; i<I.size(); ++i)
|
||||
{
|
||||
const indexgroup *sh = &shape[i];
|
||||
I[i].resize(sh->number);
|
||||
I[i] = sh->offset;
|
||||
}
|
||||
const T *pp=&data[0];
|
||||
int ss=shape.size()-1;
|
||||
const indexgroup *sh = &shape[ss];
|
||||
constloopingroups(*this,ss,sh->number-1,&pp,I,callback);
|
||||
}
|
||||
|
||||
|
||||
static std::ostream *sout;
|
||||
template<typename T>
|
||||
static void outputcallback(const SUPERINDEX &I, T *v)
|
||||
static void outputcallback(const SUPERINDEX &I, const T *v)
|
||||
{
|
||||
//print indices flat
|
||||
for(int i=0; i<I.size(); ++i)
|
||||
for(int j=0; j<I[i].size(); ++j) *sout << I[i][j]<<" ";
|
||||
//*sout<<" "<< " "<<(void *)v<<" "<< *v<<std::endl;
|
||||
*sout<<" "<< *v<<std::endl;
|
||||
}
|
||||
|
||||
@ -480,7 +545,7 @@ std::ostream & operator<<(std::ostream &s, const Tensor<T> &x)
|
||||
{
|
||||
s<<x.shape;
|
||||
sout= &s;
|
||||
const_cast<Tensor<T> *>(&x)->loopover(&outputcallback<T>);
|
||||
x.constloopover(&outputcallback<T>);
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -521,6 +586,28 @@ loopovergroups(*this,shape.size()-1,&pp,I,callback);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
void constloopovergroups(const Tensor<T> &t, int ngroup, const T **p, GROUPINDEX &I, void (*callback)(const GROUPINDEX &, const T *))
|
||||
{
|
||||
for(LA_largeindex i = 0; i<t.groupsizes[ngroup]; ++i)
|
||||
{
|
||||
I[ngroup]=i;
|
||||
if(ngroup==0) (*callback)(I,(*p)++);
|
||||
else constloopovergroups(t,ngroup-1,p,I,callback);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Tensor<T>::constgrouploopover(void (*callback)(const GROUPINDEX &, const T *)) const
|
||||
{
|
||||
GROUPINDEX I(shape.size());
|
||||
const T *pp= &data[0];
|
||||
constloopovergroups(*this,shape.size()-1,&pp,I,callback);
|
||||
}
|
||||
|
||||
|
||||
const NRPerm<int> *help_p;
|
||||
template<typename T>
|
||||
Tensor<T> *help_t;
|
||||
@ -528,7 +615,7 @@ template<typename T>
|
||||
const Tensor<T> *help_tt;
|
||||
|
||||
template<typename T>
|
||||
static void permutecallback(const GROUPINDEX &I, T *v)
|
||||
static void permutecallback(const GROUPINDEX &I, const T *v)
|
||||
{
|
||||
LA_largeindex target=0;
|
||||
for(int i=0; i< help_t<T>->shape.size(); ++i)
|
||||
@ -553,7 +640,7 @@ help_p = &p;
|
||||
help_t<T> = &r;
|
||||
|
||||
//now rearrange the data
|
||||
const_cast<Tensor<T> *>(this)->grouploopover(permutecallback<T>);
|
||||
const_cast<Tensor<T> *>(this)->constgrouploopover(permutecallback<T>);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
4
tensor.h
4
tensor.h
@ -49,8 +49,6 @@
|
||||
//@@@conversions to/from fourindex, optional negarive rande for beta spin handling
|
||||
//@@@ optional distinguish covariant and contravariant check in contraction
|
||||
//
|
||||
//maybe const loopover and grouploopover to avoid problems with shallowly copied tensors
|
||||
//
|
||||
//@@@?general permutation of individual indices - check the indices in sym groups remain adjacent, calculate result's shape, loopover the result and permute using unwind_callback
|
||||
//
|
||||
//
|
||||
@ -224,7 +222,9 @@ public:
|
||||
inline void randomize(const typename LA_traits<T>::normtype &x) {data.randomize(x);};
|
||||
|
||||
void loopover(void (*callback)(const SUPERINDEX &, T *)); //loop over all elements
|
||||
void constloopover(void (*callback)(const SUPERINDEX &, const T *)) const; //loop over all elements
|
||||
void grouploopover(void (*callback)(const GROUPINDEX &, T *)); //loop over all elements disregarding the internal structure of index groups
|
||||
void constgrouploopover(void (*callback)(const GROUPINDEX &, const T *)) const; //loop over all elements disregarding the internal structure of index groups
|
||||
|
||||
Tensor permute_index_groups(const NRPerm<int> &p) const; //rearrange the tensor storage permuting index groups as a whole
|
||||
Tensor unwind_index(int group, int index) const; //separate an index from a group and expand it to full range as the least significant one (the leftmost one)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user