예제 #1
0
    def companion(self):
        field = LazyIntegralDomain(self._original_base).fraction_field()

        coefficients = [field(el) for el in self.coefficients()]

        ## We divide by the leading coefficient
        coefficients = [
            -(coefficients[i] / coefficients[-1])
            for i in range(len(coefficients) - 1)
        ]
        ## Trying to reduce the elements
        try:
            for i in range(len(coefficients)):
                coefficients[i].reduce()
        except AttributeError:
            pass
        except ArithmeticError:
            pass
        d = len(coefficients)

        ## Building the rows of our matrix
        rows = [[0 for i in range(d - 1)] + [coefficients[0]]]
        for i in range(d - 1):
            rows += [[kronecker_delta(i, j)
                      for j in range(d - 1)] + [coefficients[i + 1]]]

        ## Returning the matrix
        return Matrix(field, rows)
예제 #2
0
def fractional_CRT_split(residues, ps_roots, K, BI_coordinates = None):
    if K is QQ:
        return fractional_CRT_QQ(residues, ps_roots);

    OK = K.ring_of_integers();
    BOK = OK.basis();

    residues_ZZ = [ r.lift() for r in residues];
    primes = [p for p, _ in ps_roots];
    lift = CRT_list(residues_ZZ, primes);
    lift_coordinates = OK.coordinates(lift);

    if BI_coordinates is None:
        p_ideals = [ OK.ideal(p, K.gen() - root) for p, root in ps_roots ];
        I = prod(p_ideals);
        BI = I.basis(); # basis as a ZZ-module
        BI_coordinates = [ OK.coordinates(b) for b in BI ];

    M = Matrix(Integers(), [ [ kronecker_delta(i,j) for j,_ in enumerate(BOK) ] + [ lift_coordinates[i] ] + [ b[i] for b in BI_coordinates ] for i in range(len(BOK)) ])
    # v = short_vector
    Kernel_Basis =  Matrix(Integers(), M.transpose().kernel().basis())
    v =Kernel_Basis.LLL()[0];
    #print v[:len(BOK)]
    if v[len(BOK)] == 0:
        return 0;
    return (-1/v[len(BOK)]) * sum( v[i] * b for i, b in enumerate(BOK));
예제 #3
0
    def companion(self):
        R = self.__conversion
        if (self.__companion is None or self.__version != R.version()):
            self.__version = R.version()
            coefficients = [R(el) for el in self.coefficients()]

            ## We divide by the leading coefficient
            coefficients = [
                -(coefficients[i] / coefficients[-1])
                for i in range(len(coefficients) - 1)
            ]
            ## Trying to reduce the elements
            try:
                for i in range(len(coefficients)):
                    coefficients[i].reduce()
            except AttributeError:
                pass
            d = len(coefficients)

            ## Building the rows of our matrix
            rows = [[0 for i in range(d - 1)] + [coefficients[0]]]
            for i in range(d - 1):
                rows += [[kronecker_delta(i, j)
                          for j in range(d - 1)] + [coefficients[i + 1]]]

            ## Returning the matrix
            self.__companion = Matrix(R, rows)

        return self.__companion
예제 #4
0
 def _sage_(self):
     import sage.all as sage
     return sage.kronecker_delta(self.args[0]._sage_(), self.args[1]._sage_())
예제 #5
0
 def _sage_(self):
     import sage.all as sage
     return sage.kronecker_delta(self.args[0]._sage_(),
                                 self.args[1]._sage_())
