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
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))
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))
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)
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!')
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))
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))
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))
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))
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))
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)