<commit_before>import gc
import numpy
import pandas
import scipy.linalg
import theano
from theano.sandbox.linalg.ops import matrix_dot
from pandas import Series
import qit.utils
from palm.probability_vector import make_prob_vec_from_panda_series
from palm.probability_matrix import make_prob_matrix_from_panda_data_frame
from palm.util import DATA_TYPE

# UNCOMMENT AFTER IMPLEMENTING PYCUDA CLASS
# from pycuda import driver, compiler, gpuarray, tools
# import pycuda.autoinit

def vector_product(vec1, vec2, do_alignment=True):
    """
    Computes the dot product of two vectors.

    Parameters
    ----------
    vec1, vec2 : ProbabilityVector

    Returns
    -------
    product_scalar : float
    """
    if do_alignment:
        series1, series2 = vec1.series.align(vec2.series)
    else:
        series1, series2 = (vec1.series, vec2.series)
    product_scalar = series1.dot(series2)
    return product_scalar

def vector_matrix_product(vec, matrix, do_alignment=True):
    """
    Computes the dot product of a vector and a matrix.

    Parameters
    ----------
    vec : ProbabilityVector
    matrix : RateMatrix or ProbabilityMatrix
    do_alignment : bool, optional
        Whether to align the elements of the vector and matrix
        before computing the dot product.

    Returns
    -------
    product_vec : ProbabilityVector
    """
    if do_alignment:
        alignment_results = matrix.data_frame.align(
                                vec.series, axis=0, join='left')
        frame, series = alignment_results
    else:
        frame, series = (matrix.data_frame, vec.series)
    product_series = series.dot(frame)
    if type(product_series) == numpy.ndarray:
        # for some reason, the vector frame dot product produces a numpy
        # array if they only have one entry
        product_series = Series(product_series, index=vec.series.index.tolist())
    product_vec = make_prob_vec_from_panda_series(product_series)
    return product_vec

def matrix_vector_product(matrix, vec, do_alignment=True):
    """
    Computes the dot product of a matrix and a vector.

    Parameters
    ----------
    matrix : RateMatrix or ProbabilityMatrix
    vec : ProbabilityVector
    do_alignment : bool, optional
        Whether to align the elements of the matrix and the vector
        before computing the dot product.

    Returns
    -------
    product_vec : ProbabilityVector
    """
    if do_alignment:
        alignment_results = matrix.data_frame.align(
                                vec.series, axis=1, join='right')
        frame, series = alignment_results
    else:
        frame, series = (matrix.data_frame, vec.series)
    product_series = frame.dot(series)
    if type(product_series) == numpy.ndarray:
        # for some reason, the vector frame dot product produces a numpy
        # array if they only have one entry
        product_series = Series(product_series, index=vec.series.index.tolist())
    product_vec = make_prob_vec_from_panda_series(product_series)
    return product_vec

def asym_vector_matrix_product(vec, matrix, do_alignment=True):
    """
    Compute the dot product of a vector and a matrix. In this case,
    the matrix is asymmetric: the number of rows match the length of the
    vector but the number of columns does not.

    Parameters
    ----------
    vec : ProbabilityVector
    matrix : RateMatrix or ProbabilityMatrix
    do_alignment : bool, optional
        Whether to align the elements of the vector with the rows of the
        matrix before computing the dot product.

    Returns
    -------
    product_vec : ProbabilityVector
    """
    if do_alignment:
        alignment_results = matrix.data_frame.align(
                                vec.series, axis=0, join='left')
        frame, series = alignment_results
    else:
        frame, series = (matrix.data_frame, vec.series)
    product_series = Series(numpy.dot(series.values, frame.values),
                            index=frame.columns)
    product_vec = make_prob_vec_from_panda_series(product_series)
    return product_vec

def asym_matrix_vector_product(matrix, vec, do_alignment=True):
    """
    Compute the dot product of a matrix and a vector. In this case,
    the matrix is asymmetric: the number of columns match the length of the
    vector but the number of rows does not.

    Parameters
    ----------
    matrix : RateMatrix or ProbabilityMatrix
    vec : ProbabilityVector
    do_alignment : bool, optional
        Whether to align the elements of the vector with the columns of the
        matrix before computing the dot product.

    Returns
    -------
    product_vec : ProbabilityVector
    """
    if do_alignment:
        alignment_results = matrix.data_frame.align(
                                vec.series, axis=1, join='right')
        frame, series = alignment_results
    else:
        frame, series = (matrix.data_frame, vec.series)
    product_series = Series(numpy.dot(frame.values, series.values),
                            index=frame.index)
    product_vec = make_prob_vec_from_panda_series(product_series)
    return product_vec

def symmetric_matrix_matrix_product(matrix1, matrix2, do_alignment=True):
    """
    Compute the dot product of two symmetric matrices.

    Parameters
    ----------
    matrix1, matrix2 : ProbabilityMatrix
    do_alignment : bool, optional
        Whether to align the columns of `matrix1` with the rows of
        `matrix2` before computing the dot product.

    Returns
    -------
    product_matrix : ProbabilityMatrix
    """
    if do_alignment:
        alignment_results = matrix1.data_frame.align(
                                matrix2.data_frame, axis=None, join='left')
        frame1, frame2 = alignment_results
    else:
        frame1, frame2 = (matrix1.data_frame, matrix2.data_frame)
    product_frame = frame1.dot(frame2)
    product_matrix = make_prob_matrix_from_panda_data_frame(product_frame)
    return product_matrix