예제 #6
0
def test_sage_conversions():

    x, y = sage.SR.var('x y')
    x1, y1 = symbols('x, y')

    # Symbol
    assert x1._sage_() == x
    assert x1 == sympify(x)

    # Integer
    assert Integer(12)._sage_() == sage.Integer(12)
    assert Integer(12) == sympify(sage.Integer(12))

    # Rational
    assert (Integer(1) / 2)._sage_() == sage.Integer(1) / 2
    assert Integer(1) / 2 == sympify(sage.Integer(1) / 2)

    # Operators
    assert x1 + y == x1 + y1
    assert x1 * y == x1 * y1
    assert x1**y == x1**y1
    assert x1 - y == x1 - y1
    assert x1 / y == x1 / y1

    assert x + y1 == x + y
    assert x * y1 == x * y
    # Doesn't work in Sage 6.1.1ubuntu2
    # assert x ** y1 == x ** y
    assert x - y1 == x - y
    assert x / y1 == x / y

    # Conversions
    assert (x1 + y1)._sage_() == x + y
    assert (x1 * y1)._sage_() == x * y
    assert (x1**y1)._sage_() == x**y
    assert (x1 - y1)._sage_() == x - y
    assert (x1 / y1)._sage_() == x / y

    assert x1 + y1 == sympify(x + y)
    assert x1 * y1 == sympify(x * y)
    assert x1**y1 == sympify(x**y)
    assert x1 - y1 == sympify(x - y)
    assert x1 / y1 == sympify(x / y)

    # Functions
    assert sin(x1) == sin(x)
    assert sin(x1)._sage_() == sage.sin(x)
    assert sin(x1) == sympify(sage.sin(x))

    assert cos(x1) == cos(x)
    assert cos(x1)._sage_() == sage.cos(x)
    assert cos(x1) == sympify(sage.cos(x))

    assert function_symbol('f', x1, y1)._sage_() == sage.function('f')(x, y)
    assert (function_symbol('f', 2 * x1,
                            x1 + y1).diff(x1)._sage_() == sage.function('f')(
                                2 * x, x + y).diff(x))

    assert LambertW(x1) == LambertW(x)
    assert LambertW(x1)._sage_() == sage.lambert_w(x)

    assert KroneckerDelta(x1, y1) == KroneckerDelta(x, y)
    assert KroneckerDelta(x1, y1)._sage_() == sage.kronecker_delta(x, y)

    assert erf(x1) == erf(x)
    assert erf(x1)._sage_() == sage.erf(x)

    assert lowergamma(x1, y1) == lowergamma(x, y)
    assert lowergamma(x1, y1)._sage_() == sage.gamma_inc_lower(x, y)

    assert uppergamma(x1, y1) == uppergamma(x, y)
    assert uppergamma(x1, y1)._sage_() == sage.gamma_inc(x, y)

    assert loggamma(x1) == loggamma(x)
    assert loggamma(x1)._sage_() == sage.log_gamma(x)

    assert beta(x1, y1) == beta(x, y)
    assert beta(x1, y1)._sage_() == sage.beta(x, y)

    assert floor(x1) == floor(x)
    assert floor(x1)._sage_() == sage.floor(x)

    assert ceiling(x1) == ceiling(x)
    assert ceiling(x1)._sage_() == sage.ceil(x)

    assert conjugate(x1) == conjugate(x)
    assert conjugate(x1)._sage_() == sage.conjugate(x)

    # For the following test, sage needs to be modified
    # assert sage.sin(x) == sage.sin(x1)

    # Constants and Booleans
    assert pi._sage_() == sage.pi
    assert E._sage_() == sage.e
    assert I._sage_() == sage.I
    assert GoldenRatio._sage_() == sage.golden_ratio
    assert Catalan._sage_() == sage.catalan
    assert EulerGamma._sage_() == sage.euler_gamma
    assert oo._sage_() == sage.oo
    assert zoo._sage_() == sage.unsigned_infinity
    assert nan._sage_() == sage.NaN
    assert true._sage_() == True
    assert false._sage_() == False

    assert pi == sympify(sage.pi)
    assert E == sympify(sage.e)
    assert GoldenRatio == sympify(sage.golden_ratio)
    assert Catalan == sympify(sage.catalan)
    assert EulerGamma == sympify(sage.euler_gamma)
    assert oo == sympify(sage.oo)
    assert zoo == sympify(sage.unsigned_infinity)
    assert nan == sympify(sage.NaN)

    # SympyConverter does not support converting the following
    # assert I == sympify(sage.I)

    # Matrix
    assert DenseMatrix(1, 2, [x1, y1])._sage_() == sage.matrix([[x, y]])

    # SympyConverter does not support converting the following
    # assert DenseMatrix(1, 2, [x1, y1]) == sympify(sage.matrix([[x, y]]))

    # Sage Number
    a = sage.Mod(2, 7)
    b = PyNumber(a, sage_module)

    a = a + 8
    b = b + 8
    assert isinstance(b, PyNumber)
    assert b._sage_() == a
    assert str(a) == str(b)

    # Sage Function
    e = x1 + wrap_sage_function(sage.log_gamma(x))
    assert str(e) == "x + log_gamma(x)"
    assert isinstance(e, Add)
    assert (e + wrap_sage_function(sage.log_gamma(x)) == x1 +
            2 * wrap_sage_function(sage.log_gamma(x)))

    f = e.subs({x1: 10})
    assert f == 10 + log(362880)

    f = e.subs({x1: 2})
    assert f == 2

    f = e.subs({x1: 100})
    v = f.n(53, real=True)
    assert abs(float(v) - 459.13420537) < 1e-7

    f = e.diff(x1)
