[Insight-developers] Optimizers : CostFunction and Const-Correctness : ITK + VNL

Luis Ibanez luis.ibanez at kitware.com
Tue Mar 8 09:42:21 EST 2005


Dear vnl-users:


We have been using the VNL optimizer in the Insight Toolkit (ITK)
by wrapping them into thin ITK classes.


This is the case for classes such as:

    Amoeba
    Levenberg-Marquardt
    Conjugate gradient descent


We recently found a problem with the definition of const-correctness
in the vnl_cost_function that is propagating into ITK and preventing
us from implementing constness... correctly      :-)


We have noticed that VXL does in general a pretty good job of supporting
const-correctness. This make us think that you should have had good
reasons for leaving some of the cost-function methods to be non-const.
We will appreciate your insights on the rational behind the choices
you made for assigning const/non-const in the hierarchy of the cost
functions.


In general we will prefer not to have to modify our local copy of VNL
since that will result in a huge effort the next time we update VNL
in the ITK repository. It will be great if we can reach some consensus
on the best way of customizing these classes.



Here are the specific classes and methods of concern:


1) vnl_unary_function

    has the method f() with signature

        Return f( Argument const & i)  ===>  non-const

    This prevents the use of const-correctness on any class
    deriving from it, which includes all the functions used
    for optimization. In ITK this impacts all the Image Metrics
    used for registration, and the shape analysis active contours.



2) vnl_cost_function

    that derives from vnl_unary_function<> (class above)


    has methods f(), gradf(), compute() that are non-const,
    the full list is:


     virtual double f( vnl_vector<double> const & x );  : non-const
     virtual double gradf( vnl_vector<double> const & x,
                           vnl_vector<double> gradient ); : non-const

     virtual void compute( vnl_vector<double> const & x,
                           double * f,
                           vnl_vector<double> * g);    non-const

     void fdgradf( vnl_vector<double> const & x,
                   vnl_vector<double> const & gradient,
                   double stepsize );                   non-const


     virttual double reported_error(double f_value);   non-const

     vnl_vector<double> gradf( vnl_vector<double> const & x); non-const
     vnl_vector<double> fdgradf( vnl_vector<double> const & x); non-const




3)  vnl_identity

     a vnl_unary_function class that returns its own argument:

       T   f (  T const & x ) ;    non-const




In seems that in principle, there shouldn't be a reason for a
cost_function class to "change" when it is invoked for computing
a value, a gradient, or when reporting errors.  In the rare cases
when cost_function classes keep cache member variables, that
situation can be indicated with the "mutable" keyword, which will
document the intent of such variables appropriately.



We will be happy to send you the diff of the local modifications
that we have made in an attempt to support const-correctness in
the optimizers and const functions.


   Best regards,


      Luis





More information about the Insight-developers mailing list