source: git/Singular/LIB/nctools.lib @ 6fe9a5

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