def test_magnitude_pruning(): # Create a 4-D tensor of 1s a = torch.ones(3, 64, 32, 32) # Change one element a[1, 4, 17, 31] = 0.2 # Create a masks dictionary and populate it with one ParameterMasker zeros_mask_dict = {} masker = distiller.ParameterMasker('a') zeros_mask_dict['a'] = masker # Try to use a MagnitudeParameterPruner with defining a default threshold with pytest.raises(AssertionError): pruner = distiller.pruning.MagnitudeParameterPruner("test", None) # Now define the default threshold thresholds = {"*": 0.4} pruner = distiller.pruning.MagnitudeParameterPruner("test", thresholds) assert distiller.sparsity(a) == 0 # Create a mask for parameter 'a' pruner.set_param_mask(a, 'a', zeros_mask_dict, None) assert common.almost_equal(distiller.sparsity(zeros_mask_dict['a'].mask), 1/distiller.volume(a)) # Let's now use the masker to prune a parameter masker = zeros_mask_dict['a'] masker.apply_mask(a) assert common.almost_equal(distiller.sparsity(a), 1/distiller.volume(a)) # We can use the masker on other tensors, if we want (and if they have the correct shape). # Remember that the mask was created already, so we're not thresholding - we are pruning b = torch.ones(3, 64, 32, 32) b[:] = 0.3 masker.apply_mask(b) assert common.almost_equal(distiller.sparsity(b), 1/distiller.volume(a))
def test_level_mask(): # Create a 4-D tensor of 1s a = torch.rand(3, 64, 32, 32) # Create and apply a mask mask = distiller.create_mask_level_criterion(a, desired_sparsity=0.3) assert common.almost_equal(distiller.sparsity(mask), 0.3, max_diff=0.0001)
def intersection(p1, p2, p3, p4): d = cm.area_rectangle(p2, p1, p4, p3) a = cm.area_rectangle(p4, p3, p1, p3) b = cm.area_rectangle(p2, p1, p1, p3) if cm.almost_equal(d, 0): # Lines coincide if cm.almost_equal(cm.almost_equal(a, b), 0): return None, "coincident" # Lines are parallel return None, "parallel" ua = a / d ub = b / d # Lines do not touch if not 0 <= ua <= 1 or not 0 <= ub <= 1: return None, "none" # Calculate touching point x = p1[0] + ua * (p2[0] - p1[0]) y = p1[1] + ua * (p2[1] - p1[1]) xy = np.array([x, y]) if cm.almost_equal(ua, 0) or cm.almost_equal(ua, 1) or cm.almost_equal(ub, 0) or cm.almost_equal(ub, 1): return xy, "touch" else: return xy, "intersection"
def test_sparsity(): zeros = torch.zeros(2, 3, 5, 6) print(distiller.sparsity(zeros)) assert distiller.sparsity(zeros) == 1.0 assert distiller.sparsity_3D(zeros) == 1.0 assert distiller.density_3D(zeros) == 0.0 ones = torch.ones(12, 43, 4, 6) assert distiller.sparsity(ones) == 0.0 x = torch.tensor([[1., 2., 0, 4., 0], [1., 2., 0, 4., 0]]) assert distiller.density(x) == 0.6 assert distiller.density_cols(x, transposed=False) == 0.6 assert distiller.sparsity_rows(x, transposed=False) == 0 x = torch.tensor([[0., 0., 0], [1., 4., 0], [1., 2., 0], [0., 0., 0]]) assert distiller.density(x) == 4 / 12 assert distiller.sparsity_rows(x, transposed=False) == 0.5 assert common.almost_equal(distiller.sparsity_cols(x, transposed=False), 1 / 3) assert common.almost_equal(distiller.sparsity_rows(x), 1 / 3)
def test_threshold_mask(): # Create a 4-D tensor of 1s a = torch.ones(3, 64, 32, 32) # Change one element a[1, 4, 17, 31] = 0.2 # Create and apply a mask mask = distiller.threshold_mask(a, threshold=0.3) assert np.sum(distiller.to_np(mask)) == (distiller.volume(a) - 1) assert mask[1, 4, 17, 31] == 0 assert common.almost_equal(distiller.sparsity(mask), 1/distiller.volume(a))
def test_sensitivity_mask(): # Create a 4-D tensor of normally-distributed coefficients a = torch.randn(3, 64, 32, 32) # Create and apply a mask mask = distiller.create_mask_sensitivity_criterion(a, sensitivity=1) # The width of 1-std on ~N(0,1) is about 68.27%. In other words: # Pr(mean - std <= X <= mean + std) is about 68.27% assert common.almost_equal(distiller.sparsity(mask), 0.6827, max_diff=0.005)
def quickhull_sub(s, e1, e2, main=None): # Find biggest triangle area for s max_area, max_p, max_i = -np.inf, None, -1 for i, p in enumerate(s): area = cm.area_triangle(e1, p, e2) if cm.almost_equal(area, max_area): # Take biggest angle if same area a = p - e1 # Vector from e1 to point b = e2 - p # Vector from e2 to point angle1 = np.arctan2(b[1], b[0]) - np.arctan2(a[1], a[0]) a = max_p - e1 # Vector from e1 to point b = e2 - max_p # Vector from e2 to point angle2 = np.arctan2(b[1], b[0]) - np.arctan2(a[1], a[0]) if angle1 > angle2: max_area, max_p, max_i = area, p, i elif area > max_area: max_area, max_p, max_i = area, p, i # if main is not None: # main.plot_point(max_p, text="M", color="blue") # Debug # main.plot_connection(e1, max_p, color="blue", temp=True) # Debug # main.plot_connection(e2, max_p, color="blue", temp=True) # Debug ch_points = np.array([max_p]) # Split into 2 areas outside of triangle (ignoring points inside triangle) s1 = [] s2 = [] for p in s[:max_i] + s[(max_i + 1):]: u1 = cm.area_triangle(e1, p, max_p) u2 = cm.area_triangle(max_p, p, e2) if u1 > 0 and u2 < 0: # Right of one line s1.append(p) # if main is not None: # main.plot_point(p, text="1", color="blue") # Debug elif u2 > 0 and u1 < 0: # Right of the other line s2.append(p) # if main is not None: # main.plot_point(p, text="2", color="blue") # Debug if s1: sub_ch_points1 = quickhull_sub(s1, e1, max_p) if sub_ch_points1.any(): ch_points = np.vstack((ch_points, sub_ch_points1)) if s2: sub_ch_points2 = quickhull_sub(s2, max_p, e2) if sub_ch_points2.any(): ch_points = np.vstack((ch_points, sub_ch_points2)) return ch_points
@dataclass class Point: x: float y: float def euclidean_distance(a: Point, b: Point) -> float: return distance.euclidean((a.x, a.y), (b.x, b.y)) class UnitCircle: center: ClassVar[Point] = Point(0.5, 0.5) radius: ClassVar[float] = 0.5 def contains(self, point: Point) -> bool: return euclidean_distance(point, self.center) < self.radius def simulate(n_iter: int) -> float: unit_circle = UnitCircle() random_points: Generator[Point] = (Point(x=random.random(), y=random.random()) for _ in range(n_iter)) num_points_within_circle: int = sum( [1 if unit_circle.contains(point) else 0 for point in random_points] ) return (float(num_points_within_circle) / n_iter) * 4 assert almost_equal(simulate(100000), math.pi)
from functools import lru_cache from common import almost_equal def even_heads(tosses: int, p: float) -> float: @lru_cache(maxsize=128) def _even_heads(n: int, even: bool) -> float: if n == 0: return 1 if even else 0 else: return p * _even_heads(n - 1, not even) + (1 - p) * _even_heads( n - 1, even) return _even_heads(tosses, even=True) assert even_heads(10, p=0.5) == 0.5 assert almost_equal(even_heads(10, p=0.6), 0.5000000512)
import numpy as np from typing import List from common import almost_equal def correlation(x: List[int], y: List[int]) -> float: assert len(x) == len(y) n = len(x) x_mean, y_mean = np.mean(x), np.mean(y) x_std_dev, y_std_dev = np.std(x), np.std(y) numerator = sum([x_i * y_i for (x_i, y_i) in zip(x, y)]) - (n * x_mean * y_mean) denominator = n * x_std_dev * y_std_dev return numerator / denominator a, b = [0, 14, 1, 10, 5], [2, 6, 8, 5, 6] assert almost_equal(correlation(a, b), np.corrcoef(a, b)[0][1])
from random import sample from common import almost_equal def experiment(total_shows: int, num_top_shows: int): shows = range(total_shows) alice = sample(shows, num_top_shows) bob = sample(shows, num_top_shows) return len(set(alice) & set(bob)) def simulate(n_experiments=1000000): count = 0 for i in range(n_experiments): count += experiment(total_shows=50, num_top_shows=3) return float(count) / n_experiments assert almost_equal(simulate(), 0.18)
def jarvis_march(points, main=None): amount = len(points) start_extreme = timer() # Find extreme point (start of convex hull) points = points[np.lexsort((points[:, 0], points[:, 1]))] e = points[0] end_extreme = timer() # if main is not None: # main.plot_point(e, text="E", color="blue") # Debug start_first = timer() # Find second point by calculating angles to all points (smallest angle) min_angle, min_i = np.inf, -1 for i, p in enumerate(points[1:]): angle = np.arctan2(p[1] - e[1], p[0] - e[0]) if cm.almost_equal(angle, min_angle): # Take smaller distance if same angles if pl.euclidean_dist(e, p) < pl.euclidean_dist(e, points[min_i]): min_angle, min_i = angle, i + 1 elif angle < min_angle: min_angle, min_i = angle, i + 1 end_first = timer() ch_points = np.vstack((e, points[min_i])) points = np.concatenate((points[:min_i], points[(min_i + 1):])) start_other = timer() # Find all other points pi = ch_points[-1] while not np.array_equal(pi, e): min_angle, min_i = np.inf, -1 for i, p in enumerate(points): a = pi - ch_points[-2] # Vector from previous point to last point b = p - pi # Vector from last point to new point angle = np.arctan2(b[1], b[0]) - np.arctan2(a[1], a[0]) if angle < 0: angle += 2 * np.pi # Bring into positive if cm.almost_equal(angle, min_angle): # Take smaller distance if same angles if pl.euclidean_dist(pi, p) < pl.euclidean_dist( pi, points[min_i]): min_angle, min_i = angle, i elif angle < min_angle: min_angle, min_i = angle, i ch_points = np.vstack((ch_points, points[min_i])) points = np.concatenate((points[:min_i], points[(min_i + 1):])) pi = ch_points[-1] end_other = timer() if main is not None: time_extreme = (end_extreme - start_extreme) * 1000 time_first = (end_first - start_first) * 1000 time_other = (end_other - start_other) * 1000 main.log( "Calculated convex hull on {} points using Jarvis March algorithm in {} ms:" .format(amount, int(time_extreme + time_first + time_other))) main.log("- Found extreme point in {} ms".format(int(time_extreme))) main.log("- Found second point using extreme in {} ms".format( int(time_first))) main.log("- Found all remaining points in {} ms".format( int(time_other))) return ch_points