00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _chemistry_qc_basis_cartiter_h
00029 #define _chemistry_qc_basis_cartiter_h
00030
00031 #ifdef __GNUC__
00032 #pragma interface
00033 #endif
00034
00035 namespace sc {
00036
00039 class CartesianIter {
00040 protected:
00041 int a_;
00042 int b_;
00043 int c_;
00044 int l_;
00045 int bfn_;
00046
00047 public:
00049 CartesianIter(int l);
00050 virtual ~CartesianIter();
00051
00053 virtual void start() =0;
00055 virtual void next() =0;
00057 virtual operator int() =0;
00058
00060 int n() { return ((l_>=0)?((((l_)+2)*((l_)+1))>>1):0); }
00062 int a() { return a_; }
00064 int b() { return b_; }
00066 int c() { return c_; }
00068 int l() { return l_; }
00070 int l(int i) { return i ? (i==1 ? b_ : c_) : a_; }
00073 int bfn() { return bfn_; }
00074 };
00075
00080 class RedundantCartesianIter {
00081 private:
00082 int done_;
00083 int l_;
00084 int *axis_;
00085
00086 public:
00088 RedundantCartesianIter(int l);
00089 virtual ~RedundantCartesianIter();
00090
00092 virtual int bfn() =0;
00093
00095 void start();
00097 void next();
00099 operator int() { return !done_; }
00100
00102 int a();
00104 int b();
00106 int c();
00108 int l() { return l_; }
00110 int l(int i);
00112 int axis(int i) { return axis_[i]; }
00113 };
00114
00115 inline void
00116 RedundantCartesianIter::start()
00117 {
00118 if (l_==0)
00119 done_ = 1;
00120 else
00121 done_ = 0;
00122
00123 for (int i=0; i<l_; i++)
00124 axis_[i] = 0;
00125 }
00126
00127 inline void
00128 RedundantCartesianIter::next()
00129 {
00130 for (int i=0; i<l_; i++) {
00131 if (axis_[i] == 2)
00132 axis_[i] = 0;
00133 else {
00134 axis_[i]++;
00135 return;
00136 }
00137 }
00138 done_ = 1;
00139 }
00140
00141 inline int
00142 RedundantCartesianIter::l(int axis)
00143 {
00144 int i;
00145 int r = 0;
00146 for (i=0; i<l_; i++) if (axis_[i]==axis) r++;
00147 return r;
00148 }
00149
00150 inline int
00151 RedundantCartesianIter::a()
00152 {
00153 return l(0);
00154 }
00155
00156 inline int
00157 RedundantCartesianIter::b()
00158 {
00159 return l(1);
00160 }
00161
00162 inline int
00163 RedundantCartesianIter::c()
00164 {
00165 return l(2);
00166 }
00167
00170 class RedundantCartesianSubIter {
00171 private:
00172 int done_;
00173 int l_;
00174 int e_[3];
00175 int *axis_;
00176
00177
00178 int *zloc_;
00179
00180 int *yloc_;
00181
00182 int valid();
00183
00184 public:
00186 RedundantCartesianSubIter(int l);
00187 virtual ~RedundantCartesianSubIter();
00188
00190 virtual int bfn() =0;
00191
00194 void start(int a, int b, int c);
00196 void next();
00198 operator int() const { return !done_; }
00199
00201 int a() const { return e_[0]; }
00203 int b() const { return e_[1]; }
00205 int c() const { return e_[2]; }
00207 int l() const { return l_; }
00209 int l(int i) { return e_[i]; }
00211 int axis(int i) { return axis_[i]; }
00212 };
00213
00214 }
00215
00216 #endif
00217
00218
00219
00220
00221