SemiDiscreteOT 1.0
Semi-Discrete Optimal Transport Library
Loading...
Searching...
No Matches
ParameterManager.cc
Go to the documentation of this file.
2#include <iomanip>
3
5 : ParameterAcceptor("SotParameterManager")
6 , source_params(source_params_storage)
7 , target_params(target_params_storage)
8 , solver_params(solver_params_storage)
9 , multilevel_params(multilevel_params_storage)
10 , power_diagram_params(power_diagram_params_storage)
11 , transport_map_params(transport_map_params_storage)
12 , conditional_density_params(conditional_density_params_storage)
13 , selected_task(selected_task_storage)
14 , io_coding(io_coding_storage)
15 , mpi_communicator(comm)
16 , n_mpi_processes(Utilities::MPI::n_mpi_processes(comm))
17 , this_mpi_process(Utilities::MPI::this_mpi_process(comm))
18 , pcout(std::cout, Utilities::MPI::this_mpi_process(comm) == 0)
19{
20 add_parameter("selected_task", selected_task);
21 add_parameter("io_coding", io_coding,
22 "File format for I/O operations (txt/bin)");
23
24 enter_subsection("mesh_generation");
25 {
26 enter_subsection("source");
27 {
28 add_parameter("number of refinements", source_params.n_refinements);
29 add_parameter("grid generator function", source_params.grid_generator_function);
30 add_parameter("grid generator arguments", source_params.grid_generator_arguments);
31 add_parameter("use tetrahedral mesh", source_params.use_tetrahedral_mesh,
32 "Whether to convert the mesh to tetrahedral cells (only for 3D)");
33 add_parameter("use custom density", source_params.use_custom_density,
34 "Whether to use custom density from file");
35 add_parameter("density file path", source_params.density_file_path,
36 "Path to the density file");
37 add_parameter("density file format", source_params.density_file_format,
38 "Format of the density file (vtk/h5)");
39 add_parameter("density field name", source_params.density_field_name,
40 "Name of the field in the VTK file");
41 }
42 leave_subsection();
43
44 enter_subsection("target");
45 {
46 add_parameter("number of refinements", target_params.n_refinements);
47 add_parameter("grid generator function", target_params.grid_generator_function);
48 add_parameter("grid generator arguments", target_params.grid_generator_arguments);
49 add_parameter("use tetrahedral mesh", target_params.use_tetrahedral_mesh,
50 "Whether to convert the mesh to tetrahedral cells (only for 3D)");
51 add_parameter("use custom density", target_params.use_custom_density,
52 "Whether to use custom density from file");
53 add_parameter("density file path", target_params.density_file_path,
54 "Path to the density file");
55 add_parameter("density file format", target_params.density_file_format,
56 "Format of the density file (vtk/h5)");
57 add_parameter("density field name", target_params.density_field_name,
58 "Name of the field in the VTK file");
59 }
60 leave_subsection();
61 }
62 leave_subsection();
63
64 enter_subsection("rsot_solver");
65 {
66 add_parameter("max_iterations", solver_params.max_iterations,
67 "Maximum number of iterations for the optimization solver");
68 add_parameter("tolerance", solver_params.tolerance,
69 "Convergence tolerance for the optimization solver");
70 add_parameter("solver_control_type", solver_params.solver_control_type,
71 "Type of solver control to use (l1norm/componentwise)");
72 add_parameter("epsilon", solver_params.epsilon,
73 "Entropy regularization parameter (lambda)");
74 add_parameter("tau", solver_params.tau,
75 "Truncation error tolerance for integral radius bound");
76 add_parameter("distance_threshold_type", solver_params.distance_threshold_type,
77 "Type of distance threshold bound (pointwise/integral/geometric)");
78 add_parameter("verbose_output", solver_params.verbose_output,
79 "Enable detailed solver output");
80 add_parameter("solver_type", solver_params.solver_type,
81 "Type of optimization solver (BFGS)");
82 add_parameter("quadrature_order", solver_params.quadrature_order,
83 "Order of quadrature formula for numerical integration");
84 add_parameter("number_of_threads", solver_params.n_threads,
85 "Number of threads to use for parallel SOT");
86 add_parameter("use_epsilon_scaling", solver_params.use_epsilon_scaling,
87 "Enable epsilon scaling strategy");
88 add_parameter("epsilon_scaling_factor", solver_params.epsilon_scaling_factor,
89 "Factor by which to reduce epsilon in each scaling step");
90 add_parameter("epsilon_scaling_steps", solver_params.epsilon_scaling_steps,
91 "Number of epsilon scaling steps");
92 add_parameter("use_log_sum_exp_trick", solver_params.use_log_sum_exp_trick,
93 "Enable log-sum-exp trick for numerical stability with small entropy");
94 }
95 leave_subsection();
96
97 enter_subsection("multilevel_parameters");
98 {
99 // Source mesh hierarchy parameters
100 add_parameter("source_enabled", multilevel_params.source_enabled,
101 "Whether to use source multilevel approach");
102 add_parameter("source_min_vertices", multilevel_params.source_min_vertices,
103 "Minimum number of vertices for the coarsest source level");
104 add_parameter("source_max_vertices", multilevel_params.source_max_vertices,
105 "Maximum number of vertices for finest source level");
106 add_parameter("source_hierarchy_dir", multilevel_params.source_hierarchy_dir,
107 "Directory to store the source mesh hierarchy");
108
109 // Target point cloud hierarchy parameters
110 add_parameter("target_enabled", multilevel_params.target_enabled,
111 "Whether to use target multilevel approach");
112 add_parameter("target_min_points", multilevel_params.target_min_points,
113 "Minimum number of points for the coarsest target level");
114 add_parameter("target_max_points", multilevel_params.target_max_points,
115 "Maximum number of points for the finest target level");
116 add_parameter("target_hierarchy_dir", multilevel_params.target_hierarchy_dir,
117 "Directory to store target point cloud hierarchy");
118 add_parameter("use_softmax_potential_transfer", multilevel_params.use_softmax_potential_transfer,
119 "Whether to use softmax-based potential transfer between target levels");
120
121 // Python clustering parameters
122 add_parameter("use_python_clustering", multilevel_params.use_python_clustering,
123 "Whether to use Python scripts for clustering");
124 add_parameter("python_script_name", multilevel_params.python_script_name,
125 "Name of the Python script to use for clustering");
126
127 // Common parameters
128 add_parameter("output_prefix", multilevel_params.output_prefix,
129 "Directory prefix for multilevel SOT results");
130 }
131 leave_subsection();
132
133
134 enter_subsection("power_diagram_parameters");
135 {
136 add_parameter("implementation", power_diagram_params.implementation,
137 "Implementation to use for power diagram computation (dealii/geogram)");
138 }
139 leave_subsection();
140
141 enter_subsection("transport_map_parameters");
142 {
143 add_parameter("truncation_radius", transport_map_params.truncation_radius,
144 "Truncation radius for map approximation (-1 = disabled)");
145 }
146 leave_subsection();
147
148 enter_subsection("conditional_density_parameters");
149 {
150 add_parameter("indices", conditional_density_params.indices,
151 "Indices for conditional density computation");
152 add_parameter("potential_folder", conditional_density_params.potential_folder,
153 "Folder to load potential from (empty = default)");
154 add_parameter("truncation_radius", conditional_density_params.truncation_radius,
155 "Truncation radius for conditional density computation (-1 = disabled)");
156 }
157 leave_subsection();
158}
159
160
162{
163 std::string logo = R"(
164 ▗▄▄▖▗▄▄▄▖▗▖ ▗▖▗▄▄▄▖▗▄▄▄ ▗▄▄▄▖ ▗▄▄▖ ▗▄▄▖▗▄▄▖ ▗▄▄▄▖▗▄▄▄▖▗▄▄▄▖ ▗▄▖▗▄▄▄▖
165▐▌ ▐▌ ▐▛▚▞▜▌ █ ▐▌ █ █ ▐▌ ▐▌ ▐▌ ▐▌▐▌ █ ▐▌ ▐▌ ▐▌ █
166 ▝▀▚▖▐▛▀▀▘▐▌ ▐▌ █ ▐▌ █ █ ▝▀▚▖▐▌ ▐▛▀▚▖▐▛▀▀▘ █ ▐▛▀▀▘▐▌ ▐▌ █
167▗▄▄▞▘▐▙▄▄▖▐▌ ▐▌▗▄█▄▖▐▙▄▄▀▗▄█▄▖▗▄▄▞▘▝▚▄▄▖▐▌ ▐▌▐▙▄▄▖ █ ▐▙▄▄▖▝▚▄▞▘ █
168 )";
169
170 // Print the logo with cyan color
171 pcout << CYAN << logo << RESET << std::endl;
172
173 // Add a simple morphing visualization
174 pcout << std::endl;
175 pcout << GREEN << " ∎∎∎∎∎∎∎ " << BLUE << " ◆ " << RESET << std::endl;
176 pcout << GREEN << " ∎∎∎∎∎∎∎∎∎∎∎ " << MAGENTA << " ↗ " << BLUE << " ◆ ◆ " << RESET << std::endl;
177 pcout << GREEN << " ∎∎∎∎∎∎∎∎∎∎∎∎∎ " << MAGENTA << " ↗ " << BLUE << " ◆ ◆ " << RESET << std::endl;
178 pcout << GREEN << " ∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎ " << MAGENTA << " ↗ " << BLUE << " ◆ ◆◆ ◆ " << RESET << std::endl;
179 pcout << GREEN << " ∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎ " << MAGENTA << " → " << BLUE << " ◆ ◆ ◆ ◆ " << RESET << std::endl;
180 pcout << GREEN << " ∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎ " << MAGENTA << " ↘ " << BLUE << " ◆ ◆◆ ◆ " << RESET << std::endl;
181 pcout << GREEN << " ∎∎∎∎∎∎∎∎∎∎∎∎∎ " << MAGENTA << " ↘ " << BLUE << " ◆ ◆ " << RESET << std::endl;
182 pcout << GREEN << " ∎∎∎∎∎∎∎∎∎∎∎ " << MAGENTA << " ↘ " << BLUE << " ◆ ◆ " << RESET << std::endl;
183 pcout << GREEN << " ∎∎∎∎∎∎∎ " << BLUE << " ◆ " << RESET << std::endl;
184 pcout << std::endl;
185
186 pcout << MAGENTA << " Semidiscrete Optimal Transport " << RESET << std::endl;
187 pcout << std::endl;
188}
189
190
192{
193 print_logo();
195
196 // Print a visually appealing header for the selected task
197 pcout << YELLOW << "\nCONFIGURATION FOR: " << BOLD << selected_task << RESET << std::endl;
198 pcout << std::string(80, '-') << std::endl;
199
200 pcout << "I/O Format: " << BOLD << io_coding << RESET << "\n" << std::endl;
201
202 // Print relevant parameters based on selected task
203 if (selected_task == "generate_mesh" || selected_task == "sot" ||
204 selected_task == "load_meshes" || selected_task == "multilevel_sot" ||
205 selected_task == "exact_sot")
206 {
207 print_section_header("MESH PARAMETERS");
209 }
210
211 if (selected_task == "sot" || selected_task == "multilevel_sot" ||
212 selected_task == "exact_sot")
213 {
214 print_section_header("SOLVER PARAMETERS");
216 }
217
218 if (selected_task == "multilevel_sot" || selected_task == "prepare_source_multilevel" ||
219 selected_task == "prepare_target_multilevel")
220 {
221 print_section_header("MULTILEVEL PARAMETERS");
223 }
224
225 if (selected_task == "power_diagram")
226 {
227 print_section_header("POWER DIAGRAM PARAMETERS");
229 }
230
231 if (selected_task == "map")
232 {
233 print_section_header("TRANSPORT MAP PARAMETERS");
235 }
236
237 if (selected_task == "conditional_density")
238 {
239 print_section_header("CONDITIONAL DENSITY PARAMETERS");
241 }
242
243 pcout << std::endl;
244}
245
246void SotParameterManager::print_section_header(const std::string& section_name) const
247{
248 pcout << MAGENTA << section_name << RESET << std::endl;
249 pcout << std::string(section_name.length(), '-') << std::endl;
250}
251
253{
254 pcout << YELLOW << "\n=== AVAILABLE TASKS ===" << RESET << std::endl;
255 pcout << std::string(80, '-') << std::endl;
256
257 // Define task descriptions
258 struct TaskInfo {
259 std::string name;
260 std::string description;
261 };
262
263 std::vector<TaskInfo> tasks = {
264 {"generate_mesh", "Generate source and target meshes based on specified parameters"},
265 {"load_meshes", "Load pre-existing source and target meshes"},
266 {"sot", "Run standard semidiscrete optimal transport"},
267 {"exact_sot", "Run exact semidiscrete optimal transport (no regularization)"},
268 {"power_diagram", "Compute power diagram for given potentials"},
269 {"map", "Compute transport map between source and target"},
270 {"prepare_source_multilevel", "Prepare source mesh hierarchy for multilevel approach"},
271 {"prepare_target_multilevel", "Prepare target point cloud hierarchy for multilevel approach"},
272 {"multilevel_sot", "Run multilevel semidiscrete optimal transport"},
273 {"conditional_density", "Compute conditional densities for specified indices"}
274 };
275
276 // Print each task with proper formatting
277 for (const auto& task : tasks) {
278 // Highlight the currently selected task
279 if (task.name == selected_task) {
280 pcout << CYAN << BOLD;
281 }
282
283 // Print task name and description
284 pcout << std::setw(30) << std::left << task.name
285 << task.description << RESET << std::endl;
286 }
287
288 pcout << std::string(80, '-') << std::endl;
289 pcout << std::endl;
290}
291
293{
294 // Source mesh parameters
295 pcout << CYAN << " Source Mesh:" << RESET << std::endl;
296 pcout << " Grid Generator Function: " << BOLD << source_params.grid_generator_function << RESET << std::endl;
297 pcout << " Grid Generator Arguments: " << BOLD << source_params.grid_generator_arguments << RESET << std::endl;
298 pcout << " Number of Refinements: " << BOLD << source_params.n_refinements << RESET << std::endl;
299 pcout << " Use Tetrahedral Mesh: " << BOLD << (source_params.use_tetrahedral_mesh ? "yes" : "no") << RESET << std::endl;
300 pcout << std::endl;
301
302 // Target mesh parameters
303 pcout << CYAN << " Target Mesh:" << RESET << std::endl;
304 pcout << " Grid Generator Function: " << BOLD << target_params.grid_generator_function << RESET << std::endl;
305 pcout << " Grid Generator Arguments: " << BOLD << target_params.grid_generator_arguments << RESET << std::endl;
306 pcout << " Number of Refinements: " << BOLD << target_params.n_refinements << RESET << std::endl;
307 pcout << " Use Tetrahedral Mesh: " << BOLD << (target_params.use_tetrahedral_mesh ? "yes" : "no") << RESET << std::endl;
308 pcout << std::endl;
309}
310
312{
313 pcout << CYAN << " Solver Configuration:" << RESET << std::endl;
314 pcout << " Solver Type: " << BOLD << solver_params.solver_type << RESET << std::endl;
315 pcout << " Maximum Iterations: " << BOLD << solver_params.max_iterations << RESET << std::endl;
316 pcout << " Tolerance: " << BOLD << solver_params.tolerance << RESET << std::endl;
317 pcout << " Solver Control Type: " << BOLD << solver_params.solver_control_type << RESET << std::endl;
318
319 pcout << CYAN << " Regularization Settings:" << RESET << std::endl;
320 pcout << " Epsilon: " << BOLD << solver_params.epsilon << RESET << std::endl;
321 pcout << " Tau: " << BOLD << solver_params.tau << RESET << std::endl;
322 pcout << " Distance Threshold Type: " << BOLD << solver_params.distance_threshold_type << RESET << std::endl;
323 pcout << " Log-Sum-Exp Trick: " << BOLD << (solver_params.use_log_sum_exp_trick ? "enabled" : "disabled") << RESET << std::endl;
324
326 pcout << " Epsilon Scaling: " << BOLD << "enabled" << RESET << std::endl;
327 pcout << " Epsilon Scaling Factor: " << BOLD << solver_params.epsilon_scaling_factor << RESET << std::endl;
328 pcout << " Epsilon Scaling Steps: " << BOLD << solver_params.epsilon_scaling_steps << RESET << std::endl;
329 } else {
330 pcout << " Epsilon Scaling: " << BOLD << "disabled" << RESET << std::endl;
331 }
332 pcout << std::endl;
333
334 pcout << CYAN << " Computation Settings:" << RESET << std::endl;
335 pcout << " Quadrature Order: " << BOLD << solver_params.quadrature_order << RESET << std::endl;
336 pcout << " Number of Points: " << BOLD << solver_params.nb_points << RESET << std::endl;
337 pcout << " Number of Threads: " << BOLD << (solver_params.n_threads == 0 ? "auto" : std::to_string(solver_params.n_threads)) << RESET << std::endl;
338 pcout << std::endl;
339}
340
342{
343 // Source multilevel parameters
344 pcout << CYAN << " Source Multilevel:" << RESET << std::endl;
345 pcout << " Enabled: " << BOLD << (multilevel_params.source_enabled ? "yes" : "no") << RESET << std::endl;
347 pcout << " Minimum Vertices: " << BOLD << multilevel_params.source_min_vertices << RESET << std::endl;
348 pcout << " Maximum Vertices: " << BOLD << multilevel_params.source_max_vertices << RESET << std::endl;
349 pcout << " Hierarchy Directory: " << BOLD << multilevel_params.source_hierarchy_dir << RESET << std::endl;
350 }
351 pcout << std::endl;
352
353 // Target multilevel parameters
354 pcout << CYAN << " Target Multilevel:" << RESET << std::endl;
355 pcout << " Enabled: " << BOLD << (multilevel_params.target_enabled ? "yes" : "no") << RESET << std::endl;
357 pcout << " Minimum Points: " << BOLD << multilevel_params.target_min_points << RESET << std::endl;
358 pcout << " Maximum Points: " << BOLD << multilevel_params.target_max_points << RESET << std::endl;
359 pcout << " Hierarchy Directory: " << BOLD << multilevel_params.target_hierarchy_dir << RESET << std::endl;
360 pcout << " Softmax Potential Transfer: " << BOLD << (multilevel_params.use_softmax_potential_transfer ? "enabled" : "disabled") << RESET << std::endl;
361
362 // Python clustering parameters
363 pcout << " Python Clustering: " << BOLD << (multilevel_params.use_python_clustering ? "enabled" : "disabled") << RESET << std::endl;
365 pcout << " Python Script: " << BOLD << multilevel_params.python_script_name << RESET << std::endl;
366 }
367 }
368 pcout << std::endl;
369
370 // Common parameters
371 pcout << CYAN << " Output Settings:" << RESET << std::endl;
372 pcout << " Output Prefix: " << BOLD << multilevel_params.output_prefix << RESET << std::endl;
373 pcout << std::endl;
374}
375
376
378{
379 pcout << CYAN << " Power Diagram Computation:" << RESET << std::endl;
380 pcout << " Implementation: " << BOLD << power_diagram_params.implementation << RESET << std::endl;
381 pcout << std::endl;
382}
383
385{
386 pcout << CYAN << " Transport Map Settings:" << RESET << std::endl;
387 pcout << " Truncation Radius: " << BOLD << (transport_map_params.truncation_radius < 0 ? "disabled" :
388 std::to_string(transport_map_params.truncation_radius)) << RESET << std::endl;
389 pcout << std::endl;
390}
391
393{
394 pcout << CYAN << " Conditional Density Settings:" << RESET << std::endl;
395 pcout << " Indices: " << BOLD;
397 pcout << "none specified";
398 } else {
399 for (size_t i = 0; i < conditional_density_params.indices.size(); ++i) {
400 if (i > 0) pcout << ", ";
402 }
403 }
404 pcout << RESET << std::endl;
405 pcout << " Potential Folder: " << BOLD << (conditional_density_params.potential_folder.empty() ? "default" :
407 pcout << " Truncation Radius: " << BOLD << (conditional_density_params.truncation_radius < 0 ? "disabled" :
408 std::to_string(conditional_density_params.truncation_radius)) << RESET << std::endl;
409 pcout << std::endl;
410}
411
413 : SotParameterManager(comm)
414 , lloyd_params(lloyd_params_storage)
415{
416 enter_subsection("lloyd parameters");
417 {
418 add_parameter("max iterations", lloyd_params.max_iterations);
419 add_parameter("relative tolerance", lloyd_params.relative_tolerance);
420 }
421 leave_subsection();
422}
423
425{
426 pcout << YELLOW << "\n=== AVAILABLE TASKS ===" << RESET << std::endl;
427 pcout << std::string(80, '-') << std::endl;
428
429 // Define task descriptions
430 struct TaskInfo {
431 std::string name;
432 std::string description;
433 };
434
435 std::vector<TaskInfo> tasks = {
436 {"lloyd", "Run Lloyd algorithm with regularized SOT"},
437 };
438
439 // Print each task with proper formatting
440 for (const auto& task : tasks) {
441 // Highlight the currently selected task
442 if (task.name == selected_task) {
443 pcout << CYAN << BOLD;
444 }
445
446 // Print task name and description
447 pcout << std::setw(30) << std::left << task.name
448 << task.description << RESET << std::endl;
449 }
450
451 pcout << std::string(80, '-') << std::endl;
452 pcout << std::endl;
453}
454
456{
457 // Lloyd parameters
458 pcout << CYAN << " Lloyd:" << RESET << std::endl;
459 pcout << " Number of max iterations: " << BOLD << lloyd_params.max_iterations << RESET << std::endl;
460 pcout << " Relative tolerance: " << BOLD << lloyd_params.relative_tolerance << RESET << std::endl;
461 pcout << std::endl;
462}
463
465{
466 print_logo();
468
469 // Print a visually appealing header for the selected task
470 pcout << YELLOW << "\nCONFIGURATION FOR: " << BOLD << selected_task << RESET << std::endl;
471 pcout << std::string(80, '-') << std::endl;
472
473 pcout << "I/O Format: " << BOLD << io_coding << RESET << "\n" << std::endl;
474
475 // Print relevant parameters based on selected task
476 if (selected_task == "generate_mesh" || selected_task == "lloyd" ||
477 selected_task == "load_meshes")
478 {
479 print_section_header("MESH PARAMETERS");
481 }
482
483 if (selected_task == "lloyd")
484 {
485 print_section_header("SOLVER PARAMETERS");
488 }
489
490 if (selected_task == "power_diagram")
491 {
492 print_section_header("POWER DIAGRAM PARAMETERS");
494 }
495
496 if (selected_task == "map")
497 {
498 print_section_header("TRANSPORT MAP PARAMETERS");
500 }
501
502 pcout << std::string(80, '-') << std::endl;
503 pcout << std::endl;
504}
#define BOLD
#define MAGENTA
#define BLUE
#define RESET
#define YELLOW
#define GREEN
#define CYAN
void print_lloyd_parameters() const
virtual void print_parameters() const override
LloydParameterManager(const MPI_Comm &comm)
void print_task_information() const
LloydParameters & lloyd_params
ConditionalDensityParameters & conditional_density_params
MeshParameters & source_params
ConditionalOStream pcout
void print_section_header(const std::string &section_name) const
SolverParameters & solver_params
MultilevelParameters & multilevel_params
void print_power_diagram_parameters() const
void print_conditional_density_parameters() const
void print_mesh_parameters() const
MeshParameters & target_params
virtual void print_parameters() const
void print_transport_map_parameters() const
std::string & selected_task
SotParameterManager(const MPI_Comm &comm)
PowerDiagramParameters & power_diagram_params
void print_solver_parameters() const
void print_multilevel_parameters() const
void print_task_information() const
TransportMapParameters & transport_map_params
unsigned int max_iterations
Number of max iterations.
double relative_tolerance
Convergence tolerance.
std::vector< unsigned int > indices
Indices for conditional density computation.
double truncation_radius
Truncation radius for conditional density computation (-1 = disabled)
std::string potential_folder
Folder to load potential from (empty = default)
bool use_custom_density
Whether to use custom density.
unsigned int n_refinements
Number of global refinement steps.
std::string density_field_name
Name of the field in the VTK file.
bool use_tetrahedral_mesh
Whether to use tetrahedral elements (3D only)
std::string grid_generator_arguments
Arguments for the grid generator.
std::string density_file_path
Path to the density file.
std::string grid_generator_function
Name of the grid generator function.
std::string density_file_format
Format of the density file (vtk/h5)
std::string source_hierarchy_dir
Source hierarchy directory.
bool target_enabled
Whether to use target multilevel approach.
bool source_enabled
Whether to use source multilevel approach.
bool use_softmax_potential_transfer
Use softmax for potential transfer between target levels.
int source_max_vertices
Maximum vertices for finest source level.
int target_min_points
Minimum points for coarsest target level.
std::string target_hierarchy_dir
Target hierarchy directory.
int target_max_points
Maximum points for finest target level.
bool use_python_clustering
Whether to use Python scripts for clustering.
std::string python_script_name
Name of the Python script to use.
int source_min_vertices
Minimum vertices for coarsest source level.
std::string output_prefix
Output directory prefix.
std::string implementation
Implementation choice (dealii/geogram)
unsigned int nb_points
Number of points for discretization.
std::string distance_threshold_type
Type of distance threshold bound (pointwise|integral|geometric)
double tolerance
Convergence tolerance.
unsigned int epsilon_scaling_steps
Number of scaling steps.
std::string solver_type
Type of optimization solver.
bool use_log_sum_exp_trick
Enable log-sum-exp trick for numerical stability with small entropy.
unsigned int quadrature_order
Order of quadrature formula.
unsigned int n_threads
Number of threads (0 = auto)
std::string solver_control_type
Type of solver control to use (l1norm/componentwise)
bool verbose_output
Enable detailed solver output.
unsigned int max_iterations
Maximum number of solver iterations.
bool use_epsilon_scaling
Enable epsilon scaling strategy.
double epsilon_scaling_factor
Factor for epsilon reduction.
double tau
Integral radius bound tolerance.
double epsilon
Entropy regularization parameter.
double truncation_radius
Truncation radius for map approximation (-1 = disabled)