Zip and Skip Tries
Loading...
Searching...
No Matches
Classes | Functions | Variables
plot_synthetic Namespace Reference

Classes

class  DataType
 
class  FitLine
 

Functions

 get_dpi (bool savefig)
 
Path get_file (str method_name, DataType data_type)
 
int binary_search (list[int] x, int key)
 
FitLine|None fit_log_line (list[int] x, list[float] y, int skip_until=0, bool all_points=False, list[int] add_next=[])
 
 plot (str figure_name, bool save, str ylabel, str xlabel='Num nodes(n)', str legend_loc='best')
 
dict[tuple[int, int, int], tuple[int, int]] load_agg_data (str data_structure, DataType data_type)
 
tuple[tuple[int], tuple[float]] load_data (str data_structure, DataType data_type, tuple[int, int, int] match)
 
tuple[list[int], list[float]] moving_average (list[int] x, list[float] y, float window=1.9)
 
 add_data_point_to_plot (str method_name, DataType data_type, tuple[int, int, int] match, int skip_until=0, str fitlabel='', int max_value=-1, float markersize=POINT_SIZE, bool draw_best_fit=True, str label='')
 
 compare_construction_data (bool savefig=False)
 
 compare_search_data (bool savefig=False)
 

Variables

 DATA_DIRECTORY = Path('data-synthetic')
 
 HOSTNAME = socket.gethostname()
 
int MAX_WORD_LENGTH = 2**22
 
str CONSTRUCTION_FILENAME = 'construction-data'
 
str REMOVAL_FILENAME = 'removal-data'
 
str SEARCH_FILENAME = 'search-data'
 
int START_PARALLEL = 1
 
 FIGURE_DIRECTORY = Path('figures')
 
 parents
 
 True
 
 exist_ok
 
list OKABE_COLORS = ['#000000', '#E69F00', '#56B4E9', '#009E73', '#F0E442', '#0072B2', '#D55E00', '#CC79A7']
 
 color
 
int POINT_SIZE = 1
 
bool savefig = False
 

Detailed Description

Plotting script for synthetic benchmark data.

This script generates plots from benchmark data collected using synthetic_benchmark.cu.
It creates various plots comparing the performance of different trie implementations
on synthetic data with controlled properties, focusing on construction and search times.

The script reads CSV files from the data-synthetic directory and generates plots in the
figures directory. It supports plotting construction time and search time against
different parameters (number of keys, key length, LCP length).

The plots include trend lines with log-log regression to analyze asymptotic behavior.

Function Documentation

◆ add_data_point_to_plot()

