| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #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 |
| |
|