# Path: preimage/features/string_feature_space.py
# def build_feature_space_with_positions(alphabet, n, Y):
#     """Create the feature space by considering the position of the n-gram in the strings
# 
#     Parameters
#     ----------
#     alphabet : list
#         list of letters
#     n : int
#         n-gram length
#     Y : array, [n_samples, ]
#         The training strings.
# 
#     Returns
#     -------
#     feature_space : sparse matrix, shape = [n_samples, max_n_gram_count * len(alphabet)**n]
#         Sparse matrix representation of the n-grams in each string of Y, where n_samples is the number of training
#         samples and max_n_gram_count is the number of n-gram in the highest length string of Y.
#     """
#     n = int(n)
#     n_examples = numpy.array(Y).shape[0]
#     n_gram_to_index = get_n_gram_to_index(alphabet, n)
#     index_pointers, indexes, data = __initialize_pointers_indexes_data(n_examples)
#     __build_pointers_indexes_data_with_positions(index_pointers, indexes, data, n, n_gram_to_index, Y)
#     n_columns = __get_n_columns(n, len(n_gram_to_index), Y)
#     feature_space = __build_csr_matrix(index_pointers, indexes, data, n_examples, n_columns)
#     return feature_space
# 
# Path: preimage/utils/position.py
# def compute_position_weights(position_index, max_position, sigma_position):
#     position_penalties = numpy.array([(position_index - j) ** 2 for j in range(max_position)], dtype=numpy.float)
#     position_penalties /= -2. * (sigma_position ** 2)
#     return numpy.exp(position_penalties)
# 
# Path: preimage/kernels/generic_string.py
# def element_wise_kernel(X, sigma_position, n, alphabet):
#     """Compute the similarity of each string in X with itself in the Generic String kernel.
# 
#     Takes only in account the position penalties and the n-gram of length n. No n-gram penalties (no sigma_c).
# 
#     Parameters
#     ----------
#     X : array, shape = [n_samples]
#         Strings, where n_samples is the number of examples in X.
#     sigma_position : float
#         Controls the penalty incurred when two n-grams are not sharing the same position.
#     n : int
#         N-gram length.
#     alphabet : list
#         List of letters.
# 
#     Returns
#     -------
#     kernel : array, shape = [n_samples]
#         Similarity of each string with itself in the GS kernel, where n_samples is the number of examples in X.
#         """
#     X = numpy.array(X)
#     x_lengths = numpy.array([len(x) for x in X], dtype=numpy.int64)
#     max_length = numpy.max(x_lengths) - n + 1
#     position_matrix = compute_position_weights_matrix(max_length, sigma_position)
#     X_int = transform_strings_to_integer_lists(X, alphabet)
#     kernel = element_wise_generic_string_kernel(X_int, x_lengths, position_matrix, n)
#     return kernel


import numpy
from preimage.features.string_feature_space import build_feature_space_with_positions
from preimage.utils.position import compute_position_weights
from preimage.kernels.generic_string import element_wise_kernel
    sigma_position : float
        Parameter of the Generic String Kernel controlling the penalty incurred when two n-grams are not sharing the
        same position.
    max_n_gram_count : int
        The number of n-grams in the training string of highest length.
    feature_space : sparse matrix, shape = [n_samples, max_n_gram_count * 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, sigma_position, is_normalized):
        """Create the output feature space for the Generic String kernel

        Parameters
        ----------
        alphabet : list
            list of letters
        n : int
            n-gram length
        Y : array, [n_samples, ]
            The training strings.
        sigma_position : float
            Parameter of the Generic String Kernel controlling the penalty incurred when two n-grams are not sharing the
            same position.
        is_normalized : bool
            True if the feature space should be normalized, False otherwise.
        """
        self.n = int(n)
        self.sigma_position = sigma_position
        self._alphabet_n_gram_count = len(alphabet) ** n

