36 if constexpr (std::is_arithmetic_v<T>) {
37 return std::abs(current - previous);
38 }
else if constexpr (std::is_same_v<T, std::vector<double>> ||
39 std::is_same_v<T, std::vector<float>> ||
40 std::is_same_v<T, std::vector<int>>) {
42 if (current.size() != previous.size()) {
43 return std::numeric_limits<double>::max();
46 for (
size_t i = 0; i < current.size(); ++i) {
47 double diff = current[i] - previous[i];
50 return std::sqrt(sum);
53 "Unsupported type for difference calculation");
59 if constexpr (std::is_arithmetic_v<T>) {
60 return std::to_string(value);
61 }
else if constexpr (std::is_same_v<T, std::string>) {
63 }
else if constexpr (std::is_same_v<T, std::vector<double>> ||
64 std::is_same_v<T, std::vector<float>> ||
65 std::is_same_v<T, std::vector<int>>) {
68 for (
size_t i = 0; i < value.size(); ++i) {
70 if (i < value.size() - 1)
82 const std::vector<std::pair<size_t, size_t>>& chunk_sizes) {
83 std::ofstream file(filename);
89 file <<
"# Chunk_Index Size\n";
92 for (
size_t i = 0; i < chunk_sizes.size(); ++i) {
93 file << i <<
" " << chunk_sizes[i].second <<
"\n";
100 std::ifstream check(filename);
101 if (!check || check.peek() == std::ifstream::traits_type::eof()) {
116 const std::string& viz_dir =
"./viz")
117 : data(reinterpret_cast<const std::vector<T>&>(input_data)), output_dir(viz_dir) {
118 std::filesystem::create_directories(output_dir);
119 static_assert(std::is_same_v<T, std::vector<U>>,
120 "Template parameter must match vector element type");
125 std::vector<std::pair<size_t, size_t>> chunk_sizes;
126 size_t current_size = 1;
134 if (data.size() == 1) {
135 chunk_sizes.push_back({0, 1});
138 for (
size_t i = 1; i < data.size(); ++i) {
139 if (calculate_difference(data[i], data[i - 1]) > threshold) {
140 chunk_sizes.push_back({i - current_size, current_size});
148 if (current_size > 0) {
149 chunk_sizes.push_back({data.size() - current_size, current_size});
154 std::string dat_file = output_dir +
"/chunk_sizes.dat";
155 write_data_file(dat_file, chunk_sizes);
158 std::string gnu_file = output_dir +
"/plot_chunks.gnu";
159 std::ofstream gnuplot(gnu_file);
164 gnuplot <<
"set title 'Chunk Size Distribution'\n"
165 <<
"set xlabel 'Chunk Index'\n"
166 <<
"set ylabel 'Size'\n"
167 <<
"set style fill solid\n"
168 <<
"plot '" << dat_file <<
"' using 1:2 with boxes title 'Chunk Sizes'\n";
175 std::filesystem::create_directories(output_dir);
178 std::string actual_filename;
179 if (filename.find(
'/') != std::string::npos) {
181 actual_filename = filename;
184 actual_filename = output_dir +
"/" + filename;
188 std::ofstream file(actual_filename);
189 if (!file.is_open()) {
195 file <<
"digraph chunks {\n";
196 for (
size_t i = 0; i < data.size(); ++i) {
197 file <<
" chunk" << i <<
" [label=\"Value: " << format_value(data[i]) <<
"\"];\n";
199 file <<
" chunk" << (i - 1) <<
" -> chunk" << i <<
";\n";
211 }
catch (
const std::exception& e) {
213 std::string(
"Error writing GraphViz file: ") + e.what());
219 if (!std::filesystem::exists(actual_filename) ||
220 std::filesystem::file_size(actual_filename) == 0) {
227 std::ofstream boundary_data(output_dir +
"/boundaries.dat");
228 if (!boundary_data) {
233 std::ofstream gnuplot_script(output_dir +
"/plot_boundaries.gnu");
234 if (!gnuplot_script) {
239 for (
size_t i = 0; i < data.size(); ++i) {
240 if constexpr (std::is_arithmetic_v<T>) {
241 boundary_data << i <<
" " << data[i] <<
" "
242 << (i > 0 && std::abs(data[i] - data[i - 1]) > 1.0 ?
"1" :
"0")
246 double value = data[i].empty() ? 0.0 : data[i][0];
247 boundary_data << i <<
" " << value <<
" "
248 << (i > 0 && std::abs(value -
249 (data[i - 1].empty() ? 0.0 : data[i - 1][0])) >
259 <<
"set terminal png\n"
260 <<
"set output '" << output_dir <<
"/boundaries.png'\n"
261 <<
"set title 'Chunk Boundaries'\n"
262 <<
"set xlabel 'Index'\n"
263 <<
"set ylabel 'Value'\n"
264 <<
"plot '" << output_dir <<
"/boundaries.dat' using 1:2 with lines title 'Data', "
265 <<
" '" << output_dir
266 <<
"/boundaries.dat' using 1:($3 * $2) with points pt 7 title 'Boundaries'\n";