Example #1
0
    def test_arnoldi(self):
        dim = 10
        A = np.arange(dim**2).reshape(dim, dim)
        b = np.zeros(dim, dtype=float)
        b[0] = 1.0
        n = 3
        V = arnoldi(A, b, n)
        # check orthogonality
        assert_allclose(V.T.dot(V), np.identity(n), atol=1e-12)
        # check subspace angles
        V_sub = np.zeros((dim, n), dtype=float)
        V_sub[:, 0] = b
        V_sub[:, 1] = A.dot(b)
        V_sub[:, 2] = A.dot(V_sub[:, 1])
        angles = subspace_angles(V, V_sub)
        assert_allclose(angles, np.zeros(n, dtype=float), atol=1e-12)

        # Test without orthogonalization
        V = arnoldi(A, b, n, orthogonal=False)
        # check normals
        for v in V.T:
            assert_allclose(np.linalg.norm(v), 1.0)
        # check subspace angles
        V_sub = np.zeros((dim, n), dtype=float)
        V_sub[:, 0] = b
        V_sub[:, 1] = A.dot(b)
        V_sub[:, 2] = A.dot(V_sub[:, 1])
        angles = subspace_angles(V, V_sub)
        assert_allclose(angles, np.zeros(n, dtype=float), atol=1e-12)
Example #2
0
    def test_eigendecomposition_slepsc_regression(
        self,
        test_matrix_1: np.ndarray,
        test_matrix_1_eigenvalues: np.ndarray,
        test_matrix_1_eigenvectors: np.ndarray,
        test_matrix_2: np.ndarray,
        test_matrix_2_eigenvalues: np.ndarray,
        test_matrix_2_eigenvectors: np.ndarray,
    ):

        eigs_1, vecs_1 = _eigs_slepc(csr_matrix(test_matrix_1), k=11)
        assert_allclose(
            test_matrix_1_eigenvalues,
            eigs_1,
        )
        assert_allclose(subspace_angles(test_matrix_1_eigenvectors, vecs_1),
                        0.0,
                        atol=1e-6,
                        rtol=1e-5)

        eigs_2, vecs_2 = _eigs_slepc(csr_matrix(test_matrix_2), k=13)
        assert_allclose(test_matrix_2_eigenvalues, eigs_2)
        assert_allclose(subspace_angles(test_matrix_2_eigenvectors, vecs_2),
                        0.0,
                        atol=1e-6,
                        rtol=1e-5)
Example #3
0
    def test_gpcca_krylov_sparse_eq_dense_mu(self,
                                             example_matrix_mu: np.ndarray):
        mu = int(example_matrix_mu[2, 4])
        if mu == 1000:
            pytest.skip("rtol=0.03359514, atol=3.73976903e+14")
        opt_clust = {0: 3, 10: 3, 50: 3, 100: 3, 200: 2, 500: 2, 1000: 5}[mu]

        P, sd = get_known_input(example_matrix_mu)

        g_s = GPCCA(csr_matrix(P), eta=sd, method="krylov").optimize(opt_clust)
        g_d = GPCCA(P, eta=sd, method="krylov").optimize(opt_clust)
        g_b = GPCCA(P, eta=sd, method="brandts").optimize(opt_clust)

        assert issparse(g_s.transition_matrix)
        assert not issparse(g_d.transition_matrix)
        assert not issparse(g_b.transition_matrix)

        assert_allclose(g_s.memberships.sum(1), 1.0)
        assert_allclose(g_d.memberships.sum(1), 1.0)
        assert_allclose(g_b.memberships.sum(1), 1.0)

        X_k, X_kd, X_b = g_s.schur_vectors, g_d.schur_vectors, g_b.schur_vectors
        RR_k, RR_kd, RR_b = g_s.schur_matrix, g_d.schur_matrix, g_b.schur_matrix

        # check if it's a correct Schur form
        _assert_schur(P, X_k, RR_k, N=None)
        _assert_schur(P, X_kd, RR_kd, N=None)
        _assert_schur(P, X_b, RR_b, N=None)
        # check if they span the same subspace
        assert np.max(subspace_angles(X_k, X_kd)) < eps
        assert np.max(subspace_angles(X_kd, X_b)) < eps

        ms, md, mb = g_s.memberships, g_d.memberships, g_b.memberships
        cs, cd, cb = (
            g_s.coarse_grained_transition_matrix,
            g_d.coarse_grained_transition_matrix,
            g_b.coarse_grained_transition_matrix,
        )

        for left, right in combinations(
            ["brandts", "dense_krylov", "sparse_krylov"], r=2):
            ml, cl = locals()[f"m{left[0]}"], locals()[f"c{left[0]}"]
            mr, cr = locals()[f"m{right[0]}"], locals()[f"c{right[0]}"]

            perm = _find_permutation(ml, mr)

            mr = mr[:, perm]
            assert_allclose(mr, ml, atol=1e-4)

            cr = cr[perm, :][:, perm]
            try:
                assert_allclose(cr, cl, atol=1e-4)
            except AssertionError as e:
                raise RuntimeError(f"Comparing: {left} and {right}.") from e