# Path: preimage/features/string_feature_space.py
# def build_feature_space_with_positions(alphabet, n, Y):
#     """Create the feature space by considering the position of the n-gram in the strings
# 
#     Parameters
#     ----------
#     alphabet : list
#         list of letters
#     n : int
#         n-gram length
#     Y : array, [n_samples, ]
#         The training strings.
# 
#     Returns
#     -------
#     feature_space : sparse matrix, shape = [n_samples, max_n_gram_count * len(alphabet)**n]
#         Sparse matrix representation of the n-grams in each string of Y, where n_samples is the number of training
#         samples and max_n_gram_count is the number of n-gram in the highest length string of Y.
#     """
#     n = int(n)
#     n_examples = numpy.array(Y).shape[0]
#     n_gram_to_index = get_n_gram_to_index(alphabet, n)
#     index_pointers, indexes, data = __initialize_pointers_indexes_data(n_examples)
#     __build_pointers_indexes_data_with_positions(index_pointers, indexes, data, n, n_gram_to_index, Y)
#     n_columns = __get_n_columns(n, len(n_gram_to_index), Y)
#     feature_space = __build_csr_matrix(index_pointers, indexes, data, n_examples, n_columns)
#     return feature_space
# 
# Path: preimage/utils/position.py
# def compute_position_weights(position_index, max_position, sigma_position):
#     position_penalties = numpy.array([(position_index - j) ** 2 for j in range(max_position)], dtype=numpy.float)
#     position_penalties /= -2. * (sigma_position ** 2)
#     return numpy.exp(position_penalties)
# 
# Path: preimage/kernels/generic_string.py
# def element_wise_kernel(X, sigma_position, n, alphabet):
#     """Compute the similarity of each string in X with itself in the Generic String kernel.
# 
#     Takes only in account the position penalties and the n-gram of length n. No n-gram penalties (no sigma_c).
# 
#     Parameters
#     ----------
#     X : array, shape = [n_samples]
#         Strings, where n_samples is the number of examples in X.
#     sigma_position : float
#         Controls the penalty incurred when two n-grams are not sharing the same position.
#     n : int
#         N-gram length.
#     alphabet : list
#         List of letters.
# 
#     Returns
#     -------
#     kernel : array, shape = [n_samples]
#         Similarity of each string with itself in the GS kernel, where n_samples is the number of examples in X.
#         """
#     X = numpy.array(X)
#     x_lengths = numpy.array([len(x) for x in X], dtype=numpy.int64)
#     max_length = numpy.max(x_lengths) - n + 1
#     position_matrix = compute_position_weights_matrix(max_length, sigma_position)
#     X_int = transform_strings_to_integer_lists(X, alphabet)
#     kernel = element_wise_generic_string_kernel(X_int, x_lengths, position_matrix, n)
#     return kernel


# Path: preimage/features/gs_feature_space.py
import numpy
from preimage.features.string_feature_space import build_feature_space_with_positions
from preimage.utils.position import compute_position_weights
from preimage.kernels.generic_string import element_wise_kernel

    sigma_position : float
        Parameter of the Generic String Kernel controlling the penalty incurred when two n-grams are not sharing the
        same position.
    max_n_gram_count : int
        The number of n-grams in the training string of highest length.
    feature_space : sparse matrix, shape = [n_samples, max_n_gram_count * 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, sigma_position, is_normalized):
        """Create the output feature space for the Generic String kernel

        Parameters
        ----------
        alphabet : list
            list of letters
        n : int
            n-gram length
        Y : array, [n_samples, ]
            The training strings.
        sigma_position : float
            Parameter of the Generic String Kernel controlling the penalty incurred when two n-grams are not sharing the
            same position.
        is_normalized : bool
            True if the feature space should be normalized, False otherwise.
        """
        self.n = int(n)
        self.sigma_position = sigma_position
        self._alphabet_n_gram_count = len(alphabet) ** n

        self.feature_space = build_feature_space_with_positions(alphabet, self.n, Y)