MPQC
2.3.1
|
00001 // 00002 // storage.h 00003 // 00004 // Copyright (C) 1996 Limit Point Systems, Inc. 00005 // 00006 // Author: Curtis Janssen <cljanss@limitpt.com> 00007 // Maintainer: LPS 00008 // 00009 // This file is part of the SC Toolkit. 00010 // 00011 // The SC Toolkit is free software; you can redistribute it and/or modify 00012 // it under the terms of the GNU Library General Public License as published by 00013 // the Free Software Foundation; either version 2, or (at your option) 00014 // any later version. 00015 // 00016 // The SC Toolkit is distributed in the hope that it will be useful, 00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 // GNU Library General Public License for more details. 00020 // 00021 // You should have received a copy of the GNU Library General Public License 00022 // along with the SC Toolkit; see the file COPYING.LIB. If not, write to 00023 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 00024 // 00025 // The U.S. Government is granted a limited license as per AL 91-7. 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 namespace sc { 00043 00044 // the max shell number is 2^15 (sizeof(int) must be >= 4) 00045 #define SH_BITS 15 // the number of bits holding a shell index 00046 #define PE_BITS 1 // the number of bits holding a permutation 00047 00048 #define SH_MASK ((1<<SH_BITS)-1) 00049 #define PE_MASK ((1<<PE_BITS)-1) 00050 00051 #define SH0_SHIFT 0 00052 #define SH1_SHIFT (SH_BITS + SH0_SHIFT) 00053 #define P12_SHIFT (SH_BITS + SH1_SHIFT) 00054 #define P34_SHIFT (PE_BITS + P12_SHIFT) 00055 #define SH2_SHIFT 0 00056 #define SH3_SHIFT (SH_BITS + SH2_SHIFT) 00057 #define P13P24_SHIFT (SH_BITS + SH3_SHIFT) 00058 class IntegralKey { 00059 public: 00060 unsigned int sh0_sh1_p12_p34; 00061 unsigned int sh2_sh3_p13p24; 00062 public: 00063 IntegralKey(int,int,int,int,int,int,int); 00064 IntegralKey(const IntegralKey&); 00065 bool operator == (const IntegralKey &k) const { 00066 return (sh0_sh1_p12_p34 == k.sh0_sh1_p12_p34) 00067 && (sh2_sh3_p13p24 == k.sh2_sh3_p13p24); 00068 } 00069 bool operator < (const IntegralKey &k) const { 00070 return ((sh0_sh1_p12_p34 < k.sh0_sh1_p12_p34)? 00071 true:(sh2_sh3_p13p24 < k.sh2_sh3_p13p24)); 00072 } 00073 int sh0() const { return (sh0_sh1_p12_p34>>SH0_SHIFT) & SH_MASK; } 00074 int sh1() const { return (sh0_sh1_p12_p34>>SH1_SHIFT) & SH_MASK; } 00075 int p12() const { return (sh0_sh1_p12_p34>>P12_SHIFT) & PE_MASK; } 00076 int p34() const { return (sh0_sh1_p12_p34>>P34_SHIFT) & PE_MASK; } 00077 int sh2() const { return (sh2_sh3_p13p24>>SH2_SHIFT) & SH_MASK; } 00078 int sh3() const { return (sh2_sh3_p13p24>>SH3_SHIFT) & SH_MASK; } 00079 int p13p24() const { return (sh2_sh3_p13p24>>P13P24_SHIFT) & PE_MASK; } 00080 }; 00081 00082 inline 00083 IntegralKey::IntegralKey(int sh1_, int sh2_, int sh3_, int sh4_, 00084 int p12_, int p34_, int p13p24_) 00085 { 00086 sh0_sh1_p12_p34 = (sh1_<<SH0_SHIFT) 00087 |(sh2_<<SH1_SHIFT) 00088 |(p12_<<P12_SHIFT) 00089 |(p34_<<P34_SHIFT); 00090 sh2_sh3_p13p24 = (sh3_<<SH2_SHIFT) 00091 |(sh4_<<SH3_SHIFT) 00092 |(p13p24_<<P13P24_SHIFT); 00093 } 00094 00095 inline 00096 IntegralKey::IntegralKey(const IntegralKey& ik) 00097 { 00098 sh0_sh1_p12_p34 = ik.sh0_sh1_p12_p34; 00099 sh2_sh3_p13p24 = ik.sh2_sh3_p13p24; 00100 } 00101 00102 inline int 00103 compare(const IntegralKey&k1, const IntegralKey&k2) 00104 { 00105 if (k1.sh0_sh1_p12_p34 < k2.sh0_sh1_p12_p34) return -1; 00106 else if (k1.sh0_sh1_p12_p34 > k2.sh0_sh1_p12_p34) return 1; 00107 00108 if (k1.sh2_sh3_p13p24 < k2.sh2_sh3_p13p24) return -1; 00109 else if (k1.sh2_sh3_p13p24 > k2.sh2_sh3_p13p24) return 1; 00110 else return 0; 00111 } 00112 00113 class IntegralLink { 00114 public: 00115 EAVLMMapNode<IntegralKey, IntegralLink> intlist; 00116 EAVLMMapNode<int, IntegralLink> costlist; 00117 int size; 00118 public: 00119 IntegralLink(IntegralKey& key, int cost, int size); 00120 static int size_to_actualsize(int size); 00121 ~IntegralLink(); 00122 int actualsize() const; 00123 int hash() const; 00124 static int shells_to_hash(int,int,int,int); 00125 int cost() const { return costlist.key; } 00126 void print(); 00127 00128 // the integrals are squirreled away after this 00129 double* buffer() { return (double*)&this[1]; } 00130 void* operator new(size_t, int); 00131 void operator delete(void*, int); 00132 void operator delete(void*); 00133 }; 00134 00135 inline int 00136 IntegralLink::shells_to_hash(int sh1,int sh2,int sh3,int sh4) 00137 { 00138 return sh1 ^ (sh4<<4) ^ (sh2<<8) ^ (sh3<<12); 00139 } 00140 00141 inline int 00142 IntegralLink::hash() const 00143 { 00144 return shells_to_hash(intlist.key.sh0(), 00145 intlist.key.sh1(), 00146 intlist.key.sh2(), 00147 intlist.key.sh3()); 00148 } 00149 00150 inline int 00151 IntegralLink::size_to_actualsize(int size) 00152 { 00153 return size*sizeof(double) + sizeof(IntegralLink) + sizeof(void*)*2; 00154 } 00155 00156 inline int 00157 IntegralLink::actualsize() const 00158 { 00159 return size_to_actualsize(size); 00160 } 00161 00162 class IntegralStorer: public DescribedClass { 00163 private: 00164 int table_size_; 00165 EAVLMMap<int,IntegralLink> costlist; 00166 EAVLMMap<IntegralKey,IntegralLink>* table_; 00167 int maxsize_; 00168 int currentsize_; 00169 int n_integrals_; 00170 int n_shellquart_; 00171 public: 00172 IntegralStorer(); 00173 IntegralStorer(const Ref<KeyVal>&); 00174 ~IntegralStorer(); 00175 void init(int nbytes); 00176 void done(); 00177 IntegralLink *find(IntegralKey&); 00178 int should_store(int cost, int actualsize); 00179 void store(IntegralKey& key, const double *buf, 00180 int size, int cost, int actualsize); 00181 void print_stats(); 00182 int table_size() const { return table_size_; } 00183 }; 00184 00185 } 00186 00187 #endif 00188 00189 #endif 00190 00191 // Local Variables: 00192 // mode: c++ 00193 // c-file-style: "CLJ" 00194 // End: