source: git/Singular/LIB/sing4ti2.lib

spielwiese
Last change on this file was 314f6db, checked in by Hans Schoenemann <hannes@…>, 3 years ago
fix: use of system("executable"..) vs. symbolic links
  • Property mode set to 100644
File size: 14.0 KB
Line 
1///////////////////////////////////////////////////////////////
2version="version sing4ti2.lib 4.2.1 Nov_2021 "; // $Id$
3category="Commutative Algebra";
4info="
5LIBRARY:  sing4ti2.lib          Communication Interface to 4ti2
6
7AUTHORS:  Thomas Kahle , kahle@mis.mpg.de
8@*        Anne Fruehbis-Krueger, anne@math.uni-hannover.de
9
10NOTE: This library uses the external program 4ti2 for calculations
11@*    and the standard unix tools sed and awk for conversion of
12@*    the returned result
13
14PROCEDURES:
15markov4ti2(A[,i])   compute Markov basis of given lattice
16hilbert4ti2(A[,i])  compute Hilbert basis of given lattice
17graver4ti2(A[,i])   compute Graver basis of given lattice
18";
19
20
21proc markov4ti2(matrix A, list #)
22"USAGE:  markov4ti2(A[,i]);
23@*       A=intmat
24@*       i=int
25ASSUME:  - A is a matrix with integer entries which describes the lattice
26@*         as ker(A), if second argument is not present,
27@*         as left image Im(A) = {zA, z \in ZZ^k}(!), if second argument is a positive integer
28@*       - number of variables of basering equals number of columns of A
29@*         (for ker(A)) resp. of rows of A (for Im(A))
30CREATE:  files sing4ti2.mat, sing4ti2.lat, sing4ti2.mar in the current
31@*       directory (I/O files for communication with 4ti2)
32NOTE:    input rules for 4ti2 also apply to input to this procedure
33@*       hence ker(A)={x|Ax=0} and Im(A)={xA}
34RETURN:  toric ideal specified by Markov basis thereof
35EXAMPLE: example markov4ti2; shows an example
36"
37{
38//--------------------------------------------------------------------------
39// Initialization and Sanity Checks
40//--------------------------------------------------------------------------
41   int i,j;
42   int nr=nrows(A);
43   int nc=ncols(A);
44   string fileending="mat";
45   if (size(#)!=0)
46   {
47//--- default behaviour: use ker(A) as lattice
48//--- if #[1]!=0 use Im(A) as lattice
49      if(typeof(#[1])!="int")
50      {
51         ERROR("optional parameter needs to be integer value");\
52      }
53      if(#[1]!=0)
54      {
55         fileending="lat";
56      }
57   }
58//--- we should also be checking whether all entries are indeed integers
59//--- or whether there are fractions, but in this case the error message
60//--- of 4ti2 is printed directly
61   if(nvars(basering)!=ncols(A))
62      {
63          ERROR("number of columns needs to match number of variables");
64      }
65//--------------------------------------------------------------------------
66// preparing input file for 4ti2
67//--------------------------------------------------------------------------
68   link eing=":w sing4ti2."+fileending;
69   string eingstring=string(nr)+" "+string(nc);
70   write(eing,eingstring);
71   for(i=1;i<=nr;i++)
72   {
73      kill eingstring;
74      string eingstring;
75      for(j=1;j<=nc;j++)
76      {
77          if((deg(A[i,j])>0)||(char(basering)!=0)||(npars(basering)>0))
78          {
79             ERROR("Input to markov4ti2 needs to be a matrix with integer entries");
80          }
81          eingstring=eingstring+string(A[i,j])+" ";
82      }
83      write(eing, eingstring);
84   }
85   close(eing);
86
87//----------------------------------------------------------------------
88// calling 4ti2 and converting output
89// Singular's string is too clumsy for this, hence we first prepare
90// using standard unix commands
91//----------------------------------------------------------------------
92   // find the name of markov/4ti2-markov
93   string s_name=system("executable","markov");
94   if (size(s_name)==0)
95   {
96     s_name=system("executable","4ti2-markov"); /* debian*/
97     if (size(s_name)==0)
98     {
99       ERROR("markov not found (part of 4ti2)");
100     }
101     else { s_name="4ti2-markov";}
102   }
103   else { s_name="markov";}
104   j=system("sh",s_name+" sing4ti2 >/dev/null 2>&1");
105   j=system("sh","awk \'BEGIN{ORS=\",\";}{print $0;}\' sing4ti2.mar | sed s/[\\\ \\\t\\\v\\\f]/,/g | sed s/,+/,/g|sed s/,,/,/g|sed s/,,/,/g > sing4ti2.converted");
106   if(!defined(keepfiles))
107   {
108      j=system("sh",("rm -f sing4ti2.mar sing4ti2."+fileending));
109   }
110//----------------------------------------------------------------------
111// reading output of 4ti2
112//----------------------------------------------------------------------
113   link ausg=":r sing4ti2.converted";
114//--- last entry ideal(0) is used to tie the list to the basering
115//--- it will not be processed any further
116   string ergstr="list erglist="+read(ausg)+ string(ideal(0))+";";
117   execute(ergstr);
118   ideal toric;
119   poly temppol1,temppol2;
120   for(i=1;i<=erglist[1];i++)
121   {
122     temppol1=1;
123     temppol2=1;
124     for(j=1;j<=erglist[2];j++)
125     {
126        if(erglist[2+(i-1)*erglist[2]+j]>=0)
127        {
128//--- positive exponents
129           temppol1=temppol1*(var(j)^erglist[2+(i-1)*erglist[2]+j]);
130        }
131        else
132        {
133//--- negative exponents
134           temppol2=temppol2*(var(j)^(-erglist[2+(i-1)*erglist[2]+j]));
135        }
136     }
137     toric=toric,temppol1-temppol2;
138   }
139//--- get rid of leading entry 0;
140   toric=toric[2..ncols(toric)];
141   return(toric);
142}
143example
144{"EXAMPLE:";
145   echo=2;
146   ring r=0,(x,y,z),dp;
147   matrix M[2][3]=0,1,2,2,1,0;
148   markov4ti2(M);
149   matrix N[1][3]=1,2,1;
150   markov4ti2(N,1);
151}
152
153///////////////////////////////////////////////////////////////////////////////
154
155proc graver4ti2(matrix A, list #)
156"USAGE:  graver4ti2(A[,i]);
157@*       A=intmat
158@*       i=int
159ASSUME:  - A is a matrix with integer entries which describes the lattice
160@*         as ker(A), if second argument is not present,
161@*         as the left image Im(A) = {zA : z \in ZZ^k}, if second argument is a positive integer
162@*       - number of variables of basering equals number of columns of A
163@*         (for ker(A)) resp. of rows of A (for Im(A))
164CREATE:  temporary files sing4ti2.mat, sing4ti2.lat, sing4ti2.gra
165@*       in the current directory (I/O files for communication with 4ti2)
166NOTE:    input rules for 4ti2 also apply to input to this procedure
167@*       hence ker(A)={x|Ax=0} and Im(A)={xA}
168RETURN:  toric ideal specified by Graver basis thereof
169EXAMPLE: example graver4ti2; shows an example
170"
171{
172//--------------------------------------------------------------------------
173// Initialization and Sanity Checks
174//--------------------------------------------------------------------------
175   int i,j;
176   int nr=nrows(A);
177   int nc=ncols(A);
178   string fileending="mat";
179   if (size(#)!=0)
180   {
181//--- default behaviour: use ker(A) as lattice
182//--- if #[1]!=0 use Im(A) as lattice
183      if(typeof(#[1])!="int")
184      {
185         ERROR("optional parameter needs to be integer value");\
186      }
187      if(#[1]!=0)
188      {
189         fileending="lat";
190      }
191   }
192//--- we should also be checking whether all entries are indeed integers
193//--- or whether there are fractions, but in this case the error message
194//--- of 4ti2 is printed directly
195      if(nvars(basering)!=ncols(A))
196      {
197          ERROR("number of columns needs to match number of variables");
198      }
199//--------------------------------------------------------------------------
200// preparing input file for 4ti2
201//--------------------------------------------------------------------------
202   link eing=":w sing4ti2."+fileending;
203   string eingstring=string(nr)+" "+string(nc);
204   write(eing,eingstring);
205   for(i=1;i<=nr;i++)
206   {
207      kill eingstring;
208      string eingstring;
209      for(j=1;j<=nc;j++)
210      {
211          if((deg(A[i,j])>0)||(char(basering)!=0)||(npars(basering)>0))
212          {
213             ERROR("Input to graver4ti2 needs to be a matrix with integer entries");
214          }
215          eingstring=eingstring+string(A[i,j])+" ";
216      }
217      write(eing, eingstring);
218   }
219   close(eing);
220
221//----------------------------------------------------------------------
222// calling 4ti2 and converting output
223// Singular's string is too clumsy for this, hence we first prepare
224// using standard unix commands
225//----------------------------------------------------------------------
226   // find the name of graver/4ti2-graver
227   string s_name=system("executable","graver");
228   if (size(s_name)==0)
229   {
230     s_name=system("executable","4ti2-graver"); /* debian*/
231     if (size(s_name)==0)
232     {
233       ERROR("graver not found (part of 4ti2)");
234     }
235     else { s_name="4ti2-graver"; }
236   }
237   else { s_name="graver"; }
238   j=system("sh",s_name+" sing4ti2 >/dev/null 2>&1");
239   j=system("sh","awk \'BEGIN{ORS=\",\";}{print $0;}\' sing4ti2.gra | sed s/[\\\ \\\t\\\v\\\f]/,/g | sed s/,+/,/g |sed s/,,/,/g|sed s/,,/,/g > sing4ti2.converted");
240   if(!defined(keepfiles))
241   {
242     j=system("sh",("rm -f sing4ti2.gra sing4ti2."+fileending));
243   }
244//----------------------------------------------------------------------
245// reading output of 4ti2
246//----------------------------------------------------------------------
247   link ausg=":r sing4ti2.converted";
248//--- last entry ideal(0) is used to tie the list to the basering
249//--- it will not be processed any further
250   string ergstr="list erglist="+read(ausg)+ string(ideal(0))+";";
251   execute(ergstr);
252   ideal toric;
253   poly temppol1,temppol2;
254   for(i=1;i<=erglist[1];i++)
255   {
256     temppol1=1;
257     temppol2=1;
258     for(j=1;j<=erglist[2];j++)
259     {
260        if(erglist[2+(i-1)*erglist[2]+j]>=0)
261        {
262//--- positive exponents
263           temppol1=temppol1*(var(j)^erglist[2+(i-1)*erglist[2]+j]);
264        }
265        else
266        {
267//--- negative exponents
268           temppol2=temppol2*(var(j)^(-erglist[2+(i-1)*erglist[2]+j]));
269        }
270     }
271     toric=toric,temppol1-temppol2;
272   }
273//--- get rid of leading entry 0;
274   toric=toric[2..ncols(toric)];
275   return(toric);
276}
277example
278{"EXAMPLE:";
279   echo=2;
280   ring r=0,(x,y,z,w),dp;
281   matrix M[2][4]=0,1,2,3,3,2,1,0;
282   graver4ti2(M);
283}
284
285///////////////////////////////////////////////////////////////////////////////
286
287proc hilbert4ti2(matrix A, list #)
288"USAGE:  hilbert4ti2(A[,i]);
289@*       A=intmat
290@*       i=int
291ASSUME:  - A is a matrix with integer entries which describes the lattice
292@*         as ker(A), if second argument is not present,
293@*         as the left image Im(A) = {zA : z \in ZZ^k}, if second argument is a positive integer
294@*       - number of variables of basering equals number of columns of A
295@*         (for ker(A)) resp. of rows of A (for Im(A))
296CREATE:  temporary files sing4ti2.mat, sing4ti2.lat, sing4ti2.mar
297@*       in the current directory (I/O files for communication with 4ti2)
298NOTE:    input rules for 4ti2 also apply to input to this procedure
299@*       hence ker(A)={x|Ax=0} and Im(A)={xA}
300RETURN:  toric ideal specified by Hilbert basis thereof
301EXAMPLE: example graver4ti2; shows an example
302"
303{
304//--------------------------------------------------------------------------
305// Initialization and Sanity Checks
306//--------------------------------------------------------------------------
307   int i,j;
308   int nr=nrows(A);
309   int nc=ncols(A);
310   string fileending="mat";
311   if (size(#)!=0)
312   {
313//--- default behaviour: use ker(A) as lattice
314//--- if #[1]!=0 use Im(A) as lattice
315      if(typeof(#[1])!="int")
316      {
317         ERROR("optional parameter needs to be integer value");\
318      }
319      if(#[1]!=0)
320      {
321         fileending="lat";
322      }
323   }
324//--- we should also be checking whether all entries are indeed integers
325//--- or whether there are fractions, but in this case the error message
326//--- of 4ti2 is printed directly
327      if(nvars(basering)!=ncols(A))
328      {
329          ERROR("number of columns needs to match number of variables");
330      }
331//--------------------------------------------------------------------------
332// preparing input file for 4ti2
333//--------------------------------------------------------------------------
334   link eing=":w sing4ti2."+fileending;
335   string eingstring=string(nr)+" "+string(nc);
336   write(eing,eingstring);
337   for(i=1;i<=nr;i++)
338   {
339      kill eingstring;
340      string eingstring;
341      for(j=1;j<=nc;j++)
342      {
343          if((deg(A[i,j])>0)||(char(basering)!=0)||(npars(basering)>0))
344          {
345             ERROR("Input to hilbert4ti2 needs to be a matrix with integer entries");
346          }
347          eingstring=eingstring+string(A[i,j])+" ";
348      }
349      write(eing, eingstring);
350   }
351   close(eing);
352
353//----------------------------------------------------------------------
354// calling 4ti2 and converting output
355// Singular's string is too clumsy for this, hence we first prepare
356// using standard unix commands
357//----------------------------------------------------------------------
358   // find the name of hilbert/4ti2-hilbert
359   string s_name=system("executable","hilbert");
360   if (size(s_name)==0)
361   {
362     s_name=system("executable","4ti2-hilbert"); /* debian*/
363     if (size(s_name)==0)
364     {
365       ERROR("hilbert not found (part of 4ti2)");
366     }
367     else { s_name="4ti2-hilbert"; }
368   }
369   else { s_name="hilbert"; }
370   j=system("sh",s_name+" sing4ti2 >/dev/null 2>&1");
371   j=system("sh","awk \'BEGIN{ORS=\",\";}{print $0;}\' sing4ti2.hil | sed s/[\\\ \\\t\\\v\\\f]/,/g | sed s/,+/,/g |sed s/,,/,/g|sed s/,,/,/g > sing4ti2.converted");
372   if(!defined(keepfiles))
373   {
374      j=system("sh",("rm -f sing4ti2.hil sing4ti2."+fileending));
375   }
376//----------------------------------------------------------------------
377// reading output of 4ti2
378//----------------------------------------------------------------------
379   link ausg=":r sing4ti2.converted";
380//--- last entry ideal(0) is used to tie the list to the basering
381//--- it will not be processed any further
382   string ergstr="list erglist="+read(ausg)+ string(ideal(0))+";";
383   execute(ergstr);
384   ideal toric;
385   poly temppol1,temppol2;
386   for(i=1;i<=erglist[1];i++)
387   {
388     temppol1=1;
389     temppol2=1;
390     for(j=1;j<=erglist[2];j++)
391     {
392        if(erglist[2+(i-1)*erglist[2]+j]>=0)
393        {
394//--- positive exponents
395           temppol1=temppol1*(var(j)^erglist[2+(i-1)*erglist[2]+j]);
396        }
397        else
398        {
399//--- negative exponents
400           temppol2=temppol2*(var(j)^(-erglist[2+(i-1)*erglist[2]+j]));
401        }
402     }
403     toric=toric,temppol1-temppol2;
404   }
405//--- get rid of leading entry 0;
406   toric=toric[2..ncols(toric)];
407   return(toric);
408}
409// A nice example here is the 3x3 Magic Squares
410example
411{"EXAMPLE:";
412   echo=2;
413   ring r=0,(x1,x2,x3,x4,x5,x6,x7,x8,x9),dp;
414   matrix M[7][9]=1,1,1,-1,-1,-1,0,0,0,1,1,1,0,0,0,-1,-1,-1,0,1,1,-1,0,0,-1,0,0,1,0,1,0,-1,0,0,-1,0,1,1,0,0,0,-1,0,0,-1,0,1,1,0,-1,0,0,0,-1,1,1,0,0,-1,0,-1,0,0;
415   hilbert4ti2(M);
416}
417
418/////////////////////////////////////////////////////////////////////////////
419
Note: See TracBrowser for help on using the repository browser.