00001 /// 00002 /// \file intervals.cpp 00003 /// \brief defintions for quantile(), p_value(), and hpd() 00004 /// \author Kent Holsinger 00005 /// \date 2005-05-18 00006 /// 00007 00008 00009 // This file is part of MCMC++, a library for constructing C++ programs 00010 // that implement MCMC analyses of Bayesian statistical models. 00011 // Copyright (c) 2004-2006 Kent E. Holsinger 00012 // 00013 // MCMC++ is free software; you can redistribute it and/or modify 00014 // it under the terms of the GNU General Public License as published by 00015 // the Free Software Foundation; either version 2 of the License, or 00016 // (at your option) any later version. 00017 // 00018 // MCMC++ is distributed in the hope that it will be useful, 00019 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00020 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00021 // GNU General Public License for more details. 00022 // 00023 // You should have received a copy of the GNU General Public License 00024 // along with MCMC++; if not, write to the Free Software 00025 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00026 // 00027 00028 // standard includes 00029 #include <algorithm> 00030 // local includes 00031 #include "mcmc++/intervals.h" 00032 00033 using std::vector; 00034 00035 /// Returns the sample quantile corresponding to p. 00036 /// 00037 /// This implementation corresponds to Type 8 continuous sample types 00038 /// of Hyndman and Fan (American Statistician, 50:361-365; 1996) 00039 /// 00040 /// Notice that as a side effect of calling this routine, the input 00041 /// vector is sorted. 00042 /// 00043 /// \param ox The vector from which to calculate the quantile 00044 /// \param p The desired quantile 00045 /// 00046 double quantile(vector<double>& ox, const double p) { 00047 unsigned int n = ox.size(); 00048 double pn = n*p; 00049 double m = (p + 1.0)/3.0; 00050 unsigned int j = static_cast<int>(floor(pn + m)); 00051 double q; 00052 std::sort(ox.begin(), ox.end()); 00053 if (j == 0) { 00054 q = ox[0]; 00055 } else if (j == n) { 00056 q = ox[n-1]; 00057 } else { 00058 double g = pn + m - j; 00059 q = (1.0 - g)*ox[j - 1] + g*ox[j]; 00060 } 00061 return q; 00062 } 00063 00064 /// Returns P(x <= p). 00065 /// 00066 /// Notice that as a side effect of calling this routine, the input 00067 /// vector is sorted. 00068 /// 00069 /// \param x The vector 00070 /// \param p The desired P-value 00071 /// 00072 double p_value(vector<double>& x, const double p) { 00073 unsigned i; 00074 std::sort(x.begin(), x.end()); 00075 for (i = 0; i < x.size(); i++) { 00076 if (x[i] > p) { 00077 break; 00078 } 00079 } 00080 return static_cast<double>(i) / x.size(); 00081 } 00082 00083 /// Returns HPD interval, low in x[0], high in x[1]. 00084 /// 00085 /// Returns lower limit of HPD interval in first element of vector, upper 00086 /// limit of HPD interval in second element of vector. This method is an 00087 /// implementation of the Chen-Shao HPD estimation algorithm. 00088 /// 00089 /// Notice that as a side effect of calling this routine, the input 00090 /// vector is sorted. 00091 /// 00092 /// \param x The vector 00093 /// \param p The credible interval desired, e.g., 0.95 for 95% 00094 /// 00095 vector<double> hpd(vector<double>& x, const double p) { 00096 vector<double> interval; 00097 std::sort(x.begin(), x.end()); 00098 // x.size()*p is the number of elements desired 00099 // x.size()*p - 1 is the index of the first (starting from 0) 00100 int idx = static_cast<int>(floor(x.size() * p - 1 + 0.5)); 00101 double shortest = x[idx] - x[0]; 00102 interval.push_back(x[0]); 00103 interval.push_back(x[idx]); 00104 00105 for (unsigned int i = 1; i + idx < x.size(); i++) { 00106 if (x[idx + i] - x[i] < shortest) { 00107 shortest = x[idx + i] - x[i]; 00108 interval[0] = x[i]; 00109 interval[1] = x[i + idx]; 00110 } 00111 } 00112 00113 return interval; 00114 } 00115 00116 00117 00118
1.5.1