https://github.com/ITensor/ITensor
Raw File
Tip revision: e2c6ea98c5d68dee7ad38c16a7f71574a46589e0 authored by Miles Stoudenmire on 20 August 2015, 19:47:53 UTC
Shortened some type names in cplx_literal.h and names of constants in global.h
Tip revision: e2c6ea9
counter.h
//
// Distributed under the ITensor Library License, Version 1.1.
//    (See accompanying LICENSE file.)
//
#ifndef __ITENSOR_COUNTER_H
#define __ITENSOR_COUNTER_H

#include "indexset.h"

#define Cout std::cout
#define Endl std::endl

namespace itensor {

//
// Counter
//

//
// A Counter "C" is iterated as
// for(; C.notDone(); ++C) { ... }
//
// When iterated, each index C.i[j]
// runs from 1 to C.n[j] such that taken
// together the C.i run over all values
// compatible with their ranges.
//
// The index C.i[1] changes every step,
// C.i[2] after every C.n[1] steps, etc.
//
// For example: (if C.n[1] == C.n[2] == 2, say)
// C.i[1]  C.i[2]   C.i[3]
//   0       0        0
//   1       0        0
//   0       1        0
//   1       1        0
//   0       0        1
//   1       0        1
//   ...
// 
// Counters also keep a straight count of which
// step they are on through the field C.ind
// (which starts from 0).
//
// ITensor data is ordered and the method
// ITensor::_ind is defined such that
// v[C.ind] == v[_ind(C.i[1],C.i[2],...,C.i[8]]
// where v is the Vector in an ITDat.
//

class Counter
    {
    public:

    array<int,NMAX+1> n, 
                      i;
    int ind,
        rn,
        r;

    Counter();

    template <class IndexT>
    Counter(const array<IndexT,NMAX+1>& ii,int rn,int r);

    template <class IndexT> 
    explicit
    Counter(const IndexSet<IndexT>& is);

    Counter& 
    operator++();

    bool 
    notDone() const { return i[1] >= 0; }

    void 
    reset();

    };


//
// Counter implementation
//

inline Counter::
Counter() 
    : rn(0), r(0)
    {
    n.fill(1); 
    n[0] = 0;
    reset();
    }

void inline Counter::
reset()
    {
    i.fill(0);
    ind = 0;
    }

template <class IndexT>
Counter::
Counter(const array<IndexT,NMAX+1>& ii, int rn_, int r_)
    {
    rn = rn_;
    r = r_;
    n[0] = 0;
    for(int j = 1; j <= rn; ++j) 
        n[j] = ii[j].m();
    for(int j = rn+1; j <= NMAX; ++j) 
        n[j] = 1;
    reset();
    }

template <class IndexT>
Counter::
Counter(const IndexSet<IndexT>& is)
    {
    rn = is.rn();
    r = is.r();
    n[0] = 0;
    for(int j = 1; j <= rn; ++j) 
        n[j] = is.index(j).m();
    for(int j = rn+1; j <= NMAX; ++j) 
        n[j] = 1;
    reset();
    }

inline
Counter& Counter::
operator++()
    {
    ++ind;
    ++i[1];
    if(i[1] >= n[1])
        {
        for(int j = 2; j <= rn; ++j)
            {
            i[j-1] = 0;
            ++i[j];
            if(i[j] < n[j]) break;
            }
        }
    //set 'done' condition
    if(i[rn] >= n[rn]) 
        {
        i[1] = -1;
        }
    return *this;
    }

inline
std::ostream&
operator<<(std::ostream& s, const Counter& c)
    {
    s << "("; 
    if(c.r >= 1) s << (c.i[1]+1);
    for(int i = 2; i <= c.r; ++i)
        {
        s << "," << (c.i[i]+1);
        }
    s << ")";
    return s;
    }

} //namespace itensor

#undef Cout
#undef Endl
#endif
back to top