Пример #1
0
def rbd(X, dmax, Er=0.01):
    """Decompose a matrix X using reduced basis decomposition. X = YT. Y basis vectors are constructed using mod_gramm_schmidt until an maximum basis number threshold (dmax) or an error requirement (Er) are satisfied."""

    #Call start_state from the setup.py module to instantiate the parameters for the RBD
    X, Y, T, d, e_cur, i, used_i, complete = start_state(X)

    #Set the current_state to the initial parameters; subject to iterative change.
    current_state = [X, Y, T, d, e_cur, Er, i, used_i, complete]

    #While the requirements for the RBD have not been met...
    while d <= dmax and e_cur > Er and complete == False:

        #Orthogonally project the X[:,i] vector into Y, calling the mod_gramm_schmidt.py module.
        orthonormalization = mod_gramm_schmidt(*current_state)

        #mod_gramm_schmidt has a clause that signals complete to equal True.
        complete = orthonormalization[-1]

        #Break the while loop if mod_gramm_schmidt tells us the decomposition is complete.
        if complete == True:
            current_state = orthonormalization
            break

        else:
            #Prepare for the next round of orthonormalization by calling the find_error.py and check_error.py modules.
            current_state = check_error(*find_error(*orthonormalization))

            #Update the active parameters, some of which govern the while loop. check_error() has a clause that signals completion.
            X, Y, T, d, e_cur, Er, i, used_i, complete = current_state

    #Final output of the function is a list of all the parameters.
    return current_state
def test_find_new_vector():
    """Test that find_error returns new e_cur and i values. """

    #Setup parameters
    test_image = mpimg.imread('images/DrawingHands.jpg')
    X, Y, T, d, e_cur, i, used_i, complete = start_state(test_image)
    Er = 0.0000000001

    #Complete a full iteration of RBD
    d1_parameters = check_error(*find_error(
        *mod_gramm_schmidt(X, Y, T, d, e_cur, Er, i, used_i, complete)))

    #Take a snapshot of e_cur and i before running the find_error function
    e_cur_before_find_error = d1_parameters[4]
    i_before_find_error = d1_parameters[6]

    #Capture the results of find_error
    find_error_results = find_error(*mod_gramm_schmidt(*d1_parameters))
    e_cur_after_find_error = find_error_results[4]
    i_after_find_error = find_error_results[6]
    used_i = find_error_results[7]

    #Assert that the new e_cur and i values returned by find_error are distinct.
    assert e_cur_before_find_error != e_cur_after_find_error
    assert i_before_find_error != i_after_find_error
    assert i_after_find_error not in used_i
def test_d1_not_done():
    """Test mod_gramm_schmidt where d!=0 and there is a need to continue building the basis."""

    #Setup parameters
    X, Y, T, d, e_cur, i, used_i, complete = start_state(test_image)
    Er = 0.0000000001

    #Complete 1 round of the RBD decomposition algorithm
    d1_parameters = check_error(*find_error(
        *mod_gramm_schmidt(X, Y, T, d, e_cur, Er, i, used_i, complete)))

    #Apply gramm_schmidt at the beginning of stage d = 1
    gramm_schmidt_results = mod_gramm_schmidt(*d1_parameters)

    #Update testing parameters
    X, Y, T, d, e_cur, Er, i, used_i, complete = gramm_schmidt_results

    #Test datatypes and values
    assert type(X) == np.ndarray
    assert type(Y) == np.ndarray
    assert type(T) == np.ndarray
    assert type(d) == int
    assert type(Er) == float
    assert type(used_i) == list
    assert complete == False

    #Assert that an orthogonal projection has been added to Y, and that a vector has been added to T. The dimensions of the dot product of Y and T should equal X.
    assert Y.shape[1] == T.shape[0] == 2
    compression = np.dot(Y, T)
    assert compression.shape == X.shape

    #Definition of orthogonal matrix
    print("Y.T.dot(Y)", Y.T.dot(Y))
    assert np.isclose(np.linalg.det(Y.T.dot(Y).astype(float)), 1)
Пример #4
0
def test_rbd_setup():
    '''Test harness for the setup.py module'''

    test_image = mpimg.imread('images/DrawingHands.jpg')
    dmax = 40
    X, Y, T, d, e_cur, i, used_i, complete = start_state(test_image)

    #Test datatypes and values
    assert type(X) == np.ndarray
    assert type(Y) == np.ndarray
    assert type(T) == np.ndarray
    assert type(d) == int
    assert type(e_cur) == float
    assert type(i) == int
    assert type(used_i) == list
    assert complete == False
    assert d < dmax

    #Test shapes
    assert Y.shape[0] == X.shape[0]
    assert Y.shape[1] == 1
    assert T.shape[0] == 1
    assert T.shape[1] == X.shape[1]
    assert len(used_i) == 0
    assert d < dmax
