示例#1
0
def truncate_eigenvalues(evals, ev_min=None, ev_max=None):
    """Truncate the vector ``evals`` so that values lower than
    ``ev_min`` are replaced with ``ev_min`` and values larger than
    ``ev_max`` are replaced with ``ev_max``.

    Parameters
    ------------
    evals: `np.ndarray` (N, )
    ev_min: `float`, optional
        If ``None``, no lower truncation is done.
    ev_max: `float`, optional
        If ``None``, no upper truncation is done.

    Returns
    ---------
    eig_val_trunc
        A truncated version of ``evals``.
    """
    eig_val_trunc = copy.deepcopy(evals)
    if not ev_min is None:
        if not np.isreal(ev_min):
            raise ValueError('ev_min must be real-valued.')
        ev_min = float(ev_min)
        eig_val_trunc[np.real(eig_val_trunc) <= ev_min] = ev_min
    if not ev_max is None:
        if not np.isreal(ev_max):
            raise ValueError('ev_max must be real-valued.')
        ev_max = float(ev_max)
        eig_val_trunc[np.real(eig_val_trunc) >= ev_max] = ev_max
    return eig_val_trunc
示例#2
0
 def test_inner(self):
     X = self.man.rand()
     G = self.man.randvec(X)
     H = self.man.randvec(X)
     np_testing.assert_almost_equal(np.real(np.trace(np.conjugate(G.T)@H)),
                                    self.man.inner(X, G, H))
     assert np.isreal(self.man.inner(X, G, H))
示例#3
0
 def test_inner(self):
     X = self.man.rand()
     G = self.man.randvec(X)
     H = self.man.randvec(X)
     np_testing.assert_allclose(
         np.real(np.sum(np.conjugate(G) * H)),
         self.man.inner(X, G, H))
     assert np.isreal(self.man.inner(X, G, H))
 def test_inner_product(self):
     X = self.manifold.random_point()
     G = self.manifold.random_tangent_vector(X)
     H = self.manifold.random_tangent_vector(X)
     np_testing.assert_almost_equal(
         np.real(np.trace(np.conjugate(G.T) @ H)),
         self.manifold.inner_product(X, G, H),
     )
     assert np.isreal(self.manifold.inner_product(X, G, H))
 def test_inner_product(self):
     X = self.manifold.random_point()
     G = self.manifold.random_tangent_vector(X)
     H = self.manifold.random_tangent_vector(X)
     np_testing.assert_allclose(
         np.real(np.sum(np.conjugate(G) * H)),
         self.manifold.inner_product(X, G, H),
     )
     assert np.isreal(self.manifold.inner_product(X, G, H))
