source: git/Singular/LIB/ring.lib @ 38f64f3

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