Skip to content

Commit 1b35b8f

Browse files
committed
Added SOBOL
1 parent 2228cab commit 1b35b8f

27 files changed

+2588
-299
lines changed

.idea/pysample.iml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/workspace.xml

Lines changed: 436 additions & 246 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pysample/indicators.py

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,41 +14,44 @@ def correlation(X):
1414
return np.sum(np.tril(M, -1) ** 2)
1515

1616

17-
def centered_l2_discrepancy_slow(X, check_bounds=True):
18-
if check_bounds and (np.any(np.min(X) < 0 or np.max(X) > 1)):
19-
raise Exception("Make sure that all X are between 0 and 1.")
17+
def centered_l2_discrepancy(X):
2018

2119
n_points, n_dim = X.shape
22-
2320
acmh = np.abs(X - 0.5)
2421

25-
val = 0
26-
27-
for k in range(n_points):
28-
temp = 1
29-
for i in range(n_dim):
30-
temp = temp * (1 + 0.5 * (acmh[:, i] + acmh[k, i] - np.abs(X[:, i] - X[k, i])))
31-
val += np.sum(temp)
22+
_X = np.abs(X.T[..., None] - X.T[:, None, :])
23+
_acmh = np.abs(acmh.T[..., None] + acmh.T[:, None, :])
3224

25+
val = np.sum(np.prod((1 + 0.5 * (_acmh - _X)), axis=0))
3326
val = ((13 / 12) ** n_dim - 2 / n_points * np.sum(
3427
np.prod(1 + 0.5 * (acmh - acmh ** 2), axis=1)) + val / n_points ** 2) ** 0.5
3528

3629
return val
3730

3831

39-
def centered_l2_discrepancy(X, check_bounds=True):
40-
if check_bounds and (np.any(np.min(X) < 0 or np.max(X) > 1)):
41-
raise Exception("Make sure that all X are between 0 and 1.")
4232

43-
n_points, n_dim = X.shape
33+
def wrapped_l2_discrepancy(X):
4434

45-
acmh = np.abs(X - 0.5)
35+
"""
4636
47-
_X = np.abs(X.T[..., None] - X.T[:, None, :])
48-
_acmh = np.abs(acmh.T[..., None] + acmh.T[:, None, :])
37+
[Npts,Ndim]=size(coord);
38+
WDL2=0;
39+
for k=1:Npts
40+
yada=abs(coord(:,1)-coord(k,1));
41+
temp=(1.5-yada.*(1-yada));
42+
for i=2:Ndim
43+
yada=abs(coord(:,i)-coord(k,i));
44+
temp=temp.*(1.5-yada.*(1-yada));
45+
end
46+
WDL2=WDL2+sum(temp);
47+
end
48+
WDL2=(-(4/3)^Ndim+WDL2/Npts^2)^0.5; %^0.5;
4949
50-
val = np.sum(np.prod((1 + 0.5 * (_acmh - _X)), axis=0))
51-
val = ((13 / 12) ** n_dim - 2 / n_points * np.sum(
52-
np.prod(1 + 0.5 * (acmh - acmh ** 2), axis=1)) + val / n_points ** 2) ** 0.5
50+
end
51+
"""
52+
n_points, n_dim = X.shape
53+
_X = np.abs(X.T[..., None] - X.T[:, None, :])
54+
val = np.sum(np.prod((1.5 - _X * (1-_X)), axis=0))
55+
val = (-(4 / 3) ** n_dim + val / n_points ** 2) ** 0.5
5356

5457
return val

pysample/methods/halton.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import numpy as np
2+
3+
from pysample.methods.sampling import Sampling
4+
from pysample.util import calc_primes_until
5+
6+
7+
class HaltonSampling(Sampling):
8+
9+
def _sample(self, n_samples, n_dim):
10+
bases = calc_primes_until(500)[:n_dim]
11+
X = np.column_stack([self.halton_sequence(n_samples, b) for b in bases])
12+
return X
13+
14+
def halton_sequence(self, n, b):
15+
return np.array([self.halton_sequence_by_index(i, b) for i in range(n)])
16+
17+
def halton_sequence_by_index(self, i, b):
18+
f = 1.0
19+
x = 0.0
20+
while i > 0:
21+
f /= b
22+
x += f * (i % b)
23+
i = np.floor(i / b)
24+
return x

pysample/methods/lhs.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import numpy as np
22

33
from pysample.methods.sampling import Sampling
4-
from pysample.indicators import minimum_distance, correlation
4+
from pysample.indicators import minimum_distance, correlation, centered_l2_discrepancy, wrapped_l2_discrepancy
55
from pysample.optimization import random_search
66

77

