# Path: preimage/features/n_gram_feature_space.py
# class NGramFeatureSpace:
#     """Output feature space for the N-Gram Kernel
# 
#     Creates a sparse matrix representation of the n-grams in each training string. This is used to compute the weights
#     of the graph during the inference phase.
# 
#     Attributes
#     ----------
#     feature_space : sparse matrix, shape = [n_samples, len(alphabet)**n]
#         Sparse matrix representation of the n-grams in each training string, where n_samples is the number of training
#         samples.
#     """
# 
#     def __init__(self, alphabet, n, Y, is_normalized):
#         """Create the output feature space for the N-Gram Kernel
# 
#         Parameters
#         ----------
#         alphabet : list
#             list of letters
#         n : int
#             N-gram length.
#         Y : array, [n_samples, ]
#             The training strings.
#         is_normalized : bool
#             True if the feature space should be normalized, False otherwise.
#         """
#         self.feature_space = build_feature_space_without_positions(alphabet, n, Y)
#         self._normalize(is_normalized, self.feature_space)
# 
#     def _normalize(self, is_normalized, feature_space):
#         if is_normalized:
#             y_normalization = self._get_y_normalization(feature_space)
#             data_normalization = y_normalization.repeat(numpy.diff(feature_space.indptr))
#             feature_space.data *= data_normalization
# 
#     def _get_y_normalization(self, feature_space):
#         y_normalization = (feature_space.multiply(feature_space)).sum(axis=1)
#         y_normalization = 1. / numpy.sqrt(numpy.array((y_normalization.reshape(1, -1))[0]))
#         return y_normalization
# 
#     def compute_weights(self, y_weights):
#         """Compute the inference graph weights
# 
#         Parameters
#         ----------
#         y_weights :  array, [n_samples]
#             Weight of each training example.
# 
#         Returns
#         -------
#         n_gram_weights : [len(alphabet)**n]
#             Weight of each n-gram.
#         """
#         data_copy = numpy.copy(self.feature_space.data)
#         self.feature_space.data *= self._repeat_each_y_weight_by_y_column_count(y_weights)
#         n_gram_weights = numpy.array(self.feature_space.sum(axis=0))[0]
#         self.feature_space.data = data_copy
#         return n_gram_weights
# 
#     def _repeat_each_y_weight_by_y_column_count(self, y_weights):
#         return y_weights.repeat(numpy.diff(self.feature_space.indptr))


from math import sqrt
from mock import patch
from scipy.sparse import csr_matrix
from preimage.features.n_gram_feature_space import NGramFeatureSpace
import unittest2
import numpy.testing
        feature_space_normalized = numpy.array(feature_space.feature_space.todense())

        numpy.testing.assert_array_equal(feature_space_normalized, self.feature_space_normalized_one_gram_abb)

    def test_two_gram_one_y_normalized_feature_space_is_normalized(self):
        self.feature_space_builder_patch.start().return_value = self.feature_space_two_gram_abb

        feature_space = NGramFeatureSpace(self.alphabet, n=2, Y=self.abb, is_normalized=True)
        feature_space_normalized = numpy.array(feature_space.feature_space.todense())

        numpy.testing.assert_array_equal(feature_space_normalized, self.feature_space_normalized_two_gram_abb)

    def test_two_gram_two_y_normalized_feature_space_is_normalized(self):
        self.feature_space_builder_patch.start().return_value = self.feature_space_one_gram_abb_abaaa

        feature_space = NGramFeatureSpace(self.alphabet, n=1, Y=self.abb, is_normalized=True)
        feature_space_normalized = numpy.array(feature_space.feature_space.todense())

        numpy.testing.assert_array_equal(feature_space_normalized, self.feature_space_normalized_one_gram_abb_abaaa)

    def test_one_y_with_one_half_weight_compute_one_gram_weights_returns_expected_weights(self):
        self.feature_space_builder_patch.start().return_value = self.feature_space_one_gram_abb
        feature_space = NGramFeatureSpace(self.alphabet, n=1, Y=self.abb, is_normalized=False)

        n_gram_weights = feature_space.compute_weights(y_weights=numpy.array([0.5]))

        numpy.testing.assert_array_equal(n_gram_weights, self.one_gram_weights_one_half_abb)

    def test_one_y_with_one_half_weight_compute_two_gram_weights_returns_expected_weights(self):
        self.feature_space_builder_patch.start().return_value = self.feature_space_two_gram_abb

