source: git/Singular/LIB/ring.lib

spielwiese
Last change on this file was 84632f, checked in by Hans Schoenemann <hannes@…>, 15 months ago
fix: remove some execute from ring.lib, reesclos.lib
  • Property mode set to 100644
File size: 39.3 KB
Line 
1/////////////////////////////////////////////////////////////////////////////
2version="version ring.lib 4.3.1.3 Feb_2023 "; // $Id$
3category="General purpose";
4info="
5LIBRARY:  ring.lib      Manipulating Rings and Maps
6AUTHORS: Singular team
7
8PROCEDURES:
9 changechar(c[,r]); make a copy of basering [ring r] with new char c
10 changeord(o[,r]);  make a copy of basering [ring r] with new ord o
11 changevar(v[,r]);  make a copy of basering [ring r] with new vars v
12 defring(\"R\",c,n,v,o);  define a ring R in specified char c, n vars v, ord o
13 defrings(n[,p]);         define ring Sn in n vars, char 32003 [p], ord ds
14 defringp(n[,p]);         define ring Pn in n vars, char 32003 [p], ord dp
15 extendring(\"R\",n,v,o); extend given ring by n vars v, ord o and name it R
16 fetchall(R[,str]);       fetch all objects of ring R to basering
17 imapall(R[,str]);        imap all objects of ring R to basering
18 mapall(R,i[,str]);       map all objects of ring R via ideal i to basering
19 ord_test(R);             test whether ordering of R is global, local or mixed
20 ringtensor(s,t,..);      create ring, tensor product of rings s,t,...
21 ringweights(r);          intvec of weights of ring variables of ring r
22 preimageLoc(R,phi,Q)     computes preimage for non-global orderings
23 rootofUnity(n);          the minimal polynomial for the n-th primitive root of unity
24             (parameters in square brackets [] are optional)
25 optionIsSet(opt)         check if as a string given option is set or not.
26 hasFieldCoefficient      check if the coefficient ring is considered a field
27 hasGFCoefficient         check if the coefficient ring is GF(p,k)
28 hasZpCoefficient         check if the coefficient ring is ZZ/p
29 hasZp_aCoefficient       check if the coefficient ring is an elag. ext. of ZZ/p
30 hasQQCoefficient         check if the coefficient ring is QQ
31 hasNumericCoeffs(rng)    check for use of floating point numbers
32 hasCommutativeVars(rng)  non-commutative or commutative polynomial ring
33 hasGlobalOrdering(rng)   global versus mixed/local monomial ordering
34 hasMixedOrdering()       mixed versus global/local ordering
35 hasAlgExtensionCoefficient(r) coefficients are an algebraic extension
36 hasTransExtensionCoefficient(r) coefficients are rational functions
37 isQuotientRing(rng)      ring is a qotient ring
38 isSubModule(I,J)         check if I is in J as submodule
39
40 changeordTo(r,o)         change the ordering of a ring to a simple one
41 addvarsTo(r,vars,i)      add variables to a ring
42 addNvarsTo(r,N,name,i)   add N variables to a ring
43";
44
45LIB "inout.lib";
46LIB "general.lib";
47LIB "primdec.lib";
48
49///////////////////////////////////////////////////////////////////////////////
50proc optionIsSet(string optionName)
51"
52USAGE:       optionIsSet( optionName )
53PARAMETERS:  optionName: a name as string of an option of interest
54RETURN:      true, if the by optionName given option is active, false otherwise.
55EXAMPLE:     example optionIsSet;
56"
57{
58   intvec op = option(get);
59   //sanity check, if option is valid. will raise an error if not
60   option(optionName);    option("no" + optionName);
61   option(set,op);
62   // first entry is currently a comment "//options:", which is not an option.
63   int pos = find(option(), optionName, 11 );
64   return(pos>0);
65}
66example
67{  "EXAMPLE:"; echo = 2;
68    // check if the option "warn" is set.
69    optionIsSet("warn");
70    option("warn");
71    // now the option is set
72    optionIsSet("warn");
73
74    option("nowarn");
75    // now the option is unset
76    optionIsSet("warn");
77}
78
79
80static proc testOptionIsSet()
81{
82     option("warn");
83     ASSUME(0, optionIsSet("warn") );
84     option("nowarn");
85     ASSUME(0, 0 == optionIsSet("warn") );
86}
87
88///////////////////////////////////////////////////////////////////////////////
89
90proc changechar (list @L, list #)
91"USAGE:   changechar(c[,r]);  c=list, r=ring
92RETURN:  ring R, obtained from the ring r [default: r=basering], by changing
93         ring_list(r)[1] to c.
94EXAMPLE: example changechar; shows an example
95"
96{
97   def save_ring=basering;
98   if( size(#)==0 ) { def @r=basering; }
99   if(( size(#)==1 ) and (typeof(#[1])=="ring")) { def @r=#[1]; }
100   setring @r;
101   list rl=ring_list(@r);
102   if(defined(@L)!=voice) { def @L=fetch(save_ring,@L); }
103   if (size(@L)==1) { rl[1]=@L[1];} else { rl[1]=@L;}
104   def Rnew=ring(rl);
105   setring save_ring;
106   return(Rnew);
107}
108example
109{  "EXAMPLE:"; echo = 2;
110   ring rr=2,A,dp;
111   ring r=0,(x,y,u,v),(dp(2),ds);
112   def R=changechar(ringlist(rr)); R;"";
113   def R1=changechar(32003,R); setring R1; R1;
114   kill R,R1;
115}
116///////////////////////////////////////////////////////////////////////////////
117
118proc changeord (list @o, list #)
119"USAGE:   changeord(neword[,r]);  newordstr=list, r=ring/qring
120RETURN:  ring R, obtained from the ring r [default: r=basering], by changing
121         order(r) to neword.
122         If, say, neword=list(list(\"wp\",intvec(2,3)),list(list(\"dp\",1:(n-2))));
123         and if the ring r exists and has n variables, the ring R will be
124         equipped with the monomial ordering wp(2,3),dp.
125EXAMPLE: example changeord; shows an example
126"
127{
128   def save_ring=basering;
129   if( size(#)==0 ) { def @r=basering; }
130   if( size(#)==1 ) { def @r=#[1]; }
131   setring @r;
132   list rl=ring_list(@r);
133   rl[3]=@o;
134   def Rnew=ring(rl);
135   setring save_ring;
136   return(Rnew);
137}
138example
139{  "EXAMPLE:"; echo = 2;
140   ring r=0,(x,y,u,v),(dp(2),ds);
141   def R=changeord(list(list("wp",intvec(2,3)),list("dp",1:2))); R; "";
142   ideal i = x^2,y^2-u^3,v;
143   qring Q = std(i);
144   def Q'=changeord(list(list("lp",nvars(Q))),Q); setring Q'; Q';
145   kill R,Q,Q';
146}
147///////////////////////////////////////////////////////////////////////////////
148
149proc changevar (string vars, list #)
150"USAGE:   changevar(vars[,r]);  vars=string, r=ring/qring
151RETURN:  ring R, obtained from the ring r [default: r=basering], by changing
152         varstr(r) according to the value of vars.
153         If, say, vars = \"t()\" and the ring r exists and has n
154         variables, the new basering will have name R and variables
155         t(1),...,t(n).
156         If vars = \"a,b,c,d\", the new ring will have the variables a,b,c,d.
157NOTE:    This procedure is useful in connection with the procedure ringtensor,
158         when a conflict between variable names must be avoided.
159         This proc uses 'execute' or calls a procedure using 'execute'.
160EXAMPLE: example changevar; shows an example
161"
162{
163   if( size(#)==0 ) { def @r=basering; }
164   if( size(#)==1 ) { def @r=#[1]; }
165   setring @r;
166   ideal i = ideal(@r); int @q = size(i);
167   if( @q!=0 )
168      { string @s = "Rnew1"; }
169   else
170      { string @s = "Rnew"; }
171   string @newring = @s+"=("+charstr(@r)+"),(";
172   if( vars[size(vars)-1]=="(" and vars[size(vars)]==")" )
173   {
174      @newring = @newring+vars[1,size(vars)-2]+"(1.."+string(nvars(@r))+")";
175   }
176   else { @newring = @newring+vars; }
177   string ords=ordstr(@r);
178   int l=size(ords);
179   int l1,l2;
180   while(l>0)
181   {
182     if (ords[l]=="(") { l1=l; break; }
183     if (ords[l]==")") { l2=l; }
184     l--;
185   }
186   string last_ord=string(ords[l1-3..l1-1]);
187   if ((last_ord[1]!="w")
188   && (last_ord[1]!="W")
189   && (last_ord[2]!="M"))
190   {
191     if (l2==size(ords)) { ords=string(ords[1..l1-1]); }
192     else { ords=string(ords[1..l1-1])+string(ords[l2+1..size(ords)]); }
193   }
194   @newring = @newring+"),("+ords+");";
195   execute("ring "+@newring);
196   if( @q!=0 )
197   {
198      map phi = @r,maxideal(1);
199      ideal i = phi(i);
200      attrib(i,"isSB",1);         //*** attrib funktioniert ?
201      qring Rnew=i;
202   }
203   return(Rnew);
204}
205example
206{  "EXAMPLE:"; echo = 2;
207   ring r=0,(x,y,u,v),(dp(2),ds);
208   ideal i = x^2,y^2-u^3,v;
209   qring Q = std(i);
210   setring(r);
211   def R=changevar("A()"); R; "";
212   def Q'=changevar("a,b,c,d",Q); setring Q'; Q';
213   kill R,Q,Q';
214}
215///////////////////////////////////////////////////////////////////////////////
216
217proc defring (string s2, int n, string s3, string s4)
218"USAGE:   defring(ch,n,va,or);  ch,va,or=strings, n=integer
219RETURN:  ring R with characteristic 'ch', ordering 'or' and n variables with
220         names derived from va.
221         If va is a single letter, say va=\"a\", and if n<=26 then a and the
222         following n-1 letters from the alphabet (cyclic order) are taken as
223         variables. If n>26 or if va is a single letter followed by a bracket,
224         say va=\"T(\", the variables are T(1),...,T(n).
225NOTE:    This proc is useful for defining a ring in a procedure.
226         This proc uses 'execute' or calls a procedure using 'execute'.
227EXAMPLE: example defring; shows an example
228"
229{
230   return(create_ring(s2,A_Z_L(s3,n),s4));
231}
232example
233{ "EXAMPLE:"; echo = 2;
234   def r=defring("0",5,"u","ls"); r; setring r;"";
235   def R=defring("(2,A)",10,"x(","(dp(3),ws(1,2,3),ds)"); R; setring R;
236}
237///////////////////////////////////////////////////////////////////////////////
238
239proc defrings (int n, list #)
240"USAGE:   defrings(n,[p]);  n,p integers
241RETURN:  ring R with characteristic p [default: p=32003], ordering ds and n
242         variables x,y,z,a,b,...if n<=26 (resp. x(1..n) if n>26)
243NOTE:    This proc uses 'execute' or calls a procedure using 'execute'.
244EXAMPLE: example defrings; shows an example
245"
246{
247   int p;
248   if (size(#)==0) { p=32003; }
249   else { p=#[1]; }
250   if (n >26)
251   {
252    list l1;
253    for (int zz = 1; zz <= n; zz++)
254    {
255     l1[zz] = "x("+string(zz)+")";
256    }
257    ring S = create_ring(p, l1, "ds");
258   }
259   else
260   {
261    ring S = create_ring(p, "("+A_Z("x",n)+")", "ds");
262   }
263   dbprint(printlevel-voice+2,"
264// 'defrings' created a ring. To see the ring, type (if the name R was
265// assigned to the return value):
266    show R;
267// To make the ring the active basering, type
268    setring R; ");
269   return(S);
270}
271example
272{ "EXAMPLE:"; echo = 2;
273   def S5=defrings(5,0); S5; "";
274   def S30=defrings(30); S30;
275   kill S5,S30;
276}
277///////////////////////////////////////////////////////////////////////////////
278
279proc defringp (int n,list #)
280"USAGE:   defringp(n,[p]);  n,p=integers
281RETURN:  ring R with characteristic p [default: p=32003], ordering dp and n
282         variables x,y,z,a,b,...if n<=26 (resp. x(1..n) if n>26)
283NOTE:    This proc uses 'execute' or calls a procedure using 'execute'.
284EXAMPLE: example defringp; shows an example
285"
286{
287   int p;
288   if (size(#)==0) { p=32003; }
289   else { p=#[1]; }
290   if (n >26)
291   {
292    list l2;
293    for (int zz = 1; zz <= n; zz++)
294    {
295     l2[zz] = "x("+string(zz)+")";
296    }
297    ring P = create_ring(p, l2, "dp");
298   }
299   else
300   {
301    ring P = create_ring(p, "("+A_Z("x",n)+")", "dp");
302   }
303   dbprint(printlevel-voice+2,"
304// 'defringp' created a ring. To see the ring, type (if the name R was
305// assigned to the return value):
306    show R;
307// To make the ring the active basering, type
308    setring R; ");
309   return(P);
310}
311example
312{ "EXAMPLE:"; echo = 2;
313   def P5=defringp(5,0); P5; "";
314   def P30=defringp(30); P30;
315   kill P5,P30;
316}
317///////////////////////////////////////////////////////////////////////////////
318
319proc extendring (int n, string va, string o, list #)
320"USAGE:   extendring(n,va,o[,iv,i,r]);  va,o=strings, n,i=integers, r=ring,
321          iv=intvec of positive integers or iv=0
322RETURN:  ring R, which extends the ring r by adding n new variables in front
323         of (resp. after, if i!=0) the old variables.
324         [default: (i,r)=(0,basering)].
325@*       -- The characteristic is the characteristic of r.
326@*       -- The new vars are derived from va. If va is a single letter, say
327            va=\"T\", and if n<=26 then T and the following n-1 letters from
328            T..Z..T (resp. T(1..n) if n>26) are taken as additional variables.
329            If va is a single letter followed by a bracket, say va=\"x(\",
330            the new variables are x(1),...,x(n).
331@*       -- The ordering is the product ordering of the ordering of r and of an
332            ordering derived from `o` [and iv].
333@*        -  If o contains a 'c' or a 'C' in front resp. at the end, this is
334            taken for the whole ordering in front, resp. at the end. If o does
335            not contain a 'c' or a 'C' the same rule applies to ordstr(r).
336@*        -  If no intvec iv is given, or if iv=0, o may be any allowed ordstr,
337            like \"ds\" or \"dp(2),wp(1,2,3),Ds(2)\" or \"ds(a),dp(b),ls\" if
338            a and b are globally (!) defined integers and if a+b+1<=n.
339            If, however, a and b are local to a proc calling extendring, the
340            intvec iv must be used to let extendring know the values of a and b
341@*        -  If a non-zero intvec iv is given, iv[1],iv[2],... are taken for the
342            1st, 2nd,... block of o, if o contains no substring \"w\" or \"W\"
343            i.e. no weighted ordering (in the above case o=\"ds,dp,ls\"
344            and iv=a,b).
345            If o contains a weighted ordering (only one (!) weighted block is
346            allowed) iv[1] is taken as size for the weight-vector, the next
347            iv[1] values of iv are taken as weights and the remaining values of
348            iv as block size for the remaining non-weighted blocks.
349            e.g. o=\"dp,ws,Dp,ds\", iv=3,2,3,4,2,5 creates the ordering
350            dp(2),ws(2,3,4),Dp(5),ds
351NOTE:    This proc is useful for adding deformation parameters.
352         This proc uses 'execute' or calls a procedure using 'execute'.
353         If you use it in your own proc, it may be advisable to let the local
354         names of your proc start with a @
355EXAMPLE: example extendring; shows an example
356"
357{
358//--------------- initialization and place c/C of ordering properly -----------
359   string @o1,@o2,@ro,@wstr,@v,@newring;
360   int @i,@w,@ii,@k;
361   intvec @iv,@iw;
362   if( find(o,"c")+find(o,"C") != 0)
363   {
364      @k=1;
365      if( o[1]=="c" or o[1]=="C" ) { @o1=o[1,2]; o=o[3..size(o)]; }
366      else                         { @o2=o[size(o)-1,2]; o=o[1..size(o)-2]; }
367   }
368   if( size(#)==0 ) { #[1]=0; }
369   if( typeof(#[1])!="intvec" )
370   {
371     if( size(#)==1 ) { @i=#[1]; def @r=basering; }
372     if( size(#)==2 ) { @i=#[1]; def @r=#[2]; }
373     if( o[size(o)]!=")" and find(o,",")==0 ) { o=o+"("+string(n)+")"; }
374   }
375   else
376   {
377     @iv=#[1];
378     if( size(#)==2 ) { @i=#[2]; def @r=basering; }
379     if( size(#)==3 ) { @i=#[2]; def @r=#[3]; }
380     if( @iv==0 && o[size(o)]!=")" && find(o,",")==0 ) {o=o+"("+string(n)+")";}
381   }
382   @ro=ordstr(@r);
383   if( @ro[1]=="c" or @ro[1]=="C" )
384      { @v=@ro[1,2]; @ro=@ro[3..size(@ro)]; }
385   else
386      { @wstr=@ro[size(@ro)-1,2]; @ro=@ro[1..size(@ro)-2]; }
387   if( @k==0) { @o1=@v; @o2=@wstr; }
388//----------------- prepare ordering if an intvec is given --------------------
389   if( typeof(#[1])=="intvec" and #[1]!=0 )
390   {
391      @k=n;                             //@k counts no of vars not yet ordered
392      @w=find(o,"w")+find(o,"W");o=o+" ";
393      if( @w!=0 )
394      {
395         @wstr=o[@w..@w+1];
396         o=o[1,@w-1]+"@"+o[@w+2,size(o)];
397         @iw=@iv[2..@iv[1]+1];
398         @wstr=@wstr+"("+string(@iw)+")";
399         @k=@k-@iv[1];
400         @iv=@iv[@iv[1]+2..size(@iv)];
401         @w=0;
402      }
403      for( @ii=1; @ii<=size(@iv); @ii=@ii+1 )
404      {
405         if( find(o,",",@w+1)!=0 )
406         {
407            @w=find(o,",",@w+1);
408            if( o[@w-1]!="@" )
409            {
410               o=o[1,@w-1]+"("+string(@iv[@ii])+")"+o[@w,size(o)];
411               @w=find(o,",",@w+1);
412               @k=@k-@iv[@ii];
413            }
414            else { @ii=@ii-1; }
415         }
416      }
417      @w=find(o,"@");
418      if( @w!=0 ) { o=o[1,@w-1] + @wstr + o[@w+1,size(o)]; }
419      if( @k>0 and o[size(o)]!=")" ) { o=o+"("+string(@k)+")"; }
420   }
421//------------------------ prepare string of new ring -------------------------
422   list @ringlist=ring_list(@r);
423   list @varlist=A_Z_L(va,n);
424   if (@i==0)
425   {
426     @varlist=@varlist+@ringlist[2];
427     o=@o1+o+","+@ro+@o2;
428   }
429   else
430   {
431     @varlist=@ringlist[2]+@varlist;
432     o=@o1+@ro+","+o+@o2;
433   }
434   @i=find(o," ");
435   while(@i!=0)
436   {
437     o=o[1,@i-1]+o[@i+1,size(o)-@i];
438     @i=find(o," ");
439   }
440//---------------------------- execute and export -----------------------------
441   dbprint(printlevel-voice+2,"
442// 'extendring' created a new ring.
443// To see the ring, type (if the name 'R' was assigned to the return value):
444     show(R);
445");
446
447   o="("+o+")";
448   return(create_ring(@ringlist[1],@varlist,o));
449}
450example
451{ "EXAMPLE:"; echo = 2;
452   ring r=0,(x,y,z),ds;
453   show(r);"";
454   // blocksize is derived from no of vars:
455   int t=5;
456   def R1=extendring(t,"a","dp");         //t global: "dp" -> "dp(5)"
457   show(R1); setring R1; "";
458   def R2=extendring(4,"T(","c,dp",1,r);    //"dp" -> "c,..,dp(4)"
459   show(R2); setring R2; "";
460
461   // no intvec given, blocksize given: given blocksize is used:
462   def R3=extendring(4,"T(","dp(2)",0,r);   // "dp(2)" -> "dp(2)"
463   show(R3); setring R3; "";
464
465   // intvec given: weights and blocksize is derived from given intvec
466   // (no specification of a blocksize in the given ordstr is allowed!)
467   // if intvec does not cover all given blocks, the last block is used
468   // for the remaining variables, if intvec has too many components,
469   // the last ones are ignored
470   intvec v=3,2,3,4,1,3;
471   def R4=extendring(10,"A","ds,ws,Dp,dp",v,0,r);
472   // v covers 3 blocks: v[1] (=3) : no of components of ws
473   // next v[1] values (=v[2..4]) give weights
474   // remaining components of v are used for the remaining blocks
475   show(R4);
476   kill r,R1,R2,R3,R4;
477}
478///////////////////////////////////////////////////////////////////////////////
479
480proc fetchall (def R, list #)
481"USAGE:   fetchall(R[,s]);  R=ring/qring, s=string
482CREATE:  fetch all objects of ring R (of type poly/ideal/vector/module/number/matrix)
483         into the basering.
484         If no 2nd argument is present, the names are the same as in R. If,
485         say, f is a polynomial in R and the 2nd argument is the string \"R\", then f
486         is mapped to f_R etc.
487RETURN:  no return value
488NOTE:    As fetch, this procedure maps the 1st, 2nd, ... variable of R to the
489         1st, 2nd, ... variable of the basering.
490         The 2nd argument is useful in order to avoid conflicts of names, the
491         empty string is allowed
492CAUTION: fetchall does not work for locally defined names.
493         It does not work if R contains a map.
494SEE ALSO: imapall
495EXAMPLE: example fetchall; shows an example
496"
497{
498   list @L@=names(R);
499   int @ii@; string @s@;
500   if( size(#) > 0 ) { @s@=@s@+"_"+#[1]; }
501   for( @ii@=size(@L@); @ii@>0; @ii@-- )
502   {
503      execute("def "+@L@[@ii@]+@s@+"=fetch(R,`@L@[@ii@]`);");
504      execute("export "+@L@[@ii@]+@s@+";");
505   }
506   return();
507}
508example
509{  "EXAMPLE:"; echo=2;
510// The example is not shown since fetchall does not work in a procedure;
511// (and hence not in the example procedure). Try the following commands:
512//   ring R=0,(x,y,z),dp;
513//   ideal j=x,y2,z2;
514//   matrix M[2][3]=1,2,3,x,y,z;
515//   j; print(M);
516//   ring S=0,(a,b,c),ds;
517//   fetchall(R);       //map from R to S: x->a, y->b, z->c;
518//   names(S);
519//   j; print(M);
520//   fetchall(S,"1");   //identity map of S: copy objects, change names
521//   names(S);
522//   kill R,S;
523}
524///////////////////////////////////////////////////////////////////////////////
525
526proc imapall (def R, list #)
527"USAGE:   imapall(R[,s]);  R=ring/qring, s=string
528CREATE:  map all objects of ring R (of type poly/ideal/vector/module/number/matrix)
529         into the basering by applying imap to all objects of R.
530         If no 2nd argument is present, the names are the same as in R. If,
531         say, f is a polynomial in R and the 3rd argument is the string \"R\", then f
532         is mapped to f_R etc.
533RETURN:  no return value
534NOTE:    As imap, this procedure maps the variables of R to the variables with
535         the same name in the basering, the other variables are mapped to 0.
536         The 2nd argument is useful in order to avoid conflicts of names, the
537         empty string is allowed
538CAUTION: imapall does not work for locally defined names.
539         It does not work if R contains a map
540SEE ALSO: fetchall
541EXAMPLE: example imapall; shows an example
542"
543{
544   list @L@=names(R);
545   int @ii@; string @s@;
546   if( size(#) > 0 ) { @s@=@s@+"_"+#[1]; }
547   for( @ii@=size(@L@); @ii@>0; @ii@-- )
548   {
549         execute("def "+@L@[@ii@]+@s@+"=imap(R,`@L@[@ii@]`);");
550         execute("export "+@L@[@ii@]+@s@+";");
551   }
552   return();
553}
554example
555{  "EXAMPLE:"; echo = 2;
556// The example is not shown since imapall does not work in a procedure
557// (and hence not in the example procedure). Try the following commands:
558//   ring R=0,(x,y,z,u),dp;
559//   ideal j=x,y,z,u2+ux+z;
560//   matrix M[2][3]=1,2,3,x,y,uz;
561//   j; print(M);
562//   ring S=0,(a,b,c,x,z,y),ds;
563//   imapall(R);         //map from R to S: x->x, y->y, z->z, u->0
564//   names(S);
565//   j; print(M);
566//   imapall(S,"1");     //identity map of S: copy objects, change names
567//   names(S);
568//   kill R,S;
569}
570///////////////////////////////////////////////////////////////////////////////
571
572proc mapall (def R, ideal i, list #)
573"USAGE:   mapall(R,i[,s]);  R=ring/qring, i=ideal of basering, s=string
574CREATE:  map all objects of ring R (of type poly/ideal/vector/module/number/
575         matrix, map) into the basering by mapping the j-th variable of R to
576         the j-th generator of the ideal i. If no 3rd argument is present, the
577         names are the same as in R. If, say, f is a polynomial in R and the 3rd
578         argument is the string \"R\", then f is mapped to f_R etc.
579RETURN:  no return value.
580NOTE:    This procedure has the same effect as defining a map, say psi, by
581         map psi=R,i; and then applying psi to all objects of R. In particular,
582         maps from R to some ring S are composed with psi, creating thus a map
583         from the basering to S.
584         mapall may be combined with copyring to change vars for all objects.
585         The 3rd argument is useful in order to avoid conflicts of names, the
586         empty string is allowed.
587CAUTION: mapall does not work for locally defined names.
588EXAMPLE: example mapall; shows an example
589"
590{
591   list @L@=names(R); map @psi@ = R,i;
592   int @ii@; string @s@;
593   if( size(#) > 0 ) { @s@=@s@+"_"+#[1]; }
594   for( @ii@=size(@L@); @ii@>0; @ii@-- )
595   {
596      execute("def "+@L@[@ii@]+@s@+"=@psi@(`@L@[@ii@]`);");
597      execute("export "+@L@[@ii@]+@s@+";");
598   }
599   return();
600}
601example
602{  "EXAMPLE:"; echo = 2;
603// The example is not shown since mapall does not work in a procedure
604// (and hence not in the example procedure). Try the following commands:
605//   ring R=0,(x,y,z),dp;
606//   ideal j=x,y,z;
607//   matrix M[2][3]=1,2,3,x,y,z;
608//   map phi=R,x2,y2,z2;
609//   ring S=0,(a,b,c),ds;
610//   ideal i=c,a,b;
611//   mapall(R,i);         //map from R to S: x->c, y->a, z->b
612//   names(S);
613//   j; print(M); phi;    //phi maps R to S: x->c2, y->a2, z->b2
614//   ideal i1=a2,a+b,1;
615//   mapall(R,i1,\"\");     //map from R to S: x->a2, y->a+b, z->1
616//   names(S);
617//   j_; print(M_); phi_;
618//   changevar(\"T\",\"x()\",R);  //change vars in R and call result T
619//   mapall(R,maxideal(1));   //identity map from R to T
620//   names(T);
621//   j; print(M); phi;
622//   kill R,S,T;
623}
624///////////////////////////////////////////////////////////////////////////////
625
626proc ord_test (def r)
627"USAGE:   ord_test(r);  r ring/qring
628RETURN:  int 1 (resp. -1, resp. 0) if ordering of r is global (resp. local,
629         resp. mixed)
630SEE ALSO: attrib
631EXAMPLE: example ord_test; shows an example
632"
633{
634   if (typeof(r) != "ring")
635   {
636      ERROR("ord_test requires a ring/qring as input");
637   }
638   if (attrib(r,"global")==1) { return(1);}
639   def BAS = basering;
640   setring r;
641   poly f;
642   int n,o,u = nvars(r),1,1;
643   int ii;
644   for ( ii=1; ii<=n; ii++ )
645   {
646      f = 1+var(ii);
647      o = o*(lead(f) == var(ii));
648      u = u*(lead(f) == 1);
649   }
650   setring BAS;
651   if ( o==1 ) { return(1); }
652   if ( u==1 ) { return(-1); }
653   else { return(0); }
654}
655example
656{ "EXAMPLE:"; echo = 2;
657   ring R = 0,(x,y),dp;
658   ring S = 0,(u,v),ls;
659   ord_test(R);
660   ord_test(S);
661   ord_test(R+S);
662}
663///////////////////////////////////////////////////////////////////////////////
664
665proc ringtensor (list #)
666"USAGE:   ringtensor(r1,r2,...);  r1,r2,...=rings
667RETURN:  ring R whose variables are the variables from all rings r1,r2,...
668         and whose monomial ordering is the block (product) ordering of the
669         respective monomial orderings of r1,r2,... . Hence, R
670         is the tensor product of the rings r1,r2,... with ordering matrix
671         equal to the direct sum of the ordering matrices of r1,r2,...
672NOTE:    The characteristic of the new ring will be p if one ring has
673         characteristic p. The names of variables in the rings r1,r2,...
674         must differ.
675         The procedure works also for quotient rings ri, if the characteristic
676         of ri is compatible with the characteristic of the result
677         (i.e. if imap from ri to the result is implemented)
678SEE ALSO: ring operations
679EXAMPLE: example ringtensor; shows an example
680"
681{
682   int @i;
683   int @n = size(#);
684   if (@n<=1) { ERROR("at least 2 rings required"); }
685   def @s=#[1]+#[2];
686   for (@i=3; @i<=@n;@i++)
687   {
688     def @ss=@s+#[@i];
689     kill @s;
690     def @s=@ss;
691     kill @ss;
692   }
693   dbprint(printlevel-voice+2,"
694// 'ringtensor' created a ring. To see the ring, type (if the name R was
695// assigned to the return value):
696    show(R);
697// To make the ring the active basering, type
698    setring R; ");
699   return(@s);
700}
701example
702{ "EXAMPLE:"; echo = 2;
703   ring r=32003,(x,y,u,v),dp;
704   ring s=0,(a,b,c),wp(1,2,3);
705   ring t=0,x(1..5),(c,ls);
706   def R=ringtensor(r,s,t);
707   type R;
708   setring s;
709   ideal i = a2+b3+c5;
710   def S=changevar("x,y,z");       //change vars of s
711   setring S;
712   qring qS =std(fetch(s,i));      //create qring of S mod i (mapped to S)
713   def T=changevar("d,e,f,g,h",t); //change vars of t
714   setring T;
715   qring qT=std(d2+e2-f3);         //create qring of T mod d2+e2-f3
716   def Q=ringtensor(s,qS,t,qT);
717   setring Q; type Q;
718   kill R,S,T,Q;
719}
720///////////////////////////////////////////////////////////////////////////////
721
722proc ringweights (def P)
723"USAGE:   ringweights(P); P=name of an existing ring (true name, not a string)
724RETURN:  intvec consisting of the weights of the variables of P, as they
725         appear when typing P;.
726NOTE:    This is useful when enlarging P but keeping the weights of the old
727         variables.
728EXAMPLE: example ringweights; shows an example
729"
730{
731   int i;
732   intvec rw;
733//------------------------- find weights  -------------------------
734   for(i=nvars(P);i>0;i--)
735   { rw[i]=ord(var(i)); }
736   return(rw);
737}
738example
739{"EXAMPLE:";  echo = 2;
740  ring r0 = 0,(x,y,z),dp;
741  ringweights(r0);
742  ring r1 = 0,x(1..5),(ds(3),wp(2,3));
743  ringweights(r1);"";
744  // an example for enlarging the ring, keeping the first weights:
745  intvec v = ringweights(r1),6,2,3,4,5;
746  ring R = 0,x(1..10),(a(v),dp);
747  ordstr(R);
748}
749///////////////////////////////////////////////////////////////////////////////
750proc preimageLoc(string R_name,string phi_name,string Q_name )
751"USAGE: preimageLoc ( ring_name, map_name, ideal_name );
752        all input parameters of type string
753RETURN:  ideal
754PURPOSE: compute the preimage of an ideal under a given map for non-global
755         orderings.
756         The 2nd argument has to be the name of a map from the basering to
757         the given ring (or the name of an ideal defining such a map), and
758         the ideal has to be an ideal in the given ring.
759SEE ALSO: preimage
760KEYWORDS: preimage under a map between local rings, map between local rings, map between local and global rings
761EXAMPLE: example preimageLoc ; shows an example
762"{
763  def S=basering;
764  int i;
765  string newRing,minpoly_string;
766  if(attrib(S,"global")!=1)
767  {
768    if(size(ideal(S))>0) /*qring*/
769    {
770      ideal I=ideal(S);
771      list l8 = ring_list(S)[2];
772      ring S0 = create_ring(ring_list(S)[1], l8, "dp");
773      ideal I=imap(S,I);
774      list pr=primdecGTZ(I);
775      ring SL = create_ring(ring_list(S)[1], l8, "("+ordstr(S)+")");
776      list pr=imap(S0,pr);
777      ideal I0=std(pr[1][1]);
778      for(i=2;i<=size(pr);i++)
779      {
780         I0=intersect(I0,std(pr[i][1]));
781      }
782      setring S0;
783      ideal I0=imap(SL,I0);
784      qring S1=std(I0);
785    }
786    else
787    {
788      def S1=S;
789    }
790  }
791  else
792  {
793    def S1=S;
794  }
795  def @R=`R_name`;
796  setring @R;
797  def @phi=`phi_name`;
798  ideal phiId=ideal(@phi);
799  def Q=`Q_name`;
800  if(attrib(@R,"global")!=1)
801  {
802    if(size(ideal(@R))>0) /*qring*/
803    {
804      ideal J=ideal(@R);
805      list l9 = ringlist(@R)[2];
806      ring R0 = create_ring(ring_list(@R)[1], l9, "dp");
807      ideal J=imap(@R,J);
808      list pr=primdecGTZ(J);
809      setring(@R);
810      ring RL = create_ring(ring_list(@R)[1], l9, "("+ordstr(@R)+")");
811      list pr=imap(R0,pr);
812      ideal J0=std(pr[1][1]);
813      for(i=2;i<=size(pr);i++)
814      {
815         J0=intersect(J0,std(pr[i][1]));
816      }
817      setring R0;
818      ideal J0=imap(RL,J0);
819      qring R1=std(J0);
820      ideal Q=imap(@R,Q);
821      map @phi=S1,imap(@R,phiId);
822    }
823    else
824    {
825      def R1=@R;
826    }
827  }
828  else
829  {
830    def R1=@R;
831  }
832  setring S1;
833  ideal preQ=preimage(R1,@phi,Q);
834  setring S;
835  ideal prQ=imap(S1,preQ);
836  return(prQ);
837}
838example
839{ "EXAMPLE:"; echo=2;
840  ring S =0,(x,y,z),dp;
841  ring R0=0,(x,y,z),ds;
842  qring R=std(x+x2); if(voice>1) {export R;}
843  map psi=S,x,y,z;   if(voice>1) {export psi;}
844  ideal null;        if(voice>1) {export null;}
845  setring S;
846  ideal nu=preimageLoc("R","psi","null");
847  nu;
848}
849
850//////////////////////////////////////////////////////////////////////////////
851/* moved here from the nctools.lib */
852////////////////////////////////////////////////////////////////////////////
853proc rootofUnity(int n)
854"USAGE:  rootofUnity(n); n an integer
855RETURN:  number
856PURPOSE: compute the minimal polynomial for the n-th primitive root of unity
857NOTE: works only in field extensions by one element
858EXAMPLE: example rootofUnity; shows examples
859"
860{
861  if ( npars(basering) !=1 )
862  {
863    ERROR(" the procedure works only with one ring parameter variable");
864  }
865  if (n<0) {  ERROR(" cannot compute ("+string(n)+")-th primitive root of unity"); }
866  if (n==0) { return(number(0));}
867  number mp = par(1);
868  if (n==1) { return(mp-1); }
869  if (n==2) { return(mp+1); }
870  def OldRing = basering;
871  list l10=ringlist(OldRing);
872  l10[2]=l10[1][2];
873  l10[1]=l10[1][1];
874  l10[3]=list(list("dp",1:1),list("C",0));
875  l10[4]=ideal(0);
876  int j=1;
877  ring @@rR = ring(l10);
878  poly @t=var(1)^n-1; // (x^2i-1)=(x^i-1)(x^i+1)
879  list l=factorize(@t);
880  ideal @l=l[1];
881  list @d;
882  int s=size(@l);
883  int d=deg(@l[s]);
884  int cnt=1;
885  poly res;
886  for (j=s-1; j>=1; j--)
887  {
888    if ( deg(@l[j]) > d) { d=deg(@l[j]); }
889  }
890  for (j=1; j<=s; j++)
891  {
892    if ( deg(@l[j]) == d) { @d[cnt]=@l[j]; cnt++; }
893  }
894
895  j=1;
896  int i;
897  number pw;
898
899  int @sized = size(@d);
900
901  if (@sized==1)
902  {
903       setring OldRing;
904       list @rl = imap(@@rR,@d);
905       mp = number(@rl[1]);
906       kill @@rR;
907       return(mp);
908  }
909  def @rng;
910
911  setring OldRing;
912
913  list rl = ring_list( OldRing);
914  while ( j<=@sized )
915  {
916     ASSUME(0, n%2 ==0);
917     setring OldRing;
918     @rng = ring(rl);
919     setring @rng;
920     list @rl = imap(@@rR,@d);
921     number mp = leadcoef( @rl[j] );
922     minpoly = mp;
923     number mp = minpoly;
924     number pw = par(1)^(n div 2);
925     if ( (pw != 1) || n==1 )  {  break;  }
926     j = j+1;
927  }
928  setring OldRing;
929  list @rl=imap(@@rR,@d);
930  mp = leadcoef( @rl[j] );
931  kill @@rR;
932  return(mp);
933}
934example
935{
936  "EXAMPLE:";echo=2;
937  ring r = (0,q),(x,y,z),dp;
938  rootofUnity(6);
939  rootofUnity(7);
940  minpoly = rootofUnity(8);
941  r;
942}
943
944
945proc isQuotientRing(def rng )
946"USAGE: isQuotientRing ( rng );
947RETURN:  1 if rng is a quotient ring, 0 otherwise.
948PURPOSE: check if typeof a rng "qring"
949KEYWORDS: qring ring ideal 'factor ring'
950EXAMPLE: example isQuotientRing ; shows an example
951"
952{
953    if ( defined(basering) )  {   def BAS=basering;  }
954    else { return (0); }
955
956    //access to quotient ideal will fail, if basering and rng differs.
957    setring rng;
958    int result =  ( size(ideal(rng)) != 0);
959
960    setring BAS;
961    return (result);
962}
963example
964{
965  "EXAMPLE:";echo=2;
966  ring rng = 0,x,dp;
967  isQuotientRing(rng); //no
968  // if a certain method does not support quotient rings,
969  // then a parameter test could be performed:
970   ASSUME( 0, 0==isQuotientRing(basering));
971
972  qring q= ideal(x);  // constructs rng/ideal(x)
973  isQuotientRing(q);  // yes
974}
975
976static proc testIsQuotientRing()
977{
978   ring rng7 = 7, x, dp;
979
980   ring rng = real,x,dp;
981   ASSUME(0, 0== isQuotientRing(rng) ) ;
982   ASSUME(0, 0== isQuotientRing(rng7) ) ;
983   ASSUME(0, char(basering)==0); // check that basering was not changed
984
985   qring qrng = 1;
986   ASSUME(0, isQuotientRing(qrng) ) ;
987
988   ring rng2 = integer,x,dp;
989   ASSUME(0, 0 == isQuotientRing(rng2) ) ;
990
991   qring qrng2=0;
992   ASSUME(0, not isQuotientRing(qrng2) ) ;
993
994   ring rng3 = 0,x,dp;
995   ASSUME(0, 0 == isQuotientRing(rng3) ) ;
996
997   qring qrng3=1;
998   ASSUME(0, isQuotientRing(qrng3) ) ;
999}
1000
1001proc hasFieldCoefficient(def rng )
1002"USAGE: hasFieldCoefficient ( rng );
1003RETURN:  1 if the coefficients form  (and are considered to be) a field, 0 otherwise.
1004KEYWORDS: ring coefficients
1005EXAMPLE: example hasFieldCoefficient; shows an example
1006SEE ALSO: attrib
1007"
1008{
1009  return (attrib(rng,"ring_cf")==0);
1010}
1011example
1012{
1013  "EXAMPLE:";echo=2;
1014  ring rng = integer,x,dp;
1015  hasFieldCoefficient(rng); //no
1016  // if a certain method supports only rings with integer coefficients,
1017  // then a parameter test could be performed:
1018  ring rng2 = 0, x, dp;
1019  hasFieldCoefficient(rng2);  // yes
1020}
1021
1022proc hasAlgExtensionCoefficient(def rng )
1023"USAGE: hasAlgExtensionCoefficient ( rng );
1024RETURN:  1 if the coefficients are an algebraic extension, 0 otherwise.
1025KEYWORDS: ring coefficients
1026EXAMPLE: example hasAlgExtensionCoefficient; shows an example
1027"
1028{
1029  return(attrib(rng,"cf_class")==7);
1030}
1031example
1032{
1033  "EXAMPLE:";echo=2;
1034  ring rng = integer,x,dp;
1035  hasAlgExtensionCoefficient(rng); //no
1036  ring rng2 = (0,a), x, dp; minpoly=a2-1;
1037  hasAlgExtensionCoefficient(rng2);  // yes
1038  ring rng3=(49,a),x,dp;
1039  hasAlgExtensionCoefficient(rng3);  // no
1040}
1041
1042proc hasTransExtensionCoefficient(def rng )
1043"USAGE: hasTransExtensionCoefficient ( rng );
1044RETURN:  1 if the coefficients are rational functions, 0 otherwise.
1045KEYWORDS: ring coefficients
1046EXAMPLE: example hasTransExtensionCoefficient; shows an example
1047"
1048{
1049  return(attrib(rng,"cf_class")==8);
1050}
1051example
1052{
1053  "EXAMPLE:";echo=2;
1054  ring rng = integer,x,dp;
1055  hasTransExtensionCoefficient(rng); //no
1056  ring rng2 = (0,a), x, dp;
1057  hasTransExtensionCoefficient(rng2);  // yes
1058  ring rng3=(49,a),x,dp;
1059  hasTransExtensionCoefficient(rng3);  // no
1060}
1061
1062proc hasGFCoefficient(def rng )
1063"USAGE: hasGFCoefficient ( rng );
1064RETURN:  1 if the coefficients are of the form GF(p,k), 0 otherwise.
1065KEYWORDS: ring coefficients
1066EXAMPLE: example hasGFCoefficient; shows an example
1067"
1068{
1069  return(attrib(rng,"cf_class")==4);
1070}
1071example
1072{
1073  "EXAMPLE:";echo=2;
1074  ring r1 = integer,x,dp;
1075  hasGFCoefficient(r1);
1076  ring r2 = (4,a),x,dp;
1077  hasGFCoefficient(r2);
1078  ring r3 = (2,a),x,dp;
1079  minpoly=a2+a+1;
1080  hasGFCoefficient(r3);
1081}
1082
1083proc hasZp_aCoefficient(def rng )
1084"USAGE: hasZp_aCoefficient ( rng );
1085RETURN:  1 if the coefficients are of the form Zp_a(p,k), 0 otherwise.
1086KEYWORDS: ring coefficients
1087EXAMPLE: example hasZp_aCoefficient; shows an example
1088"
1089{
1090  return((attrib(rng,"cf_class")==7) and (char(rng)>0));
1091}
1092example
1093{
1094  "EXAMPLE:";echo=2;
1095  ring r1 = integer,x,dp;
1096  hasZp_aCoefficient(r1);
1097  ring r2 = (4,a),x,dp;
1098  hasZp_aCoefficient(r2);
1099  ring r3 = (2,a),x,dp;
1100  minpoly=a2+a+1;
1101  hasZp_aCoefficient(r3);
1102}
1103
1104proc hasZpCoefficient(def rng )
1105"USAGE: hasZpCoefficient ( rng );
1106RETURN:  1 if the coefficcients are of the form ZZ/p, 0 otherwise.
1107KEYWORDS: ring coefficients
1108EXAMPLE: example hasZpCoefficient; shows an example
1109"
1110{
1111  return(attrib(rng,"cf_class")==1);
1112}
1113example
1114{
1115  "EXAMPLE:";echo=2;
1116  ring r1 = integer,x,dp;
1117  hasZpCoefficient(r1);
1118  ring r2 = 7,x,dp;
1119  hasZpCoefficient(r2);
1120}
1121
1122proc hasQQCoefficient(def rng )
1123"USAGE: hasQQCoefficient ( rng );
1124RETURN:  1 if the coefficcients are QQ, 0 otherwise.
1125KEYWORDS: ring coefficients
1126EXAMPLE: example hasQQCoefficient; shows an example
1127"
1128{
1129  return(attrib(rng,"cf_class")==2);
1130}
1131example
1132{
1133  "EXAMPLE:";echo=2;
1134  ring r1 = integer,x,dp;
1135  hasQQCoefficient(r1);
1136  ring r2 = QQ,x,dp;
1137  hasQQCoefficient(r2);
1138}
1139
1140proc hasGlobalOrdering (def rng)
1141"USAGE: hasGlobalOrdering ( rng );
1142RETURN:  1 if rng has a global monomial ordering, 0 otherwise.
1143KEYWORDS: monomial ordering
1144EXAMPLE: example hasGlobalOrdering; shows an example
1145"
1146{
1147  return (attrib(rng,"global")==1);
1148}
1149example
1150{ "EXAMPLE:"; echo=2;
1151  ring rng = integer,x,dp;
1152  hasGlobalOrdering(rng); //yes
1153  ring rng2 = 0, x, ds;
1154  hasGlobalOrdering(rng2);  // no
1155}
1156
1157proc hasCommutativeVars (def rng)
1158"USAGE: hasCommutativeVars ( rng );
1159RETURN:  1 if rng is a commutative polynomial ring, 0 otherwise.
1160KEYWORDS: plural
1161EXAMPLE: example hasCommutativeVars; shows an example
1162"
1163{
1164  list rl=ring_list(rng);
1165  return (size(rl)==4);
1166}
1167example
1168{ "EXAMPLE:"; echo=2;
1169 ring r=0,(x,y,z),dp;
1170 hasCommutativeVars(r);
1171}
1172
1173proc hasNumericCoeffs(def rng)
1174"USAGE: hasNumericCoeffs ( rng );
1175RETURN:  1 if rng has inexact coefficcients, 0 otherwise.
1176KEYWORDS: floating point
1177EXAMPLE: example hasNumericCoeffs; shows an example
1178"
1179{
1180  return((attrib(rng,"cf_class")==3) /*real*/
1181  or     (attrib(rng,"cf_class")==5) /*gmp real*/
1182  or     (attrib(rng,"cf_class")==9) /*gmp complex*/);
1183}
1184example
1185{
1186  "EXAMPLE:";echo=2;
1187  ring r1 = integer,x,dp;
1188  hasNumericCoeffs(r1);
1189  ring r2 = complex,x,dp;
1190  hasNumericCoeffs(r2);
1191}
1192
1193
1194proc isSubModule(def I,def J)
1195"USAGE: isSubModule(I,J): I, J: ideal or module
1196RETURN: 1 if module(I) is in module(J), 0 otherwise
1197EXAMPLE: isSubModule; shows an example
1198{
1199  if (attrib(J,"isSB"))
1200  { return(size(reduce(I,J,5))==0); }
1201  else
1202  { return(size(reduce(I,groebner(J),5))==0); }
1203}
1204example
1205{
1206  "EXAMPLE:"; echo = 2;
1207  ring r=0,x,dp;
1208  ideal I1=x2;
1209  ideal I2=x3;
1210  isSubModule(I1, I2);
1211  isSubModule(I2, I1);
1212}
1213
1214proc hasMixedOrdering()
1215"USAGE:  hasMixedOrdering();
1216RETURN:  1 if ordering of basering is mixed, 0 else
1217EXAMPLE: example hasMixedOrdering(); shows an example
1218"
1219{
1220   int i,p,m;
1221   for(i = 1; i <= nvars(basering); i++)
1222   {
1223      if(var(i) > 1)
1224      {
1225         p++;
1226      }
1227      else
1228      {
1229         m++;
1230      }
1231   }
1232   if((p > 0) && (m > 0)) { return(1); }
1233   return(0);
1234}
1235example
1236{ "EXAMPLE:"; echo = 2;
1237   ring R1 = 0,(x,y,z),dp;
1238   hasMixedOrdering();
1239   ring R2 = 31,(x(1..4),y(1..3)),(ds(4),lp(3));
1240   hasMixedOrdering();
1241   ring R3 = 181,x(1..9),(dp(5),lp(4));
1242   hasMixedOrdering();
1243}
1244
1245proc changeordTo(def r,string o)
1246"USAGE:  changeordTo(ring, string s);
1247RETURN:  a ring with the oderinging changed to the (simple) ordering s
1248EXAMPLE: example changeordTo(); shows an example
1249"
1250{
1251  list rl=ring_list(r);
1252  rl[3]=list(list("C",0),list(o,1:nvars(r)));
1253  def rr=ring(rl);
1254  return(rr);
1255}
1256example
1257{
1258  "EXAMPLE:"; echo = 2;
1259  ring r=0,(x,y),lp;
1260  def rr=changeordTo(r,"dp");
1261  rr;
1262}
1263
1264proc addvarsTo(def r,list vars,int blockorder)
1265"USAGE:  addvarsTo(ring,list_of_strings, int);
1266         int may be: 0:ordering: dp
1267                     1:ordering dp,dp
1268                     2:oring.ordering,dp
1269RETURN:  a ring with the additional variables
1270EXAMPLE: example addvarsTo(); shows an example
1271"
1272{
1273  list rl=ring_list(r);
1274  int n=nvars(r);
1275  rl[2]=rl[2]+vars;
1276  if (blockorder==0)
1277  {
1278    rl[3]=list(list("C",0),list("dp",1:(nvars(r)+size(vars))));
1279  }
1280  else
1281  {
1282    if (blockorder==2)
1283    {
1284      rl[3]=rl[3]+list(list("dp",1:size(vars)));
1285    }
1286    else
1287    {
1288      rl[3]=list(list("C",0),list("dp",1:nvars(r)),list("dp",1:size(vars)));
1289    }
1290  }
1291  def rr=ring(rl);
1292  return(rr);
1293}
1294example
1295{
1296  "EXAMPLE:"; echo = 2;
1297  ring r=0,(x,y),lp;
1298  def rr=addvarsTo(r,list("a","b"),0);
1299  rr; kill rr;
1300  def rr=addvarsTo(r,list("a","b"),1);
1301  rr; kill rr;
1302  def rr=addvarsTo(r,list("a","b"),2);
1303  rr;
1304}
1305proc addNvarsTo(def r,int N,string n,int blockorder)
1306"USAGE:  addNvarsTo(ring,int N, string name, int b);
1307         b may be: 0:ordering: dp
1308                   1:ordering dp,dp
1309                   2:oring.ordering,dp
1310RETURN:  a ring with N additional variables
1311EXAMPLE: example addNvarsTo(); shows an example
1312"
1313{
1314  list v;
1315  for(int i=N;i>0;i--) { v[i]=n+"("+string(i)+")"; }
1316  return(addvarsTo(r,v,blockorder));
1317}
1318example
1319{
1320  "EXAMPLE:"; echo = 2;
1321  ring r=0,(x,y),lp;
1322  def rr=addNvarsTo(r,2,"@",0);
1323  rr; kill rr;
1324  def rr=addNvarsTo(r,2,"@",1);
1325  rr; kill rr;
1326  def rr=addNvarsTo(r,2,"@",2);
1327  rr;
1328}
Note: See TracBrowser for help on using the repository browser.