def asymmetric_matrix_matrix_product(matrix1, matrix2, do_alignment=True):
    """
    Compute the dot product of two asymmetric matrices.

    Parameters
    ----------
    matrix1, matrix2 : ProbabilityMatrix
    do_alignment : bool, optional
        Whether to align the columns of `matrix1` with the rows of
        `matrix2` before computing the dot product.

    Returns
    -------
    product_matrix : ProbabilityMatrix
    """
    if do_alignment:
        alignment_results = matrix1.data_frame.align(
                                matrix2.data_frame, axis=0, join='left')
        frame1, frame2 = alignment_results
    else:
        frame1, frame2 = (matrix1.data_frame, matrix2.data_frame)
    product_frame = frame1.dot(frame2)
    product_matrix = make_prob_matrix_from_panda_data_frame(product_frame)
    return product_matrix


class StubExponential(object):
    """
    This matrix exponential class is designed for code profiling.
    It follows the same setup procedures as `QitMatrixExponential`
    but doesn't actually call the matrix exponential routine.
    """
    def __init__(self):
        pass

    def compute_matrix_expv(self, rate_matrix, dwell_time, vec):
        alignment_results = rate_matrix.data_frame.align(
                                vec.series, axis=1, join='right')
        aligned_frame, aligned_series = alignment_results
        v = numpy.array(aligned_series)
        Q = aligned_frame.values
        return vec


