node.cpp

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, Daniel Lowd, and Jue Wang.
00006  * 
00007  * Copyright [2004-09] Stanley Kok, Parag Singla, Matthew
00008  * Richardson, Pedro Domingos, Marc Sumner, Hoifung
00009  * Poon, Daniel Lowd, and Jue Wang. 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, Daniel Lowd, and Jue Wang in the Department of
00033  * Computer Science and Engineering at the University of
00034  * Washington".
00035  * 
00036  * 4. Your publications acknowledge the use or
00037  * contribution made by the Software to your research
00038  * using the following citation(s): 
00039  * Stanley Kok, Parag Singla, Matthew Richardson and
00040  * Pedro Domingos (2005). "The Alchemy System for
00041  * Statistical Relational AI", Technical Report,
00042  * Department of Computer Science and Engineering,
00043  * University of Washington, Seattle, WA.
00044  * http://alchemy.cs.washington.edu.
00045  * 
00046  * 5. Neither the name of the University of Washington nor
00047  * the names of its contributors may be used to endorse or
00048  * promote products derived from this software without
00049  * specific prior written permission.
00050  * 
00051  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF WASHINGTON
00052  * AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00053  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00054  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00055  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY
00056  * OF WASHINGTON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00057  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00058  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00059  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00060  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00061  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00062  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00063  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00064  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00065  * 
00066  */
00067 #include "node.h"
00068 
00069 /*****************************************************************************/
00070 // Functions for class Node
00071 /*****************************************************************************/
00072 
00073   //add the factors with appropriate counts, also add the node to the
00074   //corresponding factor
00075 void Node::addFactors(Array<Factor *> * const & allFactors,
00076                       LinkIdToTwoWayMessageMap* const & lidToTWMsg)
00077 {
00078   Factor *factor;
00079   Link *link;
00080   double cnt;
00081   ClauseCounter * counter = (ClauseCounter *)superPred_->getClauseCounter();
00082   int numFactors = counter->getNumClauses();
00083   const Array<double> * cnts;
00084 
00085   for (int findex = 0; findex < numFactors; findex++)
00086   {
00087     int fid = counter->getClauseId(findex);  
00088     cnts = counter->getClauseCounts(findex);
00089     factor = (*allFactors)[fid];
00090       //predIndex is the predicate index in the clause/factor
00091     for (int predIndex = 0; predIndex < cnts->size(); predIndex++)
00092     {
00093       cnt = (*cnts)[predIndex]; 
00094       if ((*cnts)[predIndex] == 0)
00095         continue;
00096 
00097         //index where this node would be stored in the list of factors
00098       int reverseNodeIndex = factor->getNumLinks();
00099         //index where this factor would be stored in the list of nodes
00100       int reverseFactorIndex = getNumLinks();
00101 
00102       link = new Link(this, factor, reverseNodeIndex, reverseFactorIndex,
00103                         predIndex, cnt);
00104 
00105         //now find the messages from parent nodes
00106       LinkId *lid;
00107       TwoWayMessage *tmsg;
00108       double *nodeToFactorMsgs, *factorToNodeMsgs;
00109       LinkIdToTwoWayMessageMap::iterator lidToTMsgItr;
00110       int parentSuperPredId = getParentSuperPredId();
00111       int parentSuperClauseId = factor->getParentSuperClauseId();
00112 
00113       lid = new LinkId(predId_, parentSuperPredId, parentSuperClauseId,
00114                        predIndex);
00115       lidToTMsgItr = lidToTWMsg->find(lid);
00116       delete lid;
00117 
00118       if (lidToTMsgItr != lidToTWMsg->end())
00119       {
00120         tmsg = lidToTMsgItr->second;
00121         nodeToFactorMsgs = tmsg->getNodeToFactorMessage();
00122         factorToNodeMsgs = tmsg->getFactorToNodeMessage();
00123       }
00124       else
00125       {
00126         nodeToFactorMsgs = NULL;
00127         factorToNodeMsgs = NULL;
00128       }
00129       this->addLink(link, nodeToFactorMsgs);
00130       factor->addLink(link,factorToNodeMsgs);
00131     }
00132   }
00133 }
00134 
00135   //send the messages to all the factor nodes connected to this node
00136 void Node::sendMessage()
00137 {
00138   Link *link;
00139   Factor *factor;
00140   double cnt;
00141   double *msgs;
00142   double *outMsgs = new double[2];
00143 
00144   for (int lindex = 0; lindex < links_->size(); lindex++)
00145   {
00146     link = (*links_)[lindex];
00147     factor = link->getFactor();
00148     cnt = link->getCount();
00149       //subtract the msg recieved from this factor node
00150     msgs = (*msgsArr_)[lindex];
00151     for (int i = 0; i < 2; i++)
00152     {
00153       outMsgs[i] = msgProds_[i] - msgs[i];
00154     }
00155 
00156       //Assumes pass by value copy of the messages
00157     factor->receiveMessage(outMsgs, link);
00158   }
00159   delete [] outMsgs;
00160 }
00161 
00162   //send the messages to all the auxiliary factor nodes connected to this node
00163 void Node::sendAuxMessage()
00164 {
00165   Link *link;
00166   Factor *factor;
00167   double cnt;
00168   //double *msgs;
00169   double *outMsgs = new double[2];
00170 
00171   for (int lindex = 0; lindex < auxLinks_->size(); lindex++)
00172   {
00173     link = (*auxLinks_)[lindex];
00174     factor = link->getFactor();
00175     cnt = link->getCount();
00176     for (int i = 0; i < 2; i++)
00177     {
00178       outMsgs[i] = msgProds_[i];
00179     }
00180 
00181       //Assumes pass by value copy of the messages
00182     factor->receiveMessage(outMsgs, link);
00183   }
00184   delete [] outMsgs;
00185 }
00186 
00187 
00188   //update the stored msgs and update the msgProduct
00189 void Node::moveToNextStep()
00190 {
00191   double * msgs;
00192   double * nextMsgs;
00193   double cnt;
00194 
00195     //initialize to zero
00196   for (int i = 0; i < 2; i++)
00197   {
00198     msgProds_[i] = 0;
00199   }
00200 
00201     //store the current messages in prevMessages array and
00202     //reinitialize the current message array
00203   for (int lindex = 0; lindex < links_->size(); lindex++)
00204   {
00205     msgs = (*msgsArr_)[lindex];
00206     nextMsgs = (*nextMsgsArr_)[lindex];
00207 
00208       // MS: Weight of clause, but should be count of nodes belonging to supernode
00209     //if (superPred_)
00210     //  cnt = superPred_->getNumTuples();
00211     //else
00212     //  cnt = 1;
00213     cnt = (*links_)[lindex]->getCount();
00214     for (int i = 0; i < 2; i++)
00215     {
00216       msgs[i] = nextMsgs[i];
00217       nextMsgs[i] = 0;
00218         //since we store the logs, we need to take the sum
00219       msgProds_[i] = msgProds_[i] + cnt*msgs[i];
00220     }
00221   }
00222 }
00223 

Generated on Sun Jun 7 11:55:13 2009 for Alchemy by  doxygen 1.5.1