/* 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 // 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_