Program Listing for File index.hpp

Return to documentation for file (src_ed/index.hpp)

#ifndef qcm_index_h
#define qcm_index_h

#include <iostream>

#include "vector_num.hpp"

using namespace std;

struct Index{
    vector<int> dim; // array of dimensions for each index
    vector<int> ind; // array of indices
    int dim_tot; // total number of states (product of all the d[i]'s)

    Index(){
        dim_tot = 0;
    }

    Index(vector<int> &_dim) : dim(_dim){
        ind.resize(dim.size());
        set_dim_tot();
    }

    Index(const Index &x): dim(x.dim), ind(x.ind), dim_tot(x.dim_tot){}

    void set_dim_tot(){
        dim_tot = 1;
        for(int j=0; j<dim.size(); ++j) dim_tot *= dim[j];
    }

    // returns the compound index
    int operator()() {
        int label = ind[dim.size()-1];
        for(int j=(int)dim.size()-2; j>=0; j--) label = dim[j]*label + ind[j];
        return label;
    }

    // builds the indices from the compound index 'label'
    void operator()(int label){
        for(int j=0; j<dim.size(); ++j){
            ind[j] = label%dim[j];
            label /= dim[j];
        }
    }


    // returns the label associated with group product
    int operator()(int i1, int i2){
        (*this)(i1);
        vector<int> tmp(ind);
        (*this)(i2);
        for(int j=0; j<dim.size(); ++j){
            ind[j] += tmp[j];
            ind[j] %= dim[j];
        }
        return (*this)();
    }


    // increases the compound index by one and adjusts the indices
    Index & operator++(){
        shift(0);
        return *this;
    }

    void shift(int pos){
        if(pos == dim.size()) return;
        ind[pos]++;
        if(ind[pos]%dim[pos] == 0){
            ind[pos]=0;
            shift(pos+1);
        }
    }

    // hermitian product useful if the index represent a group element
    int operator*(const Index &x){
        int prod = 0;
        for(int j=0; j<dim.size(); ++j){
            prod += (ind[j]*x.ind[j]*dim_tot)/dim[j];
        }
        return prod%dim_tot;
    }

    friend std::ostream & operator<<(std::ostream &flux, const Index &A){
        flux << '[' << A.ind[0];
        for(int i=1; i<A.dim.size(); ++i) flux << ", " << A.ind[i];
        flux << ']';
        return flux;
    }

    string str(){
        ostringstream sout;
        sout << *this;
        return sout.str();
    }
};


#endif