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_intv3_storage_h
00029 #define _chemistry_qc_intv3_storage_h
00030
00031 #ifdef __GNUC__
00032 #pragma interface
00033 #endif
00034
00035 #ifdef __cplusplus
00036
00037 #include <stddef.h>
00038 #include <util/class/class.h>
00039 #include <util/keyval/keyval.h>
00040 #include <util/container/eavlmmap.h>
00041
00042
00043 #define SH_BITS 15 // the number of bits holding a shell index
00044 #define PE_BITS 1 // the number of bits holding a permutation
00045
00046 #define SH_MASK ((1<<SH_BITS)-1)
00047 #define PE_MASK ((1<<PE_BITS)-1)
00048
00049 #define SH0_SHIFT 0
00050 #define SH1_SHIFT (SH_BITS + SH0_SHIFT)
00051 #define P12_SHIFT (SH_BITS + SH1_SHIFT)
00052 #define P34_SHIFT (PE_BITS + P12_SHIFT)
00053 #define SH2_SHIFT 0
00054 #define SH3_SHIFT (SH_BITS + SH2_SHIFT)
00055 #define P13P24_SHIFT (SH_BITS + SH3_SHIFT)
00056 class IntegralKey {
00057 public:
00058 unsigned int sh0_sh1_p12_p34;
00059 unsigned int sh2_sh3_p13p24;
00060 public:
00061 IntegralKey(int,int,int,int,int,int,int);
00062 IntegralKey(const IntegralKey&);
00063 int sh0() const { return (sh0_sh1_p12_p34>>SH0_SHIFT) & SH_MASK; }
00064 int sh1() const { return (sh0_sh1_p12_p34>>SH1_SHIFT) & SH_MASK; }
00065 int p12() const { return (sh0_sh1_p12_p34>>P12_SHIFT) & PE_MASK; }
00066 int p34() const { return (sh0_sh1_p12_p34>>P34_SHIFT) & PE_MASK; }
00067 int sh2() const { return (sh2_sh3_p13p24>>SH2_SHIFT) & SH_MASK; }
00068 int sh3() const { return (sh2_sh3_p13p24>>SH3_SHIFT) & SH_MASK; }
00069 int p13p24() const { return (sh2_sh3_p13p24>>P13P24_SHIFT) & PE_MASK; }
00070 };
00071
00072 inline
00073 IntegralKey::IntegralKey(int sh1_, int sh2_, int sh3_, int sh4_,
00074 int p12_, int p34_, int p13p24_)
00075 {
00076 sh0_sh1_p12_p34 = (sh1_<<SH0_SHIFT)
00077 |(sh2_<<SH1_SHIFT)
00078 |(p12_<<P12_SHIFT)
00079 |(p34_<<P34_SHIFT);
00080 sh2_sh3_p13p24 = (sh3_<<SH2_SHIFT)
00081 |(sh4_<<SH3_SHIFT)
00082 |(p13p24_<<P13P24_SHIFT);
00083 }
00084
00085 inline
00086 IntegralKey::IntegralKey(const IntegralKey& ik)
00087 {
00088 sh0_sh1_p12_p34 = ik.sh0_sh1_p12_p34;
00089 sh2_sh3_p13p24 = ik.sh2_sh3_p13p24;
00090 }
00091
00092 inline int
00093 compare(const IntegralKey&k1, const IntegralKey&k2)
00094 {
00095 if (k1.sh0_sh1_p12_p34 < k2.sh0_sh1_p12_p34) return -1;
00096 else if (k1.sh0_sh1_p12_p34 > k2.sh0_sh1_p12_p34) return 1;
00097
00098 if (k1.sh2_sh3_p13p24 < k2.sh2_sh3_p13p24) return -1;
00099 else if (k1.sh2_sh3_p13p24 > k2.sh2_sh3_p13p24) return 1;
00100 else return 0;
00101 }
00102
00103 class IntegralLink {
00104 public:
00105 EAVLMMapNode<IntegralKey, IntegralLink> intlist;
00106 EAVLMMapNode<int, IntegralLink> costlist;
00107 int size;
00108 public:
00109 IntegralLink(IntegralKey& key, int cost, int size);
00110 static int size_to_actualsize(int size);
00111 ~IntegralLink();
00112 int actualsize() const;
00113 int hash() const;
00114 static int shells_to_hash(int,int,int,int);
00115 int cost() const { return costlist.key; }
00116 void print();
00117
00118
00119 double* buffer() { return (double*)&this[1]; }
00120 void* operator new(size_t, int);
00121 void operator delete(void*, int);
00122 void operator delete(void*);
00123 };
00124
00125 inline int
00126 IntegralLink::shells_to_hash(int sh1,int sh2,int sh3,int sh4)
00127 {
00128 return sh1 ^ (sh4<<4) ^ (sh2<<8) ^ (sh3<<12);
00129 }
00130
00131 inline int
00132 IntegralLink::hash() const
00133 {
00134 return shells_to_hash(intlist.key.sh0(),
00135 intlist.key.sh1(),
00136 intlist.key.sh2(),
00137 intlist.key.sh3());
00138 }
00139
00140 inline int
00141 IntegralLink::size_to_actualsize(int size)
00142 {
00143 return size*sizeof(double) + sizeof(IntegralLink) + sizeof(void*)*2;
00144 }
00145
00146 inline int
00147 IntegralLink::actualsize() const
00148 {
00149 return size_to_actualsize(size);
00150 }
00151
00152 class IntegralStorer: public DescribedClass {
00153 private:
00154 int table_size_;
00155 EAVLMMap<int,IntegralLink> costlist;
00156 EAVLMMap<IntegralKey,IntegralLink>* table_;
00157 int maxsize_;
00158 int currentsize_;
00159 int n_integrals_;
00160 int n_shellquart_;
00161 public:
00162 IntegralStorer();
00163 IntegralStorer(const Ref<KeyVal>&);
00164 ~IntegralStorer();
00165 void init(int nbytes);
00166 void done();
00167 IntegralLink *find(IntegralKey&);
00168 int should_store(int cost, int actualsize);
00169 void store(IntegralKey& key, const double *buf,
00170 int size, int cost, int actualsize);
00171 void print_stats();
00172 int table_size() const { return table_size_; }
00173 };
00174
00175
00176 #endif
00177
00178 #endif
00179
00180
00181
00182
00183