cartiter.h
//
// cartiter.h
//
// Copyright (C) 1996 Limit Point Systems, Inc.
//
// Author: Curtis Janssen <cljanss@limitpt.com>
// Maintainer: LPS
//
// 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_basis_cartiter_h
#define _chemistry_qc_basis_cartiter_h
#ifdef __GNUC__
#pragma interface
#endif
namespace sc {
class CartesianIter {
protected:
int a_;
int b_;
int c_;
int l_;
int bfn_;
public:
CartesianIter(int l);
virtual ~CartesianIter();
virtual void start() =0;
virtual void next() =0;
virtual operator int() =0;
int n() { return ((l_>=0)?((((l_)+2)*((l_)+1))>>1):0); }
int a() { return a_; }
int b() { return b_; }
int c() { return c_; }
int l() { return l_; }
int l(int i) { return i ? (i==1 ? b_ : c_) : a_; }
int bfn() { return bfn_; }
};
class RedundantCartesianIter {
private:
int done_;
int l_;
int *axis_;
public:
RedundantCartesianIter(int l);
virtual ~RedundantCartesianIter();
virtual int bfn() =0;
void start();
void next();
operator int() { return !done_; }
int a();
int b();
int c();
int l() { return l_; }
int l(int i);
int axis(int i) { return axis_[i]; }
};
inline void
RedundantCartesianIter::start()
{
if (l_==0)
done_ = 1;
else
done_ = 0;
for (int i=0; i<l_; i++)
axis_[i] = 0;
}
inline void
RedundantCartesianIter::next()
{
for (int i=0; i<l_; i++) {
if (axis_[i] == 2)
axis_[i] = 0;
else {
axis_[i]++;
return;
}
}
done_ = 1;
}
inline int
RedundantCartesianIter::l(int axis)
{
int i;
int r = 0;
for (i=0; i<l_; i++) if (axis_[i]==axis) r++;
return r;
}
inline int
RedundantCartesianIter::a()
{
return l(0);
}
inline int
RedundantCartesianIter::b()
{
return l(1);
}
inline int
RedundantCartesianIter::c()
{
return l(2);
}
class RedundantCartesianSubIter {
private:
int done_;
int l_;
int e_[3];
int *axis_;
// the locations of the z's in the axis array
int *zloc_;
// the locations of the y's in the subarray after the z's are removed
int *yloc_;
int valid();
public:
RedundantCartesianSubIter(int l);
virtual ~RedundantCartesianSubIter();
virtual int bfn() =0;
void start(int a, int b, int c);
void next();
operator int() const { return !done_; }
int a() const { return e_[0]; }
int b() const { return e_[1]; }
int c() const { return e_[2]; }
int l() const { return l_; }
int l(int i) { return e_[i]; }
int axis(int i) { return axis_[i]; }
};
}
#endif
// Local Variables:
// mode: c++
// c-file-style: "ETS"
// End: