14 unsigned int nr_of_residuals)
16 if (nr_of_unknowns > nr_of_residuals)
17 std::cerr <<
"vnl_sparse_lst_sqr_function: WARNING: " 18 <<
"unknowns(" << nr_of_unknowns <<
") > " 19 <<
"residuals("<< nr_of_residuals <<
")\n";
31 unsigned int num_params_per_a,
33 unsigned int num_params_per_b,
34 unsigned int num_params_c,
35 unsigned int num_residuals_per_e,
40 indices_a_(num_a+1,0),
41 indices_b_(num_b+1,0),
42 num_params_c_(num_params_c),
43 indices_e_(num_a*num_b+1,0),
44 use_gradient_(g == use_gradient),
45 use_weights_(w == use_weights)
47 unsigned int k = num_params_per_a;
48 for (
unsigned int i=1; i<
indices_a_.size(); ++i, k+=num_params_per_a)
52 for (
unsigned int i=1; i<
indices_b_.size(); ++i, k+=num_params_per_b)
55 k = num_residuals_per_e;
56 for (
unsigned int i=1; i<
indices_e_.size(); ++i, k+=num_residuals_per_e)
70 unsigned int num_params_per_a,
72 unsigned int num_params_per_b,
73 unsigned int num_params_c,
74 const std::vector<std::vector<bool> >& xmask,
75 unsigned int num_residuals_per_e,
79 residual_indices_(xmask),
80 indices_a_(num_a+1,0),
81 indices_b_(num_b+1,0),
82 num_params_c_(num_params_c),
83 indices_e_(residual_indices_.num_non_zero()+1,0),
84 use_gradient_(g == use_gradient),
85 use_weights_(w == use_weights)
87 unsigned int k = num_params_per_a;
88 for (
unsigned int i=1; i<
indices_a_.size(); ++i, k+=num_params_per_a)
92 for (
unsigned int i=1; i<
indices_b_.size(); ++i, k+=num_params_per_b)
95 k = num_residuals_per_e;
96 for (
unsigned int i=1; i<
indices_e_.size(); ++i, k+=num_residuals_per_e)
99 dim_warning(num_a*num_params_per_a + num_b*num_params_per_b + num_params_c, k);
114 const std::vector<unsigned int>& a_sizes,
115 const std::vector<unsigned int>& b_sizes,
116 unsigned int num_params_c,
117 const std::vector<unsigned int>& e_sizes,
118 const std::vector<std::vector<bool> >& xmask,
122 residual_indices_(xmask),
123 indices_a_(a_sizes.size()+1,0),
124 indices_b_(b_sizes.size()+1,0),
125 num_params_c_(num_params_c),
126 indices_e_(e_sizes.size()+1,0),
127 use_gradient_(g == use_gradient),
128 use_weights_(w == use_weights)
134 for (
unsigned int i=0; i<a_sizes.size(); ++i)
137 for (
unsigned int i=0; i<b_sizes.size(); ++i)
140 for (
unsigned int i=0; i<e_sizes.size(); ++i)
167 for (
auto & r_itr : row)
169 unsigned int j = r_itr.second;
170 unsigned int k = r_itr.first;
175 fij(i,j,ai,bj,c,eij);
204 for (
auto & r_itr : row)
206 unsigned int j = r_itr.second;
207 unsigned int k = r_itr.first;
244 for (
auto & r_itr : row)
246 unsigned int j = r_itr.second;
247 unsigned int k = r_itr.first;
280 for (
auto & r_itr : row)
282 unsigned int j = r_itr.second;
283 unsigned int k = r_itr.first;
307 for (
auto & r_itr : row)
309 unsigned int j = r_itr.second;
310 unsigned int k = r_itr.first;
332 for (
auto & r_itr : row)
334 unsigned int j = r_itr.second;
335 unsigned int k = r_itr.first;
352 std::cerr <<
"Warning: fij() called but not implemented in derived class\n";
363 std::cerr <<
"Warning: jac_Aij() called but not implemented in derived class\n";
374 std::cerr <<
"Warning: jac_Bij() called but not implemented in derived class\n";
386 std::cerr <<
"Warning: jac_Cij() called but not implemented in derived class\n";
398 const unsigned int dim = ai.
size();
399 const unsigned int n = Aij.
rows();
409 for (
unsigned int ii = 0; ii < dim; ++ii)
412 double tplus = tai[ii] = ai[ii] + stepsize;
413 this->
fij(i,j,tai,bj,c,fplus);
416 double tminus = tai[ii] = ai[ii] - stepsize;
417 this->
fij(i,j,tai,bj,c,fminus);
419 double h = 1.0 / (tplus - tminus);
420 for (
unsigned int jj = 0; jj < n; ++jj)
421 Aij(jj,ii) = (fplus[jj] - fminus[jj]) * h;
438 const unsigned int dim = bj.
size();
439 const unsigned int n = Bij.
rows();
449 for (
unsigned int ii = 0; ii < dim; ++ii)
452 double tplus = tbj[ii] = bj[ii] + stepsize;
453 this->
fij(i,j,ai,tbj,c,fplus);
456 double tminus = tbj[ii] = bj[ii] - stepsize;
457 this->
fij(i,j,ai,tbj,c,fminus);
459 double h = 1.0 / (tplus - tminus);
460 for (
unsigned int jj = 0; jj < n; ++jj)
461 Bij(jj,ii) = (fplus[jj] - fminus[jj]) * h;
478 const unsigned int dim = c.
size();
484 const unsigned int n = Cij.
rows();
493 for (
unsigned int ii = 0; ii < dim; ++ii)
496 double tplus = tc[ii] = c[ii] + stepsize;
497 this->
fij(i,j,ai,bj,tc,fplus);
500 double tminus = tc[ii] = c[ii] - stepsize;
501 this->
fij(i,j,ai,bj,tc,fminus);
503 double h = 1.0 / (tplus - tminus);
504 for (
unsigned int jj = 0; jj < n; ++jj)
505 Cij(jj,ii) = (fplus[jj] - fminus[jj]) * h;
532 double const& weight,
543 double const& weight,
unsigned int number_of_params_a(int i) const
Return the number of parameters of a_j.
unsigned int index_a(int i) const
return the index of aj in a.
virtual void jac_Aij(unsigned int i, unsigned int j, vnl_vector< double > const &ai, vnl_vector< double > const &bj, vnl_vector< double > const &c, vnl_matrix< double > &Aij)
Calculate the Jacobian A_ij, given the parameter vectors a_i, b_j, and c.
unsigned int number_of_params_c() const
Return the number of parameters of c.
Abstract base for sparse least squares functions.
std::vector< unsigned int > indices_e_
unsigned int number_of_residuals(int k) const
Return the number of residuals in the kth residual vector.
unsigned int index_b(int j) const
return the index of bj in b.
int num_rows() const
number of rows in the sparse matrix.
vnl_vector using user-supplied storage
vnl_vector using user-supplied storage.
vnl_crs_index residual_indices_
void dim_warning(unsigned int n_unknowns, unsigned int n_residuals)
unsigned int number_of_a() const
Return the number of subsets in a.
virtual void compute_weights(vnl_vector< double > const &a, vnl_vector< double > const &b, vnl_vector< double > const &c, vnl_vector< double > const &f, vnl_vector< double > &weights)
If using weighted least squares, compute the weights for each i and j.
size_t size() const
Return the length, number of elements, dimension of this vector.
T const * data_block() const
Access the contiguous block storing the elements in the vector. O(1).
unsigned int index_e(int k) const
return the index of ek in e.
void fd_jac_Cij(int i, int j, vnl_vector< double > const &ai, vnl_vector< double > const &bj, vnl_vector< double > const &c, vnl_matrix< double > &Cij, double stepsize)
Use this to compute a finite-difference Jacobian C_ij.
virtual void trace(int iteration, vnl_vector< double > const &a, vnl_vector< double > const &b, vnl_vector< double > const &c, vnl_vector< double > const &e)
Called after each LM iteration to print debugging etc.
virtual void jac_Bij(unsigned int i, unsigned int j, vnl_vector< double > const &ai, vnl_vector< double > const &bj, vnl_vector< double > const &c, vnl_matrix< double > &Bij)
Calculate the Jacobian B_ij, given the parameter vectors a_i, b_j, and c.
sparse_vector sparse_row(int i) const
returns row i as a vector of index-column pairs.
void fd_jac_Aij(int i, int j, vnl_vector< double > const &ai, vnl_vector< double > const &bj, vnl_vector< double > const &c, vnl_matrix< double > &Aij, double stepsize)
Use this to compute a finite-difference Jacobian A_ij.
virtual void apply_weight_ij(int i, int j, double const &weight, vnl_vector< double > &fij)
If using weighted least squares, apply the weight to fij.
virtual void jac_blocks(vnl_vector< double > const &a, vnl_vector< double > const &b, vnl_vector< double > const &c, std::vector< vnl_matrix< double > > &A, std::vector< vnl_matrix< double > > &B, std::vector< vnl_matrix< double > > &C)
Compute the sparse Jacobian in block form.
vnl_sparse_lst_sqr_function(unsigned int num_a, unsigned int num_params_per_a, unsigned int num_b, unsigned int num_params_per_b, unsigned int num_params_c, unsigned int num_residuals_per_e, UseGradient g=use_gradient, UseWeights w=no_weights)
Construct vnl_sparse_lst_sqr_function.
void fd_jac_Bij(int i, int j, vnl_vector< double > const &ai, vnl_vector< double > const &bj, vnl_vector< double > const &c, vnl_matrix< double > &Bij, double stepsize)
Use this to compute a finite-difference Jacobian B_ij.
virtual void fij(int i, int j, vnl_vector< double > const &ai, vnl_vector< double > const &bj, vnl_vector< double > const &c, vnl_vector< double > &fij)
Compute the residuals from the ith component of a, the jth component of b.
virtual void fd_jac_blocks(vnl_vector< double > const &a, vnl_vector< double > const &b, vnl_vector< double > const &c, std::vector< vnl_matrix< double > > &A, std::vector< vnl_matrix< double > > &B, std::vector< vnl_matrix< double > > &C, double stepsize)
Compute the sparse Jacobian in block form using a finite difference approximation.
unsigned int num_params_c_
std::vector< unsigned int > indices_b_
virtual void apply_weights(vnl_vector< double > const &weights, vnl_vector< double > &f)
If using weighted least squares, apply the weights to residuals f.
virtual void compute_weight_ij(int i, int j, vnl_vector< double > const &ai, vnl_vector< double > const &bj, vnl_vector< double > const &c, vnl_vector< double > const &fij, double &weight)
If using weighted least squares, compute the weight.
int num_cols() const
number of columns in the sparse matrix.
unsigned int rows() const
Return the number of rows.
virtual void f(vnl_vector< double > const &a, vnl_vector< double > const &b, vnl_vector< double > const &c, vnl_vector< double > &f)
Compute all residuals.
std::vector< idx_pair > sparse_vector
unsigned int number_of_params_b(int j) const
Return the number of parameters of b_i.
std::vector< unsigned int > indices_a_
virtual void jac_Cij(unsigned int i, unsigned int j, vnl_vector< double > const &ai, vnl_vector< double > const &bj, vnl_vector< double > const &c, vnl_matrix< double > &Cij)
Calculate the Jacobian C_ij, given the parameter vectors a_i, b_j, and c.
int num_non_zero() const
number of non-zero elements.
unsigned int columns() const
Return the number of columns.