source: git/Singular/LIB/nctools.lib @ 797d4f

spielwiese
Last change on this file since 797d4f was 797d4f, checked in by Motsak Oleksandr <motsak@…>, 14 years ago
*motsak: backward compatibility for superCommutative git-svn-id: file:///usr/local/Singular/svn/trunk@11697 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 38.7 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2version="$Id: nctools.lib,v 1.50 2009-04-14 12:37:04 motsak Exp $";
3category="Noncommutative";
4info="
5LIBRARY: nctools.lib     General tools for noncommutative algebras
6AUTHORS:   Levandovskyy V.,     levandov@mathematik.uni-kl.de,
7@*         Lobillo, F.J.,       jlobillo@ugr.es,
8@*         Rabelo, C.,          crabelo@ugr.es,
9@*         Motsak, O.,          U@D, where U={motsak}, D={mathematik.uni-kl.de}
10
11
12
13SUPPORT: DFG (Deutsche Forschungsgesellschaft) and Metodos algebraicos y efectivos en grupos cuanticos, BFM2001-3141, MCYT, Jose Gomez-Torrecillas (Main researcher).
14
15MAIN PROCEDURES:
16Gweights(r);              compute weights for a compatible ordering in a G-algebra,
17weightedRing(r);          change the ordering of a ring to a weighted one,
18ndcond();                 the ideal of non-degeneracy conditions in G-algebra,
19Weyl([p]);                create Weyl algebra structure in a basering (two different realizations),
20makeWeyl(n, [p]);         return n-th Weyl algebra in (x(i),D(i)) presentation,
21makeHeisenberg(N, [p,d]); return n-th Heisenberg algebra in (x(i),y(i),h) realization,
22Exterior();               return qring, the exterior algebra of a basering,
23findimAlgebra(M,[r]);     create finite dimensional algebra structure from the basering and the multiplication matrix M,
24superCommutative([b,e,Q]);  return qring, the super-commutative algebra over a basering,
25rightStd(I);              compute a right Groebner basis of an ideal,
26
27AUXILIARY PROCEDURES:
28ncRelations(r);      recover the non-commutative relations of a G-algebra,
29isCentral(p);         check for the commutativity of a polynomial in the G-algebra,
30isNC();                 check whether basering is noncommutative,
31isCommutative();  check whether basering is commutative
32isWeyl();               check whether basering is a Weyl algebra
33UpOneMatrix(N);   return NxN matrix with 1's in the whole upper triagle,
34AltVarStart();        return first alternating variable of a super-commutative algebra,
35AltVarEnd();          return last alternating variable of a super-commutative algebra,
36IsSCA();                check whether current ring is a super-commutative algebra
37";
38
39
40LIB "ring.lib"; // for rootofUnity
41LIB "poly.lib"; // for newtonDiag
42// LIB "ncalg.lib";
43
44///////////////////////////////////////////////////////////////////////////////
45
46// This procedure computes a weights vector for a G-algebra r
47
48proc Gweights(def r)
49"USAGE:   Gweights(r); r a ring or a square matrix
50RETURN:   intvec
51PURPOSE: compute an appropriate weight int vector for a G-algebra, i.e., such that
52\foral\;i<j\;\;lm_w(d_{ij}) <_w x_i x_j.
53@*       the polynomials d_{ij} are taken from r itself, if it is of the type ring
54@*       or defined by the given square polynomial matrix
55THEORY:   @code{Gweights} returns an integer vector, whose weighting should be used to redefine the G-algebra in order
56to get the same non-commutative structure w.r.t. a weighted ordering. If the input is a matrix and the output is the zero
57vector then there is not a G-algebra structure associated to these relations with respect to the given variables.
58@*Another possibility is to use @code{weightedRing} to obtain directly a G-algebra with the new appropriate (weighted) ordering.
59EXAMPLE: example Gweights; shows examples
60SEE ALSO: weightedRing
61"{
62  int novalid=0;
63  if (typeof(r)=="ring") //a ring is admissible as input
64  {
65    setring r;
66    matrix tails;
67    def l = ncRelations(r);
68    tails = l[2]; // l=C,D we need D, the tails of the relations
69  }
70  else
71  {
72    matrix tails;
73    if ( (typeof(r)=="matrix") || (typeof(r)=="intmat") )
74    {
75      if ( nrows(r)==ncols(r) ) //the input is a square matrix
76      {
77        tails = matrix(r);
78      }
79      else
80      {
81        novalid = 1;
82      }
83    }
84    else
85    {
86      novalid=1;
87    }
88  }
89  if (novalid==0)
90  {
91    intmat IM = SimplMat(tails);
92    if ( size(IM)>1 )
93    {
94      int n  = ncols(tails);
95      int m  = nrows(IM)-1;
96      int m1 = 0;
97      int m2 = m;
98      int m3 = 0;
99      ring simplexring=(real,10),(x),lp;// The simplex procedure requires a basering of this type
100      matrix M = IM;
101      list sol = simplex (M,m,n,m1,m2,m3);
102      return(weightvector(sol));
103    }
104    else
105    {
106      "Invalid input"; //usually because the input is a one variable ring
107      return();
108    }
109  }
110  else
111  {
112    "The input must be a ring or a square matrix";
113    return();
114  }
115}
116example
117{
118  "EXAMPLE:";echo=2;
119  ring r = (0,q),(a,b,c,d),lp;
120  matrix C[4][4];
121  C[1,2]=q; C[1,3]=q; C[1,4]=1; C[2,3]=1; C[2,4]=q; C[3,4]=q;
122  matrix D[4][4];
123  D[1,4]=(q-1/q)*b*c;
124  def S = nc_algebra(C,D); setring S; S;
125  Gweights(S);
126  def D=fetch(r,D);
127  Gweights(D);
128}
129
130///////////////////////////////////////////////////////////////////////////////
131
132// This procedure take a ring r, call to Gweights(r) and use the output
133// of Gweights(r) to make a change of order in r
134// The output is a new ring, equal to r but the order
135// r must be a G-algebra
136
137proc weightedRing(def r)
138"USAGE:   weightedRing(r); r a ring
139RETURN:  ring
140PURPOSE:  equip the variables of the given ring with weights such that the relations of new ring (with weighted variables) satisfies the ordering condition for G-algebras:
141e.g. \forall\;i<j\;\;lm_w(d_{ij})<_w x_i x_j.
142NOTE:    activate this ring with the \"setring\" command
143EXAMPLE: example weightedRing; shows examples
144SEE ALSO: Gweights
145"{
146  def wv=Gweights(r);
147  if (typeof(wv)=="intvec")
148  {
149    setring r;
150    int n=nvars(r);
151    // Generating an nxn-intmat order
152    intmat m[n][n];
153    m[1,1]=wv[1];
154    int i;
155    for (i=2; i<=n; i++)
156    {
157      m[1,i]=wv[i];
158      m[i,n+2-i]=1;
159    }
160    // End of generation.
161    def lr=ncRelations(r);
162    string newringstring="ring newring=("+charstr(r)+"),("+varstr(r)+"),M("+string(m)+")";
163    execute (newringstring);
164    def lnewring=imap(r,lr);
165    return( nc_algebra(lnewring[1],lnewring[2]) );
166  }
167  else
168  {
169    "Invalid input.";//usually because the input is a one variable ring
170    return();
171  }
172}
173example
174{
175  "EXAMPLE:";echo=2;
176  ring r = (0,q),(a,b,c,d),lp;
177  matrix C[4][4];
178  C[1,2]=q; C[1,3]=q; C[1,4]=1; C[2,3]=1; C[2,4]=q; C[3,4]=q;
179  matrix D[4][4];
180  D[1,4]=(q-1/q)*b*c;
181  def S = nc_algebra(C,D); setring S; S;
182  def t=weightedRing(S);
183  setring t; t;
184}
185
186///////////////////////////////////////////////////////////////////////////////
187
188// This procedure computes ei+ej-f with f running in Newton(pij) and deletes the zero rows
189
190static proc Cij(intmat M, int i,j)
191{
192  M=(-1)*M;
193  int nc=ncols(M);
194  intvec N;
195  int k;
196  for (k=1; k<=nrows(M); k++)
197  {
198    M[k,i]=M[k,i]+1;
199    M[k,j]=M[k,j]+1;
200    if (intvec(M[k,1..nc])!=0)
201    {
202      N=N,intvec(M[k,1..nc]);
203    } // we only want non-zero rows
204  }
205  if (size(N)>1)
206  {
207    N=N[2..size(N)]; // Deleting the zero added in the definition of N
208    M=intmat(N,size(N)/nc,nc); // Conversion from vector to matrix
209  }
210  else
211  {
212    intmat M[1][1]=0;
213  }
214  return (M);
215}
216
217///////////////////////////////////////////////////////////////////////////////
218
219// This procedure run over the matrix of pij calculating Cij
220
221static proc Ct(matrix P)
222{
223  int    k = ncols(P);
224  intvec T = 0;
225  int    i,j;
226//  int notails=1;
227  def S;
228  for (j=2; j<=k; j++)
229  {
230    for (i=1; i<j; i++)
231    {
232      if ( P[i,j] != 0 )
233      {
234//        notails=0;
235        S = newtonDiag(P[i,j]);
236        S = Cij(S,i,j);
237        if ( size(S)>1 )
238        {
239          T = T,S;
240        }
241      }
242    }
243  }
244  if ( size(T)==1 )
245  {
246    intmat C[1][1] = 0;
247  }
248  else
249  {
250    T=T[2..size(T)]; // Deleting the zero added in the definition of T
251    intmat C = intmat(T,size(T)/k,k); // Conversion from vector to matrix
252  }
253  return (C);
254}
255
256///////////////////////////////////////////////////////////////////////////////
257
258// The purpose of this procedure is to produce the input matrix required by simplex procedure
259
260static proc SimplMat(matrix P)
261{
262  intmat C=Ct(P);
263  if (size(C)>1)
264  {
265    int r = nrows(C);
266    int n = ncols(C);
267    int f = 1+n+r;
268    intmat M[f][n+1]=0;
269    int i;
270    for (i=2; i<=(n+1); i++)
271    {
272      M[1,i]=-1; // (0,-1,-1,-1,...) objective function in the first row
273    }
274    for (i=2; i<=f; i++) {M[i,1]=1;} // All the independent terms are 1
275    for (i=2; i<=(n+1); i++) {M[i,i]=-1;} // wi>=1 is an identity matrix
276    M[(n+2)..f,2..(n+1)]=(-1)*intvec(C); // <wi,a> >= 1, a in C ...
277  }
278  else
279  {
280    int n = ncols(P);
281    int f = 1+n;
282    intmat M[f][n+1]=0;
283    int i;
284    for (i=2; i<=(n+1); i++) {M[1,i]=-1;} // (0,-1,-1,-1,...) objective function in the first row
285    for (i=2; i<=f; i++) {M[i,1]=1;} // All the independent terms are 1
286    for (i=2; i<=(n+1); i++) {M[i,i]=-1;} // wi>=1 is an identity matrix
287  }
288  return (M);
289}
290
291///////////////////////////////////////////////////////////////////////////////
292
293// This procedure generates a nice output of the simplex method consisting of a vector
294// with the solutions. The vector is ordered.
295
296static proc weightvector(list l)
297"ASSUME:  l is the output of simplex.
298RETURN: if there is a solution, an intvec with it will be returned"
299{
300  matrix m=l[1];
301  intvec nv=l[3];
302  int sol=l[2];
303  int rows=nrows(m);
304  int N=l[6];
305  intmat wv[1][N]=0;
306  int i;
307  if (sol)
308  {
309    "no solution satisfies the given constraints";
310  }
311  else
312  {
313    for ( i = 2; i <= rows; i++ )
314    {
315      if ( nv[i-1] <= N )
316      {
317        wv[1,nv[i-1]]=int(m[i,1]);
318      }
319    }
320  }
321  return (intvec(wv));
322}
323
324
325
326///////////////////////////////////////////////////////////////////////////////
327
328// This procedure recover the non-conmutative relations (matrices C and D)
329
330proc ncRelations(def r)
331"USAGE:   ncRelations(r); r a ring
332RETURN:  list L with two elements, both elements are of type matrix:
333@*         L[1] = matrix of coefficients C,
334@*         L[2] = matrix of polynomials D
335PURPOSE: recover the noncommutative relations via matrices C and D from
336a noncommutative ring
337SEE ALSO: ringlist, G-algebras
338EXAMPLE: example ncRelations; shows examples
339"{
340  list l;
341  if (typeof(r)=="ring")
342  {
343    int n=nvars(r);
344    matrix C[n][n]=0;
345    matrix D[n][n]=0;
346    poly f; poly g;
347    if (n>1)
348    {
349      int i,j;
350      for (i=2; i<=n; i++)
351      {
352        for (j=1; j<i; j++)
353        {
354          f=var(i)*var(j); // yx=c*xy+...
355          g=var(j)*var(i); // xy
356          while (C[j,i]==0)
357          {
358            if (leadmonom(f)==leadmonom(g))
359            {
360              C[j,i]=leadcoef(f);
361              D[j,i]=D[j,i]+f-lead(f);
362            }
363            else
364            {
365              D[j,i]=D[j,i]+lead(f);
366              f=f-lead(f);
367            }
368          }
369        }
370      }
371      l=C,D;
372    }
373    else { "The ring must have two or more variables"; }
374  }
375  else { "The input must be of a type ring";}
376  return (l);
377}
378example
379{
380  "EXAMPLE:";echo=2;
381  ring r = 0,(x,y,z),dp;
382  matrix C[3][3]=0,1,2,0,0,-1,0,0,0;
383  print(C);
384  matrix D[3][3]=0,1,2y,0,0,-2x+y+1;
385  print(D);
386  def S=nc_algebra(C,D);setring S; S;
387  def l=ncRelations(S);
388  print (l[1]);
389  print (l[2]);
390}
391
392///////////////////////////////////////////////////////////////////////////////
393
394proc findimAlgebra(matrix M, list #)
395"USAGE:   findimAlgebra(M,[r]); M a matrix, r an optional ring
396RETURN:  ring
397PURPOSE: define a finite dimensional algebra structure on a ring
398NOTE:  the matrix M is used to define the relations x(j)*x(i) = M[i,j] in the
399basering (by default) or in the optional ring r.
400@* The procedure equips the ring with the noncommutative structure.
401@* The procedure exports the ideal (not a two-sided Groebner basis!), called @code{fdQuot}, for further qring definition.
402THEORY: finite dimensional algebra can be represented as a factor algebra
403of a G-algebra modulo certain two-sided ideal. The relations of a f.d. algebra are thus naturally divided into two groups: firstly, the relations
404on the variables of the ring, making it into G-algebra and the rest of them, which constitute the ideal which will be factored out.
405EXAMPLE: example findimAlgebra; shows examples
406"
407{
408  if (size(#) >0)
409  {
410    if ( typeof(#[1])!="ring" ) { return();}
411    else
412    {
413      def @R1 = #[1];
414      setring @R1;
415    }
416  }
417  int i,j;
418  int n=nvars(basering);
419  poly p;
420  ideal I;
421  number c;
422  matrix C[n][n];
423  matrix D[n][n];
424  for (i=1; i<=n; i++)
425  {
426    for (j=i; j<=n; j++)
427    {
428      p=var(i)*var(j)-M[i,j];
429      if ( (size(I)==1) && (I[1]==0) )   { I=p; }
430      else { I=I,p; }
431      if (j>i)
432      {
433        if ((M[i,j]!=0) && (M[j,i]!=0))
434        {
435          c = leadcoef(M[j,i])/leadcoef(M[i,j]);
436        }
437        else
438        {
439          c = 1;
440        }
441        C[i,j]=c;
442        D[i,j]= - M[j,i] +c*M[i,j];
443      }
444    }
445  }
446  def save = basering;
447  def S = nc_algebra(C,D); setring S;
448  ideal fdQuot = fetch(save,D);
449  export fdQuot;
450  return(S);
451}
452example
453{
454  "EXAMPLE:";echo=2;
455  ring r=(0,a,b),(x(1..3)),dp;
456  matrix S[3][3];
457  S[2,3]=a*x(1); S[3,2]=-b*x(1);
458  def A=findimAlgebra(S); setring A;
459  fdQuot = twostd(fdQuot);
460  qring Qr = fdQuot;
461  Qr;
462}
463
464///////////////////////////////////////////////////////////////////////////////
465
466proc isCentral(poly p, list #)
467"USAGE:   isCentral(p); p poly
468RETURN:  int, 1 if p commutes with all variables and 0 otherwise
469PURPOSE: check whether p is central in a basering (that is, commutes with every generator of the ring)
470NOTE: if @code{printlevel} > 0, the procedure displays intermediate information (by default, @code{printlevel}=0 )
471EXAMPLE: example isCentral; shows examples
472"{
473  //v an integer (with v!=0, procedure will be verbose)
474  int N = nvars(basering);
475  int in;
476  int flag = 1;
477  poly   q = 0;
478  for (in=1; in<=N; in++)
479  {
480    q = p*var(in)-var(in)*p;
481    if (q!=0)
482    {
483      if ( (size(#) >0 ) || (printlevel>0) )
484      {
485        "Non-central at:", var(in);
486      }
487      flag = 0;
488    }
489  }
490  return(flag);
491}
492example
493{
494  "EXAMPLE:";echo=2;
495  ring r=0,(x,y,z),dp;
496  matrix D[3][3]=0;
497  D[1,2]=-z;
498  D[1,3]=2*x;
499  D[2,3]=-2*y;
500  def S = nc_algebra(1,D); setring S;
501  S; // this is U(sl_2)
502  poly c = 4*x*y+z^2-2*z;
503  printlevel = 0;
504  isCentral(c);
505  poly h = x*c;
506  printlevel = 1;
507  isCentral(h);
508}
509
510///////////////////////////////////////////////////////////////////////////////
511
512proc UpOneMatrix(int N)
513"USAGE:   UpOneMatrix(n); n an integer
514RETURN:  intmat
515PURPOSE: compute an  n x n matrix with 1's in the whole upper triangle
516NOTE: helpful for setting noncommutative algebras with complicated
517coefficient matrices
518EXAMPLE: example UpOneMatrix; shows examples
519"{
520  int ii,jj;
521  intmat U[N][N]=0;
522  for (ii=1;ii<N;ii++)
523  {
524    for (jj=ii+1;jj<=N;jj++)
525    {
526      U[ii,jj]=1;
527    }
528  }
529  return(U);
530}
531example
532{
533  "EXAMPLE:";echo=2;
534  ring   r = (0,q),(x,y,z),dp;
535  matrix C = UpOneMatrix(3);
536  C[1,3]   = q;
537  print(C);
538  def S = nc_algebra(C,0); setring S;
539  S;
540}
541
542///////////////////////////////////////////////////////////////////////////////
543proc ndcond(list #)
544"USAGE:   ndcond();
545RETURN:  ideal
546PURPOSE: compute the non-degeneracy conditions of the basering
547NOTE: if @code{printlevel} > 0, the procedure displays intermediate information (by default, @code{printlevel}=0 )
548EXAMPLE: example ndcond; shows examples
549"
550{
551  // internal documentation, for tests etc
552  // 1st arg: v an optional integer (if v!=0, will be verbose)
553  // if the second argument is given, produces ndc wrt powers x^N
554  int N = 1;
555  int Verbose = 0;
556  if ( size(#)>=1 ) { Verbose = int(#[1]); }
557  if ( size(#)>=2 ) { N = int(#[2]); }
558  Verbose = ((Verbose) || (printlevel>0));
559  int cnt = 1;
560  int numvars = nvars(basering);
561  int a,b,c;
562  poly p = 1;
563  ideal res = 0;
564  for (cnt=1; cnt<=N; cnt++)
565  {
566    if (Verbose) { "Processing degree :",cnt;}
567    for (a=1; a<=numvars-2; a++)
568    {
569      for (b=a+1; b<=numvars-1; b++)
570      {
571        for(c=b+1; c<=numvars; c++)
572        {
573          p = (var(c)^cnt)*(var(b)^cnt);
574          p = p*(var(a)^cnt);
575          p = p-(var(c)^cnt)*((var(b)^cnt)*(var(a)^cnt));
576          if (Verbose) {a,".",b,".",c,".";}
577          if (p!=0)
578          {
579            if ( res==0 )
580            {
581              res[1] = p;
582            }
583            else
584            {
585              res = res,p;
586            }
587            if (Verbose) { "failed:",p; }
588          }
589        }
590      }
591    }
592    if (Verbose) { "done"; }
593  }
594  return(res);
595}
596example
597{
598  "EXAMPLE:";echo=2;
599  ring r = (0,q1,q2),(x,y,z),dp;
600  matrix C[3][3];
601  C[1,2]=q2; C[1,3]=q1; C[2,3]=1;
602  matrix D[3][3];
603  D[1,2]=x; D[1,3]=z;
604  def S = nc_algebra(C,D); setring S;
605  S;
606  ideal j=ndcond(); // the silent version
607  j;
608  printlevel=1;
609  ideal i=ndcond(); // the verbose version
610  i;
611}
612
613
614///////////////////////////////////////////////////////////////////////////////
615proc Weyl(list #)
616"USAGE:   Weyl()
617RETURN:  ring
618PURPOSE: create a Weyl algebra structure on the basering
619NOTE: Activate this ring using the command @code{setring}.
620@*Assume the number of variables of a basering is 2k.
621(if the number of variables is odd, an error message will be returned)
622@*    by default, the procedure treats first k variables as coordinates x_i and the last k as differentials d_i
623@*    if a non-zero optional argument is given, the procedure treats 2k variables of a basering as k pairs (x_i,d_i), i.e. variables with odd numbers are treated as coordinates and with even numbers as differentials
624SEE ALSO: makeWeyl
625EXAMPLE: example Weyl; shows examples
626"
627{
628  //there are two possibilities for choosing the PBW basis.
629  //The variables have names x(i) for coordinates and d(i) for partial
630  // differentiations. By default, the procedure
631  //creates a ring, where the variables are ordered as x(1..n),d(1..n).  the
632  // tensor product-like realization x(1),d(1),x(2),d(2),... is used.
633  string rname=nameof(basering);
634  if ( rname == "basering") // i.e. no ring has been set yet
635  {
636    "You have to call the procedure from the ring";
637    return();
638  }
639  int @chr = 0;
640  if ( size(#) > 0 )
641  {
642    if ( typeof( #[1] ) == "int" )
643    {
644      @chr = #[1];
645    }
646  }
647  int nv = nvars(basering);
648  int N = nv div 2;
649  if ((nv % 2) != 0)
650  {
651    "Cannot create Weyl structure for an odd number of generators";
652    return();
653  }
654  matrix @D[nv][nv];
655  int i;
656  for ( i=1; i<=N; i++ )
657  {
658    if ( @chr==0 ) // default
659    {
660      @D[i,N+i]=1;
661    }
662    else
663    {
664      @D[2*i-1,2*i]=1;
665    }
666  }
667  def @R = nc_algebra(1,@D);
668  return(@R);
669}
670example
671{
672  "EXAMPLE:";echo=2;
673  ring A1=0,(x(1..2),d(1..2)),dp;
674  def S=Weyl();
675  setring S;  S;
676  kill A1,S;
677  ring B1=0,(x1,d1,x2,d2),dp;
678  def S=Weyl(1);
679  setring S;  S;
680}
681
682///////////////////////////////////////////////////////////////////////////////
683proc makeHeisenberg(int N, list #)
684"USAGE:  makeHeisenberg(n, [p,d]); int n (setting 2n+1 variables), optional int p (field characteristic), optional int d (power of h in the commutator)
685RETURN: ring
686PURPOSE: create the n-th Heisenberg algebra in the variables x(1),y(1),...,x(n),y(n),h over the rationals Q or F_p with the relations
687\forall\;i\in\{1,2,\ldots,n\}\;\;y(j)x(i) = x(i)y(j)+h^d.
688SEE ALSO: makeWeyl
689NOTE: activate this ring with the @code{setring} command
690@*       If p is not prime, the next larger prime number will be used.
691EXAMPLE: example makeHeisenberg; shows examples
692"
693{
694  int @chr = 0;
695  int @deg = 1;
696  if ( size(#) > 0 )
697  {
698    if ( typeof( #[1] ) == "int" )
699    {
700      @chr = #[1];
701    }
702  }
703  if ( size(#) > 1 )
704  {
705    if ( typeof( #[2] ) == "int" )
706    {
707      @deg = #[2];
708      if (@deg <1) { @deg = 1; }
709    }
710  }
711  ring @@r=@chr,(x(1..N),y(1..N),h),lp;
712  matrix D[2*N+1][2*N+1];
713  int i;
714  for (i=1;i<=N;i++)
715  {
716    D[i,N+i]=h^@deg;
717  }
718  return(nc_algebra(1,D));
719}
720example
721{
722  "EXAMPLE:";echo=2;
723  def a = makeHeisenberg(2);
724  setring a;   a;
725  def H3 = makeHeisenberg(3, 7, 2);
726  setring H3;  H3;
727}
728
729 
730
731///////////////////////////////////////////////////////////////////////////////
732proc superCommutative(list #)
733"USAGE:   superCommutative([b,[e, [Q, [flag]]]]);
734RETURN:  qring
735PURPOSE:  create a super-commutative algebra (as a GR-algebra) over a basering,
736NOTE: activate this qring with the \"setring\" command.
737NOTE: if b==e then the resulting ring is commutative unless 'flag' is given and non-zero.
738@* By default, @code{b=1, e=nvars(basering), Q=0}, and @code{flag=0}.
739THEORY: given a basering, this procedure introduces the anticommutative relations x(j)x(i)=-x(i)x(j) for all e>=j>i>=b,
740@* moreover, creates a factor algebra modulo the two-sided ideal, generated by x(b)^2, ..., x(e)^2[ + Q]
741DISPLAY: If @code{printlevel} > 1, warning debug messages will be printed
742EXAMPLE: example superCommutative; shows examples
743"
744{
745  int fprot = (printlevel > 1); // (find(option(),"prot") != 0);
746
747  string rname=nameof(basering);
748
749  if ( rname == "basering") // i.e. no ring has been set yet
750  {
751    ERROR("You have to call the procedure from the ring");
752    return();
753  }
754
755  def saveRing = basering;
756
757  int N = nvars(saveRing);
758  int b = 1;
759  int e = N;
760  int flag = 0;
761
762  ideal Q = 0;
763
764  if(size(#)>0)
765  {
766    if(typeof(#[1]) != "int")
767    {
768      ERROR("The argument 'b' must be an integer!");
769      return();
770    }
771    b = #[1];
772
773    if((b < 1)||(b > N))
774    {
775      ERROR("The argument 'b' must within [1..nvars(basering)]!");
776      return();
777    }
778
779  }
780
781  if(size(#)>1)
782  {
783    if(typeof(#[2]) != "int")
784    {
785      ERROR("The argument 'e' must be an integer!");
786      return();
787    }
788    e = #[2];
789
790    if((e < 1)||(e > N))
791    {
792      ERROR("The argument 'e' must within [1..nvars(basering)]!");
793      return();
794    }
795
796    if(e < b)
797    {
798      ERROR("The argument 'e' must be bigger or equal to 'b'!");
799      return();
800    }
801  }
802
803  if(size(#)>2)
804  {
805    if(typeof(#[3]) != "ideal")
806    {
807      ERROR("The argument 'Q' must be an ideal!");
808      return();
809    }
810    Q = #[3];
811  }
812
813  if(size(#)>3)
814  {
815    if(typeof(#[4]) != "int")
816    {
817      ERROR("The argument 'flag' must be an integer!");
818      return();
819    }
820    flag = #[4];
821  }
822
823  int iSavedDegBoung = degBound;
824
825  if( (b == e) && (flag == 0) ) // commutative ring!!!
826  {
827    if( fprot == 1)
828    {
829      print("Warning: (b==e) means that the resulting ring will be commutative!");
830    }
831
832    degBound=0;
833    Q = std(Q + (var(b)^2));
834    degBound = iSavedDegBoung;
835
836    qring @EA = Q; // and it will be internally commutative as well!!!
837
838    return(@EA);
839  }
840
841/*
842  // Singular'(H.S.) politics: no ring copies!
843  // in future nc_algebra() should return a new ring!!!
844  list CurrRing = ringlist(basering);
845  def @R = ring(CurrRing);
846  setring @R; // @R;
847*/
848
849  if( (char(basering)==2) && (flag == 0) )// commutative ring!!!
850  {
851    if( fprot == 1)
852    {
853      print("Warning: (char == 2) means that the resulting ring will be commutative!");
854    }
855
856    int j = ncols(Q) + 1;
857
858    for ( int i=e; i>=b; i--, j++ )
859    {
860      Q[j] = var(i)^2;
861    }
862
863    degBound=0;
864    Q = std(Q);
865    degBound = iSavedDegBoung;
866
867    qring @EA = Q; // and it will be internally commutative as well!!!
868    return(@EA);
869  }
870
871
872  int i, j;
873
874  if( (b == 1) && (e == N) ) // just an exterior algebra?
875  {
876    def S = nc_algebra(-1, 0); // define ground G-algebra!
877    setring S;
878  } else
879  {
880    matrix @E = UpOneMatrix(N);
881
882    for ( i = b; i < e; i++ )
883    {
884      for ( j = i+1; j <= e; j++ )
885      {
886        @E[i, j] = -1;
887      }
888    }
889    def S = nc_algebra(@E, 0); // define ground G-algebra!
890    setring S;
891  }
892
893  ideal @Q = fetch(saveRing, Q);
894
895  j = ncols(@Q) + 1;
896
897  for ( i=e; i>=b; i--, j++ )
898  {
899    @Q[j] = var(i)^2;
900  }
901
902  if( (fprot == 1) and (attrib(basering, "global") != 1) )
903  {
904    print("Warning: Since the current ordering is not global there might be problems computing twostd(Q)!");
905    "Q:";
906    @Q;
907  }
908
909  degBound=0;
910  @Q = twostd(@Q); // must be computed within the ground G-algebra => problems with local orderings!
911  degBound = iSavedDegBoung;
912
913  qring @EA = @Q;
914
915//   "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
916  return(@EA);
917}
918example
919{
920  "EXAMPLE:";echo=2;
921  ring R = 0,(x(1..4)),dp; // global!
922  def ER = superCommutative(); // the same as Exterior (b = 1, e = N)
923  setring ER; ER;
924  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
925  kill R; kill ER;
926  ring R = 0,(x(1..4)),(lp(1), dp(3)); // global!
927  def ER = superCommutative(2); // b = 2, e = N
928  setring ER; ER;
929  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
930  kill R; kill ER;
931  ring R = 0,(x(1..6)),(ls(2), dp(2), lp(2)); // local!
932  def ER = superCommutative(3,4); // b = 3, e = 4
933  setring ER; ER;
934  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
935  kill R; kill ER;
936}
937
938
939proc SuperCommutative(list #)
940{
941  return( superCommutative(#) );
942}
943
944
945static proc ParseSCA()
946"
947RETURN: list {AltVarStart, AltVarEnd} is currRing is SCA, returns undef otherwise.
948NOTE: rings with only one non-commutative variable are commutative rings which are super-sommutative itself!
949"
950{
951  def saveRing = basering;
952
953  int i, j;
954  int N = nvars(saveRing);
955
956  int b = N+1;
957  int e =  -1;
958
959  int fprot = (find(option(),"prot") != 0);
960
961
962  if( size(ideal(saveRing)) == 0 )
963  {
964    return("SCA rings are factors by (at least) squares!"); // no squares in the factor ideal!
965  }
966
967  list L = ringlist(saveRing);
968
969  if( size(L)!=6 )
970  {
971    if(fprot)
972    {
973      print("Warning: The current ring is internally commutative!");
974    }
975
976    for( i = N; i > 0; i-- )
977    {
978      if( NF(var(i)^2, std(0)) == 0 )
979      {
980        if( (fprot == 1) and (i > 1) )
981        {
982          print("Warning: the SCA representation of the current commutative factor ring may be ambiguous!");
983        }
984
985        return( list(i, i) ); // this is not unique in this case! there may be other squares in the factor ideal!
986      }
987    }
988
989    return("The current commutative ring is not SCA! (Wrong quotient ideal)"); // no squares in the factor ideal!
990  }
991
992  module D = simplify(L[6], 2 + 4);
993
994  if( size(D)>0 )
995  {
996    return("The current ring is not SCA! (D!=0)");
997  }
998
999  matrix C = L[5];
1000  poly c;
1001
1002  for( i = 1; i < N; i++ )
1003  {
1004    for( j = i+1; j <= N; j++ )
1005    {
1006      c = C[i, j];
1007
1008      if( c == -1 )
1009      {
1010        if(i < b)
1011        {
1012          b = i;
1013        }
1014
1015        if(j > e)
1016        {
1017          e = j;
1018        }
1019      } else
1020      { // should commute
1021        if( c!=1 )
1022        {
1023          return("The current ring is not SCA! (C["+ string(i)+"," + string(j)+"]!=1)");
1024        }
1025      }
1026    }
1027  }
1028
1029  if( (b > N) || (e < 1))
1030  {
1031    if(fprot)
1032    {
1033      print("Warning: The current ring is a commutative GR-algebra!");
1034    }
1035
1036    for( i = N; i > 0; i-- )
1037    {
1038      if( NF(var(i)^2, std(0)) == 0 )
1039      {
1040        if( (fprot == 1) and (i > 1) )
1041        {
1042          print("Warning: the SCA representation of the current factor ring may be ambiguous!");
1043        }
1044
1045        return( list(i, i) ); // this is not unique in this case! there may be other squares in the factor ideal!
1046      }
1047    }
1048
1049    return("The current commutative GR-algebra is not SCA! (Wrong quotient ideal)"); // no squares in the factor ideal!
1050  }
1051
1052  for( i = 1; i < N; i++ )
1053  {
1054    for( j = i+1; j <= N; j++ )
1055    {
1056      c = C[i, j];
1057
1058      if( (b <= i) && (j <= e) ) // S <= i < j <= E
1059      { // anticommutative part
1060        if( c!= -1 )
1061        {
1062          return("The current ring is not SCA! (C["+ string(i)+"," + string(j)+"]!=-1)");
1063        }
1064      } else
1065      { // should commute
1066        if( c!=1 )
1067        {
1068          return("The current ring is not SCA! (C["+ string(i)+"," + string(j)+"]!=1)");
1069        }
1070      }
1071    }
1072  }
1073
1074  for( i = b; i <= e; i++ )
1075  {
1076    if( NF(var(i)^2, std(0)) != 0 )
1077    {
1078      return("The current ring is not SCA! (Wrong quotient ideal)");
1079    }
1080  }
1081
1082  ////////////////////////////////////////////////////////////////////////
1083  // ok. it is a SCA!!!
1084
1085  return(list(b, e));
1086}
1087
1088///////////////////////////////////////////////////////////////////////////////
1089proc AltVarStart()
1090"USAGE:   AltVarStart();
1091RETURN:  int
1092PURPOSE:  returns the number of the first alternating variable of basering
1093NOTE:  basering should be a super-commutative algebra with at most one block of anti-commutative variables
1094@* For commutative rings, @code{nvars(basering)+1} will be returned.
1095EXAMPLE: example AltVarStart; shows examples
1096"
1097{
1098  def l = ParseSCA();
1099
1100  if( typeof(l) != "string" )
1101  {
1102    return(l[1]);
1103  }
1104
1105  ERROR(l);
1106  return();
1107}
1108example
1109{
1110  "EXAMPLE:";echo=2;
1111  ring R = 0,(x(1..4)),dp; // global!
1112  def ER = superCommutative(2); // (b = 2, e = N)
1113  setring ER; ER;
1114  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
1115}
1116
1117///////////////////////////////////////////////////////////////////////////////
1118proc AltVarEnd()
1119"USAGE:   AltVarStart();
1120RETURN:  int
1121PURPOSE:  returns the number of the last alternating variable of basering
1122NOTE:  basering should be a super-commutative algebra with at most one block of anti-commutative variables
1123@* returns -1 for commutative rings
1124EXAMPLE: example AltVarEnd; shows examples
1125"
1126{
1127  def l = ParseSCA();
1128
1129  if( typeof(l) != "string" )
1130  {
1131    return(l[2]);
1132  }
1133
1134  ERROR(l);
1135  return();
1136}
1137example
1138{
1139  "EXAMPLE:";echo=2;
1140  ring R = 0,(x(1..4)),dp; // global!
1141  def ER = superCommutative(2); // (b = 2, e = N)
1142  setring ER; ER;
1143  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
1144}
1145
1146///////////////////////////////////////////////////////////////////////////////
1147proc IsSCA()
1148"USAGE:   IsSCA();
1149RETURN:  int
1150PURPOSE:  returns 1 if basering is a super-commutative algebra and 0 otherwise.
1151NOTE:     shows hint message for non-SCA algebras if the 'prot' option is on.
1152EXAMPLE: example IsSCA; shows examples
1153"
1154{
1155  def l = ParseSCA();
1156
1157  if( typeof(l) != "string" )
1158  {
1159    return(1);
1160  }
1161
1162  if( find(option(),"prot") != 0 )
1163  {
1164    print(l);
1165  }
1166
1167  return(0);
1168}
1169example
1170{
1171  "EXAMPLE:";echo=2;
1172/////////////////////////////////////////////////////////////////////
1173  ring R = 0,(x(1..4)),dp; // commutative
1174  if(IsSCA())
1175    { "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "]."; }
1176  else
1177    { "Not a super-commutative algebra!!!"; }
1178  kill R;
1179/////////////////////////////////////////////////////////////////////
1180  ring R = 0,(x(1..4)),dp;
1181  def S = nc_algebra(1, 0); setring S; S; // still commutative!
1182  if(IsSCA())
1183    { "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "]."; }
1184  else
1185    { "Not a super-commutative algebra!!!"; }
1186  kill R, S;
1187/////////////////////////////////////////////////////////////////////
1188  ring R = 0,(x(1..4)),dp;
1189  list CurrRing = ringlist(R);
1190  def ER = ring(CurrRing);
1191  setring ER; // R;
1192
1193  matrix E = UpOneMatrix(nvars(R));
1194
1195  int i, j; int b = 2; int e = 3;
1196
1197  for ( i = b; i < e; i++ )
1198  {
1199    for ( j = i+1; j <= e; j++ )
1200    {
1201      E[i, j] = -1;
1202    }
1203  }
1204
1205  def S = nc_algebra(E,0); setring S; S;
1206
1207  if(IsSCA())
1208    { "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "]."; }
1209  else
1210    { "Not a super-commutative algebra!!!"; }
1211  kill R, ER, S;
1212/////////////////////////////////////////////////////////////////////
1213  ring R = 0,(x(1..4)),dp;
1214  def ER = superCommutative(2); // (b = 2, e = N)
1215  setring ER; ER;
1216  if(IsSCA())
1217    { "This is a SCA! Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "]."; }
1218  else
1219    { "Not a super-commutative algebra!!!"; }
1220  kill R, ER;
1221}
1222
1223
1224
1225///////////////////////////////////////////////////////////////////////////////
1226proc Exterior(list #)
1227"USAGE:   Exterior();
1228RETURN:  qring
1229PURPOSE:  create the exterior algebra of a basering
1230NOTE:  activate this qring with the \"setring\" command
1231THEORY: given a basering, this procedure introduces the anticommutative relations x(j)x(i)=-x(i)x(j) for all j>i,
1232@* moreover, creates a factor algebra modulo the two-sided ideal, generated by x(i)^2 for all i
1233EXAMPLE: example Exterior; shows examples
1234"
1235{
1236  string rname=nameof(basering);
1237  if ( rname == "basering") // i.e. no ring has been set yet
1238  {
1239    "You have to call the procedure from the ring";
1240    return();
1241  }
1242  int N = nvars(basering);
1243  string NewRing = "ring @R=("+charstr(basering)+"),("+varstr(basering)+"),("+ordstr(basering)+");";
1244  execute(NewRing);
1245  matrix @E = UpOneMatrix(N);
1246  @E = -1*(@E);
1247  def @@RR = nc_algebra(@E,0); setring @@RR;
1248  int i;
1249  ideal Q;
1250  for ( i=1; i<=N; i++ )
1251  {
1252    Q[i] = var(i)^2;
1253  }
1254  Q = twostd(Q);
1255  qring @EA = Q;
1256  return(@EA);
1257}
1258example
1259{
1260  "EXAMPLE:";echo=2;
1261  ring R = 0,(x(1..3)),dp;
1262  def ER = Exterior();
1263  setring ER;
1264  ER;
1265}
1266
1267///////////////////////////////////////////////////////////////////////////////
1268proc makeWeyl(int n, list #)
1269"USAGE:  makeWeyl(n,[p]); n an integer, n>0; p an optional integer (field characteristic)
1270RETURN:  ring
1271PURPOSE: create the n-th Weyl algebra over the rationals Q or F_p
1272NOTE:    activate this ring with the \"setring\" command.
1273@*       The presentation of an n-th Weyl algebra is classical: D(i)x(i)=x(i)D(i)+1,
1274@*       where x(i) correspond to coordinates and D(i) to partial differentiations, i=1,...,n.
1275@*       If p is not prime, the next larger prime number will be used.
1276SEE ALSO: Weyl
1277EXAMPLE: example makeWeyl; shows examples
1278"{
1279  if (n<1)
1280  {
1281    print("Incorrect input");
1282    return();
1283  }
1284  int @p = 0;
1285  if ( size(#) > 0 )
1286  {
1287    if ( typeof( #[1] ) == "int" )
1288    {
1289      @p = #[1];
1290    }
1291  }
1292  if (n ==1)
1293  {
1294    ring @rr = @p,(x,D),dp;
1295  }
1296  else
1297  {
1298    ring @rr = @p,(x(1..n),D(1..n)),dp;
1299  }
1300  setring @rr;
1301  def @rrr = Weyl();
1302  return(@rrr);
1303}
1304example
1305{ "EXAMPLE:"; echo = 2;
1306   def a = makeWeyl(3);
1307   setring a;
1308   a;
1309}
1310
1311//////////////////////////////////////////////////////////////////////
1312proc isNC()
1313"USAGE:   isNC();
1314PURPOSE: check whether a basering is commutative or not
1315RETURN:   int, 1 if basering is noncommutative and 0 otherwise
1316EXAMPLE: example isNC; shows examples
1317"{
1318  string rname=nameof(basering);
1319  if ( rname == "basering") // i.e. no ring has been set yet
1320  {
1321    "You have to call the procedure from the ring";
1322    return();
1323  }
1324  int n = nvars(basering);
1325  int i,j;
1326  poly p;
1327  for (i=1; i<n; i++)
1328  {
1329    for (j=i+1; j<=n; j++)
1330    {
1331      p = var(j)*var(i) - var(i)*var(j);
1332      if (p!=0) { return(1);}
1333    }
1334  }
1335  return(0);
1336}
1337example
1338{ "EXAMPLE:"; echo = 2;
1339   def a = makeWeyl(2);
1340   setring a;
1341   isNC();
1342   kill a;
1343   ring r = 17,(x(1..7)),dp;
1344   isNC();
1345   kill r;
1346}
1347
1348///////////////////////////////////////////////////////////////////////////////
1349proc rightStd(def I)
1350"USAGE:  rightStd(I); I an ideal/ module
1351PURPOSE: compute a right Groebner basis of I
1352RETURN:  the same type as input
1353EXAMPLE: example rightStd; shows examples
1354"
1355{
1356  def A = basering;
1357  def Aopp = opposite(A);
1358  setring Aopp;
1359  def Iopp = oppose(A,I);
1360  def Jopp = groebner(Iopp);
1361  setring A;
1362  def J = oppose(Aopp,Jopp);
1363  return(J);
1364}
1365example
1366{ "EXAMPLE:"; echo = 2;
1367  LIB "ncalg.lib";
1368  def A = makeUsl(2);
1369  setring A;
1370  ideal I = e2,f;
1371  option(redSB);
1372  option(redTail);
1373  ideal LI = std(I);
1374  LI;
1375  ideal RI = rightStd(I);
1376  RI;
1377}
1378
1379///////////////////////////////////////////////////////////////////////////////
1380proc rightSyz(def I)
1381"USAGE:  rightSyz(I); I an ideal/ module
1382PURPOSE: compute a right syzygy module of I
1383RETURN:  the same type as input
1384EXAMPLE: example rightSyz; shows examples
1385"
1386{
1387  def A = basering;
1388  def Aopp = opposite(A);
1389  setring Aopp;
1390  def Iopp = oppose(A,I);
1391  def Jopp = syz(Iopp);
1392  setring A;
1393  def J = oppose(Aopp,Jopp);
1394  return(J);
1395}
1396example
1397{ "EXAMPLE:"; echo = 2;
1398  ring r = 0,(x,d),dp;
1399  def S = nc_algebra(1,1); setring S; // the first Weyl algebra
1400  ideal I = x,d;
1401  module LS = syz(I);
1402  print(LS);
1403  module RS = rightSyz(I);
1404  print(RS);
1405}
1406
1407///////////////////////////////////////////////////////////////////////////////
1408proc rightNF(def v, def M)
1409"USAGE:  rightNF(I); v a poly/vector, M an ideal/module
1410PURPOSE: compute a right normal form of v w.r.t. M
1411RETURN:  poly/vector (as of the 1st argument)
1412EXAMPLE: example rightNF; shows examples
1413"
1414{
1415  def A = basering;
1416  def Aopp = opposite(A);
1417  setring Aopp;
1418  def vopp = oppose(A,v);
1419  def Mopp = oppose(A,M);
1420  Mopp = std(Mopp);
1421  def wopp = NF(vopp,Mopp);
1422  setring A;
1423  def w    = oppose(Aopp,wopp);
1424  w = simplify(w,2); // skip zeros in ideal/module
1425  return(w);
1426}
1427example
1428{ "EXAMPLE:"; echo = 2;
1429  LIB "ncalg.lib";
1430  ring r = 0,(x,d),dp;
1431  def S = nc_algebra(1,1); setring S; // Weyl algebra
1432  ideal I = x; I = std(I);
1433  poly  p = x*d+1;
1434  NF(p,I); // left normal form
1435  rightNF(p,I); // right normal form
1436}
1437
1438// **********************************
1439// * NF: Example for vector/module: *
1440// **********************************
1441// module M = [x,0],[0,d]; M = std(M);
1442// vector v = (x*d+1)*[1,1];
1443// print(NF(v,M));
1444// print(rightNF(v,M));
1445
1446///////////////////////////////////////////////////////////////////////////////
1447proc rightModulo(def M, def N)
1448"USAGE:  rightModulo(M,N); M,N are ideals/modules
1449PURPOSE: compute a right representation of the module (M+N)/N
1450RETURN:  module
1451ASSUME:  M,N are presentation matrices for right modules
1452EXAMPLE: example rightModulo; shows examples
1453"
1454{
1455  def A = basering;
1456  def Aopp = opposite(A);
1457  setring Aopp;
1458  def Mopp = oppose(A,M);
1459  def Nopp = oppose(A,N);
1460  def Kopp = modulo(Mopp,Nopp);
1461  setring A;
1462  def K = oppose(Aopp,Kopp);
1463  return(K);
1464}
1465example
1466{ "EXAMPLE:"; echo = 2;
1467  LIB "ncalg.lib";
1468  def A = makeUsl(2);
1469  setring A;
1470  option(redSB);
1471  option(redTail);
1472  ideal I = e2,f2,h2-1;
1473  I = twostd(I);
1474  print(matrix(I));
1475  ideal E  = std(e);
1476  ideal TL = e,h-1; // the result of left modulo
1477  TL;
1478  ideal T = rightModulo(E,I);
1479  T = rightStd(T+I);
1480  T = rightStd(rightNF(T,I)); // make the output canonic
1481  T;
1482}
1483
1484//////////////////////////////////////////////////////////////////////
1485
1486proc isCommutative ()
1487"USAGE:  isCommutative();
1488RETURN:  int, 1 if basering is commutative, or 0 otherwise
1489PURPOSE: check whether basering is commutative
1490EXAMPLE: example isCommutative; shows an example
1491"
1492{
1493  int iscom = 1;
1494  list L = ringlist(basering);
1495  if (size(L) > 4) // basering is nc_algebra
1496  {
1497    matrix C = L[5];
1498    matrix D = L[6];
1499    if (size(module(D)) <> 0) { iscom = 0; }
1500    else
1501    {
1502      matrix U = UpOneMatrix(nvars(basering));
1503      if (size(module(C-U)) <> 0) { iscom = 0; }
1504    }
1505  }
1506  return(iscom);
1507}
1508example
1509{
1510  "EXAMPLE:"; echo = 2;
1511  ring r = 0,(x,y),dp;
1512  isCommutative();
1513  def D = Weyl(); setring D;
1514  isCommutative();
1515  setring r;
1516  def R = nc_algebra(1,0); setring R;
1517  isCommutative();
1518}
1519
1520//////////////////////////////////////////////////////////////////////
1521
1522proc isWeyl ()
1523"USAGE:  isWeyl();
1524RETURN:  int, 1 if basering is a Weyl algebra, or 0 otherwise
1525PURPOSE: check whether basering is a Weyl algebra
1526EXAMPLE: example isWeyl; shows an example
1527"
1528{
1529  int i,j;
1530  int notW = 0;
1531  int N = nvars(basering);
1532  if (N mod 2 <> 0) { return(notW); } // odd number of generators
1533  int n = N/2;
1534  list L = ringlist(basering);
1535  if (size(L) < 6) { return(notW); } // basering is commutative
1536  matrix C = L[5];
1537  matrix D = L[6];
1538  matrix U = UpOneMatrix(N);
1539  if (size(ideal(C-U)) <> 0) { return(notW); } // lt(xy)<>lt(yx)
1540  ideal I = D;
1541  if (size(I) <> n) { return(notW); } // not n entries<>0
1542  I = simplify(I,4+2);
1543  int sI = size(I);
1544  if (sI > 2) { return(notW); }  // more than 2 distinct entries
1545  for (i=1; i<=sI; i++)
1546  {
1547    if (I[i]<>1 && I[i]<>-1) { return (notW); } // other values apart from 1,-1
1548  }
1549  ideal Ro,Co;
1550  for (i=1; i<=N; i++)
1551  {
1552    Ro = D[1..N,i];
1553    Co = D[i,1..N];
1554    if (size(Ro)>1 || size(Co)>1)
1555    {
1556      return(int(0)); // var(i) doesn't commute with more than 1 other vars
1557    }
1558  }
1559  return(int(1)); // all tests passed: basering is Weyl algebra
1560}
1561example
1562{
1563  "EXAMPLE:"; echo = 2;
1564  ring r = 0,(a,b,c,d),dp;
1565  isWeyl();
1566  def D = Weyl(1); setring D; //make from r a Weyl algebra
1567  b*a;
1568  isWeyl();
1569  ring t = 0,(Dx,x,y,Dy),dp;
1570  matrix M[4][4]; M[1,2]=-1; M[3,4]=1;
1571  def T = nc_algebra(1,M); setring T;
1572  isWeyl();
1573}
Note: See TracBrowser for help on using the repository browser.