1 | // Singular library normaliz.lib |
---|
2 | |
---|
3 | version="$Id$" |
---|
4 | category="Commutative algebra" |
---|
5 | info=" |
---|
6 | LIBRARY: normaliz.lib Provides an interface for the use of Normaliz 2.2 within SINGULAR. |
---|
7 | AUTHORS: Winfried Bruns, Winfried.Bruns@Uni-Osnabrueck.de |
---|
8 | Christof Soeger, Christof.Soeger@Uni-Osnabrueck.de |
---|
9 | |
---|
10 | OVERVIEW: |
---|
11 | @texinfo |
---|
12 | The 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 |
---|
16 | automatically created and erased behind the scenes. As long as one |
---|
17 | wants to use only the ring-theoretic functions there is no need for |
---|
18 | file management. |
---|
19 | @* |
---|
20 | @*Note that the numerical invariants computed by Normaliz can be |
---|
21 | accessed in this \"automatic file mode\". |
---|
22 | @* |
---|
23 | @*However, if Singular is used as a frontend for Normaliz or the user |
---|
24 | wants to inspect data not automatically returned to Singular, then |
---|
25 | an explicit filename and a path can be specified for the exchange of |
---|
26 | data. Moreover, the library provides functions for access to these files. |
---|
27 | Deletion of the files is left to the user. |
---|
28 | @* |
---|
29 | @* |
---|
30 | Use of this library requires the program Normaliz to be installed. |
---|
31 | You can download it from |
---|
32 | @uref{http://www.mathematik.uni-osnabrueck.de/normaliz/}. |
---|
33 | Please make sure that the executables are in the search path or use setNmzExecPath (@ref{setNmzExecPath}). |
---|
34 | @end texinfo |
---|
35 | |
---|
36 | NOTE: These library functions use @code{sed} to transfer the Normaliz output into a SINGULAR compliant format. |
---|
37 | |
---|
38 | |
---|
39 | KEYWORDS: integral closure; normalization |
---|
40 | |
---|
41 | PROCEDURES: |
---|
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 | |
---|
77 | static 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 | |
---|
89 | static 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 | |
---|
101 | static 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 | |
---|
113 | static 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 | |
---|
126 | static proc fileExists(string f) |
---|
127 | { |
---|
128 | return(!system("sh","ls "+f+" &> /dev/null")); |
---|
129 | } |
---|
130 | |
---|
131 | static 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 | |
---|
147 | proc setNmzExecPath(string nmz_exec_path_name) |
---|
148 | "USAGE: setNmzExecPath(string s); @code{s} path to the Normaliz executable |
---|
149 | CREATE: @code{Normaliz::nmz_exec_path} to save the given path @code{s} |
---|
150 | NOTE: It is not necessary to use this function if the Normaliz executable is in the search path of the system. |
---|
151 | SEE ALSO: setNmzVersion |
---|
152 | EXAMPLE: example setNmzExecPath; shows an example" |
---|
153 | { |
---|
154 | desString("nmz_exec_path",nmz_exec_path_name); |
---|
155 | nmz_exec_path=appendSlash(nmz_exec_path); |
---|
156 | } |
---|
157 | example |
---|
158 | { "EXAMPLE:";echo = 2; |
---|
159 | setNmzExecPath("../Normaliz/"); |
---|
160 | } |
---|
161 | |
---|
162 | proc setNmzVersion(string nmz_version_name) |
---|
163 | "USAGE: setNmzVersion(string s); @code{s} version of the Normaliz executable |
---|
164 | CREATE: @code{Normaliz::nmz_version} to save the given version @code{s} |
---|
165 | NOTE: 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 |
---|
169 | SEE ALSO: setNmzExecPath |
---|
170 | EXAMPLE: example setNmzVersion; shows an example |
---|
171 | " |
---|
172 | { |
---|
173 | desString("nmz_version",nmz_version_name); |
---|
174 | } |
---|
175 | example |
---|
176 | { "EXAMPLE:";echo = 2; |
---|
177 | setNmzVersion("normbig"); |
---|
178 | } |
---|
179 | |
---|
180 | |
---|
181 | proc setNmzFilename(string nmz_filename_name) |
---|
182 | "USAGE: setNmzFilename(string s); |
---|
183 | CREATE: @code{Normaliz::nmz_filename} to save the given filename @code{s} |
---|
184 | NOTE: 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. |
---|
188 | SEE ALSO: writeNmzData, readNmzData, setNmzDataPath, rmNmzFiles |
---|
189 | EXAMPLE: 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 | } |
---|
201 | example |
---|
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 | |
---|
208 | proc setNmzDataPath(string nmz_data_path_name) |
---|
209 | "USAGE: setNmzDataPath(string s); |
---|
210 | CREATE: @code{Normaliz::nmz_data_path} to save the given path @code{s} |
---|
211 | NOTE: 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. |
---|
214 | SEE ALSO: writeNmzData, readNmzData, rmNmzFiles, setNmzFilename |
---|
215 | EXAMPLE: 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 | |
---|
226 | proc writeNmzPaths(); |
---|
227 | "USAGE: writeNmzPaths(); |
---|
228 | CREATE: 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 |
---|
230 | NOTE: 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. |
---|
231 | SEE ALSO: setNmzDataPath, setNmzExecPath, startNmz |
---|
232 | EXAMPLE: 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 | } |
---|
242 | example |
---|
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 | |
---|
250 | proc startNmz() |
---|
251 | "USAGE: startNmz(); |
---|
252 | PURPOSE: This function reads the files written by @code{writeNmzPaths()}, retrieves the path names, and |
---|
253 | types them on the standard output (as far as they have been set). Thus, once the path names |
---|
254 | have been stored, a Normaliz session can simply be opened by this function. |
---|
255 | SEE ALSO: setNmzDataPath, setNmzExecPath, writeNmzPaths |
---|
256 | EXAMPLE: 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 | } |
---|
302 | example |
---|
303 | { "EXAMPLE:"; echo=2; |
---|
304 | startNmz(); |
---|
305 | } |
---|
306 | |
---|
307 | static 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 | |
---|
319 | static 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 | |
---|
335 | static 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 | |
---|
345 | static 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 | |
---|
354 | proc rmNmzFiles() |
---|
355 | "USAGE: rmNmzFiles(); |
---|
356 | PURPOSE: This function removes the files created for and by Normaliz, using the last filename specified. |
---|
357 | It needs an explicit filename set (see @ref{setNmzFilename}). |
---|
358 | SEE ALSO: writeNmzData, readNmzData, setNmzFilename, setNmzDataPath |
---|
359 | EXAMPLE: 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 | } |
---|
377 | example |
---|
378 | { "EXAMPLE:"; echo=2; |
---|
379 | setNmzFilename("VeryInteresting"); |
---|
380 | rmNmzFiles(); |
---|
381 | } |
---|
382 | |
---|
383 | |
---|
384 | |
---|
385 | // parsing normaliz output |
---|
386 | |
---|
387 | static 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 | |
---|
401 | static 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 | |
---|
432 | static 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 | |
---|
467 | static 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 | |
---|
516 | static 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 | |
---|
531 | static 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 | |
---|
546 | static 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 | |
---|
567 | proc writeNmzData(intmat sgr, int n_mode) |
---|
568 | "USAGE: writeNmzData(intmat M, int mode); |
---|
569 | CREATE: 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. |
---|
570 | NOTE: 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. |
---|
572 | SEE ALSO: readNmzData, rmNmzFiles, setNmzFilename, setNmzDataPath |
---|
573 | EXAMPLE: 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 | } |
---|
581 | example |
---|
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 | |
---|
590 | proc readNmzData(string nmz_suffix) |
---|
591 | "USAGE: readNmzData(string suffix); |
---|
592 | RETURN: 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. |
---|
593 | NOTE: 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. |
---|
596 | SEE ALSO: writeNmzData, rmNmzFiles, setNmzFilename, setNmzDataPath |
---|
597 | EXAMPLE: 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 | } |
---|
635 | example |
---|
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 | |
---|
653 | static 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 | |
---|
672 | proc setNmzOption(string s, int onoff) |
---|
673 | "USAGE: setNmzOption(string s, int onoff); |
---|
674 | PURPOSE: If @code{onoff=1} the option @code{s} is activated, and if @code{onoff=0} it is deactivated. |
---|
675 | The 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} |
---|
686 | SEE ALSO: showNmzOptions |
---|
687 | EXAMPLE: 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 | } |
---|
702 | example |
---|
703 | { "EXAMPLE:"; echo=2; |
---|
704 | setNmzOption("hilb",1); |
---|
705 | showNmzOptions(); |
---|
706 | } |
---|
707 | |
---|
708 | static 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 | |
---|
727 | proc showNmzOptions() |
---|
728 | "USAGE: showNmzOptions(); |
---|
729 | RETURN: Returns the string of activated options. |
---|
730 | NOTE: This string is used as parameter when calling Normaliz. |
---|
731 | SEE ALSO: setNmzOption |
---|
732 | EXAMPLE: example showNmzOption; shows an example |
---|
733 | " |
---|
734 | { |
---|
735 | return(collectNmzOptions()); |
---|
736 | } |
---|
737 | example |
---|
738 | { "EXAMPLE:"; echo=2; |
---|
739 | setNmzOption("hilb",1); |
---|
740 | showNmzOptions(); |
---|
741 | } |
---|
742 | |
---|
743 | |
---|
744 | static 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 | |
---|
790 | proc normaliz(intmat sgr,int nmz_mode) |
---|
791 | "USAGE: normaliz(intmat sgr,int nmz_mode); |
---|
792 | RETURN: The function applies Normaliz to the parameter sgr in the mode set by nmz_mode. The |
---|
793 | function returns the intmat defined by the file with suffix gen. |
---|
794 | NOTE: You will find procedures for many applications of Normaliz in this library, so the explicit call of this procedure may not be necessary. |
---|
795 | SEE ALSO: intclToricRing, normalToricRing, ehrhartRing, intclMonIdeal, torusInvariants, valRing, valRingIdeal |
---|
796 | EXAMPLE: example normaliz; shows an example |
---|
797 | " |
---|
798 | { |
---|
799 | return(runNormaliz(sgr,ncols(sgr),nmz_mode)); |
---|
800 | } |
---|
801 | example |
---|
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 | |
---|
813 | static 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 | |
---|
889 | proc showNuminvs() |
---|
890 | "USAGE: showNuminvs(); |
---|
891 | PURPOSE: prints the numerical invariants |
---|
892 | SEE ALSO: exportNuminvs |
---|
893 | EXAMPLE: 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 | } |
---|
904 | example |
---|
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 | |
---|
913 | proc exportNuminvs() |
---|
914 | "USAGE: exportNuminvs(); |
---|
915 | CREATE: 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. |
---|
916 | SEE ALSO: showNuminvs |
---|
917 | EXAMPLE: 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 | } |
---|
930 | example |
---|
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 | |
---|
950 | proc mons2intmat(ideal I) |
---|
951 | "USAGE: mons2intmat(ideal I); |
---|
952 | RETURN: Returns the intmat whose rows represent the leading exponents of the (non-zero) elements of I. The |
---|
953 | length of each row is nvars(basering). |
---|
954 | SEE ALSO: intmat2mons |
---|
955 | EXAMPLE: 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 | } |
---|
977 | example |
---|
978 | { "EXAMPLE:"; echo=2; |
---|
979 | ring R=0,(x,y,z),dp; |
---|
980 | ideal I=x2,y2,x2yz3; |
---|
981 | mons2intmat(I); |
---|
982 | } |
---|
983 | |
---|
984 | proc intmat2mons(intmat expo_vecs) |
---|
985 | "USAGE: intmat2mons(intmat M); |
---|
986 | RETURN: an ideal generated by the monomials which correspond to the exponent vectors given by the rows of @code{M} |
---|
987 | NOTE: 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}). |
---|
988 | SEE ALSO: mons2intmat |
---|
989 | EXAMPLE: 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 | } |
---|
1012 | example |
---|
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 | |
---|
1022 | static 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 | |
---|
1053 | static 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 | |
---|
1067 | proc intclToricRing(ideal I) |
---|
1068 | "USAGE: intclToricRing(ideal I); |
---|
1069 | RETURN: 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}). |
---|
1071 | NOTE: A mathematical remark: the toric ring depends on the list of monomials given, and not only on the ideal they generate! |
---|
1072 | SEE ALSO: normalToricRing, ehrhartRing, intclMonIdeal |
---|
1073 | EXAMPLE: example intclToricRing; shows an example |
---|
1074 | " |
---|
1075 | { |
---|
1076 | return(runIntclToricRing(I,0)); |
---|
1077 | } |
---|
1078 | example |
---|
1079 | { "EXAMPLE:"; echo=2; |
---|
1080 | ring R=37,(x,y,t),dp; |
---|
1081 | ideal I=x3,x2y,y3; |
---|
1082 | intclToricRing(I); |
---|
1083 | } |
---|
1084 | |
---|
1085 | proc normalToricRing(ideal I) |
---|
1086 | "USAGE: normalToricRing(ideal I); |
---|
1087 | RETURN: 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}). |
---|
1089 | NOTE: A mathematical remark: the toric ring depends on the list of monomials given, and not only on the ideal they generate! |
---|
1090 | SEE ALSO: intclToricRing, ehrhartRing, intclMonIdeal |
---|
1091 | EXAMPLE: example normalToricRing; shows an example |
---|
1092 | " |
---|
1093 | { |
---|
1094 | return(runIntclToricRing(I,1)); |
---|
1095 | } |
---|
1096 | example |
---|
1097 | { "EXAMPLE:"; echo=2; |
---|
1098 | ring R=37,(x,y,t),dp; |
---|
1099 | ideal I=x3,x2y,y3; |
---|
1100 | normalToricRing(I); |
---|
1101 | } |
---|
1102 | |
---|
1103 | static 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 | |
---|
1141 | proc ehrhartRing(ideal I) |
---|
1142 | "USAGE: ehrhartRing(ideal I); |
---|
1143 | RETURN: 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 |
---|
1145 | of 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, |
---|
1147 | namely 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}). |
---|
1150 | NOTE: A mathematical remark: the Ehrhart ring depends on the list of monomials given, and not only on the ideal they generate! |
---|
1151 | SEE ALSO: intclToricRing, normalToricRing, intclMonIdeal |
---|
1152 | EXAMPLE: example ehrhartRing; shows an example |
---|
1153 | " |
---|
1154 | { |
---|
1155 | return(runIntclMonIdeal(I,2)); |
---|
1156 | } |
---|
1157 | example |
---|
1158 | { "EXAMPLE:"; echo=2; |
---|
1159 | ring R=37,(x,y,t),dp; |
---|
1160 | ideal J=x3,x2y,y3,xy2t7; |
---|
1161 | ehrhartRing(J); |
---|
1162 | } |
---|
1163 | |
---|
1164 | proc intclMonIdeal(ideal I) |
---|
1165 | "USAGE: intclMonIdeal(ideal I); |
---|
1166 | RETURN: 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 |
---|
1167 | ideals: |
---|
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}). |
---|
1171 | NOTE: A mathematical remark: the Rees algebra depends on the list of monomials given, and not only on the ideal they generate! |
---|
1172 | SEE ALSO: intclToricRing, normalToricRing, ehrhartRing |
---|
1173 | EXAMPLE: example intclMonIdeal; shows an example |
---|
1174 | " |
---|
1175 | { |
---|
1176 | return(runIntclMonIdeal(I,3)); |
---|
1177 | } |
---|
1178 | example |
---|
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 | |
---|
1189 | proc torusInvariants(intmat T) |
---|
1190 | "USAGE: torusInvariants(intmat A); |
---|
1191 | RETURN: @texinfo |
---|
1192 | Returns an ideal representing the list of monomials generating the ring of invariants |
---|
1193 | @tex |
---|
1194 | $R^T$. |
---|
1195 | @end tex |
---|
1196 | @end texinfo |
---|
1197 | BACKGROUND: @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.$$ |
---|
1201 | In order to compute the ring of invariants $R^T$ one must specify the matrix $A=(a_{i,j})$. |
---|
1202 | @end tex |
---|
1203 | @end texinfo |
---|
1204 | NOTE:@texinfo |
---|
1205 | @tex |
---|
1206 | It is of course possible that $R^T=K$. At present, Normaliz cannot deal with the zero cone and |
---|
1207 | will issue the (wrong) error message that the cone is not pointed. The function also gives an error |
---|
1208 | message if the matrix $T$ has the wrong number of columns. |
---|
1209 | @end tex |
---|
1210 | @end texinfo |
---|
1211 | SEE ALSO: valRing, valRingIdeal |
---|
1212 | EXAMPLE: 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 | } |
---|
1229 | example |
---|
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 | |
---|
1236 | proc valRing(intmat V) |
---|
1237 | "USAGE: valRing(intmat V); |
---|
1238 | RETURN: The function returns a monomial ideal, to be considered as the list of monomials generating @math{S}. |
---|
1239 | BACKGROUND: @texinfo |
---|
1240 | @tex |
---|
1241 | A 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 |
---|
1242 | several 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 |
---|
1245 | NOTE:@texinfo |
---|
1246 | @tex |
---|
1247 | It is of course possible that $S=K$. At present, Normaliz cannot deal with the zero cone and |
---|
1248 | will issue the (wrong) error message that the cone is not pointed. The function also gives an error |
---|
1249 | message if the matrix $T$ has the wrong number of columns. |
---|
1250 | @end tex |
---|
1251 | @end texinfo |
---|
1252 | SEE ALSO: torusInvariants, valRingIdeal |
---|
1253 | EXAMPLE: 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 | } |
---|
1288 | example |
---|
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 | |
---|
1295 | proc valRingIdeal(intmat V) |
---|
1296 | "USAGE: valRingIdeal(intmat V); |
---|
1297 | RETURN: The function returns two ideals, both to be considered as lists of monomials. The first is the |
---|
1298 | system of monomial generators of @math{S}, the second the system of generators of @math{M}. |
---|
1299 | BACKGROUND: @texinfo |
---|
1300 | @tex |
---|
1301 | A 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 |
---|
1302 | several such valuations $v_i$, $i=1,\ldots,r$. It needs the matrix $V = (v_i(X_j))$ as its input. |
---|
1303 | |
---|
1304 | This 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 |
---|
1307 | NOTE:@texinfo |
---|
1308 | @tex |
---|
1309 | It is of course possible that $S=K$. At present, Normaliz cannot deal with the zero cone and |
---|
1310 | will issue the (wrong) error message that the cone is not pointed. The function also gives an error |
---|
1311 | message if the matrix $T$ has the wrong number of columns. |
---|
1312 | @end tex |
---|
1313 | @end texinfo |
---|
1314 | SEE ALSO: torusInvariants, valRing |
---|
1315 | EXAMPLE: 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 | } |
---|
1356 | example |
---|
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 | |
---|