gelmanconvergencetest.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 and Hoifung Poon.
00006  * 
00007  * Copyright [2004-07] Stanley Kok, Parag Singla, Matthew
00008  * Richardson, Pedro Domingos, Marc Sumner and Hoifung
00009  * Poon. 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 and Hoifung
00032  * Poon 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 #ifndef GELMANCONVERGENCETEST_H_SEP_30_2005
00067 #define GELMANCONVERGENCETEST_H_SEP_30_2005
00068 
00069 #include "meanvariance.h"
00070 
00074 class GelmanConvergenceTest
00075 {
00076  public:
00077   GelmanConvergenceTest(const int& numChains) :
00078     numChains_(numChains), 
00079     withinChainMeanVars_(new MeanVariance[numChains]),
00080     numSamples_(0) {}
00081 
00082   ~GelmanConvergenceTest() { delete [] withinChainMeanVars_; }
00083 
00084 
00085     // values is array of size numChains_
00086   void appendNewValues(const double* const & values) 
00087   {
00088     for (int i = 0; i < numChains_; i++)
00089       withinChainMeanVars_[i].appendValue(values[i]);
00090     numSamples_++;
00091   }
00092 
00093     // values is array of size numChains_
00094   void appendNewValues(const bool* const & values) 
00095   {
00096     for (int i = 0; i < numChains_; i++)
00097       withinChainMeanVars_[i].appendValue((double)values[i]);
00098     numSamples_++;
00099   }
00100 
00101 
00102   double getConvergenceScore()
00103   {
00104     betweenChainsMeanVar_.reset();
00105     double totalW = 0;
00106     for (int i = 0; i < numChains_; i++) 
00107     {
00108       betweenChainsMeanVar_.appendValue( withinChainMeanVars_[i].getMean() );
00109       totalW += withinChainMeanVars_[i].getVariance();
00110     }
00111     int numValues = withinChainMeanVars_[0].getNumValues();
00112 
00113     double B = betweenChainsMeanVar_.getVariance() * numValues;
00114     double W = totalW / numChains_;
00115 
00116       // score as stated in "Probability and Statistics", DeGroot and Schervish
00117     double score = B/W;
00118     return score; 
00119   }
00120   
00121 
00122   int getNumSamplesAdded() { return numSamples_; }
00123 
00124 
00125   static bool checkConvergenceOfAll(GelmanConvergenceTest* tests[], 
00126                                     const int& numTests,
00127                                     const bool& print=false) 
00128   {
00129     // threshold as stated in "Probability and Statistics", DeGroot & Schervish 
00130     double threshold = 1 + 0.44 * tests[0]->getNumSamplesAdded();
00131     int maxItem     = -1;
00132     double maxScore = -1;
00133     int numbad      = 0;
00134 
00135     for (int f = 0; f < numTests; f++) 
00136     {
00137       double score = tests[f]->getConvergenceScore();
00138 
00139       if (!finite(score)) { numbad++; continue; }
00140 
00141       if (score > threshold) 
00142       {
00143         if (print)
00144           cout << " Item " << f << "'s score of " << score << " > threshold of "
00145                << threshold << endl; 
00146         return false;
00147       }
00148 
00149       if (score > maxScore) 
00150       {
00151         maxScore = score;
00152         maxItem = f;
00153       }
00154     }
00155 
00156     if (numbad == numTests)
00157     {
00158       if (print) cout << " All scores were inf or Nan!" << endl;
00159       return false;
00160     }
00161   
00162     // at this point all scores are less than the threshold
00163 
00164     if (print)
00165       cout << " max item is " << maxItem << " with score " << maxScore 
00166            << " < threshold of " << threshold << endl; 
00167 
00168     return true;
00169   }
00170 
00171 
00172  private:  
00173   int numChains_;
00174   MeanVariance* withinChainMeanVars_;
00175   int numSamples_;
00176   MeanVariance betweenChainsMeanVar_;
00177 
00178 };
00179 
00180 
00181 #endif

Generated on Tue Jan 16 05:30:02 2007 for Alchemy by  doxygen 1.5.1