Пример #1
0
    def timeForSimilarity(self, similarity, freqs=None):
        """Returns time exponent so that exp(q*time) diverges to right distance.

        Takes symbol freqs into account if specified; otherwise assumes equal.

        freqs: vector of frequencies, applied to each row successively.

        NOTE: harder to understand, but a factor of 5 faster than the naive
        version. The nested matrixmultiply calls have the same effect as
        exponentiating the matrix.
        """
        #if there's no change, the time is 0
        if similarity == 1:
            return 0.0
        #try fast version first, but if it fails we'll use the naive version.
        try:
            u, v, w = self._diagonalized
            if freqs is None:
                def similarity_f(t):
                    return abs(average(diagonal(dot(u, \
                    dot(diag(exp(v*t)), w)))) - similarity)
            else:
                def similarity_f(t):
                    return abs(sum(diagonal(dot(u, \
                    dot(diag(exp(v*t)), w)))*freqs) - similarity)
        except (TypeError, ValueError):
            #get here if diagonalization fails
            q = self._data
            if freqs is None:
                def similarity_f(t):
                    return abs(average(diagonal(expm(q)(t)))-similarity)
            else:
                def similarity_f(t):
                    return abs(sum(diagonal(expm(q)(t)*freqs))-similarity)
        return brent(similarity_f)
Пример #2
0
    def timeForSimilarity(self, similarity, freqs=None):
        """Returns time exponent so that exp(q*time) diverges to right distance.

        Takes symbol freqs into account if specified; otherwise assumes equal.

        freqs: vector of frequencies, applied to each row successively.

        NOTE: harder to understand, but a factor of 5 faster than the naive
        version. The nested matrixmultiply calls have the same effect as
        exponentiating the matrix.
        """
        #if there's no change, the time is 0
        if similarity == 1:
            return 0.0
        #try fast version first, but if it fails we'll use the naive version.
        try:
            u, v, w = self._diagonalized
            if freqs is None:
                def similarity_f(t):
                    return abs(average(diagonal(dot(u, \
                    dot(diag(exp(v*t)), w)))) - similarity)
            else:
                def similarity_f(t):
                    return abs(sum(diagonal(dot(u, \
                    dot(diag(exp(v*t)), w)))*freqs) - similarity)
        except (TypeError, ValueError):
            #get here if diagonalization fails
            q = self._data
            if freqs is None:
                def similarity_f(t):
                    return abs(average(diagonal(expm(q)(t)))-similarity)
            else:
                def similarity_f(t):
                    return abs(sum(diagonal(expm(q)(t)*freqs))-similarity)
        return brent(similarity_f)
Пример #3
0
def bound_brent(func, brack=None, **kw):
    """Given a function and an initial point, find another
    point within the bounds, then use the two points to
    bracket a minimum.
    
    This differs from ordinary brent() only in that it protects
    bracket() from infinities.  bracket() may find an infinity as the
    third point, but that's OK because it finishes as soon as that happens.
    
    If bracket() returns an invalid 3rd point then we will pass it on
    to brent(), but brent() knows to use golden section until all 3
    points are finite so it will cope OK.
    """

    assert not brack, brack
    xa = 0.0
    fa = func(xa)
    assert fa is not numpy.inf, "Starting point is infinite"

    # if dx sends us over the boundry shrink and reflect it until
    # it doesn't any more.
    dx = -2.0  # this would be -2.0 in orig impl, but is smaller better?
    xb = xa + dx
    fb = numpy.inf
    while fb is numpy.inf and xb != xa:
        dx = dx * -0.5
        xb = xa + dx
        fb = func(xb)
    assert xb != xa, "Can't find a second in-bounds point on this line"
    return brent(func, brack=(xa, xb), **kw)
Пример #4
0
def bound_brent(func, brack=None, **kw):
    """Given a function and an initial point, find another
    point within the bounds, then use the two points to
    bracket a minimum.
    
    This differs from ordinary brent() only in that it protects
    bracket() from infinities.  bracket() may find an infinity as the
    third point, but that's OK because it finishes as soon as that happens.
    
    If bracket() returns an invalid 3rd point then we will pass it on
    to brent(), but brent() knows to use golden section until all 3
    points are finite so it will cope OK.
    """
    
    assert not brack, brack
    xa = 0.0
    fa = func(xa)
    assert fa is not numpy.inf, "Starting point is infinite"
    
    # if dx sends us over the boundry shrink and reflect it until
    # it doesn't any more.
    dx = -2.0  # this would be -2.0 in orig impl, but is smaller better?
    xb = xa + dx
    fb = numpy.inf
    while fb is numpy.inf and xb != xa:
        dx = dx * -0.5
        xb = xa + dx
        fb = func(xb)
    assert xb != xa, "Can't find a second in-bounds point on this line"
    return brent(func, brack=(xa, xb), **kw)