00001 /* 00002 * All of the documentation and software included in the 00003 * Alchemy Software is copyrighted by Stanley Kok, Parag 00004 * Singla, Matthew Richardson, Pedro Domingos, Marc 00005 * Sumner, Hoifung Poon, and Daniel Lowd. 00006 * 00007 * Copyright [2004-08] Stanley Kok, Parag Singla, Matthew 00008 * Richardson, Pedro Domingos, Marc Sumner, Hoifung 00009 * Poon, and Daniel Lowd. All rights reserved. 00010 * 00011 * Contact: Pedro Domingos, University of Washington 00012 * (pedrod@cs.washington.edu). 00013 * 00014 * Redistribution and use in source and binary forms, with 00015 * or without modification, are permitted provided that 00016 * the following conditions are met: 00017 * 00018 * 1. Redistributions of source code must retain the above 00019 * copyright notice, this list of conditions and the 00020 * following disclaimer. 00021 * 00022 * 2. Redistributions in binary form must reproduce the 00023 * above copyright notice, this list of conditions and the 00024 * following disclaimer in the documentation and/or other 00025 * materials provided with the distribution. 00026 * 00027 * 3. All advertising materials mentioning features or use 00028 * of this software must display the following 00029 * acknowledgment: "This product includes software 00030 * developed by Stanley Kok, Parag Singla, Matthew 00031 * Richardson, Pedro Domingos, Marc Sumner, Hoifung 00032 * Poon, and Daniel Lowd in the Department of Computer Science and 00033 * Engineering at the University of Washington". 00034 * 00035 * 4. Your publications acknowledge the use or 00036 * contribution made by the Software to your research 00037 * using the following citation(s): 00038 * Stanley Kok, Parag Singla, Matthew Richardson and 00039 * Pedro Domingos (2005). "The Alchemy System for 00040 * Statistical Relational AI", Technical Report, 00041 * Department of Computer Science and Engineering, 00042 * University of Washington, Seattle, WA. 00043 * http://www.cs.washington.edu/ai/alchemy. 00044 * 00045 * 5. Neither the name of the University of Washington nor 00046 * the names of its contributors may be used to endorse or 00047 * promote products derived from this software without 00048 * specific prior written permission. 00049 * 00050 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF WASHINGTON 00051 * AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 00052 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00053 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00054 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY 00055 * OF WASHINGTON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 00056 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00057 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00058 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00059 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00060 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00061 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00062 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 00063 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00064 * 00065 */ 00066 #include "bpnode.h" 00067 00068 /*****************************************************************************/ 00069 // Functions for class BPNode 00070 /*****************************************************************************/ 00071 00072 //add the factors with appropriate counts, also add the node to the 00073 //corresponding factor 00074 void BPNode::addFactors(Array<BPFactor *> * const & allFactors, 00075 LinkIdToTwoWayMessageMap* const & lidToTWMsg) 00076 { 00077 BPFactor *factor; 00078 BPLink *link; 00079 double cnt; 00080 ClauseCounter * counter = (ClauseCounter *)superPred_->getClauseCounter(); 00081 int numFactors = counter->getNumClauses(); 00082 const Array<double> * cnts; 00083 00084 for (int findex = 0; findex < numFactors; findex++) 00085 { 00086 int fid = counter->getClauseId(findex); 00087 cnts = counter->getClauseCounts(findex); 00088 factor = (*allFactors)[fid]; 00089 //predIndex is the predicate index in the clause/factor 00090 for (int predIndex = 0; predIndex < cnts->size(); predIndex++) 00091 { 00092 cnt = (*cnts)[predIndex]; 00093 if ((*cnts)[predIndex] == 0) 00094 continue; 00095 00096 //index where this node would be stored in the list of factors 00097 int reverseNodeIndex = factor->getNumLinks(); 00098 //index where this factor would be stored in the list of nodes 00099 int reverseFactorIndex = getNumLinks(); 00100 00101 link = new BPLink(this, factor, reverseNodeIndex, reverseFactorIndex, 00102 predIndex, cnt); 00103 00104 //now find the messages from parent nodes 00105 LinkId *lid; 00106 TwoWayMessage *tmsg; 00107 double *nodeToFactorMsgs, *factorToNodeMsgs; 00108 LinkIdToTwoWayMessageMap::iterator lidToTMsgItr; 00109 int parentSuperPredId = getParentSuperPredId(); 00110 int parentSuperClauseId = factor->getParentSuperClauseId(); 00111 00112 lid = new LinkId(predId_, parentSuperPredId, parentSuperClauseId, 00113 predIndex); 00114 lidToTMsgItr = lidToTWMsg->find(lid); 00115 delete lid; 00116 00117 if (lidToTMsgItr != lidToTWMsg->end()) 00118 { 00119 tmsg = lidToTMsgItr->second; 00120 nodeToFactorMsgs = tmsg->getNodeToFactorMessage(); 00121 factorToNodeMsgs = tmsg->getFactorToNodeMessage(); 00122 } 00123 else 00124 { 00125 nodeToFactorMsgs = NULL; 00126 factorToNodeMsgs = NULL; 00127 } 00128 this->addLink(link, nodeToFactorMsgs); 00129 factor->addLink(link,factorToNodeMsgs); 00130 } 00131 } 00132 } 00133 00134 //send the messages to all the factor nodes connected to this node 00135 void BPNode::sendMessage() 00136 { 00137 BPLink *link; 00138 BPFactor *factor; 00139 double cnt; 00140 double *msgs; 00141 double *outMsgs = new double[2]; 00142 00143 for (int lindex = 0; lindex < links_->size(); lindex++) 00144 { 00145 link = (*links_)[lindex]; 00146 factor = link->getFactor(); 00147 cnt = link->getCount(); 00148 //subtract the msg recieved from this factor node 00149 msgs = (*msgsArr_)[lindex]; 00150 for (int i = 0; i < 2; i++) 00151 { 00152 outMsgs[i] = msgProds_[i] - msgs[i]; 00153 } 00154 cout << "Link " << lindex << ": " << outMsgs[1] << " " << outMsgs[2] << endl; 00155 00156 //Assumes pass by value copy of the messages 00157 factor->receiveMessage(outMsgs, link); 00158 } 00159 delete [] outMsgs; 00160 } 00161 00162 //update the stored msgs and update the msgProduct 00163 void BPNode::moveToNextStep() 00164 { 00165 double * msgs; 00166 double * nextMsgs; 00167 double cnt; 00168 00169 //initialize to zero 00170 for (int i = 0; i < 2; i++) 00171 { 00172 msgProds_[i] = 0; 00173 } 00174 00175 //store the current messages in prevMessages array and 00176 //reinitialize the current message array 00177 for (int lindex = 0; lindex < links_->size(); lindex++) 00178 { 00179 msgs = (*msgsArr_)[lindex]; 00180 nextMsgs = (*nextMsgsArr_)[lindex]; 00181 00182 cnt = (*links_)[lindex]->getCount(); 00183 for (int i = 0; i < 2; i++) 00184 { 00185 msgs[i] = nextMsgs[i]; 00186 nextMsgs[i] = 0; 00187 //since we store the logs, we need to take the sum 00188 msgProds_[i] = msgProds_[i] + cnt*msgs[i]; 00189 } 00190 } 00191 } 00192