"""Tests for _sketches.py."""

from __future__ import division, print_function, absolute_import

import numpy as np
from numpy.testing import assert_, assert_equal
from scipy.linalg import clarkson_woodruff_transform
from scipy.linalg._sketches import cwt_matrix
from scipy.sparse import issparse, rand
from scipy.sparse.linalg import norm


class TestClarksonWoodruffTransform(object):
    """
    Testing the Clarkson Woodruff Transform
    """
    # set seed for generating test matrices
    rng = np.random.RandomState(seed=1179103485)

    # Test matrix parameters
    n_rows = 2000
    n_cols = 100
    density = 0.1

    # Sketch matrix dimensions
    n_sketch_rows = 200

    # Seeds to test with
    seeds = [1755490010, 934377150, 1391612830, 1752708722, 2008891431,
             1302443994, 1521083269, 1501189312, 1126232505, 1533465685]

    A_dense = rng.randn(n_rows,n_cols)
    A_csc = rand(
        n_rows, n_cols, density=density, format='csc', random_state=rng,
    )
    A_csr = rand(
        n_rows, n_cols, density=density, format='csr', random_state=rng,
    )
    A_coo = rand(
        n_rows, n_cols, density=density, format='coo', random_state=rng,
    )

    # Collect the test matrices
    test_matrices = [
        A_dense, A_csc, A_csr, A_coo,
    ]

    # Test vector with norm ~1
    x = rng.randn(n_rows,1) / np.sqrt(n_rows)

    def test_sketch_dimensions(self):
        for A in self.test_matrices:
            for seed in self.seeds:
                sketch = clarkson_woodruff_transform(
                    A, self.n_sketch_rows, seed=seed
                )
                assert_(sketch.shape == (self.n_sketch_rows,self.n_cols))

    def test_seed_returns_identical_transform_matrix(self):
        for A in self.test_matrices:
            for seed in self.seeds:
                S1 = cwt_matrix(
                    self.n_sketch_rows, self.n_rows, seed=seed
                ).todense()
                S2 = cwt_matrix(
                    self.n_sketch_rows, self.n_rows, seed=seed
                ).todense()
                assert_equal(S1,S2)

    def test_seed_returns_identically(self):
        for A in self.test_matrices:
            for seed in self.seeds:
                sketch1 = clarkson_woodruff_transform(
                    A, self.n_sketch_rows, seed=seed
                )
                sketch2 = clarkson_woodruff_transform(
                    A, self.n_sketch_rows, seed=seed
                )
                if issparse(sketch1): sketch1 = sketch1.todense()
                if issparse(sketch2): sketch2 = sketch2.todense()
                assert_equal(sketch1,sketch2)

    def test_sketch_preserves_frobenius_norm(self):
        # Given the probabilistic nature of the sketches
        # we run the test multiple times and check that
        # we pass all/almost all the tries.
        n_errors = 0
        for A in self.test_matrices:
            true_norm = norm(A) if issparse(A) \
                        else np.linalg.norm(A)
            for seed in self.seeds:
                sketch = clarkson_woodruff_transform(
                    A, self.n_sketch_rows, seed=seed,
                )
                sketch_norm = norm(sketch) if issparse(sketch) \
                              else np.linalg.norm(sketch)

                if np.abs(true_norm - sketch_norm) > 0.1 * true_norm:
                    n_errors += 1
        assert_(n_errors == 0)

    def test_sketch_preserves_vector_norm(self):
        # Testing that the with-high-probability bound presented
        # in the documentation is right. In particular, sketch
        # dimension >= 2 / (delta * eps**2) should ensure that
        # the Euclidean norm of a sketched vector ought to be
        # within an epsilon multiplicative factor of the original.
        # Here, we try eps=0.5 and delta=0.01 so that over
        # all our seeds this norm should be presered to a 0.5
        # factor.
        n_errors = 0
        n_sketch_rows = int(np.ceil(2. / (0.01 * 0.5**2))) # = 800
        true_norm = np.linalg.norm(self.x)
        for seed in self.seeds:
            sketch = clarkson_woodruff_transform(
                self.x, n_sketch_rows, seed=seed,
            )
            sketch_norm = np.linalg.norm(sketch)

            if np.abs(true_norm - sketch_norm) > 0.5 * true_norm:
                n_errors += 1
        assert_(n_errors == 0)


if __name__ == "__main__":
    np.testing.run_module_suite()

@@ -2488,16 +2488,36 @@
 ketch1):
+%0A                   
  sketch1
@@ -2574,16 +2574,36 @@
 ketch2):
+%0A                   
  sketch2
@@ -3508,467 +3508,8 @@
 f):%0A
-        # Testing that the with-high-probability bound presented%0A        # in the documentation is right. In particular, sketch%0A        # dimension %3E= 2 / (delta * eps**2) should ensure that%0A        # the Euclidean norm of a sketched vector ought to be%0A        # within an epsilon multiplicative factor of the original.%0A        # Here, we try eps=0.5 and delta=0.01 so that over%0A        # all our seeds this norm should be presered to a 0.5%0A        # factor.%0A
     
@@ -3587,16 +3587,8 @@
 2)))
- # = 800
 %0A   

Fix PyFlakes and PyCodeStyle issues