Пример #5
0
def test_decomposition_complete():
    """Test case for when e_cur <= Er, signaling that the decomposition is done."""

    #Setup parameters
    X, Y, T, d, e_cur, i, used_i, complete = start_state(test_image)
    Er = np.inf

    #Capture results of RBD at the point before check_error is run.
    params_before_check_error = find_error(
        *mod_gramm_schmidt(X, Y, T, d, e_cur, Er, i, used_i, complete))

    #Capture results after running check_error in a case that should return complete == True
    params_after_check_error = check_error(*params_before_check_error)

    #Test that check_error modifies complete to equal True.
    assert params_after_check_error[-1] == True != params_before_check_error[-1]
Пример #6
0
def test_decomposition_incomplete():
    """Test case for check_error when the error requirement is not met. d increases to 1 for the next iteration of RBD."""

    #Setup parameters
    X, Y, T, d, e_cur, i, used_i, complete = start_state(test_image)
    Er = 0.000000000000001

    #Capture results of RBD at the point before check_error is run.
    params_before_check_error = find_error(
        *mod_gramm_schmidt(X, Y, T, d, e_cur, Er, i, used_i, complete))

    #Capture results after running check_error in a case that should return complete == False
    params_after_check_error = check_error(*params_before_check_error)

    #Test that d is increased by 1 after check_error.
    d_before_check_error = params_before_check_error[3]
    d_after_check_error = params_after_check_error[3]
    assert d_before_check_error < d_after_check_error
    assert d_after_check_error - d_before_check_error == 1
def test_d1_done():
    """Test mod_gramm_schmidt where d!=0 and the error requirement is met, ending the RBD algorithm."""

    #Setup parameters
    X, Y, T, d, e_cur, i, used_i, complete = start_state(test_image)
    Er = 0.00001

    #Complete 1 round of the RBD decomposition algorithm and update parameters.
    d1_parameters = check_error(*find_error(
        *mod_gramm_schmidt(X, Y, T, d, e_cur, Er, i, used_i, complete)))
    X, Y, T, d, e_cur, Er, i, used_i, complete = d1_parameters
    #print("d: ",d)
    #print("Y: ", Y)

    #Ensure that the algorithm will think the decomposition is complete.
    Er = 50000

    #Apply gramm_schmidt at the beginning of stage d = 1
    gramm_schmidt_results = mod_gramm_schmidt(X, Y, T, d, e_cur, Er, i, used_i,
                                              complete)

    assert gramm_schmidt_results[-1] == True
def test_d0():
    """Test the first iteration of mod_gramm_schmidt where d == 0"""
    #Setup parameters
    X, Y, T, d, e_cur, i, used_i, complete = start_state(test_image)
    Er = 0.0000000001

    #Apply gramm_schmidt
    gramm_schmidt_results = mod_gramm_schmidt(X, Y, T, d, e_cur, Er, i, used_i,
                                              complete)

    #Update testing parameters
    X, Y, T, d, e_cur, Er, i, used_i, complete = gramm_schmidt_results

    #Test datatypes and values
    assert type(X) == np.ndarray
    assert type(Y) == np.ndarray
    assert type(T) == np.ndarray
    assert type(d) == int

    assert type(Er) == float
    assert type(i) == int
    assert type(used_i) == list
    assert complete == False

    #Test that Y and T have non-zero basis
    assert np.count_nonzero(Y) > 0
    assert np.count_nonzero(T) > 0

    #Test that Y and T have the right shapes.
    assert Y.shape[1] == 1
    assert Y.shape[0] == X.shape[0]
    assert T.shape[1] == X.shape[1]
    assert T.shape[0] == 1

    #Assert that an index has been added to used_i"""
    assert len(used_i) == 1
            return decomposition

        #If the error requirement has not been met, normalize u_d and add it to Y as a column vector. Add the dot product of u_d.transpose and X to T
        else:
            basis_vector = np.divide(u_d, np.linalg.norm(u_d))
            Y = np.column_stack((Y, basis_vector))
            T = np.row_stack((T, np.dot(Y[:, d].T, X)))
            used_i.append(i)

            #Return updated parameters, leading to the find_error process of the algorithm.
            update_state = (X, Y, T, d, e_cur, Er, i, used_i, complete)

            return update_state


if __name__ == '__main__':
    from setup import start_state
    alist = np.array([[1, 1, 0, 1, 0], [1, 0, 1, 1, 0], [0, 1, 1, 1, 0]])
    X, Y, T, d, e_cur, i, used_i, complete = start_state(alist)
    Er = 0.000001

    test_results = mod_gramm_schmidt(X, Y, T, d, e_cur, Er, i, used_i,
                                     complete)

    X, Y, T, d, e_cur, Er, i, used_i, complete = test_results

    def display_state(attributes):
        names = ['X', 'Y', 'U', 'd', 'e_cur', 'Er', 'i', 'used_i', 'complete']
        for i in range(len(names)):
            print("\n\n", names[i], " :\n", attributes[i])