plot_synthetic.add_data_point_to_plot ( str  method_name,
DataType  data_type,
tuple[int, int, int match,
int   skip_until = 0,
str   fitlabel = '',
int   max_value = -1,
float   markersize = POINT_SIZE,
bool   draw_best_fit = True,
str   label = '' 
)
    Add a data series to the current plot with optional trend line.

    Loads data for a specific method and parameter combination, applies smoothing, and adds it to the plot.
    Optionally fits and adds a trend line with equation and R² value in the legend.

    Args:
        method_name: Name of the method/implementation being benchmarked
        data_type: Type of benchmark data (construction, removal, or search)
        match: Tuple of (n, m, l) where -1 indicates the parameter to vary
        skip_until: Skip data points with x values less than this threshold for trend line fitting
        fitlabel: Label to use in the trend line equation (e.g., 'n', 'm', '\\ell')
        max_value: Maximum x value to include (-1 for no limit)
        markersize: Size of the markers for data points
        draw_best_fit: If True, fit and draw a trend line; if False, only plot data points
        label: Custom label for the data series (defaults to method_name if empty)

Definition at line 329 of file plot_synthetic.py.

329def add_data_point_to_plot(method_name: str, data_type: DataType, match: tuple[int, int, int], skip_until: int = 0, fitlabel: str = '', max_value: int = -1, markersize: float = POINT_SIZE, draw_best_fit: bool = True, label: str = ''):
330 """
331 Add a data series to the current plot with optional trend line.
332
333 Loads data for a specific method and parameter combination, applies smoothing, and adds it to the plot.
334 Optionally fits and adds a trend line with equation and R² value in the legend.
335
336 Args:
337 method_name: Name of the method/implementation being benchmarked
338 data_type: Type of benchmark data (construction, removal, or search)
339 match: Tuple of (n, m, l) where -1 indicates the parameter to vary
340 skip_until: Skip data points with x values less than this threshold for trend line fitting
341 fitlabel: Label to use in the trend line equation (e.g., 'n', 'm', '\\ell')
342 max_value: Maximum x value to include (-1 for no limit)
343 markersize: Size of the markers for data points
344 draw_best_fit: If True, fit and draw a trend line; if False, only plot data points
345 label: Custom label for the data series (defaults to method_name if empty)
346 """
347
348 x, y = load_data(method_name, data_type, match)
349
350 if max_value > 0:
351 x, y = zip(*[(x[i], y[i]) for i in range(len(x)) if x[i] <= max_value])
352
353 x, y = moving_average(x, y) # type: ignore
354
355 label = label if label else method_name
356
357 fit = fit_log_line(x, y, skip_until=skip_until)
358
359 if draw_best_fit and fit:
360 p = plt.loglog(x, y, base=2, marker = 'o', markersize = markersize, linestyle = 'None') # type: ignore
361 pcolor = p[0].get_color() # type: ignore
362
363 sign = '+' if fit.b >= 0 else '-'
364
365 plt.loglog(fit.x, fit.y, base=2, color=pcolor, linestyle='--', # type: ignore
366 label=f'{label}: $T({fitlabel}) = {fit.m:.1f} {fitlabel} {sign} {abs(fit.b):.1f}, R^2 = {fit.r2:.2f}$')
367 else:
368 plt.loglog(x, y, base=2, marker = 'o', markersize = markersize, linestyle = 'None', label=label) # type: ignore
369
T * alloc_to_device(size_t size)
Allocates memory on the CUDA device.

◆ binary_search()

int plot_synthetic.binary_search ( list[int x,
int  key 
)
    Perform binary search to find the insertion point for key in a sorted list.

    Used to find the index where data points should be skipped when fitting trend lines.

    Args:
        x: Sorted list of integers to search in
        key: Value to find the insertion point for

    Returns:
        Index where key should be inserted to maintain sorted order

Definition at line 102 of file plot_synthetic.py.

102def binary_search(x: list[int], key: int) -> int:
103 """
104 Perform binary search to find the insertion point for key in a sorted list.
105
106 Used to find the index where data points should be skipped when fitting trend lines.
107
108 Args:
109 x: Sorted list of integers to search in
110 key: Value to find the insertion point for
111
112 Returns:
113 Index where key should be inserted to maintain sorted order
114 """
115
116 low = 0
117 high = len(x)
118
119 while low < high:
120 mid = (high + low) // 2
121
122 if x[mid] < key:
123 low = mid + 1
124 else:
125 high = mid
126
127 return low
128

◆ compare_construction_data()

plot_synthetic.compare_construction_data ( bool   savefig = False)
    Create plots comparing construction time for different implementations.

    Generates two plots:
    1. Construction time vs. LCP length (ℓ)
    2. Construction time vs. key length (m)

    Some plots are commented out in the code but can be uncommented if needed.

    Args:
        savefig: If True, save the figures to files; if False, display them

Definition at line 370 of file plot_synthetic.py.

370def compare_construction_data(savefig: bool = False):
371 """
372 Create plots comparing construction time for different implementations.
373
374 Generates two plots:
375 1. Construction time vs. LCP length (ℓ)
376 2. Construction time vs. key length (m)
377
378 Some plots are commented out in the code but can be uncommented if needed.
379
380 Args:
381 savefig: If True, save the figures to files; if False, display them
382 """
383
384 # plt.figure(num = 0, figsize = (8, 5), dpi = get_dpi(savefig), facecolor = 'w', edgecolor = 'k') # type: ignore
385
386 # add_data_point_to_plot('ctrie++', DataType.CONSTRUCTION, (-1, 2**10, 2**10), fitlabel='n', label='\\texttt{c-trie++}', skip_until=2**8)
387 # # add_data_point_to_plot('skip-trie', DataType.CONSTRUCTION, (-1, 2**10, 2**10), fitlabel='n', label='ST', skip_until=2**8)
388 # add_data_point_to_plot('memory-intensive-zip-trie', DataType.CONSTRUCTION, (-1, 2**10, 2**10), fitlabel='n', label='MI-ZT', skip_until=2**8)
389 # add_data_point_to_plot('zip-trie', DataType.CONSTRUCTION, (-1, 2**10, 2**10), fitlabel='n', label='ZT', skip_until=2**8)
390 # # add_data_point_to_plot('parallel-skip-trie', DataType.CONSTRUCTION, (-1, 2**10, 2**10), fitlabel='n', label='PST', skip_until=2**8)
391 # add_data_point_to_plot('parallel-memory-intensive-zip-trie', DataType.CONSTRUCTION, (-1, 2**10, 2**10), fitlabel='n', label='MI-PZT', skip_until=2**8)
392 # add_data_point_to_plot('parallel-zip-trie', DataType.CONSTRUCTION, (-1, 2**10, 2**10), fitlabel='n', label='PZT', skip_until=2**8)
393
394 # plot(figure_name='construction-time-num-keys-comparison', save=savefig, ylabel='Time (ns)', xlabel='Number of Keys ($n$)')
395
396 plt.figure(num = 1, figsize = (8, 5), dpi = get_dpi(savefig), facecolor = 'w', edgecolor = 'k') # type: ignore
397
398 skip_until = 2**14
399
400 add_data_point_to_plot('ctrie++', DataType.CONSTRUCTION, (2**10, MAX_WORD_LENGTH, -1), fitlabel='\\ell', label='\\texttt{c-trie++}', skip_until=skip_until, draw_best_fit=False)
401 # add_data_point_to_plot('skip-trie', DataType.CONSTRUCTION, (2**10, MAX_WORD_LENGTH, -1), fitlabel='\\ell', label='ST', skip_until=2**14)
402 add_data_point_to_plot('memory-intensive-zip-trie', DataType.CONSTRUCTION, (2**10, MAX_WORD_LENGTH, -1), fitlabel='\\ell', label='MI-ZT', skip_until=skip_until, draw_best_fit=False)
403 add_data_point_to_plot('zip-trie', DataType.CONSTRUCTION, (2**10, MAX_WORD_LENGTH, -1), fitlabel='\\ell', label='ZT', skip_until=skip_until, draw_best_fit=False)
404 # add_data_point_to_plot('parallel-skip-trie', DataType.CONSTRUCTION, (2**10, MAX_WORD_LENGTH, -1), fitlabel='\\ell', label='PST', skip_until=2**14)
405 add_data_point_to_plot('parallel-memory-intensive-zip-trie', DataType.CONSTRUCTION, (2**10, MAX_WORD_LENGTH, -1), fitlabel='\\ell', label='MI-PZT', skip_until=skip_until, draw_best_fit=False)
406 add_data_point_to_plot('parallel-zip-trie', DataType.CONSTRUCTION, (2**10, MAX_WORD_LENGTH, -1), fitlabel='\\ell', label='PZT', skip_until=skip_until, draw_best_fit=False)
407
408 plot(figure_name='construction-time-lcp-comparison', save=savefig, ylabel='Time (ns)', xlabel='Mean LCP Length ($\\ell$)')
409
410 plt.figure(num = 2, figsize = (8, 5), dpi = get_dpi(savefig), facecolor = 'w', edgecolor = 'k') # type: ignore
411
412 add_data_point_to_plot('ctrie++', DataType.CONSTRUCTION, (2**10, -1, 2**10), fitlabel='m', label='\\texttt{c-trie++}', skip_until=2**11)
413 # add_data_point_to_plot('skip-trie', DataType.CONSTRUCTION, (2**10, -1, 2**10), fitlabel='m', label='ST', skip_until=2**11)
414 add_data_point_to_plot('memory-intensive-zip-trie', DataType.CONSTRUCTION, (2**10, -1, 2**10), fitlabel='m', label='MI-ZT', skip_until=2**11)
415 add_data_point_to_plot('zip-trie', DataType.CONSTRUCTION, (2**10, -1, 2**10), fitlabel='m', label='ZT', skip_until=2**11)
416 # add_data_point_to_plot('parallel-skip-trie', DataType.CONSTRUCTION, (2**10, -1, 2**10), fitlabel='m', label='PST', skip_until=2**11)
417 add_data_point_to_plot('parallel-memory-intensive-zip-trie', DataType.CONSTRUCTION, (2**10, -1, 2**10), fitlabel='m', label='MI-PZT', skip_until=2**11)
418 add_data_point_to_plot('parallel-zip-trie', DataType.CONSTRUCTION, (2**10, -1, 2**10), fitlabel='m', label='PZT', skip_until=2**11)
419
420 plot(figure_name='construction-time-key-length-comparison', save=savefig, ylabel='Time (ns)', xlabel='Key Length ($m$)')
421

◆ compare_search_data()

plot_synthetic.compare_search_data ( bool   savefig = False)
    Create plots comparing search time for different implementations.

    Generates two plots:
    1. Search time vs. key length (m)
    2. Search time vs. LCP length (ℓ)

    Some plots are commented out in the code but can be uncommented if needed.

    Args:
        savefig: If True, save the figures to files; if False, display them

Definition at line 422 of file plot_synthetic.py.

422def compare_search_data(savefig: bool = False):
423 """
424 Create plots comparing search time for different implementations.
425
426 Generates two plots:
427 1. Search time vs. key length (m)
428 2. Search time vs. LCP length (ℓ)
429
430 Some plots are commented out in the code but can be uncommented if needed.
431
432 Args:
433 savefig: If True, save the figures to files; if False, display them
434 """
435
436 # plt.figure(num = 100, figsize = (8, 5), dpi = get_dpi(savefig), facecolor = 'w', edgecolor = 'k') # type: ignore
437
438 # add_data_point_to_plot('ctrie++', DataType.SEARCH, (-1, 2**10, 2**10), fitlabel='n', label='\\texttt{c-trie++}', skip_until=2**13)
439 # # add_data_point_to_plot('skip-trie', DataType.SEARCH, (-1, 2**10, 2**10), fitlabel='n', label='ST', skip_until=2**13)
440 # add_data_point_to_plot('memory-intensive-zip-trie', DataType.SEARCH, (-1, 2**10, 2**10), fitlabel='n', label='MI-ZT', skip_until=2**13)
441 # add_data_point_to_plot('zip-trie', DataType.SEARCH, (-1, 2**10, 2**10), fitlabel='n', label='ZT', skip_until=2**13)
442 # # add_data_point_to_plot('parallel-skip-trie', DataType.SEARCH, (-1, 2**10, 2**10), fitlabel='n', label='PST', skip_until=2**13)
443 # add_data_point_to_plot('parallel-memory-intensive-zip-trie', DataType.SEARCH, (-1, 2**10, 2**10), fitlabel='n', label='MI-PZT', skip_until=2**13)
444 # add_data_point_to_plot('parallel-zip-trie', DataType.SEARCH, (-1, 2**10, 2**10), fitlabel='n', label='PZT', skip_until=2**13)
445
446 # plot(figure_name='search-time-num-keys-comparison', save=savefig, ylabel='Time (ns)', xlabel='Number of Keys ($n$)')
447
448 plt.figure(num = 101, figsize = (8, 5), dpi = get_dpi(savefig), facecolor = 'w', edgecolor = 'k') # type: ignore
449
450 add_data_point_to_plot('ctrie++', DataType.SEARCH, (2**10, -1, 2**10), fitlabel='m', label='\\texttt{c-trie++}', draw_best_fit=False)
451 # add_data_point_to_plot('skip-trie', DataType.SEARCH, (2**10, -1, 2**10), fitlabel='m', label='ST', draw_best_fit=False)
452 add_data_point_to_plot('memory-intensive-zip-trie', DataType.SEARCH, (2**10, -1, 2**10), fitlabel='m', label='MI-ZT', draw_best_fit=False)
453 add_data_point_to_plot('zip-trie', DataType.SEARCH, (2**10, -1, 2**10), fitlabel='m', label='ZT', draw_best_fit=False)
454 # add_data_point_to_plot('parallel-skip-trie', DataType.SEARCH, (2**10, -1, 2**10), fitlabel='m', label='PST', draw_best_fit=False)
455 add_data_point_to_plot('parallel-memory-intensive-zip-trie', DataType.SEARCH, (2**10, -1, 2**10), fitlabel='m', label='MI-PZT', draw_best_fit=False)
456 add_data_point_to_plot('parallel-zip-trie', DataType.SEARCH, (2**10, -1, 2**10), fitlabel='m', label='PZT', draw_best_fit=False)
457
458 plot(figure_name='search-time-key-length-comparison', save=savefig, ylabel='Time (ns)', xlabel='Key Length ($m$)')
459
460 plt.figure(num = 102, figsize = (8, 5), dpi = get_dpi(savefig), facecolor = 'w', edgecolor = 'k') # type: ignore
461
462 add_data_point_to_plot('ctrie++', DataType.SEARCH, (2**10, MAX_WORD_LENGTH, -1), fitlabel='\\ell', label='\\texttt{c-trie++}', skip_until=2**14, draw_best_fit=False)
463 # add_data_point_to_plot('skip-trie', DataType.SEARCH, (2**10, MAX_WORD_LENGTH, -1), fitlabel='\\ell', label='ST', skip_until=2**14)
464 add_data_point_to_plot('memory-intensive-zip-trie', DataType.SEARCH, (2**10, MAX_WORD_LENGTH, -1), fitlabel='\\ell', label='MI-ZT', skip_until=2**14, draw_best_fit=False)
465 add_data_point_to_plot('zip-trie', DataType.SEARCH, (2**10, MAX_WORD_LENGTH, -1), fitlabel='\\ell', label='ZT', skip_until=2**14, draw_best_fit=False)
466 # add_data_point_to_plot('parallel-skip-trie', DataType.SEARCH, (2**10, MAX_WORD_LENGTH, -1), fitlabel='\\ell', label='PST', skip_until=2**14)
467 add_data_point_to_plot('parallel-memory-intensive-zip-trie', DataType.SEARCH, (2**10, MAX_WORD_LENGTH, -1), fitlabel='\\ell', label='MI-PZT', skip_until=2**14, draw_best_fit=False)
468 add_data_point_to_plot('parallel-zip-trie', DataType.SEARCH, (2**10, MAX_WORD_LENGTH, -1), fitlabel='\\ell', label='PZT', skip_until=2**14, draw_best_fit=False)
469
470 plot(figure_name='search-time-lcp-comparison', save=savefig, ylabel='Time (ns)', xlabel='Mean LCP Length ($\\ell$)')
471

◆ fit_log_line()

FitLine | None plot_synthetic.fit_log_line ( list[int x,
list[float y,
int   skip_until = 0,
bool   all_points = False,
list[int]   add_next = [] 
)
    Fit a line to log-transformed data points for trend line analysis.

    Performs linear regression on log2-transformed data to analyze asymptotic behavior.
    Can skip initial data points to focus on asymptotic behavior at scale.

    Args:
        x: List of x-coordinates (typically problem sizes)
        y: List of y-coordinates (typically running times)
        skip_until: Skip data points with x values less than this threshold
        all_points: If True, include all points in the result; if False, only include endpoints
        add_next: Additional x values to extrapolate to

    Returns:
        A FitLine object containing the fitted line parameters, or None if fitting failed

Definition at line 129 of file plot_synthetic.py.

129def fit_log_line(x: list[int], y: list[float], skip_until: int = 0, all_points: bool = False, add_next: list[int] = []) -> FitLine | None:
130 """
131 Fit a line to log-transformed data points for trend line analysis.
132
133 Performs linear regression on log2-transformed data to analyze asymptotic behavior.
134 Can skip initial data points to focus on asymptotic behavior at scale.
135
136 Args:
137 x: List of x-coordinates (typically problem sizes)
138 y: List of y-coordinates (typically running times)
139 skip_until: Skip data points with x values less than this threshold
140 all_points: If True, include all points in the result; if False, only include endpoints
141 add_next: Additional x values to extrapolate to
142
143 Returns:
144 A FitLine object containing the fitted line parameters, or None if fitting failed
145 """
146
147 if skip_until > 0:
148 skip = binary_search(x, skip_until)
149 else:
150 skip = 0
151
152 if skip == len(x):
153 warnings.warn(f'The trend line starts after the max data, so it is not shown')
154 return None
155
156 logx, logy = np.log2(x[skip:]), np.log2(y[skip:])
157 m, b = np.polyfit(logx, logy, 1)
158
159 fit = np.poly1d((m, b))
160
161 for next_x in add_next:
162 next_logx = np.log2(next_x)
163 x.append(next_x)
164 logx = np.append(logx, next_logx)
165
166
167 expected_y = fit(logx)
168 average_y = np.sum(logy) / len(logy)
169 r2 = np.sum((expected_y[:len(expected_y) - len(add_next)] - average_y) ** 2) / np.sum((logy - average_y) ** 2)
170
171 return FitLine(m = m, b = b,
172 x = tuple(x[skip::] if all_points else x[skip::len(x) - skip - 1]),
173 y = tuple(2 ** (expected_y if all_points else expected_y[::len(expected_y) - 1])),
174 r2 = r2)
175

◆ get_dpi()

plot_synthetic.get_dpi ( bool  savefig)
    Set the DPI (dots per inch) for figures based on whether they will be saved or displayed.

    Args:
        savefig: If True, use higher DPI (600) for saved figures, otherwise use lower DPI (300) for display

Definition at line 46 of file plot_synthetic.py.

46def get_dpi(savefig: bool):
47 """
48 Set the DPI (dots per inch) for figures based on whether they will be saved or displayed.
49
50 Args:
51 savefig: If True, use higher DPI (600) for saved figures, otherwise use lower DPI (300) for display
52 """
53 plt.rcParams['figure.dpi'] = 600 if savefig else 300
54
55# Plot configuration

◆ get_file()

Path plot_synthetic.get_file ( str  method_name,
DataType  data_type 
)
    Get the file path for benchmark data based on method name and data type.

    Args:
        method_name: Name of the method/implementation being benchmarked
        data_type: Type of benchmark data (construction, removal, or search)

    Returns:
        Path object pointing to the CSV file containing the benchmark data

Definition at line 69 of file plot_synthetic.py.

69def get_file(method_name: str, data_type: DataType) -> Path:
70 """
71 Get the file path for benchmark data based on method name and data type.
72
73 Args:
74 method_name: Name of the method/implementation being benchmarked
75 data_type: Type of benchmark data (construction, removal, or search)
76
77 Returns:
78 Path object pointing to the CSV file containing the benchmark data
79 """
80
81 match data_type:
83 return DATA_DIRECTORY / f'{HOSTNAME}-{CONSTRUCTION_FILENAME}-{method_name}.csv'
85 return DATA_DIRECTORY / f'{HOSTNAME}-{REMOVAL_FILENAME}-{method_name}.csv'
86 case DataType.SEARCH:
87 return DATA_DIRECTORY / f'{HOSTNAME}-{SEARCH_FILENAME}-{method_name}.csv'
88

◆ load_agg_data()

dict[tuple[int, int, int], tuple[int, int]] plot_synthetic.load_agg_data ( str  data_structure,
DataType  data_type 
)
    Load and aggregate benchmark data from a CSV file.

    Reads benchmark data for a specific method and data type, aggregating duplicate entries.

    Args:
        data_structure: Name of the data structure/implementation being benchmarked
        data_type: Type of benchmark data (construction, removal, or search)

    Returns:
        Dictionary mapping (n, m, l) tuples to (total_time, repetition_count) tuples,
        where n is number of keys, m is key length, and l is LCP length

Definition at line 201 of file plot_synthetic.py.

201def load_agg_data(data_structure: str, data_type: DataType) -> dict[tuple[int, int, int], tuple[int, int]]:
202 """
203 Load and aggregate benchmark data from a CSV file.
204
205 Reads benchmark data for a specific method and data type, aggregating duplicate entries.
206
207 Args:
208 data_structure: Name of the data structure/implementation being benchmarked
209 data_type: Type of benchmark data (construction, removal, or search)
210
211 Returns:
212 Dictionary mapping (n, m, l) tuples to (total_time, repetition_count) tuples,
213 where n is number of keys, m is key length, and l is LCP length
214 """
215
216 data = defaultdict[tuple[int, int, int], tuple[int, int]](lambda: (0, 0))
217
218 with open(get_file(data_structure, data_type), newline='') as file:
219 reader = csv.reader(file)
220
221 for row in reader:
222 if data_type == DataType.REMOVAL:
223 n, m, time_ns, num_repetitions, par = map(int, row)
224 l = m
225 else:
226 n, m, l, time_ns, num_repetitions, par = map(int, row)
227
228 if not par in (0, START_PARALLEL):
229 continue
230
231 entry = data[(n, m, l)]
232 data[(n, m, l)] = (entry[0] + time_ns, entry[1] + num_repetitions)
233
234 return data
235
236@cache

◆ load_data()

tuple[tuple[int], tuple[float]] plot_synthetic.load_data ( str  data_structure,
DataType  data_type,
tuple[int, int, int match 
)
    Extract a specific data series from the benchmark data.

    Loads aggregated data and extracts a specific parameter series based on the match tuple.

    Args:
        data_structure: Name of the data structure/implementation being benchmarked
        data_type: Type of benchmark data (construction, removal, or search)
        match: Tuple of (n, m, l) where -1 indicates the parameter to vary
               For example, (-1, 1024, 1024) means vary n with m=1024 and l=1024

    Returns:
        Tuple of (x values, y values) sorted by x, where x is the selected parameter and y is elapsed time

Definition at line 237 of file plot_synthetic.py.

237def load_data(data_structure: str, data_type: DataType, match: tuple[int, int, int]) -> tuple[tuple[int], tuple[float]]:
238 """
239 Extract a specific data series from the benchmark data.
240
241 Loads aggregated data and extracts a specific parameter series based on the match tuple.
242
243 Args:
244 data_structure: Name of the data structure/implementation being benchmarked
245 data_type: Type of benchmark data (construction, removal, or search)
246 match: Tuple of (n, m, l) where -1 indicates the parameter to vary
247 For example, (-1, 1024, 1024) means vary n with m=1024 and l=1024
248
249 Returns:
250 Tuple of (x values, y values) sorted by x, where x is the selected parameter and y is elapsed time
251 """
252
253 x: list[int] = []
254 y: list[float] = []
255
256 match_n, match_m, match_l = match
257
258 for (n, m, l), (time_ns, num_repetitions) in load_agg_data(data_structure, data_type).items():
259 if match_n == -1 and match_m == m and match_l == l:
260 x.append(n)
261 y.append(time_ns / num_repetitions)
262 elif match_n == n and match_m == -1 and match_l == l:
263 x.append(m)
264 y.append(time_ns / num_repetitions)
265 elif match_n == n and match_m == m and match_l == -1:
266 x.append(l)
267 y.append(time_ns / num_repetitions)
268
269 A, B = zip(*sorted(zip(x, y)))
270 return A, B
271
272@cache

◆ moving_average()

tuple[list[int], list[float]] plot_synthetic.moving_average ( list[int x,
list[float y,
float   window = 1.9 
)
    Apply a moving average smoothing to data points.

    First consolidates duplicate x values, then applies a geometric window smoothing
    to reduce noise in the data while preserving trends.

    Args:
        x: List of x-coordinates
        y: List of y-coordinates
        window: Window size factor (points within x/window to x*window are averaged)

    Returns:
        Tuple of (smoothed x values, smoothed y values)

Definition at line 273 of file plot_synthetic.py.

273def moving_average(x: list[int], y: list[float], window: float = 1.9) -> tuple[list[int], list[float]]:
274 """
275 Apply a moving average smoothing to data points.
276
277 First consolidates duplicate x values, then applies a geometric window smoothing
278 to reduce noise in the data while preserving trends.
279
280 Args:
281 x: List of x-coordinates
282 y: List of y-coordinates
283 window: Window size factor (points within x/window to x*window are averaged)
284
285 Returns:
286 Tuple of (smoothed x values, smoothed y values)
287 """
288
289 new_x: list[int] = []
290 new_y: list[float] = []
291
292 i = 0
293 while i < len(x):
294 total_sum = y[i]
295 total_count = 1
296 while i < len(x) - 1 and x[i] == x[i + 1]:
297 total_sum += y[i + 1]
298 total_count += 1
299 i += 1
300
301 new_x.append(x[i])
302 new_y.append(total_sum / total_count)
303 i += 1
304
305 x, y = new_x, new_y
306
307 # Convert x and y to numpy arrays for efficient computation
308 x_array = np.array(x)
309 y_array = np.array(y)
310
311 # Prepare an array to store the moving averages
312 moving_averages = np.zeros_like(y_array)
313
314 # Calculate the moving average for each element in x
315 for i, x_val in enumerate(x_array):
316 # Define the range for the moving average
317 lower_bound = x_val / window
318 upper_bound = x_val * window
319
320 # Get indices of x values that fall within the defined window
321 window_indices = np.where((x_array >= lower_bound) & (x_array <= upper_bound))[0]
322
323 # Calculate the average of y values within this window
324 moving_averages[i] = np.mean(y_array[window_indices])
325
326 # Return the original x values and the calculated moving averages
327 return x, moving_averages.tolist()
328

◆ plot()

plot_synthetic.plot ( str  figure_name,
bool  save,
str  ylabel,
str   xlabel = 'Num nodes (n)',
str   legend_loc = 'best' 
)
    Finalize and display or save a plot.

    Adds labels, legend, and either displays the plot or saves it to a file.

    Args:
        figure_name: Base name for the saved figure file (without extension)
        save: If True, save the figure to a file; if False, display it
        ylabel: Label for the y-axis
        xlabel: Label for the x-axis (defaults to 'Num nodes (n)')
        legend_loc: Position for the legend (defaults to 'best')

Definition at line 176 of file plot_synthetic.py.

176def plot(figure_name: str, save: bool, ylabel: str, xlabel: str = 'Num nodes (n)', legend_loc: str = 'best'):
177 """
178 Finalize and display or save a plot.
179
180 Adds labels, legend, and either displays the plot or saves it to a file.
181
182 Args:
183 figure_name: Base name for the saved figure file (without extension)
184 save: If True, save the figure to a file; if False, display it
185 ylabel: Label for the y-axis
186 xlabel: Label for the x-axis (defaults to 'Num nodes (n)')
187 legend_loc: Position for the legend (defaults to 'best')
188 """
189
190 plt.xlabel(xlabel) # type: ignore
191 plt.ylabel(ylabel) # type: ignore
192
193 plt.legend(loc = legend_loc) # type: ignore
194 if save:
195 path = (FIGURE_DIRECTORY / figure_name).with_suffix('.png')
196 plt.savefig(path) # type: ignore
197 else:
198 plt.show() # type: ignore
199
200@cache

Variable Documentation

◆ color

plot_synthetic.color

Definition at line 43 of file plot_synthetic.py.

◆ CONSTRUCTION_FILENAME

str plot_synthetic.CONSTRUCTION_FILENAME = 'construction-data'

Definition at line 34 of file plot_synthetic.py.

◆ DATA_DIRECTORY

plot_synthetic.DATA_DIRECTORY = Path('data-synthetic')

Definition at line 31 of file plot_synthetic.py.

◆ exist_ok

plot_synthetic.exist_ok

Definition at line 40 of file plot_synthetic.py.

◆ FIGURE_DIRECTORY

plot_synthetic.FIGURE_DIRECTORY = Path('figures')

Definition at line 39 of file plot_synthetic.py.

◆ HOSTNAME

plot_synthetic.HOSTNAME = socket.gethostname()

Definition at line 32 of file plot_synthetic.py.

◆ MAX_WORD_LENGTH

int plot_synthetic.MAX_WORD_LENGTH = 2**22

Definition at line 33 of file plot_synthetic.py.

◆ OKABE_COLORS

list plot_synthetic.OKABE_COLORS = ['#000000', '#E69F00', '#56B4E9', '#009E73', '#F0E442', '#0072B2', '#D55E00', '#CC79A7']

Definition at line 42 of file plot_synthetic.py.

◆ parents

plot_synthetic.parents

Definition at line 40 of file plot_synthetic.py.

◆ POINT_SIZE

int plot_synthetic.POINT_SIZE = 1

Definition at line 56 of file plot_synthetic.py.

◆ REMOVAL_FILENAME

str plot_synthetic.REMOVAL_FILENAME = 'removal-data'

Definition at line 35 of file plot_synthetic.py.

◆ savefig

bool plot_synthetic.savefig = False

Definition at line 473 of file plot_synthetic.py.

◆ SEARCH_FILENAME

str plot_synthetic.SEARCH_FILENAME = 'search-data'

Definition at line 36 of file plot_synthetic.py.

◆ START_PARALLEL

int plot_synthetic.START_PARALLEL = 1

Definition at line 37 of file plot_synthetic.py.

◆ True

plot_synthetic.True

Definition at line 40 of file plot_synthetic.py.