def __init__(self, N, d): PointSet.__init__(self, N, d) num_triangles = self.N * (self.N - 1) * (self.N - 2) / 6 self.num_angles = int(3 * num_triangles) self.theta = np.empty([ self.num_angles, ]) self.theta_tensor = np.empty([N, N, N]) self.corners = np.empty([self.num_angles, 3])
class TestAlternating(BaseCommon.TestAlgorithms): def setUp(self): print('TestAlternating:setUp') BaseCommon.TestAlgorithms.setUp(self) self.n_it = 1 self.eps = 1e-8 self.N_zero = [5] self.N_relaxed = [5] self.methods = ['dwMDS', 'ACD'] def create_points(self, N=10, d=3): print('TestAlternating:create_points') self.pts = PointSet(N, d) self.pts.set_points('normal') self.X0 = self.pts.points.copy() + \ np.random.normal(scale=self.eps * 0.01, size=self.pts.points.shape) def call_method(self, method=''): Xhat, __ = call_method(self.pts.edm, X0=self.X0, tol=self.eps, method=method) return Xhat def test_nonzero_noise(self): from pylocus.simulation import create_noisy_edm noises = np.logspace(-8, -3, 10) self.create_points() for method in self.methods: for noise in noises: noisy_edm = create_noisy_edm(self.pts.edm, noise) eps = noise * 100 Xhat, costs = call_method(noisy_edm, X0=self.X0, tol=self.eps, method=method) err = np.linalg.norm(Xhat - self.pts.points) self.assertTrue( err < eps, 'error {} not smaller than {}'.format(err, eps)) def test_decreasing_cost(self): self.create_points() for method in self.methods: Xhat, costs = call_method(self.pts.edm, X0=self.X0, tol=self.eps, method=method) cprev = np.inf for c in costs: self.assertTrue(c <= cprev + self.eps, 'c: {}, cprev:{}'.format(c, cprev)) cprev = c
def setUp(self): self.pts = PointSet(N=5, d=3) self.pts.set_points(mode='convex') W = np.ones(self.pts.edm.shape) indices_missing = ([4, 1], [0, 3]) W[indices_missing] = 0.0 W = np.multiply(W, W.T) np.fill_diagonal(W, 0.0) self.W = W # TODO: find out why sdr and rank alternation don't work. #self.methods = ['acd', 'dwmds', 'sdr', 'rank'] self.methods = ['acd', 'dwmds']
def create_points(self, N=10, d=2): print('TestSRLS:create_points') self.pts = PointSet(N, d) self.pts.set_points('random') # example point set that fails: # self.pts.points = np.array([[0.63, 0.45], # [0.35, 0.37], # [0.69, 0.71], # [0.71, 0.73], # [0.43, 0.44], # [0.58, 0.59]]) self.pts.init() self.index = 0
def __init__(self, N, d): from scipy import special PointSet.__init__(self, N, d) self.T = self.N * (self.N - 1) * (self.N - 2) / 6 self.M = int(3 * self.T) self.theta = np.empty([ self.M, ]) self.theta_tensor = np.empty([N, N, N]) self.corners = np.empty([self.M, 3]) self.abs_angles = np.empty([self.N, self.N]) self.C = 0 self.A = np.empty((self.C, self.M)) self.b = np.empty((self.C, 1))
class TestSDP(BaseCommon.TestAlgorithms): def setUp(self): print('TestSDP:setUp') BaseCommon.TestAlgorithms.setUp(self) self.eps = 1e-8 self.success_rate = 50 self.n_it = 1 self.N_zero = [6] self.N_relaxed = [6] def create_points(self, N=10, d=3): print('TestSDP:create_points') self.pts = PointSet(N, d) self.pts.set_points('normal') def call_method(self, method=''): print('TestSDP:call_method') Xhat, edm = reconstruct_sdp(self.pts.edm, real_points=self.pts.points, solver='SCS', eps=1e-10, method='maximize') return Xhat def test_parameters(self): print('TestSDP:test_parameters') self.create_points() epsilons = [1e-3, 1e-5, 1e-8] options_list = [{}, { 'solver': 'CVXOPT', 'abstol': 1e-5, 'reltol': 1e-6, 'feastol': 1e-7 }, { 'solver': 'SCS', 'eps': 1e-10 }] for options, eps in zip(options_list, epsilons): self.eps = eps points_estimate, __ = reconstruct_sdp(self.pts.edm, real_points=self.pts.points, method='maximize', **options) error = np.linalg.norm(self.pts.points - points_estimate) self.assertTrue( error < self.eps, 'with options {} \nerror: {} not smaller than {}'.format( options, error, self.eps))
class TestAlgorithms(unittest.TestCase): def setUp(self): self.pts = PointSet(N=5, d=3) self.pts.set_points(mode='convex') W = np.ones(self.pts.edm.shape) indices_missing = ([4, 1], [0, 3]) W[indices_missing] = 0.0 W = np.multiply(W, W.T) np.fill_diagonal(W, 0.0) self.W = W # TODO: find out why sdr and rank alternation don't work. #self.methods = ['acd', 'dwmds', 'sdr', 'rank'] self.methods = ['acd', 'dwmds'] def call_method(self, edm_input, method): print('running method', method) edm_missing = np.multiply(edm_input, self.W) if method == 'sdr': return semidefinite_relaxation(edm_input, lamda=1000, W=self.W) elif method == 'rank': return rank_alternation(edm_missing, rank=self.pts.d + 2, niter=100)[0] else: X0 = self.pts.points X0 += np.random.normal(loc=0.0, scale=0.01) if method == 'acd': return completion_acd(edm_missing, X0, self.W) elif method == 'dwmds': return completion_dwmds(edm_missing, X0, self.W) def test_complete(self): for i in range(10): self.pts.set_points('random') for method in self.methods: edm_complete = self.pts.edm.copy() edm_output = self.call_method(edm_complete, method) np.testing.assert_allclose(edm_complete, edm_output)
class TestACD(BaseCommon.TestAlgorithms): def setUp(self): BaseCommon.TestAlgorithms.setUp(self) self.create_points() self.n_it = 10 def create_points(self, N=5, d=2): print('TestACD:create_points') self.pts = PointSet(N, d) self.pts.set_points('random') self.pts.init() self.index = 0 def call_method(self, method=''): print('TestACD:call_method') Xhat, costs = reconstruct_acd(self.pts.edm, W=np.ones(self.pts.edm.shape), X0=self.pts.points, print_out=False, sweeps=3) return Xhat def add_noise(self, noise=1e-6): self.pts.edm = create_noisy_edm(self.pts.edm, noise)
def create_points(self, N=10, d=3): print('TestSDP:create_points') self.pts = PointSet(N, d) self.pts.set_points('normal')
#! /usr/bin/env python3 # -*- coding: utf-8 -*- import numpy as np from pylocus.point_set import PointSet from pylocus.algorithms import reconstruct_srls from pylocus.simulation import create_noisy_edm, create_mask, create_weights from pylocus.basics import mse, rmse points = PointSet(N=5, d=2) points.set_points('random') print("point to localize:", points.points[0, :]) print("anchors:", points.points[1:, :]) std = 0.1 edm_noisy = create_noisy_edm(points.edm, noise=std) mask = create_mask(points.N, method='none') weights = create_weights(points.N, method='one') weights = np.multiply(mask, weights) points_estimated = reconstruct_srls(edm_noisy, points.points, W=weights) error = mse(points_estimated[0, :], points.points[0, :]) print("estimated point: {}, original point: {}, mse: {:2.2e}".format( points_estimated[0, :], points.points[0, :], error))
def create_points(self, N=10, d=3): print('TestAlternating:create_points') self.pts = PointSet(N, d) self.pts.set_points('normal') self.X0 = self.pts.points.copy() + \ np.random.normal(scale=self.eps * 0.01, size=self.pts.points.shape)
def create_points(self, N=10, d=2): self.pts = PointSet(N, d) self.pts.set_points('random') self.pts.init() self.n = 1
class TestSRLS(BaseCommon.TestAlgorithms): def setUp(self): BaseCommon.TestAlgorithms.setUp(self) self.create_points() # for d=3, N_missing=2, need at least 6 anchors (no rescale) or 7 anchors (rescaled). self.N_relaxed = range(6, 10) self.methods = ['normal', 'rescale', 'fixed'] self.eps = 1e-8 def create_points(self, N=10, d=2): self.pts = PointSet(N, d) self.pts.set_points('random') self.pts.init() self.n = 1 def call_method(self, method=''): print('TestSRLS:call_method') if method == '' or method == 'normal': return reconstruct_srls(self.pts.edm, self.pts.points, W=np.ones(self.pts.edm.shape)) elif method == 'rescale': return reconstruct_srls(self.pts.edm, self.pts.points, W=np.ones(self.pts.edm.shape), rescale=True) elif method == 'fixed' and self.pts.d == 3: return reconstruct_srls(self.pts.edm, self.pts.points, W=np.ones(self.pts.edm.shape), rescale=False, z=self.pts.points[0, 2]) def test_fail(self): # Example point set that used to fail. With the newer SRLS version this is fixed. # Status: July 16, 2018 points_fail = np.array([[0.00250654, 0.89508715, 0.35528746], [0.52509683, 0.88692205, 0.76633946], [0.64764605, 0.94040708, 0.20720253], [0.69637586, 0.99566993, 0.49537693], [0.64455557, 0.46856155, 0.80050257], [0.90556836, 0.75831552, 0.81982037], [0.86634135, 0.5139182, 0.14738743], [0.29145628, 0.54500108, 0.6586396]]) method = 'rescale' self.pts.set_points(points=points_fail) points_estimate = self.call_method(method=method) error = np.linalg.norm(self.pts.points - points_estimate) self.assertTrue( error < self.eps, 'error: {} not smaller than {}'.format(error, self.eps)) points_fail = np.array([[0.63, 0.45], [0.35, 0.37], [0.69, 0.71], [0.71, 0.73], [0.43, 0.44], [0.58, 0.59]]) method = 'normal' self.pts.set_points(points=points_fail) points_estimate = self.call_method(method=method) error = np.linalg.norm(self.pts.points - points_estimate) self.assertTrue( error < self.eps, 'error: {} not smaller than {}'.format(error, self.eps)) def test_multiple_weights(self): print('TestSRLS:test_multiple_weights') for i in range(self.n_it): self.create_points() self.zero_weights(0.0) self.zero_weights(0.1) self.zero_weights(1.0) def test_srls_rescale(self): print('TestSRLS:test_srls_rescale') anchors = np.array([[0., 8.44226166, 0.29734295], [1., 7.47840264, 1.41311759], [2., 8.08093318, 2.21959719], [3., 4.55126532, 0.0456345], [4., 5.10971446, -0.01223217], [5., 2.95745961, -0.77572604], [6., 3.12145804, 0.80297295], [7., 2.29152331, -0.48021431], [8., 1.53137609, -0.03621697], [9., 0.762208, 0.70329037]]) sigma = 3. N, d = anchors.shape w = np.ones((N, 1)) x = np.ones(d) * 4. r2 = np.linalg.norm(anchors - x[None, :], axis=1)**2 r2.resize((len(r2), 1)) # Normal ranging x_srls = SRLS(anchors, w, r2) np.testing.assert_allclose(x, x_srls) # Rescaled ranging x_srls_resc, scale = SRLS(anchors, w, sigma * r2, rescale=True) self.assertLess(abs(1 / scale - sigma), self.eps, 'not equal: {}, {}'.format(scale, sigma)) np.testing.assert_allclose(x, x_srls_resc) def test_srls_fixed(self): print('TestSRLS:test_srls_fixed') self.create_points(N=10, d=3) zreal = self.pts.points[0, 2] xhat = reconstruct_srls(self.pts.edm, self.pts.points, W=np.ones(self.pts.edm.shape), rescale=False, z=zreal) if xhat is not None: np.testing.assert_allclose(xhat[0, 2], zreal) np.testing.assert_allclose(xhat, self.pts.points) def test_srls_fail(self): anchors = np.array([[11.881, 3.722, 1.5], [11.881, 14.85, 1.5], [11.881, 7.683, 1.5]]) w = np.ones((3, 1)) distances = [153.32125426, 503.96654466, 234.80741129] z = 1.37 self.assertRaises(GeometryError, SRLS, anchors, w, distances, False, z) def zero_weights(self, noise=0.1): index = np.arange(self.n) other = np.delete(range(self.pts.N), index) edm_noisy = create_noisy_edm(self.pts.edm, noise) # missing anchors N_missing = 2 indices = np.random.choice(other, size=N_missing, replace=False) reduced_points = np.delete(self.pts.points, indices, axis=0) points_missing = create_from_points(reduced_points, PointSet) edm_anchors = np.delete(edm_noisy, indices, axis=0) edm_anchors = np.delete(edm_anchors, indices, axis=1) missing_anchors = reconstruct_srls(edm_anchors, points_missing.points, W=None, print_out=False) # missing distances weights = np.ones(edm_noisy.shape) weights[indices, index] = 0.0 weights[index, indices] = 0.0 missing_distances = reconstruct_srls(edm_noisy, self.pts.points, W=weights) left_distances = np.delete(range(self.pts.N), indices) self.assertTrue( np.linalg.norm(missing_distances[left_distances, :] - missing_anchors) < self.eps, 'anchors moved.') self.assertTrue( np.linalg.norm(missing_distances[index, :] - missing_anchors[index, :]) < self.eps, 'point moved.') if noise == 0.0: error = np.linalg.norm(missing_anchors - points_missing.points) u, s, v = np.linalg.svd(self.pts.points[other, :]) try: self.assertTrue(error < self.eps, 'error {}'.format(error)) except: print( 'failed with anchors (this can be due to unlucky geometry):', points_missing.points) raise
class TestSRLS(BaseCommon.TestAlgorithms): #class TestSRLS(unittest.TestCase): def setUp(self): self.create_points() def create_points(self, N=10, d=2): print('TestSRLS:create_points') self.pts = PointSet(N, d) self.pts.set_points('random') # example point set that fails: # self.pts.points = np.array([[0.63, 0.45], # [0.35, 0.37], # [0.69, 0.71], # [0.71, 0.73], # [0.43, 0.44], # [0.58, 0.59]]) self.pts.init() self.index = 0 def call_method(self): print('TestSRLS:call_method') return reconstruct_srls(self.pts.edm, self.pts.points, indices=[self.index], W=np.ones(self.pts.edm.shape)) def test_multiple_weights(self): print('TestSRLS:test_multiple') for i in range(100): self.create_points() self.zero_weights(0.0) self.zero_weights(0.1) self.zero_weights(1.0) def zero_weights(self, noise=0.1): print('TestSRLS:test_zero_weights({})'.format(noise)) other = np.delete(range(self.pts.N), self.index) edm_noisy = create_noisy_edm(self.pts.edm, noise) # missing anchors N_missing = 2 indices = np.random.choice(other, size=N_missing, replace=False) reduced_points = np.delete(self.pts.points, indices, axis=0) points_missing = create_from_points(reduced_points, PointSet) edm_anchors = np.delete(edm_noisy, indices, axis=0) edm_anchors = np.delete(edm_anchors, indices, axis=1) missing_anchors = reconstruct_srls(edm_anchors, points_missing.points, indices=[self.index], W=None, print_out=False) # missing distances weights = np.ones(edm_noisy.shape) weights[indices, self.index] = 0.0 weights[self.index, indices] = 0.0 missing_distances = reconstruct_srls(edm_noisy, self.pts.points, indices=[self.index], W=weights) left_distances = np.delete(range(self.pts.N), indices) self.assertTrue( np.linalg.norm(missing_distances[left_distances, :] - missing_anchors) < 1e-10, 'anchors moved.') self.assertTrue( np.linalg.norm(missing_distances[self.index, :] - missing_anchors[self.index, :]) < 1e-10, 'point moved.') if noise == 0.0: error = np.linalg.norm(missing_anchors - points_missing.points) u, s, v = np.linalg.svd(self.pts.points[other, :]) try: self.assertTrue(error < 1e-10, 'error {}'.format(error)) except: print( 'failed with anchors (this can be due to unlucky geometry):', points_missing.points) raise
def copy(self): new = PointSet.copy(self) new.theta = self.theta.copy() return new
def create_points(self, N=5, d=2): print('TestACD:create_points') self.pts = PointSet(N, d) self.pts.set_points('random') self.pts.init() self.index = 0
def init(self): PointSet.init(self) self.theta, self.corners = create_theta(self.points) self.theta_tensor = get_theta_tensor(self.theta, self.corners, self.N)
class TestSRLS(BaseCommon.TestAlgorithms): def setUp(self): BaseCommon.TestAlgorithms.setUp(self) self.create_points() # for d=3, N_missing=2, need at least 6 anchors (no rescale) or 7 anchors (rescaled). self.N_relaxed = range(6, 10) self.methods = ['normal', 'rescale', 'fixed'] self.eps = 1e-8 def create_points(self, N=10, d=2): print('TestSRLS:create_points') self.pts = PointSet(N, d) self.pts.set_points('random') # example point set that fails: # self.pts.points = np.array([[0.63, 0.45], # [0.35, 0.37], # [0.69, 0.71], # [0.71, 0.73], # [0.43, 0.44], # [0.58, 0.59]]) self.pts.init() self.n = 1 def call_method(self, method=''): print('TestSRLS:call_method') if method == '' or method == 'normal': return reconstruct_srls(self.pts.edm, self.pts.points, n=self.n, W=np.ones(self.pts.edm.shape)) elif method == 'rescale': return reconstruct_srls(self.pts.edm, self.pts.points, n=self.n, W=np.ones(self.pts.edm.shape), rescale=True) elif method == 'fixed' and self.pts.d == 3: return reconstruct_srls(self.pts.edm, self.pts.points, n=self.n, W=np.ones(self.pts.edm.shape), rescale=False, z=self.pts.points[0, 2]) def test_multiple_weights(self): print('TestSRLS:test_multiple') for i in range(100): self.create_points() self.zero_weights(0.0) self.zero_weights(0.1) self.zero_weights(1.0) def test_srls_rescale(self): anchors = np.array([[0., 8.44226166, 0.29734295], [1., 7.47840264, 1.41311759], [2., 8.08093318, 2.21959719], [3., 4.55126532, 0.0456345], [4., 5.10971446, -0.01223217], [5., 2.95745961, -0.77572604], [6., 3.12145804, 0.80297295], [7., 2.29152331, -0.48021431], [8., 1.53137609, -0.03621697], [9., 0.762208, 0.70329037]]) sigma = 3. N, d = anchors.shape w = np.ones((N, 1)) x = np.ones(d) * 4. r2 = np.linalg.norm(anchors - x[None, :], axis=1)**2 r2.resize((len(r2), 1)) # Normal ranging x_srls = SRLS(anchors, w, r2) self.assertTrue(np.allclose(x, x_srls)) # Rescaled ranging x_srls_resc, scale = SRLS(anchors, w, sigma * r2, rescale=True) self.assertLess(abs(1 / scale - sigma), self.eps, 'not equal: {}, {}'.format(scale, sigma)) np.testing.assert_allclose(x, x_srls_resc) def test_srls_fixed(self): self.create_points(N=10, d=3) zreal = self.pts.points[0, 2] xhat = reconstruct_srls(self.pts.edm, self.pts.points, n=self.n, W=np.ones(self.pts.edm.shape), rescale=False, z=self.pts.points[0, 2]) self.assertEqual(xhat[0, 2], zreal) np.testing.assert_allclose(xhat, self.pts.points) def zero_weights(self, noise=0.1): print('TestSRLS:test_zero_weights({})'.format(noise)) index = np.arange(self.n) other = np.delete(range(self.pts.N), index) edm_noisy = create_noisy_edm(self.pts.edm, noise) # missing anchors N_missing = 2 indices = np.random.choice(other, size=N_missing, replace=False) reduced_points = np.delete(self.pts.points, indices, axis=0) points_missing = create_from_points(reduced_points, PointSet) edm_anchors = np.delete(edm_noisy, indices, axis=0) edm_anchors = np.delete(edm_anchors, indices, axis=1) missing_anchors = reconstruct_srls(edm_anchors, points_missing.points, n=self.n, W=None, print_out=False) # missing distances weights = np.ones(edm_noisy.shape) weights[indices, index] = 0.0 weights[index, indices] = 0.0 missing_distances = reconstruct_srls(edm_noisy, self.pts.points, n=self.n, W=weights) left_distances = np.delete(range(self.pts.N), indices) self.assertTrue( np.linalg.norm(missing_distances[left_distances, :] - missing_anchors) < self.eps, 'anchors moved.') self.assertTrue( np.linalg.norm(missing_distances[index, :] - missing_anchors[index, :]) < self.eps, 'point moved.') if noise == 0.0: error = np.linalg.norm(missing_anchors - points_missing.points) u, s, v = np.linalg.svd(self.pts.points[other, :]) try: self.assertTrue(error < self.eps, 'error {}'.format(error)) except: print( 'failed with anchors (this can be due to unlucky geometry):', points_missing.points) raise