Appendix D SINGULAR libraries
*****************************

SINGULAR comes with a set of standard libraries. Their content is
described in the following subsections.

Use the LIB command for loading of single libraries, and the
command LIB "all.lib"; for loading all libraries.

* standard_lib:: extensions of Singular kernel
* General purpose::
* Linear algebra::
* Commutative algebra::
* Singularities::
* Invariant theory::
* Symbolic-numerical solving::
* Visualization::
* Coding theory::
D.1 standard_lib
================

The library standard.lib provides extensions to the
set of built-in commands and is automatically loaded
during the start of SINGULAR, unless SINGULAR is started up
with the --no-stdlib command line option (see
Command line options).

Library:
standard.lib
Purpose:
   Procedures which are always loaded at Start-up


Procedures:
* stdfglm:: standard basis of ideal via fglm [and ordering ord]
* stdhilb:: standard basis of ideal using the Hilbert function
* groebner:: standard basis using a heuristically chosen method
* quot:: quotient using heuristically chosen method
* res:: free resolution of ideal or module
* sprintf:: returns formatted string
* fprintf:: writes formatted string to link
* printf:: displays formatted string

D.2 General purpose
===================

* all_lib:: load all other libraries
* general_lib:: procedures of general type
* inout_lib:: procedures for manipulating in- and output
* poly_lib:: procedures for manipulating polynomials and ideals
* random_lib:: procedures of random/sparse  matrix and poly operations
* ring_lib:: procedures for manipulating rings and maps

D.2.1 all_lib
-------------

The library all.lib provides a convenient way to load all
libraries of the SINGULAR distribution.

Example:
option(loadLib);
LIB "all.lib";
==> // ** loaded all.lib (1.35.2.4,2003/02/25)
==> // ** loaded makedbm.lib (1.11,2000/12/22)
==> // ** loaded brnoeth.lib (1.11.2.5,2002/10/18)
==> // ** loaded paramet.lib (1.11.2.1,2002/10/21)
==> // ** loaded surf.lib (1.19.2.6,2002/07/17)
==> // ** loaded latex.lib (1.19.2.1,2002/02/20)
==> // ** loaded graphics.lib (1.10,2001/02/19)
==> // ** loaded zeroset.lib (1.7.2.2,2002/02/20)
==> // ** loaded ntsolve.lib (1.12.2.1,2002/04/12)
==> // ** loaded triang.lib (1.7,2001/02/19)
==> // ** loaded solve.lib (1.21.2.13,2002/10/21)
==> // ** loaded presolve.lib (1.17.2.6,2003/03/26)
==> // ** loaded stratify.lib (1.7.2.4,2002/04/11)
==> // ** loaded rinvar.lib (1.7.2.3,2002/02/20)
==> // ** loaded finvar.lib (1.32.2.2,2002/08/13)
==> // ** loaded ainvar.lib (1.6.2.2,2002/04/12)
==> // ** loaded spectrum.lib (1.12.2.3,2002/03/06)
==> // ** loaded spcurve.lib (1.15.2.1,2002/02/20)
==> // ** loaded sing.lib (1.24.2.5,2003/04/15)
==> // ** loaded qhmoduli.lib (1.0,2000/12/12)
==> // ** loaded mondromy.lib (1.22.2.2,2002/02/20)
==> // ** loaded hnoether.lib (1.29.2.14,2002/10/21)
==> // ** loaded gaussman.lib (1.33.2.26,2003/02/10)
==> // ** loaded equising.lib (1.7.2.5,2003/02/25)
==> // ** loaded deform.lib (1.25.2.2,2003/02/24)
==> // ** loaded classify.lib (1.48.2.4,2002/04/11)
==> // ** loaded toric.lib (1.11,2001/02/06)
==> // ** loaded intprog.lib (1.5,2001/02/06)
==> // ** loaded reesclos.lib (1.50,2001/08/06)
==> // ** loaded primitiv.lib (1.15,2001/02/05)
==> // ** loaded primdec.lib (1.98.2.14,2003/04/07)
==> // ** loaded normal.lib (1.34.2.17,2002/10/21)
==> // ** loaded mregular.lib (1.6.2.1,2002/02/20)
==> // ** loaded mprimdec.lib (1.1.2.3,2002/03/19)
==> // ** loaded homolog.lib (1.15.2.2,2002/10/07)
==> // ** loaded elim.lib (1.14.2.4,2003/04/16)
==> // ** loaded algebra.lib (1.9.2.3,2002/04/11)
==> // ** loaded linalg.lib (1.10.2.15,2003/04/04)
==> // ** loaded matrix.lib (1.26.2.2,2002/10/07)
==> // ** loaded ring.lib (1.17.2.1,2002/02/20)
==> // ** loaded random.lib (1.16.2.1,2002/02/20)
==> // ** loaded poly.lib (1.33.2.6,2003/02/10)
==> // ** loaded inout.lib (1.21.2.5,2002/06/12)
==> // ** loaded general.lib (1.38.2.9,2003/04/04)
D.2.2 general_lib
-----------------
Library:
general.lib
Purpose:
   Elementary Computations of General Type


Procedures:
* A_Z:: string a,b,... of n comma separated letters
* ASCII:: string of printable ASCII characters (number n to m)
* absValue:: absolute value of c
* binomial:: n choose m (type int), [type string/type number]
* deleteSublist:: delete entries given by iv from list l
* factorial:: n factorial (=n!) (type int), [type string/number]
* fibonacci:: nth Fibonacci number [char p]
* kmemory:: active [allocated] memory in kilobyte
* killall:: kill all user-defined variables
* number_e:: compute exp(1) up to n decimal digits
* number_pi:: compute pi (area of unit circle) up to n digits
* primes:: intvec of primes p, n<=p<=m
* product:: multiply components of vector/ideal/...[indices v]
* sort:: sort generators according to monomial ordering
* sum:: add components of vector/ideal/...[with indices v]
* watchdog:: only wait for result of command cmd for i seconds
* which:: search for command and return absolute path, if found
* primecoeffs:: primefactors <= min(p,32003) of coeffs of J
* primefactors:: primefactors <= min(p,32003) of n
* timeStd:: std(i) if computation finished after d seconds else i
* timeFactorize:: works as timeStd with factorization
* factorH:: factorizes with good choice of principal variable

D.2.2.1 A_Z
...........
Procedure from library general.lib (see general_lib).

Usage:
A_Z("a",n); a any letter, n integer (-26<= n <=26, !=0)

Return:
string of n small (if a is small) or capital (if a is capital)
letters, comma separated, beginning with a, in alphabetical
order (or revers alphabetical order if n<0)

Example:
LIB "general.lib";
A_Z("c",5);
==> c,d,e,f,g
A_Z("Z",-5);
==> Z,Y,X,W,V
string sR = "ring R = (0,"+A_Z("A",6)+"),("+A_Z("a",10)+"),dp;";
sR;
==> ring R = (0,A,B,C,D,E,F),(a,b,c,d,e,f,g,h,i,j),dp;
execute(sR);
R;
==> //   characteristic : 0
==> //   6 parameter    : A B C D E F 
==> //   minpoly        : 0
==> //   number of vars : 10
==> //        block   1 : ordering dp
==> //                  : names    a b c d e f g h i j 
==> //        block   2 : ordering C

D.2.2.2 ASCII
.............
Procedure from library general.lib (see general_lib).

Usage:
ASCII([n,m]); n,m= integers (32 <= n <= m <= 126)

Return:
string of printable ASCII characters (no native language support)
ASCII(): string of all ASCII characters with its numbers,
ASCII(n): n-th ASCII character

ASCII(n,m): n-th up to m-th ASCII character (inclusive)

Example:
LIB "general.lib";
ASCII();"";
==>      !    "    #    $    %    &    '    (    )    *    +    ,    -    .
==> 32   33   34   35   36   37   38   39   40   41   42   43   44   45   46
==> /    0    1    2    3    4    5    6    7    8    9    :    ;    <    =
==> 47   48   49   50   51   52   53   54   55   56   57   58   59   60   61
==> >    ?    @    A    B    C    D    E    F    G    H    I    J    K    L
==> 62   63   64   65   66   67   68   69   70   71   72   73   74   75   76
==> M    N    O    P    Q    R    S    T    U    V    W    X    Y    Z    [
==> 77   78   79   80   81   82   83   84   85   86   87   88   89   90   91
==> \    ]    ^    _    `    a    b    c    d    e    f    g    h    i    j
==> 92   93   94   95   96   97   98   99  100  101  102  103  104  105  10
==> k    l    m    n    o    p    q    r    s    t    u    v    w    x    y
==> 107  108  109  110  111  112  113  114  115  116  117  118  119  120  121
==> z    {    |    }    ~
==> 122  123  124  125  126 
==> 
ASCII(42);
==> *
ASCII(32,126);
==>  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefgh\
   ijklmnopqrstuvwxyz{|}~

D.2.2.3 absValue
................
Procedure from library general.lib (see general_lib).

Usage:
absValue(c); c int, number or poly

Return:
absValue(c); the absolute value of c

Note:
absValue(c)=c if c>=0; absValue=-c if c<=0.

 So the function can be applied to any type, for which comparison

 operators are defined.

Example:
LIB "general.lib";
ring r1 = 0,x,dp;
absValue(-2002);
==> 2002
poly f=-4;
absValue(f);
==> 4


D.2.2.4 binomial
................
Procedure from library general.lib (see general_lib).

Usage:
binomial(n,k[,p]); n,k,p integers

Return:
binomial(n,k); binomial coefficient n choose k

 - of type string (computed in characteristic 0)

 binomial(n,k,p); n choose k, computed in characteristic 0 or prime(p)

 - of type number if a basering, say R, is present and p=0=char(R)
or if prime(p)=char(R)

 - of type string else

Note:
In any characteristic, binomial(n,k) = coefficient of x^k in (1+x)^n

Example:
LIB "general.lib";
binomial(200,100);"";                   //type string, computed in char 0
==> 90548514656103281165404177077484163874504589675413336841320
==> 
binomial(200,100,3);"";                 //type string, computed in char 3
==> 0
==> 
int n,k = 200,100;
ring r = 0,x,dp;
number b1 = binomial(n,k,0);            //type number, computed in ring r
poly b2 = coeffs((x+1)^n,x)[k+1,1];     //coefficient of x^k in (x+1)^n
b1-b2;                                  //b1 and b2 should coincide
==> 0


D.2.2.5 deleteSublist
.....................
Procedure from library general.lib (see general_lib).

Usage:
deleteSublist(v,l); intvec v; list l

where the entries of the integer vector v correspond to the
positions of the elements to be deleted

Return:
list without the deleted elements

Example:
LIB "general.lib";
list l=1,2,3,4,5;
intvec v=1,3,4;
l=deleteSublist(v,l);
l;
==> [1]:
==>    2
==> [2]:
==>    5

D.2.2.6 factorial
.................
Procedure from library general.lib (see general_lib).

Usage:
factorial(n[,p]); n,p integers

Return:
factorial(n): n! (computed in characteristic 0), of type string.

 factorial(n,p): n! computed in characteristic 0 or prime(p)

 - of type number if a basering is present and 0=p=char(basering)
or if prime(p)=char(basering)

 - of type string else

Example:
LIB "general.lib";
factorial(37);"";                 //37! of type string (as long integer)
==> 13763753091226345046315979581580902400000000
==> 
ring r1 = 0,x,dp;
number p = factorial(37,0);       //37! of type number, computed in r
p;
==> 13763753091226345046315979581580902400000000


D.2.2.7 fibonacci
.................
Procedure from library general.lib (see general_lib).

Usage:
fibonacci(n); n,p integers

Return:
fibonacci(n): nth Fibonacci number, f(0)=f(1)=1, f(i+1)=f(i-1)+f(i)

 - computed in characteristic 0, of type string

 fibonacci(n,p): f(n) computed in characteristic 0 or prime(p)

 - of type number if a basering is present and p=0=char(basering)
or if prime(p)=char(basering)

 - of type string else

Example:
LIB "general.lib";
fibonacci(42); "";             //f(42) of type string (as long integer)
==> 267914296
==> 
ring r = 2,x,dp;
number b = fibonacci(42,2);    //f(42) of type number, computed in r
b;
==> 0


D.2.2.8 kmemory
...............
Procedure from library general.lib (see general_lib).

Usage:
kmemory([n,[v]]); n,v integers

Return:
memory in kilobyte of type int

 n=0: memory used by active variables (same as no parameters)

 n=1: total memory allocated by Singular

 n=2: difference between top and init memory address (sbrk memory)

 n!=0,1,2: 0

Display:
detailed information about allocated and used memory if v!=0

Note:
kmemory uses internal function 'memory' to compute kilobyte, and
is the same as 'memory' for n!=0,1,2

Example:
LIB "general.lib";
kmemory();
==> 152
kmemory(1,1);
==> // total memory allocated, at the moment, by SINGULAR (kilobyte):
==> 650

D.2.2.9 killall
...............
Procedure from library general.lib (see general_lib).

Usage:
killall(); (no parameter)

killall("type_name");

killall("not", "type_name");

Return:
killall(); kills all user-defined variables except loaded procedures,
no return value.

 - killall("type_name"); kills all user-defined variables,
of type "type_name"

 - killall("not", "type_name"); kills all user-defined variables,
except those of type "type_name" and except loaded procedures

 - killall("not", "name_1", "name_2", ...);
kills all user-defined variables, except those of name "name_i"
and except loaded procedures

Note:
killall should never be used inside a procedure

Example:
LIB "general.lib";
ring rtest; ideal i=x,y,z; string str="hi"; int j = 3;
export rtest,i,str,j;       //this makes the local variables global
==> // ** `rtest` is already global
==> // ** `i` is already global
==> // ** `str` is already global
==> // ** `j` is already global
listvar();
==> // j                    [0]  int 3
==> // str                  [0]  string hi
==> // rtest                [0]  *ring
==> //      i                    [0]  ideal, 3 generator(s)
==> // LIB                  [0]  string standard.lib,general..., 74 char(s)
killall("ring");            // kills all rings
==> // ** killing the basering for level 0
listvar();
==> // j                    [0]  int 3
==> // str                  [0]  string hi
==> // LIB                  [0]  string standard.lib,general..., 74 char(s)
killall("not", "int");      // kills all variables except int's (and procs)
listvar();
==> // j                    [0]  int 3
==> // LIB                  [0]  string standard.lib,general..., 74 char(s)
killall();                  // kills all vars except loaded procs
listvar();
==> // j                    [0]  int 3
==> // LIB                  [0]  string standard.lib,general..., 74 char(s)

D.2.2.10 number_e
.................
Procedure from library general.lib (see general_lib).

Usage:
number_e(n); n integer

Return:
Euler number e=exp(1) up to n decimal digits (no rounding)

 - of type string if no basering of char 0 is defined

 - of type number if a basering of char 0 is defined

Display:
decimal format of e if printlevel > 0 (default:printlevel=0 )

Note:
procedure uses algorithm of A.H.J. Sale

Example:
LIB "general.lib";
number_e(30);"";
==> 2.71828182845904523536028747135
==> 
ring R = 0,t,lp;
number e = number_e(30);
e;
==> 13591409142295226176801437356763/5000000000000000000000000000000

D.2.2.11 number_pi
..................
Procedure from library general.lib (see general_lib).

Usage:
number_pi(n); n positive integer

Return:
pi (area of unit circle) up to n decimal digits (no rounding)

 - of type string if no basering of char 0 is defined,

 - of type number, if a basering of char 0 is defined

Display:
decimal format of pi if printlevel > 0 (default:printlevel=0 )

Note:
procedure uses algorithm of S. Rabinowitz

Example:
LIB "general.lib";
number_pi(11);"";
==> 3.1415926535
==> 
ring r = (real,10),t,dp;
number pi = number_pi(11); pi;
==> 3.1415926536

D.2.2.12 primes
...............
Procedure from library general.lib (see general_lib).

Usage:
primes(n,m); n,m integers

Return:
intvec, consisting of all primes p, prime(n)<=p<=m, in increasing
order if n<=m, resp. prime(m)<=p<=n, in decreasing order if m<n.

Note:
prime(n); returns the biggest prime number <= min(n,32003)
if n>=2, else 2

Example:
LIB "general.lib";
primes(50,100);"";
==> 47,53,59,61,67,71,73,79,83,89,97
==> 
intvec v = primes(37,1); v;
==> 37,31,29,23,19,17,13,11,7,5,3,2

D.2.2.13 product
................
Procedure from library general.lib (see general_lib).

Usage:
product(id[,v]); id ideal/vector/module/matrix/intvec/intmat/list,
v intvec (default: v=1..number of entries of id)

Assume:
list members can be multiplied.

Return:
The product of all entries of id [with index given by v] of type
depending on the entries of id.

Note:
If id is not a list, id is treated as a list of polys resp. integers.
A module m is identified with the corresponding matrix M (columns
of M generate m).

 If v is outside the range of id, we have the empty product and the
result will be 1 (of type int).

Example:
LIB "general.lib";
ring r= 0,(x,y,z),dp;
ideal m = maxideal(1);
product(m);
==> xyz
product(m[2..3]);
==> yz
matrix M[2][3] = 1,x,2,y,3,z;
product(M);
==> 6xyz
intvec v=2,4,6;
product(M,v);
==> xyz
intvec iv = 1,2,3,4,5,6,7,8,9;
v=1..5,7,9;
product(iv,v);
==> 7560
intmat A[2][3] = 1,1,1,2,2,2;
product(A,3..5);
==> 4

D.2.2.14 sort
.............
Procedure from library general.lib (see general_lib).

Usage:
sort(id[v,o,n]); id = ideal/module/intvec/list(of intvec's or int's)

 sort may be called with 1, 2 or 3 arguments in the following way:

 sort(id[v,n]); v=intvec of positive integers, n=integer,

 sort(id[o,n]); o=string (any allowed ordstr of a ring), n=integer

Return:
a list l of two elements:
        l[1]: object of same type as input but sorted in the following way:
           - if id=ideal/module: generators of id are sorted w.r.t. intvec v
             (id[v[1]] becomes 1-st, id[v[2]]  2-nd element, etc.). If no v is
             present, id is sorted w.r.t. ordering o (if o is given) or w.r.t.
             actual monomial ordering (if no o is given):
             NOTE: generators with SMALLER(!) leading term come FIRST
             (e.g. sort(id); sorts backwards to actual monomial ordering)
           - if id=list of intvec's or int's: consider a list element, say
             id[1]=3,2,5, as exponent vector of the monomial x^3*y^2*z^5;
             the corresponding monomials are ordered w.r.t. intvec v (s.a.).
             If no v is present, the monomials are sorted w.r.t. ordering o
             (if o is given) or w.r.t. lexicographical ordering (if no o is
             given). The corresponding ordered list of exponent vectors is
             returned.
             (e.g. sort(id); sorts lexicographically, smaller int's come first)
             WARNING: Since negative exponents create the 0 polynomial in
             Singular, id should not contain negative integers: the result
             might not be as expected
           - if id=intvec: id is treated as list of integers
           - if n!=0 the ordering is inverse, i.e. w.r.t. v(size(v)..1)
             default: n=0
         l[2]: intvec, describing the permutation of the input (hence l[2]=v
             if v is given (with positive integers))

Note:
If v is given id may be any simply indexed object (e.g. any list or
string); if v[i]<0 and i<=size(id) v[i] is set internally to i;
entries of v must be pairwise distinct to get a permutation if id.
Zero generators of ideal/module are deleted

Example:
LIB "general.lib";
ring r0 = 0,(x,y,z,t),lp;
ideal i = x3,z3,xyz;
sort(i);            //sorts using lex ordering, smaller polys come first
==> [1]:
==>    _[1]=z3
==>    _[2]=xyz
==>    _[3]=x3
==> [2]:
==>    2,3,1
sort(i,3..1);
==> [1]:
==>    _[1]=xyz
==>    _[2]=z3
==>    _[3]=x3
==> [2]:
==>    3,2,1
sort(i,"ls")[1];     //sort w.r.t. negative lex ordering
==> _[1]=x3
==> _[2]=xyz
==> _[3]=z3
intvec v =1,10..5,2..4;v;
==> 1,10,9,8,7,6,5,2,3,4
sort(v)[1];          // sort v lexicographically
==> 1,2,3,4,5,6,7,8,9,10
sort(v,"Dp",1)[1];   // sort v w.r.t (total sum, reverse lex)
==> 10,9,8,7,6,5,4,3,2,1

D.2.2.15 sum
............
Procedure from library general.lib (see general_lib).

Usage:
sum(id[,v]); id ideal/vector/module/matrix/intvec/intmat/list,
v intvec (default: v=1..number of entries of id)

Assume:
list members can be added.

Return:
The sum of all entries of id [with index given by v] of type
depending on the entries of id.

Note:
If id is not a list, id is treated as a list of polys resp. integers.
A module m is identified with the corresponding matrix M (columns
of M generate m).

 If v is outside the range of id, we have the empty sum and the
result will be 0 (of type int).

Example:
LIB "general.lib";
ring r= 0,(x,y,z),dp;
vector pv = [xy,xz,yz,x2,y2,z2];
sum(pv);
==> x2+xy+y2+xz+yz+z2
sum(pv,2..5);
==> x2+y2+xz+yz
matrix M[2][3] = 1,x,2,y,3,z;
intvec w=2,4,6;
sum(M,w);
==> x+y+z
intvec iv = 1,2,3,4,5,6,7,8,9;
sum(iv,2..4);
==> 9

D.2.2.16 watchdog
.................
Procedure from library general.lib (see general_lib).

Return:
Result of cmd, if the result can be computed in i seconds.
Otherwise the computation is interrupted after i seconds,
the string "Killed" is returned and the global variable
'watchdog_interrupt' is defined.

Note:
* the MP package must be enabled

* the current basering should not be watchdog_rneu, since
watchdog_rneu will be killed

* if there are variable names of the structure x(i) all
polynomials have to be put into eval(...) in order to be
interpreted correctly

* a second Singular process is started by this procedure

Example:
LIB "general.lib";
ring r=0,(x,y,z),dp;
poly f=x^30+y^30;
watchdog(1,"factorize(eval("+string(f)+"))");
==> [1]:
==>    _[1]=1
==>    _[2]=x16+x14y2-x10y6-x8y8-x6y10+x2y14+y16
==>    _[3]=x8-x6y2+x4y4-x2y6+y8
==>    _[4]=x4-x2y2+y4
==>    _[5]=x2+y2
==> [2]:
==>    1,1,1,1,1
watchdog(100,"factorize(eval("+string(f)+"))");
==> [1]:
==>    _[1]=1
==>    _[2]=x16+x14y2-x10y6-x8y8-x6y10+x2y14+y16
==>    _[3]=x8-x6y2+x4y4-x2y6+y8
==>    _[4]=x4-x2y2+y4
==>    _[5]=x2+y2
==> [2]:
==>    1,1,1,1,1

D.2.2.17 which
..............
Procedure from library general.lib (see general_lib).

Usage:
which(command); command = string expression

Return:
Absolute pathname of command, if found in search path.
Empty string, otherwise.

Note:
Based on the Unix command 'which'.

Example:
LIB "general.lib";
which("sh");
==> /bin/sh

D.2.2.18 primecoeffs
....................
Procedure from library general.lib (see general_lib).

Usage:
primecoeffs(J[,q]); J any type which can be converted to a matrix
e.g. ideal, matrix, vector, module, int, intvec

q = intger

Compute:
primefactors <= min(p,32003) of coeffs of J (default p = 32003)

Return:
a list, say l, of two intvectors:

l[1] : the different primefactors of all coefficients of J
l[2] : the different remaining factors

Note:
the procedure works for small integers only, just by testing all
primes (not to be considerd as serious prime factorization!)

Example:
LIB "general.lib";
primecoeffs(intvec(7*8*121,7*8));"";
==> [1]:
==>    2,7,11
==> [2]:
==>    1
==> 
ring r = 0,(b,c,t),dp;
ideal I = -13b6c3t+4b5c4t,-10b4c2t-5b4ct2;
primecoeffs(I);
==> [1]:
==>    2,5,13
==> [2]:
==>    _[1]=1

D.2.2.19 primefactors
.....................
Procedure from library general.lib (see general_lib).

Usage:
primefactors(n [,p]); n = int or number, p = integer

Compute:
primefactors <= min(p,32003) of n (default p = 32003)

Return:
a list, say l,

l[1] : primefactors <= min(p,32003) of n

l[2] : l[2][i] = multiplicity of l[1][i]

l[3] : remaining factor ( n=product{ (l[1][i]^l[2][i])*l[3]} )
type(l[3])=typeof(n)

Note:
If n is a long integer (of type number) then the procedure
finds primefactors <= min(p,32003) but n may be larger as
2147483647 (max. integer representation)

Warning:
the procedure works for small integers only, just by testing all
primes (not to be considerd as serious prime factorization!)

Example:
LIB "general.lib";
primefactors(7*8*121);
==> [1]:
==>    2,7,11
==> [2]:
==>    3,1,2
==> [3]:
==>    1
ring r = 0,x,dp;
primefactors(123456789100);
==> [1]:
==>    2,5
==> [2]:
==>    2,2
==> [3]:
==>    1234567891

D.2.2.20 timeStd
................
Procedure from library general.lib (see general_lib).

Usage:
timeStd(i,d), i ideal, d integer

Return:
std(i) if the standard basis computation finished after
d-1 seconds and i otherwise

Example:
LIB "general.lib";
ring r=32003,(a,b,c,d,e),dp;
int n=6;
ideal i=
a^n-b^n,
b^n-c^n,
c^n-d^n,
d^n-e^n,
a^(n-1)*b+b^(n-1)*c+c^(n-1)*d+d^(n-1)*e+e^(n-1)*a;
ideal j=timeStd(i,2);
j;
==> j[1]=a6-b6
==> j[2]=b6-c6
==> j[3]=c6-d6
==> j[4]=d6-e6
==> j[5]=a5b+b5c+c5d+d5e+ae5

D.2.2.21 timeFactorize
......................
Procedure from library general.lib (see general_lib).

Usage:
timeFactorize(p,d) poly p , integer d

Return:
factorize(p) if the factorization finished after d-1

seconds otherwise f is considered to be irreducible

Example:
LIB "general.lib";
ring r=0,(x,y),dp;
poly p=((x2+y3)^2+xy6)*((x3+y2)^2+x10y);
p=p^2;
list l=timeFactorize(p,2);
l;
==> [1]:
==>    [1]:
==>       1
==>    [2]:
==>       x22y14+2x21y14+4x23y11+x20y14+2x25y8+4x22y11+6x24y8+4x26y5+2x18y13+\
   x28y2+4x17y13+4x15y15+8x19y10+2x16y13+8x14y15+2x12y17+4x21y7+8x18y10+16x1\
   6y12+4x13y15+4x11y17+12x20y7+8x18y9+16x15y12+8x13y14+2x10y17+8x22y4+24x17\
   y9+4x15y11+x14y12+8x12y14+2x24y+16x19y6+12x14y11+2x13y12+4x11y14+4x21y3+8\
   x16y8+4x15y9+x12y12+8x10y14+6x8y16+2x18y5+2x17y6+4x14y9+16x12y11+4x9y14+1\
   2x7y16+4x5y18+6x16y6+8x14y8+16x11y11+24x9y13+6x6y16+8x4y18+x2y20+4x18y3+2\
   4x13y8+12x11y10+24x8y13+16x6y15+4x3y18+2xy20+x20+16x15y5+36x10y10+8x8y12+\
   16x5y15+4x3y17+y20+4x17y2+24x12y7+24x7y12+2x5y14+4x2y17+6x14y4+16x9y9+6x4\
   y14+4x11y6+4x6y11+x8y8
==> [2]:
==>    1,1

D.2.2.22 factorH
................
Procedure from library general.lib (see general_lib).

Usage:
factorH(p) p poly

Return:
factorize(p)

Note:
changes variables to become the last variable the principal
one in the multivariate factorization and factorizes then
the polynomial

Example:
LIB "general.lib";
system("random",992851144);
ring r=32003,(x,y,z,w,t),lp;
poly p=y2w9+yz7t-yz5w4-z2w4t4-w8t3;
//factorize(p);  //fast
//system("random",992851262);
//factorize(p);  //slow
//system("random",992851262);
factorH(p);
==> [1]:
==>    _[1]=1
==>    _[2]=y2w9+yz7t-yz5w4-z2w4t4-w8t3
==> [2]:
==>    1,1
D.2.3 inout_lib
---------------
Library:
inout.lib
Purpose:
     Printing and Manipulating In- and Output


Procedures:
* allprint:: print list if ALLprint is defined, with pause if >0
* lprint:: display poly/... fitting to pagewidth [size n]
* pmat:: print form-matrix [first n chars of each column]
* rMacaulay:: read Macaulay_1 output and return its Singular format
* show:: display any object in a compact format
* showrecursive:: display id recursively with respect to variables in p
* split:: split given string into lines of length n
* tab:: string of n space tabs
* writelist:: write a list into a file and keep the list structure
* pause:: stop the computation until user input

D.2.3.1 allprint
................
Procedure from library inout.lib (see inout_lib).

Usage:
allprint(L); L list

Display:
prints L[1], L[2], ... if an integer with name ALLprint is defined.

 makes "pause", if ALLprint > 0

 listvar(matrix), if ALLprint = 2

Return:
no return value

Example:
LIB "inout.lib";
ring S;
matrix M=matrix(freemodule(2),3,3);
int ALLprint; export ALLprint;
==> // ** `ALLprint` is already global
allprint("M =",M);
==> M =
==> 1,0,0,
==> 0,1,0,
==> 0,0,0 
kill ALLprint;

D.2.3.2 lprint
..............
Procedure from library inout.lib (see inout_lib).

Usage:
lprint(id[,n]); id poly/ideal/vector/module/matrix, n integer

Return:
string of id in a format fitting into lines of size n, such that no
monomial is destroyed, i.e. the new line starts with + or -;
(default: n = pagewidth).

Note:
id is printed columnwise, each column separated by a blank line;
hence lprint(transpose(id)); displays a matrix id in a format which
can be used as input.

Example:
LIB "inout.lib";
ring r= 0,(x,y,z),ds;
poly f=((x+y)*(x-y)*(x+z)*(y+z)^2);
lprint(f,40);
==>   x3y2-xy4+2x3yz+x2y2z-2xy3z-y4z+x3z2
==> +2x2yz2-xy2z2-2y3z2+x2z3-y2z3
module m = [f*(x-y)],[0,f*(x-y)];
string s=lprint(m); s;"";
==>   x4y2-x3y3-x2y4+xy5+2x4yz-x3y2z-3x2y3z+xy4z+y5z+x4z2+x3yz2-3x2y2z2-xy3z2
==> +2y4z2+x3z3-x2yz3-xy2z3+y3z3,
==>   0,
==> 
==>   0,
==>   x4y2-x3y3-x2y4+xy5+2x4yz-x3y2z-3x2y3z+xy4z+y5z+x4z2+x3yz2-3x2y2z2-xy3z2
==> +2y4z2+x3z3-x2yz3-xy2z3+y3z3
==> 
execute("matrix M[2][2]="+s+";");      //use the string s as input
module m1 = transpose(M);	          //should be the same as m
print(m-m1);
==> 0,0,
==> 0,0 

D.2.3.3 pmat
............
Procedure from library inout.lib (see inout_lib).

Usage:
pmat(M,[n]); M matrix, n integer

Display:
display M in array format if it fits into pagewidth; if n is given,
only the first n characters of each column are shown

Return:
no return value

Example:
LIB "inout.lib";
ring r=0,(x,y,z),ls;
ideal i= x,z+3y,x+y,z;
matrix m[3][3]=i^2;
pmat(m);
==> x2,     xz+3xy,     xy+x2,         
==> xz,     z2+6yz+9y2, yz+3y2+xz+3xy, 
==> z2+3yz, y2+2xy+x2,  yz+xz
pmat(m,3);
==> x2  xz+ xy+ 
==> xz  z2+ yz+ 
==> z2+ y2+ yz+ 

D.2.3.4 rMacaulay
.................
Procedure from library inout.lib (see inout_lib).

Usage:
rMacaulay(s[,n]); s string, n integer

Return:
A string which should be readable by Singular if s is a string which
was produced by Macaulay. If a second argument is present the first
n lines of the file are deleted (which is useful if the file was
produced e.g. by the putstd command of Macaulay).

Note:
This does not always work with 'cut and paste' since the character
\ is treated differently

Example:
LIB "inout.lib";
// Assume there exists a file 'Macid' with the following ideal in
// Macaulay format:"
// x[0]3-101/74x[0]2x[1]+7371x[0]x[1]2-13/83x[1]3-x[0]2x[2] \
//     -4/71x[0]x[1]x[2]
// Read this file into Singular and assign it to the string s1 by:
// string s1 = read("Macid");
// This is equivalent to";
string s1 =
"x[0]3-101/74x[0]2x[1]+7371x[0]x[1]2-13/83x[1]3-x[0]2x[2]-4/71x[0]x[1]x[2]";
rMacaulay(s1);
==> x(0)^3-101/74*x(0)^2*x(1)+7371*x(0)*x(1)^2-13/83*x(1)^3-x(0)^2*x(2)-4/71*\
   x(0)*x(1)*x(2)
// You may wish to assign s1 to a Singular ideal id:
string sid = "ideal id =",rMacaulay(s1),";";
ring r = 0,x(0..3),dp;
execute(sid);
id; "";
==> id[1]=x(0)^3-101/74*x(0)^2*x(1)+7371*x(0)*x(1)^2-13/83*x(1)^3-x(0)^2*x(2)\
   -4/71*x(0)*x(1)*x(2)
==> 
// Now treat a matrix in Macaulay format. Using the execute
// command, this could be assinged to a Singular matrix as above.
string s2 = "
0  0  0  0  0
a3 0  0  0  0
0  b3 0  0  0
0  0  c3 0  0
0  0  0  d3 0
0  0  0  0  e3 ";
rMacaulay(s2);
==> 0, 0, 0, 0, 0,
==> a3,0, 0, 0, 0,
==> 0, b3,0, 0, 0,
==> 0, 0, c3,0, 0,
==> 0, 0, 0, d3,0,
==> 0, 0, 0, 0, e3

D.2.3.5 show
............
Procedure from library inout.lib (see inout_lib).

Usage:
show(id); id any object of basering or of type ring/qring

 show(R,s); R=ring, s=string (s = name of an object belonging to R)

Display:
display id/s in a compact format together with some information

Return:
no return value

Note:
objects of type string, int, intvec, intmat belong to any ring.
id may be a ring or a qring. In this case the minimal polynomial is
displayed, and, for a qring, also the defining ideal.

id may be of type list but the list must not contain a ring.

 show(R,s) does not work inside a procedure!

Example:
LIB "inout.lib";
ring r;
show(r);
==> // ring: (32003),(x,y,z),(dp(3),C);
==> // minpoly = 0
==> // objects belonging to this ring:
ideal i=x^3+y^5-6*z^3,xy,x3-y2;
show(i,3);            // introduce 3 space tabs before information
==>    // ideal, 3 generator(s)
==> y5+x3-6z3,
==> xy,
==> x3-y2
vector v=x*gen(1)+y*gen(3);
module m=v,2*v+gen(4);
list L = i,v,m;
show(L);
==> // list, 3 element(s):
==> [1]:
==>    // ideal, 3 generator(s)
==> y5+x3-6z3,
==> xy,
==> x3-y2
==> [2]:
==>    // vector
==> [x,0,y]
==> [3]:
==>    // module, 2 generator(s)
==> [x,0,y]
==> [2x,0,2y,1]
ring S=(0,T),(a,b,c,d),ws(1,2,3,4);
minpoly = T^2+1;
ideal i=a2+b,c2+T^2*d2; i=std(i);
qring Q=i;
show(Q);
==> // qring: (0,T),(a,b,c,d),(ws(1,2,3,4),C);
==> // minpoly = (T2+1)
==> // quotient ring from ideal:
==> _[1]=a2+b
==> _[2]=c2-d2
map F=r,a2,b^2,3*c3;
show(F);
==> // i-th variable of preimage ring is mapped to @map[i]
==> // @map                 [1]  map from r
==> @map[1]=a2
==> @map[2]=b2
==> @map[3]=3*c3
// Apply 'show' to i (which does not belong to the basering) by typing
// ring r; ideal i=xy,x3-y2; ring Q; show(r,"i");

D.2.3.6 showrecursive
.....................
Procedure from library inout.lib (see inout_lib).

Usage:
showrecursive(id,p[ord]); id= any object of basering, p= product of
variables and ord=string (any allowed ordstr)

Display:
display 'id' in a recursive format as a polynomial in the variables
occurring in p with coefficients in the remaining variables. This is
done by mapping to a ring with parameters [and ordering 'ord',
if a 3rd argument is present (default: ord="dp")] and applying
procedure 'show'

Return:
no return value

Example:
LIB "inout.lib";
ring r=2,(a,b,c,d,x,y),ds;
poly f=y+ax2+bx3+cx2y2+dxy3;
showrecursive(f,x);
==> // poly, 4 monomial(s)
==> (b)*x3+(a+cy2)*x2+(dy3)*x+(y)
showrecursive(f,xy,"lp");
==> // poly, 5 monomial(s)
==> (b)*x3+(c)*x2y2+(a)*x2+(d)*xy3+y

D.2.3.7 split
.............
Procedure from library inout.lib (see inout_lib).

Usage:
split(s[,n]); s string, n integer

Return:
same string, split into lines of length n separated by \
(default: n=pagewidth)

Note:
may be used in connection with lprint

Example:
LIB "inout.lib";
ring r= 0,(x,y,z),ds;
poly f = (x+y+z)^4;
split(string(f),50);
==> x4+4x3y+6x2y2+4xy3+y4+4x3z+12x2yz+12xy2z+4y3z+6x\
==> 2z2+12xyz2+6y2z2+4xz3+4yz3+z4
split(lprint(f));
==>   x4+4x3y+6x2y2+4xy3+y4+4x3z+12x2yz+12xy2z+4y3z+6x2z2+12xyz2+6y2z2+4xz3+4\
   yz3\
==> +z4

D.2.3.8 tab
...........
Procedure from library inout.lib (see inout_lib).

Usage:
tab(n); n integer

Return:
string of n space tabs

Example:
LIB "inout.lib";
for(int n=0; n<=5; n=n+1)
{ tab(5-n)+"*"+tab(n)+"+"+tab(n)+"*"; }
==>      *+*
==>     * + *
==>    *  +  *
==>   *   +   *
==>  *    +    *
==> *     +     *

D.2.3.9 writelist
.................
Procedure from library inout.lib (see inout_lib).

Usage:
writelist(file,name,L); file,name strings (file-name, list-name),
L a list.

Create:
a file with name `file`, write the content of the list L into it and
call the list `name`, keeping the list structure

Return:
no return value

Note:
The syntax of writelist uses and is similar to the syntax of the
write command of Singular which does not manage lists properly.
If (file,name) = ("listfile","L1"), writelist creates (resp.
appends if listfile exists) a file with name listfile and stores
there the list L under the name L1. The Singular command
execute(read("listfile")); assigns the content of L (stored in
listfile) to a list L1.

 On a UNIX system, write(">file",...) overwrites an existing file
`file` while write("file",...) and write(">>file",...) append.

Example:
LIB "inout.lib";
ring r;
ideal i=x,y,z;
list k="Hi",nameof(basering),i,37;
writelist("zumSpass","lustig",k);
read("zumSpass");
==> list lustig;
==>    lustig[1]=
==> Hi;
==>    lustig[2]=
==> r;
==>    lustig[3]=
==> x,y,z;
==>    lustig[4]=
==> 37;
==> 
list L=res(i,0);                    //resolution of the ideal i
writelist("res_list","res-name",L); "";
==> 
read("res_list");
==> list res-name;
==>    res-name[1]=
==> z,y,x;
==>    res-name[2]=
==> -y*gen(1)+z*gen(2),-x*gen(1)+z*gen(3),-x*gen(2)+y*gen(3);
==>    res-name[3]=
==> x*gen(1)-y*gen(2)+z*gen(3);
==> 
// execute(read("res_list")); would create a list with name res-name,
// which is the resolution of i (the same content as L)
system("sh","/bin/rm res_list zumSpass");
==> 0
// Under UNIX, this removes the files 'res_list' and 'zumSpass'
// Type help system; to get more information about the shell escape
// If your operating system does not accept the shell escape, you
// must remove the just created files 'zumSpass' and 'res_list' directly

D.2.3.10 pause
..............
Procedure from library inout.lib (see inout_lib).

Usage:
pause([ prompt ]) prompt string

Return:
none

Purpose:
interrupt the execution of commands until user input

Note:
pause is useful in procedures in connection with printlevel to
interrupt the computation and to display intermediate results.

Example:
LIB "inout.lib";
// can only be shown interactively, try the following commands:
// pause("press <return> to continue");
// pause();
// In the following pocedure TTT, xxx is printed and the execution of
// TTT is stopped until the return-key is pressed, if printlevel>0.
// xxx may be any result of a previous computation or a comment, etc:
//
// proc TTT
// { int pp = printlevel-voice+2;  //pp=0 if printlevel=0 and if TTT is
//    ....                         //not called from another procedure
//    if( pp>0 )
//    {
//       print( xxx );
//       pause("press <return> to continue");
//    }
//     ....
// }

D.2.4 poly_lib
--------------
Library:
poly.lib
Purpose:
      Procedures for Manipulating Polys, Ideals, Modules
Authors:
O. Bachmann, G.-M: Greuel, A. Fruehbis


Procedures:
* cyclic:: ideal of cyclic n-roots
* katsura:: katsura [i] ideal
* freerank:: rank of coker(input) if coker is free else -1
* is_homog:: int, =1 resp. =0 if input is homogeneous resp. not
* is_zero:: int, =1 resp. =0 if coker(input) is 0 resp. not
* lcm:: lcm of given generators of ideal
* maxcoef:: maximal length of coefficient occurring in poly/...
* maxdeg:: int/intmat = degree/s of terms of maximal order
* maxdeg1:: int = [weighted] maximal degree of input
* mindeg:: int/intmat = degree/s of terms of minimal order
* mindeg1:: int = [weighted] minimal degree of input
* normalize:: normalize poly/... such that leading coefficient is 1
* rad_con:: check radical containment of poly p in ideal I
* content:: content of polynomial/vector f
* numerator:: numerator of number n
* denominator:: denominator of number n
* mod2id:: conversion of a module M to an ideal
* id2mod:: conversion inverse to mod2id
* substitute:: substitute in I variables by polynomials
* subrInterred:: interred w.r.t. a subset of variables
* hilbPoly:: Hilbert polynomial of basering/I

D.2.4.1 cyclic
..............
Procedure from library poly.lib (see poly_lib).

Usage:
cyclic(n); n integer

Return:
ideal of cyclic n-roots from 1-st n variables of basering

Example:
LIB "poly.lib";
ring r=0,(u,v,w,x,y,z),lp;
cyclic(nvars(basering));
==> _[1]=u+v+w+x+y+z
==> _[2]=uv+uz+vw+wx+xy+yz
==> _[3]=uvw+uvz+uyz+vwx+wxy+xyz
==> _[4]=uvwx+uvwz+uvyz+uxyz+vwxy+wxyz
==> _[5]=uvwxy+uvwxz+uvwyz+uvxyz+uwxyz+vwxyz
==> _[6]=uvwxyz-1
homog(cyclic(5),z);
==> _[1]=u+v+w+x+y
==> _[2]=uv+uy+vw+wx+xy
==> _[3]=uvw+uvy+uxy+vwx+wxy
==> _[4]=uvwx+uvwy+uvxy+uwxy+vwxy
==> _[5]=uvwxy-z5

D.2.4.2 katsura
...............
Procedure from library poly.lib (see poly_lib).

Usage:
katsura([n]): n integer

Return:
katsura(n) : n-th katsura ideal of

(1) newly created and set ring (32003, x(0..n), dp), if
nvars(basering) < n

(2) basering, if nvars(basering) >= n

katsura() : katsura ideal of basering

Example:
LIB "poly.lib";
ring r; basering;
==> //   characteristic : 32003
==> //   number of vars : 3
==> //        block   1 : ordering dp
==> //                  : names    x y z 
==> //        block   2 : ordering C
katsura();
==> _[1]=x+2y+2z-1
==> _[2]=x2+2y2+2z2-x
==> _[3]=2xy+2yz-y
katsura(4); basering;
==> _[1]=x(0)+2*x(1)+2*x(2)+2*x(3)-1
==> _[2]=x(0)^2+2*x(1)^2+2*x(2)^2+2*x(3)^2-x(0)
==> _[3]=2*x(0)*x(1)+2*x(1)*x(2)+2*x(2)*x(3)-x(1)
==> _[4]=x(1)^2+2*x(0)*x(2)+2*x(1)*x(3)-x(2)
==> //   characteristic : 32003
==> //   number of vars : 5
==> //        block   1 : ordering dp
==> //                  : names    x(0) x(1) x(2) x(3) x(4) 
==> //        block   2 : ordering C

D.2.4.3 freerank
................
Procedure from library poly.lib (see poly_lib).

Usage:
freerank(M[,any]); M=poly/ideal/vector/module/matrix

Compute:
rank of module presented by M in case it is free.

By definition this is vdim(coker(M)/m*coker(M)) if coker(M)
is free, where m = maximal ideal of the variables of the
basering and M is considered as matrix.

(the 0-module is free of rank 0)

Return:
rank of coker(M) if coker(M) is free and -1 else;

in case of a second argument return a list:

L[1] = rank of coker(M) or -1

L[2] = minbase(M)

Note:
freerank(syz(M)); computes the rank of M if M is free (and -1 else)

Example:
LIB "poly.lib";
ring r;
ideal i=x;
module M=[x,0,1],[-x,0,-1];
freerank(M);          // should be 2, coker(M) is not free
==> 2
freerank(syz (M),"");
==> [1]:
==>    1
==> [2]:
==>    _[1]=gen(2)+gen(1)
// [1] should be 1, coker(syz(M))=M is free of rank 1
// [2] should be gen(2)+gen(1) (minimal relation of M)
freerank(i);
==> -1
freerank(syz(i));     // should be 1, coker(syz(i))=i is free of rank 1
==> 1

D.2.4.4 is_homog
................
Procedure from library poly.lib (see poly_lib).

Usage:
is_homog(id); id poly/ideal/vector/module/matrix

Return:
integer which is 1 if input is homogeneous (resp. weighted homogeneous
if the monomial ordering consists of one block of type ws,Ws,wp or Wp,
assuming that all weights are positive) and 0 otherwise

Note:
A vector is homogeneous, if the components are homogeneous of same
degree, a module/matrix is homogeneous if all column vectors are
homogeneous

//*** ergaenzen, wenn Matrizen-Spalten Gewichte haben

Example:
LIB "poly.lib";
ring r = 0,(x,y,z),wp(1,2,3);
is_homog(x5-yz+y3);
==> 0
ideal i = x6+y3+z2, x9-z3;
is_homog(i);
==> 1
ring s = 0,(a,b,c),ds;
vector v = [a2,0,ac+bc];
vector w = [a3,b3,c4];
is_homog(v);
==> 1
is_homog(w);
==> 0

D.2.4.5 is_zero
...............
Procedure from library poly.lib (see poly_lib).

Usage:
is_zero(M[,any]); M=poly/ideal/vector/module/matrix

Return:
integer, 1 if coker(M)=0 resp. 0 if coker(M)!=0, where M is
considered as matrix.

If a second argument is given, return a list:

L[1] = 1 if coker(M)=0 resp. 0 if coker(M)!=0

L[2] = dim(M)

Example:
LIB "poly.lib";
ring r;
module m = [x],[y],[1,z];
is_zero(m,1);
==> [1]:
==>    0
==> [2]:
==>    2
qring q = std(ideal(x2+y3+z2));
ideal j = x2+y3+z2-37;
is_zero(j);
==> 1

D.2.4.6 lcm
...........
Procedure from library poly.lib (see poly_lib).

Usage:
lcm(p[,q]); p int/intvec q a list of integers or

p poly/ideal q a list of polynomials

Return:
the least common multiple of the common entries of p and q:

 - of type int if p is an int/intvec

 - of type poly if p is a poly/ideal

Example:
LIB "poly.lib";
ring  r = 0,(x,y,z),lp;
poly  p = (x+y)*(y+z);
poly  q = (z4+2)*(y+z);
lcm(p,q);
==> xyz4+2xy+xz5+2xz+y2z4+2y2+yz5+2yz
ideal i=p,q,y+z;
lcm(i,p);
==> xyz4+2xy+xz5+2xz+y2z4+2y2+yz5+2yz
lcm(2,3,6);
==> 6
lcm(2..6);
==> 60

D.2.4.7 maxcoef
...............
Procedure from library poly.lib (see poly_lib).

Usage:
maxcoef(f); f poly/ideal/vector/module/matrix

Return:
maximal length of coefficient of f of type int (by counting the
length of the string of each coefficient)

Example:
LIB "poly.lib";
ring r= 0,(x,y,z),ds;
poly g = 345x2-1234567890y+7/4z;
maxcoef(g);
==> 10
ideal i = g,10/1234567890;
maxcoef(i);
==> 11
// since i[2]=1/123456789

D.2.4.8 maxdeg
..............
Procedure from library poly.lib (see poly_lib).

Usage:
maxdeg(id); id poly/ideal/vector/module/matrix

Return:
int/intmat, each component equals maximal degree of monomials in the
corresponding component of id, independent of ring ordering
(maxdeg of each var is 1).

Of type int if id is of type poly, of type intmat else

Note:
proc maxdeg1 returns 1 integer, the absolute maximum; moreover, it has
an option for computing weighted degrees

Example:
LIB "poly.lib";
ring r = 0,(x,y,z),wp(1,2,3);
poly f = x+y2+z3;
deg(f);             //deg; returns weighted degree (in case of 1 block)!
==> 9
maxdeg(f);
==> 3
matrix m[2][2]=f+x10,1,0,f^2;
maxdeg(m);
==> 10,0,
==> -1,6 

D.2.4.9 maxdeg1
...............
Procedure from library poly.lib (see poly_lib).

Usage:
maxdeg1(id[,v]); id=poly/ideal/vector/module/matrix, v=intvec

Return:
integer, maximal [weighted] degree of monomials of id independent of
ring ordering, maxdeg1 of i-th variable is v[i] (default: v=1..1).

Note:
This proc returns one integer while maxdeg returns, in general,
a matrix of integers. For one polynomial and if no intvec v is given
maxdeg is faster

Example:
LIB "poly.lib";
ring r = 0,(x,y,z),wp(1,2,3);
poly f = x+y2+z3;
deg(f);            //deg returns weighted degree (in case of 1 block)!
==> 9
maxdeg1(f);
==> 3
intvec v = ringweights(r);
maxdeg1(f,v);                        //weighted maximal degree
==> 9
matrix m[2][2]=f+x10,1,0,f^2;
maxdeg1(m,v);                        //absolute weighted maximal degree
==> 18

D.2.4.10 mindeg
...............
Procedure from library poly.lib (see poly_lib).

Usage:
mindeg(id); id poly/ideal/vector/module/matrix

Return:
minimal degree/s of monomials of id, independent of ring ordering
(mindeg of each variable is 1) of type int if id of type poly, else
of type intmat.

Note:
proc mindeg1 returns one integer, the absolute minimum; moreover it
has an option for computing weighted degrees.

Example:
LIB "poly.lib";
ring r = 0,(x,y,z),ls;
poly f = x5+y2+z3;
ord(f);                  // ord returns weighted order of leading term!
==> 3
mindeg(f);               // computes minimal degree
==> 2
matrix m[2][2]=x10,1,0,f^2;
mindeg(m);               // computes matrix of minimum degrees
==> 10,0,
==> -1,4 

D.2.4.11 mindeg1
................
Procedure from library poly.lib (see poly_lib).

Usage:
mindeg1(id[,v]); id=poly/ideal/vector/module/matrix, v=intvec

Return:
integer, minimal [weighted] degree of monomials of id independent of
ring ordering, mindeg1 of i-th variable is v[i] (default v=1..1).

Note:
This proc returns one integer while mindeg returns, in general,
a matrix of integers. For one polynomial and if no intvec v is given
mindeg is faster.

Example:
LIB "poly.lib";
ring r = 0,(x,y,z),ls;
poly f = x5+y2+z3;
ord(f);                  // ord returns weighted order of leading term!
==> 3
intvec v = 1,-3,2;
mindeg1(f,v);            // computes minimal weighted degree
==> -6
matrix m[2][2]=x10,1,0,f^2;
mindeg1(m,1..3);         // computes absolute minimum of weighted degrees
==> -1

D.2.4.12 normalize
..................
Procedure from library poly.lib (see poly_lib).

Usage:
normalize(id); id=poly/vector/ideal/module

Return:
object of same type with leading coefficient equal to 1

Example:
LIB "poly.lib";
ring r = 0,(x,y,z),ls;
poly f = 2x5+3y2+4z3;
normalize(f);
==> z3+3/4y2+1/2x5
module m=[9xy,0,3z3],[4z,6y,2x];
normalize(m);
==> _[1]=z3*gen(3)+3xy*gen(1)
==> _[2]=z*gen(1)+3/2y*gen(2)+1/2x*gen(3)
ring s = 0,(x,y,z),(c,ls);
module m=[9xy,0,3z3],[4z,6y,2x];
normalize(m);
==> _[1]=[xy,0,1/3z3]
==> _[2]=[z,3/2y,1/2x]

D.2.4.13 rad_con
................
Procedure from library poly.lib (see poly_lib).

Usage:
rad_con(g,I); g polynomial, I ideal

Return:
1 (TRUE) (type int) if g is contained in the radical of I

 0 (FALSE) (type int) otherwise

Example:
LIB "poly.lib";
ring R=0,(x,y,z),dp;
ideal I=x2+y2,z2;
poly f=x4+y4;
rad_con(f,I);
==> 0
ideal J=x2+y2,z2,x4+y4;
poly g=z;
rad_con(g,I);
==> 1

D.2.4.14 content
................
Procedure from library poly.lib (see poly_lib).

Usage:
content(f); f polynomial/vector

Return:
number, the content (greatest common factor of coefficients)
of the polynomial/vector f

Example:
LIB "poly.lib";
ring r=0,(x,y,z),(c,lp);
content(3x2+18xy-27xyz);
==> 3
vector v=[3x2+18xy-27xyz,15x2+12y4,3];
content(v);
==> 3

D.2.4.15 numerator
..................
Procedure from library poly.lib (see poly_lib).

Usage:
numerator(n); n number

Return:
number, the numerator of n

Example:
LIB "poly.lib";
ring r = 0,x, dp;
number n = 3/2;
numerator(n);
==> 3


D.2.4.16 denominator
....................
Procedure from library poly.lib (see poly_lib).

Usage:
denominator(n); n number

Return:
number, the denominator of n

Example:
LIB "poly.lib";
ring r = 0,x, dp;
number n = 3/2;
denominator(n);
==> 2


D.2.4.17 mod2id
...............
Procedure from library poly.lib (see poly_lib).

Usage:
mod2id(M,vpos); M matrix, vpos intvec

Assume:
vpos is an integer vector such that gen(i) corresponds
to var(vpos[i]).

The basering contains variables var(vpos[i]) which do not occur
in M.

Return:
ideal I in which each gen(i) from the module is replaced by
var(vpos[i]) and all monomials var(vpos[i])*var(vpos[j]) have
been added to the generating set of I.

Note:
This procedure should be used in the following situation:
one wants to pass to a ring with new variables, say e(1),..,e(s),
which correspond to the components gen(1),..,gen(s) of the
module M such that e(i)*e(j)=0 for all i,j.

The new ring should already exist and be the current ring

Example:
LIB "poly.lib";
ring r=0,(e(1),e(2),x,y,z),(dp(2),ds(3));
module mo=x*gen(1)+y*gen(2);
intvec iv=2,1;
mod2id(mo,iv);
==> _[1]=e(2)^2
==> _[2]=e(1)*e(2)
==> _[3]=e(1)^2
==> _[4]=e(1)*y+e(2)*x

D.2.4.18 id2mod
...............
Procedure from library poly.lib (see poly_lib).

Usage:
id2mod(I,vpos); I ideal, vpos intvec

Return:
module corresponding to the ideal by replacing var(vpos[i]) by
gen(i) and omitting all generators var(vpos[i])*var(vpos[j])

Note:
* This procedure only makes sense if the ideal contains
all var(vpos[i])*var(vpos[j]) as monomial generators and
all other generators of I are linear combinations of the
var(vpos[i]) over the ring in the other variables.

* This is the inverse procedure to mod2id and should be applied
only to ideals created by mod2id using the same intvec vpos
(possibly after a standard basis computation)

Example:
LIB "poly.lib";
ring r=0,(e(1),e(2),x,y,z),(dp(2),ds(3));
ideal i=e(2)^2,e(1)*e(2),e(1)^2,e(1)*y+e(2)*x;
intvec iv=2,1;
id2mod(i,iv);
==> _[1]=x*gen(1)+y*gen(2)

D.2.4.19 substitute
...................
Procedure from library poly.lib (see poly_lib).

Usage:
- case 1: typeof(#[1])==poly:

substitute (I,v,f[,v1,f1,v2,f2,...]); I object of basering which
can be mapped, v,v1,v2,.. ring variables, f,f1,f2,... poly

 - case 2: typeof(#[1])==ideal:
substitute1 (I,v,f); I object of basering which can be mapped,
v ideal of ring variables, f ideal

Return:
object of same type as I,

 - case 1: ring variable v,v1,v2,... substituted by polynomials
f,f1,f2,..., in this order

 - case 2: ring variables in v substituted by polynomials in f:
v[i] is substituted by f[i], i=1,...,i=min(size(v),ncols(f))

Note:
this procedure extends the built-in command subst which substitutes
ring variables only by monomials

Example:
LIB "poly.lib";
ring r = 0,(b,c,t),dp;
ideal I = -bc+4b2c2t,bc2t-5b2c;
substitute(I,c,b+c,t,0,b,b-1);
==> _[1]=-b2-bc+2b+c-1
==> _[2]=-5b3-5b2c+15b2+10bc-15b-5c+5
ideal v = c,t,b;
ideal f = b+c,0,b-1;
substitute(I,v,f);
==> _[1]=-b2-bc+2b+c-1
==> _[2]=-5b3-5b2c+15b2+10bc-15b-5c+5

D.2.4.20 subrInterred
.....................
Procedure from library poly.lib (see poly_lib).

Usage:
subrInterred(mon,sm,iv);

sm: ideal in a ring r with n + s variables,

e.g. x_1,..,x_n and t_1,..,t_s

mon: ideal with monomial generators (not divisible by
any of the t_i) such that sm is contained in the module
k[t_1,..,t_s]*mon[1]+..+k[t_1,..,t_s]*mon[size(mon)]

iv: intvec listing the variables which are supposed to be used
as x_i

Return:
list l:

l[1]=the monomials from mon in the order used

l[2]=their coefficients after interreduction

l[3]=l[1]*l[2]

Purpose:
Do interred only w.r.t. a subset of variables.

The procedure returns an interreduced system of generators of
sm considered as a k[t_1,..,t_s]-submodule of the free module
k[t_1,..,t_s]*mon[1]+..+k[t_1,..,t_s]*mon[size(mon)]).

Example:
LIB "poly.lib";
ring r=0,(x,y,z),dp;
ideal i=x^2+x*y^2,x*y+x^2*y,z;
ideal j=x^2+x*y^2,x*y,z;
ideal mon=x^2,z,x*y;
intvec iv=1,3;
subrInterred(mon,i,iv);
==> [1]:
==>    _[1,1]=z
==>    _[1,2]=xy
==>    _[1,3]=x2
==> [2]:
==>    _[1]=gen(1)
==>    _[2]=y2*gen(2)-gen(2)
==>    _[3]=y*gen(2)+gen(3)
==> [3]:
==>    _[1,1]=z
==>    _[1,2]=xy3-xy
==>    _[1,3]=xy2+x2
subrInterred(mon,j,iv);
==> [1]:
==>    _[1,1]=z
==>    _[1,2]=xy
==>    _[1,3]=x2
==> [2]:
==>    _[1]=gen(1)
==>    _[2]=gen(2)
==>    _[3]=gen(3)
==> [3]:
==>    _[1,1]=z
==>    _[1,2]=xy
==>    _[1,3]=x2

D.2.4.21 hilbPoly
.................
Procedure from library poly.lib (see poly_lib).

Usage:
hilbPoly(I) I a homogeneous ideal

Return:
the Hilbert polynomial of basering/I as an intvec v=v_0,...,v_r
such that the Hilbert polynomial is (v_0+v_1*t+...v_r*t^r)/r!

Example:
LIB "poly.lib";
ring r = 0,(b,c,t,h),dp;
ideal I=
bct-t2h+2th2+h3,
bt3-ct3-t4+b2th+c2th-2bt2h+2ct2h+2t3h-bch2-2bth2+2cth2+2th3,
b2c2+bt2h-ct2h-t3h+b2h2+2bch2+c2h2-2bth2+2cth2+t2h2-2bh3+2ch3+2th3+3h4,
c2t3+ct4-c3th-2c2t2h-2ct3h-t4h+bc2h2-2c2th2-bt2h2+4t3h2+2bth3-2cth3-t2h3
+bh4-6th4-2h5;
hilbPoly(I);
==> -11,10
D.2.5 random_lib
----------------
Library:
random.lib
Purpose:
    Creating Random and Sparse Matrices, Ideals, Polys


Procedures:
* genericid:: generic sparse linear combinations of generators of i
* randomid:: random linear combinations of generators of id
* randommat:: nxm matrix of random linear combinations of id
* sparseid:: ideal of k random sparse poly's of degree d [u<=d<=o]
* sparsematrix:: nxm sparse matrix of polynomials of degree<=o
* sparsemat:: nxm sparse integer matrix with random coefficients
* sparsepoly:: random sparse polynomial with terms of degree in [u,o]
* sparsetriag:: nxm sparse lower-triag intmat with random coefficients
* triagmatrix:: nxm sparse lower-triag matrix of poly's of degree<=o
* randomLast:: random transformation of the last variable
* randomBinomial:: binomial ideal, k random generators of degree >=u

D.2.5.1 genericid
.................
Procedure from library random.lib (see random_lib).

Usage:
genericid(id,[,p,b]); id ideal/module, k,p,b integers

Return:
system of generators of id which are generic, sparse, triagonal linear
combinations of given generators with coefficients in [1,b] and
sparseness p percent, bigger p being sparser (default: p=75, b=30000)

Note:
For performance reasons try small bound b in characteristic 0

Example:
LIB "random.lib";
ring r=0,(t,x,y,z),ds;
ideal i= x3+y4,z4+yx,t+x+y+z;
genericid(i,0,10);
==> _[1]=3t+3x+3y+3z+2xy+x3+y4+2z4
==> _[2]=4t+4x+4y+4z+xy+z4
==> _[3]=t+x+y+z
module m=[x,0,0,0],[0,y2,0,0],[0,0,z3,0],[0,0,0,t4];
print(genericid(m));
==> x,      0,      0, 0,
==> 17904y2,y2,     0, 0,
==> 0,      24170z3,z3,0,
==> 0,      0,      0, t4

D.2.5.2 randomid
................
Procedure from library random.lib (see random_lib).

Usage:
randomid(id,[k,b]); id ideal/module, b,k integers

Return:
ideal/module having k generators which are random linear combinations
of generators of id with coefficients in the interval [-b,b]
(default: b=30000, k=size(id))

Note:
For performance reasons try small bound b in characteristic 0

Example:
LIB "random.lib";
ring r=0,(x,y,z),dp;
randomid(maxideal(2),2,9);
==> _[1]=-5x2-9xy+6y2-8xz-8yz+4z2
==> _[2]=-9xy+2y2+xz+yz-z2
module m=[x,0,1],[0,y2,0],[y,0,z3];
show(randomid(m));
==> // module, 3 generator(s)
==> [1369x-11685y,-4481y2,-11685z3+1369]
==> [-642x-13756y,25342y2,-13756z3-642]
==> [2536x-6355y,8285y2,-6355z3+2536]

D.2.5.3 randommat
.................
Procedure from library random.lib (see random_lib).

Usage:
randommat(n,m[,id,b]); n,m,b integers, id ideal

Return:
nxm matrix, entries are random linear combinations of elements
of id and coefficients in [-b,b]

[default: (id,b) = (maxideal(1),30000)]

Note:
For performance reasons try small bound b in char 0

Example:
LIB "random.lib";
ring r=0,(x,y,z),dp;
matrix A=randommat(3,3,maxideal(2),9);
print(A);
==> 9x2-2xy-8y2-9xz+yz+4z2, 9x2-4xy+y2-5xz+6yz-z2,   8x2+xy-9y2+2yz-8z2,    
==> -x2+5xy-8y2-7xz+4yz-3z2,x2+xy-4y2-xz+5z2,        5x2-8xy+8y2+6xz+yz+7z2,
==> 4x2-5xy-6y2-4yz-5z2,    -4x2-6xy-4y2-8xz+3yz+5z2,2x2+3xy+y2+4xz-3yz+2z2 
A=randommat(2,3);
print(A);
==> 15276x+9897y+7526z,  6495x-24178y+11295z,-5745x-14754y+15979z,
==> 20788x-28366y-20283z,24911x-10978y+3341z,12412x+11216y+15344z 

D.2.5.4 sparseid
................
Procedure from library random.lib (see random_lib).

Usage:
sparseid(k,u[,o,p,b]); k,u,o,p,b integers

Return:
ideal having k generators, each of degree d, u<=d<=o, p percent of
terms in degree d are 0, the remaining have random coefficients
in the interval [1,b], (default: o=u=d, p=75, b=30000)

Example:
LIB "random.lib";
ring r = 0,(a,b,c,d),ds;
sparseid(2,3);"";
==> _[1]=12773a3+24263a2c+20030abc+17904b2c+26359c3
==> _[2]=24004a3+6204b2c+24170bc2+19505c2d+21962bd2
==> 
sparseid(3,0,4,90,9);
==> _[1]=1+4a2+8b2c+3c3+4a3b+4a2b2+5abc2+3ac3
==> _[2]=a+a2+7ab2+6a2c+3c3+5a3b+9ab3+2c4+3c3d+8ad3
==> _[3]=5a+ab+2ac2+2b3c+8abcd

D.2.5.5 sparsematrix
....................
Procedure from library random.lib (see random_lib).

Usage:
sparsematrix(n,m,o[,u,pe,pp,b]); n,m,o,u,pe,pp,b integers

Return:
nxm matrix, about pe percent of the entries are 0, the remaining
are random polynomials of degree d, u<=d<=o, with pp percent of
the terms being 0, the remaining have random coefficients
in the interval [1,b] [default: (pe,u,pp,b) = (0,50,75,100)]

Example:
LIB "random.lib";
ring r = 0,(a,b,c,d),dp;
// sparse matrix of sparse polys of degree <=2:
print(sparsematrix(3,4,2));"";
==> 14ab+20bc+79cd+30b,    32a2+97bc+5b,      0,             0,
==> 0,                     0,                 6c2+16b+64c+76,0,
==> 17a2+30ab+94bc+19b+45d,88a2+44bc+13d2+31a,59ac,          0 
==> 
// dense matrix of sparse linear forms:
print(sparsematrix(3,3,1,1,0,55,9));
==> 9b+7c+8d,9b+9d,5a,   
==> 7c+d,    a+6b, 2b+2d,
==> 9a+5b+9c,2a+9d,2d    

D.2.5.6 sparsemat
.................
Procedure from library random.lib (see random_lib).

Usage:
sparsemat(n,m[,p,b]); n,m,p,b integers

Return:
nxm integer matrix, p percent of the entries are 0, the remaining
are random coefficients >=1 and <= b; [defaults: (p,b) = (75,1)]

Example:
LIB "random.lib";
sparsemat(5,5);"";
==> 0,0,0,0,0,
==> 0,1,0,0,1,
==> 0,0,0,1,0,
==> 0,1,0,0,0,
==> 0,1,0,1,1 
==> 
sparsemat(5,5,95);"";
==> 1,0,0,0,0,
==> 0,0,0,0,0,
==> 0,0,0,0,0,
==> 0,0,0,0,0,
==> 0,0,0,1,0 
==> 
sparsemat(5,5,5);"";
==> 1,1,1,1,1,
==> 1,1,1,1,1,
==> 1,1,1,1,1,
==> 1,0,1,1,1,
==> 1,1,1,1,0 
==> 
sparsemat(5,5,50,100);
==> 0,17,24,80,0,
==> 0,13,30,45,0,
==> 19,0,0,0,0,
==> 93,0,23,0,69,
==> 0,88,44,31,0 

D.2.5.7 sparsepoly
..................
Procedure from library random.lib (see random_lib).

Usage:
sparsepoly(u[,o,p,b]); u,o,p,b integers

Return:
poly having only terms in degree d, u<=d<=o, p percent of the terms
in degree d are 0, the remaining have random coefficients in [1,b),
(defaults: o=u=d, p=75, b=30000)

Example:
LIB "random.lib";
ring r=0,(x,y,z),dp;
sparsepoly(5);"";
==> 24263xy4+24170x4z+21962x3yz+26642xy3z+5664xy2z2+17904xz4
==> 
sparsepoly(3,5,90,9);
==> 8x3z2+2y3z2+3xyz3+2xy3+yz3+xy2

D.2.5.8 sparsetriag
...................
Procedure from library random.lib (see random_lib).

Usage:
sparsetriag(n,m[,p,b]); n,m,p,b integers

Return:
nxm lower triagonal integer matrix, diagonal entries equal to 1, about
p percent of lower diagonal entries are 0, the remaining are random
integers >=1 and <= b; [defaults: (p,b) = (75,1)]

Example:
LIB "random.lib";
sparsetriag(5,7);"";
==> 1,0,0,0,0,0,0,
==> 0,1,0,0,0,0,0,
==> 0,1,1,0,0,0,0,
==> 0,0,0,1,0,0,0,
==> 1,1,0,0,1,0,0 
==> 
sparsetriag(7,5,90);"";
==> 1,0,0,0,0,
==> 0,1,0,0,0,
==> 0,1,1,0,0,
==> 0,0,0,1,0,
==> 0,0,0,0,1,
==> 0,0,0,1,0,
==> 0,1,0,0,0 
==> 
sparsetriag(5,5,0);"";
==> 1,0,0,0,0,
==> 1,1,0,0,0,
==> 1,1,1,0,0,
==> 1,1,1,1,0,
==> 1,1,1,1,1 
==> 
sparsetriag(5,5,50,100);
==> 1,0,0,0,0,
==> 73,1,0,0,0,
==> 0,79,1,0,0,
==> 14,0,0,1,0,
==> 0,48,23,0,1 

D.2.5.9 triagmatrix
...................
Procedure from library random.lib (see random_lib).

Usage:
triagmatrix(n,m,o[,u,pe,pp,b]); n,m,o,u,pe,pp,b integers

Return:
nxm lower triagonal matrix, diagonal entries equal to 1, about
p percent of lower diagonal entries are 0, the remaining
are random polynomials of degree d, u<=d<=o, with pp percent of
the terms being 0, the remaining have random coefficients
in the interval [1,b] [default: (pe,u,pp,b) = (0,50,75,100)]

Example:
LIB "random.lib";
ring r = 0,(a,b,c,d),dp;
// sparse triagonal matrix of sparse polys of degree <=2:
print(triagmatrix(3,4,2));"";
==> 1,                                 0,0,0,
==> 52ac+54cd+14c,                     1,0,0,
==> 17a2+19b2+45ac+94bc+50b+87c+54d+21,0,1,0 
==> 
// dense triagonal matrix of sparse linear forms:
print(triagmatrix(3,3,1,1,0,55,9));
==> 1,       0,    0,
==> 7a+8d,   1,    0,
==> 9b+7c+4d,7b+9d,1 

D.2.5.10 randomLast
...................
Procedure from library random.lib (see random_lib).

Usage:
randomLast(b); b int

Return:
ideal = maxideal(1), but the last variable is exchanged by a random
linear combination of all variables, with coefficients in the
interval [-b,b].

Example:
LIB "random.lib";
ring  r = 0,(x,y,z),lp;
ideal i = randomLast(10);
i;
==> i[1]=x
==> i[2]=y
==> i[3]=-x+z

D.2.5.11 randomBinomial
.......................
Procedure from library random.lib (see random_lib).

Usage:
randomBinomial(k,u[,o,b]); k,u,o,b integers

Return:
binomial ideal, k homogeneous generators of degree d, u<=d<=o, with
randomly chosen monomials and coefficients in the interval [-b,b]
(default: u=o, b=10).

Example:
LIB "random.lib";
ring  r = 0,(x,y,z),lp;
ideal i = randomBinomial(4,5,6);
i;
==> i[1]=-x4z-xz4
==> i[2]=8x2y3+8xy3z
==> i[3]=-4x2y2z2-4xy5
==> i[4]=5x3yz2+5xz5
D.2.6 ring_lib
--------------
Library:
ring.lib
Purpose:
      Manipulating Rings and Maps


Procedures:
* changechar:: make a copy R of basering [ring r] with new char c
* changeord:: make a copy R of basering [ring r] with new ord o
* changevar:: make a copy R of basering [ring r] with new vars v
* defring:: define a ring R in specified char c, n vars v, ord o
* defrings:: define ring Sn in n vars, char 32003 [p], ord ds
* defringp:: define ring Pn in n vars, char 32003 [p], ord dp
* extendring:: extend given ring by n vars v, ord o and name it R
* fetchall:: fetch all objects of ring R to basering
* imapall:: imap all objects of ring R to basering
* mapall:: map all objects of ring R via ideal i to basering
* ord_test:: test whether ordering of R is global, local or mixed
* ringtensor:: create ring R, tensor product of rings s,t,...
* ringweights:: intvec of weights of ring variables of ring r

D.2.6.1 changechar
..................
Procedure from library ring.lib (see ring_lib).

Usage:
changechar(newr,c[,r]); newr,c=strings, r=ring

Create:
create a new ring with name `newr` and make it the basering if r is
an existing ring [default: r=basering].

The new ring differs from the old ring only in the characteristic.
If, say, (newr,c) = ("R","0,A") and the ring r exists, the new
basering will have name R, characteristic 0 and one parameter A.

Return:
No return value

Note:
Works for qrings if map from old_char to new_char is implemented
This proc uses 'execute' or calls a procedure using 'execute'.
If you use it in your own proc, let the local names of your proc
start with @.

Example:
LIB "ring.lib";
ring r=0,(x,y,u,v),(dp(2),ds);
changechar("R","2,A"); R;"";
==> // basering is now R
==> //   characteristic : 2
==> //   1 parameter    : A 
==> //   minpoly        : 0
==> //   number of vars : 4
==> //        block   1 : ordering dp
==> //                  : names    x y 
==> //        block   2 : ordering ds
==> //                  : names    u v 
==> //        block   3 : ordering C
==> 
changechar("R1","32003",R); R1;
==> // basering is now R1
==> //   characteristic : 32003
==> //   number of vars : 4
==> //        block   1 : ordering dp
==> //                  : names    x y 
==> //        block   2 : ordering ds
==> //                  : names    u v 
==> //        block   3 : ordering C
kill R,R1;
if(system("with","Namespaces")) {
if( nameof(Current) == "Ring" ) {
kill Top::R,Top::R1;
} else {
kill Ring::R,Ring::R1;
}
}

D.2.6.2 changeord
.................
Procedure from library ring.lib (see ring_lib).

Usage:
changeord(newr,o[,r]); newr,o=strings, r=ring/qring

Create:
create a new ring with name `newr` and make it the basering if r is
an existing ring/qring [default: r=basering].

The new ring differs from the old ring only in the ordering. If, say,
(newr,o) = ("R","wp(2,3),dp") and the ring r exists and has >=3
variables, the new basering will have name R and ordering wp(2,3),dp.

Return:
No return value

Note:
This proc uses 'execute' or calls a procedure using 'execute'.
If you use it in your own proc, let the local names of your proc
start with @.

Example:
LIB "ring.lib";
ring r=0,(x,y,u,v),(dp(2),ds);
changeord("R","wp(2,3),dp"); R; "";
==> // basering is now R
==> //   characteristic : 0
==> //   number of vars : 4
==> //        block   1 : ordering wp
==> //                  : names    x y 
==> //                  : weights  2 3 
==> //        block   2 : ordering dp
==> //                  : names    u v 
==> //        block   3 : ordering C
==> 
ideal i = x^2,y^2-u^3,v;
qring Q = std(i);
changeord("Q'","lp",Q); Q';
==> // basering is now Q'
==> //   characteristic : 0
==> //   number of vars : 4
==> //        block   1 : ordering lp
==> //                  : names    x y u v 
==> //        block   2 : ordering C
==> // quotient ring from ideal
==> _[1]=v
==> _[2]=x2
==> _[3]=y2-u3
kill R,Q,Q';
if(system("with","Namespaces")) {
if( nameof(Current) == "Ring" ) {
kill Top::R,Top::Q';
} else {
kill Ring::R,Ring::Q';
}
}

D.2.6.3 changevar
.................
Procedure from library ring.lib (see ring_lib).

Usage:
changevar(newr,vars[,r]); newr,vars=strings, r=ring/qring

Create:
creates a new ring with name `newr` and makes it the basering if r
is an existing ring/qring [default: r=basering].

The new ring differs from the old ring only in the variables. If,
say, (newr,vars) = ("R","t()") and the ring r exists and has n
variables, the new basering will have name R and variables
t(1),...,t(n).

If vars = "a,b,c,d", the new ring will have the variables a,b,c,d.

Return:
No return value

Note:
This procedure is useful in connection with the procedure ringtensor,
when a conflict between variable names must be avoided.
This proc uses 'execute' or calls a procedure using 'execute'.
If you use it in your own proc, let the local names of your proc
start with @.

Example:
LIB "ring.lib";
ring r=0,(x,y,u,v),(dp(2),ds);
ideal i = x^2,y^2-u^3,v;
qring Q = std(i);
setring(r);
changevar("R","A()"); R; "";
==> // basering is now R
==> //   characteristic : 0
==> //   number of vars : 4
==> //        block   1 : ordering dp
==> //                  : names    A(1) A(2) 
==> //        block   2 : ordering ds
==> //                  : names    A(3) A(4) 
==> //        block   3 : ordering C
==> 
changevar("Q'","a,b,c,d",Q); Q';
==> // basering is now Q'
==> //   characteristic : 0
==> //   number of vars : 4
==> //        block   1 : ordering dp
==> //                  : names    a b 
==> //        block   2 : ordering ds
==> //                  : names    c d 
==> //        block   3 : ordering C
==> // quotient ring from ideal
==> _[1]=d
==> _[2]=a2
==> _[3]=b2-c3
kill R,Q,Q';
if(system("with","Namespaces")) {
if( nameof(Current) == "Ring" ) {
kill Top::R,Top::Q';
} else {
kill Ring::R,Ring::Q';
}
}

D.2.6.4 defring
...............
Procedure from library ring.lib (see ring_lib).

Usage:
defring(s1,s2,n,s3,s4); s1..s4=strings, n=integer

Create:
Define a ring with name 's1', characteristic 's2', ordering 's4' and
n variables with names derived from s3 and make it the basering.
If s3 is a single letter, say s3="a", and if n<=26 then a and the
following n-1 letters from the alphabet (cyclic order) are taken as
variables. If n>26 or if s3 is a single letter followed by (, say
s3="T(", the variables are T(1),...,T(n).

Return:
No return value

Note:
This proc is useful for defining a ring in a procedure.
This proc uses 'execute' or calls a procedure using 'execute'.
If you use it in your own proc, let the local names of your proc
start with @.

Example:
LIB "ring.lib";
defring("r","0",5,"u","ls"); r; "";
==> // basering is now: r
==> //   characteristic : 0
==> //   number of vars : 5
==> //        block   1 : ordering ls
==> //                  : names    u v w x y 
==> //        block   2 : ordering C
==> 
defring("R","2,A",10,"x(","dp(3),ws(1,2,3),ds"); R;
==> // basering is now: R
==> //   characteristic : 2
==> //   1 parameter    : A 
==> //   minpoly        : 0
==> //   number of vars : 10
==> //        block   1 : ordering dp
==> //                  : names    x(1) x(2) x(3) 
==> //        block   2 : ordering ws
==> //                  : names    x(4) x(5) x(6) 
==> //                  : weights     1    2    3 
==> //        block   3 : ordering ds
==> //                  : names    x(7) x(8) x(9) x(10) 
==> //        block   4 : ordering C
kill r,R;
if(system("with","Namespaces")) {
if( nameof(Current) == "Ring" ) {
kill Top::r,Top::R;
} else {
kill Ring::r,Ring::R;
}
}

D.2.6.5 defrings
................
Procedure from library ring.lib (see ring_lib).

Usage:
defrings(n,[p]); n,p integers

Create:
Defines a ring with name Sn, characteristic p, ordering ds and n
variables x,y,z,a,b,...if n<=26 (resp. x(1..n) if n>26) and makes it
the basering (default: p=32003)

Return:
No return value

Example:
LIB "ring.lib";
defrings(5,0); S5; "";
==> // basering is now: ring S5=0,(x,y,z,a,b),ds;
==> //   characteristic : 0
==> //   number of vars : 5
==> //        block   1 : ordering ds
==> //                  : names    x y z a b 
==> //        block   2 : ordering C
==> 
defrings(30); S30;
==> // basering is now: ring S30=32003,x(1..30),ds;
==> //   characteristic : 32003
==> //   number of vars : 30
==> //        block   1 : ordering ds
==> //                  : names    x(1) x(2) x(3) x(4) x(5) x(6) x(7) x(8) x(\
   9) x(10) x(11) x(12) x(13) x(14) x(15) x(16) x(17) x(18) x(19) x(20) x(21\
   ) x(22) x(23) x(24) x(25) x(26) x(27) x(28) x(29) x(30) 
==> //        block   2 : ordering C
kill S5, S30;
if(system("with","Namespaces")) {
if( nameof(Current) == "Ring" ) {
kill Top::S5,Top::S30;
} else {
kill Ring::S5,Ring::S30;
}
}

D.2.6.6 defringp
................
Procedure from library ring.lib (see ring_lib).

Usage:
defringp(n,[p]); n,p=integers

Create:
defines a ring with name Pn, characteristic p, ordering dp and n
variables x,y,z,a,b,...if n<=26 (resp. x(1..n) if n>26) and makes it
the basering (default: p=32003)

Return:
No return value

Example:
LIB "ring.lib";
defringp(5,0); P5; "";
==> // basering is now: ring P5=0,(x,y,z,a,b),dp;
==> //   characteristic : 0
==> //   number of vars : 5
==> //        block   1 : ordering dp
==> //                  : names    x y z a b 
==> //        block   2 : ordering C
==> 
defringp(30); P30;
==> // basering is now: ring P30=32003,x(1..30),dp;
==> //   characteristic : 32003
==> //   number of vars : 30
==> //        block   1 : ordering dp
==> //                  : names    x(1) x(2) x(3) x(4) x(5) x(6) x(7) x(8) x(\
   9) x(10) x(11) x(12) x(13) x(14) x(15) x(16) x(17) x(18) x(19) x(20) x(21\
   ) x(22) x(23) x(24) x(25) x(26) x(27) x(28) x(29) x(30) 
==> //        block   2 : ordering C
kill P5, P30;
if(system("with","Namespaces")) {
if( nameof(Current) == "Ring" ) {
kill Top::P5,Top::P30;
} else {
kill Ring::P5,Ring::P30;
}
}

D.2.6.7 extendring
..................
Procedure from library ring.lib (see ring_lib).

Usage:
extendring(na,n,va,o[iv,i,r]); na,va,o=strings,

n,i=integers, r=ring, iv=intvec of positive integers or iv=0

Create:
Define a ring with name `na` which extends the ring r by adding n new
variables in front of [after, if i!=0] the old variables and make it
the basering [default: (i,r)=(0,basering)].

 - The characteristic is the characteristic of r.

 - The new vars are derived from va. If va is a single letter, say
va="T", and if n<=26 then T and the following n-1 letters from
T..Z..T (resp. T(1..n) if n>26) are taken as additional variables.
If va is a single letter followed by (, say va="x(", the new
variables are x(1),...,x(n).

 - The ordering is the product ordering between the ordering of r and
an ordering derived from `o` [and iv].

 - If o contains a 'c' or a 'C' in front resp. at the end this is
taken for the whole ordering in front resp. at the end. If o does
not contain a 'c' or a 'C' the same rule applies to ordstr(r).

 - If no intvec iv is given, or if iv=0, o may be any allowed ordstr,
like "ds" or "dp(2),wp(1,2,3),Ds(2)" or "ds(a),dp(b),ls" if
a and b are globally (!) defined integers and if a+b+1<=n.
If, however, a and b are local to a proc calling extendring, the
intvec iv must be used to let extendring know the values of a and b

 - If an intvec iv !=0 is given, iv[1],iv[2],... is taken for the
1st, 2nd,... block of o, if o contains no substring "w" or "W"
i.e. no weighted ordering (in the above case o="ds,dp,ls"
and iv=a,b).

If o contains a weighted ordering (only one (!) weighted block is
allowed) iv[1] is taken as size for the weight-vector, the next
iv[1] values of iv are taken as weights and the remaining values of
iv as block-size for the remaining non-weighted blocks.
e.g. o="dp,ws,Dp,ds", iv=3,2,3,4,2,5 creates the ordering
dp(2),ws(2,3,4),Dp(5),ds

Return:
No return value

Note:
This proc is useful for adding deformation parameters.

This proc uses 'execute' or calls a procedure using 'execute'.
If you use it in your own proc, let the local names of your proc
start with @ (see the file HelpForProc)

Example:
LIB "ring.lib";
ring r=0,(x,y,z),ds;
show(r);"";
==> // ring: (0),(x,y,z),(ds(3),C);
==> // minpoly = 0
==> // objects belonging to this ring:
==> 
//blocksize is derived from no of vars:
int t=5;
extendring("R1",t,"a","dp");         //t global: "dp" -> "dp(5)"
==> // basering is now R1
show(R1); "";
==> // ring: (0),(a,b,c,d,e,x,y,z),(dp(5),ds(3),C);
==> // minpoly = 0
==> // objects belonging to this ring:
==> 
extendring("R2",4,"T(","c,dp",1,r);    //"dp" -> "c,..,dp(4)"
==> // basering is now R2
show(R2);"";
==> // ring: (0),(x,y,z,T(1),T(2),T(3),T(4)),(c,ds(3),dp(4));
==> // minpoly = 0
==> // objects belonging to this ring:
==> 
//no intvec given, blocksize given: given blocksize is used:
extendring("R3",4,"T(","dp(2)",0,r);   // "dp(2)" -> "dp(2)"
==> // basering is now R3
show(R3);"";
==> // ring: (0),(T(1),T(2),T(3),T(4),x,y,z),(dp(2),ds(5),C);
==> // minpoly = 0
==> // objects belonging to this ring:
==> 
//intvec given: weights and blocksize is derived from given intvec
//(no specification of a blocksize in the given ordstr is allowed!)
//if intvec does not cover all given blocks, the last block is used
//for the remaining variables, if intvec has too many components,
//the last ones are ignored
intvec v=3,2,3,4,1,3;
extendring("R4",10,"A","ds,ws,Dp,dp",v,0,r);
==> // basering is now R4
//v covers 3 blocks: v[1] (=3) : no of components of ws
//next v[1] values (=v[2..4]) give weights
//remaining components of v are used for the remaining blocks
show(R4);
==> // ring: (0),(A,B,C,D,E,F,G,H,I,J,x,y,z),(ds(1),ws(2,3,4),Dp(3),dp(3),ds(\
   3),C);
==> // minpoly = 0
==> // objects belonging to this ring:
kill r,R1,R2,R3,R4;
if(system("with","Namespaces")) {
if( nameof(Current) == "Ring" ) {
kill Top::R1,Top::R2,Top::R3,Top::R4;
} else {
kill Ring::R1,Ring::R2,Ring::R3,Ring::R4;
}
}

D.2.6.8 fetchall
................
Procedure from library ring.lib (see ring_lib).

Usage:
fetchall(R[,s]); R=ring/qring, s=string

Create:
fetch all objects of ring R (of type poly/ideal/vector/module/number/
matrix) into the basering.

If no 3rd argument is present, the names are the same as in R. If,
say, f is a poly in R and the 3rd argument is the string "R", then f
is mapped to f_R etc.

Return:
no return value

Note:
As fetch, this procedure maps the 1st, 2nd, ... variable of R to the
1st, 2nd, ... variable of the basering.

The 3rd argument is useful in order to avoid conflicts of names, the
empty string is allowed

Caution:
fetchall does not work inside a procedure.

It does not work if R contains a map.

Example:
LIB "ring.lib";
// The example is not shown since fetchall does not work in a procedure;
// (and hence not in the example procedure). Try the following commands:
//   ring R=0,(x,y,z),dp;
//   ideal j=x,y2,z2;
//   matrix M[2][3]=1,2,3,x,y,z;
//   j; print(M);
//   ring S=0,(a,b,c),ds;
//   fetchall(R);       //map from R to S: x->a, y->b, z->c;
//   names(S);
//   j; print(M);
//   fetchall(S,"1");   //identity map of S: copy objects, change names
//   names(S);
//   kill R,S;

D.2.6.9 imapall
...............
Procedure from library ring.lib (see ring_lib).

Usage:
imapall(R[,s]); R=ring/qring, s=string

Create:
map all objects of ring R (of type poly/ideal/vector/module/number/
matrix) into the basering, by applying imap to all objects of R.
If no 3rd argument is present, the names are the same as in R. If,
say, f is a poly in R and the 3rd argument is the string "R", then f
is mapped to f_R etc.

Return:
no return value

Note:
As imap, this procedure maps the variables of R to the variables with
the same name in the basering, the other variables are mapped to 0.
The 3rd argument is useful in order to avoid conflicts of names, the
empty string is allowed

Caution:
imapall does not work inside a procedure

It does not work if R contains a map

Example:
LIB "ring.lib";
// The example is not shown since imapall does not work in a procedure
// (and hence not in the example procedure). Try the following commands:
//   ring R=0,(x,y,z,u),dp;
//   ideal j=x,y,z,u2+ux+z;
//   matrix M[2][3]=1,2,3,x,y,uz;
//   j; print(M);
//   ring S=0,(a,b,c,x,z,y),ds;
//   imapall(R);         //map from R to S: x->x, y->y, z->z, u->0
//   names(S);
//   j; print(M);
//   imapall(S,"1");     //identity map of S: copy objects, change names
//   names(S);
//   kill R,S;

D.2.6.10 mapall
...............
Procedure from library ring.lib (see ring_lib).

Usage:
mapall(R,i[,s]); R=ring/qring, i=ideal of basering, s=string

Create:
map all objects of ring R (of type poly/ideal/vector/module/number/
matrix, map) into the basering, by mapping the j-th variable of R to
the j-th generator of the ideal i. If no 3rd argument is present, the
names are the same as in R. If, say, f is a poly in R and the 3rd
argument is the string "R", then f is mapped to f_R etc.

Return:
no return value.

Note:
This procedure has the same effect as defining a map, say psi, by
map psi=R,i; and then applying psi to all objects of R. In particular,
maps from R to some ring S are composed with psi, creating thus a map
from the basering to S.

mapall may be combined with copyring to change vars for all objects.
The 3rd argument is useful in order to avoid conflicts of names, the
empty string is allowed.

Caution:
mapall does not work inside a procedure.

Example:
LIB "ring.lib";
// The example is not shown since mapall does not work in a procedure
// (and hence not in the example procedure). Try the following commands:
//   ring R=0,(x,y,z),dp;
//   ideal j=x,y,z;
//   matrix M[2][3]=1,2,3,x,y,z;
//   map phi=R,x2,y2,z2;
//   ring S=0,(a,b,c),ds;
//   ideal i=c,a,b;
//   mapall(R,i);         //map from R to S: x->c, y->a, z->b
//   names(S);
//   j; print(M); phi;    //phi maps R to S: x->c2, y->a2, z->b2
//   ideal i1=a2,a+b,1;
//   mapall(R,i1,"");   //map from R to S: x->a2, y->a+b, z->1
//   names(S);
//   j_; print(M_); phi_;
//   changevar("T","x()",R);  //change vars in R and call result T
//   mapall(R,maxideal(1));       //identity map from R to T
//   names(T);
//   j; print(M); phi;
//   kill R,S,T;

D.2.6.11 ord_test
.................
Procedure from library ring.lib (see ring_lib).

Usage:
ord_test(r); r ring

Return:
int 1 (resp. -1, resp. 0) if ordering of r is global (resp. local,
resp. mixed)

Example:
LIB "ring.lib";
ring R = 0,(x,y),dp;
ring S = 0,(u,v),ls;
ord_test(R);
==> 1
ord_test(S);
==> -1
ord_test(R+S);
==> 0

D.2.6.12 ringtensor
...................
Procedure from library ring.lib (see ring_lib).

Usage:
ringtensor(s,r1,r2,...); s=string, r1,r2,...=rings

Create:
A new base ring with name `s` if r1,r2,... are existing rings.
If, say, s = "R" and the rings r1,r2,... exist, the new ring will
have name R, variables from all rings r1,r2,... and as monomial
ordering the block (product) ordering of r1,r2,... . Hence, R
is the tensor product of the rings r1,r2,... with ordering matrix
equal to the direct sum of the ordering matrices of r1,r2,...

Return:
no return value

Note:
The characteristic of the new ring will be that of r1. The names of
variables in the rings r1,r2,... should differ (if a name, say x,
occurs in r1 and r2, then, in the new ring r, x always refers to the
variable with name x in r1, there is no access to x in r2).
The procedure works also for quotient rings ri, if the characteristic
of ri is compatible with the characteristic of r1 (i.e. if imap from
ri to r1 is implemented)

This proc uses 'execute' or calls a procedure using 'execute'.
If you use it in your own proc, let the local names of your proc
start with @ (see the file HelpForProc)

Example:
LIB "ring.lib";
ring r=32003,(x,y,u,v),dp;
ring s=0,(a,b,c),wp(1,2,3);
ring t=0,x(1..5),(c,ls);
ringtensor("R",r,s,t);
==> // basering is now R
type R;
==> // R                    [0]  *ring
==> //   characteristic : 32003
==> //   number of vars : 12
==> //        block   1 : ordering dp
==> //                  : names    x y u v 
==> //        block   2 : ordering wp
==> //                  : names    a b c 
==> //                  : weights  1 2 3 
==> //        block   3 : ordering ls
==> //                  : names    x(1) x(2) x(3) x(4) x(5) 
==> //        block   4 : ordering C
setring s;
ideal i = a2+b3+c5;
changevar("S","x,y,z");       //change vars of sand make S the basering
==> // basering is now S
qring qS =std(fetch(s,i));    //create qring of S mod i (mapped to S)
changevar("T","d,e,f,g,h",t); //change vars of t and make T the basering
==> // basering is now T
qring qT=std(d2+e2-f3);       //create qring of T mod d2+e2-f3
ringtensor("Q",s,qS,t,qT);
==> // basering is now Q
type Q;
==> // Q                    [0]  *qring
==> //   characteristic : 0
==> //   number of vars : 16
==> //        block   1 : ordering wp
==> //                  : names    a b c 
==> //                  : weights  1 2 3 
==> //        block   2 : ordering wp
==> //                  : names    x y z 
==> //                  : weights  1 2 3 
==> //        block   3 : ordering ls
==> //                  : names    x(1) x(2) x(3) x(4) x(5) 
==> //        block   4 : ordering ls
==> //                  : names    d e f g h 
==> //        block   5 : ordering C
==> // quotient ring from ideal
==> _[1]=f3-e2-d2
==> _[2]=z5+y3+x2
kill R,Q,S,T;
if(system("with","Namespaces")) {
if( nameof(Current) == "Ring" ) {
kill Top::R,Top::Q,Top::S,Top::T;
} else {
kill Ring::R,Ring::Q,Ring::S,Ring::T;
}
}

D.2.6.13 ringweights
....................
Procedure from library ring.lib (see ring_lib).

Usage:
ringweights(P); P=name of an existing ring (true name, not a string)

Return:
intvec consisting of the weights of the variables of P, as they
appear when typing P;.

Note:
This is useful when enlarging P but keeping the weights of the old
variables.

Example:
LIB "ring.lib";
ring r0 = 0,(x,y,z),dp;
ringweights(r0);
==> 1,1,1
ring r1 = 0,x(1..5),(ds(3),wp(2,3));
ringweights(r1);"";
==> 1,1,1,2,3
==> 
// an example for enlarging the ring, keeping the first weights:
intvec v = ringweights(r1),6,2,3,4,5;
ring R = 0,x(1..10),(a(v),dp);
ordstr(R);
==> a(1,1,1,2,3,6,2,3,4,5),dp(10),C
D.3 Linear algebra
==================

* matrix_lib:: procedures for matrix operations
* linalg_lib:: procedures for algorithmic linear algebra

D.3.1 matrix_lib
----------------
Library:
matrix.lib
Purpose:
    Elementary Matrix Operations


Procedures:
* compress:: matrix, zero columns from A deleted
* concat:: matrix, concatenation of matrices A1,A2,...
* diag:: matrix, nxn diagonal matrix with entries poly p
* dsum:: matrix, direct sum of matrices A1,A2,...
* flatten:: ideal, generated by entries of matrix A
* genericmat:: generic nxm matrix [entries from id]
* is_complex:: 1 if list c is a complex, 0 if not
* outer:: matrix, outer product of matrices A and B
* power:: matrix/intmat, n-th power of matrix/intmat A
* skewmat:: generic skew-symmetric nxn matrix [entries from id]
* submat:: submatrix of A with rows/cols specified by intvec r/c
* symmat:: generic symmetric nxn matrix [entries from id]
* tensor:: matrix, tensor product of matrices A nd B
* unitmat:: unit square matrix of size n
* gauss_col:: transform a matrix into col-reduced Gauss normal form
* gauss_row:: transform a matrix into row-reduced Gauss normal form
* addcol:: add p*(c1-th col) to c2-th column of matrix A, p poly
* addrow:: add p*(r1-th row) to r2-th row of matrix A, p poly
* multcol:: multiply c-th column of A with poly p
* multrow:: multiply r-th row of A with poly p
* permcol:: permute i-th and j-th columns
* permrow:: permute i-th and j-th rows
* rowred:: reduction of matrix A with elementary row-operations
* colred:: reduction of matrix A with elementary col-operations
* rm_unitrow:: remove unit rows and associated columns of A
* rm_unitcol:: remove unit columns and associated rows of A
* headStand:: A[n-i+1,m-j+1]=headStand(A[i,j])

D.3.1.1 compress
................
Procedure from library matrix.lib (see matrix_lib).

Usage:
compress(A); A matrix/ideal/module/intmat/intvec

Return:
same type, zero columns/generators from A deleted

(if A=intvec, zero elements are deleted)

Example:
LIB "matrix.lib";
ring r=0,(x,y,z),ds;
matrix A[3][4]=1,0,3,0,x,0,z,0,x2,0,z2,0;
print(A);
==> 1, 0,3, 0,
==> x, 0,z, 0,
==> x2,0,z2,0 
print(compress(A));
==> 1, 3,
==> x, z,
==> x2,z2
module m=module(A); show(m);
==> // module, 4 generator(s)
==> [1,x,x2]
==> [0]
==> [3,z,z2]
==> [0]
show(compress(m));
==> // module, 2 generator(s)
==> [1,x,x2]
==> [3,z,z2]
intmat B[3][4]=1,0,3,0,4,0,5,0,6,0,7,0;
compress(B);
==> 1,3,
==> 4,5,
==> 6,7 
intvec C=0,0,1,2,0,3;
compress(C);
==> 1,2,3

D.3.1.2 concat
..............
Procedure from library matrix.lib (see matrix_lib).

Usage:
concat(A1,A2,..); A1,A2,... matrices

Return:
matrix, concatenation of A1,A2,.... Number of rows of result matrix
is max(nrows(A1),nrows(A2),...)

Example:
LIB "matrix.lib";
ring r=0,(x,y,z),ds;
matrix A[3][3]=1,2,3,x,y,z,x2,y2,z2;
matrix B[2][2]=1,0,2,0; matrix C[1][4]=4,5,x,y;
print(A);
==> 1, 2, 3,
==> x, y, z,
==> x2,y2,z2
print(B);
==> 1,0,
==> 2,0 
print(C);
==> 4,5,x,y
print(concat(A,B,C));
==> 1, 2, 3, 1,0,4,5,x,y,
==> x, y, z, 2,0,0,0,0,0,
==> x2,y2,z2,0,0,0,0,0,0 

D.3.1.3 diag
............
Procedure from library matrix.lib (see matrix_lib).

Usage:
diag(p,n); p poly, n integer

diag(A); A matrix

Return:
diag(p,n): diagonal matrix, p times unit matrix of size n.

 diag(A) : n*m x n*m diagonal matrix with entries all the entries of
the nxm matrix A, taken from the 1st row, 2nd row etc of A

Example:
LIB "matrix.lib";
ring r = 0,(x,y,z),ds;
print(diag(xy,4));
==> xy,0, 0, 0,
==> 0, xy,0, 0,
==> 0, 0, xy,0,
==> 0, 0, 0, xy
matrix A[3][2] = 1,2,3,4,5,6;
print(A);
==> 1,2,
==> 3,4,
==> 5,6 
print(diag(A));
==> 1,0,0,0,0,0,
==> 0,2,0,0,0,0,
==> 0,0,3,0,0,0,
==> 0,0,0,4,0,0,
==> 0,0,0,0,5,0,
==> 0,0,0,0,0,6 

D.3.1.4 dsum
............
Procedure from library matrix.lib (see matrix_lib).

Usage:
dsum(A1,A2,..); A1,A2,... matrices

Return:
matrix, direct sum of A1,A2,...

Example:
LIB "matrix.lib";
ring r = 0,(x,y,z),ds;
matrix A[3][3] = 1,2,3,4,5,6,7,8,9;
matrix B[2][2] = 1,x,y,z;
print(A);
==> 1,2,3,
==> 4,5,6,
==> 7,8,9 
print(B);
==> 1,x,
==> y,z 
print(dsum(A,B));
==> 1,2,3,0,0,
==> 4,5,6,0,0,
==> 7,8,9,0,0,
==> 0,0,0,1,x,
==> 0,0,0,y,z 

D.3.1.5 flatten
...............
Procedure from library matrix.lib (see matrix_lib).

Usage:
flatten(A); A matrix

Return:
ideal, generated by all entries from A

Example:
LIB "matrix.lib";
ring r = 0,(x,y,z),ds;
matrix A[2][3] = 1,2,x,y,z,7;
print(A);
==> 1,2,x,
==> y,z,7 
flatten(A);
==> _[1]=1
==> _[2]=2
==> _[3]=x
==> _[4]=y
==> _[5]=z
==> _[6]=7

D.3.1.6 genericmat
..................
Procedure from library matrix.lib (see matrix_lib).

Usage:
genericmat(n,m[,id]); n,m=integers, id=ideal

Return:
nxm matrix, with entries from id.

Note:
if id has less than nxm elements, the matrix is filled with 0's,
(default: id=maxideal(1)).

genericmat(n,m); creates the generic nxm matrix

Example:
LIB "matrix.lib";
ring R = 0,x(1..16),lp;
print(genericmat(3,3));      // the generic 3x3 matrix
==> x(1),x(2),x(3),
==> x(4),x(5),x(6),
==> x(7),x(8),x(9) 
ring R1 = 0,(a,b,c,d),dp;
matrix A = genericmat(3,4,maxideal(1)^3);
print(A);
==> a3, a2b,a2c,a2d,
==> ab2,abc,abd,ac2,
==> acd,ad2,b3, b2c 
int n,m = 3,2;
ideal i = ideal(randommat(1,n*m,maxideal(1),9));
print(genericmat(n,m,i));    // matrix of generic linear forms
==> 4a-8b-2c-3d,-a+b-4c+5d,
==> -8a-9b+c+7d,a-9b+9c+4d,
==> 6a-5b+9c,   2a+8c+d    

D.3.1.7 is_complex
..................
Procedure from library matrix.lib (see matrix_lib).

Usage:
is_complex(c); c = list of size-compatible modules or matrices

Return:
1 if c[i]*c[i+1]=0 for all i, 0 if not, hence checking whether the
list of matrices forms a complex.

Note:
Ideals are treated internally as 1-line matrices.

If printlevel > 0, the position where c is not a complex is shown.

Example:
LIB "matrix.lib";
ring r  = 32003,(x,y,z),ds;
ideal i = x4+y5+z6,xyz,yx2+xz2+zy7;
list L  = nres(i,0);
is_complex(L);
==> 1
L[4]    = matrix(i);
is_complex(L);
==> 0

D.3.1.8 outer
.............
Procedure from library matrix.lib (see matrix_lib).

Usage:
outer(A,B); A,B matrices

Return:
matrix, outer (tensor) product of A and B

Example:
LIB "matrix.lib";
ring r=32003,(x,y,z),ds;
matrix A[3][3]=1,2,3,4,5,6,7,8,9;
matrix B[2][2]=x,y,0,z;
print(A);
==> 1,2,3,
==> 4,5,6,
==> 7,8,9 
print(B);
==> x,y,
==> 0,z 
print(outer(A,B));
==> x, y, 2x,2y,3x,3y,
==> 0, z, 0, 2z,0, 3z,
==> 4x,4y,5x,5y,6x,6y,
==> 0, 4z,0, 5z,0, 6z,
==> 7x,7y,8x,8y,9x,9y,
==> 0, 7z,0, 8z,0, 9z 

D.3.1.9 power
.............
Procedure from library matrix.lib (see matrix_lib).

Usage:
power(A,n); A a square-matrix of type intmat or matrix, n=integer

Return:
intmat resp. matrix, the n-th power of A

Note:
for A=intmat and big n the result may be wrong because of int overflow

Example:
LIB "matrix.lib";
intmat A[3][3]=1,2,3,4,5,6,7,8,9;
print(power(A,3));"";
==>    468   576   684
==>   1062  1305  1548
==>   1656  2034  2412
==> 
ring r=0,(x,y,z),dp;
matrix B[3][3]=0,x,y,z,0,0,y,z,0;
print(power(B,3));"";
==> yz2,    xy2+x2z,y3+xyz,
==> y2z+xz2,yz2,    0,     
==> y3+xyz, y2z+xz2,yz2    
==> 

D.3.1.10 skewmat
................
Procedure from library matrix.lib (see matrix_lib).

Usage:
skewmat(n[,id]); n integer, id ideal

Return:
skew-symmetric nxn matrix, with entries from id

(default: id=maxideal(1))

skewmat(n); creates the generic skew-symmetric matrix

Note:
if id has less than n*(n-1)/2 elements, the matrix is

filled with 0's,

Example:
LIB "matrix.lib";
ring R=0,x(1..5),lp;
print(skewmat(4));    // the generic skew-symmetric matrix
==> 0,    x(1), x(2),x(3),
==> -x(1),0,    x(4),x(5),
==> -x(2),-x(4),0,   0,   
==> -x(3),-x(5),0,   0    
ring R1 = 0,(a,b,c),dp;
matrix A=skewmat(4,maxideal(1)^2);
print(A);
==> 0,  a2, ab, ac,
==> -a2,0,  b2, bc,
==> -ab,-b2,0,  c2,
==> -ac,-bc,-c2,0  
int n=3;
ideal i = ideal(randommat(1,n*(n-1) div 2,maxideal(1),9));
print(skewmat(n,i));  // skew matrix of generic linear forms
==> 0,       4a+b-8c, -a+6b+c,  
==> -4a-b+8c,0,       -8a+2b-9c,
==> a-6b-c,  8a-2b+9c,0         
kill R1;

D.3.1.11 submat
...............
Procedure from library matrix.lib (see matrix_lib).

Usage:
submat(A,r,c); A=matrix, r,c=intvec

Return:
matrix, submatrix of A with rows specified by intvec r
and columns specified by intvec c.

Example:
LIB "matrix.lib";
ring R=32003,(x,y,z),lp;
matrix A[4][4]=x,y,z,0,1,2,3,4,5,6,7,8,9,x2,y2,z2;
print(A);
==> x,y, z, 0,
==> 1,2, 3, 4,
==> 5,6, 7, 8,
==> 9,x2,y2,z2
intvec v=1,3,4;
matrix B=submat(A,v,1..3);
print(B);
==> x,y, z,
==> 5,6, 7,
==> 9,x2,y2

D.3.1.12 symmat
...............
Procedure from library matrix.lib (see matrix_lib).

Usage:
symmat(n[,id]); n integer, id ideal

Return:
symmetric nxn matrix, with entries from id (default: id=maxideal(1))

Note:
if id has less than n*(n+1)/2 elements, the matrix is filled with 0's,
symmat(n); creates the generic symmetric matrix

Example:
LIB "matrix.lib";
ring R=0,x(1..10),lp;
print(symmat(4));    // the generic symmetric matrix
==> x(1),x(2),x(3),x(4),
==> x(2),x(5),x(6),x(7),
==> x(3),x(6),x(8),x(9),
==> x(4),x(7),x(9),x(10)
ring R1 = 0,(a,b,c),dp;
matrix A=symmat(4,maxideal(1)^3);
print(A);
==> a3, a2b,a2c,ab2,
==> a2b,abc,ac2,b3, 
==> a2c,ac2,b2c,bc2,
==> ab2,b3, bc2,c3  
int n=3;
ideal i = ideal(randommat(1,n*(n+1) div 2,maxideal(1),9));
print(symmat(n,i));  // symmetric matrix of generic linear forms
==> 4a-8b-2c,-a+b-4c, -8a-9b+c,
==> -a+b-4c, a-9b+9c, 6a-5b+9c,
==> -8a-9b+c,6a-5b+9c,2a+8c    
kill R1;

D.3.1.13 tensor
...............
Procedure from library matrix.lib (see matrix_lib).

Usage:
tensor(A,B); A,B matrices

Return:
matrix, tensor product of A and B

Example:
LIB "matrix.lib";
ring r=32003,(x,y,z),(c,ds);
matrix A[3][3]=1,2,3,4,5,6,7,8,9;
matrix B[2][2]=x,y,0,z;
print(A);
==> 1,2,3,
==> 4,5,6,
==> 7,8,9 
print(B);
==> x,y,
==> 0,z 
print(tensor(A,B));
==> x, y, 2x,2y,3x,3y,
==> 0, z, 0, 2z,0, 3z,
==> 4x,4y,5x,5y,6x,6y,
==> 0, 4z,0, 5z,0, 6z,
==> 7x,7y,8x,8y,9x,9y,
==> 0, 7z,0, 8z,0, 9z 

D.3.1.14 unitmat
................
Procedure from library matrix.lib (see matrix_lib).

Usage:
unitmat(n); n integer >= 0

Return:
nxn unit matrix

Note:
needs a basering, diagonal entries are numbers (=1) in the basering

Example:
LIB "matrix.lib";
ring r=32003,(x,y,z),lp;
print(xyz*unitmat(4));
==> xyz,0,  0,  0, 
==> 0,  xyz,0,  0, 
==> 0,  0,  xyz,0, 
==> 0,  0,  0,  xyz
print(unitmat(5));
==> 1,0,0,0,0,
==> 0,1,0,0,0,
==> 0,0,1,0,0,
==> 0,0,0,1,0,
==> 0,0,0,0,1 

D.3.1.15 gauss_col
..................
Procedure from library matrix.lib (see matrix_lib).

Usage:
gauss_col(A[,e]); A a matrix, e any type

Return:
- a matrix B, if called with one argument; B is the complete column-
reduced upper-triangular normal form of A if A is constant,
(resp. as far as this is possible if A is a polynomial matrix;
no division by polynomials).

 - a list L of two matrices, if called with two arguments;
L satisfies L[1] = A * L[2] with L[1] the column-reduced form of A
and L[2] the transformation matrix.

Note:
* The procedure just applies interred to A with ordering (C,dp).
The transformation matrix is obtained by applying 'lift'.
This should be faster than the procedure colred.

 * It should only be used with exact coefficient field (there is no
pivoting and rounding error treatment).

 * Parameters are allowed. Hence, if the entries of A are parameters,
B is the column-reduced form of A over the rational function field.

Example:
LIB "matrix.lib";
ring r=(0,a,b),(A,B,C),dp;
matrix m[8][6]=
0,    2*C, 0,    0,  0,   0,
0,    -4*C,a*A,  0,  0,   0,
b*B,  -A,  0,    0,  0,   0,
-A,   B,   0,    0,  0,   0,
-4*C, 0,   B,    2,  0,   0,
2*A,  B,   0,    0,  0,   0,
0,    3*B, 0,    0,  2b,  0,
0,    AB,  0,    2*A,A,   2a;"";
==> 
list L=gauss_col(m,1);
print(L[1]);
==> 0,0,2*C, 0,       0,0,
==> A,0,-4*C,0,       0,0,
==> 0,0,-A,  (1/2b)*B,0,0,
==> 0,0,B,   -1/2*A,  0,0,
==> 0,1,0,   0,       0,0,
==> 0,0,B,   A,       0,0,
==> 0,0,0,   0,       1,0,
==> 0,0,0,   0,       0,1 
print(L[2]);
==> 0,         0,        0,               1/2,      0,         0,    
==> 0,         0,        1,               0,        0,         0,    
==> 1/(a),     0,        0,               0,        0,         0,    
==> -1/(2a)*B, 1/2,      0,               C,        0,         0,    
==> 0,         0,        -3/(2b)*B,       0,        1/(2b),    0,    
==> 1/(2a2)*AB,-1/(2a)*A,(-2b+3)/(4ab)*AB,-1/(a)*AC,-1/(4ab)*A,1/(2a)
ring S=0,x,(c,dp);
matrix A[5][4] =
3, 1, 1, 1,
13, 8, 6,-7,
14,10, 6,-7,
7, 4, 3,-3,
2, 1, 0, 3;
print(gauss_col(A));
==> 8/9,-5/9,-1/3,7/9,
==> 1,  0,   0,   0,  
==> 0,  1,   0,   0,  
==> 0,  0,   1,   0,  
==> 0,  0,   0,   1   


D.3.1.16 gauss_row
..................
Procedure from library matrix.lib (see matrix_lib).

Usage:
gauss_row(A [,e]); A matrix, e any type

Return:
- a matrix B, if called with one argument; B is the complete row-
reduced lower-triangular normal form of A if A is constant,
(resp. as far as this is possible if A is a polynomial matrix;
no division by polynomials).

 - a list L of two matrices, if called with two arguments;
L satisfies L[1] = L[2] * A with L[1] the row-reduced form of A
and L[2] the transformation matrix.

Note:
* This procedure just applies gauss_col to the transposed matrix.
The transformation matrix is obtained by applying lift.
This should be faster than the procedure rowred.

 * It should only be used with exact coefficient field (there is no
pivoting and rounding error treatment).

 * Parameters are allowed. Hence, if the entries of A are parameters,
B is the row-reduced form of A over the rational function field.

Example:
LIB "matrix.lib";
ring r=(0,a,b),(A,B,C),dp;
matrix m[6][8]=
0, 0,  b*B, -A,-4C,2A,0, 0,
2C,-4C,-A,B, 0,  B, 3B,AB,
0,a*A,  0, 0, B,  0, 0, 0,
0, 0,  0, 0, 2,  0, 0, 2A,
0, 0,  0, 0, 0,  0, 2b, A,
0, 0,  0, 0, 0,  0, 0, 2a;"";
==> 
print(gauss_row(m));"";
==> 0,  A,   0,       0,     0,0,0,0,
==> 0,  0,   0,       0,     1,0,0,0,
==> 2*C,-4*C,-A,      B,     0,B,0,0,
==> 0,  0,   (1/2b)*B,-1/2*A,0,A,0,0,
==> 0,  0,   0,       0,     0,0,1,0,
==> 0,  0,   0,       0,     0,0,0,1 
==> 
ring S=0,x,dp;
matrix A[4][5] =  3, 1,1,-1,2,
13, 8,6,-7,1,
14,10,6,-7,1,
7, 4,3,-3,3;
list L=gauss_row(A,1);
print(L[1]);
==> 1/2,-7/3,-19/6,5/6,
==> 1,  0,   0,    0,  
==> 0,  1,   0,    0,  
==> 0,  0,   1,    0,  
==> 0,  0,   0,    1   
print(L[2]);
==> 0,   -6,  -5,  1,   
==> -1/2,2/3, -1/6,-1/6,
==> 1/2, -5/3,-5/6,1/6, 
==> 0,   13/3,11/3,-1/3 


D.3.1.17 addcol
...............
Procedure from library matrix.lib (see matrix_lib).

Usage:
addcol(A,c1,p,c2); A matrix, p poly, c1, c2 positive integers

Return:
matrix, A being modified by adding p times column c1 to column c2

Example:
LIB "matrix.lib";
ring r=32003,(x,y,z),lp;
matrix A[3][3]=1,2,3,4,5,6,7,8,9;
print(A);
==> 1,2,3,
==> 4,5,6,
==> 7,8,9 
print(addcol(A,1,xy,2));
==> 1,xy+2, 3,
==> 4,4xy+5,6,
==> 7,7xy+8,9 

D.3.1.18 addrow
...............
Procedure from library matrix.lib (see matrix_lib).

Usage:
addcol(A,r1,p,r2); A matrix, p poly, r1, r2 positive integers

Return:
matrix, A being modified by adding p times row r1 to row r2

Example:
LIB "matrix.lib";
ring r=32003,(x,y,z),lp;
matrix A[3][3]=1,2,3,4,5,6,7,8,9;
print(A);
==> 1,2,3,
==> 4,5,6,
==> 7,8,9 
print(addrow(A,1,xy,3));
==> 1,   2,    3,   
==> 4,   5,    6,   
==> xy+7,2xy+8,3xy+9

D.3.1.19 multcol
................
Procedure from library matrix.lib (see matrix_lib).

Usage:
addcol(A,c,p); A matrix, p poly, c positive integer

Return:
matrix, A being modified by multiplying column c with p

Example:
LIB "matrix.lib";
ring r=32003,(x,y,z),lp;
matrix A[3][3]=1,2,3,4,5,6,7,8,9;
print(A);
==> 1,2,3,
==> 4,5,6,
==> 7,8,9 
print(multcol(A,2,xy));
==> 1,2xy,3,
==> 4,5xy,6,
==> 7,8xy,9 

D.3.1.20 multrow
................
Procedure from library matrix.lib (see matrix_lib).

Usage:
multrow(A,r,p); A matrix, p poly, r positive integer

Return:
matrix, A being modified by multiplying row r with p

Example:
LIB "matrix.lib";
ring r=32003,(x,y,z),lp;
matrix A[3][3]=1,2,3,4,5,6,7,8,9;
print(A);
==> 1,2,3,
==> 4,5,6,
==> 7,8,9 
print(multrow(A,2,xy));
==> 1,  2,  3,  
==> 4xy,5xy,6xy,
==> 7,  8,  9   

D.3.1.21 permcol
................
Procedure from library matrix.lib (see matrix_lib).

Usage:
permcol(A,c1,c2); A matrix, c1,c2 positive integers

Return:
matrix, A being modified by permuting column c1 and c2

Example:
LIB "matrix.lib";
ring r=32003,(x,y,z),lp;
matrix A[3][3]=1,x,3,4,y,6,7,z,9;
print(A);
==> 1,x,3,
==> 4,y,6,
==> 7,z,9 
print(permcol(A,2,3));
==> 1,3,x,
==> 4,6,y,
==> 7,9,z 

D.3.1.22 permrow
................
Procedure from library matrix.lib (see matrix_lib).

Usage:
permrow(A,r1,r2); A matrix, r1,r2 positive integers

Return:
matrix, A being modified by permuting row r1 and r2

Example:
LIB "matrix.lib";
ring r=32003,(x,y,z),lp;
matrix A[3][3]=1,2,3,x,y,z,7,8,9;
print(A);
==> 1,2,3,
==> x,y,z,
==> 7,8,9 
print(permrow(A,2,1));
==> x,y,z,
==> 1,2,3,
==> 7,8,9 

D.3.1.23 rowred
...............
Procedure from library matrix.lib (see matrix_lib).

Usage:
rowred(A[,e]); A matrix, e any type

Return:
- a matrix B, being the row reduced form of A, if rowred is called
with one argument.

(as far as this is possible over the polynomial ring; no division
by polynomials)

 - a list L of two matrices, such that L[1] = L[2] * A with L[1]
the row-reduced form of A and L[2] the transformation matrix
(if rowred is called with two arguments).

Note:
* This procedure is designed for teaching purposes mainly.

 * The straight forward Gaussian algorithm is implemented in the
library (no standard basis computation).

The transformation matrix is obtained by concatenating a unit
matrix to A. proc gauss_row should be faster.

 * It should only be used with exact coefficient field (there is no
pivoting) over the polynomial ring (ordering lp or dp).

 * Parameters are allowed. Hence, if the entries of A are parameters
the computation takes place over the field of rational functions.

Example:
LIB "matrix.lib";
ring r=(0,a,b),(A,B,C),dp;
matrix m[6][8]=
0, 0,  b*B, -A,-4C,2A,0, 0,
2C,-4C,-A,B, 0,  B, 3B,AB,
0,a*A,  0, 0, B,  0, 0, 0,
0, 0,  0, 0, 2,  0, 0, 2A,
0, 0,  0, 0, 0,  0, 2b, A,
0, 0,  0, 0, 0,  0, 0, 2a;"";
==> 
print(rowred(m));"";
==> 0,  0,    0,    0, 1,0,  0,0,
==> 0,  0,    0,    0, 0,0,  1,0,
==> 0,  0,    0,    0, 0,0,  0,1,
==> 0,  0,    (b)*B,-A,0,2*A,0,0,
==> 2*C,-4*C, -A,   B, 0,B,  0,0,
==> 0,  (a)*A,0,    0, 0,0,  0,0 
==> 
list L=rowred(m,1);
print(L[1]);
==> 0,  0,    0,    0, 1,0,  0,0,
==> 0,  0,    0,    0, 0,0,  1,0,
==> 0,  0,    0,    0, 0,0,  0,1,
==> 0,  0,    (b)*B,-A,0,2*A,0,0,
==> 2*C,-4*C, -A,   B, 0,B,  0,0,
==> 0,  (a)*A,0,    0, 0,0,  0,0 
print(L[2]);
==> 0,0,0,1/2,   0,        -1/(2a)*A,       
==> 0,0,0,0,     1/(2b),   -1/(4ab)*A,      
==> 0,0,0,0,     0,        1/(2a),          
==> 1,0,0,2*C,   0,        -2/(a)*AC,       
==> 0,1,0,0,     -3/(2b)*B,(-2b+3)/(4ab)*AB,
==> 0,0,1,-1/2*B,0,        1/(2a)*AB        


D.3.1.24 colred
...............
Procedure from library matrix.lib (see matrix_lib).

Usage:
colred(A[,e]); A matrix, e any type

Return:
- a matrix B, being the column reduced form of A, if colred is
called with one argument.

(as far as this is possible over the polynomial ring;
no division by polynomials)

 - a list L of two matrices, such that L[1] = A * L[2] with L[1]
the column-reduced form of A and L[2] the transformation matrix
(if colred is called with two arguments).

Note:
* This procedure is designed for teaching purposes mainly.

 * It applies rowred to the transposed matrix.
proc gauss_col should be faster.

 * It should only be used with exact coefficient field (there is no
pivoting) over the polynomial ring (ordering lp or dp).

 * Parameters are allowed. Hence, if the entries of A are parameters
the computation takes place over the field of rational functions.

Example:
LIB "matrix.lib";
ring r=(0,a,b),(A,B,C),dp;
matrix m[8][6]=
0,    2*C, 0,    0,  0,   0,
0,    -4*C,a*A,  0,  0,   0,
b*B,  -A,  0,    0,  0,   0,
-A,   B,   0,    0,  0,   0,
-4*C, 0,   B,    2,  0,   0,
2*A,  B,   0,    0,  0,   0,
0,    3*B, 0,    0,  2b,  0,
0,    AB,  0,    2*A,A,   2a;"";
==> 
print(colred(m));"";
==> 0,0,0,0,    2*C, 0,    
==> 0,0,0,0,    -4*C,(a)*A,
==> 0,0,0,(b)*B,-A,  0,    
==> 0,0,0,-A,   B,   0,    
==> 1,0,0,0,    0,   0,    
==> 0,0,0,2*A,  B,   0,    
==> 0,1,0,0,    0,   0,    
==> 0,0,1,0,    0,   0     
==> 
list L=colred(m,1);
print(L[1]);
==> 0,0,0,0,    2*C, 0,    
==> 0,0,0,0,    -4*C,(a)*A,
==> 0,0,0,(b)*B,-A,  0,    
==> 0,0,0,-A,   B,   0,    
==> 1,0,0,0,    0,   0,    
==> 0,0,0,2*A,  B,   0,    
==> 0,1,0,0,    0,   0,    
==> 0,0,1,0,    0,   0     
print(L[2]);
==> 0,        0,         0,     1,        0,               0,       
==> 0,        0,         0,     0,        1,               0,       
==> 0,        0,         0,     0,        0,               1,       
==> 1/2,      0,         0,     2*C,      0,               -1/2*B,  
==> 0,        1/(2b),    0,     0,        -3/(2b)*B,       0,       
==> -1/(2a)*A,-1/(4ab)*A,1/(2a),-2/(a)*AC,(-2b+3)/(4ab)*AB,1/(2a)*AB


D.3.1.25 rm_unitrow
...................
Procedure from library matrix.lib (see matrix_lib).

Usage:
rm_unitrow(A); A matrix (being col-reduced)

Return:
matrix, obtained from A by deleting unit rows (having just one 1
and else 0 as entries) and associated columns

Example:
LIB "matrix.lib";
ring r=0,(A,B,C),dp;
matrix m[8][6]=
0,0,  0,   0, 2C, 0,
0,0,  0,   0, -4C,A,
A,-C2,0,   B, -A, 0,
0,0,  1/2B,-A,B,  0,
1,0,  0,   0, 0,  0,
0,0,  0,   2A,B,  0,
0,1,  0,   0, 0,  0,
0,0,  1,   0, 0,  0;
print(rm_unitrow(m));
==> 0, 2C, 0,
==> 0, -4C,A,
==> B, -A, 0,
==> -A,B,  0,
==> 2A,B,  0 

D.3.1.26 rm_unitcol
...................
Procedure from library matrix.lib (see matrix_lib).

Usage:
rm_unitcol(A); A matrix (being row-reduced)

Return:
matrix, obtained from A by deleting unit columns (having just one 1
and else 0 as entries) and associated rows

Example:
LIB "matrix.lib";
ring r=0,(A,B,C),dp;
matrix m[6][8]=
0,  0,    A,   0, 1,0,  0,0,
0,  0,  -C2,   0, 0,0,  1,0,
0,  0,    0,1/2B, 0,0,  0,1,
0,  0,    B,  -A, 0,2A, 0,0,
2C,-4C,  -A,   B, 0,B,  0,0,
0,  A,    0,   0, 0,0,  0,0;
print(rm_unitcol(m));
==> 0, 0,  B, -A,2A,
==> 2C,-4C,-A,B, B, 
==> 0, A,  0, 0, 0  

D.3.1.27 headStand
..................
Procedure from library matrix.lib (see matrix_lib).

D.3.2 linalg_lib
----------------
Library:
linalg.lib
Purpose:
  Algorithmic Linear Algebra
Authors:
Ivor Saynisch (ivs@math.tu-cottbus.de)

 Mathias Schulze (mschulze@mathematik.uni-kl.de)


Procedures:
* inverse:: matrix, the inverse of A
* inverse_B:: list(matrix Inv,poly p),Inv*A=p*En ( using busadj(A) )
* inverse_L:: list(matrix Inv,poly p),Inv*A=p*En ( using lift )
* sym_gauss:: symmetric gaussian algorithm
* orthogonalize:: Gram-Schmidt orthogonalization
* diag_test:: test whether A can be diagonalized
* busadj:: coefficients of Adj(E*t-A) and coefficients of det(E*t-A)
* charpoly:: characteristic polynomial of A ( using busadj(A) )
* adjoint:: adjoint of A ( using busadj(A) )
* det_B:: determinant of A ( using busadj(A) )
* gaussred:: gaussian reduction: P*A=U*S, S a row reduced form of A
* gaussred_pivot:: gaussian reduction: P*A=U*S, uses row pivoting
* gauss_nf:: gaussian normal form of A
* mat_rk:: rank of constant matrix A
* U_D_O:: P*A=U*D*O, P,D,U,O=permutation,diag,lower-,upper-triang
* pos_def:: test symmetric matrix for positive definiteness
* hessenberg:: Hessenberg form of M
* evnf:: eigenvalues normal form of (e[,m])
* eigenvals:: eigenvalues with multiplicities of M
* minipoly:: minimal polynomial of M
* jordan:: Jordan data of M
* jordanbasis:: Jordan basis and weight filtration of M
* jordanmatrix:: Jordan matrix with Jordan data (e,s,m)
* jordannf:: Jordan normal form of M

D.3.2.1 inverse
...............
Procedure from library linalg.lib (see linalg_lib).

Usage:
inverse(A [,opt]); A a square matrix, opt integer

Return:
          a matrix:
          - the inverse matrix of A, if A is invertible;
          - the 1x1 0-matrix if A is not invertible (in the polynomial ring!).
          There are the following options:
          - opt=0 or not given: heuristically best option from below
          - opt=1 : apply std to (transpose(E,A)), ordering (C,dp).
          - opt=2 : apply interred (transpose(E,A)), ordering (C,dp).
          - opt=3 : apply lift(A,E), ordering (C,dp).

Note:
parameters and minpoly are allowed; opt=2 is only correct for
matrices with entries in a field

Example:
LIB "linalg.lib";
ring r=0,(x,y,z),lp;
matrix A[3][3]=
1,4,3,
1,5,7,
0,4,17;
print(inverse(A));"";
matrix B[3][3]=
y+1,  x+y,    y,
z,    z+1,    z,
y+z+2,x+y+z+2,y+z+1;
print(inverse(B));
print(B*inverse(B));


D.3.2.2 inverse_B
.................
Procedure from library linalg.lib (see linalg_lib).

Usage:
inverse_B(A); A = square matrix

Return:
list Inv with

- Inv[1] = matrix I and

- Inv[2] = poly p

such that I*A = unitmat(n)*p;

Note:
p=1 if 1/det(A) is computable and p=det(A) if not;

the computation uses busadj.

Example:
LIB "linalg.lib";
ring r=0,(x,y),lp;
matrix A[3][3]=x,y,1,1,x2,y,x,6,0;
print(A);
list Inv=inverse_B(A);
print(Inv[1]);
print(Inv[2]);
print(Inv[1]*A);


D.3.2.3 inverse_L
.................
Procedure from library linalg.lib (see linalg_lib).

Usage:
inverse_L(A); A = square matrix

Return:
list Inv representing a left inverse of A, i.e

- Inv[1] = matrix I and

- Inv[2] = poly p

such that I*A = unitmat(n)*p;

Note:
p=1 if 1/det(A) is computable and p=det(A) if not;

the computation computes first det(A) and then uses lift

Example:
LIB "linalg.lib";
ring r=0,(x,y),lp;
matrix A[3][3]=x,y,1,1,x2,y,x,6,0;
print(A);
list Inv=inverse_L(A);
print(Inv[1]);
print(Inv[2]);
print(Inv[1]*A);


D.3.2.4 sym_gauss
.................
Procedure from library linalg.lib (see linalg_lib).

Usage:
sym_gauss(A); A = symmetric matrix

Return:
matrix, diagonalisation with symmetric gauss algorithm

Example:
LIB "linalg.lib";
ring r=0,(x),lp;
matrix A[2][2]=1,4,4,15;
print(A);
print(sym_gauss(A));

D.3.2.5 orthogonalize
.....................
Procedure from library linalg.lib (see linalg_lib).

Usage:
orthogonalize(A); A = constant matrix

Return:
matrix, orthogonal basis of the column space of A

Example:
LIB "linalg.lib";
ring r=0,(x),lp;
matrix A[4][4]=5,6,12,4,7,3,2,6,12,1,1,2,6,4,2,10;
print(A);
print(orthogonalize(A));

D.3.2.6 diag_test
.................
Procedure from library linalg.lib (see linalg_lib).

Usage:
diag_test(A); A = const square matrix

Return:
int, 1 if A is diagonalisable, 0 if not

-1 no statement is possible, since A does not split.

Note:
The test works only for split matrices, i.e if eigenvalues of A
are in the ground field.

Does not work with parameters (uses factorize,gcd).

Example:
LIB "linalg.lib";
ring r=0,(x),dp;
matrix A[4][4]=6,0,0,0,0,0,6,0,0,6,0,0,0,0,0,6;
print(A);
diag_test(A);

D.3.2.7 busadj
..............
Procedure from library linalg.lib (see linalg_lib).

Usage:
busadj(A); A = square matrix (of size nxn)

Return:
list L:
         L[1] contains the (n+1) coefficients of the characteristic
              polynomial X of A, i.e.
              X = L[1][1]+..+L[1][k]*t^(k-1)+..+(L[1][n+1])*t^n
         L[2] contains the n (nxn)-matrices Hk which are the coefficients of
              the busadjoint bA = adjoint(E*t-A) of A, i.e.
              bA = (Hn-1)*t^(n-1)+...+Hk*t^k+...+H0,  ( Hk=L[2][k+1] )

Example:
LIB "linalg.lib";
ring r = 0,(t,x),lp;
matrix A[2][2] = 1,x2,x,x2+3x;
print(A);
list L = busadj(A);
poly X = L[1][1]+L[1][2]*t+L[1][3]*t2; X;
matrix bA[2][2] = L[2][1]+L[2][2]*t;
print(bA);               //the busadjoint of A;
print(bA*(t*unitmat(2)-A));

D.3.2.8 charpoly
................
Procedure from library linalg.lib (see linalg_lib).

Usage:
charpoly(A[,v]); A square matrix, v string, name of a variable

Return:
poly, the characteristic polynomial det(E*v-A)

(default: v=name of last variable)

Note:
A must be independent of the variable v. The computation uses det.
If printlevel>0, det(E*v-A) is diplayed recursively.

Example:
LIB "linalg.lib";
ring r=0,(x,t),dp;
matrix A[3][3]=1,x2,x,x2,6,4,x,4,1;
print(A);
charpoly(A,"t");

D.3.2.9 adjoint
...............
Procedure from library linalg.lib (see linalg_lib).

Usage:
adjoint(A); A = square matrix

Return:
adjoint matrix of A, i.e. Adj*A=det(A)*E

Note:
computation uses busadj(A)

Example:
LIB "linalg.lib";
ring r=0,(t,x),lp;
matrix A[2][2]=1,x2,x,x2+3x;
print(A);
matrix Adj[2][2]=adjoint(A);
print(Adj);                    //Adj*A=det(A)*E
print(Adj*A);

D.3.2.10 det_B
..............
Procedure from library linalg.lib (see linalg_lib).

Usage:
det_B(A); A any matrix

Return:
returns the determinant of A

Note:
the computation uses the busadj algorithm

Example:
LIB "linalg.lib";
ring r=0,(x),dp;
matrix A[10][10]=random(2,10,10)+unitmat(10)*x;
print(A);
det_B(A);

D.3.2.11 gaussred
.................
Procedure from library linalg.lib (see linalg_lib).

Usage:
gaussred(A); A any constant matrix

Return:
list Z: Z[1]=P , Z[2]=U , Z[3]=S , Z[4]=rank(A)

gives a row reduced matrix S, a permutation matrix P and a
normalized lower triangular matrix U, with P*A=U*S

Note:
This procedure is designed for teaching purposes mainly.
The straight forward implementation in the interpreted library
is not very efficient (no standard basis computation).

Example:
LIB "linalg.lib";
ring r=0,(x),dp;
matrix A[5][4]=1,3,-1,4,2,5,-1,3,1,3,-1,4,0,4,-3,1,-3,1,-5,-2;
print(A);
list Z=gaussred(A);   //construct P,U,S s.t. P*A=U*S
print(Z[1]);          //P
print(Z[2]);          //U
print(Z[3]);          //S
print(Z[4]);          //rank
print(Z[1]*A);        //P*A
print(Z[2]*Z[3]);     //U*S

D.3.2.12 gaussred_pivot
.......................
Procedure from library linalg.lib (see linalg_lib).

Usage:
gaussred_pivot(A); A any constant matrix

Return:
list Z: Z[1]=P , Z[2]=U , Z[3]=S , Z[4]=rank(A)

gives n row reduced matrix S, a permutation matrix P and a
normalized lower triangular matrix U, with P*A=U*S

Note:
with row pivoting

Example:
LIB "linalg.lib";
ring r=0,(x),dp;
matrix A[5][4] = 1, 3,-1,4,
2, 5,-1,3,
1, 3,-1,4,
0, 4,-3,1,
-3,1,-5,-2;
list Z=gaussred_pivot(A);  //construct P,U,S s.t. P*A=U*S
print(Z[1]);               //P
print(Z[2]);               //U
print(Z[3]);               //S
print(Z[4]);               //rank
print(Z[1]*A);             //P*A
print(Z[2]*Z[3]);          //U*S

D.3.2.13 gauss_nf
.................
Procedure from library linalg.lib (see linalg_lib).

Usage:
gauss_nf(A); A any constant matrix

Return:
matrix; gauss normal form of A (uses gaussred)

Example:
LIB "linalg.lib";
ring r = 0,(x),dp;
matrix A[4][4] = 1,4,4,7,2,5,5,4,4,1,1,3,0,2,2,7;
print(gauss_nf(A));

D.3.2.14 mat_rk
...............
Procedure from library linalg.lib (see linalg_lib).

Usage:
mat_rk(A); A any constant matrix

Return:
int, rank of A

Example:
LIB "linalg.lib";
ring r = 0,(x),dp;
matrix A[4][4] = 1,4,4,7,2,5,5,4,4,1,1,3,0,2,2,7;
mat_rk(A);

D.3.2.15 U_D_O
..............
Procedure from library linalg.lib (see linalg_lib).

Usage:
U_D_O(A); constant invertible matrix A

Return:
list Z: Z[1]=P , Z[2]=U , Z[3]=D , Z[4]=O

gives a permutation matrix P,

a normalized lower triangular matrix U ,

a diagonal matrix D, and

a normalized upper triangular matrix O

with P*A=U*D*O

Note:
Z[1]=-1 means that A is not regular (proc uses gaussred)

Example:
LIB "linalg.lib";
ring r = 0,(x),dp;
matrix A[5][5] = 10, 4,  0, -9,  8,
-3, 6, -6, -4,  9,
0, 3, -1, -9, -8,
-4,-2, -6, -10,10,
-9, 5, -1, -6,  5;
list Z = U_D_O(A);              //construct P,U,D,O s.t. P*A=U*D*O
print(Z[1]);                    //P
print(Z[2]);                    //U
print(Z[3]);                    //D
print(Z[4]);                    //O
print(Z[1]*A);                  //P*A
print(Z[2]*Z[3]*Z[4]);          //U*D*O

D.3.2.16 pos_def
................
Procedure from library linalg.lib (see linalg_lib).

Usage:
pos_def(A); A = constant, symmetric square matrix

Return:
int:

1 if A is positive definit ,

0 if not,

-1 if unknown

Example:
LIB "linalg.lib";
ring r = 0,(x),dp;
matrix A[5][5] = 20,  4,  0, -9,   8,
4, 12, -6, -4,   9,
0, -6, -2, -9,  -8,
-9, -4, -9, -20, 10,
8,  9, -8,  10, 10;
pos_def(A);
matrix B[3][3] =  3,  2,  0,
2, 12,  4,
0,  4,  2;
pos_def(B);

D.3.2.17 hessenberg
...................
Procedure from library linalg.lib (see linalg_lib).

Usage:
hessenberg(M); matrix M

Assume:
M constant square matrix

Return:
matrix H; Hessenberg form of M

Example:
LIB "linalg.lib";
ring R=0,x,dp;
matrix M[3][3]=3,2,1,0,2,1,0,0,3;
print(M);
print(hessenberg(M));

D.3.2.18 evnf
.............
Procedure from library linalg.lib (see linalg_lib).

Usage:
evnf(e[,m]); ideal e, intvec m

Assume:
ncols(e)==size(m)

Return:
order eigenvalues e with multiplicities m


D.3.2.19 eigenvals
..................
Procedure from library linalg.lib (see linalg_lib).

Usage:
eigenvals(M); matrix M

Assume:
eigenvalues of M in basefield

Return:
list l; 
  ideal l[1];
    number l[1][i];  i-th eigenvalue of M
  intvec l[2]; 
    int l[2][i];  multiplicity of i-th eigenvalue of M

Example:
LIB "linalg.lib";
ring R=0,x,dp;
matrix M[3][3]=3,2,1,0,2,1,0,0,3;
print(M);
eigenvals(M);

D.3.2.20 minipoly
.................
Procedure from library linalg.lib (see linalg_lib).

Usage:
minpoly(M); matrix M

Assume:
eigenvalues of M in basefield

Return:
list l;  minimal polynomial of M
  ideal l[1]; 
    number l[1][i];  i-th root of minimal polynomial of M
  intvec l[2]; 
    int l[2][i];  multiplicity of i-th root of minimal polynomial of M

Example:
LIB "linalg.lib";
ring R=0,x,dp;
matrix M[3][3]=3,2,1,0,2,1,0,0,3;
print(M);
minipoly(M);

D.3.2.21 jordan
...............
Procedure from library linalg.lib (see linalg_lib).

Usage:
jordan(M); matrix M

Assume:
eigenvalues of M in basefield

Return:
list l;  Jordan data of M
  ideal l[1]; 
    number l[1][i];  eigenvalue of i-th Jordan block of M
  intvec l[2]; 
    int l[2][i];  size of i-th Jordan block of M
  intvec l[3]; 
    int l[3][i];  multiplicity of i-th Jordan block of M

Example:
LIB "linalg.lib";
ring R=0,x,dp;
matrix M[3][3]=3,2,1,0,2,1,0,0,3;
print(M);
jordan(M);

D.3.2.22 jordanbasis
....................
Procedure from library linalg.lib (see linalg_lib).

Usage:
jordanbasis(M); matrix M

Assume:
eigenvalues of M in basefield

Return:
list l:
  module l[1];  inverse(l[1])*M*l[1] in Jordan normal form
  intvec l[2]; 
    int l[2][i];  weight filtration index of l[1][i]

Example:
LIB "linalg.lib";
ring R=0,x,dp;
matrix M[3][3]=3,2,1,0,2,1,0,0,3;
print(M);
list l=jordanbasis(M);
print(l[1]);
print(l[2]);
print(inverse(l[1])*M*l[1]);

D.3.2.23 jordanmatrix
.....................
Procedure from library linalg.lib (see linalg_lib).

Usage:
jordanmatrix(e,s,m); ideal e, intvec s, intvec m

Assume:
ncols(e)==size(s)==size(m)

Return:
matrix J;  Jordan matrix with list(e,s,m)==jordan(J)

Example:
LIB "linalg.lib";
ring R=0,x,dp;
ideal e=ideal(2,3);
intvec s=1,2;
intvec m=1,1;
print(jordanmatrix(e,s,m));

D.3.2.24 jordannf
.................
Procedure from library linalg.lib (see linalg_lib).

Usage:
jordannf(M); matrix M

Assume:
eigenvalues of M in basefield

Return:
matrix J; Jordan normal form of M

Example:
LIB "linalg.lib";
ring R=0,x,dp;
matrix M[3][3]=3,2,1,0,2,1,0,0,3;
print(M);
print(jordannf(M));
D.4 Commutative algebra
=======================

* algebra_lib:: procedures for computing with algebras and maps
* elim_lib:: procedures for elimination, saturation and blowing up
* homolog_lib:: procedures for homological algebra
* mprimdec_lib:: procedures for primary decomposition of modules
* mregular_lib:: procedures for Castelnuovo-Mumford regularity
* normal_lib:: procedure for normalization
* primdec_lib:: procedures for primary decomposition
* primitiv_lib:: procedures for finding a primitive element
* reesclos_lib:: Rees Algebra and integral closure of an ideal
* intprog_lib:: Integer Programming
* toric_lib:: toric ideals

D.4.1 algebra_lib
-----------------
Library:
algebra.lib
Purpose:
   Compute with Algebras and Algebra Maps
Authors:
Gert-Martin Greuel, greuel@mathematik.uni-kl.de,

 Agnes Eileen Heydtmann, agnes@math.uni-sb.de,

 Gerhard Pfister, pfister@mathematik.uni-kl.de


Procedures:
* algebra_containment:: query of algebra containment
* module_containment:: query of module containment over a subalgebra
* inSubring:: test whether poly p is in subring generated by I
* algDependent:: computes algebraic relations between generators of I
* alg_kernel:: computes the kernel of the ring map phi
* is_injective:: test for injectivity of ring map phi
* is_surjective:: test for surjectivity of ring map phi
* is_bijective:: test for bijectivity of ring map phi
* noetherNormal:: noether normalization of ideal id
* mapIsFinite:: query for finiteness of map phi:R -> basering/I
* finitenessTest:: find variables which occur as pure power in lead(i)

D.4.1.1 algebra_containment
...........................
Procedure from library algebra.lib (see algebra_lib).

Usage:
algebra_containment(p,A[,k]); p poly, A ideal, k integer.

 A = A[1],...,A[m] generators of subalgebra of the basering

Return:
         - k=0 (or if k is not given) an integer:
           1  : if p is contained in the subalgebra K[A[1],...,A[m]]
           0  : if p is not contained in K[A[1],...,A[m]]
         - k=1 : a list, say l, of size 2, l[1] integer, l[2] ring, satisfying
           l[1]=1 if p is in the subalgebra K[A[1],...,A[m]] and then the ring
           l[2] contains poly check = h(y(1),...,y(m)) if p=h(A[1],...,A[m])
           l[1]=0 if p is in not the subalgebra K[A[1],...,A[m]] and then
           l[2] contains the poly check = h(x,y(1),...,y(m)) if p satisfies
           the nonlinear relation p = h(x,A[1],...,A[m]) where
           x = x(1),...,x(n) denote the variables of the basering

Display:
if k=0 and printlevel >= voice+1 (default) display the poly check

Note:
The proc inSubring uses a different algorithm which is sometimes
faster.

Theory:
The ideal of algebraic relations of the algebra generators A[1],...,
A[m] is computed introducing new variables y(i) and the product
order with x(i) >> y(i).

p reduces to a polynomial only in the y(i) <=> p is contained in the
subring generated by the polynomials A[1],...,A[m].

Example:
LIB "algebra.lib";
int p = printlevel; printlevel = 1;
ring R = 0,(x,y,z),dp;
ideal A=x2+y2,z2,x4+y4,1,x2z-1y2z,xyz,x3y-1xy3;
poly p1=z;
poly p2=
x10z3-x8y2z3+2x6y4z3-2x4y6z3+x2y8z3-y10z3+x6z4+3x4y2z4+3x2y4z4+y6z4;
algebra_containment(p1,A);
==> // x(3)
==> 0
algebra_containment(p2,A);
==> // y(1)*y(2)*y(5)^2+y(3)*y(5)^3+4*y(1)*y(2)*y(6)^2+4*y(6)^3*y(7)+2*y(2)*y\
   (5)*y(7)^2
==> 1
list L = algebra_containment(p2,A,1);
==> 
==> // 'algebra_containment' created a ring as 2nd element of the list.
==> // The ring contains the poly check which defines the algebraic relation.
==> // To access to the ring and see check you must give the ring a name,
==> // e.g.:
==>                def S = l[2]; setring S; check;
==> 	
L[1];
==> 1
def S = L[2]; setring S;
check;
==> y(1)*y(2)*y(5)^2+y(3)*y(5)^3+4*y(1)*y(2)*y(6)^2+4*y(6)^3*y(7)+2*y(2)*y(5)\
   *y(7)^2
printlevel = p;

D.4.1.2 module_containment
..........................
Procedure from library algebra.lib (see algebra_lib).

Usage:
module_containment(p,P,M[,k]); p poly, P ideal, M ideal, k int

 P = P[1],...,P[n] generators of a subalgebra of the basering,

 M = M[1],...,M[m] generators of a module over the subalgebra K[P]

Assume:
ncols(P) = nvars(basering), the P[i] are algebraically independent

Return:
         - k=0 (or if k is not given), an integer:
           1    : if p is contained in the module <M[1],...,M[m]> over K[P]
           0    : if p is not contained in <M[1],...,M[m]>
         - k=1, a list, say l, of size 2, l[1] integer, l[2] ring:
           l[1]=1 : if p is in <M[1],...,M[m]> and then the ring l[2] contains
             the polynomial check = h(y(1),...,y(m),z(1),...,z(n)) if
             p = h(M[1],...,M[m],P[1],...,P[n])
           l[1]=0 : if p is in not in <M[1],...,M[m]>, then l[2] contains the
             poly check = h(x,y(1),...,y(m),z(1),...,z(n)) if p satisfies
             the nonlinear relation p = h(x,M[1],...,M[m],P[1],...,P[n]) where
             x = x(1),...,x(n) denote the variables of the basering

Display:
the polynomial h(y(1),...,y(m),z(1),...,z(n)) if k=0, resp.
a comment how to access the relation check if k=1, provided
printlevel >= voice+1 (default).

Theory:
The ideal of algebraic relations of all the generators p1,...,pn,
s1,...,st given by P and S is computed introducing new variables y(j),
z(i) and the product order: x^a*y^b*z^c > x^d*y^e*z^f if x^a > x^d
with respect to the lp ordering or else if z^c > z^f with respect to
the dp ordering or else if y^b > y^e with respect to the lp ordering
again. p reduces to a polynomial only in the y(j) and z(i), linear in
the z(i) <=> p is contained in the module.

Example:
LIB "algebra.lib";
int p = printlevel; printlevel = 1;
ring R=0,(x,y,z),dp;
ideal P = x2+y2,z2,x4+y4;           //algebra generators
ideal M = 1,x2z-1y2z,xyz,x3y-1xy3;  //module generators
poly p1=
x10z3-x8y2z3+2x6y4z3-2x4y6z3+x2y8z3-y10z3+x6z4+3x4y2z4+3x2y4z4+y6z4;
module_containment(p1,P,M);
==> // y(2)*z(2)*z(3)^2+z(1)^3*z(2)^2
==> 1
poly p2=z;
list l = module_containment(p2,P,M,1);
==> 
==> // 'module_containment' created a ring as 2nd element of the list. The
==> // ring contains the poly check which defines the algebraic relation
==> // for p. To access to the ring and see check you must give the ring
==> // a name, e.g.:
==>      def S = l[2]; setring S; check;
==>       
l[1];
==> 0
def S = l[2]; setring S; check;
==> x(3)
printlevel=p;

D.4.1.3 inSubring
.................
Procedure from library algebra.lib (see algebra_lib).

Usage:
inSubring(p,i); p poly, i ideal

Return:
         a list l of size 2, l[1] integer, l[2] string
         l[1]=1 iff p is in the subring generated by i=i[1],...,i[k],
                and then l[2] = y(0)-h(y(1),...,y(k)) if p = h(i[1],...,i[k])
         l[1]=0 iff p is in not the subring generated by i,
                and then l[2] = h(y(0),y(1),...,y(k) where p satisfies the
                nonlinear relation h(p,i[1],...,i[k])=0.

Note:
the proc algebra_containment tests the same with a different
algorithm, which is often faster

Example:
LIB "algebra.lib";
ring q=0,(x,y,z,u,v,w),dp;
poly p=xyzu2w-1yzu2w2+u4w2-1xu2vw+u2vw2+xyz-1yzw+2u2w-1xv+vw+2;
ideal I =x-w,u2w+1,yz-v;
inSubring(p,I);
==> [1]:
==>    1
==> [2]:
==>    y(1)*y(2)*y(3)+y(2)^2-y(0)+1

D.4.1.4 algDependent
....................
Procedure from library algebra.lib (see algebra_lib).

Usage:
algDependent(f[,c]); f ideal (say, f = f1,...,fm), c integer

Return:
         a list l  of size 2, l[1] integer, l[2] ring:
         - l[1] = 1 if f1,...,fm are algebraic dependent, 0 if not
         - l[2] is a ring with variables x(1),...,x(n),y(1),...,y(m) if the
           basering has n variables. It contains the ideal 'ker', depending
           only on the y(i) and generating the algebraic relations between the
           f[i], i.e. substituting y(i) by fi yields 0. Of course, ker is
           nothing but the kernel of the ring map
              K[y(1),...,y(m)] --> basering,  y(i) -> fi.

Note:
Three different algorithms are used depending on c = 1,2,3.
If c is not given or c=0, a heuristically best method is chosen.
The basering may be a quotient ring.

To access to the ring l[2] and see ker you must give the ring a name,
e.g. def S=l[2]; setring S; ker;

Display:
The above comment is displayed if printlevel >= 0 (default).

Example:
LIB "algebra.lib";
int p = printlevel; printlevel = 1;
ring R = 0,(x,y,z,u,v,w),dp;
ideal I = xyzu2w-1yzu2w2+u4w2-1xu2vw+u2vw2+xyz-1yzw+2u2w-1xv+vw+2,
x-w, u2w+1, yz-v;
list l = algDependent(I);
==> 
==> // The 2nd element of the list l is a ring with variables x(1),...,x(n),
==> // and y(1),...,y(m) if the basering has n variables and if the ideal
==> // is f[1],...,f[m]. The ring contains the ideal ker which depends only
==> // on the y(i) and generates the relations between the f[i].
==> // I.e. substituting y(i) by f[i] yields 0.
==> // To access to the ring and see ker you must give the ring a name,
==> // e.g.:
==>              def S = l[2]; setring S; ker;
==> 	
l[1];
==> 1
def S = l[2]; setring S;
ker;
==> ker[1]=y(2)*y(3)*y(4)+y(3)^2-y(1)+1
printlevel = p;

D.4.1.5 alg_kernel
..................
Procedure from library algebra.lib (see algebra_lib).

Usage:
alg_kernel(phi,pr[,s,c]); phi map to basering, pr preimage ring,
s string (name of kernel in pr), c integer.

Return:
a string, the kernel of phi as string.

If, moreover, a string s is given, the algorithm creates, in the
preimage ring pr the kernel of phi with name s.

Three different algorithms are used depending on c = 1,2,3.
If c is not given or c=0, a heuristically best method is chosen.
(algorithm 1 uses the preimage command)

Note:
Since the kernel of phi lives in pr, it cannot be returned to the
basering. If s is given, the user has access to it in pr via s.
The basering may be a quotient ring.

Example:
LIB "algebra.lib";
ring r = 0,(a,b,c),ds;
ring s = 0,(x,y,z,u,v,w),dp;
ideal I = x-w,u2w+1,yz-v;
map phi = r,I;                // a map from r to s:
alg_kernel(phi,r);            // a,b,c ---> x-w,u2w+1,yz-v
==> 0
ring S = 0,(a,b,c),ds;
ring R = 0,(x,y,z),dp;
qring Q = std(x-y);
ideal i = x, y, x2-y3;
map phi = S,i;                 // a map to a quotient ring
alg_kernel(phi,S,"ker",3);     // uses algorithm 3
==> a-b,b^3-b^2+c
setring S;                     // you have access to kernel in preimage
ker;
==> ker[1]=a-b
==> ker[2]=c-b2+b3

D.4.1.6 is_injective
....................
Procedure from library algebra.lib (see algebra_lib).

Usage:
is_injective(phi,pr[,c,s]); phi map, pr preimage ring, c int, s string

Return:
         - 1 (type int) if phi is injective, 0 if not (if s is not given).
         - If s is given, return a list l of size 2, l[1] int, l[2] ring:
           l[1] is 1 if phi is injective, 0 if not
           l[2] is a ring with variables x(1),...,x(n),y(1),...,y(m) if the
           basering has n variables and the map m components, it contains the
           ideal 'ker', depending only on the y(i), the kernel of the given map

Note:
Three different algorithms are used depending on c = 1,2,3.
If c is not given or c=0, a heuristically best method is chosen.
The basering may be a quotient ring. However, if the preimage ring is
a quotient ring, say pr = P/I, consider phi as a map from P and then
the algorithm returns 1 if the kernel of phi is 0 mod I.
To access to the ring l[2] and see ker you must give the ring a name,
e.g. def S=l[2]; setring S; ker;

Display:
The above comment is displayed if printlevel >= 0 (default).

Example:
LIB "algebra.lib";
int p = printlevel;
ring r = 0,(a,b,c),ds;
ring s = 0,(x,y,z,u,v,w),dp;
ideal I = x-w,u2w+1,yz-v;
map phi = r,I;                    // a map from r to s:
is_injective(phi,r);              // a,b,c ---> x-w,u2w+1,yz-v
==> 1
ring R = 0,(x,y,z),dp;
ideal i = x, y, x2-y3;
map phi = R,i;                    // a map from R to itself, z --> x2-y3
list l = is_injective(phi,R,"");
==> 
==> // The 2nd element of the list is a ring with variables x(1),...,x(n),
==> // y(1),...,y(m) if the basering has n variables and the map is
==> // F[1],...,F[m].
==> // It contains the ideal ker, the kernel of the given map y(i) --> F[i].
==> // To access to the ring and see ker you must give the ring a name,
==> // e.g.:
==>      def S = l[2]; setring S; ker;
==> 	
l[1];
==> 0
def S = l[2]; setring S;
ker;
==> ker[1]=y(2)^3-y(1)^2+y(3)

D.4.1.7 is_surjective
.....................
Procedure from library algebra.lib (see algebra_lib).

Usage:
is_surjective(phi); phi map to basering, or ideal defining it

Return:
an integer, 1 if phi is surjective, 0 if not

Note:
The algorithm returns 1 iff all the variables of the basering are
contained in the polynomial subalgebra generated by the polynomials
defining phi. Hence, if the basering has local or mixed ordering
or if the preimage ring is a quotient ring (in which case the map
may not be well defined) then the return value 1 means

"surjectivity" in this sense.

Example:
LIB "algebra.lib";
ring R = 0,(x,y,z),dp;
ideal i = x, y, x2-y3;
map phi = R,i;                    // a map from R to itself, z->x2-y3
is_surjective(phi);
==> 0
qring Q = std(ideal(z-x37));
map psi = R, x,y,x2-y3;           // the same map to the quotient ring
is_surjective(psi);
==> 1
ring S = 0,(a,b,c),dp;
map psi = R,ideal(a,a+b,c-a2+b3); // a map from R to S,
is_surjective(psi);               // x->a, y->a+b, z->c-a2+b3
==> 1

D.4.1.8 is_bijective
....................
Procedure from library algebra.lib (see algebra_lib).

Usage:
is_bijective(phi,pr); phi map to basering, pr preimage ring

Return:
an integer, 1 if phi is bijective, 0 if not

Note:
The algorithm checks first injectivity and then surjectivity
To interpret this for local/mixed orderings, or for quotient rings
type help is_surjective; and help is_injective;

Display:
A comment if printlevel >= voice-1 (default)

Example:
LIB "algebra.lib";
int p = printlevel;  printlevel = 1;
ring R = 0,(x,y,z),dp;
ideal i = x, y, x2-y3;
map phi = R,i;                      // a map from R to itself, z->x2-y3
is_bijective(phi,R);
==> // map not injective
==> 0
qring Q = std(z-x2+y3);
is_bijective(ideal(x,y,x2-y3),Q);
==> 1
ring S = 0,(a,b,c,d),dp;
map psi = R,ideal(a,a+b,c-a2+b3,0); // a map from R to S,
is_bijective(psi,R);                // x->a, y->a+b, z->c-a2+b3
==> // map injective, but not surjective
==> 0
qring T = std(d,c-a2+b3);
==> // ** _ is no standardbasis
map chi = Q,a,b,a2-b3;              // amap between two quotient rings
is_bijective(chi,Q);
==> 1
printlevel = p;

D.4.1.9 noetherNormal
.....................
Procedure from library algebra.lib (see algebra_lib).

Usage:
noetherNormal(id[,p]); id ideal, p integer

Return:
         a list l two ideals, say I,J:
         - I is generated by a subset of the variables with size(I) = dim(id)
         - J defines a map (coordinate change in the basering), such that:
           if we define  map phi=basering,J;
           then k[var(1),...,var(n)]/phi(id) is finite over k[I].
         If p is given, 0<=p<=100, a sparse coordinate change with p percent
         of the matrix entries being 0 (default: p=0 i.e. dense)

Note:
Designed for characteristic 0.It works also in char k > 0 if it
terminates,but may result in an infinite loop in small characteristic

Example:
LIB "algebra.lib";
ring r=0,(x,y,z),dp;
ideal i= xy,xz;
noetherNormal(i);
==> [1]:
==>    _[1]=x
==>    _[2]=2x+y
==>    _[3]=3x+4y+z
==> [2]:
==>    _[1]=y
==>    _[2]=z

D.4.1.10 mapIsFinite
....................
Procedure from library algebra.lib (see algebra_lib).

Usage:
mapIsFinite(phi,R[,J]); R a ring, phi: R --> basering a map
J an ideal in the basering, J = 0 if not given

Return:
1 if R --> basering/J is finite and 0 else

Example:
LIB "algebra.lib";
ring r = 0,(a,b,c),dp;
ring s = 0,(x,y,z),dp;
ideal i= xy;
map phi= r,(xy)^3+x2+z,y2-1,z3;
mapIsFinite(phi,r,i);
==> 1

D.4.1.11 finitenessTest
.......................
Procedure from library algebra.lib (see algebra_lib).

Usage:
finitenessTest(J[,v]); J ideal, v intvec (say v1,...,vr with vi>0)

Return:
         a list l with l[1] integer, l[2], l[3], l[4] ideals
         - l[1] = 1 if var(v1),...,var(vr) are in l[2] and 0 else
         - l[2] (resp. l[3]) contains those variables which occur,
           (resp. occur not) as pure power in the leading term of one of the
           generators of J,
         - l[4] contains those J[i] for which the leading term is a pure power
           of a variable (which is then in l[2])
         (default: v = [1,2,..,nvars(basering)])

Theory:
If J is a standard basis of an ideal generated by x_1 - f_1(y),...,
x_n - f_n with y_j ordered lexicographically and y_j >> x_i, then,
if y_i appears as pure power in the leading term of J[k]. J[k] defines
an integral relation for y_i over the y_(i+1),... and the f's.
Moreover, in this situation, if l[2] = y_1,...,y_r, then K[y_1,...y_r]
is finite over K[f_1..f_n]. If J contains furthermore polynomials
h_j(y), then K[y_1,...y_z]/<h_j> is finite over K[f_1..f_n].

Example:
LIB "algebra.lib";
ring s = 0,(x,y,z,a,b,c),(lp(3),dp);
ideal i= a -(xy)^3+x2-z, b -y2-1, c -z3;
ideal j = a -(xy)^3+x2-z, b -y2-1, c -z3, xy;
finitenessTest(std(i),1..3);
==> [1]:
==>    0
==> [2]:
==>    _[1]=y
==>    _[2]=z
==> [3]:
==>    _[1]=x
==>    _[2]=a
==>    _[3]=b
==>    _[4]=c
==> [4]:
==>    _[1]=z3-c
==>    _[2]=y2-b+1
finitenessTest(std(j),1..3);
==> [1]:
==>    1
==> [2]:
==>    _[1]=x
==>    _[2]=y
==>    _[3]=z
==> [3]:
==>    _[1]=a
==>    _[2]=b
==>    _[3]=c
==> [4]:
==>    _[1]=z3-c
==>    _[2]=y2-b+1
==>    _[3]=x2-z+a
D.4.2 elim_lib
--------------
Library:
elim.lib
Purpose:
      Elimination, Saturation and Blowing up


Procedures:
* blowup0:: create presentation of blownup ring of ideal j
* elim:: variable n..m eliminated from id (ideal/module)
* elim1:: p=product of vars to be eliminated from id
* nselect:: select generators not containing n-th [..m-th] variable
* sat:: saturated quotient of ideal/module id by ideal j
* select:: select generators containing all variables n...m
* select1:: select generators containing one variable n...m

D.4.2.1 blowup0
...............
Procedure from library elim.lib (see elim_lib).

Usage:
blowup0(j[,s1,s2]); j ideal, s1,s2 nonempty strings

Create:
Create a presentation of the blowup ring of j

Return:
no return value

Note:
s1 and s2 are used to give names to the blownup ring and the blownup
ideal (default: s1="j", s2="A")

Assume R = char,x(1..n),ord is the basering of j, and s1="j", s2="A"
then the procedure creates a new ring with name Bl_jR

(equal to R[A,B,...])

Bl_jR = char,(A,B,...,x(1..n)),(dp(k),ord)

with k=ncols(j) new variables A,B,... and ordering wp(d1..dk) if j is
homogeneous with deg(j[i])=di resp. dp otherwise for these vars.
If k>26 or size(s2)>1, say s2="A()", the new vars are A(1),...,A(k).
Let j_ be the kernel of the ring map Bl_jR -> R defined by A(i)->j[i],
x(i)->x(i), then the quotient ring Bl_jR/j_ is the blowup ring of j
in R (being isomorphic to R+j+j^2+...). Moreover the procedure creates
a std basis of j_ with name j_ in Bl_jR.

This proc uses 'execute' or calls a procedure using 'execute'.

Display:
printlevel >=0: explain created objects (default)

Example:
LIB "elim.lib";
ring R=0,(x,y),dp;
poly f=y2+x3; ideal j=jacob(f);
blowup0(j);
==> 
==> // The proc created the ring Bl_jR (equal to R[A,B])
==> // it contains the ideal j_ , such that
==> //             Bl_jR/j_ is the blowup ring
==> // show(Bl_jR); shows this ring.
==> // Make Bl_jR the basering and see j_ by typing:
==>    setring Bl_jR;
==>    j_;
show(Bl_jR);
==> // ring: (0),(A,B,x,y),(wp(2,1),dp(2),C);
==> // minpoly = 0
==> // objects belonging to this ring:
==> // j_                   [0]  ideal, 1 generator(s)
setring Bl_jR;
j_;"";
==> j_[1]=2Ay-3Bx2
==> 
ring r=32003,(x,y,z),ds;
blowup0(maxideal(1),"m","T()");
==> 
==> // The proc created the ring Bl_mr (equal to r[T(1..3)])
==> // it contains the ideal m_ , such that
==> //             Bl_mr/m_ is the blowup ring
==> // show(Bl_mr); shows this ring.
==> // Make Bl_mr the basering and see m_ by typing:
==>    setring Bl_mr;
==>    m_;
show(Bl_mr);
==> // ring: (32003),(T(1),T(2),T(3),x,y,z),(wp(1,1,1),ds(3),C);
==> // minpoly = 0
==> // objects belonging to this ring:
==> // m_                   [0]  ideal, 3 generator(s)
setring Bl_mr;
m_;
==> m_[1]=T(1)y-T(2)x
==> m_[2]=T(1)z-T(3)x
==> m_[3]=T(2)z-T(3)y
kill Bl_jR, Bl_mr;

D.4.2.2 elim
............
Procedure from library elim.lib (see elim_lib).

Usage:
elim(id,n,m); id ideal/module, n,m integers

Returns:
ideal/module obtained from id by eliminating variables n..m

Note:
no special monomial ordering is required, result is a SB with
respect to ordering dp (resp. ls) if the first var not to be
eliminated belongs to a -p (resp. -s) block ordering

This proc uses 'execute' or calls a procedure using 'execute'.

Example:
LIB "elim.lib";
ring r=0,(x,y,u,v,w),dp;
ideal i=x-u,y-u2,w-u3,v-x+y3;
elim(i,3,4);
==> _[1]=y2-xw
==> _[2]=xy-w
==> _[3]=x2-y
module m=i*gen(1)+i*gen(2);
m=elim(m,3,4);show(m);
==> // module, 6 generator(s)
==> [y2-xw]
==> [0,y2-xw]
==> [xy-w]
==> [0,xy-w]
==> [x2-y]
==> [0,x2-y]


D.4.2.3 elim1
.............
Procedure from library elim.lib (see elim_lib).

Usage:
elim1(id,p); id ideal/module, p product of vars to be eliminated

Return:
ideal/module obtained from id by eliminating vars occurring in poly

Note:
no special monomial ordering is required, result is a SB with
respect to ordering dp (resp. ls) if the first var not to be
eliminated belongs to a -p (resp. -s) block ordering

This proc uses 'execute' or calls a procedure using 'execute'.

Example:
LIB "elim.lib";
ring r=0,(x,y,t,s,z),dp;
ideal i=x-t,y-t2,z-t3,s-x+y3;
elim1(i,ts);
==> _[1]=y2-xz
==> _[2]=xy-z
==> _[3]=x2-y
module m=i*gen(1)+i*gen(2);
m=elim1(m,st); show(m);
==> // module, 6 generator(s)
==> [y2-xz]
==> [0,y2-xz]
==> [xy-z]
==> [0,xy-z]
==> [x2-y]
==> [0,x2-y]


D.4.2.4 nselect
...............
Procedure from library elim.lib (see elim_lib).

Usage:
nselect(id,n[,m]); id a module or ideal, n, m integers

Return:
generators of id not containing the variable n [up to m]

Example:
LIB "elim.lib";
ring r=0,(x,y,t,s,z),(c,dp);
ideal i=x-y,y-z2,z-t3,s-x+y3;
nselect(i,3);
==> _[1]=x-y
==> _[2]=-z2+y
==> _[3]=y3-x+s
module m=i*(gen(1)+gen(2));
show(m);
==> // module, 4 generator(s)
==> [x-y,x-y]
==> [-z2+y,-z2+y]
==> [-t3+z,-t3+z]
==> [y3-x+s,y3-x+s]
show(nselect(m,3,4));
==> // module, 2 generator(s)
==> [x-y,x-y]
==> [-z2+y,-z2+y]


D.4.2.5 sat
...........
Procedure from library elim.lib (see elim_lib).

Usage:
sat(id,j); id=ideal/module, j=ideal

Return:
list of an ideal/module [1] and an integer [2]:

[1] = saturation of id with respect to j (= union_(k=1...) of id:j^k)
[2] = saturation exponent (= min( k | id:j^k = id:j^(k+1) ))

Note:
[1] is a standard basis in the basering

Display:
saturation exponent during computation if printlevel >=1

Example:
LIB "elim.lib";
int p      = printlevel;
ring r     = 2,(x,y,z),dp;
poly F     = x5+y5+(x-y)^2*xyz;
ideal j    = jacob(F);
sat(j,maxideal(1));
==> [1]:
==>    _[1]=x3+x2y+xy2+y3
==>    _[2]=y4+x2yz+y3z
==>    _[3]=x2y2+x2yz+y3z
==> [2]:
==>    4
printlevel = 2;
sat(j,maxideal(2));
==> // compute quotient 1
==> // compute quotient 2
==> // compute quotient 3
==> // saturation becomes stable after 2 iteration(s)
==> 
==> [1]:
==>    _[1]=x3+x2y+xy2+y3
==>    _[2]=y4+x2yz+y3z
==>    _[3]=x2y2+x2yz+y3z
==> [2]:
==>    2
printlevel = p;

D.4.2.6 select
..............
Procedure from library elim.lib (see elim_lib).

Usage:
select(id,n[,m]); id ideal/module, n, m integers

Return:
generators of id containing the variable n [all variables up to m]

Note:
use 'select1' for selecting generators containing at least one of the
variables between n and m

Example:
LIB "elim.lib";
ring r=0,(x,y,t,s,z),(c,dp);
ideal i=x-y,y-z2,z-t3,s-x+y3;
ideal j=select(i,1);
j;
==> j[1]=x-y
==> j[2]=y3-x+s
module m=i*(gen(1)+gen(2));
m;
==> m[1]=[x-y,x-y]
==> m[2]=[-z2+y,-z2+y]
==> m[3]=[-t3+z,-t3+z]
==> m[4]=[y3-x+s,y3-x+s]
select(m,1,2);
==> _[1]=[x-y,x-y]
==> _[2]=[y3-x+s,y3-x+s]


D.4.2.7 select1
...............
Procedure from library elim.lib (see elim_lib).

Usage:
select1(id,n[,m]); id ideal/module, n, m integers

Return:
generators of id containing the variable n

[at least one of the variables up to m]

Note:
use 'select' for selecting generators containing all the
variables between n and m

Example:
LIB "elim.lib";
ring r=0,(x,y,t,s,z),(c,dp);
ideal i=x-y,y-z2,z-t3,s-x+y3;
ideal j=select1(i,1);
j;
==> j[1]=x-y
==> j[2]=y3-x+s
module m=i*(gen(1)+gen(2));
m;
==> m[1]=[x-y,x-y]
==> m[2]=[-z2+y,-z2+y]
==> m[3]=[-t3+z,-t3+z]
==> m[4]=[y3-x+s,y3-x+s]
select1(m,1,2);
==> _[1]=[x-y,x-y]
==> _[2]=[-z2+y,-z2+y]
==> _[3]=[y3-x+s,y3-x+s]

D.4.3 homolog_lib
-----------------
Library:
homolog.lib
Purpose:
   Procedures for Homological Algebra
Authors:
Gert-Martin Greuel, greuel@mathematik.uni-kl.de,

 Bernd Martin, martin@math.tu-cottbus.de

 Christoph Lossen, lossen@mathematik.uni-kl.de


Procedures:
* cup:: cup: Ext^1(M',M') x Ext^1() -> Ext^2()
* cupproduct:: cup: Ext^p(M',N') x Ext^q(N',P') -> Ext^p+q(M',P')
* depth:: depth(I,M'), I ideal, M module, M'=coker(M)
* Ext_R:: Ext^k(M',R), M module, R basering, M'=coker(M)
* Ext:: Ext^k(M',N'), M,N modules, M'=coker(M), N'=coker(N)
* fitting:: n-th Fitting ideal of M'=coker(M), M module, n int
* flatteningStrat:: Flattening stratification of M'=coker(M), M module
* Hom:: Hom(M',N'), M,N modules, M'=coker(M), N'=coker(N)
* homology:: ker(B)/im(A), homology of complex R^k-A->M'-B->N'
* isCM:: test if coker(M) is Cohen-Macaulay, M module
* isFlat:: test if coker(M) is flat, M module
* isLocallyFree:: test if coker(M) is locally free of constant rank r
* isReg:: test if I is coker(M)-sequence, I ideal, M module
* kernel:: ker(M'-A->N') M,N modules, A matrix
* kohom:: Hom(R^k,A), A matrix over basering R
* kontrahom:: Hom(A,R^k), A matrix over basering R
* KoszulHomology:: n-th Koszul homology H_n(I,coker(M)), I=ideal
* tensorMod:: Tensor product of modules M'=coker(M), N'=coker(N)
* Tor:: Tor_k(M',N'), M,N modules, M'=coker(M), N'=coker(N)

D.4.3.1 cup
...........
Procedure from library homolog.lib (see homolog_lib).

Usage:
cup(M,[,any,any]); M=module

Compute:
cup-product Ext^1(M',M') x Ext^1(M',M') --> Ext^2(M',M'), where
M':=R^m/M, if M in R^m, R basering (i.e. M':=coker(matrix(M))).

 If called with >= 2 arguments: compute symmetrized cup-product

Assume:
all Ext's are finite dimensional

Return:
- if called with 1 argument: matrix, the columns of the output present
the coordinates of b_i&b_j with respect to a kbase of Ext^2, where
b_1,b_2,... is a kbase of Ext^1 and & denotes cup product;

- if called with 2 arguments: matrix, the columns of the output
present the coordinates of (1/2)(b_i&b_j + b_j&b_i) with respect to
a kbase of Ext^2;

- if called with 3 arguments: list,
      L[1] = matrix see above (symmetric case, for >=2 arguments)
      L[2] = matrix of kbase of Ext^1
      L[3] = matrix of kbase of Ext^2

Note:
printlevel >=1; shows what is going on.

printlevel >=2; shows result in another representation.

 For computing cupproduct of M itself, apply proc to syz(M)!

Example:
LIB "homolog.lib";
int p      = printlevel;
ring  rr   = 32003,(x,y,z),(dp,C);
ideal  I   = x4+y3+z2;
qring  o   = std(I);
module M   = [x,y,0,z],[y2,-x3,z,0],[z,0,-y,-x3],[0,z,x,-y2];
print(cup(M));
==> 0,1,0, 0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,
==> 0,0,-1,0, 0,1,0,0,0,0,0, 0,0,0,0,0,0,
==> 0,0,0, -1,0,0,0,0,0,1,0, 0,0,0,0,0,0,
==> 0,0,0, 0, 1,0,0,1,0,0,-1,0,0,1,0,0,0 
print(cup(M,1));
==> 0,1,0,0,0,0,0,0,0,0,0,
==> 0,0,0,0,0,0,0,0,0,0,0,
==> 0,0,0,0,0,0,0,0,0,0,0,
==> 0,0,0,0,1,0,0,0,0,0,0 
// 2nd EXAMPLE  (shows what is going on)
printlevel = 3;
ring   r   = 0,(x,y),(dp,C);
ideal  i   = x2-y3;
qring  q   = std(i);
module M   = [-x,y],[-y2,x];
print(cup(M));
==> // vdim (Ext^1) = 2
==> // kbase of Ext^1(M,M)
==> //  - the columns present the kbase elements in Hom(F(1),F(0))
==> //  - F(*) a free resolution of M
==> -1,0,
==> 0, y,
==> 0, 1,
==> -1,0 
==> // lift kbase of Ext^1:
==> //  - the columns present liftings of kbase elements into Hom(F(2),F(1))
==> //  - F(*) a free resolution of M 
==> 1,0,
==> 0,y,
==> 0,1,
==> 1,0 
==> // vdim (Ext^2) = 2
==> // kbase of Ext^2(M,M)
==> //  - the columns present the kbase elements in Hom(F(2),F(0))
==> //  - F(*) is a a free resolution of M 
==> -1,0,
==> 0, y,
==> 0, 1,
==> -1,0 
==> // matrix of cup-products (in Ext^2)
==> 0,-1,0, 0,y,
==> 0,0, -y,y,0,
==> 0,0, -1,1,0,
==> 0,-1,0, 0,y 
==> ////// end level 2 //////
==> // the associated matrices of the bilinear mapping 'cup' 
==> // corresponding to the kbase elements of Ext^2(M,M) are shown,
==> //  i.e. the rows of the final matrix are written as matrix of
==> //  a bilinear form on Ext^1 x Ext^1
==> //-----component 1:
==> 0,1,
==> 0,0 
==> //-----component 2:
==> 0, 0,
==> -1,1 
==> ////// end level 3 //////
==> 0,1,0, 0,0,
==> 0,0,-1,1,0 
printlevel = p;

D.4.3.2 cupproduct
..................
Procedure from library homolog.lib (see homolog_lib).

Usage:
cupproduct(M,N,P,p,q[,any]); M,N,P modules, p,q integers

Compute:
cup-product Ext^p(M',N') x Ext^q(N',P') --> Ext^p+q(M',P'),
where M':=R^m/M, if M in R^m, R basering (i.e. M':=coker(matrix(M)))

Assume:
all Ext's are of finite dimension

Return:
- if called with 5 arguments: matrix of the associated linear map
Ext^p (tensor) Ext^q -> Ext^p+q, i.e. the columns of <matrix>
present the coordinates of the cup products (b_i & c_j) with respect
to a kbase of Ext^p+q (b_i resp. c_j are the choosen bases of Ext^p,
resp. Ext^q).

- if called with 6 arguments: list L,
      L[1] = matrix (see above)
      L[2] = matrix of kbase of Ext^p(M',N')
      L[3] = matrix of kbase of Ext^q(N',P')
      L[4] = matrix of kbase of Ext^p+q(N',P')

Note:
printlevel >=1; shows what is going on.

printlevel >=2; shows the result in another representation.

For computing the cupproduct of M,N itself, apply proc to syz(M),
syz(N)!

Example:
LIB "homolog.lib";
int p      = printlevel;
ring  rr   = 32003,(x,y,z),(dp,C);
ideal  I   = x4+y3+z2;
qring  o   = std(I);
module M   = [x,y,0,z],[y2,-x3,z,0],[z,0,-y,-x3],[0,z,x,-y2];
print(cupproduct(M,M,M,1,3));
==> 0,1,0, 0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,
==> 0,0,-1,0, 0,1,0,0,0,0,0, 0,0,0,0,0,0,
==> 0,0,0, -1,0,0,0,0,0,1,0, 0,0,0,0,0,0,
==> 0,0,0, 0, 1,0,0,1,0,0,-1,0,0,1,0,0,0 
printlevel = 3;
list l     = (cupproduct(M,M,M,1,3,"any"));
==> // vdim Ext(M,N) = 4
==> // kbase of Ext^p(M,N)
==> //  - the columns present the kbase elements in Hom(F(p),G(0))
==> //  - F(*),G(*) are free resolutions of M and N
==> 0, 0, 1, 0,  
==> 0, y, 0, 0,  
==> 1, 0, 0, 0,  
==> 0, 0, 0, y,  
==> 0, -1,0, 0,  
==> 0, 0, x2,0,  
==> 0, 0, 0, -x2,
==> 1, 0, 0, 0,  
==> 0, 0, 0, -1, 
==> -1,0, 0, 0,  
==> 0, 1, 0, 0,  
==> 0, 0, 1, 0,  
==> -1,0, 0, 0,  
==> 0, 0, 0, x2y,
==> 0, 0, x2,0,  
==> 0, -y,0, 0   
==> // vdim Ext(N,P) = 4
==> // kbase of Ext(N,P):
==> 0, 0, 1,  0,  
==> 0, 0, 0,  y,  
==> 1, 0, 0,  0,  
==> 0, -y,0,  0,  
==> 0, -1,0,  0,  
==> 1, 0, 0,  0,  
==> 0, 0, 0,  -x2,
==> 0, 0, -x2,0,  
==> 0, 0, 0,  -1, 
==> 0, 0, 1,  0,  
==> 0, 1, 0,  0,  
==> 1, 0, 0,  0,  
==> -1,0, 0,  0,  
==> 0, -y,0,  0,  
==> 0, 0, x2, 0,  
==> 0, 0, 0,  -x2y
==> // kbase of Ext^q(N,P)
==> //  - the columns present the kbase elements in Hom(G(q),H(0))
==> //  - G(*),H(*) are free resolutions of N and P
==> 0, 0, 1,  0,  
==> 0, 0, 0,  y,  
==> 1, 0, 0,  0,  
==> 0, -y,0,  0,  
==> 0, -1,0,  0,  
==> 1, 0, 0,  0,  
==> 0, 0, 0,  -x2,
==> 0, 0, -x2,0,  
==> 0, 0, 0,  -1, 
==> 0, 0, 1,  0,  
==> 0, 1, 0,  0,  
==> 1, 0, 0,  0,  
==> -1,0, 0,  0,  
==> 0, -y,0,  0,  
==> 0, 0, x2, 0,  
==> 0, 0, 0,  -x2y
==> // vdim Ext(M,P) = 4
==> // kbase of Ext^p+q(M,P)
==> //  - the columns present the kbase elements in Hom(F(p+q),H(0))
==> //  - F(*),H(*) are free resolutions of M and P
==> 0, 0, 1,  0,  
==> 0, 0, 0,  y,  
==> 1, 0, 0,  0,  
==> 0, -y,0,  0,  
==> 0, -1,0,  0,  
==> 1, 0, 0,  0,  
==> 0, 0, 0,  -x2,
==> 0, 0, -x2,0,  
==> 0, 0, 0,  -1, 
==> 0, 0, 1,  0,  
==> 0, 1, 0,  0,  
==> 1, 0, 0,  0,  
==> -1,0, 0,  0,  
==> 0, -y,0,  0,  
==> 0, 0, x2, 0,  
==> 0, 0, 0,  -x2y
==> // lifting of kbase of Ext^p(M,N)
==> //  - the columns present liftings of kbase elements in Hom(F(p+q),G(q))
==> 1,0, 0, 0,  
==> 0,-y,0, 0,  
==> 0,0, x2,0,  
==> 0,0, 0, x2y,
==> 0,1, 0, 0,  
==> 1,0, 0, 0,  
==> 0,0, 0, -x2,
==> 0,0, x2,0,  
==> 0,0, -1,0,  
==> 0,0, 0, y,  
==> 1,0, 0, 0,  
==> 0,y, 0, 0,  
==> 0,0, 0, -1, 
==> 0,0, -1,0,  
==> 0,-1,0, 0,  
==> 1,0, 0, 0   
==> // matrix of cup-products (in Ext^p+q)
==> 0,0, 0, -1, 0,   0, 0, 0,   y,   1,  0,  0,  0,  0,   y,   0,  0,   
==> 0,0, 0, 0,  y,   0, 0, y,   0,   0,  -y, 0,  0,  y,   0,   0,  0,   
==> 0,1, 0, 0,  0,   0, y, 0,   0,   0,  0,  x2, 0,  0,   0,   0,  -x2y,
==> 0,0, y, 0,  0,   -y,0, 0,   0,   0,  0,  0,  x2y,0,   0,   x2y,0,   
==> 0,0, 1, 0,  0,   -1,0, 0,   0,   0,  0,  0,  x2, 0,   0,   x2, 0,   
==> 0,1, 0, 0,  0,   0, y, 0,   0,   0,  0,  x2, 0,  0,   0,   0,  -x2y,
==> 0,0, 0, 0,  -x2, 0, 0, -x2, 0,   0,  x2, 0,  0,  -x2, 0,   0,  0,   
==> 0,0, 0, x2, 0,   0, 0, 0,   -x2y,-x2,0,  0,  0,  0,   -x2y,0,  0,   
==> 0,0, 0, 0,  -1,  0, 0, -1,  0,   0,  1,  0,  0,  -1,  0,   0,  0,   
==> 0,0, 0, -1, 0,   0, 0, 0,   y,   1,  0,  0,  0,  0,   y,   0,  0,   
==> 0,0, -1,0,  0,   1, 0, 0,   0,   0,  0,  0,  -x2,0,   0,   -x2,0,   
==> 0,1, 0, 0,  0,   0, y, 0,   0,   0,  0,  x2, 0,  0,   0,   0,  -x2y,
==> 0,-1,0, 0,  0,   0, -y,0,   0,   0,  0,  -x2,0,  0,   0,   0,  x2y, 
==> 0,0, y, 0,  0,   -y,0, 0,   0,   0,  0,  0,  x2y,0,   0,   x2y,0,   
==> 0,0, 0, -x2,0,   0, 0, 0,   x2y, x2, 0,  0,  0,  0,   x2y, 0,  0,   
==> 0,0, 0, 0,  -x2y,0, 0, -x2y,0,   0,  x2y,0,  0,  -x2y,0,   0,  0    
==> ////// end level 2 //////
==> // the associated matrices of the bilinear mapping 'cup' 
==> // corresponding to the kbase elements of Ext^p+q(M,P) are shown,
==> //  i.e. the rows of the final matrix are written as matrix of
==> //  a bilinear form on Ext^p x Ext^q
==> //----component 1:
==> 0,1,0,0,
==> 0,0,0,0,
==> 0,0,0,0,
==> 0,0,0,0 
==> //----component 2:
==> 0,0,-1,0,
==> 0,1,0, 0,
==> 0,0,0, 0,
==> 0,0,0, 0 
==> //----component 3:
==> 0,0,0,-1,
==> 0,0,0,0, 
==> 0,1,0,0, 
==> 0,0,0,0  
==> //----component 4:
==> 0,0,0, 0,
==> 1,0,0, 1,
==> 0,0,-1,0,
==> 0,1,0, 0 
==> ////// end level 3 //////
show(l[1]);show(l[2]);
==> // matrix, 4x17
==> 0,1,0, 0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,
==> 0,0,-1,0, 0,1,0,0,0,0,0, 0,0,0,0,0,0,
==> 0,0,0, -1,0,0,0,0,0,1,0, 0,0,0,0,0,0,
==> 0,0,0, 0, 1,0,0,1,0,0,-1,0,0,1,0,0,0 
==> // matrix, 16x4
==> 0, 0, 1, 0,  
==> 0, y, 0, 0,  
==> 1, 0, 0, 0,  
==> 0, 0, 0, y,  
==> 0, -1,0, 0,  
==> 0, 0, x2,0,  
==> 0, 0, 0, -x2,
==> 1, 0, 0, 0,  
==> 0, 0, 0, -1, 
==> -1,0, 0, 0,  
==> 0, 1, 0, 0,  
==> 0, 0, 1, 0,  
==> -1,0, 0, 0,  
==> 0, 0, 0, x2y,
==> 0, 0, x2,0,  
==> 0, -y,0, 0   
printlevel = p;

D.4.3.3 depth
.............
Procedure from library homolog.lib (see homolog_lib).

Usage:
depth(M,[I]); M module, I ideal

Return:
int,

- if called with 1 argument: the depth of M'=coker(M) w.r.t. the
maxideal in the basering (which is then assumed to be local)

- if called with 2 arguments: the depth of M'=coker(M) w.r.t. the
ideal I.

Note:
procedure makes use of KoszulHomology.

Example:
LIB "homolog.lib";
ring R=0,(x,y,z),dp;
ideal I=x2,xy,yz;
module M=0;
depth(M,I);   // depth(<x2,xy,yz>,Q[x,y,z])
==> 2
ring r=0,(x,y,z),ds;  // local ring
matrix M[2][2]=x,xy,1+yz,0;
print(M);
==> x,   xy,
==> 1+yz,0  
depth(M);     // depth(maxideal,coker(M))
==> 2
ideal I=x;
depth(M,I);   // depth(<x>,coker(M))
==> 0
I=x+z;
depth(M,I);   // depth(<x+z>,coker(M))
==> 1

D.4.3.4 Ext_R
.............
Procedure from library homolog.lib (see homolog_lib).

Usage:
Ext_R(v,M[,p]); v int resp. intvec , M module, p int

Compute:
A presentation of Ext^k(M',R); for k=v[1],v[2],..., M'=coker(M).
Let
  0 <-- M' <-- F0 <-M-- F1 <-- F2 <-- ...
be a free resolution of M'. If
        0 --> F0* -A1-> F1* -A2-> F2* -A3-> ...
is the dual sequence, Fi*=Hom(Fi,R), then Ext^k = ker(Ak+1)/im(Ak)
is presented as in the following exact sequences:
    R^p --syz(Ak+1)-> Fk* ---Ak+1---->  Fk+1* ,
    R^q ----Ext^k---> R^p --syz(Ak+1)-> Fk*/im(Ak).
Hence, Ext^k=modulo(syz(Ak+1),Ak) presents Ext^k(M',R).

Return:
- module Ext, a presentation of Ext^k(M',R) if v is of type int

- a list of Ext^k (k=v[1],v[2],...) if v is of type intvec.

- In case of a third argument of type int return a list l:
     l[1] = module Ext^k resp. list of Ext^k
     l[2] = SB of Ext^k resp. list of SB of Ext^k
     l[3] = matrix resp. list of matrices, each representing a kbase of Ext^k 
              (if finite dimensional)

Display:
printlevel >=0: (affine) dimension of Ext^k for each k (default)
printlevel >=1: Ak, Ak+1 and kbase of Ext^k in Fk*

Note:
In order to compute Ext^k(M,R) use the command Ext_R(k,syz(M));
or the 2 commands: list L=mres(M,2); Ext_R(k,L[2]);

Example:
LIB "homolog.lib";
int p      = printlevel;
printlevel = 1;
ring r     = 0,(x,y,z),dp;
ideal i    = x2y,y2z,z3x;
module E   = Ext_R(1,i);    //computes Ext^1(r/i,r)
==> // Computing Ext^1:
==> // Let 0<--coker(M)<--F0<--F1<--F2<--... be a resolution of M,
==> // then F1*-->F2* is given by:
==> x2, -yz,0,  
==> 0,  z3, -xy,
==> xz2,0,  -y2 
==> // and F0*-->F1* is given by:
==> y2z,
==> x2y,
==> xz3 
==> 
==> // dimension of Ext^1:  -1
==> 
is_zero(E);
==> 1
qring R    = std(x2+yz);
intvec v   = 0,2;
printlevel = 2;             //shows what is going on
ideal i    = x,y,z;         //computes Ext^i(r/(x,y,z),r/(x2+yz)), i=0,2
list L     = Ext_R(v,i,1);  //over the qring R=r/(x2+yz), std and kbase
==> // Computing Ext^0:
==> // Let 0<--coker(M)<--F0<--F1<--F2<--... be a resolution of M,
==> // then F0*-->F1* is given by:
==> z,
==> y,
==> x 
==> // and F-1*-->F0* is given by:
==> 0
==> 
==> // dimension of Ext^0:  -1
==> 
==> // columns of matrix are kbase of Ext^0 in F0*:
==> 0
==> 
==> // Computing Ext^2:
==> // Let 0<--coker(M)<--F0<--F1<--F2<--... be a resolution of M,
==> // then F2*-->F3* is given by:
==> x,-y,z, 0,
==> z,x, 0, z,
==> 0,0, x, y,
==> 0,0, -z,x 
==> // and F1*-->F2* is given by:
==> y,-z,0, 
==> x,0, -z,
==> 0,x, -y,
==> 0,z, x  
==> 
==> // dimension of Ext^2:  0
==> // vdim of Ext^2:       1
==> 
==> // columns of matrix are kbase of Ext^2 in F2*:
==> x, 
==> -z,
==> 0, 
==> 0  
==> 
printlevel = p;

D.4.3.5 Ext
...........
Procedure from library homolog.lib (see homolog_lib).

Usage:
Ext(v,M,N[,any]); v int resp. intvec, M,N modules

Compute:
A presentation of Ext^k(M',N'); for k=v[1],v[2],... where
M'=coker(M) and N'=coker(N). Let
       0 <-- M' <-- F0 <-M-- F1 <-- F2 <--... ,   
       0 <-- N' <-- G0 <--N- G1
be a free resolution of M', resp. a presentation of N'. Consider
the commutative diagram
           0                  0                  0
           |^                 |^                 |^
   --> Hom(Fk-1,N') -Ak-> Hom(Fk,N') -Ak+1-> Hom(Fk+1,N')
           |^                 |^                 |^
   --> Hom(Fk-1,G0) -Ak-> Hom(Fk,G0) -Ak+1-> Hom(Fk+1,G0)
                              |^                 |^
                              |C                 |B
                          Hom(Fk,G1) ------> Hom(Fk+1,G1)

      (Ak,Ak+1 induced by M and B,C induced by N).
Let K=modulo(Ak+1,B), J=module(Ak)+module(C) and Ext=modulo(K,J),
then we have exact sequences
    R^p --K-> Hom(Fk,G0) --Ak+1-> Hom(Fk+1,G0)/im(B),

    R^q -Ext-> R^p --K-> Hom(Fk,G0)/(im(Ak)+im(C)).
Hence, Ext presents Ext^k(M',N').

Return:
- module Ext, a presentation of Ext^k(M',N') if v is of type int

- a list of Ext^k (k=v[1],v[2],...) if v is of type intvec.

- In case of a third argument of any type return a list l:
             l[1] = module Ext/list of Ext^k
             l[2] = SB of Ext/list of SB of Ext^k
             l[3] = matrix/list of matrices, each representing a kbase of Ext^k
                       (if finite dimensional)

Display:
printlevel >=0: dimension, vdim of Ext^k for each k (default).

 printlevel >=1: matrices Ak, Ak+1 and kbase of Ext^k in Hom(Fk,G0)
(if finite dimensional)

Note:
In order to compute Ext^k(M,N) use the command Ext(k,syz(M),syz(N));
or: list P=mres(M,2); list Q=mres(N,2); Ext(k,P[2],Q[2]);

Example:
LIB "homolog.lib";
int p      = printlevel;
printlevel = 1;
ring r     = 0,(x,y),dp;
ideal i    = x2-y3;
ideal j    = x2-y5;
list E     = Ext(0..2,i,j);    // Ext^k(r/i,r/j) for k=0,1,2 over r
==> // Computing Ext^0 (help Ext; gives an explanation):
==> // Let 0<--coker(M)<--F0<--F1<--F2<--... be a resolution of coker(M),
==> // and 0<--coker(N)<--G0<--G1 a presentation of coker(N),
==> // then Hom(F0,G0)-->Hom(F1,G0) is given by:
==> y3-x2
==> // and Hom(F-1,G0) + Hom(F0,G1)-->Hom(F0,G0) is given by:
==> 0,-y5+x2
==> 
==> // dimension of Ext^0:  -1
==> 
==> // Computing Ext^1 (help Ext; gives an explanation):
==> // Let 0<--coker(M)<--F0<--F1<--F2<--... be a resolution of coker(M),
==> // and 0<--coker(N)<--G0<--G1 a presentation of coker(N),
==> // then Hom(F1,G0)-->Hom(F2,G0) is given by:
==> 0
==> // and Hom(F0,G0) + Hom(F1,G1)-->Hom(F1,G0) is given by:
==> y3-x2,-y5+x2
==> 
==> // dimension of Ext^1:  0
==> // vdim of Ext^1:       10
==> 
==> // Computing Ext^2 (help Ext; gives an explanation):
==> // Let 0<--coker(M)<--F0<--F1<--F2<--... be a resolution of coker(M),
==> // and 0<--coker(N)<--G0<--G1 a presentation of coker(N),
==> // then Hom(F2,G0)-->Hom(F3,G0) is given by:
==> 1
==> // and Hom(F1,G0) + Hom(F2,G1)-->Hom(F2,G0) is given by:
==> 0,-y5+x2
==> 
==> // dimension of Ext^2:  -1
==> 
qring R    = std(i);
ideal j    = fetch(r,j);
module M   = [-x,y],[-y2,x];
printlevel = 2;
module E1  = Ext(1,M,j);       // Ext^1(R^2/M,R/j) over R=r/i
==> // Computing Ext^1 (help Ext; gives an explanation):
==> // Let 0<--coker(M)<--F0<--F1<--F2<--... be a resolution of coker(M),
==> // and 0<--coker(N)<--G0<--G1 a presentation of coker(N),
==> // then Hom(F1,G0)-->Hom(F2,G0) is given by:
==> x, -y,
==> y2,-x 
==> // and Hom(F0,G0) + Hom(F1,G1)-->Hom(F1,G0) is given by:
==> x, -y,-y5+x2,0,    
==> y2,-x,0,     -y5+x2
==> 
==> // dimension of Ext^1:  -1
==> 
list l     = Ext(4,M,M,1);     // Ext^4(R^2/M,R^2/M) over R=r/i
==> // Computing Ext^4 (help Ext; gives an explanation):
==> // Let 0<--coker(M)<--F0<--F1<--F2<--... be a resolution of coker(M),
==> // and 0<--coker(N)<--G0<--G1 a presentation of coker(N),
==> // then Hom(F4,G0)-->Hom(F5,G0) is given by:
==> x, -y,0, 0, 
==> y2,-x,0, 0, 
==> 0, 0, x, -y,
==> 0, 0, y2,-x 
==> // and Hom(F3,G0) + Hom(F4,G1)-->Hom(F4,G0) is given by:
==> x, -y,0, 0, -x,0, -y2,0,  
==> y2,-x,0, 0, 0, -x,0,  -y2,
==> 0, 0, x, -y,y, 0, x,  0,  
==> 0, 0, y2,-x,0, y, 0,  x   
==> 
==> // dimension of Ext^4:  0
==> // vdim of Ext^4:       2
==> 
==> // columns of matrix are kbase of Ext^4 in Hom(F4,G0)
==> 1,0,
==> 0,y,
==> 0,1,
==> 1,0 
==> 
==> // element 1 of kbase of Ext^4 in Hom(F4,G0)
==> // as matrix: F4-->G0
==> 1,0,
==> 0,1 
==> // element 2 of kbase of Ext^4 in Hom(F4,G0)
==> // as matrix: F4-->G0
==> 0,y,
==> 1,0 
==> 
printlevel = p;

D.4.3.6 fitting
...............
Procedure from library homolog.lib (see homolog_lib).

Usage:
fitting (M,n); M module, n int

Return:
ideal, (standard basis of) n-th Fitting ideal of M'=coker(M).

Example:
LIB "homolog.lib";
ring R=0,x(0..4),dp;
matrix M[2][4]=x(0),x(1),x(2),x(3),x(1),x(2),x(3),x(4);
print(M);
==> x(0),x(1),x(2),x(3),
==> x(1),x(2),x(3),x(4) 
fitting(M,-1);
==> _[1]=0
fitting(M,0);
==> _[1]=x(3)^2-x(2)*x(4)
==> _[2]=x(2)*x(3)-x(1)*x(4)
==> _[3]=x(1)*x(3)-x(0)*x(4)
==> _[4]=x(2)^2-x(0)*x(4)
==> _[5]=x(1)*x(2)-x(0)*x(3)
==> _[6]=x(1)^2-x(0)*x(2)
fitting(M,1);
==> _[1]=x(4)
==> _[2]=x(3)
==> _[3]=x(2)
==> _[4]=x(1)
==> _[5]=x(0)
fitting(M,2);
==> _[1]=1

D.4.3.7 flatteningStrat
.......................
Procedure from library homolog.lib (see homolog_lib).

Usage:
flatteningStrat(M); M module

Return:
list of ideals.

The list entries L[1],...,L[r] describe the flattening stratification
of M'=coker(M): setting L[0]=0, L[r+1]=1, the flattening
stratification is given by the open sets Spec(A/V(L[i-1])) \ V(L[i]),
i=1,...,r+1 (A = basering).

Note:
for more information see the book 'A Singular Introduction to
Commutative Algebra' (by Greuel/Pfister, Springer 2002).

Example:
LIB "homolog.lib";
ring A = 0,x(0..4),dp;
// presentation matrix:
matrix M[2][4] = x(0),x(1),x(2),x(3),x(1),x(2),x(3),x(4);
list L = flatteningStrat(M);
L;
==> [1]:
==>    _[1]=x(3)^2-x(2)*x(4)
==>    _[2]=x(2)*x(3)-x(1)*x(4)
==>    _[3]=x(1)*x(3)-x(0)*x(4)
==>    _[4]=x(2)^2-x(0)*x(4)
==>    _[5]=x(1)*x(2)-x(0)*x(3)
==>    _[6]=x(1)^2-x(0)*x(2)
==> [2]:
==>    _[1]=x(4)
==>    _[2]=x(3)
==>    _[3]=x(2)
==>    _[4]=x(1)
==>    _[5]=x(0)

D.4.3.8 Hom
...........
Procedure from library homolog.lib (see homolog_lib).

Usage:
Hom(M,N,[any]); M,N=modules

Compute:
A presentation of Hom(M',N'), M'=coker(M), N'=coker(N) as follows:
let
   F1 --M-> F0 -->M' --> 0,    G1 --N-> G0 --> N' --> 0  
be presentations of M' and N'. Consider
                                  0               0
                                  |^              |^
       0 --> Hom(M',N') ----> Hom(F0,N') ----> Hom(F1,N')
                                  |^              |^
  (A:  induced by M)          Hom(F0,G0) --A-> Hom(F1,G0)
                                  |^              |^
  (B,C:induced by N)              |C              |B
                              Hom(F0,G1) ----> Hom(F1,G1)

Let D=modulo(A,B) and Hom=modulo(D,C), then we have exact sequences
   R^p  --D-> Hom(F0,G0) --A-> Hom(F1,G0)/im(B),

 R^q -Hom-> R^p --D-> Hom(F0,G0)/im(C) --A-> Hom(F1,G0)/im(B).
Hence Hom presents Hom(M',N')

Return:
module Hom, a presentation of Hom(M',N'), resp., in case of
3 arguments, a list l (of size <=3):
           - l[1] = Hom
           - l[2] = SB of Hom
           - l[3] = kbase of coker(Hom) (if finite dimensional, not 0),
                    represented by elements in Hom(F0,G0) via mapping D

Display:
printlevel >=0: (affine) dimension of Hom (default)

 printlevel >=1: D and C and kbase of coker(Hom) in Hom(F0,G0)

 printlevel >=2: elements of kbase of coker(Hom) as matrix :F0->G0

Note:
DISPLAY is as described only for a direct call of 'Hom'. Calling 'Hom'
from another proc has the same effect as decreasing printlevel by 1.

Example:
LIB "homolog.lib";
int p     = printlevel;
printlevel= 1;   //in 'example proc' printlevel has to be increased by 1
ring r    = 0,(x,y),dp;
ideal i   = x2-y3,xy;
qring q   = std(i);
ideal i   = fetch(r,i);
module M  = [-x,y],[-y2,x],[x3];
module H  = Hom(M,i);
==> // dimension of Hom:  0
==> // vdim of Hom:       5
==> 
==> // given  F1 --M-> F0 -->M'--> 0 and  G1 --N-> G0 -->N'--> 0,
==> // show D = ker( Hom(F0,G0) --> Hom(F1,G0)/im(Hom(F1,G1)->Hom(F1,G0)) )
==> y,x, 0,
==> x,y2,x2
==> // show C = im ( Hom(F0,G1) --> Hom(F0,G0) )
==> -y3+x2,0,     xy,0,
==> 0,     -y3+x2,0, xy
==> 
print(H);
==> 0, x, 0,y2,0, 
==> y, 0, 0,-x,x2,
==> -1,-1,x,0, 0  
printlevel= 2;
list L    = Hom(M,i,1);"";
==> // dimension of Hom:  0
==> // vdim of Hom:       5
==> 
==> // given  F1 --M-> F0 -->M'--> 0 and  G1 --N-> G0 -->N'--> 0,
==> // show D = ker( Hom(F0,G0) --> Hom(F1,G0)/im(Hom(F1,G1)->Hom(F1,G0)) )
==> y,x, 0,
==> x,y2,x2
==> // show C = im ( Hom(F0,G1) --> Hom(F0,G0) )
==> -y3+x2,0,     xy,0,
==> 0,     -y3+x2,0, xy
==> 
==> // element 1 of kbase of Hom in Hom(F0,G0) as matrix: F0-->G0:
==> y2,xy
==> // element 2 of kbase of Hom in Hom(F0,G0) as matrix: F0-->G0:
==> y,x
==> // element 3 of kbase of Hom in Hom(F0,G0) as matrix: F0-->G0:
==> x2,xy2
==> // element 4 of kbase of Hom in Hom(F0,G0) as matrix: F0-->G0:
==> x,y2
==> // element 5 of kbase of Hom in Hom(F0,G0) as matrix: F0-->G0:
==> 0,x2
==> 
printlevel=1;
ring s    = 3,(x,y,z),(c,dp);
ideal i   = jacob(ideal(x2+y5+z4));
qring rq=std(i);
matrix M[2][2]=xy,x3,5y,4z,x2;
matrix N[3][2]=x2,x,y3,3xz,x2z,z;
print(M);
==> xy,x3,
==> -y,z  
print(N);
==> x2, x,
==> y3, 0,
==> x2z,z 
list l=Hom(M,N,1);
==> // dimension of Hom:  0
==> // vdim of Hom:       16
==> 
==> // given  F1 --M-> F0 -->M'--> 0 and  G1 --N-> G0 -->N'--> 0,
==> // show D = ker( Hom(F0,G0) --> Hom(F1,G0)/im(Hom(F1,G1)->Hom(F1,G0)) )
==> 0,0, 0,0, 0,   0,0,   1,
==> 0,0, 0,0, 0,   0,y3z2,0,
==> 0,0, 0,0, 0,   1,0,   0,
==> 0,0, 0,y3,y2z2,0,0,   0,
==> 0,0, 1,0, 0,   0,0,   0,
==> z,y3,0,0, 0,   0,0,   0 
==> // show C = im ( Hom(F0,G1) --> Hom(F0,G0) )
==> x2, 0,  x,0,
==> 0,  x2, 0,x,
==> y3, 0,  0,0,
==> 0,  y3, 0,0,
==> x2z,0,  z,0,
==> 0,  x2z,0,z 
==> 
==> // columns of matrix are kbase of Hom in Hom(F0,G0)
==> 0, 0, 0, 0,0,0,   0,   0,  0, 0,  0, 0,0, 0,0,0,   
==> 0, 0, 0, 0,0,0,   0,   0,  0, 0,  0, 0,0, 0,0,y3z2,
==> 0, 0, 0, 0,0,0,   y2z2,yz2,z2,y2z,yz,z,y2,y,1,0,   
==> 0, 0, 0, 0,0,y2z2,0,   0,  0, 0,  0, 0,0, 0,0,0,   
==> 0, y3,y2,y,1,0,   0,   0,  0, 0,  0, 0,0, 0,0,0,   
==> y3,0, 0, 0,0,0,   0,   0,  0, 0,  0, 0,0, 0,0,0    
printlevel = p;

D.4.3.9 homology
................
Procedure from library homolog.lib (see homolog_lib).

Usage:
homology(A,B,M,N);

Compute:
Let M and N be submodules of R^m and R^n presenting M'=R^m/M, N'=R^n/N
(R=basering) and let A,B matrices inducing maps
    R^k --A--> R^m --B--> R^n.
Compute a presentation of the module
    ker(B)/im(A) := ker(M'/im(A) --B--> N'/im(BM)+im(BA)).
If B induces a map M'->N' (i.e BM=0) and if im(A) is contained in
ker(B) (that is, BA=0) then ker(B)/im(A) is the homology of the
complex
    R^k--A-->M'--B-->N'. 

Return:
module H, a presentation of ker(B)/im(A).

Note:
homology returns a free module of rank m if ker(B)=im(A).

Example:
LIB "homolog.lib";
ring r;
ideal id=maxideal(4);
qring qr=std(id);
module N=maxideal(3)*freemodule(2);
module M=maxideal(2)*freemodule(2);
module B=[2x,0],[x,y],[z2,y];
module A=M;
module H=homology(A,B,M,N);
H=std(H);
// dimension of homology:
dim(H);
==> 0
// vector space dimension: 
vdim(H);
==> 19
ring s=0,x,ds;
qring qs=std(x4);
module A=[x];
module B=A;
module M=[x3];
module N=M;
homology(A,B,M,N);
==> _[1]=gen(1)

D.4.3.10 isCM
.............
Procedure from library homolog.lib (see homolog_lib).

Usage:
isCM(M); M module

Return:
1 if M'=coker(M) is Cohen-Macaulay;

0 if this is not the case.

Assume:
basering is local.

Example:
LIB "homolog.lib";
ring R=0,(x,y,z),ds;  // local ring R = Q[x,y,z]_<x,y,z>
module M=xz,yz,z2;   
isCM(M);             // test if R/<xz,yz,z2> is Cohen-Macaulay
==> 0
M=x2+y2,z7;          // test if R/<x2+y2,z7> is Cohen-Macaulay
isCM(M);
==> 1

D.4.3.11 isFlat
...............
Procedure from library homolog.lib (see homolog_lib).

Usage:
isFlat(M); M module

Return:
1 if M'=coker(M) is flat;

0 if this is not the case.

Example:
LIB "homolog.lib";
ring A = 0,(x,y),dp;
matrix M[3][3] = x-1,y,x,x,x+1,y,x2,xy+x+1,x2+y;
print(M);
==> x-1,y,     x,  
==> x,  x+1,   y,  
==> x2, xy+x+1,x2+y
isFlat(M);             // coker(M) is not flat over A=Q[x,y]
==> 0
qring B = std(x2+x-y);   // the ring B=Q[x,y]/<x2+x-y>
matrix M = fetch(A,M);
isFlat(M);             // coker(M) is flat over B
==> 1
setring A;
qring C = std(x2+x+y);   // the ring C=Q[x,y]/<x2+x+y>
matrix M = fetch(A,M);
isFlat(M);             // coker(M) is not flat over C
==> 0

D.4.3.12 isLocallyFree
......................
Procedure from library homolog.lib (see homolog_lib).

Usage:
isLocallyFree(M,r); M module, r int

Return:
1 if M'=coker(M) is locally free of constant rank r;

0 if this is not the case.

Example:
LIB "homolog.lib";
ring R=0,(x,y,z),dp;
matrix M[2][3];     // the presentation matrix
M=x-1,y-1,z,y-1,x-2,x;
ideal I=fitting(M,0); // 0-th Fitting ideal of coker(M)
qring Q=I;
matrix M=fetch(R,M);
isLocallyFree(M,1); // as R/I-module, coker(M) is locally free of rk 1
==> 1
isLocallyFree(M,0);
==> 0

D.4.3.13 isReg
..............
Procedure from library homolog.lib (see homolog_lib).

Usage:
isReg(I,M); I ideal, M module

Return:
1 if given (ordered) list of generators for I is coker(M)-sequence;

0 if this is not the case.

Example:
LIB "homolog.lib";
ring R = 0,(x,y,z),dp;
ideal I = x*(y-1),y,z*(y-1);
isReg(I,0);             // given list of generators is Q[x,y,z]-sequence
==> 1
I = x*(y-1),z*(y-1),y;  // change sorting of generators 
isReg(I,0);
==> 0
ring r = 0,(x,y,z),ds;  // local ring
ideal I=fetch(R,I);
isReg(I,0);             // result independent of sorting of generators
==> 1

D.4.3.14 kernel
...............
Procedure from library homolog.lib (see homolog_lib).

Usage:
kernel(A,M,N);

Compute:
Let M and N be submodules of R^m and R^n, presenting M'=R^m/M,
N'=R^n/N (R=basering), and let A:R^m->R^n be a matrix inducing a
map A':M'->N'. Then kernel(A,M,N); computes a presentation K of
ker(A') as in the commutative diagram:
          ker(A') --->  M' --A'--> N'
             |^         |^         |^
             |          |          |
             R^r  ---> R^m --A--> R^n
             |^         |^         |^
             |K         |M         |N
             |          |          |
             R^s  ---> R^p -----> R^q

Return:
module K, a presentation of ker(A':coker(M)->coker(N)).

Example:
LIB "homolog.lib";
ring r;
module N=[2x,x],[0,y];
module M=maxideal(1)*freemodule(2);
matrix A[2][2]=2x,0,x,y,z2,y;
module K=kernel(A,M,N);
// dimension of kernel:  
dim(std(K));
==> 0
// vector space dimension of kernel: 
vdim(std(K));
==> 2
print(K);
==> z,0,y,0,x,0,
==> 0,z,0,y,0,x 

D.4.3.15 kohom
..............
Procedure from library homolog.lib (see homolog_lib).

Usage:
kohom(A,k); A=matrix, k=integer

Return:
matrix Hom(R^k,A), i.e. let A be a matrix defining a map F1->F2
of free R-modules, then the matrix of Hom(R^k,F1)->Hom(R^k,F2)
is computed (R=basering).

Example:
LIB "homolog.lib";
ring r;
matrix n[2][3]=x,y,5,z,77,33;
print(kohom(n,3));
==> x,0,0,y, 0, 0, 5, 0, 0,
==> 0,x,0,0, y, 0, 0, 5, 0,
==> 0,0,x,0, 0, y, 0, 0, 5,
==> z,0,0,77,0, 0, 33,0, 0,
==> 0,z,0,0, 77,0, 0, 33,0,
==> 0,0,z,0, 0, 77,0, 0, 33

D.4.3.16 kontrahom
..................
Procedure from library homolog.lib (see homolog_lib).

Usage:
kontrahom(A,k); A=matrix, k=integer

Return:
matrix Hom(A,R^k), i.e. let A be a matrix defining a map F1->F2 of
free R-modules, then the matrix of Hom(F2,R^k)->Hom(F1,R^k) is
computed (R=basering).

Example:
LIB "homolog.lib";
ring r;
matrix n[2][3]=x,y,5,z,77,33;
print(kontrahom(n,3));
==> x,z, 0,0, 0,0, 
==> y,77,0,0, 0,0, 
==> 5,33,0,0, 0,0, 
==> 0,0, x,z, 0,0, 
==> 0,0, y,77,0,0, 
==> 0,0, 5,33,0,0, 
==> 0,0, 0,0, x,z, 
==> 0,0, 0,0, y,77,
==> 0,0, 0,0, 5,33 

D.4.3.17 KoszulHomology
.......................
Procedure from library homolog.lib (see homolog_lib).

Compute:
A presentation of the p-th Koszul homology module H_p(f_1,...,f_k;M'),
where M'=coker(M) and f_1,...,f_k are the given (ordered list
of generators of the) ideal I. The computed presentation is minimized
via prune. In particular, if H_p(f_1,...,f_k;M')=0 then the
return value is 0.

Return:
module H, s.th. coker(H) = H_p(f_1,...,f_k;M').

Note:
size of input ideal has to be <= 20.

Example:
LIB "homolog.lib";
ring R=0,x(1..3),dp;
ideal x=maxideal(1);
module M=0;
KoszulHomology(x,M,0);  // H_0(x,R), x=(x_1,x_2,x_3)
==> _[1]=x(3)*gen(1)
==> _[2]=x(2)*gen(1)
==> _[3]=x(1)*gen(1)
KoszulHomology(x,M,1);  // H_1(x,R), x=(x_1,x_2,x_3)
==> _[1]=0
qring S=std(x(1)*x(2));
module M=0;
ideal x=maxideal(1);
KoszulHomology(x,M,1);
==> _[1]=-x(3)*gen(1)
==> _[2]=-x(2)*gen(1)
==> _[3]=-x(1)*gen(1)
KoszulHomology(x,M,2);
==> _[1]=0

D.4.3.18 tensorMod
..................
Procedure from library homolog.lib (see homolog_lib).

Usage:
tensorMod(M,N); M,N modules

Compute:
presentation matrix A of the tensor product T of the modules
M'=coker(M), N'=coker(N): if matrix(M) defines a map M: R^r->R^s and
matrix(N) defines a map N: R^p->R^q, then A defines a presentation
         R^(sp+rq) --A-> R^(sq)  --> T --> 0 .

Return:
matrix A satisfying coker(A) = tensorprod(coker(M),coker(N)) .

Example:
LIB "homolog.lib";
ring A=0,(x,y,z),dp;
matrix M[3][3]=1,2,3,4,5,6,7,8,9;
matrix N[2][2]=x,y,0,z;
print(M);
==> 1,2,3,
==> 4,5,6,
==> 7,8,9 
print(N);
==> x,y,
==> 0,z 
print(tensorMod(M,N));
==> x,y,0,0,0,0,1,0,2,0,3,0,
==> 0,z,0,0,0,0,0,1,0,2,0,3,
==> 0,0,x,y,0,0,4,0,5,0,6,0,
==> 0,0,0,z,0,0,0,4,0,5,0,6,
==> 0,0,0,0,x,y,7,0,8,0,9,0,
==> 0,0,0,0,0,z,0,7,0,8,0,9 

D.4.3.19 Tor
............
Procedure from library homolog.lib (see homolog_lib).

Compute:
a presentation of Tor_k(M',N'), for k=v[1],v[2],... , where
M'=coker(M) and N'=coker(N): let
       0 <-- M' <-- G0 <-M-- G1                
       0 <-- N' <-- F0 <--N- F1 <-- F2 <--...  
be a presentation of M', resp. a free resolution of N', and consider
the commutative diagram
          0                    0                    0
          |^                   |^                   |^
  Tensor(M',Fk+1) -Ak+1-> Tensor(M',Fk) -Ak-> Tensor(M',Fk-1)
          |^                   |^                   |^
  Tensor(G0,Fk+1) -Ak+1-> Tensor(G0,Fk) -Ak-> Tensor(G0,Fk-1)
                               |^                   |^
                               |C                   |B
                          Tensor(G1,Fk) ----> Tensor(G1,Fk-1)

       (Ak,Ak+1 induced by N and B,C induced by M).
Let K=modulo(Ak,B), J=module(C)+module(Ak+1) and Tor=modulo(K,J),
then we have exact sequences
    R^p  --K-> Tensor(G0,Fk) --Ak-> Tensor(G0,Fk-1)/im(B),

    R^q -Tor-> R^p --K-> Tensor(G0,Fk)/(im(C)+im(Ak+1)). 
Hence, Tor presents Tor_k(M',N').

Return:
- if v is of type int: module Tor, a presentation of Tor_k(M',N');

- if v is of type intvec: a list of Tor_k(M',N') (k=v[1],v[2],...);

- in case of a third argument of any type: list l with
     l[1] = module Tor/list of Tor_k(M',N'),
     l[2] = SB of Tor/list of SB of Tor_k(M',N'),
     l[3] = matrix/list of matrices, each representing a kbase of Tor_k(M',N')
                (if finite dimensional), or 0.

Display:
printlevel >=0: (affine) dimension of Tor_k for each k (default).

 printlevel >=1: matrices Ak, Ak+1 and kbase of Tor_k in Tensor(G0,Fk)
(if finite dimensional).

Note:
In order to compute Tor_k(M,N) use the command Tor(k,syz(M),syz(N));
or: list P=mres(M,2); list Q=mres(N,2); Tor(k,P[2],Q[2]);

Example:
LIB "homolog.lib";
int p      = printlevel;
printlevel = 1;
ring r     = 0,(x,y),dp;
ideal i    = x2,y;
ideal j    = x;
list E     = Tor(0..2,i,j);    // Tor_k(r/i,r/j) for k=0,1,2 over r
==> // dimension of Tor_0:  0
==> // vdim of Tor_0:       1
==> 
==> // Computing Tor_1 (help Tor; gives an explanation):
==> // Let 0 <- coker(M) <- G0 <-M- G1 be the present. of coker(M),
==> // and 0 <- coker(N) <- F0 <-N- F1 <- F2 <- ... a resolution of
==> // coker(N), then Tensor(G0,F1)-->Tensor(G0,F0) is given by:
==> x
==> // and Tensor(G0,F2) + Tensor(G1,F1)-->Tensor(G0,F1) is given by:
==> 0,x2,y
==> 
==> // dimension of Tor_1:  0
==> // vdim of Tor_1:       1
==> 
==> // Computing Tor_2 (help Tor; gives an explanation):
==> // Let 0 <- coker(M) <- G0 <-M- G1 be the present. of coker(M),
==> // and 0 <- coker(N) <- F0 <-N- F1 <- F2 <- ... a resolution of
==> // coker(N), then Tensor(G0,F2)-->Tensor(G0,F1) is given by:
==> 0
==> // and Tensor(G0,F3) + Tensor(G1,F2)-->Tensor(G0,F2) is given by:
==> 1,x2,y
==> 
==> // dimension of Tor_2:  -1
==> 
qring R    = std(i);
ideal j    = fetch(r,j);
module M   = [x,0],[0,x];
printlevel = 2;
module E1  = Tor(1,M,j);       // Tor_1(R^2/M,R/j) over R=r/i
==> // Computing Tor_1 (help Tor; gives an explanation):
==> // Let 0 <- coker(M) <- G0 <-M- G1 be the present. of coker(M),
==> // and 0 <- coker(N) <- F0 <-N- F1 <- F2 <- ... a resolution of
==> // coker(N), then Tensor(G0,F1)-->Tensor(G0,F0) is given by:
==> x,0,
==> 0,x 
==> // and Tensor(G0,F2) + Tensor(G1,F1)-->Tensor(G0,F1) is given by:
==> x,0,x,0,
==> 0,x,0,x 
==> 
==> // dimension of Tor_1:  0
==> // vdim of Tor_1:       2
==> 
list l     = Tor(3,M,M,1);     // Tor_3(R^2/M,R^2/M) over R=r/i
==> // Computing Tor_3 (help Tor; gives an explanation):
==> // Let 0 <- coker(M) <- G0 <-M- G1 be the present. of coker(M),
==> // and 0 <- coker(N) <- F0 <-N- F1 <- F2 <- ... a resolution of
==> // coker(N), then Tensor(G0,F3)-->Tensor(G0,F2) is given by:
==> x,0,0,0,
==> 0,x,0,0,
==> 0,0,x,0,
==> 0,0,0,x 
==> // and Tensor(G0,F4) + Tensor(G1,F3)-->Tensor(G0,F3) is given by:
==> x,0,0,0,x,0,0,0,
==> 0,x,0,0,0,x,0,0,
==> 0,0,x,0,0,0,x,0,
==> 0,0,0,x,0,0,0,x 
==> 
==> // dimension of Tor_3:  0
==> // vdim of Tor_3:       4
==> 
==> // columns of matrix are kbase of Tor_3 in Tensor(G0,F3)
==> 1,0,0,0,
==> 0,1,0,0,
==> 0,0,1,0,
==> 0,0,0,1 
==> 
printlevel = p;
D.4.4 mprimdec_lib
------------------
Library:
mprimdec.lib
Purpose:
   procedures for primary decomposition of modules
Authors:
Alexander Dreyer, dreyer@mathematik.uni-kl.de; adreyer@web.de

Remark:
These procedures are implemented to be used in characteristic 0.

They also work in positive characteristic >> 0.

In small characteristic and for algebraic extensions, the
procedures via Gianni, Trager, Zacharias may not terminate.


Procedures:
* separator:: computes a list of separators of prime ideals
* PrimdecA:: (not necessarily minimal) primary decomposition via Shimoyama/Yokoyama (suggested by Graebe)
* PrimdecB:: (not necessarily minimal) primary decomposition for pseudo-primary ideals
* modDec:: minimal primary decomposition via Shimoyama/Yokoyama (suggested by Graebe)
* zeroMod:: minimal zero-dimensional primary decomposition via Gianni, Trager and Zacharias
* GTZmod:: minimal primary decomposition via Gianni, Trager and Zacharias
* dec1var:: primary decomposition for one variable
* annil:: the annihilator of M/N in the basering
* splitting:: splitting to simpler modules
* primTest:: tests whether i is prime or homogeneous
* preComp:: enhanced Version of splitting
* indSet:: lists with varstrings of(in)dependent variables
* GTZopt:: a faster version of GTZmod
* zeroOpt:: a faster version of zeroMod
* clrSBmod:: extracts an minimal SB from a SB
* minSatMod:: minimal saturation of N w.r.t. I
* specialModulesEqual:: checks for equality of standard bases of modules if N1 is contained in N2 or vice versa
* stdModulesEqual:: checks for equality of standard bases
* modulesEqual:: checks for equality of modules
* getData:: extracts oldData and computes the remaining data

D.4.4.1 separator
.................
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
separator(l); list l of prime ideals

Return:
list sepList;

a list of separators of the prime ideals in l,

i.e. polynomials p_ij, s.th. p_ij is in l[j],

for all l[j] not contained in l[i]

but p_ij is not in l[i]

Example:
LIB "mprimdec.lib";
ring r=0,(x,y,z),dp;
ideal i=(x2y,xz2,y2z,z3);
list l=minAssGTZ(i);
list sepL=separator(l);
sepL;
==> [1]:
==>    x
==> [2]:
==>    y

D.4.4.2 PrimdecA
................
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
PrimdecA (N[, i]); module N, int i

Return:
list l

a (not necessarily minimal) primary decomposition of N
computed by a generalized version of

the algorithm of Schimoyama/Yokoyama,

if i=1 is given, the factorizing Groebner is used

to compute the isolated primes.

Example:
LIB "mprimdec.lib";
ring r=0,(x,y,z),dp;
module N=x*gen(1)+ y*gen(2),
x*gen(1)-x2*gen(2);
list l=PrimdecA(N);
l;
==> [1]:
==>    [1]:
==>       _[1]=x*gen(1)+y*gen(2)
==>       _[2]=x*gen(2)-gen(1)
==>    [2]:
==>       _[1]=x2+y
==> [2]:
==>    [1]:
==>       _[1]=gen(2)
==>       _[2]=x*gen(1)
==>    [2]:
==>       _[1]=x
==> [3]:
==>    [1]:
==>       _[1]=y*gen(1)
==>       _[2]=y*gen(2)
==>       _[3]=x*gen(1)
==>       _[4]=x*gen(2)
==>    [2]:
==>       _[1]=y
==>       _[2]=x

D.4.4.3 PrimdecB
................
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
PrimdecB (N, p); pseudo-primary module N, isolated prime ideal p

Return:
list l

a (not necessarily minimal) primary decomposition of N

Example:
LIB "mprimdec.lib";
ring r=0,(x,y,z),dp;
module N=y*gen(1),y2*gen(2),yz*gen(2),yx*gen(2);
ideal p=y;
list l=PrimdecB(N,p);
l;
==> [1]:
==>    [1]:
==>       _[1]=y*gen(1)
==>       _[2]=y*gen(2)
==>    [2]:
==>       _[1]=y
==> [2]:
==>    [1]:
==>       _[1]=y*gen(1)
==>       _[2]=y*gen(2)
==>       _[3]=x*gen(1)
==>       _[4]=x*gen(2)
==>    [2]:
==>       _[1]=y
==>       _[2]=x
==> [3]:
==>    [1]:
==>       _[1]=z*gen(1)
==>       _[2]=z*gen(2)
==>       _[3]=y*gen(1)
==>       _[4]=x*gen(1)
==>       _[5]=x*gen(2)
==>       _[6]=y2*gen(2)
==>    [2]:
==>       _[1]=z
==>       _[2]=y
==>       _[3]=x

D.4.4.4 modDec
..............
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
modDec (N[, i]); module N, int i

Return:
list l

a minimal primary decomposition of N

computed by an generalized version of

the algorithm of Schimoyama/Yokoyama,

if i=1 is given, the factorizing Groebner is used

Example:
LIB "mprimdec.lib";
ring r=0,(x,y,z),dp;
module N=x*gen(1)+ y*gen(2),
x*gen(1)-x2*gen(2);
list l=modDec(N);
l;
==> [1]:
==>    [1]:
==>       _[1]=x*gen(1)+y*gen(2)
==>       _[2]=x*gen(2)-gen(1)
==>    [2]:
==>       _[1]=x2+y
==> [2]:
==>    [1]:
==>       _[1]=gen(2)
==>       _[2]=x*gen(1)
==>    [2]:
==>       _[1]=x

D.4.4.5 zeroMod
...............
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
zeroMod (N[, check]); zero-dimensional module N[, module check]

Return:
list l

the minimal primary decomposition of a zero-dimensional module N,
computed by a generalized version of the algorithm

of Gianni, Trager and Zacharias

Note:
if the parameter check is given, only components

not containing check are computed

Example:
LIB "mprimdec.lib";
ring r=0,z,dp;
module N=z*gen(1),(z-1)*gen(2),(z+1)*gen(3);
list l=zeroMod(N);
==> 2
l;
==> [1]:
==>    [1]:
==>       _[1]=gen(1)
==>       _[2]=gen(3)
==>       _[3]=z*gen(2)-gen(2)
==>    [2]:
==>       _[1]=z-1
==> [2]:
==>    [1]:
==>       _[1]=gen(2)
==>       _[2]=gen(3)
==>       _[3]=z*gen(1)
==>    [2]:
==>       _[1]=z
==> [3]:
==>    [1]:
==>       _[1]=gen(1)
==>       _[2]=gen(2)
==>       _[3]=z*gen(3)+gen(3)
==>    [2]:
==>       _[1]=z+1

D.4.4.6 GTZmod
..............
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
GTZmod (N[, check]); module N[, module check]

Return:
list l

the minimal primary decomposition of the module N,

computed by a generalized version of the algorithm

of Gianny, Trager and Zacharias

Note:
if the parameter check is given, only components

not containing check are computed

Example:
LIB "mprimdec.lib";
ring r=0,(x,y,z),dp;
module N=x*gen(1)+ y*gen(2),
x*gen(1)-x2*gen(2);
list l=GTZmod(N);
==> 2
l;
==> [1]:
==>    [1]:
==>       _[1]=x*gen(1)+y*gen(2)
==>       _[2]=x*gen(2)-gen(1)
==>    [2]:
==>       _[1]=x2+y
==> [2]:
==>    [1]:
==>       _[1]=gen(2)
==>       _[2]=x*gen(1)
==>    [2]:
==>       _[1]=x

D.4.4.7 dec1var
...............
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
dec1var (N); zero-dimensional module N[, module check]

Return:
list l

the minimal primary decomposition of a submodule N of R^s
if nvars(R)=1

Note:
if the parameter check is given, only components

not containing check are computed

Example:
LIB "mprimdec.lib";
ring r=0,z,dp;
module N=z*gen(1),(z-1)*gen(2),(z+1)*gen(3);
list l=dec1var(N);
l;
==> [1]:
==>    [1]:
==>       _[1]=gen(1)
==>       _[2]=gen(3)
==>       _[3]=z*gen(2)-gen(2)
==>    [2]:
==>       _[1]=z-1
==> [2]:
==>    [1]:
==>       _[1]=gen(2)
==>       _[2]=gen(3)
==>       _[3]=z*gen(1)
==>    [2]:
==>       _[1]=z
==> [3]:
==>    [1]:
==>       _[1]=gen(1)
==>       _[2]=gen(2)
==>       _[3]=z*gen(3)+gen(3)
==>    [2]:
==>       _[1]=z+1

D.4.4.8 annil
.............
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
annil(N); module N

Return:
ideal ann=std(quotient(N,freemodule(nrows(N))));

the annihilator of M/N in the basering

Note:
ann is a std basis in the basering

Example:
LIB "mprimdec.lib";
ring r=0,(x,y,z),dp;
module N=x*gen(1), y*gen(2);
ideal ann=annil(N);
ann;
==> ann[1]=xy

D.4.4.9 splitting
.................
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
splitting(N[,check[, ann]]); module N, module check, ideal ann

Return:
(l, check) list l, module check

the elements of l consists of a triple with

[1] of type module [2] and [3] of type ideal

s.th. the intersection of the modules is equal to the
zero-dimensional module N, furthermore l[j][3]=annil(l[j][1])
if l[j][2]!=0 then the module l[j][1] is primary

with associated prime l[j][2],

and check=intersect(check, l[j][1]) is computed

Note:
if the parameter check is given, only components not containing
check are computed; if ann is given, ann is used instead of annil(N)

Example:
LIB "mprimdec.lib";
ring r=0,z,lp;
module N=z*gen(1), (z+1)*gen(2);
N=std(N);
list l; module check;
(l, check)=splitting(N);
l;
==> [1]:
==>    [1]:
==>       _[1]=gen(2)
==>       _[2]=z*gen(1)
==>    [2]:
==>       _[1]=z
==>    [3]:
==>       _[1]=z
==>    [4]:
==>       _[1]=z
==> [2]:
==>    [1]:
==>       _[1]=gen(1)
==>       _[2]=z*gen(2)+gen(2)
==>    [2]:
==>       _[1]=z+1
==>    [3]:
==>       _[1]=z+1
==>    [4]:
==>       _[1]=z+1
check;
==> check[1]=z*gen(2)+gen(2)
==> check[2]=z*gen(1)

D.4.4.10 primTest
.................
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
primTest(i[, p]); a zero-dimensional ideal i, irreducible poly p in i

Return:
if i neither is prime nor is homogeneous then ideal(0) is returned,
else radical(i)

Example:
LIB "mprimdec.lib";
ring r=0,(x,y,z),lp;
ideal i=x+1,y-1,z;
i=std(i);
ideal primId=primTest(i,z);
primId;
==> primId[1]=z
==> primId[2]=y-1
==> primId[3]=x+1
i=x,z2,yz,y2;
i=std(i);
primId=primTest(i);
primId;
==> primId[1]=x
==> primId[2]=y
==> primId[3]=z

D.4.4.11 preComp
................
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
preComp(N,check[, ann]); module N, module check, ideal ann

Return:
(l, check) list l, module check

the elements of l consists of a triple with

[1] of type module [2] and [3] of type ideal

s.th. the intersection of the modules is equal to the
zero-dimensional module N, furthermore l[j][3]=annil(l[j][1])
if l[j][2]!=0 then the module l[j][1] is primary

with associated prime l[j][2],

and check=intersect(check, l[j][1]) is computed

Note:
only components not containing check are computed;

if ann is given, ann is used instead of annil(N)

Example:
LIB "mprimdec.lib";
ring r=0,z,lp;
module N=z*gen(1), (z+1)*gen(2);
N=std(N);
list l; module check;
(l, check)=preComp(N,freemodule(2));
l;
==> [1]:
==>    [1]:
==>       _[1]=z*gen(1)
==>       _[2]=gen(2)
==>    [2]:
==>       _[1]=z
==>    [3]:
==>       _[1]=z
==> [2]:
==>    [1]:
==>       _[1]=gen(1)
==>       _[2]=z*gen(2)+gen(2)
==>    [2]:
==>       _[1]=z+1
==>    [3]:
==>       _[1]=z+1
check;
==> check[1]=z*gen(1)
==> check[2]=z*gen(2)+gen(2)

D.4.4.12 indSet
...............
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
indSet(i); i ideal

Return:
list with two entrees

both are lists of new varstrings with the dependent variables
the independent set, the ordstring with the corresp. block ordering,
and the integer where the independent set starts in the varstring

Note:
the first entry gives the strings for all maximal independent sets
the second gives the strings for the independent sets,

which cannot be enhanced

Example:
LIB "mprimdec.lib";
ring s1=(0,x,y),(a,b,c,d,e,f,g),lp;
ideal i=ea-fbg,fa+be,ec-fdg,fc+de;
i=std(i);
list  l=indSet(i);
l;
==> [1]:
==>    [1]:
==>       [1]:
==>          e,f
==>       [2]:
==>          a,b,c,d,g
==>       [3]:
==>          (C,dp(2),dp)
==>       [4]:
==>          5
==> [2]:
==>    [1]:
==>       [1]:
==>          a,b,c,d
==>       [2]:
==>          e,f,g
==>       [3]:
==>          (C,dp(4),dp)
==>       [4]:
==>          3
==>    [2]:
==>       [1]:
==>          a,c,e
==>       [2]:
==>          b,d,f,g
==>       [3]:
==>          (C,dp(3),dp)
==>       [4]:
==>          4

D.4.4.13 GTZopt
...............
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
GTZopt (N[, check]); module N[, module check]

Return:
list l

the minimal primary decomposition of the module N,

computed by a generalized and optimized version of

the algorithm of Gianny, Trager and Zacharias

Note:
if the parameter check is given, only components

not containing check are computed

Example:
LIB "mprimdec.lib";
ring r=0,(x,y,z),dp;
module N=x*gen(1)+ y*gen(2),
x*gen(1)-x2*gen(2);
list l=GTZopt(N);
l;
==> [1]:
==>    [1]:
==>       _[1]=x*gen(1)+y*gen(2)
==>       _[2]=x*gen(2)-gen(1)
==>    [2]:
==>       _[1]=x2+y
==> [2]:
==>    [1]:
==>       _[1]=gen(2)
==>       _[2]=x*gen(1)
==>    [2]:
==>       _[1]=x

D.4.4.14 zeroOpt
................
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
zeroOpt (N[, check]); zero-dimensional module N[, module check]

Return:
list l

the minimal primary decomposition of a zero-dimensional module N,
computed by a generalized and optimized version of the algorithm
of Gianny, Trager and Zacharias

Note:
if the parameter check is given, only components

not containing check are computed

Example:
LIB "mprimdec.lib";
ring r=0,z,dp;
module N=z*gen(1),(z-1)*gen(2),(z+1)*gen(3);
list l=zeroOpt(N);
l;
==> [1]:
==>    [1]:
==>       _[1]=gen(1)
==>       _[2]=z*gen(2)-gen(2)
==>       _[3]=gen(3)
==>    [2]:
==>       _[1]=z-1
==> [2]:
==>    [1]:
==>       _[1]=z*gen(1)
==>       _[2]=gen(2)
==>       _[3]=gen(3)
==>    [2]:
==>       _[1]=z
==> [3]:
==>    [1]:
==>       _[1]=gen(1)
==>       _[2]=gen(2)
==>       _[3]=z*gen(3)+gen(3)
==>    [2]:
==>       _[1]=z+1

D.4.4.15 clrSBmod
.................
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
clrSBmod(N); N module which is SB ordered by monomial ordering

Return:
module = minimal SB

Example:
LIB "mprimdec.lib";
ring  r = (0,a,b),(x,y,z),dp;
module N1=ax2+y,a2x+y,bx;
module N2=clrSBmod(N1);
N2;
==> N2[1]=(a)*x2*gen(1)+y*gen(1)
==> N2[2]=(b)*x*gen(1)

D.4.4.16 minSatMod
..................
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
minSatMod(N, I); module N, ideal I

Return:
list with 2 elements:

[1]=sat(N,product(I))[1],

[2]=p, the polynomial of minimal degree s.th. [1]=quotient(N,p)

Example:
LIB "mprimdec.lib";
ring  r = 0,(x,y,z),dp;
module N=xy*gen(1);
ideal h=yz,z2;
list l=minSatMod(N,h);
l;
==> [1]:
==>    _[1]=x*gen(1)
==> [2]:
==>    y

D.4.4.17 specialModulesEqual
............................
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
specialModulesEqual(N1, N2) N1, N2 standard bases of modules,
s.th. N1 is contained in N2 or vice versa

Return:
int i

if (N1==N2) then i=1

else i=0

Example:
LIB "mprimdec.lib";
ring  r = 0,(x,y,z),dp;
module N1=x*freemodule(2);
module N2=xy*freemodule(2);
int i=specialModulesEqual(N1,N2);
i;
==> 0
N2=N1;
i=specialModulesEqual(N1,N2);
i;
==> 1

D.4.4.18 stdModulesEqual
........................
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
stdModulesEqual(N1, N2) N1, N2 standard bases of modules,

Return:
int i

if (N1==N2) then i=1

else i=0

Example:
LIB "mprimdec.lib";
ring  r = 0,(x,y,z),dp;
module N1=x*freemodule(2);
module N2=xy*freemodule(2);
int i=stdModulesEqual(N1,N2);
i;
==> 0
N2=N1;
i=stdModulesEqual(N1,N2);
i;
==> 1

D.4.4.19 modulesEqual
.....................
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
modulesEqual(N1, N2) N1, N2 modules,

Return:
int i

if (N1==N2) then i=1

else i=0

Example:
LIB "mprimdec.lib";
ring  r = 0,(x,y,z),dp;
module N1=x*freemodule(2);
module N2=xy*freemodule(2);
int i=modulesEqual(N1,N2);
i;
==> 0
N2=N1;
i=modulesEqual(N1,N2);
i;
==> 1

D.4.4.20 getData
................
Procedure from library mprimdec.lib (see mprimdec_lib).

Usage:
getData(N, l[, noCheck]); module N, list l[, int noCheck]

Return:
(ann, check, M, checked)

ideal ann, module check, M, int checked

if l[1] is contained in N [and noCheck is not given]

then checked=1, ann=ideal(0), check=0, M=0;

else checked=0, M=freemodule(nrows(N)); check=l[1]

(resp. check=M if l is an empty list) and

if size(l)>1 then ann=l[2] else ann is the annihilator of M/N.

Note:
ann is a std basis in the basering

Example:
LIB "mprimdec.lib";
ring  r = 0,(x,y,z),lp;
module N=x*gen(1),y*gen(2);
N=std(N);
ideal ann; module check, M; int checked; list l;
(ann, check, M, checked)=getData(N,l);
ann; check; M; checked;
==> ann[1]=xy
==> check[1]=gen(1)
==> check[2]=gen(2)
==> M[1]=gen(1)
==> M[2]=gen(2)
==> 0
l=list(check,ann);
(ann, check, M, checked)=getData(N,l);
ann; check; M; checked;
==> ann[1]=xy
==> check[1]=gen(1)
==> check[2]=gen(2)
==> M[1]=gen(1)
==> M[2]=gen(2)
==> 0
l=list(N);
(ann, check, M, checked)=getData(N,l);
ann; check; M; checked;
==> ann[1]=0
==> check[1]=0
==> M[1]=0
==> 1
D.4.5 mregular_lib
------------------
Library:
mregular.lib
Purpose:
   Castelnuovo-Mumford Regularity of CM-Schemes and Curves
Authors:
I.Bermejo, ibermejo@ull.es

 Ph.Gimenez, pgimenez@agt.uva.es

 G.-M.Greuel, greuel@mathematik.uni-kl.de

Overview:
A library for computing the Castelnuovo-Mumford regularity of a subscheme of
the projective n-space that DOES NOT require the computation of a minimal
graded free resolution of the saturated ideal defining the subscheme.
The procedures are based on two papers by Isabel Bermejo and Philippe Gimenez:
'On Castelnuovo-Mumford regularity of projective curves' Proc.Amer.Math.Soc.
128(5) (2000), and 'Computing the Castelnuovo-Mumford regularity of some
subschemes of Pn using quotients of monomial ideals', Proceedings of
MEGA-2000, J. Pure Appl. Algebra (to appear).

The algorithm assumes the variables to be in Noether position.


Procedures:
* reg_CM:: regularity of arith. C-M subscheme V(id_sat) of Pn
* reg_curve:: regularity of projective curve V(id_sat) in Pn
* reg_moncurve:: regularity of projective monomial curve defined by li

D.4.5.1 reg_CM
..............
Procedure from library mregular.lib (see mregular_lib).

Usage:
reg_CM (i); i ideal

Return:
an integer, the Castelnuovo-Mumford regularity of i-sat.

Assume:
i is a homogeneous ideal of the basering S=K[x(0)..x(n)] where
the field K is infinite, and S/i-sat is Cohen-Macaulay.
Assume that K[x(n-d),...,x(n)] is a Noether normalization of S/i-sat
where d=dim S/i -1. If this is not the case, compute a Noether
normalization e.g. by using the proc noetherNormal from algebra.lib.

Note:
The output is reg(X)=reg(i-sat) where X is the arithmetically
Cohen-Macaulay subscheme of the projective n-space defined by i.
If printlevel > 0 (default = 0) additional information is displayed.
In particular, the value of the regularity of the Hilbert function of
S/i-sat is given.

Example:
LIB "mregular.lib";
ring s=0,x(0..5),dp;
ideal i=x(2)^2-x(4)*x(5),x(1)*x(2)-x(0)*x(5),x(0)*x(2)-x(1)*x(4),
x(1)^2-x(3)*x(5),x(0)*x(1)-x(2)*x(3),x(0)^2-x(3)*x(4);
reg_CM(i);
==> 2
// Additional information can be obtained as follows:
printlevel = 1;
reg_CM(i);
==> // Ideal i of S defining an arithm. Cohen-Macaulay subscheme X of P5:
==> //   - dimension of X: 2
==> //   - i is saturated: YES
==> //   - regularity of the Hilbert function of S/i-sat: -1
==> //   - time for computing reg(X): 0 sec.
==> // Castelnuovo-Mumford regularity of X:
==> 2

D.4.5.2 reg_curve
.................
Procedure from library mregular.lib (see mregular_lib).

Usage:
reg_curve (i[,e]); i ideal, e integer

Return:
an integer, the Castelnuovo-Mumford regularity of i-sat.

Assume:
i is a homogeneous ideal of the basering S=K[x(0)..x(n)] where
the field K is infinite, and it defines a projective curve C in
the projective n-space (dim(i)=2). We assume that K[x(n-1),x(n)]
is a Noether normalization of S/i-sat.

e=0: (default)

Uses a random choice of an element of K when it is necessary.
This is absolutely safe (if the element is bad, another random
choice will be done until a good element is found).

e=1: Substitutes the random choice of an element of K by a simple
transcendental field extension of K.

Note:
The output is the integer reg(C)=reg(i-sat).

If printlevel > 0 (default = 0) additional information is displayed.
In particular, says if C is arithmetically Cohen-Macaulay or not,
determines in which step of a minimal graded free resolution of i-sat
the regularity of C is attained, and sometimes gives the value of the
regularity of the Hilbert function of S/i-sat (otherwise, an upper
bound is given).

Example:
LIB "mregular.lib";
ring s = 0,(x,y,z,t),dp;
// 1st example is Ex.2.5 in [Bermejo-Gimenez], Proc.Amer.Math.Soc. 128(5):
ideal i  = x17y14-y31, x20y13, x60-y36z24-x20z20t20;
reg_curve(i);
==> 72
// 2nd example is Ex.2.9 in [Bermejo-Gimenez], Proc.Amer.Math.Soc. 128(5):
int k=43;
ideal j=x17y14-y31,x20y13,x60-y36z24-x20z20t20,y41*z^k-y40*z^(k+1);
reg_curve(j);
==> 93
// Additional information can be obtained as follows:
printlevel = 1;
reg_curve(j);
==> // Ideal i of S defining a projective curve C in P3:
==> //   - i is saturated: YES
==> //   - C is arithm. Cohen-Macaulay: NO
==> //   - reg(C) attained at the last step of a m.g.f.r. of i-sat: YES
==> //   - regularity of the Hilbert function of S/i-sat: 92
==> //   - time for computing reg(C): 0 sec.
==> // Castelnuovo-Mumford regularity of C:
==> 93

D.4.5.3 reg_moncurve
....................
Procedure from library mregular.lib (see mregular_lib).

Usage:
reg_moncurve (a0,...,an) ; ai integers with a0=0 < a1 < ... < an=:d

Return:
an integer, the Castelnuovo-Mumford regularity of the projective
monomial curve C in Pn parametrically defined by:

x(0)=t^d , x(1)=s^(a1)t^(d-a1), ... , x(n)=s^d.

Assume:
a0=0 < a1 < ... < an are integers and the base field is infinite.

Note:
The defining ideal I(C) in S is determined using elimination.
The procedure reg_curve is improved in this case since one
knows beforehand that the dimension is 2, that the variables are
in Noether position, that I(C) is prime.

If printlevel > 0 (default = 0) additional information is displayed.
In particular, says if C is arithmetically Cohen-Macaulay or not,
determines in which step of a minimal graded free resolution of I(C)
the regularity is attained, and sometimes gives the value of the
regularity of the Hilbert function of S/I(C) (otherwise, an upper
bound is given).

Example:
LIB "mregular.lib";
// The 1st example is the twisted cubic:
reg_moncurve(0,1,2,3);
==> 2
// The 2nd. example is the non arithm. Cohen-Macaulay monomial curve in P4
// parametrized by: x(0)-s6,x(1)-s5t,x(2)-s3t3,x(3)-st5,x(4)-t6:
reg_moncurve(0,1,3,5,6);
==> 3
// Additional information can be obtained as follows:
printlevel = 1;
reg_moncurve(0,1,3,5,6);
==> // Sequence of integers defining a monomial curve C in P4:
==> //   - time for computing ideal I(C) of S (elimination): 0 sec.
==> //   - C is arithm. Cohen-Macaulay: NO
==> //   - reg(C) attained at the last step of a m.g.f.r. of I(C): YES
==> //   - reg(C) attained at the second last step of a m.g.f.r. of I(C): YES
==> //   - regularity of the Hilbert function of S/I(C): 2
==> //   - time for computing reg(C): 0 sec.
==> // Castelnuovo-Mumford regularity of C:
==> 3
D.4.6 normal_lib
----------------
Library:
normal.lib
Purpose:
     Normalization of Affine Rings
Authors:
G.-M. Greuel, greuel@mathematik.uni-kl.de,

 G. Pfister, pfister@mathematik.uni-kl.de


Main procedures:
* normal:: computes the normalization of basering/I, resp. computes the normalization of basering/I and the delta invariant
* HomJJ:: presentation of End_R(J) as affine ring, L a list
* genus:: computes genus of the projective curve defined by I
Auxiliary procedure:
* deltaLoc:: (sum of) delta invariant(s) at conjugated singular points

D.4.6.1 normal
..............
Procedure from library normal.lib (see normal_lib).

Usage:
normal(i [,choose]); i a radical ideal, choose empty, 1 or "wd"
if choose=1 the normalization of the associated primes is computed
(which is sometimes more efficient);
if choose="wd" the delta invariant is computed
simultaneously; this may take much more time in the reducible case,
since the factorizing standard basis algorithm cannot be used.

Assume:
The ideal must be radical, for non-radical ideals the output may
be wrong (i=radical(i); makes i radical)

Return:
a list of rings, say nor and in case of choose="wd" an
integer at the end of the list.
Each ring nor[i] contains two ideals with given names
norid and normap such that

- the direct sum of the rings nor[i]/norid is the
normalization of basering/id;

- normap gives the normalization map from basering/id to
nor[i]/norid (for each i).

Note:
to use the i-th ring type: def R=nor[i]; setring R;.

 Increasing printlevel displays more comments (default: printlevel=0).

 Not implemented for local or mixed orderings.

 If the input ideal i is weighted homogeneous a weighted ordering may
be used (qhweight(i); computes weights).

Example:
LIB "normal.lib";
ring r=32003,(x,y,z),wp(2,1,2);
ideal i=z3-xy4;
list nor=normal(i);
==> 
==> // 'normal' created a list of 1 ring(s).
==> // nor[1+1] is the delta-invariant in case of choose=wd.
==> // To see the rings, type (if the name of your list is nor):
==>      show( nor);
==> // To access the 1-st ring and map (similar for the others), type:
==>      def R = nor[1]; setring R;  norid; normap;
==> // R/norid is the 1-st ring of the normalization and
==> // normap the map from the original basering to R/norid
show(nor);
==> // list, 1 element(s):
==> [1]:
==>    // ring: (32003),(T(1),T(2),T(3)),(a(2,1,1),dp(3),C);
==>    // minpoly = 0
==> // objects belonging to this ring:
==> // normap               [0]  ideal, 3 generator(s)
==> // norid                [0]  ideal, 1 generator(s)
def r1=nor[1];
setring r1;
norid;
==> norid[1]=T(3)3-T(1)T(2)
normap;
==> normap[1]=T(1)
==> normap[2]=T(2)
==> normap[3]=T(2)T(3)
ring s=0,(x,y),dp;
ideal i=(x-y^2)^2 - y*x^3;
nor=normal(i,"wd");
==> 
==> // 'normal' created a list of 1 ring(s).
==> // nor[1+1] is the delta-invariant in case of choose=wd.
==> // To see the rings, type (if the name of your list is nor):
==>      show( nor);
==> // To access the 1-st ring and map (similar for the others), type:
==>      def R = nor[1]; setring R;  norid; normap;
==> // R/norid is the 1-st ring of the normalization and
==> // normap the map from the original basering to R/norid
//the delta-invariant
nor[size(nor)];
==> 3

D.4.6.2 HomJJ
.............
Procedure from library normal.lib (see normal_lib).

Usage:
HomJJ (Li); Li = list: ideal SBid, ideal id, ideal J, poly p

Assume:
R = P/id, P = basering, a polynomial ring, id an ideal of P,

 SBid = standard basis of id,

 J = ideal of P containing the polynomial p,

 p = nonzero divisor of R

Compute:
Endomorphism ring End_R(J)=Hom_R(J,J) with its ring structure as
affine ring, together with the canonical map R -> Hom_R(J,J),
where R is the quotient ring of P modulo the standard basis SBid.

Return:
a list l of two objects
         l[1] : a polynomial ring, containing two ideals, 'endid' and 'endphi'
               such that l[1]/endid = Hom_R(J,J) and
               endphi describes the canonical map R -> Hom_R(J,J)
         l[2] : an integer which is 1 if phi is an isomorphism, 0 if not
         l[3] : an integer, the contribution to delta

Note:
printlevel >=1: display comments (default: printlevel=0)

Example:
LIB "normal.lib";
ring r   = 0,(x,y),wp(2,3);
ideal id = y^2-x^3;
ideal J  = x,y;
poly p   = x;
list Li = std(id),id,J,p;
list L   = HomJJ(Li);
def end = L[1];    // defines ring L[1], containing ideals endid, endphi
setring end;       // makes end the basering
end;
==> //   characteristic : 0
==> //   number of vars : 1
==> //        block   1 : ordering dp
==> //                  : names    T(1) 
==> //        block   2 : ordering C
endid;             // end/endid is isomorphic to End(r/id) as ring
==> endid[1]=0
map psi = r,endphi;// defines the canonical map r/id -> End(r/id)
psi;
==> psi[1]=T(1)^2
==> psi[2]=T(1)^3

D.4.6.3 genus
.............
Procedure from library normal.lib (see normal_lib).

Usage:
genus(I) or genus(i,1); I a 1-dimensional ideal

Return:
an integer, the geometric genus p_g = p_a - delta of the projective
curve defined by I, where p_a is the arithmetic genus.

Note:
delta is the sum of all local delta-invariants of the singularities,
i.e. dim(R'/R), R' the normalization of the local ring R of the
singularity.

genus(i,1) uses the normalization to compute delta. Usually this
is slow but sometimes not.

Example:
LIB "normal.lib";
ring r=0,(x,y),dp;
ideal i=y^9 - x^2*(x - 1)^9;
genus(i);
==> 0

D.4.6.4 deltaLoc
................
Procedure from library normal.lib (see normal_lib).

Usage:
deltaLoc(f,J); f poly, J ideal

Assume:
f is reduced bivariate polynomial; basering has exactly two variables;
J is irreducible prime component of the singular locus of f (e.g., one
entry of the output of minAssGTZ(I);, I = <f,jacob(f)>).

Return:
list L:

L[1]; int:
         the sum of (local) delta invariants of f at the (conjugated) singular
         points given by J.
L[2]; int:
         the sum of (local) Tjurina numbers of f at the (conjugated) singular
         points given by J.
L[3]; int:
         the sum of (local) number of branches of f at the (conjugated) 
         singular points given by J.

Note:
procedure makes use of execute; increasing printlevel displays
more comments (default: printlevel=0).

Example:
LIB "normal.lib";
ring r=0,(x,y),dp;
poly f=(x2+y^2-1)^3 +27x2y2;
ideal I=f,jacob(f);
I=std(I);
list qr=minAssGTZ(I);
size(qr);
==> 6
// each component of the singular locus either describes a cusp or a pair
// of conjugated nodes:
deltaLoc(f,qr[1]); 
==> [1]:
==>    1
==> [2]:
==>    2
==> [3]:
==>    1
deltaLoc(f,qr[2]); 
==> [1]:
==>    1
==> [2]:
==>    2
==> [3]:
==>    1
deltaLoc(f,qr[3]); 
==> [1]:
==>    1
==> [2]:
==>    2
==> [3]:
==>    1
deltaLoc(f,qr[4]); 
==> [1]:
==>    1
==> [2]:
==>    2
==> [3]:
==>    1
deltaLoc(f,qr[5]); 
==> [1]:
==>    2
==> [2]:
==>    2
==> [3]:
==>    4
deltaLoc(f,qr[6]);
==> [1]:
==>    2
==> [2]:
==>    2
==> [3]:
==>    4

D.4.7 primdec_lib
-----------------
Library:
primdec.lib
Purpose:
   Primary Decomposition and Radical of Ideals
Authors:
Gerhard Pfister, pfister@mathematik.uni-kl.de (GTZ)

 Wolfram Decker, decker@math.uni-sb.de (SY)

 Hans Schoenemann, hannes@mathematik.uni-kl.de (SY)

Overview:
Algorithms for primary decomposition based on the ideas of
Gianni, Trager and Zacharias (implementation by Gerhard Pfister),
respectively based on the ideas of Shimoyama and Yokoyama (implementation
by Wolfram Decker and Hans Schoenemann).

 The procedures are implemented to be used in characteristic 0.

 They also work in positive characteristic >> 0.

 In small characteristic and for algebraic extensions, primdecGTZ
may not terminate.

Algorithms for the computation of the radical based on the ideas of
Krick, Logar and Kemper (implementation by Gerhard Pfister).


Procedures:
* Ann:: annihilator of R^n/M, R=basering, M in R^n
* primdecGTZ:: complete primary decomposition via Gianni,Trager,Zacharias
* primdecSY:: complete primary decomposition via Shimoyama-Yokoyama
* minAssGTZ:: the minimal associated primes via Gianni,Trager,Zacharias
* minAssChar:: the minimal associated primes using characteristic sets
* testPrimary:: tests the result of the primary decomposition
* radical:: computes the radical of I via Krick/Logar and Kemper
* radicalEHV:: computes the radical of I via Eisenbud,Huneke,Vasconcelos
* equiRadical:: the radical of the equidimensional part of the ideal I
* prepareAss:: list of radicals of the equidimensional components of I
* equidim:: weak equidimensional decomposition of I
* equidimMax:: equidimensional locus of I
* equidimMaxEHV:: equidimensional locus of I via Eisenbud,Huneke,Vasconcelos
* zerodec:: zerodimensional decomposition via Monico

D.4.7.1 Ann
...........
Procedure from library primdec.lib (see primdec_lib).


D.4.7.2 primdecGTZ
..................
Procedure from library primdec.lib (see primdec_lib).

Usage:
primdecGTZ(i); i ideal

Return:
a list pr of primary ideals and their associated primes:
   pr[i][1]   the i-th primary component,
   pr[i][2]   the i-th prime component.

Note:
Algorithm of Gianni/Trager/Zacharias.

Designed for characteristic 0, works also in char k > 0, if it
terminates (may result in an infinite loop in small characteristic!)

Example:
LIB "primdec.lib";
ring  r = 0,(x,y,z),lp;
poly  p = z2+1;
poly  q = z3+2;
ideal i = p*q^2,y-z2;
list pr = primdecGTZ(i);
pr;
==> [1]:
==>    [1]:
==>       _[1]=z6+4z3+4
==>       _[2]=y-z2
==>    [2]:
==>       _[1]=z3+2
==>       _[2]=y-z2
==> [2]:
==>    [1]:
==>       _[1]=z2+1
==>       _[2]=y-z2
==>    [2]:
==>       _[1]=z2+1
==>       _[2]=y-z2

D.4.7.3 primdecSY
.................
Procedure from library primdec.lib (see primdec_lib).

Usage:
primdecSY(i); i ideal, c int

Return:
a list pr of primary ideals and their associated primes:
   pr[i][1]   the i-th primary component,
   pr[i][2]   the i-th prime component.

Note:
Algorithm of Shimoyama/Yokoyama.
   if c=0,  the given ordering of the variables is used,
   if c=1,  minAssChar tries to use an optimal ordering,
   if c=2,  minAssGTZ is used,
   if c=3,  minAssGTZ and facstd are used.

Example:
LIB "primdec.lib";
ring  r = 0,(x,y,z),lp;
poly  p = z2+1;
poly  q = z3+2;
ideal i = p*q^2,y-z2;
list pr = primdecSY(i);
pr;
==> [1]:
==>    [1]:
==>       _[1]=z6+4z3+4
==>       _[2]=y-z2
==>    [2]:
==>       _[1]=z3+2
==>       _[2]=y-z2
==> [2]:
==>    [1]:
==>       _[1]=z2+1
==>       _[2]=y+1
==>    [2]:
==>       _[1]=z2+1
==>       _[2]=y+1

D.4.7.4 minAssGTZ
.................
Procedure from library primdec.lib (see primdec_lib).

Usage:
minAssGTZ(i); i ideal

minAssGTZ(i,1); i ideal does not use the factorizing Groebner

Return:
a list, the minimal associated prime ideals of i.

Note:
Designed for characteristic 0, works also in char k > 0 based
on an algorithm of Yokoyama

Example:
LIB "primdec.lib";
ring  r = 0,(x,y,z),dp;
poly  p = z2+1;
poly  q = z3+2;
ideal i = p*q^2,y-z2;
list pr = minAssGTZ(i);
pr;
==> [1]:
==>    _[1]=z2+1
==>    _[2]=-z2+y
==> [2]:
==>    _[1]=z3+2
==>    _[2]=-z2+y

D.4.7.5 minAssChar
..................
Procedure from library primdec.lib (see primdec_lib).

Usage:
minAssChar(i[,c]); i ideal, c int.

Return:
list, the minimal associated prime ideals of i.

Note:
If c=0, the given ordering of the variables is used. 

Otherwise, the system tries to find an optimal ordering,
which in some cases may considerably speed up the algorithm. 

Due to a bug in the factorization, the result may be not completely
decomposed in small characteristic.

Example:
LIB "primdec.lib";
ring  r = 0,(x,y,z),dp;
poly  p = z2+1;
poly  q = z3+2;
ideal i = p*q^2,y-z2;
list pr = minAssChar(i);
pr;
==> [1]:
==>    _[1]=y+1
==>    _[2]=z2+1
==> [2]:
==>    _[1]=z2-y
==>    _[2]=yz+2
==>    _[3]=y2+2z

D.4.7.6 testPrimary
...................
Procedure from library primdec.lib (see primdec_lib).

Usage:
testPrimary(pr,k); pr a list, k an ideal.

Assume:
pr is the result of primdecGTZ(k) or primdecSY(k).

Return:
int, 1 if the intersection of the ideals in pr is k, 0 if not

Example:
LIB "primdec.lib";
ring  r = 32003,(x,y,z),dp;
poly  p = z2+1;
poly  q = z4+2;
ideal i = p^2*q^3,(y-z3)^3,(x-yz+z4)^4;
list pr = primdecGTZ(i);
testPrimary(pr,i);
==> 1

D.4.7.7 radical
...............
Procedure from library primdec.lib (see primdec_lib).

Usage:
radical(i); i ideal.

Return:
ideal, the radical of i.

Note:
A combination of the algorithms of Krick/Logar and Kemper is used.
Works also in positive characteristic (Kempers algorithm).

Example:
LIB "primdec.lib";
ring  r = 0,(x,y,z),dp;
poly  p = z2+1;
poly  q = z3+2;
ideal i = p*q^2,y-z2;
ideal pr= radical(i);
pr;
==> pr[1]=z2-y
==> pr[2]=y2z+yz+2y+2

D.4.7.8 radicalEHV
..................
Procedure from library primdec.lib (see primdec_lib).

Usage:
radicalEHV(i); i ideal.

Return:
ideal, the radical of i.

Note:
Uses the algorithm of Eisenbud/Huneke/Vasconcelos, which
reduces the computation to the complete intersection case,
by taking, in the general case, a generic linear combination
of the input.

Works only in characteristic 0 or p large.

Example:
LIB "primdec.lib";
ring  r = 0,(x,y,z),dp;
poly  p = z2+1;
poly  q = z3+2;
ideal i = p*q^2,y-z2;
ideal pr= radicalEHV(i);
pr;
==> pr[1]=z2-y
==> pr[2]=y2z+yz+2y+2
==> pr[3]=y3+y2+2yz+2z

D.4.7.9 equiRadical
...................
Procedure from library primdec.lib (see primdec_lib).

Usage:
equiRadical(i); i ideal

Return:
ideal, intersection of associated primes of i of maximal dimension.

Note:
A combination of the algorithms of Krick/Logar and Kemper is used.
Works also in positive characteristic (Kempers algorithm).

Example:
LIB "primdec.lib";
ring  r = 0,(x,y,z),dp;
poly  p = z2+1;
poly  q = z3+2;
ideal i = p*q^2,y-z2;
ideal pr= equiRadical(i);
pr;
==> pr[1]=z2-y
==> pr[2]=y2z+yz+2y+2

D.4.7.10 prepareAss
...................
Procedure from library primdec.lib (see primdec_lib).

Usage:
prepareAss(i); i ideal

Return:
list, the radicals of the maximal dimensional components of i.

Note:
Uses algorithm of Eisenbud/Huneke/Vasconcelos.

Example:
LIB "primdec.lib";
ring  r = 0,(x,y,z),dp;
poly  p = z2+1;
poly  q = z3+2;
ideal i = p*q^2,y-z2;
list pr = prepareAss(i);
pr;
==> [1]:
==>    _[1]=z2-y
==>    _[2]=y2z+yz+2y+2

D.4.7.11 equidim
................
Procedure from library primdec.lib (see primdec_lib).

Usage:
equidim(i) or equidim(i,1) ; i ideal

Return:
list of equidimensional ideals a[1],...,a[s] with:

- a[s] the equidimensional locus of i, i.e. the intersection
of the primary ideals of dimension of i

- a[1],...,a[s-1] the lower dimensional equidimensional loci.

Note:
An embedded component q (primary ideal) of i can be replaced in the
decomposition by a primary ideal q1 with the same radical as q. 

equidim(i,1) uses the algorithm of Eisenbud/Huneke/Vasconcelos.

Example:
LIB "primdec.lib";
ring  r = 32003,(x,y,z),dp;
ideal i = intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
equidim(i);
==> [1]:
==>    _[1]=z4
==>    _[2]=y5
==>    _[3]=x5
==>    _[4]=x3z3
==>    _[5]=x4y4
==> [2]:
==>    _[1]=yz
==>    _[2]=xz
==>    _[3]=x2
==> [3]:
==>    _[1]=z

D.4.7.12 equidimMax
...................
Procedure from library primdec.lib (see primdec_lib).

Usage:
equidimMax(i); i ideal

Return:
ideal of equidimensional locus (of maximal dimension) of i.

Example:
LIB "primdec.lib";
ring  r = 32003,(x,y,z),dp;
ideal i = intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
equidimMax(i);
==> _[1]=z

D.4.7.13 equidimMaxEHV
......................
Procedure from library primdec.lib (see primdec_lib).

Usage:
equidimMaxEHV(i); i ideal

Return:
ideal, the equidimensional component (of maximal dimension) of i.

Note:
Uses algorithm of Eisenbud, Huneke and Vasconcelos.

Example:
LIB "primdec.lib";
ring  r = 0,(x,y,z),dp;
ideal i=intersect(ideal(z),ideal(x,y),ideal(x2,z2),ideal(x5,y5,z5));
equidimMaxEHV(i);
==> _[1]=z

D.4.7.14 zerodec
................
Procedure from library primdec.lib (see primdec_lib).

Usage:
zerodec(I); I ideal

Assume:
I is zero-dimensional, the characteristic of the ground field is 0

Return:
list of primary ideals, the zero-dimensional decomposition of I

Note:
The algorithm (of Monico), works well only for a small total number
of solutions (vdim(std(I)) should be < 100) and without
parameters. In practice, it works also in large characteristic p>0
but may fail for small p.

 If printlevel > 0 (default = 0) additional information is displayed.

Example:
LIB "primdec.lib";
ring r  = 0,(x,y),dp;
ideal i = x2-2,y2-2;
list pr = zerodec(i);
pr;
==> [1]:
==>    _[1]=y2-2
==>    _[2]=xy-2
==>    _[3]=x2-2
==> [2]:
==>    _[1]=y2-2
==>    _[2]=xy+2
==>    _[3]=x2-2
D.4.8 primitiv_lib
------------------
Library:
primitiv.lib
Purpose:
    Computing a Primitive Element
Author:
Martin Lamm, email: lamm@mathematik.uni-kl.de


Procedures:
* primitive:: find minimal polynomial for a primitive element
* primitive_extra:: find primitive element for two generators
* splitring:: define ring extension with name R and switch to it

D.4.8.1 primitive
.................
Procedure from library primitiv.lib (see primitiv_lib).

Usage:
primitive(i); i ideal

Assume:
i is given by generators m[1],...,m[n] such that for j=1,...,n 

- m[j] is a polynomial in k[x(1),...,x(j)] 

- m[j](a[1],...,a[j-1],x(j)) is the minimal polynomial for a[j] over
k(a[1],...,a[j-1]) 

(k the ground field of the current basering and x(1),...,x(n)
the ring variables).

Return:
ideal j in k[x(n)] with

- j[1] a minimal polynomial for a primitive element b of 
k(a[1],...,a[n]) over k,

- j[2],...,j[n+1] polynomials in k[x(n)] such that j[i+1](b)=a[i]
for i=1,...,n.

Note:
the number of variables in the basering has to be exactly n,
the number of given generators (i.e., minimal polynomials).

If the ground field k has only a few elements it may happen that no
linear combination of a[1],...,a[n] is a primitive element. In this
case primitive(i) returns the zero ideal, and one should use
primitive_extra(i) instead.

Example:
LIB "primitiv.lib";
ring exring=0,(x,y),dp;
ideal i=x2+1,y2-x;                  // compute Q(i,i^(1/2))=:L
ideal j=primitive(i);
j[1];                               // L=Q(a) with a=(-1)^(1/4)
==> y4+1
j[2];                               // i=a^2
==> y2
j[3];                               // i^(1/2)=a
==> y
// the 2nd element was already primitive!
j=primitive(ideal(x2-2,y2-3));      // compute Q(sqrt(2),sqrt(3))
j[1];
==> y4-10y2+1
j[2];
==> 1/2y3-9/2y
j[3];
==> -1/2y3+11/2y
// no element was primitive -- the calculation of primitive elements 
// is based on a random choice.


D.4.8.2 primitive_extra
.......................
Procedure from library primitiv.lib (see primitiv_lib).

Usage:
primitive_extra(i); i ideal

Assume:
The ground field of the basering is k=Q or k=Z/pZ and the ideal
i is given by 2 generators f,g with the following properties:
   f is the minimal polynomial of a in k[x], 
   g is a polynomial in k[x,y] s.th. g(a,y) is the minpoly of b in k(a)[y].
Here, x is the name of the first ring variable, y the name of the
second.

Return:
ideal j in k[y] such that
   j[1] is the minimal polynomial for a primitive element c of k(a,b) over k,
   j[2] is a polynomial s.th. j[2](c)=a.

Note:
While primitive(i) may fail for finite fields,
primitive_extra(i) tries all elements of k(a,b) and, hence,
always finds a primitive element. 

In order to do this (try all elements), field extensions like Z/pZ(a)
are not allowed for the ground field k. 

primitive_extra(i) assumes that the second generator, g, is
monic as polynomial in (k[x])[y].

Example:
LIB "primitiv.lib";
ring exring=3,(x,y),dp;
ideal i=x2+1,y3+y2-1;
primitive_extra(i);
==> _[1]=y6-y5+y4-y3-y-1
==> _[2]=y5+y4+y2+y+1
ring extension=(3,y),x,dp;
minpoly=y6-y5+y4-y3-y-1;
number a=y5+y4+y2+y+1;
a^2;
==> -1
factorize(x2+1);
==> [1]:
==>    _[1]=1
==>    _[2]=x+(-y5-y4-y2-y-1)
==>    _[3]=x+(y5+y4+y2+y+1)
==> [2]:
==>    1,1,1
factorize(x3+x2-1);
==> [1]:
==>    _[1]=1
==>    _[2]=x+(-y5-y4-y3-y2-y-1)
==>    _[3]=x+(y5+y4+y2+1)
==>    _[4]=x+(y3+y+1)
==> [2]:
==>    1,1,1,1

D.4.8.3 splitring
.................
Procedure from library primitiv.lib (see primitiv_lib).

Usage:
splitring(f,R[,L]); f poly, R string, L list of polys and/or ideals
(optional)

Assume:
f is univariate and irreducible over the active basering. 

The active ring must allow an algebraic extension (e.g., it cannot
be a transcendent ring extension of Q or Z/p).

Create:
a ring with name R, in which f is reducible, and CHANGE to it.

Return:
list L mapped into the new ring R, if L is given; else nothing

Note:
If the old ring has no parameter, the name a is chosen for the
parameter of R (if a is no ring variable; if it is, b is
chosen, etc.; if a,b,c,o are ring variables,
splitring(f,R[,L]) produces an error message), otherwise the
name of the parameter is kept and only the minimal polynomial is
changed. 

The names of the ring variables and the orderings are not affected. 

It is also allowed to call splitring with R="".
Then the old basering will be REPLACED by the new ring (with the
same name as the old ring).

Example:
LIB "primitiv.lib";
ring r=0,(x,y),dp;
splitring(x2-2,"r1");   // change to Q(sqrt(2))
// change to Q(sqrt(2),sqrt(sqrt(2)))=Q(a) and return the transformed 
// old parameter:
splitring(x2-a,"r2",a); 
==> // new minimal polynomial: a4-2
==> [1]:
==>    (a2)
// the result is (a)^2 = (sqrt(sqrt(2)))^2
nameof(basering);
==> r2
r2;
==> //   characteristic : 0
==> //   1 parameter    : a 
==> //   minpoly        : (a4-2)
==> //   number of vars : 2
==> //        block   1 : ordering dp
==> //                  : names    x y 
==> //        block   2 : ordering C
kill r1; kill r2;
D.4.9 reesclos_lib
------------------
Library:
reesclos.lib
Purpose:
     procedures to compute the int. closure of an ideal
Author:
Tobias Hirsch, email: hirsch@math.tu-cottbus.de

Overview:
A library to compute the integral closure of an ideal I in a polynomial ring
R=K[x(1),...,x(n)] using the Rees Algebra R[It] of I. It computes the integral
closure of R[It] (in the same manner as done in the library 'normal.lib'),
which is a graded subalgebra of R[t]. The degree-k-component is the integral
closure of the k-th power of I.

These procedures can also be used to compute the integral closure R^ of an
integral domain R=k[x(1),...,x(n)]/ker, ker a prime ideal, in its quotient
field K=Q(R), as an affine ring R^=k[T(1),...,T(s)]]/J and to get
representations of elements of R^ as fractions of elements of R.


Procedures:
* ReesAlgebra:: computes the Rees Algebra of an ideal I
* normalI:: computes the integral closure of an ideal I using R[It]
* primeClosure:: computes the integral closure of the int. domain R
* closureRingtower:: defines the rings in the list L as global objects R(i)
* closureFrac:: computes fractions representing elements of R^=L[n]

D.4.9.1 ReesAlgebra
...................
Procedure from library reesclos.lib (see reesclos_lib).

Usage:
ReesAlgebra (I); I = ideal

Return:
The Rees algebra R[It] as an affine ring, where I is an ideal in R.
The procedure returns a list containing two rings:

[1]: a ring, say RR; in the ring an ideal ker such that R[It]=RR/ker

[2]: a ring, say Kxt; the basering with additional variable t
containing an ideal mapI that defines the map RR->Kxt

Example:
LIB "reesclos.lib";
ring R = 0,(x,y),dp;
ideal I = x2,xy4,y5;
list L = ReesAlgebra(I);
def Rees = L[1];       // defines the ring Rees, containing the ideal ker
setring Rees;          // passes to the ring Rees
Rees;
==> //   characteristic : 0
==> //   number of vars : 5
==> //        block   1 : ordering dp
==> //                  : names    x y U(1) U(2) U(3) 
==> //        block   2 : ordering C
ker;                   // R[It] is isomorphic to Rees/ker
==> ker[1]=y*U(2)-x*U(3)
==> ker[2]=y^3*U(1)*U(3)-U(2)^2
==> ker[3]=y^4*U(1)-x*U(2)
==> ker[4]=x*y^2*U(1)*U(3)^2-U(2)^3
==> ker[5]=x^2*y*U(1)*U(3)^3-U(2)^4
==> ker[6]=x^3*U(1)*U(3)^4-U(2)^5

D.4.9.2 normalI
...............
Procedure from library reesclos.lib (see reesclos_lib).

Usage:
normalI(I [,p[,c]]); I an ideal, p and c optional integers

Return:
the integral closure of I,...,I^p. If p is not given, or p==0,
compute the closure of all powers up to the maximum degree in t
occurring in the generators of the closure of R[It] (so this is the
last one that is not just the sum/product of the above ones).
c is transferred to the procedure primeClosure and toggles its
behavior in computing the integral closure of R[It].

The result is a list containing the closure of the desired powers of
I as ideals of the basering.

Example:
LIB "reesclos.lib";
ring R=0,(x,y),dp;
ideal I = x2,xy4,y5;
list J = normalI(I);
I;
==> I[1]=x2
==> I[2]=xy4
==> I[3]=y5
J;                             // J[1] is the integral closure of I
==> [1]:
==>    _[1]=x2
==>    _[2]=y5
==>    _[3]=-xy3

D.4.9.3 primeClosure
....................
Procedure from library reesclos.lib (see reesclos_lib).

Usage:
primeClosure(L [,c]); L a list of a ring containing a prime ideal
ker, c an optional integer

Return:
a list L consisting of rings L[1],...,L[n] such that

- L[1] is a copy of (not a reference to!) the input ring L[1]
- all rings L[i] contain ideals ker, L[2],...,L[n] contain ideals phi
such that

L[1]/ker -> ... -> L[n]/ker

are injections given by the corresponding ideals phi, and L[n]/ker
is the integral closure of L[1]/ker in its quotient field.
- all rings L[i] contain a polynomial nzd such that elements of
L[i]/ker are quotients of elements of L[i-1]/ker with denominator
nzd via the injection phi.

Note:
- L is constructed by recursive calls of primeClosure itself.
- c determines the choice of nzd:

- c not given or equal to 0: first generator of the ideal SL,
the singular locus of Spec(L[i]/ker)

- c<>0: the generator of SL with least number of monomials.

Example:
LIB "reesclos.lib";
ring R=0,(x,y),dp;
ideal I=x4,y4;
def K=ReesAlgebra(I)[1];        // K contains ker such that K/ker=R[It]
list L=primeClosure(K);
def R(1)=L[1];                  // L[4] contains ker, L[4]/ker is the
def R(4)=L[4];                  // integral closure of L[1]/ker
setring R(1);
R(1);
==> //   characteristic : 0
==> //   number of vars : 4
==> //        block   1 : ordering dp
==> //                  : names    x y U(1) U(2) 
==> //        block   2 : ordering C
ker;
==> ker[1]=y^4*U(1)-x^4*U(2)
setring R(4);
R(4);
==> //   characteristic : 0
==> //   number of vars : 7
==> //        block   1 : ordering a
==> //                  : names    T(1) T(2) T(3) T(4) T(5) T(6) T(7) 
==> //                  : weights     1    1    1    1    1    1    1 
==> //        block   2 : ordering dp
==> //                  : names    T(1) T(2) T(3) T(4) T(5) T(6) T(7) 
==> //        block   3 : ordering C
ker;
==> ker[1]=T(2)*T(5)-T(1)*T(7)
==> ker[2]=T(1)*T(5)-T(2)*T(6)
==> ker[3]=T(5)*T(6)-T(3)*T(7)
==> ker[4]=T(4)*T(6)-T(5)*T(7)
==> ker[5]=T(5)^2-T(6)*T(7)
==> ker[6]=T(4)*T(5)-T(7)^2
==> ker[7]=T(3)*T(5)-T(6)^2
==> ker[8]=T(2)^2*T(6)-T(1)^2*T(7)
==> ker[9]=T(3)*T(4)-T(6)*T(7)
==> ker[10]=T(1)*T(4)-T(2)*T(7)
==> ker[11]=T(2)*T(3)-T(1)*T(6)
==> ker[12]=T(2)^2*T(6)^2-T(1)^2*T(6)*T(7)

D.4.9.4 closureRingtower
........................
Procedure from library reesclos.lib (see reesclos_lib).

Usage:
closureRingtower(list L); L a list of rings

Create:
rings R(1),...,R(n) such that R(i)=L[i] for all i

Example:
LIB "reesclos.lib";
ring R=0,(x,y),dp;
ideal I=x4,y4;
list L=primeClosure(ReesAlgebra(I)[1]);
closureRingtower(L);
R(1);
==> //   characteristic : 0
==> //   number of vars : 4
==> //        block   1 : ordering dp
==> //                  : names    x y U(1) U(2) 
==> //        block   2 : ordering C
R(4);
==> //   characteristic : 0
==> //   number of vars : 7
==> //        block   1 : ordering a
==> //                  : names    T(1) T(2) T(3) T(4) T(5) T(6) T(7) 
==> //                  : weights     1    1    1    1    1    1    1 
==> //        block   2 : ordering dp
==> //                  : names    T(1) T(2) T(3) T(4) T(5) T(6) T(7) 
==> //        block   3 : ordering C

D.4.9.5 closureFrac
...................
Procedure from library reesclos.lib (see reesclos_lib).

Create:
a list fraction of two elements of L[1], such that

f=fraction[1]/fraction[2] via the injections phi L[i]->L[i+1].

Example:
LIB "reesclos.lib";
ring R=0,(x,y),dp;
ideal ker=x2+y2;
export R;
==> // ** `R` is already global
list L=primeClosure(R);          // We normalize R/ker
closureRingtower(L);             // Now R/ker=R(1) with normalization R(2)
setring R(2);
kill(R);
phi;                             // The map R(1)-->R(2)
==> phi[1]=T(1)*T(2)
==> phi[2]=T(1)
poly f=T(1)*T(2);                // We will get a representation of f
export R(2);
==> // ** `R(2)` is already global
closureFrac(L);
setring R(1);
kill (R(2));
fraction;                        // f=fraction[1]/fraction[2] via phi
==> [1]:
==>    xy
==> [2]:
==>    y
D.4.10 intprog_lib
------------------
Library:
intprog.lib
Purpose:
      Integer Programming with Groebner Basis Methods
Author:
Christine Theis, email: ctheis@math.uni-sb.de


Procedures:
* solve_IP:: procedures for solving Integer Programming problems

D.4.10.1 solve_IP
.................
Procedure from library intprog.lib (see intprog_lib).

Usage:
solve_IP(A,bx,c,alg); A intmat, bx intvec, c intvec, alg string.
solve_IP(A,bx,c,alg); A intmat, bx list of intvec, c intvec,
alg string.

solve_IP(A,bx,c,alg,prsv); A intmat, bx intvec, c intvec,
alg string, prsv intvec.

solve_IP(A,bx,c,alg,prsv); A intmat, bx list of intvec, c intvec,
alg string, prsv intvec.

Return:
same type as bx: solution of the associated integer programming
problem(s) as explained in

   Toric ideals and integer programming.

Note:
This procedure returns the solution(s) of the given IP-problem(s)
or the message `not solvable'.

One may call the procedure with several different algorithms:

- the algorithm of Conti/Traverso (ct),

- the positive variant of the algorithm of Conti/Traverso (pct),

- the algorithm of Conti/Traverso using elimination (ect),

- the algorithm of Pottier (pt),

- an algorithm of Bigatti/La Scala/Robbiano (blr),

- the algorithm of Hosten/Sturmfels (hs),

- the algorithm of DiBiase/Urbanke (du).
The argument `alg' should be the abbreviation for an algorithm as
above: ct, pct, ect, pt, blr, hs or du.

`ct' allows computation of an optimal solution of the IP-problem
directly from the right-hand vector b.

The same is true for its `positive' variant `pct' which may only be
applied if A and b have nonnegative entries.

All other algorithms need initial solutions of the IP-problem.

If `alg' is chosen to be `ct' or `pct', bx is read as the right hand
vector b of the system Ax=b. b should then be an intvec of size m
where m is the number of rows of A.

Furthermore, bx and A should be nonnegative if `pct' is used.
If `alg' is chosen to be `ect',`pt',`blr',`hs' or `du',
bx is read as an initial solution x of the system Ax=b.
bx should then be a nonnegative intvec of size n where n is the
number of columns of A.

If `alg' is chosen to be `blr' or `hs', the algorithm needs a vector
with positive coefficients in the row space of A.

If no row of A contains only positive entries, one has to use the
versions of solve_IP which take such a vector prsv as an argument.

solve_IP may also be called with a list bx of intvecs instead of a
single intvec.

Example:
LIB "intprog.lib";
// 1. call with single right-hand vector
intmat A[2][3]=1,1,0,0,1,1;
intvec b1=1,1;
intvec c=2,2,1;
intvec solution_vector=solve_IP(A,b1,c,"pct");
solution_vector;"";
==> 0,1,0
==> 
// 2. call with list of right-hand vectors
intvec b2=-1,1;
list l=b1,b2;
l;
==> [1]:
==>    1,1
==> [2]:
==>    -1,1
list solution_list=solve_IP(A,l,c,"ct");
solution_list;"";
==> [1]:
==>    0,1,0
==> [2]:
==>    not solvable
==> 
// 3. call with single initial solution vector
A=2,1,-1,-1,1,2;
b1=3,4,5;
solve_IP(A,b1,c,"du");"";
==> 0,7,2
==> 
// 4. call with single initial solution vector
//    and algorithm needing a positive row space vector
solution_vector=solve_IP(A,b1,c,"hs");"";
==> ERROR: The chosen algorithm needs a positive vector in the row space of t\
   he matrix.
==> 0
==> 
// 5. call with single initial solution vector
//     and positive row space vector
intvec prsv=1,2,1;
solution_vector=solve_IP(A,b1,c,"hs",prsv);
solution_vector;"";
==> 0,7,2
==> 
// 6. call with list of initial solution vectors
//    and positive row space vector
b2=7,8,0;
l=b1,b2;
l;
==> [1]:
==>    3,4,5
==> [2]:
==>    7,8,0
solution_list=solve_IP(A,l,c,"blr",prsv);
solution_list;
==> [1]:
==>    0,7,2
==> [2]:
==>    7,8,0

D.4.11 toric_lib
----------------
Library:
toric.lib
Purpose:
   Standard Basis of Toric Ideals
Author:
Christine Theis, email: ctheis@math.uni-sb.de


Procedures:
* toric_ideal:: computes the toric ideal of A
* toric_std:: standard basis of I by a specialized Buchberger algorithm

D.4.11.1 toric_ideal
....................
Procedure from library toric.lib (see toric_lib).

Usage:
toric_ideal(A,alg); A intmat, alg string

toric_ideal(A,alg,prsv); A intmat, alg string, prsv intvec

Return:
ideal: standard basis of the toric ideal of A

Note:
These procedures return the standard basis of the toric ideal of A
with respect to the term ordering in the current basering. Not all
term orderings are supported: The usual global term orderings may be
used, but no block orderings combining them.

One may call the procedure with several different algorithms: 

- the algorithm of Conti/Traverso using elimination (ect), 

- the algorithm of Pottier (pt),

- an algorithm of Bigatti/La Scala/Robbiano (blr),

- the algorithm of Hosten/Sturmfels (hs),

- the algorithm of DiBiase/Urbanke (du).

The argument `alg' should be the abbreviation for an algorithm as
above: ect, pt, blr, hs or du.

If `alg' is chosen to be `blr' or `hs', the algorithm needs a vector
with positive coefficients in the row space of A.

If no row of A contains only positive entries, one has to use the
second version of toric_ideal which takes such a vector as its third
argument.

For the mathematical background, see

  Toric ideals and integer programming.

Example:
LIB "toric.lib";
ring r=0,(x,y,z),dp;
// call with two arguments
intmat A[2][3]=1,1,0,0,1,1;
A;
==> 1,1,0,
==> 0,1,1 
ideal I=toric_ideal(A,"du");
I;
==> I[1]=xz-y
I=toric_ideal(A,"blr");
==> ERROR: The chosen algorithm needs a positive vector in the row space of t\
   he matrix.
I;
==> I[1]=0
// call with three arguments
intvec prsv=1,2,1;
I=toric_ideal(A,"blr",prsv);
I;
==> I[1]=xz-y


D.4.11.2 toric_std
..................
Procedure from library toric.lib (see toric_lib).

Usage:
toric_std(I); I ideal

Return:
ideal: standard basis of I

Note:
This procedure computes the standard basis of I using a specialized
Buchberger algorithm. The generating system by which I is given has
to consist of binomials of the form x^u-x^v. There is no real check
if I is toric. If I is generated by binomials of the above form,
but not toric, toric_std computes an ideal `between' I and its
saturation with respect to all variables.

For the mathematical background, see

   Toric ideals and integer programming.

Example:
LIB "toric.lib";
ring r=0,(x,y,z),wp(3,2,1);
// call with toric ideal (of the matrix A=(1,1,1))
ideal I=x-y,x-z;
ideal J=toric_std(I);
J;
==> J[1]=y-z
==> J[2]=x-z
// call with the same ideal, but badly chosen generators:
// 1) not only binomials
I=x-y,2x-y-z;
J=toric_std(I);
==> ERROR: Generator 2 of the input ideal is no difference of monomials.
// 2) binomials whose monomials are not relatively prime
I=x-y,xy-yz,y-z;
J=toric_std(I);
==> Warning: The monomials of generator 2 of the input ideal are not relative\
   ly prime.
J;
==> J[1]=y-z
==> J[2]=x-z
// call with a non-toric ideal that seems to be toric
I=x-yz,xy-z;
J=toric_std(I);
J;
==> J[1]=y2-1
==> J[2]=x-yz
// comparison with real standard basis and saturation
ideal H=std(I);
H;
==> H[1]=x-yz
==> H[2]=y2z-z
LIB "elim.lib";
sat(H,xyz);
==> [1]:
==>    _[1]=x-yz
==>    _[2]=y2-1
==> [2]:
==>    1

D.5 Singularities
=================

* classify_lib:: procedures for the Arnold-classifier of singularities
* deform_lib:: procedures for computing miniversal deformation
* equising_lib:: procedures for equisingularity strata
* gaussman_lib:: procedures for gauss-manin connection of a singularity
* hnoether_lib:: procedures for the Hamburger-Noether (Puiseux) development
* mondromy_lib:: procedures to compute the monodromy of a singularity
* qhmoduli_lib:: procedures for moduli spaces of sqh-singularities
* sing_lib:: procedures for computing invariants of singularities
* spcurve_lib:: procedures for cm codimension 2 singularities
* spectrum_lib:: procedures for computing singularity spectra

D.5.1 classify_lib
------------------
Library:
classify.lib
Purpose:
  Arnold Classifier of Singularities
Authors:
Kai Krueger, krueger@mathematik.uni-kl.de

Corina Baciu, baciu@mathematik.uni-kl.de

Overview:
A library for classifying isolated hypersurface singularities w.r.t. right
equivalence, based on the determinator of singularities by V.I. Arnold.


Procedures:
* basicinvariants:: computes Milnor number, determinacy-bound and corank of
* classify:: normal form of poly f determined with Arnold's method
* corank:: computes the corank of f (i.e. of the Hessian of f)
* Hcode:: coding of intvec v according to the number repetitions
* init_debug:: print trace and debugging information depending on int n
* internalfunctions:: display names of internal procedures of this library
* milnorcode:: Hilbert poly of [e-th] Milnor algebra coded with Hcode
* morsesplit:: residual part of f after applying the splitting lemma
* quickclass:: normal form of f determined by invariants (milnorcode)
* singularity:: normal form of singularity given by its name s and index
* swap:: returns b,a
* A_L:: shortcut for quickclass(f) or normalform(s)
* normalform:: normal form of singularity given by its name s
* debug_log:: print trace and debugging information w.r.t level>@DeBug

D.5.1.1 basicinvariants
.......................
Procedure from library classify.lib (see classify_lib).

Usage:
basicinvariants(f); f = poly

Compute:
Compute basic invariants of f: an upper bound d for the
determinacy, the milnor number mu and the corank c of f

Return:
intvec: d, mu, c

Example:
LIB "classify.lib";
ring r=0,(x,y,z),ds;
basicinvariants((x2+3y-2z)^2+xyz-(x-y3+x2*z3)^3);
==> 5,4,2

D.5.1.2 classify
................
Procedure from library classify.lib (see classify_lib).

Usage:
classify(f); f=poly

Compute:
normal form and singularity type of f with respect to right
equivalence, as given in the book "Singularities of differentiable
maps, Volume I" by V.I. Arnold, S.M. Gusein-Zade, A.N. Varchenko

Return:
normal form of f, of type poly

Remark:
This version of classify is only beta. Please send bugs and
comments to: "Kai Krueger" <krueger@mathematik.uni-kl.de> 

Be sure to have at least Singular version 1.0.1. Updates can be
found at: 

URL=http://www.mathematik.uni-kl.de/~krueger/Singular/

Note:
type init_debug(n); (0 <= n <= 10) in order to get intermediate
information, higher values of n give more information.

The proc creates several global objects with names all starting
with @, hence there should be no name conflicts

Example:
LIB "classify.lib";
ring r=0,(x,y,z),ds;
poly f=(x2+3y-2z)^2+xyz-(x-y3+x2*z3)^3;
classify(f);
==> About the singularity :
==>           Milnor number(f)   = 4
==>           Corank(f)          = 2
==>           Determinacy       <= 5
==> Guessing type via Milnorcode:   D[k]=D[4]
==> 
==> Computing normal form ...
==> I have to apply the splitting lemma. This will take some time....:-)
==>    Arnold step number 4
==> The singularity
==>    -x3+3/2xy2+1/2x3y-1/16x2y2+3x2y3
==> is R-equivalent to D[4].
==>    Milnor number = 4
==>    modality      = 0
==> 2z2+x2y+y3
init_debug(3);
==> Debugging level change from  0  to  3
classify(f);
==> Computing Basicinvariants of f ...
==> About the singularity :
==>           Milnor number(f)   = 4
==>           Corank(f)          = 2
==>           Determinacy       <= 5
==> Hcode: 1,2,1,0,0
==> Milnor code :  1,1,1
==> Debug:(2):  entering HKclass3_teil_1 1,1,1
==> Debug:(2):  finishing HKclass3_teil_1
==> Guessing type via Milnorcode:   D[k]=D[4]
==> 
==> Computing normal form ...
==> I have to apply the splitting lemma. This will take some time....:-)
==> Debug:(3):  Split the polynomial below using determinacy:  5
==> Debug:(3):  9y2-12yz+4z2-x3+6x2y-4x2z+xyz+x4+3x2y3
==> Debug:(2):  Permutations: 3,2,1
==> Debug:(2):  Permutations: 3,2,1
==> Debug:(2):  rank determined with Morse rg= 1
==> Residual singularity f= -x3+3/2xy2+1/2x3y-1/16x2y2+3x2y3
==> Step 3
==>    Arnold step number 4
==> The singularity
==>    -x3+3/2xy2+1/2x3y-1/16x2y2+3x2y3
==> is R-equivalent to D[4].
==>    Milnor number = 4
==>    modality      = 0
==> Debug:(2):  Decode:
==> Debug:(2):  S_in= D[4]   s_in= D[4]                          
==> Debug:(2):  Looking for Normalform of  D[k] with (k,r,s) = ( 4 , 0 , 0 )
==> Debug:(2):  Opening Singalarity-database:  
==>  DBM: NFlist
==> Debug:(2):  DBMread( D[k] )= x2y+y^(k-1) .
==> Debug:(2):  S= f = x2y+y^(k-1);  Tp= x2y+y^(k-1) Key= I_D[k]
==> Polynom f= x2y+y3   crk= 2   Mu= 4  MlnCd= 1,1,1
==> Debug:(2):  Info= x2y+y3
==> Debug:(2):  Normal form NF(f)= 2*x(3)^2+x(1)^2*x(2)+x(2)^3
==> 2z2+x2y+y3

D.5.1.3 corank
..............
Procedure from library classify.lib (see classify_lib).

Usage:
corank(f); f=poly

Return:
the corank of the Hessian matrix of f, of type int

Remark:
corank(f) is the number of variables occurring in the residual
singularity after applying 'morsesplit' to f

Example:
LIB "classify.lib";
ring r=0,(x,y,z),ds;
poly f=(x2+3y-2z)^2+xyz-(x-y3+x2*z3)^3;
corank(f);
==> 2

D.5.1.4 Hcode
.............
Procedure from library classify.lib (see classify_lib).

Usage:
Hcode(v); v=intvec

Return:
intvec, coding v according to the number of successive
repetitions of an entry

Example:
LIB "classify.lib";
intvec v1 = 1,3,5,5,2;
Hcode(v1);
==> 1,0,1,0,2,0,0,1,0
intvec v2 = 1,2,3,4,4,4,4,4,4,4,3,2,1;
Hcode(v2);
==> 1,1,1,7,1,1,1

D.5.1.5 init_debug
..................
Procedure from library classify.lib (see classify_lib).

Usage:
init_debug([level]); level=int

Compute:
Set the global variable @DeBug to level. The variable @DeBug is
used by the function debug_log(level, list of strings) to know
when to print the list of strings. init_debug() reports only
changes of @DeBug.

Note:
The procedure init_debug(n); is useful as trace-mode. n may
range from 0 to 10, higher values of n give more information.

Example:
LIB "classify.lib";
init_debug();
debug_log(1,"no trace information printed");
init_debug(1);
==> Debugging level change from  0  to  1
debug_log(1,"some trace information");
==> some trace information
init_debug(2);
==> Debugging level change from  1  to  2
debug_log(2,"nice for debugging scripts");
==> Debug:(2):  nice for debugging scripts
init_debug(0);
==> Debugging switched off.

D.5.1.6 internalfunctions
.........................
Procedure from library classify.lib (see classify_lib).

Usage:
internalfunctions();

Return:
nothing, display names of internal procedures of classify.lib

Example:
LIB "classify.lib";
internalfunctions();
==>    Internal functions for the classification using Arnold's method,
==>    the function numbers correspond to numbers in Arnold's classifier:
==> Klassifiziere(poly f);      //determine the type of the singularity f
==>   Funktion1bis (poly f, list cstn)
==>   Funktion3 (poly f, list cstn)
==>   Funktion6 (poly f, list cstn)
==>   Funktion13 (poly f, list cstn)
==>   Funktion17 (poly f, list cstn)
==>   Funktion25 (poly f, list cstn)
==>   Funktion40 (poly f, list cstn, int k)
==>   Funktion47 (poly f, list cstn)
==>   Funktion50 (poly f, list cstn)
==>   Funktion58 (poly fin, list cstn)
==>   Funktion59 (poly f, list cstn)
==>   Funktion66 (poly f, list cstn)
==>   Funktion82 (poly f, list cstn)
==>   Funktion83 (poly f, list cstn)
==>   Funktion91 (poly f, list cstn, int k)
==>   Funktion92 (poly f, list cstn, int k)
==>   Funktion93 (poly f, list cstn, int k)
==>   Funktion94 (poly f, list cstn, int k)
==>   Funktion95 (poly f, list cstn, int k)
==>   Funktion96 (poly f, list cstn, int k)
==>   Funktion97 (poly f, list cstn)
==>   Isomorphie_s82_x (poly f, poly fk, int k)
==>   Isomorphie_s82_z (poly f, poly fk, int k)
==>   Isomorphie_s17 (poly f, poly fk, int k, int ct)
==>   printresult (string f,string typ,int Mu,int m,int corank,int K)
==>   
==>    Internal functions for the classifcation by invariants:
==>   Cubic (poly f)
==>   parity (int e)             //return the parity of e
==>   HKclass (intvec i)
==>   HKclass3( intvec i, string SG_Typ, int cnt)
==>   HKclass3_teil_1 (intvec i, string SG_Typ, int cnt)
==>   HKclass5 (intvec i, string SG_Typ, int cnt)
==>   HKclass5_teil_1 (intvec i, string SG_Typ, int cnt)
==>   HKclass5_teil_2 (intvec i, string SG_Typ, int cnt)
==>   HKclass7 (intvec i, string SG_Typ, int cnt)
==>   HKclass7_teil_1 (intvec i, string SG_Typ, int cnt)
==>   
==>    Internal functions for the Morse-splitting lemma:
==>   Morse(poly fi, int K, int corank)  //splitting lemma itself
==>   Coeffs (list #)
==>   Coeff
==>   
==>    Internal functions providing tools:
==>   ReOrder(poly f)
==>   Singularitaet(string typ,int k,int r,int s,poly a,poly b,poly c,poly d)
==>   RandomPolyK
==>   Faktorisiere(poly f, poly g, int p, int k)   compute g = (ax+by^k)^p
==>   Teile(poly f, poly g);             //divides f by g
==>   GetRf(poly f, int n);
==>   Show(poly f);
==>   checkring();
==>   DecodeNormalFormString(string s);
==>   Setring(int n, string ringname);
==>   

D.5.1.7 milnorcode
..................
Procedure from library classify.lib (see classify_lib).

Usage:
milnorcode(f[,e]); f=poly, e=int

Return:
intvec, coding the Hilbert function of the e-th Milnor algebra
of f, i.e. of basering/(jacob(f)^e) (default e=1), according
to proc Hcode

Example:
LIB "classify.lib";
ring r=0,(x,y,z),ds;
poly f=x2y+y3+z2;
milnorcode(f);
==> 1,1,1
milnorcode(f,2);  // a big second argument may result in memory overflow
==> 1,0,1,0,2,0,0,1,0

D.5.1.8 morsesplit
..................
Procedure from library classify.lib (see classify_lib).

Usage:
morsesplit(f); f=poly

Return:
Normal form of f in M^3 after application of the splitting lemma

Compute:
apply the splitting lemma (generalized Morse lemma) to f

Example:
LIB "classify.lib";
ring r=0,(x,y,z),ds;
export r;
==> // ** `r` is already global
init_debug(1);
==> Debugging level is set to  1
poly f=(x2+3y-2z)^2+xyz-(x-y3+x2*z3)^3;
poly g=morsesplit(f);
==> Residual singularity f= -x3+3/2xy2+1/2x3y-1/16x2y2+3x2y3
g;
==> -x3+3/2xy2+1/2x3y-1/16x2y2+3x2y3

D.5.1.9 quickclass
..................
Procedure from library classify.lib (see classify_lib).

Usage:
quickclass(f); f=poly

Return:
Normal form of f in Arnold's list

Remark:
try to determine the normal form of f by invariants, mainly by
computing the Hilbert function of the Milnor algebra,
no coordinate change is needed (see also proc 'milnorcode').

Example:
LIB "classify.lib";
ring r=0,(x,y,z),ds;
poly f=(x2+3y-2z)^2+xyz-(x-y3+x2*z3)^3;
quickclass(f);
==> Singularity R-equivalent to :  D[k]=D[4]
==> normal form : z2+x2y+y3
==> z2+x2y+y3

D.5.1.10 singularity
....................
Procedure from library classify.lib (see classify_lib).

Usage:
singularity(t, l); t=string (name of singularity),

l=list of integers/polynomials (indices/parameters of singularity)

Compute:
get the singularity named by type t from the database.
list l is as follows: 

l= k [,r [,s [,a [,b [,c [,d]..]: k,r,s=int a,b,c,d=poly. 

The name of the dbm-database file is: NFlist.[dir,pag].
The file is found in the current directory. If it does not
exist, please run the script MakeDBM first.

Return:
Normal form and corank of the singularity named by type t and its
index (indices) l.

Example:
LIB "classify.lib";
ring r=0,(x,y,z),(c,ds);
init_debug(0);
singularity("E[6k]",6);
==> [1]:
==>    x3+xy13+y19
==> [2]:
==>    2
singularity("T[k,r,s]", 3, 7, 5);
==> [1]:
==>    x3+xyz+z5+y7
==> [2]:
==>    3
poly f=y;
singularity("J[k,r]", 4, 0, 0, f);
==> [1]:
==>    x3+x2y4+y13
==> [2]:
==>    2

D.5.1.11 swap
.............
Procedure from library classify.lib (see classify_lib).

Usage:
swap(a,b);

Return:
b,a if b,a is the input (any type)

Example:
LIB "classify.lib";
swap("variable1","variable2");
==> variable2 variable1

D.5.1.12 A_L
............
Procedure from library classify.lib (see classify_lib).

Usage:
A_L(f); f poly

A_L(s); s string, the name of the singularity

Compute:
the normal form of f in Arnold's list of singularities in case 1,
in case 2 nothing has to be computed.

Return:
A_L(f): compute via 'milnorcode' the class of f and return the normal
form of f found in the database.

A_L("name"): get the normal form from the database for the
singularity given by its name.

Example:
LIB "classify.lib";
ring r=0,(a,b,c),ds;
poly f=A_L("E[13]");
f;
==> c2+a3+ab5+b8
A_L(f);
==> Singularity R-equivalent to :  E[6k+1]=E[13]
==> normal form : c2+a3+ab5+b8
==> c2+a3+ab5+b8

D.5.1.13 normalform
...................
Procedure from library classify.lib (see classify_lib).

Usage:
normalform(s); s=string

Return:
Arnold's normal form of singularity with name s

Example:
LIB "classify.lib";
ring r=0,(a,b,c),ds;
normalform("E[13]");
==> c2+a3+ab5+b8

D.5.1.14 debug_log
..................
Procedure from library classify.lib (see classify_lib).

Usage:
debug_log(level,li); level=int, li=comma separated "message" list

Compute:
print "messages" if level>=@DeBug.

useful for user-defined trace messages.

Example:
LIB "classify.lib";
example init_debug;
==> // proc init_debug from lib classify.lib
==> EXAMPLE:
==>   init_debug();
==>   debug_log(1,"no trace information printed");
==>   init_debug(1);
==> Debugging level change from  0  to  1
==>   debug_log(1,"some trace information");
==> some trace information
==>   init_debug(2);
==> Debugging level change from  1  to  2
==>   debug_log(2,"nice for debugging scripts");
==> Debug:(2):  nice for debugging scripts
==>   init_debug(0);
==> Debugging switched off.
==> 

D.5.2 deform_lib
----------------
Library:
deform.lib
Purpose:
    Miniversal Deformation of Singularities and Modules
Author:
Bernd Martin, email: martin@math.tu-cottbus.de


Procedures:
* versal:: miniversal deformation of isolated singularity Fo
* mod_versal:: miniversal deformation of module Mo modulo ideal I
* lift_kbase:: lifting N into standard kbase of M
* lift_rel_kb:: relative lifting N into a kbase of M
* kill_rings:: kills the exported rings from above

D.5.2.1 versal
..............
Procedure from library deform.lib (see deform_lib).

Usage:
versal(Fo[,d,any]); Fo=ideal, d=int, any=list

Compute:
miniversal deformation of Fo up to degree d (default d=100),

Create:
Rings (exported):

'my'Px = extending the basering Po by new variables given by
"A,B,.." (deformation parameters), returns as basering; the
new variables precede the old ones, the ordering is the
product between "ls" and "ord(Po)"

'my'Qx = Px/Fo extending Qo=Po/Fo,

'my'So = the embedding-ring of the versal base space,

'my'Ox = Px/Js extending So/Js. (default my="")

Matrices (in Px, exported):

Js = giving the versal base space (obstructions),

Fs = giving the versal family of Fo,

Rs = giving the lifting of Ro=syz(Fo).

If d is defined (!=0), it computes up to degree d.

If 'any' is defined and any[1] is no string, interactive version.

Otherwise 'any' gives predefined strings: "my","param","order","out"
("my" prefix-string, "param" is a letter (e.g. "A") for the name of
first parameter or (e.g. "A(") for index parameter variables, "order"
ordering string for ring extension), "out" name of output-file).

Note:
printlevel < 0 no output at all,

printlevel >=0,1,2,.. informs you, what is going on;

this proc uses 'execute'.

Example:
LIB "deform.lib";
int p          = printlevel;
printlevel     = 0;
ring r1        = 0,(x,y,z,u,v),ds;
matrix m[2][4] = x,y,z,u,y,z,u,v;
ideal Fo       = minor(m,2);
// cone over rational normal curve of degree 4
versal(Fo);
==> // ready: T_1 and T_2
==> // start computation in degree 2.
==> 
==> // Result belongs to ring Px.
==> // Equations of total space of miniversal deformation are 
==> // given by Fs, equations of miniversal base space by Js.
==> // Make Px the basering and list objects defined in Px by typing:
==>    setring Px; show(Px);
==>    listvar(matrix);
==> // NOTE: rings Qx, Px, So are alive!
==> // (use 'kill_rings("");' to remove)
setring Px;
// ___ Equations of miniversal base space ___:
Js;"";
==> Js[1,1]=BD
==> Js[1,2]=-AD+D2
==> Js[1,3]=-CD
==> 
// ___ Equations of miniversal total space ___:
Fs;"";
==> Fs[1,1]=-u2+zv+Bu+Dv
==> Fs[1,2]=-zu+yv-Au+Du
==> Fs[1,3]=-yu+xv+Cu+Dz
==> Fs[1,4]=z2-yu+Az+By
==> Fs[1,5]=yz-xu+Bx-Cz
==> Fs[1,6]=-y2+xz+Ax+Cy
==> 

D.5.2.2 mod_versal
..................
Procedure from library deform.lib (see deform_lib).

Usage:
mod_versal(Mo,I[,d,any]); I=ideal, M=module, d=int, any =list

Compute:
miniversal deformation of coker(Mo) over Qo=Po/Io, Po=basering;

Create:
Ringsr (exported):

'my'Px = extending the basering by new variables (deformation
parameters), the new variables precede the old ones,

the ordering is the product between "my_ord"

and "ord(Po)"

'my'Qx = Px/Io extending Qo (returns as basering),

'my'Ox = Px/(Io+Js) ring of the versal deformation of coker(Ms),

'my'So = embedding-ring of the versal base space. (default 'my'="")

Matrices (in Qx, exported):

Js = giving the versal base space (obstructions),

Ms = giving the versal family of Mo,

Ls = giving the lifting of syzygies Lo=syz(Mo),

If d is defined (!=0), it computes up to degree d.

If 'any' is defined and any[1] is no string, interactive version.

Otherwise 'any' gives predefined strings:"my","param","order","out"
("my" prefix-string, "param" is a letter (e.g. "A") for the name of
first parameter or (e.g. "A(") for index parameter variables, "ord"
ordering string for ring extension), "out" name of output-file).

Note:
printlevel < 0 no output at all,

printlevel >=0,1,2,.. informs you, what is going on,

this proc uses 'execute'.

Example:
LIB "deform.lib";
int p = printlevel;
printlevel = 1;
ring  Ro = 0,(x,y),wp(3,4);
ideal Io = x4+y3;
matrix Mo[2][2] = x2,y,-y2,x2;
mod_versal(Mo,Io);
==> // vdim (Ext^2) = 4
==> // vdim (Ext^1) = 4
==> // ready: Ext1 and Ext2
==> // Ext1 is quasi-homogeneous represented: 3,6,1,4
==> // infinitesimal extension
==> x2-Ax-B,   y+Cx+D,
==> -y2+Cxy+Dy,x2+Ax+B
==> // start deg = 2
==> // start deg = 3
==> // start deg = 4
==> // start deg = 5
==> // finished in degree 
==> 5
==> // quasi-homogeneous weights of miniversal base
==> 3,6,1,4
==> // Result belongs to qring Qx
==> // Equations of total space of miniversal deformation are in Js
==> -2AB+A3+3CD2-BC3-3AC2D+A2C3,
==> -B2+A2B+D3-3BC2D+ABC3
==> // Matrix of the deformed module is Ms and lifted syzygies are Ls.
==> // Make Qx the basering and list objects defined in Qx by typing:
==>    listvar(ring);setring Qx; show(Qx);listvar(ideal);listvar(matrix);
==> // NOTE: rings Qx, Ox, So are still alive!
==> // (use: 'kill_rings();' to remove them)
printlevel = p;
if(system("with","Namespaces")) {
if(nameof(Current) == "Ring" ) {
kill Top::Px,Top::Qx,Top::So;
} else {
kill Ring::Px,Ring::So;
}
}
kill Px,Qx,So;

D.5.2.3 lift_kbase
..................
Procedure from library deform.lib (see deform_lib).

Usage:
lift_kbase(N,M); N,M=poly/ideal/vector/module

Return:
matrix A, coefficient matrix expressing N as linear combination of
k-basis of M. Let the k-basis have k elements and size(N)=c columns.
Then A satisfies:

matrix(reduce(N,std(M)),k,c) = matrix(kbase(std(M)))*A

Assume:
dim(M)=0 and the monomial ordering is a well ordering or the last
block of the ordering is c or C

Example:
LIB "deform.lib";
ring R=0,(x,y),ds;
module M=[x2,xy],[y2,xy],[0,xx],[0,yy];
module N=[x3+xy,x],[x,x+y2];
print(M);
==> x2,y2,0, 0,
==> xy,xy,x2,y2
module kb=kbase(std(M));
print(kb);
==> y2,xy,y,x,1,0,0,0,
==> 0, 0, 0,0,0,y,x,1 
print(N);
==> xy+x3,x,  
==> x,    x+y2
matrix A=lift_kbase(N,M);
print(A);
==> 0,0,
==> 1,0,
==> 0,0,
==> 0,1,
==> 0,0,
==> 0,0,
==> 1,1,
==> 0,0 
matrix(reduce(N,std(M)),nrows(kb),ncols(A)) - matrix(kbase(std(M)))*A;
==> _[1,1]=0
==> _[1,2]=0
==> _[2,1]=0
==> _[2,2]=0

D.5.2.4 lift_rel_kb
...................
Procedure from library deform.lib (see deform_lib).

Usage:
lift_rel_kb(N,M[,kbaseM,p]);

Assume:
[p a monomial ] or the product of all variables

N, M modules of same rank, M depending only on variables not in p
and vdim(M) is finite in this ring,

[ kbaseM the kbase of M in the subring given by variables not in p ] 

warning: these assumptions are not checked by the procedure

Return:
matrix A, whose j-th columns present the coeff's of N[j] in kbaseM,
i.e. kbaseM*A = reduce(N,std(M))

Example:
LIB "deform.lib";
ring r=0,(A,B,x,y),dp;
module M      = [x2,xy],[xy,y3],[y2],[0,x];
module kbaseM = [1],[x],[xy],[y],[0,1],[0,y],[0,y2];
poly f=xy;
module N = [AB,BBy],[A3xy+x4,AB*(1+y2)];
matrix A = lift_rel_kb(N,M,kbaseM,f);
print(A);
==> AB,0, 
==> 0, 0, 
==> 0, A3,
==> 0, 0, 
==> 0, AB,
==> B2,0, 
==> 0, AB 
"TEST:";
==> TEST:
print(matrix(kbaseM)*A-matrix(reduce(N,std(M))));
==> 0,0,
==> 0,0 

D.5.2.5 kill_rings
..................
Procedure from library deform.lib (see deform_lib).

Usage:
kill_rings([string]);

Return:
nothing, but kills exported rings generated by procedures
'versal' and 'mod_versal' with optional prefix 'string'

D.5.3 equising_lib
------------------
Library:
equising.lib
Purpose:
  Equisingularity Stratum of a Family of Plane Curves
Author:
Christoph Lossen, lossen@mathematik.uni-kl.de

Andrea Mindnich, mindnich@mathematik.uni-kl.de


Main procedures:
* tau_es:: codim of mu-const stratum in semi-universal def. base
* esIdeal:: (Wahl's) equisingularity ideal of f
* esStratum:: equisingularity stratum of a family F
* isEquising:: tests if a given deformation is equisingular
Auxiliary procedure:
* control_Matrix:: computes list of blowing-up data

D.5.3.1 tau_es
..............
Procedure from library equising.lib (see equising_lib).

Usage:
tau_es(f); f poly

Assume:
f is a reduced bivariate polynomial, the basering has precisely
two variables, is local and no qring.

Return:
int, the codimension of the mu-const stratum in the semi-universal
deformation base.

Note:
printlevel>=1 displays additional information.

When called with any additional parameter, the computation of the
Milnor number is avoided (no check for NND).

Example:
LIB "equising.lib";
ring r=32003,(x,y),ds;
poly f=(x4-y4)^2-x10;
tau_es(f);
==> 42


D.5.3.2 esIdeal
...............
Procedure from library equising.lib (see equising_lib).

Usage:
esIdeal(f); f poly

Assume:
f is a reduced bivariate polynomial, the basering has precisely
two variables, is local and no qring, and the characteristic of
the ground field does not divide mult(f).

Return:
list of two ideals:
          _[1]:  equisingularity ideal of f (in sense of Wahl)
          _[2]:  equisingularity ideal of f with fixed section

Note:
if some of the above condition is not satisfied then return
value is list(0,0).

Example:
LIB "equising.lib";
ring r=0,(x,y),ds;
poly f=x7+y7+(x-y)^2*x2y2; 
list K=esIdeal(f);
==> polynomial is Newton degenerated !
==> 
==> // 
==> // versal deformation with triv. section
==> // =====================================
==> // 
==> // 
==> // Compute equisingular Stratum over Spec(C[t]/t^2)
==> // ================================================
==> // 
==> // finished
==> // 
option(redSB);
// Wahl's equisingularity ideal:
std(K[1]);
==> _[1]=4x4y-10x2y3+6xy4+21x6+14y6
==> _[2]=4x3y2-6x2y3+2xy4+7x6
==> _[3]=x2y4-xy5
==> _[4]=x7
==> _[5]=xy6
==> _[6]=y7
ring rr=0,(x,y),ds;
poly f=x4+4x3y+6x2y2+4xy3+y4+2x2y15+4xy16+2y17+xy23+y24+y30+y31;
list K=esIdeal(f);
==> polynomial is Newton degenerated !
==> 
==> // 
==> // versal deformation with triv. section
==> // =====================================
==> // 
==> // 
==> // Compute equisingular Stratum over Spec(C[t]/t^2)
==> // ================================================
==> // 
==> // finished
==> // 
vdim(std(K[1]));
==> 68
// the latter should be equal to: 
tau_es(f);
==> 68


D.5.3.3 esStratum
.................
Procedure from library equising.lib (see equising_lib).

Usage:
esStratum(F[,m,L]); F poly, m int, L list

Assume:
F defines a deformation of a reduced bivariate polynomial f
and the characteristic of the basering does not divide mult(f). 

If nv is the number of variables of the basering, then the first
nv-2 variables are the deformation parameters. 

If the basering is a qring, ideal(basering) must only depend
on the deformation parameters.

Compute:
equations for the stratum of equisingular deformations with 
fixed (trivial) section.

Return:
list l: either consisting of an ideal and an integer, where
  l[1]=ideal defining the equisingular stratum
  l[2]=1 if some error has occured,  l[2]=0 otherwise;
or consisting of a ring and an integer, where
  l[1]=ESSring is a ring extension of basering containing the ideal ES 
        (describing the ES-stratum) and the poly p_F=F,
  l[2]=1 if some error has occured,  l[2]=0 otherwise.

Note:
L is supposed to be the output of reddevelop (with the given ordering
of the variables appearing in f). 

If m is given, the ES Stratum over A/maxideal(m) is computed. 

This procedure uses execute or calls a procedure using
execute.
printlevel>=2 displays additional information.

Example:
LIB "equising.lib";
int p=printlevel; 
printlevel=1;
ring r = 0,(a,b,c,d,e,f,g,x,y),ds;
poly F = (x2+2xy+y2+x5)+ax+by+cx2+dxy+ey2+fx3+gx4;
list M = esStratum(F);
M[1];
==> _[1]=g
==> _[2]=f
==> _[3]=b
==> _[4]=a
==> _[5]=-4c+4d-4e+d2-4ce
printlevel=3;    // displays additional information
esStratum(F,2);  // es stratum over Q[a,b,c,d,e,f,g] / <a,b,c,d,e,f,g>^2
==> // 
==> // Compute HN development
==> // ----------------------
==> // finished
==> // 
==> // Blowup Step 1 completed
==> // Blowup Step 2 completed
==> // Blowup Step 3 completed
==> // 1 branch finished
==> // 
==> // Elimination starts:
==> // -------------------
==> // finished
==> // 
==> // output of 'esStratum' is list consisting of:
==> //    _[1] = ideal defining equisingular stratum
==> //    _[2] = 0
==> [1]:
==>    _[1]=b
==>    _[2]=a
==>    _[3]=c-d+e
==>    _[4]=g
==>    _[5]=f
==> [2]:
==>    0
ideal I = f-fa,e+b;
qring q = std(I);
poly F = imap(r,F);
esStratum(F);
==> // 
==> // Compute HN development
==> // ----------------------
==> // finished
==> // 
==> // Blowup Step 1 completed
==> // Blowup Step 2 completed
==> // Blowup Step 3 completed
==> // 1 branch finished
==> // 
==> // Elimination starts:
==> // -------------------
==> // finished
==> // 
==> // output of 'esStratum' is list consisting of:
==> //    _[1] = ideal defining equisingular stratum
==> //    _[2] = 0
==> [1]:
==>    _[1]=e
==>    _[2]=a
==>    _[3]=-4c+4d+d2
==>    _[4]=g
==> [2]:
==>    0
printlevel=p;


D.5.3.4 isEquising
..................
Procedure from library equising.lib (see equising_lib).

Usage:
isEquising(F[,m,L]); F poly, m int, L list

Assume:
F defines a deformation of a reduced bivariate polynomial f
and the characteristic of the basering does not divide mult(f). 

If nv is the number of variables of the basering, then the first
nv-2 variables are the deformation parameters. 

If the basering is a qring, ideal(basering) must only depend
on the deformation parameters.

Compute:
tests if the given family is equisingular along the trivial
section.

Return:
int: 1 if the family is equisingular, 0 otherwise.

Note:
L is supposed to be the output of reddevelop (with the given ordering
of the variables appearing in f). 

If m is given, the family is considered over A/maxideal(m). 

This procedure uses execute or calls a procedure using
execute.
printlevel>=2 displays additional information.

Example:
LIB "equising.lib";
ring r = 0,(a,b,x,y),ds;
poly F = (x2+2xy+y2+x5)+ay3+bx5;
isEquising(F);
==> 0
ideal I = ideal(a);
qring q = std(I);
poly F = imap(r,F);
isEquising(F);
==> 1
ring rr=0,(A,B,C,x,y),ls;
poly f=x7+y7+(x-y)^2*x2y2;
poly F=f+A*y*diff(f,x)+B*x*diff(f,x);
isEquising(F);  
==> 0
isEquising(F,2);    // computation over  Q[a,b] / <a,b>^2
==> 1

D.5.3.5 control_Matrix
......................
Procedure from library equising.lib (see equising_lib).

Assume:
L is the output of multsequence(reddevelop(f)).

Return:
list M of 4 intmat's:
  M[1] contains the multiplicities at the respective infinitely near points 
       p[i,j] (i=step of blowup+1, j=branch) - if branches j=k,...,k+m pass 
       through the same p[i,j] then the multiplicity is stored in M[1][k,j], 
       while M[1][k+1]=...=M[1][k+m]=0.   
  M[2] contains the number of branches meeting at p[i,j] (again, the information 
       is stored according to the above rule)   
  M[3] contains the information about the splitting of M[1][i,j] with respect to 
       different tangents of branches at p[i,j] (information is stored only for 
       minimal j>=k corresponding to a new tangent direction). 
       The entries are the sum of multiplicities of all branches with the 
       respective tangent.
  M[4] contains the maximal sum of higher multiplicities for a branch passing 
       through p[i,j] ( = degree Bound for blowing up)  

Note:
the branches are ordered in such a way that only consecutive branches
can meet at an infinitely near point. 

the final rows of the matrices M[1],...,M[3] is (1,1,1,...,1), and
correspond to infinitely near points such that the strict transforms
of the branches are smooth and intersect the exceptional divisor
transversally.


D.5.4 gaussman_lib
------------------
Library:
gaussman.lib
Purpose:
  Algorithmic Gauss-Manin Connection

Author:
Mathias Schulze, email: mschulze@mathematik.uni-kl.de

Overview:
A library to compute Hodge-theoretic invariants

of isolated hypersurface singularities


Procedures:
* gmsring:: Gauss-Manin system of t with variable s
* gmsnf:: Gauss-Manin normal form of p
* gmscoeffs:: Gauss-Manin basis representation of p
* bernstein:: roots of the Bernstein polynomial of t
* monodromy:: Jordan data of complex monodromy of t
* spectrum:: singularity spectrum of t
* sppairs:: spectral pairs of t
* spnf:: spectrum normal form of (a,m,V)
* sppnf:: spectral pairs normal form of (a,w,m,V)
* vfilt:: V-filtration of t on Brieskorn lattice
* vwfilt:: weighted V-filtration of t on Brieskorn lattice
* tmatrix:: C[[s]]-matrix of t on Brieskorn lattice
* endvfilt:: endomorphism V-filtration on Jacobian algebra
* spprint:: print spectrum sp
* sppprint:: print spectral pairs spp
* spadd:: sum of spectra sp1 and sp2
* spsub:: difference of spectra sp1 and sp2
* spmul:: linear combination of spectra sp
* spissemicont:: semicontinuity test of spectrum sp
* spsemicont:: semicontinuous combinations of spectra sp0 in sp
* spmilnor:: Milnor number of spectrum sp
* spgeomgenus:: geometrical genus of spectrum sp
* spgamma:: gamma invariant of spectrum sp


D.5.4.1 gmsring
...............
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
gmsring(t,s); poly t, string s

Assume:
characteristic 0; local degree ordering;

isolated critical point 0 of t

Return:
ring G;  Gauss-Manin system of t with variable s
  poly gmspoly=t;
  ideal gmsjacob;  Jacobian ideal of t
  ideal gmsstd;  standard basis of Jacobian ideal
  matrix gmsmatrix;  matrix(gmsjacob)*gmsmatrix==matrix(gmsstd)
  ideal gmsbasis;  monomial vector space basis of Jacobian algebra
  int gmsmaxdeg;  maximal weight of variables

Note:
gmsbasis is a C[[s]]-basis of H" and [t,s]=s^2

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
poly t=x5+x2y2+y5;
def G=gmsring(t,"s");
setring(G);
gmspoly;
==> x2y2+x5+y5
print(gmsjacob);
==> 2xy2+5x4,
==> 2x2y+5y4
print(gmsstd);
==> 2x2y+5y4,
==> 2xy2+5x4,
==> 5x5-5y5,
==> 10y6+25x3y4
print(gmsmatrix);
==> 0,1,x, -2xy,  
==> 1,0,-y,2y2+5x3
print(gmsbasis);
==> y5,
==> y4,
==> y3,
==> y2,
==> xy,
==> y,
==> x4,
==> x3,
==> x2,
==> x,
==> 1
gmsmaxdeg;
==> 1

D.5.4.2 gmsnf
.............
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
gmsnf(p,K); poly p, int K

Assume:
basering returned by gmsring

Return:
list nf;
  ideal nf[1];  projection of p to <gmsbasis>C[[s]] mod s^(K+1)
  ideal nf[2];  p==nf[1]+nf[2]

Note:
computation can be continued by setting p=nf[2]

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
poly t=x5+x2y2+y5;
def G=gmsring(t,"s");
setring(G);
list l0=gmsnf(gmspoly,0);
print(l0[1]);
==> -1/2y5
list l1=gmsnf(gmspoly,1);
print(l1[1]);
==> -1/2y5+1/2s
list l=gmsnf(l0[2],1);
print(l[1]);
==> 1/2s

D.5.4.3 gmscoeffs
.................
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
gmscoeffs(p,K); poly p, int K

Assume:
basering constructed by gmsring

Return:
list l;
  matrix l[1];  C[[s]]-basis representation of p mod s^(K+1)
  ideal l[2];  p==matrix(gmsbasis)*l[1]+l[2]

Note:
computation can be continued by setting p=l[2]

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
poly t=x5+x2y2+y5;
def G=gmsring(t,"s");
setring(G);
list l0=gmscoeffs(gmspoly,0);
print(l0[1]);
==> -1/2,
==> 0,   
==> 0,   
==> 0,   
==> 0,   
==> 0,   
==> 0,   
==> 0,   
==> 0,   
==> 0,   
==> 0    
list l1=gmscoeffs(gmspoly,1);
print(l1[1]);
==> -1/2,
==> 0,   
==> 0,   
==> 0,   
==> 0,   
==> 0,   
==> 0,   
==> 0,   
==> 0,   
==> 0,   
==> 1/2s 
list l=gmscoeffs(l0[2],1);
print(l[1]);
==> 0,  
==> 0,  
==> 0,  
==> 0,  
==> 0,  
==> 0,  
==> 0,  
==> 0,  
==> 0,  
==> 0,  
==> 1/2s

D.5.4.4 bernstein
.................
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
bernstein(t); poly t

Assume:
characteristic 0; local degree ordering;

isolated critical point 0 of t

Return:
ideal r; roots of the Bernstein polynomial b excluding the root -1

Note:
the roots of b are negative rational numbers and -1 is a root of b

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
poly t=x5+x2y2+y5;
bernstein(t);
==> [1]:
==>    _[1]=-1/2
==>    _[2]=-7/10
==>    _[3]=-9/10
==>    _[4]=-1
==>    _[5]=-11/10
==>    _[6]=-13/10
==> [2]:
==>    2,1,1,2,1,1

D.5.4.5 monodromy
.................
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
monodromy(t); poly t

Assume:
characteristic 0; local degree ordering;

isolated critical point 0 of t

Return:
list l;  Jordan data jordan(M) of monodromy matrix exp(-2*pi*i*M)
  ideal l[1]; 
    number l[1][i];  eigenvalue of i-th Jordan block of M
  intvec l[2]; 
    int l[2][i];  size of i-th Jordan block of M
  intvec l[3]; 
    int l[3][i];  multiplicity of i-th Jordan block of M

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
poly t=x5+x2y2+y5;
monodromy(t);
==> [1]:
==>    _[1]=1/2
==>    _[2]=7/10
==>    _[3]=9/10
==>    _[4]=1
==>    _[5]=11/10
==>    _[6]=13/10
==> [2]:
==>    2,1,1,1,1,1
==> [3]:
==>    1,2,2,1,2,2


D.5.4.6 spectrum
................
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
spectrum(t); poly t

Assume:
characteristic 0; local degree ordering;

isolated critical point 0 of t

Return:
list sp;  singularity spectrum of t
  ideal sp[1];
    number sp[1][i];  i-th spectral number
  intvec sp[2];
    int sp[2][i];  multiplicity of i-th spectral number

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
poly t=x5+x2y2+y5;
spprint(spectrum(t));
==> (-1/2,1),(-3/10,2),(-1/10,2),(0,1),(1/10,2),(3/10,2),(1/2,1)


D.5.4.7 sppairs
...............
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
sppairs(t); poly t

Assume:
characteristic 0; local degree ordering;

isolated critical point 0 of t

Return:
list spp;  spectral pairs of t
  ideal spp[1];
    number spp[1][i];  V-filtration index of i-th spectral pair
  intvec spp[2];
    int spp[2][i];  weight filtration index of i-th spectral pair
  intvec spp[3];
    int spp[3][i];  multiplicity of i-th spectral pair

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
poly t=x5+x2y2+y5;
sppprint(sppairs(t));
==> ((-1/2,2),1),((-3/10,1),2),((-1/10,1),2),((0,1),1),((1/10,1),2),((3/10,1)\
   ,2),((1/2,0),1)


D.5.4.8 spnf
............
Procedure from library gaussman.lib (see gaussman_lib).

Assume:
ncols(a)==size(m)==size(V); typeof(V[i])=="int"

Return:
order (a[i][,V[i]]) with multiplicity m[i] lexicographically


D.5.4.9 sppnf
.............
Procedure from library gaussman.lib (see gaussman_lib).

Assume:
ncols(e)=size(w)=size(m)=size(V); typeof(V[i])=="module"

Return:
order (a[i][,w[i]][,V[i]]) with multiplicity m[i] lexicographically


D.5.4.10 vfilt
..............
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
vfilt(t); poly t

Assume:
characteristic 0; local degree ordering;

isolated critical point 0 of t

Return:
list v;  V-filtration on H"/s*H"
  ideal v[1];
    number v[1][i];  V-filtration index of i-th spectral number
  intvec v[2];
    int v[2][i];  multiplicity of i-th spectral number
  list v[3];
    module v[3][i];  vector space of i-th graded part in terms of v[4]
  ideal v[4];  monomial vector space basis of H"/s*H"
  ideal v[5];  standard basis of Jacobian ideal

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
poly t=x5+x2y2+y5;
vfilt(t);
==> [1]:
==>    _[1]=-1/2
==>    _[2]=-3/10
==>    _[3]=-1/10
==>    _[4]=0
==>    _[5]=1/10
==>    _[6]=3/10
==>    _[7]=1/2
==> [2]:
==>    1,2,2,1,2,2,1
==> [3]:
==>    [1]:
==>       _[1]=gen(11)
==>    [2]:
==>       _[1]=gen(10)
==>       _[2]=gen(6)
==>    [3]:
==>       _[1]=gen(9)
==>       _[2]=gen(4)
==>    [4]:
==>       _[1]=gen(5)
==>    [5]:
==>       _[1]=gen(3)
==>       _[2]=gen(8)
==>    [6]:
==>       _[1]=gen(2)
==>       _[2]=gen(7)
==>    [7]:
==>       _[1]=gen(1)
==> [4]:
==>    _[1]=y5
==>    _[2]=y4
==>    _[3]=y3
==>    _[4]=y2
==>    _[5]=xy
==>    _[6]=y
==>    _[7]=x4
==>    _[8]=x3
==>    _[9]=x2
==>    _[10]=x
==>    _[11]=1
==> [5]:
==>    _[1]=2x2y+5y4
==>    _[2]=2xy2+5x4
==>    _[3]=5x5-5y5
==>    _[4]=10y6+25x3y4


D.5.4.11 vwfilt
...............
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
vwfilt(t); poly t

Assume:
characteristic 0; local degree ordering;

isolated critical point 0 of t

Return:
list vw;  weighted V-filtration on H"/s*H"
  ideal vw[1];
    number vw[1][i];  V-filtration index of i-th spectral pair
  intvec vw[2];
    int vw[2][i];  weight filtration index of i-th spectral pair
  intvec vw[3];
    int vw[3][i];  multiplicity of i-th spectral pair
  list vw[4];
    module vw[4][i];  vector space of i-th graded part in terms of vw[5]
  ideal vw[5];  monomial vector space basis of H"/s*H"
  ideal vw[6];  standard basis of Jacobian ideal

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
poly t=x5+x2y2+y5;
vwfilt(t);
==> [1]:
==>    _[1]=-1/2
==>    _[2]=-3/10
==>    _[3]=-1/10
==>    _[4]=0
==>    _[5]=1/10
==>    _[6]=3/10
==>    _[7]=1/2
==> [2]:
==>    2,1,1,1,1,1,0
==> [3]:
==>    1,2,2,1,2,2,1
==> [4]:
==>    [1]:
==>       _[1]=gen(11)
==>    [2]:
==>       _[1]=gen(10)
==>       _[2]=gen(6)
==>    [3]:
==>       _[1]=gen(9)
==>       _[2]=gen(4)
==>    [4]:
==>       _[1]=gen(5)
==>    [5]:
==>       _[1]=gen(3)
==>       _[2]=gen(8)
==>    [6]:
==>       _[1]=gen(2)
==>       _[2]=gen(7)
==>    [7]:
==>       _[1]=gen(1)
==> [5]:
==>    _[1]=y5
==>    _[2]=y4
==>    _[3]=y3
==>    _[4]=y2
==>    _[5]=xy
==>    _[6]=y
==>    _[7]=x4
==>    _[8]=x3
==>    _[9]=x2
==>    _[10]=x
==>    _[11]=1
==> [6]:
==>    _[1]=2x2y+5y4
==>    _[2]=2xy2+5x4
==>    _[3]=5x5-5y5
==>    _[4]=10y6+25x3y4


D.5.4.12 tmatrix
................
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
tmatrix(t); poly t

Assume:
characteristic 0; local degree ordering;

isolated critical point 0 of t

Return:
list l=A0,A1,T,M;
  matrix A0,A1;  t=A0+s*A1+s^2*(d/ds) on H" w.r.t. C[[s]]-basis M*T
  module T;  C-basis of C^mu
  ideal M;  monomial C-basis of H"/sH"

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
poly t=x5+x2y2+y5;
list A=tmatrix(t);
print(A[1]);
==> 0,0,0,0,0,0,0,0,0,0,0,
==> 0,0,0,0,0,0,0,0,0,0,0,
==> 0,0,0,0,0,0,0,0,0,0,0,
==> 0,0,0,0,0,0,0,0,0,0,0,
==> 0,0,0,0,0,0,0,0,0,0,0,
==> 0,0,0,0,0,0,0,0,0,0,0,
==> 0,0,0,0,0,0,0,0,0,0,0,
==> 0,0,0,0,0,0,0,0,0,0,0,
==> 0,0,0,0,0,0,0,0,0,0,0,
==> 0,0,0,0,0,0,0,0,0,0,0,
==> 1,0,0,0,0,0,0,0,0,0,0 
print(A[2]);
==> 1/2,0,   0,   0,   0,   0,0,    0,    0,    0,    0, 
==> 0,  7/10,0,   0,   0,   0,0,    0,    0,    0,    0, 
==> 0,  0,   7/10,0,   0,   0,0,    0,    0,    0,    0, 
==> 0,  0,   0,   9/10,0,   0,0,    0,    0,    0,    0, 
==> 0,  0,   0,   0,   9/10,0,0,    0,    0,    0,    0, 
==> 0,  0,   0,   0,   0,   1,0,    0,    0,    0,    0, 
==> 0,  0,   0,   0,   0,   0,11/10,0,    0,    0,    0, 
==> 0,  0,   0,   0,   0,   0,0,    11/10,0,    0,    0, 
==> 0,  0,   0,   0,   0,   0,0,    0,    13/10,0,    0, 
==> 0,  0,   0,   0,   0,   0,0,    0,    0,    13/10,0, 
==> 0,  0,   0,   0,   0,   0,0,    0,    0,    0,    3/2
print(A[3]);
==> -1445/64,0,  0,  0,0,85/8,0,0,0,0,1/2,
==> 0,       125,0,  0,0,0,   0,0,1,0,0,  
==> 0,       0,  0,  5,0,0,   1,0,0,0,0,  
==> 0,       0,  0,  0,4,0,   0,0,0,0,0,  
==> 2,       0,  0,  0,0,1,   0,0,0,0,0,  
==> 0,       0,  16, 0,0,0,   0,0,0,0,0,  
==> 0,       0,  125,0,0,0,   0,0,0,1,0,  
==> 0,       0,  0,  0,5,0,   0,1,0,0,0,  
==> 0,       0,  0,  4,0,0,   0,0,0,0,0,  
==> 0,       16, 0,  0,0,0,   0,0,0,0,0,  
==> -1,      0,  0,  0,0,0,   0,0,0,0,0   
print(A[4]);
==> y5,
==> y4,
==> y3,
==> y2,
==> xy,
==> y,
==> x4,
==> x3,
==> x2,
==> x,
==> 1

D.5.4.13 endvfilt
.................
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
endvfilt(v); list v

Assume:
v returned by vfilt

Return:
list ev;  V-filtration on Jacobian algebra
  ideal ev[1];
    number ev[1][i];  i-th V-filtration index
  intvec ev[2];
    int ev[2][i];  i-th multiplicity
  list ev[3];
    module ev[3][i];  vector space of i-th graded part in terms of ev[4]
  ideal ev[4];  monomial vector space basis of Jacobian algebra
  ideal ev[5];  standard basis of Jacobian ideal

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
poly t=x5+x2y2+y5;
endvfilt(vfilt(t));
==> [1]:
==>    _[1]=0
==>    _[2]=1/5
==>    _[3]=2/5
==>    _[4]=1/2
==>    _[5]=3/5
==>    _[6]=4/5
==>    _[7]=1
==> [2]:
==>    1,2,2,1,2,2,1
==> [3]:
==>    [1]:
==>       _[1]=gen(11)
==>    [2]:
==>       _[1]=gen(10)
==>       _[2]=gen(6)
==>    [3]:
==>       _[1]=gen(9)
==>       _[2]=gen(4)
==>    [4]:
==>       _[1]=gen(5)
==>    [5]:
==>       _[1]=gen(8)
==>       _[2]=gen(3)
==>    [6]:
==>       _[1]=gen(7)
==>       _[2]=gen(2)
==>    [7]:
==>       _[1]=gen(1)
==> [4]:
==>    _[1]=y5
==>    _[2]=y4
==>    _[3]=y3
==>    _[4]=y2
==>    _[5]=xy
==>    _[6]=y
==>    _[7]=x4
==>    _[8]=x3
==>    _[9]=x2
==>    _[10]=x
==>    _[11]=1
==> [5]:
==>    _[1]=2x2y+5y4
==>    _[2]=2xy2+5x4
==>    _[3]=5x5-5y5
==>    _[4]=10y6+25x3y4

D.5.4.14 spprint
................
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
spprint(sp); list sp

Return:
string s; spectrum sp

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
list sp=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
spprint(sp);
==> (-1/2,1),(-3/10,2),(-1/10,2),(0,1),(1/10,2),(3/10,2),(1/2,1)

D.5.4.15 sppprint
.................
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
sppprint(spp); list spp

Return:
string s; spectral pairs spp

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
list spp=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(2,1,1,1,1,1,0),intvec(1,2,2,1,2,2,1));
sppprint(spp);
==> ((-1/2,2),1),((-3/10,1),2),((-1/10,1),2),((0,1),1),((1/10,1),2),((3/10,1)\
   ,2),((1/2,0),1)

D.5.4.16 spadd
..............
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
spadd(sp1,sp2); list sp1, list sp2

Return:
list sp; sum of spectra sp1 and sp2

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
list sp1=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
spprint(sp1);
==> (-1/2,1),(-3/10,2),(-1/10,2),(0,1),(1/10,2),(3/10,2),(1/2,1)
list sp2=list(ideal(-1/6,1/6),intvec(1,1));
spprint(sp2);
==> (-1/6,1),(1/6,1)
spprint(spadd(sp1,sp2));
==> (-1/2,1),(-3/10,2),(-1/6,1),(-1/10,2),(0,1),(1/10,2),(1/6,1),(3/10,2),(1/\
   2,1)

D.5.4.17 spsub
..............
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
spsub(sp1,sp2); list sp1, list sp2

Return:
list sp; difference of spectra sp1 and sp2

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
list sp1=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
spprint(sp1);
==> (-1/2,1),(-3/10,2),(-1/10,2),(0,1),(1/10,2),(3/10,2),(1/2,1)
list sp2=list(ideal(-1/6,1/6),intvec(1,1));
spprint(sp2);
==> (-1/6,1),(1/6,1)
spprint(spsub(sp1,sp2));
==> (-1/2,1),(-3/10,2),(-1/6,-1),(-1/10,2),(0,1),(1/10,2),(1/6,-1),(3/10,2),(\
   1/2,1)

D.5.4.18 spmul
..............
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
spmul(sp0,k); list sp0, int[vec] k

Return:
list sp; linear combination of spectra sp0 with coefficients k

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
list sp=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
spprint(sp);
==> (-1/2,1),(-3/10,2),(-1/10,2),(0,1),(1/10,2),(3/10,2),(1/2,1)
spprint(spmul(sp,2));
==> (-1/2,2),(-3/10,4),(-1/10,4),(0,2),(1/10,4),(3/10,4),(1/2,2)
list sp1=list(ideal(-1/6,1/6),intvec(1,1));
spprint(sp1);
==> (-1/6,1),(1/6,1)
list sp2=list(ideal(-1/3,0,1/3),intvec(1,2,1));
spprint(sp2);
==> (-1/3,1),(0,2),(1/3,1)
spprint(spmul(list(sp1,sp2),intvec(1,2)));
==> (-1/3,2),(-1/6,1),(0,4),(1/6,1),(1/3,2)

D.5.4.19 spissemicont
.....................
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
spissemicont(sp[,1]); list sp, int opt

Return:
int k=
  1;  if sum of sp is positive on all intervals [a,a+1) [and (a,a+1)]
  0;  if sum of sp is negative on some interval [a,a+1) [or (a,a+1)]

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
list sp1=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
spprint(sp1);
==> (-1/2,1),(-3/10,2),(-1/10,2),(0,1),(1/10,2),(3/10,2),(1/2,1)
list sp2=list(ideal(-1/6,1/6),intvec(1,1));
spprint(sp2);
==> (-1/6,1),(1/6,1)
spissemicont(spsub(sp1,spmul(sp2,3)));
==> 1
spissemicont(spsub(sp1,spmul(sp2,4)));
==> 0

D.5.4.20 spsemicont
...................
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
spsemicont(sp0,sp,k[,1]); list sp0, list sp

Return:
list l;
  intvec l[i];  if the spectra sp0 occur with multiplicities k
                in a deformation of a [quasihomogeneous] singularity
                with spectrum sp then k<=l[i]

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
list sp0=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
spprint(sp0);
==> (-1/2,1),(-3/10,2),(-1/10,2),(0,1),(1/10,2),(3/10,2),(1/2,1)
list sp1=list(ideal(-1/6,1/6),intvec(1,1));
spprint(sp1);
==> (-1/6,1),(1/6,1)
list sp2=list(ideal(-1/3,0,1/3),intvec(1,2,1));
spprint(sp2);
==> (-1/3,1),(0,2),(1/3,1)
list sp=sp1,sp2;
list l=spsemicont(sp0,sp);
l;
==> [1]:
==>    3
==> [2]:
==>    2,1
spissemicont(spsub(sp0,spmul(sp,l[1])));
==> 1
spissemicont(spsub(sp0,spmul(sp,l[1]-1)));
==> 1
spissemicont(spsub(sp0,spmul(sp,l[1]+1)));
==> 0

D.5.4.21 spmilnor
.................
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
spmilnor(sp); list sp

Return:
int mu; Milnor number of spectrum sp

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
list sp=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
spprint(sp);
==> (-1/2,1),(-3/10,2),(-1/10,2),(0,1),(1/10,2),(3/10,2),(1/2,1)
spmilnor(sp);
==> 11

D.5.4.22 spgeomgenus
....................
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
spgeomgenus(sp); list sp

Return:
int g; geometrical genus of spectrum sp

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
list sp=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
spprint(sp);
==> (-1/2,1),(-3/10,2),(-1/10,2),(0,1),(1/10,2),(3/10,2),(1/2,1)
spgeomgenus(sp);
==> 6

D.5.4.23 spgamma
................
Procedure from library gaussman.lib (see gaussman_lib).

Usage:
spgamma(sp); list sp

Return:
number gamma; gamma invariant of spectrum sp

Example:
LIB "gaussman.lib";
ring R=0,(x,y),ds;
list sp=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
spprint(sp);
==> (-1/2,1),(-3/10,2),(-1/10,2),(0,1),(1/10,2),(3/10,2),(1/2,1)
spgamma(sp);
==> 1/240
D.5.5 hnoether_lib
------------------
Library:
hnoether.lib
Purpose:
   Hamburger-Noether (Puiseux) Development
Author:
Martin Lamm, lamm@mathematik.uni-kl.de

Overview:
A library for computing the Hamburger-Noether, resp. Puiseux, development
of a plane curve singularity following [Campillo, A.: Algebroid curves
in positive characteristic, Springer LNM 813 (1980)]. 

The library contains also procedures for computing the (topological)
numerical invariants of plane curve singularities.


Main procedures:
* hnexpansion:: Hamburger-Noether (H-N) development of f
* sethnering:: changes to the hnering created by hnexpansion
* develop:: H-N development of irreducible curves
* extdevelop:: extension of the H-N development hne of f
* parametrisation:: a parametrization of f
* displayHNE:: display H-N development as an ideal
* invariants:: invariants of f, e.g. the characteristic exponents
* displayInvariants:: display invariants of f
* multsequence:: sequence of multiplicities
* displayMultsequence:: display sequence of multiplicities
* intersection:: intersection multiplicity of two curves
* stripHNE:: reduce amount of memory consumed by hne
* is_irred:: test if f is irreducible
* delta:: delta invariant of f
* newtonpoly:: (local) Newton polygon of f
* is_NND:: test if f is Newton non-degenerate
Auxiliary procedures:
* puiseux2generators:: convert Puiseux pairs to generators of semigroup
* separateHNE:: number of quadratic transf. needed for separation
* squarefree:: a squarefree divisor of the poly f
* allsquarefree:: the maximal squarefree divisor of the poly f
* further_hn_proc:: show further procedures useful for interactive use

D.5.5.1 hnexpansion
...................
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
hnexpansion(f); or hnexpansion(f,"ess"); f poly

Usage:
hnexpansion(f); f poly

Assume:
f is a bivariate polynomial (in the first 2 ring variables)

Create:
ring with variables x,y and ordering ls over a
field extension of the current basering's ground field, 
since the Hamburger-Noether development usually does not exist
in the originally given basering. The field extension is chosen
minimally.

Moreover, in the ring a list hne of lists hne[i] is
created (corresponding to the output of develop(f[i]),
f[i] a branch of f, but the last entry being omitted).

hne[i][1]; matrix:
         Each row contains the coefficients of the corresponding line of the
         Hamburger-Noether expansion (HNE) for f[i]. The end of the line is
         marked in the matrix by the first ring variable (usually x).
hne[i][2]; intvec:
         indicating the length of lines of the HNE
hne[i][3]; int:
         0  if the 1st ring variable was transversal (with respect to f[i]), 

         1  if the variables were changed at the beginning of the
            computation, 

        -1  if an error has occurred.
hne[i][4]; poly:
         the transformed polynomial of f[i] to make it possible to extend the
         Hamburger-Noether development a posteriori without having to do
         all the previous calculation once again (0 if not needed)

Return:
a list, say hn, containing the created ring

Note:
to use the ring type: def HNEring=hn[i]; setring HNEring;.


If f is known to be irreducible as a power series, develop(f)
could be chosen instead to avoid the change of basering. 

Increasing printlevel leads to more and more comments.

Usage:
hnexpansion(f,"ess"); f poly

Assume:
f is a bivariate polynomial (in the first 2 ring variables)

Create:
ring with variables x,y and ordering ls over a
field extension of the current basering's ground field, 
since the Hamburger-Noether development usually does not exist
in the originally given basering. The field extension is chosen
minimally.


Moreover, in the ring a list hne of lists hne[i] is
created (corresponding to the output of develop(f[i]), f[i] an
"essential" branch of f, but the last entry being omitted). See
hnexpansion above for more details.

Return:
a list, say hn, containing the created ring

Note:
to use the ring type: def hnering=hn[i]; setring hnering;.


Alternatively you may use the procedure sethnering and type:
sethnering(hn);


If the HNE needs a field extension, some of the branches will be
conjugate. In this case hnexpansion(f,"ess") reduces the
computation to one representative for each group of conjugate
branches.

Note that the degree of each branch is in general less than the degree
of the field extension in which all HNEs can be put.

Use hnexpansion(f) to compute a complete HNE, i.e., a HNE for
all branches.

Increasing printlevel leads to more and more comments.

Example:
LIB "hnoether.lib";
ring r=0,(x,y),ls;
list hn=hnexpansion(x4-y6);
show(hn);
==> // list, 1 element(s):
==> [1]:
==>    // ring: (0),(x,y),(ls(2),C);
==>    // minpoly = 0
==> // objects belonging to this ring:
==> // hne                  [0]  list, size: 2
def hnering=hn[1];
setring hnering;
size(hne);           // number of branches
==> 2
print(hne[1][1]);    // HN-matrix of 1st branch
==> 0,x,0,
==> 0,1,x 
parametrisation(hne);    // parametrization of the two branches
==> [1]:
==>    _[1]=x3
==>    _[2]=x2
==> [2]:
==>    _[1]=-x3
==>    _[2]=-x2
/////////////////////////////////////////////////////////
ring s=2,(x,y),ls;
poly f=(x4+x2y+y2)*(x3+xy2+y3);
// --------- compute all branches: ---------
hn=hnexpansion(f);
==> // new minimal polynomial: a6+a5+a3+a2+1
hnering=hn[1];
setring hnering;
displayHNE(hne[1]);   // HN-matrix of 1st branch
==> HNE[1]=y+(a^4+a+1)*z(0)
==> HNE[2]=x+z(0)
displayHNE(hne[4]);   // HN-matrix of 4th branch
==> HNE[1]=y+(a^4+a^2+a+1)*z(0)^2
==> HNE[2]=x+z(0)
setring s;
// --- compute only one of conjugate branches: ---
hn=hnexpansion(f,"ess");
==> // new minimal polynomial: a6+a5+a3+a2+1
hnering=hn[1];
setring hnering;
displayHNE(hne);
==> // Hamburger-Noether development of branch nr.1:
==> HNE[1]=y+(a^4+a^2)*z(0)
==> HNE[2]=x+z(0)
==> 
==> // Hamburger-Noether development of branch nr.2:
==> HNE[1]=y+(a^4+a^2+a)*z(0)^2
==> HNE[2]=x+z(0)
==> 
// no. 1 of hnexpansion(f,"ess") represents no. 1 - 3 of hnexpansion(f) and
// no. 2 of hnexpansion(f,"ess") represents no. 4 + 5 of hnexpansion(f)


D.5.5.2 sethnering
..................
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
sethnering(L[,s]); L list, s string (optional)

Assume:
L is a list containing a ring (e.g. the output of hnexpansion).

Create:
The procedure creates a ring with name given by the optional parameter
s resp. with name hnering, if no optional parameter is given, and
changes your ring to this ring. The new ring will be the ring given
as the first entry in the list L.

Return:
nothing.

Example:
LIB "hnoether.lib";
// -------- prepare for example ---------
if (defined(hnering))
{
def rette@ring=hnering;
if (nameof(basering)=="hnering")
{
int wechsel=1;
}
else
{
int wechsel;
}
kill hnering;
}
// ------ the example starts here -------
ring r=0,(x,y),ls;
nameof(basering);
==> r
sethnering(hnexpansion(x4-y6)); // Creates hnering and changes to it!
nameof(basering);
==> hnering
// --- restore HNEring if previously defined ---
kill hnering;
if (defined(rette@ring)) {
def hnering=rette@ring;
export hnering;
if (wechsel==1)
{
setring hnering;
}
}


D.5.5.3 develop
...............
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
develop(f [,n]); f poly, n int

Assume:
f is a bivariate polynomial (in the first 2 ring variables) and
irreducible as power series (for reducible f use hnexpansion).

Return:
list L with:

L[1]; matrix:
         Each row contains the coefficients of the corresponding line of the
         Hamburger-Noether expansion (HNE). The end of the line is marked in
         the matrix by the first ring variable (usually x).
L[2]; intvec:
         indicating the length of lines of the HNE
L[3]; int:
         0  if the 1st ring variable was transversal (with respect to f), 

         1  if the variables were changed at the beginning of the
            computation, 

        -1  if an error has occurred.
L[4]; poly:
         the transformed polynomial of f to make it possible to extend the
         Hamburger-Noether development a posteriori without having to do
         all the previous calculation once again (0 if not needed)
L[5]; int:
         1  if the curve has exactly one branch (i.e., is irreducible), 

         0  else (i.e., the curve has more than one HNE, or f is not valid).

Display:
The (non zero) elements of the HNE (if not called by another proc).

Note:
The optional parameter n affects only the computation of
the LAST line of the HNE. If it is given, the HN-matrix L[1]
will have at least n columns. 

Otherwise, the number of columns will be chosen minimal such that the
matrix contains all necessary information (i.e., all lines of the HNE
but the last (which is in general infinite) have place). 

If n is negative, the algorithm is stopped as soon as the
computed information is sufficient for invariants(L), but the
HN-matrix L[1] may still contain undetermined elements, which
are marked with the 2nd variable (of the basering). 

For time critical computations it is recommended to use
ring ...,(x,y),ls as basering - it increases the algorithm's
speed. 

If printlevel>=0 comments are displayed (default is
printlevel=0).

Example:
LIB "hnoether.lib";
ring exring = 7,(x,y),ds;
list hne=develop(4x98+2x49y7+x11y14+2y14);
print(hne[1]);
==> 0,0, 0,0,0,0,3,x,
==> 0,x, 0,0,0,0,0,0,
==> 0,0, 0,x,0,0,0,0,
==> 0,x, 0,0,0,0,0,0,
==> 0,-1,0,0,0,0,0,0 
// therefore the HNE is:
// z(-1)= 3*z(0)^7 + z(0)^7*z(1),
// z(0) = z(1)*z(2),       (there is 1 zero in the 2nd row before x)
// z(1) = z(2)^3*z(3),     (there are 3 zeroes in the 3rd row)
// z(2) = z(3)*z(4),
// z(3) = -z(4)^2 + 0*z(4)^3 +...+ 0*z(4)^8 + ?*z(4)^9 + ...
// (the missing x in the last line indicates that it is not complete.)
hne[2];
==> 7,1,3,1,-1
parametrisation(hne);
==> [1]:
==>    _[1]=-x14
==>    _[2]=-3x98-x109
// parametrization:   x(t)= -t^14+O(t^21),  y(t)= -3t^98+O(t^105)
// (the term -t^109 in y may have a wrong coefficient)
displayHNE(hne);
==> HNE[1]=-y+3*z(0)^7+z(0)^7*z(1)
==> HNE[2]=-x+z(1)*z(2)
==> HNE[3]=z(2)^3*z(3)
==> HNE[4]=z(3)*z(4)
==> HNE[5]=-z(4)^2


D.5.5.4 extdevelop
..................
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
extdevelop(L,N); list L, int N

Assume:
L is the output of develop(f), or of extdevelop(l,n),
or one entry in the list hne in the ring created by
hnexpansion(f[,"ess"]).

Return:
an extension of the Hamburger-Noether development of f as a list
in the same format as L has (up to the last entry in the output
of develop(f)).

Type help develop;, resp. help hnexpansion; for more
details.

Note:
The new HN-matrix will have at least N columns (if the HNE is not
finite). In particular, if f is irreducible then (in most cases)
extdevelop(develop(f),N) will produce the same result as
develop(f,N).

If the matrix M of L has n columns then, compared with
parametrisation(L), paramametrize(extdevelop(L,N)) will increase the
exactness by at least (N-n) more significant monomials.

Example:
LIB "hnoether.lib";
if (defined(HNEring))
{
def save_r_i_n_g=HNEring;
kill HNEring;
}
// ------ the example starts here -------
ring exring=0,(x,y),dp;
list hn=hnexpansion(x14-3y2x11-y3x10-y2x9+3y4x8+y5x7+3y4x6+x5*(-y6+y5)
-3y6x3-y7x2+y8);
def HNEring=hn[1];
setring HNEring;  
export(HNEring);  
==> // ** `HNEring` is already global
print(hne[1][1]);    // HNE of 1st branch is finite
==> 0,x,0,
==> 0,1,x 
print(extdevelop(hne[1],5)[1]);
==>  No extension is possible
==> 0,x,0,
==> 0,1,x 
print(hne[2][1]);    // HNE of 2nd branch can be extended
==> 0,x,0,
==> 0,1,x,
==> 0,1,-1
list ehne=extdevelop(hne[2],5);
print(ehne[1]);      // new HN-matrix has 5 columns
==> 0,x,0, 0,0,
==> 0,1,x, 0,0,
==> 0,1,-1,1,-1
parametrisation(hne[2]);
==> [1]:
==>    _[1]=x4-x5-x6+x7
==>    _[2]=x6-2x7+2x9-x10
parametrisation(ehne);
==> [1]:
==>    _[1]=x4-x5+x6-x7-x8+x9-x10+x11
==>    _[2]=x6-2x7+3x8-4x9+2x10-2x12+4x13-3x14+2x15-x16
if (defined(save_r_i_n_g))
{
kill HNEring;
def HNEring=save_r_i_n_g;
}


D.5.5.5 parametrisation
.......................
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
parametrisation(INPUT [,x]); INPUT list or poly, x int (optional)

Assume:
INPUT is either a bivariate polynomial f defining a plane curve
singularity, or it is the output of hnexpansion(f[,"ess"]),
or of develop(f), or of extdevelop(develop(f),n),
or the list @{hne} in the ring created by hnexpansion(f)
respectively one entry thereof.

Return:
a list L containing a parametrization L[i] for each branch f[i] of f
in the following format: 

- if only the list INPUT is given, L[i] is an ideal of two polynomials
p[1],p[2]: if the HNE of was finite then f[i](p[1],p[2])=0; if not,
the "real" parametrization will be two power series and p[1],p[2] are
truncations of these series.

- if the optional parameter x is given, L[i] is itself a list:
L[i][1] is the parametrization ideal as above and L[i][2] is an intvec
with two entries indicating the highest degree up to which the
coefficients of the monomials in L[i][1] are exact (entry -1 means that
the corresponding parametrization is exact).

Note:
If the basering has only 2 variables, the first variable is chosen
as indefinite. Otherwise, the 3rd variable is chosen. 

In case the Hamburger-Noether expansion of the curve f is needed
for other purposes as well it is better to calculate this first
with the aid of hnexpansion and use it as input instead of
the polynomial itself.

Example:
LIB "hnoether.lib";
ring exring=0,(x,y,t),ds;
// 1st Example: input is a polynomial
poly g=(x2-y3)*(x3-y5);
parametrisation(g);
==> [1]:
==>    _[1]=t3
==>    _[2]=t2
==> [2]:
==>    _[1]=t5
==>    _[2]=t3
// 2nd Example: input is the ring of a Hamburger-Noether expansion
poly h=x2-y2-y3;
list hn=hnexpansion(h);
parametrisation(h,1);
==> [1]:
==>    [1]:
==>       _[1]=t
==>       _[2]=t-1/2t2
==>    [2]:
==>       -1,2
==> [2]:
==>    [1]:
==>       _[1]=t
==>       _[2]=-t-1/2t2
==>    [2]:
==>       -1,2
// 3rd Example: input is a Hamburger-Noether expansion
poly f=x3+2xy2+y2;
list hne=develop(f);
list hne_extended=extdevelop(hne,10);
//   compare the matrices ...
print(hne[1]);
==> 0,x,
==> 0,-1
print(hne_extended[1]);
==> 0,x, 0,0,0,0, 0,0,0,0, 
==> 0,-1,0,2,0,-4,0,8,0,-16
// ... and the resulting parametrizations:
parametrisation(hne);
==> [1]:
==>    _[1]=-t2
==>    _[2]=-t3
parametrisation(hne_extended);
==> [1]:
==>    _[1]=-t2+2t4-4t6+8t8-16t10
==>    _[2]=-t3+2t5-4t7+8t9-16t11
parametrisation(hne_extended,0);
==> [1]:
==>    [1]:
==>       _[1]=-t2+2t4-4t6+8t8-16t10
==>       _[2]=-t3+2t5-4t7+8t9-16t11
==>    [2]:
==>       10,11


D.5.5.6 displayHNE
..................
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
displayHNE(L[,n]); L list, n int

Assume:
L is the output of develop(f), or of exdevelop(f,n),
or of hnexpansion(f[,"ess"]), or (one entry in) the list
hne in the ring created by hnexpansion(f[,"ess"]).

Return:
- if only one argument is given, no return value, but
display an ideal HNE of the following form:
     HNE[1]=-y+[]*z(0)^1+[]*z(0)^2+...+z(0)^<>*z(1)
     HNE[2]=-x+          []*z(1)^2+...+z(1)^<>*z(2)
     HNE[3]=             []*z(2)^2+...+z(2)^<>*z(3)
     .......             ..........................
     HNE[r+1]=           []*z(r)^2+[]*z(r)^3+......
where x,y are the first 2 variables of the basering.
The values of [] are the coefficients of the Hamburger-Noether
matrix, the values of <> are represented by x in the
HN-matrix.

- if a second argument is given, create and export a new ring with
name displayring containing an ideal HNE as described
above.

- if L corresponds to the output of hnexpansion(f[,"ess"])
or to the list hne in the ring created by hnexpansion(f[,"ess"]),
displayHNE(L[,n]) shows the HNE's of all branches of f in the form
described above. The optional parameter is then ignored.

Note:
The 1st line of the above ideal (i.e., HNE[1]) means that
y=[]*z(0)^1+..., the 2nd line (HNE[2]) means that
x=[]*z(1)^2+..., so you can see which indeterminate
corresponds to which line (it's also possible that x corresponds
to the 1st line and y to the 2nd).

Example:
LIB "hnoether.lib";
ring r=0,(x,y),dp;
poly f=x3+2xy2+y2;
list hn=develop(f);
displayHNE(hn);
==> HNE[1]=-y+z(0)*z(1)
==> HNE[2]=-x-z(1)^2


D.5.5.7 invariants
..................
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
invariants(INPUT); INPUT list or poly

Assume:
INPUT is the output of develop(f), or of
extdevelop(develop(f),n), or one entry in the list hne
of the HNEring created by hnexpansion.

Return:
list, if INPUT contains a valid HNE:
    invariants(INPUT)[1]:  intvec    (characteristic exponents)
    invariants(INPUT)[2]:  intvec    (generators of the semigroup)
    invariants(INPUT)[3]:  intvec    (Puiseux pairs, 1st components)
    invariants(INPUT)[4]:  intvec    (Puiseux pairs, 2nd components)
    invariants(INPUT)[5]:  int       (degree of the conductor)
    invariants(INPUT)[6]:  intvec    (sequence of multiplicities)
an empty list, if INPUT contains no valid HNE.

Assume:
INPUT is bivariate polynomial f or the output of hnexpansion(f[,"ess"]),
or the list hne in the HNEring created by hnexpansion.

Return:
list INV, such that INV[i] is the output of invariants(develop(f[i]))
as above, where f[i] is the ith branch of the curve f, and the last
entry contains further invariants of f in the format:
    INV[i][1]    : intvec    (characteristic exponents)
    INV[i][2]    : intvec    (generators of the semigroup)
    INV[i][3]    : intvec    (Puiseux pairs, 1st components)
    INV[i][4]    : intvec    (Puiseux pairs, 2nd components)
    INV[i][5]    : int       (degree of the conductor)
    INV[i][6]    : intvec    (sequence of multiplicities)
    INV[last][1] : intmat    (contact matrix of the branches)
    INV[last][2] : intmat    (intersection multiplicities of the branches)
    INV[last][3] : int       (delta invariant of f)

Note:
In case the Hamburger-Noether expansion of the curve f is needed
for other purposes as well it is better to calculate this first
with the aid of hnexpansion and use it as input instead of
the polynomial itself.

Example:
LIB "hnoether.lib";
ring exring=0,(x,y),dp;
list hne=develop(y4+2x3y2+x6+x5y);
list INV=invariants(hne);
INV[1];                   // the characteristic exponents
==> 4,6,7
INV[2];                   // the generators of the semigroup of values
==> 4,6,13
INV[3],INV[4];            // the Puiseux pairs in packed form
==> 3,7 2,2
INV[5] / 2;               // the delta-invariant
==> 8
INV[6];                   // the sequence of multiplicities
==> 4,2,2,1,1
// To display the invariants more 'nicely':
displayInvariants(hne);
==>  characteristic exponents  : 4,6,7
==>  generators of semigroup   : 4,6,13
==>  Puiseux pairs             : (3,2)(7,2)
==>  degree of the conductor   : 16
==>  delta invariant           : 8
==>  sequence of multiplicities: 4,2,2,1,1
/////////////////////////////
INV=invariants((x2-y3)*(x3-y5));
INV[1][1];                // the characteristic exponents of the first branch
==> 2,3
INV[2][6];                // the sequence of multiplicities of the second branch
==> 3,2,1,1
print(INV[size(INV)][1]);         // the contact matrix of the branches
==>      0     3
==>      3     0
print(INV[size(INV)][2]);         // the intersection numbers of the branches
==>      0     9
==>      9     0
INV[size(INV)][3];                // the delta invariant of the curve
==> 14


D.5.5.8 displayInvariants
.........................
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
displayInvariants(INPUT); INPUT list or poly

Assume:
INPUT is a bivariate polynomial, or the output of develop(f), or of
extdevelop(develop(f),n), or (one entry of) the list hne
in the ring created by hnexpansion(f[,"ess"]).

Return:
none

Display:
invariants of the corresponding branch, resp. of all branches,
in a better readable form.

Note:
In case the Hamburger-Noether expansion of the curve f is needed
for other purposes as well it is better to calculate this first
with the aid of hnexpansion and use it as input instead of
the polynomial itself.

Example:
LIB "hnoether.lib";
ring exring=0,(x,y),dp;
list hne=develop(y4+2x3y2+x6+x5y);
displayInvariants(hne);
==>  characteristic exponents  : 4,6,7
==>  generators of semigroup   : 4,6,13
==>  Puiseux pairs             : (3,2)(7,2)
==>  degree of the conductor   : 16
==>  delta invariant           : 8
==>  sequence of multiplicities: 4,2,2,1,1


D.5.5.9 multsequence
....................
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
multsequence(INPUT); INPUT list or poly

Assume:
INPUT is the output of develop(f), or of extdevelop(develop(f),n),
or one entry in the list hne of the ring created by hnexpansion(f).

Return:
intvec corresponding to the multiplicity sequence of (a branch)
of the curve (the same as invariants(INPUT)[6]).

Assume:
INPUT is a bivariate polynomial, or the output of hnexpansion(f),
or the list hne in the ring created by hnexpansion(f).

Return:
list of two integer matrices:

multsequence(INPUT)[1][i,*]
   contains the multiplicities of the branches at their infinitely near point
   of 0 in its (i-1) order neighbourhood (i.e., i=1: multiplicity of the
   branches themselves, i=2: multiplicity of their 1st quadratic transformed,
   etc., 

   Hence, multsequence(INPUT)[1][*,j] is the multiplicity sequence
   of branch j.
multsequence(INPUT)[2][i,*]:
   contains the information which of these infinitely near points coincide.

Note:
The order of elements of the list hne obtained from hnexpansion(f[,"ess")
must not be changed (because then the coincident infinitely near points
couldn't be grouped together, cf. meaning of 2nd intmat in example).
Hence, it is not wise to compute the HNE of several polynomials
separately, put them into a list INPUT and call multsequence(INPUT). 

Use displayMultsequence to produce a better readable output for
reducible curves on the screen. 

In case the Hamburger-Noether expansion of the curve f is needed
for other purposes as well it is better to calculate this first
with the aid of hnexpansion and use it as input instead of
the polynomial itself.

Example:
LIB "hnoether.lib";
// -------- prepare for example ---------
if (nameof(basering)=="HNEring") {
def rettering=HNEring;
kill HNEring;
}
// ------ the example starts here -------
ring r=0,(x,y),dp;
list hn=hnexpansion((x6-y10)*(x+y2-y3)*(x+y2+y3));   // 4 branches
def HNEring=hn[1];
setring HNEring;
multsequence(hne[1]),"  |  ",multsequence(hne[2]),"  |  ",
multsequence(hne[3]),"  |  ",multsequence(hne[4]);
==> 3,2,1,1   |   3,2,1,1   |   1   |   1
multsequence(hne);
==> [1]:
==>    3,3,1,1,
==>    2,2,1,1,
==>    1,1,1,1,
==>    1,1,1,1,
==>    1,1,1,1 
==> [2]:
==>    4,0,0,0,
==>    4,0,0,0,
==>    2,2,0,0,
==>    2,1,1,0,
==>    1,1,1,1 
// The meaning of the entries of the 2nd matrix is as follows:
displayMultsequence(hne);
==> [(3,3,1,1)],
==> [(2,2,1,1)],
==> [(1,1),(1,1)],
==> [(1,1),(1),(1)],
==> [(1),(1),(1),(1)]
// --- restore HNEring if previously defined ---
kill HNEring,r;
if (defined(rettering)) {
setring rettering;
def HNEring=rettering;
export HNEring;
}


D.5.5.10 displayMultsequence
............................
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
displayMultsequence(INPUT); INPUT list or poly

Assume:
INPUT is a bivariate polynomial, or the output of develop(f),
or of extdevelop(develop(f),n), or of of hnexpansion(f[,"ess"]),
or (one entry in) the list hne of the ring created by hnexpansion(f[,"ess "]).

Return:
nothing

Display:
the sequence of multiplicities:
 - if INPUT=develop(f) or INPUT=extdevelop(develop(f),n) or INPUT=hne[i]:
                      a , b , c , ....... , 1
 - if INPUT=f or INPUT=hnexpansion(f[,"ess"]) or INPUT=hne:
                      [(a_1, .... , b_1 , .... , c_1)],
                      [(a_2, ... ), ... , (... , c_2)],
                       ........................................ ,
                      [(a_n),(b_n), ....., (c_n)]
     with:
       a_1 , ... , a_n the sequence of multiplicities of the 1st branch,
       [...] the multiplicities of the j-th transformed of all branches,
       (...) indicating branches meeting in an infinitely near point.

Note:
The same restrictions for INPUT as in multsequence apply.

In case the Hamburger-Noether expansion of the curve f is needed
for other purposes as well it is better to calculate this first
with the aid of hnexpansion and use it as input instead of
the polynomial itself.

Example:
LIB "hnoether.lib";
// ------ the example starts here -------
ring r=0,(x,y),dp;
//// Example 1: Input = output of develop
displayMultsequence(develop(x3-y5));
==> The sequence of multiplicities is   3,2,1,1
//// Example 2: Input = bivariate polynomial
displayMultsequence((x6-y10)*(x+y2-y3)*(x+y2+y3));
==> [(3,3,1,1)],
==> [(2,2,1,1)],
==> [(1,1),(1,1)],
==> [(1,1),(1),(1)],
==> [(1),(1),(1),(1)]


D.5.5.11 intersection
.....................
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
intersection(hne1,hne2); hne1, hne2 lists

Assume:
hne1, hne2 represent a HNE (i.e., are the output of
develop(f), or of extdevelop(develop(f),n), or
one entry of the list hne in the ring created by
hnexpansion(f[,"ess"])).

Return:
int, the intersection multiplicity of the branches corresponding to
hne1 and hne2.

Example:
LIB "hnoether.lib";
// ------ the example starts here -------
ring r=0,(x,y),dp;
list hn=hnexpansion((x2-y3)*(x2+y3));
def HNEring=hn[1];
setring HNEring;
intersection(hne[1],hne[2]);
==> 6


D.5.5.12 stripHNE
.................
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
stripHNE(L); L list

Assume:
L is the output of develop(f), or of
extdevelop(develop(f),n), or (one entry of) the list
hne in the ring created by hnexpansion(f[,"ess"]).

Return:
list in the same format as L, but all polynomials L[4], resp.
L[i][4], are set to zero.

Note:
The purpose of this procedure is to remove huge amounts of data
no longer needed. It is useful, if one or more of the polynomials
in L consume much memory. It is still possible to compute invariants,
parametrizations etc. with the stripped HNE(s), but it is not possible
to use extdevelop with them.

Example:
LIB "hnoether.lib";
ring r=0,(x,y),dp;
list hne=develop(x2+y3+y4);
hne;
==> [1]:
==>    _[1,1]=0
==>    _[1,2]=x
==>    _[2,1]=0
==>    _[2,2]=-1
==> [2]:
==>    1,-1
==> [3]:
==>    1
==> [4]:
==>    x4-2x2y+y2+y
==> [5]:
==>    1
stripHNE(hne);
==> [1]:
==>    _[1,1]=0
==>    _[1,2]=x
==>    _[2,1]=0
==>    _[2,2]=-1
==> [2]:
==>    1,-1
==> [3]:
==>    1
==> [4]:
==>    0
==> [5]:
==>    1


D.5.5.13 is_irred
.................
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
is_irred(f); f poly

Assume:
f is a squarefree bivariate polynomial (in the first 2 ring
variables).

Return:
int (0 or 1): 

- is_irred(f)=1 if f is irreducible as a formal power
series over the algebraic closure of its coefficient field (f
defines an analytically irreducible curve at zero), 

- is_irred(f)=0 otherwise.

Note:
0 and units in the ring of formal power series are considered to be
not irreducible.

Example:
LIB "hnoether.lib";
ring exring=0,(x,y),ls;
is_irred(x2+y3);
==> 1
is_irred(x2+y2);
==> 0
is_irred(x2+y3+1);
==> 0

D.5.5.14 delta
..............
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
delta(INPUT); INPUT a polynomial defining an isolated plane curve
singularity at 0, or the Hamburger-Noether expansion thereof, i.e.
the output of develop(f), or the output of hnexpansion(f[,"ess"]),
or (one of the entries of) the list hne in the ring created
by hnexpansion(f[,"ess"]).

Return:
the delta invariant of the singularity at 0, the vector space
dimension of R~/R, where R~ is the normalization of the
singularity R=basering/f

Note:
In case the Hamburger-Noether expansion of the curve f is needed
for other purposes as well it is better to calculate this first
with the aid of hnexpansion and use it as input instead of
the polynomial itself.

Example:
LIB "hnoether.lib";
ring r = 32003,(x,y),ds;
poly f = x25+x24-4x23-1x22y+4x22+8x21y-2x21-12x20y-4x19y2+4x20+10x19y
+12x18y2-24x18y-20x17y2-4x16y3+x18+60x16y2+20x15y3-9x16y
-80x14y3-10x13y4+36x14y2+60x12y4+2x11y5-84x12y3-24x10y5
+126x10y4+4x8y6-126x8y5+84x6y6-36x4y7+9x2y8-1y9;
delta(f);
==> 96


D.5.5.15 newtonpoly
...................
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
newtonpoly(f); f poly

Assume:
basering has exactly two variables; 

f is convenient, that is, f(x,0) != 0 != f(0,y).

Return:
list of intvecs (= coordinates x,y of the Newton polygon of f).

Note:
Procedure uses execute; this can be avoided by calling
newtonpoly(f,1) if the ordering of the basering is ls.

Example:
LIB "hnoether.lib";
ring r=0,(x,y),ls;
poly f=x5+2x3y-x2y2+3xy5+y6-y7;
newtonpoly(f);
==> [1]:
==>    0,6
==> [2]:
==>    2,2
==> [3]:
==>    3,1
==> [4]:
==>    5,0

D.5.5.16 is_NND
...............
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
is_NND(f[,mu,NP]); f poly, mu int, NP list of intvecs

Assume:
f is convenient, that is, f(x,0) != 0 != f(0,y);

mu (optional) is Milnor number of f.

NP (optional) is output of newtonpoly(f).

Return:
int: 1 if f in Newton non-degenerate, 0 otherwise.

Example:
LIB "hnoether.lib";
ring r=0,(x,y),ls;
poly f=x5+y3;
is_NND(f);
==> 1
poly g=(x-y)^5+3xy5+y6-y7;
is_NND(g);
==> 0
// if already computed, one should give the Minor number and Newton polygon
// as second and third input: 
int mu=milnor(g);
list NP=newtonpoly(g);
is_NND(g,mu,NP);
==> 0


D.5.5.17 puiseux2generators
...........................
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
puiseux2generators(m,n); m,n intvec

Assume:
m, resp. n, represent the 1st, resp. 2nd, components of Puiseux pairs
(e.g., m=invariants(L)[3], n=invariants(L)[4]).

Return:
intvec of the generators of the semigroup of values.

Example:
LIB "hnoether.lib";
// take (3,2),(7,2),(15,2),(31,2),(63,2),(127,2) as Puiseux pairs:
puiseux2generators(intvec(3,7,15,31,63,127),intvec(2,2,2,2,2,2));
==> 64,96,208,424,852,1706,3413


D.5.5.18 separateHNE
....................
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
separateHNE(hne1,hne2); hne1, hne2 lists

Assume:
hne1, hne2 are HNEs (=output of
develop(f), extdevelop(develop(f),n), or
one entry in the list hne in the ring created by
hnexpansion(f[,"ess"]).

Return:
number of quadratic transformations needed to separate both curves
(branches).

Example:
LIB "hnoether.lib";
int p=printlevel; printlevel=-1;
ring r=0,(x,y),dp;
list hne1=develop(x);
list hne2=develop(x+y);
list hne3=develop(x+y2);
separateHNE(hne1,hne2);  // two transversal lines
==> 1
separateHNE(hne1,hne3);  // one quadratic transform. gives 1st example
==> 2
printlevel=p;


D.5.5.19 squarefree
...................
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
squarefree(f); f poly

Assume:
f is a bivariate polynomial (in the first 2 ring variables).

Return:
poly, a squarefree divisor of f.

Note:
Usually, the return value is the greatest squarefree divisor, but
there is one exception: factors with a p-th root, p the
characteristic of the basering, are lost.

Example:
LIB "hnoether.lib";
ring exring=3,(x,y),dp;
squarefree((x3+y)^2);
==> x3+y
squarefree((x+y)^3*(x-y)^2); // Warning: (x+y)^3 is lost
==> x-y
squarefree((x+y)^4*(x-y)^2); // result is (x+y)*(x-y)
==> x2-y2


D.5.5.20 allsquarefree
......................
Procedure from library hnoether.lib (see hnoether_lib).

Usage :
allsquarefree(f,g); f,g poly

Assume:
g is the output of squarefree(f).

Return:
the greatest squarefree divisor of f.

Note  :
This proc uses factorize to get the missing factors of f not in g and,
therefore, may be slow.

Example:
LIB "hnoether.lib";
ring exring=7,(x,y),dp;
poly f=(x+y)^7*(x-y)^8;
poly g=squarefree(f);
g;                      // factor x+y lost, since characteristic=7
==> x-y
allsquarefree(f,g);     // all factors (x+y)*(x-y) found
==> x2-y2


D.5.5.21 further_hn_proc
........................
Procedure from library hnoether.lib (see hnoether_lib).

Usage:
further_hn_proc();

Note:
The library hnoether.lib contains some more procedures which
are not shown when typing help hnoether.lib;. They may be useful
for interactive use (e.g. if you want to do the calculation of an HN
development "by hand" to see the intermediate results), and they
can be enumerated by calling further_hn_proc(). 

Use help <procedure>; for detailed information about each of
them.

Example:
LIB "hnoether.lib";
further_hn_proc();
==> 
==>  The following procedures are also part of `hnoether.lib':
==> 
==>  getnm(f);           intersection pts. of Newton polygon with axes
==>  T_Transform(f,Q,N); returns f(y,xy^Q)/y^NQ (f: poly, Q,N: int)
==>  T1_Transform(f,d,M); returns f(x,y+d*x^M)  (f: poly,d:number,M:int)
==>  T2_Transform(f,d,M,N,ref);   a composition of T1 & T
==>  koeff(f,I,J);       gets coefficient of indicated monomial of poly f
==>  redleit(f,S,E);     restriction of monomials of f to line (S-E)
==>  leit(f,n,m);        special case of redleit (for irred. polynomials)
==>  testreducible(f,n,m); tests whether f is reducible
==>  charPoly(f,M,N);    characteristic polynomial of f
==>  find_in_list(L,p);  find int p in list L
==>  get_last_divisor(M,N); last divisor in Euclid's algorithm
==>  factorfirst(f,M,N); try to factor f without `factorize'
==>  factorlist(L);      factorize a list L of polynomials
==>  referencepoly(D);   a polynomial f s.t. D is the Newton diagram of f
D.5.6 mondromy_lib
------------------
Library:
mondromy.lib
Purpose:
  Monodromy of an Isolated Hypersurface Singularity
Author:
Mathias Schulze, email: mschulze@mathematik.uni-kl.de

Overview:
A library to compute the monodromy of an isolated hypersurface singularity.
It uses an algorithm by Brieskorn (manuscripta math. 2 (1970), 103-161) to
compute a connection matrix of the meromorphic Gauss-Manin connection up to
arbitrarily high order, and an algorithm of Gerard and Levelt (Ann. Inst.
Fourier, Grenoble 23,1 (1973), pp. 157-195) to transform it to a simple pole.


Procedures:
* detadj:: determinant and adjoint matrix of square matrix U
* invunit:: series inverse of polynomial u up to order n
* jacoblift:: lifts f^kappa in jacob(f) with minimal kappa
* monodromyB:: monodromy of isolated hypersurface singularity f
* H2basis:: basis of Brieskorn lattice H"


D.5.6.1 detadj
..............
Procedure from library mondromy.lib (see mondromy_lib).

Usage:
detadj(U); U matrix

Assume:
U is a square matrix with non zero determinant.

Return:
The procedure returns a list with at most 2 entries.

If U is not a square matrix, the list is empty.

If U is a square matrix, then the first entry is the determinant of U.
If U is a square matrix and the determinant of U not zero,
then the second entry is the adjoint matrix of U.

Display:
The procedure displays comments if printlevel>=1.

Example:
LIB "mondromy.lib";
ring R=0,x,dp;
matrix U[2][2]=1,1+x,1+x2,1+x3;
list daU=detadj(U);
daU[1];
==> -x2-x
print(daU[2]);
==> x3+1, -x-1,
==> -x2-1,1    

D.5.6.2 invunit
...............
Procedure from library mondromy.lib (see mondromy_lib).

Usage:
invunit(u,n); u poly, n int

Assume:
The polynomial u is a series unit.

Return:
The procedure returns the series inverse of u up to order n
or a zero polynomial if u is no series unit.

Display:
The procedure displays comments if printlevel>=1.

Example:
LIB "mondromy.lib";
ring R=0,(x,y),dp;
invunit(2+x3+xy4,10);
==> 1/8x2y8-1/16x9+1/4x4y4+1/8x6-1/4xy4-1/4x3+1/2

D.5.6.3 jacoblift
.................
Procedure from library mondromy.lib (see mondromy_lib).

Usage:
jacoblift(f); f poly

Assume:
The polynomial f in a series ring (local ordering) defines
an isolated hypersurface singularity.

Return:
The procedure returns a list with entries kappa, xi, u of type
int, vector, poly such that kappa is minimal with f^kappa in jacob(f),
u is a unit, and u*f^kappa=(matrix(jacob(f))*xi)[1,1].

Display:
The procedure displays comments if printlevel>=1.

Example:
LIB "mondromy.lib";
ring R=0,(x,y),ds;
poly f=x2y2+x6+y6;
jacoblift(f);
==> [1]:
==>    2
==> [2]:
==>    1/2x2y3*gen(2)+1/6x7*gen(1)+5/6x6y*gen(2)-2/3xy6*gen(1)+1/6y7*gen(2)-4\
   x4y5*gen(2)-3/2x9y2*gen(1)-15/2x8y3*gen(2)+9/2x3y8*gen(1)-3/2x2y9*gen(2)
==> [3]:
==>    1-9x2y2

D.5.6.4 monodromyB
..................
Procedure from library mondromy.lib (see mondromy_lib).

Usage:
monodromyB(f[,opt]); f poly, opt int

Assume:
The polynomial f in a series ring (local ordering) defines
an isolated hypersurface singularity.

Return:
The procedure returns a residue matrix M of the meromorphic
Gauss-Manin connection of the singularity defined by f
or an empty matrix if the assumptions are not fulfilled.
If opt=0 (default), exp(-2*pi*i*M) is a monodromy matrix of f,
else, only the characteristic polynomial of exp(-2*pi*i*M) coincides
with the characteristic polynomial of the monodromy of f.

Display:
The procedure displays more comments for higher printlevel.

Example:
LIB "mondromy.lib";
ring R=0,(x,y),ds;
poly f=x2y2+x6+y6;
matrix M=monodromyB(f);
print(M);
==> 7/6,0,  0,0,  0,  0,0,   0,-1/2,0,  0,  0,    0,       
==> 0,  7/6,0,0,  0,  0,-1/2,0,0,   0,  0,  0,    0,       
==> 0,  0,  1,0,  0,  0,0,   0,0,   0,  0,  0,    0,       
==> 0,  0,  0,4/3,0,  0,0,   0,0,   0,  0,  0,    0,       
==> 0,  0,  0,0,  4/3,0,0,   0,0,   0,  0,  0,    0,       
==> 0,  0,  0,0,  0,  1,0,   0,0,   0,  0,  0,    0,       
==> 0,  0,  0,0,  0,  0,5/6, 0,0,   0,  0,  0,    0,       
==> 0,  0,  0,0,  0,  0,0,   1,0,   0,  0,  0,    0,       
==> 0,  0,  0,0,  0,  0,0,   0,5/6, 0,  0,  0,    0,       
==> 0,  0,  0,0,  0,  0,0,   0,0,   2/3,0,  0,    0,       
==> 0,  0,  0,0,  0,  0,0,   0,0,   0,  2/3,0,    0,       
==> 0,  0,  0,0,  0,  0,0,   0,0,   0,  0,  47/44,-625/396,
==> 0,  0,  0,0,  0,  0,0,   0,0,   0,  0,  9/44, -3/44    

D.5.6.5 H2basis
...............
Procedure from library mondromy.lib (see mondromy_lib).

Usage:
H2basis(f); f poly

Assume:
The polynomial f in a series ring (local ordering) defines
an isolated hypersurface singularity.

Return:
The procedure returns a list of representatives of a C{f}-basis of the
Brieskorn lattice H"=Omega^(n+1)/df^dOmega^(n-1).

Theory:
H" is a free C{f}-module of rank milnor(f).

Display:
The procedure displays more comments for higher printlevel.

Example:
LIB "mondromy.lib";
ring R=0,(x,y),ds;
poly f=x2y2+x6+y6;
H2basis(f);
==> [1]:
==>    x4
==> [2]:
==>    x2y2
==> [3]:
==>    y4
==> [4]:
==>    x3
==> [5]:
==>    x2y
==> [6]:
==>    xy2
==> [7]:
==>    y3
==> [8]:
==>    x2
==> [9]:
==>    xy
==> [10]:
==>    y2
==> [11]:
==>    x
==> [12]:
==>    y
==> [13]:
==>    1
D.5.7 qhmoduli_lib
------------------
Library:
qhmoduli.lib
Purpose:
    Moduli Spaces of Semi-Quasihomogeneous Singularities
Author:
Thomas Bayer, email: bayert@in.tum.de


Procedures:
* ArnoldAction:: Induced action of G_f on T_.
* ModEqn:: Equations of the moduli space for principal part f
* QuotientEquations:: Equations of Variety(I)/G w.r.t. action 'A'
* StabEqn:: Equations of the stabilizer of f.
* StabEqnId:: Equations of the stabilizer of the qhom. ideal I.
* StabOrder:: Order of the stabilizer of f.
* UpperMonomials:: Upper basis of the Milnor algebra of f.
* Max:: maximal integer contained in 'data'
* Min:: minimal integer contained in 'data'
* Table:: list, i-th entry is cmd(i), lb <= i <= ub

D.5.7.1 ArnoldAction
....................
Procedure from library qhmoduli.lib (see qhmoduli_lib).

Usage:
ArnoldAction(f, [Gf, B]); poly f; list Gf, B;

'Gf' is a list of two rings (coming from 'StabEqn')

Purpose:
compute the induced action of the stabilizer G of f on T_, where
T_ is given by the upper monomials B of the Milnor algebra of f.

Assume:
f is quasihomogeneous

Return:
polynomial ring over the same ground field, containing the ideals
'actionid' and 'stabid'.

- 'actionid' is the ideal defining the induced action of Gf on T_ 

- 'stabid' is the ideal of the stabilizer Gf in the new ring

Example:
LIB "qhmoduli.lib";
ring B   = 0,(x,y,z), ls;
poly f = -z5+y5+x2z+x2y;
def R = ArnoldAction(f);
setring R;
actionid;
==> actionid[1]=-s(2)*t(1)+s(3)*t(1)
==> actionid[2]=-s(2)^2*t(2)+2*s(2)^2*t(3)^2+s(3)^2*t(2)
==> actionid[3]=s(2)*t(3)+s(3)*t(3)
stabid;
==> stabid[1]=s(2)*s(3)
==> stabid[2]=s(1)^2*s(2)+s(1)^2*s(3)-1
==> stabid[3]=s(1)^2*s(3)^2-s(3)
==> stabid[4]=s(1)^2+s(2)^4-s(3)^4
==> stabid[5]=s(1)^4+s(2)^3-s(3)^3
==> stabid[6]=-s(1)^2*s(3)+s(3)^5

D.5.7.2 ModEqn
..............
Procedure from library qhmoduli.lib (see qhmoduli_lib).

Usage:
ModEqn(f [, opt]); poly f; int opt;

Purpose:
compute equations of the moduli space of semiquasihomogeneous hypersurface singularity with principal part f w.r.t. right equivalence

Assume:
f quasihomogeneous polynomial with an isolated singularity at 0

Return:
polynomial ring, possibly a simple extension of the ground field of
the basering, containing the ideal 'modid'

- 'modid' is the ideal of the moduli space if opt is even (> 0).
otherwise it contains generators of the coordinate ring R of the
moduli space (note : Spec(R) is the moduli space)

Options:
1 compute equations of the mod. space,

2 use a primary decomposition

4 compute E_f0, i.e., the image of G_f0

To combine options, add their value, default: opt =7

Example:
LIB "qhmoduli.lib";
ring B   = 0,(x,y), ls;
poly f = -x4 + xy5;
def R = ModEqn(f);
setring R;
modid;
==> modid[1]=Y(5)^2-Y(4)*Y(6)
==> modid[2]=Y(4)*Y(5)-Y(3)*Y(6)
==> modid[3]=Y(3)*Y(5)-Y(2)*Y(6)
==> modid[4]=Y(2)*Y(5)-Y(1)*Y(6)
==> modid[5]=Y(4)^2-Y(2)*Y(6)
==> modid[6]=Y(3)*Y(4)-Y(1)*Y(6)
==> modid[7]=Y(2)*Y(4)-Y(1)*Y(5)
==> modid[8]=Y(3)^2-Y(1)*Y(5)
==> modid[9]=Y(2)*Y(3)-Y(1)*Y(4)
==> modid[10]=Y(2)^2-Y(1)*Y(3)

D.5.7.3 QuotientEquations
.........................
Procedure from library qhmoduli.lib (see qhmoduli_lib).

Usage:
QuotientEquations(G,action,emb [, opt]); ideal G,action,emb;int opt

Purpose:
compute the quotient of the variety given by the parameterization
'emb' by the linear action 'action' of the algebraic group G.

Assume:
'action' is linear, G must be finite if the Reynolds operator is
needed (i.e., NullCone(G,action) returns some non-invariant polys)

Return:
polynomial ring over a simple extension of the ground field of the
basering, containing the ideals 'id' and 'embedid'.

- 'id' contains the equations of the quotient, if opt = 1;
if opt = 0, 2, 'id' contains generators of the coordinate ring R
of the quotient (Spec(R) is the quotient)

- 'embedid' = 0, if opt = 1;

if opt = 0, 2, it is the ideal defining the equivariant embedding

Options:
1 compute equations of the quotient,

2 use a primary decomposition when computing the Reynolds operator 

To combine options, add their value, default: opt =3.


D.5.7.4 StabEqn
...............
Procedure from library qhmoduli.lib (see qhmoduli_lib).

Usage:
StabEqn(f); f polynomial

Purpose:
compute the equations of the isometry group of f.

Assume:
f semiquasihomogeneous polynomial with an isolated singularity at 0

Return:
list of two ring 'S1', 'S2'

- 'S1' contains the equations of the stabilizer (ideal 'stabid') 

- 'S2' contains the action of the stabilizer (ideal 'actionid')

Global:
varSubsList, contains the index j s.t. x(i) -> x(i)t(j) ...

Example:
LIB "qhmoduli.lib";
ring B = 0,(x,y,z), ls;
poly f = -z5+y5+x2z+x2y;
list stab = StabEqn(f);
def S1 = stab[1]; setring S1;  stabid;
==> stabid[1]=s(2)*s(3)
==> stabid[2]=s(1)^2*s(2)+s(1)^2*s(3)-1
==> stabid[3]=s(1)^2*s(3)^2-s(3)
==> stabid[4]=s(2)^4-s(3)^4+s(1)^2
==> stabid[5]=s(1)^4+s(2)^3-s(3)^3
==> stabid[6]=s(3)^5-s(1)^2*s(3)
def S2 = stab[2]; setring S2;  actionid;
==> actionid[1]=s(1)*x
==> actionid[2]=s(3)*y+s(2)*z
==> actionid[3]=s(2)*y+s(3)*z

D.5.7.5 StabEqnId
.................
Procedure from library qhmoduli.lib (see qhmoduli_lib).

Usage:
StabEqn(I, w); I ideal, w intvec

Purpose:
compute the equations of the isometry group of the ideal I
each generator of I is fixed by the stabilizer.

Assume:
I semiquasihomogeneous ideal wrt 'w' with an isolated singularity at 0

Return:
list of two ring 'S1', 'S2'

- 'S1' contains the equations of the stabilizer (ideal 'stabid') 

- 'S2' contains the action of the stabilizer (ideal 'actionid')

Global:
varSubsList, contains the index j s.t. t(i) -> t(i)t(j) ...

Example:
LIB "qhmoduli.lib";
ring B   = 0,(x,y,z), ls;
ideal I = x2,y3,z6;
intvec w = 3,2,1;
list stab = StabEqnId(I, w);
==> // ** redefining d **
==> // ** redefining newcoMx **
==> // ** redefining coMx **
==> // ** redefining d **
==> // ** redefining newcoMx **
==> // ** redefining coMx **
def S1 = stab[1]; setring S1;  stabid;
==> stabid[1]=s(1)^2-1
==> stabid[2]=s(2)^3-1
==> stabid[3]=s(3)^6-1
def S2 = stab[2]; setring S2;  actionid;
==> actionid[1]=s(1)*x
==> actionid[2]=s(2)*y
==> actionid[3]=s(3)*z

D.5.7.6 StabOrder
.................
Procedure from library qhmoduli.lib (see qhmoduli_lib).

Usage:
StabOrder(f); poly f;

Purpose:
compute the order of the stabilizer group of f.

Assume:
f quasihomogeneous polynomial with an isolated singularity at 0

Return:
int

Global:
varSubsList


D.5.7.7 UpperMonomials
......................
Procedure from library qhmoduli.lib (see qhmoduli_lib).

Usage:
UpperMonomials(poly f, [intvec w])

Purpose:
compute the upper monomials of the milnor algebra of f.

Assume:
f is quasihomogeneous (w.r.t. w)

Return:
ideal

Example:
LIB "qhmoduli.lib";
ring B   = 0,(x,y,z), ls;
poly f = -z5+y5+x2z+x2y;
UpperMonomials(f);
==> _[1]=y3z3
==> _[2]=x2y3
==> _[3]=x2y2

D.5.7.8 Max
...........
Procedure from library qhmoduli.lib (see qhmoduli_lib).

Usage:
Max(data); intvec/list of integers data

Purpose:
find the maximal integer contained in 'data'

Return:
list

Assume:
'data' contains only integers and is not empty


D.5.7.9 Min
...........
Procedure from library qhmoduli.lib (see qhmoduli_lib).

Usage:
Min(data); intvec/list of integers data

Purpose:
find the minimal integer contained in 'data'

Return:
list

Assume:
'data' contains only integers and is not empty


D.5.7.10 Table
..............
Procedure from library qhmoduli.lib (see qhmoduli_lib).

Usage:
Table(cmd,i, lb, ub); string cmd, i; int lb, ub

Purpose:
generate a list of size ub - lb + 1 s.t. _[i] = cmd(i)

Return:
list

D.5.8 sing_lib
--------------
Library:
sing.lib
Purpose:
      Invariants of Singularities
Authors:
Gert-Martin Greuel, email: greuel@mathematik.uni-kl.de 

Bernd Martin, email: martin@math.tu-cottbus.de


Procedures:
* deform:: infinitesimal deformations of ideal i
* dim_slocus:: dimension of singular locus of ideal i
* is_active:: is poly f an active element mod id? (id ideal/module)
* is_ci:: is ideal i a complete intersection?
* is_is:: is ideal i an isolated singularity?
* is_reg:: is poly f a regular element mod id? (id ideal/module)
* is_regs:: are gen's of ideal i regular sequence modulo id?
* locstd:: SB for local degree ordering without cancelling units
* milnor:: milnor number of ideal i; (assume i is ICIS in nf)
* nf_icis:: generic combinations of generators; get ICIS in nf
* slocus:: ideal of singular locus of ideal i
* qhspectrum:: spectrum numbers of w-homogeneous polynomial f
* Tjurina:: SB of Tjurina module of ideal i (assume i is ICIS)
* tjurina:: Tjurina number of ideal i (assume i is ICIS)
* T_1:: T^1-module of ideal i
* T_2:: T^2-module of ideal i
* T_12:: T^1- and T^2-module of ideal i
* tangentcone:: compute tangent cone of id

D.5.8.1 deform
..............
Procedure from library sing.lib (see sing_lib).

Usage:
deform(id); id=ideal or poly

Return:
matrix, columns are kbase of infinitesimal deformations

Example:
LIB "sing.lib";
ring r   = 32003,(x,y,z),ds;
ideal i  = xy,xz,yz;
matrix T = deform(i);
print(T);
==> x,0,0,
==> 0,0,z,
==> 0,y,0 
print(deform(x3+y5+z2));
==> xy3,y3,xy2,y2,xy,y,x,1

D.5.8.2 dim_slocus
..................
Procedure from library sing.lib (see sing_lib).

Usage:
dim_slocus(i); i ideal or poly

Return:
dimension of singular locus of i

Example:
LIB "sing.lib";
ring r  = 32003,(x,y,z),ds;
ideal i = x5+y6+z6,x2+2y2+3z2;
dim_slocus(i);
==> 0

D.5.8.3 is_active
.................
Procedure from library sing.lib (see sing_lib).

Usage:
is_active(f,id); f poly, id ideal or module

Return:
1 if f is an active element modulo id (i.e. dim(id)=dim(id+f*R^n)+1,
if id is a submodule of R^n) resp. 0 if f is not active.
The basering may be a quotient ring

Note:
regular parameters are active but not vice versa (id may have embedded
components). proc is_reg tests whether f is a regular parameter

Example:
LIB "sing.lib";
ring r   =32003,(x,y,z),ds;
ideal i  = yx3+y,yz3+y3z;
poly f   = x;
is_active(f,i);
==> 1
qring q  = std(x4y5);
poly f   = x;
module m = [yx3+x,yx3+y3x];
is_active(f,m);
==> 0

D.5.8.4 is_ci
.............
Procedure from library sing.lib (see sing_lib).

Usage:
is_ci(i); i ideal

Return:
intvec = sequence of dimensions of ideals (j[1],...,j[k]), for
k=1,...,size(j), where j is minimal base of i. i is a complete
intersection if last number equals nvars-size(i)

Note:
dim(0-ideal) = -1. You may first apply simplify(i,10); in order to
delete zeroes and multiples from set of generators

printlevel >=0: display comments (default)

Example:
LIB "sing.lib";
int p      = printlevel;
printlevel = 1;                // display comments
ring r     = 32003,(x,y,z),ds;
ideal i    = x4+y5+z6,xyz,yx2+xz2+zy7;
is_ci(i);
==> // complete intersection of dim 0
==> // dim-sequence:
==> 2,1,0
i          = xy,yz;
is_ci(i);
==> // no complete intersection
==> // dim-sequence:
==> 2,2
printlevel = p;

D.5.8.5 is_is
.............
Procedure from library sing.lib (see sing_lib).

Usage:
is_is(id); id ideal or poly

Return:
intvec = sequence of dimensions of singular loci of ideals
generated by id[1]..id[i], k = 1..size(id); 

dim(0-ideal) = -1;

id defines an isolated singularity if last number is 0

Note:
printlevel >=0: display comments (default)

Example:
LIB "sing.lib";
int p      = printlevel;
printlevel = 1;
ring r     = 32003,(x,y,z),ds;
ideal i    = x2y,x4+y5+z6,yx2+xz2+zy7;
is_is(i);
==> // dim of singular locus = 0
==> // isolated singularity if last number is 0 in dim-sequence:
==> 2,1,0
poly f     = xy+yz;
is_is(f);
==> // dim of singular locus = 1
==> // isolated singularity if last number is 0 in dim-sequence:
==> 1
printlevel = p;

D.5.8.6 is_reg
..............
Procedure from library sing.lib (see sing_lib).

Usage:
is_reg(f,id); f poly, id ideal or module

Return:
1 if multiplication with f is injective modulo id, 0 otherwise

Note:
let R be the basering and id a submodule of R^n. The procedure checks
injectivity of multiplication with f on R^n/id. The basering may be a
quotient ring

Example:
LIB "sing.lib";
ring r  = 32003,(x,y),ds;
ideal i = x8,y8;
ideal j = (x+y)^4;
i       = intersect(i,j);
poly f  = xy;
is_reg(f,i);
==> 0

D.5.8.7 is_regs
...............
Procedure from library sing.lib (see sing_lib).

Usage:
is_regs(i[,id]); i poly, id ideal or module (default: id=0)

Return:
1 if generators of i are a regular sequence modulo id, 0 otherwise

Note:
let R be the basering and id a submodule of R^n. The procedure checks
injectivity of multiplication with i[k] on R^n/id+i[1..k-1].
The basering may be a quotient ring

printlevel >=0: display comments (default)

printlevel >=1: display comments during computation

Example:
LIB "sing.lib";
int p      = printlevel;
printlevel = 1;
ring r1    = 32003,(x,y,z),ds;
ideal i    = x8,y8,(x+y)^4;
is_regs(i);
==> // checking whether element 1 is regular mod 1 .. 0
==> // checking whether element 2 is regular mod 1 .. 1
==> // checking whether element 3 is regular mod 1 .. 2
==> // elements 1..2 are regular, 3 is not regular mod 1..2
==> 0
module m   = [x,0,y];
i          = x8,(x+z)^4;;
is_regs(i,m);
==> // checking whether element 1 is regular mod 1 .. 0
==> // checking whether element 2 is regular mod 1 .. 1
==> // elements are a regular sequence of length 2
==> 1
printlevel = p;

D.5.8.8 locstd
..............
Procedure from library sing.lib (see sing_lib).

Usage:
locstd (id); id = ideal

Return:
a standard basis for a local degree ordering

Note:
the procedure homogenizes id w.r.t. a new 1st variable @t@, computes
a SB wrt (dp(1),dp) and substitutes @t@ by 1.

Hence the result is a SB with respect to an ordering which sorts
first w.r.t. the order and then refines it with dp. This is a
local degree ordering.

This is done in order to avoid cancellation of units and thus
be able to use option(contentSB);

Example:
LIB "sing.lib";
ring R = 0,(x,y,z),ds;
ideal i  = xyz+z5,2x2+y3+z7,3z5+y5;
locstd(i);
==> _[1]=y5+3z5
==> _[2]=3x4y3z8-4x3y3z9+6x2y4z9+3y5z10
==> _[3]=3x4z13-4x3z14+6x2yz14+3y2z15
==> _[4]=3x4yz12-4x3yz13+6x2y2z13+3y3z14
==> _[5]=2x2z9+x2y2z8+y3z9
==> _[6]=2x2y4z5+y7z5-3x2yz9
==> _[7]=6y2z10-3x2y3z8+4xy3z9-3y4z9
==> _[8]=3x2y2z8+3y3z9+2xy4z8
==> _[9]=18z14-4xy6z8+3y7z8-9x2yz12
==> _[10]=xyz+z5
==> _[11]=3xz6-y4z5
==> _[12]=3y3z6+2xy4z5-3xyz9
==> _[13]=y4z5-2xz9-xy2z8
==> _[14]=3z10+2xyz9+xy3z8
==> _[15]=2x2z5+y3z5-xyz8
==> _[16]=y4z-2xz5+yz8
==> _[17]=3z6+2xyz5-y2z8
==> _[18]=2x2+y3+z7

D.5.8.9 milnor
..............
Procedure from library sing.lib (see sing_lib).

Usage:
milnor(i); i ideal or poly

Return:
Milnor number of i, if i is ICIS (isolated complete intersection
singularity) in generic form, resp. -1 if not

Note:
use proc nf_icis to put generators in generic form

printlevel >=0: display comments (default)

Example:
LIB "sing.lib";
int p      = printlevel;
printlevel = 1;
ring r     = 32003,(x,y,z),ds;
ideal j    = x5+y6+z6,x2+2y2+3z2,xyz+yx;
milnor(j);
==> //sequence of discriminant numbers: 100,149,70
==> 21
poly f     = x7+y7+(x-y)^2*x2y2+z2;
milnor(f);
==> 28
printlevel = p;

D.5.8.10 nf_icis
................
Procedure from library sing.lib (see sing_lib).

Usage:
nf_icis(i); i ideal

Return:
ideal = generic linear combination of generators of i if i is an ICIS
(isolated complete intersection singularity), return i if not

Note:
this proc is useful in connection with proc milnor

printlevel >=0: display comments (default)

Example:
LIB "sing.lib";
int p      = printlevel;
printlevel = 1;
ring r     = 32003,(x,y,z),ds;
ideal i    = x3+y4,z4+yx;
nf_icis(i);
==> // complete intersection of dim 1
==> // dim-sequence:
==> // dim of singular locus = 0
==> // isolated singularity if last number is 0 in dim-sequence:
==> // dim of singular locus = 0
==> // isolated singularity if last number is 0 in dim-sequence:
==> // ICIS in generic form after 1 genericity loop(s)
==> _[1]=2xy+x3+y4+2z4
==> _[2]=xy+z4
ideal j    = x3+y4,xy,yz;
nf_icis(j);
==> // no complete intersection
==> // dim-sequence:
==> // no complete intersection
==> _[1]=x3+y4
==> _[2]=xy
==> _[3]=yz
printlevel = p;

D.5.8.11 slocus
...............
Procedure from library sing.lib (see sing_lib).

Usage:
slocus(i); i ideal

Return:
ideal of singular locus of i

Example:
LIB "sing.lib";
ring r  = 0,(u,v,w,x,y,z),dp;
ideal i = wx,wy,wz,vx,vy,vz,ux,uy,uz,y3-x2;;
slocus(i);
==> _[1]=x
==> _[2]=w
==> _[3]=v
==> _[4]=u
==> _[5]=y2

D.5.8.12 qhspectrum
...................
Procedure from library sing.lib (see sing_lib).

Usage:
qhspectrum(f,w); f=poly, w=intvec;

Assume:
f is a weighted homogeneous isolated singularity w.r.t. the weights
given by w; w must consist of as many positive integers as there
are variables of the basering

Compute:
the spectral numbers of the w-homogeneous polynomial f, computed in a
ring of characteristic 0

Return:
intvec d,s1,...,su where:

d = w-degree(f) and si/d = i-th spectral-number(f)

No return value if basering has parameters or if f is no isolated
singularity, displays a warning in this case

Example:
LIB "sing.lib";
ring r;
poly f=x3+y5+z2;
intvec w=10,6,15;
qhspectrum(f,w);
==> 30,1,7,11,13,17,19,23,29
// the spectrum numbers are:
// 1/30,7/30,11/30,13/30,17/30,19/30,23/30,29/30

D.5.8.13 Tjurina
................
Procedure from library sing.lib (see sing_lib).

Usage:
Tjurina(id[,<any>]); id=ideal or poly

Assume:
id=ICIS (isolated complete intersection singularity)

Return:
standard basis of Tjurina-module of id,

of type module if id=ideal, resp. of type ideal if id=poly.
If a second argument is present (of any type) return a list: 

[1] = Tjurina number,

[2] = k-basis of miniversal deformation,

[3] = SB of Tjurina module,

[4] = Tjurina module

Display:
Tjurina number if printlevel >= 0 (default)

Note:
Tjurina number = -1 implies that id is not an ICIS

Example:
LIB "sing.lib";
int p      = printlevel;
printlevel = 1;
ring r     = 0,(x,y,z),ds;
poly f     = x5+y6+z7+xyz;        // singularity T[5,6,7]
list T     = Tjurina(f,"");
==> // Tjurina number = 16
show(T[1]);                       // Tjurina number, should be 16
==> // int, size 1
==> 16
show(T[2]);                       // basis of miniversal deformation
==> // ideal, 16 generator(s)
==> z6,
==> z5,
==> z4,
==> z3,
==> z2,
==> z,
==> y5,
==> y4,
==> y3,
==> y2,
==> y,
==> x4,
==> x3,
==> x2,
==> x,
==> 1
show(T[3]);                       // SB of Tjurina ideal
==> // ideal, 6 generator(s)
==> xy+7z6,
==> xz+6y5,
==> yz+5x4,
==> 5x5-6y6,
==> 6y6,
==> z7
show(T[4]); "";                   // Tjurina ideal
==> // ideal, 4 generator(s)
==> yz+5x4,
==> xz+6y5,
==> xy+7z6,
==> xyz+x5+y6+z7
==> 
ideal j    = x2+y2+z2,x2+2y2+3z2;
show(kbase(Tjurina(j)));          // basis of miniversal deformation
==> // Tjurina number = 5
==> // module, 5 generator(s)
==> [z]
==> [y]
==> [x]
==> [1]
==> [0,1]
hilb(Tjurina(j));                 // Hilbert series of Tjurina module
==> // Tjurina number = 5
==> //         2 t^0
==> //        -3 t^1
==> //        -3 t^2
==> //         7 t^3
==> //        -3 t^4
==> 
==> //         2 t^0
==> //         3 t^1
==> // dimension (local)   = 0
==> // multiplicity = 5
printlevel = p;

D.5.8.14 tjurina
................
Procedure from library sing.lib (see sing_lib).

Usage:
tjurina(id); id=ideal or poly

Assume:
id=ICIS (isolated complete intersection singularity)

Return:
int = Tjurina number of id

Note:
Tjurina number = -1 implies that id is not an ICIS

Example:
LIB "sing.lib";
ring r=32003,(x,y,z),(c,ds);
ideal j=x2+y2+z2,x2+2y2+3z2;
tjurina(j);
==> 5

D.5.8.15 T_1
............
Procedure from library sing.lib (see sing_lib).

Usage:
T_1(id[,<any>]); id = ideal or poly

Return:
T_1(id): of type module/ideal if id is of type ideal/poly.
We call T_1(id) the T_1-module of id. It is a std basis of the
presentation of 1st order deformations of P/id, if P is the basering.
If a second argument is present (of any type) return a list of
3 modules:

[1]= T_1(id)

[2]= generators of normal bundle of id, lifted to P

[3]= module of relations of [2], lifted to P

(note: transpose[3]*[2]=0 mod id)

The list contains all non-easy objects which must be computed
to get T_1(id).

Display:
k-dimension of T_1(id) if printlevel >= 0 (default)

Note:
T_1(id) itself is usually of minor importance. Nevertheless, from it
all relevant information can be obtained. The most important are
probably vdim(T_1(id)); (which computes the Tjurina number),
hilb(T_1(id)); and kbase(T_1(id));

If T_1 is called with two argument, then matrix([2])*(kbase([1]))
represents a basis of 1st order semiuniversal deformation of id
(use proc 'deform', to get this in a direct way).

For a complete intersection the proc Tjurina is faster

Example:
LIB "sing.lib";
int p      = printlevel;
printlevel = 1;
ring r     = 32003,(x,y,z),(c,ds);
ideal i    = xy,xz,yz;
module T   = T_1(i);
==> // dim T_1 = 3
vdim(T);                      // Tjurina number = dim_K(T_1), should be 3
==> 3
list L=T_1(i,"");
==> // dim T_1 = 3
module kB  = kbase(L[1]);
print(L[2]*kB);               // basis of 1st order miniversal deformation
==> 0,0,0,
==> z,0,0,
==> 0,y,z 
show(L[2]);                   // presentation of normal bundle
==> // module, 6 generator(s)
==> [x]
==> [y,z]
==> [0,x,y]
==> [0,z]
==> [0,0,y]
==> [0,0,z]
print(L[3]);                  // relations of i
==> z, 0,
==> -y,y,
==> 0, -x
print(transpose(L[3])*L[2]);  // should be 0 (mod i)
==> xz,0, -xy,-yz,0,  0, 
==> 0, yz,0,  yz, -xy,-xz
printlevel = p;

D.5.8.16 T_2
............
Procedure from library sing.lib (see sing_lib).

Usage:
T_2(id[,<any>]); id = ideal

Return:
T_2(id): T_2-module of id . This is a std basis of a presentation of
the module of obstructions of R=P/id, if P is the basering.
If a second argument is present (of any type) return a list of
4 modules and 1 ideal:

[1]= T_2(id)

[2]= standard basis of id (ideal)

[3]= module of relations of id (=1st syzygy module of id) 

[4]= presentation of syz/kos

[5]= relations of Hom_P([3]/kos,R), lifted to P

The list contains all non-easy objects which must be computed
to get T_2(id).

Display:
k-dimension of T_2(id) if printlevel >= 0 (default)

Note:
The most important information is probably vdim(T_2(id)).
Use proc miniversal to get equations of miniversal deformation.

Example:
LIB "sing.lib";
int p      = printlevel;
printlevel = 1;
ring  r    = 32003,(x,y),(c,dp);
ideal j    = x6-y4,x6y6,x2y4-x5y2;
module T   = T_2(j);
==> // dim T_2 = 6
vdim(T);
==> 6
hilb(T);"";
==> //         1 t^0
==> //        -1 t^2
==> //        -1 t^3
==> //         1 t^5
==> 
==> //         1 t^0
==> //         2 t^1
==> //         2 t^2
==> //         1 t^3
==> // dimension (affine)  = 0
==> // degree      = 6
==> 
ring r1    = 0,(x,y,z),dp;
ideal id   = xy,xz,yz;
list L     = T_2(id,"");
==> // dim T_2 = 0
vdim(L[1]);                           // vdim of T_2
==> 0
print(L[3]);                          // syzygy module of id
==> -z,-z,
==> y, 0, 
==> 0, x  
printlevel = p;

D.5.8.17 T_12
.............
Procedure from library sing.lib (see sing_lib).

Usage:
T_12(i[,any]); i = ideal

Return:
T_12(i): list of 2 modules: 

* standard basis of T_1-module =T_1(i), 1st order deformations 

* standard basis of T_2-module =T_2(i), obstructions of R=P/i 

If a second argument is present (of any type) return a list of
9 modules, matrices, integers: 

[1]= standard basis of T_1-module

[2]= standard basis of T_2-module

[3]= vdim of T_1

[4]= vdim of T_2

[5]= matrix, whose cols present infinitesimal deformations 

[6]= matrix, whose cols are generators of relations of i(=syz(i)) 

[7]= matrix, presenting Hom_P(syz/kos,R), lifted to P 

[8]= presentation of T_1-module, no std basis

[9]= presentation of T_2-module, no std basis

Display:
k-dimension of T_1 and T_2 if printlevel >= 0 (default)

Note:
Use proc miniversal from deform.lib to get miniversal deformation of i,
the list contains all objects used by proc miniversal

Example:
LIB "sing.lib";
int p      = printlevel;
printlevel = 1;
ring r     = 200,(x,y,z,u,v),(c,ws(4,3,2,3,4));
ideal i    = xz-y2,yz2-xu,xv-yzu,yu-z3,z2u-yv,zv-u2;
//a cyclic quotient singularity
list L     = T_12(i,1);
==> // dim T_1 = 5
==> // dim T_2 = 3
print(L[5]);             //matrix of infin. deformations
==> 0,  0,  0,  0,  0,  
==> yz, y,  z2, 0,  0,  
==> -z3,-z2,-zu,yz, yu, 
==> -z2,-z, -u, 0,  0,  
==> zu, u,  v,  -z2,-zu,
==> 0,  0,  0,  u,  v   
printlevel = p;

D.5.8.18 tangentcone
....................
Procedure from library sing.lib (see sing_lib).

Usage:
tangentcone(id [,n]); id = ideal, n = int

Return:
the tangent cone of id

Note:
the procedure works for any monomial ordering.

If n=0 use std w.r.t. local ordering ds, if n=1 use locstd

Example:
LIB "sing.lib";
ring R = 0,(x,y,z),ds;
ideal i  = 7xyz+z5,x2+y3+z7,5z5+y5;
tangentcone(i);
==> _[1]=x2
==> _[2]=7xyz
==> _[3]=y5+5z5
==> _[4]=7y4z
==> _[5]=35z6
D.5.9 spcurve_lib
-----------------
Library:
spcurve.lib
Purpose:
    Deformations and Invariants of CM-codim 2 Singularities
Author:
Anne Fruehbis-Krueger, anne@mathematik.uni-kl.de


Procedures:
* isCMcod2:: presentation matrix of the ideal i, if i is CM
* CMtype:: Cohen-Macaulay type of the ideal i
* matrixT1:: 1st order deformation T1 in matrix description
* semiCMcod2:: semiuniversal deformation of maximal minors of M
* discr:: discriminant of semiuniversal deformation
* qhmatrix:: weights if M is quasihomogeneous
* relweight:: relative matrix weight of N w.r.t. weights (W,a)
* posweight:: deformation of coker(M) of non-negative weight
* KSpencerKernel:: kernel of the Kodaira-Spencer map

D.5.9.1 isCMcod2
................
Procedure from library spcurve.lib (see spcurve_lib).

Usage:
isCMcod2(i); i an ideal

Return:
presentation matrix of i, if i is Cohen-Macaulay of codimension 2 

a zero matrix otherwise

Example:
LIB "spcurve.lib";
ring r=32003,(x,y,z),ds;
ideal i=xz,yz,x^3-y^4;
print(isCMcod2(i));
==> -y,-x2,
==> x, y3, 
==> 0, z   

D.5.9.2 CMtype
..............
Procedure from library spcurve.lib (see spcurve_lib).

Usage:
CMtype(i); i an ideal, CM of codimension 2

Return:
Cohen-Macaulay type of i (integer)

(-1, if i is not Cohen-Macaulay of codimension 2)

Example:
LIB "spcurve.lib";
ring r=32003,(x,y,z),ds;
ideal i=xy,xz,yz;
CMtype(i);
==> 2

D.5.9.3 matrixT1
................
Procedure from library spcurve.lib (see spcurve_lib).

Usage:
matrixT1(M,n); M matrix, n integer

Assume:
M is a presentation matrix of an ideal i, CM of codimension 2;
consider i as a family of ideals in a ring in the first n
variables where the remaining variables are considered as
parameters

Return:
list consisting of the k x (k+1) matrix M and a module K_M such that
T1=Mat(k,k+1;R)/K_M is the space of first order deformations of i

Example:
LIB "spcurve.lib";
ring r=32003,(x(1),x(2),x(3)),ds;
ideal curve=x(1)*x(2),x(1)*x(3),x(2)*x(3);
matrix M=isCMcod2(curve);
matrixT1(M,3);
==> [1]:
==>    _[1,1]=0
==>    _[1,2]=-x(3)
==>    _[2,1]=-x(2)
==>    _[2,2]=x(2)
==>    _[3,1]=x(1)
==>    _[3,2]=0
==> [2]:
==>    _[1]=gen(5)
==>    _[2]=gen(4)-gen(3)
==>    _[3]=-gen(2)
==>    _[4]=x(1)*gen(5)-x(2)*gen(3)
==>    _[5]=x(1)*gen(6)-x(2)*gen(4)
==>    _[6]=x(2)*gen(3)-x(3)*gen(1)
==>    _[7]=x(2)*gen(4)-x(3)*gen(2)
==>    _[8]=-x(3)*gen(2)
==>    _[9]=x(2)*gen(2)-x(2)*gen(1)
==>    _[10]=x(1)*gen(1)
==>    _[11]=-x(3)*gen(4)
==>    _[12]=x(2)*gen(4)-x(2)*gen(3)
==>    _[13]=x(1)*gen(3)
==>    _[14]=-x(3)*gen(6)
==>    _[15]=x(2)*gen(6)-x(2)*gen(5)
==>    _[16]=x(1)*gen(5)

D.5.9.4 semiCMcod2
..................
Procedure from library spcurve.lib (see spcurve_lib).

Usage:
semiCMcod2(M,t1); M matrix, t1 module

Assume:
M is a presentation matrix of an ideal i, CM of codimension 2,
and t1 is a presentation of the space of first order deformations
of i ((M,t1) as returned by the procedure matrixT1)

Create:
new basering with name rneu

Return:
ideal in rneu describing the semiuniversal deformation of i

Note:
The current basering should not contain any variables named
A(j) where j is some integer!

Example:
LIB "spcurve.lib";
ring r=32003,(x(1),x(2),x(3)),ds;
ideal curve=x(1)*x(2),x(1)*x(3),x(2)*x(3);
matrix M=isCMcod2(curve);
list l=matrixT1(M,3);
semiCMcod2(l[1],std(l[2]));
==> _[1]=A(2)*A(3)-x(2)*A(3)-x(1)*x(2)
==> _[2]=A(1)*A(3)+x(1)*x(3)
==> _[3]=-x(2)*A(1)-x(3)*A(2)+x(2)*x(3)

D.5.9.5 discr
.............
Procedure from library spcurve.lib (see spcurve_lib).

Usage:
discr(sem,n); sem ideal, n integer

Assume:
sem is the versal deformation of an ideal of codimension 2. 

the first n variables of the ring are treated as variables
all the others as parameters

Return:
ideal describing the discriminant

Note:
This is not a powerful algorithm!

Example:
LIB "spcurve.lib";
ring r=32003,(x(1),x(2),x(3)),ds;
ideal curve=x(1)*x(2),x(1)*x(3),x(2)*x(3);
matrix M=isCMcod2(curve);
list l=matrixT1(M,3);
def sem=semiCMcod2(l[1],std(l[2]));
basering;
==> //   characteristic : 32003
==> //   number of vars : 6
==> //        block   1 : ordering ds
==> //                  : names    x(1) x(2) x(3) 
==> //        block   2 : ordering dp
==> //                  : names    A(1) A(2) A(3) 
==> //        block   3 : ordering C
discr(sem,3);
==> _[1]=A(1)*A(2)*A(3)

D.5.9.6 qhmatrix
................
Procedure from library spcurve.lib (see spcurve_lib).

Usage:
qhmatrix(M); M a k x (k+1) matrix

Return:
list, consisting of an integer vector containing the weights of
the variables of the basering and an integer matrix giving the
weights of the entries of M, if M is quasihomogeneous;
zero integer vector and zero integer matrix, if M is not
quasihomogeneous, i.e. does not allow row and column weights

Example:
LIB "spcurve.lib";
ring r=0,(x,y,z),ds;
matrix M[3][2]=z,0,y,x,x^3,y;
qhmatrix(M);
==> [1]:
==>    1,2,1
==> [2]:
==>    1,0,
==>    2,1,
==>    3,2 
pmat(M);
==> z,  0, 
==> y,  x, 
==> x3, y

D.5.9.7 relweight
.................
Procedure from library spcurve.lib (see spcurve_lib).

Assume:
N is a non-zero matrix

W is an integer matrix of the same size as N

a is an integer vector giving the weights of the variables

Return:
integer, max(a-weighted order(N_ij) - W_ij | all entries ij) 

string "ERROR" if sizes do not match

Example:
LIB "spcurve.lib";
ring r=32003,(x,y,z),ds;
matrix N[2][3]=z,0,y,x,x^3,y;
intmat W[2][3]=1,1,1,1,1,1;
intvec a=1,1,1;
relweight(N,W,a);
==> 2

D.5.9.8 posweight
.................
Procedure from library spcurve.lib (see spcurve_lib).

Usage:
posweight(M,t1,n[,s]); M matrix, t1 module, n int, s string 

n=0 : all deformations of non-negative weight 

n=1 : only non-constant deformations of non-negative weight 

n=2 : all deformations of positive weight 

As an optional parameter the name of a new ring may be
specified.

Assume:
M is a presentation matrix of a Cohen-Macaulay codimension 2
ideal and t1 is its T1 space in matrix notation

Create:
new basering (default name: rneu); a different name for this ring
may be given as a 4th parameter

Return:
list, consisting of a presentation matrix describing the deformation
given by the generators of T1 of non-negative/positive weight
and the weight vector for the new variables

Note:
The current basering should not contain any variables named
T(i) where i is some integer!

Example:
LIB "spcurve.lib";
ring r=32003,(x(1),x(2),x(3)),ds;
ideal curve=(x(3)-x(1)^2)*x(3),(x(3)-x(1)^2)*x(2),x(2)^2-x(1)^7*x(3);
matrix M=isCMcod2(curve);
list l=matrixT1(M,3);
list li=posweight(l[1],std(l[2]),0);
pmat(li[1]);
==> T(2)+x(1)*T(1), -x(3)+x(1)^2, 
==> -x(3),          x(2),         
==> x(2),           -x(1)^7
li[2];
==> 3,1

D.5.9.9 KSpencerKernel
......................
Procedure from library spcurve.lib (see spcurve_lib).

Usage:
KSpencerKernel(M[,s][,v]); M matrix, s string, v intvec 

optional parameters (please specify in this order, if both are
present):

* s = first of the names of the new rings

e.g. "R" leads to ring names R and R1

* v of size n(n+1) leads to the following module ordering 

gen(v[1]) > gen(v[2]) > ... > gen(v[n(n+1)]) where the matrix
entry ij corresponds to gen((i-1)*n+j)

Assume:
M is a quasihomogeneous n x (n+1) matrix where the n minors define
an isolated space curve singularity

Create:
2 new rings (default names: rneu and reneu)

different ring names may be specified as a 2nd parameter

Return:
coefficient matrix representing the kernel of the Kodaira-
Spencer map of the family of non-negative deformations
having the given singularity as special fibre

Note:
* the initial basering should not contain variables with name
e(i) or T(i), since those variable names will internally be
used by the script

* setting an intvec with 5 entries and name watchProgress
shows the progress of the computations: 

watchProgress[1]>0 => option(prot) in groebner commands 

watchProgress[2]>0 => trace output for highcorner 

watchProgress[3]>0 => output of deformed matrix 

watchProgress[4]>0 => result of elimination step 

watchProgress[4]>1 => trace output of multiplications with xyz
and subsequent reductions 

watchProgress[5]>0 => matrix representing the kernel using print

Example:
LIB "spcurve.lib";
ring r=0,(x,y,z),ds;
matrix M[3][2]=z-x^7,0,y^2,z,x^9,y;
def KS=KSpencerKernel(M,"ar");
print(KS);
==> T(7),   0,      0,      0,     0,     0,     0,     0,  
==> KS[2,1],6*T(3), 3*T(7), 0,     0,     0,     0,     0,  
==> KS[3,1],KS[3,2],KS[3,3],6*T(3),3*T(7),0,     0,     0,  
==> 10*T(4),8*T(1), 7*T(5), 5*T(2),4*T(6),2*T(8),2*T(3),T(7)
nameof(basering);
==> ar
basering;
==> //   characteristic : 0
==> //   number of vars : 17
==> //        block   1 : ordering Ws
==> //                  : names    e(1) e(2) e(3) e(4) e(5) e(6) x y z 
==> //                  : weights  -21 -10 -32 -21 -27 -16 3 16 21 
==> //        block   2 : ordering wp
==> //                  : names    T(1) T(2) T(3) T(4) T(5) T(6) T(7) T(8) 
==> //                  : weights     8    5    2   10    7    4    1    2 
==> //        block   3 : ordering C
D.5.10 spectrum_lib
-------------------
Library:
spectrum.lib
Purpose:
  Singularity Spectrum for Nondegenerate Singularities
Author:
S. Endrass


Procedures:
* spectrumnd:: spectrum of nondegenerate isolated singularity f

D.5.10.1 spectrumnd
...................
Procedure from library spectrum.lib (see spectrum_lib).

Usage:
spectrumnd(f[,1]); poly f

Assume:
basering has characteristic 0 and local ordering,

f has isolated singularity at 0 and nondegenerate principal part

Return:
list S:
  ideal S[1]: spectral numbers in increasing order
  intvec S[2]:
    int S[2][i]: multiplicity of spectral number S[1][i]

Note:
if a second argument 1 is given,

no test for a degenerate principal part will be done

SEE_ALSO: gaussman_lib

Example:
LIB "spectrum.lib";
ring R=0,(x,y),ds;
poly f=x^31+x^6*y^7+x^2*y^12+x^13*y^2+y^29;
spectrumnd(f);
==> [1]:
==>    _[1]=-67/79
==>    _[2]=-62/79
==>    _[3]=-45/58
==>    _[4]=-57/79
==>    _[5]=-41/58
==>    _[6]=-55/79
==>    _[7]=-52/79
==>    _[8]=-37/58
==>    _[9]=-50/79
==>    _[10]=-18/29
==>    _[11]=-47/79
==>    _[12]=-45/79
==>    _[13]=-33/58
==>    _[14]=-16/29
==>    _[15]=-43/79
==>    _[16]=-42/79
==>    _[17]=-40/79
==>    _[18]=-1/2
==>    _[19]=-15/31
==>    _[20]=-14/29
==>    _[21]=-38/79
==>    _[22]=-27/58
==>    _[23]=-14/31
==>    _[24]=-35/79
==>    _[25]=-25/58
==>    _[26]=-13/31
==>    _[27]=-33/79
==>    _[28]=-12/29
==>    _[29]=-23/58
==>    _[30]=-31/79
==>    _[31]=-12/31
==>    _[32]=-30/79
==>    _[33]=-21/58
==>    _[34]=-11/31
==>    _[35]=-28/79
==>    _[36]=-10/29
==>    _[37]=-26/79
==>    _[38]=-19/58
==>    _[39]=-10/31
==>    _[40]=-25/79
==>    _[41]=-9/29
==>    _[42]=-17/58
==>    _[43]=-23/79
==>    _[44]=-9/31
==>    _[45]=-8/29
==>    _[46]=-21/79
==>    _[47]=-15/58
==>    _[48]=-8/31
==>    _[49]=-20/79
==>    _[50]=-7/29
==>    _[51]=-19/79
==>    _[52]=-18/79
==>    _[53]=-7/31
==>    _[54]=-13/58
==>    _[55]=-6/29
==>    _[56]=-16/79
==>    _[57]=-6/31
==>    _[58]=-15/79
==>    _[59]=-11/58
==>    _[60]=-14/79
==>    _[61]=-5/29
==>    _[62]=-13/79
==>    _[63]=-5/31
==>    _[64]=-9/58
==>    _[65]=-11/79
==>    _[66]=-4/29
==>    _[67]=-4/31
==>    _[68]=-10/79
==>    _[69]=-7/58
==>    _[70]=-9/79
==>    _[71]=-3/29
==>    _[72]=-8/79
==>    _[73]=-3/31
==>    _[74]=-7/79
==>    _[75]=-5/58
==>    _[76]=-6/79
==>    _[77]=-2/29
==>    _[78]=-2/31
==>    _[79]=-5/79
==>    _[80]=-3/58
==>    _[81]=-4/79
==>    _[82]=-3/79
==>    _[83]=-1/29
==>    _[84]=-1/31
==>    _[85]=-2/79
==>    _[86]=-1/58
==>    _[87]=-1/79
==>    _[88]=0
==>    _[89]=1/79
==>    _[90]=1/58
==>    _[91]=2/79
==>    _[92]=1/31
==>    _[93]=1/29
==>    _[94]=3/79
==>    _[95]=4/79
==>    _[96]=3/58
==>    _[97]=5/79
==>    _[98]=2/31
==>    _[99]=2/29
==>    _[100]=6/79
==>    _[101]=5/58
==>    _[102]=7/79
==>    _[103]=3/31
==>    _[104]=8/79
==>    _[105]=3/29
==>    _[106]=9/79
==>    _[107]=7/58
==>    _[108]=10/79
==>    _[109]=4/31
==>    _[110]=4/29
==>    _[111]=11/79
==>    _[112]=9/58
==>    _[113]=5/31
==>    _[114]=13/79
==>    _[115]=5/29
==>    _[116]=14/79
==>    _[117]=11/58
==>    _[118]=15/79
==>    _[119]=6/31
==>    _[120]=16/79
==>    _[121]=6/29
==>    _[122]=13/58
==>    _[123]=7/31
==>    _[124]=18/79
==>    _[125]=19/79
==>    _[126]=7/29
==>    _[127]=20/79
==>    _[128]=8/31
==>    _[129]=15/58
==>    _[130]=21/79
==>    _[131]=8/29
==>    _[132]=9/31
==>    _[133]=23/79
==>    _[134]=17/58
==>    _[135]=9/29
==>    _[136]=25/79
==>    _[137]=10/31
==>    _[138]=19/58
==>    _[139]=26/79
==>    _[140]=10/29
==>    _[141]=28/79
==>    _[142]=11/31
==>    _[143]=21/58
==>    _[144]=30/79
==>    _[145]=12/31
==>    _[146]=31/79
==>    _[147]=23/58
==>    _[148]=12/29
==>    _[149]=33/79
==>    _[150]=13/31
==>    _[151]=25/58
==>    _[152]=35/79
==>    _[153]=14/31
==>    _[154]=27/58
==>    _[155]=38/79
==>    _[156]=14/29
==>    _[157]=15/31
==>    _[158]=1/2
==>    _[159]=40/79
==>    _[160]=42/79
==>    _[161]=43/79
==>    _[162]=16/29
==>    _[163]=33/58
==>    _[164]=45/79
==>    _[165]=47/79
==>    _[166]=18/29
==>    _[167]=50/79
==>    _[168]=37/58
==>    _[169]=52/79
==>    _[170]=55/79
==>    _[171]=41/58
==>    _[172]=57/79
==>    _[173]=45/58
==>    _[174]=62/79
==>    _[175]=67/79
==> [2]:
==>    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,2,1,1,1,1,1,1,\
   1,1,2,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,2,1,1,1,1,2,1,1,1\
   ,1,1,2,1,1,1,1,2,1,1,1,1,1,2,1,4,1,2,1,1,1,1,1,2,1,1,1,1,2,1,1,1,1,1,2,1,\
   1,1,1,2,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1\
   ,1,2,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
D.6 Invariant theory
====================

* finvar_lib:: procedures to compute invariant rings of finite groups
* ainvar_lib:: procedures to compute invariants rings of the additive group
* rinvar_lib:: procedures to compute invariants ring of reductive groups
* stratify_lib:: algorithmic stratification by the Greuel-Pfister algorithm

D.6.1 finvar_lib
----------------
Library:
finvar.lib
Purpose:
    Invariant Rings of Finite Groups
Author:
Agnes E. Heydtmann, email: agnes@math.uni-sb.de

Overview:
A library for computing polynomial invariants of finite matrix groups and
generators of related varieties. The algorithms are based on B. Sturmfels,
G. Kemper and W. Decker et al..


Main procedures:
* invariant_ring:: generators of the invariant ring (i.r.)
* invariant_ring_random:: generators of the i.r., randomized alg.
* primary_invariants:: primary invariants (p.i.)
* primary_invariants_random:: primary invariants, randomized alg.
Auxiliary procedures:
* cyclotomic:: cyclotomic polynomial
* group_reynolds:: finite group and Reynolds operator (R.o.)
* molien:: Molien series (M.s.)
* reynolds_molien:: Reynolds operator and Molien series
* partial_molien:: partial expansion of Molien series
* evaluate_reynolds:: image under the Reynolds operator
* invariant_basis:: basis of homogeneous invariants of a degree
* invariant_basis_reynolds:: as invariant_basis(), with R.o.
* primary_char0:: primary invariants in char 0
* primary_charp:: primary invariant in char p
* primary_char0_no_molien:: p.i., char 0, without Molien series
* primary_charp_no_molien:: p.i., char p, without Molien series
* primary_charp_without:: p.i., char p, without R.o. or Molien series
* primary_char0_random:: primary invariants in char 0, randomized
* primary_charp_random:: primary invariants in char p, randomized
* primary_char0_no_molien_random:: p.i., char 0, without M.s., randomized
* primary_charp_no_molien_random:: p.i., char p, without M.s., randomized
* primary_charp_without_random:: p.i., char p, without R.o. or M.s., random.
* power_products:: exponents for power products
* secondary_char0:: secondary (s.i.) invariants in char 0
* secondary_charp:: secondary invariants in char p
* secondary_no_molien:: secondary invariants, without Molien series
* secondary_and_irreducibles_no_molien:: s.i. & irreducible s.i., without M.s.
* secondary_not_cohen_macaulay:: s.i. when invariant ring not Cohen-Macaulay
* orbit_variety:: ideal of the orbit variety
* relative_orbit_variety:: ideal of a relative orbit variety
* image_of_variety:: ideal of the image of a variety

D.6.1.1 invariant_ring
......................
Procedure from library finvar.lib (see finvar_lib).

Usage:
invariant_ring(G1,G2,...[,flags]);

G1,G2,...: <matrices> generating a finite matrix group, flags: an
optional <intvec> with three entries: if the first one equals 0, the
program attempts to compute the Molien series and Reynolds operator,
if it equals 1, the program is told that the Molien series should not
be computed, if it equals -1 characteristic 0 is simulated, i.e. the
Molien series is computed as if the base field were characteristic 0
(the user must choose a field of large prime characteristic, e.g.
32003) and if the first one is anything else, it means that the
characteristic of the base field divides the group order (i.e. it will
not even be attempted to compute the Reynolds operator or Molien
series), the second component should give the size of intervals
between canceling common factors in the expansion of Molien series, 0
(the default) means only once after generating all terms, in prime
characteristic also a negative number can be given to indicate that
common factors should always be canceled when the expansion is simple
(the root of the extension field occurs not among the coefficients)

Return:
primary and secondary invariants (both of type <matrix>) generating
the invariant ring with respect to the matrix group generated by the
matrices in the input and irreducible secondary invariants (type
<matrix>) if the Molien series was available

Display:
information about the various stages of the program if the third flag
does not equal 0

Theory:
Bases of homogeneous invariants are generated successively and those
are chosen as primary invariants that lower the dimension of the ideal
generated by the previously found invariants (see "Generating a
Noetherian Normalization of the Invariant Ring of a Finite Group" by
Decker, Heydtmann, Schreyer (1998)). In the

non-modular case secondary invariants are calculated by finding a
basis (in terms of monomials) of the basering modulo the primary
invariants, mapping to invariants with the Reynolds operator and using
those or their power products such that they are linearly independent
modulo the primary invariants (see "Some Algorithms in Invariant
Theory of Finite Groups" by Kemper and Steel (1997)). In the modular
case they are generated according to "Generating Invariant Rings of
Finite Groups over Arbitrary Fields" by Kemper (1996).

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
matrix P,S,IS=invariant_ring(A);
print(P);
==> z2,x2+y2,x2y2
print(S);
==> 1,xyz,x2z-y2z,x3y-xy3
print(IS);
==> xyz,x2z-y2z,x3y-xy3

D.6.1.2 invariant_ring_random
.............................
Procedure from library finvar.lib (see finvar_lib).

Usage:
invariant_ring_random(G1,G2,...,r[,flags]);

G1,G2,...: <matrices> generating a finite matrix group, r: an <int>
where -|r| to |r| is the range of coefficients of random
combinations of bases elements that serve as primary invariants,
flags: an optional <intvec> with three entries: if the first equals 0,
the program attempts to compute the Molien series and Reynolds
operator, if it equals 1, the program is told that the Molien series
should not be computed, if it equals -1 characteristic 0 is simulated,
i.e. the Molien series is computed as if the base field were
characteristic 0 (the user must choose a field of large prime
characteristic, e.g. 32003) and if the first one is anything else,
then the characteristic of the base field divides the group order
(i.e. we will not even attempt to compute the Reynolds operator or
Molien series), the second component should give the size of intervals
between canceling common factors in the expansion of the Molien
series, 0 (the default) means only once after generating all terms,
in prime characteristic also a negative number can be given to
indicate that common factors should always be canceled when the
expansion is simple (the root of the extension field does not occur
among the coefficients)

Return:
primary and secondary invariants (both of type <matrix>) generating
invariant ring with respect to the matrix group generated by the
matrices in the input and irreducible secondary invariants (type
<matrix>) if the Molien series was available

Display:
information about the various stages of the program if the third flag
does not equal 0

Theory:
is the same as for invariant_ring except that random combinations of
basis elements are chosen as candidates for primary invariants and
hopefully they lower the dimension of the previously found primary
invariants by the right amount.

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
matrix P,S,IS=invariant_ring_random(A,1);
print(P);
==> z2,x2+y2,x4+y4-z4
print(S);
==> 1,xyz,x2z-y2z,x3y-xy3
print(IS);
==> xyz,x2z-y2z,x3y-xy3

D.6.1.3 primary_invariants
..........................
Procedure from library finvar.lib (see finvar_lib).

Usage:
primary_invariants(G1,G2,...[,flags]);

G1,G2,...: <matrices> generating a finite matrix group, flags: an
optional <intvec> with three entries, if the first one equals 0 (also
the default), the program attempts to compute the Molien series and
Reynolds operator, if it equals 1, the program is told that the
Molien series should not be computed, if it equals -1 characteristic 0
is simulated, i.e. the Molien series is computed as if the base field
were characteristic 0 (the user must choose a field of large prime
characteristic, e.g. 32003) and if the first one is anything else, it
means that the characteristic of the base field divides the group
order, the second component should give the size of intervals between
canceling common factors in the expansion of the Molien series, 0 (the
default) means only once after generating all terms, in prime
characteristic also a negative number can be given to indicate that
common factors should always be canceled when the expansion is simple
(the root of the extension field occurs not among the coefficients)

Display:
information about the various stages of the program if the third
flag does not equal 0

Return:
primary invariants (type <matrix>) of the invariant ring and if
computable Reynolds operator (type <matrix>) and Molien series (type
<matrix>) or ring name (type string) where the Molien series
can be found in the char p case; if the first flag is 1 and we are in
the non-modular case then an <intvec> is returned giving some of the
degrees where no non-trivial homogeneous invariants can be found

Theory:
Bases of homogeneous invariants are generated successively and those
are chosen as primary invariants that lower the dimension of the ideal
generated by the previously found invariants (see paper "Generating a
Noetherian Normalization of the Invariant Ring of a Finite Group" by
Decker, Heydtmann, Schreyer (1998)).

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
list L=primary_invariants(A);
print(L[1]);
==> z2,x2+y2,x2y2

D.6.1.4 primary_invariants_random
.................................
Procedure from library finvar.lib (see finvar_lib).

Usage:
primary_invariants_random(G1,G2,...,r[,flags]);

G1,G2,...: <matrices> generating a finite matrix group, r: an <int>
where -|r| to |r| is the range of coefficients of the random
combinations of bases elements, flags: an optional <intvec> with three
entries, if the first one equals 0 (also the default), the program
attempts to compute the Molien series and Reynolds operator, if it
equals 1, the program is told that the Molien series should not be
computed, if it equals -1 characteristic 0 is simulated, i.e. the
Molien series is computed as if the base field were characteristic 0
(the user must choose a field of large prime characteristic, e.g.
32003) and if the first one is anything else, it means that the
characteristic of the base field divides the group order, the second
component should give the size of intervals between canceling common
factors in the expansion of the Molien series, 0 (the default) means
only once after generating all terms, in prime characteristic also a
negative number can be given to indicate that common factors should
always be canceled when the expansion is simple (the root of the
extension field does not occur among the coefficients)

Display:
information about the various stages of the program if the third
flag does not equal 0

Return:
primary invariants (type <matrix>) of the invariant ring and if
computable Reynolds operator (type <matrix>) and Molien series (type
<matrix>), if the first flag is 1 and we are in the non-modular case
then an <intvec> is returned giving some of the degrees where no
non-trivial homogeneous invariants can be found

Theory:
Bases of homogeneous invariants are generated successively and random
linear combinations are chosen as primary invariants that lower the
dimension of the ideal generated by the previously found invariants
(see "Generating a Noetherian Normalization of the Invariant Ring of
a Finite Group" by Decker, Heydtmann, Schreyer (1998)).

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
list L=primary_invariants_random(A,1);
print(L[1]);
==> z2,x2+y2,x4+y4-z4

D.6.1.5 cyclotomic
..................
Procedure from library finvar.lib (see finvar_lib).

Usage:
cyclotomic(i); i integer > 0

Returns:
the i-th cyclotomic polynomial (type <poly>) as one in the first ring
variable

Theory:
x^i-1 is divided by the j-th cyclotomic polynomial where j takes on
the value of proper divisors of i

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
print(cyclotomic(25));
==> x20+x15+x10+x5+1

D.6.1.6 group_reynolds
......................
Procedure from library finvar.lib (see finvar_lib).

Usage:
group_reynolds(G1,G2,...[,v]);

G1,G2,...: nxn <matrices> generating a finite matrix group, v: an
optional <int>

Assume:
n is the number of variables of the basering, g the number of group
elements

Return:
a <list>, the first list element will be a gxn <matrix> representing
the Reynolds operator if we are in the non-modular case; if the
characteristic is >0, minpoly==0 and the finite group non-cyclic the
second list element is an <int> giving the lowest common multiple of
the matrix group elements' order (used in molien); in general all
other list elements are nxn <matrices> listing all elements of the
finite group

Display:
information if v does not equal 0

Theory:
The entire matrix group is generated by getting all left products of
generators with the new elements from the last run through the loop
(or the generators themselves during the first run). All the ones that
have been generated before are thrown out and the program terminates
when no new elements found in one run. Additionally each time a new
group element is found the corresponding ring mapping of which the
Reynolds operator is made up is generated. They are stored in the rows
of the first return value.

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
list L=group_reynolds(A);
print(L[1]);
==> y, -x,-z,
==> -x,-y,z, 
==> -y,x, -z,
==> x, y, z  
print(L[2..size(L)]);
==> 0, 1,0,
==> -1,0,0,
==> 0, 0,-1
==> -1,0, 0,
==> 0, -1,0,
==> 0, 0, 1 
==> 0,-1,0,
==> 1,0, 0,
==> 0,0, -1
==> 1,0,0,
==> 0,1,0,
==> 0,0,1 

D.6.1.7 molien
..............
Procedure from library finvar.lib (see finvar_lib).

Usage:
molien(G1,G2,...[,ringname,lcm,flags]);

G1,G2,...: nxn <matrices>, all elements of a finite matrix group,
ringname: a <string> giving a name for a new ring of characteristic 0
for the Molien series in case of prime characteristic, lcm: an <int>
giving the lowest common multiple of the elements' orders in case of
prime characteristic, minpoly==0 and a non-cyclic group, flags: an
optional <intvec> with three components: if the first element is not
equal to 0 characteristic 0 is simulated, i.e. the Molien series is
computed as if the base field were characteristic 0 (the user must
choose a field of large prime characteristic, e.g. 32003), the second
component should give the size of intervals between canceling common
factors in the expansion of the Molien series, 0 (the default) means
only once after generating all terms, in prime characteristic also a
negative number can be given to indicate that common factors should
always be canceled when the expansion is simple (the root of the
extension field does not occur among the coefficients)

Assume:
n is the number of variables of the basering, G1,G2... are the group
elements generated by group_reynolds(), lcm is the second return value
of group_reynolds()

Return:
in case of characteristic 0 a 1x2 <matrix> giving enumerator and
denominator of Molien series; in case of prime characteristic a ring
with the name `ringname` of characteristic 0 is created where the same
Molien series (named M) is stored

Display:
information if the third component of flags does not equal 0

Theory:
In characteristic 0 the terms 1/det(1-xE) for all group elements of
the Molien series are computed in a straight forward way. In prime
characteristic a Brauer lift is involved. The returned matrix gives
enumerator and denominator of the expanded version where common
factors have been canceled.

Example:
LIB "finvar.lib";
"         note the case of prime characteristic"; 
==>          note the case of prime characteristic
ring R=0,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
list L=group_reynolds(A);
matrix M=molien(L[2..size(L)]);
print(M);
==> x3+x2-x+1,-x7+x6+x5-x4+x3-x2-x+1
ring S=3,(x,y,z),dp;
string newring="alksdfjlaskdjf";
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
list L=group_reynolds(A);
molien(L[2..size(L)],newring);
setring alksdfjlaskdjf;
print(M);
==> x3+x2-x+1,-x7+x6+x5-x4+x3-x2-x+1
setring S;
kill alksdfjlaskdjf;

D.6.1.8 reynolds_molien
.......................
Procedure from library finvar.lib (see finvar_lib).

Usage:
reynolds_molien(G1,G2,...[,ringname,flags]);

G1,G2,...: nxn <matrices> generating a finite matrix group, ringname:
a <string> giving a name for a new ring of characteristic 0 for the
Molien series in case of prime characteristic, flags: an optional
<intvec> with three components: if the first element is not equal to 0
characteristic 0 is simulated, i.e. the Molien series is computed as
if the base field were characteristic 0 (the user must choose a field
of large prime characteristic, e.g. 32003) the second component should
give the size of intervals between canceling common factors in the
expansion of the Molien series, 0 (the default) means only once after
generating all terms, in prime characteristic also a negative number
can be given to indicate that common factors should always be canceled
when the expansion is simple (the root of the extension field does not
occur among the coefficients)

Assume:
n is the number of variables of the basering, G1,G2... are the group
elements generated by group_reynolds(), g is the size of the group

Return:
a gxn <matrix> representing the Reynolds operator is the first return
value and in case of characteristic 0 a 1x2 <matrix> giving enumerator
and denominator of Molien series is the second one; in case of prime
characteristic a ring with the name `ringname` of characteristic 0 is
created where the same Molien series (named M) is stored

Display:
information if the third component of flags does not equal 0

Theory:
The entire matrix group is generated by getting all left products of
the generators with new elements from the last run through the loop
(or the generators themselves during the first run). All the ones that
have been generated before are thrown out and the program terminates
when are no new elements found in one run. Additionally each time a
new group element is found the corresponding ring mapping of which the
Reynolds operator is made up is generated. They are stored in the rows
of the first return value. In characteristic 0 the terms 1/det(1-xE)
is computed whenever a new element E is found. In prime characteristic
a Brauer lift is involved and the terms are only computed after the
entire matrix group is generated (to avoid the modular case). The
returned matrix gives enumerator and denominator of the expanded
version where common factors have been canceled.

Example:
LIB "finvar.lib";
"         note the case of prime characteristic"; 
==>          note the case of prime characteristic
ring R=0,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
matrix REY,M=reynolds_molien(A);
print(REY);
==> y, -x,-z,
==> -x,-y,z, 
==> -y,x, -z,
==> x, y, z  
print(M);
==> x3+x2-x+1,-x7+x6+x5-x4+x3-x2-x+1
ring S=3,(x,y,z),dp;
string newring="Qadjoint";
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
matrix REY=reynolds_molien(A,newring);
print(REY);
==> y, -x,-z,
==> -x,-y,z, 
==> -y,x, -z,
==> x, y, z  
setring Qadjoint;
print(M);
==> x3+x2-x+1,-x7+x6+x5-x4+x3-x2-x+1
setring S;
kill Qadjoint;

D.6.1.9 partial_molien
......................
Procedure from library finvar.lib (see finvar_lib).

Usage:
partial_molien(M,n[,p]);

M: a 1x2 <matrix>, n: an <int> indicating number of terms in the
expansion, p: an optional <poly>

Assume:
M is the return value of molien or the second return value of
reynolds_molien, p ought to be the second return value of a previous
run of partial_molien and avoids recalculating known terms

Return:
n terms (type <poly>) of the partial expansion of the Molien series
(first n if there is no third parameter given, otherwise the next n
terms depending on a previous calculation) and an intermediate result
(type <poly>) of the calculation to be used as third parameter in a
next run of partial_molien

Theory:
The following calculation is implemented:
(1+a1x+a2x^2+...+anx^n)/(1+b1x+b2x^2+...+bmx^m)=(1+(a1-b1)x+...
(1+b1x+b2x^2+...+bmx^m)
---------------
   (a1-b1)x+(a2-b2)x^2+...
   (a1-b1)x+b1(a1-b1)x^2+...

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
matrix REY,M=reynolds_molien(A);
poly p(1..2);
p(1..2)=partial_molien(M,5);
p(1);
==> 4x5+5x4+2x3+2x2+1
p(1..2)=partial_molien(M,5,p(2));
p(1);
==> 18x10+12x9+13x8+8x7+8x6

D.6.1.10 evaluate_reynolds
..........................
Procedure from library finvar.lib (see finvar_lib).

Usage:
evaluate_reynolds(REY,I);

REY: a <matrix> representing the Reynolds operator, I: an arbitrary
<ideal>

Assume:
REY is the first return value of group_reynolds() or reynolds_molien()

Returns:
image of the polynomials defining I under the Reynolds operator
(type <ideal>)

Note:
the characteristic of the coefficient field of the polynomial ring
should not divide the order of the finite matrix group

Theory:
REY has been constructed in such a way that each row serves as a ring
mapping of which the Reynolds operator is made up.

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
list L=group_reynolds(A);
ideal I=x2,y2,z2;
print(evaluate_reynolds(L[1],I));
==> 1/2x2+1/2y2,
==> 1/2x2+1/2y2,
==> z2

D.6.1.11 invariant_basis
........................
Procedure from library finvar.lib (see finvar_lib).

Usage:
invariant_basis(g,G1,G2,...);

g: an <int> indicating of which degree (>0) the homogeneous basis
should be, G1,G2,...: <matrices> generating a finite matrix group

Returns:
the basis (type <ideal>) of the space of invariants of degree g

Theory:
A general polynomial of degree g is generated and the generators of
the matrix group applied. The difference ought to be 0 and this way a
system of linear equations is created. It is solved by computing
syzygies.

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
print(invariant_basis(2,A));
==> x2+y2,
==> z2

D.6.1.12 invariant_basis_reynolds
.................................
Procedure from library finvar.lib (see finvar_lib).

Usage:
invariant_basis_reynolds(REY,d[,flags]);

REY: a <matrix> representing the Reynolds operator, d: an <int>
indicating of which degree (>0) the homogeneous basis should be, flags:
an optional <intvec> with two entries: its first component gives the
dimension of the space (default <0 meaning unknown) and its second
component is used as the number of polynomials that should be mapped
to invariants during one call of evaluate_reynolds if the dimension of
the space is unknown or the number such that number x dimension
polynomials are mapped to invariants during one call of
evaluate_reynolds

Assume:
REY is the first return value of group_reynolds() or reynolds_molien()
and flags[1] given by partial_molien

Return:
the basis (type <ideal>) of the space of invariants of degree d

Theory:
Monomials of degree d are mapped to invariants with the Reynolds
operator. A linearly independent set is generated with the help of
minbase.

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
intvec flags=0,1,0;
matrix REY,M=reynolds_molien(A,flags);
flags=8,6;
print(invariant_basis_reynolds(REY,6,flags));
==> z6,
==> x2z4+y2z4,
==> x2y2z2,
==> x3yz2-xy3z2,
==> x4z2+y4z2,
==> x4y2+x2y4,
==> x5y-xy5,
==> x6+y6

D.6.1.13 primary_char0
......................
Procedure from library finvar.lib (see finvar_lib).

Usage:
primary_char0(REY,M[,v]);

REY: a <matrix> representing the Reynolds operator, M: a 1x2 <matrix>
representing the Molien series, v: an optional <int>

Assume:
REY is the first return value of group_reynolds or reynolds_molien and
M the one of molien or the second one of reynolds_molien

Display:
information about the various stages of the program if v does not
equal 0

Return:
primary invariants (type <matrix>) of the invariant ring

Theory:
Bases of homogeneous invariants are generated successively and those
are chosen as primary invariants that lower the dimension of the ideal
generated by the previously found invariants (see paper "Generating a
Noetherian Normalization of the Invariant Ring of a Finite Group" by
Decker, Heydtmann, Schreyer (1998)).

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
matrix REY,M=reynolds_molien(A);
matrix P=primary_char0(REY,M);
print(P);
==> z2,x2+y2,x2y2

D.6.1.14 primary_charp
......................
Procedure from library finvar.lib (see finvar_lib).

Usage:
primary_charp(REY,ringname[,v]);

REY: a <matrix> representing the Reynolds operator, ringname: a
<string> giving the name of a ring where the Molien series is stored,
v: an optional <int>

Assume:
REY is the first return value of group_reynolds or reynolds_molien and
ringname gives the name of a ring of characteristic 0 that has been
created by molien or reynolds_molien

Display:
information about the various stages of the program if v does not
equal 0

Return:
primary invariants (type <matrix>) of the invariant ring

Theory:
Bases of homogeneous invariants are generated successively and those
are chosen as primary invariants that lower the dimension of the ideal
generated by the previously found invariants (see paper "Generating a
Noetherian Normalization of the Invariant Ring of a Finite Group" by
Decker, Heydtmann, Schreyer (1998)).

Example:
LIB "finvar.lib";
ring R=3,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
list L=group_reynolds(A);
string newring="alskdfj";
molien(L[2..size(L)],newring);
matrix P=primary_charp(L[1],newring);
if(system("with","Namespaces")) { kill Top::`newring`; }
kill `newring`;
print(P);
==> z2,x2+y2,x2y2

D.6.1.15 primary_char0_no_molien
................................
Procedure from library finvar.lib (see finvar_lib).

Usage:
primary_char0_no_molien(REY[,v]);

REY: a <matrix> representing the Reynolds operator, v: an optional
<int>

Assume:
REY is the first return value of group_reynolds or reynolds_molien

Display:
information about the various stages of the program if v does not
equal 0

Return:
primary invariants (type <matrix>) of the invariant ring and an
<intvec> listing some of the degrees where no non-trivial homogeneous
invariants are to be found

Theory:
Bases of homogeneous invariants are generated successively and those
are chosen as primary invariants that lower the dimension of the ideal
generated by the previously found invariants (see paper "Generating a
Noetherian Normalization of the Invariant Ring of a Finite Group" by
Decker, Heydtmann, Schreyer (1998)).

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
list L=group_reynolds(A);
list l=primary_char0_no_molien(L[1]);
print(l[1]);
==> z2,x2+y2,x2y2

D.6.1.16 primary_charp_no_molien
................................
Procedure from library finvar.lib (see finvar_lib).

Usage:
primary_charp_no_molien(REY[,v]);

REY: a <matrix> representing the Reynolds operator, v: an optional
<int>

Assume:
REY is the first return value of group_reynolds or reynolds_molien

Display:
information about the various stages of the program if v does not
equal 0

Return:
primary invariants (type <matrix>) of the invariant ring and an
<intvec> listing some of the degrees where no non-trivial homogeneous
invariants are to be found

Theory:
Bases of homogeneous invariants are generated successively and those
are chosen as primary invariants that lower the dimension of the ideal
generated by the previously found invariants (see paper "Generating a
Noetherian Normalization of the Invariant Ring of a Finite Group" by
Decker, Heydtmann, Schreyer (1998)).

Example:
LIB "finvar.lib";
ring R=3,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
list L=group_reynolds(A);
list l=primary_charp_no_molien(L[1]);
print(l[1]);
==> z2,x2+y2,x2y2

D.6.1.17 primary_charp_without
..............................
Procedure from library finvar.lib (see finvar_lib).

Usage:
primary_charp_without(G1,G2,...[,v]);

G1,G2,...: <matrices> generating a finite matrix group, v: an optional
<int>

Display:
information about the various stages of the program if v does not
equal 0

Return:
primary invariants (type <matrix>) of the invariant ring

Theory:
Bases of homogeneous invariants are generated successively and those
are chosen as primary invariants that lower the dimension of the ideal
generated by the previously found invariants (see paper "Generating a
Noetherian Normalization of the Invariant Ring of a Finite Group" by
Decker, Heydtmann, Schreyer (1998)). No Reynolds

operator or Molien series is used.

Example:
LIB "finvar.lib";
ring R=2,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
matrix P=primary_charp_without(A);
print(P);
==> x+y,z,xy

D.6.1.18 primary_char0_random
.............................
Procedure from library finvar.lib (see finvar_lib).

Usage:
primary_char0_random(REY,M,r[,v]);

REY: a <matrix> representing the Reynolds operator, M: a 1x2 <matrix>
representing the Molien series, r: an <int> where -|r| to |r| is the
range of coefficients of the random combinations of bases elements,
v: an optional <int>

Assume:
REY is the first return value of group_reynolds or reynolds_molien and
M the one of molien or the second one of reynolds_molien

Display:
information about the various stages of the program if v does not
equal 0

Return:
primary invariants (type <matrix>) of the invariant ring

Theory:
Bases of homogeneous invariants are generated successively and random
linear combinations are chosen as primary invariants that lower the
dimension of the ideal generated by the previously found invariants
(see "Generating a Noetherian Normalization of the Invariant Ring of
a Finite Group" by Decker, Heydtmann, Schreyer (1998)).

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
matrix REY,M=reynolds_molien(A);
matrix P=primary_char0_random(REY,M,1);
print(P);
==> z2,x2+y2,x4+y4-z4

D.6.1.19 primary_charp_random
.............................
Procedure from library finvar.lib (see finvar_lib).

Usage:
primary_charp_random(REY,ringname,r[,v]);

REY: a <matrix> representing the Reynolds operator, ringname: a
<string> giving the name of a ring where the Molien series is stored,
r: an <int> where -|r| to |r| is the range of coefficients of the
random combinations of bases elements, v: an optional <int>

Assume:
REY is the first return value of group_reynolds or reynolds_molien and
ringname gives the name of a ring of characteristic 0 that has been
created by molien or reynolds_molien

Display:
information about the various stages of the program if v does not
equal 0

Return:
primary invariants (type <matrix>) of the invariant ring

Theory:
Bases of homogeneous invariants are generated successively and random
linear combinations are chosen as primary invariants that lower the
dimension of the ideal generated by the previously found invariants
(see "Generating a Noetherian Normalization of the Invariant Ring of
a Finite Group" by Decker, Heydtmann, Schreyer (1998)).

Example:
LIB "finvar.lib";
ring R=3,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
list L=group_reynolds(A);
string newring="alskdfj";
molien(L[2..size(L)],newring);
matrix P=primary_charp_random(L[1],newring,1);
if(system("with","Namespaces")) { kill Top::`newring`; }
kill `newring`;
print(P);
==> z2,x2+y2,x4+y4-z4

D.6.1.20 primary_char0_no_molien_random
.......................................
Procedure from library finvar.lib (see finvar_lib).

Usage:
primary_char0_no_molien_random(REY,r[,v]);

REY: a <matrix> representing the Reynolds operator, r: an <int> where
-|r| to |r| is the range of coefficients of the random combinations of
bases elements, v: an optional <int>

Assume:
REY is the first return value of group_reynolds or reynolds_molien

Display:
information about the various stages of the program if v does not
equal 0

Return:
primary invariants (type <matrix>) of the invariant ring and an
<intvec> listing some of the degrees where no non-trivial homogeneous
invariants are to be found

Theory:
Bases of homogeneous invariants are generated successively and random
linear combinations are chosen as primary invariants that lower the
dimension of the ideal generated by the previously found invariants
(see "Generating a Noetherian Normalization of the Invariant Ring of
a Finite Group" by Decker, Heydtmann, Schreyer (1998)).

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
list L=group_reynolds(A);
list l=primary_char0_no_molien_random(L[1],1);
print(l[1]);
==> z2,x2+y2,x4+y4-z4

D.6.1.21 primary_charp_no_molien_random
.......................................
Procedure from library finvar.lib (see finvar_lib).

Usage:
primary_charp_no_molien_random(REY,r[,v]);

REY: a <matrix> representing the Reynolds operator, r: an <int> where
-|r| to |r| is the range of coefficients of the random combinations of
bases elements, v: an optional <int>

Assume:
REY is the first return value of group_reynolds or reynolds_molien

Display:
information about the various stages of the program if v does not
equal 0

Return:
primary invariants (type <matrix>) of the invariant ring and an
<intvec> listing some of the degrees where no non-trivial homogeneous
invariants are to be found

Theory:
Bases of homogeneous invariants are generated successively and random
linear combinations are chosen as primary invariants that lower the
dimension of the ideal generated by the previously found invariants
(see "Generating a Noetherian Normalization of the Invariant Ring of
a Finite Group" by Decker, Heydtmann, Schreyer (1998)).

Example:
LIB "finvar.lib";
ring R=3,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
list L=group_reynolds(A);
list l=primary_charp_no_molien_random(L[1],1);
print(l[1]);
==> z2,x2+y2,x4+y4-z4

D.6.1.22 primary_charp_without_random
.....................................
Procedure from library finvar.lib (see finvar_lib).

Usage:
primary_charp_without_random(G1,G2,...,r[,v]);

G1,G2,...: <matrices> generating a finite matrix group, r: an <int>
where -|r| to |r| is the range of coefficients of the random
combinations of bases elements, v: an optional <int>

Display:
information about the various stages of the program if v does not
equal 0

Return:
primary invariants (type <matrix>) of the invariant ring

Theory:
Bases of homogeneous invariants are generated successively and random
linear combinations are chosen as primary invariants that lower the
dimension of the ideal generated by the previously found invariants
(see "Generating a Noetherian Normalization of the Invariant Ring of
a Finite Group" by Decker, Heydtmann, Schreyer (1998)). No Reynolds
operator or Molien series is used.

Example:
LIB "finvar.lib";
ring R=2,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
matrix P=primary_charp_without_random(A,1);
print(P);
==> x+y,z,xy

D.6.1.23 power_products
.......................
Procedure from library finvar.lib (see finvar_lib).

Usage:
power_products(dv,d);

dv: an <intvec> giving the degrees of homogeneous polynomials, d: the
degree of the desired power products

Return:
a size(dv)*m <intmat> where each column ought to be interpreted as
containing the exponents of the corresponding polynomials. The product
of the powers is then homogeneous of degree d.

Example:
LIB "finvar.lib";
intvec dv=5,5,5,10,10;
print(power_products(dv,10));
==>      2     1     1     0     0     0     0     0
==>      0     1     0     2     1     0     0     0
==>      0     0     1     0     1     2     0     0
==>      0     0     0     0     0     0     1     0
==>      0     0     0     0     0     0     0     1
print(power_products(dv,7));
==>      0
==>      0
==>      0
==>      0
==>      0

D.6.1.24 secondary_char0
........................
Procedure from library finvar.lib (see finvar_lib).

Usage:
secondary_char0(P,REY,M[,v]);

P: a 1xn <matrix> with primary invariants, REY: a gxn <matrix>
representing the Reynolds operator, M: a 1x2 <matrix> giving numerator
and denominator of the Molien series, v: an optional <int>

Assume:
n is the number of variables of the basering, g the size of the group,
REY is the 1st return value of group_reynolds(), reynolds_molien() or
the second one of primary_invariants(), M the return value of molien()
or the second one of reynolds_molien() or the third one of
primary_invariants()

Return:
secondary invariants of the invariant ring (type <matrix>) and
irreducible secondary invariants (type <matrix>)

Display:
information if v does not equal 0

Theory:
The secondary invariants are calculated by finding a basis (in terms
of monomials) of the basering modulo the primary invariants, mapping
those to invariants with the Reynolds operator and using these images
or their power products such that they are linearly independent modulo
the primary invariants (see paper "Some Algorithms in Invariant
Theory of Finite Groups" by Kemper and Steel (1997)).

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
list L=primary_invariants(A);
matrix S,IS=secondary_char0(L[1..3]);
print(S);
==> 1,xyz,x2z-y2z,x3y-xy3
print(IS);
==> xyz,x2z-y2z,x3y-xy3

D.6.1.25 secondary_charp
........................
Procedure from library finvar.lib (see finvar_lib).

Usage:
secondary_charp(P,REY,ringname[,v]);

P: a 1xn <matrix> with primary invariants, REY: a gxn <matrix>
representing the Reynolds operator, ringname: a <string> giving the
name of a ring of characteristic 0 where the Molien series is stored,
v: an optional <int>

Assume:
n is the number of variables of the basering, g the size of the group,
REY is the 1st return value of group_reynolds(), reynolds_molien() or
the second one of primary_invariants(), `ringname` is a ring of
char 0 that has been created by molien() or reynolds_molien() or
primary_invariants()

Return:
secondary invariants of the invariant ring (type <matrix>) and
irreducible secondary invariants (type <matrix>)

Display:
information if v does not equal 0

Theory:
Secondary invariants are calculated by finding a basis (in terms of
monomials) of the basering modulo primary invariants, mapping those
to invariants with the Reynolds operator and using these images or
their power products such that they are linearly independent modulo
the primary invariants (see paper "Some Algorithms in Invariant
Theory of Finite Groups" by Kemper and Steel (1997)).

Example:
LIB "finvar.lib";
ring R=3,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
list L=primary_invariants(A);
matrix S,IS=secondary_charp(L[1..size(L)]);
print(S);
==> 1,xyz,x2z-y2z,x3y-xy3
print(IS);
==> xyz,x2z-y2z,x3y-xy3

D.6.1.26 secondary_no_molien
............................
Procedure from library finvar.lib (see finvar_lib).

Usage:
secondary_no_molien(P,REY[,deg_vec,v]);

P: a 1xn <matrix> with primary invariants, REY: a gxn <matrix>
representing the Reynolds operator, deg_vec: an optional <intvec>
listing some degrees where no non-trivial homogeneous invariants can
be found, v: an optional <int>

Assume:
n is the number of variables of the basering, g the size of the group,
REY is the 1st return value of group_reynolds(), reynolds_molien() or
the second one of primary_invariants(), deg_vec is the second return
value of primary_char0_no_molien(), primary_charp_no_molien(),
primary_char0_no_molien_random() or primary_charp_no_molien_random()

Return:
secondary invariants of the invariant ring (type <matrix>)

Display:
information if v does not equal 0

Theory:
Secondary invariants are calculated by finding a basis (in terms of
monomials) of the basering modulo primary invariants, mapping those to
invariants with the Reynolds operator and using these images as
candidates for secondary invariants.

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
list L=primary_invariants(A,intvec(1,1,0));
matrix S=secondary_no_molien(L[1..3]);
print(S);
==> 1,xyz,x2z-y2z,x3y-xy3

D.6.1.27 secondary_and_irreducibles_no_molien
.............................................
Procedure from library finvar.lib (see finvar_lib).

Usage:
secondary_and_irreducibles_no_molien(P,REY[,v]);

P: a 1xn <matrix> with primary invariants, REY: a gxn <matrix>
representing the Reynolds operator, v: an optional <int>

Assume:
n is the number of variables of the basering, g the size of the group,
REY is the 1st return value of group_reynolds(), reynolds_molien() or
the second one of primary_invariants()

Return:
secondary invariants of the invariant ring (type <matrix>) and
irreducible secondary invariants (type <matrix>)

Display:
information if v does not equal 0

Theory:
Secondary invariants are calculated by finding a basis (in terms of
monomials) of the basering modulo primary invariants, mapping those to
invariants with the Reynolds operator and using these images or their
power products such that they are linearly independent modulo the
primary invariants (see paper "Some Algorithms in Invariant Theory of
Finite Groups" by Kemper and Steel (1997)).

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
list L=primary_invariants(A,intvec(1,1,0));
matrix S,IS=secondary_and_irreducibles_no_molien(L[1..2]);
print(S);
==> 1,xyz,x2z-y2z,x3y-xy3
print(IS);
==> xyz,x2z-y2z,x3y-xy3

D.6.1.28 secondary_not_cohen_macaulay
.....................................
Procedure from library finvar.lib (see finvar_lib).

Usage:
secondary_not_cohen_macaulay(P,G1,G2,...[,v]);

P: a 1xn <matrix> with primary invariants, G1,G2,...: nxn <matrices>
generating a finite matrix group, v: an optional <int>

Assume:
n is the number of variables of the basering

Return:
secondary invariants of the invariant ring (type <matrix>)

Display:
information if v does not equal 0

Theory:
Secondary invariants are generated following "Generating Invariant
Rings of Finite Groups over Arbitrary Fields" by Kemper (1996).

Example:
LIB "finvar.lib";
ring R=2,(x,y,z),dp;
matrix A[3][3]=0,1,0,-1,0,0,0,0,-1;
list L=primary_invariants(A);
matrix S=secondary_not_cohen_macaulay(L[1],A);
print(S);
==> 1

D.6.1.29 orbit_variety
......................
Procedure from library finvar.lib (see finvar_lib).

Usage:
orbit_variety(F,s);

F: a 1xm <matrix> defining an invariant ring, s: a <string> giving the
name for a new ring

Return:
a Groebner basis (type <ideal>, named G) for the ideal defining the
orbit variety (i.e. the syzygy ideal) in the new ring (named `s`)

Theory:
The ideal of algebraic relations of the invariant ring generators is
calculated, then the variables of the original ring are eliminated and
the polynomials that are left over define the orbit variety

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
matrix F[1][7]=x2+y2,z2,x4+y4,1,x2z-1y2z,xyz,x3y-1xy3;
string newring="E";
orbit_variety(F,newring);
print(G);
==> y(4)-1,
==> y(5)*y(6)-y(2)*y(7),
==> y(2)*y(3)-y(5)^2-2*y(6)^2,
==> y(1)^2*y(6)-2*y(3)*y(6)+y(5)*y(7),
==> y(1)^2*y(5)-y(3)*y(5)-2*y(6)*y(7),
==> y(1)^2*y(2)-y(2)*y(3)-2*y(6)^2,
==> y(1)^4-3*y(1)^2*y(3)+2*y(3)^2+2*y(7)^2
basering;
==> //   characteristic : 0
==> //   number of vars : 7
==> //        block   1 : ordering dp
==> //                  : names    y(1) y(2) y(3) y(4) y(5) y(6) y(7) 
==> //        block   2 : ordering C

D.6.1.30 relative_orbit_variety
...............................
Procedure from library finvar.lib (see finvar_lib).

Usage:
relative_orbit_variety(I,F,s);

I: an <ideal> invariant under the action of a group, F: a 1xm
<matrix> defining the invariant ring of this group, s: a <string>
giving a name for a new ring

Return:
a Groebner basis (type <ideal>, named G) for the ideal defining the
relative orbit variety with respect to I in the new ring (named s)

Theory:
A Groebner basis of the ideal of algebraic relations of the invariant
ring generators is calculated, then one of the basis elements plus the
ideal generators. The variables of the original ring are eliminated
and the polynomials that are left define the relative orbit variety
with respect to I.

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
matrix F[1][3]=x+y+z,xy+xz+yz,xyz;
ideal I=x2+y2+z2-1,x2y+y2z+z2x-2x-2y-2z,xy2+yz2+zx2-2x-2y-2z;
string newring="E";
relative_orbit_variety(I,F,newring);
print(G);
==> 27*y(3)^6-513*y(3)^4+33849*y(3)^2-784,
==> 1475*y(2)+9*y(3)^4-264*y(3)^2+736,
==> 8260*y(1)+9*y(3)^5-87*y(3)^3+5515*y(3)
basering;
==> //   characteristic : 0
==> //   number of vars : 3
==> //        block   1 : ordering lp
==> //                  : names    y(1) y(2) y(3) 
==> //        block   2 : ordering C

D.6.1.31 image_of_variety
.........................
Procedure from library finvar.lib (see finvar_lib).

Usage:
image_of_variety(I,F);

I: an arbitrary <ideal>, F: a 1xm <matrix> defining an invariant ring
of a some matrix group

Return:
the <ideal> defining the image under that group of the variety defined
by I

Theory:
relative_orbit_variety(I,F,s) is called and the newly introduced
variables in the output are replaced by the generators of the
invariant ring. This ideal in the original variables defines the image
of the variety defined by I

Example:
LIB "finvar.lib";
ring R=0,(x,y,z),dp;
matrix F[1][3]=x+y+z,xy+xz+yz,xyz;
ideal I=xy;
print(image_of_variety(I,F));
==> xyz
D.6.2 ainvar_lib
----------------
Library:
ainvar.lib
Purpose:
    Invariant Rings of the Additive Group
Authors:
Gerhard Pfister (email: pfister@mathematik.uni-kl.de),
Gert-Martin Greuel (email: greuel@mathematik.uni-kl.de)


Procedures:
* invariantRing:: compute ring of invariants of (K,+)-action given by m
* derivate:: derivation of f with respect to the vector field m
* actionIsProper:: tests whether action defined by m is proper
* reduction:: SAGBI reduction of p in the subring generated by I
* completeReduction:: complete SAGBI reduction
* localInvar:: invariant polynomial under m computed from p,...
* furtherInvar:: compute further invariants of m from the given ones
* sortier:: sorts generators of id by increasing leading terms

D.6.2.1 invariantRing
.....................
Procedure from library ainvar.lib (see ainvar_lib).

Usage:
invariantRing(m,p,q,b[,r,pa]); m matrix, p,q poly, b,r int, pa string

Assume:
p,q variables with m(p)=q and q invariant under m

i.e. if p=x(i) and q=x(j) then m[j,1]=0 and m[i,1]=x(j)

Return:
ideal, containing generators of the ring of invariants of the
additive group (K,+) given by the vector field
         m = m[1,1]*d/dx(1) +...+ m[n,1]*d/dx(n).
If b>0 the computation stops after all invariants of degree <= b
(and at least one of higher degree) are found or when all invariants
are computed.

If b<=0, the computation continues until all generators
of the ring of invariants are computed (should be used only if the
ring of invariants is known to be finitely generated otherwise the
algorithm might not stop).

If r=1 a different reduction is used which is sometimes faster
(default r=0).

Display:
if pa is given (any string as 5th or 6th argument), the computation
pauses whenever new invariants are found and displays them

Theory:
The algorithm to compute the ring of invariants works in char 0
or big enough characteristic. (K,+) acts as the exponential of the
vector field defined by the matrix m. For background see G.-M. Greuel,
G. Pfister, Geometric quotients of unipotent group actions, Proc.
London Math. Soc. (3) 67, 75-105 (1993).

Example:
LIB "ainvar.lib";
//Winkelmann: free action but Spec(k[x(1),...,x(5)]) --> Spec(invariant ring)
//is not surjective
ring rw=0,(x(1..5)),dp;
matrix m[5][1];
m[3,1]=x(1);
m[4,1]=x(2);
m[5,1]=1+x(1)*x(4)+x(2)*x(3);
ideal in=invariantRing(m,x(3),x(1),0);      //compute full invarint ring
in;
==> in[1]=x(1)
==> in[2]=x(2)
==> in[3]=x(2)*x(3)*x(4)-x(2)*x(5)+x(4)
==> in[4]=x(1)*x(3)*x(4)-x(1)*x(5)+x(3)
//Deveney/Finston: The ring of invariants is not finitely generated
ring rf=0,(x(1..7)),dp;
matrix m[7][1];
m[4,1]=x(1)^3;
m[5,1]=x(2)^3;
m[6,1]=x(3)^3;
m[7,1]=(x(1)*x(2)*x(3))^2;
ideal in=invariantRing(m,x(4),x(1),6);      //all invariants up to degree 6
in;
==> in[1]=x(1)
==> in[2]=x(3)
==> in[3]=x(2)
==> in[4]=x(3)^3*x(4)-x(1)^3*x(6)
==> in[5]=x(2)^3*x(4)-x(1)^3*x(5)
==> in[6]=x(2)^2*x(3)^2*x(4)-x(1)*x(7)
==> in[7]=x(1)^2*x(2)^2*x(6)-x(3)*x(7)
==> in[8]=x(1)^2*x(3)^2*x(5)-x(2)*x(7)
==> in[9]=x(1)^2*x(2)*x(3)^4*x(4)*x(5)+x(1)^2*x(2)^4*x(3)*x(4)*x(6)-x(1)^5*x(\
   2)*x(3)*x(5)*x(6)-2*x(2)^2*x(3)^2*x(4)*x(7)+x(1)*x(7)^2

D.6.2.2 derivate
................
Procedure from library ainvar.lib (see ainvar_lib).

Usage:
derivate(m,id); m matrix, id poly/vector/ideal

Assume:
m is a nx1 matrix, where n = number of variables of the basering

Return:
poly/vector/ideal (same type as input), result of applying the
vector field by the matrix m componentwise to id;

Note:
the vector field is m[1,1]*d/dx(1) +...+ m[1,n]*d/dx(n)

Example:
LIB "ainvar.lib";
ring q=0,(x,y,z,u,v,w),dp;
poly f=2xz-y2;
matrix m[6][1] =x,y,0,u,v;
derivate(m,f);
==> -2y2+2xz
vector v = [2xz-y2,u6-3];
derivate(m,v);
==> 6u6*gen(2)-2y2*gen(1)+2xz*gen(1)
derivate(m,ideal(2xz-y2,u6-3));
==> _[1]=-2y2+2xz
==> _[2]=6u6

D.6.2.3 actionIsProper
......................
Procedure from library ainvar.lib (see ainvar_lib).

Usage:
actionIsProper(m); m matrix

Assume:
m is a nx1 matrix, where n = number of variables of the basering

Return:
int = 1, if the action defined by m is proper, 0 if not

Note:
m defines a group action which is the exponential of the vector
field m[1,1]*d/dx(1) +...+ m[1,n]*d/dx(n)

Example:
LIB "ainvar.lib";
ring rf=0,x(1..7),dp;
matrix m[7][1];
m[4,1]=x(1)^3;
m[5,1]=x(2)^3;
m[6,1]=x(3)^3;
m[7,1]=(x(1)*x(2)*x(3))^2;
actionIsProper(m);
==> 0
ring rd=0,x(1..5),dp;
matrix m[5][1];
m[3,1]=x(1);
m[4,1]=x(2);
m[5,1]=1+x(1)*x(4)^2;
actionIsProper(m);
==> 1

D.6.2.4 reduction
.................
Procedure from library ainvar.lib (see ainvar_lib).

Usage:
reduction(p,I[,q,n]); p poly, I ideal, [q monomial, n int (optional)]

Return:
a polynomial equal to p-H(f1,...,fr), in case the leading
term LT(p) of p is of the form H(LT(f1),...,LT(fr)) for some
polynomial H in r variables over the base field, I=f1,...,fr;
if q is given, a maximal power a is computed such that q^a divides
p-H(f1,...,fr), and then (p-H(f1,...,fr))/q^a is returned;
return p if no H is found

if n=1, a different algorithm is chosen which is sometimes faster
(default: n=0; q and n can be given (or not) in any order)

Note:
this is a kind of SAGBI reduction in the subalgebra K[f1,...,fr] of
the basering

Example:
LIB "ainvar.lib";
ring q=0,(x,y,z,u,v,w),dp;
poly p=x2yz-x2v;
ideal dom =x-w,u2w+1,yz-v;
reduction(p,dom);
==> 2xyzw-yzw2-2xvw+vw2
reduction(p,dom,w);
==> 2xyz-yzw-2xv+vw

D.6.2.5 completeReduction
.........................
Procedure from library ainvar.lib (see ainvar_lib).

Usage:
completeReduction(p,I[,q,n]); p poly, I ideal, [q monomial, n int]

Return:
a polynomial, the SAGBI reduction of the polynomial p with I
via the procedure 'reduction' as long as possible

if n=1, a different algorithm is chosen which is sometimes faster
(default: n=0; q and n can be given (or not) in any order)

Note:
help reduction; shows an explanation of SAGBI reduction

Example:
LIB "ainvar.lib";
ring q=0,(x,y,z,u,v,w),dp;
poly p=x2yz-x2v;
ideal dom =x-w,u2w+1,yz-v;
completeReduction(p,dom);
==> 2xyzw-yzw2-2xvw+vw2
completeReduction(p,dom,w);
==> 0

D.6.2.6 localInvar
..................
Procedure from library ainvar.lib (see ainvar_lib).

Usage:
localInvar(m,p,q,h); m matrix, p,q,h polynomials

Assume:
m(q) and h are invariant under the vector field m, i.e. m(m(q))=m(h)=0
h must be a ring variable

Return:
a polynomial, the invariant polynomial of the vector field
         m = m[1,1]*d/dx(1) +...+ m[n,1]*d/dx(n)
with respect to p,q,h. It is defined as follows: set inv = p if p is
invariant, and else as

inv = m(q)^N * sum_i=1..N-1{ (-1)^i*(1/i!)*m^i(p)*(q/m(q))^i }
where m^N(p) = 0, m^(N-1)(p) != 0;

the result is inv divided by h as much as possible

Example:
LIB "ainvar.lib";
ring q=0,(x,y,z),dp;
matrix m[3][1];
m[2,1]=x;
m[3,1]=y;
poly in=localInvar(m,z,y,x);
in;
==> -1/2y2+xz

D.6.2.7 furtherInvar
....................
Procedure from library ainvar.lib (see ainvar_lib).

Usage:
furtherInvar(m,id,karl,q); m matrix, id,karl ideals, q poly, n int

Assume:
karl,id,q are invariant under the vector field m,

moreover, q must be a variable

Return:
list of two ideals, the first ideal contains further invariants of
the vector field
         m = sum m[i,1]*d/dx(i) with respect to id,p,q,
i.e. we compute elements in the (invariant) subring generated by id
which are divisible by q and divide them by q as much as possible
the second ideal contains all invariants given before
if n=1, a different algorithm is chosen which is sometimes faster
(default: n=0)

Example:
LIB "ainvar.lib";
ring r=0,(x,y,z,u),dp;
matrix m[4][1];
m[2,1]=x;
m[3,1]=y;
m[4,1]=z;
ideal id=localInvar(m,z,y,x),localInvar(m,u,y,x);
ideal karl=id,x;
list in=furtherInvar(m,id,karl,x);
in;
==> [1]:
==>    _[1]=y2z2-8/3xz3-2y3u+6xyzu-3x2u2
==> [2]:
==>    _[1]=-1/2y2+xz
==>    _[2]=1/3y3-xyz+x2u
==>    _[3]=x

D.6.2.8 sortier
...............
Procedure from library ainvar.lib (see ainvar_lib).

Usage:
sortier(id); id ideal/module

Return:
the same ideal/module but with generators ordered by there
leading term, starting with the smallest

Example:
LIB "ainvar.lib";
ring q=0,(x,y,z,u,v,w),dp;
ideal i=w,x,z,y,v;
sortier(i);
==> _[1]=w
==> _[2]=v
==> _[3]=z
==> _[4]=y
==> _[5]=x
D.6.3 rinvar_lib
----------------
Library:
rinvar.lib
Purpose:
      Invariant Rings of Reductive Groups
Author:
Thomas Bayer, tbayer@in.tum.de

http://wwwmayr.informatik.tu-muenchen.de/personen/bayert/
Current Adress: Institut fuer Informatik, TU Muenchen

Overview:
Implementation based on Derksen's algorithm. Written in the frame of the
diploma thesis (advisor: Prof. Gert-Martin Greuel) 'Computations of moduli
spaces of semiquasihomogeneous singularities and an implementation in Singular'


Procedures:
* HilbertSeries:: Hilbert series of the ideal I w.r.t. weight w
* HilbertWeights:: weighted degrees of the generators of I
* ImageVariety:: ideal of the image variety F(variety(I))
* ImageGroup:: ideal of G w.r.t. the induced representation
* InvariantRing:: generators of the invariant ring of G
* InvariantQ:: decide if f is invariant w.r.t. G
* LinearizeAction:: linearization of the action 'Gaction' of G
* LinearActionQ:: decide if action is linear in var(s..nvars)
* LinearCombinationQ:: decide if f is in the linear hull of 'base'
* MinimalDecomposition:: minimal decomposition of f (like coef)
* NullCone:: ideal of the null cone of the action 'act' of G
* ReynoldsImage:: image of f under the Reynolds operator 'RO'
* ReynoldsOperator:: Reynolds operator of the group G
* SimplifyIdeal:: simplify the ideal I (try to reduce variables)
* TransferIdeal:: transfer the ideal 'name' from R to basering


D.6.3.1 HilbertSeries
.....................
Procedure from library rinvar.lib (see rinvar_lib).

Usage:
HilbertSeries(I, w); ideal I, intvec wt

Purpose:
compute the polynomial p of the Hilbert Series,represented by p/q, of
the ring K[t_1,...,t_m,y_1,...,y_r]/I1 where 'w' are the weights of
the variables, computed, e.g., by 'HilbertWeights', 'I1' is of the
form I[1] - y_1,...,I[r] - y_r and is quasihomogeneous w.r.t. 'w'

Return:
intvec

Note:
the leading 0 of the result does not belong to p, but is needed in
the hilbert-driven 'std'.


D.6.3.2 HilbertWeights
......................
Procedure from library rinvar.lib (see rinvar_lib).

Purpose:
compute the weights of the "slack" variables needed for the
computation of the algebraic relations of the generators of 'I' s.t.
the Hilbert driven 'std' can be used.

Return:
intvec

Assume:
basering = K[t_1,...,t_m,...], 'I' is quasihomogeneous w.r.t. 'w' and
contains only polynomials in t_1,...,t_m


D.6.3.3 ImageVariety
....................
Procedure from library rinvar.lib (see rinvar_lib).

Usage:
ImageVariety(ideal I, F [, w]);ideal I; F is a list/ideal, intvec w.

Purpose:
compute the Zariski closure of the image of the variety of I under
the morphism F.

Note:
if 'I' and 'F' are quasihomogeneous w.r.t. 'w' then the Hilbert-driven
'std' is used.

Return:
polynomial ring over the same ground field, containing the ideal
'imageid'. The variables are Y(1),...,Y(k) where k = size(F)
- 'imageid' is the ideal of the Zariski closure of F(X) where
X is the variety of I.

Example:
LIB "rinvar.lib";
ring B   = 0,(x,y),dp;
ideal I  = x4 - y4;
ideal F  = x2, y2, x*y;
def R = ImageVariety(I, F);
setring R;
imageid;
==> imageid[1]=Y(1)*Y(2)-Y(3)^2
==> imageid[2]=Y(1)^2-Y(2)^2
==> imageid[3]=Y(2)^3-Y(1)*Y(3)^2

D.6.3.4 ImageGroup
..................
Procedure from library rinvar.lib (see rinvar_lib).

Usage:
ImageGroup(G, action); ideal G, action;

Purpose:
compute the ideal of the image of G in GL(m,K) induced by the linear
action 'action', where G is an algebraic group and 'action' defines
an action of G on K^m (size(action) = m).

Return:
ring, a polynomial ring over the same ground field as the basering,
containing the ideals 'groupid' and 'actionid'.

- 'groupid' is the ideal of the image of G (order <= order of G)
- 'actionid' defines the linear action of 'groupid' on K^m.

Note:
'action' and 'actionid' have the same orbits

all variables which give only rise to 0's in the m x m matrices of G
have been omitted.

Assume:
basering K[s(1..r),t(1..m)] has r + m variables, G is the ideal of an
algebraic group and F is an action of G on K^m. G contains only the
variables s(1)...s(r). The action 'action' is given by polynomials
f_1,...,f_m in basering, s.t. on the ring level we have
K[t_1,...,t_m] -> K[s_1,...,s_r,t_1,...,t_m]/G

t_i -> f_i(s_1,...,s_r,t_1,...,t_m)

Example:
LIB "rinvar.lib";
ring B   = 0,(s(1..2), t(1..2)),dp;
ideal G = s(1)^3-1, s(2)^10-1;
ideal action = s(1)*s(2)^8*t(1), s(1)*s(2)^7*t(2);
def R = ImageGroup(G, action);
setring R;
groupid;
==> groupid[1]=-s(1)+s(2)^4
==> groupid[2]=s(1)^8-s(2)^2
==> groupid[3]=s(1)^7*s(2)^2-1
actionid;
==> actionid[1]=s(1)*t(1)
==> actionid[2]=s(2)*t(2)

D.6.3.5 InvariantRing
.....................
Procedure from library rinvar.lib (see rinvar_lib).

Usage:
InvariantRing(G, Gact [, opt]); ideal G, Gact; int opt

Purpose:
compute generators of the invariant ring of G w.r.t. the action 'Gact'

Assume:
G is a finite group and 'Gact' is a linear action.

Return:
polynomial ring over a simple extension of the ground field of the
basering (the extension might be trivial), containing the ideals
'invars' and 'groupid' and the poly 'newA'

- 'invars' contains the algebra-generators of the invariant ring
- 'groupid' is the ideal of G in the new ring

- 'newA' if the minpoly changes this is the new representation of the
algebraic number, otherwise it is set to 'a'.

Note:
the delivered ring might have a different minimal polynomial

Example:
LIB "rinvar.lib";
ring B = 0, (s(1..2), t(1..2)), dp;
ideal G = -s(1)+s(2)^3, s(1)^4-1;
ideal action = s(1)*t(1), s(2)*t(2);
def R = InvariantRing(std(G), action);
setring R;
invars;
==> invars[1]=t(1)^4
==> invars[2]=t(1)^3*t(2)^3
==> invars[3]=t(1)^2*t(2)^6
==> invars[4]=t(1)*t(2)^9
==> invars[5]=t(2)^12

D.6.3.6 InvariantQ
..................
Procedure from library rinvar.lib (see rinvar_lib).

Usage:
InvariantQ(f, G, action); poly f; ideal G, action

Purpose:
check if the polynomial f is invariant w.r.t. G where G acts via
'action' on K^m.

Assume:
basering = K[s_1,...,s_m,t_1,...,t_m] where K = Q of K = Q(a) and
minpoly != 0, f contains only t_1,...,t_m, G is the ideal of an
algebraic group and a standard basis.

Return:
int;

0 if f is not invariant,

1 if f is invariant

Note:
G need not be finite


D.6.3.7 LinearizeAction
.......................
Procedure from library rinvar.lib (see rinvar_lib).

Usage:
LinearizeAction(G,action,r); ideal G, action; int r

Purpose:
linearize the group action 'action' and find an equivariant embedding
of K^m where m = size(action).

Assume:
G contains only variables var(1..r) (r = nrs)

basering = K[s(1..r),t(1..m)], K = Q or K = Q(a) and minpoly != 0.

Return:
polynomial ring containing the ideals 'actionid', 'embedid', 'groupid'
- 'actionid' is the ideal defining the linearized action of G
- 'embedid' is a parameterization of an equivariant embedding (closed)
- 'groupid' is the ideal of G in the new ring

Note:
set printlevel > 0 to see a trace

Example:
LIB "rinvar.lib";
ring B   = 0,(s(1..5), t(1..3)),dp;
ideal G =  s(3)-s(4), s(2)-s(5), s(4)*s(5), s(1)^2*s(4)+s(1)^2*s(5)-1, s(1)^2*s(5)^2-s(5), s(4)^4-s(5)^4+s(1)^2, s(1)^4+s(4)^3-s(5)^3, s(5)^5-s(1)^2*s(5);
ideal action = -s(4)*t(1)+s(5)*t(1), -s(4)^2*t(2)+2*s(4)^2*t(3)^2+s(5)^2*t(2), s(4)*t(3)+s(5)*t(3);
LinearActionQ(action, 5);
==> 0
def R = LinearizeAction(G, action, 5);
setring R;
R;
==> //   characteristic : 0
==> //   number of vars : 9
==> //        block   1 : ordering dp
==> //                  : names    s(1) s(2) s(3) s(4) s(5) t(1) t(2) t(3) t(\
   4) 
==> //        block   2 : ordering C
actionid;
==> actionid[1]=-s(4)*t(1)+s(5)*t(1)
==> actionid[2]=-s(4)^2*t(2)+s(5)^2*t(2)+2*s(4)^2*t(4)
==> actionid[3]=s(4)*t(3)+s(5)*t(3)
==> actionid[4]=s(4)^2*t(4)+s(5)^2*t(4)
embedid;
==> embedid[1]=t(1)
==> embedid[2]=t(2)
==> embedid[3]=t(3)
==> embedid[4]=t(3)^2
groupid;
==> groupid[1]=s(3)-s(4)
==> groupid[2]=s(2)-s(5)
==> groupid[3]=s(4)*s(5)
==> groupid[4]=s(1)^2*s(4)+s(1)^2*s(5)-1
==> groupid[5]=s(1)^2*s(5)^2-s(5)
==> groupid[6]=s(4)^4-s(5)^4+s(1)^2
==> groupid[7]=s(1)^4+s(4)^3-s(5)^3
==> groupid[8]=s(5)^5-s(1)^2*s(5)
LinearActionQ(actionid, 5);
==> 1

D.6.3.8 LinearActionQ
.....................
Procedure from library rinvar.lib (see rinvar_lib).

Usage:
LinearActionQ(action,nrs,nrt); ideal action, int nrs

Purpose:
check if the action defined by 'action' is linear w.r.t. the variables
var(nrs + 1...nvars(basering)).

Return:
0 action not linear

1 action is linear

Example:
LIB "rinvar.lib";
ring R   = 0,(s(1..5), t(1..3)),dp;
ideal G =  s(3)-s(4), s(2)-s(5), s(4)*s(5), s(1)^2*s(4)+s(1)^2*s(5)-1, s(1)^2*s(5)^2-s(5), s(4)^4-s(5)^4+s(1)^2, s(1)^4+s(4)^3-s(5)^3, s(5)^5-s(1)^2*s(5);
ideal Gaction = -s(4)*t(1)+s(5)*t(1), -s(4)^2*t(2)+2*s(4)^2*t(3)^2+s(5)^2*t(2), s(4)*t(3)+s(5)*t(3);
LinearActionQ(Gaction, 5, 3);
==> // ** too many arguments for LinearActionQ
==> 0

D.6.3.9 LinearCombinationQ
..........................
Procedure from library rinvar.lib (see rinvar_lib).

Usage:
LinearCombination(I, f); ideal I, poly f

Purpose:
test if f can be written as a linear combination of the generators of I.

Return:
0 f is not a linear combination

1 f is a linear combination


D.6.3.10 MinimalDecomposition
.............................
Procedure from library rinvar.lib (see rinvar_lib).

Usage:
MinimalDecomposition(f,a,b); poly f; int a, b.

Purpose:
decompose f as a sum M[1,1]*M[2,1] + ... + M[1,r]*M[2,r] where M[1,i]
contains only s(1..a), M[2,i] contains only t(1...b) s.t. r is minimal

Assume:
f polynomial in K[s(1..a),t(1..b)], K = Q or K = Q(a) and minpoly != 0

Return:
2 x r matrix M s.t. f = M[1,1]*M[2,1] + ... + M[1,r]*M[2,r]

Example:
LIB "rinvar.lib";
ring R = 0, (s(1..2), t(1..2)), dp;
poly h = s(1)*(t(1) + t(1)^2) +  (t(2) + t(2)^2)*(s(1)^2 + s(2));
matrix M = MinimalDecomposition(h, 2, 2);
M;
==> M[1,1]=s(1)^2+s(2)
==> M[1,2]=s(1)
==> M[2,1]=t(2)^2+t(2)
==> M[2,2]=t(1)^2+t(1)
M[1,1]*M[2,1] + M[1,2]*M[2,2] - h;
==> 0

D.6.3.11 NullCone
.................
Procedure from library rinvar.lib (see rinvar_lib).

Usage:
NullCone(G, action); ideal G, action

Purpose:
compute the ideal of the null cone of the linear action of G on K^n,
given by 'action', by means of Derksen's algorithm

Assume:
basering = K[s(1..r),t(1..n)], K = Q or K = Q(a) and minpoly != 0,
G is an ideal of a reductive algebraic group in K[s(1..r)],
'action' is a linear group action of G on K^n (n = ncols(action))

Return:
ideal of the null cone of G.

Note:
the generators of the null cone are homogeneous, but i.g. not invariant

Example:
LIB "rinvar.lib";
ring R = 0, (s(1..2), x, y), dp;
ideal G = -s(1)+s(2)^3, s(1)^4-1;
ideal action = s(1)*x, s(2)*y;
ideal inv = NullCone(G, action);
inv;
==> inv[1]=x^4
==> inv[2]=x^3*y^3
==> inv[3]=x^2*y^6
==> inv[4]=x*y^9
==> inv[5]=y^12

D.6.3.12 ReynoldsImage
......................
Procedure from library rinvar.lib (see rinvar_lib).

Usage:
ReynoldsImage(RO, f); list RO, poly f

Purpose:
compute the Reynolds image of the polynomial f where RO represents
the Reynolds operator

Return:
poly


D.6.3.13 ReynoldsOperator
.........................
Procedure from library rinvar.lib (see rinvar_lib).

Usage:
ReynoldsOperator(G, action [, opt); ideal G, action; int opt

Purpose:
compute the Reynolds operator of the group G which act via 'action'

Return:
polynomial ring R over a simple extension of the ground field of the
basering (the extension might be trivial), containing a list
'ROelements', the ideals 'id', 'actionid' and the polynomial 'newA'.
R = K(a)[s(1..r),t(1..n)].

- 'ROelements' is a list of ideal, each ideal represents a
substitution map F : R -> R according to the zero-set of G
- 'id' is the ideal of G in the new ring

- 'newA' is the new representation of a' in terms of a. If the
basering does not contain a parameter then 'newA' = 'a'.

Assume:
basering = K[s(1..r),t(1..n)], K = Q or K = Q(a') and minpoly != 0,
G is the ideal of a finite group in K[s(1..r)], 'action' is a linear
group action of G


D.6.3.14 SimplifyIdeal
......................
Procedure from library rinvar.lib (see rinvar_lib).

Purpose:
simplify ideal I to the ideal I', do not change the names of the
first m variables, new ideal I' might contain less variables.
I' contains variables var(1..m)

Return:
list

_[1] ideal I'

_[2] ideal representing a map phi to a ring with probably less vars. s.t.
phi(I) = I'

_[3] list of variables

_[4] list from 'elimpart'


D.6.3.15 TransferIdeal
......................
Procedure from library rinvar.lib (see rinvar_lib).

D.6.4 stratify_lib
------------------
Library:
stratify.lib
Purpose:
   Algorithmic Stratification for Unipotent Group-Actions
Author:
Anne Fruehbis-Krueger, anne@mathematik.uni-kl.de

Overview:
This library provides an implementation of the algorithm
of Greuel and Pfister introduced in the article <Geometric
quotients of unipotent group actions>.


Procedures:
* prepMat:: list of submatrices corresp. to given filtration
* stratify:: algorithmic stratification (main procedure)

D.6.4.1 prepMat
...............
Procedure from library stratify.lib (see stratify_lib).

Usage:
prepMat(M,wr,ws,step);

where M is a matrix, wr is an intvec of size ncols(M),
ws an intvec of size nrows(M) and step is an integer

Return:
2 lists of submatrices corresponding to the filtrations
specified by wr and ws

the first list corresponds to the list for the filtration
of AdA, i.e. the ranks of these matrices will be the r_i,
the second one to the list for the filtration of L, i.e.
the ranks of these matrices will be the s_i

Note:
* the entries of the matrix M are M_ij=delta_i(x_j),

* wr is used to determine what subset of the set of all dx_i is
generating AdF^l(A):

if (k-1)*step <= wr[i] < k*step, then dx_i is in the set of
generators of AdF^l(A) for all l>=k and the i-th column
of M appears in each submatrix starting from the k-th

* ws is used to determine what subset of the set of all delta_i
is generating Z_l(L):

if (k-1)*step <= ws[i] < k*step, then delta_i is in the set
of generators of Z_l(A) for l < k and the i-th row of M
appears in each submatrix up to the (k-1)th

* the entries of wr and ws as well as step should be positive
integers

Example:
LIB "stratify.lib";
ring r=0,(t(1..3)),dp;
matrix M[2][3]=0,t(1),3*t(2),0,0,t(1);
print(M);
==> 0,t(1),3*t(2),
==> 0,0,   t(1)   
intvec wr=1,3,5;
intvec ws=2,4;
int step=2;
prepMat(M,wr,ws,step);
==> [1]:
==>    [1]:
==>       _[1,1]=0
==>       _[2,1]=0
==>    [2]:
==>       _[1,1]=0
==>       _[1,2]=t(1)
==>       _[2,1]=0
==>       _[2,2]=0
==>    [3]:
==>       _[1,1]=0
==>       _[1,2]=t(1)
==>       _[1,3]=3*t(2)
==>       _[2,1]=0
==>       _[2,2]=0
==>       _[2,3]=t(1)
==> [2]:
==>    [1]:
==>       _[1,1]=0
==>       _[1,2]=t(1)
==>       _[1,3]=3*t(2)
==>       _[2,1]=0
==>       _[2,2]=0
==>       _[2,3]=t(1)
==>    [2]:
==>       _[1,1]=0
==>       _[1,2]=0
==>       _[1,3]=t(1)

D.6.4.2 stratify
................
Procedure from library stratify.lib (see stratify_lib).

Usage:
stratify(M,wr,ws,step);

where M is a matrix, wr is an intvec of size ncols(M),
ws an intvec of size nrows(M) and step is an integer

Return:
list of lists, each entry of the big list corresponds to one
locally closed set and has the following entries:

1) intvec giving the corresponding rs-vector

2) ideal determining the closed set

3) list d of polynomials determining the open set D(d[1])
empty list if there is more than one open set

4-n) lists of polynomials determining open sets which all lead
to the same rs-vector

Note:
* ring ordering should be global, i.e. the ring should be a
polynomial ring

* the entries of the matrix M are M_ij=delta_i(x_j),

* wr is used to determine what subset of the set of all dx_i is
generating AdF^l(A):

if (k-1)*step < wr[i] <= k*step, then dx_i is in the set of
generators of AdF^l(A) for all l>=k

* ws is used to determine what subset of the set of all delta_i
is generating Z_l(L):

if (k-1)*step <= ws[i] < k*step, then delta_i is in the set
of generators of Z_l(A) for l < k

* the entries of wr and ws as well as step should be positive
integers

* the filtrations have to be known, no sanity checks concerning
the filtrations are performed !!!

Example:
LIB "stratify.lib";
ring r=0,(t(1..3)),dp;
matrix M[2][3]=0,t(1),3*t(2),0,0,t(1);
intvec wr=1,3,5;
intvec ws=2,4;
int step=2;
stratify(M,wr,ws,step);
==> [1]:
==>    [1]:
==>       0,0,0,0
==>    [2]:
==>       _[1]=t(2)
==>       _[2]=t(1)
==>    [3]:
==>       [1]:
==>          1
==> [2]:
==>    [1]:
==>       0,1,0,1
==>    [2]:
==>       _[1]=t(1)
==>    [3]:
==>       [1]:
==>          t(2)
==>       [2]:
==>          t(2)
==> [3]:
==>    [1]:
==>       1,2,1,2
==>    [2]:
==>       _[1]=0
==>    [3]:
==>       [1]:
==>          t(1)
==>       [2]:
==>          t(1)
D.7 Symbolic-numerical solving
==============================

* presolve_lib:: procedures for pre-solving polynomial equations
* solve_lib:: procedures to solve polynomial systems
* triang_lib:: procedures for decomposing zero-dimensional ideals
* ntsolve_lib:: one real solution of polynomial systems (Newton iteration)
* zeroset_lib:: procedures for roots and factorization

D.7.1 presolve_lib
------------------
Library:
presolve.lib
Purpose:
     Pre-Solving of Polynomial Equations
Author:
Gert-Martin Greuel, email: greuel@mathematik.uni-kl.de,


Procedures:
* degreepart:: elements of id of total degree >= d1 and <= d2
* elimlinearpart:: linear part eliminated from id
* elimpart:: partial elimination of vars [among first n vars]
* elimpartanyr:: factors of p partially eliminated from i in any ring
* fastelim:: fast elimination of factors of p from i [options]
* findvars:: ideal of variables occurring in id [more information]
* hilbvec:: intvec of Hilbert-series of id [in char c and ord o]
* linearpart:: elements of id of total degree <=1
* tolessvars:: maps id to new basering having only vars occurring in id
* solvelinearpart:: reduced std-basis of linear part of id
* sortandmap:: map to new basering with vars sorted w.r.t. complexity
* sortvars:: sort vars w.r.t. complexity in id [different blocks]
* shortid:: generators of id having <= n terms
* valvars:: valuation of vars w.r.t. to their complexity in id
* idealSimplify:: eliminates variables which are linear in id
* idealSplit:: intersection of the ideals has the same radical as id

D.7.1.1 degreepart
..................
Procedure from library presolve.lib (see presolve_lib).

Usage:
degreepart(id,d1,d2[,v]); id=ideal/module, d1,d1=integers, v=intvec

Return:
generators of id of [v-weighted] total degree >= d1 and <= d2
(default: v = 1,...,1)

Example:
LIB "presolve.lib";
ring r=0,(x,y,z),dp;
ideal i=1+x+x2+x3+x4,3,xz+y3+z8;
degreepart(i,0,4);
==> _[1]=x4+x3+x2+x+1
==> _[2]=3
module m=[x,y,z],x*[x3,y2,z],[1,x2,z3,0,1];
intvec v=2,3,6;
show(degreepart(m,8,8,v));
==> // module, 1 generator(s)
==> [x4,xy2,xz]

D.7.1.2 elimlinearpart
......................
Procedure from library presolve.lib (see presolve_lib).

Usage:
elimlinearpart(i[,n]); i=ideal, n=integer,

default: n=nvars(basering)

Return:
list L with 5 entries:
    L[1]: (interreduced) ideal obtained from i by substituing
        from the first n variables those, which appear in a linear part
        of i, by putting this part into triangular form
  L[2]: ideal of variables which have been substituted
  L[3]: ideal, j-th element defines substitution of j-th var in [2]
  L[4]: ideal of variables of basering, eliminated ones are set to 0
  L[5]: ideal, describing the map from the basering to itself such that
        L[1] is the image of i
  

Note:
the procedure does always interreduce the ideal i internally w.r.t.
ordering dp.

Example:
LIB "presolve.lib";
ring s=0,(x,y,z),dp;
ideal i = x3+y2+z,x2y2+z3,y+z+1;
elimlinearpart(i);
==> [1]:
==>    _[1]=x3+z2+3z+1
==>    _[2]=x2z2+2x2z+z3+x2
==> [2]:
==>    _[1]=y
==> [3]:
==>    _[1]=y+z+1
==> [4]:
==>    _[1]=x
==>    _[2]=0
==>    _[3]=z
==> [5]:
==>    _[1]=x
==>    _[2]=-z-1
==>    _[3]=z

D.7.1.3 elimpart
................
Procedure from library presolve.lib (see presolve_lib).

Usage:
elimpart(i [,n,e] ); i=ideal, n,e=integers

n : only the first n vars are considered for substitution,

e =0: substitute from linear part of i (same as elimlinearpart)

e!=0: eliminate also by direct substitution

(default: n = nvars(basering), e = 1)

Return:
list of 5 objects:
    [1]: ideal obtained by substituting from the first n variables those
       from i, which appear in the linear part of i (or, if e!=0, which
       can be expressed directly in the remaining vars)
  [2]: ideal, variables which have been substituted
  [3]: ideal, i-th element defines substitution of i-th var in [2]
  [4]: ideal of variables of basering, substituted ones are set to 0
  [5]: ideal, describing the map from the basering, say k[x(1..m)], to
       itself onto k[..variables fom [4]..] and [1] is the image of i
  
The ideal i is generated by [1] and [3] in k[x(1..m)], the map [5]
maps [3] to 0, hence induces an isomorphism
              k[x(1..m)]/i -> k[..variables fom [4]..]/[1]
  

Note:
If the basering has ordering (c,dp), this is faster for big ideals,
since it avoids internal ring change and mapping.

Example:
LIB "presolve.lib";
ring s=0,(x,y,z),dp;
ideal i =x2+y2,x2+y+1;
elimpart(i,3,0);
==> [1]:
==>    _[1]=y2-y-1
==>    _[2]=x2+y+1
==> [2]:
==>    _[1]=0
==> [3]:
==>    _[1]=0
==> [4]:
==>    _[1]=x
==>    _[2]=y
==>    _[3]=z
==> [5]:
==>    _[1]=x
==>    _[2]=y
==>    _[3]=z
elimpart(i,3,1);
==> [1]:
==>    _[1]=x4+3x2+1
==> [2]:
==>    _[1]=y
==> [3]:
==>    _[1]=x2+y+1
==> [4]:
==>    _[1]=x
==>    _[2]=0
==>    _[3]=z
==> [5]:
==>    _[1]=x
==>    _[2]=-x2-1
==>    _[3]=z

D.7.1.4 elimpartanyr
....................
Procedure from library presolve.lib (see presolve_lib).

Usage:
elimpartanyr(i [,p,e] ); i=ideal, p=polynomial, e=integer

p: product of vars to be eliminated,

e =0: substitute from linear part of i (same as elimlinearpart)

e!=0: eliminate also by direct substitution

(default: p=product of all vars, e=1)

Return:
list of 6 objects:
    [1]: (interreduced) ideal obtained by substituting from i those vars
       appearing in p, which occur in the linear part of i (or which can
       be expressed directly in the remaining variables, if e!=0)
  [2]: ideal, variables which have been substituted
  [3]: ideal, i-th element defines substitution of i-th var in [2]
  [4]: ideal of variables of basering, substituted ones are set to 0
  [5]: ideal, describing the map from the basering, say k[x(1..m)], to
       itself onto k[..variables fom [4]..] and [1] is the image of i
  [6]: int, # of vars considered for substitution (= # of factors of p)
  
The ideal i is generated by [1] and [3] in k[x(1..m)], the map [5]
maps [3] to 0, hence induces an isomorphism
              k[x(1..m)]/i -> k[..variables fom [4]..]/[1]
  

Note:
the proc uses execute to create a ring with ordering dp and vars
placed correctly and then applies elimpart.

Example:
LIB "presolve.lib";
ring s=0,(x,y,z),dp;
ideal i = x3+y2+z,x2y2+z3,y+z+1;
elimpartanyr(i,z);
==> [1]:
==>    _[1]=x3+y2-y-1
==>    _[2]=x2y2-y3-3y2-3y-1
==> [2]:
==>    _[1]=z
==> [3]:
==>    _[1]=y+z+1
==> [4]:
==>    _[1]=0
==>    _[2]=x
==>    _[3]=y
==> [5]:
==>    _[1]=-y-1
==>    _[2]=x
==>    _[3]=y
==> [6]:
==>    1

D.7.1.5 fastelim
................
Procedure from library presolve.lib (see presolve_lib).

Usage:
fastelim(i,p[h,o,a,b,e,m]); i=ideal, p=polynomial; h,o,a,b,e=integers
p: product of variables to be eliminated;

Optional parameters:
    - h !=0: use Hilbert-series driven std-basis computation
  - o !=0: use proc valvars for a - hopefully - optimal ordering of vars
  - a !=0: order vars to be eliminated w.r.t. increasing complexity
  - b !=0: order vars not to be eliminated w.r.t. increasing complexity
  - e !=0: use elimpart first to eliminate easy part
  - m !=0: compute a minimal system of generators
  
(default: h,o,a,b,e,m = 0,1,0,0,0,0)

Return:
ideal obtained from i by eliminating those variables, which occur in p

Example:
LIB "presolve.lib";
ring s=31991,(e,f,x,y,z,t,u,v,w,a,b,c,d),dp;
ideal i = w2+f2-1, x2+t2+a2-1,  y2+u2+b2-1, z2+v2+c2-1,
d2+e2-1, f4+2u, wa+tf, xy+tu+ab;
fastelim(i,xytua,1,1);       //with hilb,valvars
==> _[1]=f2+w2-1
==> _[2]=z2+v2+c2-1
==> _[3]=e2+d2-1
fastelim(i,xytua,1,0,1);     //with hilb,minbase
==> _[1]=z2+v2+c2-1
==> _[2]=f2+w2-1
==> _[3]=e2+d2-1

D.7.1.6 findvars
................
Procedure from library presolve.lib (see presolve_lib).

Usage:
findvars(id [,any] ); id=poly/ideal/vector/module/matrix, any=any type

Return:
if no second argument is present: ideal of variables occurring in id,

if a second argument is given (of any type): list L with 4 entries:
    L[1]: ideal of variables occurring in id
  L[2]: intvec of variables occurring in id
  L[3]: ideal of variables not occurring in id
  L[4]: intvec of variables not occurring in id
  

Example:
LIB "presolve.lib";
ring s  = 0,(e,f,x,y,t,u,v,w,a,d),dp;
ideal i = w2+f2-1, x2+t2+a2-1;
findvars(i);
==> _[1]=f
==> _[2]=x
==> _[3]=t
==> _[4]=w
==> _[5]=a
findvars(i,1);
==> [1]:
==>    _[1]=f
==>    _[2]=x
==>    _[3]=t
==>    _[4]=w
==>    _[5]=a
==> [2]:
==>    2,3,5,8,9
==> [3]:
==>    _[1]=e
==>    _[2]=y
==>    _[3]=u
==>    _[4]=v
==>    _[5]=d
==> [4]:
==>    1,4,6,7,10

D.7.1.7 hilbvec
...............
Procedure from library presolve.lib (see presolve_lib).

Usage:
hilbvec(id[,c,o]); id=poly/ideal/vector/module/matrix, c,o=strings,

c=char, o=ordering used by hilb

(default: c="32003", o="dp")

Return:
intvec of 1-st Hilbert-series of id, computed in char c and ordering o

Note:
id must be homogeneous (i.e. all vars have weight 1)

Example:
LIB "presolve.lib";
ring s   = 0,(e,f,x,y,z,t,u,v,w,a,b,c,d,H),dp;
ideal id = w2+f2-1, x2+t2+a2-1,  y2+u2+b2-1, z2+v2+c2-1,
d2+e2-1, f4+2u, wa+tf, xy+tu+ab;
id = homog(id,H);
hilbvec(id);
==> 1,0,-7,0,20,0,-28,0,14,0,14,0,-28,0,20,0,-7,0,1,0

D.7.1.8 linearpart
..................
Procedure from library presolve.lib (see presolve_lib).

Usage:
linearpart(id); id=ideal/module

Return:
generators of id of total degree <= 1

Example:
LIB "presolve.lib";
ring r=0,(x,y,z),dp;
ideal i=1+x+x2+x3,3,x+3y+5z;
linearpart(i);
==> _[1]=3
==> _[2]=x+3y+5z
module m=[x,y,z],x*[x3,y2,z],[1,x2,z3,0,1];
show(linearpart(m));
==> // module, 1 generator(s)
==> [x,y,z]

D.7.1.9 tolessvars
..................
Procedure from library presolve.lib (see presolve_lib).

Usage:
tolessvars(id [,s1,s2] ); id poly/ideal/vector/module/matrix,
s1,s2=strings

s1: name of new ring,

s2: new ordering

(default: s1="R(n)" where n is the # of vars in the new ring,
s2="dp" or "ds" depending whether the first block of the old
ordering is a p- resp. an s-ordering)

Create:
nothing, if id contains all vars of the basering.

Else, create a ring with same char as the basering, but possibly less
variables (only those variables which actually occur in id) and map
id to the new ring, which will be the basering after the proc has
finished.

Display:
If printlevel >=0, display ideal of vars, which have been omitted from
the old ring

Return:
the original ideal id (see NOTE)

Note:
You must not type, say, 'ideal id=tolessvars(id);' since the ring
to which 'id' would belong will only be defined by the r.h.s.. But you
may type 'def id=tolessvars(id);' or 'list id=tolessvars(id);'
since then 'id' does not a priory belong to a ring, its type will
be defined by the right hand side. Moreover, do not use a name which
occurs in the old ring, for the same reason.

Example:
LIB "presolve.lib";
ring r  = 0,(x,y,z),dp;
ideal i = y2-x3,x-3,y-2x;
def j   = tolessvars(i,"R_r","lp");
==> 
==> // variables which did not occur:
==> z
==> // basering is now R_r
show(basering);
==> // ring: (0),(x,y),(lp(2),C);
==> // minpoly = 0
==> // objects belonging to this ring:
==> // j                    [0]  ideal, 3 generator(s)
j;
==> j[1]=-x3+y2
==> j[2]=x-3
==> j[3]=-2x+y
kill R_r;

D.7.1.10 solvelinearpart
........................
Procedure from library presolve.lib (see presolve_lib).

Usage:
solvelinearpart(id [,n] ); id=ideal/module, n=integer,

(default: n=0)

Return:
(interreduced) generators of id of degree <=1 in reduced triangular
form if n=0 [non-reduced triangular form if n!=0]

Assume:
monomial ordering is a global ordering (p-ordering)

Note:
may be used to solve a system of linear equations
see proc gauss_row from 'matrix.lib' for a different method

Warning:
the result is very likely to be false for 'real' coefficients, use
char 0 instead!

Example:
LIB "presolve.lib";
// Solve the system of linear equations:
//         3x +   y +  z -  u = 2
//         3x +  8y + 6z - 7u = 1
//        14x + 10y + 6z - 7u = 0
//         7x +  4y + 3z - 3u = 3
ring r = 0,(x,y,z,u),lp;
ideal i= 3x +   y +  z -  u,
13x +  8y + 6z - 7u,
14x + 10y + 6z - 7u,
7x +  4y + 3z - 3u;
ideal j= 2,1,0,3;
j = i-j;                        // difference of 1x4 matrices
// compute reduced triangular form, setting
solvelinearpart(j);             // the RHS equal 0 gives the solutions!
==> _[1]=u-4
==> _[2]=z-4
==> _[3]=y+1
==> _[4]=x-1
solvelinearpart(j,1); "";       // triangular form, not reduced
==> _[1]=u-4
==> _[2]=3z-8u+20
==> _[3]=18y-6z+7u+14
==> _[4]=13x+8y+6z-7u-1
==> 

D.7.1.11 sortandmap
...................
Procedure from library presolve.lib (see presolve_lib).

Usage:
sortandmap(id,s1,s2[,n1,p1,n2,p2...,o1,m1,o2,m2...]);

id=poly/ideal/vector/module,

s1,s2 = strings (names for new ring and mapped id),

p1,p2,...= polynomials (product of variables),

n1,n2,...= integers,

o1,o2,...= strings,

m1,m2,...= integers

(default: p1=product of all vars, n1=0, o1="dp",m1=0)

the last pi (containing the remaining vars) may be omitted

Create:
a new ring and map id into it, the new ring has same char as basering
but with new ordering and vars sorted in the following manner:
    - each block of vars occurring in pi is sorted w.r.t. its complexity in id,
  - ni controls the sorting in i-th block (= vars occurring in pi):
    ni=0 (resp.!=0) means that less (resp. more) complex vars come first
  - oi and mi define the monomial ordering of the i-th block:
    if mi =0, oi=ordstr(i-th block)
    if mi!=0, the ordering of the i-th block itself is a blockordering,
      each subblock having ordstr=oi, such that vars of same complexity are
      in one block
  
Note that only simple ordstrings oi are allowed:

"lp","dp","Dp","ls","ds","Ds".

Return:
nothing

Note:
We define a variable x to be more complex than y (with respect to id)
if val(x) > val(y) lexicographically, where val(x) denotes the
valuation vector of x:

consider id as list of polynomials in x with coefficients in the
remaining variables. Then:

val(x) = (maximal occurring power of x, # of all monomials in leading
coefficient, # of all monomials in coefficient of next smaller power
of x,...).

Example:
LIB "presolve.lib";
ring s = 32003,(x,y,z),dp;
ideal i=x3+y2,xz+z2;
sortandmap(i,"R_r","i");
// i is now an ideal in the new basering R_r
show(R_r);
==> // ring: (32003),(y,z,x),(dp(3),C);
==> // minpoly = 0
==> // objects belonging to this ring:
==> // i                    [0]  ideal, 2 generator(s)
kill R_r; setring s;
sortandmap(i,"R_r","i",1,xy,0,z,0,"ds",0,"lp",0);
show(R_r);
==> // ring: (32003),(x,y,z),(ds(2),lp(1),C);
==> // minpoly = 0
==> // objects belonging to this ring:
==> // i                    [0]  ideal, 2 generator(s)
kill R_r;

D.7.1.12 sortvars
.................
Procedure from library presolve.lib (see presolve_lib).

Usage:
sortvars(id[,n1,p1,n2,p2,...]);

id=poly/ideal/vector/module,

p1,p2,...= polynomials (product of vars),

n1,n2,...=integers

(default: p1=product of all vars, n1=0)

the last pi (containing the remaining vars) may be omitted

Compute:
sort variables with respect to their complexity in id

Return:
list of two elements, an ideal and a list:
    [1]: ideal, variables of basering sorted w.r.t their complexity in id
       ni controls the ordering in i-th block (= vars occurring in pi):
       ni=0 (resp.!=0) means that less (resp. more) complex vars come first
  [2]: a list with 4 entries for each pi:
       ideal ai : vars of pi in correct order,
       intvec vi: permutation vector describing the ordering in ai,
       intmat Mi: valuation matrix of ai, the columns of Mi being the
                  valuation vectors of the vars in ai
       intvec wi: size of 1-st, 2-nd,... block of identical columns of Mi
                  (vars with same valuation)
  

Note:
We define a variable x to be more complex than y (with respect to id)
if val(x) > val(y) lexicographically, where val(x) denotes the
valuation vector of x:

consider id as list of polynomials in x with coefficients in the
remaining variables. Then:

val(x) = (maximal occurring power of x, # of all monomials in leading
coefficient, # of all monomials in coefficient of next smaller power
of x,...).

Example:
LIB "presolve.lib";
ring s=0,(x,y,z,w),dp;
ideal i = x3+y2+yw2,xz+z2,xyz-w2;
sortvars(i,0,xy,1,zw);
==> [1]:
==>    _[1]=y
==>    _[2]=x
==>    _[3]=w
==>    _[4]=z
==> [2]:
==>    [1]:
==>       _[1]=y
==>       _[2]=x
==>    [2]:
==>       2,1
==>    [3]:
==>       2,3,
==>       1,1,
==>       2,0,
==>       0,2 
==>    [4]:
==>       1,1
==>    [5]:
==>       _[1]=w
==>       _[2]=z
==>    [6]:
==>       2,1
==>    [7]:
==>       2,2,
==>       2,1,
==>       0,2 
==>    [8]:
==>       1,1

D.7.1.13 shortid
................
Procedure from library presolve.lib (see presolve_lib).

Usage:
shortid(id,n[,e]); id= ideal/module, n,e=integers

Return:
- if called with two arguments or e=0:

 same type as id, containing generators of id having <= n terms.

 - if called with three arguments and e!=0:

 a list L:

 L[1]: same type as id, containing generators of id having <= n terms.

 L[2]: number of corresponding generator of id

Note:
May be used to compute partial standard basis in case id is to hard

Example:
LIB "presolve.lib";
ring s=0,(x,y,z,w),dp;
ideal i = (x3+y2+yw2)^2,(xz+z2)^2,xyz-w2-xzw; 
shortid(i,3);
==> _[1]=x2z2+2xz3+z4
==> _[2]=xyz-xzw-w2

D.7.1.14 valvars
................
Procedure from library presolve.lib (see presolve_lib).

Usage:
valvars(id[,n1,p1,n2,p2,...]);

id=poly/ideal/vector/module,

p1,p2,...= polynomials (product of vars),

n1,n2,...= integers,

ni controls the ordering of vars occurring in pi: ni=0 (resp.!=0) means
that less (resp. more) complex vars come first

(default: p1=product of all vars, n1=0)

the last pi (containing the remaining vars) may be omitted

Compute:
valuation (complexity) of variables with respect to id.

ni controls the ordering of vars occurring in pi:

ni=0 (resp.!=0) means that less (resp. more) complex vars come first.

Return:
list with 3 entries:
    [1]: intvec, say v, describing the permutation such that the permuted
       ringvariables are ordered with respect to their complexity in id
  [2]: list of intvecs, i-th intvec, say v(i) describing permutation
       of vars in a(i) such that v=v(1),v(2),...
  [3]: list of ideals and intmat's, say a(i) and M(i), where
       a(i): factors of pi,
       M(i): valuation matrix of a(i), such that the j-th column of M(i)
             is the valuation vector of j-th generator of a(i)
         

Note:
Use sortvars in order to actually sort the variables!
We define a variable x to be more complex than y (with respect to id)
if val(x) > val(y) lexicographically, where val(x) denotes the
valuation vector of x:

consider id as list of polynomials in x with coefficients in the
remaining variables. Then:

val(x) = (maximal occurring power of x, # of all monomials in leading
coefficient, # of all monomials in coefficient of next smaller power
of x,...).

Example:
LIB "presolve.lib";
ring s=0,(x,y,z,a,b),dp;
ideal i=ax2+ay3-b2x,abz+by2;
valvars (i,0,xyz);
==> [1]:
==>    3,1,2,4,5
==> [2]:
==>    [1]:
==>       3,1,2
==>    [2]:
==>       1,2
==> [3]:
==>    [1]:
==>       _[1]=x
==>       _[2]=y
==>       _[3]=z
==>    [2]:
==>       2,3,1,
==>       1,1,1,
==>       1,1,0 
==>    [3]:
==>       _[1]=a
==>       _[2]=b
==>    [4]:
==>       1,2,
==>       3,1,
==>       0,2 

D.7.1.15 idealSimplify
......................
Procedure from library presolve.lib (see presolve_lib).

Usage:
idealSimplify(id); id ideal

Return:
ideal I = eliminate(Id,m) m is a product of variables
which are only linearly involved in the generators of id

Example:
LIB "presolve.lib";
ring r=0,(x,y,z,w,t),dp;
ideal i=
t,
x3+y2+2z,
x2+3y,
x2+y2+z2,
w2+z;
ideal j=idealSimplify(i);
ideal k=eliminate(i,zyt);
reduce(k,std(j));
==> _[1]=0
==> _[2]=0
reduce(j,std(k));
==> _[1]=0
==> _[2]=0

D.7.1.16 idealSplit
...................
Procedure from library presolve.lib (see presolve_lib).

Usage:
idealSplit(id,timeF,timeS); id ideal and optional

timeF ,timeS integers to bound the time which can be used
for factorization resp. standard basis computation

Return:
a list of ideals such that their intersection

has the same radical as id

Example:
LIB "presolve.lib";
ring r=32003,(b,s,t,u,v,w,x,y,z),dp;
ideal i=
bv+su,
bw+tu,
sw+tv,
by+sx,
bz+tx,
sz+ty,
uy+vx,
uz+wx,
vz+wy,
bvz;
idealSplit(i);
==> [1]:
==>    _[1]=x
==>    _[2]=u
==>    _[3]=t
==>    _[4]=s
==>    _[5]=b
==>    _[6]=wy+vz
==> [2]:
==>    _[1]=z
==>    _[2]=w
==>    _[3]=t
==>    _[4]=s
==>    _[5]=b
==>    _[6]=vx+uy
==> [3]:
==>    _[1]=z
==>    _[2]=x
==>    _[3]=w
==>    _[4]=u
==>    _[5]=t
==>    _[6]=b
==> [4]:
==>    _[1]=z
==>    _[2]=y
==>    _[3]=x
==>    _[4]=t
==>    _[5]=s
==>    _[6]=b
==> [5]:
==>    _[1]=z
==>    _[2]=y
==>    _[3]=x
==>    _[4]=u
==>    _[5]=b
==>    _[6]=tv+sw
==> [6]:
==>    _[1]=z
==>    _[2]=y
==>    _[3]=x
==>    _[4]=w
==>    _[5]=t
==>    _[6]=su+bv
==> [7]:
==>    _[1]=w
==>    _[2]=v
==>    _[3]=u
==>    _[4]=t
==>    _[5]=s
==>    _[6]=b
==> [8]:
==>    _[1]=x
==>    _[2]=w
==>    _[3]=v
==>    _[4]=u
==>    _[5]=b
==>    _[6]=ty+sz
==> [9]:
==>    _[1]=z
==>    _[2]=w
==>    _[3]=v
==>    _[4]=u
==>    _[5]=t
==>    _[6]=sx+by
==> [10]:
==>    _[1]=z
==>    _[2]=y
==>    _[3]=x
==>    _[4]=w
==>    _[5]=v
==>    _[6]=u
==> [11]:
==>    _[1]=y
==>    _[2]=v
==>    _[3]=t
==>    _[4]=s
==>    _[5]=b
==>    _[6]=wx+uz
==> [12]:
==>    _[1]=y
==>    _[2]=x
==>    _[3]=v
==>    _[4]=u
==>    _[5]=s
==>    _[6]=b
==> [13]:
==>    _[1]=z
==>    _[2]=y
==>    _[3]=x
==>    _[4]=v
==>    _[5]=s
==>    _[6]=tu+bw
==> [14]:
==>    _[1]=z
==>    _[2]=y
==>    _[3]=w
==>    _[4]=v
==>    _[5]=t
==>    _[6]=s
==> [15]:
==>    _[1]=y
==>    _[2]=w
==>    _[3]=v
==>    _[4]=u
==>    _[5]=s
==>    _[6]=tx+bz
D.7.2 solve_lib
---------------
Library:
solve.lib
Purpose:
     Complex Solving of Polynomial Systems
Author:
Moritz Wenk, email: wenk@mathematik.uni-kl.de

Wilfred Pohl, email: pohl@mathematik.uni-kl.de


Procedures:
* laguerre_solve:: find all roots of univariate polynomial p
* solve:: all roots of 0-dim. ideal i using triangular sets
* ures_solve:: find all roots of 0-dimensional ideal i with resultants
* mp_res_mat:: multipolynomial resultant matrix of ideal i
* interpolate:: interpolate poly from evaluation points i and results j
* fglm_solve:: find roots of 0-dim. ideal using FGLM and lex_solve
* lex_solve:: find roots of reduced lexicographic standard basis
* simplexOut:: prints solution of simplex in nice format
* triangLf_solve:: find roots using triangular sys. (factorizing Lazard)
* triangM_solve:: find roots of given triangular system (Moeller)
* triangL_solve:: find roots using triangular system (Lazard)
* triang_solve:: find roots of given triangular system

D.7.2.1 laguerre_solve
......................
Procedure from library solve.lib (see solve_lib).

Usage:
laguerre_solve(f [, m, l, n, s] ); f = polynomial,

m, l, n, s = integers (control parameters of the method)
 m: precision of output in digits ( 4 <= m), if basering is not ring of 
      complex numbers;
 l: precision of internal computation in decimal digits ( l >=8 )
      only if the basering is not complex or complex with smaller precision;
 n: control of multiplicity of roots or of splitting of f into
      squarefree factors
      n < 0, no split of f (good, if all roots are simple)
      n >= 0, try to split
      n = 0, return only different roots
      n > 0, find all roots (with multiplicity)
 s: s != 0, returns ERROR if  | f(root) | > 0.1^m (when computing in the 
      current ring)
 ( default: m, l, n, s = 8, 30, 1, 0 )

Assume:
f is a univariate polynomial;

basering has characteristic 0 and is either complex or without
parameters.

Return:
list of (complex) roots of the polynomial f, depending on n. The
result is of type
 string: if the basering is not complex,
 number: otherwise.

Note:
If printlevel >0: displays comments ( default = 0 ).

If s != 0 and if the procedure stops with ERROR, try a higher
internal precision m.

Example:
LIB "solve.lib";
// Find all roots of an univariate polynomial using Laguerre's method:
ring rs1= 0,(x,y),lp;
poly f = 15x5 + x3 + x2 - 10;
// 10 digits precision
laguerre_solve(f,10);
==> [1]:
==>    (0.2930464644-i*0.9003002396)
==> [2]:
==>    (0.2930464644+i*0.9003002396)
==> [3]:
==>    (-0.7392783383-i*0.5355190078)
==> [4]:
==>    (-0.7392783383+i*0.5355190078)
==> [5]:
==>    0.8924637479
// Now with complex coefficients,
// internal precision is 30 digits (default)
printlevel=2;
ring rsc= (real,10,i),x,lp;
poly f = (15.4+i*5)*x^5 + (25.0e-2+i*2)*x^3 + x2 - 10*i;
list l = laguerre_solve(f);
==> //BEGIN laguerre_solve
==> //control: complex ring with precision 30
==> //working in:  ring lagc=(complex,30,30),x,lp;
==> //         polynomial has complex coefficients
==> //split in working ring:
==> // split without result
==> //END laguerre_solve
l;
==> [1]:
==>    (0.04588498039+i*0.9133296179)
==> [2]:
==>    (0.5037408279-i*0.8058051828)
==> [3]:
==>    (-0.5462895588-i*0.6796668873)
==> [4]:
==>    (0.8524014357+i*0.2163760334)
==> [5]:
==>    (-0.8557376852+i*0.3557664188)
// check result, value of substituted poly should be near to zero
// remember that l contains a list of strings
// in the case of a different ring
subst(f,x,l[1]);
==> 0
subst(f,x,l[2]);
==> 0

D.7.2.2 solve
.............
Procedure from library solve.lib (see solve_lib).

Assume:
the ideal is 0-dimensional;

basering has characteristic 0 and is either complex or
without parameters;

Return:
list of solutions of the ideal G, depending on n; one solution is a
list of complex numbers in the generated output ring (the new
basering).
 The result is a list L
    n  = 0: a list of all different solutions (L[i]),
    n != 0: a list of two elements,
            L[i][1] contains all different solutions with the same multiplicity
            L[i][2] the multiplicity
 L is ordered w.r.t. multiplicity (the smallest first).

Note:
If the problem is not 0-dim. the procedure stops with ERROR, if the
ideal G is not a lex. standard basis, it is generated with internal
computation (Hilbert driven), if the input-ring (with char 0) has
the name "<A>", the lexicographical and complex output-ring has the
name "<A>C".

Example:
LIB "solve.lib";
// Find all roots of a multivariate ideal using triangular sets:
int d=4;// with these 3 parameters you may construct
int t=3;// very hard problems for 'solve'
int s=2;
int i;
ring A=0,(x(1..d)),dp;
poly p=-1;
for(i=d;i>0;i--){p=p+x(i)^s;}
ideal I=x(d)^t-x(d)^s+p;
for(i=d-1;i>0;i--){I=x(i)^t-x(i)^s+p,I;}
I;
==> I[1]=x(1)^3+x(2)^2+x(3)^2+x(4)^2-1
==> I[2]=x(2)^3+x(1)^2+x(3)^2+x(4)^2-1
==> I[3]=x(3)^3+x(1)^2+x(2)^2+x(4)^2-1
==> I[4]=x(4)^3+x(1)^2+x(2)^2+x(3)^2-1
// the mutiplicity is
vdim(std(I));
==> 81
list l1=solve(I,6,0);
==> // name of new current ring: AC
// the current ring is
AC;
==> //   characteristic : 0 (complex:6 digits, additional 6 digits)
==> //   1 parameter    : i 
==> //   minpoly        : (i^2+1)
==> //   number of vars : 4
==> //        block   1 : ordering lp
==> //                  : names    x(1) x(2) x(3) x(4) 
==> //        block   2 : ordering C
// you must start with char. 0
setring A;
list l2=solve(I,6,1);
==> // name of current ring: AC
// the number of different solutions is
size(l1);
==> 37
// this is equal to
size(l2[1][1])+size(l2[2][1]);
==> 37
// the number of solutions with multiplicity is
size(l2[1][1])*l2[1][2]+size(l2[2][1])*l2[2][2];
==> 81
// the solutions with multiplicity
l2[2][2];
==> 12
// are
l2[2][1];
==> [1]:
==>    [1]:
==>       0
==>    [2]:
==>       0
==>    [3]:
==>       1
==>    [4]:
==>       0
==> [2]:
==>    [1]:
==>       0
==>    [2]:
==>       1
==>    [3]:
==>       0
==>    [4]:
==>       0
==> [3]:
==>    [1]:
==>       1
==>    [2]:
==>       0
==>    [3]:
==>       0
==>    [4]:
==>       0
==> [4]:
==>    [1]:
==>       0
==>    [2]:
==>       0
==>    [3]:
==>       0
==>    [4]:
==>       1

D.7.2.3 ures_solve
..................
Procedure from library solve.lib (see solve_lib).

Usage:
ures_solve(i [, k, p] ); i = ideal, k, p = integers
   k=0: use sparse resultant matrix of Gelfand, Kapranov and Zelevinsky,
   k=1: use resultant matrix of Macaulay which works only for
          homogeneous ideals,
   p>0: defines precision of the long floats for internal computation
          if the basering is not complex (in decimal digits),
   (default: k=0, p=30)

Assume:
i is a zerodimensional ideal with

nvars(basering) = ncols(i) = number of vars

actually occurring in i,

Return:
list of all (complex) roots of the polynomial system i = 0; the
result is of type
   string: if the basering is not complex,
   number: otherwise.

Example:
LIB "solve.lib";
// compute the intersection points of two curves
ring rsq = 0,(x,y),lp;
ideal gls=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
ures_solve(gls,0,16);
==> [1]:
==>    [1]:
==>       1
==>    [2]:
==>       -3
==> [2]:
==>    [1]:
==>       -1
==>    [2]:
==>       3
==> [3]:
==>    [1]:
==>       2.82842712474619
==>    [2]:
==>       1.414213562373095
==> [4]:
==>    [1]:
==>       -2.82842712474619
==>    [2]:
==>       -1.414213562373095
// result is a list (x,y)-coordinates as strings
// now with complex coefficient field, precision is 20 digits
ring rsc= (real,20,I),(x,y),lp;
ideal i = (2+3*I)*x2 + (0.35+I*45.0e-2)*y2 - 8, x2 + xy + (42.7)*y2;
list l= ures_solve(i,0,10);
// result is a list of (x,y)-coordinates of complex numbers
l;
==> [1]:
==>    [1]:
==>       (-1.315392899374542198+I*0.70468233142752928117)
==>    [2]:
==>       (0.12292646536251281054+I*0.19245727404407015049)
==> [2]:
==>    [1]:
==>       (1.315392899374542198-I*0.70468233142752928117)
==>    [2]:
==>       (-0.12292646536251281054-I*0.19245727404407015049)
==> [3]:
==>    [1]:
==>       (1.31584587549391830705-I*0.70396753310002259573)
==>    [2]:
==>       (0.092006639590217681983+I*0.20902112035965287775)
==> [4]:
==>    [1]:
==>       (-1.31584587549391830705+I*0.70396753310002259573)
==>    [2]:
==>       (-0.092006639590217681983-I*0.20902112035965287775)
// check the result
subst(subst(i[1],x,l[1][1]),y,l[1][2]);
==> 0

D.7.2.4 mp_res_mat
..................
Procedure from library solve.lib (see solve_lib).

Usage:
mp_res_mat(i [, k] ); i ideal, k integer,
    k=0: sparse resultant matrix of Gelfand, Kapranov and Zelevinsky,
    k=1: resultant matrix of Macaulay (k=0 is default)

Assume:
The number of elements in the input system must be the number of
variables in the basering plus one;

if k=1 then i must be homogeneous.

Return:
module representing the multipolynomial resultant matrix

Example:
LIB "solve.lib";
// compute resultant matrix in ring with parameters (sparse resultant matrix)
ring rsq= (0,u0,u1,u2),(x1,x2),lp;
ideal i= u0+u1*x1+u2*x2,x1^2 + x2^2 - 10,x1^2 + x1*x2 + 2*x2^2 - 16;
module m = mp_res_mat(i);
print(m);
==> -16,0,  -10,0,  (u0),0,   0,  0,   0,   0,  
==> 0,  -16,0,  -10,(u2),(u0),0,  0,   0,   0,  
==> 2,  0,  1,  0,  0,   (u2),0,  0,   0,   0,  
==> 0,  2,  0,  1,  0,   0,   0,  0,   0,   0,  
==> 0,  0,  0,  0,  (u1),0,   -10,(u0),0,   -16,
==> 1,  0,  0,  0,  0,   (u1),0,  (u2),(u0),0,  
==> 0,  1,  0,  0,  0,   0,   1,  0,   (u2),2,  
==> 1,  0,  1,  0,  0,   0,   0,  (u1),0,   0,  
==> 0,  1,  0,  1,  0,   0,   0,  0,   (u1),1,  
==> 0,  0,  0,  0,  0,   0,   1,  0,   0,   1   
// computing sparse resultant
det(m);
==> (-2*u0^4+18*u0^2*u1^2+4*u0^2*u1*u2+22*u0^2*u2^2-16*u1^4+80*u1^3*u2-52*u1^\
   2*u2^2-120*u1*u2^3-36*u2^4)
// compute resultant matrix (Macaulay resultant matrix)
ring rdq= (0,u0,u1,u2),(x0,x1,x2),lp;
ideal h=  homog(imap(rsq,i),x0);
h;
==> h[1]=(u0)*x0+(u1)*x1+(u2)*x2
==> h[2]=-10*x0^2+x1^2+x2^2
==> h[3]=-16*x0^2+x1^2+x1*x2+2*x2^2
module m = mp_res_mat(h,1);
print(m);
==> x0, x1, x2, 0, 0, 0, 0,0, 0, 0,
==> 0,  x0, 0,  x1,x2,0, 0,0, 0, 0,
==> 0,  0,  x0, 0, x1,x2,0,0, 0, 0,
==> -10,0,  0,  1, 0, 1, 0,0, 0, 0,
==> 0,  0,  0,  0, x0,0, 0,x1,x2,0,
==> -16,0,  0,  1, 1, 2, 0,0, 0, 0,
==> 0,  -10,0,  0, 0, 0, 1,0, 1, 0,
==> 0,  0,  -10,0, 0, 0, 0,1, 0, 1,
==> 0,  -16,0,  0, 0, 0, 1,1, 2, 0,
==> 0,  0,  -16,0, 0, 0, 0,1, 1, 2 
// computing Macaulay resultant (should be the same as above!)
det(m);
==> 2*x0^4-18*x0^2*x1^2-4*x0^2*x1*x2-22*x0^2*x2^2+16*x1^4-80*x1^3*x2+52*x1^2*\
   x2^2+120*x1*x2^3+36*x2^4
// compute numerical sparse resultant matrix
setring rsq;
ideal ir= 15+2*x1+5*x2,x1^2 + x2^2 - 10,x1^2 + x1*x2 + 2*x2^2 - 16;
module mn = mp_res_mat(ir);
print(mn);
==> 15,0, -10,0,  0, 0, 0,  -16,0,  0,  
==> 5, 15,0,  -10,0, 0, 0,  0,  -16,0,  
==> 0, 5, 1,  0,  0, 0, 0,  2,  0,  0,  
==> 0, 0, 0,  1,  0, 0, 0,  0,  2,  0,  
==> 2, 0, 0,  0,  15,0, -10,0,  0,  -16,
==> 0, 2, 0,  0,  5, 15,0,  1,  0,  0,  
==> 0, 0, 0,  0,  0, 5, 1,  0,  1,  2,  
==> 0, 0, 1,  0,  2, 0, 0,  1,  0,  0,  
==> 0, 0, 0,  1,  0, 2, 0,  0,  1,  1,  
==> 0, 0, 0,  0,  0, 0, 1,  0,  0,  1   
// computing sparse resultant
det(mn);
==> -7056

D.7.2.5 interpolate
...................
Procedure from library solve.lib (see solve_lib).

Usage:
interpolate(p,v,d); p,v=ideals of numbers, d=integer

Assume:
Ground field K is the field of rational numbers, p and v are lists
of elements of the ground field K with p[j] != -1,0,1, size(p) = n
(= number of vars) and size(v)=N=(d+1)^n.

Return:
poly f, the unique polynomial f of degree n*d with prescribed values
v[i] at the points p(i)=(p[1]^(i-1),..,p[n]^(i-1)), i=1,..,N.

Note:
mainly useful when n=1, i.e. f is satisfying f(p^(i-1)) = v[i],
i=1..d+1.

Example:
LIB "solve.lib";
ring r1 = 0,(x),lp;
// determine f with deg(f) = 4 and
// v = values of f at points 3^0, 3^1, 3^2, 3^3, 3^4
ideal v=16,0,11376,1046880,85949136;
interpolate( 3, v, 4 );
==> 2x4-22x2+36


D.7.2.6 fglm_solve
..................
Procedure from library solve.lib (see solve_lib).

Usage:
fglm_solve(i [, p] ); i ideal, p integer

Assume:
the ground field has char 0.

Return:
a list of numbers, the complex roots of i;

p>0: gives precision of complex numbers in decimal digits (default:
p=30).

Note:
The procedure uses a standard basis of i to determine all complex
roots of i.

It creates a ring rC with the same number of variables but with
complex coefficients (and precision p).

Example:
LIB "solve.lib";
ring r = 0,(x,y),lp;
// compute the intersection points of two curves
ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
fglm_solve(s,10);
==> // name of new ring: rC
==> // list of roots: rlist
rlist;
==> [1]:
==>    [1]:
==>       2.8284271247
==>    [2]:
==>       1.4142135624
==> [2]:
==>    [1]:
==>       -2.8284271247
==>    [2]:
==>       -1.4142135624
==> [3]:
==>    [1]:
==>       1
==>    [2]:
==>       -3
==> [4]:
==>    [1]:
==>       -1
==>    [2]:
==>       3

D.7.2.7 lex_solve
.................
Procedure from library solve.lib (see solve_lib).

Usage:
lex_solve( i[,p] ); i=ideal, p=integer,
   p>0: gives precision of complex numbers in decimal digits (default: p=30).
 

Assume:
i is a reduced lexicographical Groebner bases of a zero-dimensional
ideal, sorted by increasing leading terms.

Return:
nothing

Create:
The procedure creates a complec ring with the same variables but
with complex coefficients (and precision p).

In this ring a list rlist of numbers is created, in which the complex
roots of i are stored.

Example:
LIB "solve.lib";
ring r = 0,(x,y),lp;
// compute the intersection points of two curves
ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
lex_solve(stdfglm(s),10);
==> // name of new ring: rC
==> // list of roots: rlist
rlist;
==> [1]:
==>    [1]:
==>       2.8284271247
==>    [2]:
==>       1.4142135624
==> [2]:
==>    [1]:
==>       -2.8284271247
==>    [2]:
==>       -1.4142135624
==> [3]:
==>    [1]:
==>       1
==>    [2]:
==>       -3
==> [4]:
==>    [1]:
==>       -1
==>    [2]:
==>       3

D.7.2.8 simplexOut
..................
Procedure from library solve.lib (see solve_lib).

Usage:
simplexOut(l); l list

Assume:
l is the output of simplex.

Return:
nothing. The procedure prints the computed solution of simplex
(as strings) in a nice format.

Example:
LIB "solve.lib";
ring r = (real,10),(x),lp;
// consider the max. problem:
//
//    maximize  x(1) + x(2) + 3*x(3) - 0.5*x(4)
//
//  with constraints:   x(1) +          2*x(3)          <= 740
//                             2*x(2)          - 7*x(4) <=   0
//                               x(2) -   x(3) + 2*x(4) >=   0.5
//                      x(1) +   x(2) +   x(3) +   x(4)  =   9
//
matrix sm[5][5]=   0, 1, 1, 3,-0.5,
740,-1, 0,-2, 0,
0, 0,-2, 0, 7,
0.5, 0,-1, 1,-2,
9,-1,-1,-1,-1;
int n = 4;  // number of constraints
int m = 4;  // number of variables
int m1= 2;  // number of <= constraints
int m2= 1;  // number of >= constraints
int m3= 1;  // number of == constraints
list sol=simplex(sm, n, m, m1, m2, m3);
simplexOut(sol);
==> z = 17.025
==> x2 = 3.325
==> x4 = 0.95
==> x3 = 4.725


D.7.2.9 triangLf_solve
......................
Procedure from library solve.lib (see solve_lib).

Usage:
triangLf_solve(i [, p] ); i ideal, p integer,

p>0: gives precision of complex numbers in digits (default: p=30).

Assume:
the ground field has char 0; i is a zero-dimensional ideal

Return:
nothing

Create:
The procedure creates a ring rC with the same number of variables but
with complex coefficients (and precision p).

In rC a list rlist of numbers is created, in which the complex
roots of i are stored.

The proc uses a triangular system (Lazard's Algorithm with
factorization) computed from a standard basis to determine recursively
all complex roots with Laguerre's algorithm of input ideal i.

Example:
LIB "solve.lib";
ring r = 0,(x,y),lp;
// compute the intersection points of two curves
ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
triangLf_solve(s,10);
==> // name of new ring: rC
==> // list of roots: rlist
rlist;
==> [1]:
==>    [1]:
==>       -1
==>    [2]:
==>       3
==> [2]:
==>    [1]:
==>       1
==>    [2]:
==>       -3
==> [3]:
==>    [1]:
==>       2.8284271247
==>    [2]:
==>       1.4142135624
==> [4]:
==>    [1]:
==>       -2.8284271247
==>    [2]:
==>       -1.4142135624

D.7.2.10 triangM_solve
......................
Procedure from library solve.lib (see solve_lib).

Usage:
triangM_solve(i [, p ] ); i=ideal, p=integer,

p>0: gives precision of complex numbers in digits (default: p=30).

Assume:
the ground field has char 0;

i zero-dimensional ideal

Return:
nothing

Create:
The procedure creates a ring rC with the same number of variables but
with complex coefficients (and precision p).

In rC a list rlist of numbers is created, in which the complex
roots of i are stored.

The proc uses a triangular system (Moellers Algorithm) computed from a
standard basis to determine recursively all complex roots with
Laguerre's algorithm of input ideal i.

Example:
LIB "solve.lib";
ring r = 0,(x,y),lp;
// compute the intersection points of two curves
ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
triangM_solve(s,10);
==> // name of new ring: rC
==> // list of roots: rlist
rlist;
==> [1]:
==>    [1]:
==>       2.8284271247
==>    [2]:
==>       1.4142135624
==> [2]:
==>    [1]:
==>       -2.8284271247
==>    [2]:
==>       -1.4142135624
==> [3]:
==>    [1]:
==>       1
==>    [2]:
==>       -3
==> [4]:
==>    [1]:
==>       -1
==>    [2]:
==>       3

D.7.2.11 triangL_solve
......................
Procedure from library solve.lib (see solve_lib).

Usage:
triangL_solve(i [, p] ); i=ideal, p=integer,

p>0: gives precision of complex numbers in digits (default: p=30).

Assume:
the ground field has char 0; i is a zero-dimensional ideal.

Return:
nothing

Create:
The procedure creates a ring rC with the same number of variables but
with complex coefficients (and precision p).

In rC a list rlist of numbers is created, in which the complex
roots of i are stored.

The proc uses a triangular system (Lazard's Algorithm) computed from
a standard basis to determine recursively all complex roots with
Laguerre's algorithm of input ideal i.

Example:
LIB "solve.lib";
ring r = 0,(x,y),lp;
// compute the intersection points of two curves
ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
triangL_solve(s,10);
==> // name of new ring: rC
==> // list of roots: rlist
rlist;
==> [1]:
==>    [1]:
==>       2.8284271247
==>    [2]:
==>       1.4142135624
==> [2]:
==>    [1]:
==>       -2.8284271247
==>    [2]:
==>       -1.4142135624
==> [3]:
==>    [1]:
==>       1
==>    [2]:
==>       -3
==> [4]:
==>    [1]:
==>       -1
==>    [2]:
==>       3

D.7.2.12 triang_solve
.....................
Procedure from library solve.lib (see solve_lib).

Usage:
triang_solve(l,p [, d] ); l=list, p,d=integers,

l a list of finitely many triangular systems, such that the union of
their varieties equals the variety of the initial ideal.

p>0: gives precision of complex numbers in digits,

d>0: gives precision (1<d<p) for near-zero-determination,

(default: d=1/2*p).

Assume:
the ground field has char 0;

l was computed using Algorithm of Lazard or Algorithm of Moeller
(see triang.lib).

Return:
nothing

Create:
The procedure creates a ring rC with the same number of variables but
with complex coefficients (and precision p).

In rC a list rlist of numbers is created, in which the complex
roots of i are stored.


Example:
LIB "solve.lib";
ring r = 0,(x,y),lp;
// compute the intersection points of two curves
ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
triang_solve(triangLfak(stdfglm(s)),10);
==> // name of new ring: rC
==> // list of roots: rlist
rlist;
==> [1]:
==>    [1]:
==>       -1
==>    [2]:
==>       3
==> [2]:
==>    [1]:
==>       1
==>    [2]:
==>       -3
==> [3]:
==>    [1]:
==>       2.8284271247
==>    [2]:
==>       1.4142135624
==> [4]:
==>    [1]:
==>       -2.8284271247
==>    [2]:
==>       -1.4142135624
D.7.3 triang_lib
----------------
Library:
triang.lib
Purpose:
   Decompose Zero-dimensional Ideals into Triangular Sets
Author:
D. Hillebrand


Procedures:
* triangL:: Decomposition of (G) into triangular systems (Lazard).
* triangLfak:: Decomp. of (G) into tri. systems plus factorization.
* triangM:: Decomposition of (G) into triangular systems (Moeller).
* triangMH:: Decomp. of (G) into tri. syst. with disjoint varieties.

D.7.3.1 triangL
...............
Procedure from library triang.lib (see triang_lib).

Usage:
triangL(G); G=ideal

Assume:
G is the reduced lexicographical Groebner bases of the
zero-dimensional ideal (G), sorted by increasing leading terms.

Return:
a list of finitely many triangular systems, such that
the union of their varieties equals the variety of (G).

Note:
Algorithm of Lazard (see: Lazard, D.: Solving zero-dimensional
algebraic systems, J. Symb. Comp. 13, 117 - 132, 1992).

Example:
LIB "triang.lib";
ring rC5 = 0,(e,d,c,b,a),lp;
triangL(stdfglm(cyclic(5)));

D.7.3.2 triangLfak
..................
Procedure from library triang.lib (see triang_lib).

Usage:
triangLfak(G); G=ideal

Assume:
G is the reduced lexicographical Groebner bases of the
zero-dimensional ideal (G), sorted by increasing leading terms.

Return:
a list of finitely many triangular systems, such that
the union of their varieties equals the variety of (G).

Note:
Algorithm of Lazard with factorization (see: Lazard, D.: Solving
zero-dimensional algebraic systems, J. Symb. Comp. 13, 117 - 132, 1992).

Remark:
each polynomial of the triangular systems is factorized.

Example:
LIB "triang.lib";
ring rC5 = 0,(e,d,c,b,a),lp;
triangLfak(stdfglm(cyclic(5)));

D.7.3.3 triangM
...............
Procedure from library triang.lib (see triang_lib).

Usage:
triangM(G[,i]); G=ideal, i=integer,


Assume:
G is the reduced lexicographical Groebner bases of the
zero-dimensional ideal (G), sorted by increasing leading terms.

Return:
a list of finitely many triangular systems, such that
the union of their varieties equals the variety of (G).
If i = 2, then each polynomial of the triangular systems
is factorized.

Note:
Algorithm of Moeller (see: Moeller, H.M.:

On decomposing systems of polynomial equations with

finitely many solutions, Appl. Algebra Eng. Commun. Comput. 4,
217 - 230, 1993).

Example:
LIB "triang.lib";
ring rC5 = 0,(e,d,c,b,a),lp;
triangM(stdfglm(cyclic(5))); //oder: triangM(stdfglm(cyclic(5)),2);

D.7.3.4 triangMH
................
Procedure from library triang.lib (see triang_lib).

Usage:
triangMH(G[,i]); G=ideal, i=integer

Assume:
G is the reduced lexicographical Groebner bases of the
zero-dimensional ideal (G), sorted by increasing leading terms.

Return:
a list of finitely many triangular systems, such that
the disjoint union of their varieties equals the variety of (G).
If i = 2, then each polynomial of the triangular systems is factorized.

Note:
Algorithm of Moeller and Hillebrand (see: Moeller, H.M.:
On decomposing systems of polynomial equations with finitely many
solutions, Appl. Algebra Eng. Commun. Comput. 4, 217 - 230, 1993 and
Hillebrand, D.: Triangulierung nulldimensionaler Ideale -
Implementierung und Vergleich zweier Algorithmen, master thesis,
Universitaet Dortmund, Fachbereich Mathematik, Prof. Dr. H.M. Moeller,
1999).

Example:
LIB "triang.lib";
ring rC5 = 0,(e,d,c,b,a),lp;
triangMH(stdfglm(cyclic(5)));
D.7.4 ntsolve_lib
-----------------
Library:
ntsolve.lib
Purpose:
     Real Newton Solving of Polynomial Systems
Authors:
Wilfred Pohl, email: pohl@mathematik.uni-kl.de

Dietmar Hillebrand


Procedures:
* nt_solve:: find one real root of 0-dimensional ideal G
* triMNewton:: find one real root for 0-dim triangular system G

D.7.4.1 nt_solve
................
Procedure from library ntsolve.lib (see ntsolve_lib).

Usage:
nt_solve(gls,ini[,ipar]); gls,ini= ideals, ipar=list/intvec,

gls: contains the equations, for which a solution will be computed
ini: ideal of initial values (approximate solutions to start with),

ipar: control integers (default: ipar = 100,10)
   ipar[1]: max. number of iterations
 ipar[2]: accuracy (we have the l_2-norm ||.||): accept solution sol
          if ||gls(sol)|| < eps0*(0.1^ipar[2])
          where eps0 = ||gls(ini)|| is the initial error
  

Assume:
gls is a zerodimensional ideal with nvars(basering) = size(gls) (>1)

Return:
ideal, coordinates of one solution (if found), 0 else

Note:
if printlevel >0: displays comments (default =0)

Example:
LIB "ntsolve.lib";
ring rsq = (real,40),(x,y,z,w),lp;
ideal gls =  x2+y2+z2-10, y2+z3+w-8, xy+yz+xz+w5 - 1,w3+y;
ideal ini = 3.1,2.9,1.1,0.5;
intvec ipar = 200,0;
ideal sol = nt_solve(gls,ini,ipar);
sol;
==> sol[1]=0.8698104581550055082008024750939710335537
==> sol[2]=2.8215774457503246008496262517717182369409
==> sol[3]=1.1323120084664179900060940157112668717318
==> sol[4]=-1.413071026406678849397999475590194239628

D.7.4.2 triMNewton
..................
Procedure from library ntsolve.lib (see ntsolve_lib).

Usage:
triMNewton(G,a[,ipar]); G,a= ideals, ipar=list/intvec

Assume:
G: g1,..,gn, a triangular system of n equations in n vars, i.e.
gi=gi(var(n-i+1),..,var(n)),

a: ideal of numbers, coordinates of an approximation of a common
zero of G to start with (with a[i] to be substituted in var(i)),

ipar: control integer vector (default: ipar = 100,10)
    ipar[1]: max. number of iterations
  ipar[2]: accuracy (we have as norm |.| absolute value ):
           accept solution sol if |G(sol)| < |G(a)|*(0.1^ipar[2]).
  

Return:
an ideal, coordinates of a better approximation of a zero of G

Example:
LIB "ntsolve.lib";
ring r = (real,30),(z,y,x),(lp);
ideal i = x^2-1,y^2+x4-3,z2-y4+x-1;
ideal a = 2,3,4;
intvec e = 20,10;
ideal l = triMNewton(i,a,e);
l;
==> l[1]=-2.000000000042265738880279143423
==> l[2]=1.41421356237309504880168872421
==> l[3]=1
D.7.5 zeroset_lib
-----------------
Library:
zeroset.lib
Purpose:
      Procedures For Roots and Factorization
Author:
Thomas Bayer, email: tbayer@mathematik.uni-kl.de

http://wwwmayr.informatik.tu-muenchen.de/personen/bayert/
Current Adress: Institut fuer Informatik, TU Muenchen

Overview:
Algorithms for finding the zero-set of a zero-dim. ideal in Q(a)[x_1,..,x_n],
Roots and Factorization of univariate polynomials over Q(a)[t]
where a is an algebraic number. Written in the frame of the
diploma thesis (advisor: Prof. Gert-Martin Greuel) 'Computations of moduli
spaces of semiquasihomogeneous singularities and an implementation in Singular'.
This library is meant as a preliminary extension of the functionality
of Singular for univariate factorization of polynomials over simple algebraic
extensions in characteristic 0.

Subprocedures with postfix 'Main' require that the ring contains a variable
'a' and no parameters, and the ideal 'mpoly', where 'minpoly' from the
basering is stored.


Procedures:
* EGCD:: gcd over an algebraic extension field of Q
* Factor:: factorization of f over an algebraic extension field
* Quotient:: quotient q of f w.r.t. g (in f = q*g + remainder)
* Remainder:: remainder of the division of f by g
* Roots:: computes all roots of f in an extension field of Q
* SQFRNorm:: norm of f (f must be squarefree)
* ZeroSet:: zero-set of the 0-dim. ideal I
Auxiliary procedures:
* EGCDMain:: gcd over an algebraic extension field of Q
* FactorMain:: factorization of f over an algebraic extension field
* InvertNumberMain:: inverts an element of an algebraic extension field
* QuotientMain:: quotient of f w.r.t. g
* RemainderMain:: remainder of the division of f by g
* RootsMain:: computes all roots of f, might extend the ground field
* SQFRNormMain:: norm of f (f must be squarefree)
* ContainedQ:: f in data ?
* SameQ:: a == b (list a,b)

D.7.5.1 EGCD
............
Procedure from library zeroset.lib (see zeroset_lib).

Usage:
EGCD(f, g); where f,g are polynomials

Purpose:
compute the polynomial gcd of f and g over Q(a)[x]

Return:
polynomial h s.t. h is a greatest common divisor of f and g (not nec.
monic)

Assume:
basering = Q(a)[t]

Example:
LIB "zeroset.lib";
ring R = (0,a), x, lp;
minpoly = a2+1;
poly f =  x4 - 1;
poly g = x2 - 2*a*x - 1;
EGCD(f, g);
==> (-4a)*x-4

D.7.5.2 Factor
..............
Procedure from library zeroset.lib (see zeroset_lib).

Usage:
Factor(f); where f is a polynomial

Purpose:
compute the factorization of the squarefree poly f over Q(a)[t]

Return:
list with two entries
    _[1] = factors (monic), first entry is the leading coefficient
  _[2] = multiplicities (not yet implemented)
  

Assume:
basering must be the univariate polynomial ring over a field, which
is Q or a simple extension of Q given by a minpoly.

Note:
if basering = Q[t] then this is the built-in factorize

Example:
LIB "zeroset.lib";
ring R = (0,a), x, lp;
minpoly = a2+1;
poly f =  x4 - 1;
list fl = Factor(f);
fl;
==> [1]:
==>    _[1]=1
==>    _[2]=(40a+60)*x+(40a+60)
==>    _[3]=(1/65a-29/130)*x+(-1/65a+29/130)
==>    _[4]=(4a)*x+4
==>    _[5]=(7/520a+1/130)*x+(1/130a-7/520)
==> [2]:
==>    _[1]=1
==>    _[2]=1
==>    _[3]=1
==>    _[4]=1
==>    _[5]=1
fl[1][1]*fl[1][2]*fl[1][3]*fl[1][4]*fl[1][5] - f;
==> 0

D.7.5.3 Quotient
................
Procedure from library zeroset.lib (see zeroset_lib).

Usage:
Quotient(f, g); where f,g are polynomials;

Purpose:
compute the quotient q and remainder r s.t. f = g*q + r, deg(r) < deg(g)

Return:
list of polynomials
    _[1] = quotient  q
  _[2] = remainder r
  

Assume:
basering = Q[x] or Q(a)[x]

Example:
LIB "zeroset.lib";
ring R = (0,a), x, lp;
minpoly = a2+1;
poly f =  x4 - 2;
poly g = x - a;
list qr = Quotient(f, g);
qr;
==> [1]:
==>    x3+(a)*x2-x+(-a)
==> [2]:
==>    0
qr[1]*g + qr[2] - f;
==> 1

D.7.5.4 Remainder
.................
Procedure from library zeroset.lib (see zeroset_lib).

Usage:
Remainder(f, g); where f,g are polynomials

Purpose:
compute the remainder of the division of f by g, i.e. a polynomial r
s.t. f = g*q + r, deg(r) < deg(g).

Return:
poly

Assume:
basering = Q[x] or Q(a)[x]

Example:
LIB "zeroset.lib";
ring R = (0,a), x, lp;
minpoly = a2+1;
poly f =  x4 - 1;
poly g = x3 - 1;
Remainder(f, g);
==> x-1

D.7.5.5 Roots
.............
Procedure from library zeroset.lib (see zeroset_lib).

Usage:
Roots(f); where f is a polynomial

Purpose:
compute all roots of f in a finite extension of the ground field
without multiplicities.

Return:
ring, a polynomial ring over an extension field of the ground field,
containing a list 'roots' and polynomials 'newA' and 'f':
    - 'roots' is the list of roots of the polynomial f (no multiplicities)
  - if the ground field is Q(a') and the extension field is Q(a), then
    'newA' is the representation of a' in Q(a). 
    If the basering contains a parameter 'a' and the minpoly remains unchanged
    then 'newA' = 'a'.
    If the basering does not contain a parameter then 'newA' = 'a' (default).
  - 'f' is the polynomial f in Q(a) (a' being substituted by 'newA')
  

Assume:
ground field to be Q or a simple extension of Q given by a minpoly

Example:
LIB "zeroset.lib";
ring R = (0,a), x, lp;
minpoly = a2+1;
poly f = x3 - a;
def R1 = Roots(f);
==> 
==> // 'Roots' created a new ring which contains the list 'roots' and
==> // the polynomials 'f' and 'newA'
==> // To access the roots, newA and the new representation of f, type
==>    def R = Roots(f); setring R; roots; newA; f;
==> 
setring R1;
minpoly;
==> (a4-a2+1)
newA;
==> (a3)
f;
==> x3+(-a3)
roots;
==> [1]:
==>    (-a3)
==> [2]:
==>    (a3-a)
==> [3]:
==>    (a)
map F;
F[1] = roots[1];
F(f);
==> 0

D.7.5.6 SQFRNorm
................
Procedure from library zeroset.lib (see zeroset_lib).

Usage:
SQFRNorm(f); where f is a polynomial

Purpose:
compute the norm of the squarefree polynomial f in Q(a)[x].

Return:
list with 3 entries
    _[1] = squarefree norm of g (poly)
  _[2] = g (= f(x - s*a)) (poly)
  _[3] = s (int)
  

Assume:
f must be squarefree, basering = Q(a)[x] and minpoly != 0.

Note:
the norm is an element of Q[x]

Example:
LIB "zeroset.lib";
ring R = (0,a), x, lp;
minpoly = a2+1;
poly f =  x4 - 2*x + 1;
SQFRNorm(f);
==> [1]:
==>    x8+4*x6-4*x5+8*x4+8*x3-4*x2+8*x+8
==> [2]:
==>    x4+(-4a)*x3-6*x2+(4a-2)*x+(2a+2)
==> [3]:
==>    1

D.7.5.7 ZeroSet
...............
Procedure from library zeroset.lib (see zeroset_lib).

Usage:
ZeroSet(I [,opt] ); I=ideal, opt=integer

Purpose:
compute the zero-set of the zero-dim. ideal I, in a finite extension
of the ground field.

Return:
ring, a polynomial ring over an extension field of the ground field,
containing a list 'zeroset', a polynomial 'newA', and an
ideal 'id':
    - 'zeroset' is the list of the zeros of the ideal I, each zero is an ideal.
  - if the ground field is Q(a') and the extension field is Q(a), then
    'newA' is the representation of a' in Q(a).
    If the basering contains a parameter 'a' and the minpoly remains unchanged
    then 'newA' = 'a'.
    If the basering does not contain a parameter then 'newA' = 'a' (default).    
  - 'id' is the ideal I in Q(a)[x_1,...] (a' substituted by 'newA')
  

Assume:
dim(I) = 0, and ground field to be Q or a simple extension of Q given
by a minpoly.

Options:
opt = 0 no primary decomposition (default)

opt > 0 primary decomposition

Note:
If I contains an algebraic number (parameter) then 'I' must be
transformed w.r.t. 'newA' in the new ring.

Example:
LIB "zeroset.lib";
ring R = (0,a), (x,y,z), lp;
minpoly = a2 + 1;
ideal I = x2 - 1/2, a*z - 1, y - 2;
def T = ZeroSet(I);
==> 1
setring T;
minpoly;
==> (4a4+4a2+9)
newA;
==> (1/3a3+5/6a)
id;
==> id[1]=(1/3a3+5/6a)*z-1
==> id[2]=y-2
==> id[3]=2*x2-1
zeroset;
==> [1]:
==>    _[1]=(1/3a3-1/6a)
==>    _[2]=2
==>    _[3]=(-1/3a3-5/6a)
==> [2]:
==>    _[1]=(-1/3a3+1/6a)
==>    _[2]=2
==>    _[3]=(-1/3a3-5/6a)
map F1 = basering, zeroset[1];
map F2 = basering, zeroset[2];
F1(id);
==> _[1]=0
==> _[2]=0
==> _[3]=0
F2(id);
==> _[1]=0
==> _[2]=0
==> _[3]=0

D.7.5.8 EGCDMain
................
Procedure from library zeroset.lib (see zeroset_lib).

Purpose:
compute the polynomial gcd of f and g over Q(a)[x]

Return:
poly

Assume:
basering = Q[x,a] and ideal mpoly is defined (it might be 0),
this represents the ring Q(a)[x] together with its minimal polynomial.


D.7.5.9 FactorMain
..................
Procedure from library zeroset.lib (see zeroset_lib).

Purpose:
compute the factorization of the squarefree poly f over Q(a)[t],
minpoly = p(a).

Return:
list with 2 entries
    _[1] = factors, first is a constant
  _[2] = multiplicities (not yet implemented)
  

Assume:
basering = Q[x,a], representing Q(a)[x]. An ideal mpoly must
be defined, representing the minimal polynomial (it might be 0!).


D.7.5.10 InvertNumberMain
.........................
Procedure from library zeroset.lib (see zeroset_lib).

Usage:
InvertNumberMain(f); where f is a polynomial

Purpose:
compute 1/f if f is a number in Q(a) i.e., f is represented by a
polynomial in Q[a].

Return:
poly 1/f

Assume:
basering = Q[x_1,...,x_n,a], ideal mpoly must be defined and != 0 !


D.7.5.11 QuotientMain
.....................
Procedure from library zeroset.lib (see zeroset_lib).

Usage:
QuotientMain(f, g); where f,g are polynomials

Purpose:
compute the quotient q and remainder r s.t. f = g*q + r, deg(r) < deg(g)

Return:
list of polynomials
    _[1] = quotient  q
  _[2] = remainder r
  

Assume:
basering = Q[x,a] and ideal mpoly is defined (it might be 0),
this represents the ring Q(a)[x] together with its minimal polynomial.


D.7.5.12 RemainderMain
......................
Procedure from library zeroset.lib (see zeroset_lib).

Usage:
RemainderMain(f, g); where f,g are polynomials

Purpose:
compute the remainder r s.t. f = g*q + r, deg(r) < deg(g)

Return:
poly

Assume:
basering = Q[x,a] and ideal mpoly is defined (it might be 0),
this represents the ring Q(a)[x] together with its minimal polynomial.


D.7.5.13 RootsMain
..................
Procedure from library zeroset.lib (see zeroset_lib).

Usage:
RootsMain(f); where f is a polynomial

Purpose:
compute all roots of f in a finite extension of the ground field
without multiplicities.

Return:
list, all entries are polynomials
    _[1] = roots of f, each entry is a polynomial
  _[2] = 'newA' - if the ground field is Q(a') and the extension field
         is Q(a), then 'newA' is the representation of a' in Q(a)
  _[3] = minpoly of the algebraic extension of the ground field
  

Assume:
basering = Q[x,a] ideal mpoly must be defined, it might be 0!

Note:
might change the ideal mpoly !!


D.7.5.14 SQFRNormMain
.....................
Procedure from library zeroset.lib (see zeroset_lib).

Usage:
SQFRNorm(f); where f is a polynomial

Purpose:
compute the norm of the squarefree polynomial f in Q(a)[x].

Return:
list with 3 entries
    _[1] = squarefree norm of g (poly)
  _[2] = g (= f(x - s*a)) (poly)
  _[3] = s (int)
  

Assume:
f must be squarefree, basering = Q[x,a] and ideal mpoly is equal to
'minpoly',this represents the ring Q(a)[x] together with 'minpoly'.

Note:
the norm is an element of Q[x]


D.7.5.15 ContainedQ
...................
Procedure from library zeroset.lib (see zeroset_lib).

Usage:
ContainedQ(data, f [, opt]); data=list; f=any type, opt=integer

Purpose:
test if f is an element of data.

Return:
int

0 if f not contained in data

1 if f contained in data

Options:
opt = 0 : use '==' for comparing f with elements from data

opt = 1 : use SameQ for comparing f with elements from data


D.7.5.16 SameQ
..............
Procedure from library zeroset.lib (see zeroset_lib).

Usage:
SameQ(a, b); a,b=list/intvec

Purpose:
test a == b elementwise, i.e., a[i] = b[i].

Return:
int

0 if a != b

1 if a == b


D.8 Visualization
=================

* graphics_lib:: procedures to draw  with Mathematica
* latex_lib:: procedures for typesetting in TeX
* paramet_lib:: procedures for parametrizations
* surf_lib:: interface to the surf program

D.8.1 graphics_lib
------------------
Library:
graphics.lib
Purpose:
    Procedures to use Graphics with Mathematica
Author:
Christian Gorzel, gorzelc@math.uni-muenster.de


Procedures:
* staircase:: Mathematica text for displaying staircase of I
* mathinit:: string for loading Mathematica's ImplicitPlot
* mplot:: Mathematica text for various plots

D.8.1.1 staircase
.................
Procedure from library graphics.lib (see graphics_lib).

Usage:
staircase(s,I); s a string, I ideal in two variables

Return:
string with Mathematica input for displaying staircase diagrams of an
ideal I, i.e. exponent vectors of the initial ideal of I

Note:
ideal I should be given by a standard basis. Let s="" and copy and
paste the result into a Mathematica notebook.

Example:
LIB "graphics.lib";
ring r0 = 0,(x,y),ls;
ideal I = -1x2y6-1x4y2, 7x6y5+1/2x7y4+6x4y6;
staircase("",std(I));
ring r1 = 0,(x,y),dp;
ideal I = fetch(r0,I);
staircase("",std(I));
ring r2 = 0,(x,y),wp(2,3);
ideal I = fetch(r0,I);
staircase("",std(I));
// Paste the output into a Mathematica notebook
// active evalutation of the cell with SHIFT RETURN

D.8.1.2 mathinit
................
Procedure from library graphics.lib (see graphics_lib).

Usage:
mathinit();

Return:
initializing string for loading Mathematica's ImplicitPlot

Example:
LIB "graphics.lib";
mathinit();
// Paste the output into a Mathematica notebook
// active evalutation of the cell with SHIFT RETURN

D.8.1.3 mplot
.............
Procedure from library graphics.lib (see graphics_lib).

Usage:
mplot(fname, I [,I1,I2,..,s] ); fname=string; I,I1,I2,..=ideals,
s=string representing the plot region.

Use the ideals I1,I2,.. in order to produce multiple plots (they need
to have the same number of entries as I!).

Return:
string, text with Mathematica commands to display a plot

Note:
The plotregion is defaulted to -1,1 around zero.

For implicit given curves enter first the string returned by
proc mathinit into Mathematica in order to load ImplicitPlot.
The following conventions for I are used:
    - ideal with 2 entries in one variable means a parametrised plane curve,
  - ideal with 3 entries in one variable means a parametrised space curve,
  - ideal with 3 entries in two variables means a parametrised surface,
  - ideal with 2 entries in two variables means an implicit curve
    given as I[1]==I[2],
  - ideal with 1 entry (or one polynomial) in two variables means
    an implicit curve given as  f == 0,
  

Example:
LIB "graphics.lib";
// ---------  plane curves ------------
ring rr0 = 0,x,dp; export rr0;
ideal I = x3 + x, x2;
ideal J = x2, -x+x3;
mplot("",I,J,"-2,2");
// Paste the output into a Mathematica notebook
// active evalutation of the cell with SHIFT RETURN
// --------- space curves --------------
I = x3,-1/10x3+x2,x2;
mplot("",I);
// Paste the output into a Mathematica notebook
// active evalutation of the cell with SHIFT RETURN
// ----------- surfaces -------------------
ring rr1 = 0,(x,y),dp; export rr1;
ideal J = xy,y,x2;
mplot("",J,"-2,1","1,2");
// Paste the output into a Mathematica notebook
// active evalutation of the cell with SHIFT RETURN
kill rr0,rr1;
D.8.2 latex_lib
---------------
Library:
latex.lib
Purpose:
    Typesetting of Singular-Objects in LaTeX2e
Author:
Christian Gorzel, gorzelc@math.uni-muenster.de


Procedures:
* closetex:: writes closing line for LaTeX-document
* opentex:: writes header for LaTeX-file fnm
* tex:: calls LaTeX2e for LaTeX-file fnm
* texdemo:: produces a file explaining the features of this lib
* texfactorize:: creates string in LaTeX-format for factors of poly f
* texmap:: creates string in LaTeX-format for map m:r1->r2
* texname:: creates string in LaTeX-format for identifier
* texobj:: creates string in LaTeX-format for any (basic) type
* texpoly:: creates string in LaTeX-format for poly
* texproc:: creates string in LaTeX-format of text from proc p
* texring:: creates string in LaTeX-format for ring/qring
* rmx:: removes .aux and .log files of LaTeX-files
* xdvi:: calls xdvi for dvi-files
Global variables:
TeXwidth, TeXnofrac, TeXbrack, TeXproj, TeXaligned, TeXreplace, NoDollars
are used to control the typesetting.
Call texdemo(); to obtain a LaTeX2e file texlibdemo.tex
explaining the features of latex.lib and its global variables.
  TeXwidth (int) -1, 0, 1..9, >9:  controls breaking of long polynomials
  TeXnofrac (int) flag:  write 1/2 instead of \frac{1}{2}
  TeXbrack (string) "{", "(", "<", "|", empty string: 
                                   controls brackets around ideals and matrices
  TeXproj (int) flag:  write ":" instead of "," in vectors
  TeXaligned (int) flag:  write maps (and ideals) aligned
  TeXreplace (list) list entries = 2 strings:  replacing symbols
  NoDollars (int) flag:  suppresses surrounding $ signs


D.8.2.1 closetex
................
Procedure from library latex.lib (see latex_lib).

Usage:
closetex(fname); fname string

Return:
nothing; writes a LaTeX2e closing line into file <fname>.

Note:
preceding ">>" are deleted and suffix ".tex" (if not given)
is added to fname.

Example:
LIB "latex.lib";
opentex("exmpl");
texobj("exmpl","{\\large \\bf hello}");
closetex("exmpl");

D.8.2.2 opentex
...............
Procedure from library latex.lib (see latex_lib).

Usage:
opentex(fname); fname string

Return:
nothing; writes a LaTeX2e header into a new file <fname>.

Note:
preceding ">>" are deleted and suffix ".tex" (if not given)
is added to fname.

Example:
LIB "latex.lib";
opentex("exmpl");
texobj("exmpl","hello");
closetex("exmpl");

D.8.2.3 tex
...........
Procedure from library latex.lib (see latex_lib).

Usage:
tex(fname); fname string

Return:
nothing; calls latex (LaTeX2e) for compiling the file fname

Note:
preceding ">>" are deleted and suffix ".tex" (if not given)
is added to fname.

Example:
LIB "latex.lib";
ring r;
ideal I = maxideal(7);
opentex("exp001");              // open latex2e document
texobj("exp001","An ideal ",I);
closetex("exp001");
tex("exp001"); 
==> calling  latex2e  for : exp001.tex 
==> 
==> This is TeX, Version 3.14159 (Web2C 7.3.1)
==> (exp001.tex
==> LaTeX2e <1998/12/01> patch level 1
==> Babel <v3.6x> and hyphenation patterns for american, french, german, nger\
   man, i
==> talian, nohyphenation, loaded.
==> (/usr/share/texmf/tex/latex/base/article.cls
==> Document Class: article 1999/01/07 v1.4a Standard LaTeX document class
==> (/usr/share/texmf/tex/latex/base/size10.clo))
==> (/usr/share/texmf/tex/latex/amslatex/amsmath.sty
==> (/usr/share/texmf/tex/latex/amslatex/amstext.sty
==> (/usr/share/texmf/tex/latex/amslatex/amsgen.sty))
==> (/usr/share/texmf/tex/latex/amslatex/amsbsy.sty)
==> (/usr/share/texmf/tex/latex/amslatex/amsopn.sty))
==> (/usr/share/texmf/tex/latex/amsfonts/amssymb.sty
==> (/usr/share/texmf/tex/latex/amsfonts/amsfonts.sty))
==> No file exp001.aux.
==> (/usr/share/texmf/tex/latex/amsfonts/umsa.fd)
==> (/usr/share/texmf/tex/latex/amsfonts/umsb.fd) [1] (exp001.aux) )
==> Output written on exp001.dvi (1 page, 2912 bytes).
==> Transcript written on exp001.log.
system("sh","rm exp001.*");
==> 0

D.8.2.4 texdemo
...............
Procedure from library latex.lib (see latex_lib).

Usage:
texdemo();

Return:
nothing; generates a LaTeX2e file called texlibdemo.tex
explaining the features of latex.lib and its global variables.

Note:
this proc may take some time.


D.8.2.5 texfactorize
....................
Procedure from library latex.lib (see latex_lib).

Usage:
texfactorize(fname,f); fname string, f poly

Return:
if fname="": string, f as a product of its irreducible
factors

otherwise: append this string to the file <fname>, and
return nothing.

Note:
preceding ">>" are deleted and suffix ".tex" (if not given)
is added to fname.

Example:
LIB "latex.lib";
ring r2 = 13,(x,y),dp;
poly f = (x+1+y)^2*x3y*(2x-2y)*y12;
texfactorize("",f);
==> $-2\cdot x^{3}\cdot y^{13}\cdot (-x+y)\cdot (x+y+1)^{2}$
ring R49 = (7,a),x,dp;
minpoly = a2+a+3;
poly f = (a24x5+x3)*a2x6*(x+1)^2;
f;
==> (a+3)*x13+(2a-1)*x12+(-2a+1)*x10+(-a-3)*x9
texfactorize("",f);
==> $(a+3)\cdot (x-1)\cdot (x+1)^{3}\cdot x^{9}$

D.8.2.6 texmap
..............
Procedure from library latex.lib (see latex_lib).

Usage:
texmap(fname,m,@r1,@r2); fname string, m string/map, @r1,@r2 rings

Return:
if fname="": string, the map m from @r1 to @r2 (preceded
by its name if m = string) in TeX-typesetting;

otherwise: append this string to the file <fname>, and
return nothing.

Note:
preceding ">>" are deleted in fname, and suffix ".tex"
(if not given) is added to fname.
If m is a string then it has to be the name of an existing map
from @r1 to @r2.

Example:
LIB "latex.lib";
// -------- prepare for example ---------
if (defined(TeXaligned)) {int Teali=TeXaligned; kill TeXaligned;}
if (defined(TeXreplace)) {list Terep=TeXreplace; kill TeXreplace;}
// -------- the example starts here ---------
//
string fname = "tldemo";
ring @r1=0,(x,y,z),dp;
if(system("with","Namespaces")) { exportto(Current, @r1); }
else { export @r1; }
==> // ** `@r1` is already global
ring r2=0,(u,v),dp;
map @phi =(@r1,u2,uv -v,v2); export @phi;
==> // ** `@phi` is already global
list TeXreplace;
TeXreplace[1] = list("@phi","\\phi");    // @phi --> \phi
export TeXreplace;
==> // ** `TeXreplace` is already global
texmap("","@phi",@r1,r2);                // standard form
==> $$
==> \begin{array}{rcc}
==> \phi:\Q[x,y,z] & \longrightarrow & \Q[u,v]\\[2mm]
==> \left(x,y,z\right) & \longmapsto & 
==>  \left(
==> \begin{array}{c}
==> u^{2}\\
==> uv-v\\
==> v^{2}
==> \end{array}
==> \right)
==> \end{array}
==> $$
//
int TeXaligned; export TeXaligned;       // map in one line
==> // ** `TeXaligned` is already global
texmap("",@phi,@r1,r2);
==> $\Q[x,y,z]\longrightarrow\Q[u,v], \ \left(x,y,z\right)\longmapsto \left(u\
   ^{2},uv-v,v^{2}\right)$
//
kill @r1,TeXreplace,TeXaligned;
//
// --- restore global variables if previously defined ---
if (defined(Teali)) {int TeXaligned=Teali; export TeXaligned; kill Teali;}
if (defined(Terep)) {list TeXreplace=Terep; export TeXreplace; kill Terep;}

D.8.2.7 texname
...............
Procedure from library latex.lib (see latex_lib).

Usage:
texname(fname,s); fname,s strings

Return:
if fname="": string, the transformed string s, where the
following rules apply:
      s' + "~"             -->  "\\tilde{"+ s' +"}"
     "_" + int             -->       "_{" + int +"}" 
  "[" + s' + "]"           -->      "_{" + s' + "}"
   "A..Z" + int            --> "A..Z" + "^{" + int + "}"    
   "a..z" + int            --> "a..z" + "_{" + int + "}"
"(" + int + "," + s' + ")" --> "_{"+ int +"}" + "^{" + s'+"}"
Anyhow, strings which begin with a "{" are only changed
by deleting the first and last character (intended to remove the
surrounding curly brackets).

if fname!="": append the transformed string s to the file
<fname>, and return nothing.

Note:
preceding ">>" are deleted in fname, and suffix ".tex"
(if not given) is added to fname.

Example:
LIB "latex.lib";
ring r = 0,(x,y),lp;
poly f = 3xy4 + 2xy2 + x5y3 + x + y6;
texname("","{f(10)}");
==> f(10)
texname("","f(10) =");
==> f_{10} =
texname("","n1");
==> n_{1}
texname("","T1_12");
==> T^{1}_{12}
texname("","g'_11");
==> g'_{11}
texname("","f23");
==> f_{23}
texname("","M[2,3]");
==> M_{2,3}
texname("","A(0,3);");
==> A_{0}^{3};
texname("","E~(3)");
==> \tilde{E}_{3}

D.8.2.8 texobj
..............
Procedure from library latex.lib (see latex_lib).

Usage:
texobj(fname,l); fname string, l list

Return:
if fname="": string, the entries of l in LaTeX-typesetting;

otherwise: append this string to the file <fname>, and
return nothing.

Note:
preceding ">>" are deleted in fname, and suffix ".tex"
(if not given) is added to fname.

Example:
LIB "latex.lib";
// -------- prepare for example ---------
if (defined(TeXaligned)) {int Teali=TeXaligned; kill TeXaligned;}
if (defined(TeXbrack)){string Tebra=TeXbrack; kill TeXbrack;}
//
//  --------------  typesetting for polynomials ----------
ring r = 0,(x,y),lp;
poly f = x5y3 + 3xy4 + 2xy2 + y6;
f;
==> x5y3+3xy4+2xy2+y6
texobj("",f);
==> $$\begin{array}{rl}
==> & x^{5}y^{3}+3xy^{4}+2xy^{2}+y^{6}\\
==> \end{array}
==> $$
==> 
//  --------------  typesetting for ideals ----------
ideal G = jacob(f);
G;
==> G[1]=5x4y3+3y4+2y2
==> G[2]=3x5y2+12xy3+4xy+6y5
texobj("",G);
==> $$\left(
==> \begin{array}{c}
==> 5x^{4}y^{3}+3y^{4}+2y^{2}, \\
==> 3x^{5}y^{2}+12xy^{3}+4xy+6y^{5}
==> \end{array}
==> \right)$$
==> 
//  --------------  variation of typesetting for ideals ----------
int TeXaligned = 1; export TeXaligned;
==> // ** `TeXaligned` is already global
string TeXbrack = "<"; export TeXbrack;
==> // ** `TeXbrack` is already global
texobj("",G);
==> $\left<5x^{4}y^{3}+3y^{4}+2y^{2},3x^{5}y^{2}+12xy^{3}+4xy+6y^{5}\right>$
==> 
kill TeXaligned, TeXbrack;
//  --------------  typesetting for matrices ----------
matrix J = jacob(G);
texobj("",J);
==> $$\left(
==> \begin{array}{*{2}{c}}
==> 20x^{3}y^{3} & 15x^{4}y^{2}+12y^{3}+4y \\
==> 15x^{4}y^{2}+12y^{3}+4y & 6x^{5}y+36xy^{2}+4x+30y^{4}
==> \end{array}
==> \right)
==> $$
==> 
//  --------------  typesetting for intmats ----------
intmat m[3][4] = 9,2,4,5,2,5,-2,4,-6,10,-1,2,7;
texobj("",m);
==> $$\left(
==> \begin{array}{*{4}{r}}
==> 9 & 2 & 4 & 5\\
==> 2 & 5 & -2 & 4\\
==> -6 & 10 & -1 & 2
==> \end{array}
==> \right)
==> $$
==> 
//
// --- restore global variables if previously defined ---
if (defined(Teali)){int TeXaligned=Teali; export TeXaligned; kill Teali;}
if (defined(Tebra)){string TeXbrack=Tebra; export TeXbrack; kill Tebra;}

D.8.2.9 texpoly
...............
Procedure from library latex.lib (see latex_lib).

Usage:
texpoly(fname,p); fname string, p poly

Return:
if fname="": string, the poly p in LaTeX-typesetting;

otherwise: append this string to the file <fname>, and
return nothing.

Note:
preceding ">>" are deleted in fname, and suffix ".tex"
(if not given) is added to fname.

Example:
LIB "latex.lib";
ring r0=0,(x,y,z),dp;
poly f = -1x^2 + 2;
texpoly("",f);
==> $-x^{2}+2$
ring rr= real,(x,y,z),dp;
texpoly("",2x2y23z);
==> $2.000x^{2}y^{23}z$
ring r7= 7,(x,y,z),dp;
poly f = 2x2y23z;
texpoly("",f);
==> $2x^{2}y^{23}z$
ring rab =(0,a,b),(x,y,z),dp;
poly f = (-2a2 +b3 -2)/a * x2y4z5 + (a2+1)*x + a+1;
f;
==> (-2a2+b3-2)/(a)*x2y4z5+(a2+1)*x+(a+1)
texpoly("",f);
==> $-\frac{2a^{2}-b^{3}+2}{a}x^{2}y^{4}z^{5}+(a^{2}+1)x+(a+1)$

D.8.2.10 texproc
................
Procedure from library latex.lib (see latex_lib).

Usage:
texproc(fname,pname); fname,pname strings

Assume:
`pname` is a procedure.

Return:
if fname="": string, the proc `pname` in a verbatim
environment in LaTeX-typesetting;

otherwise: append this string to the file <fname>, and
return nothing.

Note:
preceding ">>" are deleted in fname, and suffix ".tex"
(if not given) is added to fname.

texproc cannot be applied to itself correctly.

Example:
LIB "latex.lib";
proc exp(int i,int j,list #)
{ string s;
if (size(#))
{
for(i;i<=j;i++)
{ s = s + string(j) + string(#); }
}
return(s);
}
export exp;
==> // ** `exp` is already global
texproc("","exp");
==> \begin{verbatim}
==> proc exp(int i,int j,list #)
==> { 
==>  string s;
==> if (size(#))
==> {
==> for(i;i<=j;i++)
==> { s = s + string(j) + string(#); }
==> }
==> return(s);
==> 
==> }
==> \end{verbatim}
==> 
kill exp;

D.8.2.11 texring
................
Procedure from library latex.lib (see latex_lib).

Usage:
texring(fname, r[,L]); fname string, r ring, L list

Return:
if fname="": string, the ring in TeX-typesetting;

otherwise: append this string to the file <fname> and
return nothing.

Note:
preceding ">>" are deleted and suffix ".tex" (if not given)
is added to fname.

The optional list L is assumed to be a list of strings which control,
e.g., the symbol for the field of coefficients.

For more details call texdemo(); (generates a LaTeX2e
file called texlibdemo.tex which explains all features of
texring).

Example:
LIB "latex.lib";
ring r0 = 0,(x,y),dp;                // char = 0, polynomial ordering
texring("",r0);
==> $\Q[x,y]$
//
ring r7 =7,(x(0..2)),ds;             // char = 7, local ordering
texring("",r7);
==> $\Z_{7}[[x_{0},x_{1},x_{2}]]$
//
ring r1 = 0,(x1,x2,y1,y2),wp(1,2,3,4);
texring("",r1);
==> $\Q[x_{1},x_{2},y_{1},y_{2}]$
//
ring rr = real,(x),dp;               // real numbers
texring("",rr);
==> $\R[x]$
//
ring rabc =(0,t1,t2,t3),(x,y),dp;    // ring with parameters
texring("",rabc);
==> $\Q(t_{1},t_{2},t_{3})[x,y]$
//
ring ralg = (7,a),(x1,x2),ds;        // algebraic extension
minpoly = a2-a+3;
texring("",ralg);
==> $\Z_{7}(a)[[x_{1},x_{2}]]$
texring("",ralg,"mipo");
==> $\Z_{7}(a)/(a^{2}-a+3)[[x_{1},x_{2}]]$
//
ring r49=(49,a),x,dp;                // Galois field  
texring("",r49);
==> $\F_{49}[x]$
//
setring r0;                          // quotient ring
ideal i = x2-y3;
qring q = std(i);
texring("",q);
==> $\Q[x,y]/\left(y^{3}-x^{2}\right)
==> $
//
// ------------------ additional features -------------------
ring r9 =0,(x(0..9)),ds;
texring("",r9,1);
==> $\Q[[x_{0},\ldots,x_{9}]]$
texring("",r9,"C","{","^G");
==> $\C\{x_{0},x_{1},x_{2},x_{3},x_{4},x_{5},x_{6},x_{7},x_{8},x_{9}\}^G$
//
ring rxy = 0,(x(1..5),y(1..6)),ds;
intvec v = 5,6;
texring("",rxy,v);
==> $\Q[[x_{1},\ldots,x_{5},y_{1},\ldots,y_{6}]]$

D.8.2.12 rmx
............
Procedure from library latex.lib (see latex_lib).

Usage:
rmx(fname); fname string

Return:
nothing; removes the .log and .aux files associated to
the LaTeX file <fname>.


Note:
If fname ends by ".dvi" or ".tex", the
.dvi or .tex file will be deleted, too.

Example:
LIB "latex.lib";
ring r;
poly f = x+y+z;
opentex("exp001");              // defaulted latex2e document
texobj("exp001","A polynom",f);
closetex("exp001");
tex("exp001");
==> calling  latex2e  for : exp001.tex 
==> 
==> This is TeX, Version 3.14159 (Web2C 7.3.1)
==> (exp001.tex
==> LaTeX2e <1998/12/01> patch level 1
==> Babel <v3.6x> and hyphenation patterns for american, french, german, nger\
   man, i
==> talian, nohyphenation, loaded.
==> (/usr/share/texmf/tex/latex/base/article.cls
==> Document Class: article 1999/01/07 v1.4a Standard LaTeX document class
==> (/usr/share/texmf/tex/latex/base/size10.clo))
==> (/usr/share/texmf/tex/latex/amslatex/amsmath.sty
==> (/usr/share/texmf/tex/latex/amslatex/amstext.sty
==> (/usr/share/texmf/tex/latex/amslatex/amsgen.sty))
==> (/usr/share/texmf/tex/latex/amslatex/amsbsy.sty)
==> (/usr/share/texmf/tex/latex/amslatex/amsopn.sty))
==> (/usr/share/texmf/tex/latex/amsfonts/amssymb.sty
==> (/usr/share/texmf/tex/latex/amsfonts/amsfonts.sty))
==> No file exp001.aux.
==> (/usr/share/texmf/tex/latex/amsfonts/umsa.fd)
==> (/usr/share/texmf/tex/latex/amsfonts/umsb.fd) [1] (exp001.aux) )
==> Output written on exp001.dvi (1 page, 308 bytes).
==> Transcript written on exp001.log.
rmx("exp001");   // removes aux and log file of exp001
system("sh","rm exp001.*");
==> 0

D.8.2.13 xdvi
.............
Procedure from library latex.lib (see latex_lib).

Usage:
xdvi(fname[,style]); fname,style = string

Return:
nothing; displays dvi-file fname.dvi with previewer xdvi

Note:
ending .dvi may miss in fname

style overwrites the default setting xdvi

Example:
LIB "latex.lib";
intmat m[3][4] = 9,2,4,5,2,5,-2,4,-6,10,-1,2,7;
opentex("exp001"); 
texobj("exp001","An intmat:  ",m);
closetex("exp001");
tex("exp001");
==> calling  latex2e  for : exp001.tex 
==> 
==> This is TeX, Version 3.14159 (Web2C 7.3.1)
==> (exp001.tex
==> LaTeX2e <1998/12/01> patch level 1
==> Babel <v3.6x> and hyphenation patterns for american, french, german, nger\
   man, i
==> talian, nohyphenation, loaded.
==> (/usr/share/texmf/tex/latex/base/article.cls
==> Document Class: article 1999/01/07 v1.4a Standard LaTeX document class
==> (/usr/share/texmf/tex/latex/base/size10.clo))
==> (/usr/share/texmf/tex/latex/amslatex/amsmath.sty
==> (/usr/share/texmf/tex/latex/amslatex/amstext.sty
==> (/usr/share/texmf/tex/latex/amslatex/amsgen.sty))
==> (/usr/share/texmf/tex/latex/amslatex/amsbsy.sty)
==> (/usr/share/texmf/tex/latex/amslatex/amsopn.sty))
==> (/usr/share/texmf/tex/latex/amsfonts/amssymb.sty
==> (/usr/share/texmf/tex/latex/amsfonts/amsfonts.sty))
==> No file exp001.aux.
==> (/usr/share/texmf/tex/latex/amsfonts/umsa.fd)
==> (/usr/share/texmf/tex/latex/amsfonts/umsb.fd) [1] (exp001.aux) )
==> Output written on exp001.dvi (1 page, 524 bytes).
==> Transcript written on exp001.log.
xdvi("exp001");
==> calling  xdvi  for : exp001 
==> 
system("sh","rm exp001.*");
==> 0
D.8.3 paramet_lib
-----------------
Library:
paramet.lib
Purpose:
   Parametrization of Varieties
Author:
Thomas Keilen, keilen@mathematik.uni-kl.de


Procedures:
* parametrize:: parametrizes a prime ideal via the normalization
* parametrizepd:: calculates the prim.dec. and parametrizes the components
* parametrizesing:: parametrizes an isolated plane curve singularity
Overview:
A library to compute parametrizations of algebraic varieties (if possible)
with the aid of a normalization, or a primary decomposition, resp. to compute
a parametrization of a plane curve singularity with the aid of a
Hamburger-Noether expansion.



D.8.3.1 parametrize
...................
Procedure from library paramet.lib (see paramet_lib).

Usage:
parametrize(I); I ideal in an arbitrary number of variables,
whose radical is prime, in a ring with global ordering

Create:
If the parametrization is successful, the basering will be changed to
the parametrization ring, that is to the ring PR=0,(s,t),dp;
respectively PR=0,t(1..d),dp;, depending on the dimension of the
parametrized variety.

Return:
a list containing the parametrization ideal resp. the original ideal,
the number of variables needed for the parametrization resp. 0, and
1 resp. 0 depending on whether the parametrization was successful
or not

Example:
LIB "paramet.lib";
ring RING=0,(x,y,z),dp;
ideal I=z2-y2x2+x3;
parametrize(I);
==> [1]:
==>    _[1]=s2-t2
==>    _[2]=s
==>    _[3]=s2t-t3
==> [2]:
==>    2
==> [3]:
==>    1


D.8.3.2 parametrizepd
.....................
Procedure from library paramet.lib (see paramet_lib).

Usage:
parametrizepd(I); I ideal in a polynomial ring with global ordering

Create:
If the parametrization is successful, the basering will be changed to
the parametrization ring, that is to the ring PR=0,(s,t),dp;
respectively PR=0,t(1..d),dp;, depending on the dimension of the
parametrized variety.

Return:
a list of lists, where each entry contains the parametrization
of a primary component of I resp. 0, the number of variables
resp. 0, and 1 resp. 0 depending on whether the parametrization
of the component was successful or not

Example:
LIB "paramet.lib";
ring RING=0,(x,y,z),dp;
ideal I=(x2-y2z2+z3)*(x2-z2-z3),(x2-y2z2+z3)*yz;
parametrizepd(I);
==> [1]:
==>    [1]:
==>       _[1]=s2t-t3
==>       _[2]=s
==>       _[3]=s2-t2
==>    [2]:
==>       2
==>    [3]:
==>       1
==> [2]:
==>    [1]:
==>       _[1]=0
==>       _[2]=s
==>       _[3]=0
==>    [2]:
==>       1
==>    [3]:
==>       1
==> [3]:
==>    [1]:
==>       _[1]=s3-s
==>       _[2]=0
==>       _[3]=s2-1
==>    [2]:
==>       1
==>    [3]:
==>       1


D.8.3.3 parametrizesing
.......................
Procedure from library paramet.lib (see paramet_lib).

Usage:
parametrizesing(f); f a polynomial in two variables, ordering ls or ds

Create:
If the parametrization is successful, the basering will be changed to
the parametrization ring, that is to the ring 0,(x,y),ls;

Return:
a list containing the parametrizations of the different branches of the
singularity at the origin resp. 0, if f was not of the desired kind

Example:
LIB "paramet.lib";
ring RING=0,(x,y),ls;
poly f=(x^2-y^3)*(x^2-y^2-y^3);
parametrizesing(f);
==> [1]:
==>    _[1]=x
==>    _[2]=x-1/2x2
==> [2]:
==>    _[1]=x
==>    _[2]=-x-1/2x2
==> [3]:
==>    _[1]=x3
==>    _[2]=x2

D.8.4 surf_lib
--------------
Library:
surf.lib
Purpose:
    Procedures for Graphics with Surf
Author:
Hans Schoenemann,

the program surf is written by Stefan Endrass

Note:
To use this library requires the program surf to be installed.
 surf is only available for Linux PCs and Sun workstations.
 You can download surf either from
  <http://sourceforge.net/projects/surf>
  or from <ftp://www.mathematik.uni-kl.de/pub/Math/Singular/utils/>.


Procedures:
* plot:: plots plane curves and surfaces

D.8.4.1 plot
............
Procedure from library surf.lib (see surf_lib).

Usage:
plot(I); I ideal or poly

Assume:
I defines a plane curve or a surface given by one equation

Return:
nothing

Note:
requires the external program 'surf' to be installed

Example:
LIB "surf.lib";
// ---------  plane curves ------------
ring rr0 = 0,(x1,x2),dp;
ideal I = x1^3 - x2^2;
plot(I);
ring rr1 = 0,(x,y,z),dp;
ideal I(1) = 2x2-1/2x3 +1-y+1;
plot(I(1));
//  ---- Singular Logo --------------
poly logo = ((x+3)^3 + 2*(x+3)^2 - y^2)*(x^3 - y^2)*((x-3)^3-2*(x-3)^2-y^2);
plot(logo);
// Steiner surface
ideal J(2) = x^2*y^2+x^2*z^2+y^2*z^2-17*x*y*z;
plot(J(2));
// --------------------
plot(x*(x2-y2)+z2);
// E7
plot(x^3-x*y^3+z^2);
// Whitney umbrella
plot(z^2-x^2*y);

D.9 Coding theory
=================

* brnoeth_lib:: Brill-Noether algorithm, Weierstrass semigroups and AG codes

D.9.1 brnoeth_lib
-----------------
Library:
brnoeth.lib
Purpose:
  Brill-Noether Algorithm, Weierstrass-SG and AG-codes
Authors:
Jose Ignacio Farran Martin, ignfar@eis.uva.es

Christoph Lossen, lossen@mathematik.uni-kl.de

Overview:
Implementation of the Brill-Noether algorithm for solving the
Riemann-Roch problem and applications in Algebraic Geometry codes.
The computation of Weierstrass semigroups is also implemented.

The procedures are intended only for plane (singular) curves defined over
a prime field of positive characteristic.

For more information about the library see the end of the file brnoeth.lib.


Main procedures:
* Adj_div:: computes the conductor of a curve
* NSplaces:: computes non-singular places with given degrees
* BrillNoether:: computes a vector space basis of the linear system L(D)
* Weierstrass:: computes the Weierstrass semigroup of C at P up to m
* extcurve:: extends the curve C to an extension of degree d
* AGcode_L:: computes the evaluation AG code with divisors G and D
* AGcode_Omega:: computes the residual AG code with divisors G and D
* prepSV:: preprocessing for the basic decoding algorithm
* decodeSV:: decoding of a word with the basic decoding algorithm
Auxiliary procedures:
* closed_points:: computes the zero-set of a zero-dim. ideal in 2 vars
* dual_code:: computes the dual code
* sys_code:: computes an equivalent systematic code
* permute_L:: applies a permutation to a list


D.9.1.1 Adj_div
...............
Procedure from library brnoeth.lib (see brnoeth_lib).

Usage:
Adj_div( f [,l] ); f a poly, [l a list]

Return:
list L with the computed data:
    L[1] a list of rings: L[1][1]=aff_r (affine), L[1][2]=Proj_R (projective),
  L[2] an intvec with 2 entries (degree, genus),
  L[3] a list of intvec (closed places),
  L[4] an intvec (conductor),
  L[5] a list of lists:
     L[5][d][1] a (local) ring over an extension of degree d,
     L[5][d][2] an intvec (degrees of base points of places of degree d)
  

Note:
Adj_div(f); computes and stores the fundamental data of the
plane curve defined by f as needed for AG codes.

In the affine ring you can find the following data:
      poly CHI:  affine equation of the curve,
   ideal Aff_SLocus:  affine singular locus (std),
   list Inf_Points:  points at infinity
            Inf_Points[1]:  singular points
            Inf_Points[2]:  non-singular points,
   list Aff_SPoints:  affine singular points (if not empty).
   
In the projective ring you can find the projective equation
CHI of the curve (poly).

In the local rings L[5][d][1] you find:
      list POINTS:  base points of the places of degree d,
   list LOC_EQS:  local equations of the curve at the base points,
   list BRANCHES:  Hamburger-Noether developments of the places,
   list PARAMETRIZATIONS:  local parametrizations of the places,
   
Each entry of the list L[3] corresponds to one closed place (i.e.,
a place and all its conjugates) which is represented by an intvec
of size two, the first entry is the degree of the place (in
particular, it tells the local ring where to find the data
describing one representative of the closed place), and the
second one is the position of those data in the lists POINTS, etc.,
inside this local ring.

In the intvec L[4] (conductor) the i-th entry corresponds to the
i-th entry in the list of places L[3].

With no optional arguments, the conductor is computed by
local invariants of the singularities; otherwise it is computed
by the Dedekind formula. 

An affine point is represented by a list P where P[1] is std
of a prime ideal and P[2] is an intvec containing the position
of the places above P in the list of closed places L[3]. 

If the point is at infinity, P[1] is a homogeneous irreducible
polynomial in two variables.

If printlevel>=0 additional comments are displayed (default:
printlevel=0).

Example:
LIB "brnoeth.lib";
int plevel=printlevel;
printlevel=-1;
ring s=2,(x,y),lp;
list C=Adj_div(y9+y8+xy6+x2y3+y2+x3);
==> The genus of the curve is 3
def aff_R=C[1][1];      // the affine ring
setring aff_R;
listvar(aff_R);         // data in the affine ring
==> // aff_R                [0]  *ring
==> // Inf_Points           [0]  list, size: 2
==> // Aff_SPoints          [0]  list, size: 3
==> // Aff_SLocus           [0]  ideal (SB), 2 generator(s)
==> // CHI                  [0]  poly
CHI;                    // affine equation of the curve
==> x3+x2y3+xy6+y9+y8+y2
Aff_SLocus;             // ideal of the affine singular locus
==> Aff_SLocus[1]=y8+y2
==> Aff_SLocus[2]=x2+y6
Aff_SPoints[1];         // 1st affine singular point: (1:1:1), no.1
==> [1]:
==>    _[1]=y2+y+1
==>    _[2]=x+1
==> [2]:
==>    1
Inf_Points[1];          // singular point(s) at infinity: (1:0:0), no.4
==> [1]:
==>    [1]:
==>       y
==>    [2]:
==>       4
Inf_Points[2];          // list of non-singular points at infinity
==> empty list
//
def proj_R=C[1][2];     // the projective ring
setring proj_R;
CHI;                    // projective equation of the curve
==> x3z6+x2y3z4+xy6z2+y9+y8z+y2z7
C[2][1];                // degree of the curve
==> 9
C[2][2];                // genus of the curve
==> 3
C[3];                   // list of computed places
==> [1]:
==>    2,1
==> [2]:
==>    1,1
==> [3]:
==>    1,2
==> [4]:
==>    1,3
C[4];                   // adjunction divisor (all points are singular!)
==> 2,2,2,42
//
// we look at the place(s) of degree 2 by changing to the ring
C[5][2][1];
==> //   characteristic : 2
==> //   1 parameter    : a 
==> //   minpoly        : ...
==> //   number of vars : 3
==> //        block   1 : ordering ls
==> //                  : names    x y t 
==> //        block   2 : ordering C
def S(2)=C[5][2][1];
setring S(2);
POINTS;                // base point(s) of place(s) of degree 2: (1:a:1)
==> [1]:
==>    [1]:
==>       1
==>    [2]:
==>       (a)
==>    [3]:
==>       1
LOC_EQS;               // local equation(s)
==> [1]:
==>    y2+y3+(a+1)*y4+y6+(a+1)*y8+y9+(a)*xy2+(a+1)*xy4+xy6+(a+1)*x2y+(a)*x2y2\
   +x2y3+x3
PARAMETRIZATIONS;      // parametrization(s) and exactness
==> [1]:
==>    [1]:
==>       _[1]=t2+(a+1)*t3
==>       _[2]=t3+(a+1)*t4
==>    [2]:
==>       3,4
BRANCHES;              // Hamburger-Noether development
==> [1]:
==>    [1]:
==>       _[1,1]=0
==>       _[1,2]=x
==>       _[1,3]=0
==>       _[2,1]=0
==>       _[2,2]=1
==>       _[2,3]=(a+1)
==>    [2]:
==>       1,-4
==>    [3]:
==>       0
==>    [4]:
==>       y+(a+1)*xy+(a)*x2y+(a)*x2y2+(a+1)*x3+x3y+x3y3+(a)*x4+(a+1)*x4y2+(a+\
   1)*x4y3+x5+x5y2+(a)*x6+(a+1)*x6y2+x6y4+x6y5+x7y+(a+1)*x8+(a+1)*x8y+x8y4+(\
   a+1)*x8y6+x9+x9y7+(a+1)*x10+x11y6+(a+1)*x12y4+x13y5+x14+x14y+x15y4+x16+(a\
   +1)*x16y2+x17y3+x19y2+(a+1)*x20+x21y+x23
printlevel=plevel;


D.9.1.2 NSplaces
................
Procedure from library brnoeth.lib (see brnoeth_lib).

Usage:
NSplaces( h, CURVE ), where h is an intvec and CURVE is a list

Return:
list L with updated data of CURVE after computing all non-singular
affine closed places whose degrees are in the intvec h: 

      in L[1][1]: (affine ring) lists Aff_Points(d) with affine non-singular
               (closed) points of degree d (if non-empty),
   in L[3]:    the newly computed closed places are added,
   in L[5]:    local rings created/updated to store (repres. of) new places.
   
See Adj_div for a description of the entries in L.

Note:
The list_expression should be the output of the procedure Adj_div.

If printlevel>=0 additional comments are displayed (default:
printlevel=0).

Example:
LIB "brnoeth.lib";
int plevel=printlevel;
printlevel=-1;
ring s=2,(x,y),lp;
list C=Adj_div(x3y+y3+x);
==> The genus of the curve is 3
// The list of computed places:
C[3];
==> [1]:
==>    1,1
==> [2]:
==>    1,2
// create places up to degree 4
list L=NSplaces(1..4,C);
// The list of computed places is now:
L[3];
==> [1]:
==>    1,1
==> [2]:
==>    1,2
==> [3]:
==>    1,3
==> [4]:
==>    2,1
==> [5]:
==>    3,1
==> [6]:
==>    3,2
==> [7]:
==>    3,3
==> [8]:
==>    3,4
==> [9]:
==>    3,5
==> [10]:
==>    3,6
==> [11]:
==>    3,7
==> [12]:
==>    4,1
==> [13]:
==>    4,2
==> [14]:
==>    4,3
// e.g., affine non-singular points of degree 4 :
def aff_r=L[1][1];
setring aff_r;
Aff_Points(4);
==> [1]:
==>    [1]:
==>       _[1]=y2+y+1
==>       _[2]=x2+xy+x+1
==>    [2]:
==>       12
==> [2]:
==>    [1]:
==>       _[1]=y4+y3+y2+y+1
==>       _[2]=x+y2+y+1
==>    [2]:
==>       13
==> [3]:
==>    [1]:
==>       _[1]=y4+y3+1
==>       _[2]=x+y3+y
==>    [2]:
==>       14
// e.g., base point of the 1st place of degree 4 :
def S(4)=L[5][4][1];
setring S(4);
POINTS[1];
==> [1]:
==>    (a3)
==> [2]:
==>    (a2+a)
==> [3]:
==>    1
printlevel=plevel;


D.9.1.3 BrillNoether
....................
Procedure from library brnoeth.lib (see brnoeth_lib).

Usage:
BrillNoether(G,CURVE); G an intvec, CURVE a list

Return:
list of ideals (each of them with two homogeneous generators,
which represent the numerator, resp. denominator, of a rational
function).

The corresponding rational functions form a vector basis of the
linear system L(G), G a rational divisor over a non-singular curve.

Note:
The procedure must be called from the ring CURVE[1][2], where
CURVE is the output of the procedure NSplaces. 

The intvec G represents a rational divisor supported on the closed
places of CURVE[3] (e.g. G=2,0,-1; means 2 times the closed
place 1 minus 1 times the closed place 3).

Example:
LIB "brnoeth.lib";
int plevel=printlevel;
printlevel=-1;
ring s=2,(x,y),lp;
list C=Adj_div(x3y+y3+x);
==> The genus of the curve is 3
C=NSplaces(1..4,C);
// the first 3 Places in C[3] are of degree 1.
// we define the rational divisor G = 4*C[3][1]+4*C[3][3] (of degree 8):
intvec G=4,0,4;
def R=C[1][2];
setring R;
list LG=BrillNoether(G,C);
==> Vector basis successfully computed 
// here is the vector basis of L(G):
LG;
==> [1]:
==>    _[1]=1
==>    _[2]=1
==> [2]:
==>    _[1]=y
==>    _[2]=x
==> [3]:
==>    _[1]=z
==>    _[2]=x
==> [4]:
==>    _[1]=y2
==>    _[2]=x2
==> [5]:
==>    _[1]=xz2+y3
==>    _[2]=x3
==> [6]:
==>    _[1]=xyz2+y4
==>    _[2]=x4
printlevel=plevel;


D.9.1.4 Weierstrass
...................
Procedure from library brnoeth.lib (see brnoeth_lib).

Usage:
Weierstrass( i, m, CURVE ); i,m integers and CURVE a list

Return:
list WS of two lists:
    WS[1] list of integers (Weierstr. semigroup of the curve at place i up to m)
  WS[2] list of ideals (the associated rational functions)
  

Note:
The procedure must be called from the ring CURVE[1][2],
where CURVE is the output of the procedure NSplaces.

 i represents the place CURVE[3][i].

 Rational functions are represented by numerator/denominator
in form of ideals with two homogeneous generators.

Warning:
The place must be rational, i.e., necessarily CURVE[3][i][1]=1. 


Example:
LIB "brnoeth.lib";
int plevel=printlevel;
printlevel=-1;
ring s=2,(x,y),lp;
list C=Adj_div(x3y+y3+x);
==> The genus of the curve is 3
C=NSplaces(1..4,C);
def R=C[1][2];
setring R;
// Place C[3][1] has degree 1 (i.e it is rational);
list WS=Weierstrass(1,7,C);
==> Vector basis successfully computed 
// the first part of the list is the Weierstrass semigroup up to 7 :
WS[1];
==> [1]:
==>    0
==> [2]:
==>    3
==> [3]:
==>    5
==> [4]:
==>    6
==> [5]:
==>    7
// and the second part are the corresponding functions :
WS[2];
==> [1]:
==>    _[1]=1
==>    _[2]=1
==> [2]:
==>    _[1]=y
==>    _[2]=z
==> [3]:
==>    _[1]=xy
==>    _[2]=z2
==> [4]:
==>    _[1]=y2
==>    _[2]=z2
==> [5]:
==>    _[1]=y3
==>    _[2]=xz2
printlevel=plevel;


D.9.1.5 extcurve
................
Procedure from library brnoeth.lib (see brnoeth_lib).

Usage:
extcurve( d, CURVE ); d an integer, CURVE a list

Return:
list L which is the update of the list CURVE with additional entries
      L[1][3]: ring (p,a),(x,y),lp (affine),
   L[1][4]: ring (p,a),(x,y,z),lp (projective),
   L[1][5]: ring (p,a),(x,y,t),ls (local),
   L[2][3]: int  (the number of rational places),
   
the rings being defined over a field extension of degree d. 

If d<2 then extcurve(d,CURVE); creates a list L which
is the update of the list CURVE with additional entries
      L[1][5]: ring p,(x,y,t),ls,
   L[2][3]: int  (the number of computed places over the base field).
   
In both cases, in the ring L[1][5] lists with the data for all the
computed rational places (after a field extension of degree d) are
created (see Adj_div):
      lists POINTS, LOC_EQS, BRANCHES, PARAMETRIZATIONS.
   

Note:
The list CURVE should be the output of NSplaces,
and must contain (at least) one place of degree d. 

You actually need all the places with degree dividing d.
Otherwise, not all the places are computed, but only part of them. 

This procedure must be executed before constructing AG codes,
even if no extension is needed. The ring L[1][4] must be active
when constructing codes over the field extension.


Example:
LIB "brnoeth.lib";
int plevel=printlevel;
printlevel=-1;
ring s=2,(x,y),lp;
list C=Adj_div(x5+y2+y);
==> The genus of the curve is 2
C=NSplaces(1..4,C);
// since we have all points up to degree 4, we can extend the curve
// to that extension, in order to get rational points over F_16;
C=extcurve(4,C);
==> Total number of rational places : NrRatPl = 33
// e.g., display the basepoint of place no. 32:
def R=C[1][5];
setring R;
POINTS[32];
==> [1]:
==>    (a3+a2+a+1)
==> [2]:
==>    (a2+a)
==> [3]:
==>    1
printlevel=plevel;


D.9.1.6 AGcode_L
................
Procedure from library brnoeth.lib (see brnoeth_lib).

Usage:
AGcode_L( G, D, EC ); G,D intvec, EC a list

Return:
a generator matrix for the evaluation AG code defined by the
divisors G and D.

Note:
The procedure must be called within the ring EC[1][4],
where EC is the output of extcurve(d) (or within
the ring EC[1][2] if d=1). 

The entry i in the intvec D refers to the i-th rational
place in EC[1][5] (i.e., to POINTS[i], etc., see extcurve).

The intvec G represents a rational divisor (see BrillNoether
for more details).

The code evaluates the vector basis of L(G) at the rational
places given by D.

Warnings:
G should satisfy 
, which is
not checked by the algorithm.

G and D should have disjoint supports (checked by the algorithm).

Example:
LIB "brnoeth.lib";
int plevel=printlevel;
printlevel=-1;
ring s=2,(x,y),lp;
list HC=Adj_div(x3+y2+y);
==> The genus of the curve is 1
HC=NSplaces(1..2,HC);
HC=extcurve(2,HC);
==> Total number of rational places : NrRatPl = 9
def ER=HC[1][4];
setring ER;
intvec G=5;      // the rational divisor G = 5*HC[3][1]
intvec D=2..9;   // D = sum of the rational places no. 2..9 over F_4
// let us construct the corresponding evaluation AG code :
matrix C=AGcode_L(G,D,HC);
==> Vector basis successfully computed 
// here is a linear code of type [8,5,>=3] over F_4
print(C);
==> 0,0,(a),  (a+1),1,  1,    (a+1),(a),  
==> 1,0,(a),  (a+1),(a),(a+1),(a),  (a+1),
==> 1,1,1,    1,    1,  1,    1,    1,    
==> 0,0,(a+1),(a),  1,  1,    (a),  (a+1),
==> 0,0,(a+1),(a),  (a),(a+1),1,    1     
printlevel=plevel;


D.9.1.7 AGcode_Omega
....................
Procedure from library brnoeth.lib (see brnoeth_lib).

Usage:
AGcode_Omega( G, D, EC ); G,D intvec, EC a list

Return:
a generator matrix for the residual AG code defined by the
divisors G and D.

Note:
The procedure must be called within the ring EC[1][4],
where EC is the output of extcurve(d) (or within
the ring EC[1][2] if d=1). 

The entry i in the intvec D refers to the i-th rational
place in EC[1][5] (i.e., to POINTS[i], etc., see extcurve).

The intvec G represents a rational divisor (see BrillNoether
for more details).

The code computes the residues of a vector space basis of

 at the rational places given by D.

Warnings:
G should satisfy 
, which is
not checked by the algorithm.

G and D should have disjoint supports (checked by the algorithm).

Example:
LIB "brnoeth.lib";
int plevel=printlevel;
printlevel=-1;
ring s=2,(x,y),lp;
list HC=Adj_div(x3+y2+y);
==> The genus of the curve is 1
HC=NSplaces(1..2,HC);
HC=extcurve(2,HC);
==> Total number of rational places : NrRatPl = 9
def ER=HC[1][4];
setring ER;
intvec G=5;      // the rational divisor G = 5*HC[3][1]
intvec D=2..9;   // D = sum of the rational places no. 2..9 over F_4
// let us construct the corresponding residual AG code :
matrix C=AGcode_Omega(G,D,HC);
==> Vector basis successfully computed 
// here is a linear code of type [8,3,>=5] over F_4
print(C);
==> 0,    (a),(a),(a),  (a+1),1,0,  0,
==> (a+1),1,  (a),0,    (a),  0,(a),0,
==> (a+1),0,  (a),(a+1),(a+1),0,0,  1 
printlevel=plevel;


D.9.1.8 prepSV
..............
Procedure from library brnoeth.lib (see brnoeth_lib).

Usage:
prepSV( G, D, F, EC ); G,D,F intvecs and EC a list

Return:
list E of size n+3, where n=size(D). All its entries but E[n+3]
are matrices:
      E[1]:  parity check matrix for the current AG code
   E[2] ... E[n+2]:  matrices used in the procedure decodeSV
   E[n+3]:  intvec with
       E[n+3][1]: correction capacity 
 of the algorithm
       E[n+3][2]: designed Goppa distance 
 of the current AG code
   

Note:
Computes the preprocessing for the basic (Skorobogatov-Vladut)
decoding algorithm.

The procedure must be called within the ring EC[1][4], where EC is
the output of extcurve(d) (or in the ring EC[1][2] if d=1) 

The intvec G and F represent rational divisors (see
BrillNoether for more details).

The intvec D refers to rational places (see AGcode_Omega
for more details.).
The current AG code is AGcode_Omega(G,D,EC).

If you know the exact minimum distance d and you want to use it in
decodeSV instead of 
, you can change the value
of E[n+3][2] to d before applying decodeSV.

If you have a systematic encoding for the current code and want to
keep it during the decoding, you must previously permute D (using
permute_L(D,P);), e.g., according to the permutation
P=L[3], L being the output of sys_code.

Warnings:
F must be a divisor with support disjoint from the support of D and
with degree 
, where

.

G should satisfy 
, which is
not checked by the algorithm.

G and D should also have disjoint supports (checked by the
algorithm).

Example:
LIB "brnoeth.lib";
int plevel=printlevel;
printlevel=-1;
ring s=2,(x,y),lp;
list HC=Adj_div(x3+y2+y);
==> The genus of the curve is 1
HC=NSplaces(1..2,HC);
HC=extcurve(2,HC);
==> Total number of rational places : NrRatPl = 9
def ER=HC[1][4];
setring ER;
intvec G=5;      // the rational divisor G = 5*HC[3][1]
intvec D=2..9;   // D = sum of the rational places no. 2..9 over F_4
// construct the corresp. residual AG code of type [8,3,>=5] over F_4:
matrix C=AGcode_Omega(G,D,HC);
==> Vector basis successfully computed 
// we can correct 1 error and the genus is 1, thus F must have degree 2
// and support disjoint from that of D;
intvec F=2;
list SV=prepSV(G,D,F,HC);
==> Vector basis successfully computed 
==> Vector basis successfully computed 
==> Vector basis successfully computed 
// now everything is prepared to decode with the basic algorithm;
// for example, here is a parity check matrix to compute the syndrome :
print(SV[1]);
==> 0,0,(a),  (a+1),1,  1,    (a+1),(a),  
==> 1,0,(a),  (a+1),(a),(a+1),(a),  (a+1),
==> 1,1,1,    1,    1,  1,    1,    1,    
==> 0,0,(a+1),(a),  1,  1,    (a),  (a+1),
==> 0,0,(a+1),(a),  (a),(a+1),1,    1     
// and here you have the correction capacity of the algorithm :
int epsilon=SV[size(D)+3][1];
epsilon;
==> 1
printlevel=plevel;


D.9.1.9 decodeSV
................
Procedure from library brnoeth.lib (see brnoeth_lib).

Usage:
decodeSV( y, K ); y a row-matrix and K a list

Return:
a codeword (row-matrix) if possible, resp. the 0-matrix (of size
1) if decoding is impossible.

For decoding the basic (Skorobogatov-Vladut) decoding algorithm
is applied.

Note:
The list_expression should be the output K of the procedure
prepSV.

The matrix_expression should be a (1 x n)-matrix, where
n = ncols(K[1]).

The decoding may fail if the number of errors is greater than
the correction capacity of the algorithm.

Example:
LIB "brnoeth.lib";
int plevel=printlevel;
printlevel=-1;
ring s=2,(x,y),lp;
list HC=Adj_div(x3+y2+y);
==> The genus of the curve is 1
HC=NSplaces(1..2,HC);
HC=extcurve(2,HC);
==> Total number of rational places : NrRatPl = 9
def ER=HC[1][4];
setring ER;
intvec G=5;      // the rational divisor G = 5*HC[3][1]
intvec D=2..9;   // D = sum of the rational places no. 2..9 over F_4
// construct the corresp. residual AG code of type [8,3,>=5] over F_4:
matrix C=AGcode_Omega(G,D,HC);
==> Vector basis successfully computed 
// we can correct 1 error and the genus is 1, thus F must have degree 2
// and support disjoint from that of D
intvec F=2;
list SV=prepSV(G,D,F,HC);
==> Vector basis successfully computed 
==> Vector basis successfully computed 
==> Vector basis successfully computed 
// now we produce 1 error on the zero-codeword :
matrix y[1][8];
y[1,3]=a;
// and then we decode :
print(decodeSV(y,SV));
==> 0,0,0,0,0,0,0,0
printlevel=plevel;


D.9.1.10 closed_points
......................
Procedure from library brnoeth.lib (see brnoeth_lib).

Usage:
closed_points(I); I an ideal

Return:
list of prime ideals (each a Groebner basis), corresponding to
the (distinct affine closed) points of V(I)

Note:
The ideal must have dimension 0, the basering must have 2
variables, the ordering must be lp, and the base field must
be finite and prime.

It might be convenient to set the option(redSB) in advance.

Example:
LIB "brnoeth.lib";
ring s=2,(x,y),lp;
// this is just the affine plane over F_4 :
ideal I=x4+x,y4+y;
list L=closed_points(I);
// and here you have all the points :
L;
==> [1]:
==>    _[1]=y2+y+1
==>    _[2]=x+y
==> [2]:
==>    _[1]=y2+y+1
==>    _[2]=x+1
==> [3]:
==>    _[1]=y2+y+1
==>    _[2]=x+y+1
==> [4]:
==>    _[1]=y2+y+1
==>    _[2]=x
==> [5]:
==>    _[1]=y+1
==>    _[2]=x2+x+1
==> [6]:
==>    _[1]=y+1
==>    _[2]=x+1
==> [7]:
==>    _[1]=y+1
==>    _[2]=x
==> [8]:
==>    _[1]=y
==>    _[2]=x2+x+1
==> [9]:
==>    _[1]=y
==>    _[2]=x+1
==> [10]:
==>    _[1]=y
==>    _[2]=x


D.9.1.11 dual_code
..................
Procedure from library brnoeth.lib (see brnoeth_lib).

Usage:
dual_code(G); G a matrix of numbers

Return:
a generator matrix of the dual code generated by G

Note:
The input should be a matrix G of numbers. 

The output is also a parity check matrix for the code defined by G

Example:
LIB "brnoeth.lib";
ring s=2,T,lp;
// here is the Hamming code of length 7 and dimension 3
matrix G[3][7]=1,0,1,0,1,0,1,0,1,1,0,0,1,1,0,0,0,1,1,1,1;
print(G);
==> 1,0,1,0,1,0,1,
==> 0,1,1,0,0,1,1,
==> 0,0,0,1,1,1,1 
matrix H=dual_code(G);
print(H);
==> 1,1,1,0,0,0,0,
==> 1,0,0,1,1,0,0,
==> 0,1,0,1,0,1,0,
==> 1,1,0,1,0,0,1 

D.9.1.12 sys_code
.................
Procedure from library brnoeth.lib (see brnoeth_lib).

Usage:
sys_code(C); C is a matrix of constants

Return:
list L with:
      L[1] is the generator matrix in standard form of an equivalent code,
   L[2] is the parity check matrix in standard form of such code,
   L[3] is an intvec which represents the needed permutation.
   

Note:
Computes a systematic code which is equivalent to the given one.

The input should be a matrix of numbers.

The output has to be interpreted as follows: if the input was
the generator matrix of an AG code then one should apply the
permutation L[3] to the divisor D of rational points by means
of permute_L(D,L[3]); before continuing to work with the
code (for instance, if you want to use the systematic encoding
together with a decoding algorithm).

Example:
LIB "brnoeth.lib";
ring s=3,T,lp;
matrix C[2][5]=0,1,0,1,1,0,1,0,0,1;
print(C);
==> 0,1,0,1,1,
==> 0,1,0,0,1 
list L=sys_code(C);
L[3];
==> 2,4,3,1,5
// here is the generator matrix in standard form
print(L[1]);
==> 1,0,0,0,1,
==> 0,1,0,0,0 
// here is the control matrix in standard form
print(L[2]);
==> 0, 0,1,0,0,
==> 0, 0,0,1,0,
==> -1,0,0,0,1 
// we can check that both codes are dual to each other
print(L[1]*transpose(L[2]));
==> 0,0,0,
==> 0,0,0 


D.9.1.13 permute_L
..................
Procedure from library brnoeth.lib (see brnoeth_lib).

Usage:
permute_L( L, P ); L,P either intvecs or lists

Return:
list obtained from L by applying the permutation given by P.

Note:
If P is a list, all entries must be integers.

Example:
LIB "brnoeth.lib";
list L=list();
L[1]="a";
L[2]="b";
L[3]="c";
L[4]="d";
intvec P=1,3,4,2;
// the list L is permuted according to P :
permute_L(L,P);
==> [1]:
==>    a
==> [2]:
==>    c
==> [3]:
==>    d
==> [4]:
==>    b

