/*! \file HyParEstimator.h \brief Contains declaration of class for estimating hyper parameters for a given GP model and data. \author Jesper Andersson \version 1.0b, Nov., 2013. */ // Contains declaration of class for estimating // hyper parameters for a given GP model and data. // // HyParEstimator.h // // Jesper Andersson, FMRIB Image Analysis Group // // Copyright (C) 2013 University of Oxford // #ifndef HyParEstimator_h #define HyParEstimator_h #include #include #include #include #include #include #include #include "armawrap/newmat.h" #include "miscmaths/miscmaths.h" #include "miscmaths/nonlin.h" #include "EddyHelperClasses.h" #include "KMatrix.h" namespace EDDY { class FourthDimension { public: explicit FourthDimension(unsigned int d4) : _d4(d4) {} unsigned int _d4; }; class DataSelector { public: DataSelector(const std::vector > >& idata, const NEWIMAGE::volume& mask, unsigned int nvox, int rndinit=0) EddyTry { common_constructor(idata,mask,nvox,0.0,0,rndinit); } EddyCatch DataSelector(const std::vector > >& idata, const NEWIMAGE::volume& mask, unsigned int nvox, float fwhm, int rndinit=0) EddyTry { common_constructor(idata,mask,nvox,fwhm,0,rndinit); } EddyCatch DataSelector(const std::vector > >& idata, const NEWIMAGE::volume& mask, unsigned int nvox, const FourthDimension& d4, int rndinit=0) EddyTry { common_constructor(idata,mask,nvox,0.0,d4._d4,rndinit); } EddyCatch DataSelector(const std::vector > >& idata, const NEWIMAGE::volume& mask, unsigned int nvox, const FourthDimension& d4, float fwhm, int rndinit=0) EddyTry { common_constructor(idata,mask,nvox,fwhm,d4._d4,rndinit); } EddyCatch ~DataSelector() {} const std::vector& GetData() const EddyTry { return(_data); } EddyCatch DataSelector& ConcatToMe(const DataSelector& ds); NEWMAT::Matrix AsNEWMAT() const; NEWMAT::Matrix CoordsAsNEWMAT() const; void Write(const std::string& fname) const EddyTry { MISCMATHS::write_ascii_matrix(AsNEWMAT(),fname); } EddyCatch void WriteCoords(const std::string& fname) const EddyTry { MISCMATHS::write_ascii_matrix(CoordsAsNEWMAT(),fname); } EddyCatch private: void common_constructor(const std::vector > >& idata, const NEWIMAGE::volume& mask, unsigned int nvox, float fwhm, unsigned int d4, int rndinit); float get_smooth(const NEWIMAGE::volume& ima, const NEWIMAGE::volume& mask, const std::vector& coords, const std::vector& kernels); std::vector _data; // std::vector > _coords; // }; class HyParCF : public MISCMATHS::NonlinCF { public: HyParCF(unsigned int nthreads) EddyTry { _nthreads=nthreads; } EddyCatch HyParCF() EddyTry : HyParCF(1) {} EddyCatch virtual ~HyParCF() {} virtual std::shared_ptr Clone() const = 0; virtual void SetData(const std::vector& data) EddyTry { _data = data; } EddyCatch virtual void SetKMatrix(std::shared_ptr K) EddyTry { _K = K->Clone(); } EddyCatch virtual double cf(const NEWMAT::ColumnVector& p) const = 0; protected: std::vector _data; // Data std::shared_ptr _K; // K-matrix unsigned int _nthreads; // No of threads for cf double sqr(double a) const { return(a*a); } float sqr(float a) const { return(a*a); } bool is_odd(int val) const { return(bool(val%2)); } }; class MMLHyParCF : public HyParCF { public: MMLHyParCF(unsigned int nthreads) EddyTry : HyParCF(nthreads) {} EddyCatch MMLHyParCF() EddyTry : MMLHyParCF(1) {} EddyCatch virtual ~MMLHyParCF() {} std::shared_ptr Clone() const EddyTry { return(std::shared_ptr(new MMLHyParCF(*this))); } EddyCatch double cf(const NEWMAT::ColumnVector& p) const; private: /// Helper function for when running cf() multi-threaded void cf_helper(// Input unsigned int first, unsigned int last, const std::vector& data, const std::shared_ptr K, // Output double& neg_log_marg_ll) const; }; class CVHyParCF : public HyParCF { public: CVHyParCF(unsigned int nthreads) EddyTry : HyParCF(nthreads) {} EddyCatch CVHyParCF() EddyTry : CVHyParCF(1) {} EddyCatch virtual ~CVHyParCF() {} std::shared_ptr Clone() const EddyTry { return(std::shared_ptr(new CVHyParCF(*this))); } EddyCatch double cf(const NEWMAT::ColumnVector& p) const; private: /// Helper function for when running cf() multi-threaded void cf_helper(// Input unsigned int first, unsigned int last, unsigned int tid, // Thread number (N.B. not thread.id()) unsigned int numt, // Number of threads std::vector& threads, const std::vector& data, const std::shared_ptr K, // Output std::vector& ssd_vec_vec) const; }; class GPPHyParCF : public HyParCF { public: GPPHyParCF(unsigned int nthreads) EddyTry : HyParCF(nthreads) {} EddyCatch GPPHyParCF() EddyTry : GPPHyParCF(1) {} EddyCatch virtual ~GPPHyParCF() {} std::shared_ptr Clone() const EddyTry { return(std::shared_ptr(new GPPHyParCF(*this))); } EddyCatch double cf(const NEWMAT::ColumnVector& p) const; }; class HyParEstimator { public: HyParEstimator() {} HyParEstimator(const NEWMAT::ColumnVector& hpar) EddyTry : _hpar(hpar) {} EddyCatch virtual ~HyParEstimator() {} virtual std::shared_ptr Clone() const = 0; std::vector GetHyperParameters() const EddyTry { return(newmat_2_stl(_hpar)); } EddyCatch virtual unsigned int GetNVox() const { return(0); } virtual int RndInit() const { return(0); } virtual void SetData(const std::vector& data) {} virtual void Estimate(std::shared_ptr K, bool verbose) = 0; protected: const NEWMAT::ColumnVector& get_hpar() const EddyTry { return(_hpar); } EddyCatch void set_hpar(const NEWMAT::ColumnVector& hpar) EddyTry { _hpar = hpar; } EddyCatch std::vector newmat_2_stl(const NEWMAT::ColumnVector& nm) const EddyTry { std::vector stl(nm.Nrows()); for (unsigned int i=0; i& stl) const EddyTry { NEWMAT::ColumnVector nm(stl.size()); for (unsigned int i=0; i Clone() const EddyTry { return(std::shared_ptr(new FixedValueHyParEstimator(*this))); } EddyCatch virtual void Estimate(std::shared_ptr K, bool verbose) EddyTry { if (verbose) std::cout << "Hyperparameters set to user specified values: " << get_hpar() << std::endl; } EddyCatch }; class CheapAndCheerfulHyParEstimator : public HyParEstimator { public: CheapAndCheerfulHyParEstimator(unsigned int nvox=1000, int ir=0) EddyTry : _nvox(nvox), _ir(ir) {} EddyCatch virtual ~CheapAndCheerfulHyParEstimator() {} std::shared_ptr Clone() const EddyTry { return(std::shared_ptr(new CheapAndCheerfulHyParEstimator(*this))); } EddyCatch virtual unsigned int GetNVox() const { return(_nvox); } virtual int RndInit() const { return(_ir); } virtual void SetData(const std::vector& data) EddyTry { _data = data; } EddyCatch virtual void Estimate(std::shared_ptr K, bool verbose); private: unsigned int _nvox; int _ir; // Initialise rand? std::vector _data; }; class FullMontyHyParEstimator : public HyParEstimator { public: FullMontyHyParEstimator(std::shared_ptr hpcf, double evff=1.0, unsigned int nvox=1000, int ir=0, bool verbose=false) EddyTry : _cf(hpcf->Clone()), _evff(evff), _nvox(nvox), _ir(ir), _v(verbose) {} EddyCatch virtual ~FullMontyHyParEstimator() {} std::shared_ptr Clone() const EddyTry { return(std::shared_ptr(new FullMontyHyParEstimator(*this))); } EddyCatch virtual unsigned int GetNVox() const { return(_nvox); } virtual int RndInit() const { return(_ir); } virtual void SetData(const std::vector& data) EddyTry { _data = data; } EddyCatch virtual void Estimate(std::shared_ptr K, bool verbose); private: static const unsigned int MITER=500; std::shared_ptr _cf; // Cost-function object for use with nonlin double _evff; // Error variance fudge factor unsigned int _nvox; int _ir; bool _v; // Verbose flag std::vector _data; }; } // End namespace EDDY #endif // end #ifndef HyParEstimator_h