示例#6
0
def polyinterp(points, doPlot=None, xminBound=None, xmaxBound=None):
    """ polynomial interpolation
    Parameters
    ----------
    points: shape(pointNum, 3), three columns represents x, f, g
    doPolot: set to 1 to plot, default 0
    xmin: min value that brackets minimum (default: min of points)
    xmax: max value that brackets maximum (default: max of points)
    
    set f or g to sqrt(-1)=1j if they are not known
    the order of the polynomial is the number of known f and g values minus 1

    Returns
    -------
    minPos:
    fmin:
    """
    
    if doPlot == None:
        doPlot = 0

    nPoints = points.shape[0]
    order = np.sum(np.imag(points[:, 1:3]) == 0) -1
    
    # code for most common case: cubic interpolation of 2 points
    if nPoints == 2 and order == 3 and doPlot == 0:
        [minVal, minPos] = [np.min(points[:,0]), np.argmin(points[:,0])]
        notMinPos = 1 - minPos
        d1 = points[minPos,2] + points[notMinPos,2] - 3*(points[minPos,1]-\
                points[notMinPos,1])/(points[minPos,0]-points[notMinPos,0])

        t_d2 =  d1**2 - points[minPos,2]*points[notMinPos,2]
        if t_d2 > 0:
            d2 = np.sqrt(t_d2)
        else:
            d2 = np.sqrt(-t_d2) * np.complex(0,1)
        if np.isreal(d2):
            t = points[notMinPos,0] - (points[notMinPos,0]-points[minPos,0])*\
                    ((points[notMinPos,2]+d2-d1)/(points[notMinPos,2]-\
                    points[minPos,2]+2*d2))
            minPos = np.min([np.max([t,points[minPos,0]]), points[notMinPos,0]])
        else:
            minPos = np.mean(points[:,0])
        fmin = minVal
        return (minPos, fmin)
    
    xmin = np.min(points[:,0])
    xmax = np.max(points[:,0])

    # compute bounds of interpolation area
    if xminBound == None:
        xminBound = xmin
    if xmaxBound == None:
        xmaxBound = xmax

    # constraints based on available function values
    A = np.zeros((0, order+1))
    b = np.zeros((0, 1))
    for i in range(nPoints):
        if np.imag(points[i,1]) == 0:
            constraint = np.zeros(order+1)
            for j in np.arange(order,-1,-1):
                constraint[order-j] = points[i,0]**j
            A = np.vstack((A, constraint))
            b = np.append(b, points[i,1])
    
    # constraints based on availabe derivatives
    for i in range(nPoints):
        if np.isreal(points[i,2]):
            constraint = np.zeros(order+1)
            for j in range(1,order+1):
                constraint[j-1] = (order-j+1)* points[i,0]**(order-j)
            A = np.vstack((A, constraint))
            b = np.append(b,points[i,2])
    
    # find interpolating polynomial
    params = np.linalg.solve(A, b)

    # compute critical points
    dParams = np.zeros(order)
    for i in range(params.size-1):
        dParams[i] = params[i] * (order-i)
    
    if np.any(np.isinf(dParams)):
        cp = np.concatenate((np.array([xminBound, xmaxBound]), points[:,0]))
    else:
        cp = np.concatenate((np.array([xminBound, xmaxBound]), points[:,0], \
                np.roots(dParams)))
    
    # test critical points
    fmin = np.infty;
    minPos = (xminBound + xmaxBound)/2.
    for xCP in cp:
        if np.imag(xCP) == 0 and xCP >= xminBound and xCP <= xmaxBound:
            fCP = np.polyval(params, xCP)
            if np.imag(fCP) == 0 and fCP < fmin:
                minPos = np.double(np.real(xCP))
                fmin = np.double(np.real(fCP))
    
    # plot situation (omit this part for now since we are not going to use it
    # anyway)

    return (minPos, fmin)
