node.h

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 #ifndef _NODE_H_Jan_2008
00068 #define _NODE_H_Jan_2008
00069 
00070 #include <math.h>
00071 #include "util.h"
00072 #include "mrf.h"
00073 #include "array.h"
00074 #include "link.h"
00075 #include "superpred.h"
00076 #include "twowaymessage.h"
00077 #include "factor.h"
00078 
00079 const double MIN = 1e-6;
00080 const double MINEXP = logl(MIN);
00081 
00082 const double SMOOTHTERM = 1e-6;
00083 
00084 using namespace std;
00085 using namespace __gnu_cxx;
00086 
00090 class Node
00091 {
00092  public:
00093 
00097   Node(int predId, SuperPred * const & superPred, 
00098        Array<int> * const & constants, Domain * const & domain)
00099   {
00100     predId_ = predId;
00101     superPred_ = superPred;
00102     constants_ = constants;
00103     domain_ = domain;
00104     links_ = new Array<Link *>();
00105     auxLinks_ = new Array<Link *>();
00106     msgsArr_ = new Array<double *>();
00107     nextMsgsArr_ = new Array<double *>();
00108     msgProds_[0] = msgProds_[1] = 0;
00109   }
00110 
00114   ~Node()
00115   {
00116     for (int i = 0; i < links_->size(); i++)
00117       delete (*links_)[i];
00118     for (int i = 0; i < auxLinks_->size(); i++)
00119       delete (*auxLinks_)[i];
00120     for (int i = 0; i < msgsArr_->size(); i++)
00121     {
00122       delete (*msgsArr_)[i];
00123       delete (*nextMsgsArr_)[i];
00124     }
00125     delete links_;
00126     delete auxLinks_;
00127     delete msgsArr_;
00128     delete nextMsgsArr_;
00129   }
00130 
00131   int getPredId() { return predId_;}
00132 
00133   int getSuperPredId()
00134   {
00135     if (superPred_) 
00136       return superPred_->getSuperPredId();
00137     else
00138       return -1;
00139   }
00140 
00141   int getParentSuperPredId()
00142   {
00143     if (superPred_) 
00144       return superPred_->getParentSuperPredId();
00145     else
00146       return -1;
00147   }
00148 
00149   SuperPred* getSuperPred() {return superPred_;}
00150   Array<int> * getConstants() {return constants_;}
00151 
00152   int getGroundNodeCount()
00153   {
00154     if (superPred_)
00155     {
00156       return superPred_->getNumTuples();
00157     }
00158     else
00159       return 1;
00160   }
00161 
00166   int getNumLinks() { return links_->size();}
00167   
00168   Link * getLink(int index) {return (*links_)[index];}
00169   
00177   void getMessage(int index, double msgs[])
00178   {
00179     msgs[0] = (*msgsArr_)[index][0];
00180     msgs[1] = (*msgsArr_)[index][1];
00181   }
00182 
00187   void addAuxLink(Link *link)
00188   {
00189     auxLinks_->append(link);
00190   }
00191 
00196   void addLink(Link *link, double inpMsgs[2])
00197   {
00198     links_->append(link);
00199     double *msgs;
00200     msgs = new double[2];
00201 
00202     double cnt = link->getCount(); 
00203     for (int i = 0; i < 2; i++)
00204     {
00205       if (inpMsgs)
00206       {
00207         msgs[i] = inpMsgs[i];
00208       }
00209       else
00210       {
00211         msgs[i] = 0;
00212       }
00213       msgProds_[i] = msgProds_[i] + cnt*msgs[i];
00214     }
00215 
00216     msgsArr_->append(msgs);
00217     msgs = new double[2];
00218     nextMsgsArr_->append(msgs);
00219   }
00220 
00225   void addFactors(Array<Factor *> * const & allFactors,
00226                   LinkIdToTwoWayMessageMap* const & lidToTWMsg);
00227 
00231   void receiveMessage(double* inpMsgs, Link * const & link)
00232   {
00233     double *nextMsgs;
00234     int reverseFactorIndex = link->getReverseFactorIndex();
00235     nextMsgs = (*nextMsgsArr_)[reverseFactorIndex];
00236     nextMsgs[0] = inpMsgs[0];
00237     nextMsgs[1] = inpMsgs[1];
00238   }
00239 
00240   double getExp()
00241   {
00242     double exp = msgProds_[1] - msgProds_[0];
00243     return exp;
00244   }
00245 
00250   double * getProbs(double * const & probs)
00251   {
00252     double exps[2];
00253     double norm, smooth;
00254     exps[0] = 0; //msgProds_[0];
00255     exps[1] = msgProds_[1] - msgProds_[0];
00256 
00257     for (int i = 0; i < 2; i++)
00258     {
00259       if(exps[i] < MINEXP)
00260         exps[i] = MINEXP;
00261       if(exps[i] > -MINEXP)
00262         exps[i] = -MINEXP;
00263       probs[i] = expl(exps[i]);
00264     }
00265 
00266     norm = probs[0] + probs[1];
00267     smooth = norm*SMOOTHTERM;
00268     norm += smooth;
00269 
00270     for (int i = 0; i < 2 ; i++)
00271     {
00272       probs[i] += smooth/2;
00273       probs[i] = probs[i]/norm;
00274     }
00275     return probs;       
00276   }
00277 
00281   void sendMessage();
00282 
00286   void sendAuxMessage();
00287 
00291   void moveToNextStep();
00292 
00293   ostream& print(ostream& out)
00294   {
00295     out << predId_ << ": ";
00296     if (superPred_ != NULL)
00297       printArray(*(superPred_->getConstantTuple(0)),out);
00298     else
00299       printArray(*constants_,out);
00300     return out;
00301   }
00302 
00303  private:
00304 
00305   int predId_;
00306 
00307     //only one of the two below is used - superPred in case of lifted
00308     //inference and constants in case of ground inference
00309   SuperPred * superPred_;
00310   Array<int> *constants_;
00311 
00312   Domain * domain_;
00313 
00314   Array<Link *> * links_;
00315     // Links to auxiliary factors
00316   Array<Link *> * auxLinks_;
00317     //log of the actual message received from factor is stored
00318   Array<double *> * msgsArr_; 
00319   Array<double *> * nextMsgsArr_;
00320 
00321     //we store these so that we do not have to n^2 squared
00322     //computation while calculating the outgoing messages - we can 
00323     //just divide (subtract in the log domain) by the message from the 
00324     //factor node to which it is being sent
00325   double msgProds_[2];
00326 };
00327 
00328 #endif
00329 

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