| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #ifndef CERES_PUBLIC_DYNAMIC_NUMERIC_DIFF_COST_FUNCTION_H_ |
| #define CERES_PUBLIC_DYNAMIC_NUMERIC_DIFF_COST_FUNCTION_H_ |
|
|
| #include <cmath> |
| #include <memory> |
| #include <numeric> |
| #include <vector> |
|
|
| #include "ceres/dynamic_cost_function.h" |
| #include "ceres/internal/eigen.h" |
| #include "ceres/internal/numeric_diff.h" |
| #include "ceres/internal/parameter_dims.h" |
| #include "ceres/numeric_diff_options.h" |
| #include "ceres/types.h" |
| #include "glog/logging.h" |
|
|
| namespace ceres { |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| template <typename CostFunctor, NumericDiffMethodType method = CENTRAL> |
| class DynamicNumericDiffCostFunction final : public DynamicCostFunction { |
| public: |
| explicit DynamicNumericDiffCostFunction( |
| const CostFunctor* functor, |
| Ownership ownership = TAKE_OWNERSHIP, |
| const NumericDiffOptions& options = NumericDiffOptions()) |
| : functor_(functor), ownership_(ownership), options_(options) {} |
|
|
| DynamicNumericDiffCostFunction(DynamicNumericDiffCostFunction&& other) |
| : functor_(std::move(other.functor_)), ownership_(other.ownership_) {} |
|
|
| ~DynamicNumericDiffCostFunction() override { |
| if (ownership_ != TAKE_OWNERSHIP) { |
| functor_.release(); |
| } |
| } |
|
|
| bool Evaluate(double const* const* parameters, |
| double* residuals, |
| double** jacobians) const override { |
| using internal::NumericDiff; |
| CHECK_GT(num_residuals(), 0) |
| << "You must call DynamicNumericDiffCostFunction::SetNumResiduals() " |
| << "before DynamicNumericDiffCostFunction::Evaluate()."; |
|
|
| const std::vector<int32_t>& block_sizes = parameter_block_sizes(); |
| CHECK(!block_sizes.empty()) |
| << "You must call DynamicNumericDiffCostFunction::AddParameterBlock() " |
| << "before DynamicNumericDiffCostFunction::Evaluate()."; |
|
|
| const bool status = |
| internal::VariadicEvaluate<internal::DynamicParameterDims>( |
| *functor_.get(), parameters, residuals); |
| if (jacobians == nullptr || !status) { |
| return status; |
| } |
|
|
| |
| int parameters_size = accumulate(block_sizes.begin(), block_sizes.end(), 0); |
| std::vector<double> parameters_copy(parameters_size); |
| std::vector<double*> parameters_references_copy(block_sizes.size()); |
| parameters_references_copy[0] = ¶meters_copy[0]; |
| for (size_t block = 1; block < block_sizes.size(); ++block) { |
| parameters_references_copy[block] = |
| parameters_references_copy[block - 1] + block_sizes[block - 1]; |
| } |
|
|
| |
| for (size_t block = 0; block < block_sizes.size(); ++block) { |
| memcpy(parameters_references_copy[block], |
| parameters[block], |
| block_sizes[block] * sizeof(*parameters[block])); |
| } |
|
|
| for (size_t block = 0; block < block_sizes.size(); ++block) { |
| if (jacobians[block] != nullptr && |
| !NumericDiff<CostFunctor, |
| method, |
| ceres::DYNAMIC, |
| internal::DynamicParameterDims, |
| ceres::DYNAMIC, |
| ceres::DYNAMIC>:: |
| EvaluateJacobianForParameterBlock(functor_.get(), |
| residuals, |
| options_, |
| this->num_residuals(), |
| block, |
| block_sizes[block], |
| ¶meters_references_copy[0], |
| jacobians[block])) { |
| return false; |
| } |
| } |
| return true; |
| } |
|
|
| private: |
| std::unique_ptr<const CostFunctor> functor_; |
| Ownership ownership_; |
| NumericDiffOptions options_; |
| }; |
|
|
| } |
|
|
| #endif |
|
|