00001 /*! \file ItemParamPriorBeta4.cpp 00002 00003 \brief 00004 Class representing a four-parameter beta prior distribution of item parameters 00005 in Bayes modal estimation. 00006 00007 mParameter[0] = a shape parameter 00008 mParameter[1] = b shape parameter 00009 mParameter[2] = lower limit of distribution 00010 mParameter[3] = upper limit of distribution 00011 00012 Estimation Toolkit for Item Response Models (ETIRM) 00013 http://www.smallwaters.com/software/cpp/etirm.html 00014 00015 Author(s): 00016 Werner Wothke, maintenance (http://www.smallwaters.com) 00017 Brad Hanson (http://www.b-a-h.com/) 00018 See the file LICENSE for information on usage and redistribution. 00019 00020 Copyright (C) 2008, Werner Wothke 00021 Copyright (c) 2000-2001, Bradley A. Hanson 00022 */ 00023 00024 #ifdef ETIRM_NO_DIR_PREFIX 00025 #include "ItemParamPriorBeta4.h" 00026 #else 00027 #include "etirm/ItemParamPriorBeta4.h" 00028 #endif 00029 00030 #include <cmath> // for log 00031 // for compilers which do not put C library functions in std namespace 00032 #ifdef BOOST_NO_STDC_NAMESPACE 00033 namespace std 00034 { using ::log;} 00035 #endif 00036 00037 namespace etirm 00038 { 00039 00040 /*! 00041 \brief 00042 Class construction from a parameter vector. 00043 */ 00044 ItemParamPriorBeta4::ItemParamPriorBeta4(RealVector ¶m) : 00045 ItemParamPrior(param) 00046 { 00047 } 00048 00049 /*! 00050 \brief 00051 Class construction from four individual parameter values. 00052 */ 00053 ItemParamPriorBeta4::ItemParamPriorBeta4(Real a, Real b, Real l, Real u) : 00054 ItemParamPrior(4) 00055 { 00056 // check for valid parameters 00057 if (a <= 0.0 || b <= 0.0) 00058 throw RuntimeError("Invalid shape parameter for beta dist", 00059 "ItemParamPriorBeta4::ItemParamPriorBeta4"); 00060 if (l >= u) 00061 throw RuntimeError("Invalid upper or lower limit for beta dist", 00062 "ItemParamPriorBeta4::ItemParamPriorBeta4"); 00063 00064 mParameters[0] = a; 00065 mParameters[1] = b; 00066 mParameters[2] = l; 00067 mParameters[3] = u; 00068 } 00069 00070 /*! 00071 \brief 00072 Default constructor - assign uniform [0,1] distribution 00073 */ 00074 ItemParamPriorBeta4::ItemParamPriorBeta4() : 00075 ItemParamPrior(4) 00076 { 00077 00078 mParameters[0] = 1.0; 00079 mParameters[1] = 1.0; 00080 mParameters[2] = 0.0; 00081 mParameters[3] = 1.0; 00082 } 00083 00084 // If the density of x is zero then return the point nearest x that 00085 // has a non-zero density. 00086 Real ItemParamPriorBeta4::NearestNonZero(Real x) 00087 { 00088 // Density at lower and upper limits has zero 00089 // density, so return a value that is offset 00090 // from the lower and upper limits by the following amount 00091 const Real offset = 0.001; 00092 00093 if (x <= mParameters[2]) 00094 { 00095 return mParameters[2]+offset; 00096 } 00097 else if (x >= mParameters[3]) 00098 { 00099 return mParameters[3]-offset; 00100 } 00101 else 00102 { 00103 return x; 00104 } 00105 } 00106 00107 /*! 00108 \brief 00109 Only computes part of the log of the density that depends on the parameter. 00110 00111 \param[in] p Argument of log density function (an item parameter value) 00112 */ 00113 Real ItemParamPriorBeta4::LogDensity(Real p) 00114 { 00115 00116 /* Check for value outside limits of distribution */ 00117 if (ItemParamPriorBeta4::ZeroDensity(p)) 00118 { 00119 { 00120 return std::log(0.0); 00121 } 00122 } 00123 00124 Real value = (mParameters[0] - 1.0) * std::log(p - mParameters[2]); 00125 00126 value += (mParameters[1] - 1.0) * std::log(mParameters[3] - p); 00127 00128 return value; 00129 } 00130 00131 /*! 00132 \brief 00133 First derivative of log density. 00134 00135 Only computes part of the log of the density that depends on the parameter 00136 */ 00137 Real ItemParamPriorBeta4::DerivLogDensity1(Real p) 00138 { 00139 /* Outside limits of distribution density does not change, 00140 so derivative is zero */ 00141 if (ItemParamPriorBeta4::ZeroDensity(p)) 00142 return 0.0; 00143 00144 Real value = (mParameters[0] - 1.0) / (p - mParameters[2]); 00145 value -= (mParameters[1] - 1.0) / (mParameters[3] - p); 00146 00147 return value; 00148 } 00149 00150 /*! 00151 \brief 00152 Second derivative of log density. 00153 00154 Only computes part of the log of the density that depends on the parameter. 00155 */ 00156 Real ItemParamPriorBeta4::DerivLogDensity2(Real p) 00157 { 00158 /* Outside limits of distribution density does not change, 00159 so derivative is zero */ 00160 if (ItemParamPriorBeta4::ZeroDensity(p)) 00161 return 0.0; 00162 00163 Real denom = p - mParameters[2]; 00164 Real value = (1.0 - mParameters[0]); 00165 value /= denom*denom; 00166 denom = mParameters[3] - p; 00167 value -= (mParameters[1] - 1.0) / (denom*denom); 00168 00169 return value; 00170 } 00171 00172 } // namespace etirm