1 /** 2 * 3 * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(_at_LIP6) & Christophe GONZALES(_at_AMU) 4 * info_at_agrum_dot_org 5 * 6 * This library is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU Lesser General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public License 17 * along with this library. If not, see <http://www.gnu.org/licenses/>. 18 * 19 */ 20 21 22 #include <agrum/CN/tools/varMod2BNsMap.h> 23 24 namespace gum { 25 namespace credal { 26 27 template < typename GUM_SCALAR > VarMod2BNsMap()28 VarMod2BNsMap< GUM_SCALAR >::VarMod2BNsMap() { 29 cnet = nullptr; 30 31 GUM_CONSTRUCTOR(VarMod2BNsMap); 32 } 33 34 template < typename GUM_SCALAR > VarMod2BNsMap(const CredalNet<GUM_SCALAR> & cn)35 VarMod2BNsMap< GUM_SCALAR >::VarMod2BNsMap(const CredalNet< GUM_SCALAR >& cn) { 36 setCNet(cn); 37 38 GUM_CONSTRUCTOR(VarMod2BNsMap); 39 } 40 41 template < typename GUM_SCALAR > ~VarMod2BNsMap()42 VarMod2BNsMap< GUM_SCALAR >::~VarMod2BNsMap() { 43 GUM_DESTRUCTOR(VarMod2BNsMap); 44 } 45 46 template < typename GUM_SCALAR > setCNet(const CredalNet<GUM_SCALAR> & cn)47 void VarMod2BNsMap< GUM_SCALAR >::setCNet(const CredalNet< GUM_SCALAR >& cn) { 48 auto* cpt = &cn.credalNet_currentCpt(); 49 auto nNodes = cpt->size(); 50 sampleDef_.resize(nNodes); 51 52 for (NodeId node = 0; node < nNodes; node++) { 53 auto pConfs = (*cpt)[node].size(); 54 sampleDef_[node].resize(pConfs); 55 56 for (Size pconf = 0; pconf < pConfs; pconf++) { 57 Size nVertices = Size((*cpt)[node][pconf].size()); 58 unsigned long b, c; // needed by superiorPow 59 superiorPow(static_cast< unsigned long >(nVertices), b, c); 60 Size nBits = Size(b); 61 sampleDef_[node][pconf].resize(nBits); 62 } 63 } 64 65 cnet = &cn; 66 } 67 68 template < typename GUM_SCALAR > insert(const std::vector<bool> & bn,const std::vector<Size> & key)69 bool VarMod2BNsMap< GUM_SCALAR >::insert(const std::vector< bool >& bn, 70 const std::vector< Size >& key) { 71 currentHash_ = Size(vectHash_(bn)); 72 std::list< Size >& nets = myVarHashs_.getWithDefault(key, std::list< Size >()); //[ key ]; 73 74 for (std::list< Size >::iterator it = nets.begin(); it != nets.end(); ++it) { 75 if (*it == currentHash_) return false; 76 } 77 78 // add it 79 myHashNet_.set(currentHash_, bn); //[currentHash_] = bn; 80 // insert net hash in our key net list 81 nets.push_back(currentHash_); 82 // insert out key in the hash key list 83 myHashVars_.getWithDefault(currentHash_, 84 std::list< varKey >()) /*[currentHash_]*/.push_back(key); 85 return true; 86 } 87 88 template < typename GUM_SCALAR > insert(const std::vector<Size> & key,const bool isBetter)89 bool VarMod2BNsMap< GUM_SCALAR >::insert(const std::vector< Size >& key, const bool isBetter) { 90 if (isBetter) { 91 // get all nets of this key (maybe entry does not exists) 92 std::list< Size >& old_nets 93 = myVarHashs_.getWithDefault(key, std::list< Size >()); //[ key ]; 94 95 // for each one 96 for (std::list< Size >::iterator it = old_nets.begin(); it != old_nets.end(); ++it) { 97 // get all keys associated to this net 98 std::list< varKey >& netKeys 99 = myHashVars_.getWithDefault(*it, std::list< varKey >()); //[ *it ]; 100 101 // if we are the sole user, delete the net entry 102 if (netKeys.size() == 1) { 103 myHashVars_.erase(*it); 104 } 105 // other keys use the net, delete our key from list 106 else { 107 for (std::list< varKey >::iterator it2 = netKeys.begin(); it2 != netKeys.end(); ++it2) { 108 if (*it2 == key) { 109 netKeys.erase(it2); 110 break; 111 } 112 } 113 } 114 } // end of : for each old_net 115 116 // clear all old_nets 117 old_nets.clear(); 118 // insert new net with it's hash 119 myHashNet_.set(currentHash_, 120 currentSample_); //[currentHash_] = currentSample_; 121 // insert net hash in our key net list 122 old_nets.push_back(currentHash_); 123 // insert out key in the hash key list 124 myHashVars_ 125 .getWithDefault(currentHash_, std::list< varKey >()) /*[currentHash_]*/ 126 .push_back(key); 127 return true; 128 129 } // end of isBetter 130 // another opt net 131 else { 132 // check that we didn't add it for this key 133 std::list< Size >& nets = myVarHashs_.getWithDefault(key, std::list< Size >()); //[ key ]; 134 135 for (std::list< Size >::iterator it = nets.begin(); it != nets.end(); ++it) { 136 if (*it == currentHash_) return false; 137 } 138 139 // add it 140 myHashNet_.set(currentHash_, currentSample_); 141 // insert net hash in our key net list 142 nets.push_back(currentHash_); 143 // insert out key in the hash key list 144 myHashVars_.getWithDefault(currentHash_, std::list< varKey >()).push_back(key); 145 146 /* 147 // add it 148 myHashNet_[currentHash_] = currentSample_; 149 // insert net hash in our key net list 150 nets.push_back(currentHash_); 151 // insert out key in the hash key list 152 myHashVars_[currentHash_].push_back(key); 153 */ 154 return true; 155 } // end of ! isBetter 156 } 157 158 template < typename GUM_SCALAR > setCurrentSample(const std::vector<std::vector<std::vector<bool>>> & sample)159 void VarMod2BNsMap< GUM_SCALAR >::setCurrentSample( 160 const std::vector< std::vector< std::vector< bool > > >& sample) { 161 currentSample_.clear(); 162 163 for (Size i = 0; i < sample.size(); i++) 164 for (Size j = 0; j < sample[j].size(); j++) 165 for (Size k = 0; k < sample[i][j].size(); k++) 166 currentSample_.push_back(sample[i][j][k]); 167 168 // std::cout << sample << std::endl; 169 // std::cout << currentSample_ << std::endl; 170 171 currentHash_ = Size(vectHash_(currentSample_)); 172 } 173 174 template < typename GUM_SCALAR > getCurrentSample()175 const std::vector< bool >& VarMod2BNsMap< GUM_SCALAR >::getCurrentSample() { 176 return currentSample_; 177 } 178 179 template < typename GUM_SCALAR > 180 const std::vector< std::vector< std::vector< bool > > >& getSampleDef()181 VarMod2BNsMap< GUM_SCALAR >::getSampleDef() { 182 return sampleDef_; 183 } 184 185 template < typename GUM_SCALAR > 186 const std::vector< std::vector< bool >* > getBNOptsFromKey(const std::vector<Size> & key)187 VarMod2BNsMap< GUM_SCALAR >::getBNOptsFromKey(const std::vector< Size >& key) { 188 // return something even if key does not exist 189 if (!myVarHashs_.exists(key)) return std::vector< std::vector< bool >* >(); 190 191 std::list< Size >& netsHash = myVarHashs_[key]; //.at(key); 192 193 std::vector< dBN* > nets; 194 nets.resize(netsHash.size()); 195 196 std::list< Size >::iterator it = netsHash.begin(); 197 198 for (Size i = 0; i < netsHash.size(); i++, ++it) { 199 nets[i] = &myHashNet_ /*.at(*/[*it]; //); 200 } 201 202 return nets; 203 } 204 205 template < typename GUM_SCALAR > 206 std::vector< std::vector< std::vector< std::vector< bool > > > > getFullBNOptsFromKey(const std::vector<Size> & key)207 VarMod2BNsMap< GUM_SCALAR >::getFullBNOptsFromKey(const std::vector< Size >& key) { 208 if (cnet == nullptr) 209 GUM_ERROR(OperationNotAllowed, 210 "No CredalNet associated to me ! Can't get FullBNOptsFromKey : " << key); 211 212 if (!myVarHashs_.exists(key)) 213 return std::vector< std::vector< std::vector< std::vector< bool > > > >(); 214 215 std::list< Size >& netsHash = myVarHashs_[key]; //.at(key); 216 217 std::vector< std::vector< std::vector< std::vector< bool > > > > nets; 218 nets.resize(netsHash.size(), sampleDef_); 219 220 std::list< Size >::iterator it = netsHash.begin(); 221 222 for (Size i = 0; i < netsHash.size(); i++, ++it) { 223 // std::vector< std::vector< std::vector < bool > > > net(sampleDef_); 224 dBN::iterator it2 = myHashNet_ /*.at(*/[*it] /*)*/.begin(); 225 226 for (Size j = 0; j < sampleDef_.size(); j++) { 227 for (Size k = 0; k < sampleDef_[j].size(); k++) { 228 for (Size l = 0; l < sampleDef_[j][k].size(); l++) { 229 nets[i][j][k][l] = *it2; 230 ++it2; 231 } 232 } 233 } 234 } 235 236 return nets; 237 } 238 239 template < typename GUM_SCALAR > getEntrySize()240 Size VarMod2BNsMap< GUM_SCALAR >::getEntrySize() const { 241 return myHashNet_.size(); 242 } 243 244 } // namespace credal 245 } // namespace gum 246