contrib/brl/bbas/bsta/algo/bsta_fit_weibull.h
Go to the documentation of this file.
00001 // This is brl/bbas/bsta/algo/bsta_fit_weibull.h
00002 #ifndef bsta_fit_weibull_h_
00003 #define bsta_fit_weibull_h_
00004 //:
00005 // \file
00006 // \brief Fit a Weibull distribution given sufficient statistics
00007 // \author J. L. Mundy
00008 // \date November 8, 2008
00009 //
00010 // \verbatim
00011 //  Modifications
00012 //   (none yet)
00013 // \endverbatim
00014 
00015 #include <bsta/bsta_weibull.h>
00016 #include <vnl/vnl_cost_function.h>
00017 #include <vnl/algo/vnl_brent_minimizer.h>
00018 #include <vcl_cassert.h>
00019 
00020 class bsta_weibull_cost_function : public vnl_cost_function
00021 {
00022  public:
00023    //! Default constructor
00024   bsta_weibull_cost_function(): vnl_cost_function(1),
00025     mean_(1), std_dev_(1){}
00026 
00027   //! Construct with a specified number of unknowns
00028   bsta_weibull_cost_function(double mean, double std_dev):
00029     vnl_cost_function(1), mean_(mean), std_dev_(std_dev){}
00030 
00031   virtual ~bsta_weibull_cost_function() {}
00032 
00033   //:  The main function.  Given the parameter vector x, compute the value of f(x).
00034   virtual double f(vnl_vector<double> const& x);
00035 
00036   //:  Calculate the gradient of f at parameter vector x.
00037   virtual void gradf(vnl_vector<double> const& x, vnl_vector<double>& gradient);
00038   //: sample mean
00039   double mean() const {return mean_;}
00040 
00041   //: sample standard deviation
00042   double std_dev() const {return std_dev_;}
00043 
00044   //: Weibull scale parameter from sample mean and k
00045   double lambda(double k) const;
00046 
00047  private:
00048   double mean_;
00049   double std_dev_;
00050 };
00051 
00052 template <class T>
00053 class bsta_fit_weibull
00054 {
00055  public:
00056   bsta_fit_weibull() : wcf_(0), residual_(T(0)){}
00057   bsta_fit_weibull(bsta_weibull_cost_function* wcf) : wcf_(wcf), residual_(T(0)){}
00058 
00059   void set_cost_function(bsta_weibull_cost_function* wcf)
00060     {wcf_ = wcf;}
00061 
00062   //:provides an initial guess for k
00063   bool init(T& k)
00064   {
00065     if (!wcf_) return false;
00066     double m = wcf_->mean();
00067     double sd = wcf_->std_dev();
00068     if (!sd) return false;
00069     double ki = 1.0 + 1.21*((m/sd)-1.0);
00070     if (ki>0) {
00071       if (ki < 1.0)
00072         ki = 1.0001;  // we need it to be ki > 1.0
00073       k = static_cast<T>(ki);
00074       return true;
00075     } else
00076       return false;
00077   }
00078 
00079   //:solves for k that matches the sample mean and variance ratio
00080   void solve(T& k)
00081   {
00082     double kinit = static_cast<double>(k);
00083     vnl_brent_minimizer bmin(*wcf_);
00084     double kmin = bmin.minimize_given_bounds(1,kinit,10.0*kinit);
00085     double res = bmin.f_at_last_minimum();
00086     k = static_cast<T>(kmin);
00087     residual_ = static_cast<T>(res);
00088   }
00089   //: the residual after solving
00090   T residual() const {return residual_;}
00091 
00092   //: the Weibull scale parameter
00093   T lambda(T const& k) const
00094   {
00095     if (wcf_)
00096       return static_cast<T>(wcf_->lambda(k));
00097     return T(0);
00098   }
00099 
00100  private:
00101   bsta_weibull_cost_function* wcf_;
00102   T residual_;
00103 };
00104 
00105 #endif // bsta_fit_weibull_h_