source: git/Singular/LIB/nctools.lib @ bf42f0

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