Skip to content

Commit

Permalink
Merge branch 'master' of github.com:lcav/pylocus
Browse files Browse the repository at this point in the history
  • Loading branch information
duembgen committed Nov 9, 2018
2 parents e05f785 + 5790607 commit 758c456
Show file tree
Hide file tree
Showing 14 changed files with 965 additions and 85 deletions.
26 changes: 9 additions & 17 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ To perform a local install on your computer, run from this folder level (where s
pip install -e .
This installs the package using symbolic links, avoiding the need for a reinstall whenever the source code is changed.
If you use conda, then

.. code-block:: bash
conda develop .
does the same trick.

Install
*******
Expand All @@ -49,21 +56,6 @@ Depending on which parts of the project you are using, you might need to install
Documentation
*************

You can import the package and its submodules as usual, for example:

.. code-block:: python
from pylocus import algorithms
Xhat = algorithms.reconstruct_mds(...)
or

.. code-block:: python
from pylocus.algorithms import *
Xhat = reconstruct_mds(...)
See the tutorials folder for some exmaple scripts on how to use this package. More scripts will be added soon.

Documentation of all available functionalities can be found on ReadTheDocs: http://pylocus.readthedocs.org/en/latest/
This is a constantly growing package and documentation is work-in-progress. The current version can be found on ReadTheDocs: http://pylocus.readthedocs.org/en/latest/
89 changes: 57 additions & 32 deletions pylocus/algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,53 @@
# module ALGORITHMS
import numpy as np


def execute_method(method, noisy_edm=None, real_points=None, W=None, z=None, **kwargs):
IMPLEMENTED_METHODS = ['MDS',
'MDSoptspace',
'MDSalternate',
'SDR',
'ACD',
'dwMDS',
'SRLS']


def execute_method(method, measured_matrix=None, all_points=None, W=None, **kwargs):
if method not in IMPLEMENTED_METHODS:
raise NotImplementedError(
'method {} is not implemented.'.format(method))
if method == 'MDS':
xhat = reconstruct_mds(
noisy_edm, real_points=real_points, method='geometric')
measured_matrix, all_points=all_points, method='geometric')
if method == 'MDSoptspace':
xhat = reconstruct_mds(noisy_edm, real_points=real_points,
xhat = reconstruct_mds(measured_matrix, all_points=all_points,
method='geometric', mask=W,
completion='optspace', print_out=False)
if method == 'MDSalternate':
xhat = reconstruct_mds(noisy_edm, real_points=real_points,
xhat = reconstruct_mds(measured_matrix, all_points=all_points,
method='geometric', mask=W,
completion='alternate', print_out=False)
if method == 'SDR':
x_SDRold, EDMbest = reconstruct_sdp(
noisy_edm, W=W, real_points=real_points)
x_SDRold, __ = reconstruct_sdp(
measured_matrix, W=W, all_points=all_points)
# TODO
# Added to avoid strange "too large to be a matrix" error
N, d = real_points.shape
N, d = all_points.shape
xhat = np.zeros((N, d))
xhat[:, :] = x_SDRold
if method == 'ACD':
X0 = kwargs.get('X0', None)
xhat, costs = reconstruct_acd(noisy_edm, W=W, X0=X0)
if X0 is None:
raise NameError('Need to provide X0 for method ACD.')
xhat, costs = reconstruct_acd(measured_matrix, W=W, X0=X0)
if method == 'dwMDS':
X0 = kwargs.pop('X0', None)
xhat, costs = reconstruct_dwmds(noisy_edm, W=W, X0=X0, **kwargs)
if X0 is None:
raise NameError('Need to provide X0 for method dwMDS.')
xhat, costs = reconstruct_dwmds(measured_matrix, W=W, X0=X0, **kwargs)
if method == 'SRLS':
n = kwargs.get('n', None)
n = kwargs.get('n', 1)
z = kwargs.get('z', None)
rescale = kwargs.get('rescale', False)
xhat = reconstruct_srls(noisy_edm, real_points,
xhat = reconstruct_srls(measured_matrix, all_points,
n=n, W=W, rescale=rescale, z=z)
return xhat

Expand Down Expand Up @@ -95,16 +112,16 @@ def centralize(X):
return X_transformed, R, t, c


def reconstruct_emds(edm, Om, real_points, method=None, **kwargs):
def reconstruct_emds(edm, Om, all_points, method=None, **kwargs):
""" Reconstruct point set using E(dge)-MDS.
"""
from .point_set import dm_from_edm
N = real_points.shape[0]
d = real_points.shape[1]
N = all_points.shape[0]
d = all_points.shape[1]
dm = dm_from_edm(edm)
if method is None:
from .mds import superMDS
Xhat, __ = superMDS(real_points[0, :], N, d, Om=Om, dm=dm)
Xhat, __ = superMDS(all_points[0, :], N, d, Om=Om, dm=dm)
else:
C = kwargs.get('C', None)
b = kwargs.get('b', None)
Expand All @@ -115,24 +132,24 @@ def reconstruct_emds(edm, Om, real_points, method=None, **kwargs):
if method == 'iterative':
from .mds import iterativeEMDS
Xhat, __ = iterativeEMDS(
real_points[0, :], N, d, KE=KE_noisy, C=C, b=b)
all_points[0, :], N, d, KE=KE_noisy, C=C, b=b)
elif method == 'relaxed':
from .mds import relaxedEMDS
Xhat, __ = relaxedEMDS(
real_points[0, :], N, d, KE=KE_noisy, C=C, b=b)
all_points[0, :], N, d, KE=KE_noisy, C=C, b=b)
else:
raise NameError('Undefined method', method)
Y, R, t, c = procrustes(real_points, Xhat, scale=False)
Y, R, t, c = procrustes(all_points, Xhat, scale=False)
return Y


def reconstruct_cdm(dm, absolute_angles, real_points, W=None):
def reconstruct_cdm(dm, absolute_angles, all_points, W=None):
""" Reconstruct point set from angle and distance measurements, using coordinate difference matrices.
"""
from pylocus.point_set import dmi_from_V, sdm_from_dmi, get_V
from pylocus.mds import signedMDS

N = real_points.shape[0]
N = all_points.shape[0]

V = get_V(absolute_angles, dm)

Expand All @@ -146,17 +163,17 @@ def reconstruct_cdm(dm, absolute_angles, real_points, W=None):
points_y = signedMDS(sdmy, W)

Xhat = np.c_[points_x, points_y]
Y, R, t, c = procrustes(real_points, Xhat, scale=False)
Y, R, t, c = procrustes(all_points, Xhat, scale=False)
return Y


def reconstruct_mds(edm, real_points, completion='optspace', mask=None, method='geometric', print_out=False, n=1):
def reconstruct_mds(edm, all_points, completion='optspace', mask=None, method='geometric', print_out=False, n=1):
""" Reconstruct point set using MDS and matrix completion algorithms.
"""
from .point_set import dm_from_edm
from .mds import MDS
N = real_points.shape[0]
d = real_points.shape[1]
N = all_points.shape[0]
d = all_points.shape[1]
if mask is not None:
edm_missing = np.multiply(edm, mask)
if completion == 'optspace':
Expand All @@ -174,30 +191,30 @@ def reconstruct_mds(edm, real_points, completion='optspace', mask=None, method='
print('{}: relative error:{}'.format(completion, err))
edm = edm_complete
Xhat = MDS(edm, d, method, False).T
Y, R, t, c = procrustes(real_points[n:], Xhat, True)
#Y, R, t, c = procrustes(real_points, Xhat, True)
Y, R, t, c = procrustes(all_points[n:], Xhat, True)
#Y, R, t, c = procrustes(all_points, Xhat, True)
return Y


def reconstruct_sdp(edm, real_points, W=None, print_out=False, lamda=1000, **kwargs):
def reconstruct_sdp(edm, all_points, W=None, print_out=False, lamda=1000, **kwargs):
""" Reconstruct point set using semi-definite rank relaxation.
"""
from .edm_completion import semidefinite_relaxation
edm_complete = semidefinite_relaxation(
edm, lamda=lamda, W=W, print_out=print_out, **kwargs)
Xhat = reconstruct_mds(edm_complete, real_points, method='geometric')
Xhat = reconstruct_mds(edm_complete, all_points, method='geometric')
return Xhat, edm_complete


def reconstruct_srls(edm, real_points, W=None, print_out=False, n=1, rescale=False,
def reconstruct_srls(edm, all_points, W=None, print_out=False, n=1, rescale=False,
z=None):
""" Reconstruct point set using S(quared)R(ange)L(east)S(quares) method.
"""
from .lateration import SRLS, get_lateration_parameters
Y = real_points.copy()
Y = all_points.copy()
indices = range(n)
for index in indices:
anchors, w, r2 = get_lateration_parameters(real_points, indices, index,
anchors, w, r2 = get_lateration_parameters(all_points, indices, index,
edm, W)
if print_out:
print('SRLS parameters:')
Expand All @@ -216,6 +233,9 @@ def reconstruct_acd(edm, X0, W=None, print_out=False, tol=1e-10, sweeps=10):
""" Reconstruct point set using alternating coordinate descent.
:param X0: Nxd matrix of starting points.
:param tol: Stopping criterion: if the stepsize in all coordinate directions
is less than tol for 2 consecutive sweeps, we stop.
:param sweep: Maximum number of sweeps. One sweep goes through all coordintaes and points once.
"""

def get_unique_delta(delta, i, coord, print_out=False):
Expand Down Expand Up @@ -306,8 +326,13 @@ def loop_point(i):
def reconstruct_dwmds(edm, X0, W=None, n=None, r=None, X_bar=None, print_out=False, tol=1e-10, sweeps=100):
""" Reconstruct point set using d(istributed)w(eighted) MDS.
Refer to paper "Distributed Weighted-Multidimensional Scaling for Node Localization in Sensor Networks" for
implementation details (doi.org/10.1145/1138127.1138129)
:param X0: Nxd matrix of starting points.
:param n: Number of points of unknown position. The first n points in X0 and edm are considered unknown.
:param tol: Stopping criterion: when the cost is below this level, we stop.
:param sweeps: Maximum number of sweeps.
"""
from .basics import get_edm
from .distributed_mds import get_b, get_Si
Expand Down
Loading

0 comments on commit 758c456

Please sign in to comment.