Skip to content

Commit

Permalink
Fix elfi.Distance to support scipy 1.0.0 (#249)
Browse files Browse the repository at this point in the history
  • Loading branch information
vuolleko committed Nov 7, 2017
1 parent 7d92eda commit cfe0347
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ dev
- Implemented the Two Stage Procedure, a method of summary-statistics diagnostics
- Added the MaxVar acquisition method
- Added the RandMaxVar acquisition method
- Fix elfi.Distance to support scipy 1.0.0

0.6.3 (2017-09-28)
------------------
Expand Down
35 changes: 18 additions & 17 deletions elfi/model/elfi_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -968,7 +968,7 @@ def __init__(self, discrepancy, *parents, **kwargs):
class Distance(Discrepancy):
"""A convenience class for the discrepancy node."""

def __init__(self, distance, *summaries, p=None, w=None, V=None, VI=None, **kwargs):
def __init__(self, distance, *summaries, **kwargs):
"""Initialize a distance node of an ELFI graph.
This class contains many common distance implementations through scipy.
Expand All @@ -983,18 +983,12 @@ def __init__(self, distance, *summaries, p=None, w=None, V=None, VI=None, **kwar
that contains the observed values (summaries). The callable should return
a vector of distances between the simulated summaries and the observed
summaries.
summaries
summary nodes of the model
p : double, optional
The p-norm to apply Only for distance Minkowski (`'minkowski'`), weighted
and unweighted. Default: 2.
w : ndarray, optional
The weight vector. Only for weighted Minkowski (`'wminkowski'`). Mandatory.
V : ndarray, optional
The variance vector. Only for standardized Euclidean (`'seuclidean'`).
Mandatory.
VI : ndarray, optional
The inverse of the covariance matrix. Only for Mahalanobis. Mandatory.
*summaries
Summary nodes of the model.
**kwargs
Additional parameters may be required depending on the chosen distance.
See the scipy documentation. (The support is not exhaustive.)
ELFI-related kwargs are passed on to elfi.Discrepancy.
Examples
--------
Expand All @@ -1021,16 +1015,23 @@ def __init__(self, distance, *summaries, p=None, w=None, V=None, VI=None, **kwar
raise ValueError("This node requires that at least one parent is specified.")

if isinstance(distance, str):
if distance == 'wminkowski' and w is None:
cdist_kwargs = dict(metric=distance)
if distance == 'wminkowski' and 'w' not in kwargs.keys():
raise ValueError('Parameter w must be specified for distance=wminkowski.')
if distance == 'seuclidean' and V is None:
elif distance == 'seuclidean' and 'V' not in kwargs.keys():
raise ValueError('Parameter V must be specified for distance=seuclidean.')
if distance == 'mahalanobis' and VI is None:
elif distance == 'mahalanobis' and 'VI' not in kwargs.keys():
raise ValueError('Parameter VI must be specified for distance=mahalanobis.')
cdist_kwargs = dict(metric=distance, p=p, w=w, V=V, VI=VI)

# extract appropriate keyword arguments (depends on distance, not exhaustive!)
for key in ['p', 'w', 'V', 'VI']:
if key in kwargs.keys():
cdist_kwargs[key] = kwargs.pop(key)

dist_fn = partial(scipy.spatial.distance.cdist, **cdist_kwargs)
else:
dist_fn = distance

discrepancy = partial(distance_as_discrepancy, dist_fn)
super(Distance, self).__init__(discrepancy, *summaries, **kwargs)
# Store the original passed distance
Expand Down

0 comments on commit cfe0347

Please sign in to comment.