-
Notifications
You must be signed in to change notification settings - Fork 1
/
other.py
109 lines (93 loc) · 3.45 KB
/
other.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# -*- coding: utf-8 -*-
"""
Useful functions that don't need to go into the appendix of the paper.
"""
from config import MagicConstants
from probabilities import A, C, P, W, Probabilities
from mpmath import mp
from utils import load_probabilities
import os
import csv
def fast_probabilities(d, n, k, beta=None, prec=None):
"""
Useful probabilities.
:param d: We consider the sphere `S^{d-1}`
:param n: Number of popcount vectors
:param k: popcount threshold
:param beta: If not ``None`` vectors are considered in a bucket around some `w` with angle β.
:param prec: compute with this precision
"""
# NOTE: This function is unused.
prec = prec if prec else mp.prec
with mp.workprec(prec):
if beta is None:
S1 = mp.quad(lambda x: P(n, k, x) * A(d, x), (0, mp.pi / 3), error=True)[0]
S2 = mp.quad(lambda x: P(n, k, x) * A(d, x), (mp.pi / 3, mp.pi), error=True)[0]
pf_ = S1 + S2
ngr_ = C(d, mp.pi / 3)
ngr_pf_ = S1
elif beta < mp.pi / 6:
pf_ = mp.quad(lambda x: P(n, k, x) * W(d, beta, beta, x) * A(d, x), (0, min(mp.pi, 2 * beta)), error=True)[
0
]
ngr_ = mp.mpf(1.0)
ngr_pf_ = mp.mpf(1.0)
else:
S1 = mp.quad(
lambda x: P(n, k, x) * W(d, beta, beta, x) * A(d, x), (0, min(mp.pi / 3, 2 * beta)), error=True
)[0]
S2 = mp.quad(
lambda x: P(n, k, x) * W(d, beta, beta, x) * A(d, x),
(min(mp.pi / 3, 2 * beta), min(mp.pi, 2 * beta)),
error=True,
)[0]
S3 = mp.quad(lambda x: W(d, beta, beta, x) * A(d, x), (0, mp.pi / 3), error=True)[0]
S4 = mp.quad(lambda x: W(d, beta, beta, x) * A(d, x), (mp.pi / 3, 2 * beta), error=True)[0]
ngr_ = S3 / (S3 + S4)
pf_ = (S1 + S2) / (S3 + S4)
ngr_pf_ = S1 / (S3 + S4)
probs = Probabilities(
d=d,
n=n,
k=k,
ngr=ngr_,
gr=1 - ngr_,
pf=pf_,
gr_pf=-1,
ngr_pf=ngr_pf_,
rho=-1,
eta=1 - ngr_pf_ / ngr_,
beta=beta,
prec=prec,
)
return probs
def read_csv(filename, columns, read_range=None, ytransform=lambda y: y):
with open(filename) as csvfile:
reader = csv.reader(csvfile, delimiter=",")
data = []
for i, row in enumerate(reader):
if i == 0:
columns = row.index(columns[0]), row.index(columns[1])
continue
data.append((int(row[columns[0]]), ytransform(float(row[columns[1]]))))
if read_range is not None:
data = [(x, y) for x, y in data if x in read_range]
data = sorted(data)
X = [x for x, y in data]
Y = [y for x, y in data]
return tuple(X), tuple(Y)
def linear_fit(filename, columns=("d", "log_cost"),
low_index=0, high_index=100000, leading_coefficient=None):
from scipy.optimize import curve_fit
X, Y = read_csv(filename, columns=columns, read_range=range(low_index, high_index))
if leading_coefficient is None:
def f(x, a, b):
return a * x + b
else:
def f(x, b):
return leading_coefficient * x + b
r = list(curve_fit(f, X, Y)[0])
if leading_coefficient is not None:
r = [leading_coefficient] + r
print("{r[0]:.4}*x + {r[1]:.3}".format(r=r))
return r