Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
""" libSingular: Conversion Routines and Initialisation
AUTHOR:
- Martin Albrecht <malb@informatik.uni-bremen.de> """
#***************************************************************************** # Copyright (C) 2005, 2006 William Stein <wstein@gmail.com> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ ############################################################################### from __future__ import print_function, absolute_import
include "sage/libs/ntl/decl.pxi"
cdef extern from "limits.h": long INT_MAX long INT_MIN
import os
from libc.stdint cimport int64_t from sage.libs.singular.decl cimport *
from sage.rings.rational_field import RationalField from sage.rings.integer_ring cimport IntegerRing_class from sage.rings.finite_rings.integer_mod_ring import IntegerModRing_generic from sage.rings.finite_rings.finite_field_base import FiniteField from sage.rings.finite_rings.finite_field_prime_modn import FiniteField_prime_modn from sage.rings.finite_rings.finite_field_givaro import FiniteField_givaro from sage.rings.finite_rings.finite_field_ntl_gf2e import FiniteField_ntl_gf2e from sage.libs.pari.all import pari from sage.libs.gmp.all cimport *
from sage.cpython.string import FS_ENCODING from sage.cpython.string cimport str_to_bytes, char_to_str
from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular
_saved_options = (int(0),0,0)
cdef Rational si2sa_QQ(number *n, number **nn, ring *_ring): """ TESTS::
sage: P.<x,y,z> = QQ[] sage: P(1/3).lc() 1/3 sage: P(1).lc() 1 sage: P(0).lc() 0 sage: P(-1/3).lc() -1/3 sage: type(P(3).lc()) <type 'sage.rings.rational.Rational'> """ cdef number *nom cdef number *denom cdef mpq_t _z
cdef mpz_t nom_z, denom_z
cdef Rational z
## Immediate integers handles carry the tag 'SR_INT', i.e. the last bit is 1. ## This distinguishes immediate integers from other handles which point to ## structures aligned on 4 byte boundaries and therefor have last bit zero. ## (The second bit is reserved as tag to allow extensions of this scheme.) ## Using immediates as pointers and dereferencing them gives address errors.
cdef Integer si2sa_ZZ(number *n, ring *_ring): """ TESTS::
sage: P.<x,y,z> = ZZ[] sage: P(3).lc() 3 sage: P(0).lc() 0 sage: P(-3).lc() -3 sage: P(-1234567890).lc() -1234567890 sage: type(P(3).lc()) <type 'sage.rings.integer.Integer'> """ cdef Integer z
cdef FFgivE si2sa_GFqGivaro(number *n, ring *_ring, Cache_givaro cache): """ TESTS::
sage: K.<a> = GF(5^3) sage: R.<x,y,z> = PolynomialRing(K) sage: K( (4*R(a)^2 + R(a))^3 ) a^2 sage: K(R(0)) 0 """ cdef poly *z cdef int c, e cdef int a cdef int ret cdef int order
return cache._zero_element
else:
cdef FFgf2eE si2sa_GFqNTLGF2E(number *n, ring *_ring, Cache_ntl_gf2e cache): """ TESTS::
sage: K.<a> = GF(2^20) sage: P.<x,y,z> = K[] sage: f = a^21*x^2 + 1 # indirect doctest sage: f.lc() a^11 + a^10 + a^8 + a^7 + a^6 + a^5 + a^2 + a sage: type(f.lc()) <type 'sage.rings.finite_rings.element_ntl_gf2e.FiniteField_ntl_gf2eElement'> """ cdef poly *z cdef long c cdef int e cdef FFgf2eE a cdef FFgf2eE ret
return cache._zero_element return cache._one_element
cdef object si2sa_GFq_generic(number *n, ring *_ring, object base): """ TESTS::
sage: K.<a> = GF(3^16) sage: P.<x,y,z> = K[] sage: f = a^21*x^2 + 1 # indirect doctest sage: f.lc() a^12 + a^11 + a^9 + a^8 + a^7 + 2*a^6 + a^5 sage: type(f.lc()) <type 'sage.rings.finite_rings.element_pari_ffelt.FiniteFieldElement_pari_ffelt'>
Try the largest characteristic which Singular supports::
sage: p = previous_prime(2^31) sage: F.<a> = FiniteField(p^2) sage: R.<x,y> = F[] sage: R(-1).constant_coefficient() # indirect doctest 2147483646
""" cdef poly *z cdef long c cdef int e cdef object a cdef object ret
return base.zero()
cdef object si2sa_NF(number *n, ring *_ring, object base): """ TESTS::
sage: K.<a> = NumberField(x^2 - 2) sage: P.<x,y,z> = K[] sage: f = a^21*x^2 + 1 # indirect doctest sage: f.lc() 1024*a sage: type(f.lc()) <type 'sage.rings.number_field.number_field_element_quadratic.NumberFieldElement_quadratic'> """ cdef poly *z cdef number *c cdef int e cdef object a cdef object ret
return base._zero_element
# p_GetCoeff returns a reference # si2sa_QQ might modify c # so we force it back. #pSetCoeff0(z,c) #p_SetCoeff(z, c, cfRing) # rather than trying to let Cython and C++ automagically modify it #coeff = si2sa_QQ(p_GetCoeff(z, cfRing), cfRing)
cdef inline object si2sa_ZZmod(number *n, ring *_ring, object base): """ TESTS::
sage: P.<x,y,z> = Integers(10)[] sage: P(3).lc() 3 sage: P(13).lc() 3
sage: P.<x,y,z> = Integers(16)[] sage: P(3).lc() 3 sage: P(19).lc() 3
sage: P.<x,y,z> = Integers(3**2)[] sage: P(3).lc() 3 sage: P(12).lc() 3
sage: P.<x,y,z> = Integers(2^32)[] sage: P(2^32-1).lc() 4294967295
sage: P(3).lc() 3
sage: P.<x,y,z> = Integers(17^20)[] sage: P(17^19 + 3).lc() 239072435685151324847156
sage: P(3) 3 """ cdef Integer ret elif _ring.cf.type == n_Znm or _ring.cf.type == n_Zn:
return base(_ring.cf.cfInt(n,_ring.cf))
cdef number *sa2si_QQ(Rational r, ring *_ring): """ TESTS::
sage: P.<x,y,z> = QQ[] sage: P(0) + 1/2 - 2/4 0 sage: P(1/2) + 3/5 - 3/5 1/2 sage: P(2/3) + 1/4 - 1/4 2/3 sage: P(12345678901234567890/23) + 5/2 - 5/2 12345678901234567890/23 """
cdef number *sa2si_GFqGivaro(int quo, ring *_ring): """ """ rChangeCurrRing(_ring) cdef number* n1 cdef number* n2 cdef number* a cdef number* coeff cdef number* apow1 cdef number* apow2
cdef number *sa2si_GFqNTLGF2E(FFgf2eE elem, ring *_ring): """ """ cdef int i cdef number *n1 cdef number *n2 cdef number *a cdef number *coeff cdef number *apow1 cdef number *apow2
else:
cdef number *sa2si_GFq_generic(object elem, ring *_ring): """ """ cdef int i cdef number *n1 cdef number *n2 cdef number *a cdef number *coeff cdef number *apow1 cdef number *apow2
else:
cdef number *sa2si_NF(object elem, ring *_ring): """ """ cdef int i cdef number *n1 cdef number *n2 cdef number *a cdef number *nlCoeff cdef number *naCoeff cdef number *apow1 cdef number *apow2
raise RuntimeError("Failed to determine nMapFuncPtr")
rChangeCurrRing(_ring)
cdef char *_name
# the result of nlInit2gmp() is in a plain polynomial ring over QQ (not an extension ring!), # so we hace to get/create one : # # todo: reuse qqr/ get an existing Singular polynomial ring over Q. cdef char **_ext_names
cdef poly *_p
# faster would be to assign the coefficient directly
cdef number *sa2si_ZZ(Integer d, ring *_ring): """ TESTS::
sage: P.<x,y,z> = ZZ[] sage: P(0) + 1 - 1 0 sage: P(1) + 1 - 1 1 sage: P(2) + 1 - 1 2 sage: P(12345678901234567890) + 2 - 2 12345678901234567890 """
cdef inline number *sa2si_ZZmod(IntegerMod_abstract d, ring *_ring): """ TESTS::
sage: P.<x,y,z> = Integers(10)[] sage: P(3) 3 sage: P(13) 3
sage: P.<x,y,z> = Integers(16)[] sage: P(3) 3 sage: P(19) 3
sage: P.<x,y,z> = Integers(3^2)[] sage: P(3) 3 sage: P(12) 3
sage: P.<x,y,z> = Integers(2^32)[] sage: P(2^32-1) 4294967295
sage: P(3) 3
sage: P.<x,y,z> = Integers(17^20)[] sage: P(17^19 + 3) 239072435685151324847156
sage: P(3) 3 """
cdef number *nn
cdef int64_t _d cdef char *_name cdef char **_ext_names
elif _ring.cf.type == n_Zn or _ring.cf.type == n_Znm:
# if I understand nrnMapGMP/nMapFuncPtr correctly we need first # a source value in ZZr # create ZZr, a plain polynomial ring over ZZ with one variable. # # todo (later): reuse ZZr
else: raise ValueError
cdef object si2sa(number *n, ring *_ring, object base):
return base(_ring.cf.cfInt(n, _ring.cf))
else: raise ValueError("cannot convert from SINGULAR number")
cdef number *sa2si(Element elem, ring * _ring):
return n_Init(int(elem),_ring) else: raise ValueError("cannot convert to SINGULAR number")
cdef object si2sa_intvec(intvec *v): cdef int r
# ============== # Initialisation # ==============
cdef extern from *: # hack to get at cython macro int unlikely(int)
cdef extern from "dlfcn.h": void *dlopen(char *, long) char *dlerror() void dlclose(void *handle)
cdef extern from "dlfcn.h": cdef long RTLD_LAZY cdef long RTLD_GLOBAL
cdef int overflow_check(unsigned long e, ring *_ring) except -1: """ Raise an ``OverflowError`` if e is > max degree per variable.
INPUT:
- ``e`` -- some integer representing a degree.
- ``_ring`` -- a pointer to some ring.
Whether an overflow occurs or not partially depends on the number of variables in the ring. See trac ticket :trac:`11856`. With Singular 4, it is by default optimized for at least 4 variables on 64-bit and 2 variables on 32-bit, which in both cases makes a maximal default exponent of 2^16-1.
EXAMPLES::
sage: P.<x,y> = QQ[] sage: y^(2^16-1) y^65535 sage: y^2^16 Traceback (most recent call last): ... OverflowError: exponent overflow (65536) """
cdef init_libsingular(): """ This initializes the SINGULAR library. This is a hack to some extent.
SINGULAR has a concept of compiled extension modules similar to Sage. For this, the compiled modules need to see the symbols from the main program. However, SINGULAR is a shared library in this context these symbols are not known globally. The work around so far is to load the library again and to specify ``RTLD_GLOBAL``. """ global singular_options global singular_verbose_options global WerrorS_callback global error_messages
cdef void *handle = NULL
from sage.env import SINGULAR_SO lib = SINGULAR_SO
if not os.path.exists(lib): raise ImportError("cannot locate Singular library ({})".format(lib))
lib = str_to_bytes(lib, FS_ENCODING, "surrogateescape")
handle = dlopen(lib, RTLD_GLOBAL|RTLD_LAZY) if not handle: err = dlerror() raise ImportError("cannot load Singular library ({})".format(err))
# load SINGULAR siInit(lib)
dlclose(handle)
# we set and save some global Singular options singular_options = singular_options | Sy_bit(OPT_REDSB) | Sy_bit(OPT_INTSTRATEGY) | Sy_bit(OPT_REDTAIL) | Sy_bit(OPT_REDTHROUGH) global _saved_options global _saved_verbose_options _saved_options = (int(singular_options), 0, 0) _saved_verbose_options = int(singular_verbose_options)
#On(SW_USE_NTL) On(SW_USE_EZGCD) Off(SW_USE_NTL_SORT)
WerrorS_callback = libsingular_error_callback
error_messages = []
# call the init routine init_libsingular()
cdef void libsingular_error_callback(const_char_ptr s): |