Exemplo n.º 1
0
    def SetMultinormalInitialPoints(self, mean, var=None):
        """Generate Initial Points from Multivariate Normal.

input::
    - mean must be a sequence of length self.nDim
    - var can be...
        None: -> it becomes the identity
        scalar: -> var becomes scalar * I
        matrix: -> the variance matrix. must be the right size!
        """
        from mystic.tools import random_state
        rng = random_state(module='numpy.random')
        assert (len(mean) == self.nDim)
        if var is None:
            var = numpy.eye(self.nDim)
        else:
            try:  # scalar ?
                float(var)
            except:  # nope. var better be matrix of the right size (no check)
                pass
            else:
                var = var * numpy.eye(self.nDim)
        for i in range(len(self.population)):
            self.population[i] = rng.multivariate_normal(mean, var).tolist()
        return
Exemplo n.º 2
0
    def SetMultinormalInitialPoints(self, mean, var = None):
        """Generate Initial Points from Multivariate Normal.

input::
    - mean must be a sequence of length self.nDim
    - var can be...
        None: -> it becomes the identity
        scalar: -> var becomes scalar * I
        matrix: -> the variance matrix. must be the right size!
        """
        from mystic.tools import random_state
        prng = random_state(module='numpy.random')
        assert(len(mean) == self.nDim)
        if var is None:
            var = numpy.eye(self.nDim)
        else:
            try: # scalar ?
                float(var)
            except: # nope. var better be matrix of the right size (no check)
                pass
            else:
                var = var * numpy.eye(self.nDim)
        for i in range(len(self.population)):
            self.population[i] = prng.multivariate_normal(mean, var).tolist()
        return
