Coverage for lapspython/stats.py: 100%
48 statements
« prev ^ index » next coverage.py v6.4.4, created at 2022-08-27 20:15 +0200
« prev ^ index » next coverage.py v6.4.4, created at 2022-08-27 20:15 +0200
1"""Collect statistics for program translations."""
3from typing import List
5import numpy as np
6import uniplot
7from scipy import stats
9from lapspython.types import CompactFrontier, CompactResult
12class Statistics:
13 """Collect statistics for translated frontiers and results."""
15 stats: dict
17 def __init__(self, result: CompactResult = None):
18 """Construct object and optionally summarized result.
20 :param result: Extracted and translated programs.
21 :type result: CompactResult, optional
22 """
23 self.stats = {}
25 if result is not None:
26 self.summarize(result)
28 def __str__(self) -> str:
29 """Convert summary to string."""
30 return '\n'.join([f'{k}:\t{v}' for k, v in self.stats.items()])
32 def summarize(self, result: CompactResult) -> dict:
33 """Compute descriptive statistics for given result.
35 :param result: Translated checkpoint.
36 :type result: lapspython.types.CompactResult
37 :returns: Descriptive statistics.
38 :rtype: dict
39 """
40 program_count = self.count_programs(result)
41 self.stats.update({'programs': program_count})
42 translation_count = self.count_translations(result)
43 self.stats.update({'translations': translation_count})
45 percentages = self.percentages_result(result)
46 n_obs, minmax, mean, var, skew, kurtosis = stats.describe(percentages)
47 self.stats.update({'tasks (total)': n_obs})
48 self.stats.update({'tasks (solved)': np.count_nonzero(percentages)})
49 self.stats.update({'median\t(%)': np.median(percentages)})
50 self.stats.update({'min\t(%)': minmax[0]})
51 self.stats.update({'max\t(%)': minmax[1]})
52 self.stats.update({'mean\t(%)': mean})
53 self.stats.update({'std\t(%)': np.sqrt(var)})
55 return self.stats
57 def plot_histogram(self, result: CompactResult) -> None:
58 """Print histogram of percentages to terminal.
60 :param result: Translated checkpoint.
61 :type result: CompactResult
62 """
63 percentages = self.percentages_result(result)
64 uniplot.histogram(percentages)
66 def count_programs(self, result: CompactResult) -> int:
67 """Count totals number of programs across all tasks.
69 :param result: Translated checkpoint.
70 :type result: lapspython.types.CompactResult
71 rtype: int
72 """
73 program_count: int = 0
74 for frontier in result.hit_frontiers.values():
75 program_count += len(frontier.programs)
76 return program_count
78 def count_translations(self, result: CompactResult) -> int:
79 """Count total number of correct translations across all tasks.
81 :param result: Translated checkpoint.
82 :type result: lapspython.types.CompactResult
83 :rtype: int
84 """
85 translation_count: int = 0
86 for frontier in result.hit_frontiers.values():
87 translation_count += len(frontier.translations)
88 return translation_count
90 def percentages_result(self, result: CompactResult) -> List[float]:
91 """Return percentage of correctly translated programs per frontier.
93 :param result: Translated checkpoint.
94 :type result: lapspython.types.CompactResult
95 :rtype: List[float]
96 """
97 percentages: list = []
98 for frontier in result.hit_frontiers.values():
99 percentages.append(self.percentage_frontier(frontier))
100 return percentages
102 def percentage_frontier(self, frontier: CompactFrontier) -> float:
103 """Return percentage of correctly translated programs.
105 :param result: Translated frontier (task).
106 :type result: lapspython.types.CompactFrontier
107 :rtype: float
108 """
109 return len(frontier.translations) / len(frontier.programs) * 100