Changeset 824 for mystic


Ignore:
Timestamp:
09/04/15 08:00:51 (9 months ago)
Author:
mmckerns
Message:

reconcile Lnorm and minkowski, add hamming distance;
fix Lnorm and minkowski behavior at large p; allow default xp of zeros

File:
1 edited

Legend:

Unmodified
Added
Removed
  • mystic/_math/distance.py

    r822 r824  
    2020  # weights is a numpy array 
    2121  # p is an int 
     22  from numpy import asarray, seterr, inf 
     23  weights = asarray(weights).flatten() 
    2224  if not p: 
    2325    w = float(len(weights[weights != 0.0])) # total number of nonzero elements 
     26  elif p == inf: 
     27    w = float(max(abs(weights))) 
    2428  else: 
    25     w = float(sum(abs(weights**p)))**(1./p) 
     29    orig = seterr(over='raise', invalid='raise') 
     30    try: 
     31      w = float(sum(abs(weights**p)))**(1./p) 
     32    except FloatingPointError: # use the infinity norm 
     33      w = float(max(abs(weights))) 
     34    seterr(**orig) 
    2635  return w 
    2736 
    28 def absolute_distance(x, xp, up=False, dmin=0): 
     37def absolute_distance(x, xp=None, up=False, dmin=0): 
    2938  """distance = |x - x'|;  (see euclidean_distance for notes)""" 
    30   from numpy import abs, asarray, newaxis as nwxs 
     39  from numpy import abs, asarray, newaxis as nwxs, zeros_like 
    3140  from __builtin__ import max 
    3241  # cast as arrays of the same dimension 
    33   x = asarray(x); xp = asarray(xp) 
     42  x = asarray(x) 
     43  xp = zeros_like(x) if xp is None else asarray(xp) 
    3444  xsize = max(len(x.shape), len(xp.shape), dmin) 
    3545  while len(x.shape) < xsize: x = x[nwxs] 
     
    3949  return abs(x - xp) 
    4050 
    41 def euclidean_distance(x, xp, up=True, dmin=0): 
     51def euclidean_distance(x, xp=None, up=True, dmin=0): 
    4252  """1-D euclidean distance between points 
    4353 
     
    5464  return absolute_distance(x,xp,up=up,dmin=dmin).swapaxes(0,1).T 
    5565 
    56 def manhattan_distance(x, xp, **kwds): 
     66def manhattan_distance(x, xp=None, **kwds): 
    5767  """1-D manhattan distance between points 
    5868 
     
    6575  # dmin: force upconvert to x,x' to dimension >= dmin 
    6676  dmin = kwds['dmin'] if 'dmin' in kwds else 0 # default dimension 
    67   from numpy import abs, asarray, newaxis as nwxs 
     77  from numpy import abs, asarray, newaxis as nwxs, zeros_like 
    6878  from __builtin__ import max 
    6979  # cast as arrays of the same dimension 
    70   x = asarray(x); xp = asarray(xp) 
     80  x = asarray(x) 
     81  xp = zeros_like(x) if xp is None else asarray(xp) 
    7182  xsize = max(len(x.shape), len(xp.shape), dmin) 
    7283  while len(x.shape) < xsize: x = x[nwxs] 
     
    8697############################################################################### 
    8798 
    88 def lipschitz_metric(L, x, xp): 
     99def lipschitz_metric(L, x, xp=None): 
    89100  """sum of lipschitz-weighted distance between points 
    90101 
     
    119130########################################################################### 
    120131 
    121 def chebyshev(x,xp, up=True, dmin=0, axis=None): 
     132def chebyshev(x,xp=None, up=True, dmin=0, axis=None): 
    122133  """infinity norm distance between points in euclidean space 
    123134 
     
    138149""" 
    139150  d = euclidean_distance(x,xp,up=up,dmin=dmin) 
    140   from numpy import max 
    141   return max(d, axis=axis) 
    142  
    143  
    144 def minkowski(x,xp, up=True, dmin=0, p=3, axis=None): 
     151  return d.max(axis=axis).astype(float) 
     152 
     153 
     154def hamming(x,xp=None, up=True, dmin=0, axis=None): 
     155  """zero 'norm' distance between points in euclidean space 
     156 
     157  d(0) =  sum( x[0] != x[0]', x[1] != x[1]', ..., x[n] != x[n]' )  
     158 
     159Input: 
     160  x    = array of points, x 
     161  xp   = array pf points, x' 
     162 
     163Additional Input: 
     164  up   = True if upconvert x with x[:,newaxis] 
     165  dmin = upconvert to x,x' to dimension >= dmin 
     166  axis = if not None, reduce across the selected axis 
     167 
     168Notes: 
     169  for standard array behavior, use up=False 
     170  for element-wise across all elements, use up=True 
     171""" 
     172  d = euclidean_distance(x,xp,up=up,dmin=dmin) 
     173  return d.astype(bool).sum(axis=axis).astype(float) 
     174 
     175 
     176def minkowski(x,xp=None, up=True, dmin=0, p=3, axis=None): 
    145177  """p-norm distance between points in euclidean space 
    146178 
     
    161193  for element-wise across all elements, use up=True 
    162194""" 
     195  from numpy import seterr, inf 
     196  if p == inf: return chebyshev(x,xp,up=up,dmin=dmin,axis=axis) 
    163197  d = euclidean_distance(x,xp,up=up,dmin=dmin) 
    164   from numpy import sum 
    165   return sum(d**p, axis=axis)**(1./p) 
    166  
    167  
    168 def euclidean(x,xp, up=True, dmin=0, axis=None): 
     198  orig = seterr(over='raise', invalid='raise') 
     199  try: 
     200      d = (d**p).sum(axis=axis)**(1./p) 
     201  except FloatingPointError: # use the infinity norm 
     202      d = d.max(axis=axis).astype(float) 
     203  seterr(**orig) 
     204  return d 
     205 
     206 
     207def euclidean(x,xp=None, up=True, dmin=0, axis=None): 
    169208  """L-2 norm distance between points in euclidean space 
    170209 
     
    187226 
    188227 
    189 def manhattan(x,xp, up=True, dmin=0, axis=None): 
     228def manhattan(x,xp=None, up=True, dmin=0, axis=None): 
    190229  """L-1 norm distance between points in euclidean space 
    191230 
Note: See TracChangeset for help on using the changeset viewer.