source: git/Singular/LIB/normaliz.lib @ 4c20ee

spielwiese
Last change on this file since 4c20ee was 4c20ee, checked in by Hans Schoenemann <hannes@…>, 11 years ago
fix: new version numbers for libs
  • Property mode set to 100644
File size: 49.6 KB
Line 
1// Singular library normaliz.lib
2
3version="version normaliz.lib 4.0.0.0 Jun_2013 ";
4category="Commutative algebra"
5info="
6LIBRARY: normaliz.lib  Provides an interface for the use of Normaliz 2.7
7         within SINGULAR.
8AUTHORS:  Winfried Bruns, Winfried.Bruns@Uni-Osnabrueck.de
9          Christof Soeger, Christof.Soeger@Uni-Osnabrueck.de
10
11OVERVIEW:
12The library normaliz.lib provides an interface for the use of Normaliz 2.7
13within SINGULAR. The exchange of data is via files.
14In addition to the top level
15functions that aim at objects of type ideal or ring, several other auxiliary
16functions allow the user to apply Normaliz to data of type intmat. Therefore
17SINGULAR can be used as a comfortable environment for the work with Normaliz.
18@* Please see the @code{Normaliz2.7Documentation.pdf} (included in the Normaliz
19distribution) for a more extensive documentation of Normaliz.
20@code{nmz_sing.pdf} describes this library version 2.2, but most points are
21still valid.
22
23@*Singular and Normaliz exchange data via files. These files are automatically
24created and erased behind the scenes. As long as one wants to use only the
25ring-theoretic functions there is no need for file management.
26
27@*Note that the numerical invariants computed by Normaliz can be
28accessed in this \"automatic file mode\".
29
30@*However, if Singular is used as a frontend for Normaliz or the user
31wants to inspect data not automatically returned to Singular, then
32an explicit filename and a path can be specified for the exchange of
33data. Moreover, the library provides functions for access to these files.
34Deletion of the files is left to the user.
35
36@* Use of this library requires the program Normaliz to be installed.
37You can download it from
38@uref{http://www.mathematik.uni-osnabrueck.de/normaliz/}. Please make sure
39that the executables are in the search path or use setNmzExecPath
40(@ref{setNmzExecPath}).
41
42KEYWORDS: integral closure; normalization
43
44PROCEDURES:
45 intclToricRing(ideal I)      computes the integral closure of the toric ring
46                              generated by the leading monomials of the
47                              elements of I in the basering
48 normalToricRing(ideal I)     computes the normalization of the toric ring
49                              generated by the leading monomials of the
50                              elements of I
51 normalToricRingFromBinomials(ideal I)  computes the normalization of the
52                              polynomial ring modulo the unique minimal prime
53                              ideal of the binomial ideal I
54 ehrhartRing(ideal I)         computes the monomials representing the lattice
55                              points of the polytop generated leading monomials
56                              of the elements of I
57 intclMonIdeal(ideal I)       the exponent vectors of the leading monomials of
58                              the elements of I are considered as generators of
59                              a monomial ideal whose Rees algebra is computed
60
61 torusInvariants(intmat T)    computes the ring of invariants of a torus action
62 finiteDiagInvariants(intmat C)  computes the ring of invariants of a finite
63                                 abelian group acting diagonally on a polynomial
64                                 ring
65 diagInvariants(intmat C)     computes the ring of invariants of a
66                              diagonalizable group
67 intersectionValRings(intmat V)   computes the intersection of the polynomial
68                                  ring with the valuation rings of monomial
69                                  valuations
70 intersectionValRingIdeals(intmat V)       computes ideals of monomial valuations
71
72 showNuminvs()                prints the numerical invariants
73 exportNuminvs()              exports the numerical invariants
74
75 setNmzOption(string s, int onoff) sets the option s to onoff
76 showNmzOptions()             prints the enabled options to the standard output
77
78 normaliz(intmat sgr,int nmz_mode) applies Normaliz
79 setNmzExecPath(string nmz_exec_path_name) sets the path to the Normaliz
80                                           executable
81
82 writeNmzData(intmat sgr, int n_mode) creates an input file for Normaliz
83 readNmzData(string nmz_suffix) reads the Normaliz output file with the
84                                specified suffix
85
86 setNmzFilename(string nmz_filename_name) sets the filename for the exchange
87                                          of data
88 setNmzDataPath(string nmz_data_path_name) sets the directory for the exchange
89                                           of data
90 writeNmzPaths()              writes the path names into two files
91 startNmz()                   retrieves the path names written by writeNmzPaths
92 rmNmzFiles()                 removes the files created for and by Normaliz
93
94 mons2intmat(ideal I)         returns the intmat whose rows represent the
95                              leading exponents of the elements of I
96 intmat2mons(intmat expo_vecs) returns the ideal generated by the monomials
97                               which have the rows of expo_vecs as
98                               exponent vector
99 binomials2intmat(ideal I)    returns the intmat whose rows represent the
100                              exponents of the elements of the binomial ideal I
101";
102
103
104// helpers
105
106static proc desInt(string intname, int value)
107// define, export and set an integer
108{
109    int exists;
110    if(defined(`intname`)){exists=1;}
111    if(!exists)
112    {
113        int `intname`=value;export(`intname`);
114    }
115    `intname`=value;
116}
117
118static proc desString(string stringname, string value)
119// define, export and set a string
120{
121    int exists;
122    if(defined(`stringname`)){exists=1;}
123    if(!exists)
124    {
125        string `stringname`=value;export(`stringname`);
126    }
127    `stringname`=value;
128}
129
130static proc queryInt(string intname)
131// if intname is defined, return(intname), else return(0)
132{
133    int exists,value;
134    if(defined(`intname`)){exists=1;}
135    if(!exists)
136    {
137        return(0);
138    }
139    return(`intname`);
140}
141
142static proc queryString(string stringname)
143// if stringname is defined, return(stringname), else return("")
144{
145    int exists;
146    string value;
147    if(defined(`stringname`)){exists=1;}
148    if(!exists)
149    {
150        return("");
151    }
152    return(`stringname`);
153}
154
155static proc fileExists(string f)
156{
157    return(status (f,"exists")=="yes");
158}
159
160static proc appendSlash(string s)
161// if nonempty and / is not the terminating char
162{
163    if(size(s)>0)
164    {
165        if(s[size(s)]!="/")
166        {
167            s=s+"/";
168            return(s);
169        }
170    }
171    return(s);
172}
173
174// filenames and paths
175
176proc setNmzExecPath(string nmz_exec_path_name)
177"USAGE:   setNmzExecPath(string s);   @code{s} path to the Normaliz executable
178CREATE:   @code{Normaliz::nmz_exec_path} to save the given path @code{s}
179NOTE:     It is not necessary to use this function if the Normaliz executable
180          is in the search path of the system.
181SEE ALSO: setNmzOption
182EXAMPLE:  example setNmzExecPath; shows an example"
183{
184    desString("nmz_exec_path",nmz_exec_path_name);
185    nmz_exec_path=appendSlash(nmz_exec_path);
186}
187example
188{ "EXAMPLE:";echo = 2;
189  setNmzExecPath("../Normaliz/");
190}
191
192proc setNmzFilename(string nmz_filename_name)
193"USAGE:   setNmzFilename(string s);
194CREATE:   @code{Normaliz::nmz_filename} to save the given filename @code{s}
195NOTE:     The function sets the filename for the exchange of data. Unless a
196          path is set by setNmzDataPath, files will be created in the current
197          directory.
198          @* If a non-empty filename is set, the files created for and by
199             Normaliz are kept. This is mandatory for the data access functions
200             (see @ref{writeNmzData} and @ref{readNmzData}).
201          @* Resetting the filename by setNmzFilename(\"\") forces the library
202             to return to deletion of temporary files, but the files created
203             while the filename had been set will not be erased.
204SEE ALSO: writeNmzData, readNmzData, setNmzDataPath, rmNmzFiles
205EXAMPLE:  example setNmzFilename; shows an example"
206{
207    desString("nmz_filename",nmz_filename_name);
208    if(nmz_filename_name!="")
209    {
210        desInt("nmz_files_keep_switch",1);
211    }
212    else
213    {
214        desInt("nmz_files_keep_switch",0);
215    }
216}
217example
218{ "EXAMPLE:";echo = 2;
219  setNmzDataPath("examples/");
220  setNmzFilename("example1");
221  //now the files for the exchange with Normaliz are examples/example1.SUFFIX
222}
223
224proc setNmzDataPath(string nmz_data_path_name)
225"USAGE:   setNmzDataPath(string s);
226CREATE:   @code{Normaliz::nmz_data_path} to save the given path @code{s}
227NOTE:     The function sets the path for the exchange of data. By default the
228          files will be created in the current directory.
229          @* It seems that Singular cannot use filenames starting with @code{~}
230             or @code{$HOME} in its input/output functions.
231          @* You must also avoid path names starting with @code{/} if you work
232             under Cygwin, since Singular and Normaliz interpret them in
233             different ways.
234SEE ALSO: writeNmzData, readNmzData, rmNmzFiles, setNmzFilename
235EXAMPLE:  example setNmzDataPath; shows an example"
236{
237    desString("nmz_data_path",nmz_data_path_name);
238    nmz_data_path=appendSlash(nmz_data_path);
239}example
240{ "EXAMPLE:";echo = 2;
241  setNmzDataPath("examples/");
242  setNmzFilename("example1");
243  //now the files for the exchange with Normalize are examples/example1.SUFFIX
244}
245
246proc writeNmzPaths();
247"USAGE:   writeNmzPaths();
248CREATE:   the file nmz_sing_exec.path where the path to the Normaliz executable
249          is saved
250          @* the file nmz_sing_data.path where the directory for the exchange
251          of data is saved
252NOTE:     Both files are saved in the current directory. If one of the names
253          has not been defined, the corresponding file is created, but
254          contains nothing.
255SEE ALSO: setNmzDataPath, setNmzExecPath, startNmz
256EXAMPLE:  example writeNmzPaths; shows an example
257"{
258    link outf=":w nmz_sing_exec.path";
259    write(outf, queryString("nmz_exec_path"));
260    close(outf);
261
262    outf=":w nmz_sing_data.path";
263    write(outf, queryString("nmz_data_path"));
264    close(outf);
265}
266example
267{ "EXAMPLE:";echo = 2;
268  setNmzExecPath("../Normaliz/");
269  writeNmzPaths();
270  int dummy=system("sh","cat nmz_sing_exec.path");
271  dummy=system("sh","cat nmz_sing_data.path");
272}
273
274proc startNmz()
275"USAGE:   startNmz();
276PURPOSE:  This function reads the files written by @code{writeNmzPaths()},
277          retrieves the path names, and types them on the standard output
278          (as far as they have been set). Thus, once the path names have been
279          stored, a Normaliz session can simply be opened by this function.
280SEE ALSO: setNmzDataPath, setNmzExecPath, writeNmzPaths
281EXAMPLE:  example startNmz; shows an example
282"
283{
284    link inf=":r nmz_sing_exec.path";
285    string s=read(inf);
286    int i,p;
287    p=findWord("/",s,1);
288    if(p!=-1)
289    {
290        for(i=size(s);i>=1;i--)
291        {
292            if(s[i]=="/")
293            {
294                s=s[1..i];
295                break;
296            }
297        }
298        desString("nmz_exec_path",s);
299        "nmz_exec_path is",nmz_exec_path;
300    }
301    else
302    {
303        "nmz_exec_path not set";
304    }
305
306    inf=":r nmz_sing_data.path";
307    s=read(inf);
308    p=findWord("/",s,1);
309    if(p!=-1)
310    {
311        for(i=size(s);i>=1;i--)
312        {
313            if(s[i]=="/")
314            {
315                s=s[1..i];
316                break;
317            }
318        }
319        desString("nmz_data_path",s);
320        "nmz_data_path is",nmz_data_path;
321    }
322    else
323    {
324        "nmz_data_path not set";
325    }
326}
327example
328{ "EXAMPLE:"; echo=2;
329  startNmz();
330}
331
332static proc getNmzFile()
333{
334    if(queryInt("nmz_files_keep_switch"))
335    {
336        return(queryString("nmz_data_path")+queryString("nmz_filename"));
337    }
338    else
339    {
340        return(queryString("nmz_filename"));
341    }
342}
343
344static proc makeTempNmzDataPath()
345{
346    string testdir, testdir1;
347    int i,dummy;
348
349    testdir1="/tmp/nmz_sing_"+string(system("pid"));
350    testdir=testdir1;
351    while(fileExists(testdir))
352    {
353        i++;
354        testdir=testdir1+string(i);
355    }
356    dummy=system("sh","mkdir "+ testdir);
357    desString("nmz_filename",testdir+"/nmz"); //files are nmz+suffix in testdir
358}
359
360static proc eraseTempNmzDataPath();
361{
362    int dummy;
363
364    string tmpdir=getNmzFile();
365    tmpdir=tmpdir[1..size(tmpdir)-4]; // remove "/nmz"
366    dummy=system("sh","rm -r "+tmpdir);
367    setNmzFilename("");
368}
369
370static proc setNmzExec()
371{
372    return(queryString("nmz_exec_path")+"normaliz");
373}
374
375proc rmNmzFiles()
376"USAGE:  rmNmzFiles();
377PURPOSE: This function removes the files created for and by Normaliz, using
378         the last filename specified.
379         It needs an explicit filename set (see @ref{setNmzFilename}).
380SEE ALSO: writeNmzData, readNmzData, setNmzFilename, setNmzDataPath
381EXAMPLE:  example rmNmzFiles; shows an example
382"{
383
384    if(!queryInt("nmz_files_keep_switch"))
385    {
386        ERROR("rmNmzFiles: no filename specified");
387    }
388
389    list suffixes="in","gen","out","cst","typ","egn","esp","inv","tri","ht1",
390                  "ext";
391    int i,dummy;
392    string f;
393
394    for(i=1;i<=size(suffixes);i++)
395    {
396        f=getNmzFile()+"."+suffixes[i];
397        if (fileExists(f)) { dummy=system("sh","rm "+f+ "&> /dev/null"); }
398    }
399}
400example
401{ "EXAMPLE:"; echo=2;
402  setNmzFilename("VeryInteresting");
403  rmNmzFiles();
404}
405
406
407
408// parsing normaliz output
409
410static proc digit(string s)
411{
412    if(s==" ") // skip blanks quickly
413    {
414        return(0);
415    }
416
417    if((s[1]>="0" && s[1]<="9")||s[1]=="-")
418    {
419        return(1);
420    }
421    return(0);
422}
423
424static proc nextWord(string s, int p)
425{
426    int j,sw,ew;
427
428    for(;p<=size(s);p++) // must start with a letter
429    {
430
431        if((s[p]>="a" && s[p]<="z")||
432             (s[p]>="A" && s[p]<="Z"))
433        {
434            sw=p; break;
435        }
436    }
437    if(p>size(s))
438    {
439        return(-1,-1); // no word found
440    }
441
442    for(;p<=size(s);p++) // now numerals and -_ allowed
443    {
444        if(!((s[p]>="a" && s[p]<="z")||
445             (s[p]>="A" && s[p]<="Z")||
446             (s[p]>="0" && s[p]<="9")||
447              s[p]=="_"||s[p]=="-"))
448        {
449            break;
450        }
451    }
452    return(sw,p);
453}
454
455static proc getInt(string s, int p)
456{
457    string nst;
458    int i,j,en,sn;
459
460    for(;p<=size(s);p++)
461    {
462
463        if(digit(s[p]))
464        {
465            sn=p; break;
466        }
467    }
468    if(not(sn))
469    {
470        return(0,-1); // -1 indicates: no number found
471    }
472    p++;
473    for(;p<=size(s);p++)
474    {
475        if(!digit(s[p]))
476        {
477            en=p-1; break;
478        }
479    }
480    if(p>size(s))
481    {
482        en=size(s);
483    }
484    nst="i="+s[sn,en-sn+1];
485    execute(nst);
486    return(i,p);
487}
488
489
490static proc getRational(string s, int p)
491{
492    string nst;
493    int i,j,en,sn;
494
495    for(;p<=size(s);p++)
496    {
497        if(digit(s[p]))
498        {
499            sn=p; break;
500        }
501    }
502    if(not(sn))
503    {
504        return(0,-1); // -1 indicates: no number found
505    }
506    p++;
507    int slash_at;
508    for(;p<=size(s);p++)
509    {
510        if(s[p]=="/")
511        {
512            slash_at=p;
513            p++;
514            continue;
515        }
516        if(!digit(s[p]))
517        {
518            en=p-1; break;
519        }
520    }
521    if(p>size(s))
522    {
523        en=size(s);
524    }
525    if(slash_at)
526    {
527        nst="i="+s[sn,slash_at-sn];
528        execute(nst);
529        nst="j="+s[slash_at+1,en-slash_at];
530        execute(nst);
531        return(i,p,j);
532    }
533    nst="i="+s[sn,en-sn+1];
534    execute(nst);
535    return(i,p);
536}
537
538
539static proc findWord(string s, string t, int p)
540{
541    for(;p<=size(t)-size(s)+1;p++)
542    {
543        if(t[p]==s[1])
544        {
545            if(t[p,size(s)]==s)
546            {
547                 return(p+size(s));
548            }
549        }
550    }
551    return(-1);
552}
553
554
555static proc skipEqualsign(string s,int p)
556{
557    for(;p<=size(s);p++)
558    {
559        if(s[p]=="=")
560        {
561            break;
562        }
563    }
564    return(p+1);
565}
566
567
568// input and output to/from normaliz
569
570//list must have pairs of intmat, nmz_mode
571static proc doWriteNmzData(list #)
572{
573    string s;
574    int i,j;
575    link outf=":w "+ getNmzFile() +".in";  // also sets the filename
576
577    intmat sgr;
578    int num_rows, num_cols, n_mode;
579
580    for (int k=1; k+1<=size(#); k=k+2) {
581    //get data from the parameter list
582      sgr   = #[k];
583      num_rows = nrows(sgr);
584      num_cols = ncols(sgr);
585                n_mode   = #[k+1];
586
587      write(outf,num_rows);
588      write(outf,num_cols);
589
590      for(i=1;i<=nrows(sgr);i++)
591      {
592        s="";
593        for(j=1;j<=num_cols;j++)
594        {
595           s=s+string(sgr[i,j])+" ";
596        }
597        write(outf,s);
598      }
599      write(outf,n_mode);
600      write(outf,"");
601    }
602    close(outf);
603}
604
605
606proc writeNmzData(intmat sgr, int n_mode, list #)
607"USAGE:   writeNmzData(intmat M, int mode);
608          writeNmzData(intmat M, int mode, intmat M2, int mode2, ...);
609CREATE:   Creates an input file for Normaliz from the matrix M. The second
610          parameter sets the mode. How the matrix is interpreted depends on the
611          mode. See the Normaliz documentation for more information.
612
613                         It is also possible to give more than one pair of matrix and mode. In
614                         this case all matrices and modes are written. This can be used to
615                         combine modes 4,5,6.
616NOTE:     Needs an explicit filename set. The filename is created from the
617          current filename.
618   @*     Note that all functions in normaliz.lib write and read their data
619          automatically to and from the hard disk so that writeNmzData will
620          hardly ever be used explicitly.
621SEE ALSO: readNmzData, rmNmzFiles, setNmzFilename, setNmzDataPath
622EXAMPLE:  example writeNmzData; shows an example"
623{
624    if(queryString("nmz_filename")=="")
625    {
626        ERROR("writeNmzData: no filename specified");
627    }
628    doWriteNmzData(list(sgr, n_mode) + #);
629}
630example
631{ "EXAMPLE:"; echo=2;
632  setNmzFilename("VeryInteresting");
633  intmat sgr[3][3]=1,2,3,4,5,6,7,8,10;
634  writeNmzData(sgr,1);
635  int dummy=system("sh","cat VeryInteresting.in");
636
637  intmat Hyperplanes[2][3] = 2,-1,0, // 2x-y >= 0
638                             1, 1,0; //  x+y >= 0
639  intmat Equation[1][3] = 0,1,-1;    // y = z
640  intmat Congruence[1][4] = 1,0,0,3;  // x = 0 (3)
641  writeNmzData(Hyperplanes,4,Equation,5,Congruence,6);
642  dummy=system("sh","cat VeryInteresting.in");
643}
644
645
646proc readNmzData(string nmz_suffix)
647"USAGE:  readNmzData(string suffix);
648RETURN:  Reads an output file of Normaliz containing an integer matrix and
649         returns it as an intmat. For example, this function is useful if one
650         wants to inspect the support hyperplanes. The filename is created
651         from the current  filename and the suffix given to the function.
652NOTE:    Needs an explicit filename set by setNmzFilename.
653   @*    Note that all functions in normaliz.lib write and read their data
654         automatically so that readNmzData will usually not be used explicitly.
655   @*    This function reads only the first matrix in a file!
656SEE ALSO: writeNmzData, rmNmzFiles, setNmzFilename, setNmzDataPath
657EXAMPLE:  example readNmzData; shows an example"
658{
659    if(queryString("nmz_filename")=="")
660    {
661        ERROR("readNmzData: no filename specified");
662    }
663
664    string s;
665    int n_rows,n_cols;            //number of rows/columns
666    int p;                     //position
667    int i,j;
668    int returnvalue;
669
670    string filename = getNmzFile() + "."+ nmz_suffix;
671    link in_f=":r "+ filename;
672    s=read(in_f);
673    close(in_f);
674
675    p=1;
676    (n_rows,p)=getInt(s,p);
677    (n_cols,p)=getInt(s,p);
678    if (n_rows <= 0 || n_cols <= 0) {
679             intmat empty;
680             return(empty);
681    }
682         intmat nmz_gen[n_rows][n_cols];
683    for(i=1;i<=n_rows;i++)
684    {
685        for(j=1;j<=n_cols;j++)
686        {
687            (nmz_gen[i,j],p) = getInt(s,p);
688        }
689    }
690    return(nmz_gen);
691}
692example
693{ "EXAMPLE:"; echo=2;
694  setNmzFilename("VeryInteresting");
695  intmat sgr[3][3]=1,2,3,4,5,6,7,8,10;
696  intmat sgrnormal=normaliz(sgr,0);
697  readNmzData("cst");
698  readNmzData("typ");
699}
700
701
702// running normaliz (with options)
703
704// component 1 is name of option
705// 2 is default value
706// 3 is command line option to be passed to Normaliz
707// 4 indictes whether file "gen" is generated
708// value 2 of 4 indicates "no influence"
709
710static proc defNmzOptions()
711{
712    if(!defined(nmz_options)) // can be defined only once
713    {
714        list nmz_options=
715        list("supp",0,"-s",0),
716        list("triang",0,"-v",0),
717        list("volume",0,"-V",0),
718        list("hvect",0,"-p",0),
719        list("hvect_l",0,"-P",0),
720        list("height1",0,"-1",0),
721        list("normal",0,"-n",1),
722        list("normal_l",0,"-N",1),
723        list("hilb",0,"-h",1),
724        list("hilb_l",0,"-H",1),
725        list("dual",0,"-d",1),
726        list("control",0,"-c",2),
727        list("allf",0,"-a",2),
728        list("errorcheck",0,"-e",2),
729        list("bigint",0,"-B",2),
730        list("threads",0,"-x=",2);
731        export(nmz_options);
732    }
733}
734
735proc setNmzOption(string s, int onoff)
736"USAGE:   setNmzOption(string s, int onoff);
737PURPOSE:  If @code{onoff=1} the option @code{s} is activated, and
738          if @code{onoff=0} it is deactivated.
739The Normaliz options are accessible via the following names:
740@* @code{-s:  supp}
741@* @code{-v:  triang}
742@* @code{-V:  volume}
743@* @code{-p:  hvect}
744@* @code{-P:  hvect_l}
745@* @code{-1:  height1}
746@* @code{-n:  normal}
747@* @code{-N:  normal_l}
748@* @code{-h:  hilb}
749@* @code{-H:  hilb_l}
750@* @code{-d:  dual}
751@* @code{-a:  allf}
752@* @code{-c:  control}
753@* @code{-e:  errorcheck}
754@* @code{-B:  bigint} Use GMP for arbitrary precision integers
755@* @code{-x=N:  threads} In this case the int parameter is used to set the
756                         number of threads N, 0 means no explicit limiting.
757
758SEE ALSO: showNmzOptions
759EXAMPLE:  example setNmzOption; shows an example
760"
761{
762    defNmzOptions();
763    for(int i=1;i<=size(nmz_options);i++)
764    {
765        if(s==nmz_options[i][1])
766        {
767            nmz_options[i][2]=onoff;
768            return(1);
769        }
770    }
771    "Invalid option ", s;
772    return(0);
773}
774example
775{ "EXAMPLE:"; echo=2;
776  setNmzOption("hilb",1);
777  showNmzOptions();
778}
779
780static proc collectNmzOptions()
781{
782    defNmzOptions();
783    string run_options=" -f ";
784    desInt("GenGen",1); // indicates whether "gen" is generated
785    for(int i=1;i<=size(nmz_options);i++)
786    {
787        if(nmz_options[i][2])
788        {
789            run_options=run_options+nmz_options[i][3];
790                                if (nmz_options[i][1]=="threads") {
791                                        run_options=run_options+string(nmz_options[i][2]);
792                                }
793                                run_options=run_options+" ";
794            if(nmz_options[i][4]!=2)
795            {
796                GenGen=nmz_options[i][4];
797            }
798        }
799    }
800    return(run_options+" ");
801}
802
803proc showNmzOptions()
804"USAGE:   showNmzOptions();
805RETURN:   Returns the string of activated options.
806NOTE:     This string is used as parameter when calling Normaliz.
807SEE ALSO: setNmzOption
808EXAMPLE:  example showNmzOption; shows an example
809"
810{
811    return(collectNmzOptions());
812}
813example
814{ "EXAMPLE:"; echo=2;
815  setNmzOption("hilb",1);
816  showNmzOptions();
817}
818
819
820static proc runNormaliz(intmat sgr,nmz_mode, list #)
821{
822    if(!queryInt("nmz_files_keep_switch"))
823    {
824        makeTempNmzDataPath();
825    }
826
827    doWriteNmzData(list(sgr, nmz_mode) + #);
828
829    if(queryInt("nmz_files_keep_switch"))
830    {
831       int dummy=system("sh",setNmzExec()+ collectNmzOptions() + getNmzFile());
832    }
833    else
834    {
835        string gotodir="/tmp";
836        string fname=getNmzFile();
837        fname=fname[6..size(fname)];
838        string exec="cd "+gotodir+" ; ";
839        exec=exec+setNmzExec()+ collectNmzOptions()+" ";
840        exec=exec+fname+" ;";
841        int dummy=system("sh",exec);
842    }
843
844    if(!GenGen) // return input matrix if "gen" has not been generated
845    {
846        if(!queryInt("nmz_files_keep_switch"))
847        {
848            eraseTempNmzDataPath();
849        }
850        return(sgr);
851    }
852    intmat Gen=readNmzData("gen");
853
854    if(!defined(Num_Invs))
855    {
856        list Num_Invs;
857        export Num_Invs;
858    }
859    Num_Invs=getNuminvs();
860
861    if(!queryInt("nmz_files_keep_switch"))
862    {
863        eraseTempNmzDataPath();
864    }
865
866    return(Gen);
867
868}
869
870proc normaliz(intmat sgr,int nmz_mode, list #)
871"USAGE:   normaliz(intmat sgr,int nmz_mode);
872          normaliz(intmat sgr, int nmz_mode, intmat sgr2, int nmz_mode2, ...);
873RETURN:   The function applies Normaliz to the parameter sgr in the mode set
874          by nmz_mode. The function returns the intmat defined by the file
875          with suffix gen.
876
877          It is also possible to give more than one pair of matrix and mode. In
878                         this case all matrices and modes are used. This can be used to
879                         combine modes 4,5,6.
880NOTE:     You will find procedures for many applications of Normaliz in this
881          library, so the explicit call of this procedure may not be necessary.
882SEE ALSO: intclToricRing, normalToricRing, ehrhartRing, intclMonIdeal,
883          torusInvariants, diagInvariants, finiteDiagInvariants, intersectionValRings,
884                         intersectionValRingIdeals
885EXAMPLE:  example normaliz; shows an example
886"
887{
888    return(runNormaliz(sgr,nmz_mode,#));
889}
890example
891{ "EXAMPLE:"; echo=2;
892  ring R=0,(x,y,z),dp;
893  intmat M[3][2]=3,1,
894                 3,2,
895                 1,3;
896  normaliz(M,1);
897
898  intmat Hyperplanes[2][3] = 2,-1,0, // 2x-y >= 0
899                             1, 1,0; //  x+y >= 0
900  intmat Equation[1][3] = 0,1,-1;    // y = z
901  intmat Congruence[1][4] = 1,0,0,3;  // x = 0 (3)
902  normaliz(Hyperplanes,4,Equation,5,Congruence,6);
903}
904
905
906// retrieving normaliz numerical invariants
907
908static proc getNuminvs()
909{
910    string s;
911    list num_invs;
912    int p,sw,v_length,i,dummy_int;
913    intvec dummy_vec;
914    string type_inv,name_inv,dummy_bool;
915
916    link in_f=":r "+ getNmzFile() + "."+"inv";
917    s=read(in_f);
918
919    p=1;
920    while(p<size(s))
921    {
922        (sw,p)=nextWord(s,p);
923        if(sw==-1)
924        {
925            break;
926        }
927        type_inv=s[sw..p-1];
928        if(type_inv=="vector")
929        {
930            (v_length,p)=getInt(s,p);
931            (sw,p)=nextWord(s,p);
932            name_inv=s[sw..p-1];
933            if(name_inv=="h-vector")
934            {
935                name_inv="h_vector";
936            }
937            if(name_inv!="hilbert_polynomial")
938            {
939                for(i=1;i<=v_length;i++)
940                {
941                    if(i==1)
942                    {
943                        (dummy_int,p)=getInt(s,p);
944                        dummy_vec=dummy_int;
945                    }
946                    else
947                    {
948                        (dummy_int,p)=getInt(s,p);
949                        dummy_vec=dummy_vec,dummy_int;
950                    }
951                }
952                num_invs=num_invs+list(list(name_inv,dummy_vec,"intvec"));
953            }
954            else
955            {
956                p=skipEqualsign(s,p);
957            }
958        }
959        if(type_inv=="integer")
960        {
961            (sw,p)=nextWord(s,p);
962            name_inv=s[sw..p-1];
963            (dummy_int,p)=getInt(s,p);
964            num_invs=num_invs+list(list(name_inv,dummy_int,"int"));
965        }
966        if(type_inv=="boolean")
967        {
968            (sw,p)=nextWord(s,p);
969            name_inv=s[sw..p-1];
970            p=skipEqualsign(s,p);
971            (sw,p)=nextWord(s,p);
972            dummy_bool=s[sw..p-1];
973            dummy_int=0;
974            if(dummy_bool=="true")
975            {
976                dummy_int=1;
977            }
978            num_invs=num_invs+list(list(name_inv,dummy_int,"int"));
979        }
980    }
981    return(num_invs);
982}
983
984proc showNuminvs()
985"USAGE:   showNuminvs();
986PURPOSE:  prints the numerical invariants
987SEE ALSO: exportNuminvs
988EXAMPLE:  example showNuminvs(); shows an example
989"
990{
991    list dummy;
992    int i;
993    for(i=1;i<=size(Num_Invs);i++)
994    {
995        dummy=Num_Invs[i];
996        dummy[1],":", dummy[2];
997    }
998}
999example
1000{ "EXAMPLE:"; echo=2;
1001  ring R=0,(x,y,z,t),dp;
1002  ideal I=x^2,y^2,z^3;
1003  list l=intclMonIdeal(I);
1004  showNuminvs();
1005}
1006
1007
1008proc exportNuminvs()
1009"USAGE:   exportNuminvs();
1010CREATE:   Creates top-level variables which contain the numerical invariants.
1011          Depending on the options of normaliz different invariants are
1012          calculated. Use showNuminvs (@ref{showNuminvs}) to see which
1013          invariants are available.
1014SEE ALSO: showNuminvs
1015EXAMPLE:  example exportNuminvs; shows an example
1016"
1017{
1018    list dummy;
1019    int i;
1020    string s;
1021    for(i=1;i<=size(Num_Invs);i++)
1022    {
1023        dummy=Num_Invs[i];
1024        s=dummy[3]+" nmz_" + dummy[1] + "=dummy[2]; exportto(Top," + "nmz_" + dummy[1] + ");";
1025        execute(s);
1026    }
1027}
1028example
1029{ "EXAMPLE:"; echo=2;
1030  ring R=0,(x,y,z,t),dp;
1031  ideal I=x^2,y^2,z^3;
1032  list l=intclMonIdeal(I);
1033  exportNuminvs();
1034  // now the following variables are set:
1035  nmz_hilbert_basis_elements;
1036  nmz_number_extreme_rays;
1037  nmz_rank;
1038  nmz_index;
1039  nmz_number_support_hyperplanes;
1040  nmz_homogeneous;
1041  nmz_primary;
1042  nmz_ideal_multiplicity;
1043}
1044
1045
1046// intmats to/from monomials
1047
1048proc mons2intmat(ideal I)
1049"USAGE:   mons2intmat(ideal I);
1050RETURN:   Returns the intmat whose rows represent the leading exponents of the
1051          (non-zero) elements of I. The length of each row is nvars(basering).
1052SEE ALSO: intmat2mons
1053EXAMPLE:  example mons2intmat; shows an example"
1054{
1055    int i,j,k;
1056    intmat expo_vecs[size(I)][nvars(basering)];
1057    intvec expo_v;
1058
1059    k=0;
1060    for(i=1;i<=ncols(I);i++)
1061    {
1062        if(I[i]!=0)
1063        {
1064            k++;
1065            expo_v=leadexp(I[i]);
1066            for(j=1;j<=nvars(basering);j++)
1067            {
1068                expo_vecs[k,j]=expo_v[j];
1069            }
1070        }
1071    }
1072    return(expo_vecs);
1073}
1074example
1075{ "EXAMPLE:"; echo=2;
1076  ring R=0,(x,y,z),dp;
1077  ideal I=x2,y2,x2yz3;
1078  mons2intmat(I);
1079}
1080
1081proc intmat2mons(intmat expo_vecs)
1082"USAGE:   intmat2mons(intmat M);
1083RETURN:   an ideal generated by the monomials which correspond to the exponent
1084          vectors given by the rows of @code{M}
1085NOTE:     The number of variables in the basering @code{nvars(basering)} has to
1086          be at least the number of columns @code{ncols(M)}, otherwise the
1087          function exits with an error.
1088          is thrown (see @ref{ERROR}).
1089SEE ALSO: mons2intmat
1090EXAMPLE:  example intmat2mons; shows an example
1091"
1092{
1093    int i,j;
1094    poly m;
1095    ideal mons;
1096
1097    if(nvars(basering)<ncols(expo_vecs))
1098    {
1099        ERROR("intmat2mons: not enough variables in ring");
1100    }
1101
1102    for(i=1;i<=nrows(expo_vecs);i++)
1103    {
1104        m=1;
1105        for(j=1;j<=ncols(expo_vecs);j++)
1106        {
1107            m=m*var(j)^expo_vecs[i,j];
1108        }
1109        mons=mons,m;
1110    }
1111     mons=simplify(mons,2);    // get rid of starting 0
1112     return(mons);
1113}
1114example
1115{ "EXAMPLE:"; echo=2;
1116  ring R=0,(x,y,z),dp;
1117  intmat expo_vecs[3][3] =
1118  2,0,0,
1119  0,2,0,
1120  2,1,3;
1121  intmat2mons(expo_vecs);
1122}
1123
1124static proc intmat2monsSel(intmat expo_vecs, int d)
1125{
1126    int i,j;
1127    poly m;
1128    ideal mons;
1129
1130    if(nvars(basering)<ncols(expo_vecs)-1)
1131    {
1132        ERROR("intmat2monsSel: not enough variables in ring");
1133    }
1134
1135    for(i=1;i<=nrows(expo_vecs);i++)
1136    {
1137        if(expo_vecs[i,ncols(expo_vecs)]==d)
1138        {
1139
1140            m=1;
1141            for(j=1;j<=ncols(expo_vecs)-1;j++)
1142            {
1143                m=m*var(j)^expo_vecs[i,j];
1144            }
1145            mons=mons,m;
1146        }
1147    }
1148     mons=simplify(mons,2);    // get rid of starting 0
1149     return(mons);
1150}
1151
1152
1153proc binomials2intmat(ideal I)
1154"USAGE:   binomials2intmat(ideal I);
1155RETURN:   Returns the intmat whose rows represent the exponents of the
1156          (non-zero) elements of I which have to be binomials.
1157                         The length of each row is nvars(basering).
1158SEE ALSO: mons2intmat, intmat2mons
1159EXAMPLE:  example binomials2intmat; shows an example"
1160{
1161  int i,j,k;
1162  intmat expo_vecs[size(I)][nvars(basering)];
1163  intvec expo_v;
1164
1165  k=0;
1166  poly f;
1167
1168  for(i=1; i<=ncols(I); i++)
1169  {
1170    if( I[i] != 0 )
1171    {
1172      k++;
1173      f = I[i];
1174      if (leadcoef(f) != 1) {f = -f};  //works in all characteristics
1175      if (size(f)!=2 || leadcoef(f)!=1 || leadcoef(f[2])!=-1)
1176      {
1177        ERROR(string("normalToricRing: binomial ideal expected: generator ",i,": ",I[i]));
1178      }
1179      expo_v = leadexp(f)-leadexp(f[2]);
1180      for(j=1;j<=nvars(basering);j++)
1181      {
1182        expo_vecs[k,j]=expo_v[j];
1183      }
1184    }
1185  }
1186  return(expo_vecs);
1187}
1188example
1189{ "EXAMPLE:"; echo=2;
1190  ring S = 37,(u,v,w,x,y,z),dp;
1191  ideal I = u2v-xyz, ux2-vyz, uvw-y2z;
1192  binomials2intmat(I);
1193}
1194
1195
1196// integral closure of rings and ideals
1197
1198static proc runIntclToricRing(ideal I, int nmz_mode)
1199{
1200    intmat expo_vecs=mons2intmat(I);
1201
1202    string dummy=collectNmzOptions(); // only to set GenGen
1203
1204    return( intmat2mons( runNormaliz(expo_vecs,nmz_mode) ) );
1205}
1206
1207proc intclToricRing(ideal I)
1208"USAGE:   intclToricRing(ideal I);
1209RETURN:   The toric ring S is the subalgebra of the basering generated by the
1210          leading monomials of the elements of I. The function computes the
1211          integral closure T of S in the basering and returns an ideal listing
1212          the algebra generators of T over the coefficient field.
1213@*        The function returns the input ideal I if one of the options
1214          @code{supp}, @code{triang}, or @code{hvect} has been activated.
1215          However, in this case some numerical invariants are computed, and
1216          some other data may be contained in files that you can read into
1217          Singular (see @ref{showNuminvs}, @ref{exportNuminvs}).
1218NOTE:     A mathematical remark: the toric ring depends on the list of
1219          monomials given, and not only on the ideal they generate!
1220SEE ALSO:  normalToricRing, ehrhartRing, intclMonIdeal
1221EXAMPLE:   example intclToricRing; shows an example
1222"
1223{
1224    return(runIntclToricRing(I,0));
1225}
1226example
1227{ "EXAMPLE:"; echo=2;
1228  ring R=37,(x,y,t),dp;
1229  ideal I=x3,x2y,y3;
1230  intclToricRing(I);
1231}
1232
1233proc normalToricRing(ideal I)
1234"USAGE:   normalToricRing(ideal I);
1235RETURN:   The toric ring S is the subalgebra of the basering generated by the
1236          leading monomials of the elements of I. The function computes the
1237          normalisation T of S and returns an ideal listing the algebra
1238          generators of T over the coefficient field.
1239@*        The function returns the input ideal I if one of the options
1240          @code{supp}, @code{triang}, or @code{hvect} has been activated.
1241          However, in this case some numerical invariants are computed, and
1242          some other data may be contained in files that you can read into
1243          Singular (see @ref{showNuminvs}, @ref{exportNuminvs}).
1244NOTE:     A mathematical remark: the toric ring depends on the list of
1245          monomials given, and not only on the ideal they generate!
1246SEE ALSO: intclToricRing, ehrhartRing, intclMonIdeal, normalToricRingFromBinomials
1247EXAMPLE:  example normalToricRing; shows an example
1248"
1249{
1250    return(runIntclToricRing(I,1));
1251}
1252example
1253{ "EXAMPLE:"; echo=2;
1254  ring  R = 37,(x,y,t),dp;
1255  ideal I = x3,x2y,y3;
1256  normalToricRing(I);
1257}
1258
1259
1260proc normalToricRingFromBinomials(ideal I)
1261"USAGE:   normalToricRingFromBinomials(ideal I);
1262RETURN:
1263@tex
1264The ideal $I$ is generated by binomials of type $X^a-X^b$ (multiindex notation)
1265in the surrounding polynomial ring $K[X]=K[X_1,...,X_n]$. The binomials
1266represent a congruence on the monoid ${Z}^n$ with residue monoid $M$.
1267Let $N$ be the image of $M$ in gp($M$)/torsion. Then $N$ is universal in the
1268sense that every homomorphism from $M$ to an affine monoid factors through $N$.
1269If $I$ is a prime ideal, then $K[N]= K[X]/I$. In general, $K[N]=K[X]/P$ where
1270$P$ is the unique minimal prime ideal of $I$ generated by binomials of type
1271$X^a-X^b$.
1272
1273The function computes the normalization of $K[N]$ and returns a newly created
1274polynomial ring of the same Krull dimension, whose variables are
1275$x(1),...,x(n-r)$, where $r$ is the rank of the matrix with rows $a-b$.
1276(In general there is no canonical choice for such an embedding.)
1277Inside this polynomial ring there is an ideal $I$ which lists the algebra
1278generators of the normalization of $K[N]$.
1279@end tex
1280@*        The function returns the input ideal I if one of the options
1281          @code{supp}, @code{triang}, or @code{hvect} has been activated.
1282          However, in this case some numerical invariants are computed, and
1283          some other data may be contained in files that you can read into
1284          Singular.
1285SEE ALSO: intclToricRing, normalToricRing, ehrhartRing, intclMonIdeal
1286EXAMPLE:  example normalToricRing; shows an example
1287"
1288{
1289        intmat expo_vecs = binomials2intmat(I);
1290        string dummy=collectNmzOptions(); // only to set GenGen
1291        intmat result = runNormaliz(expo_vecs,10);
1292
1293        list baseringlist = ringlist(basering);
1294        ring S = (baseringlist[1]),(x(1..ncols(result))),dp;
1295        ideal I = intmat2mons(result);
1296        export(I);
1297        return (S);
1298}
1299example
1300{ "EXAMPLE:"; echo=2;
1301  ring R = 37,(u,v,w,x,y,z),dp;
1302  ideal I = u2v-xyz, ux2-wyz, uvw-y2z;
1303  def S = normalToricRingFromBinomials(I);
1304  setring S;
1305  I;
1306}
1307
1308static proc runIntclMonIdeal(ideal I, int nmz_mode)
1309{
1310    intmat expo_vecs=mons2intmat(I);
1311    int i,last_comp;
1312
1313    // we test if there is room for the Rees algebra
1314
1315    for(i=1;i<=nrows(expo_vecs);i++)
1316    {
1317        if(expo_vecs[i,ncols(expo_vecs)]!=0)
1318        {
1319            last_comp=1;  break; // no
1320        }
1321    }
1322
1323    string dummy=collectNmzOptions(); // only to set GenGen
1324
1325    //adjust size of input matrix
1326         if (!last_comp) { // remove last component
1327             intmat tmp[nrows(expo_vecs)][ncols(expo_vecs)-1] = expo_vecs[1..nrows(expo_vecs),1..(ncols(expo_vecs)-1)];
1328                  expo_vecs = tmp;
1329         }
1330    intmat nmz_data=runNormaliz(expo_vecs,nmz_mode);
1331
1332    if(last_comp)
1333    {
1334        ideal I1=intmat2monsSel(nmz_data,1);
1335        return(list(I1));
1336    }
1337    else
1338    {
1339        ideal I1=intmat2monsSel(nmz_data,1);
1340        ideal I2=intmat2mons(nmz_data);
1341        return(list(I1,I2));
1342    }
1343}
1344
1345proc ehrhartRing(ideal I)
1346"USAGE:    ehrhartRing(ideal I);
1347RETURN:    The exponent vectors of the leading monomials of the elements of I
1348           are considered as vertices of a lattice polytope P.
1349           The Ehrhart ring of a (lattice) polytope P is the monoid algebra
1350           defined by the monoid of lattice points in the cone over the
1351           polytope P; see Bruns and Gubeladze, Polytopes, Rings, and K-theory,
1352           Springer 2009, pp. 228, 229.
1353           The function returns a list of ideals:
1354@*         (i) If the last ring variable is not used by the monomials, it is
1355               treated as the auxiliary variable of the Ehrhart ring. The
1356               function returns two ideals, the first containing the monomials
1357               representing the lattice points of the polytope, the second
1358               containing the algebra generators of the Ehrhart ring over the
1359                    coefficient field.
1360@*         (ii) If the last ring variable is used by the monomials, the list
1361                returned contains only one ideal, namely the monomials
1362                representing the lattice points of the polytope.
1363@*
1364@*        The function returns the a list containing the input ideal I if one
1365          of the options @code{supp}, @code{triang}, or @code{hvect} has been
1366                         activated.
1367          However, in this case some numerical invariants are computed, and
1368          some other data may be contained in files that you can read into
1369          Singular.
1370NOTE:      A mathematical remark: the Ehrhart ring depends on the list of
1371           monomials given, and not only on the ideal they generate!
1372SEE ALSO: intclToricRing, normalToricRing, intclMonIdeal
1373EXAMPLE:  example ehrhartRing; shows an example
1374"
1375{
1376    return(runIntclMonIdeal(I,2));
1377}
1378example
1379{ "EXAMPLE:"; echo=2;
1380  ring R=37,(x,y,t),dp;
1381  ideal J=x3,x2y,y3,xy2t7;
1382  ehrhartRing(J);
1383}
1384
1385proc intclMonIdeal(ideal I)
1386"USAGE:   intclMonIdeal(ideal I);
1387RETURN:   The exponent vectors of the leading monomials of the elements of I
1388          are considered as generators of a monomial ideal for which the
1389          normalization of its Rees algebra is computed. For a Definiton of the
1390          Rees algebra (or Rees ring) see Bruns and Herzog, Cohen-Macaulay
1391          rings, Cambridge University Press 1998, p. 182.
1392          The function returns a list of ideals:
1393@* (i) If the last ring variable is not used by the monomials, it is treated
1394       as the auxiliary variable of the Rees algebra. The function returns two
1395       ideals, the first containing the monomials generating the integral
1396       closure of the monomial ideal, the second containing the algebra
1397         generators of the normalization of the Rees algebra.
1398@* (ii) If the last ring variable is used by the monomials, the list returned
1399        contains only one ideal, namely the monomials generating the integral
1400        closure of the ideal.
1401@*        The function returns the a list containing the input ideal I if one
1402          of the options @code{supp}, @code{triang}, or @code{hvect} has been
1403                         activated.
1404          However, in this case some numerical invariants are computed, and
1405          some other data may be contained in files that you can read into
1406          Singular (see @ref{showNuminvs}, @ref{exportNuminvs}).
1407SEE ALSO: intclToricRing, normalToricRing, ehrhartRing
1408EXAMPLE:  example intclMonIdeal; shows an example
1409"
1410{
1411    return(runIntclMonIdeal(I,3));
1412}
1413example
1414{ "EXAMPLE"; echo=2;
1415    ring R=0,(x,y,z,t),dp;
1416    ideal I=x^2,y^2,z^3;
1417    list l=intclMonIdeal(I);
1418    l[1]; // integral closure of I
1419    l[2];  // monomials generating the integral closure of the Rees algebra
1420}
1421
1422// torus invariants and valuation rings and ideals
1423
1424proc torusInvariants(intmat E)
1425"USAGE:   torusInvariants(intmat A);
1426RETURN:
1427Returns an ideal representing the list of monomials generating the ring of
1428invariants as an algebra over the coefficient field.
1429@tex
1430$R^T$.
1431@end tex
1432@*The function returns the ideal given by the input matrix A if one of
1433the options @code{supp}, @code{triang}, or @code{hvect} has been
1434activated.
1435However, in this case some numerical invariants are computed, and
1436some other data may be contained in files that you can read into
1437Singular.
1438BACKGROUND:
1439@tex
1440 Let $T = (K^*)^r$ be the $r$-dimensional torus acting on the polynomial ring
1441 $R = K[X_1 ,\ldots,X_n]$ diagonally. Such an action can be described as
1442 follows: there are integers $a_{i,j}$, $i=1,\ldots,r$, $j=1,\ldots,n$, such
1443 that $(\lambda_1,\ldots,\lambda_r)\in T$ acts by the substitution
1444$$ X_j \mapsto \lambda_1^{a_{1,j}} \cdots \lambda_r^{a_{r,j}}X_j,
1445   \quad j=1,\ldots,n.$$
1446In order to compute the ring of invariants $R^T$ one must specify the matrix
1447$A=(a_{i,j})$.
1448@end tex
1449SEE ALSO: diagInvariants, finiteDiagInvariants, intersectionValRings,
1450          intersectionValRingIdeals
1451EXAMPLE:  example torusInvariants; shows an example
1452"
1453{
1454    if(nvars(basering)!=ncols(E))
1455    {
1456        ERROR("torusInvariants: wrong number of columns in matrix");
1457    }
1458
1459    string dummy=collectNmzOptions();  // only to set GenGen
1460
1461    return( intmat2mons( runNormaliz(E,5) ) );
1462}
1463example
1464{ "EXAMPLE:"; echo=2;
1465  ring R=0,(x,y,z,w),dp;
1466  intmat E[2][4] = -1,-1,2,0, 1,1,-2,-1;
1467  torusInvariants(E);
1468}
1469
1470proc finiteDiagInvariants(intmat C)
1471"USAGE:   finiteDiagInvariants(intmat U);
1472RETURN:
1473@tex
1474This function computes the ring of invariants of a finite abelian group $G$
1475acting diagonally on the surrounding polynomial ring $K[X_1,...,X_n]$. The
1476group is the direct product of cyclic groups generated by finitely many
1477elements $g_1,...,g_w$. The element $g_i$ acts on the indeterminate $X_j$ by
1478$g_i(X_j)=\lambda_i^{u_{ij}}X_j$ where $\lambda_i$ is a primitive root of
1479unity of order equal to $ord(g_i)$. The ring of invariants is generated by all
1480monomials satisfying the system
1481$u_{i1}a_1+\ldots+u_{in} a_n \equiv 0$ mod ord$(g_i)$, $i=1,\ldots,w$.
1482The input to the function is the $w\times(n+1)$ matrix $U$ with rows
1483$u_{i1}\ldots u_{in}$ ord$(gi)$, $i=1,\ldots,w$. The output is a monomial ideal
1484listing the algebra generators of the subalgebra of invariants
1485{$R^G=\{f\in R : g_i f = f$ for all $i=1,\ldots,w\}$}.
1486@end tex
1487@*The function returns the ideal given by the input matrix C if one of
1488the options @code{supp}, @code{triang}, or @code{hvect} has been
1489activated.
1490However, in this case some numerical invariants are computed, and
1491some other data may be contained in files that you can read into
1492Singular.
1493NOTE:
1494SEE ALSO: torusInvariants, diagInvariants, intersectionValRings,
1495          intersectionValRingIdeals,showNuminvs,exportNuminvs
1496EXAMPLE:  example finiteDiagInvariants; shows an example
1497"
1498{
1499    if(nvars(basering)!=ncols(C)-1)
1500    {
1501        ERROR("finiteDiagInvariants: wrong number of columns in matrix");
1502    }
1503
1504    string dummy=collectNmzOptions();  // only to set GenGen
1505
1506    return( intmat2mons( runNormaliz(C,6) ) );
1507}
1508example
1509{ "EXAMPLE:"; echo=2;
1510  ring R = 0,(x,y,z,w),dp;
1511  intmat C[2][5] = 1,1,1,1,5, 1,0,2,0,7;
1512  finiteDiagInvariants(C);
1513}
1514
1515proc diagInvariants(intmat E, intmat C)
1516"USAGE:   diagInvariants(intmat A, intmat U);
1517RETURN:
1518@tex
1519This function computes the ring of invariants of a diagonalizable group
1520$D = T\times G$ where $T$ is a torus and $G$ is a finite abelian group, both
1521acting diagonally on the polynomial ring $K[X_1,\ldots,X_n]$. The group
1522actions are specified by the input matrices A and U. The first matrix specifies
1523the torus action, the second the action of the finite group. See
1524torusInvariants and finiteDiagInvariants for more detail. The output is a
1525monomial ideal listing the algebra generators of the subalgebra of invariants.
1526@end tex
1527@*The function returns the ideal given by the input matrix A if one of
1528the options @code{supp}, @code{triang}, or @code{hvect} has been
1529activated.
1530However, in this case some numerical invariants are computed, and
1531some other data may be contained in files that you can read into
1532Singular.
1533SEE ALSO: torusInvariants, finiteDiagInvariants, intersectionValRings, intersectionValRingIdeals,showNuminvs,exportNuminvs
1534EXAMPLE:  example diagInvariants; shows an example
1535"
1536{
1537    if(nvars(basering)!=ncols(E) || nvars(basering)!=ncols(C)-1)
1538    {
1539        ERROR("diagInvariants: wrong number of columns in matrix");
1540    }
1541
1542    string dummy=collectNmzOptions();  // only to set GenGen
1543
1544    return( intmat2mons( runNormaliz(E,5,C,6) ) );
1545}
1546example
1547{ "EXAMPLE:"; echo=2;
1548  ring R=0,(x,y,z,w),dp;
1549  intmat E[2][4] = -1,-1,2,0, 1,1,-2,-1;
1550  intmat C[2][5] = 1,1,1,1,5, 1,0,2,0,7;
1551  diagInvariants(E,C);
1552}
1553
1554proc intersectionValRings(intmat V)
1555"USAGE:   intersectionValRings(intmat V);
1556RETURN:   The function returns a monomial ideal, to be considered as the list
1557          of monomials generating @math{S} as an algebra over the coefficient
1558          field.
1559BACKGROUND:
1560@tex
1561A discrete monomial valuation $v$ on $R = K[X_1 ,\ldots,X_n]$ is determined by
1562the values $v(X_j)$ of the indeterminates. This function computes the
1563subalgebra $S = \{ f \in R : v_i ( f ) \geq 0,\ i = 1,\ldots,r\}$ for several
1564such valuations $v_i$, $i=1,\ldots,r$. It needs the matrix $V = (v_i(X_j))$ as
1565its input.
1566@end tex
1567@*The function returns the ideal given by the input matrix V if one of
1568the options @code{supp}, @code{triang}, or @code{hvect} has been
1569activated.
1570However, in this case some numerical invariants are computed, and
1571some other data may be contained in files that you can read into
1572Singular.
1573SEE ALSO: torusInvariants, diagInvariants, finiteDiagInvariants, intersectionValRingIdeals,showNuminvs,exportNuminvs
1574EXAMPLE:  example intersectionValRings; shows an example
1575"
1576{
1577
1578    if(nvars(basering)!=ncols(V))
1579    {
1580        ERROR("intersectionValRings: wrong number of columns in matrix");
1581    }
1582
1583    intmat V1[nrows(V)+ncols(V)][ncols(V)];
1584    int i,j;
1585
1586    for(i=1;i<=ncols(V);i++)
1587    {
1588        V1[i,i]=1;
1589    }
1590    for(i=1;i<=nrows(V);i++)
1591    {
1592        for(j=1;j<=ncols(V);j++)
1593        {
1594            V1[i+ncols(V),j]=V[i,j];
1595        }
1596    }
1597
1598
1599    string dummy=collectNmzOptions();  // only to set GenGen
1600
1601/*    if(!GenGen) // return V
1602    {
1603        runNormaliz(V1,4);
1604        return(V);
1605    }
1606*/
1607    return(intmat2mons(runNormaliz(V1,4)));
1608}
1609example
1610{ "EXAMPLE:"; echo=2;
1611  ring R=0,(x,y,z,w),dp;
1612  intmat V0[2][4]=0,1,2,3, -1,1,2,1;
1613  intersectionValRings(V0);
1614}
1615
1616proc intersectionValRingIdeals(intmat V)
1617"USAGE:   intersectionValRingIdeals(intmat V);
1618RETURN:   The function returns two ideals, both to be considered as lists of
1619          monomials which generate an algebra over the coefficient field. The
1620          first is the system of monomial generators of @math{S}, the second
1621          the system of generators of @math{M}.
1622@*        The function returns a list consisting of the ideal given by the
1623          input matrix T if one of the options @code{supp}, @code{triang}, or
1624          @code{hvect} has been activated.
1625          However, in this case some numerical invariants are computed, and
1626          some other data may be contained in files that you can read into
1627          Singular (see @ref{showNuminvs}, @ref{exportNuminvs}).
1628BACKGROUND:
1629@tex
1630A discrete monomial valuation $v$ on $R = K[X_1 ,\ldots,X_n]$ is determined by
1631the values $v(X_j)$ of the indeterminates. This function computes the
1632subalgebra $S = \{ f \in R : v_i ( f ) \geq 0,\ i = 1,\ldots,r\}$ for several
1633such valuations $v_i$, $i=1,\ldots,r$. It needs the matrix $V = (v_i(X_j))$ as
1634its input.
1635
1636This function simultaneously determines the $S$-submodule
1637$M = \{ f \in R : v_i(f) \geq w_i ,\ i = 1,\ldots,r\}$ for integers
1638$w_1,\ldots\,w_r$. (If $w_i \geq 0$ for all $i$, $M$ is an ideal of $S$.)
1639The numbers $w_i$ form the $(n+1)$th column of the input matrix.
1640@end tex
1641NOTE:   The function also gives an error message if the matrix V has the
1642        wrong number of columns.
1643SEE ALSO: torusInvariants, diagInvariants, finiteDiagInvariants, intersectionValRings
1644EXAMPLE:  example intersectionValRingIdeals; shows an example
1645"
1646{
1647    if(nvars(basering)!=ncols(V)-1)
1648    {
1649        ERROR("intersectionValRingIdeals: wrong number of columns in matrix");
1650    }
1651
1652    intmat V1[nrows(V)+ncols(V)][ncols(V)];
1653    int i,j;
1654
1655    for(i=1;i<=ncols(V);i++)
1656    {
1657        V1[i,i]=1;
1658    }
1659    for(i=1;i<=nrows(V);i++)
1660    {
1661        for(j=1;j<=ncols(V);j++)
1662        {
1663            V1[i+ncols(V),j]=V[i,j];
1664        }
1665    }
1666    for(i=1;i<=nrows(V);i++)
1667    {
1668        V1[i+ncols(V),ncols(V)]=-V1[i+ncols(V),ncols(V)];
1669    }
1670
1671    string dummy=collectNmzOptions();  // only to set GenGen
1672
1673    intmat nmz_data=runNormaliz(V1,4);
1674
1675    ideal I1=intmat2monsSel(nmz_data,0);
1676    ideal I2=intmat2monsSel(nmz_data,1);
1677    return(list(I1,I2));
1678}
1679example
1680{ "EXAMPLE:"; echo=2;
1681 ring R=0,(x,y,z,w),dp;
1682 intmat V[2][5]=0,1,2,3,4, -1,1,2,1,3;
1683 intersectionValRingIdeals(V);
1684}
Note: See TracBrowser for help on using the repository browser.