예제 #7
0
def block_matrix(parent, rows, constant_or_identity=True):
    '''
        Method that build a matrix using as blocks the elements of rows. 
        
        This method allows the user to build a matrix defining its blocks. There are two options for the inputs:
            * A matrix (that will be directly used as a block
            * Elements alone: will build a constant matrix or a diagonal matrix depending on the argument ``constant_or_identity``.
            
        This method checks that the size of the input is correct, i.e., all rows have the same amount of columns and that all 
        matrices within a row provide the same amount of rows.

        INPUT:
            * ``parent``: the desired parent for the final matrix. All elements mast be inside this parent.
            * ``rows``: a list of arguments representing the rows of the matrix. Each row is another list
              where the elements may be matrices (indicating the number of rows for this block) or elements
              in ``parent`` that will create constant or diagonal matrices with such element.
            * ``constant_or_identity``: this argument decides whether the elements create a diagonal
              matrix (``True``) or a constant matrix (``False``).

        OUTPUT:
            A matrix with the corresponding struture. If any of the sizes does not match, a :class:`~ajpastor.misc.exceptions.SizeMatrixError`
            will be raised.

        EXAMPLES::

            sage: from ajpastor.misc.matrix import *
            sage: M = Matrix(QQ,[[1,2],[3,4]]); I = identity_matrix(QQ, 3)
            sage: block_matrix(QQ,[[M,0],[0,I]])
            [1 2 0 0 0]
            [3 4 0 0 0]
            [0 0 1 0 0]
            [0 0 0 1 0]
            [0 0 0 0 1]
            sage: block_matrix(QQ, [[I, 1],[2, M]])
            [1 0 0 1 0]
            [0 1 0 0 1]
            [0 0 1 0 0]
            [2 0 0 1 2]
            [0 2 0 3 4]
            sage: block_matrix(QQ, [[I, 1],[2, M]], False)
            [1 0 0 1 1]
            [0 1 0 1 1]
            [0 0 1 1 1]
            [2 2 2 1 2]
            [2 2 2 3 4]

        This method also works with non-square matrices::

            sage: N = Matrix(QQ, [[1,2,3],[4,5,6]])
            sage: block_matrix(QQ, [[N,1],[0,M]])
            [1 2 3 1 0]
            [4 5 6 0 1]
            [0 0 0 1 2]
            [0 0 0 3 4]
            sage: block_matrix(QQ, [[N,M],[1,2]], False)
            [1 2 3 1 2]
            [4 5 6 3 4]
            [1 1 1 2 2]
        
        However, the sizes of the columns and rows has to fit::

            sage: block_matrix(QQ, [[N, 1], [M, 0]])
            Traceback (most recent call last):
            ...
            SizeMatrixError: The col has not the proper format -- different size

        This method also allows matrices in list format::

            sage: block_matrix(QQ, [[N, [[0, 1],[-1,0]]], [1, M]])
            [ 1  2  3  0  1]
            [ 4  5  6 -1  0]
            [ 1  0  0  1  2]
            [ 0  1  0  3  4]
            sage: block_matrix(QQ, [[N, [[0, 1],[1,0],[1,1]]],[1, M]])
            Traceback (most recent call last):
            ...
            SizeMatrixError: The row has not the proper format -- different size

        And also, if all entries are matrices, we do not need to have in the input all the 
        rows with the same length::

            sage: L = Matrix(QQ, [[5, 4, 3, 2, 1]])
            sage: block_matrix(QQ, [[M, N],[L]])
            [1 2 1 2 3]
            [3 4 4 5 6]
            [5 4 3 2 1]
            sage: block_matrix(QQ, [[N, I[:2]], [L,[[9]]]])
            [1 2 3 1 0 0]
            [4 5 6 0 1 0]
            [5 4 3 2 1 9]
            sage: block_matrix(QQ, [[N, I[:2]], [L]])
            Traceback (most recent call last):
            ...
            SizeMatrixError: The given rows have different column size

        Finally, this method also allows the user to create a Matrix in a normal fashion 
        (providing each of its elements)::

            sage: block_matrix(QQ, [[1,2],[3,4]]) == M
            True
    '''
    ## We have two different ways of seeing the input: either all the provided rows are of the same size,
    ## allowing to have input in the parent ring, or the sizes must match perfectly between the rows.

    # Checking the first case: if any element is in parent
    if (any(any((el in parent) for el in row) for row in rows)):
        d = len(rows[0])
        for i in range(1, len(rows)):
            if (d != len(rows[i])):
                raise SizeMatrixError(
                    "The rows provided can not be seen as a matrix")

        ## We check the sizes
        rows_hights = [__check_row(row, parent) for row in rows]
        cols_widths = [
            __check_col([rows[i][j] for i in range(len(rows))], parent)
            for j in range(len(rows[0]))
        ]

        rows_with_matrix = []
        for i in range(len(rows)):
            row_with_matrix = []
            for j in range(len(rows[0])):
                if (rows[i][j] in parent):
                    if (constant_or_identity):
                        row_with_matrix += [
                            Matrix(parent, [[
                                rows[i][j] * kronecker_delta(k, l)
                                for l in range(cols_widths[j])
                            ] for k in range(rows_hights[i])])
                        ]
                    else:
                        row_with_matrix += [
                            Matrix(
                                parent,
                                [[rows[i][j] for l in range(cols_widths[j])]
                                 for k in range(rows_hights[i])])
                        ]
                else:
                    row_with_matrix += [Matrix(parent, rows[i][j])]
            rows_with_matrix += [row_with_matrix]
    else:  # Second case: all elements are matrices, hence they must fit exactly
        ## We check the sizes
        rows_hights = [__check_row(row, parent) for row in rows]
        cols_widths = [sum(__ncols(el) for el in row) for row in rows]

        if (any(el != cols_widths[0] for el in cols_widths)):
            raise SizeMatrixError("The given rows have different column size")

        rows_with_matrix = []
        for i in range(len(rows)):
            row_with_matrix = []
            for j in range(len(rows[i])):
                row_with_matrix += [Matrix(parent, rows[i][j])]
            rows_with_matrix += [row_with_matrix]

    ## At this point the variable "row_with_matrix" has all the entries for the final matrix
    ## No checks are needed
    final_rows = []
    for i in range(len(rows_with_matrix)):
        for j in range(rows_hights[i]):
            final_rows += [
                reduce(lambda p, q: p + q,
                       [list(el[j]) for el in rows_with_matrix[i]])
            ]
    return Matrix(parent, final_rows)