pairiter.h
//
// pairiter.h
//
// Copyright (C) 2004 Edward Valeev
//
// Author: Edward Valeev <edward.valeev@chemistry.gatech.edu>
// Maintainer: EV
//
// This file is part of the SC Toolkit.
//
// The SC Toolkit is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// The SC Toolkit is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with the SC Toolkit; see the file COPYING.LIB. If not, write to
// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
//
// The U.S. Government is granted a limited license as per AL 91-7.
//
#ifndef _chemistry_qc_mbptr12_pairiter_h
#define _chemistry_qc_mbptr12_pairiter_h
#ifdef __GNUC__
#pragma interface
#endif
#include <stdexcept>
#include <chemistry/qc/mbptr12/moindexspace.h>
namespace sc {
class MOPairIter : public RefCount {
protected:
bool i_eq_j_;
int ni_;
int nj_;
int i_;
int j_;
int nij_;
int ij_;
public:
MOPairIter(const Ref<MOIndexSpace>& space_i, const Ref<MOIndexSpace>& space_j);
virtual ~MOPairIter();
virtual void start(const int first_ij =0) =0;
virtual void next() =0;
virtual operator int() const =0;
int ni() const { return ni_; }
int nj() const { return nj_; }
int i() const { return i_; }
int j() const { return j_; }
int nij() const { return nij_; }
int ij() const { return ij_; }
};
class SpatialMOPairIter : public MOPairIter {
public:
SpatialMOPairIter(const Ref<MOIndexSpace>& space_i, const Ref<MOIndexSpace>& space_j) :
MOPairIter(space_i,space_j) {};
~SpatialMOPairIter() {};
virtual int nij_aa() const =0;
virtual int nij_ab() const =0;
virtual int ij_aa() const =0;
virtual int ij_ab() const =0;
virtual int ij_ba() const =0;
};
class SpatialMOPairIter_eq : public SpatialMOPairIter {
int nij_aa_;
int nij_ab_;
int ij_aa_;
int ij_ab_;
int ji_ab_;
void init_ij(const int ij) {
if (ij<0)
throw std::runtime_error("SpatialMOPairIter_eq::start() -- argument ij out of range");
ij_ = 0;
const int renorm_ij = ij%nij_;
i_ = (int)floor((sqrt(1.0+8.0*renorm_ij) - 1.0)/2.0);
const int i_off = i_*(i_+1)/2;
j_ = renorm_ij - i_off;
ij_ab_ = i_*nj_ + j_;
ji_ab_ = j_*ni_ + i_;
if (i_ != 0) {
const int i_off = i_*(i_-1)/2;
ij_aa_ = i_off + j_;
if (i_ == j_)
ij_aa_--;
}
else {
ij_aa_ = -1;
}
};
void inc_ij() {
ij_++;
if (ij_ab_ == nij_ab_-1) {
i_ = 0;
j_ = 0;
ij_ab_ = 0;
ji_ab_ = 0;
ij_aa_ = -1;
}
else {
if (i_ == j_) {
i_++;
j_ = 0;
ji_ab_ = i_;
ij_ab_ = i_*nj_;
ij_aa_ += (i_ == j_) ? 0 : 1;
}
else {
j_++;
ji_ab_ += ni_;
ij_ab_++;
ij_aa_ += (i_ == j_) ? 0 : 1;
}
}
};
public:
SpatialMOPairIter_eq(const Ref<MOIndexSpace>& space1);
~SpatialMOPairIter_eq();
void start(const int ij_offset=0)
{
ij_ = 0;
init_ij(ij_offset);
};
void next() {
inc_ij();
};
operator int() const { return (nij_ > ij_);};
int nij_aa() const { return nij_aa_; }
int nij_ab() const { return nij_ab_; }
int ij_aa() const { return (i_ == j_) ? -1 : ij_aa_; }
int ij_ab() const { return ij_ab_; }
int ij_ba() const { return ji_ab_; }
};
class SpatialMOPairIter_neq : public SpatialMOPairIter {
int IJ_;
void init_ij(const int ij) {
if (ij<0)
throw std::runtime_error("SpatialMOPairIter_neq::start() -- argument ij out of range");
IJ_ = 0;
const int renorm_ij = ij%nij_;
i_ = renorm_ij/nj_;
j_ = renorm_ij - i_*nj_;
IJ_ = i_*nj_ + j_;
};
void inc_ij() {
ij_++;
IJ_++;
if (IJ_ == nij_) {
i_ = 0;
j_ = 0;
IJ_ = 0;
}
else {
if (j_ == nj_-1) {
i_++;
j_ = 0;
}
else {
j_++;
}
}
};
public:
SpatialMOPairIter_neq(const Ref<MOIndexSpace>& space1, const Ref<MOIndexSpace>& space2);
~SpatialMOPairIter_neq();
void start(const int ij_offset=0)
{
ij_ = 0;
init_ij(ij_offset);
};
void next() {
inc_ij();
};
operator int() const { return (nij_ > ij_);};
int nij_aa() const { return nij_; }
int nij_ab() const { return nij_; }
int ij_aa() const { return IJ_; }
int ij_ab() const { return IJ_; }
int ij_ba() const { return IJ_; }
};
class MOPairIterFactory {
public:
MOPairIterFactory() {}
~MOPairIterFactory() {}
Ref<SpatialMOPairIter> mopairiter(const Ref<MOIndexSpace>& space1, const Ref<MOIndexSpace>& space2);
RefSCDimension scdim_aa(const Ref<MOIndexSpace>& space1, const Ref<MOIndexSpace>& space2);
RefSCDimension scdim_ab(const Ref<MOIndexSpace>& space1, const Ref<MOIndexSpace>& space2);
};
}
#endif
// Local Variables:
// mode: c++
// c-file-style: "ETS"
// End: