00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifdef ETIRM_NO_DIR_PREFIX
00020 #include "ICRF_GPCM.h"
00021 #else
00022 #include "etirm/ICRF_GPCM.h"
00023 #endif
00024
00025 #include <cmath>
00026 #if defined(ETIRM_USE_BOOST_CONFIG) || defined(BOOST_NO_LIMITS)
00027
00028
00029 #include <boost/detail/limits.hpp>
00030 #else
00031 #include <limits>
00032 #endif
00033
00034 #ifdef BOOST_NO_STDC_NAMESPACE
00035
00036 namespace std
00037 { using ::exp;}
00038 #endif
00039
00040 namespace etirm
00041 {
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 Real ICRF_GPCM::ICRF(Response r, const RealVector ¶m, Real theta) const
00056 {
00057
00058 Real z = 0.0;
00059 Real num = (r == mFirstResponse) ? 1.0 : -1.0;
00060 Real sum = 1.0;
00061 Real a = param[0];
00062 Response ir = mFirstResponse+1;
00063 RealVector::const_iterator ip = param.begin()+1;
00064 for (int i = mNumCat-1; i--; ++ir, ++ip)
00065 {
00066 z += a * (theta - *ip);
00067 Real ez = std::exp(z);
00068 if (ir == r)
00069 num = ez;
00070
00071 sum += ez;
00072 }
00073
00074 return num/sum;
00075
00076 }
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 Real ICRF_GPCM::OpenICRF(Response r, const RealVector ¶m, Real theta) const
00087 {
00088
00089 double prob = ICRF(r, param, theta);
00090
00091
00092 if (prob <= 0.0)
00093 {
00094 prob = std::numeric_limits<Real>::min();
00095 }
00096 else if (prob >= 1.0)
00097 {
00098 prob = 1.0 - std::numeric_limits<Real>::epsilon();
00099 }
00100
00101 return prob;
00102 }
00103
00104
00105
00106
00107
00108
00109
00110 void ICRF_GPCM::ExpZ(const RealVector ¶m, Real theta)
00111 {
00112 Real a = param[0];
00113
00114 mExpz[0] = 1.0;
00115 mDenom = 1.0;
00116 RealVector::iterator ie = mExpz.begin()+1;
00117 RealVector::const_iterator ip = param.begin() + 1;
00118 Real num = 0.0;
00119 for (int i = mNumCat-1; i--; ++ip, ++ie)
00120 {
00121 num += a * (theta - *ip);
00122 *ie = std::exp(num);
00123 mDenom += *ie;
00124 }
00125
00126 mDenom2 = mDenom * mDenom;
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 void ICRF_GPCM::ICRFDeriv1(Response r, const RealVector ¶m, Real theta, RealVector &deriv)
00142 {
00143 ExpZ(param, theta);
00144
00145 Real probnum = mExpz[r - mFirstResponse];
00146 Real a = param[0];
00147
00148
00149 Real du = 0.0;
00150 Real nderiv = 0.0;
00151 Real dderiv = 0.0;
00152 RealVector::const_iterator ip = param.begin()+1;
00153 RealVector::const_iterator ie = mExpz.begin()+1;
00154 Response ir = mFirstResponse + 1;
00155 int i;
00156 for (i = mNumCat-1; i--; ++ip, ++ie, ++ir)
00157 {
00158 du += theta - *ip;
00159 dderiv += du * *ie;
00160 if (ir == r)
00161 nderiv = du * *ie;
00162 }
00163 deriv[0] = nderiv * mDenom;
00164 deriv[0] -= probnum * dderiv;
00165 deriv[0] /= mDenom2;
00166
00167
00168
00169 ie = mExpz.begin()+mNumCat-1;
00170 RealVector::iterator id = deriv.begin() + mNumCat-1;
00171 dderiv = 0.0;
00172 nderiv = -a * probnum;
00173 ir = mFirstResponse + mNumCat - 1;
00174 for (i = mNumCat-1; i--; --ir, --ie, --id)
00175 {
00176 dderiv += -a * *ie;
00177
00178 if (ir <= r)
00179 *id = nderiv * mDenom;
00180 else
00181 *id = 0.0;
00182 *id -= probnum * dderiv;
00183 *id /= mDenom2;
00184 }
00185
00186 }
00187
00188
00189
00190
00191 void ICRF_GPCM::Scale(Real slope, Real intercept, RealVector ¶m)
00192 {
00193
00194
00195 param[0] /= slope;
00196
00197
00198 RealVector::iterator ip = param.begin() + 1;
00199 for (int i = mNumParameters-1; i--; ++ip)
00200 {
00201 *ip *= slope;
00202 *ip += intercept;
00203 }
00204 }
00205
00206
00207 void ICRF_GPCM::GetAllParameters(const RealVector &estParam, RealVector &allParam) const
00208 {
00209 if (estParam.size() != mNumParameters || allParam.size() != mNumParameters)
00210 {
00211 throw InvalidArgument("Invalid number of parameters", "ICRF_GPCM::GetAllParameters");
00212 }
00213
00214 RealVector::iterator ia = allParam.begin();
00215 RealVector::const_iterator ie = estParam.begin();
00216 for (int i = mNumParameters; i--; ++ia, ++ie)
00217 {
00218 *ia = *ie;
00219 }
00220 }
00221
00222 }