mirror of
https://github.com/ceres-solver/ceres-solver.git
synced 2026-08-29 16:40:38 +08:00
Sized cost function using variadic templates
This PR changes the interface of sized_cost_fucntion, autodiff_cost_function and numeric_diff_costfunction from using ten hardcoded parameter blocks to a variable number of parameter blocks using variadic templates. Trailing parameter blocks of size zero are now considered as error. Change-Id: I37b9a0a420ef0eda6476a46672bbf6bd57e19760
This commit is contained in:
@@ -41,49 +41,24 @@
|
||||
#include "ceres/cost_function.h"
|
||||
#include "ceres/types.h"
|
||||
#include "glog/logging.h"
|
||||
#include "internal/parameter_dims.h"
|
||||
|
||||
namespace ceres {
|
||||
|
||||
template<int kNumResiduals,
|
||||
int N0 = 0, int N1 = 0, int N2 = 0, int N3 = 0, int N4 = 0,
|
||||
int N5 = 0, int N6 = 0, int N7 = 0, int N8 = 0, int N9 = 0>
|
||||
template <int kNumResiduals, int... Ns>
|
||||
class SizedCostFunction : public CostFunction {
|
||||
public:
|
||||
static_assert(kNumResiduals > 0 || kNumResiduals == DYNAMIC,
|
||||
"Cost functions must have at least one residual block.");
|
||||
static_assert(internal::StaticParameterDims<Ns...>::kIsValid,
|
||||
"Invalid parameter block dimension detected. Each parameter "
|
||||
"block dimension must be bigger than zero.");
|
||||
|
||||
using ParameterDims = internal::StaticParameterDims<Ns...>;
|
||||
|
||||
SizedCostFunction() {
|
||||
CHECK(kNumResiduals > 0 || kNumResiduals == DYNAMIC)
|
||||
<< "Cost functions must have at least one residual block.";
|
||||
|
||||
// This block breaks the 80 column rule to keep it somewhat readable.
|
||||
CHECK((!N1 && !N2 && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
|
||||
((N1 > 0) && !N2 && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
|
||||
((N1 > 0) && (N2 > 0) && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) || // NOLINT
|
||||
((N1 > 0) && (N2 > 0) && (N3 > 0) && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) || // NOLINT
|
||||
((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && !N5 && !N6 && !N7 && !N8 && !N9) || // NOLINT
|
||||
((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && !N6 && !N7 && !N8 && !N9) || // NOLINT
|
||||
((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && !N7 && !N8 && !N9) || // NOLINT
|
||||
((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && !N8 && !N9) || // NOLINT
|
||||
((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && (N8 > 0) && !N9) || // NOLINT
|
||||
((N1 > 0) && (N2 > 0) && (N3 > 0) && (N4 > 0) && (N5 > 0) && (N6 > 0) && (N7 > 0) && (N8 > 0) && (N9 > 0))) // NOLINT
|
||||
<< "Zero block cannot precede a non-zero block. Block sizes are "
|
||||
<< "(ignore trailing 0s): " << N0 << ", " << N1 << ", " << N2 << ", "
|
||||
<< N3 << ", " << N4 << ", " << N5 << ", " << N6 << ", " << N7 << ", "
|
||||
<< N8 << ", " << N9;
|
||||
|
||||
set_num_residuals(kNumResiduals);
|
||||
|
||||
#define CERES_ADD_PARAMETER_BLOCK(N) \
|
||||
if (N) mutable_parameter_block_sizes()->push_back(N);
|
||||
CERES_ADD_PARAMETER_BLOCK(N0);
|
||||
CERES_ADD_PARAMETER_BLOCK(N1);
|
||||
CERES_ADD_PARAMETER_BLOCK(N2);
|
||||
CERES_ADD_PARAMETER_BLOCK(N3);
|
||||
CERES_ADD_PARAMETER_BLOCK(N4);
|
||||
CERES_ADD_PARAMETER_BLOCK(N5);
|
||||
CERES_ADD_PARAMETER_BLOCK(N6);
|
||||
CERES_ADD_PARAMETER_BLOCK(N7);
|
||||
CERES_ADD_PARAMETER_BLOCK(N8);
|
||||
CERES_ADD_PARAMETER_BLOCK(N9);
|
||||
#undef CERES_ADD_PARAMETER_BLOCK
|
||||
*mutable_parameter_block_sizes() = std::vector<int32_t>{Ns...};
|
||||
}
|
||||
|
||||
virtual ~SizedCostFunction() { }
|
||||
|
||||
Reference in New Issue
Block a user