Example #4
0
    def test_gpcca_krylov_sparse_eq_dense_count(self, P: np.ndarray,
                                                sd: np.ndarray):
        # all of them cluster optimally into 3 clusters
        g_s = GPCCA(csr_matrix(P), eta=sd, method="krylov").optimize([2, 5])
        g_d = GPCCA(P, eta=sd, method="krylov").optimize([2, 5])
        g_b = GPCCA(P, eta=sd, method="brandts").optimize([2, 5])

        assert issparse(g_s.transition_matrix)
        assert not issparse(g_d.transition_matrix)
        assert not issparse(g_b.transition_matrix)

        assert_allclose(g_s.memberships.sum(1), 1.0)
        assert_allclose(g_d.memberships.sum(1), 1.0)
        assert_allclose(g_b.memberships.sum(1), 1.0)

        X_k, X_kd, X_b = g_s.schur_vectors, g_d.schur_vectors, g_b.schur_vectors
        RR_k, RR_kd, RR_b = g_s.schur_matrix, g_d.schur_matrix, g_b.schur_matrix

        # check if it's a correct Schur form
        _assert_schur(P, X_k, RR_k, N=None, subspace=True)
        _assert_schur(P, X_kd, RR_kd, N=None, subspace=True)
        _assert_schur(P, X_b, RR_b, N=None, subspace=True)
        # check if they span the same subspace
        assert np.max(subspace_angles(X_k, X_kd)) < eps
        assert np.max(subspace_angles(X_kd, X_b)) < eps

        ms, md, mb = g_s.memberships, g_d.memberships, g_b.memberships
        cs, cd, cb = (
            g_s.coarse_grained_transition_matrix,
            g_d.coarse_grained_transition_matrix,
            g_b.coarse_grained_transition_matrix,
        )

        for left, right in combinations(
            ["brandts", "dense_krylov", "sparse_krylov"], r=2):
            ml, cl = locals()[f"m{left[0]}"], locals()[f"c{left[0]}"]
            mr, cr = locals()[f"m{right[0]}"], locals()[f"c{right[0]}"]

            perm = _find_permutation(ml, mr)

            mr = mr[:, perm]
            assert_allclose(mr, ml)

            cr = cr[perm, :][:, perm]
            try:
                assert_allclose(cr, cl)
            except AssertionError as e:
                raise RuntimeError(f"Comparing: {left} and {right}.") from e
def compute_subspace_angles():
    """Computes average subspace angle between each pair of eigendistortions"""
    img_name = 'dog'
    jacobians = load_eigendistortions(img_name)
    combos = [comb for comb in combinations(range(20), 2)]
    combos = combos + [(i, i) for i in range(20)]

    all_angles = {}
    n_boot = 20
    save_dir = op.join(DIR_DATA, 'subspace_angles')
    filename = 'subspace_angles_' + img_name
    safe_mkdir(save_dir)
    if op.exists(op.join(save_dir, filename)):
        return

    for comb in tqdm(combos):
        tmp = []
        for _ in tqdm(range(n_boot)):
            ind1, ind2 = comb
            j1 = jacobians[torch.randint(0, 20, (ind1+1, ))]
            j2 = jacobians[torch.randint(0, 20, (ind2+1, ))]

            _, _, v1 = torch.svd(j1.mean(0))
            _, _, v2 = torch.svd(j2.mean(0))

            tmp.append(subspace_angles(v1, v2))

        all_angles.update({str(comb): tmp.copy()})

    with open(op.join(save_dir, filename + '.pkl'), 'wb') as f:
        pickle.dump(all_angles, f, pickle.HIGHEST_PROTOCOL)

    return all_angles
