/** * @brief the cumulative gaussian likelihood function * @author Erik Rodner * @date 02/17/2010 */ #include #include #include "LHCumulativeGauss.h" using namespace OBJREC; using namespace std; static const double sqrt2pi = sqrt(2*M_PI); LHCumulativeGauss::LHCumulativeGauss( double _lengthScale, double _bias ) { lengthScale = _lengthScale; bias = _bias; } double LHCumulativeGauss::stdNormPDF (double x) { return exp(-x*x)/sqrt(M_PI); } double LHCumulativeGauss::thirdgrad ( double y, double f ) const { /** Computing the third gradient of the LOG likelihood with * respect to f * dl / df hessian = hessian * (-2 * (f*lengthScale + bias)) *lengthScale * + gradient * (-2*lengthScale*lengthScale) - 2 * hessian * gradient * **/ double gradient = this->gradient(y,f); double hessian = this->hessian(y,f); return -2* ( hessian*lengthScale*(f*lengthScale+bias) + gradient * lengthScale * lengthScale + hessian * gradient ); } double LHCumulativeGauss::hessian ( double y, double f ) const { /** Computing the hessian of the LOG likelihood with respect to f * d^2 / (d^2 f) log l(x) = d/df (dl/df * 1/l(f)) * = (d^2 l)/(d^2 f) 1/l(f) - dl/df dl/df / (l(f)^2) * = (d^2 l)/(d^2 f) 1/l(f) - gradient * gradient * * dl/df = y*lengthScale*stdNormPDF(f*lengthScale + bias) * d/df dl/df = y*lengthScale*stdNormPDF(f*lengthScale + bias)*(-2 * (f*lengthScale + bias)) * lengthScale * (d^2 l)/(d^2 f) / l(f) = gradient * (-2 * (f*lengthScale + bias)) * lengthScale * * **/ double gradient = this->gradient(y,f); return ( -2*(f*lengthScale + bias)*lengthScale*gradient - gradient*gradient ); } double LHCumulativeGauss::gradient ( double y, double f ) const { /* Computing the derivation of the LOG likelihood with respect to f * erf'(x) = 2/pi e^{-x*x} * phi'(x) = 1/pi e^{-x*x} = stdNormPDF(x) * x = y*(f*lengthScale + bias) * dx/dy = lengthScale*y * d/dx log l(x) = dl/dx * 1/l(x) * y is assumed to be in {-1, 1} * stdNormPDF(y*(f*lengthScale + bias)) = stdNormPDF(f*lengthScale + bias) * All of the above equations yield */ return ( y*lengthScale*stdNormPDF(f*lengthScale + bias)/likelihood(y,f) ); } double LHCumulativeGauss::logLike ( double y, double f ) const { return log ( likelihood(y, f) ); } double LHCumulativeGauss::likelihood ( double y, double f ) const { /* * erf(x) = 2/pi \int_0^x e^{-t*t} * The likelihood is denoted as phi(x) in the following. * phi(x) = (erf(x) + 1)/2 */ return ( ::erf(y*(f*lengthScale + bias))+1 ) / 2.0; } double LHCumulativeGauss::predictAnalytically ( double fmean, double fvariance ) const { // Rasmussen, Williams page 74 // \int_{-inf}^{inf} phi~((x-m)/v) N(x | mu, sigma^2) dx // = phi~( (mu-m)/(v*sqrt(1+sigma^2/v^2)) ) // phi^(f*lengthScale + bias) = phi~(f*sqrt(2)*lengthScale + bias*sqrt(2)) // v = 1 / (sqrt(2) * lengthScale) // m = - bias*sqrt(2) * v = - bias / lengthScale // // phi~(f) = phi^( f/sqrt(2) ) = phi( (f/(sqrt(2)*lengthScale) - bias/lengthScale) ) // // (mu-m)/(v*sqrt(1+sigma^2/v^2)) // = (fmean + bias/lengthScale) * sqrt(2) * lengthScale / sqrt(1 + sigma^2 * 2 * lssqr) // -> we would like to put this into our likelihood // (fmean + bias/lengthScale) * sqrt(2) * lengthScale / sqrt(1 + sigma^2 * 2 * lssqr) / (sqrt(2) * lengthScale) - bias/lengthScale // = (fmean + bias/lengthScale) / sqrt(1 + sigma^2 * 2 * lssqr) - bias/lengthScale // double lssqr = lengthScale * lengthScale; // variant without bias: return likelihood( 1.0, fmean / sqrt(1.0 + 2.0 * fvariance * lssqr) ); return likelihood( 1.0, (fmean + bias/lengthScale) / sqrt(1.0 + 2.0 * fvariance * lssqr) - bias/lengthScale ); }