Go to the documentation of this file.00001 #include "m23d_correction_matrix_error.h"
00002
00003
00004
00005
00006
00007 #include <mbl/mbl_matxvec.h>
00008 #include <vcl_cassert.h>
00009
00010 m23d_correction_matrix_error::m23d_correction_matrix_error(const vnl_matrix<double>& A,
00011 const vnl_vector<double>& rhs,
00012 unsigned n_modes,
00013 unsigned k)
00014 : vnl_least_squares_function(9*(n_modes+1),A.rows(),use_gradient),
00015 A_(A),rhs_(rhs),n_modes_(n_modes),k_(k)
00016 {
00017 #ifndef NDEBUG
00018 unsigned t = 3*(n_modes+1);
00019 assert(A.cols() == (t*(t+1))/2);
00020 #endif
00021 q_.set_size(A.cols());
00022 }
00023
00024
00025
00026
00027
00028 void m23d_correction_matrix_error::compute_q(const vnl_vector<double>& g1,
00029 const vnl_vector<double>& g2,
00030 vnl_vector<double>& q)
00031 {
00032 unsigned t = 3*(n_modes_+1);
00033 unsigned k=0;
00034 const double* r1=g1.data_block();
00035 for (unsigned i=0;i<t;++i,r1+=3)
00036 {
00037 const double* r2=g2.data_block();
00038 for (unsigned j=0;j<=i;++j,++k,r2+=3)
00039 q[k]= r1[0]*r2[0] + r1[1]*r2[1] +r1[2]*r2[2];
00040 }
00041 }
00042
00043
00044
00045
00046
00047
00048
00049 void m23d_correction_matrix_error::f(vnl_vector<double> const& g,
00050 vnl_vector<double>& fx)
00051 {
00052 assert(g.size() == 9*(n_modes_+1));
00053 compute_q(g,g,q_);
00054 mbl_matxvec_prod_mv(A_,q_,fx);
00055 fx-=rhs_;
00056 }
00057
00058
00059 void m23d_correction_matrix_error::gradf(vnl_vector<double> const& g,
00060 vnl_matrix<double>& jacobian)
00061 {
00062 unsigned ng = 9*(n_modes_+1);
00063 assert(g.size() == ng);
00064 jacobian.set_size(get_number_of_residuals(),ng);
00065 r_.set_size(get_number_of_residuals());
00066
00067 vnl_vector<double> g1(ng,0.0),q1(A_.cols());
00068 for (unsigned j=0;j<ng;++j)
00069 {
00070 g1[j]=1.0;
00071 compute_q(g,g1,q_);
00072 compute_q(g1,g,q1);
00073 q_+=q1;
00074 mbl_matxvec_prod_mv(A_,q_,r_);
00075 jacobian.set_column(j,r_);
00076 g1[j]=0.0;
00077 }
00078 }