Skip to content

Commit 8f683b8

Browse files
committed
new 3D plot and running the tests in paralell
1 parent 9e3b88b commit 8f683b8

File tree

8 files changed

+577
-104
lines changed

8 files changed

+577
-104
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
__pycache__
33
.ipynb*
44
surface-images/*
5+
*.npy

pattern.ipynb

Lines changed: 10 additions & 10 deletions
Large diffs are not rendered by default.

results.ipynb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@
289289
"metadata": {
290290
"anaconda-cloud": {},
291291
"kernelspec": {
292-
"display_name": "Python [default]",
292+
"display_name": "Python 3",
293293
"language": "python",
294294
"name": "python3"
295295
},
@@ -303,7 +303,7 @@
303303
"name": "python",
304304
"nbconvert_exporter": "python",
305305
"pygments_lexer": "ipython3",
306-
"version": "3.5.2"
306+
"version": "3.6.0"
307307
}
308308
},
309309
"nbformat": 4,

solvers.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class ConstrainedALS(AlternatingLS):
9292

9393
def __init__(self, samples, model_size, model_type, start_pos,
9494
show_plots=False, hold_edges=True, stopping_error=1.0e-6, beta=0.01, interval_length=1, max_iter=10000,
95-
fl=1.0, angle=0):
95+
fl=1.0, angle=0, verbose=True):
9696
super(ConstrainedALS, self).__init__(samples, model_size, model_type, show_plots,
9797
hold_edges, stopping_error, beta, interval_length)
9898
assert len(samples) == len(start_pos)
@@ -104,6 +104,7 @@ def __init__(self, samples, model_size, model_type, start_pos,
104104
self.tr_param[2] = fl
105105
self.tr_param[0] = angle
106106
self.max_iterations = max_iter
107+
self.verb = verbose
107108

108109
def solve(self):
109110
sign = -1
@@ -120,15 +121,17 @@ def solve(self):
120121
self.error = np.linalg.norm(np.dot(x, self.parameter_estimate) - self.samples) / self.number_samples
121122

122123
if self.error < self.stopping_error:
123-
print("error small enough after fitting parameters")
124+
if self.verb:
125+
print("error small enough after fitting parameters")
124126
break
125127

126128
g = self.model_type.compute_ls_gradient(self.start_positions, self.parameter_estimate, self.samples,
127129
self.tr_param)
128130
# print "gradient: %f" % g
129131
# print "alpha: %f" % self.tr_param
130132
if np.max(np.abs(g*self.beta)) < np.finfo(float).eps:
131-
print("converged to local minimum after", k, "steps")
133+
if self.verb:
134+
print("converged to local minimum after", k, "steps")
132135
break
133136

134137
# normalize the gradient so it does not explode for many samples
@@ -137,11 +140,13 @@ def solve(self):
137140
error = np.linalg.norm(np.dot(x, self.parameter_estimate) - self.samples) / self.number_samples
138141

139142
if error < self.stopping_error:
140-
print("error small enough after fitting positions")
143+
if self.verb:
144+
print("error small enough after fitting positions")
141145
break
142146

143147
if self.error < error:
144-
print("error:", self.error, "beta:", self.beta)
148+
if self.verb:
149+
print("error:", self.error, "beta:", self.beta)
145150
if self.beta > 10*np.finfo(float).eps:
146151
self.beta *= 0.5
147152

@@ -161,7 +166,8 @@ def solve(self):
161166
pylab.pause(0.01)
162167

163168
if k == self.max_iterations - 1:
164-
print('force stop after', self.max_iterations, 'steps')
169+
if self.verb:
170+
print('force stop after', self.max_iterations, 'steps')
165171

166172

167173
class InvertedLS(OrdinaryLS):

surface-reconstruction.ipynb

Lines changed: 40 additions & 11 deletions
Large diffs are not rendered by default.

surface-tests.py

Lines changed: 77 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,86 @@
11
from samplers import *
22
from solvers import *
33
from plots import *
4+
from multiprocessing import Pool
45

56
# set parameters
67
tests = 50 # number of tests
7-
n = 4 # number of parameters of the polynomial (degree + 1)
8-
f = 1.0 # distance between the origin and the image plane
9-
b = 1.0 # intersection between camera axis and the surface
10-
slopes = np.linspace(-np.pi/6, np.pi/6, 13)
8+
pools = 5
9+
n = 6 # number of parameters of the polynomial (degree + 1)
10+
ovs = 1 # oversampling
11+
f = 1.0 # distance between the origin and the image plane
12+
b = 1.0 # intersection between camera axis and the surface
13+
slopes = np.linspace(-np.pi / 9, np.pi / 9, 13)
14+
# slopes = slopes[1:-1]
15+
noise_scale = 0
16+
noise_ampl = 0.0
17+
if noise_scale is not 0:
18+
noise_ampl = 10.0 ** (-noise_scale)
19+
1120

1221
# containers for results:
13-
errors = []
14-
nsr = []
15-
16-
for test in range(tests):
17-
print("test: ", test)
18-
19-
tmp_err = []
20-
start_param = nr.randn(n, 1)
21-
22-
print(start_param)
23-
24-
for slope in slopes:
25-
polynomial = SecondSurfacePolynomial(start_param)
26-
sampler = SurfaceSampler(polynomial, 2*n, [slope, b, f], interval_length=2, sigma=0.0, beg=-1)
27-
noise = 1e-1*nr.randn(2*n)
28-
nsr.append(np.linalg.norm(noise) / np.linalg.norm(sampler.sample_values))
29-
sample_values = sampler.sample_values + noise
30-
31-
solver = ConstrainedALS(
32-
sample_values,
33-
polynomial.model_size,
34-
SecondSurfacePolynomial,
35-
start_pos=sampler.sample_positions,
36-
stopping_error=1e-10,
37-
beta=0.1,
38-
show_plots=False,
39-
max_iter=10000,
40-
fl=f)
41-
42-
true_error = 0
43-
try:
44-
solver.solve()
45-
true_error = abs(slope - solver.tr_param[0])
46-
except AssertionError as as_err:
47-
print("assertion error:", as_err.args[0])
48-
true_error = np.NAN
49-
50-
tmp_err.append(true_error)
51-
errors.append(tmp_err)
52-
53-
errors = np.array(errors)
54-
nsr = np.array(nsr)
55-
56-
print("mean:", np.nanmean(errors)*180/np.pi)
57-
print("median:", np.nanmedian(errors))
58-
print("std:", np.nanstd(errors))
59-
print("NANS:", str(np.count_nonzero(np.isnan(errors))/len(errors.flatten())*100)+"%")
22+
23+
def test_block(beginning):
24+
errors = []
25+
nsr = []
26+
params = []
27+
np.random.seed(beginning)
28+
for test in range(int(tests / pools)):
29+
print("test: ", int(tests / pools) * beginning + test)
30+
31+
tmp_err = []
32+
start_param = nr.randn(n, 1)
33+
start_param[0] = 1
34+
35+
# print(start_param)
36+
params.append(start_param)
37+
38+
for slope in slopes:
39+
polynomial = SecondSurfacePolynomial(start_param)
40+
sampler = SurfaceSampler(polynomial, 2 * ovs * n, [slope, b, f], interval_length=2, sigma=0.0, beg=0)
41+
noise = noise_ampl * nr.randn(2 * ovs * n)
42+
nsr.append(np.linalg.norm(noise) / np.linalg.norm(sampler.sample_values))
43+
sample_values = sampler.sample_values + noise
44+
45+
solver = ConstrainedALS(
46+
sample_values,
47+
polynomial.model_size,
48+
SecondSurfacePolynomial,
49+
start_pos=sampler.sample_positions,
50+
stopping_error=1e-10,
51+
beta=0.1,
52+
show_plots=False,
53+
max_iter=10000,
54+
fl=f,
55+
verbose=False)
56+
57+
true_error = 0
58+
try:
59+
solver.solve()
60+
true_error = abs(slope - solver.tr_param[0])
61+
except AssertionError as as_err:
62+
print("assertion error:", as_err.args[0])
63+
true_error = np.NAN
64+
65+
tmp_err.append(true_error)
66+
errors.append(np.array(tmp_err))
67+
return (errors, nsr, params)
68+
69+
70+
p = Pool(pools)
71+
sth = p.map(test_block, range(pools))
72+
sth = np.array(sth)
73+
errors = np.concatenate(sth[:, 0])
74+
nsr = np.concatenate(sth[:, 1]).reshape(tests, len(slopes))
75+
params = np.concatenate(sth[:, 2]).reshape(tests, n)
76+
77+
print("mean:", np.degrees(np.nanmean(errors)))
78+
print("median:", np.degrees(np.nanmedian(errors)))
79+
print("std:", np.degrees(np.nanstd(errors)))
80+
print("NANS:", str(np.count_nonzero(np.isnan(errors)) / len(errors.flatten()) * 100) + "%")
6081
print("noise to signal", np.nanmean(nsr))
82+
83+
version = str(n)+"_"+str(ovs)+"_"+str(noise_scale)
84+
np.save("errors_"+version, errors)
85+
np.save("nsr_"+version, nsr)
86+
np.save("params_"+version, params)

0 commit comments

Comments
 (0)