Files
Denso/ipc/CeresWrapper/ceres_wrapper.h
2026-07-03 16:31:37 +07:00

1061 lines
49 KiB
C

/* Ceres Wrapper - Extended C API for CeresSharp
* Copyright 2024 RobotNet10. All rights reserved.
*
* This wrapper provides additional C APIs that are missing from the official
* Ceres C API (c_api.h) but are required for Cartographer integration.
*
* This wrapper uses the official Ceres C++ API internally and exposes
* a C interface for P/Invoke from C#.
*/
#ifndef CERES_WRAPPER_H_
#define CERES_WRAPPER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
// Export macro for shared library
#ifdef _WIN32
#ifdef CERES_WRAPPER_BUILDING
#define CERES_WRAPPER_EXPORT __declspec(dllexport)
#else
#define CERES_WRAPPER_EXPORT __declspec(dllimport)
#endif
#else
#define CERES_WRAPPER_EXPORT __attribute__((visibility("default")))
#endif
// ============================================================================
// Error Codes
// ============================================================================
/* Error codes returned by wrapper functions */
typedef enum {
CERES_WRAPPER_SUCCESS = 0, /* Operation succeeded */
CERES_WRAPPER_ERROR_NULL_POINTER = 1, /* Null pointer argument */
CERES_WRAPPER_ERROR_INVALID_PARAMETER = 2, /* Invalid parameter value */
CERES_WRAPPER_ERROR_INVALID_ENUM = 3, /* Invalid enum value */
CERES_WRAPPER_ERROR_EXCEPTION = 4, /* C++ exception occurred */
CERES_WRAPPER_ERROR_OUT_OF_MEMORY = 5, /* Memory allocation failed */
CERES_WRAPPER_ERROR_INVALID_OPERATION = 6, /* Invalid operation for current state */
CERES_WRAPPER_ERROR_BUFFER_TOO_SMALL = 7, /* Output buffer too small */
CERES_WRAPPER_ERROR_NOT_FOUND = 8, /* Resource not found */
CERES_WRAPPER_ERROR_ALREADY_EXISTS = 9 /* Resource already exists */
} ceres_wrapper_error_code_t;
/* Get error message for error code */
CERES_WRAPPER_EXPORT const char* ceres_wrapper_get_error_message(ceres_wrapper_error_code_t error_code);
// ============================================================================
// Library Information and Version
// ============================================================================
/* Get Ceres version string (e.g., "2.2.0") */
CERES_WRAPPER_EXPORT const char* ceres_wrapper_get_version_string();
/* Get Ceres major version number */
CERES_WRAPPER_EXPORT int ceres_wrapper_get_version_major();
/* Get Ceres minor version number */
CERES_WRAPPER_EXPORT int ceres_wrapper_get_version_minor();
/* Get Ceres revision version number */
CERES_WRAPPER_EXPORT int ceres_wrapper_get_version_revision();
/* Get detailed Ceres version string with build configuration */
/* Returns error code (CERES_WRAPPER_SUCCESS on success) */
/* buffer: output buffer for version string (can be NULL) */
/* buffer_size: size of buffer (ignored if buffer is NULL) */
CERES_WRAPPER_EXPORT ceres_wrapper_error_code_t ceres_wrapper_get_detailed_version_string(
char* buffer,
int buffer_size);
/* Get comprehensive library information including version, build configuration, and features */
/* Returns error code (CERES_WRAPPER_SUCCESS on success) */
/* buffer: output buffer for library info string (can be NULL) */
/* buffer_size: size of buffer (ignored if buffer is NULL) */
CERES_WRAPPER_EXPORT ceres_wrapper_error_code_t ceres_wrapper_get_library_info(
char* buffer,
int buffer_size);
// Forward declarations
struct ceres_problem_s;
typedef struct ceres_problem_s ceres_problem_t;
struct ceres_residual_block_id_s;
typedef struct ceres_residual_block_id_s ceres_residual_block_id_t;
// ============================================================================
// Solver Options
// ============================================================================
struct ceres_solver_options_s;
typedef struct ceres_solver_options_s ceres_solver_options_t;
/* Create and destroy solver options */
CERES_WRAPPER_EXPORT ceres_solver_options_t* ceres_wrapper_create_solver_options();
CERES_WRAPPER_EXPORT void ceres_wrapper_free_solver_options(ceres_solver_options_t* options);
/* Linear solver type */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_linear_solver_type(
ceres_solver_options_t* options, int linear_solver_type);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_linear_solver_type(
const ceres_solver_options_t* options);
/* Minimizer type */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_minimizer_type(
ceres_solver_options_t* options, int minimizer_type);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_minimizer_type(
const ceres_solver_options_t* options);
/* Iterations */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_max_num_iterations(
ceres_solver_options_t* options, int max_num_iterations);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_max_num_iterations(
const ceres_solver_options_t* options);
/* Threads */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_num_threads(
ceres_solver_options_t* options, int num_threads);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_num_threads(
const ceres_solver_options_t* options);
/* Tolerances */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_function_tolerance(
ceres_solver_options_t* options, double function_tolerance);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_options_get_function_tolerance(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_gradient_tolerance(
ceres_solver_options_t* options, double gradient_tolerance);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_options_get_gradient_tolerance(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_parameter_tolerance(
ceres_solver_options_t* options, double parameter_tolerance);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_options_get_parameter_tolerance(
const ceres_solver_options_t* options);
/* Trust region */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_initial_trust_region_radius(
ceres_solver_options_t* options, double radius);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_options_get_initial_trust_region_radius(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_max_trust_region_radius(
ceres_solver_options_t* options, double radius);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_options_get_max_trust_region_radius(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_min_trust_region_radius(
ceres_solver_options_t* options, double radius);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_options_get_min_trust_region_radius(
const ceres_solver_options_t* options);
/* Preconditioner */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_preconditioner_type(
ceres_solver_options_t* options, int preconditioner_type);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_preconditioner_type(
const ceres_solver_options_t* options);
/* Trust region strategy */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_trust_region_strategy_type(
ceres_solver_options_t* options, int trust_region_strategy_type);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_trust_region_strategy_type(
const ceres_solver_options_t* options);
/* Dogleg type */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_dogleg_type(
ceres_solver_options_t* options, int dogleg_type);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_dogleg_type(
const ceres_solver_options_t* options);
/* Other options */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_use_nonmonotonic_steps(
ceres_solver_options_t* options, int use_nonmonotonic_steps);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_use_nonmonotonic_steps(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_max_consecutive_nonmonotonic_steps(
ceres_solver_options_t* options, int max_steps);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_max_consecutive_nonmonotonic_steps(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_max_num_consecutive_invalid_steps(
ceres_solver_options_t* options, int max_steps);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_max_num_consecutive_invalid_steps(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_min_relative_decrease(
ceres_solver_options_t* options, double min_relative_decrease);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_options_get_min_relative_decrease(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_logging_type(
ceres_solver_options_t* options, int logging_type);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_logging_type(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_minimizer_progress_to_stdout(
ceres_solver_options_t* options, int minimizer_progress_to_stdout);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_minimizer_progress_to_stdout(
const ceres_solver_options_t* options);
/* Validation */
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_is_valid(
const ceres_solver_options_t* options, char* error_message, int error_message_size);
// ============================================================================
// Solver Summary
// ============================================================================
struct ceres_solver_summary_s;
typedef struct ceres_solver_summary_s ceres_solver_summary_t;
/* Create and destroy solver summary */
CERES_WRAPPER_EXPORT ceres_solver_summary_t* ceres_wrapper_create_solver_summary();
CERES_WRAPPER_EXPORT void ceres_wrapper_free_solver_summary(ceres_solver_summary_t* summary);
/* Termination type */
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_summary_get_termination_type(
const ceres_solver_summary_t* summary);
/* Message */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_summary_get_message(
const ceres_solver_summary_t* summary, char* message, int message_size);
/* Cost */
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_summary_get_initial_cost(
const ceres_solver_summary_t* summary);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_summary_get_final_cost(
const ceres_solver_summary_t* summary);
/* Iterations */
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_summary_get_iterations(
const ceres_solver_summary_t* summary);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_summary_get_num_successful_steps(
const ceres_solver_summary_t* summary);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_summary_get_num_unsuccessful_steps(
const ceres_solver_summary_t* summary);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_summary_get_num_inner_iteration_steps(
const ceres_solver_summary_t* summary);
/* Timing */
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_summary_get_total_time_in_seconds(
const ceres_solver_summary_t* summary);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_summary_get_preprocessor_time_in_seconds(
const ceres_solver_summary_t* summary);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_summary_get_minimizer_time_in_seconds(
const ceres_solver_summary_t* summary);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_summary_get_postprocessor_time_in_seconds(
const ceres_solver_summary_t* summary);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_summary_get_linear_solver_time_in_seconds(
const ceres_solver_summary_t* summary);
/* Full report */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_summary_get_full_report(
const ceres_solver_summary_t* summary, char* report, int report_size);
// ============================================================================
// Solve with Options and Summary
// ============================================================================
/* Solve problem with options and summary */
/* Returns error code (CERES_WRAPPER_SUCCESS on success) */
/* error_message: optional output buffer for error message (can be NULL) */
/* error_message_size: size of error_message buffer (ignored if error_message is NULL) */
CERES_WRAPPER_EXPORT ceres_wrapper_error_code_t ceres_wrapper_solve(
ceres_problem_t* problem,
const ceres_solver_options_t* options,
ceres_solver_summary_t* summary,
char* error_message,
int error_message_size);
// ============================================================================
// Parameter Blocks Management
// ============================================================================
/* Add parameter block */
/* Returns error code (CERES_WRAPPER_SUCCESS on success) */
/* error_message: optional output buffer for error message (can be NULL) */
/* error_message_size: size of error_message buffer (ignored if error_message is NULL) */
CERES_WRAPPER_EXPORT ceres_wrapper_error_code_t ceres_wrapper_problem_add_parameter_block(
ceres_problem_t* problem,
double* parameters,
int size,
char* error_message,
int error_message_size);
/* Set parameter block constant */
CERES_WRAPPER_EXPORT void ceres_wrapper_problem_set_parameter_block_constant(
ceres_problem_t* problem,
double* parameters);
/* Set parameter block variable */
CERES_WRAPPER_EXPORT void ceres_wrapper_problem_set_parameter_block_variable(
ceres_problem_t* problem,
double* parameters);
/* Remove parameter block */
/* Returns error code (CERES_WRAPPER_SUCCESS on success) */
/* error_message: optional output buffer for error message (can be NULL) */
/* error_message_size: size of error_message buffer (ignored if error_message is NULL) */
CERES_WRAPPER_EXPORT ceres_wrapper_error_code_t ceres_wrapper_problem_remove_parameter_block(
ceres_problem_t* problem,
double* parameters,
char* error_message,
int error_message_size);
/* Remove residual block */
/* Returns error code (CERES_WRAPPER_SUCCESS on success) */
/* error_message: optional output buffer for error message (can be NULL) */
/* error_message_size: size of error_message buffer (ignored if error_message is NULL) */
CERES_WRAPPER_EXPORT ceres_wrapper_error_code_t ceres_wrapper_problem_remove_residual_block(
ceres_problem_t* problem,
ceres_residual_block_id_t* residual_block_id,
char* error_message,
int error_message_size);
/* Add residual block with cost function and loss function */
/* cost_function: pointer to cost function (from ceres_wrapper_create_autodiff_cost_function or similar) */
/* loss_function: pointer to loss function (ceres_wrapper_loss_function_t* - can be NULL for TrivialLoss) */
/* parameter_blocks: array of parameter block pointers */
/* num_parameter_blocks: number of parameter blocks */
/* residual_block_id: output parameter for residual block ID (can be NULL if not needed) */
/* Returns error code (CERES_WRAPPER_SUCCESS on success) */
/* error_message: optional output buffer for error message (can be NULL) */
/* error_message_size: size of error_message buffer (ignored if error_message is NULL) */
CERES_WRAPPER_EXPORT ceres_wrapper_error_code_t ceres_wrapper_problem_add_residual_block(
ceres_problem_t* problem,
void* cost_function,
void* loss_function, /* ceres_wrapper_loss_function_t* - can be NULL */
double** parameter_blocks,
int num_parameter_blocks,
ceres_residual_block_id_t** residual_block_id,
char* error_message,
int error_message_size);
/* Get problem statistics */
CERES_WRAPPER_EXPORT int ceres_wrapper_problem_num_parameter_blocks(
const ceres_problem_t* problem);
CERES_WRAPPER_EXPORT int ceres_wrapper_problem_num_residual_blocks(
const ceres_problem_t* problem);
CERES_WRAPPER_EXPORT int ceres_wrapper_problem_num_parameters(
const ceres_problem_t* problem);
CERES_WRAPPER_EXPORT int ceres_wrapper_problem_num_residuals(
const ceres_problem_t* problem);
// ============================================================================
// Loss Functions
// ============================================================================
struct ceres_wrapper_loss_function_s;
typedef struct ceres_wrapper_loss_function_s ceres_wrapper_loss_function_t;
/* Create loss functions */
CERES_WRAPPER_EXPORT ceres_wrapper_loss_function_t* ceres_wrapper_create_huber_loss(double a);
CERES_WRAPPER_EXPORT ceres_wrapper_loss_function_t* ceres_wrapper_create_trivial_loss();
CERES_WRAPPER_EXPORT ceres_wrapper_loss_function_t* ceres_wrapper_create_cauchy_loss(double a);
CERES_WRAPPER_EXPORT ceres_wrapper_loss_function_t* ceres_wrapper_create_softl1_loss(double a);
CERES_WRAPPER_EXPORT ceres_wrapper_loss_function_t* ceres_wrapper_create_arctan_loss(double a);
CERES_WRAPPER_EXPORT ceres_wrapper_loss_function_t* ceres_wrapper_create_tolerant_loss(double a, double b);
/* Create composed loss function: f(g(s)) */
/* f: first loss function (takes ownership if ownership_f != 0) */
/* g: second loss function (takes ownership if ownership_g != 0) */
/* ownership_f: 1 to take ownership of f, 0 otherwise */
/* ownership_g: 1 to take ownership of g, 0 otherwise */
CERES_WRAPPER_EXPORT ceres_wrapper_loss_function_t* ceres_wrapper_create_composed_loss(
ceres_wrapper_loss_function_t* f,
int ownership_f,
ceres_wrapper_loss_function_t* g,
int ownership_g);
/* Create scaled loss function: a * rho(s) */
/* rho: loss function to scale (can be NULL for identity, takes ownership if ownership != 0) */
/* a: scaling factor */
/* ownership: 1 to take ownership of rho, 0 otherwise */
CERES_WRAPPER_EXPORT ceres_wrapper_loss_function_t* ceres_wrapper_create_scaled_loss(
ceres_wrapper_loss_function_t* rho,
double a,
int ownership);
/* Free loss function */
CERES_WRAPPER_EXPORT void ceres_wrapper_free_loss_function(ceres_wrapper_loss_function_t* loss);
// ============================================================================
// Manifolds
// ============================================================================
struct ceres_manifold_s;
typedef struct ceres_manifold_s ceres_manifold_t;
/* Create manifolds */
CERES_WRAPPER_EXPORT ceres_manifold_t* ceres_wrapper_create_quaternion_manifold();
CERES_WRAPPER_EXPORT ceres_manifold_t* ceres_wrapper_create_sphere_manifold(int dimension);
CERES_WRAPPER_EXPORT ceres_manifold_t* ceres_wrapper_create_line_manifold(int dimension);
/* Free manifold */
CERES_WRAPPER_EXPORT void ceres_wrapper_free_manifold(ceres_manifold_t* manifold);
/* Set manifold for parameter block */
CERES_WRAPPER_EXPORT void ceres_wrapper_problem_set_manifold(
ceres_problem_t* problem,
double* parameters,
ceres_manifold_t* manifold);
/* Get manifold dimensions */
CERES_WRAPPER_EXPORT int ceres_wrapper_manifold_ambient_size(const ceres_manifold_t* manifold);
CERES_WRAPPER_EXPORT int ceres_wrapper_manifold_tangent_size(const ceres_manifold_t* manifold);
// ============================================================================
// AutoDiff Manifold
// ============================================================================
/* Callback for AutoDiff manifold Plus operation */
/* x: point on manifold (ambient_size elements) */
/* delta: tangent vector (tangent_size elements) */
/* x_plus_delta: output point on manifold (ambient_size elements) */
/* Returns 1 on success, 0 on failure */
typedef int (*ceres_autodiff_manifold_plus_t)(
void* user_data,
const double* x,
const double* delta,
double* x_plus_delta);
/* Callback for AutoDiff manifold Minus operation */
/* y: point on manifold (ambient_size elements) */
/* x: point on manifold (ambient_size elements) */
/* y_minus_x: output tangent vector (tangent_size elements) */
/* Returns 1 on success, 0 on failure */
typedef int (*ceres_autodiff_manifold_minus_t)(
void* user_data,
const double* y,
const double* x,
double* y_minus_x);
/* Create AutoDiff manifold */
/* ambient_size: dimension of ambient space */
/* tangent_size: dimension of tangent space */
/* plus_callback: callback for Plus operation */
/* minus_callback: callback for Minus operation */
/* user_data: user data passed to callbacks */
CERES_WRAPPER_EXPORT ceres_manifold_t* ceres_wrapper_create_autodiff_manifold(
int ambient_size,
int tangent_size,
ceres_autodiff_manifold_plus_t plus_callback,
ceres_autodiff_manifold_minus_t minus_callback,
void* user_data);
/* Free AutoDiff manifold */
CERES_WRAPPER_EXPORT void ceres_wrapper_free_autodiff_manifold(ceres_manifold_t* manifold);
// ============================================================================
// BiCubic Interpolator
// ============================================================================
struct ceres_bicubic_interpolator_s;
typedef struct ceres_bicubic_interpolator_s ceres_bicubic_interpolator_t;
/* Create bicubic interpolator from 2D grid data */
/* data: row-major order, size = rows * cols */
CERES_WRAPPER_EXPORT ceres_bicubic_interpolator_t* ceres_wrapper_create_bicubic_interpolator(
const double* data,
int rows,
int cols);
/* Free interpolator */
CERES_WRAPPER_EXPORT void ceres_wrapper_free_bicubic_interpolator(
ceres_bicubic_interpolator_t* interpolator);
/* Evaluate interpolator at point (x, y) */
/* x, y: coordinates in grid space (0 <= x < cols, 0 <= y < rows) */
CERES_WRAPPER_EXPORT void ceres_wrapper_bicubic_interpolator_evaluate(
const ceres_bicubic_interpolator_t* interpolator,
double x,
double y,
double* value,
double* gradient_x,
double* gradient_y);
// ============================================================================
// AutoDiff Cost Function Wrapper
// ============================================================================
/* Callback for AutoDiff cost function evaluation */
/* This is called from C# to evaluate the cost function */
typedef int (*ceres_autodiff_cost_function_callback_t)(
void* user_data,
const double* const* parameters,
double* residuals);
/* Create AutoDiff cost function wrapper */
/* num_residuals: number of residuals */
/* num_parameter_blocks: number of parameter blocks */
/* parameter_block_sizes: array of sizes for each parameter block */
CERES_WRAPPER_EXPORT void* ceres_wrapper_create_autodiff_cost_function(
ceres_autodiff_cost_function_callback_t callback,
void* user_data,
int num_residuals,
int num_parameter_blocks,
const int* parameter_block_sizes);
/* Free AutoDiff cost function */
CERES_WRAPPER_EXPORT void ceres_wrapper_free_autodiff_cost_function(void* cost_function);
// ============================================================================
// Dynamic AutoDiff Cost Function Wrapper
// ============================================================================
/* Create Dynamic AutoDiff cost function wrapper */
/* num_residuals: number of residuals (determined at runtime) */
/* num_parameter_blocks: number of parameter blocks */
/* parameter_block_sizes: array of sizes for each parameter block */
CERES_WRAPPER_EXPORT void* ceres_wrapper_create_dynamic_autodiff_cost_function(
ceres_autodiff_cost_function_callback_t callback,
void* user_data,
int num_residuals,
int num_parameter_blocks,
const int* parameter_block_sizes);
/* Free Dynamic AutoDiff cost function */
CERES_WRAPPER_EXPORT void ceres_wrapper_free_dynamic_autodiff_cost_function(void* cost_function);
// ============================================================================
// Numeric Differentiation Cost Functions (Phase 2)
// ============================================================================
/* Numeric differentiation method types */
typedef enum {
CERES_NUMERIC_DIFF_FORWARD = 0,
CERES_NUMERIC_DIFF_CENTRAL = 1,
CERES_NUMERIC_DIFF_RIDDERS = 2
} ceres_numeric_diff_method_t;
/* Cost function callback for numeric differentiation */
/* parameters: array of parameter blocks (each block is contiguous) */
/* residuals: output array for residuals */
/* Returns 1 on success, 0 on failure */
/* Note: Renamed to avoid conflict with ceres_cost_function_t in c_api.h */
typedef int (*ceres_numeric_diff_cost_function_t)(
const double* const* parameters,
double* residuals,
void* user_data);
/* Options for numeric diff cost function */
typedef struct {
int num_residuals;
int num_parameter_blocks;
int* parameter_block_sizes; /* Array of sizes for each parameter block */
ceres_numeric_diff_cost_function_t callback;
void* user_data;
} ceres_numeric_diff_options_t;
/* Create NumericDiffCostFunction with fixed parameter block sizes */
/* method: FORWARD, CENTRAL, or RIDDERS */
CERES_WRAPPER_EXPORT void* ceres_wrapper_create_numeric_diff_cost_function(
const ceres_numeric_diff_options_t* options,
ceres_numeric_diff_method_t method);
/* Create DynamicNumericDiffCostFunction with runtime-determined parameter block sizes */
CERES_WRAPPER_EXPORT void* ceres_wrapper_create_dynamic_numeric_diff_cost_function(
const ceres_numeric_diff_options_t* options,
ceres_numeric_diff_method_t method);
/* Free numeric diff cost function */
CERES_WRAPPER_EXPORT void ceres_wrapper_free_numeric_diff_cost_function(void* cost_function);
// ============================================================================
// Product Manifold
// ============================================================================
/* Create product manifold from multiple manifolds */
/* Combines multiple manifolds into one (e.g., quaternion + translation) */
CERES_WRAPPER_EXPORT ceres_manifold_t* ceres_wrapper_create_product_manifold(
const ceres_manifold_t** manifolds,
int num_manifolds);
/* Create Euclidean manifold (standard Euclidean space, no constraints) */
CERES_WRAPPER_EXPORT ceres_manifold_t* ceres_wrapper_create_euclidean_manifold(int dimension);
/* Create Subset manifold (fix subset of parameters) */
/* constant_subset: array of indices to keep constant */
/* constant_subset_size: number of constant indices */
/* ambient_size: total size of parameter block */
CERES_WRAPPER_EXPORT ceres_manifold_t* ceres_wrapper_create_subset_manifold(
const int* constant_subset,
int constant_subset_size,
int ambient_size);
// ============================================================================
// Problem Query Methods
// ============================================================================
/* Check if parameter block exists in problem */
CERES_WRAPPER_EXPORT int ceres_wrapper_problem_has_parameter_block(
const ceres_problem_t* problem,
const double* parameters);
/* Check if parameter block is constant */
CERES_WRAPPER_EXPORT int ceres_wrapper_problem_is_parameter_block_constant(
const ceres_problem_t* problem,
const double* parameters);
/* Get parameter block size */
CERES_WRAPPER_EXPORT int ceres_wrapper_problem_get_parameter_block_size(
const ceres_problem_t* problem,
const double* parameters);
/* Get parameter block tangent size (with manifold) */
CERES_WRAPPER_EXPORT int ceres_wrapper_problem_get_parameter_block_tangent_size(
const ceres_problem_t* problem,
const double* parameters);
/* Check if parameter block has manifold */
CERES_WRAPPER_EXPORT int ceres_wrapper_problem_has_manifold(
const ceres_problem_t* problem,
const double* parameters);
/* Get manifold for parameter block (returns NULL if no manifold) */
CERES_WRAPPER_EXPORT ceres_manifold_t* ceres_wrapper_problem_get_manifold(
const ceres_problem_t* problem,
const double* parameters);
// ============================================================================
// Iteration Callback
// ============================================================================
/* Callback type for iteration monitoring */
/* Return 0 to continue, non-zero to stop optimization */
typedef int (*ceres_iteration_callback_t)(
void* user_data,
const ceres_solver_summary_t* summary);
/* Set iteration callback in solver options */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_iteration_callback(
ceres_solver_options_t* options,
ceres_iteration_callback_t callback,
void* user_data);
// ============================================================================
// Additional SolverOptions (Phase 2)
// ============================================================================
/* Line search options */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_line_search_type(
ceres_solver_options_t* options, int line_search_type);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_line_search_type(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_line_search_direction_type(
ceres_solver_options_t* options, int line_search_direction_type);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_line_search_direction_type(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_nonlinear_conjugate_gradient_type(
ceres_solver_options_t* options, int ncg_type);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_nonlinear_conjugate_gradient_type(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_max_lbfgs_rank(
ceres_solver_options_t* options, int max_lbfgs_rank);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_max_lbfgs_rank(
const ceres_solver_options_t* options);
/* Line search parameters */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_max_line_search_step_contraction(
ceres_solver_options_t* options, double max_step_contraction);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_options_get_max_line_search_step_contraction(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_min_line_search_step_contraction(
ceres_solver_options_t* options, double min_step_contraction);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_options_get_min_line_search_step_contraction(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_max_num_line_search_step_size_iterations(
ceres_solver_options_t* options, int max_iterations);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_max_num_line_search_step_size_iterations(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_max_num_line_search_direction_restarts(
ceres_solver_options_t* options, int max_restarts);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_max_num_line_search_direction_restarts(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_line_search_sufficient_function_decrease(
ceres_solver_options_t* options, double sufficient_decrease);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_options_get_line_search_sufficient_function_decrease(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_line_search_sufficient_curvature_decrease(
ceres_solver_options_t* options, double sufficient_curvature_decrease);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_options_get_line_search_sufficient_curvature_decrease(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_max_line_search_step_expansion(
ceres_solver_options_t* options, double max_step_expansion);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_options_get_max_line_search_step_expansion(
const ceres_solver_options_t* options);
/* Trust region parameters */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_max_lm_diagonal(
ceres_solver_options_t* options, double max_lm_diagonal);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_options_get_max_lm_diagonal(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_min_lm_diagonal(
ceres_solver_options_t* options, double min_lm_diagonal);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_options_get_min_lm_diagonal(
const ceres_solver_options_t* options);
/* Linear solver options */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_sparse_linear_algebra_library_type(
ceres_solver_options_t* options, int sparse_library_type);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_sparse_linear_algebra_library_type(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_dense_linear_algebra_library_type(
ceres_solver_options_t* options, int dense_library_type);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_dense_linear_algebra_library_type(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_max_linear_solver_iterations(
ceres_solver_options_t* options, int max_iterations);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_max_linear_solver_iterations(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_min_linear_solver_iterations(
ceres_solver_options_t* options, int min_iterations);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_min_linear_solver_iterations(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_linear_solver_tolerance(
ceres_solver_options_t* options, double tolerance);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_options_get_linear_solver_tolerance(
const ceres_solver_options_t* options);
/* Inner iterations */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_use_inner_iterations(
ceres_solver_options_t* options, int use_inner_iterations);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_use_inner_iterations(
const ceres_solver_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_inner_iteration_tolerance(
ceres_solver_options_t* options, double tolerance);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_options_get_inner_iteration_tolerance(
const ceres_solver_options_t* options);
/* Timing */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_max_solver_time_in_seconds(
ceres_solver_options_t* options, double max_time);
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_options_get_max_solver_time_in_seconds(
const ceres_solver_options_t* options);
/* Checkpointing */
CERES_WRAPPER_EXPORT void ceres_wrapper_solver_options_set_update_state_every_iteration(
ceres_solver_options_t* options, int update_every_iteration);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_options_get_update_state_every_iteration(
const ceres_solver_options_t* options);
// ============================================================================
// Problem Options (Phase 2)
// ============================================================================
struct ceres_problem_options_s;
typedef struct ceres_problem_options_s ceres_problem_options_t;
CERES_WRAPPER_EXPORT ceres_problem_options_t* ceres_wrapper_create_problem_options();
CERES_WRAPPER_EXPORT void ceres_wrapper_free_problem_options(ceres_problem_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_problem_options_set_cost_function_ownership(
ceres_problem_options_t* options, int ownership);
CERES_WRAPPER_EXPORT int ceres_wrapper_problem_options_get_cost_function_ownership(
const ceres_problem_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_problem_options_set_loss_function_ownership(
ceres_problem_options_t* options, int ownership);
CERES_WRAPPER_EXPORT int ceres_wrapper_problem_options_get_loss_function_ownership(
const ceres_problem_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_problem_options_set_manifold_ownership(
ceres_problem_options_t* options, int ownership);
CERES_WRAPPER_EXPORT int ceres_wrapper_problem_options_get_manifold_ownership(
const ceres_problem_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_problem_options_set_enable_fast_removal(
ceres_problem_options_t* options, int enable);
CERES_WRAPPER_EXPORT int ceres_wrapper_problem_options_get_enable_fast_removal(
const ceres_problem_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_problem_options_set_disable_all_safety_checks(
ceres_problem_options_t* options, int disable);
CERES_WRAPPER_EXPORT int ceres_wrapper_problem_options_get_disable_all_safety_checks(
const ceres_problem_options_t* options);
/* Evaluation callback for shared computation */
/* Called before evaluating cost functions to allow shared computation */
typedef void (*ceres_evaluation_callback_t)(
void* user_data,
int num_residuals,
int num_parameter_blocks,
const int* parameter_block_sizes);
CERES_WRAPPER_EXPORT void ceres_wrapper_problem_options_set_evaluation_callback(
ceres_problem_options_t* options,
ceres_evaluation_callback_t callback,
void* user_data);
/* Create problem (official C API) */
CERES_WRAPPER_EXPORT ceres_problem_t* ceres_create_problem();
CERES_WRAPPER_EXPORT void ceres_free_problem(ceres_problem_t* problem);
/* Create problem with options */
CERES_WRAPPER_EXPORT ceres_problem_t* ceres_wrapper_create_problem_with_options(
const ceres_problem_options_t* options);
// ============================================================================
// Parameter Bounds (Phase 2)
// ============================================================================
/* Set parameter lower bound */
CERES_WRAPPER_EXPORT void ceres_wrapper_problem_set_parameter_lower_bound(
ceres_problem_t* problem,
double* parameters,
int index,
double lower_bound);
/* Set parameter upper bound */
CERES_WRAPPER_EXPORT void ceres_wrapper_problem_set_parameter_upper_bound(
ceres_problem_t* problem,
double* parameters,
int index,
double upper_bound);
/* Get parameter lower bound (returns -infinity if not set) */
CERES_WRAPPER_EXPORT double ceres_wrapper_problem_get_parameter_lower_bound(
const ceres_problem_t* problem,
const double* parameters,
int index);
/* Get parameter upper bound (returns +infinity if not set) */
CERES_WRAPPER_EXPORT double ceres_wrapper_problem_get_parameter_upper_bound(
const ceres_problem_t* problem,
const double* parameters,
int index);
// ============================================================================
// Additional SolverSummary Fields (Phase 2)
// ============================================================================
// Note: get_total_time_in_seconds, get_preprocessor_time_in_seconds,
// get_minimizer_time_in_seconds, get_postprocessor_time_in_seconds,
// get_linear_solver_time_in_seconds, get_initial_cost, get_final_cost
// are already declared in the Phase 1 Solver Summary section above.
/* Get iteration statistics */
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_summary_get_num_parameter_blocks(
const ceres_solver_summary_t* summary);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_summary_get_num_parameters(
const ceres_solver_summary_t* summary);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_summary_get_num_effective_parameters(
const ceres_solver_summary_t* summary);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_summary_get_num_residual_blocks(
const ceres_solver_summary_t* summary);
CERES_WRAPPER_EXPORT int ceres_wrapper_solver_summary_get_num_residuals(
const ceres_solver_summary_t* summary);
/* Get cost reduction information */
CERES_WRAPPER_EXPORT double ceres_wrapper_solver_summary_get_cost_change(
const ceres_solver_summary_t* summary);
// ============================================================================
// Covariance Estimation (Phase 3 - HIGH Priority)
// ============================================================================
struct ceres_covariance_options_s;
typedef struct ceres_covariance_options_s ceres_covariance_options_t;
struct ceres_covariance_s;
typedef struct ceres_covariance_s ceres_covariance_t;
/* Create and destroy covariance options */
CERES_WRAPPER_EXPORT ceres_covariance_options_t* ceres_wrapper_create_covariance_options();
CERES_WRAPPER_EXPORT void ceres_wrapper_free_covariance_options(ceres_covariance_options_t* options);
/* Configure covariance options */
CERES_WRAPPER_EXPORT void ceres_wrapper_covariance_options_set_num_threads(
ceres_covariance_options_t* options, int num_threads);
CERES_WRAPPER_EXPORT int ceres_wrapper_covariance_options_get_num_threads(
const ceres_covariance_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_covariance_options_set_sparse_linear_algebra_library_type(
ceres_covariance_options_t* options, int library_type);
CERES_WRAPPER_EXPORT int ceres_wrapper_covariance_options_get_sparse_linear_algebra_library_type(
const ceres_covariance_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_covariance_options_set_algorithm_type(
ceres_covariance_options_t* options, int algorithm_type);
CERES_WRAPPER_EXPORT int ceres_wrapper_covariance_options_get_algorithm_type(
const ceres_covariance_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_covariance_options_set_min_reciprocal_condition_number(
ceres_covariance_options_t* options, double min_reciprocal_condition_number);
CERES_WRAPPER_EXPORT double ceres_wrapper_covariance_options_get_min_reciprocal_condition_number(
const ceres_covariance_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_covariance_options_set_null_space_rank(
ceres_covariance_options_t* options, int null_space_rank);
CERES_WRAPPER_EXPORT int ceres_wrapper_covariance_options_get_null_space_rank(
const ceres_covariance_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_covariance_options_set_apply_loss_function(
ceres_covariance_options_t* options, int apply_loss_function);
CERES_WRAPPER_EXPORT int ceres_wrapper_covariance_options_get_apply_loss_function(
const ceres_covariance_options_t* options);
/* Create and destroy covariance */
CERES_WRAPPER_EXPORT ceres_covariance_t* ceres_wrapper_create_covariance();
CERES_WRAPPER_EXPORT ceres_covariance_t* ceres_wrapper_create_covariance_with_options(
const ceres_covariance_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_free_covariance(ceres_covariance_t* covariance);
/* Compute covariance */
/* Returns error code (CERES_WRAPPER_SUCCESS on success) */
/* error_message: optional output buffer for error message (can be NULL) */
/* error_message_size: size of error_message buffer (ignored if error_message is NULL) */
CERES_WRAPPER_EXPORT ceres_wrapper_error_code_t ceres_wrapper_covariance_compute(
ceres_covariance_t* covariance,
const ceres_problem_t* problem,
const ceres_covariance_options_t* options,
const double** parameter_blocks,
int num_parameter_blocks,
char* error_message,
int error_message_size);
/* Get covariance blocks */
/* Returns error code (CERES_WRAPPER_SUCCESS on success) */
/* error_message: optional output buffer for error message (can be NULL) */
/* error_message_size: size of error_message buffer (ignored if error_message is NULL) */
CERES_WRAPPER_EXPORT ceres_wrapper_error_code_t ceres_wrapper_covariance_get_covariance_block(
const ceres_covariance_t* covariance,
const double* parameter_block1,
const double* parameter_block2,
double* covariance_block,
char* error_message,
int error_message_size);
/* Get covariance matrix for multiple parameter blocks */
/* Returns error code (CERES_WRAPPER_SUCCESS on success) */
/* error_message: optional output buffer for error message (can be NULL) */
/* error_message_size: size of error_message buffer (ignored if error_message is NULL) */
CERES_WRAPPER_EXPORT ceres_wrapper_error_code_t ceres_wrapper_covariance_get_covariance_matrix(
const ceres_covariance_t* covariance,
const double** parameter_blocks,
int num_parameter_blocks,
double* covariance_matrix,
char* error_message,
int error_message_size);
// ============================================================================
// Gradient Checker (Phase 3 - MEDIUM Priority)
// ============================================================================
struct ceres_gradient_checker_options_s;
typedef struct ceres_gradient_checker_options_s ceres_gradient_checker_options_t;
struct ceres_gradient_checker_s;
typedef struct ceres_gradient_checker_s ceres_gradient_checker_t;
/* Create and destroy gradient checker options */
CERES_WRAPPER_EXPORT ceres_gradient_checker_options_t* ceres_wrapper_create_gradient_checker_options();
CERES_WRAPPER_EXPORT void ceres_wrapper_free_gradient_checker_options(ceres_gradient_checker_options_t* options);
/* Configure gradient checker options */
CERES_WRAPPER_EXPORT void ceres_wrapper_gradient_checker_options_set_gradient_check_relative_precision(
ceres_gradient_checker_options_t* options, double precision);
CERES_WRAPPER_EXPORT double ceres_wrapper_gradient_checker_options_get_gradient_check_relative_precision(
const ceres_gradient_checker_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_gradient_checker_options_set_gradient_check_numeric_derivative_relative_step_size(
ceres_gradient_checker_options_t* options, double step_size);
CERES_WRAPPER_EXPORT double ceres_wrapper_gradient_checker_options_get_gradient_check_numeric_derivative_relative_step_size(
const ceres_gradient_checker_options_t* options);
/* Create and destroy gradient checker */
/* cost_function: pointer to cost function (from ceres_wrapper_create_autodiff_cost_function or similar) */
/* manifolds: array of manifolds (can be NULL if no manifolds) */
/* num_manifolds: number of manifolds (0 if manifolds is NULL) */
CERES_WRAPPER_EXPORT ceres_gradient_checker_t* ceres_wrapper_create_gradient_checker(
void* cost_function,
const ceres_manifold_t** manifolds,
int num_manifolds,
const ceres_gradient_checker_options_t* options);
CERES_WRAPPER_EXPORT void ceres_wrapper_free_gradient_checker(ceres_gradient_checker_t* checker);
/* Probe gradients at given parameters */
/* Returns error code (CERES_WRAPPER_SUCCESS if gradients match, CERES_WRAPPER_ERROR_INVALID_PARAMETER if mismatch) */
/* error_message: optional output buffer for error message (can be NULL) */
/* error_message_size: size of error_message buffer (ignored if error_message is NULL) */
CERES_WRAPPER_EXPORT ceres_wrapper_error_code_t ceres_wrapper_gradient_checker_probe(
const ceres_gradient_checker_t* checker,
const double* const* parameters,
double relative_precision,
char* error_message,
int error_message_size);
// ============================================================================
// Context (Phase 3 - MEDIUM Priority)
// ============================================================================
struct ceres_context_s;
typedef struct ceres_context_s ceres_context_t;
/* Create and destroy context for performance optimization */
/* Context allows reuse of expensive objects across multiple solves */
CERES_WRAPPER_EXPORT ceres_context_t* ceres_wrapper_create_context();
CERES_WRAPPER_EXPORT void ceres_wrapper_free_context(ceres_context_t* context);
/* Set context in problem options */
CERES_WRAPPER_EXPORT void ceres_wrapper_problem_options_set_context(
ceres_problem_options_t* options,
ceres_context_t* context);
// ============================================================================
// Cubic Interpolator (1D) (Phase 3 - MEDIUM Priority)
// ============================================================================
struct ceres_cubic_interpolator_s;
typedef struct ceres_cubic_interpolator_s ceres_cubic_interpolator_t;
/* Create 1D cubic interpolator from data array */
/* data: array of values, size = num_values */
/* num_values: number of data points */
CERES_WRAPPER_EXPORT ceres_cubic_interpolator_t* ceres_wrapper_create_cubic_interpolator(
const double* data,
int num_values);
/* Free cubic interpolator */
CERES_WRAPPER_EXPORT void ceres_wrapper_free_cubic_interpolator(
ceres_cubic_interpolator_t* interpolator);
/* Evaluate interpolator at point x */
/* x: coordinate in data space (0 <= x < num_values) */
/* value: output value at x */
/* gradient: output gradient at x (can be NULL) */
CERES_WRAPPER_EXPORT void ceres_wrapper_cubic_interpolator_evaluate(
const ceres_cubic_interpolator_t* interpolator,
double x,
double* value,
double* gradient);
#ifdef __cplusplus
}
#endif
#endif // CERES_WRAPPER_H_