00001 #ifndef vnl_least_squares_function_h_ 00002 #define vnl_least_squares_function_h_ 00003 // This is vxl/vnl/vnl_least_squares_function.h 00004 00005 00006 //: \file 00007 // \brief Abstract base for minimising functions 00008 // \author Andrew W. Fitzgibbon, Oxford RRG, 31 Aug 96 00009 00010 // 00011 // Modifications: 00012 // 280697 AWF Changed return type of f from double to void, as it wasn't used, and 00013 // people were going to extra trouble to compute it. 00014 // 20 Apr 1999 FSM 00015 // Added failure flag so that f() and grad() may signal failure to the caller. 00016 // 23/3/01 LSB (Manchester) Tidied documentation 00017 // 00018 #include <vcl_string.h> 00019 #include <vnl/vnl_vector.h> 00020 #include <vnl/vnl_matrix.h> 00021 00022 //: Abstract base for minimising functions 00023 // vnl_least_squares_function is an abstract base for functions to be minimized 00024 // by an optimizer. To define your own function to be minimized, subclass 00025 // from vnl_least_squares_function, and implement the pure virtual f (and 00026 // optionally grad_f). 00027 // 00028 // Whether or not f ought to be const is a problem. Clients might well 00029 // want to cache some information during the call, and if they're compute 00030 // objects, will almost certainly be writing to members during the 00031 // computation. For the moment it's non-const, but we'll see... 00032 class vnl_least_squares_function { 00033 public: 00034 enum UseGradient { 00035 no_gradient, 00036 use_gradient 00037 }; 00038 bool failure; 00039 00040 //: Construct vnl_least_squares_function, passing number of parameters 00041 // (unknowns, domain dimension) and number of residuals (range dimension). 00042 // The optional argument should be no_gradient if the gradf function has not 00043 // been implemented. 00044 vnl_least_squares_function(int number_of_unknowns, int number_of_residuals, UseGradient = use_gradient); 00045 00046 virtual ~vnl_least_squares_function(); 00047 00048 // the virtuals may call this to signal a failure. 00049 void throw_failure(); 00050 void clear_failure(); 00051 00052 // Computations-------------------------------------------------------------- 00053 00054 //: The main function. Given the parameter vector x, compute the vector 00055 // of residuals fx. Fx has been sized appropriately before the call. 00056 virtual void f(vnl_vector<double> const & x, vnl_vector<double>& fx) = 0; 00057 00058 //: Calculate the Jacobian, given the parameter vector x. 00059 virtual void gradf(vnl_vector<double> const & x, vnl_matrix<double>& jacobian); 00060 00061 //: Called after each LM iteration to print debugging etc. 00062 virtual void trace(int iteration, vnl_vector<double> const & x, vnl_vector<double> const & fx); 00063 00064 //: Compute the rms error at x by calling f and returning the norm of the residual 00065 // vector. 00066 double rms(vnl_vector<double> const & x); 00067 00068 // Data Access--------------------------------------------------------------- 00069 00070 //: Return the number of unknowns 00071 int get_number_of_unknowns() const { return p_; } 00072 00073 //: Return the number of residuals. 00074 int get_number_of_residuals() const { return n_; } 00075 00076 //: Return true if the derived class has indicated that gradf has been implemented 00077 bool has_gradient() const { return use_gradient_; } 00078 00079 protected: 00080 // Data Members-------------------------------------------------------------- 00081 int p_; 00082 int n_; 00083 bool use_gradient_; 00084 vcl_string print_x_fmt_; 00085 vcl_string print_f_fmt_; 00086 00087 void init(int number_of_unknowns, int number_of_residuals); 00088 }; 00089 00090 #endif // vnl_least_squares_function_h_