Пример #1
0
def main(data_sizes: List, approximation_ranks: List, increments: List,
         singular_values: RowVector, used_data_factory: Callable,
         results_path: str, experiment_type: str, power_method_iterations,
         _seed) -> None:
    """ The main function of this project

    This functions performs the desired experiment according to the given configuration.
    The function runs the random_svd and random_id for every combination of data_size, approximation rank and increment
    given in the config and saves all the results to a csv file in the results folder (given in the configuration).
    """
    seed(_seed)  # Seed the interpolative package of Scipy for later usage.
    results_log = DataLog(LogFields)  # Initializing an empty results log.
    random_svd_with_run_time: Callable = measure_time(random_svd)
    random_id_with_run_time: Callable = measure_time(random_id)

    for data_size in data_sizes:
        data_matrix: Matrix = used_data_factory(data_size, singular_values)

        for approximation_rank in approximation_ranks:
            next_singular_value: Scalar = singular_values[approximation_rank + 1] if \
                approximation_rank < len(singular_values) else singular_values[-1]

            for increment in increments:
                # Executing all the tested methods.
                print(
                    f'n={data_size}, k={approximation_rank}, l={approximation_rank + increment}'
                )
                random_svd_approximation, svd_duration = random_svd_with_run_time(
                    data_matrix, approximation_rank, increment)
                random_svd_accuracy: Scalar = estimate_spectral_norm_diff(
                    data_matrix, random_svd_approximation,
                    power_method_iterations)
                print(
                    f'runtime={svd_duration}, accuracy={random_svd_accuracy}')
                random_id_approximation, id_duration = random_id_with_run_time(
                    data_matrix, approximation_rank, increment)
                random_id_accuracy: Scalar = estimate_spectral_norm_diff(
                    data_matrix, random_id_approximation,
                    power_method_iterations)
                print(f'runtime={id_duration}, accuracy={random_id_accuracy}')

                # Appending all the experiment results to the log.
                results_log.append(LogFields.DataSize, data_size)
                results_log.append(LogFields.ApproximationRank,
                                   approximation_rank)
                results_log.append(LogFields.Increment,
                                   increment + approximation_rank)
                results_log.append(LogFields.NextSingularValue,
                                   next_singular_value)
                results_log.append(LogFields.RandomSVDAccuracy,
                                   random_svd_accuracy)
                results_log.append(LogFields.RandomIDAccuracy,
                                   random_id_accuracy)
                results_log.append(LogFields.RandomSVDDuration, svd_duration)
                results_log.append(LogFields.RandomIDDuration, id_duration)

    results_log.save_log(experiment_type + " results",
                         results_folder_path=results_path)