示例#7
0
    def calc_step(self, x, trust_radius, obj):
        tags = []
        method = self.setting.step_method
        if method == 'dogleg':
            n = x.size
            g = obj.gradient(x)
            H = obj.hessian(x)
            B = posdefify(H, self.setting.pos_hess_eps)

            # Find the minimizing tau along the dogleg path
            pU = -(np.dot(g, g) / np.dot(g, np.dot(B, g))) * g
            pB = -la.solve(B, g)
            dp = pB - pU
            if la.norm(pB) <= trust_radius:
                # Minimum of model lies inside the trust region
                p = np.copy(pB)
            else:
                # Minimum of model lies outside the trust region
                tau_U = trust_radius / la.norm(pU)
                if tau_U <= 1:
                    # First dogleg segment intersects trust region boundary
                    p = tau_U * pU
                else:
                    # Second dogleg segment intersects trust region boundary
                    aa = np.dot(dp, dp)
                    ab = 2 * np.dot(dp, pU)
                    ac = np.dot(pU, pU) - trust_radius**2
                    alphas = quadratic_formula(aa, ab, ac)
                    alpha = np.max(alphas)
                    p = pU + alpha * dp
            return p, tags

        elif method == '2d_subspace':
            g = obj.gradient(x)
            H = obj.hessian(x)
            B = posdefify(H, self.setting.pos_hess_eps)

            # Project g and B onto the 2D-subspace spanned by (normalized versions of) -g and -B^-1 g
            s1 = -g
            s2 = -la.solve(B, g)
            Sorig = np.vstack([s1, s2]).T
            S, Rtran = la.qr(
                Sorig
            )  # This is necessary for us to use same trust_radius before/after transforming
            g2 = np.dot(S.T, g)
            B2 = np.dot(S.T, np.dot(B, S))

            # Solve the 2D trust-region subproblem
            try:
                R, lower = cho_factor(B2)
                p2 = -cho_solve((R, lower), g2)
                p22 = np.dot(p2, p2)
                if np.dot(p2, p2) <= trust_radius**2:
                    p = np.dot(S, p2)
                    return p, tags
            except LinAlgError:
                pass

            a = B2[0, 0] * trust_radius**2
            b = B2[0, 1] * trust_radius**2
            c = B2[1, 1] * trust_radius**2

            d = g2[0] * trust_radius
            f = g2[1] * trust_radius

            coeffs = np.array(
                [-b + d, 2 * (a - c + f), 6 * b, 2 * (-a + c + f), -b - d])
            t = np.roots(coeffs)  # Can handle leading zeros
            t = np.real(t[np.isreal(t)])

            p2 = trust_radius * np.vstack(
                (2 * t / (1 + t**2), (1 - t**2) / (1 + t**2)))
            value = 0.5 * np.sum(p2 * np.dot(B2, p2), axis=0) + np.dot(g2, p2)
            i = np.argmin(value)
            p2 = p2[:, i]

            # Project back into the original n-dim space
            p = np.dot(S, p2)
            return p, tags

        elif method == 'cg_steihaug':
            # Settings
            max_iters = 100000  # TODO put in settings

            # Init
            n = x.size
            g = obj.gradient(x)
            B = obj.hessian(x)

            z = np.zeros(n)
            r = np.copy(g)
            d = -np.copy(g)

            # Choose eps according to Algo 7.1
            grad_norm = la.norm(g)
            eps = min(0.5, grad_norm**0.5) * grad_norm

            if la.norm(r) < eps:
                p = np.zeros(n)
                tags.append('Stopping tolerance reached!')
                return p, tags

            j = 0
            while j + 1 < max_iters:
                # Check if 'd' is a direction of non-positive curvature
                dBd = np.dot(d, np.dot(B, d))
                rr = np.dot(r, r)
                if dBd <= 0:
                    ta = np.dot(d, d)
                    tb = 2 * np.dot(d, z)
                    tc = np.dot(z, z) - trust_radius**2
                    taus = quadratic_formula(ta, tb, tc)
                    tau = np.max(taus)
                    p = z + tau * d
                    tags.append('Negative curvature encountered!')
                    return p, tags

                alpha = rr / dBd
                z_new = z + alpha * d

                # Check if trust region bound violated
                if la.norm(z_new) >= trust_radius:
                    ta = np.dot(d, d)
                    tb = 2 * np.dot(d, z)
                    tc = np.dot(z, z) - trust_radius**2
                    taus = quadratic_formula(ta, tb, tc)
                    tau = np.max(taus)
                    p = z + tau * d
                    tags.append('Trust region boundary reached!')
                    return p, tags

                z = np.copy(z_new)
                r = r + alpha * np.dot(B, d)
                rr_new = np.dot(r, r)

                if la.norm(r) < eps:
                    p = np.copy(z)
                    tags.append('Stopping tolerance reached!')
                    return p, tags

                beta = rr_new / rr
                d = -r + beta * d

                j += 1

            p = np.zeros(n)
            tags.append(
                'ALERT!  CG-Steihaug failed to solve trust-region subproblem within max_iters'
            )
            return p, tags
        else:
            raise ValueError('Invalid step method!')
示例#8
0
 def test_norm(self):
     X = self.man.rand()
     U = self.man.randvec(X)
     np_testing.assert_almost_equal(np.trace(np.conjugate(U.T)@U),
                                    self.man.norm(X, U))
     assert np.isreal(self.man.norm(X, U))
