Changeset 821


Ignore:
Timestamp:
08/13/15 12:51:47 (9 months ago)
Author:
mmckerns
Message:

normalize with prior behavior, with Ln-norm included; default mass from 1 to L2

Location:
mystic
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • mystic/_math/discrete.py

    r776 r821  
    894894""" 
    895895  from mystic.math.measures import normalize 
    896   return [normalize([1.]*len(xi)) for xi in samples] 
     896  return [normalize([1.]*len(xi), 1.0) for xi in samples] 
    897897 
    898898 
  • mystic/_math/measures.py

    r820 r821  
    374374 
    375375##### weight shift methods ##### 
    376 def impose_weight_norm(samples, weights, mass=None): 
     376def impose_weight_norm(samples, weights, mass=1.0): 
    377377  """normalize the weights for a list of (weighted) points 
    378378  (this function is 'mean-preserving') 
     
    381381    samples -- a list of sample points 
    382382    weights -- a list of sample weights 
    383     mass -- target of normalized weights 
     383    mass -- float target of normalized weights 
    384384""" 
    385385  m = mean(samples, weights) 
    386   wts = normalize(weights,mass) #NOTE: not "mean-preserving", until next line 
     386  wts = normalize(weights,mass) #NOTE: not mean-preserving, until next line 
    387387  return impose_mean(m, samples, wts), wts 
    388388 
    389389 
    390 def normalize(weights, mass=None, zsum=False, zmass=1.0, l=1): 
     390def Lnorm(weights, n=1): 
     391  "calculate L-n norm of weights" 
     392  # weights is a numpy array 
     393  # n is an int 
     394  if not n: 
     395    w = float(len(weights[weights != 0.0])) # total number of nonzero elements 
     396  else: 
     397    w = float(sum(abs(weights**n)))**(1./n) 
     398  return w 
     399 
     400 
     401def normalize(weights, mass='l2', zsum=False, zmass=1.0): 
    391402  """normalize a list of points (e.g. normalize to 1.0) 
    392403 
    393404Inputs: 
    394405    weights -- a list of sample weights 
    395     mass -- target of normalized weights 
     406    mass -- float target of normalized weights (or string for Ln norm) 
    396407    zsum -- use counterbalance when mass = 0.0 
    397408    zmass -- member scaling when mass = 0.0 
    398     l -- integer power for the norm (i.e. l=1 is the L1 norm) 
    399  
    400 Note: if mass is None, use mass = sum(weights)/sum(abs(weights)) 
    401 """ 
    402   l = int(l) 
     409 
     410Note: if mass='l1', will use L1-norm; if mass='l2' will use L2-norm; etc. 
     411""" 
     412  try: 
     413    mass = int(mass.lstrip('l')) 
     414    fixed = False 
     415  except AttributeError: 
     416    fixed = True 
    403417  weights = asarray(list(weights)) #XXX: faster to use x = array(x, copy=True) ? 
    404   if mass is None: 
    405     mass = sum(weights)/sum(abs(weights)) #XXX: correct? 
    406     if not mass: mass = None 
    407   if not l: 
    408     w = float(len(weights[weights != 0.0])) # total number of nonzero elements 
     418 
     419  if fixed: 
     420    w = sum(abs(weights)) 
    409421  else: 
    410     w = float(sum(weights**l))**(1./l) 
    411   if not w:  #XXX: is this the best behavior? 
    412     if mass is None: 
    413       w = sum(abs(weights)); mass = 1.0 # XXX: correct? 
    414     else: 
     422    mass = int(min(200, mass)) # x**200 is ~ x**inf 
     423    w = Lnorm(weights,mass) 
     424    mass = 1.0 
     425 
     426  if not w: 
     427    if not zsum: return list(weights * 0.0) 
     428    from numpy import inf, nan 
     429    weights[weights == 0.0] = nan 
     430    return list(weights * inf)  # protect against ZeroDivision 
     431 
     432  if float(mass) or not zsum: 
     433    w = weights / w #FIXME: not "mean-preserving" 
     434    if not fixed: return list(w) # <- scaled so sum(abs(x)) = 1 
     435    #REMAINING ARE fixed mean 
     436    m = sum(w) 
     437    w = mass * w 
     438    if not m:  #XXX: do similar to zsum (i.e. shift) when sum(weights)==0 ? 
     439      if not zsum: return list(weights * 0.0) 
    415440      from numpy import inf, nan 
    416441      weights[weights == 0.0] = nan 
    417442      return list(weights * inf)  # protect against ZeroDivision 
    418   if mass is None: mass = 1.0 
    419   if float(mass) or not zsum: 
    420     return list(mass * weights / w)  #FIXME: not "mean-preserving" 
     443    return list(w/m) # <- scaled so sum(x) = 1 
     444 
    421445  # force selected member to satisfy sum = 0.0 
    422446  zsum = -1 
    423   if not l: 
    424     weights[:] = 0.0 #XXX: correct? 
    425   else: 
    426     weights[zsum] = (-(w**l - weights[zsum]**l))**(1./l) 
     447  weights[zsum] = -(sum(weights) - weights[zsum]) 
    427448  mass = zmass 
    428449  return list(mass * weights / w)  #FIXME: not "mean-preserving" 
  • mystic/examples2/cvxqp_alt2.py

    r811 r821  
    1515 
    1616def constraint(x): # impose exactly 
    17     return normalize(x) 
     17    return normalize(x, 1.0) 
    1818 
    1919 
  • mystic/tests/test_dirac_measure.py

    r776 r821  
    4646  if disp: print "weights (when normalized to 0.0): %s" % weights 
    4747  assert almostEqual(sum(weights), 0.0, tol=1e-15) 
    48   weights = normalize(wts) 
     48  weights = normalize(wts, 1.0) 
    4949  assert almostEqual(sum(weights), 1.0, tol=1e-15) 
    5050  if disp: print "weights (when normalized to 1.0): %s" % weights 
Note: See TracChangeset for help on using the changeset viewer.