Пример #2
0
    def check_id(self, dtype):
        # Test ID routines on a Hilbert matrix.

        # set parameters
        n = 300
        eps = 1e-12

        # construct Hilbert matrix
        A = hilbert(n).astype(dtype)
        if np.issubdtype(dtype, np.complexfloating):
            A = A * (1 + 1j)
        L = aslinearoperator(A)

        # find rank
        S = np.linalg.svd(A, compute_uv=False)
        try:
            rank = np.nonzero(S < eps)[0][0]
        except:
            rank = n

        # print input summary
        _debug_print("Hilbert matrix dimension:        %8i" % n)
        _debug_print("Working precision:               %8.2e" % eps)
        _debug_print("Rank to working precision:       %8i" % rank)

        # set print format
        fmt = "%8.2e (s) / %5s"

        # test real ID routines
        _debug_print("-----------------------------------------")
        _debug_print("Real ID routines")
        _debug_print("-----------------------------------------")

        # fixed precision
        _debug_print("Calling iddp_id / idzp_id  ...", )
        t0 = time.clock()
        k, idx, proj = pymatrixid.interp_decomp(A, eps, rand=False)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddp_aid / idzp_aid ...", )
        t0 = time.clock()
        k, idx, proj = pymatrixid.interp_decomp(A, eps)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddp_rid / idzp_rid ...", )
        t0 = time.clock()
        k, idx, proj = pymatrixid.interp_decomp(L, eps)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        # fixed rank
        k = rank

        _debug_print("Calling iddr_id / idzr_id  ...", )
        t0 = time.clock()
        idx, proj = pymatrixid.interp_decomp(A, k, rand=False)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddr_aid / idzr_aid ...", )
        t0 = time.clock()
        idx, proj = pymatrixid.interp_decomp(A, k)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddr_rid / idzr_rid ...", )
        t0 = time.clock()
        idx, proj = pymatrixid.interp_decomp(L, k)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        # check skeleton and interpolation matrices
        idx, proj = pymatrixid.interp_decomp(A, k, rand=False)
        P = pymatrixid.reconstruct_interp_matrix(idx, proj)
        B = pymatrixid.reconstruct_skel_matrix(A, k, idx)
        assert_(np.allclose(B, A[:, idx[:k]], eps))
        assert_(np.allclose(B.dot(P), A, eps))

        # test SVD routines
        _debug_print("-----------------------------------------")
        _debug_print("SVD routines")
        _debug_print("-----------------------------------------")

        # fixed precision
        _debug_print("Calling iddp_svd / idzp_svd ...", )
        t0 = time.clock()
        U, S, V = pymatrixid.svd(A, eps, rand=False)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddp_asvd / idzp_asvd...", )
        t0 = time.clock()
        U, S, V = pymatrixid.svd(A, eps)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddp_rsvd / idzp_rsvd...", )
        t0 = time.clock()
        U, S, V = pymatrixid.svd(L, eps)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        # fixed rank
        k = rank

        _debug_print("Calling iddr_svd / idzr_svd ...", )
        t0 = time.clock()
        U, S, V = pymatrixid.svd(A, k, rand=False)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddr_asvd / idzr_asvd ...", )
        t0 = time.clock()
        U, S, V = pymatrixid.svd(A, k)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddr_rsvd / idzr_rsvd ...", )
        t0 = time.clock()
        U, S, V = pymatrixid.svd(L, k)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        # ID to SVD
        idx, proj = pymatrixid.interp_decomp(A, k, rand=False)
        Up, Sp, Vp = pymatrixid.id_to_svd(A[:, idx[:k]], idx, proj)
        B = U.dot(np.diag(S).dot(V.T.conj()))
        assert_(np.allclose(A, B, eps))

        # Norm estimates
        s = svdvals(A)
        norm_2_est = pymatrixid.estimate_spectral_norm(A)
        assert_(np.allclose(norm_2_est, s[0], 1e-6))

        B = A.copy()
        B[:, 0] *= 1.2
        s = svdvals(A - B)
        norm_2_est = pymatrixid.estimate_spectral_norm_diff(A, B)
        assert_(np.allclose(norm_2_est, s[0], 1e-6))

        # Rank estimates
        B = np.array([[1, 1, 0], [0, 0, 1], [0, 0, 1]], dtype=dtype)
        for M in [A, B]:
            ML = aslinearoperator(M)

            rank_tol = 1e-9
            rank_np = np.linalg.matrix_rank(M, norm(M, 2) * rank_tol)
            rank_est = pymatrixid.estimate_rank(M, rank_tol)
            rank_est_2 = pymatrixid.estimate_rank(ML, rank_tol)

            assert_(rank_est >= rank_np)
            assert_(rank_est <= rank_np + 10)

            assert_(rank_est_2 >= rank_np - 4)
            assert_(rank_est_2 <= rank_np + 4)