示例#9
0
 def test_norm(self):
     X = self.man.rand()
     U = self.man.randvec(X)
     np_testing.assert_almost_equal(self.man.norm(X, U), la.norm(U))
     assert np.isreal(self.man.norm(X, U))
示例#10
0
def rdc(x, y, f=np.sin, k=20, s=1 / 6., n=1):
    """
    Computes the Randomized Dependence Coefficient
    x,y: numpy arrays 1-D or 2-D
         If 1-D, size (samples,)
         If 2-D, size (samples, variables)
    f:   function to use for random projection
    k:   number of random projections to use
    s:   scale parameter
    n:   number of times to compute the RDC and
         return the median (for stability)
    According to the paper, the coefficient should be relatively insensitive to
    the settings of the f, k, and s parameters.
    
    Source: https://github.com/garydoranjr/rdc
    """
    #x = x.reshape((len(x)))
    #y = y.reshape((len(y)))

    if n > 1:
        values = []
        for i in range(n):
            try:
                values.append(rdc(x, y, f, k, s, 1))
            except np.linalg.linalg.LinAlgError:
                pass
        return np.median(values)

    if len(x.shape) == 1: x = x.reshape((-1, 1))
    if len(y.shape) == 1: y = y.reshape((-1, 1))

    # Copula Transformation
    cx = np.column_stack([rankdata(xc, method='ordinal')
                          for xc in x.T]) / float(x.size)
    cy = np.column_stack([rankdata(yc, method='ordinal')
                          for yc in y.T]) / float(y.size)

    # Add a vector of ones so that w.x + b is just a dot product
    O = np.ones(cx.shape[0])
    X = np.column_stack([cx, O])
    Y = np.column_stack([cy, O])

    # Random linear projections
    Rx = (s / X.shape[1]) * np.random.randn(X.shape[1], k)
    Ry = (s / Y.shape[1]) * np.random.randn(Y.shape[1], k)
    X = np.dot(X, Rx)
    Y = np.dot(Y, Ry)

    # Apply non-linear function to random projections
    fX = f(X)
    fY = f(Y)

    # Compute full covariance matrix
    C = np.cov(np.hstack([fX, fY]).T)

    # Due to numerical issues, if k is too large,
    # then rank(fX) < k or rank(fY) < k, so we need
    # to find the largest k such that the eigenvalues
    # (canonical correlations) are real-valued
    k0 = k
    lb = 1
    ub = k
    while True:

        # Compute canonical correlations
        Cxx = C[:k, :k]
        Cyy = C[k0:k0 + k, k0:k0 + k]
        Cxy = C[:k, k0:k0 + k]
        Cyx = C[k0:k0 + k, :k]

        eigs = np.linalg.eigvals(
            np.dot(np.dot(np.linalg.pinv(Cxx), Cxy),
                   np.dot(np.linalg.pinv(Cyy), Cyx)))

        # Binary search if k is too large
        if not (np.all(np.isreal(eigs)) and 0 <= np.min(eigs)
                and np.max(eigs) <= 1):
            ub -= 1
            k = (ub + lb) // 2
            continue
        if lb == ub: break
        lb = k
        if ub == lb + 1:
            k = ub
        else:
            k = (ub + lb) // 2

    return np.sqrt(np.max(eigs))
示例#11
0
 def test_norm(self):
     X = self.manifold.random_point()
     U = self.manifold.random_tangent_vector(X)
     np_testing.assert_almost_equal(np.trace(np.conjugate(U.T) @ U),
                                    self.manifold.norm(X, U))
     assert np.isreal(self.manifold.norm(X, U))
示例#12
0
 def test_norm(self):
     X = self.manifold.random_point()
     U = self.manifold.random_tangent_vector(X)
     np_testing.assert_almost_equal(self.manifold.norm(X, U),
                                    np.linalg.norm(U))
     assert np.isreal(self.manifold.norm(X, U))
