blob: f4615f94768d2d52b9e539d66c5c946f8da6d7d6 [file] [log] [blame]
Keir Mierle8ebb0732012-04-30 23:09:08 -07001// Ceres Solver - A fast non-linear least squares minimizer
2// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
3// http://code.google.com/p/ceres-solver/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are met:
7//
8// * Redistributions of source code must retain the above copyright notice,
9// this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above copyright notice,
11// this list of conditions and the following disclaimer in the documentation
12// and/or other materials provided with the distribution.
13// * Neither the name of Google Inc. nor the names of its contributors may be
14// used to endorse or promote products derived from this software without
15// specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27// POSSIBILITY OF SUCH DAMAGE.
28//
29// Author: sameeragarwal@google.com (Sameer Agarwal)
30// keir@google.com (Keir Mierle)
31
32#include "ceres/problem_impl.h"
33
34#include <algorithm>
35#include <cstddef>
Sergey Sharybin16636ef2013-03-21 15:12:01 +060036#include <iterator>
Keir Mierle8ebb0732012-04-30 23:09:08 -070037#include <set>
38#include <string>
39#include <utility>
40#include <vector>
Sameer Agarwal509f68c2013-02-20 01:39:03 -080041#include "ceres/casts.h"
42#include "ceres/compressed_row_sparse_matrix.h"
Sameer Agarwal0beab862012-08-13 15:12:01 -070043#include "ceres/cost_function.h"
Sameer Agarwal509f68c2013-02-20 01:39:03 -080044#include "ceres/crs_matrix.h"
45#include "ceres/evaluator.h"
Sameer Agarwal0beab862012-08-13 15:12:01 -070046#include "ceres/loss_function.h"
47#include "ceres/map_util.h"
Keir Mierle8ebb0732012-04-30 23:09:08 -070048#include "ceres/parameter_block.h"
49#include "ceres/program.h"
50#include "ceres/residual_block.h"
51#include "ceres/stl_util.h"
Keir Mierle8ebb0732012-04-30 23:09:08 -070052#include "ceres/stringprintf.h"
Sameer Agarwal0beab862012-08-13 15:12:01 -070053#include "glog/logging.h"
Keir Mierle8ebb0732012-04-30 23:09:08 -070054
55namespace ceres {
56namespace internal {
57
58typedef map<double*, internal::ParameterBlock*> ParameterMap;
59
Sergey Sharybinf46de9e2013-03-21 15:31:35 +060060namespace {
Sameer Agarwal020d8e12013-03-06 16:19:26 -080061internal::ParameterBlock* FindParameterBlockOrDie(
62 const ParameterMap& parameter_map,
63 double* parameter_block) {
64 ParameterMap::const_iterator it = parameter_map.find(parameter_block);
65 CHECK(it != parameter_map.end())
66 << "Parameter block not found: " << parameter_block;
67 return it->second;
68}
69
Keir Mierle8ebb0732012-04-30 23:09:08 -070070// Returns true if two regions of memory, a and b, with sizes size_a and size_b
71// respectively, overlap.
Sergey Sharybinf46de9e2013-03-21 15:31:35 +060072bool RegionsAlias(const double* a, int size_a,
73 const double* b, int size_b) {
Keir Mierle8ebb0732012-04-30 23:09:08 -070074 return (a < b) ? b < (a + size_a)
75 : a < (b + size_b);
76}
77
Sergey Sharybinf46de9e2013-03-21 15:31:35 +060078void CheckForNoAliasing(double* existing_block,
79 int existing_block_size,
80 double* new_block,
81 int new_block_size) {
Keir Mierle8ebb0732012-04-30 23:09:08 -070082 CHECK(!RegionsAlias(existing_block, existing_block_size,
83 new_block, new_block_size))
84 << "Aliasing detected between existing parameter block at memory "
85 << "location " << existing_block
86 << " and has size " << existing_block_size << " with new parameter "
Sameer Agarwalc290df82013-04-07 09:17:47 -070087 << "block that has memory address " << new_block << " and would have "
Keir Mierle8ebb0732012-04-30 23:09:08 -070088 << "size " << new_block_size << ".";
89}
90
Sergey Sharybinf46de9e2013-03-21 15:31:35 +060091} // namespace
92
Sameer Agarwal8e1f83c2013-02-15 08:35:40 -080093ParameterBlock* ProblemImpl::InternalAddParameterBlock(double* values,
94 int size) {
95 CHECK(values != NULL) << "Null pointer passed to AddParameterBlock "
96 << "for a parameter with size " << size;
Keir Mierle8ebb0732012-04-30 23:09:08 -070097
98 // Ignore the request if there is a block for the given pointer already.
Sameer Agarwal8e1f83c2013-02-15 08:35:40 -080099 ParameterMap::iterator it = parameter_block_map_.find(values);
100 if (it != parameter_block_map_.end()) {
101 if (!options_.disable_all_safety_checks) {
102 int existing_size = it->second->Size();
103 CHECK(size == existing_size)
104 << "Tried adding a parameter block with the same double pointer, "
105 << values << ", twice, but with different block sizes. Original "
106 << "size was " << existing_size << " but new size is "
107 << size;
108 }
Keir Mierle8ebb0732012-04-30 23:09:08 -0700109 return it->second;
110 }
Keir Mierle8ebb0732012-04-30 23:09:08 -0700111
Sameer Agarwal8e1f83c2013-02-15 08:35:40 -0800112 if (!options_.disable_all_safety_checks) {
113 // Before adding the parameter block, also check that it doesn't alias any
114 // other parameter blocks.
115 if (!parameter_block_map_.empty()) {
116 ParameterMap::iterator lb = parameter_block_map_.lower_bound(values);
Keir Mierle8ebb0732012-04-30 23:09:08 -0700117
Sameer Agarwal8e1f83c2013-02-15 08:35:40 -0800118 // If lb is not the first block, check the previous block for aliasing.
119 if (lb != parameter_block_map_.begin()) {
120 ParameterMap::iterator previous = lb;
121 --previous;
122 CheckForNoAliasing(previous->first,
123 previous->second->Size(),
124 values,
125 size);
126 }
127
128 // If lb is not off the end, check lb for aliasing.
129 if (lb != parameter_block_map_.end()) {
130 CheckForNoAliasing(lb->first,
131 lb->second->Size(),
132 values,
133 size);
134 }
Keir Mierle8ebb0732012-04-30 23:09:08 -0700135 }
136 }
Sameer Agarwal8e1f83c2013-02-15 08:35:40 -0800137
Keir Mierle04938ef2013-02-17 12:37:55 -0800138 // Pass the index of the new parameter block as well to keep the index in
139 // sync with the position of the parameter in the program's parameter vector.
140 ParameterBlock* new_parameter_block =
141 new ParameterBlock(values, size, program_->parameter_blocks_.size());
142
143 // For dynamic problems, add the list of dependent residual blocks, which is
144 // empty to start.
145 if (options_.enable_fast_parameter_block_removal) {
146 new_parameter_block->EnableResidualBlockDependencies();
147 }
Sameer Agarwal8e1f83c2013-02-15 08:35:40 -0800148 parameter_block_map_[values] = new_parameter_block;
149 program_->parameter_blocks_.push_back(new_parameter_block);
Keir Mierle8ebb0732012-04-30 23:09:08 -0700150 return new_parameter_block;
151}
152
Keir Mierle04938ef2013-02-17 12:37:55 -0800153// Deletes the residual block in question, assuming there are no other
154// references to it inside the problem (e.g. by another parameter). Referenced
155// cost and loss functions are tucked away for future deletion, since it is not
156// possible to know whether other parts of the problem depend on them without
157// doing a full scan.
158void ProblemImpl::DeleteBlock(ResidualBlock* residual_block) {
159 // The const casts here are legit, since ResidualBlock holds these
160 // pointers as const pointers but we have ownership of them and
161 // have the right to destroy them when the destructor is called.
162 if (options_.cost_function_ownership == TAKE_OWNERSHIP &&
163 residual_block->cost_function() != NULL) {
164 cost_functions_to_delete_.push_back(
165 const_cast<CostFunction*>(residual_block->cost_function()));
166 }
167 if (options_.loss_function_ownership == TAKE_OWNERSHIP &&
168 residual_block->loss_function() != NULL) {
169 loss_functions_to_delete_.push_back(
170 const_cast<LossFunction*>(residual_block->loss_function()));
171 }
172 delete residual_block;
173}
174
175// Deletes the parameter block in question, assuming there are no other
176// references to it inside the problem (e.g. by any residual blocks).
177// Referenced parameterizations are tucked away for future deletion, since it
178// is not possible to know whether other parts of the problem depend on them
179// without doing a full scan.
180void ProblemImpl::DeleteBlock(ParameterBlock* parameter_block) {
181 if (options_.local_parameterization_ownership == TAKE_OWNERSHIP &&
182 parameter_block->local_parameterization() != NULL) {
183 local_parameterizations_to_delete_.push_back(
184 parameter_block->mutable_local_parameterization());
185 }
186 parameter_block_map_.erase(parameter_block->mutable_user_state());
187 delete parameter_block;
188}
189
Keir Mierle8ebb0732012-04-30 23:09:08 -0700190ProblemImpl::ProblemImpl() : program_(new internal::Program) {}
191ProblemImpl::ProblemImpl(const Problem::Options& options)
192 : options_(options),
193 program_(new internal::Program) {}
194
195ProblemImpl::~ProblemImpl() {
196 // Collect the unique cost/loss functions and delete the residuals.
Sameer Agarwalbeb45052013-02-22 13:37:01 -0800197 const int num_residual_blocks = program_->residual_blocks_.size();
Keir Mierle04938ef2013-02-17 12:37:55 -0800198 cost_functions_to_delete_.reserve(num_residual_blocks);
199 loss_functions_to_delete_.reserve(num_residual_blocks);
Keir Mierle8ebb0732012-04-30 23:09:08 -0700200 for (int i = 0; i < program_->residual_blocks_.size(); ++i) {
Keir Mierle04938ef2013-02-17 12:37:55 -0800201 DeleteBlock(program_->residual_blocks_[i]);
Keir Mierle8ebb0732012-04-30 23:09:08 -0700202 }
203
204 // Collect the unique parameterizations and delete the parameters.
Keir Mierle8ebb0732012-04-30 23:09:08 -0700205 for (int i = 0; i < program_->parameter_blocks_.size(); ++i) {
Keir Mierle04938ef2013-02-17 12:37:55 -0800206 DeleteBlock(program_->parameter_blocks_[i]);
Keir Mierle8ebb0732012-04-30 23:09:08 -0700207 }
208
209 // Delete the owned cost/loss functions and parameterizations.
Keir Mierle04938ef2013-02-17 12:37:55 -0800210 STLDeleteUniqueContainerPointers(local_parameterizations_to_delete_.begin(),
211 local_parameterizations_to_delete_.end());
212 STLDeleteUniqueContainerPointers(cost_functions_to_delete_.begin(),
213 cost_functions_to_delete_.end());
214 STLDeleteUniqueContainerPointers(loss_functions_to_delete_.begin(),
215 loss_functions_to_delete_.end());
Keir Mierle8ebb0732012-04-30 23:09:08 -0700216}
217
Keir Mierle04938ef2013-02-17 12:37:55 -0800218ResidualBlock* ProblemImpl::AddResidualBlock(
Keir Mierle8ebb0732012-04-30 23:09:08 -0700219 CostFunction* cost_function,
220 LossFunction* loss_function,
221 const vector<double*>& parameter_blocks) {
222 CHECK_NOTNULL(cost_function);
223 CHECK_EQ(parameter_blocks.size(),
224 cost_function->parameter_block_sizes().size());
225
226 // Check the sizes match.
227 const vector<int16>& parameter_block_sizes =
228 cost_function->parameter_block_sizes();
Keir Mierle8ebb0732012-04-30 23:09:08 -0700229
Sameer Agarwal8e1f83c2013-02-15 08:35:40 -0800230 if (!options_.disable_all_safety_checks) {
231 CHECK_EQ(parameter_block_sizes.size(), parameter_blocks.size())
232 << "Number of blocks input is different than the number of blocks "
233 << "that the cost function expects.";
234
235 // Check for duplicate parameter blocks.
236 vector<double*> sorted_parameter_blocks(parameter_blocks);
237 sort(sorted_parameter_blocks.begin(), sorted_parameter_blocks.end());
238 vector<double*>::const_iterator duplicate_items =
239 unique(sorted_parameter_blocks.begin(),
240 sorted_parameter_blocks.end());
241 if (duplicate_items != sorted_parameter_blocks.end()) {
242 string blocks;
243 for (int i = 0; i < parameter_blocks.size(); ++i) {
Sameer Agarwal509f68c2013-02-20 01:39:03 -0800244 blocks += StringPrintf(" %p ", parameter_blocks[i]);
Sameer Agarwal8e1f83c2013-02-15 08:35:40 -0800245 }
246
247 LOG(FATAL) << "Duplicate parameter blocks in a residual parameter "
248 << "are not allowed. Parameter block pointers: ["
249 << blocks << "]";
Keir Mierle8ebb0732012-04-30 23:09:08 -0700250 }
Keir Mierle8ebb0732012-04-30 23:09:08 -0700251 }
252
253 // Add parameter blocks and convert the double*'s to parameter blocks.
254 vector<ParameterBlock*> parameter_block_ptrs(parameter_blocks.size());
255 for (int i = 0; i < parameter_blocks.size(); ++i) {
256 parameter_block_ptrs[i] =
257 InternalAddParameterBlock(parameter_blocks[i],
Sameer Agarwal8e1f83c2013-02-15 08:35:40 -0800258 parameter_block_sizes[i]);
Keir Mierle8ebb0732012-04-30 23:09:08 -0700259 }
260
Sameer Agarwal8e1f83c2013-02-15 08:35:40 -0800261 if (!options_.disable_all_safety_checks) {
262 // Check that the block sizes match the block sizes expected by the
263 // cost_function.
264 for (int i = 0; i < parameter_block_ptrs.size(); ++i) {
265 CHECK_EQ(cost_function->parameter_block_sizes()[i],
266 parameter_block_ptrs[i]->Size())
267 << "The cost function expects parameter block " << i
268 << " of size " << cost_function->parameter_block_sizes()[i]
269 << " but was given a block of size "
270 << parameter_block_ptrs[i]->Size();
271 }
Keir Mierle8ebb0732012-04-30 23:09:08 -0700272 }
273
274 ResidualBlock* new_residual_block =
275 new ResidualBlock(cost_function,
276 loss_function,
Keir Mierle04938ef2013-02-17 12:37:55 -0800277 parameter_block_ptrs,
278 program_->residual_blocks_.size());
279
280 // Add dependencies on the residual to the parameter blocks.
281 if (options_.enable_fast_parameter_block_removal) {
282 for (int i = 0; i < parameter_blocks.size(); ++i) {
283 parameter_block_ptrs[i]->AddResidualBlock(new_residual_block);
284 }
285 }
286
Keir Mierle8ebb0732012-04-30 23:09:08 -0700287 program_->residual_blocks_.push_back(new_residual_block);
288 return new_residual_block;
289}
290
291// Unfortunately, macros don't help much to reduce this code, and var args don't
292// work because of the ambiguous case that there is no loss function.
Keir Mierle04938ef2013-02-17 12:37:55 -0800293ResidualBlock* ProblemImpl::AddResidualBlock(
Keir Mierle8ebb0732012-04-30 23:09:08 -0700294 CostFunction* cost_function,
295 LossFunction* loss_function,
296 double* x0) {
297 vector<double*> residual_parameters;
298 residual_parameters.push_back(x0);
299 return AddResidualBlock(cost_function, loss_function, residual_parameters);
300}
301
Keir Mierle04938ef2013-02-17 12:37:55 -0800302ResidualBlock* ProblemImpl::AddResidualBlock(
Keir Mierle8ebb0732012-04-30 23:09:08 -0700303 CostFunction* cost_function,
304 LossFunction* loss_function,
305 double* x0, double* x1) {
306 vector<double*> residual_parameters;
307 residual_parameters.push_back(x0);
308 residual_parameters.push_back(x1);
309 return AddResidualBlock(cost_function, loss_function, residual_parameters);
310}
311
Keir Mierle04938ef2013-02-17 12:37:55 -0800312ResidualBlock* ProblemImpl::AddResidualBlock(
Keir Mierle8ebb0732012-04-30 23:09:08 -0700313 CostFunction* cost_function,
314 LossFunction* loss_function,
315 double* x0, double* x1, double* x2) {
316 vector<double*> residual_parameters;
317 residual_parameters.push_back(x0);
318 residual_parameters.push_back(x1);
319 residual_parameters.push_back(x2);
320 return AddResidualBlock(cost_function, loss_function, residual_parameters);
321}
322
Keir Mierle04938ef2013-02-17 12:37:55 -0800323ResidualBlock* ProblemImpl::AddResidualBlock(
Keir Mierle8ebb0732012-04-30 23:09:08 -0700324 CostFunction* cost_function,
325 LossFunction* loss_function,
326 double* x0, double* x1, double* x2, double* x3) {
327 vector<double*> residual_parameters;
328 residual_parameters.push_back(x0);
329 residual_parameters.push_back(x1);
330 residual_parameters.push_back(x2);
331 residual_parameters.push_back(x3);
332 return AddResidualBlock(cost_function, loss_function, residual_parameters);
333}
334
Keir Mierle04938ef2013-02-17 12:37:55 -0800335ResidualBlock* ProblemImpl::AddResidualBlock(
Keir Mierle8ebb0732012-04-30 23:09:08 -0700336 CostFunction* cost_function,
337 LossFunction* loss_function,
338 double* x0, double* x1, double* x2, double* x3, double* x4) {
339 vector<double*> residual_parameters;
340 residual_parameters.push_back(x0);
341 residual_parameters.push_back(x1);
342 residual_parameters.push_back(x2);
343 residual_parameters.push_back(x3);
344 residual_parameters.push_back(x4);
345 return AddResidualBlock(cost_function, loss_function, residual_parameters);
346}
347
Keir Mierle04938ef2013-02-17 12:37:55 -0800348ResidualBlock* ProblemImpl::AddResidualBlock(
Keir Mierle8ebb0732012-04-30 23:09:08 -0700349 CostFunction* cost_function,
350 LossFunction* loss_function,
351 double* x0, double* x1, double* x2, double* x3, double* x4, double* x5) {
352 vector<double*> residual_parameters;
353 residual_parameters.push_back(x0);
354 residual_parameters.push_back(x1);
355 residual_parameters.push_back(x2);
356 residual_parameters.push_back(x3);
357 residual_parameters.push_back(x4);
358 residual_parameters.push_back(x5);
359 return AddResidualBlock(cost_function, loss_function, residual_parameters);
360}
361
Keir Mierle04938ef2013-02-17 12:37:55 -0800362ResidualBlock* ProblemImpl::AddResidualBlock(
Fisher12626e82012-10-21 14:12:04 -0400363 CostFunction* cost_function,
364 LossFunction* loss_function,
365 double* x0, double* x1, double* x2, double* x3, double* x4, double* x5,
366 double* x6) {
367 vector<double*> residual_parameters;
368 residual_parameters.push_back(x0);
369 residual_parameters.push_back(x1);
370 residual_parameters.push_back(x2);
371 residual_parameters.push_back(x3);
372 residual_parameters.push_back(x4);
373 residual_parameters.push_back(x5);
374 residual_parameters.push_back(x6);
375 return AddResidualBlock(cost_function, loss_function, residual_parameters);
376}
377
Keir Mierle04938ef2013-02-17 12:37:55 -0800378ResidualBlock* ProblemImpl::AddResidualBlock(
Fisher12626e82012-10-21 14:12:04 -0400379 CostFunction* cost_function,
380 LossFunction* loss_function,
381 double* x0, double* x1, double* x2, double* x3, double* x4, double* x5,
382 double* x6, double* x7) {
383 vector<double*> residual_parameters;
384 residual_parameters.push_back(x0);
385 residual_parameters.push_back(x1);
386 residual_parameters.push_back(x2);
387 residual_parameters.push_back(x3);
388 residual_parameters.push_back(x4);
389 residual_parameters.push_back(x5);
390 residual_parameters.push_back(x6);
391 residual_parameters.push_back(x7);
392 return AddResidualBlock(cost_function, loss_function, residual_parameters);
393}
394
Keir Mierle04938ef2013-02-17 12:37:55 -0800395ResidualBlock* ProblemImpl::AddResidualBlock(
Fisher12626e82012-10-21 14:12:04 -0400396 CostFunction* cost_function,
397 LossFunction* loss_function,
398 double* x0, double* x1, double* x2, double* x3, double* x4, double* x5,
399 double* x6, double* x7, double* x8) {
400 vector<double*> residual_parameters;
401 residual_parameters.push_back(x0);
402 residual_parameters.push_back(x1);
403 residual_parameters.push_back(x2);
404 residual_parameters.push_back(x3);
405 residual_parameters.push_back(x4);
406 residual_parameters.push_back(x5);
407 residual_parameters.push_back(x6);
408 residual_parameters.push_back(x7);
409 residual_parameters.push_back(x8);
410 return AddResidualBlock(cost_function, loss_function, residual_parameters);
411}
412
Keir Mierle04938ef2013-02-17 12:37:55 -0800413ResidualBlock* ProblemImpl::AddResidualBlock(
Fisher12626e82012-10-21 14:12:04 -0400414 CostFunction* cost_function,
415 LossFunction* loss_function,
416 double* x0, double* x1, double* x2, double* x3, double* x4, double* x5,
417 double* x6, double* x7, double* x8, double* x9) {
418 vector<double*> residual_parameters;
419 residual_parameters.push_back(x0);
420 residual_parameters.push_back(x1);
421 residual_parameters.push_back(x2);
422 residual_parameters.push_back(x3);
423 residual_parameters.push_back(x4);
424 residual_parameters.push_back(x5);
425 residual_parameters.push_back(x6);
426 residual_parameters.push_back(x7);
427 residual_parameters.push_back(x8);
428 residual_parameters.push_back(x9);
429 return AddResidualBlock(cost_function, loss_function, residual_parameters);
430}
Keir Mierle8ebb0732012-04-30 23:09:08 -0700431
432void ProblemImpl::AddParameterBlock(double* values, int size) {
Sameer Agarwal8e1f83c2013-02-15 08:35:40 -0800433 InternalAddParameterBlock(values, size);
Keir Mierle8ebb0732012-04-30 23:09:08 -0700434}
435
436void ProblemImpl::AddParameterBlock(
437 double* values,
438 int size,
439 LocalParameterization* local_parameterization) {
440 ParameterBlock* parameter_block =
Sameer Agarwal8e1f83c2013-02-15 08:35:40 -0800441 InternalAddParameterBlock(values, size);
Keir Mierle8ebb0732012-04-30 23:09:08 -0700442 if (local_parameterization != NULL) {
443 parameter_block->SetParameterization(local_parameterization);
444 }
445}
446
Keir Mierle04938ef2013-02-17 12:37:55 -0800447// Delete a block from a vector of blocks, maintaining the indexing invariant.
448// This is done in constant time by moving an element from the end of the
449// vector over the element to remove, then popping the last element. It
450// destroys the ordering in the interest of speed.
451template<typename Block>
452void ProblemImpl::DeleteBlockInVector(vector<Block*>* mutable_blocks,
453 Block* block_to_remove) {
454 CHECK_EQ((*mutable_blocks)[block_to_remove->index()], block_to_remove)
455 << "You found a Ceres bug! Block: " << block_to_remove->ToString();
456
457 // Prepare the to-be-moved block for the new, lower-in-index position by
458 // setting the index to the blocks final location.
459 Block* tmp = mutable_blocks->back();
460 tmp->set_index(block_to_remove->index());
461
462 // Overwrite the to-be-deleted residual block with the one at the end.
463 (*mutable_blocks)[block_to_remove->index()] = tmp;
464
465 DeleteBlock(block_to_remove);
466
467 // The block is gone so shrink the vector of blocks accordingly.
468 mutable_blocks->pop_back();
469}
470
471void ProblemImpl::RemoveResidualBlock(ResidualBlock* residual_block) {
472 CHECK_NOTNULL(residual_block);
473
474 // If needed, remove the parameter dependencies on this residual block.
475 if (options_.enable_fast_parameter_block_removal) {
476 const int num_parameter_blocks_for_residual =
477 residual_block->NumParameterBlocks();
478 for (int i = 0; i < num_parameter_blocks_for_residual; ++i) {
479 residual_block->parameter_blocks()[i]
480 ->RemoveResidualBlock(residual_block);
481 }
482 }
483 DeleteBlockInVector(program_->mutable_residual_blocks(), residual_block);
484}
485
486void ProblemImpl::RemoveParameterBlock(double* values) {
Sameer Agarwal020d8e12013-03-06 16:19:26 -0800487 ParameterBlock* parameter_block =
488 FindParameterBlockOrDie(parameter_block_map_, values);
Keir Mierle04938ef2013-02-17 12:37:55 -0800489
490 if (options_.enable_fast_parameter_block_removal) {
491 // Copy the dependent residuals from the parameter block because the set of
492 // dependents will change after each call to RemoveResidualBlock().
493 vector<ResidualBlock*> residual_blocks_to_remove(
494 parameter_block->mutable_residual_blocks()->begin(),
495 parameter_block->mutable_residual_blocks()->end());
496 for (int i = 0; i < residual_blocks_to_remove.size(); ++i) {
497 RemoveResidualBlock(residual_blocks_to_remove[i]);
498 }
499 } else {
500 // Scan all the residual blocks to remove ones that depend on the parameter
501 // block. Do the scan backwards since the vector changes while iterating.
502 const int num_residual_blocks = NumResidualBlocks();
503 for (int i = num_residual_blocks - 1; i >= 0; --i) {
504 ResidualBlock* residual_block =
505 (*(program_->mutable_residual_blocks()))[i];
506 const int num_parameter_blocks = residual_block->NumParameterBlocks();
Sameer Agarwalbeb45052013-02-22 13:37:01 -0800507 for (int j = 0; j < num_parameter_blocks; ++j) {
508 if (residual_block->parameter_blocks()[j] == parameter_block) {
Keir Mierle04938ef2013-02-17 12:37:55 -0800509 RemoveResidualBlock(residual_block);
510 // The parameter blocks are guaranteed unique.
511 break;
512 }
513 }
514 }
515 }
516 DeleteBlockInVector(program_->mutable_parameter_blocks(), parameter_block);
517}
518
Keir Mierle8ebb0732012-04-30 23:09:08 -0700519void ProblemImpl::SetParameterBlockConstant(double* values) {
Sameer Agarwal020d8e12013-03-06 16:19:26 -0800520 FindParameterBlockOrDie(parameter_block_map_, values)->SetConstant();
Keir Mierle8ebb0732012-04-30 23:09:08 -0700521}
522
523void ProblemImpl::SetParameterBlockVariable(double* values) {
Sameer Agarwal020d8e12013-03-06 16:19:26 -0800524 FindParameterBlockOrDie(parameter_block_map_, values)->SetVarying();
Keir Mierle8ebb0732012-04-30 23:09:08 -0700525}
526
527void ProblemImpl::SetParameterization(
528 double* values,
529 LocalParameterization* local_parameterization) {
Sameer Agarwal020d8e12013-03-06 16:19:26 -0800530 FindParameterBlockOrDie(parameter_block_map_, values)
Keir Mierle8ebb0732012-04-30 23:09:08 -0700531 ->SetParameterization(local_parameterization);
532}
533
Sameer Agarwal509f68c2013-02-20 01:39:03 -0800534bool ProblemImpl::Evaluate(const Problem::EvaluateOptions& evaluate_options,
535 double* cost,
536 vector<double>* residuals,
537 vector<double>* gradient,
538 CRSMatrix* jacobian) {
539 if (cost == NULL &&
540 residuals == NULL &&
541 gradient == NULL &&
542 jacobian == NULL) {
543 LOG(INFO) << "Nothing to do.";
544 return true;
545 }
546
547 // If the user supplied residual blocks, then use them, otherwise
548 // take the residual blocks from the underlying program.
549 Program program;
550 *program.mutable_residual_blocks() =
551 ((evaluate_options.residual_blocks.size() > 0)
552 ? evaluate_options.residual_blocks : program_->residual_blocks());
553
554 const vector<double*>& parameter_block_ptrs =
555 evaluate_options.parameter_blocks;
556
557 vector<ParameterBlock*> variable_parameter_blocks;
558 vector<ParameterBlock*>& parameter_blocks =
559 *program.mutable_parameter_blocks();
560
561 if (parameter_block_ptrs.size() == 0) {
562 // The user did not provide any parameter blocks, so default to
563 // using all the parameter blocks in the order that they are in
564 // the underlying program object.
565 parameter_blocks = program_->parameter_blocks();
566 } else {
567 // The user supplied a vector of parameter blocks. Using this list
568 // requires a number of steps.
569
570 // 1. Convert double* into ParameterBlock*
571 parameter_blocks.resize(parameter_block_ptrs.size());
572 for (int i = 0; i < parameter_block_ptrs.size(); ++i) {
573 parameter_blocks[i] =
Sameer Agarwal020d8e12013-03-06 16:19:26 -0800574 FindParameterBlockOrDie(parameter_block_map_,
575 parameter_block_ptrs[i]);
Sameer Agarwal509f68c2013-02-20 01:39:03 -0800576 }
577
578 // 2. The user may have only supplied a subset of parameter
579 // blocks, so identify the ones that are not supplied by the user
580 // and are NOT constant. These parameter blocks are stored in
581 // variable_parameter_blocks.
582 //
583 // To ensure that the parameter blocks are not included in the
584 // columns of the jacobian, we need to make sure that they are
585 // constant during evaluation and then make them variable again
586 // after we are done.
587 vector<ParameterBlock*> all_parameter_blocks(program_->parameter_blocks());
588 vector<ParameterBlock*> included_parameter_blocks(
589 program.parameter_blocks());
590
591 vector<ParameterBlock*> excluded_parameter_blocks;
592 sort(all_parameter_blocks.begin(), all_parameter_blocks.end());
593 sort(included_parameter_blocks.begin(), included_parameter_blocks.end());
594 set_difference(all_parameter_blocks.begin(),
595 all_parameter_blocks.end(),
596 included_parameter_blocks.begin(),
597 included_parameter_blocks.end(),
598 back_inserter(excluded_parameter_blocks));
599
600 variable_parameter_blocks.reserve(excluded_parameter_blocks.size());
601 for (int i = 0; i < excluded_parameter_blocks.size(); ++i) {
602 ParameterBlock* parameter_block = excluded_parameter_blocks[i];
603 if (!parameter_block->IsConstant()) {
604 variable_parameter_blocks.push_back(parameter_block);
605 parameter_block->SetConstant();
606 }
607 }
608 }
609
610 // Setup the Parameter indices and offsets before an evaluator can
611 // be constructed and used.
612 program.SetParameterOffsetsAndIndex();
613
614 Evaluator::Options evaluator_options;
615
616 // Even though using SPARSE_NORMAL_CHOLESKY requires SuiteSparse or
617 // CXSparse, here it just being used for telling the evaluator to
618 // use a SparseRowCompressedMatrix for the jacobian. This is because
619 // the Evaluator decides the storage for the Jacobian based on the
620 // type of linear solver being used.
621 evaluator_options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
622 evaluator_options.num_threads = evaluate_options.num_threads;
623
624 string error;
625 scoped_ptr<Evaluator> evaluator(
626 Evaluator::Create(evaluator_options, &program, &error));
627 if (evaluator.get() == NULL) {
628 LOG(ERROR) << "Unable to create an Evaluator object. "
629 << "Error: " << error
630 << "This is a Ceres bug; please contact the developers!";
631
632 // Make the parameter blocks that were temporarily marked
633 // constant, variable again.
634 for (int i = 0; i < variable_parameter_blocks.size(); ++i) {
635 variable_parameter_blocks[i]->SetVarying();
636 }
637 return false;
638 }
639
640 if (residuals !=NULL) {
641 residuals->resize(evaluator->NumResiduals());
642 }
643
644 if (gradient != NULL) {
645 gradient->resize(evaluator->NumEffectiveParameters());
646 }
647
648 scoped_ptr<CompressedRowSparseMatrix> tmp_jacobian;
649 if (jacobian != NULL) {
650 tmp_jacobian.reset(
651 down_cast<CompressedRowSparseMatrix*>(evaluator->CreateJacobian()));
652 }
653
654 // Point the state pointers to the user state pointers. This is
655 // needed so that we can extract a parameter vector which is then
656 // passed to Evaluator::Evaluate.
657 program.SetParameterBlockStatePtrsToUserStatePtrs();
658
659 // Copy the value of the parameter blocks into a vector, since the
660 // Evaluate::Evaluate method needs its input as such. The previous
661 // call to SetParameterBlockStatePtrsToUserStatePtrs ensures that
662 // these values are the ones corresponding to the actual state of
663 // the parameter blocks, rather than the temporary state pointer
664 // used for evaluation.
665 Vector parameters(program.NumParameters());
666 program.ParameterBlocksToStateVector(parameters.data());
667
668 double tmp_cost = 0;
Sameer Agarwal039ff072013-02-26 09:15:39 -0800669
670 Evaluator::EvaluateOptions evaluator_evaluate_options;
671 evaluator_evaluate_options.apply_loss_function =
672 evaluate_options.apply_loss_function;
673 bool status = evaluator->Evaluate(evaluator_evaluate_options,
674 parameters.data(),
Sameer Agarwal509f68c2013-02-20 01:39:03 -0800675 &tmp_cost,
676 residuals != NULL ? &(*residuals)[0] : NULL,
677 gradient != NULL ? &(*gradient)[0] : NULL,
678 tmp_jacobian.get());
679
Sameer Agarwal931c3092013-02-25 09:46:21 -0800680 // Make the parameter blocks that were temporarily marked constant,
681 // variable again.
Sameer Agarwal509f68c2013-02-20 01:39:03 -0800682 for (int i = 0; i < variable_parameter_blocks.size(); ++i) {
683 variable_parameter_blocks[i]->SetVarying();
684 }
685
686 if (status) {
687 if (cost != NULL) {
688 *cost = tmp_cost;
689 }
690 if (jacobian != NULL) {
691 tmp_jacobian->ToCRSMatrix(jacobian);
692 }
693 }
694
695 return status;
696}
697
Keir Mierle8ebb0732012-04-30 23:09:08 -0700698int ProblemImpl::NumParameterBlocks() const {
699 return program_->NumParameterBlocks();
700}
701
702int ProblemImpl::NumParameters() const {
703 return program_->NumParameters();
704}
705
706int ProblemImpl::NumResidualBlocks() const {
707 return program_->NumResidualBlocks();
708}
709
710int ProblemImpl::NumResiduals() const {
711 return program_->NumResiduals();
712}
713
714} // namespace internal
715} // namespace ceres