@@ -17,12 +17,16 @@ def __init__(self, criterion="maxmin", optimizer="random_search", iterations=100
1717
self.fun_obj = minimum_distance
1818
elif criterion == "correlation":
1919
self.fun_obj = correlation
20+
elif criterion == "centered_l2_discrepancy":
21+
self.fun_obj = centered_l2_discrepancy
22+
elif criterion == "wrapped_l2_discrepancy":
23+
self.fun_obj = wrapped_l2_discrepancy
2024
else:
2125
raise Exception("Criterion not known.")
2226

2327
def _sample(self, n_samples, n_dim):
2428

25-
if self.optimizer == "random_trials":
29+
if self.optimizer == "random_search":
2630
fun_sample = lambda: _sample(n_samples, n_dim)
2731
X = random_search(fun_sample, self.fun_obj, self.iterations)
2832

@@ -31,13 +35,10 @@ def _sample(self, n_samples, n_dim):
3135
pass
3236

3337
elif self.optimizer == "ga":
34-
3538
n_generations = 100
3639
pop_size = 20
3740

3841

39-
40-
4142
else:
4243
X = _sample(n_samples, n_dim)
4344

pysample/methods/sobol.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import numpy as np
2+
3+
import re
4+
5+
from pysample.methods.sampling import Sampling
6+
from pysample.util import path_to_resources
7+
8+
9+
class SobolSampling(Sampling):
10+
11+
def __init__(self, n_skip=-1, n_leap=0, setup="matlab") -> None:
12+
super().__init__()
13+
fname = "sobol_%s.dat" % setup
14+
self.setup = parse_file(path_to_resources(fname))
15+
16+
self.n_skip = n_skip
17+
self.n_leap = n_leap
18+
19+
def _sample(self, n_samples, n_dim):
20+
21+
# find out how long the sequence needs to be - skip or leap included
22+
I = np.arange(0, n_samples, self.n_leap+1)
23+
if self.n_skip == -1:
24+
I += n_samples
25+
else:
26+
I += self.n_skip
27+
n_sequence = np.max(I) + 1
28+
29+
# containts all the values of the sequences as integer
30+
_X = np.zeros((n_sequence, n_dim), dtype=np.int)
31+
32+
# number of bits which will be necessary for this sequence
33+
L = int(np.ceil(np.log2(n_sequence)))
34+
35+
# number of bits necessary for the equation for each of them
36+
C = [highest_bit(i) for i in range(0, n_sequence)]
37+
38+
for j in range(n_dim):
39+
40+
if j == 0:
41+
V = np.concatenate((np.array([0]), 2 ** np.arange(31, -1, -1)))
42+
43+
else:
44+
45+
s, a, m = self.setup[j]["s"], self.setup[j]["a"], self.setup[j]["m"]
46+
V = np.zeros(L + 1, dtype=np.int)
47+
48+
if L <= s:
49+
for k in range(1, L + 1):
50+
V[k] = m[k - 1] << (32 - k)
51+
52+
else:
53+
54+
for k in range(1, s + 1):
55+
V[k] = m[k - 1] << (32 - k)
56+
57+
for i in range(s + 1, L + 1):
58+
V[i] = V[i - s] ^ int(V[i - s] >> s)
59+
for k in range(1, s):
60+
V[i] ^= (((a >> (s - 1 - k)) & 1) * V[i - k])
61+
62+
for i in range(1, n_sequence):
63+
_X[i, j] = _X[i - 1, j] ^ V[C[i - 1]]
64+
65+
X = (_X / 2 ** 32)[I]
66+
return X
67+
68+
69+
def highest_bit(i):
70+
bit = 1
71+
while i > 0 and i % 2 != 0:
72+
i = np.floor(i / 2)
73+
bit += 1
74+
return bit
75+
76+
77+
def parse_file(path_to_file):
78+
setup = [{}]
79+
80+
with open(path_to_file) as f:
81+
content = f.read().splitlines()[1:]
82+
83+
for line in content:
84+
entries = [int(e) for e in re.split("\s+|\t", line.strip())]
85+
86+
setup.append({
87+
'd': entries[0],
88+
's': entries[1],
89+
'a': entries[2],
90+
'm': np.array(entries[3:])
91+
92+
})
93+
94+
return setup

pysample/optimization.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ def random_search(fun_sample, fun_obj, iterations):
1212
f = _f
1313
X = _X
1414

15+
print(f)
16+
1517
return X
1618

1719

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
d s a m_i
2+
2 1 1 1
3+
3 1 3 1
4+
4 2 7 1 1
5+
5 3 11 1 3 7
6+
6 3 13 1 1 5
7+
7 4 19 1 3 1 1
8+
8 4 25 1 1 3 7
9+
9 5 37 1 3 3 9 9
10+
10 5 59 1 3 7 13 3
11+
11 5 47 1 1 5 11 27
12+
12 5 61 1 3 5 1 15
13+
13 5 55 1 1 7 3 29
14+
14 5 41 1 3 7 7 21
15+
15 6 67 1 1 1 9 23 37
16+
16 6 97 1 3 3 5 19 33
17+
17 6 91 1 1 3 13 11 7
18+
18 6 109 1 1 7 13 25 5
19+
19 6 103 1 3 5 11 7 11
20+
20 6 115 1 1 1 3 13 39
21+
21 7 131 1 3 1 15 17 63 13
22+
22 7 193 1 1 5 5 1 27 33
23+
23 7 137 1 3 3 3 25 17 115
24+
24 7 145 1 1 3 15 29 15 41
25+
25 7 143 1 3 1 7 3 23 79
26+
26 7 241 1 3 7 9 31 29 17
27+
27 7 157 1 1 5 13 11 3 29
28+
28 7 185 1 3 1 9 5 21 119
29+
29 7 167 1 1 3 1 23 13 75
30+
30 7 229 1 3 3 11 27 31 73
31+
31 7 171 1 1 7 7 19 25 105
32+
32 7 213 1 3 5 5 21 9 7
33+
33 7 191 1 1 1 15 5 49 59
34+
34 7 253 1 1 1 1 1 33 65
35+
35 7 203 1 3 5 15 17 19 21
36+
36 7 211 1 1 7 11 13 29 3
37+
37 7 239 1 3 7 5 7 11 113
38+
38 7 247 1 1 5 3 15 19 61
39+
39 8 285 1 3 1 1 9 27 89 7
40+
40 8 369 1 1 3 7 31 15 45 23
41+
41 8 299 1 3 3 9 9 25 107 39

0 commit comments

Comments
 (0)