示例#13
0
def polyinterp(points, doPlot=None, xminBound=None, xmaxBound=None):
    """ polynomial interpolation
    Parameters
    ----------
    points: shape(pointNum, 3), three columns represents x, f, g
    doPolot: set to 1 to plot, default 0
    xmin: min value that brackets minimum (default: min of points)
    xmax: max value that brackets maximum (default: max of points)
    
    set f or g to sqrt(-1)=1j if they are not known
    the order of the polynomial is the number of known f and g values minus 1

    Returns
    -------
    minPos:
    fmin:
    """

    if doPlot == None:
        doPlot = 0

    nPoints = points.shape[0]
    order = np.sum(np.imag(points[:, 1:3]) == 0) - 1

    # code for most common case: cubic interpolation of 2 points
    if nPoints == 2 and order == 3 and doPlot == 0:
        [minVal, minPos] = [np.min(points[:, 0]), np.argmin(points[:, 0])]
        notMinPos = 1 - minPos
        d1 = points[minPos,2] + points[notMinPos,2] - 3*(points[minPos,1]-\
                points[notMinPos,1])/(points[minPos,0]-points[notMinPos,0])

        t_d2 = d1**2 - points[minPos, 2] * points[notMinPos, 2]
        if t_d2 > 0:
            d2 = np.sqrt(t_d2)
        else:
            d2 = np.sqrt(-t_d2) * np.complex(0, 1)
        if np.isreal(d2):
            t = points[notMinPos,0] - (points[notMinPos,0]-points[minPos,0])*\
                    ((points[notMinPos,2]+d2-d1)/(points[notMinPos,2]-\
                    points[minPos,2]+2*d2))
            minPos = np.min(
                [np.max([t, points[minPos, 0]]), points[notMinPos, 0]])
        else:
            minPos = np.mean(points[:, 0])
        fmin = minVal
        return (minPos, fmin)

    xmin = np.min(points[:, 0])
    xmax = np.max(points[:, 0])

    # compute bounds of interpolation area
    if xminBound == None:
        xminBound = xmin
    if xmaxBound == None:
        xmaxBound = xmax

    # constraints based on available function values
    A = np.zeros((0, order + 1))
    b = np.zeros((0, 1))
    for i in range(nPoints):
        if np.imag(points[i, 1]) == 0:
            constraint = np.zeros(order + 1)
            for j in np.arange(order, -1, -1):
                constraint[order - j] = points[i, 0]**j
            A = np.vstack((A, constraint))
            b = np.append(b, points[i, 1])

    # constraints based on availabe derivatives
    for i in range(nPoints):
        if np.isreal(points[i, 2]):
            constraint = np.zeros(order + 1)
            for j in range(1, order + 1):
                constraint[j - 1] = (order - j + 1) * points[i, 0]**(order - j)
            A = np.vstack((A, constraint))
            b = np.append(b, points[i, 2])

    # find interpolating polynomial
    params = np.linalg.solve(A, b)

    # compute critical points
    dParams = np.zeros(order)
    for i in range(params.size - 1):
        dParams[i] = params[i] * (order - i)

    if np.any(np.isinf(dParams)):
        cp = np.concatenate((np.array([xminBound, xmaxBound]), points[:, 0]))
    else:
        cp = np.concatenate((np.array([xminBound, xmaxBound]), points[:,0], \
                np.roots(dParams)))

    # test critical points
    fmin = np.infty
    minPos = (xminBound + xmaxBound) / 2.
    for xCP in cp:
        if np.imag(xCP) == 0 and xCP >= xminBound and xCP <= xmaxBound:
            fCP = np.polyval(params, xCP)
            if np.imag(fCP) == 0 and fCP < fmin:
                minPos = np.double(np.real(xCP))
                fmin = np.double(np.real(fCP))

    # plot situation (omit this part for now since we are not going to use it
    # anyway)

    return (minPos, fmin)