Exemplo n.º 3
0
def randomly_bin(N, ndim=None, ones=True, exact=True):
    """
generate N bins randomly gridded across ndim dimensions

Inputs:
    N  --  integer number of bins, where N = prod(bins)
    ndim  --  integer length of bins, thus ndim = len(bins)
    ones  --  if False, prevent bins from containing "1s", wherever possible
    exact  --  if False, find N-1 bins for prime numbers
    """
    if ndim == 0: return []
    if N == 0: return [0] if ndim else [0] * ndim
    from itertools import chain
    from mystic.tools import random_state
    try:
        xrange
    except NameError:
        xrange = range
    random = random_state().random

    def factors(n):
        result = list()
        for i in chain([2], xrange(3, n + 1, 2)):
            s = 0
            while n % i == 0:
                n //= i
                s += 1
            result.extend([i] * s)
            if n == 1:
                return result

    result = factors(N)
    dim = nfact = len(result)
    prime = nfact == 1
    if ndim:
        result += [1] * (ndim - (nfact // ndim))
        dim = ndim
    elif ones:
        result += [1]  # add some 'randomness' by adding a "1"
    # if ones, mix in the 1s; otherwise, only use 1s when ndim < len(result)
    if ones: result = sorted(result, key=lambda v: random())
    else: result[:nfact] = sorted(result[:nfact], key=lambda v: random())
    from numpy import product
    result = [product(result[i::dim]) for i in range(dim)]
    # if not ones, now needs a full sort to sort in the 1s
    if not ones: result = sorted(result, key=lambda v: random())
    elif not ndim and 1 in result: result.remove(1)  # remove the added "1"
    # if it's a prime, then do N-1 if exact=False
    if not exact and N > 3 and prime:
        result = randomly_bin(N - 1, ndim, ones)
    return result
Exemplo n.º 4
0
def _random_samples(lb,ub,npts=10000):
  """
generate npts random samples between given lb & ub

Inputs:
    lower bounds  --  a list of the lower bounds
    upper bounds  --  a list of the upper bounds
    npts  --  number of sample points [default = 10000]
"""
  from mystic.tools import random_state
  dim = len(lb)
  pts = random_state(module='numpy.random').rand(dim,npts)
  for i in range(dim):
    pts[i] = (pts[i] * abs(ub[i] - lb[i])) + lb[i]
  return pts  #XXX: returns a numpy.array
Exemplo n.º 5
0
def _random_samples(lb, ub, npts=10000):
    """
generate npts random samples between given lb & ub

Inputs:
    lower bounds  --  a list of the lower bounds
    upper bounds  --  a list of the upper bounds
    npts  --  number of sample points [default = 10000]
"""
    from mystic.tools import random_state
    dim = len(lb)
    pts = random_state(module='numpy.random').rand(dim, npts)
    for i in range(dim):
        pts[i] = (pts[i] * abs(ub[i] - lb[i])) + lb[i]
    return pts  #XXX: returns a numpy.array
Exemplo n.º 6
0
def randomly_bin(N, ndim=None, ones=True, exact=True):
    """
generate N bins randomly gridded across ndim dimensions

Inputs:
    N  --  integer number of bins, where N = prod(bins)
    ndim  --  integer length of bins, thus ndim = len(bins)
    ones  --  if False, prevent bins from containing "1s", wherever possible
    exact  --  if False, find N-1 bins for prime numbers
    """
    if ndim == 0: return []
    if N == 0: return [0] if ndim else [0]*ndim
    from itertools import chain
    from mystic.tools import random_state
    try:
        xrange
    except NameError:
        xrange = range
    random = random_state().random
    def factors(n):
        result = list()
        for i in chain([2],xrange(3,n+1,2)):
            s = 0
            while n%i == 0:
                n //= i
                s += 1
            result.extend([i]*s)
            if n == 1:
                return result
    result = factors(N)
    dim = nfact = len(result)
    prime = nfact == 1
    if ndim: result += [1] * (ndim - (nfact // ndim));  dim = ndim
    elif ones: result += [1] # add some 'randomness' by adding a "1"
    # if ones, mix in the 1s; otherwise, only use 1s when ndim < len(result)
    if ones: result = sorted(result, key=lambda v: random())
    else: result[:nfact] = sorted(result[:nfact], key=lambda v: random())
    from numpy import product
    result = [product(result[i::dim]) for i in range(dim)]
    # if not ones, now needs a full sort to sort in the 1s
    if not ones: result = sorted(result, key=lambda v: random())
    elif not ndim and 1 in result: result.remove(1) # remove the added "1"
    # if it's a prime, then do N-1 if exact=False
    if not exact and N > 3 and prime:
        result = randomly_bin(N-1, ndim, ones)
    return result
Exemplo n.º 7
0
def weighted_select(samples, weights, mass=1.0):
    """randomly select a sample from weighted set of samples

Inputs:
    samples -- a list of sample points
    weights -- a list of sample weights
    mass -- sum of normalized weights
"""
    from numpy import sum, array
    from mystic.tools import random_state
    rand = random_state().random
    # generate a list representing the weighted distribution
    wts = normalize(weights, mass)
    wts = array([sum(wts[:i + 1]) for i in range(len(wts))])
    # correct for any rounding error
    wts[-1] = mass
    # generate a random weight
    w = mass * rand()
    # select samples that corresponds to randomly selected weight
    selected = len(wts[wts <= w])
    return samples[selected]
Exemplo n.º 8
0
def weighted_select(samples, weights, mass=1.0):
  """randomly select a sample from weighted set of samples

Inputs:
    samples -- a list of sample points
    weights -- a list of sample weights
    mass -- sum of normalized weights
"""
  from numpy import sum, array
  from mystic.tools import random_state
  rand = random_state().random
  # generate a list representing the weighted distribution
  wts = normalize(weights, mass)
  wts = array([sum(wts[:i+1]) for i in range(len(wts))])
  # correct for any rounding error
  wts[-1] = mass
  # generate a random weight
  w = mass * rand()
  # select samples that corresponds to randomly selected weight
  selected = len(wts[ wts <= w ])
  return samples[selected]
Exemplo n.º 9
0
    def __init__(self, generator=None, *args, **kwds):
        """
generate a sampling distribution with interface dist(size=None)

input::
    - generator: a 'distribution' method from scipy.stats or numpy.random
    - args: positional arguments for the distribtution object
    - kwds: keyword arguments for the distribution object

note::
    this method only accepts numpy.random methods with the keyword 'size'
        """
        from mystic.tools import random_state
        rng = random_state(module='numpy.random')
        if generator is None: generator = rng.random
        if getattr(generator, 'rvs', False):
            d = generator(*args, **kwds)
            self.rvs = lambda size=None: d.rvs(size=size, random_state=rng)
        else:
            d = getattr(rng, generator.__name__)
            self.rvs = lambda size=None: d(size=size, *args, **kwds)
        return
Exemplo n.º 10
0
    def __init__(self, generator=None, *args, **kwds):
        """
generate a sampling distribution with interface dist(size=None)

input::
    - generator: a 'distribution' method from scipy.stats or numpy.random
    - args: positional arguments for the distribtution object
    - kwds: keyword arguments for the distribution object

note::
    this method only accepts numpy.random methods with the keyword 'size'
        """
        from mystic.tools import random_state
        rng = random_state(module='numpy.random')
        if generator is None: generator = rng.random
        if getattr(generator, 'rvs', False): 
            d = generator(*args, **kwds)
            self.rvs = lambda size=None: d.rvs(size=size, random_state=rng)
        else:
            d = getattr(rng, generator.__name__)
            self.rvs = lambda size=None: d(size=size, *args, **kwds)
        return
Exemplo n.º 11
0
def scem(Ck, ak, Sk, Sak, target, cn):
    """
This is the SCEM algorithm starting from line [35] of the reference [1].

- [inout] Ck is the kth 'complex' with m points. This should be an m by n array
  n being the dimensionality of the density function. i.e., the data
  are arranged in rows. 

  Ck is assumed to be sorted according to the target density.

- [inout] ak, the density of the points of Ck.

- [inout] Sk, the entire chain. (should be a list)

- [inout] Sak, the cost of the entire chain (should be a list)

  Sak would be more convenient to use if it is a numpy array, but we need
  to append to it frequently.

- [in] target: target density function

- [in] cn: jumprate. (see Paragraph 37 of [1.]

- The invariants: ak is always aligned with Ck, and are the cost of Ck
- Similarly, Sak is always aligned with Sk in the same way.

- On return... sort order in Ck/ak is destroyed. but see sort_complex2

    """
    import numpy
    from mystic.tools import random_state
    prng = random_state(module=numpy.random)

    # function level constants
    T = 100000. # predefined likelihood ratio. Paragraph 45 of [1.]

    # Sort Ck according to ak
    #Ck, ak = sort_complex0(Ck, ak) 
    #print("ak before: %s" % ak)
    #Ck, ak = sort_complex(Ck, ak) 
    sort_complex2(Ck, ak) 
    #print("ak after: %s" % ak)

    # number of points per complex
    M = Ck.shape[0]

    mu = numpy.mean(Ck,0) # row mean

    # (numpy.cov takes data in columns)
    Sigma = numpy.cov(numpy.transpose(Ck)) 

    # Gamma (line 35 of [1]. Best to Worst)
    Gamma = ak[0] / (ak[-1]+TINY)
   
    if len(Sak) >= M:
        meansak = numpy.mean(Sak[-M:])
    else:
        meansak = numpy.mean(Sak)
    alpha_k = numpy.mean(ak) / (meansak+TINY)
  
    if alpha_k < T:
         # Paragraph 37 of [1]
         basept = Sk[-1]
    else: # numpy.mean(asak) is very close to zero.
         # Paragraph 38 of [1]
         basept = mu

    # TODO should take a proposal instead !
    Yt = prng.multivariate_normal(basept, cn*cn * Sigma)
    cY = target(Yt)    

    # print("new/orig : %s %s" % (cY, Sak[-1]))

    r = min( cY / (Sak[-1]+TINY), 1)

    if prng.rand() <= r:
        Sk.append(Yt)
        Sak.append(cY)
        # Paragraph 43 of [1] (update the best of Ck)
        Ck[0], ak[0] = Sk[-1], Sak[-1]
    else:
        Sk.append(Sk[-1])
        Sak.append(Sak[-1])
        if Gamma > T and Sak[-1] > ak[-1]:
            # Paragraph 43 of [1] (update the worst of Ck)
            Ck[-1], ak[-1] = Sk[-1], Sak[-1]

    # mainly because of the logic in Paragraph [43] that updates the complex,
    # this function is not "functional" and modifies its argument instead.
    # hence no return value
    return     
Exemplo n.º 12
0
def scem(Ck, ak, Sk, Sak, target, cn):
    """
This is the SCEM algorithm starting from line [35] of the reference [1].

- [inout] Ck is the kth 'complex' with m points. This should be an m by n array
  n being the dimensionality of the density function. i.e., the data
  are arranged in rows. 

  Ck is assumed to be sorted according to the target density.

- [inout] ak, the density of the points of Ck.

- [inout] Sk, the entire chain. (should be a list)

- [inout] Sak, the cost of the entire chain (should be a list)

  Sak would be more convenient to use if it is a numpy array, but we need
  to append to it frequently.

- [in] target: target density function

- [in] cn: jumprate. (see Paragraph 37 of [1.]

- The invariants: ak is always aligned with Ck, and are the cost of Ck
- Similarly, Sak is always aligned with Sk in the same way.

- On return... sort order in Ck/ak is destroyed. but see sort_complex2

    """
    import numpy
    from mystic.tools import random_state
    prng = random_state(module=numpy.random)

    # function level constants
    T = 100000. # predefined likelihood ratio. Paragraph 45 of [1.]

    # Sort Ck according to ak
    #Ck, ak = sort_complex0(Ck, ak) 
    #print("ak before: %s" % ak)
    #Ck, ak = sort_complex(Ck, ak) 
    sort_complex2(Ck, ak) 
    #print("ak after: %s" % ak)

    # number of points per complex
    M = Ck.shape[0]

    mu = numpy.mean(Ck,0) # row mean

    # (numpy.cov takes data in columns)
    Sigma = numpy.cov(numpy.transpose(Ck)) 

    # Gamma (line 35 of [1]. Best to Worst)
    Gamma = ak[0] / (ak[-1]+TINY)
   
    if len(Sak) >= M:
        meansak = numpy.mean(Sak[-M:])
    else:
        meansak = numpy.mean(Sak)
    alpha_k = numpy.mean(ak) / (meansak+TINY)
  
    if alpha_k < T:
         # Paragraph 37 of [1]
         basept = Sk[-1]
    else: # numpy.mean(asak) is very close to zero.
         # Paragraph 38 of [1]
         basept = mu

    # TODO should take a proposal instead !
    Yt = prng.multivariate_normal(basept, cn*cn * Sigma)
    cY = target(Yt)    

    # print("new/orig : %s %s" % (cY, Sak[-1]))

    r = min( cY / (Sak[-1]+TINY), 1)

    if prng.rand() <= r:
        Sk.append(Yt)
        Sak.append(cY)
        # Paragraph 43 of [1] (update the best of Ck)
        Ck[0], ak[0] = Sk[-1], Sak[-1]
    else:
        Sk.append(Sk[-1])
        Sak.append(Sak[-1])
        if Gamma > T and Sak[-1] > ak[-1]:
            # Paragraph 43 of [1] (update the worst of Ck)
            Ck[-1], ak[-1] = Sk[-1], Sak[-1]

    # mainly because of the logic in Paragraph [43] that updates the complex,
    # this function is not "functional" and modifies its argument instead.
    # hence no return value
    return