class DynCostFunction : public ceres::CostFunction {
public:
DynCostFunction() {}
virtual bool Evaluate(double const* const* parameters,
double* residuals,
double** jacobians) const {
// NOT POINTING TO ANYWHERE
const double* sample_params_1 = parameters[0];
const double* sample_params_2 = parameters[1];
// FAILS AS CAN'T READ MEMORY STORING PARAMETERS
std::cout << "(" << sample_params_1[0] << "," << sample_params_1[1] << "," << ")" << "\t (" << sample_params_2[0] << "," << sample_params_2[1] << ")" << std::endl;
// IN REAL APP, RESIDUAL AND JACOBIAN CALCULATED HERE
// ...
return true;
}
};
class DynCostFunctor {
public:
std::unique_ptr<ceres::DynamicCostFunctionToFunctor> _compute_via_dyn_cost;
DynCostFunctor()
{
_compute_via_dyn_cost.reset(new ceres::DynamicCostFunctionToFunctor(new DynCostFunction()));
}
template<typename T>
bool operator()(T const* const* parameters, T* residual) const {
const T* sample_params_1 = parameters[0];
const T* sample_params_2 = parameters[1];
// CORRECTLY DISPLAYS THE PARAMETERS STORED IN PARAMETER BLOCKS AS EXPECTED
std::cout << "(" << sample_params_1[0] << "," << sample_params_1[1] << "," << ")" << "\t (" << sample_params_2[0] << "," << sample_params_2[1] << ")" << std::endl;
(*_compute_via_dyn_cost)(parameters, residual);
return true;
}
};
int main()
{
Problem problem;
const int parameter_1_block_size = 5 ;
const int n_samples = 100 ;
const int n_verts = 8;
const int parameter_2_block_size = n_verts *3 ;
MatrixXd X(parameter_1_block_size, n_samples);
X.setZero();
double lower_bound = 0;
double upper_bound = 1.0;
std::uniform_real_distribution<double> unif(lower_bound, upper_bound);
std::default_random_engine re;
for (auto v : range(0, n_samples)) {
X(0, v) = v;
X(1, v) = unif(re);
X(2, v) = unif(re);
X(3, v) = unif(re);
X(4, v) = unif(re);
}
MatrixXd Y(parameter_2_block_size, 1);
Y.setZero();
for (auto v : range(0, parameter_2_block_size)) {
Y(v) = unif(re);
}
std::vector<double*> parameter_blocks(n_samples+1);
for (auto v : range(0, n_samples)) {
parameter_blocks[v] = X.data() + (parameter_1_block_size * v);
problem.AddParameterBlock(parameter_blocks[v], parameter_1_block_size);
}
parameter_blocks[n_samples] = &Y(0);
problem.AddParameterBlock(parameter_blocks[n_samples], parameter_2_block_size);
ceres::DynamicAutoDiffCostFunction<DynCostFunctor>*
dynamic_sized_cost_function (
new ceres::DynamicAutoDiffCostFunction<DynCostFunctor>(
new DynCostFunctor()));
dynamic_sized_cost_function->AddParameterBlock(parameter_1_block_size);
dynamic_sized_cost_function->AddParameterBlock(parameter_2_block_size);
dynamic_sized_cost_function->SetNumResiduals(3);
for (auto s : range(0, n_samples)) {
problem.AddResidualBlock(
dynamic_sized_cost_function,
NULL,
parameter_blocks[s],
parameter_blocks[n_samples]);
}
Solver::Options options;
options.max_num_iterations = 50;
options.minimizer_progress_to_stdout = true;
options.function_tolerance = 1e-100;
Solver::Summary summary;
ceres::Solve(options, &problem, &summary);
std::cout << summary.FullReport() << std::endl;
}