7 #ifndef IMPISD_VON_MISES_SUFFICIENT_H
8 #define IMPISD_VON_MISES_SUFFICIENT_H
10 #include <IMP/isd/isd_config.h>
15 #include <boost/math/special_functions/bessel.hpp>
17 IMPISD_BEGIN_NAMESPACE
48 base::Object(
"von Mises sufficient %1%"), x_(chi), R0_(R0), chiexp_(chiexp)
52 force_set_kappa(kappa);
63 base::Object(
"von Mises sufficient %1%"), x_(chi)
65 Floats stats = get_sufficient_statistics(obs);
66 N_= (unsigned) stats[0];
69 force_set_kappa(kappa);
73 virtual double evaluate()
const
75 return logterm_ - R0_*kappa_*cos(x_-chiexp_);
78 virtual double evaluate_derivative_x()
const
80 return R0_*kappa_*sin(x_-chiexp_) ;
83 virtual double evaluate_derivative_kappa()
const
85 return - R0_ * cos(x_-chiexp_) + double(N_) * I1_/I0_ ;
89 virtual double density()
const
91 return exp(R0_*kappa_*cos(x_-chiexp_))/(2*
IMP::PI*I0N_);
95 double get_x() {
return x_; }
96 double get_R0() {
return R0_; }
97 double get_chiexp() {
return chiexp_; }
98 double get_N() {
return N_; }
99 double get_kappa() {
return kappa_; }
102 void set_x(
double x) {
106 void set_R0(
double R0) {
110 void set_chiexp(
double chiexp) {
114 void set_N(
unsigned N){
116 I0N_=pow(I0_, static_cast<int>(N_));
117 logterm_ = log(2*
IMP::PI*I0N_);
120 void set_kappa(
double kappa) {
121 if (kappa_ != kappa) {
122 force_set_kappa(kappa);
134 unsigned N = data.size();
138 for (
unsigned i=0; i<N; ++i){
139 cosbar += cos(data[i]);
140 sinbar += sin(data[i]);
142 double R=sqrt(cosbar*cosbar + sinbar*sinbar);
143 double chi=acos(cosbar/R);
144 if (sinbar < 0) chi=-chi;
153 <<
", " << N_ <<
", " << R0_ <<
", " << chiexp_
154 <<
", " << kappa_ <<std::endl, {});
157 double x_,R0_,chiexp_,kappa_,I0_,I1_,logterm_,I0N_;
159 void force_set_kappa(
double kappa) {
161 I0_ = double(boost::math::cyl_bessel_i(0, kappa));
162 I1_ = double(boost::math::cyl_bessel_i(1, kappa));
163 I0N_=pow(I0_, static_cast<int>(N_));
164 logterm_ = log(2*
IMP::PI*I0N_);