class ScipyMatrixExponential(object):
    """
    Compute matrix exponential via scipy.linalg.expm, which uses
    the pade approximation.
    """
    def __init__(self):
        super(ScipyMatrixExponential, self).__init__()
        print "Warning: scipy.linalg.expm appears to leak memory,"\
              "as of version 0.13. ScipyMatrixExponential2 is preferred."

    def compute_matrix_exp(self, rate_matrix, dwell_time):
        """
        Computes ``exp(Qt)``

        Parameters
        ----------
        rate_matrix : RateMatrix
        dwell_time : float<commit_msg>Check scipy version before warning about expm.<commit_after>import gc
import numpy
import pandas
import scipy
import scipy.linalg
import theano
from theano.sandbox.linalg.ops import matrix_dot
from pandas import Series
import qit.utils
from palm.probability_vector import make_prob_vec_from_panda_series
from palm.probability_matrix import make_prob_matrix_from_panda_data_frame
from palm.util import DATA_TYPE

# UNCOMMENT AFTER IMPLEMENTING PYCUDA CLASS
# from pycuda import driver, compiler, gpuarray, tools
# import pycuda.autoinit

def vector_product(vec1, vec2, do_alignment=True):
    """
    Computes the dot product of two vectors.

    Parameters
    ----------
    vec1, vec2 : ProbabilityVector

    Returns
    -------
    product_scalar : float
    """
    if do_alignment:
        series1, series2 = vec1.series.align(vec2.series)
    else:
        series1, series2 = (vec1.series, vec2.series)
    product_scalar = series1.dot(series2)
    return product_scalar

def vector_matrix_product(vec, matrix, do_alignment=True):
    """
    Computes the dot product of a vector and a matrix.

    Parameters
    ----------
    vec : ProbabilityVector
    matrix : RateMatrix or ProbabilityMatrix
    do_alignment : bool, optional
        Whether to align the elements of the vector and matrix
        before computing the dot product.

    Returns
    -------
    product_vec : ProbabilityVector
    """
    if do_alignment:
        alignment_results = matrix.data_frame.align(
                                vec.series, axis=0, join='left')
        frame, series = alignment_results
    else:
        frame, series = (matrix.data_frame, vec.series)
    product_series = series.dot(frame)
    if type(product_series) == numpy.ndarray:
        # for some reason, the vector frame dot product produces a numpy
        # array if they only have one entry
        product_series = Series(product_series, index=vec.series.index.tolist())
    product_vec = make_prob_vec_from_panda_series(product_series)
    return product_vec

def matrix_vector_product(matrix, vec, do_alignment=True):
    """
    Computes the dot product of a matrix and a vector.

    Parameters
    ----------
    matrix : RateMatrix or ProbabilityMatrix
    vec : ProbabilityVector
    do_alignment : bool, optional
        Whether to align the elements of the matrix and the vector
        before computing the dot product.

    Returns
    -------
    product_vec : ProbabilityVector
    """
    if do_alignment:
        alignment_results = matrix.data_frame.align(
                                vec.series, axis=1, join='right')
        frame, series = alignment_results
    else:
        frame, series = (matrix.data_frame, vec.series)
    product_series = frame.dot(series)
    if type(product_series) == numpy.ndarray:
        # for some reason, the vector frame dot product produces a numpy
        # array if they only have one entry
        product_series = Series(product_series, index=vec.series.index.tolist())
    product_vec = make_prob_vec_from_panda_series(product_series)
    return product_vec

def asym_vector_matrix_product(vec, matrix, do_alignment=True):
    """
    Compute the dot product of a vector and a matrix. In this case,
    the matrix is asymmetric: the number of rows match the length of the
    vector but the number of columns does not.

    Parameters
    ----------
    vec : ProbabilityVector
    matrix : RateMatrix or ProbabilityMatrix
    do_alignment : bool, optional
        Whether to align the elements of the vector with the rows of the
        matrix before computing the dot product.

    Returns
    -------
    product_vec : ProbabilityVector
    """
    if do_alignment:
        alignment_results = matrix.data_frame.align(
                                vec.series, axis=0, join='left')
        frame, series = alignment_results
    else:
        frame, series = (matrix.data_frame, vec.series)
    product_series = Series(numpy.dot(series.values, frame.values),
                            index=frame.columns)
    product_vec = make_prob_vec_from_panda_series(product_series)
    return product_vec

def asym_matrix_vector_product(matrix, vec, do_alignment=True):
    """
    Compute the dot product of a matrix and a vector. In this case,
    the matrix is asymmetric: the number of columns match the length of the
    vector but the number of rows does not.

    Parameters
    ----------
    matrix : RateMatrix or ProbabilityMatrix
    vec : ProbabilityVector
    do_alignment : bool, optional
        Whether to align the elements of the vector with the columns of the
        matrix before computing the dot product.

    Returns
    -------
    product_vec : ProbabilityVector
    """
    if do_alignment:
        alignment_results = matrix.data_frame.align(
                                vec.series, axis=1, join='right')
        frame, series = alignment_results
    else:
        frame, series = (matrix.data_frame, vec.series)
    product_series = Series(numpy.dot(frame.values, series.values),
                            index=frame.index)
    product_vec = make_prob_vec_from_panda_series(product_series)
    return product_vec

def symmetric_matrix_matrix_product(matrix1, matrix2, do_alignment=True):
    """
    Compute the dot product of two symmetric matrices.

    Parameters
    ----------
    matrix1, matrix2 : ProbabilityMatrix
    do_alignment : bool, optional
        Whether to align the columns of `matrix1` with the rows of
        `matrix2` before computing the dot product.

    Returns
    -------
    product_matrix : ProbabilityMatrix
    """
    if do_alignment:
        alignment_results = matrix1.data_frame.align(
                                matrix2.data_frame, axis=None, join='left')
        frame1, frame2 = alignment_results
    else:
        frame1, frame2 = (matrix1.data_frame, matrix2.data_frame)
    product_frame = frame1.dot(frame2)
    product_matrix = make_prob_matrix_from_panda_data_frame(product_frame)
    return product_matrix

def asymmetric_matrix_matrix_product(matrix1, matrix2, do_alignment=True):
    """
    Compute the dot product of two asymmetric matrices.

    Parameters
    ----------
    matrix1, matrix2 : ProbabilityMatrix
    do_alignment : bool, optional
        Whether to align the columns of `matrix1` with the rows of
        `matrix2` before computing the dot product.

    Returns
    -------
    product_matrix : ProbabilityMatrix
    """
    if do_alignment:
        alignment_results = matrix1.data_frame.align(
                                matrix2.data_frame, axis=0, join='left')
        frame1, frame2 = alignment_results
    else:
        frame1, frame2 = (matrix1.data_frame, matrix2.data_frame)
    product_frame = frame1.dot(frame2)
    product_matrix = make_prob_matrix_from_panda_data_frame(product_frame)
    return product_matrix


class StubExponential(object):
    """
    This matrix exponential class is designed for code profiling.
    It follows the same setup procedures as `QitMatrixExponential`
    but doesn't actually call the matrix exponential routine.
    """
    def __init__(self):
        pass

    def compute_matrix_expv(self, rate_matrix, dwell_time, vec):
        alignment_results = rate_matrix.data_frame.align(
                                vec.series, axis=1, join='right')
        aligned_frame, aligned_series = alignment_results
        v = numpy.array(aligned_series)
        Q = aligned_frame.values
        return vec


class ScipyMatrixExponential(object):
    """
    Compute matrix exponential via scipy.linalg.expm, which uses
    the pade approximation.
    """
    def __init__(self):
        super(ScipyMatrixExponential, self).__init__()
        if scipy.__version__ == 0.13:
            print "Warning: scipy.linalg.expm appears to leak memory,"\
                  "in version 0.13."

    def compute_matrix_exp(self, rate_matrix, dwell_time):
        """
        Computes ``exp(Qt)``

        Parameters
        ----------
        rate_matrix : RateMatrix
        dwell_time : float
{'fraction_non_alphanumeric': 0.07968895800933126, 'fraction_numerical': 0.007091757387247278, 'mean_word_length': 2.590797408979227, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6909110', 'n_tokens_mistral': 4509, 'n_tokens_neox': 4349, 'n_words': 1304}