5#ifndef MONTECARLO_1_PLOTTER_HPP
6#define MONTECARLO_1_PLOTTER_HPP
15#include "../domains/integration_domain.hpp"
23 std::system(
"pkill -f gnuplot > /dev/null 2>&1");
27 std::string target =
"_samples";
28 size_t pos = name.find(target);
29 if (pos != std::string::npos) name.erase(pos, target.length());
30 for (
auto &c : name)
if (c ==
'_') c =
' ';
41 size_t currentSamples) {
46 std::string baseName = tempRawDataFile;
47 size_t lastDot = baseName.find_last_of(
".");
48 if (lastDot != std::string::npos) baseName = baseName.substr(0, lastDot);
49 size_t lastSlash = baseName.find_last_of(
"/\\");
50 if (lastSlash != std::string::npos) baseName = baseName.substr(lastSlash + 1);
52 std::string uniqueID = baseName +
"_geom_" + std::to_string(currentSamples);
53 std::string uniqueDataFile = uniqueID +
".dat";
54 std::string scriptName =
"plot_" + uniqueID +
".gp";
57 std::ifstream inFile(tempRawDataFile);
58 if (!inFile.is_open())
return;
60 std::vector<mc::geom::Point<dim>> points;
62 while (std::getline(inFile, line)) {
63 if (line.empty())
continue;
64 std::stringstream ss(line);
66 for (
size_t i = 0; i < dim; ++i) ss >> p[i];
71 std::ofstream outFile(uniqueDataFile);
72 for (
const auto& p : points) {
73 for (
size_t i = 0; i <
dim; ++i) outFile << p[i] <<
" ";
75 outFile << (isInside ? 1 : 0) <<
"\n";
80 std::ofstream gp(scriptName);
81 if (!gp.is_open())
return;
84 gp <<
"set title 'Domain Geometry (" <<
dim <<
"D) - N=" << currentSamples <<
"'\n";
85 gp <<
"set key outside\n";
90 auto setRange = [&](
int axisIdx, std::string axisName) {
92 double min = bounds[axisIdx].first;
93 double max = bounds[axisIdx].second;
94 double span = max - min;
95 gp <<
"set " << axisName <<
"range [" << (min - span * margin) <<
":" << (max + span * margin) <<
"]\n";
99 if (
dim >= 2) setRange(1,
"y");
100 if (
dim >= 3) setRange(2,
"z");
102 int statusCol =
dim + 1;
105 gp <<
"set xlabel 'X'\n unset ytics\n set yrange [-1:1]\n";
106 gp <<
"plot '" << uniqueDataFile <<
"' u 1:($" << statusCol <<
"==0?0:1/0) w p pt 7 ps 0.4 lc rgb 'blue' t 'Out', \\\n";
107 gp <<
" '" << uniqueDataFile <<
"' u 1:($" << statusCol <<
"==1?0:1/0) w p pt 7 ps 0.4 lc rgb 'red' t 'In'\n";
110 gp <<
"set size square\n set xlabel 'X'\n set ylabel 'Y'\n";
111 gp <<
"plot '" << uniqueDataFile <<
"' u 1:($" << statusCol <<
"==0?$2:1/0) w p pt 7 ps 0.4 lc rgb 'blue' t 'Out', \\\n";
112 gp <<
" '" << uniqueDataFile <<
"' u 1:($" << statusCol <<
"==1?$2:1/0) w p pt 7 ps 0.4 lc rgb 'red' t 'In'\n";
115 gp <<
"set view equal xyz\n set xlabel 'X'\n set ylabel 'Y'\n set zlabel 'Z'\n set view 60, 30\n";
116 gp <<
"splot '" << uniqueDataFile <<
"' u 1:2:($" << statusCol <<
"==0?$3:1/0) w p pt 7 ps 0.4 lc rgb 'blue' t 'Out', \\\n";
117 gp <<
" '" << uniqueDataFile <<
"' u 1:2:($" << statusCol <<
"==1?$3:1/0) w p pt 7 ps 0.4 lc rgb 'red' t 'In'\n";
120 gp <<
"pause mouse close\n";
124 std::string command =
"gnuplot " + scriptName +
" > /dev/null 2>&1 &";
125 std::system(command.c_str());
133template <
size_t dim,
typename Func>
137 size_t currentSamples) {
140 std::string baseName = tempRawDataFile;
141 size_t lastDot = baseName.find_last_of(
".");
142 if (lastDot != std::string::npos) baseName = baseName.substr(0, lastDot);
143 size_t lastSlash = baseName.find_last_of(
"/\\");
144 if (lastSlash != std::string::npos) baseName = baseName.substr(lastSlash + 1);
147 std::string uniqueID = baseName +
"_func_" + std::to_string(currentSamples);
148 std::string uniqueDataFile = uniqueID +
".dat";
149 std::string scriptName =
"plot_" + uniqueID +
".gp";
152 std::ifstream inFile(tempRawDataFile);
153 if (!inFile.is_open())
return;
155 std::ofstream outFile(uniqueDataFile);
158 while (std::getline(inFile, line)) {
159 if (line.empty())
continue;
160 std::stringstream ss(line);
162 for (
size_t i = 0; i < dim; ++i) ss >> p[i];
165 double val = func(p);
166 for(size_t i=0; i<dim; ++i) outFile << p[i] <<
" ";
167 outFile << val <<
"\n";
174 std::ofstream gp(scriptName);
175 if (!gp.is_open())
return;
178 gp <<
"set title 'Function Value (" <<
dim <<
"D) - N=" << currentSamples <<
"'\n";
183 gp <<
"set palette rgbformulae 33,13,10\n";
184 gp <<
"set colorbox\n";
187 gp <<
"unset colorbox\n";
190 int valCol =
dim + 1;
193 gp <<
"set xlabel 'X'\n set ylabel 'f(X)'\n";
195 gp <<
"plot '" << uniqueDataFile <<
"' u 1:" << valCol <<
" w p pt 7 ps 0.4 lc rgb 'green' t 'f(x)'\n";
198 gp <<
"set size square\n set view 60, 30\n";
199 gp <<
"set xlabel 'X'\n set ylabel 'Y'\n set zlabel 'f(X,Y)'\n";
201 gp <<
"splot '" << uniqueDataFile <<
"' u 1:2:" << valCol <<
" w p pt 7 ps 0.4 lc rgb 'green' t 'f(x,y)'\n";
204 gp <<
"set view equal xyz\n set view 60, 30\n";
205 gp <<
"set xlabel 'X'\n set ylabel 'Y'\n set zlabel 'Z'\n";
207 gp <<
"splot '" << uniqueDataFile <<
"' u 1:2:3:" << valCol <<
" w p pt 7 ps 0.4 lc palette t 'f(x,y,z)'\n";
210 gp <<
"pause mouse close\n";
213 std::string command =
"gnuplot " + scriptName +
" > /dev/null 2>&1 &";
214 std::system(command.c_str());
222template <
typename Func>
224 double x_min,
double x_max,
double y_min,
double y_max,
225 int resolution = 100) {
227 std::string dir =
"./pso_frames";
228 if (filename.find(
"ga_") != std::string::npos) {
234 std::filesystem::create_directories(dir);
235 }
catch (
const std::exception&) {}
237 std::string fullpath = dir +
"/" + filename;
238 std::ofstream out(fullpath);
239 if (!out.is_open())
return;
241 double dx = (x_max - x_min) / resolution;
242 double dy = (y_max - y_min) / resolution;
244 for (
int i = 0; i <= resolution; ++i) {
245 double x = x_min + i * dx;
246 for (
int j = 0; j <= resolution; ++j) {
247 double y = y_min + j * dy;
248 std::vector<double> p = {x, y};
249 double val = func(p);
251 out << x <<
" " << y <<
" " << val <<
"\n";
262template <
typename ParticleT>
263inline void saveSwarmFrame(
const std::string& basename,
size_t iteration,
const std::vector<ParticleT>& swarm) {
265 std::string dir =
"./pso_frames";
266 if (basename.find(
"ga_") != std::string::npos) {
272 std::filesystem::create_directories(dir);
273 }
catch (
const std::exception&) {}
275 std::string filename = dir +
"/" + basename +
"_iter_" + std::to_string(iteration) +
".dat";
276 std::ofstream out(filename);
277 if (!out.is_open())
return;
279 for (
const auto& p : swarm) {
280 if (p.position.size() >= 3) {
282 out << p.position[0] <<
" " << p.position[1] <<
" " << p.position[2] <<
"\n";
283 }
else if (p.position.size() == 2) {
285 out << p.position[0] <<
" " << p.position[1] <<
" 0.0\n";
296 const std::string& gridFile,
297 const std::string& swarmBasename,
299 const std::string& title) {
301 std::string dir =
"./pso_frames";
302 if (swarmBasename.find(
"ga_") != std::string::npos) {
306 std::ofstream gp(scriptName);
307 if (!gp.is_open())
return;
309 gp <<
"set title '" << title <<
"'\n";
310 gp <<
"set view map\n";
311 gp <<
"set dgrid3d\n";
312 gp <<
"set pm3d interpolate 0,0\n";
313 gp <<
"set palette rgbformulae 33,13,10\n";
315 gp <<
"set size square\n";
318 gp <<
"do for [i=0:" << (max_iter-1) <<
"] {\n";
319 gp <<
" set title sprintf('" << title <<
" - Iter: %d', i)\n";
320 gp <<
" plot '" << dir <<
"/" << gridFile <<
"' with image, \\\n";
321 gp <<
" sprintf('" << dir <<
"/" << swarmBasename <<
"_iter_%d.dat', i) u 1:2 with points pt 7 ps 1.5 lc rgb 'white'\n";
322 gp <<
" pause 0.1\n";
324 gp <<
"pause mouse close\n";
328 std::string command =
"gnuplot " + scriptName +
" > /dev/null 2>&1 &";
329 std::system(command.c_str());
337template <
typename Func>
339 double min,
double max,
int resolution = 50) {
341 std::string dir =
"./pso_frames";
342 if (filename.find(
"ga_") != std::string::npos) {
348 std::filesystem::create_directories(dir);
349 }
catch (
const std::exception&) {}
351 std::string fullpath = dir +
"/" + filename;
352 std::ofstream out(fullpath);
353 if (!out.is_open())
return;
355 double step = (max - min) / resolution;
358 for (
int i = 0; i <= resolution; ++i) {
359 double x = min + i * step;
360 for (
int j = 0; j <= resolution; ++j) {
361 double y = min + j * step;
363 double val = func({x, y, z});
364 out << x <<
" " << y <<
" " << z <<
" " << val <<
"\n";
372 for (
int i = 0; i <= resolution; ++i) {
373 double x = min + i * step;
374 for (
int k = 0; k <= resolution; ++k) {
375 double z = min + k * step;
377 double val = func({x, y, z});
378 out << x <<
" " << y <<
" " << z <<
" " << val <<
"\n";
385 for (
int j = 0; j <= resolution; ++j) {
386 double y = min + j * step;
387 for (
int k = 0; k <= resolution; ++k) {
388 double z = min + k * step;
390 double val = func({x, y, z});
391 out << x <<
" " << y <<
" " << z <<
" " << val <<
"\n";
404 const std::string& slicesFile,
405 const std::string& swarmBasename,
407 const std::string& title,
408 double min_bound,
double max_bound) {
410 std::string dir =
"pso_frames";
411 if (swarmBasename.find(
"ga_") != std::string::npos) {
417 std::filesystem::create_directories(dir);
418 }
catch (
const std::exception& e) {
419 std::cerr <<
"Error creating directory " << dir <<
": " << e.what() << std::endl;
423 std::string fullSlicesFile = dir +
"/" + slicesFile;
424 std::string fullSwarmBasename = dir +
"/" + swarmBasename;
426 std::ofstream gp(scriptName);
427 if (!gp.is_open())
return;
429 gp <<
"set title '" << title <<
"'\n";
432 gp <<
"set view 60, 120\n";
440 gp <<
"set pm3d explicit\n";
441 gp <<
"set palette rgbformulae 33,13,10\n";
442 gp <<
"unset colorbox\n";
445 gp <<
"set xrange [" << min_bound <<
":" << max_bound <<
"]\n";
446 gp <<
"set yrange [" << min_bound <<
":" << max_bound <<
"]\n";
447 gp <<
"set zrange [" << min_bound <<
":" << max_bound <<
"]\n";
450 gp <<
"do for [i=0:" << (max_iter-1) <<
"] {\n";
451 gp <<
" set title sprintf('" << title <<
" - Iter: %d', i)\n";
454 gp <<
" splot '" << fullSlicesFile <<
"' u 1:2:3:4 with pm3d nocontour title '', \\\n";
455 gp <<
" sprintf('" << fullSwarmBasename <<
"_iter_%d.dat', i) u 1:2:3 with points pt 7 ps 1.5 lc rgb 'white' title 'Particles'\n";
457 gp <<
" pause 0.1\n";
459 gp <<
"pause mouse close\n";
463 std::cout <<
"Executing Gnuplot 3D script: " << scriptName << std::endl;
464 std::string command =
"gnuplot -p " + scriptName;
465 int ret = std::system(command.c_str());
467 std::cerr <<
"GNUPLOT ERROR (Code " << ret <<
"): Ensure gnuplot is installed." << std::endl;
477 const std::string& geometryFile,
478 const std::string& title =
"Drone Arm Domain Geometry") {
479 std::ofstream gp(scriptName);
481 std::cerr <<
"Could not create gnuplot script: " << scriptName << std::endl;
485 gp <<
"#!/usr/bin/gnuplot\n";
486 gp <<
"# Visualization script for drone arm domain geometry\n";
487 gp <<
"# Auto-generated by drone_optimization\n\n";
489 gp <<
"set title '" << title <<
"'\n";
490 gp <<
"set xlabel 'X'\n";
491 gp <<
"set ylabel 'Y'\n";
492 gp <<
"set zlabel 'Z'\n";
494 gp <<
"# Equal aspect ratio to prevent distortion\n";
495 gp <<
"set view equal xyz\n";
496 gp <<
"set view 60, 30\n";
497 gp <<
"set grid\n\n";
499 gp <<
"# Data file location\n";
500 gp <<
"datafile = '" << geometryFile <<
"'\n\n";
502 gp <<
"# Plot arm (blue) and motor (red) with smaller points for volume effect\n";
504 gp <<
"splot datafile u (stringcolumn(1) eq \"arm\" ? $2 : 1/0):3:4 with points pt 7 ps 0.5 lc rgb '#3366cc' title 'Arm', \\\n";
505 gp <<
" datafile u (stringcolumn(1) eq \"motor\" ? $2 : 1/0):3:4 with points pt 7 ps 0.5 lc rgb '#dc3912' title 'Motor'\n\n";
507 gp <<
"pause mouse close\n";
510 std::cout <<
"Gnuplot visualization script created: " << scriptName << std::endl;
511 std::cout <<
"To visualize: gnuplot -persist " << scriptName << std::endl;
Abstract base class for N-dimensional integration domains.
virtual bool isInside(const mc::geom::Point< dim > &point) const =0
Test whether a point lies inside the domain.
virtual mc::geom::Bounds< dim > getBounds() const =0
Get the axis-aligned bounding box of the domain.
N-dimensional point representation.
constexpr int dim
Default dimensionality for integration.
void createFunctionGnuplotScript(const std::string &tempRawDataFile, const mc::domains::IntegrationDomain< dim > &domain, const Func &func, size_t currentSamples)
void createPSOAnimationScript3D(const std::string &scriptName, const std::string &slicesFile, const std::string &swarmBasename, size_t max_iter, const std::string &title, double min_bound, double max_bound)
void saveFunctionGrid(const std::string &filename, const Func &func, double x_min, double x_max, double y_min, double y_max, int resolution=100)
void createPSOAnimationScript(const std::string &scriptName, const std::string &gridFile, const std::string &swarmBasename, size_t max_iter, const std::string &title)
void createDroneVisualizationScript(const std::string &scriptName, const std::string &geometryFile, const std::string &title="Drone Arm Domain Geometry")
void saveSwarmFrame(const std::string &basename, size_t iteration, const std::vector< ParticleT > &swarm)
void createGnuplotScript(const std::string &tempRawDataFile, const mc::domains::IntegrationDomain< dim > &domain, size_t currentSamples)
void saveFunctionSlices3D(const std::string &filename, const Func &func, double min, double max, int resolution=50)
std::string formatTitle(std::string name)
void closeGnuplotWindows()
Utility to close all currently open Gnuplot windows.