source: git/Singular/LIB/nctools.lib @ 334c21f

spielwiese
Last change on this file since 334c21f was 3360fb, checked in by Hans Schönemann <hannes@…>, 15 years ago
*hannes: format git-svn-id: file:///usr/local/Singular/svn/trunk@11695 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 38.6 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2version="$Id: nctools.lib,v 1.49 2009-04-14 12:00:14 Singular 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///////////////////////////////////////////////////////////////////////////////
730proc superCommutative(list #)
731"USAGE:   superCommutative([b,[e, [Q, [flag]]]]);
732RETURN:  qring
733PURPOSE:  create a super-commutative algebra (as a GR-algebra) over a basering,
734NOTE: activate this qring with the \"setring\" command.
735NOTE: if b==e then the resulting ring is commutative unless 'flag' is given and non-zero.
736@* By default, @code{b=1, e=nvars(basering), Q=0}, and @code{flag=0}.
737THEORY: given a basering, this procedure introduces the anticommutative relations x(j)x(i)=-x(i)x(j) for all e>=j>i>=b,
738@* moreover, creates a factor algebra modulo the two-sided ideal, generated by x(b)^2, ..., x(e)^2[ + Q]
739DISPLAY: If @code{printlevel} > 1, warning debug messages will be printed
740EXAMPLE: example superCommutative; shows examples
741"
742{
743  int fprot = (printlevel > 1); // (find(option(),"prot") != 0);
744
745  string rname=nameof(basering);
746
747  if ( rname == "basering") // i.e. no ring has been set yet
748  {
749    ERROR("You have to call the procedure from the ring");
750    return();
751  }
752
753  def saveRing = basering;
754
755  int N = nvars(saveRing);
756  int b = 1;
757  int e = N;
758  int flag = 0;
759
760  ideal Q = 0;
761
762  if(size(#)>0)
763  {
764    if(typeof(#[1]) != "int")
765    {
766      ERROR("The argument 'b' must be an integer!");
767      return();
768    }
769    b = #[1];
770
771    if((b < 1)||(b > N))
772    {
773      ERROR("The argument 'b' must within [1..nvars(basering)]!");
774      return();
775    }
776
777  }
778
779  if(size(#)>1)
780  {
781    if(typeof(#[2]) != "int")
782    {
783      ERROR("The argument 'e' must be an integer!");
784      return();
785    }
786    e = #[2];
787
788    if((e < 1)||(e > N))
789    {
790      ERROR("The argument 'e' must within [1..nvars(basering)]!");
791      return();
792    }
793
794    if(e < b)
795    {
796      ERROR("The argument 'e' must be bigger or equal to 'b'!");
797      return();
798    }
799  }
800
801  if(size(#)>2)
802  {
803    if(typeof(#[3]) != "ideal")
804    {
805      ERROR("The argument 'Q' must be an ideal!");
806      return();
807    }
808    Q = #[3];
809  }
810
811  if(size(#)>3)
812  {
813    if(typeof(#[4]) != "int")
814    {
815      ERROR("The argument 'flag' must be an integer!");
816      return();
817    }
818    flag = #[4];
819  }
820
821  int iSavedDegBoung = degBound;
822
823  if( (b == e) && (flag == 0) ) // commutative ring!!!
824  {
825    if( fprot == 1)
826    {
827      print("Warning: (b==e) means that the resulting ring will be commutative!");
828    }
829
830    degBound=0;
831    Q = std(Q + (var(b)^2));
832    degBound = iSavedDegBoung;
833
834    qring @EA = Q; // and it will be internally commutative as well!!!
835
836    return(@EA);
837  }
838
839/*
840  // Singular'(H.S.) politics: no ring copies!
841  // in future nc_algebra() should return a new ring!!!
842  list CurrRing = ringlist(basering);
843  def @R = ring(CurrRing);
844  setring @R; // @R;
845*/
846
847  if( (char(basering)==2) && (flag == 0) )// commutative ring!!!
848  {
849    if( fprot == 1)
850    {
851      print("Warning: (char == 2) means that the resulting ring will be commutative!");
852    }
853
854    int j = ncols(Q) + 1;
855
856    for ( int i=e; i>=b; i--, j++ )
857    {
858      Q[j] = var(i)^2;
859    }
860
861    degBound=0;
862    Q = std(Q);
863    degBound = iSavedDegBoung;
864
865    qring @EA = Q; // and it will be internally commutative as well!!!
866    return(@EA);
867  }
868
869
870  int i, j;
871
872  if( (b == 1) && (e == N) ) // just an exterior algebra?
873  {
874    def S = nc_algebra(-1, 0); // define ground G-algebra!
875    setring S;
876  } else
877  {
878    matrix @E = UpOneMatrix(N);
879
880    for ( i = b; i < e; i++ )
881    {
882      for ( j = i+1; j <= e; j++ )
883      {
884        @E[i, j] = -1;
885      }
886    }
887    def S = nc_algebra(@E, 0); // define ground G-algebra!
888    setring S;
889  }
890
891  ideal @Q = fetch(saveRing, Q);
892
893  j = ncols(@Q) + 1;
894
895  for ( i=e; i>=b; i--, j++ )
896  {
897    @Q[j] = var(i)^2;
898  }
899
900  if( (fprot == 1) and (attrib(basering, "global") != 1) )
901  {
902    print("Warning: Since the current ordering is not global there might be problems computing twostd(Q)!");
903    "Q:";
904    @Q;
905  }
906
907  degBound=0;
908  @Q = twostd(@Q); // must be computed within the ground G-algebra => problems with local orderings!
909  degBound = iSavedDegBoung;
910
911  qring @EA = @Q;
912
913//   "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
914  return(@EA);
915}
916example
917{
918  "EXAMPLE:";echo=2;
919  ring R = 0,(x(1..4)),dp; // global!
920  def ER = superCommutative(); // the same as Exterior (b = 1, e = N)
921  setring ER; ER;
922  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
923  kill R; kill ER;
924  ring R = 0,(x(1..4)),(lp(1), dp(3)); // global!
925  def ER = superCommutative(2); // b = 2, e = N
926  setring ER; ER;
927  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
928  kill R; kill ER;
929  ring R = 0,(x(1..6)),(ls(2), dp(2), lp(2)); // local!
930  def ER = superCommutative(3,4); // b = 3, e = 4
931  setring ER; ER;
932  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
933  kill R; kill ER;
934}
935
936
937static proc ParseSCA()
938"
939RETURN: list {AltVarStart, AltVarEnd} is currRing is SCA, returns undef otherwise.
940NOTE: rings with only one non-commutative variable are commutative rings which are super-sommutative itself!
941"
942{
943  def saveRing = basering;
944
945  int i, j;
946  int N = nvars(saveRing);
947
948  int b = N+1;
949  int e =  -1;
950
951  int fprot = (find(option(),"prot") != 0);
952
953
954  if( size(ideal(saveRing)) == 0 )
955  {
956    return("SCA rings are factors by (at least) squares!"); // no squares in the factor ideal!
957  }
958
959  list L = ringlist(saveRing);
960
961  if( size(L)!=6 )
962  {
963    if(fprot)
964    {
965      print("Warning: The current ring is internally commutative!");
966    }
967
968    for( i = N; i > 0; i-- )
969    {
970      if( NF(var(i)^2, std(0)) == 0 )
971      {
972        if( (fprot == 1) and (i > 1) )
973        {
974          print("Warning: the SCA representation of the current commutative factor ring may be ambiguous!");
975        }
976
977        return( list(i, i) ); // this is not unique in this case! there may be other squares in the factor ideal!
978      }
979    }
980
981    return("The current commutative ring is not SCA! (Wrong quotient ideal)"); // no squares in the factor ideal!
982  }
983
984  module D = simplify(L[6], 2 + 4);
985
986  if( size(D)>0 )
987  {
988    return("The current ring is not SCA! (D!=0)");
989  }
990
991  matrix C = L[5];
992  poly c;
993
994  for( i = 1; i < N; i++ )
995  {
996    for( j = i+1; j <= N; j++ )
997    {
998      c = C[i, j];
999
1000      if( c == -1 )
1001      {
1002        if(i < b)
1003        {
1004          b = i;
1005        }
1006
1007        if(j > e)
1008        {
1009          e = j;
1010        }
1011      } else
1012      { // should commute
1013        if( c!=1 )
1014        {
1015          return("The current ring is not SCA! (C["+ string(i)+"," + string(j)+"]!=1)");
1016        }
1017      }
1018    }
1019  }
1020
1021  if( (b > N) || (e < 1))
1022  {
1023    if(fprot)
1024    {
1025      print("Warning: The current ring is a commutative GR-algebra!");
1026    }
1027
1028    for( i = N; i > 0; i-- )
1029    {
1030      if( NF(var(i)^2, std(0)) == 0 )
1031      {
1032        if( (fprot == 1) and (i > 1) )
1033        {
1034          print("Warning: the SCA representation of the current factor ring may be ambiguous!");
1035        }
1036
1037        return( list(i, i) ); // this is not unique in this case! there may be other squares in the factor ideal!
1038      }
1039    }
1040
1041    return("The current commutative GR-algebra is not SCA! (Wrong quotient ideal)"); // no squares in the factor ideal!
1042  }
1043
1044  for( i = 1; i < N; i++ )
1045  {
1046    for( j = i+1; j <= N; j++ )
1047    {
1048      c = C[i, j];
1049
1050      if( (b <= i) && (j <= e) ) // S <= i < j <= E
1051      { // anticommutative part
1052        if( c!= -1 )
1053        {
1054          return("The current ring is not SCA! (C["+ string(i)+"," + string(j)+"]!=-1)");
1055        }
1056      } else
1057      { // should commute
1058        if( c!=1 )
1059        {
1060          return("The current ring is not SCA! (C["+ string(i)+"," + string(j)+"]!=1)");
1061        }
1062      }
1063    }
1064  }
1065
1066  for( i = b; i <= e; i++ )
1067  {
1068    if( NF(var(i)^2, std(0)) != 0 )
1069    {
1070      return("The current ring is not SCA! (Wrong quotient ideal)");
1071    }
1072  }
1073
1074  ////////////////////////////////////////////////////////////////////////
1075  // ok. it is a SCA!!!
1076
1077  return(list(b, e));
1078}
1079
1080///////////////////////////////////////////////////////////////////////////////
1081proc AltVarStart()
1082"USAGE:   AltVarStart();
1083RETURN:  int
1084PURPOSE:  returns the number of the first alternating variable of basering
1085NOTE:  basering should be a super-commutative algebra with at most one block of anti-commutative variables
1086@* For commutative rings, @code{nvars(basering)+1} will be returned.
1087EXAMPLE: example AltVarStart; shows examples
1088"
1089{
1090  def l = ParseSCA();
1091
1092  if( typeof(l) != "string" )
1093  {
1094    return(l[1]);
1095  }
1096
1097  ERROR(l);
1098  return();
1099}
1100example
1101{
1102  "EXAMPLE:";echo=2;
1103  ring R = 0,(x(1..4)),dp; // global!
1104  def ER = superCommutative(2); // (b = 2, e = N)
1105  setring ER; ER;
1106  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
1107}
1108
1109///////////////////////////////////////////////////////////////////////////////
1110proc AltVarEnd()
1111"USAGE:   AltVarStart();
1112RETURN:  int
1113PURPOSE:  returns the number of the last alternating variable of basering
1114NOTE:  basering should be a super-commutative algebra with at most one block of anti-commutative variables
1115@* returns -1 for commutative rings
1116EXAMPLE: example AltVarEnd; shows examples
1117"
1118{
1119  def l = ParseSCA();
1120
1121  if( typeof(l) != "string" )
1122  {
1123    return(l[2]);
1124  }
1125
1126  ERROR(l);
1127  return();
1128}
1129example
1130{
1131  "EXAMPLE:";echo=2;
1132  ring R = 0,(x(1..4)),dp; // global!
1133  def ER = superCommutative(2); // (b = 2, e = N)
1134  setring ER; ER;
1135  "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "].";
1136}
1137
1138///////////////////////////////////////////////////////////////////////////////
1139proc IsSCA()
1140"USAGE:   IsSCA();
1141RETURN:  int
1142PURPOSE:  returns 1 if basering is a super-commutative algebra and 0 otherwise.
1143NOTE:     shows hint message for non-SCA algebras if the 'prot' option is on.
1144EXAMPLE: example IsSCA; shows examples
1145"
1146{
1147  def l = ParseSCA();
1148
1149  if( typeof(l) != "string" )
1150  {
1151    return(1);
1152  }
1153
1154  if( find(option(),"prot") != 0 )
1155  {
1156    print(l);
1157  }
1158
1159  return(0);
1160}
1161example
1162{
1163  "EXAMPLE:";echo=2;
1164/////////////////////////////////////////////////////////////////////
1165  ring R = 0,(x(1..4)),dp; // commutative
1166  if(IsSCA())
1167    { "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "]."; }
1168  else
1169    { "Not a super-commutative algebra!!!"; }
1170  kill R;
1171/////////////////////////////////////////////////////////////////////
1172  ring R = 0,(x(1..4)),dp;
1173  def S = nc_algebra(1, 0); setring S; S; // still commutative!
1174  if(IsSCA())
1175    { "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "]."; }
1176  else
1177    { "Not a super-commutative algebra!!!"; }
1178  kill R, S;
1179/////////////////////////////////////////////////////////////////////
1180  ring R = 0,(x(1..4)),dp;
1181  list CurrRing = ringlist(R);
1182  def ER = ring(CurrRing);
1183  setring ER; // R;
1184
1185  matrix E = UpOneMatrix(nvars(R));
1186
1187  int i, j; int b = 2; int e = 3;
1188
1189  for ( i = b; i < e; i++ )
1190  {
1191    for ( j = i+1; j <= e; j++ )
1192    {
1193      E[i, j] = -1;
1194    }
1195  }
1196
1197  def S = nc_algebra(E,0); setring S; S;
1198
1199  if(IsSCA())
1200    { "Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "]."; }
1201  else
1202    { "Not a super-commutative algebra!!!"; }
1203  kill R, ER, S;
1204/////////////////////////////////////////////////////////////////////
1205  ring R = 0,(x(1..4)),dp;
1206  def ER = superCommutative(2); // (b = 2, e = N)
1207  setring ER; ER;
1208  if(IsSCA())
1209    { "This is a SCA! Alternating variables: [", AltVarStart(), ",", AltVarEnd(), "]."; }
1210  else
1211    { "Not a super-commutative algebra!!!"; }
1212  kill R, ER;
1213}
1214
1215
1216
1217///////////////////////////////////////////////////////////////////////////////
1218proc Exterior(list #)
1219"USAGE:   Exterior();
1220RETURN:  qring
1221PURPOSE:  create the exterior algebra of a basering
1222NOTE:  activate this qring with the \"setring\" command
1223THEORY: given a basering, this procedure introduces the anticommutative relations x(j)x(i)=-x(i)x(j) for all j>i,
1224@* moreover, creates a factor algebra modulo the two-sided ideal, generated by x(i)^2 for all i
1225EXAMPLE: example Exterior; shows examples
1226"
1227{
1228  string rname=nameof(basering);
1229  if ( rname == "basering") // i.e. no ring has been set yet
1230  {
1231    "You have to call the procedure from the ring";
1232    return();
1233  }
1234  int N = nvars(basering);
1235  string NewRing = "ring @R=("+charstr(basering)+"),("+varstr(basering)+"),("+ordstr(basering)+");";
1236  execute(NewRing);
1237  matrix @E = UpOneMatrix(N);
1238  @E = -1*(@E);
1239  def @@RR = nc_algebra(@E,0); setring @@RR;
1240  int i;
1241  ideal Q;
1242  for ( i=1; i<=N; i++ )
1243  {
1244    Q[i] = var(i)^2;
1245  }
1246  Q = twostd(Q);
1247  qring @EA = Q;
1248  return(@EA);
1249}
1250example
1251{
1252  "EXAMPLE:";echo=2;
1253  ring R = 0,(x(1..3)),dp;
1254  def ER = Exterior();
1255  setring ER;
1256  ER;
1257}
1258
1259///////////////////////////////////////////////////////////////////////////////
1260proc makeWeyl(int n, list #)
1261"USAGE:  makeWeyl(n,[p]); n an integer, n>0; p an optional integer (field characteristic)
1262RETURN:  ring
1263PURPOSE: create the n-th Weyl algebra over the rationals Q or F_p
1264NOTE:    activate this ring with the \"setring\" command.
1265@*       The presentation of an n-th Weyl algebra is classical: D(i)x(i)=x(i)D(i)+1,
1266@*       where x(i) correspond to coordinates and D(i) to partial differentiations, i=1,...,n.
1267@*       If p is not prime, the next larger prime number will be used.
1268SEE ALSO: Weyl
1269EXAMPLE: example makeWeyl; shows examples
1270"{
1271  if (n<1)
1272  {
1273    print("Incorrect input");
1274    return();
1275  }
1276  int @p = 0;
1277  if ( size(#) > 0 )
1278  {
1279    if ( typeof( #[1] ) == "int" )
1280    {
1281      @p = #[1];
1282    }
1283  }
1284  if (n ==1)
1285  {
1286    ring @rr = @p,(x,D),dp;
1287  }
1288  else
1289  {
1290    ring @rr = @p,(x(1..n),D(1..n)),dp;
1291  }
1292  setring @rr;
1293  def @rrr = Weyl();
1294  return(@rrr);
1295}
1296example
1297{ "EXAMPLE:"; echo = 2;
1298   def a = makeWeyl(3);
1299   setring a;
1300   a;
1301}
1302
1303//////////////////////////////////////////////////////////////////////
1304proc isNC()
1305"USAGE:   isNC();
1306PURPOSE: check whether a basering is commutative or not
1307RETURN:   int, 1 if basering is noncommutative and 0 otherwise
1308EXAMPLE: example isNC; shows examples
1309"{
1310  string rname=nameof(basering);
1311  if ( rname == "basering") // i.e. no ring has been set yet
1312  {
1313    "You have to call the procedure from the ring";
1314    return();
1315  }
1316  int n = nvars(basering);
1317  int i,j;
1318  poly p;
1319  for (i=1; i<n; i++)
1320  {
1321    for (j=i+1; j<=n; j++)
1322    {
1323      p = var(j)*var(i) - var(i)*var(j);
1324      if (p!=0) { return(1);}
1325    }
1326  }
1327  return(0);
1328}
1329example
1330{ "EXAMPLE:"; echo = 2;
1331   def a = makeWeyl(2);
1332   setring a;
1333   isNC();
1334   kill a;
1335   ring r = 17,(x(1..7)),dp;
1336   isNC();
1337   kill r;
1338}
1339
1340///////////////////////////////////////////////////////////////////////////////
1341proc rightStd(def I)
1342"USAGE:  rightStd(I); I an ideal/ module
1343PURPOSE: compute a right Groebner basis of I
1344RETURN:  the same type as input
1345EXAMPLE: example rightStd; shows examples
1346"
1347{
1348  def A = basering;
1349  def Aopp = opposite(A);
1350  setring Aopp;
1351  def Iopp = oppose(A,I);
1352  def Jopp = groebner(Iopp);
1353  setring A;
1354  def J = oppose(Aopp,Jopp);
1355  return(J);
1356}
1357example
1358{ "EXAMPLE:"; echo = 2;
1359  LIB "ncalg.lib";
1360  def A = makeUsl(2);
1361  setring A;
1362  ideal I = e2,f;
1363  option(redSB);
1364  option(redTail);
1365  ideal LI = std(I);
1366  LI;
1367  ideal RI = rightStd(I);
1368  RI;
1369}
1370
1371///////////////////////////////////////////////////////////////////////////////
1372proc rightSyz(def I)
1373"USAGE:  rightSyz(I); I an ideal/ module
1374PURPOSE: compute a right syzygy module of I
1375RETURN:  the same type as input
1376EXAMPLE: example rightSyz; shows examples
1377"
1378{
1379  def A = basering;
1380  def Aopp = opposite(A);
1381  setring Aopp;
1382  def Iopp = oppose(A,I);
1383  def Jopp = syz(Iopp);
1384  setring A;
1385  def J = oppose(Aopp,Jopp);
1386  return(J);
1387}
1388example
1389{ "EXAMPLE:"; echo = 2;
1390  ring r = 0,(x,d),dp;
1391  def S = nc_algebra(1,1); setring S; // the first Weyl algebra
1392  ideal I = x,d;
1393  module LS = syz(I);
1394  print(LS);
1395  module RS = rightSyz(I);
1396  print(RS);
1397}
1398
1399///////////////////////////////////////////////////////////////////////////////
1400proc rightNF(def v, def M)
1401"USAGE:  rightNF(I); v a poly/vector, M an ideal/module
1402PURPOSE: compute a right normal form of v w.r.t. M
1403RETURN:  poly/vector (as of the 1st argument)
1404EXAMPLE: example rightNF; shows examples
1405"
1406{
1407  def A = basering;
1408  def Aopp = opposite(A);
1409  setring Aopp;
1410  def vopp = oppose(A,v);
1411  def Mopp = oppose(A,M);
1412  Mopp = std(Mopp);
1413  def wopp = NF(vopp,Mopp);
1414  setring A;
1415  def w    = oppose(Aopp,wopp);
1416  w = simplify(w,2); // skip zeros in ideal/module
1417  return(w);
1418}
1419example
1420{ "EXAMPLE:"; echo = 2;
1421  LIB "ncalg.lib";
1422  ring r = 0,(x,d),dp;
1423  def S = nc_algebra(1,1); setring S; // Weyl algebra
1424  ideal I = x; I = std(I);
1425  poly  p = x*d+1;
1426  NF(p,I); // left normal form
1427  rightNF(p,I); // right normal form
1428}
1429
1430// **********************************
1431// * NF: Example for vector/module: *
1432// **********************************
1433// module M = [x,0],[0,d]; M = std(M);
1434// vector v = (x*d+1)*[1,1];
1435// print(NF(v,M));
1436// print(rightNF(v,M));
1437
1438///////////////////////////////////////////////////////////////////////////////
1439proc rightModulo(def M, def N)
1440"USAGE:  rightModulo(M,N); M,N are ideals/modules
1441PURPOSE: compute a right representation of the module (M+N)/N
1442RETURN:  module
1443ASSUME:  M,N are presentation matrices for right modules
1444EXAMPLE: example rightModulo; shows examples
1445"
1446{
1447  def A = basering;
1448  def Aopp = opposite(A);
1449  setring Aopp;
1450  def Mopp = oppose(A,M);
1451  def Nopp = oppose(A,N);
1452  def Kopp = modulo(Mopp,Nopp);
1453  setring A;
1454  def K = oppose(Aopp,Kopp);
1455  return(K);
1456}
1457example
1458{ "EXAMPLE:"; echo = 2;
1459  LIB "ncalg.lib";
1460  def A = makeUsl(2);
1461  setring A;
1462  option(redSB);
1463  option(redTail);
1464  ideal I = e2,f2,h2-1;
1465  I = twostd(I);
1466  print(matrix(I));
1467  ideal E  = std(e);
1468  ideal TL = e,h-1; // the result of left modulo
1469  TL;
1470  ideal T = rightModulo(E,I);
1471  T = rightStd(T+I);
1472  T = rightStd(rightNF(T,I)); // make the output canonic
1473  T;
1474}
1475
1476//////////////////////////////////////////////////////////////////////
1477
1478proc isCommutative ()
1479"USAGE:  isCommutative();
1480RETURN:  int, 1 if basering is commutative, or 0 otherwise
1481PURPOSE: check whether basering is commutative
1482EXAMPLE: example isCommutative; shows an example
1483"
1484{
1485  int iscom = 1;
1486  list L = ringlist(basering);
1487  if (size(L) > 4) // basering is nc_algebra
1488  {
1489    matrix C = L[5];
1490    matrix D = L[6];
1491    if (size(module(D)) <> 0) { iscom = 0; }
1492    else
1493    {
1494      matrix U = UpOneMatrix(nvars(basering));
1495      if (size(module(C-U)) <> 0) { iscom = 0; }
1496    }
1497  }
1498  return(iscom);
1499}
1500example
1501{
1502  "EXAMPLE:"; echo = 2;
1503  ring r = 0,(x,y),dp;
1504  isCommutative();
1505  def D = Weyl(); setring D;
1506  isCommutative();
1507  setring r;
1508  def R = nc_algebra(1,0); setring R;
1509  isCommutative();
1510}
1511
1512//////////////////////////////////////////////////////////////////////
1513
1514proc isWeyl ()
1515"USAGE:  isWeyl();
1516RETURN:  int, 1 if basering is a Weyl algebra, or 0 otherwise
1517PURPOSE: check whether basering is a Weyl algebra
1518EXAMPLE: example isWeyl; shows an example
1519"
1520{
1521  int i,j;
1522  int notW = 0;
1523  int N = nvars(basering);
1524  if (N mod 2 <> 0) { return(notW); } // odd number of generators
1525  int n = N/2;
1526  list L = ringlist(basering);
1527  if (size(L) < 6) { return(notW); } // basering is commutative
1528  matrix C = L[5];
1529  matrix D = L[6];
1530  matrix U = UpOneMatrix(N);
1531  if (size(ideal(C-U)) <> 0) { return(notW); } // lt(xy)<>lt(yx)
1532  ideal I = D;
1533  if (size(I) <> n) { return(notW); } // not n entries<>0
1534  I = simplify(I,4+2);
1535  int sI = size(I);
1536  if (sI > 2) { return(notW); }  // more than 2 distinct entries
1537  for (i=1; i<=sI; i++)
1538  {
1539    if (I[i]<>1 && I[i]<>-1) { return (notW); } // other values apart from 1,-1
1540  }
1541  ideal Ro,Co;
1542  for (i=1; i<=N; i++)
1543  {
1544    Ro = D[1..N,i];
1545    Co = D[i,1..N];
1546    if (size(Ro)>1 || size(Co)>1)
1547    {
1548      return(int(0)); // var(i) doesn't commute with more than 1 other vars
1549    }
1550  }
1551  return(int(1)); // all tests passed: basering is Weyl algebra
1552}
1553example
1554{
1555  "EXAMPLE:"; echo = 2;
1556  ring r = 0,(a,b,c,d),dp;
1557  isWeyl();
1558  def D = Weyl(1); setring D; //make from r a Weyl algebra
1559  b*a;
1560  isWeyl();
1561  ring t = 0,(Dx,x,y,Dy),dp;
1562  matrix M[4][4]; M[1,2]=-1; M[3,4]=1;
1563  def T = nc_algebra(1,M); setring T;
1564  isWeyl();
1565}
Note: See TracBrowser for help on using the repository browser.