C:/programs/etirm/src/ItemNR.h

Go to the documentation of this file.
00001 /*! \file ItemNR.h
00002  
00003   \brief
00004   ItemNR class, derived from Item, maintains information calculated for 
00005   an Item object in the E-step so that it can be used in the M-step
00006   to estimate item parameters.
00007  
00008   Information stored from the E-step includes the expected number of
00009   examinees in each category of the discrete latent variable of those
00010   that took the item (these usually are denoted by the letter "n"),
00011   and for each item response the expected number of examinees in each
00012   category of the discrete latent variable who gave that item response
00013   of those examinees who took the item (these usually are denoted by
00014   the letter "r").
00015 
00016   Estimation Toolkit for Item Response Models (ETIRM)
00017   http://www.smallwaters.com/software/cpp/etirm.html
00018 
00019   Author(s): 
00020   Werner Wothke, maintenance (http://www.smallwaters.com)
00021   Brad Hanson (http://www.b-a-h.com/)
00022   See the file LICENSE for information on usage and redistribution.
00023 
00024   Copyright (C) 2008, Werner Wothke
00025   Copyright (c) 2000-2001, Bradley A. Hanson
00026  */
00027 
00028 #ifndef ETIRM_ITEMNR_H_
00029 #define ETIRM_ITEMNR_H_
00030 
00031 #ifdef ETIRM_NO_DIR_PREFIX
00032 #include "Item.h"
00033 #else
00034 #include "etirm/Item.h"
00035 #endif
00036 
00037 namespace etirm
00038 {
00039   /*!    
00040     \brief
00041     Class, derived from Item, to maintain information calculated for 
00042     an Item object in the E-step so that it can be used in the M-step
00043     to estimate item parameters.
00044  
00045     Information stored from the E-step includes the expected number of
00046     examinees in each category of the discrete latent variable of those
00047     that took the item (these usually are denoted by the letter "n"),
00048     and for each item response the expected number of examinees in each
00049     category of the discrete latent variable who gave that item response
00050     of those examinees who took the item (these usually are denoted by
00051     the letter "r").
00052 
00053     \section template_args Template Parameters
00054    
00055     \param D  Class for discrete latent variable distribution.
00056    */
00057   template <class D> class ItemNR : public Item<typename D::latentvar_type>
00058   {
00059 
00060 public:
00061   
00062     //! Type iterator over responses of an item.
00063     typedef RealMatrix::row_iterator r_iterator;
00064     
00065     //! Type iterator over number of examinees who responded to an item.
00066     typedef RealVector::iterator n_iterator;
00067 
00068     //! Type iterator over quadrature points.
00069     typedef typename D::point_iterator point_iterator;
00070     
00071     /*!
00072       \brief
00073       Constructor.
00074       
00075       \section template_args Template Parameters
00076    
00077       \param D  Class for discrete latent variable distribution.
00078     
00079       \section function_args Function Parameters
00080 
00081       \param[in] nparam Number of item parameters.
00082       \param[in] index  Zero-offset index of item in vector of all item responses.
00083       \param[in] respCat  Number of response categories.
00084       \param[in] dist Latent variable distribution.
00085      */ 
00086     ItemNR(int nparam, int index, int respCat, D *dist = 0);
00087 
00088     //! Destructor.
00089     virtual ~ItemNR();
00090 
00091     /*!
00092       \brief
00093       Returns iterator to first element of row of mR corresponding to response "resp" 
00094       for examinee group "group" (where the first examinee group is group 1)
00095     
00096       \section function_args Function Parameters
00097     
00098       \param[in] resp Response vector.
00099       \param[in] group  Examinee group (default =1).
00100      */ 
00101     r_iterator RVector(Response resp, int group = 1);
00102 
00103     /*!
00104       \brief
00105       Returns iterator to first element of mN for examinee group "group" 
00106       (where the first examinee group is group 1).
00107       
00108       \section function_args Function Parameters
00109     
00110       \param[in]  group Group index.
00111      */
00112     n_iterator NVector(int group = 1);
00113 
00114 
00115     /*!
00116       \brief
00117       Assigns values associated with discrete latent variable categories.
00118       
00119       Note: I was not able to locate any SetLatentVarPoints function in the code base.
00120       It is questionable whether this function is operative at all (ww, 2-28-2008).
00121       
00122       \section function_args Function Parameters
00123    
00124       \param[in]  n Number of discrete categories of the latent ability distribution.
00125       \param[in]  points  Iterator over quadrature points.
00126      */
00127     void SetLatentVarPoints(int n, point_iterator points);
00128 
00129     /*!
00130       \brief
00131       Returns iterator over quadrature points.
00132 
00133       \section function_args Function Parameters
00134    
00135       \param[in]  group \ Examinee group (1, 2, ..., "number of groups").
00136      */       
00137     point_iterator GetLatentVarPoints(int group = 1)
00138     {
00139       return mLatentDist->begin_points(group);
00140     }
00141 
00142     //! Returns number of discrete latent variable categories.
00143     int NumLatentVarCat()
00144     {
00145       return mNumLatentVarCat;
00146     }
00147 
00148     /*!
00149       \brief
00150       Initializes elements of mR and mN to zero.
00151      */
00152     void InitializeNR();
00153 
00154     /*  The following functions provide an interface to minimization routines (such as UNCMIN)
00155      that are used in the M-step to estimates parameters for one item. */
00156 
00157     /*! 
00158       \brief
00159       Function to maximize in M-step.
00160       
00161       \section function_args Function Parameters
00162       
00163       \param[in] &p Address of item parameter vector.
00164       
00165       Note: Technically, negative value of function is being minimized, so the negative function 
00166         value is being returned.
00167      */
00168     virtual double f_to_minimize(RealVector &p) = 0;
00169 
00170     /*!
00171       \brief
00172       Computes gradient of function to maximize in M-step.
00173       
00174       \section function_args Function Parameters
00175       
00176       \param[in] &p Address of item parameter vector.
00177       \param[out] &g  Address of gradient vector. Gradient values are returned in the vector elements.
00178       
00179       Note: Technically, negative value of function is being minimized, so the negative gradient 
00180         is being returned.
00181      */
00182     virtual void gradient(RealVector &p, RealVector &g) = 0;
00183 
00184     /*!
00185       \brief
00186       Computes hessian of function to maximize in M-step.
00187       
00188       Note: Technically, the negative value of the function is to be minimized by UNCMIN++,
00189            see inline comments in function code.
00190       
00191       Note: The hessian is stored in the lower trangle of h.
00192      */
00193     virtual void hessian(RealVector &x, RealMatrix &h) = 0;
00194 
00195     /*!
00196       \brief
00197       Function to indicate that the algebraic gradient of the item (ICCDeriv1) is defined.
00198       
00199       This function can be used by UNCMIN++.
00200      */
00201     virtual int HasAnalyticGradient() const = 0;
00202 
00203     /*!
00204       \brief
00205       Function to indicate that the algebraic hessian of the item (ICCDeriv2) is defined.
00206       
00207       This function can be used by UNCMIN++.
00208      */
00209     virtual int HasAnalyticHessian() const = 0;
00210 
00211     /*!
00212       \brief
00213       Returns 1 if all parameters have a non-zero prior density, or 0 otherwise.
00214       
00215       \section function_args Function Parameters
00216       
00217       \param[in]  &p Address of parameter vector for this item.
00218       \param[in]  ignorePriors  Boolan flag to bypass the test of prior densities.
00219      */
00220     virtual int ValidParameters(const RealVector &p, bool ignorePriors = false) const;
00221 
00222     /*!
00223       \brief
00224       Number of item parameters.
00225      */
00226     int dim() const
00227     {
00228       return Item<typename D::latentvar_type>::NumParameters();
00229     } // Added "Item<typename D::latentvar_type>::" to NumParameters method call. ww, 1/12/2008
00230 
00231 protected:
00232 
00233     D *mLatentDist;
00234     //!< Latent variable distribution used to determine discrete categories on the latent variable.
00235 
00236     /*!
00237       \brief
00238       Expected number of respondents in each latent variable category
00239       who took this item and gave the i-th response.
00240       
00241       If there are different points for different examinee groups
00242       the expected number of examinees will differ for different groups,
00243       and will be stacked in each row.
00244 
00245       The first mNumLatentVarCat values will be for the first group,
00246       the second mNumLatentVarCat values will be for the second group, etc.
00247       These expected counts are computed in the E-step.
00248      */
00249     RealMatrix *mR;
00250 
00251     /*!
00252       \brief
00253       Expected number of examinees who took this item in
00254       each latent variable category.
00255       
00256       If there are different points for different examinee groups
00257       the expected number of examinees will differ for different groups,
00258       and will be stacked.
00259 
00260       The first mNumLatentVarCat values will be for the first group,
00261       the second mNumLatentVarCat values will be for the second group, etc.
00262       These expected counts are computed in the E-step.
00263      */
00264     RealVector *mN;
00265 
00266 
00267     int mNumLatentVarCat;
00268     //!< Number of latent variable categories.
00269 
00270   };
00271 
00272   /* 
00273     \brief
00274     Class constructor.
00275    
00276     \section template_args Template Parameters
00277    
00278     \param D  Class for discrete latent variable distribution.
00279 
00280     \section function_args Function Parameters
00281     
00282     \param[in]  nparam  Number of item parameters
00283     \param[in]  index   Zero-offset index of item in vector of all item responses
00284     \param[in]  respCat Number of response categories for item.
00285     \param[in]  dist    Latent variable distribution used to define discrete 
00286         latent variable points.
00287    */
00288   template <class D>
00289 #ifndef BOOST_MSVC
00290   ItemNR<D>::ItemNR(int nparam, int index, int respCat, D *dist) :
00291     Item<typename D::latentvar_type>(nparam, index, respCat),
00292 #else
00293         ItemNR<D>::ItemNR(int nparam, int index, int respCat, D *dist) : Item<D::latentvar_type>(nparam, index, respCat),
00294 #endif
00295         mLatentDist(dist), mR(0), mN(0), mNumLatentVarCat(0)
00296   {
00297     if (dist)
00298     {
00299       mNumLatentVarCat = dist->size();
00300       // Compute total number of latent distribution points over all groups for
00301       // which the points are unique
00302       int totpoints = mLatentDist->NumGroupsUnique() * mNumLatentVarCat;
00303 
00304       mR = new RealMatrix(respCat, totpoints);
00305       mN = new RealVector(totpoints);
00306     }
00307   }
00308 
00309   /*
00310     \brief
00311     Class destructor. 
00312    */
00313   template <class D> ItemNR<D>::~ItemNR()
00314   {
00315     if (mN)
00316       delete mN;
00317     if (mR)
00318       delete mR;
00319   }
00320 
00321   /*
00322     \brief
00323     Initializes elements of mR and mN to zero.
00324    */
00325   template <class D> void ItemNR<D>::InitializeNR()
00326   {
00327     if (mN)
00328       *mN = 0.0;
00329     if (mR)
00330       *mR = 0.0;
00331   }
00332 
00333   /*
00334     \brief
00335     Returns iterator to first element of row of mR corresponding to response "resp" 
00336     for examinee group "group" (where the first examinee group is group 1)
00337     
00338     \section function_args Function Parameters
00339     
00340     \param[in] resp Response vector.
00341     \param[in] group  Examinee group.
00342    */
00343   template <class D> typename ItemNR<D>::r_iterator ItemNR<D>::RVector(Response resp, int group)
00344   {
00345     int ngroups = mLatentDist->NumGroups();
00346     if (group > ngroups || group < 1)
00347       throw InvalidArgument("Invalid group", "ItemNR::RVector");
00348 
00349     r_iterator rvec = mR->begin_row(Item<typename D::latentvar_type>::ResponseIndex(resp)+1); // Added "Item<typename D::latentvar_type>::" to ResponseIndex method call. ww, 1/12/2008
00350 
00351     return (mLatentDist->NumGroupsUnique() == 1) ? rvec : (rvec + (group-1) * mNumLatentVarCat);
00352   }
00353 
00354   /*
00355     \brief
00356     Returns iterator to first element of mN for examinee group "group" 
00357     (where the first examinee group is group 1).
00358     
00359     \section function_args Function Parameters
00360     
00361     \param[in]  group Group index.
00362    */
00363   template <class D> typename ItemNR<D>::n_iterator ItemNR<D>::NVector(int group)
00364   {
00365     int ngroups = mLatentDist->NumGroups();
00366     if (group > ngroups || group < 1)
00367       throw InvalidArgument("Invalid group", "ItemNR::NVector");
00368 
00369     n_iterator nvec = mN->begin();
00370     return (mLatentDist->NumGroupsUnique() == 1) ? nvec : (nvec + (group-1) * mNumLatentVarCat);
00371   }
00372 
00373   /*
00374     \brief
00375     Returns 1 if all parameters have a non-zero prior density, or 0 otherwise.
00376     
00377     \section function_args Function Parameters
00378     
00379     \param[in]  &param Address of parameter vector for this item.
00380     \param[in]  ignorePriors  Boolan flag to bypass the test of prior densities.
00381    */
00382   template <class D> int ItemNR<D>::ValidParameters(const RealVector &param, bool ignorePriors) const
00383   {
00384     // For each parameter check that prior density at the value of the
00385     // parameter is not zero
00386     if (!ignorePriors)
00387     {
00388       PriorVector::const_iterator iprior = Item<typename D::latentvar_type>::mPriors.begin();
00389       RealVector::const_iterator iparam = param.begin();
00390       for (int i=Item<typename D::latentvar_type>::NumParameters(); i--; ++iprior, ++iparam) // Added "Item<typename D::latentvar_type>::" to NumParameters method call. ww, 1/12/2008
00391       {
00392         if (*iprior)
00393         {
00394           if ((*iprior)->ZeroDensity(*iparam))
00395           {
00396             return 0;
00397           }
00398         }
00399       }
00400     }
00401     return 1;
00402   }
00403 
00404 } // namespace etirm
00405 
00406 #endif // ETIRM_ITEMNR_H_

Generated on Sat Mar 1 21:40:15 2008 for ETIRM by  doxygen 1.5.4