first_60_minutes - morinim/ultra GitHub Wiki
First 60 Minutes with ULTRA
ULTRA is a modern C++ framework for evolutionary computation, including genetic programming, differential evolution, and symbolic regression.
A practical quickstart for newcomers: a successful first run, a tiny custom program, and a clear path for what to learn next.
Goal
In one hour you will:
- build ULTRA;
- run a built-in example;
- write and run your own minimal program;
- know where to go next depending on whether you are a user or future contributor.
0) Prerequisites (2 minutes)
You need:
- a C++23-capable compiler;
cmake;- Python 3 for some helper tools (optional).
ULTRA is primarily supported on Linux and Windows; other platforms may work but can have rough edges.
1) Get the code (3 minutes)
git clone https://github.com/morinim/ultra.git
cd ultra
2) Configure and build (8 minutes)
Configure:
cmake -B build/ src/
Build:
cmake --build build/
If this completes without errors, your toolchain is working and you are ready to run examples.
3) Run a built-in example (10 minutes)
The easiest first run is the differential evolution example based on the Rastrigin function.
Try one of the following (the path may vary depending on generator/platform):
./build/examples/rastrigin
or, if your generator places binaries at the top-level build directory:
./build/rastrigin
Expected result: optimisation logs followed by a final line reporting a minimum (near zero for a successful run) and the corresponding coordinates.
...
0.101 380: -1.98952e-13
0.101 381: -1.63425e-13
0.102 384: -1.42109e-13
0.102 385: -1.13687e-13
0.103 386: -5.68434e-14
0.104 391: -1.42109e-14
0.104 393: -7.10543e-15
0.106 398: -0
[INFO] Evolution completed at generation: 1002. Elapsed time: 0.241
Run 0 TRAINING. Fitness: -0
Minimum found: -0
Coordinates: [ -5.21528e-10 2.36987e-09 1.52008e-09 2.08037e-10 3.37312e-09 ]
4) Write your first ULTRA program (20 minutes)
Create quickstart_rosen.cc in the repository root:
#include "kernel/ultra.h"
// Rosenbrock minimisation converted to maximisation.
double rosenbrock(const ultra::de::individual &x)
{
double s = 0.0;
for (std::size_t i = 0; i + 1 < x.size(); ++i)
{
double a = x[i + 1] - x[i] * x[i];
double b = 1.0 - x[i];
s += 100.0 * a * a + b * b;
}
return -s;
}
int main()
{
ultra::de::problem prob(3, {-3.0, 3.0});
prob.params.population.individuals = 40;
prob.params.evolution.generations = 300;
ultra::de::search search(prob, rosenbrock);
auto result = search.run();
std::cout << "Best fitness: "
<< *result.best_measurements().fitness
<< " at [" << result.best_individual() << "]\n";
}
This program runs a simple optimisation using Differential Evolution. It searches for the point that minimises the Rosenbrock function (ULTRA maximises by default, so the function is negated).
Compile and run it using the library you just built:
c++ -std=c++23 -Isrc quickstart_rosen.cc build/kernel/libultra.a -lpthread -o quickstart_rosen
./quickstart_rosen
If your platform or toolchain needs extra libraries, prefer adding this file under src/examples/ and building via CMake instead.

5) Understand the core mental model (10 minutes)
ULTRA usage usually follows this sequence:
- define a problem (
problem) with domain bounds/data; - set parameters (
prob.params...) for population and evolution; - choose a search (
de::search,ga::search,src::search...); - run (
search.run()); - inspect results (
best_individual,best_measurements, stats/logs).
If you keep this flow in mind, most examples become easy to read.
6) Common first-hour pitfalls
- Build succeeds, executable path not found: check where your generator emits binaries (
build/examples/vsbuild/). - Result quality seems poor: increase generations and/or population first.
- Compiler errors about language features: verify C++23 toolchain.
- Confusion about objective direction: if you are minimizing, return the negative value (as shown above).
7) What to do next
If you are mainly a user
- Read and run more examples from
src/examples/. - Try symbolic regression and classification examples.
- Start tuning
prob.paramsand compare solution quality and speed.
If you want to contribute
- Read
CONTRIBUTING.md. - Learn the structure of
src/kernel,src/utility, andsrc/test. - Run tests and explore sanitizer presets in
src/CMakePresets.json. - Study Software Architecture Document.
8) Optional: install ULTRA
cmake --install build/
This may require elevated privileges depending on your installation prefix.
9) 60-minute checklist
- Build completed.
- At least one example executed.
- Custom minimal program compiled and ran.
- You can explain the 5-step mental model.
- You picked a next path (user vs contributor).
If all are checked, you are fully out of "blank page" mode.