source: git/Singular/LIB/ncfactor.lib @ ecf019

fieker-DuValspielwiese
Last change on this file since ecf019 was 62c2b0, checked in by Hans Schoenemann <hannes@…>, 13 years ago
se div instead of /, part 4 (last part) git-svn-id: file:///usr/local/Singular/svn/trunk@14196 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100755
File size: 82.4 KB
Line 
1///////////////////////////////////////////////////////////
2version = "$Id$";
3category="Noncommutative";
4info="
5LIBRARY: ncfactor.lib  Tools for factorization in some noncommutative algebras
6AUTHORS: Albert Heinle,     albert.heinle@rwth-aachen.de
7@*       Viktor Levandovskyy,     levandov@math.rwth-aachen.de
8
9OVERVIEW: In this library, new methods for factorization on polynomials
10  are implemented for two algebras, both generated by two generators (Weyl and
11  shift algebras) over a field K. Recall, that   the first Weyl algebra over K
12  is generated by x,d obeying the relation d*x=x*d+1.
13@* The first shift algebra over K is generated by x,s obeying the relation s*x=x*s+s.
14@* More detailled description of the algorithms can be found at
15@url{http://www.math.rwth-aachen.de/\~Albert.Heinle}.
16
17Guide: We are interested in computing a tree of factorizations, that is at the moment
18a list of all found factorizations is returned. It may contain factorizations, which
19are further reducible.
20
21PROCEDURES:
22  facFirstWeyl(h);           factorization in the first Weyl algebra
23  testNCfac(l[,h[,1]]);      tests factorizations from a given list for correctness
24  facSubWeyl(h,X,D);         factorization in the first Weyl algebra as a subalgebra
25  facFirstShift(h);          factorization in the first shift algebra
26  homogfacFirstQWeyl(h);     [-1,1]-homogeneous factorization in the first Q-Weyl algebra
27  homogfacFirstQWeyl_all(h); [-1,1] homogeneous factorization(complete) in the first Q-Weyl algebra
28";
29
30LIB "general.lib";
31LIB "nctools.lib";
32LIB "involut.lib";
33LIB "freegb.lib"; // for isVar
34
35proc tst_ncfactor()
36{
37  example facFirstWeyl;
38  example facFirstShift;
39  example facSubWeyl;
40  example testNCfac;
41  example homogfacFirstQWeyl;
42  example homogfacFirstQWeyl_all;
43}
44
45/////////////////////////////////////////////////////
46//==================================================*
47//deletes double-entries in a list of factorization
48//without evaluating the product.
49static proc delete_dublicates_noteval(list l)
50{//proc delete_dublicates_noteval
51  list result= l;
52  int j; int k; int i;
53  int deleted = 0;
54  int is_equal;
55  for (i = 1; i<= size(l); i++)
56  {//Iterate over the different factorizations
57    for (j = i+1; j<= size(l); j++)
58    {//Compare the i'th factorization to the j'th
59      if (size(l[i])!= size(l[j]))
60      {//different sizes => not equal
61        j++;
62        continue;
63      }//different sizes => not equal
64      is_equal = 1;
65      for (k = 1; k <= size(l[i]);k++)
66      {//Compare every entry
67        if (l[i][k]!=l[j][k])
68        {
69          is_equal = 0;
70          break;
71        }
72      }//Compare every entry
73      if (is_equal == 1)
74      {//Delete this entry, because there is another equal one int the list
75        result = delete(result, i-deleted);
76        deleted = deleted+1;
77        break;
78      }//Delete this entry, because there is another equal one int the list
79    }//Compare the i'th factorization to the j'th
80  }//Iterate over the different factorizations
81  return(result);
82}//proc delete_dublicates_noteval
83
84//==================================================
85//deletes the double-entries in a list with
86//evaluating the products
87static proc delete_dublicates_eval(list l)
88{//proc delete_dublicates_eval
89  list result=l;
90  int j; int k; int i;
91  int deleted = 0;
92  int is_equal;
93  for (i = 1; i<= size(result); i++)
94  {//Iterating over all elements in result
95    for (j = i+1; j<= size(result); j++)
96    {//comparing with the other elements
97      if (product(result[i]) == product(result[j]))
98      {//There are two equal results; throw away that one with the smaller size
99        if (size(result[i])>=size(result[j]))
100        {//result[i] has more entries
101          result = delete(result,j);
102          continue;
103        }//result[i] has more entries
104        else
105        {//result[j] has more entries
106          result = delete(result,i);
107          i--;
108          break;
109        }//result[j] has more entries
110      }//There are two equal results; throw away that one with the smaller size
111    }//comparing with the other elements
112  }//Iterating over all elements in result
113  return(result);
114}//proc delete_dublicates_eval
115
116
117//==================================================*
118//given a list of factors g and a desired size nof, the following
119//procedure combines the factors, such that we recieve a
120//list of the length nof.
121static proc combinekfinlf(list g, int nof, intvec limits) //nof stands for "number of factors"
122{//Procedure combinekfinlf
123  list result;
124  int i; int j; int k; //iteration variables
125  list fc; //fc stands for "factors combined"
126  list temp; //a temporary store for factors
127  def nofgl = size(g); //nofgl stands for "number of factors of the given list"
128  if (nofgl == 0)
129  {//g was the empty list
130    return(result);
131  }//g was the empty list
132  if (nof <= 0)
133  {//The user wants to recieve a negative number or no element as a result
134    return(result);
135  }//The user wants to recieve a negative number or no element as a result
136  if (nofgl == nof)
137  {//There are no factors to combine
138    if (limitcheck(g,limits))
139    {
140      result = result + list(g);
141    }
142    return(result);
143  }//There are no factors to combine
144  if (nof == 1)
145  {//User wants to get just one factor
146    if (limitcheck(list(product(g)),limits))
147    {
148      result = result + list(list(product(g)));
149    }
150    return(result);
151  }//User wants to get just one factor
152  for (i = nof; i > 1; i--)
153  {//computing the possibilities that have at least one original factor from g
154    for (j = i; j>=1; j--)
155    {//shifting the window of combinable factors to the left
156      //fc below stands for "factors combined"
157      fc = combinekfinlf(list(g[(j)..(j+nofgl - i)]),nof - i + 1,limits);
158      for (k = 1; k<=size(fc); k++)
159      {//iterating over the different solutions of the smaller problem
160        if (j>1)
161        {//There are g_i before the combination
162          if (j+nofgl -i < nofgl)
163          {//There are g_i after the combination
164            temp = list(g[1..(j-1)]) + fc[k] + list(g[(j+nofgl-i+1)..nofgl]);
165          }//There are g_i after the combination
166          else
167          {//There are no g_i after the combination
168            temp = list(g[1..(j-1)]) + fc[k];
169          }//There are no g_i after the combination
170        }//There are g_i before the combination
171        if (j==1)
172        {//There are no g_i before the combination
173          if (j+ nofgl -i <nofgl)
174          {//There are g_i after the combination
175            temp = fc[k]+ list(g[(j + nofgl - i +1)..nofgl]);
176          }//There are g_i after the combination
177        }//There are no g_i before the combination
178        if (limitcheck(temp,limits))
179        {
180          result = result + list(temp);
181        }
182      }//iterating over the different solutions of the smaller problem
183    }//shifting the window of combinable factors to the left
184  }//computing the possibilities that have at least one original factor from g
185  for (i = 2; i<=nofgl div nof;i++)
186  {//getting the other possible results
187    result = result + combinekfinlf(list(product(list(g[1..i])))+list(g[(i+1)..nofgl]),nof,limits);
188  }//getting the other possible results
189  result = delete_dublicates_noteval(result);
190  return(result);
191}//Procedure combinekfinlf
192
193
194//==================================================*
195//merges two sets of factors ignoring common
196//factors
197static proc merge_icf(list l1, list l2, intvec limits)
198{//proc merge_icf
199  list g;
200  list f;
201  int i; int j;
202  if (size(l1)==0)
203  {
204    return(list());
205  }
206  if (size(l2)==0)
207  {
208    return(list());
209  }
210  if (size(l2)<=size(l1))
211  {//l1 will be our g, l2 our f
212    g = l1;
213    f = l2;
214  }//l1 will be our g, l2 our f
215  else
216  {//l1 will be our f, l2 our g
217    g = l2;
218    f = l1;
219  }//l1 will be our f, l2 our g
220  def result = combinekfinlf(g,size(f),limits);
221  for (i = 1 ; i<= size(result); i++)
222  {//Adding the factors of f to every possibility listed in temp
223    for (j = 1; j<= size(f); j++)
224    {
225      result[i][j] = result[i][j]+f[j];
226    }
227    if(!limitcheck(result[i],limits))
228    {
229      result = delete(result,i);
230      i--;
231    }
232  }//Adding the factors of f to every possibility listed in temp
233  return(result);
234}//proc merge_icf
235
236//==================================================*
237//merges two sets of factors with respect to the occurrence
238//of common factors
239static proc merge_cf(list l1, list l2, intvec limits)
240{//proc merge_cf
241  list g;
242  list f;
243  int i; int j;
244  list pre;
245  list post;
246  list candidate;
247  list temp;
248  int temppos;
249  if (size(l1)==0)
250  {//the first list is empty
251    return(list());
252  }//the first list is empty
253  if(size(l2)==0)
254  {//the second list is empty
255    return(list());
256  }//the second list is empty
257  if (size(l2)<=size(l1))
258  {//l1 will be our g, l2 our f
259    g = l1;
260    f = l2;
261  }//l1 will be our g, l2 our f
262  else
263  {//l1 will be our f, l2 our g
264    g = l2;
265    f = l1;
266  }//l1 will be our f, l2 our g
267  list M;
268  for (i = 2; i<size(f); i++)
269  {//finding common factors of f and g...
270    for (j=2; j<size(g);j++)
271    {//... with g
272      if (f[i] == g[j])
273      {//we have an equal pair
274        M = M + list(list(i,j));
275      }//we have an equal pair
276    }//... with g
277  }//finding common factors of f and g...
278  if (g[1]==f[1])
279  {//Checking for the first elements to be equal
280    M = M + list(list(1,1));
281  }//Checking for the first elements to be equal
282  if (g[size(g)]==f[size(f)])
283  {//Checking for the last elements to be equal
284    M = M + list(list(size(f),size(g)));
285  }//Checking for the last elements to be equal
286  list result;//= list(list());
287  while(size(M)>0)
288  {//set of equal pairs is not empty
289    temp = M[1];
290    temppos = 1;
291    for (i = 2; i<=size(M); i++)
292    {//finding the minimal element of M
293      if (M[i][1]<=temp[1])
294      {//a possible candidate that is smaller than temp could have been found
295        if (M[i][1]==temp[1])
296        {//In this case we must look at the second number
297          if (M[i][2]< temp[2])
298          {//the candidate is smaller
299            temp = M[i];
300            temppos = i;
301          }//the candidate is smaller
302        }//In this case we must look at the second number
303        else
304        {//The candidate is definately smaller
305          temp = M[i];
306          temppos = i;
307        }//The candidate is definately smaller
308      }//a possible candidate that is smaller than temp could have been found
309    }//finding the minimal element of M
310    M = delete(M, temppos);
311    if(temp[1]>1)
312    {//There are factors to combine before the equal factor
313      if (temp[1]<size(f))
314      {//The most common case
315        //first the combinations ignoring common factors
316        pre = merge_icf(list(f[1..(temp[1]-1)]),list(g[1..(temp[2]-1)]),limits);
317        post = merge_icf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
318        for (i = 1; i <= size(pre); i++)
319        {//all possible pre's...
320          for (j = 1; j<= size(post); j++)
321          {//...combined with all possible post's
322            candidate = pre[i]+list(f[temp[1]])+post[j];
323            if (limitcheck(candidate,limits))
324            {
325              result = result + list(candidate);
326            }
327          }//...combined with all possible post's
328        }//all possible pre's...
329        //Now the combinations with respect to common factors
330        post = merge_cf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
331        if (size(post)>0)
332        {//There are factors to combine
333          for (i = 1; i <= size(pre); i++)
334          {//all possible pre's...
335            for (j = 1; j<= size(post); j++)
336            {//...combined with all possible post's
337              candidate= pre[i]+list(f[temp[1]])+post[j];
338              if (limitcheck(candidate,limits))
339              {
340                result = result + list(candidate);
341              }
342            }//...combined with all possible post's
343          }//all possible pre's...
344        }//There are factors to combine
345      }//The most common case
346      else
347      {//the last factor is the common one
348        pre = merge_icf(list(f[1..(temp[1]-1)]),list(g[1..(temp[2]-1)]),limits);
349        for (i = 1; i<= size(pre); i++)
350        {//iterating over the possible pre-factors
351          candidate = pre[i]+list(f[temp[1]]);
352          if (limitcheck(candidate,limits))
353          {
354            result = result + list(candidate);
355          }
356        }//iterating over the possible pre-factors
357      }//the last factor is the common one
358    }//There are factors to combine before the equal factor
359    else
360    {//There are no factors to combine before the equal factor
361      if (temp[1]<size(f))
362      {//Just a check for security
363        //first without common factors
364        post=merge_icf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
365        for (i = 1; i<=size(post); i++)
366        {
367          candidate = list(f[temp[1]])+post[i];
368          if (limitcheck(candidate,limits))
369          {
370            result = result + list(candidate);
371          }
372        }
373        //Now with common factors
374        post = merge_cf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
375        if(size(post)>0)
376        {//we could find other combinations
377          for (i = 1; i<=size(post); i++)
378          {
379            candidate = list(f[temp[1]])+post[i];
380            if (limitcheck(candidate,limits))
381            {
382              result = result + list(candidate);
383            }
384          }
385        }//we could find other combinations
386      }//Just a check for security
387    }//There are no factors to combine before the equal factor
388  }//set of equal pairs is not empty
389  return(result);
390}//proc merge_cf
391
392
393//==================================================*
394//merges two sets of factors
395
396static proc mergence(list l1, list l2, intvec limits)
397{//Procedure mergence
398  list g;
399  list f;
400  int l; int k;
401  list F;
402  if (size(l2)<=size(l1))
403  {//l1 will be our g, l2 our f
404    g = l1;
405    f = l2;
406  }//l1 will be our g, l2 our f
407  else
408  {//l1 will be our f, l2 our g
409    g = l2;
410    f = l1;
411  }//l1 will be our f, l2 our g
412  list result;
413  for (l = size(f); l>=1; l--)
414  {//all possibilities to combine the factors of f
415    F = combinekfinlf(f,l,limits);
416    for (k = 1; k<= size(F);k++)
417    {//for all possibilities of combinations of the factors of f
418      result = result + merge_cf(F[k],g,limits);
419      result = result + merge_icf(F[k],g,limits);
420    }//for all possibilities of combinations of the factors of f
421  }//all possibilities to combine the factors of f
422  return(result);
423}//Procedure mergence
424
425
426//==================================================
427//Checks, whether a list of factors doesn't exceed the given limits
428static proc limitcheck(list g, intvec limits)
429{//proc limitcheck
430  int i;
431  if (size(limits)!=3)
432  {//check the input
433    return(0);
434  }//check the input
435  if(size(g)==0)
436  {
437    return(0);
438  }
439  def prod = product(g);
440  intvec iv11 = intvec(1,1);
441  intvec iv10 = intvec(1,0);
442  intvec iv01 = intvec(0,1);
443  def limg = intvec(deg(prod,iv11) ,deg(prod,iv10),deg(prod,iv01));
444  for (i = 1; i<=size(limg);i++)
445  {//the final check
446    if(limg[i]>limits[i])
447    {
448      return(0);
449    }
450  }//the final check
451  return(1);
452}//proc limitcheck
453
454
455//==================================================*
456//one factorization of a homogeneous polynomial
457//in the first Weyl Algebra
458static proc homogfacFirstWeyl(poly h)
459"USAGE: homogfacFirstWeyl(h); h is a homogeneous polynomial in the
460        first Weyl algebra with respect to the weight vector [-1,1]
461RETURN: list
462PURPOSE: Computes a factorization of a homogeneous polynomial h with
463         respect to the weight vector [-1,1] in the first Weyl algebra
464THEORY: @code{homogfacFirstWeyl} returns a list with a factorization of the given,
465        [-1,1]-homogeneous polynomial. If the degree of the polynomial is k with
466        k positive, the last k entries in the output list are the second
467        variable. If k is positive, the last k entries will be x. The other
468        entries will be irreducible polynomials of degree zero or 1 resp. -1.
469SEE ALSO: homogfacFirstWeyl_all
470"{//proc homogfacFirstWeyl
471  int p = printlevel-voice+2;//for dbprint
472  def r = basering;
473  poly hath;
474  int i; int j;
475  intvec ivm11 = intvec(-1,1);
476  if (!homogwithorder(h,ivm11))
477  {//The given polynomial is not homogeneous
478    ERROR("Given polynomial was not [-1,1]-homogeneous");
479    return(list());
480  }//The given polynomial is not homogeneous
481  if (h==0)
482  {
483    return(list(0));
484  }
485  list result;
486  int m = deg(h,ivm11);
487  dbprint(p,"==> Splitting the polynomial in A_0 and A_k-Part");
488  if (m!=0)
489  {//The degree is not zero
490    if (m <0)
491    {//There are more x than y
492      hath = lift(var(1)^(-m),h)[1,1];
493      for (i = 1; i<=-m; i++)
494      {
495        result = result + list(var(1));
496      }
497    }//There are more x than y
498    else
499    {//There are more y than x
500      hath = lift(var(2)^m,h)[1,1];
501      for (i = 1; i<=m;i++)
502      {
503        result = result + list(var(2));
504      }
505    }//There are more y than x
506  }//The degree is not zero
507  else
508  {//The degree is zero
509    hath = h;
510  }//The degree is zero
511  dbprint(p,"==> Done");
512  //beginning to transform x^i*y^i in theta(theta-1)...(theta-i+1)
513  list mons;
514  dbprint(p,"==> Putting the monomials in the A_0-part in a list.");
515  for(i = 1; i<=size(hath);i++)
516  {//Putting the monomials in a list
517    mons = mons+list(hath[i]);
518  }//Putting the monomials in a list
519  dbprint(p,"==> Done");
520  dbprint(p,"==> Mapping this monomials to K[theta]");
521  ring tempRing = 0,(x,y,theta),dp;
522  setring tempRing;
523  map thetamap = r,x,y;
524  list mons = thetamap(mons);
525  poly entry;
526  for (i = 1; i<=size(mons);i++)
527  {//transforming the monomials as monomials in theta
528    entry = leadcoef(mons[i]);
529    for (j = 0; j<leadexp(mons[i])[2];j++)
530    {
531      entry = entry * (theta-j);
532    }
533    mons[i] = entry;
534  }//transforming the monomials as monomials in theta
535  dbprint(p,"==> Done");
536  dbprint(p,"==> Factorize the A_0-Part in K[theta]");
537  list azeroresult = factorize(sum(mons));
538  dbprint(p,"==> Successful");
539  list azeroresult_return_form;
540  for (i = 1; i<=size(azeroresult[1]);i++)
541  {//rewrite the result of the commutative factorization
542    for (j = 1; j <= azeroresult[2][i];j++)
543    {
544      azeroresult_return_form = azeroresult_return_form + list(azeroresult[1][i]);
545    }
546  }//rewrite the result of the commutative factorization
547  dbprint(p,"==> Mapping back to A_0.");
548  setring(r);
549  map finalmap = tempRing,var(1),var(2),var(1)*var(2);
550  list tempresult = finalmap(azeroresult_return_form);
551  dbprint(p,"Successful.");
552  for (i = 1; i<=size(tempresult);i++)
553  {//factorizations of theta resp. theta +1
554    if(tempresult[i]==var(1)*var(2))
555    {
556      tempresult = insert(tempresult,var(1),i-1);
557      i++;
558      tempresult[i]=var(2);
559    }
560    if(tempresult[i]==var(2)*var(1))
561    {
562      tempresult = insert(tempresult,var(2),i-1);
563      i++;
564      tempresult[i]=var(1);
565    }
566  }//factorizations of theta resp. theta +1
567  result = tempresult+result;
568  return(result);
569}//proc homogfacFirstWeyl
570/* example */
571/* { */
572/*      "EXAMPLE:";echo=2; */
573/*      ring R = 0,(x,y),Ws(-1,1); */
574/*      def r = nc_algebra(1,1); */
575/*      setring(r); */
576/*      poly h = (x^2*y^2+1)*(x^4); */
577/*      homogfacFirstWeyl(h); */
578/* } */
579
580//==================================================
581//Computes all possible homogeneous factorizations
582static proc homogfacFirstWeyl_all(poly h)
583"USAGE: homogfacFirstWeyl_all(h); h is a homogeneous polynomial in the first Weyl algebra
584        with respect to the weight vector [-1,1]
585RETURN: list
586PURPOSE: Computes all factorizations of a homogeneous polynomial h with respect
587         to the weight vector [-1,1] in the first Weyl algebra
588THEORY: @code{homogfacFirstWeyl} returns a list with all factorization of the given,
589        homogeneous polynomial. It uses the output of homogfacFirstWeyl and permutes
590        its entries with respect to the commutation rule. Furthermore, if a
591        factor of degree zero is irreducible in K[\theta], but reducible in
592        the first Weyl algebra, the permutations of this element with the other
593        entries will also be computed.
594SEE ALSO: homogfacFirstWeyl
595"{//proc HomogfacFirstWeylAll
596  int p=printlevel-voice+2;//for dbprint
597  intvec iv11= intvec(1,1);
598  if (deg(h,iv11) <= 0 )
599  {//h is a constant
600    dbprint(p,"Given polynomial was not homogeneous");
601    return(list(list(h)));
602  }//h is a constant
603  def r = basering;
604  list one_hom_fac; //stands for one homogeneous factorization
605  int i; int j; int k;
606  intvec ivm11 = intvec(-1,1);
607  dbprint(p,"==> Calculate one homogeneous factorization using homogfacFirstWeyl");
608  //Compute again a homogeneous factorization
609  one_hom_fac = homogfacFirstWeyl(h);
610  dbprint(p,"Successful");
611  if (size(one_hom_fac) == 0)
612  {//there is no homogeneous factorization or the polynomial was not homogeneous
613    return(list());
614  }//there is no homogeneous factorization or the polynomial was not homogeneous
615  //divide list in A0-Part and a list of x's resp. y's
616  list list_not_azero = list();
617  list list_azero;
618  list k_factor;
619  int is_list_not_azero_empty = 1;
620  int is_list_azero_empty = 1;
621  k_factor = list(one_hom_fac[1]);
622  if (absValue(deg(h,ivm11))<size(one_hom_fac)-1)
623  {//There is a nontrivial A_0-part
624    list_azero = one_hom_fac[2..(size(one_hom_fac)-absValue(deg(h,ivm11)))];
625    is_list_azero_empty = 0;
626  }//There is a nontrivial A_0 part
627  dbprint(p,"==> Combine x,y to xy in the factorization again.");
628  for (i = 1; i<=size(list_azero)-1;i++)
629  {//in homogfacFirstWeyl, we factorized theta, and this will be made undone
630    if (list_azero[i] == var(1))
631    {
632      if (list_azero[i+1]==var(2))
633      {
634        list_azero[i] = var(1)*var(2);
635        list_azero = delete(list_azero,i+1);
636      }
637    }
638    if (list_azero[i] == var(2))
639    {
640      if (list_azero[i+1]==var(1))
641      {
642        list_azero[i] = var(2)*var(1);
643        list_azero = delete(list_azero,i+1);
644      }
645    }
646  }//in homogfacFirstWeyl, we factorized theta, and this will be made undone
647  dbprint(p,"==> Done");
648  if(deg(h,ivm11)!=0)
649  {//list_not_azero is not empty
650    list_not_azero =
651      one_hom_fac[(size(one_hom_fac)-absValue(deg(h,ivm11))+1)..size(one_hom_fac)];
652    is_list_not_azero_empty = 0;
653  }//list_not_azero is not empty
654  //Map list_azero in K[theta]
655  dbprint(p,"==> Map list_azero to K[theta]");
656  ring tempRing = 0,(x,y,theta), dp;
657  setring(tempRing);
658  poly entry;
659  map thetamap = r,x,y;
660  if(!is_list_not_azero_empty)
661  {//Mapping in Singular is only possible, if the list before
662    //contained at least one element of the other ring
663    list list_not_azero = thetamap(list_not_azero);
664  }//Mapping in Singular is only possible, if the list before
665  //contained at least one element of the other ring
666  if(!is_list_azero_empty)
667  {//Mapping in Singular is only possible, if the list before
668    //contained at least one element of the other ring
669    list list_azero= thetamap(list_azero);
670  }//Mapping in Singular is only possible, if the list before
671  //contained at least one element of the other ring
672  list k_factor = thetamap(k_factor);
673  list tempmons;
674  dbprint(p,"==> Done");
675  for(i = 1; i<=size(list_azero);i++)
676  {//rewrite the polynomials in A1 as polynomials in K[theta]
677    tempmons = list();
678    for (j = 1; j<=size(list_azero[i]);j++)
679    {
680      tempmons = tempmons + list(list_azero[i][j]);
681    }
682    for (j = 1 ; j<=size(tempmons);j++)
683    {
684      entry = leadcoef(tempmons[j]);
685      for (k = 0; k < leadexp(tempmons[j])[2];k++)
686      {
687        entry = entry*(theta-k);
688      }
689      tempmons[j] = entry;
690    }
691    list_azero[i] = sum(tempmons);
692  }//rewrite the polynomials in A1 as polynomials in K[theta]
693  //Compute all permutations of the A0-part
694  dbprint(p,"==> Compute all permutations of the A_0-part with the first resp. the snd. variable");
695  list result;
696  int shift_sign;
697  int shift;
698  poly shiftvar;
699  if (size(list_not_azero)!=0)
700  {//Compute all possibilities to permute the x's resp. the y's in the list
701    if (list_not_azero[1] == x)
702    {//h had a negative weighted degree
703      shift_sign = 1;
704      shiftvar = x;
705    }//h had a negative weighted degree
706    else
707    {//h had a positive weighted degree
708      shift_sign = -1;
709      shiftvar = y;
710    }//h had a positive weighted degree
711    result = permpp(list_azero + list_not_azero);
712    for (i = 1; i<= size(result); i++)
713    {//adjust the a_0-parts
714      shift = 0;
715      for (j=1; j<=size(result[i]);j++)
716      {
717        if (result[i][j]==shiftvar)
718        {
719          shift = shift + shift_sign;
720        }
721        else
722        {
723          result[i][j] = subst(result[i][j],theta,theta + shift);
724        }
725      }
726    }//adjust the a_0-parts
727  }//Compute all possibilities to permute the x's resp. the y's in the list
728  else
729  {//The result is just all the permutations of the a_0-part
730    result = permpp(list_azero);
731  }//The result is just all the permutations of the a_0 part
732  if (size(result)==0)
733  {
734    return(result);
735  }
736  dbprint(p,"==> Done");
737  dbprint(p,"==> Searching for theta resp. theta + 1 in the list and factorize them");
738  //Now we are going deeper and search for theta resp. theta + 1, substitute
739  //them by xy resp. yx and go on permuting
740  int found_theta;
741  int thetapos;
742  list leftpart;
743  list rightpart;
744  list lparts;
745  list rparts;
746  list tempadd;
747  for (i = 1; i<=size(result) ; i++)
748  {//checking every entry of result for theta or theta +1
749    found_theta = 0;
750    for(j=1;j<=size(result[i]);j++)
751    {
752      if (result[i][j]==theta)
753      {//the jth entry is theta and can be written as x*y
754        thetapos = j;
755        result[i]= insert(result[i],x,j-1);
756        j++;
757        result[i][j] = y;
758        found_theta = 1;
759        break;
760      }//the jth entry is theta and can be written as x*y
761      if(result[i][j] == theta +1)
762      {
763        thetapos = j;
764        result[i] = insert(result[i],y,j-1);
765        j++;
766        result[i][j] = x;
767        found_theta = 1;
768        break;
769      }
770    }
771    if (found_theta)
772    {//One entry was theta resp. theta +1
773      leftpart = result[i];
774      leftpart = leftpart[1..thetapos];
775      rightpart = result[i];
776      rightpart = rightpart[(thetapos+1)..size(rightpart)];
777      lparts = list(leftpart);
778      rparts = list(rightpart);
779      //first deal with the left part
780      if (leftpart[thetapos] == x)
781      {
782        shift_sign = 1;
783        shiftvar = x;
784      }
785      else
786      {
787        shift_sign = -1;
788        shiftvar = y;
789      }
790      for (j = size(leftpart); j>1;j--)
791      {//drip x resp. y
792        if (leftpart[j-1]==shiftvar)
793        {//commutative
794          j--;
795          continue;
796        }//commutative
797        if (deg(leftpart[j-1],intvec(-1,1,0))!=0)
798        {//stop here
799          break;
800        }//stop here
801        //Here, we can only have a a0- part
802        leftpart[j] = subst(leftpart[j-1],theta, theta + shift_sign);
803        leftpart[j-1] = shiftvar;
804        lparts = lparts + list(leftpart);
805      }//drip x resp. y
806      //and now deal with the right part
807      if (rightpart[1] == x)
808      {
809        shift_sign = 1;
810        shiftvar = x;
811      }
812      else
813      {
814        shift_sign = -1;
815        shiftvar = y;
816      }
817      for (j = 1 ; j < size(rightpart); j++)
818      {
819        if (rightpart[j+1] == shiftvar)
820        {
821          j++;
822          continue;
823        }
824        if (deg(rightpart[j+1],intvec(-1,1,0))!=0)
825        {
826          break;
827        }
828        rightpart[j] = subst(rightpart[j+1], theta, theta - shift_sign);
829        rightpart[j+1] = shiftvar;
830        rparts = rparts + list(rightpart);
831      }
832      //And now, we put all possibilities together
833      tempadd = list();
834      for (j = 1; j<=size(lparts); j++)
835      {
836        for (k = 1; k<=size(rparts);k++)
837        {
838          tempadd = tempadd + list(lparts[j]+rparts[k]);
839        }
840      }
841      tempadd = delete(tempadd,1); // The first entry is already in the list
842      result = result + tempadd;
843      continue; //We can may be not be done already with the ith entry
844    }//One entry was theta resp. theta +1
845  }//checking every entry of result for theta or theta +1
846  dbprint(p,"==> Done");
847  //map back to the basering
848  dbprint(p,"==> Mapping back everything to the basering");
849  setring(r);
850  map finalmap = tempRing, var(1), var(2),var(1)*var(2);
851  list result = finalmap(result);
852  for (i=1; i<=size(result);i++)
853  {//adding the K factor
854    result[i] = k_factor + result[i];
855  }//adding the k-factor
856  dbprint(p,"==> Done");
857  dbprint(p,"==> Delete double entries in the list.");
858  result = delete_dublicates_noteval(result);
859  dbprint(p,"==> Done");
860  return(result);
861}//proc HomogfacFirstWeylAll
862/* example */
863/* { */
864/*      "EXAMPLE:";echo=2; */
865/*      ring R = 0,(x,y),Ws(-1,1); */
866/*      def r = nc_algebra(1,1); */
867/*      setring(r); */
868/*      poly h = (x^2*y^2+1)*(x^4); */
869/*      homogfacFirstWeyl_all(h); */
870/* } */
871
872//==================================================*
873//Computes all permutations of a given list
874static proc perm(list l)
875{//proc perm
876  int i; int j;
877  list tempresult;
878  list result;
879  if (size(l)==0)
880  {
881    return(list());
882  }
883  if (size(l)==1)
884  {
885    return(list(l));
886  }
887  for (i = 1; i<=size(l); i++ )
888  {
889    tempresult = perm(delete(l,i));
890    for (j = 1; j<=size(tempresult);j++)
891    {
892      tempresult[j] = list(l[i])+tempresult[j];
893    }
894    result = result+tempresult;
895  }
896  return(result);
897}//proc perm
898
899//==================================================
900//computes all permutations of a given list by
901//ignoring equal entries (faster than perm)
902static proc permpp(list l)
903{//proc permpp
904  int i; int j;
905  list tempresult;
906  list l_without_double;
907  list l_without_double_pos;
908  int double_entry;
909  list result;
910  if (size(l)==0)
911  {
912    return(list());
913  }
914  if (size(l)==1)
915  {
916    return(list(l));
917  }
918  for (i = 1; i<=size(l);i++)
919  {//Filling the list with unique entries
920    double_entry = 0;
921    for (j = 1; j<=size(l_without_double);j++)
922    {
923      if (l_without_double[j] == l[i])
924      {
925        double_entry = 1;
926        break;
927      }
928    }
929    if (!double_entry)
930    {
931      l_without_double = l_without_double + list(l[i]);
932      l_without_double_pos = l_without_double_pos + list(i);
933    }
934  }//Filling the list with unique entries
935  for (i = 1; i<=size(l_without_double); i++ )
936  {
937    tempresult = permpp(delete(l,l_without_double_pos[i]));
938    for (j = 1; j<=size(tempresult);j++)
939    {
940      tempresult[j] = list(l_without_double[i])+tempresult[j];
941    }
942    result = result+tempresult;
943  }
944  return(result);
945}//proc permpp
946
947//==================================================
948//factorization of the first Weyl Algebra
949
950//The following procedure just serves the purpose to
951//transform the input into an appropriate input for
952//the procedure sfacwa, where the ring must contain the
953//variables in a certain order.
954proc facFirstWeyl(poly h)
955"USAGE: facFirstWeyl(h); h a polynomial in the first Weyl algebra
956RETURN: list
957PURPOSE: compute all factorizations of a polynomial in the first Weyl algebra
958THEORY: Implements the new algorithm by A. Heinle and V. Levandovskyy, see the thesis of A. Heinle
959ASSUME: basering is the first Weyl algebra
960NOTE: Every entry of the output list is a list with factors for one possible factorization.
961The first factor is always a constant (1, if no nontrivial constant could be excluded).
962EXAMPLE: example facFirstWeyl; shows examples
963SEE ALSO: facSubWeyl, testNCfac, facFirstShift
964"{//proc facFirstWeyl
965  //Definition of printlevel variable
966  int p = printlevel-voice+2;
967  dbprint(p,"==> Checking if the given algebra is a Weyl algebra");
968  //Redefine the ring in my standard form
969  if (!isWeyl())
970  {//Our basering is not the Weyl algebra
971    ERROR("Ring was not the first Weyl algebra");
972    return(list());
973  }//Our basering is not the Weyl algebra
974  dbprint(p,"==> Successful");
975  dbprint(p,"==> Checking, if the given ring is the first Weyl algebra");
976  if(nvars(basering)!=2)
977  {//Our basering is the Weyl algebra, but not the first
978    ERROR("==>Ring is not the first Weyl algebra");
979    return(list());
980  }//Our basering is the Weyl algebra, but not the first
981  dbprint(p,"==> Successful");
982  list result = list();
983  int i;int j; int k; int l; //counter
984  if (ringlist(basering)[6][1,2] == -1) //manual of ringlist will tell you why
985  {
986    dbprint(p,"==> positions of the variables have to be switched");
987    def r = basering;
988    ring tempRing = ringlist(r)[1][1],(x,y),Ws(-1,1); // very strange:
989    // setting Wp(-1,1) leads to SegFault; to clarify why!!!
990    def NTR = nc_algebra(1,1);
991    setring NTR ;
992    map transf = r, var(2), var(1);
993    dbprint(p,"==> Successful");
994    dbprint(p, "==> factorization of the polynomial with the routine sfacwa");
995    list resulttemp = sfacwa(transf(h));
996    dbprint(p,"==> Done");
997    setring(r);
998    map transfback = NTR, var(2),var(1);
999    result = transfback(resulttemp);
1000  }
1001  else
1002  {
1003    dbprint(p, "==> factorization of the polynomial with the routine sfacwa");
1004    result = sfacwa(h);
1005    dbprint(p,"==> Done");
1006  }
1007  dbprint(p,"==> recursively check factors for irreducibility");
1008  list recursivetemp;
1009  for(i = 1; i<=size(result);i++)
1010  {//recursively factorize factors
1011    if(size(result[i])>2)
1012    {//Nontrivial factorization
1013      for (j=2;j<=size(result[i]);j++)
1014      {//Factorize every factor
1015        recursivetemp = facFirstWeyl(result[i][j]);
1016        if(size(recursivetemp)>1)
1017        {//we have a nontrivial factorization
1018          for(k=1; k<=size(recursivetemp);k++)
1019          {//insert factorized factors
1020            if(size(recursivetemp[k])>2)
1021            {//nontrivial
1022              result = insert(result,result[i],i);
1023              for(l = size(recursivetemp[k]);l>=2;l--)
1024              {
1025                result[i+1] = insert(result[i+1],recursivetemp[k][l],j);
1026              }
1027              result[i+1] = delete(result[i+1],j);
1028            }//nontrivial
1029          }//insert factorized factors
1030        }//we have a nontrivial factorization
1031      }//Factorize every factor
1032    }//Nontrivial factorization
1033  }//recursively factorize factors
1034  dbprint(p,"==> Done");
1035  if (size(result)==0)
1036  {//only the trivial factorization could be found
1037    result = list(list(1,h));
1038  }//only the trivial factorization could be found
1039  //now, refine the possible redundant list
1040  return( delete_dublicates_noteval(result) );
1041}//proc facFirstWeyl
1042example
1043{
1044  "EXAMPLE:";echo=2;
1045  ring R = 0,(x,y),dp;
1046  def r = nc_algebra(1,1);
1047  setring(r);
1048  poly h = (x^2*y^2+x)*(x+1);
1049  facFirstWeyl(h);
1050}
1051
1052//This is the main program
1053static proc sfacwa(poly h)
1054"USAGE: sfacwa(h); h is a polynomial in the first Weyl algebra
1055RETURN: list
1056PURPOSE: Computes a factorization of a polynomial h in the first Weyl algebra
1057THEORY: @code{sfacwa} returns a list with some factorizations of the given
1058        polynomial. The possibilities of the factorization of the highest
1059        homogeneous part and those of the lowest will be merged. If during this
1060        procedure a factorization of the polynomial occurs, it will be added to
1061        the output list. For a more detailed description visit
1062        @url{http://www.math.rwth-aachen.de/\~Albert.Heinle}
1063SEE ALSO: homogfacFirstWeyl_all, homogfacFirstWeyl
1064"{//proc sfacwa
1065  int p=printlevel-voice+2; // for dbprint
1066  intvec ivm11 = intvec(-1,1);
1067  intvec iv11 = intvec(1,1);
1068  intvec iv10 = intvec(1,0);
1069  intvec iv01 = intvec(0,1);
1070  intvec iv1m1 = intvec(1,-1);
1071  if(homogwithorder(h,ivm11))
1072  {
1073    dbprint(p,"==> Given polynomial is -1,1 homogeneous. Start homog. fac. and ret. its result");
1074    return(homogfacFirstWeyl_all(h));
1075  }
1076  def r = basering;
1077  map invo = basering,-var(1),var(2);
1078  int i; int j; int k;
1079  dbprint(p,"==> Computing the degree-limits of the factorization");
1080  intvec limits = deg(h,iv11) ,deg(h,iv10),deg(h,iv01);
1081  def prod;
1082  //end finding the limits
1083  dbprint(p,"==> Computing the maximal and the minimal homogeneous part of the give polynomial");
1084  poly maxh = jet(h,deg(h,ivm11),ivm11)-jet(h,deg(h,ivm11)-1,ivm11);
1085  poly minh = jet(h,deg(h,iv1m1),iv1m1)-jet(h,deg(h,iv1m1)-1,iv1m1);
1086  list result;
1087  list temp;
1088  list homogtemp;
1089  def invhath;
1090  def invideal;
1091  list M; list hatM;
1092  dbprint(p,"==> Factorize the maximal and the minimal homog. part of the given polynomial");
1093  list f1 = homogfacFirstWeyl_all(maxh);
1094  list f2 = homogfacFirstWeyl_all(minh);
1095  int is_equal;
1096  poly hath;
1097  dbprint(p,"==> Merging the factorizations");
1098  for (i = 1; i<=size(f1);i++)
1099  {//Merge all combinations
1100    for (j = 1; j<=size(f2); j++)
1101    {
1102      M = M + mergence(f1[i],f2[j],limits);
1103    }
1104  }//Merge all combinations
1105  dbprint(p,"==> Filtering invalid combinations");
1106  for (i = 1 ; i<= size(M); i++)
1107  {//filter valid combinations
1108    if (product(M[i]) == h)
1109    {//We have one factorization
1110      result = result + list(M[i]);
1111      dbprint(p,"Result list updated:");
1112      dbprint(p,result);
1113      M = delete(M,i);
1114      continue;
1115    }//We have one factorization
1116    else
1117    {
1118      if (deg(h,ivm11)<=deg(h-product(M[i]),ivm11))
1119      {
1120        M = delete(M,i);
1121        continue;
1122      }
1123      if (deg(h,iv1m1)<=deg(h-product(M[i]),iv1m1))
1124      {
1125        M = delete(M,i);
1126        continue;
1127      }
1128    }
1129  }//filter valid combinations
1130  dbprint(p,"==> Deleting doublicates in the resulting list");
1131  M = delete_dublicates_eval(M);
1132  dbprint(p,"==> Iterating over all possible Combinations");
1133  while(size(M)>0)
1134  {//work on the elements of M
1135    hatM = list();
1136    for(i = 1; i<=size(M); i++)
1137    {//iterate over all elements of M
1138      hath = h-product(M[i]);
1139      temp = list();
1140      //First check for common inhomogeneous factors between hath and h
1141      invhath = involution(hath,invo);
1142      invideal = std(involution(ideal(M[i][1]),invo));
1143      if (involution(NF(invhath,invideal) ,invo)==0)
1144      {//hath and h have a common factor on the left
1145        j = 1;
1146        f1 = M[i];
1147        if (j+1<=size(f1))
1148        {//Checking for more than one common factor
1149          invideal = std(involution(ideal(product(f1[1..(j+1)])),invo));
1150          while(involution(NF(invhath,invideal),invo)==0)
1151          {
1152            if (j+1<size(f1))
1153            {
1154              j++;
1155            }
1156            else
1157            {
1158              break;
1159            }
1160          }
1161        }//Checking for more than one common factor
1162        invideal = lift(involution(product(f1[1..j]),invo),invhath);
1163        f2 = list(f1[1..j])+list(involution(invideal[1,1],invo));
1164        temp = temp + merge_cf(f2,f1,limits);
1165      }//hath and h have a common factor on the left
1166      if (reduce(hath, std(ideal(M[i][size(M[i])])))==0)
1167      {//hath and h have a common factor on the right
1168        j = size(M[i]);
1169        f1 = M[i];
1170        if (j-1>0)
1171        {//Checking for more than one factor
1172          while(reduce(hath,std(ideal(product(f1[(j-1)..size(f1)]))))==0)
1173          {
1174            if (j-1>1)
1175            {
1176              j--;
1177            }
1178            else
1179            {
1180              break;
1181            }
1182          }
1183        }//Checking for more than one factor
1184        f2 = list(lift(product(f1[j..size(f1)]),hath)[1,1])+list(f1[j..size(f1)]);
1185        temp = temp + merge_cf(f2,M[i],limits);
1186      }//hath and h have a common factor on the right
1187      //and now the homogeneous
1188      maxh = jet(hath,deg(hath,ivm11),ivm11)-jet(hath,deg(hath,ivm11)-1,ivm11);
1189      minh = jet(hath,deg(hath,iv1m1),iv1m1)-jet(hath,deg(hath,iv1m1)-1,iv1m1);
1190      f1 = homogfacFirstWeyl_all(maxh);
1191      f2 = homogfacFirstWeyl_all(minh);
1192      for (j = 1; j<=size(f1);j++)
1193      {
1194        for (k=1; k<=size(f2);k++)
1195        {
1196          homogtemp = mergence(f1[j],f2[k],limits);
1197        }
1198      }
1199      for (j = 1; j<= size(homogtemp); j++)
1200      {
1201        temp = temp + mergence(homogtemp[j],M[i],limits);
1202      }
1203      for (j = 1; j<=size(temp); j++)
1204      {//filtering invalid entries in temp
1205        if(product(temp[j])==h)
1206        {//This is already a result
1207          result = result + list(temp[j]);
1208          temp = delete(temp,j);
1209          continue;
1210        }//This is already a result
1211        if (deg(hath,ivm11)<=deg(hath-product(temp[j]),ivm11))
1212        {
1213          temp = delete(temp,j);
1214          continue;
1215        }
1216      }//filtering invalid entries in temp
1217      hatM = hatM + temp;
1218    }//iterate over all elements of M
1219    M = hatM;
1220    for (i = 1; i<=size(M);i++)
1221    {//checking for complete factorizations
1222      if (h == product(M[i]))
1223      {
1224        result = result + list(M[i]);
1225  dbprint(p,"Result list updated:");
1226        dbprint(p,result);
1227        M = delete(M,i);
1228        continue;
1229      }
1230    }//checking for complete factorizations
1231    M = delete_dublicates_eval(M);
1232  }//work on the elements of M
1233  //In the case, that there is none, write a constant factor before the factor of interest.
1234  dbprint(p,"==> Done");
1235  for (i = 1 ; i<=size(result);i++)
1236  {//add a constant factor
1237    if (deg(result[i][1],iv11)!=0)
1238    {
1239      result[i] = insert(result[i],1);
1240    }
1241  }//add a constant factor
1242  dbprint(p,"==> Deleting doublicates in the output list");
1243  result = delete_dublicates_noteval(result);
1244  return(result);
1245}//proc sfacwa
1246
1247
1248//==================================================
1249/*Singular has no way implemented to test polynomials
1250  for homogenity with respect to a weight vector.
1251  The following procedure does exactly this*/
1252static proc homogwithorder(poly h, intvec weights)
1253{//proc homogwithorder
1254  if(size(weights) != nvars(basering))
1255  {//The user does not know how many variables the current ring has
1256    return(0);
1257  }//The user does not know how many variables the current ring has
1258  int i;
1259  int dofp = deg(h,weights); //degree of polynomial
1260  for (i = 1; i<=size(h);i++)
1261  {
1262    if (deg(h[i],weights)!=dofp)
1263    {
1264      return(0);
1265    }
1266  }
1267  return(1);
1268}//proc homogwithorder
1269
1270//==================================================
1271//Testfac: Given a list with different factorizations of
1272// one polynomial, the following procedure checks
1273// whether they all refer to the same polynomial.
1274// If they do, the output will be a list, that contains
1275// the product of each factorization. If not, the empty
1276// list will be returned.
1277// If the optional argument # is given (i.e. the polynomial
1278// which is factorized by the elements of the given list),
1279// then we look, if the entries are factorizations of p
1280// and if not, a list with the products subtracted by p
1281// will be returned
1282proc testNCfac(list l, list #)
1283"USAGE: testNCfac(l[,p,b]); l is a list, p is an optional poly, b is 1 or 0
1284RETURN: Case 1: No optional argument. In this case the output is 1, if the
1285                entries in the given list represent the same polynomial or 0
1286                otherwise.
1287        Case 2: One optional argument p is given. In this case it returns 1,
1288                if all the entries in l are factorizations of p, otherwise 0.
1289        Case 3: Second optional b is given. In this case a list is returned
1290                containing the difference between the product of each entry in
1291                l and p.
1292ASSUME: basering is the first Weyl algebra, the entries of l are polynomials
1293PURPOSE: Checks whether a list of factorizations contains factorizations of
1294         the same element in the first Weyl algebra
1295THEORY: @code{testNCfac} multiplies out each factorization and checks whether
1296        each factorization was a factorization of the same element.
1297@* - if there is only a list given, the output will be 0, if it
1298     does not contain factorizations of the same element. Otherwise the output
1299     will be 1.
1300@* - if there is a polynomial in the second argument, then the procedure checks
1301     whether the given list contains factorizations of this polynomial. If it
1302     does, then the output depends on the third argument. If it is not given,
1303     the procedure will check whether the factorizations in the list
1304     l are associated to this polynomial and return either 1 or 0, respectively.
1305     If the third argument is given, the output will be a list with
1306     the length of the given one and in each entry is the product of one
1307     entry in l subtracted by the polynomial.
1308EXAMPLE: example testNCfac; shows examples
1309SEE ALSO: facFirstWeyl, facSubWeyl, facFirstShift
1310"{//proc testfac
1311  int p = printlevel - voice + 2;
1312  dbprint(p,"==> Checking the input");
1313  if (size(l)==0)
1314  {//The empty list is given
1315    dbprint(p,"==> Given list was empty");
1316    return(list());
1317  }//The empty list is given
1318  if (size(#)>2)
1319  {//We want max. two optional arguments
1320    dbprint(p,"==> More than two optional arguments");
1321    return(list());
1322  }//We want max. two optional arguments
1323  dbprint(p,"==> Done");
1324  list result;
1325  int i; int j;
1326  if (size(#)==0)
1327  {//No optional argument is given
1328    dbprint(p,"==> No optional arguments");
1329    int valid = 1;
1330    for (i = size(l);i>=1;i--)
1331    {//iterate over the elements of the given list
1332      if (size(result)>0)
1333      {
1334        if (product(l[i])!=result[size(l)-i])
1335        {
1336          valid = 0;
1337          break;
1338        }
1339      }
1340      result = insert(result, product(l[i]));
1341    }//iterate over the elements of the given list
1342    return(valid);
1343  }//No optional argument is given
1344  else
1345  {
1346    dbprint(p,"==> Optional arguments are given.");
1347    int valid = 1;
1348    for (i = size(l);i>=1;i--)
1349    {//iterate over the elements of the given list
1350      if (product(l[i])!=#[1])
1351      {
1352        valid = 0;
1353      }
1354      result = insert(result, product(l[i])-#[1]);
1355    }//iterate over the elements of the given list
1356    if(size(#)==2)
1357    {
1358      dbprint(p,"==> A third argument is given. Output is a list now.");
1359      return(result);
1360    }
1361    return(valid);
1362  }
1363}//proc testfac
1364example
1365{
1366  "EXAMPLE:";echo=2;
1367  ring r = 0,(x,y),dp;
1368  def R = nc_algebra(1,1);
1369  setring R;
1370  poly h = (x^2*y^2+1)*(x^2);
1371  def t1 = facFirstWeyl(h);
1372  //fist a correct list
1373  testNCfac(t1);
1374  //now a correct list with the factorized polynomial
1375  testNCfac(t1,h);
1376  //now we put in an incorrect list without a polynomial
1377  t1[3][3] = y;
1378  testNCfac(t1);
1379  // take h as additional input
1380  testNCfac(t1,h);
1381  // take h as additional input and output list of differences
1382  testNCfac(t1,h,1);
1383}
1384//==================================================
1385//Procedure facSubWeyl:
1386//This procedure serves the purpose to compute a
1387//factorization of a given polynomial in a ring, whose subring
1388//is the first Weyl algebra. The polynomial must only contain
1389//the two arguments, which are also given by the user.
1390
1391proc facSubWeyl(poly h, X, D)
1392"USAGE:  facSubWeyl(h,x,y); h, X, D polynomials
1393RETURN: list
1394ASSUME: X and D are variables of a basering, which satisfy DX = XD +1.
1395@* That is,  they generate the copy of the first Weyl algebra in a basering.
1396@* Moreover, h is a polynomial in X and D only.
1397PURPOSE: compute factorizations of the polynomial, which depends on X and D.
1398EXAMPLE: example facSubWeyl; shows examples
1399SEE ALSO: facFirstWeyl, testNCfac, facFirstShift
1400"{
1401  int p = printlevel - voice + 2;
1402  dbprint(p,"==> Start initial Checks of the input.");
1403    // basering can be anything having a Weyl algebra as subalgebra
1404  def @r = basering;
1405  //We begin to check the input for assumptions
1406  // which are: X,D are vars of the basering,
1407  if ( (isVar(X)!=1) || (isVar(D)!=1) || (size(X)>1) || (size(D)>1) ||
1408       (leadcoef(X) != number(1)) || (leadcoef(D) != number(1)) )
1409  {
1410    ERROR("expected pure variables as generators of a subalgebra");
1411  }
1412  // Weyl algebra:
1413  poly w = D*X-X*D-1; // [D,X]=1
1414  poly u = D*X-X*D+1; // [X,D]=1
1415  if (u*w!=0)
1416  {
1417    // that is no combination gives Weyl
1418    ERROR("2nd and 3rd argument do not generate a Weyl algebra");
1419  }
1420  // one of two is correct
1421  int isReverted = 0; // Reverted Weyl if dx=xd-1 holds
1422  if (u==0)
1423  {
1424    isReverted = 1;
1425  }
1426  // else: do nothing
1427  // DONE with assumptions, Input successfully checked
1428  dbprint(p,"==> Successful");
1429  intvec lexpofX = leadexp(X);
1430  intvec lexpofD = leadexp(D);
1431  int varnumX=1;
1432  int varnumD=1;
1433  while(lexpofX[varnumX] != 1)
1434  {
1435    varnumX++;
1436  }
1437  while(lexpofD[varnumD] != 1)
1438  {
1439    varnumD++;
1440  }
1441  /* VL : to add printlevel stuff */
1442  dbprint(p,"==> Change positions of the two variables in the list, if needed");
1443  if (isReverted)
1444  {
1445    ring firstweyl = 0,(var(varnumD),var(varnumX)),dp;
1446    def Firstweyl = nc_algebra(1,1);
1447    setring Firstweyl;
1448    ideal M = 0:nvars(@r);
1449    M[varnumX]=var(2);
1450    M[varnumD]=var(1);
1451    map Q = @r,M;
1452    poly h= Q(h);
1453  }
1454  else
1455  { // that is unReverted
1456    ring firstweyl = 0,(var(varnumX),var(varnumD)),dp;
1457    def Firstweyl = nc_algebra(1,1);
1458    setring Firstweyl;
1459    poly h= imap(@r,h);
1460  }
1461  dbprint(p,"==> Done!");
1462  list result = facFirstWeyl(h);
1463  setring @r;
1464  list result;
1465  if (isReverted)
1466  {
1467    // map swap back
1468    ideal M; M[1] = var(varnumD); M[2] = var(varnumX);
1469    map S = Firstweyl, M;
1470    result = S(result);
1471  }
1472  else
1473  {
1474    // that is unReverted
1475    result = imap(Firstweyl,result);
1476  }
1477  return(result);
1478}//proc facSubWeyl
1479example
1480{
1481  "EXAMPLE:";echo=2;
1482  ring r = 0,(x,y,z),dp;
1483  matrix D[3][3]; D[1,3]=-1;
1484  def R = nc_algebra(1,D); // x,z generate Weyl subalgebra
1485  setring R;
1486  poly h = (x^2*z^2+x)*x;
1487  list fact1 = facSubWeyl(h,x,z);
1488  // compare with facFirstWeyl:
1489  ring s = 0,(z,x),dp;
1490  def S = nc_algebra(1,1); setring S;
1491  poly h = (x^2*z^2+x)*x;
1492  list fact2 = facFirstWeyl(h);
1493  map F = R,x,0,z;
1494  list fact1 = F(fact1); // it is identical to list fact2
1495  testNCfac(fact1); // check the correctness again
1496}
1497//==================================================
1498
1499//==================================================
1500//************From here: Shift-Algebra**************
1501//==================================================
1502//==================================================*
1503//one factorization of a homogeneous polynomial
1504//in the first Shift Algebra
1505static proc homogfacFirstShift(poly h)
1506{//proc homogfacFirstShift
1507  int p=printlevel-voice+2; //for dbprint
1508  def r = basering;
1509  poly hath;
1510  intvec iv01 = intvec(0,1);
1511  int i; int j;
1512  if (!homogwithorder(h,iv01))
1513  {//The given polynomial is not homogeneous
1514    ERROR("The given polynomial is not homogeneous.");
1515    return(list());
1516  }//The given polynomial is not homogeneous
1517  if (h==0)
1518  {
1519    return(list(0));
1520  }
1521  list result;
1522  int m = deg(h,iv01);
1523  dbprint(p,"==> exclude the homogeneous part of deg. 0");
1524  if (m>0)
1525  {//The degree is not zero
1526    hath = lift(var(2)^m,h)[1,1];
1527    for (i = 1; i<=m;i++)
1528    {
1529      result = result + list(var(2));
1530    }
1531  }//The degree is not zero
1532  else
1533  {//The degree is zero
1534    hath = h;
1535  }//The degree is zero
1536  ring tempRing = 0,(x),dp;
1537  setring tempRing;
1538  map thetamap = r,x,1;
1539  poly hath = thetamap(hath);
1540  dbprint(p,"==> Factorize it using commutative factorization.");
1541  list azeroresult = factorize(hath);
1542  list azeroresult_return_form;
1543  for (i = 1; i<=size(azeroresult[1]);i++)
1544  {//rewrite the result of the commutative factorization
1545    for (j = 1; j <= azeroresult[2][i];j++)
1546    {
1547      azeroresult_return_form = azeroresult_return_form + list(azeroresult[1][i]);
1548    }
1549  }//rewrite the result of the commutative factorization
1550  setring(r);
1551  map finalmap = tempRing,var(1);
1552  list tempresult = finalmap(azeroresult_return_form);
1553  result = tempresult+result;
1554  return(result);
1555}//proc homogfacFirstShift
1556
1557//==================================================
1558//Computes all possible homogeneous factorizations
1559static proc homogfacFirstShift_all(poly h)
1560{//proc HomogfacFirstShiftAll
1561  int p=printlevel-voice+2; //for dbprint
1562  intvec iv11 = intvec(1,1);
1563  if (deg(h,iv11) <= 0 )
1564  {//h is a constant
1565    return(list(list(h)));
1566  }//h is a constant
1567  def r = basering;
1568  list one_hom_fac; //stands for one homogeneous factorization
1569  int i; int j; int k;
1570  int shiftcounter;
1571  //Compute again a homogeneous factorization
1572  dbprint(p,"==> Computing one homog. factorization of the polynomial");
1573  one_hom_fac = homogfacFirstShift(h);
1574  one_hom_fac = delete(one_hom_fac,1);
1575  if (size(one_hom_fac) == 0)
1576  {//there is no homogeneous factorization or the polynomial was not homogeneous
1577    return(list());
1578  }//there is no homogeneous factorization or the polynomial was not homogeneous
1579  dbprint(p,"==> Permuting the 0-homogeneous part with the s");
1580  list result = permpp(one_hom_fac);
1581  for (i = 1; i<=size(result);i++)
1582  {
1583    shiftcounter = 0;
1584    for (j = 1; j<=size(result[i]); j++)
1585    {
1586      if (result[i][j]==var(2))
1587      {
1588        shiftcounter++;
1589      }
1590      else
1591      {
1592        result[i][j] = subst(result[i][j], var(1), var(1)-shiftcounter);
1593      }
1594    }
1595    result[i] = insert(result[i],1);
1596  }
1597  dbprint(p,"==> Deleting double entries in the resulting list");
1598  result = delete_dublicates_noteval(result);
1599  return(result);
1600}//proc HomogfacFirstShiftAll
1601
1602//==================================================
1603//factorization of the first Shift Algebra
1604proc facFirstShift(poly h)
1605"USAGE: facFirstShift(h); h a polynomial in the first shift algebra
1606RETURN: list
1607PURPOSE: compute all factorizations of a polynomial in the first shift algebra
1608THEORY: Implements the new algorithm by A. Heinle and V. Levandovskyy, see the thesis of A. Heinle
1609ASSUME: basering is the first shift algebra
1610NOTE: Every entry of the output list is a list with factors for one possible factorization.
1611EXAMPLE: example facFirstShift; shows examples
1612SEE ALSO: testNCfac, facFirstWeyl, facSubWeyl
1613"{//facFirstShift
1614  int p = printlevel - voice + 2;
1615  dbprint(p,"==> Checking the input.");
1616  if(nvars(basering)!=2)
1617  {//Our basering is the Shift algebra, but not the first
1618    ERROR("Basering is not the first shift algebra");
1619    return(list());
1620  }//Our basering is the Shift algebra, but not the first
1621  def r = basering;
1622  setring r;
1623  list LR = ringlist(r);
1624  number @n = leadcoef(LR[5][1,2]);
1625  poly @p = LR[6][1,2];
1626  if  ( @n!=number(1) )
1627  {
1628    ERROR("Basering is not the first shift algebra");
1629    return(list());
1630  }
1631  dbprint(p,"==> Done");
1632  list result = list();
1633  int i;int j; int k; int l; //counter
1634  // create a ring with the ordering which makes shift algebra
1635  // graded
1636  // def r = basering; // done before
1637  ring tempRing = LR[1][1],(x,s),(a(0,1),Dp);
1638  def tempRingnc = nc_algebra(1,s);
1639  setring r;
1640  // information on relations
1641  if (@p == -var(1)) // reverted shift algebra
1642  {
1643    dbprint(p,"==> Reverted shift algebra. Swaping variables in Ringlist");
1644    setring(tempRingnc);
1645    map transf = r, var(2), var(1);
1646    setring(r);
1647    map transfback = tempRingnc, var(2),var(1);
1648    //    result = transfback(resulttemp);
1649  }
1650  else
1651  {
1652    if ( @p == var(2)) // usual shift algebra
1653    {
1654      setring(tempRingnc);
1655      map transf = r, var(1), var(2);
1656      //    result = facshift(h);
1657      setring(r);
1658      map transfback = tempRingnc, var(1),var(2);
1659    }
1660    else
1661    {
1662      ERROR("Basering is not the first shift algebra");
1663      return(list());
1664    }
1665  }
1666  // main calls
1667  setring(tempRingnc);
1668  dbprint(p,"==> Factorize the given polynomial with the subroutine facshift");
1669  list resulttemp = facshift(transf(h));
1670  dbprint(p,"==> Successful");
1671  setring(r);
1672  result = transfback(resulttemp);
1673  dbprint(p,"==> Recursively check the found factors for reducibility.");
1674  list recursivetemp;
1675  for(i = 1; i<=size(result);i++)
1676  {//recursively factorize factors
1677    if(size(result[i])>2)
1678    {//Nontrivial factorization
1679      for (j=2;j<=size(result[i]);j++)
1680      {//Factorize every factor
1681        recursivetemp = facFirstShift(result[i][j]);
1682        if(size(recursivetemp)>1)
1683        {//we have a nontrivial factorization
1684          for(k=1; k<=size(recursivetemp);k++)
1685          {//insert factorized factors
1686            if(size(recursivetemp[k])>2)
1687            {//nontrivial
1688              result = insert(result,result[i],i);
1689              for(l = size(recursivetemp[k]);l>=2;l--)
1690              {
1691                result[i+1] = insert(result[i+1],recursivetemp[k][l],j);
1692              }
1693              result[i+1] = delete(result[i+1],j);
1694            }//nontrivial
1695          }//insert factorized factors
1696        }//we have a nontrivial factorization
1697      }//Factorize every factor
1698    }//Nontrivial factorization
1699  }//recursively factorize factors
1700  //now, refine the possible redundant list
1701  dbprint(p,"==> Done");
1702  return( delete_dublicates_noteval(result) );
1703}//facFirstShift
1704example
1705{
1706  "EXAMPLE:";echo=2;
1707  ring R = 0,(x,s),dp;
1708  def r = nc_algebra(1,s);
1709  setring(r);
1710  poly h = (s^2*x+x)*s;
1711  facFirstShift(h);
1712}
1713
1714static proc facshift(poly h)
1715"USAGE: facshift(h); h is a polynomial in the first Shift algebra
1716RETURN: list
1717PURPOSE: Computes a factorization of a polynomial h in the first Shift algebra
1718THEORY: @code{facshift} returns a list with some factorizations of the given
1719        polynomial. The possibilities of the factorization of the highest
1720        homogeneous part and those of the lowest will be merged. If during this
1721        procedure a factorization of the polynomial occurs, it will be added to
1722        the output list. For a more detailled description visit
1723        @url{http://www.math.rwth-aachen.de/\~Albert.Heinle}
1724SEE ALSO: homogfacFirstShift_all, homogfacFirstShift
1725"{//proc facshift
1726  int p=printlevel-voice+2; // for dbprint
1727  intvec iv01 = intvec(0,1);
1728  intvec iv11 = intvec(1,1);
1729  intvec iv10 = intvec(1,0);
1730  intvec iv0m1 = intvec(0,-1);
1731  if(homogwithorder(h,iv01))
1732  {
1733    dbprint(p,"==> Given polynomial was 1,0-homogeneous. Calling subroutine for homog. polys.");
1734    return(homogfacFirstShift_all(h));
1735  }
1736  def r = basering;
1737  map invo = basering,-var(1),-var(2);
1738  int i; int j; int k;
1739  intvec limits = deg(h,iv11) ,deg(h,iv10),deg(h,iv01);
1740  def prod;
1741  //end finding the limits
1742  poly maxh = jet(h,deg(h,iv01),iv01)-jet(h,deg(h,iv01)-1,iv01);
1743  poly minh = jet(h,deg(h,iv0m1),iv0m1)-jet(h,deg(h,iv0m1)-1,iv0m1);
1744  list result;
1745  list temp;
1746  list homogtemp;
1747  list M; list hatM;
1748  def invhath;
1749  def invideal;
1750  dbprint(p,"==> Factorizing the highest and the lowest homogeneous part");
1751  list f1 = homogfacFirstShift_all(maxh);
1752  list f2 = homogfacFirstShift_all(minh);
1753  int is_equal;
1754  poly hath;
1755  dbprint(p,"==> Merging their factors");
1756  for (i = 1; i<=size(f1);i++)
1757  {//Merge all combinations
1758    for (j = 1; j<=size(f2); j++)
1759    {
1760      M = M + mergence(f1[i],f2[j],limits);
1761    }
1762  }//Merge all combinations
1763  dbprint(p,"==> Filtering invalid combinations");
1764  for (i = 1 ; i<= size(M); i++)
1765  {//filter valid combinations
1766    if (product(M[i]) == h)
1767    {//We have one factorization
1768      result = result + list(M[i]);
1769      dbprint(p,"Result list updated:");
1770      dbprint(p,result);
1771      M = delete(M,i);
1772      continue;
1773    }//We have one factorization
1774    else
1775    {
1776      if (deg(h,iv01)<=deg(h-product(M[i]),iv01))
1777      {
1778        M = delete(M,i);
1779        continue;
1780      }
1781      if (deg(h,iv0m1)<=deg(h-product(M[i]),iv0m1))
1782      {
1783        M = delete(M,i);
1784        continue;
1785      }
1786    }
1787  }//filter valid combinations
1788  dbprint(p,"==> Iterating over all elements in M");
1789  M = delete_dublicates_eval(M);
1790  while(size(M)>0)
1791  {//work on the elements of M
1792    hatM = list();
1793    for(i = 1; i<=size(M); i++)
1794    {//iterate over all elements of M
1795      hath = h-product(M[i]);
1796      temp = list();
1797      //First check for common inhomogeneous factors between hath and h
1798      invhath = involution(hath,invo);
1799      invideal = std(involution(ideal(M[i][1]),invo));
1800      if (involution(NF(invhath, invideal ),invo)==0)
1801      {//hath and h have a common factor on the left
1802        j = 1;
1803        f1 = M[i];
1804        if (j+1<=size(f1))
1805        {//Checking for more than one common factor
1806          invideal = std(involution(ideal(product(f1[1..(j+1)])),invo));
1807          while(involution(NF(invhath,invideal),invo)==0)
1808          {
1809            if (j+1<size(f1))
1810            {
1811              j++;
1812            }
1813            else
1814            {
1815              break;
1816            }
1817          }
1818        }//Checking for more than one common factor
1819        if (deg(product(f1[1..j]),iv11)!=0)
1820        {
1821          invideal = lift(involution(product(f1[1..j]),invo),invhath);
1822          f2 = list(f1[1..j])+list(involution(invideal[1,1],invo));
1823        }
1824        else
1825        {
1826          invideal = lift(product(f1[1..j]),involution(hath,invo));
1827          f2 = list(f1[1..j])+list(involution(invideal[1,1],invo));
1828        }
1829        temp = temp + merge_cf(f2,f1,limits);
1830      }//hath and h have a common factor on the left
1831      if (reduce(hath, std(ideal(M[i][size(M[i])])))==0)
1832      {//hath and h have a common factor on the right
1833        j = size(M[i]);
1834        f1 = M[i];
1835        if (j-1>0)
1836        {//Checking for more than one factor
1837          while(reduce(hath,std(ideal(product(f1[(j-1)..size(f1)]))))==0)
1838          {
1839            if (j-1>1)
1840            {
1841              j--;
1842            }
1843            else
1844            {
1845              break;
1846            }
1847          }
1848        }//Checking for more than one factor
1849        f2 = list(lift(product(f1[j..size(f1)]),hath)[1,1])+list(f1[j..size(f1)]);
1850        temp = temp + merge_cf(f2,M[i],limits);
1851      }//hath and h have a common factor on the right
1852      //and now the homogeneous
1853      maxh = jet(hath,deg(hath,iv01),iv01)-jet(hath,deg(hath,iv01)-1,iv01);
1854      minh = jet(hath,deg(hath,iv0m1),iv0m1)-jet(hath,deg(hath,iv0m1)-1,iv0m1);
1855      f1 = homogfacFirstShift_all(maxh);
1856      f2 = homogfacFirstShift_all(minh);
1857      for (j = 1; j<=size(f1);j++)
1858      {
1859        for (k=1; k<=size(f2);k++)
1860        {
1861          homogtemp = mergence(f1[j],f2[k],limits);
1862        }
1863      }
1864      for (j = 1; j<= size(homogtemp); j++)
1865      {
1866        temp = temp + mergence(homogtemp[j],M[i],limits);
1867      }
1868      for (j = 1; j<=size(temp); j++)
1869      {//filtering invalid entries in temp
1870        if(product(temp[j])==h)
1871        {//This is already a result
1872          result = result + list(temp[j]);
1873          temp = delete(temp,j);
1874          continue;
1875        }//This is already a result
1876        if (deg(hath,iv01)<=deg(hath-product(temp[j]),iv01))
1877        {
1878          temp = delete(temp,j);
1879          continue;
1880        }
1881      }//filtering invalid entries in temp
1882      hatM = hatM + temp;
1883    }//iterate over all elements of M
1884    M = hatM;
1885    for (i = 1; i<=size(M);i++)
1886    {//checking for complete factorizations
1887      if (h == product(M[i]))
1888      {
1889        result = result + list(M[i]);
1890        dbprint(p,"Result list updated:");
1891        dbprint(p,result);
1892        M = delete(M,i);
1893        continue;
1894      }
1895    }//checking for complete factorizations
1896    M = delete_dublicates_eval(M);
1897  }//work on the elements of M
1898  //In the case, that there is none, write a constant factor before the factor of interest.
1899  for (i = 1 ; i<=size(result);i++)
1900  {//add a constant factor
1901    if (deg(result[i][1],iv11)!=0)
1902    {
1903      result[i] = insert(result[i],1);
1904    }
1905  }//add a constant factor
1906  dbprint(p,"==> Deleting double entries in the resulting list.");
1907  result = delete_dublicates_noteval(result);
1908  if (size(result)==0)
1909  {//only the trivial factorization could be found
1910    result = list(list(1,h));
1911  }//only the trivial factorization could be found
1912  dbprint(p,"==> done");
1913  return(result);
1914}//proc facshift
1915
1916static proc refineFactList(list L)
1917{
1918  // assume: list L is an output of factorization proc
1919  // doing: remove doubled entries
1920  int s = size(L); int sm;
1921  int i,j,k,cnt;
1922  list M, U, A, B;
1923  A = L;
1924  k = 0;
1925  cnt  = 1;
1926  for (i=1; i<=s; i++)
1927  {
1928    if (size(A[i]) != 0)
1929    {
1930      M = A[i];
1931      //      "probing with"; M; i;
1932      B[cnt] = M; cnt++;
1933      for (j=i+1; j<=s; j++)
1934      {
1935        if ( isEqualList(M,A[j]) )
1936        {
1937          k++;
1938        // U consists of intvecs with equal pairs
1939          U[k] = intvec(i,j);
1940          A[j] = 0;
1941        }
1942      }
1943    }
1944  }
1945  kill A,U,M;
1946  return(B);
1947}
1948example
1949{
1950  "EXAMPLE:";echo=2;
1951  ring R = 0,(x,s),dp;
1952  def r = nc_algebra(1,1);
1953  setring(r);
1954  list l,m;
1955  l = list(1,s2+1,x,s,x+s);
1956  m = l,list(1,s,x,s,x),l;
1957  refineFactList(m);
1958}
1959
1960static proc isEqualList(list L, list M)
1961{
1962  // int boolean: 1=yes, 0 =no : test whether two lists are identical
1963  int s = size(L);
1964  if (size(M)!=s) { return(0); }
1965  int j=1;
1966  while ( (L[j]==M[j]) && (j<s) )
1967  {
1968    j++;
1969  }
1970  if (L[j]==M[j])
1971  {
1972    return(1);
1973  }
1974  return(0);
1975}
1976example
1977{
1978  "EXAMPLE:";echo=2;
1979  ring R = 0,(x,s),dp;
1980  def r = nc_algebra(1,1);
1981  setring(r);
1982  list l,m;
1983  l = list(1,s2+1,x,s,x+s);
1984  m = l;
1985  isEqualList(m,l);
1986}
1987
1988
1989//////////////////////////////////////////////////
1990// Q-WEYL-SECTION
1991//////////////////////////////////////////////////
1992
1993//==================================================
1994//A function to get the i'th triangular number
1995static proc triangNum(int n)
1996{
1997  if (n == 0)
1998  {
1999    return(0);
2000  }
2001  return (n*(n+1) div 2);
2002}
2003
2004//==================================================*
2005//one factorization of a homogeneous polynomial
2006//in the first Q Weyl Algebra
2007proc homogfacFirstQWeyl(poly h)
2008"USAGE: homogfacFirstQWeyl(h); h is a homogeneous polynomial in the
2009        first q-Weyl algebra with respect to the weight vector [-1,1]
2010RETURN: list
2011PURPOSE: Computes a factorization of a homogeneous polynomial h with
2012         respect to the weight vector [-1,1] in the first q-Weyl algebra
2013THEORY: @code{homogfacFirstQWeyl} returns a list with a factorization of the given,
2014        [-1,1]-homogeneous polynomial. If the degree of the polynomial is k with
2015        k positive, the last k entries in the output list are the second
2016        variable. If k is positive, the last k entries will be x. The other
2017        entries will be irreducible polynomials of degree zero or 1 resp. -1.
2018SEE ALSO: homogfacFirstQWeyl_all
2019"{//proc homogfacFirstQWeyl
2020  int p = printlevel-voice+2;//for dbprint
2021  def r = basering;
2022  poly hath;
2023  int i; int j;
2024  intvec ivm11 = intvec(-1,1);
2025  if (!homogwithorder(h,ivm11))
2026  {//The given polynomial is not homogeneous
2027    ERROR("Given polynomial was not [-1,1]-homogeneous");
2028    return(list());
2029  }//The given polynomial is not homogeneous
2030  if (h==0)
2031  {
2032    return(list(0));
2033  }
2034  list result;
2035  int m = deg(h,ivm11);
2036  dbprint(p,"==> Splitting the polynomial in A_0 and A_k-Part");
2037  if (m!=0)
2038  {//The degree is not zero
2039    if (m <0)
2040    {//There are more x than y
2041      hath = lift(var(1)^(-m),h)[1,1];
2042      for (i = 1; i<=-m; i++)
2043      {
2044        result = result + list(var(1));
2045      }
2046    }//There are more x than y
2047    else
2048    {//There are more y than x
2049      hath = lift(var(2)^m,h)[1,1];
2050      for (i = 1; i<=m;i++)
2051      {
2052        result = result + list(var(2));
2053      }
2054    }//There are more y than x
2055  }//The degree is not zero
2056  else
2057  {//The degree is zero
2058    hath = h;
2059  }//The degree is zero
2060  dbprint(p,"==> Done");
2061  //beginning to transform x^i*y^i in theta(theta-1)...(theta-i+1)
2062  list mons;
2063  dbprint(p,"==> Putting the monomials in the A_0-part in a list.");
2064  for(i = 1; i<=size(hath);i++)
2065  {//Putting the monomials in a list
2066    mons = mons+list(hath[i]);
2067  }//Putting the monomials in a list
2068  dbprint(p,"==> Done");
2069  dbprint(p,"==> Mapping this monomials to K(q)[theta]");
2070  //Now, map to the commutative ring with theta:
2071  list tempRingList = ringlist(r);
2072  tempRingList[2] = insert(tempRingList[2],"theta",2); //New variable theta = x*d
2073  tempRingList = delete(tempRingList,5);
2074  tempRingList = delete(tempRingList,5); //The ring should now be commutative
2075  def tempRing = ring(tempRingList);
2076  setring tempRing;
2077  map thetamap = r,var(1),var(2);
2078  list mons = thetamap(mons);
2079  poly entry;
2080  poly tempSummand;
2081  for (i = 1; i<=size(mons);i++)
2082  {//transforming the monomials as monomials in theta
2083    entry = 1;//leadcoef(mons[i]) * q^(-triangNum(leadexp(mons[i])[2]-1));
2084    for (j = 0; j<leadexp(mons[i])[2];j++)
2085    {
2086      tempSummand = (par(1)^j-1)/(par(1)-1);
2087      entry = entry * theta-tempSummand*entry;
2088    }
2089    //entry;
2090    //leadcoef(mons[i]) * q^(-triangNum(leadexp(mons[i])[2]-1));
2091    mons[i] = entry*leadcoef(mons[i]) * par(1)^(-triangNum(leadexp(mons[i])[2]-1));
2092  }//transforming the monomials as monomials in theta
2093  dbprint(p,"==> Done");
2094  dbprint(p,"==> Factorize the A_0-Part in K[theta]");
2095  list azeroresult = factorize(sum(mons));
2096  dbprint(p,"==> Successful");
2097  list azeroresult_return_form;
2098  for (i = 1; i<=size(azeroresult[1]);i++)
2099  {//rewrite the result of the commutative factorization
2100    for (j = 1; j <= azeroresult[2][i];j++)
2101    {
2102      azeroresult_return_form = azeroresult_return_form + list(azeroresult[1][i]);
2103    }
2104  }//rewrite the result of the commutative factorization
2105  dbprint(p,"==> Mapping back to A_0.");
2106  setring(r);
2107  map finalmap = tempRing,var(1),var(2),var(1)*var(2);
2108  list tempresult = finalmap(azeroresult_return_form);
2109  dbprint(p,"Successful.");
2110  for (i = 1; i<=size(tempresult);i++)
2111  {//factorizations of theta resp. theta +1
2112    if(tempresult[i]==var(1)*var(2))
2113    {
2114      tempresult = insert(tempresult,var(1),i-1);
2115      i++;
2116      tempresult[i]=var(2);
2117    }
2118    if(tempresult[i]==var(2)*var(1))
2119    {
2120      tempresult = insert(tempresult,var(2),i-1);
2121      i++;
2122      tempresult[i]=var(1);
2123    }
2124  }//factorizations of theta resp. theta +1
2125  result = tempresult+result;
2126  //Correction of the result in the special q-Case:
2127  for (j = 2 ; j<= size(result);j++)
2128  {//Div the whole Term by the leading coefficient and multiply it to the first entry in result[i]
2129    result[1] = result[1] * leadcoef(result[j]);
2130    result[j] = 1/leadcoef(result[j]) * result[j];
2131  }//Div the whole Term by the leading coefficient and multiply it to the first entry in result[i]
2132  return(result);
2133}//proc homogfacFirstQWeyl
2134example
2135{
2136  "EXAMPLE:";echo=2;
2137  ring R = (0,q),(x,d),dp;
2138  def r = nc_algebra (q,1);
2139  setring(r);
2140  poly h = q^25*x^10*d^10+q^16*(q^4+q^3+q^2+q+1)^2*x^9*d^9+
2141           q^9*(q^13+3*q^12+7*q^11+13*q^10+20*q^9+26*q^8+30*q^7+
2142           31*q^6+26*q^5+20*q^4+13*q^3+7*q^2+3*q+1)*x^8*d^8+
2143           q^4*(q^9+2*q^8+4*q^7+6*q^6+7*q^5+8*q^4+6*q^3+
2144     4*q^2+2q+1)*(q^4+q^3+q^2+q+1)*(q^2+q+1)*x^7*d^7+
2145           q*(q^2+q+1)*(q^5+2*q^4+2*q^3+3*q^2+2*q+1)*(q^4+q^3+q^2+q+1)*(q^2+1)*(q+1)*x^6*d^6+
2146           (q^10+5*q^9+12*q^8+21*q^7+29*q^6+33*q^5+31*q^4+24*q^3+15*q^2+7*q+12)*x^5*d^5+
2147           6*x^3*d^3+24;
2148  homogfacFirstQWeyl(h);
2149}
2150
2151
2152
2153//==================================================
2154//Computes all possible homogeneous factorizations for an element in the first Q-Weyl Algebra
2155proc homogfacFirstQWeyl_all(poly h)
2156"USAGE: homogfacFirstQWeyl_all(h); h is a homogeneous polynomial in the first q-Weyl algebra
2157        with respect to the weight vector [-1,1]
2158RETURN: list
2159PURPOSE: Computes all factorizations of a homogeneous polynomial h with respect
2160         to the weight vector [-1,1] in the first q-Weyl algebra
2161THEORY: @code{homogfacFirstQWeyl} returns a list with all factorization of the given,
2162        homogeneous polynomial. It uses the output of homogfacFirstQWeyl and permutes
2163        its entries with respect to the commutation rule. Furthermore, if a
2164        factor of degree zero is irreducible in K[\theta], but reducible in
2165        the first q-Weyl algebra, the permutations of this element with the other
2166        entries will also be computed.
2167SEE ALSO: homogfacFirstQWeyl
2168"{//proc HomogfacFirstQWeylAll
2169  int p=printlevel-voice+2;//for dbprint
2170  intvec iv11= intvec(1,1);
2171  if (deg(h,iv11) <= 0 )
2172  {//h is a constant
2173    dbprint(p,"Given polynomial was not homogeneous");
2174    return(list(list(h)));
2175  }//h is a constant
2176  def r = basering;
2177  list one_hom_fac; //stands for one homogeneous factorization
2178  int i; int j; int k;
2179  intvec ivm11 = intvec(-1,1);
2180  dbprint(p,"==> Calculate one homogeneous factorization using homogfacFirstQWeyl");
2181  //Compute again a homogeneous factorization
2182  one_hom_fac = homogfacFirstQWeyl(h);
2183  dbprint(p,"Successful");
2184  if (size(one_hom_fac) == 0)
2185  {//there is no homogeneous factorization or the polynomial was not homogeneous
2186    return(list());
2187  }//there is no homogeneous factorization or the polynomial was not homogeneous
2188  //divide list in A0-Part and a list of x's resp. y's
2189  list list_not_azero = list();
2190  list list_azero;
2191  list k_factor;
2192  int is_list_not_azero_empty = 1;
2193  int is_list_azero_empty = 1;
2194  k_factor = list(one_hom_fac[1]);
2195  if (absValue(deg(h,ivm11))<size(one_hom_fac)-1)
2196  {//There is a nontrivial A_0-part
2197    list_azero = one_hom_fac[2..(size(one_hom_fac)-absValue(deg(h,ivm11)))];
2198    is_list_azero_empty = 0;
2199  }//There is a nontrivial A_0 part
2200  dbprint(p,"==> Combine x,y to xy in the factorization again.");
2201  for (i = 1; i<=size(list_azero)-1;i++)
2202  {//in homogfacFirstQWeyl, we factorized theta, and this will be made undone
2203    if (list_azero[i] == var(1))
2204    {
2205      if (list_azero[i+1]==var(2))
2206      {
2207        list_azero[i] = var(1)*var(2);
2208        list_azero = delete(list_azero,i+1);
2209      }
2210    }
2211    if (list_azero[i] == var(2))
2212    {
2213      if (list_azero[i+1]==var(1))
2214      {
2215        list_azero[i] = var(2)*var(1);
2216        list_azero = delete(list_azero,i+1);
2217      }
2218    }
2219  }//in homogfacFirstQWeyl, we factorized theta, and this will be made undone
2220  dbprint(p,"==> Done");
2221  if(deg(h,ivm11)!=0)
2222  {//list_not_azero is not empty
2223    list_not_azero =
2224    one_hom_fac[(size(one_hom_fac)-absValue(deg(h,ivm11))+1)..size(one_hom_fac)];
2225    is_list_not_azero_empty = 0;
2226  }//list_not_azero is not empty
2227  //Map list_azero in K[theta]
2228  dbprint(p,"==> Map list_azero to K[theta]");
2229  //Now, map to the commutative ring with theta:
2230  list tempRingList = ringlist(r);
2231  tempRingList[2] = insert(tempRingList[2],"theta",2); //New variable theta = x*d
2232  tempRingList = delete(tempRingList,5);
2233  tempRingList = delete(tempRingList,5); //The ring should now be commutative
2234  def tempRing = ring(tempRingList);
2235  setring(tempRing);
2236  poly entry;
2237  map thetamap = r,var(1),var(2);
2238  if(!is_list_not_azero_empty)
2239  {//Mapping in Singular is only possible, if the list before
2240    //contained at least one element of the other ring
2241    list list_not_azero = thetamap(list_not_azero);
2242  }//Mapping in Singular is only possible, if the list before
2243  //contained at least one element of the other ring
2244  if(!is_list_azero_empty)
2245  {//Mapping in Singular is only possible, if the list before
2246    //contained at least one element of the other ring
2247    list list_azero= thetamap(list_azero);
2248  }//Mapping in Singular is only possible, if the list before
2249  //contained at least one element of the other ring
2250  list k_factor = thetamap(k_factor);
2251  list tempmons;
2252  dbprint(p,"==> Done");
2253  for(i = 1; i<=size(list_azero);i++)
2254  {//rewrite the polynomials in A1 as polynomials in K[theta]
2255    tempmons = list();
2256    for (j = 1; j<=size(list_azero[i]);j++)
2257    {
2258      tempmons = tempmons + list(list_azero[i][j]);
2259    }
2260    for (j = 1 ; j<=size(tempmons);j++)
2261    {
2262      //entry = leadcoef(tempmons[j]);
2263      entry = leadcoef(tempmons[j]) * par(1)^(-triangNum(leadexp(tempmons[j])[2]-1));
2264      for (k = 0; k < leadexp(tempmons[j])[2];k++)
2265      {
2266        entry = entry*(theta-(par(1)^k-1)/(par(1)-1));
2267      }
2268      tempmons[j] = entry;
2269    }
2270    list_azero[i] = sum(tempmons);
2271  }//rewrite the polynomials in A1 as polynomials in K[theta]
2272  //Compute all permutations of the A0-part
2273  dbprint(p,"==> Compute all permutations of the A_0-part with the first resp. the snd. variable");
2274  list result;
2275  int shift_sign;
2276  int shift;
2277  poly shiftvar;
2278  if (size(list_not_azero)!=0)
2279  {//Compute all possibilities to permute the x's resp. the y's in the list
2280    if (list_not_azero[1] == x)
2281    {//h had a negative weighted degree
2282      shift_sign = 1;
2283      shiftvar = x;
2284    }//h had a negative weighted degree
2285    else
2286    {//h had a positive weighted degree
2287      shift_sign = -1;
2288      shiftvar = y;
2289    }//h had a positive weighted degree
2290    result = permpp(list_azero + list_not_azero);
2291    for (i = 1; i<= size(result); i++)
2292    {//adjust the a_0-parts
2293      shift = 0;
2294      for (j=1; j<=size(result[i]);j++)
2295      {
2296        if (result[i][j]==shiftvar)
2297        {
2298          shift = shift + shift_sign;
2299        }
2300        else
2301        {
2302          if (shift < 0)
2303          {//We have two distict formulas for x and y. In this case use formula for y
2304            if (shift == -1)
2305            {
2306              result[i][j] = subst(result[i][j],theta,1/par(1)*(theta - 1));
2307            }
2308            else
2309            {
2310              result[i][j] =
2311                subst(result[i][j],
2312                  theta,
2313                  1/par(1)*((theta - 1)/par(1)^(absValue(shift)-1)
2314                    - (par(1)^(shift +2)-par(1))/(1-par(1))));
2315            }
2316          }//We have two distict formulas for x and y. In this case use formula for y
2317          if (shift > 0)
2318          {//We have two distict formulas for x and y. In this case use formula for x
2319            if (shift == 1)
2320            {
2321              result[i][j] = subst(result[i][j],theta,par(1)*theta + 1);
2322            }
2323            else
2324            {
2325              result[i][j] =
2326                subst(result[i][j],
2327                theta,par(1)^shift*theta+(par(1)^shift-1)/(par(1)-1));
2328            }
2329          }//We have two distict formulas for x and y. In this case use formula for x
2330        }
2331      }
2332    }//adjust the a_0-parts
2333  }//Compute all possibilities to permute the x's resp. the y's in the list
2334  else
2335  {//The result is just all the permutations of the a_0-part
2336    result = permpp(list_azero);
2337  }//The result is just all the permutations of the a_0 part
2338  if (size(result)==0)
2339  {
2340    return(result);
2341  }
2342  dbprint(p,"==> Done");
2343  dbprint(p,"==> Searching for theta resp. theta + 1 in the list and factorize them");
2344  //Now we are going deeper and search for theta resp. theta + 1, substitute
2345  //them by xy resp. yx and go on permuting
2346  int found_theta;
2347  int thetapos;
2348  list leftpart;
2349  list rightpart;
2350  list lparts;
2351  list rparts;
2352  list tempadd;
2353  for (i = 1; i<=size(result) ; i++)
2354  {//checking every entry of result for theta or theta +1
2355    found_theta = 0;
2356    for(j=1;j<=size(result[i]);j++)
2357    {
2358      if (result[i][j]==theta)
2359      {//the jth entry is theta and can be written as x*y
2360        thetapos = j;
2361        result[i]= insert(result[i],x,j-1);
2362        j++;
2363        result[i][j] = y;
2364        found_theta = 1;
2365        break;
2366      }//the jth entry is theta and can be written as x*y
2367      if(result[i][j] == par(1)*theta +1)
2368      {
2369        thetapos = j;
2370        result[i] = insert(result[i],y,j-1);
2371        j++;
2372        result[i][j] = x;
2373        found_theta = 1;
2374        break;
2375      }
2376    }
2377    if (found_theta)
2378    {//One entry was theta resp. theta +1
2379      leftpart = result[i];
2380      leftpart = leftpart[1..thetapos];
2381      rightpart = result[i];
2382      rightpart = rightpart[(thetapos+1)..size(rightpart)];
2383      lparts = list(leftpart);
2384      rparts = list(rightpart);
2385      //first deal with the left part
2386      if (leftpart[thetapos] == x)
2387      {
2388        shift_sign = 1;
2389        shiftvar = x;
2390      }
2391      else
2392      {
2393        shift_sign = -1;
2394        shiftvar = y;
2395      }
2396      for (j = size(leftpart); j>1;j--)
2397      {//drip x resp. y
2398        if (leftpart[j-1]==shiftvar)
2399        {//commutative
2400          j--;
2401          continue;
2402        }//commutative
2403        if (deg(leftpart[j-1],intvec(-1,1,0))!=0)
2404        {//stop here
2405          break;
2406        }//stop here
2407        //Here, we can only have a a0- part
2408        if (shift_sign<0)
2409        {
2410          leftpart[j] = subst(leftpart[j-1],theta, 1/par(1)*(theta +shift_sign));
2411        }
2412        if (shift_sign>0)
2413        {
2414          leftpart[j] = subst(leftpart[j-1],theta, par(1)*theta + shift_sign);
2415        }
2416        leftpart[j-1] = shiftvar;
2417        lparts = lparts + list(leftpart);
2418      }//drip x resp. y
2419      //and now deal with the right part
2420      if (rightpart[1] == x)
2421      {
2422        shift_sign = 1;
2423        shiftvar = x;
2424      }
2425      else
2426      {
2427        shift_sign = -1;
2428        shiftvar = y;
2429      }
2430      for (j = 1 ; j < size(rightpart); j++)
2431      {
2432        if (rightpart[j+1] == shiftvar)
2433        {
2434          j++;
2435          continue;
2436        }
2437        if (deg(rightpart[j+1],intvec(-1,1,0))!=0)
2438        {
2439          break;
2440        }
2441        if (shift_sign<0)
2442        {
2443          rightpart[j] = subst(rightpart[j+1], theta, par(1)*theta - shift_sign);
2444        }
2445        if (shift_sign>0)
2446        {
2447          rightpart[j] = subst(rightpart[j+1], theta, 1/par(1)*(theta - shift_sign));
2448        }
2449        rightpart[j+1] = shiftvar;
2450        rparts = rparts + list(rightpart);
2451      }
2452      //And now, we put all possibilities together
2453      tempadd = list();
2454      for (j = 1; j<=size(lparts); j++)
2455      {
2456        for (k = 1; k<=size(rparts);k++)
2457        {
2458          tempadd = tempadd + list(lparts[j]+rparts[k]);
2459        }
2460      }
2461      tempadd = delete(tempadd,1); // The first entry is already in the list
2462      result = result + tempadd;
2463      continue; //We can may be not be done already with the ith entry
2464    }//One entry was theta resp. theta +1
2465  }//checking every entry of result for theta or theta +1
2466  dbprint(p,"==> Done");
2467  //map back to the basering
2468  dbprint(p,"==> Mapping back everything to the basering");
2469  setring(r);
2470  map finalmap = tempRing, var(1), var(2),var(1)*var(2);
2471  list result = finalmap(result);
2472  for (i=1; i<=size(result);i++)
2473  {//adding the K factor
2474    result[i] = k_factor + result[i];
2475  }//adding the k-factor
2476  dbprint(p,"==> Done");
2477  dbprint(p,"==> Delete double entries in the list.");
2478  result = delete_dublicates_noteval(result);
2479  dbprint(p,"==> Done");
2480  return(result);
2481}//proc HomogfacFirstQWeylAll
2482example
2483{
2484  "EXAMPLE:";echo=2;
2485  ring R = (0,q),(x,d),dp;
2486  def r = nc_algebra (q,1);
2487  setring(r);
2488  poly h = q^25*x^10*d^10+q^16*(q^4+q^3+q^2+q+1)^2*x^9*d^9+
2489           q^9*(q^13+3*q^12+7*q^11+13*q^10+20*q^9+26*q^8+30*q^7+
2490           31*q^6+26*q^5+20*q^4+13*q^3+7*q^2+3*q+1)*x^8*d^8+
2491           q^4*(q^9+2*q^8+4*q^7+6*q^6+7*q^5+8*q^4+6*q^3+
2492           4*q^2+2q+1)*(q^4+q^3+q^2+q+1)*(q^2+q+1)*x^7*d^7+
2493           q*(q^2+q+1)*(q^5+2*q^4+2*q^3+3*q^2+2*q+1)*(q^4+q^3+q^2+q+1)*(q^2+1)*(q+1)*x^6*d^6+
2494           (q^10+5*q^9+12*q^8+21*q^7+29*q^6+33*q^5+31*q^4+24*q^3+15*q^2+7*q+12)*x^5*d^5+
2495           6*x^3*d^3+24;
2496  homogfacFirstQWeyl_all(h);
2497}
2498
2499//TODO: FirstQWeyl check the parameters...
2500
2501/*
2502  Example polynomials where one can find factorizations: K<x,y |yx=xy+1>
2503  (x^2+y)*(x^2+y);
2504  (x^2+x)*(x^2+y);
2505  (x^3+x+1)*(x^4+y*x+2);
2506  (x^2*y+y)*(y+x*y);
2507  y^3+x*y^3+2*y^2+2*(x+1)*y^2+y+(x+2)*y; //Example 5 Grigoriev-Schwarz.
2508  (y+1)*(y+1)*(y+x*y); //Landau Example projected to the first dimension.
2509*/
2510
2511
2512/* very hard things from Martin Lee:
2513// ex1, ex2
2514ring s = 0,(z,x),Ws(-1,1);
2515def S = nc_algebra(1,1); setring S;
2516poly a = 10z5x4+26z4x5+47z5x2-97z4x3; //Abgebrochen nach einer Stunde; yes, it takes long
2517def l= facFirstWeyl (a); l;
2518kill l;
2519poly b = -5328z8x5-5328z7x6+720z9x2+720z8x3-16976z7x4-38880z6x5
2520-5184z7x3-5184z6x4-3774z5x5+2080z8x+5760z7x2-6144z6x3-59616z5x4
2521+3108z3x6-4098z6x2-25704z5x3-21186z4x4+8640z6x-17916z4x3+22680z2x5
2522+2040z5x-4848z4x2-9792z3x3+3024z2x4-10704z3x2-3519z2x3+34776zx4
2523+12096zx3+2898x4-5040z2x+8064x3+6048x2; //Abgebrochen nach 1.5 Stunden;seems to be very complicated
2524def l= facFirstWeyl (b); l;
2525
2526// ex3: there was difference in answers => fixed
2527LIB "ncfactor.lib";
2528ring r = 0,(x,y,z),dp;
2529matrix D[3][3]; D[1,3]=-1;
2530def R = nc_algebra(1,D);
2531setring R;
2532poly g= 7*z4*x+62*z3+26*z;
2533def l1= facSubWeyl (g, x, z);
2534l1;
2535//---- other ring
2536ring s = 0,(x,z),dp;
2537def S = nc_algebra(1,-1); setring S;
2538poly g= 7*z4*x+62*z3+26*z;
2539def l2= facFirstWeyl (g);
2540l2;
2541map F = R,x,0,z;
2542list l1 = F(l1);
2543l1;
2544//---- so the answers look different, check them!
2545testNCfac(l2); // ok
2546testNCfac(l1); // was not ok, but now it's been fixed!!!
2547
2548// selbst D und X so vertauschen dass sie erfuellt ist : ist gemacht
2549
2550*/
2551
2552/*
2553// bug from M Lee
2554LIB "ncfactor.lib";
2555ring s = 0,(z,x),dp;
2556def S = nc_algebra(1,1); setring S;
2557poly f= -60z4x2-54z4-56zx3-59z2x-64;
2558def l= facFirstWeyl (f);
2559l; // before: empty list; after fix: 1 entry, f is irreducible
2560poly g = 75z3x2+92z3+24;
2561def l= facFirstWeyl (g);
2562l; //before: empty list, now: correct
2563*/
2564
2565/* more things from Martin Lee; fixed
2566ring R = 0,(x,s),dp;
2567def r = nc_algebra(1,s);
2568setring(r);
2569poly h = (s2*x+x)*s;
2570h= h* (x+s);
2571def l= facFirstShift(h);
2572l; // contained doubled entries: not anymore, fixed!
2573
2574ring R = 0,(x,s),dp;
2575def r = nc_algebra(1,-1);
2576setring(r);
2577poly h = (s2*x+x)*s;
2578h= h* (x+s);
2579def l= facFirstWeyl(h);
2580l; // contained doubled entries: not anymore, fixed!
2581
2582*/
Note: See TracBrowser for help on using the repository browser.