# Path: preimage/features/n_gram_feature_space.py
# class NGramFeatureSpace:
#     """Output feature space for the N-Gram Kernel
# 
#     Creates a sparse matrix representation of the n-grams in each training string. This is used to compute the weights
#     of the graph during the inference phase.
# 
#     Attributes
#     ----------
#     feature_space : sparse matrix, shape = [n_samples, len(alphabet)**n]
#         Sparse matrix representation of the n-grams in each training string, where n_samples is the number of training
#         samples.
#     """
# 
#     def __init__(self, alphabet, n, Y, is_normalized):
#         """Create the output feature space for the N-Gram Kernel
# 
#         Parameters
#         ----------
#         alphabet : list
#             list of letters
#         n : int
#             N-gram length.
#         Y : array, [n_samples, ]
#             The training strings.
#         is_normalized : bool
#             True if the feature space should be normalized, False otherwise.
#         """
#         self.feature_space = build_feature_space_without_positions(alphabet, n, Y)
#         self._normalize(is_normalized, self.feature_space)
# 
#     def _normalize(self, is_normalized, feature_space):
#         if is_normalized:
#             y_normalization = self._get_y_normalization(feature_space)
#             data_normalization = y_normalization.repeat(numpy.diff(feature_space.indptr))
#             feature_space.data *= data_normalization
# 
#     def _get_y_normalization(self, feature_space):
#         y_normalization = (feature_space.multiply(feature_space)).sum(axis=1)
#         y_normalization = 1. / numpy.sqrt(numpy.array((y_normalization.reshape(1, -1))[0]))
#         return y_normalization
# 
#     def compute_weights(self, y_weights):
#         """Compute the inference graph weights
# 
#         Parameters
#         ----------
#         y_weights :  array, [n_samples]
#             Weight of each training example.
# 
#         Returns
#         -------
#         n_gram_weights : [len(alphabet)**n]
#             Weight of each n-gram.
#         """
#         data_copy = numpy.copy(self.feature_space.data)
#         self.feature_space.data *= self._repeat_each_y_weight_by_y_column_count(y_weights)
#         n_gram_weights = numpy.array(self.feature_space.sum(axis=0))[0]
#         self.feature_space.data = data_copy
#         return n_gram_weights
# 
#     def _repeat_each_y_weight_by_y_column_count(self, y_weights):
#         return y_weights.repeat(numpy.diff(self.feature_space.indptr))


# Path: preimage/tests/features/test_n_gram_feature_space.py
from math import sqrt
from mock import patch
from scipy.sparse import csr_matrix
from preimage.features.n_gram_feature_space import NGramFeatureSpace
import unittest2
import numpy.testing

        feature_space_normalized = numpy.array(feature_space.feature_space.todense())

        numpy.testing.assert_array_equal(feature_space_normalized, self.feature_space_normalized_one_gram_abb)

    def test_two_gram_one_y_normalized_feature_space_is_normalized(self):
        self.feature_space_builder_patch.start().return_value = self.feature_space_two_gram_abb

        feature_space = NGramFeatureSpace(self.alphabet, n=2, Y=self.abb, is_normalized=True)
        feature_space_normalized = numpy.array(feature_space.feature_space.todense())

        numpy.testing.assert_array_equal(feature_space_normalized, self.feature_space_normalized_two_gram_abb)

    def test_two_gram_two_y_normalized_feature_space_is_normalized(self):
        self.feature_space_builder_patch.start().return_value = self.feature_space_one_gram_abb_abaaa

        feature_space = NGramFeatureSpace(self.alphabet, n=1, Y=self.abb, is_normalized=True)
        feature_space_normalized = numpy.array(feature_space.feature_space.todense())

        numpy.testing.assert_array_equal(feature_space_normalized, self.feature_space_normalized_one_gram_abb_abaaa)

    def test_one_y_with_one_half_weight_compute_one_gram_weights_returns_expected_weights(self):
        self.feature_space_builder_patch.start().return_value = self.feature_space_one_gram_abb
        feature_space = NGramFeatureSpace(self.alphabet, n=1, Y=self.abb, is_normalized=False)

        n_gram_weights = feature_space.compute_weights(y_weights=numpy.array([0.5]))

        numpy.testing.assert_array_equal(n_gram_weights, self.one_gram_weights_one_half_abb)

    def test_one_y_with_one_half_weight_compute_two_gram_weights_returns_expected_weights(self):
        self.feature_space_builder_patch.start().return_value = self.feature_space_two_gram_abb

        feature_space = NGramFeatureSpace(self.alphabet, n=2, Y=self.abb, is_normalized=False)