Example #6
0
def test_sweep(m=5):
    dom = psdr.BoxDomain(-np.ones(m), np.ones(m))

    # Default arguments
    X, y = dom.sweep()
    assert np.all(dom.isinside(X))

    # Specify sample
    x = dom.sample()
    X, y = dom.sweep(x=x)
    assert np.all(dom.isinside(X))
    # Check x is on the line
    dom2 = psdr.ConvexHullDomain(X)
    assert dom2.isinside(x)

    # Specify direction
    p = np.random.randn(m)
    X, y = dom.sweep(p=p)
    assert np.all(dom.isinside(X))
    d = (X[-1] - X[0]).reshape(-1, 1)
    assert np.isclose(subspace_angles(d, p.reshape(-1, 1)), 0)

    # Check corner
    X, y = dom.sweep(p=p, corner=True)
    c = dom.corner(p)
    assert np.any([np.isclose(x, c) for x in X])
Example #7
0
def test_lipschitz_approx_class():
    r""" Integration testing
	"""
    fun = psdr.demos.OTLCircuit()
    X = fun.domain.sample_grid(2)
    lip = psdr.LipschitzMatrix()
    lip.fit(grads=fun.grad(X))

    lipapprox = LipschitzApproximation(lip.L, fun.domain)
    X = fun.domain.sample(40)
    fX = fun(X)
    #fX += 0.1*np.random.randn(*fX.shape)
    lipapprox.fit(X, fX[:, 0])

    y = lipapprox(X)
    print(fX[:, 0] - y)
    err = np.max(np.abs(fX[:, 0] - y))
    assert err < 1e-9

    # Check identification of active subspace
    for i in range(1, len(fun.domain)):
        U = lip.U[:, :-i]
        LUU = lip.L @ U @ U.T
        lipapprox = LipschitzApproximation(LUU, fun.domain)
        print(U.shape)
        print(lipapprox.U.shape)
        ang = subspace_angles(U, lipapprox.U)
        print(ang)
        assert np.max(ang) < 1e-7, "Did not correctly identify active subspace"
Example #8
0
def tran_angles(df, df2):
    r"""Subspace angles

    Compute the subspace angles between two matrices. A wrapper for
    scipy.linalg.subspace_angles that corrects for column ordering. Row ordering
    is assumed.

    Args:
        df (DataFrame): First matrix to compare
        df2 (DataFrame): Second matrix to compare

    Returns:
        array: Array of angles (in radians)

    Examples:

        >>> import grama as gr
        >>> import pandas as pd
        >>> df = pd.DataFrame(dict(v=[+1, +1]))
        >>> df_v1 = pd.DataFrame(dict(w=[+1, -1]))
        >>> df_v2 = pd.DataFrame(dict(w=[+1, +1]))
        >>> theta1 = angles(df, df_v1)
        >>> theta2 = angles(df, df_v2)

    """
    ## Compute subspace angles
    A1 = df.values
    A2 = df2.values

    return subspace_angles(A1, A2)
Example #9
0
    def test_P_i(self, P_i: np.ndarray, method: str):
        if method == "krylov":
            pytest.importorskip("mpi4py")
            pytest.importorskip("petsc4py")
            pytest.importorskip("slepc4py")

        g = GPCCA(P_i, eta=None, method=method)

        for m in range(2, 8):
            try:
                g.optimize(m)
            except ValueError:
                continue

            X, RR = g.schur_vectors, g.schur_matrix

            assert_allclose(g.memberships.sum(1), 1.0)
            assert_allclose(g.coarse_grained_transition_matrix.sum(1), 1.0)
            assert_allclose(g.coarse_grained_input_distribution.sum(), 1.0)
            if g.coarse_grained_stationary_probability is not None:
                assert_allclose(g.coarse_grained_stationary_probability.sum(),
                                1.0)
            np.testing.assert_allclose(X[:, 0], 1.0)

            assert np.max(subspace_angles(P_i @ X, X @ RR)) < eps
