00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef ETIRM_ITEMPOLYTOMOUS_H_
00021 #define ETIRM_ITEMPOLYTOMOUS_H_
00022
00023 #ifdef ETIRM_NO_DIR_PREFIX
00024 #include "etirmtypes.h"
00025 #include "ItemNR.h"
00026 #else
00027 #include "etirm/etirmtypes.h"
00028 #include "etirm/ItemNR.h"
00029 #endif
00030
00031 #if defined(ETIRM_USE_BOOST_CONFIG) || defined(BOOST_NO_LIMITS)
00032
00033
00034 #include <boost/detail/limits.hpp>
00035 #else
00036 #include <limits>
00037 #endif
00038
00039 #include <cmath>
00040 #ifdef BOOST_NO_STDC_NAMESPACE
00041
00042 namespace std
00043 { using ::log;}
00044 #endif
00045
00046 namespace etirm
00047 {
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 template <class LC, class M> class ItemPolytomous : public ItemNR<LC>
00063 {
00064
00065 public:
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 ItemPolytomous(int index, M &icrf, LC *dist);
00085
00086
00087 virtual ~ItemPolytomous();
00088
00089
00090
00091
00092
00093
00094
00095
00096 virtual RealVector GetAllParameters() const
00097 {
00098 RealVector allParam(mICRF.NumAllParameters());
00099 mICRF.GetAllParameters(ItemNR<LC>::mParameterEstimates, allParam);
00100 return allParam;
00101 }
00102
00103
00104 virtual void SetAllParameters(const RealVector &allParam)
00105 {
00106 mICRF.SetAllParameters(allParam.begin(), allParam.end(), ItemNR<LC>::mParameterEstimates);
00107 }
00108
00109
00110 virtual Real ICRF(const Response r, const RealVector ¶meters, const Real &theta) const;
00111
00112 virtual int ScaleParameters(Real slope, Real intercept, bool ignorePrior = false);
00113
00114
00115 virtual std::string ModelName() const
00116 {
00117 return mICRF.Name();
00118 }
00119
00120
00121 virtual IRTModel Model() const
00122 {
00123 return mICRF.Model();
00124 }
00125
00126
00127
00128
00129
00130 virtual double f_to_minimize(RealVector &p);
00131
00132 virtual void gradient(RealVector &p, RealVector &g);
00133
00134 virtual void hessian(RealVector &, RealMatrix &)
00135 {
00136 }
00137
00138 virtual int HasAnalyticGradient() const
00139 {
00140 return mICRF.GradientDefined();
00141 }
00142
00143 virtual int HasAnalyticHessian() const
00144 {
00145 return 0;
00146 }
00147
00148 protected:
00149
00150 M mICRF;
00151
00152
00153 };
00154
00155
00156 template <class LC, class M> ItemPolytomous<LC, M>::ItemPolytomous(int index, M &icrf, LC *dist) :
00157 ItemNR<LC>(icrf.NumParameters(), index, icrf.NumRespCat(), dist), mICRF(icrf)
00158 {
00159 if (ItemNR<LC>::mNRespCat != icrf.NumRespCat())
00160 {
00161 throw InvalidArgument("Mismatch in number of response categories for item and ICRF",
00162 "ItemPolytomous::ItemPolytomous");
00163 }
00164 }
00165
00166
00167 template <class LC, class M> ItemPolytomous<LC, M>::~ItemPolytomous()
00168 {
00169 }
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 template <class LC, class M> inline Real ItemPolytomous<LC, M>::ICRF(const Response r,
00190 const RealVector ¶meters, const Real &theta) const
00191 {
00192 return mICRF.ICRF(r, parameters, theta);
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 template <class LC, class M> double ItemPolytomous<LC, M>::f_to_minimize(RealVector ¶m)
00214 {
00215 int i, j, grp;
00216 Real value = 0.0;
00217 int ngroups = ItemNR<LC>::mLatentDist->NumGroupsUnique();
00218
00219
00220 for (grp=1; grp<=ngroups; ++grp)
00221 {
00222 Response r = ItemNR<LC>::FirstResponse();
00223 for (i = ItemNR<LC>::mNRespCat; i--; ++r)
00224 {
00225 typename ItemNR<LC>::r_iterator ir = ItemNR<LC>::RVector(r, grp);
00226 typename ItemNR<LC>::point_iterator it = ItemNR<LC>::mLatentDist->begin_points(grp);
00227 for (j=ItemNR<LC>::mNumLatentVarCat; j--; ++ir, ++it)
00228 {
00229 Real prob = mICRF.OpenICRF(r, param, *it);
00230 value += *ir * std::log(prob);
00231 }
00232 }
00233 }
00234
00235
00236 PriorVector::const_iterator iprior = ItemNR<LC>::mPriors.begin();
00237 RealVector::iterator iparam = param.begin();
00238 for (int j = ItemNR<LC>::NumParameters(); j--; ++iprior, ++iparam)
00239 {
00240 if (*iprior)
00241 {
00242 if ((*iprior)->ZeroDensity(*iparam))
00243 {
00244
00245
00246
00247 if (std::numeric_limits<Real>::has_infinity)
00248 {
00249 return std::numeric_limits<Real>::infinity();
00250 }
00251 else
00252 {
00253 return std::numeric_limits<Real>::max();
00254 }
00255 }
00256 else
00257 {
00258 value += (*iprior)->LogDensity(*iparam);
00259 }
00260 }
00261 }
00262
00263 return -value;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 template <class LC, class M> void ItemPolytomous<LC, M>::gradient(RealVector ¶m,
00286 RealVector &g)
00287 {
00288 g = 0.0;
00289 RealVector deriv(ItemNR<LC>::NumParameters(), 0.0);
00290
00291 int i, j, grp;
00292 int ngroups = ItemNR<LC>::mLatentDist->NumGroupsUnique();
00293
00294 for (grp=1; grp<=ngroups; ++grp)
00295 {
00296 Response r = ItemNR<LC>::FirstResponse();
00297 for (i = ItemNR<LC>::mNRespCat; i--; ++r)
00298 {
00299
00300 typename ItemNR<LC>::r_iterator ir = ItemNR<LC>::RVector(r, grp);
00301 typename ItemNR<LC>::point_iterator itheta = ItemNR<LC>::mLatentDist->begin_points(grp);
00302 for (j=ItemNR<LC>::mNumLatentVarCat; j--; ++ir, ++itheta)
00303 {
00304 Real t = *ir / mICRF.OpenICRF(r, param, *itheta);
00305
00306 mICRF.ICRFDeriv1(r, param, *itheta, deriv);
00307
00308
00309 deriv *= -t;
00310 g += deriv;
00311
00312 }
00313 }
00314 }
00315
00316
00317 PriorVector::const_iterator iprior = ItemNR<LC>::mPriors.begin();
00318 RealVector::iterator iparam = param.begin();
00319 RealVector::iterator ig = g.begin();
00320 for (int j = ItemNR<LC>::NumParameters(); j--; ++iprior, ++iparam, ++ig)
00321 {
00322
00323 if (*iprior)
00324 *ig -= (*iprior)->DerivLogDensity1(*iparam);
00325 }
00326
00327 }
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 template <class LC, class M> int ItemPolytomous<LC, M>::ScaleParameters(Real slope,
00350 Real intercept, bool ignorePriors)
00351 {
00352 RealVector scaledParam(ItemNR<LC>::mParameterEstimates);
00353
00354 mICRF.Scale(slope, intercept, scaledParam);
00355
00356
00357 if (!(ItemNR<LC>::ValidParameters(scaledParam, ignorePriors)))
00358 return 1;
00359
00360 ItemNR<LC>::mParameterEstimates = scaledParam;
00361
00362 return 0;
00363 }
00364
00365 }
00366
00367 #endif // ETIRM_ITEMPOLYTOMOUS_H_