Raw File
test_robust_decomposition.py
from numpy.testing import assert_array_almost_equal, assert_
import numpy as np

from ...random import cp_tensor
from ...tenalg import norm
from ..robust_decomposition import robust_pca


def test_RPCA():
    """Test for RPCA"""
    # Tensor is the sum of a low rank tensor + sparse noise
    clean = cp_tensor((500, 15, 16), rank=5, full=True)
    noise = np.random.choice([0, 1, -1], size=clean.shape, replace=True, p=[0.9, 0.05, 0.05])
    tensor = clean + noise
    clean_pred, noise_pred = robust_pca(tensor, mask=None, reg_E=0.05, mu_max=10e12, n_iter_max=1000, tol=10e-12)
    # check recovery 
    assert_array_almost_equal(tensor, clean_pred+noise_pred)
    # check low rank recovery
    assert_array_almost_equal(clean, clean_pred)
    # check sparse gross error recovery
    assert_array_almost_equal(noise, noise_pred)

    ## Test with missing values
    clean = cp_tensor((500, 15, 16), rank=5, full=True)
    noise = np.random.choice([0, 1, -1], size=clean.shape, replace=True, p=[0.9, 0.05, 0.05])
    corrupted_clean = np.copy(clean)
    # Add some corruption (missing values, replaced by ones)
    mask = np.random.choice([False, True], clean.shape, replace=True, p=[0.05, 0.95])
    corrupted_clean[~mask] = 1
    tensor = corrupted_clean + noise
    # Decompose the tensor
    clean_pred, noise_pred = robust_pca(tensor, mask=mask, reg_E=0.05, mu_max=10e12, n_iter_max=1000, tol=10e-12)
    # check recovery 
    assert_array_almost_equal(tensor, clean_pred+noise_pred)
    # check low rank recovery
    assert_array_almost_equal(corrupted_clean[mask], clean_pred[mask])
    # check sparse gross error recovery
    assert_array_almost_equal(noise[mask], noise_pred[mask])

    tol = 10e-12
    # Check for recovery of the corrupted/missing part
    error = norm((clean[~mask] - clean_pred[~mask]), 2)/norm(clean[~mask], 2)
    assert_(error <= tol)

back to top