Ticket #13568: Trac13569_quaternion_orders.patch

File Trac13569_quaternion_orders.patch, 35.7 KB (added by aly.deines, 10 years ago)
  • sage/algebras/quatalg/quaternion_algebra.py

    # HG changeset patch
    # User Aly Deines <aly.deines@gmail.com>
    # Date 1349330214 25200
    # Node ID 9334dd8aea4fce8ec9f087adae1fe567a846889f
    # Parent  bab2690a542fc02d4d78e7056252cda3a2f157fc
    Fixed some doctests
    
    diff --git a/sage/algebras/quatalg/quaternion_algebra.py b/sage/algebras/quatalg/quaternion_algebra.py
    a b  
    5555from sage.structure.element import is_RingElement
    5656from sage.modules.free_module import VectorSpace, FreeModule
    5757from sage.modules.free_module_element import vector
     58import sage.libs.pari.all as pari
    5859
    5960from operator import itemgetter
    6061
     
    312313        except AttributeError:
    313314            self.__basis = tuple([self(1)] + list(self.gens()))
    314315            return self.__basis
     316           
     317    def basis_for_quaternion_lattice(self, gens, ideal_list = None, reverse = False):
     318        """
     319        Return a basis for the `\\ZZ_F`-lattice in a quaternion algebra
     320        spanned by the given gens.
     321
     322        INPUT:
     323
     324
     325        - ``gens`` -- list of elements of the quaternion algebra
     326
     327        - ``reverse`` -- (when A is over the rationals) when computing the HNF do it on the basis
     328                         (k,j,i,1) instead of (1,i,j,k). This ensures
     329                         that if ``gens`` are the generators for an order,
     330                         the first returned basis vector is 1.
     331
     332        EXAMPLES::
     333
     334            sage: A.<i,j,k> = QuaternionAlgebra(-1,-7)
     335            sage: A.basis_for_quaternion_lattice([i+j, i-j, 2*k, A(1/3)])
     336            [1/3, i + j, 2*j, 2*k]
     337
     338            sage: A.basis_for_quaternion_lattice([A(1),i,j,k])
     339            [1, i, j, k]
     340           
     341            sage: F.<a> = NumberField(x^2-x-1)
     342            sage: B.<i,j,k> = QuaternionAlgebra(F, 2*a,F(-1))
     343            sage: B.basis_for_quaternion_lattice([1,i+2*j,j,i+j+3*k])
     344            [1, i, j, 3*k]
     345           
     346            sage: K.<b> = NumberField(x^2+5)
     347            sage: A.<i,j,k> = QuaternionAlgebra(K,b,2*b)
     348            sage: A.basis_for_quaternion_lattice([1,(b+5)*i,10*i,j,k])
     349            ([1, i, j, k], [Fractional ideal (1), Fractional ideal (10, b + 5),
     350            Fractional ideal (1), Fractional ideal (1)])
     351            sage: A.basis_for_quaternion_lattice([1,i,j,k],[K.ideal(1),A.discriminant(),K.ideal(1),A.discriminant()])
     352            ([1, i, j, k], [Fractional ideal (1), Fractional ideal (10, b + 5), Fractional ideal (1), Fractional ideal (10, b + 5)])
     353            sage: A.basis_for_quaternion_lattice([1,i+j+2*k,j+3*i,k],[K.ideal(1),A.discriminant(),K.ideal(1),A.discriminant()])
     354            ([1, i + 3*j, j, k], [Fractional ideal (1), Fractional ideal (20, 2*b + 10), Fractional ideal (1), Fractional ideal (10, b + 5)])
     355
     356        """
     357        F = self.base_ring()
     358        gens = [self(g) for g in gens]
     359        if len(gens) == 0: return []
     360       
     361        #if over a number field
     362        if F != QQ:
     363            try:
     364                #create pari matrix and list of ideals
     365                Mpari =  pari.pari(matrix([vector(elt).list() for elt in gens]).transpose())
     366                if ideal_list:
     367                    Ipari = [pari.pari(ids) for ids in ideal_list]
     368                else:
     369                    Ipari = [pari.pari(F.ideal(1)) for elt in gens]
     370               
     371                #pari version of number field F
     372                Fp = pari.pari(F)
     373               
     374                #use pari's nfhnf to find a pseudo-basis
     375                M1,I1 = Fp.nfhnf([Mpari,Ipari])
     376               
     377                #convert back to sage
     378                M = matrix([[F(M1[i][j]) for i in range(len(M1))] for j in range(len(M1[0]))])
     379                I = [F.ideal(id) for id in I1]
     380
     381                #and back to sage quaternion algebra elements
     382                basis_elts = [sum([M[n][l]*self.basis()[l] for l in range(M.nrows())]) for n in range(M.ncols())]
     383               
     384                #if each ideal in I is principal, there is a basis:
     385                #check
     386                IT = [id.is_principal() for id in I]
     387                if sum(IT) == len(I):
     388                    return [basis_elts[k]*I[k].gens_reduced()[0] for k in range(len(basis_elts))]
     389                #otherwise we only have a pseudo-basis
     390                else:
     391                    return basis_elts, I
     392            except NotImplementedError:
     393                print "Not implemented for quaternion algebras over rings other than QQ or number fields."
     394        else:
     395            Z, d = quaternion_algebra_cython.integral_matrix_and_denom_from_rational_quaternions(gens, reverse)
     396            H = Z._hnf_pari(0, include_zero_rows=False)
     397            return quaternion_algebra_cython.rational_quaternions_from_integral_matrix_and_denom(self, H, d, reverse)
    315398
    316399    def inner_product_matrix(self):
    317400        """
     
    625708        ::
    626709
    627710            sage: QuaternionAlgebra(-1,-7).maximal_order()
    628             Order of Quaternion Algebra (-1, -7) with base ring Rational Field with basis (1/2 + 1/2*j, 1/2*i + 1/2*k, j, k)
     711            Order of Quaternion Algebra (-1, -7) with base ring Rational Field with basis [1/2 + 1/2*j, 1/2*i + 1/2*k, j, k]
    629712
    630713            sage: QuaternionAlgebra(-1,-1).maximal_order().basis()
    631             (1/2 + 1/2*i + 1/2*j + 1/2*k, i, j, k)
     714            [1/2 + 1/2*i + 1/2*j + 1/2*k, i, j, k]
    632715
    633716            sage: QuaternionAlgebra(-1,-11).maximal_order().basis()
    634             (1/2 + 1/2*j, 1/2*i + 1/2*k, j, k)
     717            [1/2 + 1/2*j, 1/2*i + 1/2*k, j, k]
    635718
    636719            sage: QuaternionAlgebra(-1,-3).maximal_order().basis()
    637             (1/2 + 1/2*j, 1/2*i + 1/2*k, j, k)
     720            [1/2 + 1/2*j, 1/2*i + 1/2*k, j, k]
    638721
    639722            sage: QuaternionAlgebra(-3,-1).maximal_order().basis()
    640             (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k)
     723            [1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k]
    641724
    642725            sage: QuaternionAlgebra(-2,-5).maximal_order().basis()
    643             (1/2 + 1/2*j + 1/2*k, 1/4*i + 1/2*j + 1/4*k, j, k)
     726            [1/2 + 1/2*j + 1/2*k, 1/4*i + 1/2*j + 1/4*k, j, k]
    644727
    645728            sage: QuaternionAlgebra(-5,-2).maximal_order().basis()
    646             (1/2 + 1/2*i - 1/2*k, 1/2*i + 1/4*j - 1/4*k, i, -k)
     729            [1/2 + 1/2*i - 1/2*k, 1/2*i + 1/4*j - 1/4*k, i, -k]
    647730
    648731            sage: QuaternionAlgebra(-17,-3).maximal_order().basis()
    649             (1/2 + 1/2*j, 1/2*i + 1/2*k, -1/3*j - 1/3*k, k)
     732            [1/2 + 1/2*j, 1/2*i + 1/2*k, -1/3*j - 1/3*k, k]
    650733
    651734            sage: QuaternionAlgebra(-3,-17).maximal_order().basis()
    652             (1/2 + 1/2*i, 1/2*j - 1/2*k, -1/3*i + 1/3*k, -k)
     735            [1/2 + 1/2*i, 1/2*j - 1/2*k, -1/3*i + 1/3*k, -k]
    653736
    654737            sage: QuaternionAlgebra(-17*9,-3).maximal_order().basis()
    655             (1, 1/3*i, 1/6*i + 1/2*j, 1/2 + 1/3*j + 1/18*k)
     738            [1, 1/3*i, 1/6*i + 1/2*j, 1/2 + 1/3*j + 1/18*k]
    656739
    657740            sage: QuaternionAlgebra(-2, -389).maximal_order().basis()
    658             (1/2 + 1/2*j + 1/2*k, 1/4*i + 1/2*j + 1/4*k, j, k)
     741            [1/2 + 1/2*j + 1/2*k, 1/4*i + 1/2*j + 1/4*k, j, k]
    659742
    660743        If you want bases containing 1, switch off ``take_shortcuts``:
    661744
    662745        ::
    663746
    664747            sage: QuaternionAlgebra(-3,-89).maximal_order(take_shortcuts=False)
    665             Order of Quaternion Algebra (-3, -89) with base ring Rational Field with basis (1, 1/2 + 1/2*i, j, 1/2 + 1/6*i + 1/2*j + 1/6*k)
     748            Order of Quaternion Algebra (-3, -89) with base ring Rational Field with basis [1, 1/2 + 1/2*i, j, 1/2 + 1/6*i + 1/2*j + 1/6*k]
    666749
    667750            sage: QuaternionAlgebra(1,1).maximal_order(take_shortcuts=False)    # Matrix ring
    668             Order of Quaternion Algebra (1, 1) with base ring Rational Field with basis (1, 1/2 + 1/2*i, j, 1/2*j + 1/2*k)
     751            Order of Quaternion Algebra (1, 1) with base ring Rational Field with basis [1, 1/2 + 1/2*i, j, 1/2*j + 1/2*k]
    669752
    670753            sage: QuaternionAlgebra(-22,210).maximal_order(take_shortcuts=False)
    671             Order of Quaternion Algebra (-22, 210) with base ring Rational Field with basis (1, i, 1/2*i + 1/2*j, 1/2 + 17/22*i + 1/44*k)
     754            Order of Quaternion Algebra (-22, 210) with base ring Rational Field with basis [1, i, 1/2*i + 1/2*j, 1/2 + 17/22*i + 1/44*k]
    672755
    673756            sage: for d in ( m for m in range(1, 750) if is_squarefree(m) ):        # long time (3s)
    674757            ...       A = QuaternionAlgebra(d)
     
    818901                        h = (z*b)*e_n[1] - (y*a)*e_n[2]
    819902                        e_n[1:4] = [g,h,g*h]
    820903                        if (1 - a*y**2 - b*z**2 + a*b*w**2).valuation(2) > 2:
    821                             e_n = basis_for_quaternion_lattice(list(e) + e_n[1:], reverse=True)
     904                            e_n = self.basis_for_quaternion_lattice(list(e) + e_n[1:], reverse=True)
    822905
    823906                # e_n now contains elements that locally at p give a bigger order,
    824907                # but the basis may be messed up at other primes (it might not even
     
    827910
    828911            e_new_gens.extend(e[1:])
    829912
    830         e_new = basis_for_quaternion_lattice(list(R.basis()) + e_new_gens, reverse=True)
     913        e_new = self.basis_for_quaternion_lattice(list(R.basis()) + e_new_gens, reverse=True)
    831914        self.__maximal_order = self.quaternion_order(e_new)
    832915        return self.__maximal_order
    833916
     
    10321115                                              self._a._magma_init_(magma),
    10331116                                              self._b._magma_init_(magma))
    10341117
    1035     def quaternion_order(self, basis, check=True):
     1118    def quaternion_order(self, basis,ideal_list = None, check=True):
    10361119        """
    10371120        Return the order of this quaternion order with given basis.
    10381121
     
    10451128
    10461129            sage: Q.<i,j,k> = QuaternionAlgebra(-11,-1)
    10471130            sage: Q.quaternion_order([1,i,j,k])
    1048             Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis (1, i, j, k)
     1131            Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis [1, i, j, k]
    10491132
    10501133        We test out ``check=False``::
    10511134
     
    10541137            sage: Q.quaternion_order([i,j,k], check=False)
    10551138            Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis [i, j, k]
    10561139        """
    1057         return QuaternionOrder(self, basis, check=check)
     1140        return QuaternionOrder(self, basis, ideal_list = ideal_list, check=check)
    10581141
    10591142    def ideal(self, gens, left_order=None, right_order=None, check=True, **kwds):
    10601143        r"""
     
    12501333    EXAMPLES::
    12511334   
    12521335        sage: QuaternionAlgebra(-1,-7).maximal_order()
    1253         Order of Quaternion Algebra (-1, -7) with base ring Rational Field with basis (1/2 + 1/2*j, 1/2*i + 1/2*k, j, k)
     1336        Order of Quaternion Algebra (-1, -7) with base ring Rational Field with basis [1/2 + 1/2*j, 1/2*i + 1/2*k, j, k]
    12541337        sage: type(QuaternionAlgebra(-1,-7).maximal_order())
    12551338        <class 'sage.algebras.quatalg.quaternion_algebra.QuaternionOrder'>
    12561339    """
    1257     def __init__(self, A, basis, check=True):
     1340    def __init__(self, A, basis,ideal_list = None, check=True):
    12581341        """
    12591342        INPUT:
    12601343
     
    12701353
    12711354            sage: A.<i,j,k> = QuaternionAlgebra(-3,-5)
    12721355            sage: sage.algebras.quatalg.quaternion_algebra.QuaternionOrder(A, [1,i,j,k])
    1273             Order of Quaternion Algebra (-3, -5) with base ring Rational Field with basis (1, i, j, k)
     1356            Order of Quaternion Algebra (-3, -5) with base ring Rational Field with basis [1, i, j, k]
    12741357            sage: R = sage.algebras.quatalg.quaternion_algebra.QuaternionOrder(A, [1,2*i,2*j,2*k]); R
    1275             Order of Quaternion Algebra (-3, -5) with base ring Rational Field with basis (1, 2*i, 2*j, 2*k)
     1358            Order of Quaternion Algebra (-3, -5) with base ring Rational Field with basis [1, 2*i, 2*j, 2*k]
    12761359            sage: type(R)
    12771360            <class 'sage.algebras.quatalg.quaternion_algebra.QuaternionOrder'>
    12781361
     
    12961379            sage: K = QuadraticField(10)
    12971380            sage: A.<i,j,k> = QuaternionAlgebra(K,-1,-1)
    12981381            sage: A.quaternion_order([1,i,j,k])
    1299             Order of Quaternion Algebra (-1, -1) with base ring Number Field in a with defining polynomial x^2 - 10 with basis (1, i, j, k)
     1382            Order of Quaternion Algebra (-1, -1) with base ring Number Field in a with defining polynomial x^2 - 10 with basis [1, i, j, k]
    13001383            sage: A.quaternion_order([1,i/2,j,k])
    13011384            Traceback (most recent call last):
    13021385            ...
    13031386            ValueError: given lattice must be a ring
     1387           
     1388            sage: F.<a> = NumberField(x^2-x-1)
     1389            sage: B.<i,j,k> = QuaternionAlgebra(F, 2*a,F(-1))
     1390            sage: B.quaternion_order([1,i+2*j,j,i+j+3*k])
     1391            Traceback (most recent call last):
     1392            ...
     1393            ValueError: given lattice must be a ring
     1394            sage: B.quaternion_order([1,i/2,j,k])
     1395            Traceback (most recent call last):
     1396            ...
     1397            ValueError: given lattice must be a ring
     1398            sage: B.quaternion_order([1,i,j,i+j+k])
     1399            Order of Quaternion Algebra (2*a, -1) with base ring Number Field in a with defining polynomial x^2 - x - 1 with basis [1, i, j, k]
     1400            sage: K.<b> = NumberField(x^2+5)
     1401            sage: A.<i,j,k> = QuaternionAlgebra(K,b,2*b)
     1402            sage: A.quaternion_order([1,(b+5)*i,10*i,j,k])
     1403            Traceback (most recent call last):
     1404            ...
     1405            ValueError: basis must have length 4
     1406            sage: bas = A.basis_for_quaternion_lattice([1,i+j+2*k,j+3*i,k],[K.ideal(1),A.discriminant(),K.ideal(1),A.discriminant()])
     1407            sage: A.quaternion_order(bas[0],bas[1])
     1408            Order of Quaternion Algebra (b, 2*b) with base ring Number Field in b with defining polynomial x^2 + 5 with pseudo-basis
     1409            [[1, i, j, k], [Fractional ideal (1), Fractional ideal (20, 2*b + 10), Fractional ideal (1), Fractional ideal (10, b + 5)]]
     1410            sage: A.quaternion_order([2,2*i,2*j,2*k])
     1411            Traceback (most recent call last):
     1412            ...
     1413            ValueError: lattice must contain 1
     1414            sage: A.quaternion_order([1,i,j,k],ideal_list = [A.discriminant(), A.discriminant(), A.discriminant(), A.discriminant()])
     1415            Traceback (most recent call last):
     1416            ...
     1417            ValueError: lattice must contain 1
     1418           
    13041419        """
     1420        basis = [A(e) for e in basis]
     1421       
    13051422        if check:
    13061423            # right data type
    13071424            if not isinstance(basis, (list, tuple)):
     
    13091426            # right length
    13101427            if len(basis) != 4:
    13111428                raise ValueError("basis must have length 4")
    1312             # coerce to common parent
    1313             basis = tuple([A(x) for x in basis])
    13141429
    13151430            # has rank 4
    13161431            V = A.base_ring()**4
     
    13291444                    raise ValueError, "lattice must contain 1"
    13301445
    13311446                # check if multiplicatively closed
    1332                 M1 = basis_for_quaternion_lattice(basis)
    1333                 M2 = basis_for_quaternion_lattice(list(basis) + [ x*y for x in basis for y in basis])
     1447                M1 = A.basis_for_quaternion_lattice(basis)
     1448                M2 = A.basis_for_quaternion_lattice(list(basis) + [ x*y for x in basis for y in basis])
    13341449                if M1 != M2:
    13351450                    raise ValueError, "given lattice must be a ring"
     1451                self.__basis = basis
    13361452
    13371453            if A.base_ring() != QQ:     # slow code over number fields (should eventually use PARI's nfhnf)
    13381454                O = None
    13391455                try:
    1340                     O = A.base_ring().maximal_order()
     1456                    O = A.base_ring().maximal_order() 
    13411457                except AttributeError:
    13421458                    pass
    1343 
    13441459                if O:
    1345                     M = matrix(A.base_ring(), 4, 4, [ x.coefficient_tuple() for x in basis])
    1346                     v = M.solve_left(V([1,0,0,0]))
    1347 
    1348                     if any([ not a in O for a in v]):
     1460                    M1 = A.basis_for_quaternion_lattice(basis, ideal_list = ideal_list)
     1461                    if ideal_list:
     1462                        M2 = A.basis_for_quaternion_lattice(basis+[x*y for x in basis for y in basis], ideal_list+[I*J for I in ideal_list for J in ideal_list])
     1463                    else:
     1464                        M2 = A.basis_for_quaternion_lattice(basis+[x*y for x in basis for y in basis])
     1465                    if M1 != M2:
     1466                        raise ValueError, "given lattice must be a ring"                   
     1467                if len(M1) == 2:
     1468                    if M1[0][0] != 1 or M1[1][0] != A.base_ring().ideal(1):
    13491469                        raise ValueError, "lattice must contain 1"
    1350 
    1351                     # check if multiplicatively closed
    1352                     Y = matrix(QQ, 16, 4, [ (x*y).coefficient_tuple() for x in basis for y in basis])
    1353                     X = M.solve_left(Y)
    1354                     if any([ not a in O for x in X for a in x ]):
    1355                         raise ValueError, "given lattice must be a ring"
    1356 
    1357         self.__basis = basis
     1470                    basis = M1[0]
     1471                    ideal_list = M1[1]
     1472                    self.__basis = None
     1473                    self.__pseudobasis = [basis,ideal_list]
     1474                else:
     1475                    if M1[0] != 1:
     1476                        raise ValueError, "lattice must contain 1"
     1477                    self.__basis = M1
     1478        else:
     1479            self.__basis = basis
     1480                   
    13581481        self.__quaternion_algebra = A
    13591482        ParentWithGens.__init__(self, ZZ, names=None) 
    13601483
     
    13651488        EXAMPLES::
    13661489
    13671490            sage: QuaternionAlgebra(-1,-7).maximal_order().gens()
    1368             (1/2 + 1/2*j, 1/2*i + 1/2*k, j, k)
     1491            [1/2 + 1/2*j, 1/2*i + 1/2*k, j, k]
    13691492        """
    13701493        return self.__basis
    13711494
     
    13911514        EXAMPLES::
    13921515
    13931516            sage: R = QuaternionAlgebra(-11,-1).maximal_order(); R
    1394             Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k)
     1517            Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis [1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k]
    13951518            sage: R.gen(0)
    13961519            1/2 + 1/2*i
    13971520            sage: R.gen(1)
     
    14321555        EXAMPLES::
    14331556
    14341557            sage: QuaternionAlgebra(-11,-1).maximal_order().basis()
    1435             (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k)
     1558            [1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k]
     1559           
     1560            sage: K.<b> = NumberField(x^2+5)
     1561            sage: A.<i,j,k> = QuaternionAlgebra(K,b,2*b)
     1562            sage: O = A.quaternion_order([1,i,j,k])
     1563            sage: O.basis()
     1564            [1, i, j, k]
     1565
    14361566        """
    14371567        return self.__basis
     1568   
     1569    def pseudobasis(self):
     1570        """
     1571        Return fix choice of basis for this quaternion order.
     1572       
     1573        EXAMPLES::
     1574
     1575            sage: QuaternionAlgebra(-11,-1).maximal_order().pseudobasis()
     1576            [1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k]
     1577           
     1578            sage: K.<b> = NumberField(x^2+5)
     1579            sage: A.<i,j,k> = QuaternionAlgebra(K,b,2*b)
     1580            sage: O = A.quaternion_order([1,i,j,k],[K.ideal(1),A.discriminant(), K.ideal(1),K.ideal(1)])
     1581            sage: O.pseudobasis()
     1582            [[1, i, j, k], [Fractional ideal (1), Fractional ideal (10, b + 5), Fractional ideal (1), Fractional ideal (1)]]
     1583           
     1584        """
     1585        if self.basis():
     1586            return self.basis()
     1587        else:
     1588            return self.__pseudobasis
    14381589
    14391590    def quaternion_algebra(self):
    14401591        """
     
    14541605        EXAMPLES::
    14551606
    14561607            sage: QuaternionAlgebra(-11,-1).maximal_order()._repr_()
    1457             'Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k)'
     1608            'Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis [1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k]'
    14581609            sage: QuaternionAlgebra(-11,-1).maximal_order()
    1459             Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k)
     1610            Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis [1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k]
     1611           
     1612            sage: K.<b> = NumberField(x^2+5)
     1613            sage: A.<i,j,k> = QuaternionAlgebra(K,b,2*b)
     1614            sage: O = A.quaternion_order([1,i,j,k],[K.ideal(1),A.discriminant(), K.ideal(1),K.ideal(1)])
     1615            sage: O._repr_()
     1616            'Order of Quaternion Algebra (b, 2*b) with base ring Number Field in b with defining polynomial x^2 + 5 with pseudo-basis
     1617            [[1, i, j, k], [Fractional ideal (1), Fractional ideal (10, b + 5), Fractional ideal (1), Fractional ideal (1)]]'
     1618            sage: O
     1619            Order of Quaternion Algebra (b, 2*b) with base ring Number Field in b with defining polynomial x^2 + 5 with pseudo-basis
     1620            [[1, i, j, k], [Fractional ideal (1), Fractional ideal (10, b + 5), Fractional ideal (1), Fractional ideal (1)]]
     1621           
    14601622        """
    1461         return 'Order of %s with basis %s'%(self.quaternion_algebra(), self.basis())
     1623        if self.basis():
     1624            return 'Order of %s with basis %s'%(self.quaternion_algebra(), self.basis())
     1625        else:
     1626            return 'Order of %s with pseudo-basis %s'%(self.quaternion_algebra(), self.pseudobasis())
    14621627
    14631628    def random_element(self, *args, **kwds):
    14641629        """
     
    14971662       
    14981663            sage: R = QuaternionAlgebra(-11,-1).maximal_order()
    14991664            sage: R.intersection(R)
    1500             Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis (1/2 + 1/2*i, i, 1/2*j + 1/2*k, k)
     1665            Order of Quaternion Algebra (-11, -1) with base ring Rational Field with basis [1/2 + 1/2*i, i, 1/2*j + 1/2*k, k]
    15011666
    15021667        We intersect various orders in the quaternion algebra ramified at 11::
    15031668       
    15041669            sage: B = BrandtModule(11,3)
    15051670            sage: R = B.maximal_order(); S = B.order_of_level_N()
    15061671            sage: R.intersection(S)
    1507             Order of Quaternion Algebra (-1, -11) with base ring Rational Field with basis (1/2 + 1/2*j, 1/2*i + 5/2*k, j, 3*k)
     1672            Order of Quaternion Algebra (-1, -11) with base ring Rational Field with basis [1/2 + 1/2*j, 1/2*i + 5/2*k, j, 3*k]
    15081673            sage: R.intersection(S) == S
    15091674            True
    15101675            sage: B = BrandtModule(11,5)
    15111676            sage: T = B.order_of_level_N()
    15121677            sage: S.intersection(T)
    1513             Order of Quaternion Algebra (-1, -11) with base ring Rational Field with basis (1/2 + 1/2*j, 1/2*i + 23/2*k, j, 15*k)
     1678            Order of Quaternion Algebra (-1, -11) with base ring Rational Field with basis [1/2 + 1/2*j, 1/2*i + 23/2*k, j, 15*k]
    15141679        """
    15151680        if not isinstance(other, QuaternionOrder):
    15161681            raise TypeError("other must be a QuaternionOrder")
     
    15391704       
    15401705            sage: R = QuaternionAlgebra(-11,-1).maximal_order()
    15411706            sage: R.basis()
    1542             (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k)
     1707            [1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k]
    15431708            sage: R.free_module()
    15441709            Free module of degree 4 and rank 4 over Integer Ring
    15451710            Echelon basis matrix:
     
    16341799
    16351800            sage: R = QuaternionAlgebra(-11,-1).maximal_order()
    16361801            sage: I = R.unit_ideal(); I
    1637             Fractional ideal (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k)
     1802            Fractional ideal [1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k]
    16381803        """
    16391804        if self.base_ring() == ZZ:
    16401805            return QuaternionFractionalIdeal_rational(self.basis(), left_order=self, right_order=self, check=False)
     
    18562021            sage: R.<i,j,k> = QuaternionAlgebra(-1,-11)
    18572022            sage: I = R.ideal([2 + 2*j + 140*k, 2*i + 4*j + 150*k, 8*j + 104*k, 152*k])
    18582023            sage: Ol = I._compute_order('left'); Ol
    1859             Order of Quaternion Algebra (-1, -11) with base ring Rational Field with basis (1/2 + 1/2*j + 35*k, 1/4*i + 1/2*j + 75/4*k, j + 32*k, 38*k)
     2024            Order of Quaternion Algebra (-1, -11) with base ring Rational Field with basis [1/2 + 1/2*j + 35*k, 1/4*i + 1/2*j + 75/4*k, j + 32*k, 38*k]
    18602025            sage: Or = I._compute_order('right'); Or
    1861             Order of Quaternion Algebra (-1, -11) with base ring Rational Field with basis (1/2 + 1/2*j + 16*k, 1/2*i + 11/2*k, j + 13*k, 19*k)
     2026            Order of Quaternion Algebra (-1, -11) with base ring Rational Field with basis [1/2 + 1/2*j + 16*k, 1/2*i + 11/2*k, j + 13*k, 19*k]
    18622027            sage: Ol.discriminant()
    18632028            209
    18642029            sage: Or.discriminant()
     
    19042069            sage: R = B.maximal_order()
    19052070            sage: I = R.unit_ideal()
    19062071            sage: I.left_order()
    1907             Order of Quaternion Algebra (-1, -11) with base ring Rational Field with basis (1/2 + 1/2*j, 1/2*i + 1/2*k, j, k)
     2072            Order of Quaternion Algebra (-1, -11) with base ring Rational Field with basis [1/2 + 1/2*j, 1/2*i + 1/2*k, j, k]
    19082073
    19092074        We do a consistency check::
    19102075       
     
    19272092            sage: I = BrandtModule(389).right_ideals()[1]; I
    19282093            Fractional ideal (2 + 6*j + 2*k, i + 2*j + k, 8*j, 8*k)
    19292094            sage: I.right_order()
    1930             Order of Quaternion Algebra (-2, -389) with base ring Rational Field with basis (1/2 + 1/2*j + 1/2*k, 1/4*i + 1/2*j + 1/4*k, j, k)
     2095            Order of Quaternion Algebra (-2, -389) with base ring Rational Field with basis [1/2 + 1/2*j + 1/2*k, 1/4*i + 1/2*j + 1/4*k, j, k]
    19312096            sage: I.left_order()
    1932             Order of Quaternion Algebra (-2, -389) with base ring Rational Field with basis (1/2 + 1/2*j + 3/2*k, 1/8*i + 1/4*j + 9/8*k, j + k, 2*k)
     2097            Order of Quaternion Algebra (-2, -389) with base ring Rational Field with basis [1/2 + 1/2*j + 3/2*k, 1/8*i + 1/4*j + 9/8*k, j + k, 2*k]
    19332098
    19342099        The following is a big consistency check.  We take reps for
    19352100        all the right ideal classes of a certain order, take the
     
    20112176        EXAMPLES::
    20122177
    20132178            sage: QuaternionAlgebra(-11,-1).maximal_order().unit_ideal().basis()
    2014             (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k)
     2179            [1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k]
    20152180        """
    20162181        return self.__basis
    20172182
     
    20232188        EXAMPLES::
    20242189
    20252190            sage: QuaternionAlgebra(-11,-1).maximal_order().unit_ideal().gens()
    2026             (1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k)
     2191            [1/2 + 1/2*i, 1/2*j - 1/2*k, i, -k]
    20272192        """
    20282193        return self.__basis
    20292194
     
    23352500        #if self.__right_order == right.__left_order:
    23362501        #    left_order = self.__left_order
    23372502        #    right_order = right.__right_order
    2338         basis = tuple(basis_for_quaternion_lattice(gens))
    23392503        A = self.quaternion_algebra()
     2504        basis = tuple(A.basis_for_quaternion_lattice(gens))
    23402505        return A.ideal(basis, check=False)
    23412506
    23422507    @cached_method
     
    24162581        """
    24172582        Jbar = [b.conjugate() for b in J.basis()]
    24182583        gens = [a*b for a in self.basis() for b in Jbar]
    2419         basis = tuple(basis_for_quaternion_lattice(gens))
    24202584        R = self.quaternion_algebra()
     2585        basis = tuple(R.basis_for_quaternion_lattice(gens))
    24212586        return R.ideal(basis, check=False)
    24222587
    24232588    def is_equivalent(I, J, B=10):
     
    26182783#######################################################################
    26192784# Some utility functions that are needed here and are too
    26202785# specialized to go elsewhere.
    2621 #######################################################################
    2622 
    2623 def basis_for_quaternion_lattice(gens, reverse = False):
    2624     """
    2625     Return a basis for the `\\ZZ`-lattice in a quaternion algebra
    2626     spanned by the given gens.
    2627 
    2628     INPUT:
    2629 
    2630     - ``gens`` -- list of elements of a single quaternion algebra
    2631 
    2632     - ``reverse`` -- when computing the HNF do it on the basis
    2633                      (k,j,i,1) instead of (1,i,j,k). This ensures
    2634                      that if ``gens`` are the generators for an order,
    2635                      the first returned basis vector is 1.
    2636 
    2637     EXAMPLES::
    2638 
    2639         sage: from sage.algebras.quatalg.quaternion_algebra import basis_for_quaternion_lattice
    2640         sage: A.<i,j,k> = QuaternionAlgebra(-1,-7)
    2641         sage: basis_for_quaternion_lattice([i+j, i-j, 2*k, A(1/3)])
    2642         [1/3, i + j, 2*j, 2*k]
    2643 
    2644         sage: basis_for_quaternion_lattice([A(1),i,j,k])
    2645         [1, i, j, k]
    2646 
    2647     """
    2648     if len(gens) == 0: return []
    2649     Z, d = quaternion_algebra_cython.integral_matrix_and_denom_from_rational_quaternions(gens, reverse)
    2650     H = Z._hnf_pari(0, include_zero_rows=False)
    2651     A = gens[0].parent()
    2652     return quaternion_algebra_cython.rational_quaternions_from_integral_matrix_and_denom(A, H, d, reverse)
     2786#######################################################################   
     2787   
    26532788
    26542789
    26552790def intersection_of_row_modules_over_ZZ(v):
  • sage/algebras/quatalg/quaternion_algebra_cython.pyx

    diff --git a/sage/algebras/quatalg/quaternion_algebra_cython.pyx b/sage/algebras/quatalg/quaternion_algebra_cython.pyx
    a b  
    3131from sage.rings.integer_ring import ZZ
    3232from sage.rings.rational_field import QQ
    3333from sage.rings.integer cimport Integer
     34from sage.rings.number_field.number_field import NumberField
    3435from sage.matrix.matrix_space import MatrixSpace
    3536from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense
    3637from sage.matrix.matrix_rational_dense cimport Matrix_rational_dense
  • sage/modular/quatalg/brandt.py

    diff --git a/sage/modular/quatalg/brandt.py b/sage/modular/quatalg/brandt.py
    a b  
    144144    sage: B = BrandtModule(23)
    145145
    146146    sage: B.maximal_order()
    147     Order of Quaternion Algebra (-1, -23) with base ring Rational Field with basis (1/2 + 1/2*j, 1/2*i + 1/2*k, j, k)
     147    Order of Quaternion Algebra (-1, -23) with base ring Rational Field with basis [1/2 + 1/2*j, 1/2*i + 1/2*k, j, k]
    148148
    149149    sage: B.right_ideals()
    150150    (Fractional ideal (2 + 2*j, 2*i + 2*k, 4*j, 4*k), Fractional ideal (2 + 2*j, 2*i + 6*k, 8*j, 8*k), Fractional ideal (2 + 10*j + 8*k, 2*i + 8*j + 6*k, 16*j, 16*k))
     
    218218from sage.rings.all    import (Integer, ZZ, QQ, is_CommutativeRing, prime_divisors,
    219219                            kronecker, PolynomialRing, GF, next_prime, lcm, gcd)
    220220
    221 from sage.algebras.quatalg.quaternion_algebra import QuaternionAlgebra, basis_for_quaternion_lattice
     221from sage.algebras.quatalg.quaternion_algebra import QuaternionAlgebra
    222222from sage.algebras.quatalg.quaternion_algebra_cython import rational_matrix_from_rational_quaternions
    223223
    224224from sage.rings.arith import gcd, factor, kronecker_symbol
     
    366366   
    367367        sage: A = BrandtModule(17).quaternion_algebra()
    368368        sage: sage.modular.quatalg.brandt.maximal_order(A)
    369         Order of Quaternion Algebra (-17, -3) with base ring Rational Field with basis (1/2 + 1/2*j, 1/2*i + 1/2*k, -1/3*j - 1/3*k, k)
     369        Order of Quaternion Algebra (-17, -3) with base ring Rational Field with basis [1/2 + 1/2*j, 1/2*i + 1/2*k, -1/3*j - 1/3*k, k]
    370370
    371371        sage: A = QuaternionAlgebra(17,names='i,j,k')
    372372        sage: A.maximal_order()
    373         Order of Quaternion Algebra (-3, -17) with base ring Rational Field with basis (1/2 + 1/2*i, 1/2*j - 1/2*k, -1/3*i + 1/3*k, -k)
     373        Order of Quaternion Algebra (-3, -17) with base ring Rational Field with basis [1/2 + 1/2*i, 1/2*j - 1/2*k, -1/3*i + 1/3*k, -k]
    374374    """
    375375
    376376    return A.maximal_order()
     
    394394        sage: sage.modular.quatalg.brandt.basis_for_left_ideal(B.maximal_order(), [3*(i+j),3*(i-j),6*k,A(3)])
    395395        [3/2 + 1/2*j + 2*k, 3/2*i + 3/2*k, j + k, 3*k]
    396396    """
    397     return basis_for_quaternion_lattice([b*g for b in R.basis() for g in gens])
     397    A = R.quaternion_algebra()
     398    return A.basis_for_quaternion_lattice([b*g for b in R.basis() for g in gens])
    398399   
    399400
    400401def right_order(R, basis):
     
    415416   
    416417        sage: B = BrandtModule(17); basis = sage.modular.quatalg.brandt.basis_for_left_ideal(B.maximal_order(), B.maximal_order().basis())
    417418        sage: sage.modular.quatalg.brandt.right_order(B.maximal_order(), basis)
    418         Order of Quaternion Algebra (-17, -3) with base ring Rational Field with basis (1/2 + 1/6*j + 2/3*k, 1/2*i + 1/2*k, 1/3*j + 1/3*k, k)
     419        Order of Quaternion Algebra (-17, -3) with base ring Rational Field with basis [1/2 + 1/6*j + 2/3*k, 1/2*i + 1/2*k, 1/3*j + 1/3*k, k]
    419420        sage: basis
    420421        [1/2 + 1/6*j + 2/3*k, 1/2*i + 1/2*k, 1/3*j + 1/3*k, k]
    421422
    422423        sage: B = BrandtModule(17); A = B.quaternion_algebra(); i,j,k = A.gens()
    423424        sage: basis = sage.modular.quatalg.brandt.basis_for_left_ideal(B.maximal_order(), [i*j-j])
    424425        sage: sage.modular.quatalg.brandt.right_order(B.maximal_order(), basis)
    425         Order of Quaternion Algebra (-17, -3) with base ring Rational Field with basis (1/2 + 1/2*i + 1/2*j + 17/2*k, i, j + 8*k, 9*k)
     426        Order of Quaternion Algebra (-17, -3) with base ring Rational Field with basis [1/2 + 1/2*i + 1/2*j + 17/2*k, i, j + 8*k, 9*k]
    426427    """
    427428    # Compute matrix of multiplication by each element of the basis.
    428429    B = R.basis()
     
    610611        EXAMPLES::
    611612       
    612613            sage: BrandtModule(17).maximal_order()
    613             Order of Quaternion Algebra (-17, -3) with base ring Rational Field with basis (1/2 + 1/2*j, 1/2*i + 1/2*k, -1/3*j - 1/3*k, k)
     614            Order of Quaternion Algebra (-17, -3) with base ring Rational Field with basis [1/2 + 1/2*j, 1/2*i + 1/2*k, -1/3*j - 1/3*k, k]
    614615            sage: BrandtModule(17).maximal_order() is BrandtModule(17).maximal_order()
    615616            True
    616617        """
     
    627628        EXAMPLES::
    628629
    629630            sage: BrandtModule(7).order_of_level_N()
    630             Order of Quaternion Algebra (-1, -7) with base ring Rational Field with basis (1/2 + 1/2*j, 1/2*i + 1/2*k, j, k)
     631            Order of Quaternion Algebra (-1, -7) with base ring Rational Field with basis [1/2 + 1/2*j, 1/2*i + 1/2*k, j, k]
    631632            sage: BrandtModule(7,13).order_of_level_N()
    632             Order of Quaternion Algebra (-1, -7) with base ring Rational Field with basis (1/2 + 1/2*j + 12*k, 1/2*i + 9/2*k, j + 11*k, 13*k)
     633            Order of Quaternion Algebra (-1, -7) with base ring Rational Field with basis [1/2 + 1/2*j + 12*k, 1/2*i + 9/2*k, j + 11*k, 13*k]
    633634            sage: BrandtModule(7,3*17).order_of_level_N()
    634             Order of Quaternion Algebra (-1, -7) with base ring Rational Field with basis (1/2 + 1/2*j + 35*k, 1/2*i + 65/2*k, j + 19*k, 51*k)
     635            Order of Quaternion Algebra (-1, -7) with base ring Rational Field with basis [1/2 + 1/2*j + 35*k, 1/2*i + 65/2*k, j + 19*k, 51*k]
    635636        """
    636637        try: return self.__order_of_level_N
    637638        except AttributeError: pass
  • sage/schemes/elliptic_curves/heegner.py

    diff --git a/sage/schemes/elliptic_curves/heegner.py b/sage/schemes/elliptic_curves/heegner.py
    a b  
    47434743        EXAMPLES::
    47444744       
    47454745            sage: heegner_points(11).reduce_mod(3).left_orders()
    4746             [Order of Quaternion Algebra (-1, -3) with base ring Rational Field with basis (1/2 + 1/2*j + 7*k, 1/2*i + 13/2*k, j + 3*k, 11*k),
    4747              Order of Quaternion Algebra (-1, -3) with base ring Rational Field with basis (1/2 + 1/2*j + 7*k, 1/4*i + 1/2*j + 63/4*k, j + 14*k, 22*k)]
     4746            [Order of Quaternion Algebra (-1, -3) with base ring Rational Field with basis [1/2 + 1/2*j + 7*k, 1/2*i + 13/2*k, j + 3*k, 11*k],
     4747             Order of Quaternion Algebra (-1, -3) with base ring Rational Field with basis [1/2 + 1/2*j + 7*k, 1/4*i + 1/2*j + 63/4*k, j + 14*k, 22*k]]
    47484748        """
    47494749        return [I.left_order() for I in self.right_ideals()]
    47504750
     
    58405840
    58415841            sage: H = heegner_points(11).reduce_mod(3); R = H.left_orders()[0]
    58425842            sage: H.optimal_embeddings(-7, 2, R)[0].codomain()
    5843             Order of Quaternion Algebra (-1, -3) with base ring Rational Field with basis (1/2 + 1/2*j + 7*k, 1/2*i + 13/2*k, j + 3*k, 11*k)
     5843            Order of Quaternion Algebra (-1, -3) with base ring Rational Field with basis [1/2 + 1/2*j + 7*k, 1/2*i + 13/2*k, j + 3*k, 11*k]
    58445844        """
    58455845        return self.__R
    58465846