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