source: git/Singular/LIB/ring.lib @ 49998f

spielwiese
Last change on this file since 49998f was 49998f, checked in by Anne Frühbis-Krüger <anne@…>, 23 years ago
*anne: added category to libraries for "General Purpose" and "Linear Algebra" git-svn-id: file:///usr/local/Singular/svn/trunk@4940 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 27.0 KB
Line 
1// $Id: ring.lib,v 1.13 2000-12-19 14:37:27 anne Exp $
2//(GMG, last modified 03.11.95)
3///////////////////////////////////////////////////////////////////////////////
4
5version="$Id: ring.lib,v 1.13 2000-12-19 14:37:27 anne Exp $";
6category="General purpose";
7info="
8LIBRARY:  ring.lib      PROCEDURES FOR MANIPULATING RINGS AND MAPS
9
10PROCEDURES:
11 changechar(\"R\",c[,r]); make a copy R of basering [ring r] with new char c
12 changeord(\"R\",o[,r]);  make a copy R of basering [ring r] with new ord o
13 changevar(\"R\",v[,r]);  make a copy R of basering [ring r] with new vars v
14 defring(\"R\",c,n,v,o);  define a ring R in specified char c, n vars v, ord o
15 defrings(n[,p]);       define ring Sn in n vars, char 32003 [p], ord ds
16 defringp(n[,p]);       define ring Pn in n vars, char 32003 [p], ord dp
17 extendring(\"R\",n,v,o); extend given ring by n vars v, ord o and name it R
18 fetchall(R[,str]);     fetch all objects of ring R to basering
19 imapall(R[,str]);      imap all objects of ring R to basering
20 mapall(R,i[,str]);     map all objects of ring R via ideal i to basering
21 ord_test(R);           test wether ordering of R is global, local or mixed
22 ringtensor(\"R\",s,t,..);create ring R, tensor product of rings s,t,...
23           (parameters in square brackets [] are optional)
24";
25
26LIB "inout.lib";
27LIB "general.lib";
28///////////////////////////////////////////////////////////////////////////////
29
30proc changechar (string newr, string c, list #)
31"USAGE:   changechar(newr,c[,r]);  newr,c=strings, r=ring
32CREATE:  create a new ring with name `newr` and make it the basering if r is
33         an existing ring [default: r=basering].
34         The new ring differs from the old ring only in the characteristic.
35         If, say, (newr,c) = (\"R\",\"0,A\") and the ring r exists, the new
36         basering will have name R characteristic 0 and one parameter A.
37RETURN:  No return value
38NOTE:    Works for qrings if map from old_char to new_char is implemented
39         This proc uses 'execute' or calls a procedure using 'execute'.
40         If you use it in your own proc, let the local names of your proc
41         start with @ (see the file HelpForProc)
42EXAMPLE: example changechar; shows an example
43"
44{
45   if( size(#)==0 ) { def @r=basering; }
46   if( size(#)==1 ) { def @r=#[1]; }
47   setring @r;
48   ideal i = ideal(@r); int @q = size(i);
49   if( @q!=0 )
50      { string @s = "@newr1"; }
51   else
52      { string @s = newr; }
53   string @newring = @s+"=("+c+"),("+varstr(@r)+"),("+ordstr(@r)+");";
54   execute("ring "+@newring);
55   if( @q!=0 )
56   {
57      map phi = @r,maxideal(1);
58      ideal i = phi(i);
59      attrib(i,"isSB",1);         //*** attrib funktioniert ?
60      execute("qring "+newr+"=i;");
61   }
62   export(`newr`);
63   keepring(`newr`);
64   if (voice==2) { "// basering is now",newr; }
65   return();
66}
67example
68{  "EXAMPLE:"; echo = 2;
69   ring r=0,(x,y,u,v),(dp(2),ds);
70   changechar("R","2,A"); R;"";
71   changechar("R1","32003",R); R1;
72   kill R,R1;
73   if(system("with","Namespaces")) {
74      if( nameof(Current) == "Ring" ) {
75        kill Top::R,Top::R1;
76      } else {
77        kill Ring::R,Ring::R1;
78      }
79   }
80}
81///////////////////////////////////////////////////////////////////////////////
82
83proc changeord (string newr, string o, list #)
84"USAGE:   changeord(newr,o[,r]);  newr,o=strings, r=ring/qring
85CREATE:  create a new ring with name `newr` and make it the basering if r is
86         an existing ring/qring [default: r=basering].
87         The new ring differs from the old ring only in the ordering. If, say,
88         (newr,o) = (\"R\",\"wp(2,3),dp\") and the ring r exists and has >=3
89         variables, the new basering will have name R and ordering wp(2,3),dp.
90RETURN:  No return value
91NOTE:    This proc uses 'execute' or calls a procedure using 'execute'.
92         If you use it in your own proc, let the local names of your proc
93         start with @ (see the file HelpForProc)
94EXAMPLE: example changeord; shows an example
95"
96{
97   if( size(#)==0 ) { def @r=basering; }
98   if( size(#)==1 ) { def @r=#[1]; }
99   setring @r;
100   ideal i = ideal(@r); int @q = size(i);
101   if( @q!=0 )
102      { string @s = "@newr1"; }
103   else
104      { string @s = newr; }
105   string @newring = @s+"=("+charstr(@r)+"),("+varstr(@r)+"),("+o+");";
106   execute("ring "+@newring);
107   if( @q!=0 )
108   {
109      map phi = @r,maxideal(1);
110      ideal i = phi(i);
111      attrib(i,"isSB",1);         //*** attrib funktioniert ?
112      execute("qring "+newr+"=i;");
113   }
114   export(`newr`);
115   keepring(`newr`);
116   if (voice==2) { "// basering is now",newr; }
117   return();
118}
119example
120{  "EXAMPLE:"; echo = 2;
121   ring r=0,(x,y,u,v),(dp(2),ds);
122   changeord("R","wp(2,3),dp"); R; "";
123   ideal i = x^2,y^2-u^3,v;
124   qring Q = std(i);
125   changeord("Q'","lp",Q); Q';
126   kill R,Q,Q';
127   if(system("with","Namespaces")) {
128      if( nameof(Current) == "Ring" ) {
129        kill Top::R,Top::Q';
130      } else {
131        kill Ring::R,Ring::Q';
132      }
133   }
134}
135///////////////////////////////////////////////////////////////////////////////
136
137proc changevar (string newr, string vars, list #)
138"USAGE:   changevar(newr,vars[,r]);  newr,vars=strings, r=ring/qring
139CREATE:  creates a new ring with name `newr` and makes it the basering if r
140         is an existing ring/qring [default: r=basering].
141         The new ring differs from the old ring only in the variables. If,
142         say, (newr,vars) = (\"R\",\"t()\") and the ring r exists and has n
143         variables, the new basering will have name R and variables
144         t(1),...,t(n).
145         If vars = \"a,b,c,d\", the new ring will have the variables a,b,c,d.
146RETURN:  No return value
147NOTE:    This procedure is useful in connection with the procedure ringtensor,
148         when a conflict between variable names must be avoided.
149         This proc uses 'execute' or calls a procedure using 'execute'.
150         If you use it in your own proc, let the local names of your proc
151         start with @ (see the file HelpForProc)
152EXAMPLE: example changevar; shows an example
153"
154{
155   if( size(#)==0 ) { def @r=basering; }
156   if( size(#)==1 ) { def @r=#[1]; }
157   setring @r;
158   ideal i = ideal(@r); int @q = size(i);
159   if( @q!=0 )
160      { string @s = "@newr1"; }
161   else
162      { string @s = newr; }
163   string @newring = @s+"=("+charstr(@r)+"),(";
164   if( vars[size(vars)-1]=="(" and vars[size(vars)]==")" )
165   {
166      @newring = @newring+vars[1,size(vars)-2]+"(1.."+string(nvars(@r))+")";
167   }
168   else { @newring = @newring+vars; }
169   @newring = @newring+"),("+ordstr(@r)+");";
170   execute("ring "+@newring);
171   if( @q!=0 )
172   {
173      map phi = @r,maxideal(1);
174      ideal i = phi(i);
175      attrib(i,"isSB",1);         //*** attrib funktioniert ?
176      execute("qring "+newr+"=i;");
177   }
178   export(`newr`);
179   keepring(`newr`);
180   if (voice==2) { "// basering is now",newr; }
181   return();
182}
183example
184{  "EXAMPLE:"; echo = 2;
185   ring r=0,(x,y,u,v),(dp(2),ds);
186   ideal i = x^2,y^2-u^3,v;
187   qring Q = std(i);
188   setring(r);
189   changevar("R","A()"); R; "";
190   changevar("Q'","a,b,c,d",Q); Q';
191   kill R,Q,Q';
192   if(system("with","Namespaces")) {
193      if( nameof(Current) == "Ring" ) {
194        kill Top::R,Top::Q';
195      } else {
196        kill Ring::R,Ring::Q';
197      }
198   }
199}
200///////////////////////////////////////////////////////////////////////////////
201
202proc defring (string s1, string s2, int n, string s3, string s4)
203"USAGE:   defring(s1,s2,n,s3,s4);  s1..s4=strings, n=integer
204CREATE:  Define a ring with name 's1', characteristic 's2', ordering 's4' and
205         n variables with names derived from s3 and make it the basering.
206         If s3 is a single letter, say s3=\"a\", and if n<=26 then a and the
207         following n-1 letters from the alphabeth (cyclic order) are taken as
208         variables. If n>26 or if s3 is a single letter followed by (, say
209         s3=\"T(\", the variables are T(1),...,T(n).
210RETURN:  No return value
211NOTE:    This proc is useful for defining a ring in a procedure.
212         This proc uses 'execute' or calls a procedure using 'execute'.
213         If you use it in your own proc, let the local names of your proc
214         start with @ (see the file HelpForProc)
215EXAMPLE: example defring; shows an example
216"
217{
218   string @newring = "ring "+s1+"=("+s2+"),(";
219   if( n>26 or s3[2]=="(" ) { string @v = s3[1]+"(1.."+string(n)+")"; }
220   else { string @v = A_Z(s3,n); }
221   @newring=@newring+@v+"),("+s4+");";
222   execute(@newring);
223   export(basering);
224   keepring(`s1`);
225   if (voice==2) { "// basering is now:",s1; }
226   return();
227}
228example
229{ "EXAMPLE:"; echo = 2;
230   defring("r","0",5,"u","ls"); r; "";
231   defring("R","2,A",10,"x(","dp(3),ws(1,2,3),ds"); R;
232   kill r,R;
233   if(system("with","Namespaces")) {
234      if( nameof(Current) == "Ring" ) {
235        kill Top::r,Top::R;
236      } else {
237        kill Ring::r,Ring::R;
238      }
239   }
240}
241///////////////////////////////////////////////////////////////////////////////
242
243proc defrings (int n, list #)
244"USAGE:   defrings(n,[p]);  n,p integers
245CREATE:  Defines a ring with name Sn, characteristic p, ordering ds and n
246         variables x,y,z,a,b,...if n<=26 (resp. x(1..n) if n>26) and makes it
247         the basering (default: p=32003)
248RETURN:  No return value
249EXAMPLE: example defrings; shows an example
250"
251{
252   int p;
253   if (size(#)==0) { p=32003; }
254   else { p=#[1]; }
255   if (n >26)
256   {
257      string s="ring S"+string(n)+"="+string(p)+",x(1.."+string(n)+"),ds;";
258   }
259   else
260   {
261      string s="ring S"+string(n)+"="+string(p)+",("+A_Z("x",n)+"),ds;";
262   }
263   execute(s);
264   export basering;
265   execute("keepring S"+string(n)+";");
266   if (voice==2) { "// basering is now:",s; }
267}
268example
269{ "EXAMPLE:"; echo = 2;
270   defrings(5,0); S5; "";
271   defrings(30); S30;
272   kill S5, S30;
273   if(system("with","Namespaces")) {
274      if( nameof(Current) == "Ring" ) {
275        kill Top::S5,Top::S30;
276      } else {
277        kill Ring::S5,Ring::S30;
278      }
279   }
280}
281///////////////////////////////////////////////////////////////////////////////
282
283proc defringp (int n,list #)
284"USAGE:   defringp(n,[p]);  n,p=integers
285CREATE:  defines a ring with name Pn, characteristic p, ordering dp and n
286         variables x,y,z,a,b,...if n<=26 (resp. x(1..n) if n>26) and makes it
287         the basering (default: p=32003)
288RETURN:  No return value
289EXAMPLE: example defringp; shows an example
290"
291{
292   int p;
293   if (size(#)==0) { p=32003; }
294   else { p=#[1]; }
295   if (n >26)
296   {
297      string s="ring P"+string(n)+"="+string(p)+",x(1.."+string(n)+"),dp;";
298   }
299   else
300   {
301     string s="ring P"+string(n)+"="+string(p)+",("+A_Z("x",n)+"),dp;";
302   }
303   execute(s);
304   export basering;
305   execute("keepring P"+string(n)+";");
306   //the next comment is only shown if defringp is not called by another proc
307   if (voice==2) { "// basering is now:",s; }
308}
309example
310{ "EXAMPLE:"; echo = 2;
311   defringp(5,0); P5; "";
312   defringp(30); P30;
313   kill P5, P30;
314   if(system("with","Namespaces")) {
315      if( nameof(Current) == "Ring" ) {
316        kill Top::P5,Top::P30;
317      } else {
318        kill Ring::P5,Ring::P30;
319      }
320   }
321}
322///////////////////////////////////////////////////////////////////////////////
323
324proc extendring (string na, int n, string va, string o, list #)
325"USAGE:   extendring(na,n,va,o[iv,i,r]);  na,va,o=strings,
326         n,i=integers, r=ring, iv=intvec of positive integers or iv=0
327CREATE:  Define a ring with name `na` which extends the ring r by adding n new
328         variables in front of [after, if i!=0] the old variables and make it
329         the basering [default: (i,r)=(0,basering)]
330         -- The characteristic is the characteristic of r
331         -- The new vars are derived from va. If va is a single letter, say
332            va=\"T\", and if n<=26 then T and the following n-1 letters from
333            T..Z..T (resp. T(1..n) if n>26) are taken as additional variables.
334            If va is a single letter followed by (, say va=\"x(\", the new
335            variables are x(1),...,x(n)
336         -- The ordering is the product ordering between the ordering of r and
337            an ordering derived from `o` [and iv]
338         -  If o contains a 'c' or a 'C' in front resp. at the end this is
339            taken for the whole ordering in front resp. at the end. If o does
340            not contain a 'c' or a 'C' the same rule applies to ordstr(r).
341         -  If no intvec iv is given, or if iv=0, o may be any allowed ordstr,
342            like \"ds\" or \"dp(2),wp(1,2,3),Ds(2)\" or \"ds(a),dp(b),ls\" if a and b
343            are globally (!) defined integers and if a+b+1<=n
344            If, however, a and b are local to a proc calling extendring, the
345            intvec iv must be used to let extendring know the values of a and b
346         -  If an intvec iv !=0 is given, iv[1],iv[2],... is taken for the 1st,
347            2nd,... block of o, if o contains no substring \"w\" or \"W\" i.e. no
348            weighted ordering (in the above case o=\"ds,dp,ls\" and iv=a,b).
349            If o contains a weighted ordering (only one (!) weighted block is
350            allowed) iv[1] is taken as size for the weight-vector, the next
351            iv[1] values of iv are taken as weights and the remaining values of
352            iv as block-size for the remaining non-weighted blocks.
353            e.g. o=\"dp,ws,Dp,ds\", iv=3,2,3,4,2,5 creates the ordering
354            dp(2),ws(2,3,4),Dp(5),ds
355RETURN:  No return value
356NOTE:    This proc is useful for adding deformation parameters.
357         This proc uses 'execute' or calls a procedure using 'execute'.
358         If you use it in your own proc, let the local names of your proc
359         start with @ (see the file HelpForProc)
360EXAMPLE: example extendring; shows an example
361"
362{
363//--------------- initialization and place c/C of ordering properly -----------
364   string @o1,@o2,@ro,@wstr,@v,@newring;
365   int @i,@w,@ii,@k;
366   intvec @iv,@iw;
367   if( find(o,"c")+find(o,"C") != 0)
368   {
369      @k=1;
370      if( o[1]=="c" or o[1]=="C" ) { @o1=o[1,2]; o=o[3..size(o)]; }
371      else                         { @o2=o[size(o)-1,2]; o=o[1..size(o)-2]; }
372   }
373   if( size(#)==0 ) { #[1]=0; }
374   if( typeof(#[1])!="intvec" )
375   {
376     if( size(#)==1 ) { @i=#[1]; def @r=basering; }
377     if( size(#)==2 ) { @i=#[1]; def @r=#[2]; }
378     if( o[size(o)]!=")" and find(o,",")==0 ) { o=o+"("+string(n)+")"; }
379   }
380   else
381   {
382     @iv=#[1];
383     if( size(#)==2 ) { @i=#[2]; def @r=basering; }
384     if( size(#)==3 ) { @i=#[2]; def @r=#[3]; }
385     if( @iv==0 && o[size(o)]!=")" && find(o,",")==0 ) {o=o+"("+string(n)+")";}
386   }
387   @ro=ordstr(@r);
388   if( @ro[1]=="c" or @ro[1]=="C" )
389      { @v=@ro[1,2]; @ro=@ro[3..size(@ro)]; }
390   else
391      { @wstr=@ro[size(@ro)-1,2]; @ro=@ro[1..size(@ro)-2]; }
392   if( @k==0) { @o1=@v; @o2=@wstr; }
393//----------------- prepare ordering if an intvec is given --------------------
394   if( typeof(#[1])=="intvec" and #[1]!=0 )
395   {
396      @k=n;                               //@k counts no of vars not yet ordered
397      @w=find(o,"w")+find(o,"W");o=o+" ";
398      if( @w!=0 )
399      {
400         @wstr=o[@w..@w+1];
401         o=o[1,@w-1]+"@"+o[@w+2,size(o)];
402         @iw=@iv[2..@iv[1]+1];
403         @wstr=@wstr+"("+string(@iw)+")";
404         @k=@k-@iv[1];
405         @iv=@iv[@iv[1]+2..size(@iv)];
406         @w=0;
407      }
408      for( @ii=1; @ii<=size(@iv); @ii=@ii+1 )
409      {
410         if( find(o,",",@w+1)!=0 )
411         {
412            @w=find(o,",",@w+1);
413            if( o[@w-1]!="@" )
414            {
415               o=o[1,@w-1]+"("+string(@iv[@ii])+")"+o[@w,size(o)];
416               @w=find(o,",",@w+1);
417               @k=@k-@iv[@ii];
418            }
419            else { @ii=@ii-1; }
420         }
421      }
422      @w=find(o,"@");
423      if( @w!=0 ) { o=o[1,@w-1] + @wstr + o[@w+1,size(o)]; }
424      if( @k>0 and o[size(o)]!=")" ) { o=o+"("+string(@k)+")"; }
425   }
426//------------------------ prepare string of new ring -------------------------
427   @newring = "ring "+na+"=("+charstr(@r)+"),(";
428   if( n>26 or va[2]=="(" ) { @v = va[1]+"(1.."+string(n)+")"; }
429   else                     { @v = A_Z(va,n); }
430   if( @i==0 )
431   {
432      @v=@v+","+varstr(@r);
433      o=@o1+o+","+@ro+@o2;
434   }
435   else
436   {
437      @v=varstr(@r)+","+@v;
438      o=@o1+@ro+","+o+@o2;
439   }
440   @newring=@newring+@v+"),("+o+");";
441//---------------------------- execute and export -----------------------------
442   execute(@newring);
443   export(basering);
444   keepring(`na`);
445   if (voice==2) { "// basering is now",na; }
446   return();
447}
448example
449{ "EXAMPLE:"; echo = 2;
450   ring r=0,(x,y,z),ds;
451   show(r);"";
452   //no intvec given, no blocksize given: blocksize is derived from no of vars
453   int t=5;
454   extendring("R1",t,"a","dp");         //t global: "dp" -> "dp(5)"
455   show(R1); "";
456   extendring("R2",4,"T(","c,dp",1,r);    //"dp" -> "c,..,dp(4)"
457   show(R2);"";
458
459   //no intvec given, blocksize given: given blocksize is used
460   extendring("R3",4,"T(","dp(2)",0,r);   // "dp(2)" -> "dp(2)"
461   show(R3);"";
462
463   //intvec given: weights and blocksize is derived from given intvec
464   //(no specification of a blocksize in the given ordstr is allowed!)
465   //if intvec does not cover all given blocks, the last block is used for
466   //the remaining variables, if intvec has too many components, the last
467   //ones are ignored
468   intvec v=3,2,3,4,1,3;
469   extendring("R4",10,"A","ds,ws,Dp,dp",v,0,r);
470         //v covers 3 blocks: v[1] (=3) : no of components of ws
471         //next v[1] values (=v[2..4]) give weights
472         //remaining components of v are used for the remaining blocks
473   show(R4);
474   kill r,R1,R2,R3,R4;
475   if(system("with","Namespaces")) {
476      if( nameof(Current) == "Ring" ) {
477        kill Top::R1,Top::R2,Top::R3,Top::R4;
478      } else {
479        kill Ring::R1,Ring::R2,Ring::R3,Ring::R4;
480      }
481   }
482}
483///////////////////////////////////////////////////////////////////////////////
484
485proc fetchall (R, list #)
486"USAGE:   fetchall(R[,s]);  R=ring/qring, s=string
487CREATE:  fetch all objects of ring R (of type poly/ideal/vector/module/number/
488         matrix) into the basering.
489         If no 3rd argument is present, the names are the same as in R. If,
490         say, f is a poly in R and the 3rd argument is the string \"R\", then f
491         is maped to f_R etc.
492RETURN:  no return value
493NOTE:    As fetch, this procedure maps the 1st, 2nd, ... variable of R to the
494         1st, 2nd, ... variable of the basering.
495         The 3rd argument is useful in order to avoid conflicts of names, the
496         empty string is allowed
497CAUTION: fetchall does not work inside a procedure
498         //***at the moment it does not work if R contains a map
499EXAMPLE: example fetchall; shows an example
500"
501{
502   list @L@=names(R);
503   int @ii@; string @s@;
504   if( size(#) > 0 ) { @s@=@s@+"_"+#[1]; }
505   for( @ii@=size(@L@); @ii@>0; @ii@=@ii@-1 )
506   {
507      execute("def "+@L@[@ii@]+@s@+"=fetch(R,`@L@[@ii@]`);");
508      execute("export "+@L@[@ii@]+@s@+";");
509   }
510   return();
511}
512example
513{  "EXAMPLE:"; echo=2;
514// This example is not executed since fetchall does not work in a procedure;
515// (and hence not in the example procedure). Just try the following commands:;
516//   ring R=0,(x,y,z),dp;
517//   ideal j=x,y2,z2;
518//   matrix M[2][3]=1,2,3,x,y,z;
519//   j; print(M);
520//   ring S=0,(a,b,c),ds;
521//   fetchall(R);           // map from R to S: x->a, y->b, z->c;
522//   names(S);
523//   j; print(M);
524//   fetchall(S,"1");       // identity map of S: copy objects, change names;
525//   names(S);
526//   kill R,S;
527}
528///////////////////////////////////////////////////////////////////////////////
529
530proc imapall (R, list #)
531"USAGE:   imapall(R[,s]);  R=ring/qring, s=string
532CREATE:  map all objects of ring R (of type poly/ideal/vector/module/number/
533         matrix) into the basering, by applying imap to all objects of R.
534         If no 3rd argument is present, the names are the same as in R. If,
535         say, f is a poly in R and the 3rd argument is the string \"R\", then f
536         is maped to f_R etc.
537RETURN:  no return value
538NOTE:    As imap, this procedure maps the variables of R to the variables with
539         the same name in the basering, the other variables are maped to 0.
540         The 3rd argument is useful in order to avoid conflicts of names, the
541         empty string is allowed
542CAUTION: imapall does not work inside a procedure
543         //***at the moment it does not work if R contains a map
544EXAMPLE: example imapall; shows an example
545"
546{
547   list @L@=names(R);
548   int @ii@; string @s@;
549   if( size(#) > 0 ) { @s@=@s@+"_"+#[1]; }
550   for( @ii@=size(@L@); @ii@>0; @ii@=@ii@-1 )
551   {
552         execute("def "+@L@[@ii@]+@s@+"=imap(R,`@L@[@ii@]`);");
553         execute("export "+@L@[@ii@]+@s@+";");
554   }
555   return();
556}
557example
558{  "EXAMPLE:"; echo = 2;
559// This example is not executed since imapall does not work in a procedure
560// (and hence not in the example procedure). Just try the following commands:
561//   ring R=0,(x,y,z,u),dp;
562//   ideal j=x,y,z,u2+ux+z;
563//   matrix M[2][3]=1,2,3,x,y,uz;
564//   j; print(M);
565//   ring S=0,(a,b,c,x,z,y),ds;
566//   imapall(R);           // map from R to S: x->x, y->y, z->z, u->0
567//   names(S);
568//   j; print(M);
569//   imapall(S,"1");       // identity map of S: copy objects, change names
570//   names(S);
571//   kill R,S;
572}
573///////////////////////////////////////////////////////////////////////////////
574
575proc mapall (R, ideal i, list #)
576"USAGE:   mapall(R,i[,s]);  R=ring/qring, i=ideal of basering, s=string
577CREATE:  map all objects of ring R (of type poly/ideal/vector/module/number/
578         matrix, map) into the basering, by mapping the jth variable of R to
579         the jth generator of the ideal i. If no 3rd argument is present, the
580         names are the same as in R. If, say, f is a poly in R and the 3rd
581         argument is the string \"R\", then f is maped to f_R etc.
582RETURN:  no return value
583NOTE:    This procedure has the same effect as defining a map, say psi, by
584         map psi=R,i; and then applying psi to all objects of R. In particular,
585         maps from R to some ring S are composed with psi, creating thus a map
586         from the basering to S.
587         mapall may be combined with copyring to change vars for all objects.
588         The 3rd argument is useful in order to avoid conflicts of names, the
589         empty string is allowed
590CAUTION: mapall does not work inside a procedure
591EXAMPLE: example mapall; shows an example
592"
593{
594   list @L@=names(R); map @psi@ = R,i;
595   int @ii@; string @s@;
596   if( size(#) > 0 ) { @s@=@s@+"_"+#[1]; }
597   for( @ii@=size(@L@); @ii@>0; @ii@=@ii@-1 )
598   {
599      execute("def "+@L@[@ii@]+@s@+"=@psi@(`@L@[@ii@]`);");
600      execute("export "+@L@[@ii@]+@s@+";");
601   }
602   return();
603}
604example
605{  "EXAMPLE:"; echo = 2;
606// This example is not executed since mapall does not work in a procedure
607// (and hence not in the example procedure). Just try the following commands:
608//   ring R=0,(x,y,z),dp;
609//   ideal j=x,y,z;
610//   matrix M[2][3]=1,2,3,x,y,z;
611//   map phi=R,x2,y2,z2;
612//   ring S=0,(a,b,c),ds;
613//   ideal i=c,a,b;
614//   mapall(R,i);             // map from R to S: x->c, y->a, z->b
615//   names(S);
616//   j; print(M); phi;        // phi is a map from R to S: x->c2, y->a2, z->b2
617//   ideal i1=a2,a+b,1;
618//   mapall(R,i1,\"\");         // map from R to S: x->a2, y->a+b, z->1
619//   names(S);
620//   j_; print(M_); phi_;
621//   changevar(\"T\",\"x()\",R);  // change vars in R and call result T
622//   mapall(R,maxideal(1));   // identity map from R to T
623//   names(T);
624//   j; print(M); phi;
625//   kill R,S,T;
626}
627///////////////////////////////////////////////////////////////////////////////
628
629proc ord_test (r)
630"USAGE:   ord_test(r);  r ring
631RETURN:  int 1 (resp. -1, resp. 0) if ordering of r is global (resp. local,
632         resp. mixed)
633EXAMPLE: example ord_test; shows an example
634"
635{
636   if (typeof(r) != "ring")
637   {
638      "// ord_test requires a ring as input";
639      return();
640   }
641   def BAS = basering;
642   setring r;
643   poly f;
644   int n,o,u = nvars(r),1,1;
645   int ii;
646   for ( ii=1; ii<=n; ii++ )
647   {
648      f = 1+var(ii);
649      o = o*(lead(f) == var(ii));
650      u = u*(lead(f) == 1);
651   }
652   setring BAS;
653   if ( o==1 ) { return(1); }
654   if ( u==1 ) { return(-1); }
655   else { return(0); }
656}
657example
658{ "EXAMPLE:"; echo = 2;
659   ring R = 0,(x,y),dp;
660   ring S = 0,(u,v),ls;
661   ord_test(R);
662   ord_test(S);
663   ord_test(R+S);   
664}
665///////////////////////////////////////////////////////////////////////////////
666
667proc ringtensor (string s, list #)
668"USAGE:   ringtensor(s,r1,r2,...); s=string, r1,r2,...=rings
669CREATE:  A new base ring with name `s` if r1,r2,... are existing rings.
670         If, say, s = \"R\" and the rings r1,r2,... exist, the new ring will
671         have name R, variables from all rings r1,r2,... and as monomial
672         ordering the block (product) ordering of r1,r2,... . Hence, R
673         is the tensor product of the rings r1,r2,... with ordering matrix
674         equal to the direct sum of the ordering matrices of r1,r2,...
675RETURN:  no return value
676NOTE:    The characteristic of the new ring will be that of r1. The names of
677         variables in the rings r1,r2,... should differ (if a name, say x,
678         occurs in r1 and r2, then, in the new ring r, x always refers to the
679         variable with name x in r1, there is no access to x in r2).
680         The procedure works also for quotient rings ri, if the characteristic
681         of ri is compatible with the characteristic of r1 (i.e. if imap from
682         ri to r1 is implemented)
683         This proc uses 'execute' or calls a procedure using 'execute'.
684         If you use it in your own proc, let the local names of your proc
685         start with @ (see the file HelpForProc)
686EXAMPLE: example ringtensor; shows an example
687"
688{
689   int @ii,@q;
690   int @n = size(#);
691   string @vars,@order,@oi,@s1;
692//---- gather variables, orderings and ideals (of qrings) from given rings ----
693   for(@ii=1; @ii<=@n; @ii=@ii+1)
694   {
695      if( ordstr(#[@ii])[1]=="C" or ordstr(#[@ii])[1]=="c" )
696           { @oi=ordstr(#[@ii])[3,size(ordstr(#[@ii]))-2]; }
697      else { @oi=ordstr(#[@ii])[1,size(ordstr(#[@ii]))-2]; }
698      @vars = @vars+varstr(#[@ii])+",";
699      @order= @order+@oi+",";
700      def @r(@ii)=#[@ii];
701      setring @r(@ii);
702      ideal i(@ii)=ideal(@r(@ii));
703      int @q(@ii)=size(i(@ii));
704      @q=@q+@q(@ii);
705   }
706   if( @q!=0 ) { @s1 = "@newr"; }   // @q=0 iff none of the rings ri is a qring
707   else {  @s1 = s; }
708//------------------------------- create new ring -----------------------------
709   string @newring ="=("+charstr(#[1])+"),("+@vars[1,size(@vars)-1]+"),("
710                  +@order[1,size(@order)-1]+");";
711   execute("ring "+@s1+@newring);
712//------ create ideal for new ring if one of the given rings is a qring -------
713   if( @q!=0 )
714   {
715      ideal i;
716      for(@ii=1; @ii<=@n; @ii=@ii+1)
717      {
718         if( @q(@ii)!=0 )
719         {
720            i=i+imap(@r(@ii),i(@ii));
721         }
722      }
723      i=std(i);
724      execute("qring "+s+"=i;");
725   }
726//----------------------- export and keep created ring ------------------------
727   export(`s`);
728   keepring(`s`);
729   if (voice==2) { "// basering is now",s; }
730   return();
731}
732example
733{ "EXAMPLE:"; echo = 2;
734   ring r=32003,(x,y,u,v),dp;
735   ring s=0,(a,b,c),wp(1,2,3);
736   ring t=0,x(1..5),(c,ls);
737   ringtensor("R",r,s,t);
738   type R;
739   setring s;
740   ideal i = a2+b3+c5;
741   changevar("S","x,y,z");       //set S (change vars of s to x,y,z) the basering
742   qring qS =std(fetch(s,i));    //create qring of S mod i (maped to S)
743   changevar("T","d,e,f,g,h",t); //set T (change vars of t to d..h) the basering
744   qring qT=std(d2+e2-f3);       //create qring of T mod d2+e2-f3
745   ringtensor("Q",s,qS,t,qT);
746   type Q;
747   kill R,Q,S,T;
748   if(system("with","Namespaces")) {
749      if( nameof(Current) == "Ring" ) {
750        kill Top::R,Top::Q,Top::S,Top::T;
751      } else {
752        kill Ring::R,Ring::Q,Ring::S,Ring::T;
753      }
754   }
755}
756///////////////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.