contrib/rpl/rgrl/rgrl_trans_spline.cxx
Go to the documentation of this file.
00001 //:
00002 // \file
00003 // \author Lee, Ying-Lin (Bess)
00004 // \date  Sept 2003
00005 
00006 #include "rgrl_trans_spline.h"
00007 #include <rgrl/rgrl_util.h>
00008 #include <rgrl/rgrl_trans_reader.h>
00009 #include <vcl_iostream.h>
00010 #include <vcl_cassert.h>
00011 
00012 rgrl_trans_spline::
00013 rgrl_trans_spline( unsigned int dim )
00014   : x0_( dim, 0.0 ), delta_( dim, 0.0 )
00015 {
00016 }
00017 
00018 rgrl_trans_spline::
00019 rgrl_trans_spline( vcl_vector<rgrl_spline_sptr> const& splines,
00020                    vnl_vector< double > const& x0, vnl_vector< double > const& delta,
00021                    rgrl_transformation_sptr xform )
00022   : xform_( xform ), splines_( splines ),
00023     x0_( x0 ), delta_( delta )
00024 {
00025   assert( x0_.size() == delta_.size() );
00026   // covar_ = vnl_matrix< double >( splines[0]->num_of_control_points(), splines[0]->num_of_control_points(), 0.0 );
00027 }
00028 
00029 rgrl_trans_spline::
00030 rgrl_trans_spline( vcl_vector<rgrl_spline_sptr> const& splines,
00031                    vnl_vector< double > const& x0, vnl_vector< double > const& delta,
00032                    vnl_matrix< double > const& covar,
00033                    rgrl_transformation_sptr xform )
00034   : rgrl_transformation( covar ),
00035     xform_( xform ), splines_( splines ), x0_( x0 ), delta_( delta )
00036 {
00037   assert( x0_.size() == delta_.size() );
00038 }
00039 
00040 void
00041 rgrl_trans_spline::
00042 point_in_knots( vnl_vector< double > const& point, vnl_vector< double > & spline_pt ) const
00043 {
00044   spline_pt.set_size( point.size() );
00045   for ( unsigned i = 0; i < point.size(); ++i ) {
00046     spline_pt[ i ] = ( point[ i ] - x0_[ i ] ) / delta_[ i ];
00047   }
00048 }
00049 
00050 void
00051 rgrl_trans_spline::
00052 map_loc( vnl_vector<double> const& from,
00053          vnl_vector<double> & to) const
00054 {
00055   unsigned dim = from.size();
00056   assert(dim == splines_.size());
00057   vnl_vector< double > to_no_spline( from );
00058 
00059   if ( xform_ )
00060     xform_->map_location( from, to_no_spline );
00061 
00062   vnl_vector< double > from_in_spline;
00063   point_in_knots( from, from_in_spline );
00064   vnl_vector<double> delta( dim );
00065   for (unsigned i=0; i<dim; ++i)
00066     delta[i] = splines_[i]->f_x( from_in_spline );
00067 
00068   to = to_no_spline + delta;
00069 }
00070 
00071 void
00072 rgrl_trans_spline::
00073 map_dir( vnl_vector<double> const& from_loc,
00074          vnl_vector<double> const& from_dir,
00075          vnl_vector<double> & to_dir) const
00076 {
00077   unsigned dim = x0_.size();
00078   vnl_matrix< double > spline_jacobian( dim, dim );
00079 
00080   for ( unsigned i=0; i<dim; ++i )
00081     spline_jacobian.set_row( i, splines_[ i ]->jacobian( from_loc ) );
00082 
00083   // ???? -Gehua
00084   // Don't understand why plus
00085   // to_dir = jacobian * from_dir + from_dir;
00086 
00087   // Gehua's way:
00088   // to_dir = jacobian * from_dir
00089   // but jacobian = xform_jacobian + spline_jacobian
00090   to_dir = (spline_jacobian + xform_->jacobian( from_loc ) ) * from_dir;
00091 
00092   to_dir.normalize();
00093 }
00094 
00095 //: Return the jacobian of the transform
00096 void
00097 rgrl_trans_spline::
00098 jacobian_wrt_loc( vnl_matrix<double>& spline_jacobian, vnl_vector<double> const& from_loc ) const
00099 {
00100   // ???? Don't understand why map_dir is implemented but not this function
00101   // assert( false );
00102   // return vnl_matrix<double>(from_loc.size(), from_loc.size(), vnl_matrix_identity);
00103 
00104   unsigned dim = x0_.size();
00105   spline_jacobian.set_size( dim, dim );
00106 
00107   for ( unsigned i=0; i<dim; ++i )
00108     spline_jacobian.set_row( i, splines_[ i ]->jacobian( from_loc ) );
00109 
00110   // add with the Jacobian of xform
00111   vnl_matrix<double> xform_jac;
00112   xform_->jacobian_wrt_loc( xform_jac, from_loc );
00113   spline_jacobian += xform_jac;
00114 }
00115 
00116 // ??? -Gehua
00117 // since covariance is assumed to be identical
00118 // in each axis, the transfer error has to be
00119 // diagonal?
00120 // FIXME - needs to be fixed
00121 vnl_matrix<double>
00122 rgrl_trans_spline::
00123 transfer_error_covar( vnl_vector<double> const& p ) const
00124 {
00125   const unsigned dim = p.size();
00126   assert(is_covar_set());
00127   assert(dim==splines_.size());
00128 
00129   vnl_matrix<double> transfer_err_cov(dim,dim,0);
00130   vnl_vector<double> f_prime;
00131   vnl_vector<double> tmp;
00132 
00133   for (unsigned i=0; i<dim; ++i) {
00134     splines_[i]->basis_response( p, f_prime );
00135     tmp = f_prime.pre_multiply(covar_);
00136     for (unsigned j=0; j<tmp.size(); ++j)
00137       transfer_err_cov[i][i] += f_prime[j] * tmp[j];
00138   }
00139   return transfer_err_cov;
00140 }
00141 
00142 void
00143 rgrl_trans_spline::
00144 write( vcl_ostream& os ) const
00145 {
00146   // output tag
00147   os << "BSPLINE\n";
00148 
00149   // global xform
00150   if ( xform_ ) {
00151     xform_->write( os );
00152     os << vcl_endl;
00153   }
00154 
00155   // dim
00156   const unsigned int dim = x0_.size();
00157   os << dim << vcl_endl;
00158   // x0
00159   os << x0_ << vcl_endl;
00160   // deltas
00161   assert( delta_.size() == dim );
00162   os << delta_ << vcl_endl;
00163   // output the spline
00164   assert( splines_.size() == dim );
00165   for (unsigned int i=0; i<splines_.size(); ++i)
00166     os << *splines_[i] << vcl_endl;
00167 
00168   // parent
00169   rgrl_transformation::write( os );
00170 }
00171 
00172 bool
00173 rgrl_trans_spline::
00174 read( vcl_istream& is )
00175 {
00176   // skip empty lines
00177   rgrl_util_skip_empty_lines( is );
00178 
00179   vcl_string str;
00180   vcl_getline( is, str );
00181 
00182   // The token should appear at the beginning of line
00183   if ( str.find( "BSPLINE" ) != 0 ) {
00184     WarningMacro( "The tag is not BSPLINE. reading is aborted.\n" );
00185     return false;
00186   }
00187 
00188   // read global xform
00189   xform_ = rgrl_trans_reader::read( is );
00190 
00191   // dimension of spline transformation
00192   int dim;
00193   dim=-1;
00194   is >> dim;
00195   vnl_vector<double> tmp;
00196   // x0
00197   x0_.set_size( dim );
00198   is >> x0_;
00199   // deltas
00200   delta_.set_size( dim );
00201   is >> delta_;
00202 
00203   // input of splines
00204   splines_.resize( dim );
00205   for ( int i=0; i<dim; ++i ) {
00206     splines_[i] = new rgrl_spline;
00207     is >> *splines_[i];
00208   }
00209 
00210   // parent
00211   return is.good() && rgrl_transformation::read( is );
00212 }
00213 
00214 void
00215 rgrl_trans_spline::
00216 inv_map( vnl_vector<double> const& /*to*/,
00217          bool /*initialize_next*/,
00218          vnl_vector<double> const& /*to_delta*/,
00219          vnl_vector<double>& /*from*/,
00220          vnl_vector<double>& /*from_next_est*/) const
00221 {
00222   assert ( ! "rgrl_trans_spline::inv_map() is not defined" );
00223 }
00224 
00225 void
00226 rgrl_trans_spline::
00227 inv_map( vnl_vector<double> const& /*to*/,
00228          vnl_vector<double>& /*from*/ ) const
00229 {
00230   assert ( ! "rgrl_trans_spline::inv_map() is not defined" );
00231 }
00232 
00233 rgrl_transformation_sptr
00234 rgrl_trans_spline::
00235 inverse_transform( ) const
00236 {
00237   assert ( ! "rgrl_trans_spline::inverse_transform() is not defined" );
00238   return 0;
00239 }
00240 
00241 rgrl_transformation_sptr
00242 rgrl_trans_spline::
00243 scale_by( double /*scale*/ ) const
00244 {
00245   assert ( ! "rgrl_trans_spline::scale_by() is not defined" );
00246   return 0;
00247 }
00248 
00249 //: make a clone copy
00250 rgrl_transformation_sptr
00251 rgrl_trans_spline::
00252 clone() const
00253 {
00254   return new rgrl_trans_spline( *this );
00255 }