Description

Singular is a Computer Algebra System for polynomial computations with special emphasis on the needs of commutative algebra, algebraic geometry, and singularity theory.

Singular is distributed freely under the GNU General Public License (version 2 of the License); with the following additional restrictions (which override any conflicting restrictions in the GPL): The following software used with SINGULAR have their own copyright: the omalloc library, the readline library, the Gnu Multiple Precision Library (GMP), NTL: A Library for doing Number Theory (NTL), the MultiProtocol library (MP), the Singular-Factory library, the Singular-libfac library, and, for the Windows distributions the Cygwin DLL and the Cygwin tools (Cygwin), and the XEmacs editor (XEmacs). Their copyrights and licenses can be found in the accompanying files which are distributed along with these packages.

The Singular team won the ISAAC 2004 Richard D. Jenks Memorial Prize for Excellence in Software Engineering for Computer Algebra.

Website

http://www.singular.uni-kl.de/

Integration into SAGE

Singular is integrated in two ways:

Examples

   1 sage: P.<x,y,z> = PolynomialRing(QQ,3) # uses Singular in shared library mode
   2 sage: type(P)
   3 <type 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_libsingular'>
   4 sage: I = sage.rings.ideal.Katsura(P)
   5 sage: I.groebner_basis() # calls Singular via the  pexpect interface in background
   6 [x + 2*y + 2*z - 1, 10*y*z + 12*z^2 - y - 4*z, 5*y^2 - 3*z^2 - y + z, 210*z^3 - 79*z^2 + 7*y + 3*z]
   7 sage: f = I.gens()[0]
   8 sage: g = f._singular_() # -> pexpect interface
   9 sage: P(g) # -> shared library mode
  10 sage: x + 2*y + 2*z - 1

Performance

Singular provides a very fast multivariate polynomial implementation. Please note, that benchmarking these things in the Singular interpreter will probably give false results as the interpreter is very basic. To gather some simple performance datapoints consider:

   1 sage: print "over QQ"
   2 
   3 sage: P.<x,y,z> = PolynomialRing(QQ,3)
   4 sage: p = (x + y + z + 1)^20 # the Fateman fastmult benchmark
   5 sage: q = p + 1
   6 sage: t = cputime()
   7 sage: r = p*q
   8 sage: print "SAGE/Singular %0.2f"%cputime(t)
   9 
  10 sage: p = p._magma_() # MAGMA 2.13-2
  11 sage: q = q._magma_()
  12 sage: t = magma.cputime()
  13 sage: r = p*q
  14 sage: print "MAGMA         %0.2f"%magma.cputime(t)
  15 
  16 sage: print "over GF(32003)"
  17 
  18 sage: P.<x,y,z> = PolynomialRing(GF(32003),3)
  19 sage: p = (x + y + z + 1)^20 # the Fateman fastmult benchmark
  20 sage: q = p + 1
  21 sage: t = cputime()
  22 sage: r = p*q
  23 sage: print "SAGE/Singular %0.2f"%cputime(t)
  24 
  25 sage: p = p._magma_() # MAGMA 2.13-2
  26 sage: q = q._magma_()
  27 sage: t = magma.cputime()
  28 sage: r = p*q
  29 sage: print "MAGMA         %0.2f"%magma.cputime(t)

On http://sage.math.washington.edu (1.8Ghz Opteron) and SAGE 2.5.1 (with a libSINGULAR without debugging options) this produces

   1 over QQ
   2 SAGE/Singular 2.35
   3 MAGMA         0.86
   4 over GF(32003)
   5 SAGE/Singular 0.24
   6 MAGMA         0.52

as output. On a 2.33Ghu Core2Duo Macbook Pro running a 64-bit Debian/Linux and the same software configuration this produces

   1 over QQ
   2 SAGE/Singular 1.42
   3 MAGMA         0.76
   4 over GF(32003)
   5 SAGE/Singular 0.15
   6 MAGMA         0.39

as output.

Tips, Tricks, and Pitfalls

   1 sage: singular.ring(0,'(x,y)','dp')
   2 //   characteristic : 0
   3 //   number of vars : 2
   4 //        block   1 : ordering dp
   5 //                  : names    x y
   6 //        block   2 : ordering C
   7 sage: x=singular("x")
   8 sage: f=0
   9 sage: time for i in range(1000): f+=x^i
  10 CPU times: user 0.95 s, sys: 0.12 s, total: 1.08 s
  11 Wall time: 1.69
  12 sage: time _ = singular.eval("poly f=0; for(i=0; i<1000 ; i=i+1) { f=f+x^i; }; f")
  13 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
  14 Wall time: 0.15