source: git/Singular/LIB/normaliz.lib @ a25fbca

fieker-DuValspielwiese
Last change on this file since a25fbca was 13d171b, checked in by Hans Schönemann <hannes@…>, 14 years ago
normaliz.lib: doc git-svn-id: file:///usr/local/Singular/svn/trunk@12500 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 39.4 KB
Line 
1// Singular library normaliz.lib
2
3version="$Id$"
4category="Commutative algebra"
5info="
6LIBRARY: normaliz.lib  Provides an interface for the use of Normaliz 2.2 within SINGULAR.
7AUTHORS:  Winfried Bruns, Winfried.Bruns@Uni-Osnabrueck.de
8          Christof Soeger, Christof.Soeger@Uni-Osnabrueck.de
9
10OVERVIEW:
11@texinfo
12The library normaliz.lib provides an interface for the use of Normaliz 2.2 within SINGULAR. The exchange of data is via files, the only possibility offered by Normaliz in its present version. In addition to the top level functions that aim at objects of type ideal or ring, several other auxiliary functions allow the user to apply Normaliz to data of type intmat. Therefore SINGULAR can be used as a comfortable environment for the work with Normaliz.
13@* Please see the @code{Normaliz2.2Documentation.pdf} and @code{nmz_sing.pdf} (both are included in the Normaliz distribution) for a more extensive documentation of Normaliz.
14@*
15@*Singular and Normaliz exchange data via files. These files are
16automatically created and erased behind the scenes. As long as one
17wants to use only the ring-theoretic functions there is no need for
18file management.
19@*
20@*Note that the numerical invariants computed by Normaliz can be
21accessed in this \"automatic file mode\".
22@*
23@*However, if Singular is used as a frontend for Normaliz or the user
24wants to inspect data not automatically returned to Singular, then
25an explicit filename and a path can be specified for the exchange of
26data. Moreover, the library provides functions for access to these files.
27Deletion of the files is left to the user.
28@*
29@*
30Use of this library requires the program Normaliz to be installed.
31You can download it from
32@uref{http://www.mathematik.uni-osnabrueck.de/normaliz/}.
33Please make sure that the executables are in the search path or use setNmzExecPath (@ref{setNmzExecPath}).
34@end texinfo
35
36NOTE:    These library functions use @code{sed} to transfer the Normaliz output into a SINGULAR compliant format.
37
38
39KEYWORDS: integral closure; normalization
40
41PROCEDURES:
42  intclToricRing(ideal I)        computes the integral closure of the toric ring generated by the leading monomials of the elements of I in the basering
43  normalToricRing(ideal I)       computes the normalization of the toric ring generated by the leading monomials of the elements of I
44  ehrhartRing(ideal I)           computes the monomials representing the lattice points of the polytop generated leading monomials of the elements of I
45  intclMonIdeal(ideal I)         the exponent vectors of the leading monomials of the elements of I are considered as generators of a monomial ideal whose Rees algebra is computed
46
47  torusInvariants(intmat T)      computes the ring of invariants of a torus action
48  valRing(intmat V)              computes the intersection of the polynomial ring with the valuation rings of monomial valuations
49  valRingIdeal(intmat V)         computes ideals of monomial valuations
50
51  showNuminvs()                  prints the numerical invariants
52  exportNuminvs()                exports the numerical invariants
53
54  setNmzOption(string s, int onoff) sets the option s to onoff
55  showNmzOptions()               prints the enabled options to the standard output
56
57  normaliz(intmat sgr,int nmz_mode) applies Normaliz
58  setNmzVersion(string nmz_version_name) sets the version of the Normaliz executable
59  setNmzExecPath(string nmz_exec_path_name) sets the path to the Normaliz executable
60
61  writeNmzData(intmat sgr, int n_mode) creates an input file for Normaliz
62  readNmzData(string nmz_suffix) reads the Normaliz output file with the specified suffix
63
64  setNmzFilename(string nmz_filename_name) sets the filename for the exchange of data
65  setNmzDataPath(string nmz_data_path_name) sets the directory for the exchange of data
66  writeNmzPaths()                writes the path names into two files
67  startNmz()                     retrieves the path names written by writeNmzPaths
68  rmNmzFiles()                   removes the files created for and by Normaliz
69
70  mons2intmat(ideal I)           returns the intmat whose rows represent the leading exponents of the elements of I.
71  intmat2mons(intmat expo_vecs)  returns the ideal generated by the monomials which have the rows of expo_vecs as exponent vector
72";
73
74
75// helpers
76
77static proc desInt(string intname, int value)
78// define, export and set an integer
79{
80    int exists;
81    if(defined(`intname`)){exists=1;}
82    if(!exists)
83    {
84        int `intname`=value;export(`intname`);
85    }
86    `intname`=value;
87}
88
89static proc desString(string stringname, string value)
90// define, export and set a string
91{
92    int exists;
93    if(defined(`stringname`)){exists=1;}
94    if(!exists)
95    {
96        string `stringname`=value;export(`stringname`);
97    }
98    `stringname`=value;
99}
100
101static proc queryInt(string intname)
102// if intname is defined, return(intname), else return(0)
103{
104    int exists,value;
105    if(defined(`intname`)){exists=1;}
106    if(!exists)
107    {
108        return(0);
109    }
110    return(`intname`);
111}
112
113static proc queryString(string stringname)
114// if stringname is defined, return(stringname), else return("")
115{
116    int exists;
117    string value;
118    if(defined(`stringname`)){exists=1;}
119    if(!exists)
120    {
121        return("");
122    }
123    return(`stringname`);
124}
125
126static proc fileExists(string f)
127{
128    return(!system("sh","ls "+f+" &> /dev/null"));
129}
130
131static proc appendSlash(string s)
132// if nonempty and / is not the terminating char
133{
134    if(size(s)>0)
135    {
136        if(s[size(s)]!="/")
137        {
138            s=s+"/";
139            return(s);
140        }
141    }
142    return(s);
143}
144
145// filenames and paths
146
147proc setNmzExecPath(string nmz_exec_path_name)
148"USAGE:   setNmzExecPath(string s);   @code{s} path to the Normaliz executable
149CREATE:   @code{Normaliz::nmz_exec_path} to save the given path @code{s}
150NOTE:     It is not necessary to use this function if the Normaliz executable is in the search path of the system.
151SEE ALSO: setNmzVersion
152EXAMPLE:  example setNmzExecPath; shows an example"
153{
154    desString("nmz_exec_path",nmz_exec_path_name);
155    nmz_exec_path=appendSlash(nmz_exec_path);
156}
157example
158{ "EXAMPLE:";echo = 2;
159  setNmzExecPath("../Normaliz/");
160}
161
162proc setNmzVersion(string nmz_version_name)
163"USAGE:   setNmzVersion(string s);   @code{s} version of the Normaliz executable
164CREATE:   @code{Normaliz::nmz_version} to save the given version @code{s}
165NOTE:     The version coincides with the filename of the Normaliz executable. Possible arguments are:
166          @* @code{norm32} for 32bit integer precision
167          @* @code{norm64} for 64bit integer precision (default)
168          @* @code{normbig} for arbitrary precision
169SEE ALSO: setNmzExecPath
170EXAMPLE:  example setNmzVersion; shows an example
171"
172{
173    desString("nmz_version",nmz_version_name);
174}
175example
176{ "EXAMPLE:";echo = 2;
177  setNmzVersion("normbig");
178}
179
180
181proc setNmzFilename(string nmz_filename_name)
182"USAGE:   setNmzFilename(string s);
183CREATE:   @code{Normaliz::nmz_filename} to save the given filename @code{s}
184NOTE:     The function sets the filename for the exchange of data. Unless a path is set by setNmzDataPath,
185          files will be created in the current directory.
186          @* If a non-empty filename is set, the files created for and by Normaliz are kept. This is mandatory for the data access functions (see @ref{writeNmzData} and @ref{readNmzData}).
187          @* Resetting the filename by setNmzFilename(\"\") forces the library to return to deletion of temporary files, but the files created while the filename had been set will not be erased.
188SEE ALSO: writeNmzData, readNmzData, setNmzDataPath, rmNmzFiles
189EXAMPLE:  example setNmzFilename; shows an example"
190{
191    desString("nmz_filename",nmz_filename_name);
192    if(nmz_filename_name!="")
193    {
194        desInt("nmz_files_keep_switch",1);
195    }
196    else
197    {
198        desInt("nmz_files_keep_switch",0);
199    }
200}
201example
202{ "EXAMPLE:";echo = 2;
203  setNmzDataPath("examples/");
204  setNmzFilename("example1");
205  //now the files for the exchange with Normalize are examples/example1.SUFFIX
206}
207
208proc setNmzDataPath(string nmz_data_path_name)
209"USAGE:   setNmzDataPath(string s);
210CREATE:   @code{Normaliz::nmz_data_path} to save the given path @code{s}
211NOTE:     The function sets the path for the exchange of data. By default the files will be created in the current directory.
212          @* It seems that Singular cannot use filenames starting with @code{~} or @code{$HOME} in its input/output functions.
213          @* You must also avoid path names starting with @code{/} if you work under Cygwin, since Singular and Normaliz interpret them in different ways.
214SEE ALSO: writeNmzData, readNmzData, rmNmzFiles, setNmzFilename
215EXAMPLE:  example setNmzDataPath; shows an example"
216{
217    desString("nmz_data_path",nmz_data_path_name);
218    nmz_data_path=appendSlash(nmz_data_path);
219}example
220{ "EXAMPLE:";echo = 2;
221  setNmzDataPath("examples/");
222  setNmzFilename("example1");
223  //now the files for the exchange with Normalize are examples/example1.SUFFIX
224}
225
226proc writeNmzPaths();
227"USAGE:   writeNmzPaths();
228CREATE:   the file nmz_sing_exec.path where the path to the Normaliz executable is saved
229          @* the file nmz_sing_data.path where the directory for the exchange of data is saved
230NOTE:     Both files are saved in the current directory. If one of the names has not been defined, the corresponding file is created, but contains nothing.
231SEE ALSO: setNmzDataPath, setNmzExecPath, startNmz
232EXAMPLE:  example writeNmzPaths; shows an example
233"{
234    link outf=":w nmz_sing_exec.path";
235    write(outf, queryString("nmz_exec_path"));
236    close(outf);
237
238    outf=":w nmz_sing_data.path";
239    write(outf, queryString("nmz_data_path"));
240    close(outf);
241}
242example
243{ "EXAMPLE:";echo = 2;
244  setNmzExecPath("../Normaliz/");
245  writeNmzPaths();
246  int dummy=system("sh","cat nmz_sing_exec.path");
247  dummy=system("sh","cat nmz_sing_data.path");
248}
249
250proc startNmz()
251"USAGE:   startNmz();
252PURPOSE:  This function reads the files written by @code{writeNmzPaths()}, retrieves the path names, and
253types them on the standard output (as far as they have been set). Thus, once the path names
254have been stored, a Normaliz session can simply be opened by this function.
255SEE ALSO: setNmzDataPath, setNmzExecPath, writeNmzPaths
256EXAMPLE:  example startNmz; shows an example
257"
258{
259    link inf=":r nmz_sing_exec.path";
260    string s=read(inf);
261    int i,p;
262    p=findWord("/",s,1);
263    if(p!=-1)
264    {
265        for(i=size(s);i>=1;i--)
266        {
267            if(s[i]=="/")
268            {
269                s=s[1..i];
270                break;
271            }
272        }
273        desString("nmz_exec_path",s);
274        "nmz_exec_path is",nmz_exec_path;
275    }
276    else
277    {
278        "nmz_exec_path not set";
279    }
280
281    inf=":r nmz_sing_data.path";
282    s=read(inf);
283    p=findWord("/",s,1);
284    if(p!=-1)
285    {
286        for(i=size(s);i>=1;i--)
287        {
288            if(s[i]=="/")
289            {
290                s=s[1..i];
291                break;
292            }
293        }
294        desString("nmz_data_path",s);
295        "nmz_data_path is",nmz_data_path;
296    }
297    else
298    {
299        "nmz_data_path not set";
300    }
301}
302example
303{ "EXAMPLE:"; echo=2;
304  startNmz();
305}
306
307static proc getNmzFile()
308{
309    if(queryInt("nmz_files_keep_switch"))
310    {
311        return(queryString("nmz_data_path")+queryString("nmz_filename"));
312    }
313    else
314    {
315        return(queryString("nmz_filename"));
316    }
317}
318
319static proc makeTempNmzDataPath()
320{
321    string testdir, testdir1;
322    int i,dummy;
323
324    testdir1="/tmp/nmz_sing_"+string(system("pid"));
325    testdir=testdir1;
326    while(fileExists(testdir))
327    {
328        i++;
329        testdir=testdir1+string(i);
330    }
331    dummy=system("sh","mkdir "+ testdir);
332    desString("nmz_filename",testdir+"/nmz"); // files are nmz+suffix in testdir
333}
334
335static proc eraseTempNmzDataPath();
336{
337    int dummy;
338
339    string tmpdir=getNmzFile();
340    tmpdir=tmpdir[1..size(tmpdir)-4]; // remove "/nmz"
341    dummy=system("sh","rm -r "+tmpdir);
342    setNmzFilename("");
343}
344
345static proc setNmzExec()
346{
347    if(queryString("nmz_exec")=="")
348    {
349        return(queryString("nmz_exec_path")+"norm64");
350    }
351    return(queryString("nmz_exec_path")+queryString("nmz_exec"));
352}
353
354proc rmNmzFiles()
355"USAGE:   rmNmzFiles();
356PURPOSE: This function removes the files created for and by Normaliz, using the last filename specified.
357It needs an explicit filename set (see @ref{setNmzFilename}).
358SEE ALSO: writeNmzData, readNmzData, setNmzFilename, setNmzDataPath
359EXAMPLE:  example rmNmzFiles; shows an example
360"{
361
362    if(!queryInt("nmz_files_keep_switch"))
363    {
364        ERROR("rmNmzFiles: no filename specified");
365    }
366
367    list suffixes="in","gen","out","sup","typ","egn","esp","inv","tri","ht1","ext";
368    int i,dummy;
369    string f;
370
371    for(i=1;i<=size(suffixes);i++)
372    {
373        f=getNmzFile()+"."+suffixes[i];
374        dummy=system("sh","rm "+f+ "&> /dev/null");
375    }
376}
377example
378{ "EXAMPLE:"; echo=2;
379  setNmzFilename("VeryInteresting");
380  rmNmzFiles();
381}
382
383
384
385// parsing normaliz output
386
387static proc digit(string s)
388{
389    if(s==" ") // skip blanks quickly
390    {
391        return(0);
392    }
393
394    if((s[1]>="0" && s[1]<="9")||s[1]=="-")
395    {
396        return(1);
397    }
398    return(0);
399}
400
401static proc nextWord(string s, int p)
402{
403    int j,sw,ew;
404
405    for(;p<=size(s);p++) // must start with a letter
406    {
407
408        if((s[p]>="a" && s[p]<="z")||
409             (s[p]>="A" && s[p]<="Z"))
410        {
411            sw=p; break;
412        }
413    }
414    if(p>size(s))
415    {
416        return(-1,-1); // no word found
417    }
418
419    for(;p<=size(s);p++) // now numerals and -_ allowed
420    {
421        if(!((s[p]>="a" && s[p]<="z")||
422             (s[p]>="A" && s[p]<="Z")||
423             (s[p]>="0" && s[p]<="9")||
424              s[p]=="_"||s[p]=="-"))
425        {
426            break;
427        }
428    }
429    return(sw,p);
430}
431
432static proc getInt(string s, int p)
433{
434
435    string nst;
436    int i,j,en,sn;
437
438    for(;p<=size(s);p++)
439    {
440
441        if(digit(s[p]))
442        {
443            sn=p; break;
444        }
445    }
446    if(not(sn))
447    {
448        return(0,-1); // -1 indicates: no number found
449    }
450    p++;
451    for(;p<=size(s);p++)
452    {
453        if(!digit(s[p]))
454        {
455            en=p-1; break;
456        }
457    }
458    if(p>size(s))
459    {
460        en=size(s);
461    }
462    nst="i="+s[sn,en-sn+1];
463    execute(nst);
464    return(i,p);
465}
466
467static proc getRational(string s, int p)
468{
469
470    string nst;
471    int i,j,en,sn;
472
473    for(;p<=size(s);p++)
474    {
475        if(digit(s[p]))
476        {
477            sn=p; break;
478        }
479    }
480    if(not(sn))
481    {
482        return(0,-1); // -1 indicates: no number found
483    }
484    p++;
485    int slash_at;
486    for(;p<=size(s);p++)
487    {
488        if(s[p]=="/")
489        {
490            slash_at=p;
491            p++;
492            continue;
493        }
494        if(!digit(s[p]))
495        {
496            en=p-1; break;
497        }
498    }
499    if(p>size(s))
500    {
501        en=size(s);
502    }
503    if(slash_at)
504    {
505        nst="i="+s[sn,slash_at-sn];
506        execute(nst);
507        nst="j="+s[slash_at+1,en-slash_at];
508        execute(nst);
509        return(i,p,j);
510    }
511    nst="i="+s[sn,en-sn+1];
512    execute(nst);
513    return(i,p);
514}
515
516static proc findWord(string s, string t, int p)
517{
518    for(;p<=size(t)-size(s)+1;p++)
519    {
520        if(t[p]==s[1])
521        {
522            if(t[p,size(s)]==s)
523            {
524                 return(p+size(s));
525            }
526        }
527    }
528    return(-1);
529}
530
531static proc skipEqualsign(string s,int p)
532{
533    for(;p<=size(s);p++)
534    {
535        if(s[p]=="=")
536        {
537            break;
538        }
539    }
540    return(p+1);
541}
542
543
544// input and output to/from normaliz
545
546static proc doWriteNmzData(intmat sgr, int num_cols, n_mode)
547{
548    string s;
549    int j;
550    link outf=":w "+ getNmzFile() +".in";  // also sets the filename
551    write(outf,nrows(sgr));
552    write(outf,num_cols);
553
554    for(int i=1;i<=nrows(sgr);i++)
555    {
556        s="";
557        for(j=1;j<=num_cols;j++)
558        {
559             s=s+string(sgr[i,j])+" ";
560        }
561        write(outf,s);
562    }
563    write(outf,n_mode);
564    close(outf);
565}
566
567proc writeNmzData(intmat sgr, int n_mode)
568"USAGE:   writeNmzData(intmat M, int mode);
569CREATE:   Creates an input file for Normaliz from the matrix M. The second parameter sets the mode. How the matrix is interpreted depends on the mode. See the Normaliz documentation for more information.
570NOTE:     Needs an explicit filename set. The filename is created from the current  filename and the suffix given to the function.
571   @*     Note that all functions in normaliz.lib write and read their data automatically to and from the hard disk so that writeNmzData will hardly ever be used explicitly.
572SEE ALSO: readNmzData, rmNmzFiles, setNmzFilename, setNmzDataPath
573EXAMPLE:  example writeNmzData; shows an example"
574{
575    if(queryString("nmz_filename")=="")
576    {
577        ERROR("writeNmzData: no filename specified");
578    }
579    doWriteNmzData(sgr, ncols(sgr), n_mode);
580}
581example
582{ "EXAMPLE:"; echo=2;
583  setNmzFilename("VeryInteresting");
584  intmat sgr[3][3]=1,2,3,4,5,6,7,8,10;
585  writeNmzData(sgr,1);
586  int dummy=system("sh","cat VeryInteresting.in");
587}
588
589
590proc readNmzData(string nmz_suffix)
591"USAGE:   readNmzData(string suffix);
592RETURN:   Reads an output file of Normaliz containing an integer matrix and returns it as an intmat. For example, this function is useful if one wants to inspect the support hyperplanes. The filename is created from the current  filename and the suffix given to the function.
593NOTE:     Needs an explicit filename set by setNmzFilename.
594   @*     Note that all functions in normaliz.lib write and read their data automatically so that readNmzData will usually not be used explicitly.
595   @*     This function uses the command @code{sed} to transfer the normaliz output into a singular conform format.
596SEE ALSO: writeNmzData, rmNmzFiles, setNmzFilename, setNmzDataPath
597EXAMPLE:  example readNmzData; shows an example"
598{
599    if(queryString("nmz_filename")=="")
600    {
601        ERROR("readNmzData: no filename specified");
602    }
603
604    string s;
605    int n_rows,n_cols;            //number of rows/columns
606    int p, q;                     //positions
607    int returnvalue;
608
609    string filename = getNmzFile() + "."+ nmz_suffix;
610    string tmpfilename = filename+".tmp";
611//"// ** readNmzData: initialisiert";    //TODO debugoutput wieder rausnehmen
612    returnvalue = system("sh","sed 's/ /,/g' < "+filename+" > "+tmpfilename);
613//"// ** readNmzData: sed ausgefuehrt";
614    link in_f=":r "+ tmpfilename;
615
616    s=read(in_f);
617    close(in_f);
618    returnvalue = system("sh","rm "+tmpfilename);
619//"// ** readNmzData: datei eingelesen";
620    p=1; q=size(s);
621    (n_rows,p)=getInt(s,p);
622    (n_cols,p)=getInt(s,p);
623    //intmat nmz_gen[n_rows][n_cols];
624    while(s[q]!=",")
625    {
626      q--;
627    }
628    //string c = "nmz_gen=" + s[p,q-p] + ";";
629    string c = "intmat nmz_gen["+ string(n_rows) +"]["+ string(n_cols) +"]=" + s[p,q-p] + ";";
630//"// ** readNmzData: string gebastelt";
631    execute(c);
632//"// ** readNmzData: string ausgefuehrt";
633    return(nmz_gen);
634}
635example
636{ "EXAMPLE:"; echo=2;
637  setNmzFilename("VeryInteresting");
638  intmat sgr[3][3]=1,2,3,4,5,6,7,8,10;
639  intmat sgrnormal=normaliz(sgr,0);
640  readNmzData("sup");
641  readNmzData("typ");
642}
643
644
645// running normaliz (with options)
646
647// component 1 is name of option
648// 2 is default value
649// 3 is command line option to be passed to Normaliz
650// 4 indictes whether file "gen" is generated
651// value 2 of 4 indicates "no influence"
652
653static proc defNmzOptions()
654{
655    if(!defined(nmz_options)) // can be defined only once
656    {
657        list nmz_options=
658        list("hvect",0,"-p",0),
659        list("triang",0,"-v",0),
660        list("supp",0,"-s",0),
661        list("normal",0,"-n",1),
662        list("hilb",0,"-h",1),
663        list("dual",0,"-d",1),
664        list("control",0,"-c",2),
665        list("allf",0,"-a",2),
666        list("ignore",1,"-i",2),
667        list("errorcheck",0,"-e",2);
668        export(nmz_options);
669    }
670}
671
672proc setNmzOption(string s, int onoff)
673"USAGE:   setNmzOption(string s, int onoff);
674PURPOSE:  If @code{onoff=1} the option @code{s} is activated, and if @code{onoff=0} it is deactivated.
675The Normaliz options are accessible via the following names:
676@* @code{-s:  supp}
677@* @code{-v:  triang}
678@* @code{-p:  hvect}
679@* @code{-n:  normal}
680@* @code{-h:  hilb}
681@* @code{-d:  dual}
682@* @code{-a:  allf}
683@* @code{-c:  control}
684@* @code{-i:  ignore}
685@* @code{-e:  errorcheck}
686SEE ALSO: showNmzOptions
687EXAMPLE:  example setNmzOption; shows an example
688"
689{
690    defNmzOptions();
691    for(int i=1;i<=size(nmz_options);i++)
692    {
693        if(s==nmz_options[i][1])
694        {
695            nmz_options[i][2]=onoff;
696            return(1);
697        }
698    }
699    "Invalid option ", s;
700    return(0);
701}
702example
703{ "EXAMPLE:"; echo=2;
704  setNmzOption("hilb",1);
705  showNmzOptions();
706}
707
708static proc collectNmzOptions()
709{
710    defNmzOptions();
711    string run_options=" -f ";
712    desInt("GenGen",1); // indicates whether "gen" is generated
713    for(int i=1;i<=size(nmz_options);i++)
714    {
715        if(nmz_options[i][2])
716        {
717            run_options=run_options+nmz_options[i][3]+" ";
718            if(nmz_options[i][4]!=2)
719            {
720                GenGen=nmz_options[i][4];
721            }
722        }
723    }
724    return(run_options+" ");
725}
726
727proc showNmzOptions()
728"USAGE:   showNmzOptions();
729RETURN:   Returns the string of activated options.
730NOTE:     This string is used as parameter when calling Normaliz.
731SEE ALSO: setNmzOption
732EXAMPLE:  example showNmzOption; shows an example
733"
734{
735    return(collectNmzOptions());
736}
737example
738{ "EXAMPLE:"; echo=2;
739  setNmzOption("hilb",1);
740  showNmzOptions();
741}
742
743
744static proc runNormaliz(intmat sgr,int num_cols, nmz_mode)
745{
746    if(!queryInt("nmz_files_keep_switch"))
747    {
748        makeTempNmzDataPath();
749    }
750
751    doWriteNmzData(sgr,num_cols,nmz_mode);
752
753    if(queryInt("nmz_files_keep_switch"))
754    {
755        int dummy=system("sh",setNmzExec()+ collectNmzOptions() + getNmzFile());
756    }
757    else
758    {
759        string gotodir="/tmp";
760        string fname=getNmzFile();
761        fname=fname[6..size(fname)];
762        string exec="cd "+gotodir+" ; ";
763        exec=exec+setNmzExec()+ collectNmzOptions()+" ";
764        exec=exec+fname+" ;";
765        int dummy=system("sh",exec);
766    }
767
768    if(!GenGen) // return nothing if "gen" has not been generated
769    {
770        return();
771    }
772    intmat Gen=readNmzData("gen");
773
774    if(!defined(Num_Invs))
775    {
776        list Num_Invs;
777        export Num_Invs;
778    }
779    Num_Invs=getNuminvs();
780
781    if(!queryInt("nmz_files_keep_switch"))
782    {
783        eraseTempNmzDataPath();
784    }
785
786    return(Gen);
787
788}
789
790proc normaliz(intmat sgr,int nmz_mode)
791"USAGE:   normaliz(intmat sgr,int nmz_mode);
792RETURN:   The function applies Normaliz to the parameter sgr in the mode set by nmz_mode. The
793function returns the intmat defined by the file with suffix gen.
794NOTE:     You will find procedures for many applications of Normaliz in this library, so the explicit call of this procedure may not be necessary.
795SEE ALSO: intclToricRing, normalToricRing, ehrhartRing, intclMonIdeal, torusInvariants, valRing, valRingIdeal
796EXAMPLE:  example normaliz; shows an example
797"
798{
799    return(runNormaliz(sgr,ncols(sgr),nmz_mode));
800}
801example
802{ "EXAMPLE:"; echo=2;
803  ring R=0,(x,y,z),dp;
804  intmat M[3][2]=3,1,
805                 3,2,
806                 1,3;
807  normaliz(M,1);
808}
809
810
811// retrieving normaliz numerical invariants
812
813static proc getNuminvs()
814{
815    string s;
816    list num_invs;
817    int p,sw,v_length,i,dummy_int;
818    intvec dummy_vec;
819    string type_inv,name_inv,dummy_bool;
820
821    link in_f=":r "+ getNmzFile() + "."+"inv";
822    s=read(in_f);
823
824    p=1;
825    while(p<size(s))
826    {
827        (sw,p)=nextWord(s,p);
828        if(sw==-1)
829        {
830            break;
831        }
832        type_inv=s[sw..p-1];
833        if(type_inv=="vector")
834        {
835            (v_length,p)=getInt(s,p);
836            (sw,p)=nextWord(s,p);
837            name_inv=s[sw..p-1];
838            if(name_inv=="h-vector")
839            {
840                name_inv="h_vector";
841            }
842            if(name_inv!="hilbert_polynomial")
843            {
844                for(i=1;i<=v_length;i++)
845                {
846                    if(i==1)
847                    {
848                        (dummy_int,p)=getInt(s,p);
849                        dummy_vec=dummy_int;
850                    }
851                    else
852                    {
853                        (dummy_int,p)=getInt(s,p);
854                        dummy_vec=dummy_vec,dummy_int;
855                    }
856                }
857                num_invs=num_invs+list(list(name_inv,dummy_vec,"intvec"));
858            }
859            else
860            {
861                p=skipEqualsign(s,p);
862            }
863        }
864        if(type_inv=="integer")
865        {
866            (sw,p)=nextWord(s,p);
867            name_inv=s[sw..p-1];
868            (dummy_int,p)=getInt(s,p);
869            num_invs=num_invs+list(list(name_inv,dummy_int,"int"));
870        }
871        if(type_inv=="boolean")
872        {
873            (sw,p)=nextWord(s,p);
874            name_inv=s[sw..p-1];
875            p=skipEqualsign(s,p);
876            (sw,p)=nextWord(s,p);
877            dummy_bool=s[sw..p-1];
878            dummy_int=0;
879            if(dummy_bool=="true")
880            {
881                dummy_int=1;
882            }
883            num_invs=num_invs+list(list(name_inv,dummy_int,"int"));
884        }
885    }
886    return(num_invs);
887}
888
889proc showNuminvs()
890"USAGE:   showNuminvs();
891PURPOSE:  prints the numerical invariants
892SEE ALSO: exportNuminvs
893EXAMPLE:  example showNuminvs(); shows an example
894"
895{
896    list dummy;
897    int i;
898    for(i=1;i<=size(Num_Invs);i++)
899    {
900        dummy=Num_Invs[i];
901        dummy[1],":", dummy[2];
902    }
903}
904example
905{ "EXAMPLE:"; echo=2;
906  ring R=0,(x,y,z,t),dp;
907  ideal I=x^2,y^2,z^3;
908  list l=intclMonIdeal(I);
909  showNuminvs();
910}
911
912
913proc exportNuminvs()
914"USAGE:   exportNuminvs();
915CREATE:   Creates top-level variables which contain the numerical invariants. Depending on the options of normaliz different invariants are calculated. Use showNuminvs (@ref{showNuminvs}) to see which invariants are available.
916SEE ALSO: showNuminvs
917EXAMPLE:  example exportNuminvs; shows an example
918"
919{
920    list dummy;
921    int i;
922    string s;
923    for(i=1;i<=size(Num_Invs);i++)
924    {
925        dummy=Num_Invs[i];
926        s=dummy[3]+" nmz_" + dummy[1] + "=dummy[2]; exportto(Top," + "nmz_" + dummy[1] + ");";
927        execute(s);
928    }
929}
930example
931{ "EXAMPLE:"; echo=2;
932  ring R=0,(x,y,z,t),dp;
933  ideal I=x^2,y^2,z^3;
934  list l=intclMonIdeal(I);
935  exportNuminvs();
936  // now the following variables are set:
937  nmz_hilbert_basis_elements;
938  nmz_number_extreme_rays;
939  nmz_rank;
940  nmz_index;
941  nmz_number_support_hyperplanes;
942  nmz_homogeneous;
943  nmz_primary;
944  nmz_ideal_multiplicity;
945}
946
947
948// intmats to/from monomials
949
950proc mons2intmat(ideal I)
951"USAGE:   mons2intmat(ideal I);
952RETURN:   Returns the intmat whose rows represent the leading exponents of the (non-zero) elements of I. The
953length of each row is nvars(basering).
954SEE ALSO: intmat2mons
955EXAMPLE:  example mons2intmat; shows an example"
956{
957    int i,j,k;
958    intmat expo_vecs[size(I)][nvars(basering)];
959    intvec expo_v;
960
961    int last_comp;
962    k=0;
963    for(i=1;i<=ncols(I);i++)
964    {
965        if(I[i]!=0)
966        {
967            k++;
968            expo_v=leadexp(I[i]);
969            for(j=1;j<=nvars(basering);j++)
970            {
971                expo_vecs[k,j]=expo_v[j];
972            }
973        }
974    }
975    return(expo_vecs);
976}
977example
978{ "EXAMPLE:"; echo=2;
979  ring R=0,(x,y,z),dp;
980  ideal I=x2,y2,x2yz3;
981  mons2intmat(I);
982}
983
984proc intmat2mons(intmat expo_vecs)
985"USAGE:   intmat2mons(intmat M);
986RETURN:   an ideal generated by the monomials which correspond to the exponent vectors given by the rows of @code{M}
987NOTE:     The number of variables in the basering @code{nvars(basering)} has to be at least the number of columns @code{ncols(M)}, otherwise an error is omitted (see  @ref{ERROR}).
988SEE ALSO: mons2intmat
989EXAMPLE:  example intmat2mons; shows an example
990"
991{
992    int i,j;
993    poly m;
994    ideal mons;
995
996    if(nvars(basering)<ncols(expo_vecs))
997    {
998        ERROR("intmat2mons: not enough variables in ring");
999    }
1000
1001    for(i=1;i<=nrows(expo_vecs);i++)
1002    {
1003        m=1;
1004        for(j=1;j<=ncols(expo_vecs);j++)
1005        {
1006            m=m*var(j)^expo_vecs[i,j];
1007        }
1008        mons=mons,m;
1009    }
1010    return(mons[2..ncols(mons)]);
1011}
1012example
1013{ "EXAMPLE:"; echo=2;
1014  ring R=0,(x,y,z),dp;
1015  intmat expo_vecs[3][3] =
1016  2,0,0,
1017  0,2,0,
1018  2,1,3;
1019  intmat2mons(expo_vecs);
1020}
1021
1022static proc intmat2monsSel(intmat expo_vecs, int d)
1023{
1024    int i,j;
1025    poly m;
1026    ideal mons;
1027
1028    if(nvars(basering)<ncols(expo_vecs)-1)
1029    {
1030        ERROR("intmat2monsSel: not enough variables in ring");
1031    }
1032
1033    for(i=1;i<=nrows(expo_vecs);i++)
1034    {
1035        if(expo_vecs[i,ncols(expo_vecs)]==d)
1036        {
1037
1038            m=1;
1039            for(j=1;j<=ncols(expo_vecs)-1;j++)
1040            {
1041                m=m*var(j)^expo_vecs[i,j];
1042            }
1043            mons=mons,m;
1044        }
1045    }
1046    return(mons[2..ncols(mons)]); // get rid of starting 0
1047}
1048
1049
1050
1051// integral closure of rings and ideals
1052
1053static proc runIntclToricRing(ideal I, int nmz_mode)
1054{
1055    intmat expo_vecs=mons2intmat(I);
1056
1057    string dummy=collectNmzOptions(); // only to set GenGen
1058
1059    if(!GenGen) // return nothing
1060    {
1061        runNormaliz(expo_vecs,ncols(expo_vecs),nmz_mode);
1062        return();
1063    }
1064    return( intmat2mons( runNormaliz(expo_vecs,ncols(expo_vecs),nmz_mode) ) );
1065}
1066
1067proc intclToricRing(ideal I)
1068"USAGE:    intclToricRing(ideal I);
1069RETURN:    Let S be the toric ring generated by the leading monomials of the elements of I. The function computes the integral closure of S in the basering and returns an ideal listing the generators.
1070@*         The function returns nothing if one of the options @code{supp}, @code{triang}, or @code{hvect} has been activated. However, in this case some numerical invariants are computed, and some other data may be contained in files that you can read into Singular (see @ref{showNuminvs}, @ref{exportNuminvs}).
1071NOTE:     A mathematical remark: the toric ring depends on the list of monomials given, and not only on the ideal they generate!
1072SEE ALSO:  normalToricRing, ehrhartRing, intclMonIdeal
1073EXAMPLE:   example intclToricRing; shows an example
1074"
1075{
1076    return(runIntclToricRing(I,0));
1077}
1078example
1079{ "EXAMPLE:"; echo=2;
1080  ring R=37,(x,y,t),dp;
1081  ideal I=x3,x2y,y3;
1082  intclToricRing(I);
1083}
1084
1085proc normalToricRing(ideal I)
1086"USAGE:    normalToricRing(ideal I);
1087RETURN:    Computes the normalization of the toric ring generated by the leading monomials of the elements of I. The function returns an ideal listing the generators of the normalization.
1088@*         The function returns nothing if one of the options @code{supp}, @code{triang}, or @code{hvect} has been activated. However, in this case some numerical invariants are computed, and some other data may be contained in files that you can read into Singular (see @ref{showNuminvs}, @ref{exportNuminvs}).
1089NOTE:     A mathematical remark: the toric ring depends on the list of monomials given, and not only on the ideal they generate!
1090SEE ALSO: intclToricRing, ehrhartRing, intclMonIdeal
1091EXAMPLE:  example normalToricRing; shows an example
1092"
1093{
1094    return(runIntclToricRing(I,1));
1095}
1096example
1097{ "EXAMPLE:"; echo=2;
1098  ring R=37,(x,y,t),dp;
1099  ideal I=x3,x2y,y3;
1100  normalToricRing(I);
1101}
1102
1103static proc runIntclMonIdeal(ideal I, int nmz_mode)
1104{
1105    intmat expo_vecs=mons2intmat(I);
1106    int i,last_comp;
1107
1108    // we test if there is room for the Rees algebra
1109
1110    for(i=1;i<=nrows(expo_vecs);i++)
1111    {
1112        if(expo_vecs[i,ncols(expo_vecs)]!=0)
1113        {
1114            last_comp=1;  break; // no
1115        }
1116    }
1117
1118    string dummy=collectNmzOptions(); // only to set GenGen
1119
1120    if(!GenGen) // return nothing
1121    {
1122        runNormaliz(expo_vecs,ncols(expo_vecs),nmz_mode);
1123        return();
1124    }
1125
1126    intmat nmz_data=runNormaliz(expo_vecs,ncols(expo_vecs)-1+last_comp,nmz_mode);
1127
1128    if(last_comp)
1129    {
1130        ideal I1=intmat2monsSel(nmz_data,1);
1131        return(list(I1));
1132    }
1133    else
1134    {
1135        ideal I1=intmat2monsSel(nmz_data,1);
1136        ideal I2=intmat2mons(nmz_data);
1137        return(list(I1,I2));
1138    }
1139}
1140
1141proc ehrhartRing(ideal I)
1142"USAGE:    ehrhartRing(ideal I);
1143RETURN:    The exponent vectors of the leading monomials of the elements of I are considered as verices of a lattice polytope. The function returns a list of ideals:
1144@*         (i) If the last ring variable is not used by the monomials, it is treated as the auxiliary variable
1145of the Ehrhart ring. The function returns two ideals, the first containing the monomials representing the lattice points of the polytope, the second containing the generators of the Ehrhart ring.
1146@*         (ii) If the last ring variable is used by the monomials, the list returned contains only one ideal,
1147namely the monomials representing the lattice points of the polytope.
1148@*
1149@*         The function returns nothing if one of the options @code{supp}, @code{triang}, or @code{hvect} has been activated. However, in this case some numerical invariants are computed, and some other data may be contained in files that you can read into Singular (see @ref{showNuminvs}, @ref{exportNuminvs}).
1150NOTE:      A mathematical remark: the Ehrhart ring depends on the list of monomials given, and not only on the ideal they generate!
1151SEE ALSO: intclToricRing, normalToricRing, intclMonIdeal
1152EXAMPLE:  example ehrhartRing; shows an example
1153"
1154{
1155    return(runIntclMonIdeal(I,2));
1156}
1157example
1158{ "EXAMPLE:"; echo=2;
1159  ring R=37,(x,y,t),dp;
1160  ideal J=x3,x2y,y3,xy2t7;
1161  ehrhartRing(J);
1162}
1163
1164proc intclMonIdeal(ideal I)
1165"USAGE:   intclMonIdeal(ideal I);
1166RETURN:   The exponent vectors of the leading monomials of the elements of I are considered as generators of a monomial ideal for which the normalization of its Rees algebra is computed. The function returns a list of
1167ideals:
1168@* (i) If the last ring variable is not used by the monomials, it is treated as the auxiliary variable of the Rees algebra. The function returns two ideals, the first containing the monomials generating the integral closure of the monomial ideal, the second containing the generators of the normalization Rees algebra.
1169@* (ii) If the last ring variable is used by the monomials, the list returned contains only one ideal, namely the monomials generating the integral closure of the ideal.
1170@*         The function returns nothing if one of the options @code{supp}, @code{triang}, or @code{hvect} has been activated. However, in this case some numerical invariants are computed, and some other data may be contained in files that you can read into Singular (see @ref{showNuminvs}, @ref{exportNuminvs}).
1171NOTE:     A mathematical remark: the Rees algebra depends on the list of monomials given, and not only on the ideal they generate!
1172SEE ALSO: intclToricRing, normalToricRing, ehrhartRing
1173EXAMPLE:  example intclMonIdeal; shows an example
1174"
1175{
1176    return(runIntclMonIdeal(I,3));
1177}
1178example
1179{ "EXAMPLE"; echo=2;
1180    ring R=0,(x,y,z,t),dp;
1181    ideal I=x^2,y^2,z^3;
1182    list l=intclMonIdeal(I);
1183    l[1]; // integral closure of I
1184    l[2];  // monomials generating the integral closure of the Rees algebra
1185}
1186
1187// torus invariants and valuation rings and ideals
1188
1189proc torusInvariants(intmat T)
1190"USAGE:   torusInvariants(intmat A);
1191RETURN:   @texinfo
1192Returns an ideal representing the list of monomials generating the ring of invariants
1193@tex
1194$R^T$.
1195@end tex
1196@end texinfo
1197BACKGROUND: @texinfo
1198@tex
1199 Let $T = (K^*)^r$ be the $r$-dimensional torus acting on the polynomial ring $R = K[X_1 ,\ldots,X_n]$ diagonally. Such an action can be described as follows: there are integers $a_{i,j}$, $i=1,\ldots,r$, $j=1,\ldots,n$, such that $(\lambda_1,\ldots,\lambda_r)\in T$ acts by the substitution
1200$$ X_j \mapsto \lambda_1^{a_{1,j}} \cdots \lambda_r^{a_{r,j}}X_j,  \quad j=1,\ldots,n.$$
1201In order to compute the ring of invariants $R^T$ one must specify the matrix $A=(a_{i,j})$.
1202@end tex
1203@end texinfo
1204NOTE:@texinfo
1205@tex
1206It is of course possible that $R^T=K$. At present, Normaliz cannot deal with the zero cone and
1207will issue the (wrong) error message that the cone is not pointed. The function also gives an error
1208message if the matrix $T$ has the wrong number of columns.
1209@end tex
1210@end texinfo
1211SEE ALSO: valRing, valRingIdeal
1212EXAMPLE:  example torusInvariants; shows an example
1213"
1214{
1215    if(nvars(basering)!=ncols(T))
1216    {
1217        ERROR("torusInvariants: wrong number of columns in matrix");
1218    }
1219
1220    string dummy=collectNmzOptions();  // only to set GenGen
1221
1222    if(!GenGen) // return nothing
1223    {
1224        runNormaliz(T,ncols(T),5);
1225        return();
1226    }
1227    return( intmat2mons( runNormaliz(T,ncols(T),5) ) );
1228}
1229example
1230{ "EXAMPLE:"; echo=2;
1231  ring R=0,(x,y,z,w),dp;
1232  intmat V0[2][4]=0,1,2,3, -1,1,2,1;
1233  valRing(V0);
1234}
1235
1236proc valRing(intmat V)
1237"USAGE:   valRing(intmat V);
1238RETURN:   The function returns a monomial ideal, to be considered as the list of monomials generating @math{S}.
1239BACKGROUND: @texinfo
1240@tex
1241A discrete monomial valuation $v$ on $R = K[X_1 ,\ldots,X_n]$ is determined by the values $v(X_j)$ of the indeterminates. This function computes the subalgebra $S = \{ f \in R : v_i ( f ) \geq 0,\ i = 1,\ldots,r\}$ for
1242several such valuations $v_i$, $i=1,\ldots,r$. It needs the matrix $V = (v_i(X_j))$ as its input.
1243@end tex
1244@end texinfo
1245NOTE:@texinfo
1246@tex
1247It is of course possible that $S=K$. At present, Normaliz cannot deal with the zero cone and
1248will issue the (wrong) error message that the cone is not pointed. The function also gives an error
1249message if the matrix $T$ has the wrong number of columns.
1250@end tex
1251@end texinfo
1252SEE ALSO: torusInvariants, valRingIdeal
1253EXAMPLE:  example valRing; shows an example
1254"
1255{
1256
1257    if(nvars(basering)!=ncols(V))
1258    {
1259        ERROR("valRing: wrong number of columns in matrix");
1260    }
1261
1262    intmat V1[nrows(V)+ncols(V)][ncols(V)];
1263    int i,j;
1264
1265    for(i=1;i<=ncols(V);i++)
1266    {
1267        V1[i,i]=1;
1268    }
1269    for(i=1;i<=nrows(V);i++)
1270    {
1271        for(j=1;j<=ncols(V);j++)
1272        {
1273            V1[i+ncols(V),j]=V[i,j];
1274        }
1275    }
1276
1277
1278    string dummy=collectNmzOptions();  // only to set GenGen
1279
1280    if(!GenGen) // return nothing
1281    {
1282        runNormaliz(V1,ncols(V),4);
1283        return();
1284    }
1285
1286    return(intmat2mons(runNormaliz(V1,ncols(V),4)));
1287}
1288example
1289{ "EXAMPLE:"; echo=2;
1290  ring R=0,(x,y,z,w),dp;
1291  intmat V0[2][4]=0,1,2,3, -1,1,2,1;
1292  valRing(V0);
1293}
1294
1295proc valRingIdeal(intmat V)
1296"USAGE:   valRingIdeal(intmat V);
1297RETURN:   The function returns two ideals, both to be considered as lists of monomials. The first is the
1298system of monomial generators of @math{S}, the second the system of generators of @math{M}.
1299BACKGROUND: @texinfo
1300@tex
1301A discrete monomial valuation $v$ on $R = K[X_1 ,\ldots,X_n]$ is determined by the values $v(X_j)$ of the indeterminates. This function computes the subalgebra $S = \{ f \in R : v_i ( f ) \geq 0,\ i = 1,\ldots,r\}$ for
1302several such valuations $v_i$, $i=1,\ldots,r$. It needs the matrix $V = (v_i(X_j))$ as its input.
1303
1304This function simultaneously determines the $S$-submodule $M = \{ f \in R : v_i(f) \geq w_i ,\ i = 1,\ldots,r\}$ for integers $w_1,\ldots\,w_r$. (If $w_i \geq 0$ for all $i$, $M$ is an ideal of $S$.) The numbers $w_i$ form the $(n+1)$th column of the input matrix.
1305@end tex
1306@end texinfo
1307NOTE:@texinfo
1308@tex
1309It is of course possible that $S=K$. At present, Normaliz cannot deal with the zero cone and
1310will issue the (wrong) error message that the cone is not pointed. The function also gives an error
1311message if the matrix $T$ has the wrong number of columns.
1312@end tex
1313@end texinfo
1314SEE ALSO: torusInvariants, valRing
1315EXAMPLE:  example valRingIdeal; shows an example
1316"
1317{
1318    if(nvars(basering)!=ncols(V)-1)
1319    {
1320        ERROR("valRingIdeal: wrong number of columns in matrix");
1321    }
1322
1323    intmat V1[nrows(V)+ncols(V)][ncols(V)];
1324    int i,j;
1325
1326    for(i=1;i<=ncols(V);i++)
1327    {
1328        V1[i,i]=1;
1329    }
1330    for(i=1;i<=nrows(V);i++)
1331    {
1332        for(j=1;j<=ncols(V);j++)
1333        {
1334            V1[i+ncols(V),j]=V[i,j];
1335        }
1336    }
1337    for(i=1;i<=nrows(V);i++)
1338    {
1339        V1[i+ncols(V),ncols(V)]=-V1[i+ncols(V),ncols(V)];
1340    }
1341
1342    string dummy=collectNmzOptions();  // only to set GenGen
1343
1344    if(!GenGen) // return nothing
1345    {
1346        runNormaliz(V1,ncols(V),4);
1347        return();
1348    }
1349
1350    intmat nmz_data=runNormaliz(V1,ncols(V),4);
1351
1352    ideal I1=intmat2monsSel(nmz_data,0);
1353    ideal I2=intmat2monsSel(nmz_data,1);
1354    return(list(I1,I2));
1355}
1356example
1357{ "EXAMPLE:"; echo=2;
1358 ring R=0,(x,y,z,w),dp;
1359 intmat V[2][5]=0,1,2,3,4, -1,1,2,1,3;
1360 valRingIdeal(V);
1361}
1362
1363
Note: See TracBrowser for help on using the repository browser.