28 #ifndef _chemistry_qc_intv3_storage_h
29 #define _chemistry_qc_intv3_storage_h
34 #include <util/class/class.h>
35 #include <util/keyval/keyval.h>
36 #include <util/container/eavlmmap.h>
41 #define SH_BITS 15 // the number of bits holding a shell index
42 #define PE_BITS 1 // the number of bits holding a permutation
44 #define SH_MASK ((1<<SH_BITS)-1)
45 #define PE_MASK ((1<<PE_BITS)-1)
48 #define SH1_SHIFT (SH_BITS + SH0_SHIFT)
49 #define P12_SHIFT (SH_BITS + SH1_SHIFT)
50 #define P34_SHIFT (PE_BITS + P12_SHIFT)
52 #define SH3_SHIFT (SH_BITS + SH2_SHIFT)
53 #define P13P24_SHIFT (SH_BITS + SH3_SHIFT)
56 unsigned int sh0_sh1_p12_p34;
57 unsigned int sh2_sh3_p13p24;
59 IntegralKey(
int,
int,
int,
int,
int,
int,
int);
60 IntegralKey(
const IntegralKey&);
62 return (sh0_sh1_p12_p34 == k.sh0_sh1_p12_p34)
63 && (sh2_sh3_p13p24 == k.sh2_sh3_p13p24);
66 if (sh0_sh1_p12_p34 < k.sh0_sh1_p12_p34)
return true;
67 else if (sh0_sh1_p12_p34 > k.sh0_sh1_p12_p34)
return false;
68 return sh2_sh3_p13p24 < k.sh2_sh3_p13p24;
70 int sh0()
const {
return (sh0_sh1_p12_p34>>SH0_SHIFT) & SH_MASK; }
71 int sh1()
const {
return (sh0_sh1_p12_p34>>SH1_SHIFT) & SH_MASK; }
72 int p12()
const {
return (sh0_sh1_p12_p34>>P12_SHIFT) & PE_MASK; }
73 int p34()
const {
return (sh0_sh1_p12_p34>>P34_SHIFT) & PE_MASK; }
74 int sh2()
const {
return (sh2_sh3_p13p24>>SH2_SHIFT) & SH_MASK; }
75 int sh3()
const {
return (sh2_sh3_p13p24>>SH3_SHIFT) & SH_MASK; }
76 int p13p24()
const {
return (sh2_sh3_p13p24>>P13P24_SHIFT) & PE_MASK; }
86 <<
' ' << k.p12() << k.p34() << k.p13p24()
87 <<
" (" << k.sh0_sh1_p12_p34 <<
' ' << k.sh2_sh3_p13p24 <<
')'
93 IntegralKey::IntegralKey(
int sh1_,
int sh2_,
int sh3_,
int sh4_,
94 int p12_,
int p34_,
int p13p24_)
96 sh0_sh1_p12_p34 = (sh1_<<SH0_SHIFT)
100 sh2_sh3_p13p24 = (sh3_<<SH2_SHIFT)
102 |(p13p24_<<P13P24_SHIFT);
106 IntegralKey::IntegralKey(
const IntegralKey& ik)
108 sh0_sh1_p12_p34 = ik.sh0_sh1_p12_p34;
109 sh2_sh3_p13p24 = ik.sh2_sh3_p13p24;
113 compare(
const IntegralKey&k1,
const IntegralKey&k2)
115 if (k1.sh0_sh1_p12_p34 < k2.sh0_sh1_p12_p34)
return -1;
116 else if (k1.sh0_sh1_p12_p34 > k2.sh0_sh1_p12_p34)
return 1;
118 if (k1.sh2_sh3_p13p24 < k2.sh2_sh3_p13p24)
return -1;
119 else if (k1.sh2_sh3_p13p24 > k2.sh2_sh3_p13p24)
return 1;
125 EAVLMMapNode<IntegralKey, IntegralLink> intlist;
126 EAVLMMapNode<int, IntegralLink> costlist;
129 IntegralLink(IntegralKey& key,
int cost,
int size);
130 static int size_to_actualsize(
int size);
132 int actualsize()
const;
134 static int shells_to_hash(
int,
int,
int,
int);
135 int cost()
const {
return costlist.key; }
139 double* buffer() {
return (
double*)&
this[1]; }
140 void*
operator new(size_t, int);
141 void operator delete(
void*, int);
142 void operator delete(
void*);
146 IntegralLink::shells_to_hash(
int sh1,
int sh2,
int sh3,
int sh4)
148 return sh1 ^ (sh4<<4) ^ (sh2<<8) ^ (sh3<<12);
152 IntegralLink::hash()
const
154 return shells_to_hash(intlist.key.sh0(),
161 IntegralLink::size_to_actualsize(
int size)
163 return size*
sizeof(double) +
sizeof(IntegralLink) +
sizeof(
void*)*2;
167 IntegralLink::actualsize()
const
169 return size_to_actualsize(size);
172 class IntegralStorer:
public DescribedClass {
175 EAVLMMap<int,IntegralLink> costlist;
176 EAVLMMap<IntegralKey,IntegralLink>* table_;
183 IntegralStorer(
const Ref<KeyVal>&);
185 void init(
int nbytes);
187 IntegralLink *find(IntegralKey&);
188 int should_store(
int cost,
int actualsize);
189 void store(IntegralKey& key,
const double *buf,
190 int size,
int cost,
int actualsize);
192 int table_size()
const {
return table_size_; }
193 EAVLMMap<IntegralKey,IntegralLink>&table_entry(
int i){
return table_[i];}