Example #10
0
def test_proj_raw_duration(duration, sfreq):
    """Test equivalence of `duration` options."""
    n_ch, n_dim = 30, 3
    rng = np.random.RandomState(0)
    signals = rng.randn(n_dim, 10000)
    mixing = rng.randn(n_ch, n_dim) + [0, 1, 2]
    data = np.dot(mixing, signals)
    raw = RawArray(data, create_info(n_ch, sfreq, 'eeg'))
    raw.set_eeg_reference(projection=True)
    n_eff = int(round(raw.info['sfreq'] * duration))
    # crop to an even "duration" number of epochs
    stop = ((len(raw.times) // n_eff) * n_eff - 1) / raw.info['sfreq']
    raw.crop(0, stop)
    proj_def = compute_proj_raw(raw, n_eeg=n_dim)
    proj_dur = compute_proj_raw(raw, duration=duration, n_eeg=n_dim)
    proj_none = compute_proj_raw(raw, duration=None, n_eeg=n_dim)
    assert len(proj_dur) == len(proj_none) == len(proj_def) == n_dim
    # proj_def is not in here because it does not necessarily evenly divide
    # the signal length:
    for pu, pn in zip(proj_dur, proj_none):
        assert_allclose(pu['data']['data'], pn['data']['data'])
    # but we can test it here since it should still be a small subspace angle:
    for proj in (proj_dur, proj_none, proj_def):
        computed = np.concatenate([p['data']['data'] for p in proj], 0)
        angle = np.rad2deg(linalg.subspace_angles(computed.T, mixing)[0])
        assert angle < 1e-5
def subspace_dist(A, B):
    '''
    Inputs: 
        A, B - Two subspaces (columns of each matrix are basis for the subspace)
    Outputs: The distance between the two subspaces, defined as the Frobenius norm of the sine of principal angles
    '''
    return np.linalg.norm(np.sin(subspace_angles(A, B)))
Example #12
0
def test_proj_raw_duration(duration, sfreq):
    """Test equivalence of `duration` options."""
    n_ch, n_dim = 30, 3
    rng = np.random.RandomState(0)
    signals = rng.randn(n_dim, 10000)
    mixing = rng.randn(n_ch, n_dim) + [0, 1, 2]
    data = np.dot(mixing, signals)
    raw = RawArray(data, create_info(n_ch, sfreq, 'eeg'))
    raw.set_eeg_reference(projection=True)
    n_eff = int(round(raw.info['sfreq'] * duration))
    # crop to an even "duration" number of epochs
    stop = ((len(raw.times) // n_eff) * n_eff - 1) / raw.info['sfreq']
    raw.crop(0, stop)
    proj_def = compute_proj_raw(raw, n_eeg=n_dim)
    proj_dur = compute_proj_raw(raw, duration=duration, n_eeg=n_dim)
    proj_none = compute_proj_raw(raw, duration=None, n_eeg=n_dim)
    assert len(proj_dur) == len(proj_none) == len(proj_def) == n_dim
    # proj_def is not in here because it does not necessarily evenly divide
    # the signal length:
    for pu, pn in zip(proj_dur, proj_none):
        assert_allclose(pu['data']['data'], pn['data']['data'])
    # but we can test it here since it should still be a small subspace angle:
    for proj in (proj_dur, proj_none, proj_def):
        computed = np.concatenate([p['data']['data'] for p in proj], 0)
        angle = np.rad2deg(linalg.subspace_angles(computed.T, mixing)[0])
        assert angle < 1e-5
def find_theta_max(p,dim):
  theta_max = []
  for i in range(100): 
    rand_subspac1 = orth(np.random.randn(p, dim))
    rand_subspac2 = orth(np.random.randn(p, dim))
    theta_max.append(subspace_angles(rand_subspac1,rand_subspac2).max())  #using min or max 
  max_avg_theta = np.average(theta_max)
  return(max_avg_theta)
Example #14
0
def find_theta_max(b, t, k):
    theta_max = []
    for i in range(1, k + 1):
        for j in range(1, i):
            theta_max.append(subspace_angles(b[i], b[j]).max())
    max_avg_theta = mean(theta_max)
    theta = max_avg_theta * t
    return theta
 def find_a_for_theta(a,p=p, dim=dim,theta = theta) :
   temp_theta = []
   for i in range(100): 
     rand_subspac0 = orth(np.random.randn(p, dim))
     rand_subspac1 = orth(np.random.randn(p, dim))
     rand_subspac2 = orth(np.random.randn(p, dim))
     temp_theta.append(subspace_angles(rand_subspac0*(1-a)+rand_subspac1*a,rand_subspac0*(1-a)+rand_subspac2*a).max())
   return (np.average(temp_theta)-theta)
def performance_measure1(k,B1,B2): 
  all_per = list(it.permutations(range(k)))
  sum_cos_angles_all_per = np.zeros(len(all_per))
  for l, val in enumerate(all_per):
    for i in range(k) : 
      if B2[val[i]].shape[1]>0 : # handling with empty clusters
        sum_cos_angles_all_per[l]+= (math.cos(subspace_angles(B1[i],B2[val[i]]).max()))**2   #use min or max????????????????
  cost_subspace = sum_cos_angles_all_per.max()
  return (cost_subspace)
Example #17
0
    def test_pod(self):
        S = np.array([[1.0, 1.0, 1.0, 0.0, 0.0, 0.0],
                      [2.0, 0.0, 0.0, 2.0, 0.0, 0.0],
                      [2.5, 1.5, 0.0, 0.0, 0.0, 0.5],
                      [4.0, 0.0, 0.0, 4.00000000001, 0.0, 0.0]]).T

        sigma, V = pod(S, 2)
        angles = subspace_angles(V, S)
        assert_allclose(angles, 0.0, atol=1e-14)
        self.assertEqual(V.shape[1], 2)

        sigma, V = pod(S, 4)
        angles = subspace_angles(V, S)
        assert_allclose(angles, 0.0, atol=1e-14)
        self.assertEqual(V.shape[1], 4)
        print(sigma)

        sigma, V = pod(S, tol=1e-10)
        self.assertEqual(V.shape[1], 3)
Example #18
0
def measure_cost_subspace(k, B1, B2):
    all_perm = list(permutations(range(k)))
    sum_cos_angles_all_per = np.zeros(len(all_perm))
    for l, perm in enumerate(all_perm):
        for i in range(k):
            if B2[perm[i]].shape[1] > 0:  # handling with empty clusters
                sum_cos_angles_all_per[l] += math.cos(
                    subspace_angles(B1[i], B2[perm[i]]).max()) ** 2  # use min or max????????????????
    cost_subspace = sum_cos_angles_all_per.max()
    return cost_subspace
Example #19
0
def test_arnoldi_simple():
    """Test the Arnoldi algorithm for a simple system."""
    num_directions = 3
    x = np.empty((a.shape[0], num_directions))
    x[:, 0] = b.squeeze()
    x[:, 0] /= np.linalg.norm(x[:, 0])
    for i in range(1, num_directions):
        x[:, i] = np.linalg.solve(a, x[:, i - 1])
        x[:, i] /= np.linalg.norm(x[:, i])
    rks = arnoldi(a, b, num_directions)
    npt.assert_almost_equal(np.abs(subspace_angles(x, rks)).max(), 0.0)
Example #20
0
    def test_do_schur_krylov_eq_brandts(self, example_matrix_mu: np.ndarray):
        P, sd = get_known_input(example_matrix_mu)

        X_b, RR_b, _ = _do_schur(P, eta=sd, m=3, method="brandts")
        X_k, RR_k, _ = _do_schur(P, eta=sd, m=3, method="krylov")

        # check if it's a correct Schur form
        _assert_schur(P, X_b, RR_b, N=None)
        _assert_schur(P, X_k, RR_k, N=None)
        # check if they span the same subspace
        assert np.max(subspace_angles(X_b, X_k)) < eps
Example #21
0
def c_subspace(data, Bs, d, n_subspaces, labels):
    metric = 0
    for i in range(n_subspaces):
        b_hat = data[labels == i].T
        if data[labels == i].shape[0] > d:
            centered_data = data[labels == i] - np.mean(data[labels == i],
                                                        axis=1)[:, None]
            pca = PCA(n_components=d).fit(centered_data.T)
            b_hat = pca.transform(centered_data.T)
        metric += np.cos(max(subspace_angles(Bs[i], b_hat)))**2
    return metric
Example #22
0
def _find_theta(subspaces):
    K = len(subspaces)
    sum_thetas = 0
    for i in range(K):
        for j in range(i):
            a = subspace_angles(subspaces[i], subspaces[j])[0]
            if a > np.pi / 2:
                print(a)
            sum_thetas += a
    if (1 / binom(K, 2)) * sum_thetas > np.pi / 2:
        print((1 / binom(K, 2)) * sum_thetas)
    return (1 / binom(K, 2)) * sum_thetas
Example #23
0
def test_arnoldi_xxl():
    """Test the Arnoldi algorithm for a larger system."""
    np.random.seed(777)
    a_xxl = np.random.rand(100, 100)
    b_xxl = np.random.rand(100)
    num_directions = 10

    x = np.empty((a_xxl.shape[0], num_directions))
    x[:, 0] = b_xxl
    x[:, 0] /= np.linalg.norm(x[:, 0])
    for i in range(1, num_directions):
        x[:, i] = np.linalg.solve(a_xxl, x[:, i - 1])
        x[:, i] /= np.linalg.norm(x[:, i])
    rks = arnoldi(a_xxl, b_xxl, num_directions)
    npt.assert_almost_equal(np.abs(subspace_angles(x, rks)).max(), 0.0)
Example #24
0
def plot_angles(X, y):
    n_pairs = 5000
    same = np.array([
        X[np.random.choice(np.where(y == np.random.choice(n_clusters))[0],
                           size=2)] for _ in range(n_pairs)
    ])
    labels = np.array([
        np.random.choice(n_clusters, size=2, replace=False)
        for _ in range(n_pairs)
    ]).flatten()
    different = np.array([
        X[np.random.choice(np.where(y == label)[0])] for label in labels
    ]).reshape((n_pairs, 2, 784))
    same_angles = [
        np.degrees(max(subspace_angles(pair[0][:, None], pair[1][:, None])))
        for pair in same
    ]
    diff_angles = [
        np.degrees(max(subspace_angles(pair[0][:, None], pair[1][:, None])))
        for pair in different
    ]

    plt.figure(figsize=(10, 7))
    plt.hist(same_angles,
             alpha=0.5,
             label="same class",
             bins=100,
             density=True)
    plt.hist(diff_angles,
             alpha=0.5,
             label="different classes",
             bins=100,
             density=True)
    plt.title("Histogram of angles between pairs of data-points")
    plt.legend()
    plt.show()
Example #25
0
def principal_angle_mat(X, Y):
    """Principal angles between two subspaces X and Y.
    
    Parameters
    ----------
    X : ndarray
        feature vectors in M-dimensional space, shape (Nx, M).
    Y : ndarray
        feature vectors in M-dimensional space, shape (Ny, M).
    
    Returns
    -------
    float
        subspace angle in radian.
    """
    angles = subspace_angles(X.T, Y.T)
    return angles[0]
Example #26
0
    def test_normal_case(
        self,
        P: np.ndarray,
        sd: np.ndarray,
        count_sd: np.ndarray,
        count_Pc: np.ndarray,
        count_chi: np.ndarray,
    ):
        assert_allclose(sd, count_sd)

        g = GPCCA(P, eta=sd)
        g.optimize((2, 10))

        Pc = g.coarse_grained_transition_matrix
        assert_allclose(Pc, count_Pc, atol=eps)

        assert_allclose(Pc.sum(1), 1.0)
        assert_allclose(g.coarse_grained_transition_matrix.sum(1), 1.0)
        assert_allclose(g.memberships.sum(1), 1.0)

        assert np.max(subspace_angles(g.memberships, count_chi)) < eps
Example #27
0
def _assert_schur(
    P: np.ndarray,
    X: np.ndarray,
    RR: np.ndarray,
    N: Optional[int] = None,
    subspace: bool = False,
):
    if N is not None:
        np.testing.assert_array_equal(P.shape, [N, N])
        np.testing.assert_array_equal(X.shape, [N, N])
        np.testing.assert_array_equal(RR.shape, [N, N])

    if subspace:
        assert_allclose(subspace_angles(P @ X, X @ RR),
                        0.0,
                        atol=1e-6,
                        rtol=1e-5)
    else:
        assert np.all(np.abs(X @ RR - P @ X) < eps), np.abs(X @ RR -
                                                            P @ X).max()
    assert np.all(np.abs(X[:, 0] - 1) < eps), np.abs(X[:, 0]).max()
Example #28
0
def angles(df1, df2, rowname="rowname"):
    """Subspace angles

    Compute the subspace angles between two matrices. A wrapper for
    scipy.linalg.subspace_angles that corrects for row and column ordering.

    Args:
        df1 (DataFrame): First matrix to compare
        df2 (DataFrame): Second matrix to compare
        rowname (str): Rownames which define new column names
            Must be same for df1 and df2

    Returns:
        np.array: Array of angles (in radians)

    Examples:

    from pybuck import *
        >>> df = col_matrix(v = dict(x=+1, y=+1))
        >>> df_v1 = col_matrix(w = dict(x=+1, y=-1))
        >>> df_v2 = col_matrix(w = dict(x=+1, y=+1))
        >>> theta1 = angles(df, df_v1)
        >>> theta2 = angles(df, df_v2)

    """
    ## Check invariants
    if not (rowname in df1.columns):
        raise ValueError("df1 must have {} column".format(rowname))
    if not (rowname in df2.columns):
        raise ValueError("df2 must have {} column".format(rowname))

    ## Compute subspace angles
    A1 = df1.sort_values(rowname) \
            .drop(rowname, axis=1) \
            .values
    A2 = df2.sort_values(rowname) \
            .drop(rowname, axis=1) \
            .values

    return subspace_angles(A1, A2)
Example #29
0
    def test_krylov_basis(self):
        dim = 10
        m_toeplitz_arr = np.zeros(dim)
        m_toeplitz_arr[0] = 2.0
        m_toeplitz_arr[1] = -1.0
        M = toeplitz(m_toeplitz_arr)

        k_toeplitz_arr = np.zeros(dim)
        k_toeplitz_arr[0] = 5.0
        k_toeplitz_arr[1] = -2.0
        k_toeplitz_arr[1] = -0.5
        K = toeplitz(k_toeplitz_arr)

        b = np.zeros(dim, dtype=float)
        b[0] = 1.0
        n = 3

        V = krylov_basis(M, K, b, n, mass_orth=False)
        # Check if K^{-1} b is in basis
        U = K.dot(V)
        angle = subspace_angles(U, b.reshape(-1, 1))
        assert_allclose(angle, 0.0, atol=1e-10)

        # Check if K^{-1} M K^{-1} b is in basis
        u = solve(K, M.dot(solve(K, b)))
        angle = subspace_angles(u.reshape(-1, 1), V)
        assert_allclose(angle, 0.0, atol=1e-10)

        # check orthogonality and shape
        assert_allclose(V.T.dot(V), np.identity(n), atol=1e-12)
        rows, cols = V.shape
        self.assertEqual(rows, dim)
        self.assertEqual(cols, n)

        # check m-orthogonality and shape
        V = krylov_basis(M, K, b, n, mass_orth=True, n_iter_orth=2)
        assert_allclose(V.T.dot(M).dot(V), np.identity(n), atol=1e-12)
        rows, cols = V.shape
        self.assertEqual(rows, dim)
        self.assertEqual(cols, n)

        # check different number of moments
        n = 5
        V = krylov_basis(M, K, b, n, mass_orth=False)
        assert_allclose(V.T.dot(V), np.identity(n), atol=1e-12)
        rows, cols = V.shape
        self.assertEqual(rows, dim)
        self.assertEqual(cols, n)

        # check if it also works with matrix inputs
        no_of_inputs = 2
        B = np.zeros((dim, no_of_inputs))
        B[0, 0] = 1.0
        B[3, 1] = 1.0
        # check orthogonality and shape
        V = krylov_basis(M, K, B, n, mass_orth=False)
        assert_allclose(V.T.dot(V), np.identity(n * no_of_inputs), atol=1e-12)
        rows, cols = V.shape
        self.assertEqual(rows, dim)
        self.assertEqual(cols, n * no_of_inputs)
        # check m-orthogonality and shape
        V = krylov_basis(M, K, B, n, mass_orth=True)
        assert_allclose(V.T.dot(M).dot(V),
                        np.identity(n * no_of_inputs),
                        atol=1e-12)
        rows, cols = V.shape
        self.assertEqual(rows, dim)
        self.assertEqual(cols, n * no_of_inputs)
Example #30
0
 def find_a_for_theta(a, b=b, k=k, theta=theta):
     temp_theta = []
     for i in range(1, k + 1):
         for j in range(1, i):
             temp_theta.append(subspace_angles(b[0] * (1 - a) + b[i] * a, b[0] * (1 - a) + b[j] * a).max())
     return mean(temp_theta) - theta
Example #31
0
def _check_schur(P: np.ndarray, Q: np.ndarray, R: np.ndarray,
                 eigenvalues: np.ndarray, method: str) -> None:
    """
    Run a number of checks on the sorted Schur decomposition.

    Parameters
    ----------
    %(P)s
    Q
        %(Q_sort)s
    R
        %(R_sort)s
    eigenvalues
        %(eigenvalues_m)s
    %(method)s

    Returns
    -------
    Nothing.
    """
    m = len(eigenvalues)

    # check the dimensions
    if Q.shape[1] != len(eigenvalues):
        raise ValueError(
            f"Number of Schur vectors does not match number of eigenvalues for `method={method!r}`."
        )
    if R.shape[0] != R.shape[1]:
        raise ValueError(f"R is not rectangular for `method={method!r}`.")
    if P.shape[0] != Q.shape[0]:
        raise ValueError(
            f"First dimension in P does not match first dimension in Q for `method={method!r}`."
        )
    if R.shape[0] != Q.shape[1]:
        raise ValueError(
            f"First dimension in R does not match second dimension in Q for `method={method!r}`."
        )

    # check whether things are real
    if not np.all(np.isreal(Q)):
        raise TypeError(
            f"The orthonormal basis of the subspace returned by `method={method!r}` is not real. "
            "G-PCCA needs real basis vectors to work.")

    dummy = np.dot(P, csr_matrix(Q) if issparse(P) else Q)
    if issparse(dummy):
        dummy = dummy.toarray()

    dummy1 = np.dot(Q, np.diag(eigenvalues))
    # dummy2 = np.concatenate((dummy, dummy1), axis=1)
    dummy3 = subspace_angles(dummy, dummy1)
    # test1 = ( ( matrix_rank(dummy2) - matrix_rank(dummy) ) == 0 )
    test2 = np.allclose(dummy3, 0.0, atol=1e-8, rtol=1e-5)
    test3 = dummy3.shape[0] == m
    dummy4 = subspace_angles(dummy, Q)
    test4 = np.allclose(dummy4, 0.0, atol=1e-6, rtol=1e-5)
    if not test4:
        raise ValueError(
            f"According to `scipy.linalg.subspace_angles()`, `{method}` didn't "
            f"return an invariant subspace of P. The subspace angles are: `{dummy4}`."
        )

    if not test2:
        warnings.warn(
            f"According to `scipy.linalg.subspace_angles()`, `{method}` didn't "
            f"return the invariant subspace associated with the top k eigenvalues, "
            f"since the subspace angles between the column spaces of P*Q and Q*L "
            f"aren't near zero (L is a diagonal matrix with the "
            f"sorted top eigenvalues on the diagonal). The subspace angles are: `{dummy3}`."
        )

    if not test3:
        warnings.warn(
            f"According to `scipy.linalg.subspace_angles()`, the dimension of the "
            f"column space of P*Q and/or Q*L is not equal to m (L is a diagonal "
            f"matrix with the sorted top eigenvalues on the diagonal), method=`{method}`."
        )