00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef INC_STORM_H
00021 #define INC_STORM_H
00022
00023 #include <TooN/TooN.h>
00024 #include <cvd/image.h>
00025 #include <utility>
00026 #include <tr1/tuple>
00027 #include "utility.h"
00028
00029
00030
00031
00032
00033
00034
00035
00036 template<class B> double spot_shape_s(const TooN::Vector<2>& x, const TooN::Vector<4, double, B>& phi)
00037 {
00038 return -norm_sq(x - phi.template slice<2,2>()) / (2*phi[1]*phi[1]);
00039 }
00040
00041
00042
00043
00044
00045
00046 template<class B> std::pair<double, TooN::Vector<4> > spot_shape_diff_position(const TooN::Vector<2>& x, const TooN::Vector<4, double, B>& phi)
00047 {
00048 using namespace TooN;
00049
00050 double s = spot_shape_s(x, phi);
00051 double r_2_pi = sqrt(2*M_PI);
00052
00053 double prob = exp(s) * phi[0]/(phi[1]*r_2_pi);
00054
00055 Vector<4> deriv = (exp(s) / (phi[1]*r_2_pi)) *
00056 makeVector(1,
00057 -phi[0] * (1 + 2*s)/phi[1],
00058 (x[0] - phi[2])*(phi[0]/sq(phi[1])),
00059 (x[1] - phi[3])*(phi[0]/sq(phi[1])));
00060 return std::make_pair(prob, deriv);
00061 }
00062
00063
00064
00065
00066
00067
00068 template<class B> std::tr1::tuple<double, TooN::Vector<4>, TooN::Matrix<4> > spot_shape_hess_position(const TooN::Vector<2>& x, const TooN::Vector<4, double, B>& phi)
00069 {
00070 using namespace TooN;
00071 using namespace std::tr1;
00072
00073 double s = spot_shape_s(x, phi);
00074 double r_2_pi = sqrt(2*M_PI);
00075
00076 double es = exp(s);
00077
00078 double prob = es * phi[0]/(phi[1]*r_2_pi);
00079
00080 Vector<4> deriv = (es / (phi[1]*r_2_pi)) *
00081 makeVector(1,
00082 -phi[0] * (1 + 2*s)/phi[1],
00083 (x[0] - phi[2])*(phi[0]/sq(phi[1])),
00084 (x[1] - phi[3])*(phi[0]/sq(phi[1])));
00085
00086 Matrix<4> hess;
00087 hess[0][0] = 0;
00088
00089 hess[0][1] = -es*(1+2*s) / (phi[1] * phi[1] * r_2_pi);
00090 hess[1][0] = hess[0][1];
00091
00092 hess[0][2] = es * (x[0] - phi[2]) / (pow(phi[1], 3)*r_2_pi);
00093 hess[2][0] = es * (x[0] - phi[2]) / (pow(phi[1], 3)*r_2_pi);
00094
00095 hess[0][3] = es * (x[1] - phi[3]) / (pow(phi[1], 3)*r_2_pi);
00096 hess[3][0] = es * (x[1] - phi[3]) / (pow(phi[1], 3)*r_2_pi);
00097
00098 hess[1][1] = 2*phi[0]*es*(1 + 5*s + 2*s*s) / ( pow(phi[1], 3) * r_2_pi);
00099
00100 hess[1][2] = -phi[0] * es * (3 + 2*s) * (x[0] - phi[2]) / (pow(phi[1], 4) * r_2_pi);
00101 hess[1][3] = -phi[0] * es * (3 + 2*s) * (x[1] - phi[3]) / (pow(phi[1], 4) * r_2_pi);
00102
00103 hess[2][1] = hess[1][2];
00104 hess[3][1] = hess[1][3];
00105
00106 hess[2][2] = phi[0] * es * (sq(x[0] - phi[2]) - sq(phi[1])) / (r_2_pi * pow(phi[1], 5));
00107 hess[3][3] = phi[0] * es * (sq(x[1] - phi[3]) - sq(phi[1])) / (r_2_pi * pow(phi[1], 5));
00108
00109 hess[2][3] = phi[0] * es * (x[0] - phi[2])*(x[1] - phi[3]) / (r_2_pi * pow(phi[1], 5));
00110 hess[3][2] = hess[2][3];
00111
00112
00113 return make_tuple(prob, deriv, hess);
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 template<class B> std::tr1::tuple<double, TooN::Vector<2>, TooN::Matrix<2> > spot_shape_hess(const TooN::Vector<2>& x, const TooN::Vector<4, double, B>& phi)
00144 {
00145 double s = spot_shape_s(x, phi);
00146 double r_2_pi = sqrt(2*M_PI);
00147
00148 double prob = exp(s) * phi[0]/(phi[1]*r_2_pi);
00149 TooN::Vector<2> deriv = (exp(s) / (phi[1]*r_2_pi)) * TooN::makeVector(1, -phi[0] * (1 + 2*s)/phi[1]);
00150 TooN::Matrix<2> hess;
00151
00152 hess[0][0] = 0;
00153 hess[0][1] = -exp(s)*(1+2*s) / (phi[1] * phi[1] * r_2_pi);
00154 hess[1][0] = hess[0][1];
00155 hess[1][1] = 2*phi[0]*exp(s)*(1 + 5*s + 2*s*s) / ( pow(phi[1], 3) * r_2_pi);
00156
00157 return std::tr1::make_tuple(prob, deriv, hess);
00158 }
00159
00160
00161
00162
00163
00164
00165 template<class B> std::pair<double, TooN::Vector<2> > spot_shape_diff(const TooN::Vector<2>& x, const TooN::Vector<4, double, B>& phi)
00166 {
00167 double s = spot_shape_s(x, phi);
00168 double r_2_pi = sqrt(2*M_PI);
00169
00170 double prob = exp(s) * phi[0]/(phi[1]*r_2_pi);
00171 TooN::Vector<2> deriv = (exp(s) / (phi[1]*r_2_pi)) * TooN::makeVector(1, -phi[0] * (1 + 2*s)/phi[1]);
00172 return std::make_pair(prob, deriv);
00173 }
00174
00175
00176
00177
00178
00179
00180
00181 template<class B> double spot_shape(const TooN::Vector<2>& x, const TooN::Vector<4, double, B>& phi)
00182 {
00183 double s = spot_shape_s(x, phi);
00184 double r_2_pi = sqrt(2*M_PI);
00185
00186
00187
00188
00189 double prob = exp(s) * phi[0]/(phi[1]*r_2_pi);
00190
00191
00192 return prob;
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202 inline double log_probability_no_spot(const CVD::SubImage<float>& im, double variance)
00203 {
00204 double logprob_part=0;
00205 for(int y=0; y < im.size().y; y++)
00206 for(int x=0; x < im.size().x; x++)
00207 logprob_part -= im[y][x] * im[y][x];
00208 return logprob_part/(2*variance) - im.size().area() * log(2*M_PI*variance)/2;
00209
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 template<class Base> std::tr1::tuple<double, TooN::Vector<2>, TooN::Matrix<2> > log_probability_spot_hess(const CVD::SubImage<float>& im, double variance, const TooN::Vector<4, double, Base>& spot_parameters)
00237 {
00238 using namespace TooN;
00239 using namespace std::tr1;
00240
00241
00242
00243 Vector<2> centre = makeVector((im.size().x-1) / 2.0, (im.size().y-1) / 2.0);
00244
00245 double logprob_part=0;
00246 Vector<2> diff = Zeros;
00247 Matrix<2> hess = Zeros;
00248 for(int y=0; y < im.size().y; y++)
00249 for(int x=0; x < im.size().x; x++)
00250 {
00251 Vector<2> d = TooN::makeVector(x, y) - centre;
00252
00253 double mu;
00254 Vector<2> diff_mu;
00255 Matrix<2> hess_mu;
00256 tie(mu, diff_mu, hess_mu) = spot_shape_hess(d, spot_parameters);
00257
00258 double e = im[y][x] - mu;
00259
00260 logprob_part += -sq(e);
00261 diff += diff_mu * e;
00262 hess += e * hess_mu - diff_mu.as_col() * diff_mu.as_row();
00263 }
00264 return make_tuple( logprob_part / (2*variance) - im.size().area() * log(2*M_PI*variance)/2,
00265 diff / variance,
00266 hess / variance);
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276 template<class Base> std::pair<double, TooN::Vector<2> > log_probability_spot_diff(const CVD::SubImage<float>& im, double variance, const TooN::Vector<4, double, Base>& spot_parameters)
00277 {
00278 using namespace TooN;
00279 using namespace std::tr1;
00280 using namespace std;
00281
00282
00283 Vector<2> centre = makeVector((im.size().x-1) / 2.0, (im.size().y-1) / 2.0);
00284
00285 double logprob_part=0;
00286 Vector<2> diff = Zeros;
00287 for(int y=0; y < im.size().y; y++)
00288 for(int x=0; x < im.size().x; x++)
00289 {
00290 Vector<2> d = makeVector(x, y) - centre;
00291
00292 double mu;
00293 Vector<2> diff_mu;
00294 tie(mu, diff_mu) = spot_shape_diff(d, spot_parameters);
00295
00296 double e = im[y][x] - mu;
00297
00298 logprob_part += -sq(e);
00299 diff += diff_mu * e;
00300 }
00301 return make_pair(logprob_part / (2*variance) - im.size().area() * log(2*M_PI*variance)/2, diff / variance);
00302 }
00303
00304
00305
00306
00307
00308
00309
00310
00311 template<class Base> double log_probability_spot(const CVD::SubImage<float>& im, double variance, const TooN::Vector<4, double, Base>& spot_parameters)
00312 {
00313
00314
00315 TooN::Vector<2> centre = TooN::makeVector((im.size().x-1) / 2.0, (im.size().y-1) / 2.0);
00316
00317 double logprob_part=0;
00318 for(int y=0; y < im.size().y; y++)
00319 for(int x=0; x < im.size().x; x++)
00320 {
00321 TooN::Vector<2> d = TooN::makeVector(x, y) - centre;
00322
00323 double mu = spot_shape(d, spot_parameters);
00324
00325 double e = im[y][x] - mu;
00326
00327 logprob_part += -sq(e);
00328 }
00329 return logprob_part / (2*variance) - im.size().area() * log(2*M_PI*variance)/2;
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 inline double log_normal_std(double mu, double sigma)
00344 {
00345 return sqrt((exp(sq(sigma)) - 1) * exp(2*mu + sq(sigma)));
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 inline double log_normal_mode(double mu, double sigma)
00360 {
00361 return exp(mu - sigma * sigma);
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 inline double log_log_normal(double x, double mu, double sigma)
00375 {
00376 return -sq(ln(x) - mu) / (2*sq(sigma)) - ln(x) - ln(sigma * sqrt(2*M_PI));
00377 }
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 inline double diff_log_log_normal(double x, double mu, double sigma)
00389 {
00390 return -(1 + (ln(x) - mu)/sq(sigma)) / x;
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 inline double hess_log_log_normal(double x, double mu, double sigma)
00404 {
00405 return (1 + (ln(x) - mu - 1)/sq(sigma)) / sq(x);
00406 }
00407
00408
00409 #endif