Пример #3
0
    def check_id(self, dtype):
        # Test ID routines on a Hilbert matrix.

        # set parameters
        n = 300
        eps = 1e-12

        # construct Hilbert matrix
        A = hilbert(n).astype(dtype)
        if np.issubdtype(dtype, np.complexfloating):
            A = A * (1 + 1j)
        L = aslinearoperator(A)

        # find rank
        S = np.linalg.svd(A, compute_uv=False)
        try:
            rank = np.nonzero(S < eps)[0][0]
        except:
            rank = n

        # print input summary
        _debug_print("Hilbert matrix dimension:        %8i" % n)
        _debug_print("Working precision:               %8.2e" % eps)
        _debug_print("Rank to working precision:       %8i" % rank)

        # set print format
        fmt = "%8.2e (s) / %5s"

        # test real ID routines
        _debug_print("-----------------------------------------")
        _debug_print("Real ID routines")
        _debug_print("-----------------------------------------")

        # fixed precision
        _debug_print("Calling iddp_id / idzp_id  ...",)
        t0 = time.clock()
        k, idx, proj = pymatrixid.interp_decomp(A, eps, rand=False)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddp_aid / idzp_aid ...",)
        t0 = time.clock()
        k, idx, proj = pymatrixid.interp_decomp(A, eps)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddp_rid / idzp_rid ...",)
        t0 = time.clock()
        k, idx, proj = pymatrixid.interp_decomp(L, eps)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        # fixed rank
        k = rank

        _debug_print("Calling iddr_id / idzr_id  ...",)
        t0 = time.clock()
        idx, proj = pymatrixid.interp_decomp(A, k, rand=False)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddr_aid / idzr_aid ...",)
        t0 = time.clock()
        idx, proj = pymatrixid.interp_decomp(A, k)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddr_rid / idzr_rid ...",)
        t0 = time.clock()
        idx, proj = pymatrixid.interp_decomp(L, k)
        t = time.clock() - t0
        B = pymatrixid.reconstruct_matrix_from_id(A[:, idx[:k]], idx, proj)
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        # check skeleton and interpolation matrices
        idx, proj = pymatrixid.interp_decomp(A, k, rand=False)
        P = pymatrixid.reconstruct_interp_matrix(idx, proj)
        B = pymatrixid.reconstruct_skel_matrix(A, k, idx)
        assert_(np.allclose(B, A[:,idx[:k]], eps))
        assert_(np.allclose(B.dot(P), A, eps))

        # test SVD routines
        _debug_print("-----------------------------------------")
        _debug_print("SVD routines")
        _debug_print("-----------------------------------------")

        # fixed precision
        _debug_print("Calling iddp_svd / idzp_svd ...",)
        t0 = time.clock()
        U, S, V = pymatrixid.svd(A, eps, rand=False)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddp_asvd / idzp_asvd...",)
        t0 = time.clock()
        U, S, V = pymatrixid.svd(A, eps)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddp_rsvd / idzp_rsvd...",)
        t0 = time.clock()
        U, S, V = pymatrixid.svd(L, eps)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        # fixed rank
        k = rank

        _debug_print("Calling iddr_svd / idzr_svd ...",)
        t0 = time.clock()
        U, S, V = pymatrixid.svd(A, k, rand=False)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddr_asvd / idzr_asvd ...",)
        t0 = time.clock()
        U, S, V = pymatrixid.svd(A, k)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        _debug_print("Calling iddr_rsvd / idzr_rsvd ...",)
        t0 = time.clock()
        U, S, V = pymatrixid.svd(L, k)
        t = time.clock() - t0
        B = np.dot(U, np.dot(np.diag(S), V.T.conj()))
        _debug_print(fmt % (t, np.allclose(A, B, eps)))
        assert_(np.allclose(A, B, eps))

        # ID to SVD
        idx, proj = pymatrixid.interp_decomp(A, k, rand=False)
        Up, Sp, Vp = pymatrixid.id_to_svd(A[:, idx[:k]], idx, proj)
        B = U.dot(np.diag(S).dot(V.T.conj()))
        assert_(np.allclose(A, B, eps))

        # Norm estimates
        s = svdvals(A)
        norm_2_est = pymatrixid.estimate_spectral_norm(A)
        assert_(np.allclose(norm_2_est, s[0], 1e-6))

        B = A.copy()
        B[:,0] *= 1.2
        s = svdvals(A - B)
        norm_2_est = pymatrixid.estimate_spectral_norm_diff(A, B)
        assert_(np.allclose(norm_2_est, s[0], 1e-6))

        # Rank estimates
        B = np.array([[1, 1, 0], [0, 0, 1], [0, 0, 1]], dtype=dtype)
        for M in [A, B]:
            ML = aslinearoperator(M)

            rank_np = np.linalg.matrix_rank(M, 1e-9)
            rank_est = pymatrixid.estimate_rank(M, 1e-9)
            rank_est_2 = pymatrixid.estimate_rank(ML, 1e-9)

            assert_(rank_est >= rank_np)
            assert_(rank_est <= rank_np + 10)

            assert_(rank_est_2 >= rank_np)
            assert_(rank_est_2 <= rank_np + 10)
 def test_estimate_spectral_norm_diff(self, A):
     B = A.copy()
     B[:, 0] *= 1.2
     s = svdvals(A - B)
     norm_2_est = pymatrixid.estimate_spectral_norm_diff(A, B)
     assert_(np.allclose(norm_2_est, s[0], 1e-6))