Main Page Class Hierarchy Compound List File List Compound Members Related Pages

# storage.h

    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     int sh0() const { return (sh0_sh1_p12_p34>>SH0_SHIFT) & SH_MASK; }
    00066     int sh1() const { return (sh0_sh1_p12_p34>>SH1_SHIFT) & SH_MASK; }
    00067     int p12() const { return (sh0_sh1_p12_p34>>P12_SHIFT) & PE_MASK; }
    00068     int p34() const { return (sh0_sh1_p12_p34>>P34_SHIFT) & PE_MASK; }
    00069     int sh2() const { return (sh2_sh3_p13p24>>SH2_SHIFT) & SH_MASK; }
    00070     int sh3() const { return (sh2_sh3_p13p24>>SH3_SHIFT) & SH_MASK; }
    00071     int p13p24() const { return (sh2_sh3_p13p24>>P13P24_SHIFT) & PE_MASK; }
    00072 };
    00073
    00074 inline
    00075 IntegralKey::IntegralKey(int sh1_, int sh2_, int sh3_, int sh4_,
    00076                          int p12_, int p34_, int p13p24_)
    00077 {
    00078   sh0_sh1_p12_p34 = (sh1_<<SH0_SHIFT)
    00079                     |(sh2_<<SH1_SHIFT)
    00080                     |(p12_<<P12_SHIFT)
    00081                     |(p34_<<P34_SHIFT);
    00082   sh2_sh3_p13p24 = (sh3_<<SH2_SHIFT)
    00083                    |(sh4_<<SH3_SHIFT)
    00084                    |(p13p24_<<P13P24_SHIFT);
    00085 }
    00086
    00087 inline
    00088 IntegralKey::IntegralKey(const IntegralKey& ik)
    00089 {
    00090   sh0_sh1_p12_p34 = ik.sh0_sh1_p12_p34;
    00091   sh2_sh3_p13p24 = ik.sh2_sh3_p13p24;
    00092 }
    00093
    00094 inline int
    00095 compare(const IntegralKey&k1, const IntegralKey&k2)
    00096 {
    00097   if (k1.sh0_sh1_p12_p34 < k2.sh0_sh1_p12_p34) return -1;
    00098   else if (k1.sh0_sh1_p12_p34 > k2.sh0_sh1_p12_p34) return 1;
    00099
    00100   if (k1.sh2_sh3_p13p24 < k2.sh2_sh3_p13p24) return -1;
    00101   else if (k1.sh2_sh3_p13p24 > k2.sh2_sh3_p13p24) return 1;
    00102   else return 0;
    00103 }
    00104
    00105 class IntegralLink {
    00106   public:
    00107     EAVLMMapNode<IntegralKey, IntegralLink> intlist;
    00108     EAVLMMapNode<int, IntegralLink> costlist;
    00109     int size;
    00110   public:
    00111     IntegralLink(IntegralKey& key, int cost, int size);
    00112     static int size_to_actualsize(int size);
    00113     ~IntegralLink();
    00114     int actualsize() const;
    00115     int hash() const;
    00116     static int shells_to_hash(int,int,int,int);
    00117     int cost() const { return costlist.key; }
    00118     void print();
    00119
    00120     // the integrals are squirreled away after this
    00121     double* buffer() { return (double*)&this[1]; }
    00122     void* operator new(size_t, int);
    00123     void operator delete(void*, int);
    00124     void operator delete(void*);
    00125 };
    00126
    00127 inline int
    00128 IntegralLink::shells_to_hash(int sh1,int sh2,int sh3,int sh4)
    00129 {
    00130   return sh1 ^ (sh4<<4) ^ (sh2<<8) ^ (sh3<<12);
    00131 }
    00132
    00133 inline int
    00134 IntegralLink::hash() const
    00135 {
    00136   return shells_to_hash(intlist.key.sh0(),
    00137                         intlist.key.sh1(),
    00138                         intlist.key.sh2(),
    00139                         intlist.key.sh3());
    00140 }
    00141
    00142 inline int
    00143 IntegralLink::size_to_actualsize(int size)
    00144 {
    00145   return size*sizeof(double) + sizeof(IntegralLink) + sizeof(void*)*2;
    00146 }
    00147
    00148 inline int
    00149 IntegralLink::actualsize() const
    00150 {
    00151   return size_to_actualsize(size);
    00152 }
    00153
    00154 class IntegralStorer: public DescribedClass {
    00155   private:
    00156     int table_size_;
    00157     EAVLMMap<int,IntegralLink> costlist;
    00158     EAVLMMap<IntegralKey,IntegralLink>* table_;
    00159     int maxsize_;
    00160     int currentsize_;
    00161     int n_integrals_;
    00162     int n_shellquart_;
    00163   public:
    00164     IntegralStorer();
    00165     IntegralStorer(const Ref<KeyVal>&);
    00166     ~IntegralStorer();
    00167     void init(int nbytes);
    00168     void done();
    00169     IntegralLink *find(IntegralKey&);
    00170     int should_store(int cost, int actualsize);
    00171     void store(IntegralKey& key, const double *buf,
    00172                int size, int cost, int actualsize);
    00173     void print_stats();
    00174     int table_size() const { return table_size_; }
    00175 };
    00176
    00177 }
    00178
    00179 #endif
    00180
    00181 #endif
    00182
    00183 // Local Variables:
    00184 // mode: c++
    00185 // c-file-style: "CLJ"
    00186 // End: