Overview
The C++ core of ucminfcpp is a
header-only library that can be embedded directly into
any C++17 project without R or Rcpp. This article shows C++ developers
how to integrate and use the optimizer.
Getting the Headers
After installing the R package, the headers are available under
inst/include/ in the package source tree. You can also copy
them directly from the GitHub repository:
src/include/ucminf_core.hpp
src/include/ucminf_core_impl.hpp
Add the directory containing these headers to your compiler’s include path, e.g.:
High-Level API: ucminfcpp::minimize()
Use minimize() when the callable type is not known at
compile time (for example, when it is stored in a
std::function).
#include "ucminf_core.hpp"
#include <iostream>
int main() {
// Rosenbrock's Banana Function
auto banana = [](const std::vector<double>& x,
std::vector<double>& g,
double& f) {
double a = 1.0 - x[0];
double b = x[1] - x[0] * x[0];
f = a * a + 100.0 * b * b;
g[0] = -2.0 * a - 400.0 * x[0] * b;
g[1] = 200.0 * b;
};
ucminfcpp::Result res = ucminfcpp::minimize({-1.2, 1.0}, banana);
std::cout << "par = (" << res.par[0] << ", " << res.par[1] << ")\n";
std::cout << "f = " << res.value << "\n";
std::cout << "conv = " << res.convergence << "\n";
return 0;
}Zero-Overhead API:
ucminfcpp::minimize_direct<F>()
When the callable type is known at compile time, use
minimize_direct so that the compiler can inline the
objective and gradient into the optimizer loop.
#include "ucminf_core.hpp"
// Free function
void rosenbrock(const std::vector<double>& x,
std::vector<double>& g, double& f) {
double a = 1.0 - x[0];
double b = x[1] - x[0] * x[0];
f = a * a + 100.0 * b * b;
g[0] = -2.0 * a - 400.0 * x[0] * b;
g[1] = 200.0 * b;
}
int main() {
ucminfcpp::Result res = ucminfcpp::minimize_direct({-1.2, 1.0}, rosenbrock);
// ...
return 0;
}This also works with lambdas and stateless function objects:
Adjusting Optimizer Settings
Pass a ucminfcpp::Options struct to either API to
control convergence criteria and iteration limits:
Building with CMake
The repository ships a CMakeLists.txt that builds the
C++ tests and optional Python/Julia bindings. To build only the core
tests:
cmake -S . -B build -DBUILD_TESTS=ON -DBUILD_PYTHON=OFF -DBUILD_JULIA=OFF
cmake --build build
ctest --test-dir buildTo embed ucminfcpp in your own CMake project, add the
src/include directory as an interface include:
Example: Integrating into an Existing Optimizer
The following pattern is common in scientific computing where
ucminfcpp replaces a numerical optimization dependency:
#include "ucminf_core.hpp"
#include <vector>
#include <functional>
// Generic fitting routine
ucminfcpp::Result fit_model(
std::vector<double> theta0,
std::function<void(const std::vector<double>&,
std::vector<double>&, double&)> neg_log_lik)
{
return ucminfcpp::minimize(theta0, neg_log_lik);
}This keeps the optimizer decoupled from the specific model, making the code easy to test and extend.