source: git/Singular/LIB/ncfactor.lib @ 1b2216

spielwiese
Last change on this file since 1b2216 was 1e1ec4, checked in by Oleksandr Motsak <motsak@…>, 11 years ago
Updated LIBs according to master add: new LIBs from master fix: updated LIBs due to minpoly/(de)numerator changes fix: -> $Id$ fix: Fixing wrong rebase of SW on master (LIBs)
  • Property mode set to 100755
File size: 146.1 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  tst_ncfactor();            Runs the examples of all contained not static functions. Test thing.
29";
30
31LIB "general.lib";
32LIB "nctools.lib";
33LIB "involut.lib";
34LIB "freegb.lib"; // for isVar
35LIB "crypto.lib"; //for introot
36LIB "matrix.lib"; //for submatrix
37LIB "poly.lib"; //for content
38
39proc tst_ncfactor()
40"
41A little test if the library works correct.
42Runs simply all examples of non-static functions.
43"
44{
45  example facFirstWeyl;
46  example facFirstShift;
47  example facSubWeyl;
48  example testNCfac;
49  example homogfacFirstQWeyl;
50  example homogfacFirstQWeyl_all;
51}
52example
53{
54  "EXAMPLE:";echo=2;
55   tst_ncfactor();
56}
57
58/////////////////////////////////////////////////////
59//==================================================*
60//deletes double-entries in a list of factorization
61//without evaluating the product.
62static proc delete_dublicates_noteval(list l)
63"
64INPUT: A list of lists; Output same as e.g. FacFirstWeyl. Containing different factorizations
65       of a polynomial
66OUTPUT: If there are dublicates in this list, this procedure deletes them and returns the list
67 without double entries
68"
69{//proc delete_dublicates_noteval
70  list result= l;
71  int j; int k; int i;
72  int deleted = 0;
73  int is_equal;
74  for (i = 1; i<= size(l); i++)
75  {//Iterate over the different factorizations
76    for (j = i+1; j<= size(l); j++)
77    {//Compare the i'th factorization to the j'th
78      if (size(l[i])!= size(l[j]))
79      {//different sizes => not equal
80        j++;
81        continue;
82      }//different sizes => not equal
83      is_equal = 1;
84      for (k = 1; k <= size(l[i]);k++)
85      {//Compare every entry
86        if (l[i][k]!=l[j][k])
87        {
88          is_equal = 0;
89          break;
90        }
91      }//Compare every entry
92      if (is_equal == 1)
93      {//Delete this entry, because there is another equal one int the list
94        result = delete(result, i-deleted);
95        deleted = deleted+1;
96        break;
97      }//Delete this entry, because there is another equal one int the list
98    }//Compare the i'th factorization to the j'th
99  }//Iterate over the different factorizations
100  return(result);
101}//proc delete_dublicates_noteval
102
103//==================================================
104//deletes the double-entries in a list with
105//evaluating the products
106static proc delete_dublicates_eval(list l)
107"
108DEPRECATED
109"
110{//proc delete_dublicates_eval
111  list result=l;
112  int j; int k; int i;
113  int deleted = 0;
114  int is_equal;
115  for (i = 1; i<= size(result); i++)
116  {//Iterating over all elements in result
117    for (j = i+1; j<= size(result); j++)
118    {//comparing with the other elements
119      if (product(result[i]) == product(result[j]))
120      {//There are two equal results; throw away that one with the smaller size
121        if (size(result[i])>=size(result[j]))
122        {//result[i] has more entries
123          result = delete(result,j);
124          continue;
125        }//result[i] has more entries
126        else
127        {//result[j] has more entries
128          result = delete(result,i);
129          i--;
130          break;
131        }//result[j] has more entries
132      }//There are two equal results; throw away that one with the smaller size
133    }//comparing with the other elements
134  }//Iterating over all elements in result
135  return(result);
136}//proc delete_dublicates_eval
137
138
139//==================================================*
140
141static proc combinekfinlf(list g, int nof) //nof stands for "number of factors"
142"
143given a list of factors g and a desired size nof, this
144procedure combines the factors, such that we recieve a
145list of the length nof.
146INPUT: A list of containing polynomials or any type where the *-operator is existent
147OUTPUT: All possibilities (without permutation of the given list) to combine the polynomials
148 into nof polynomials given by the user.
149"
150{//Procedure combinekfinlf
151  list result;
152  int i; int j; int k; //iteration variables
153  list fc; //fc stands for "factors combined"
154  list temp; //a temporary store for factors
155  def nofgl = size(g); //nofgl stands for "number of factors of the given list"
156  if (nofgl == 0)
157  {//g was the empty list
158    return(result);
159  }//g was the empty list
160  if (nof <= 0)
161  {//The user wants to recieve a negative number or no element as a result
162    return(result);
163  }//The user wants to recieve a negative number or no element as a result
164  if (nofgl == nof)
165  {//There are no factors to combine
166    result = result + list(g);
167    return(result);
168  }//There are no factors to combine
169  if (nof == 1)
170  {//User wants to get just one factor
171    result = result + list(list(product(g)));
172    return(result);
173  }//User wants to get just one factor
174  for (i = nof; i > 1; i--)
175  {//computing the possibilities that have at least one original factor from g
176    for (j = i; j>=1; j--)
177    {//shifting the window of combinable factors to the left
178      //fc below stands for "factors combined"
179      fc = combinekfinlf(list(g[(j)..(j+nofgl - i)]),nof - i + 1);
180      for (k = 1; k<=size(fc); k++)
181      {//iterating over the different solutions of the smaller problem
182        if (j>1)
183        {//There are g_i before the combination
184          if (j+nofgl -i < nofgl)
185          {//There are g_i after the combination
186            temp = list(g[1..(j-1)]) + fc[k] + list(g[(j+nofgl-i+1)..nofgl]);
187          }//There are g_i after the combination
188          else
189          {//There are no g_i after the combination
190            temp = list(g[1..(j-1)]) + fc[k];
191          }//There are no g_i after the combination
192        }//There are g_i before the combination
193        if (j==1)
194        {//There are no g_i before the combination
195          if (j+ nofgl -i <nofgl)
196          {//There are g_i after the combination
197            temp = fc[k]+ list(g[(j + nofgl - i +1)..nofgl]);
198          }//There are g_i after the combination
199        }//There are no g_i before the combination
200        result = result + list(temp);
201      }//iterating over the different solutions of the smaller problem
202    }//shifting the window of combinable factors to the left
203  }//computing the possibilities that have at least one original factor from g
204  for (i = 2; i<=nofgl div nof;i++)
205  {//getting the other possible results
206    result = result + combinekfinlf(list(product(list(g[1..i])))+list(g[(i+1)..nofgl]),nof);
207  }//getting the other possible results
208  result = delete_dublicates_noteval(result);
209  return(result);
210}//Procedure combinekfinlf
211
212
213//==================================================*
214//merges two sets of factors ignoring common
215//factors
216static proc merge_icf(list l1, list l2, intvec limits)
217"
218DEPRECATED
219"
220{//proc merge_icf
221  list g;
222  list f;
223  int i; int j;
224  if (size(l1)==0)
225  {
226    return(list());
227  }
228  if (size(l2)==0)
229  {
230    return(list());
231  }
232  if (size(l2)<=size(l1))
233  {//l1 will be our g, l2 our f
234    g = l1;
235    f = l2;
236  }//l1 will be our g, l2 our f
237  else
238  {//l1 will be our f, l2 our g
239    g = l2;
240    f = l1;
241  }//l1 will be our f, l2 our g
242  def result = combinekfinlf(g,size(f),limits);
243  for (i = 1 ; i<= size(result); i++)
244  {//Adding the factors of f to every possibility listed in temp
245    for (j = 1; j<= size(f); j++)
246    {
247      result[i][j] = result[i][j]+f[j];
248    }
249    if(!limitcheck(result[i],limits))
250    {
251      result = delete(result,i);
252      continue;
253    }
254    for (j = 1; j<=size(f);j++)
255    {//Delete entry if there is a zero or an integer as a factor
256      if (deg(result[i][j]) <= 0)
257      {//found one
258        result = delete(result,i);
259        i--;
260        break;
261      }//found one
262    }//Delete entry if there is a zero as factor
263  }//Adding the factors of f to every possibility listed in temp
264  return(result);
265}//proc merge_icf
266
267//==================================================*
268//merges two sets of factors with respect to the occurrence
269//of common factors
270static proc merge_cf(list l1, list l2, intvec limits)
271"
272DEPRECATED
273"
274{//proc merge_cf
275  list g;
276  list f;
277  int i; int j;
278  list pre;
279  list post;
280  list candidate;
281  list temp;
282  int temppos;
283  if (size(l1)==0)
284  {//the first list is empty
285    return(list());
286  }//the first list is empty
287  if(size(l2)==0)
288  {//the second list is empty
289    return(list());
290  }//the second list is empty
291  if (size(l2)<=size(l1))
292  {//l1 will be our g, l2 our f
293    g = l1;
294    f = l2;
295  }//l1 will be our g, l2 our f
296  else
297  {//l1 will be our f, l2 our g
298    g = l2;
299    f = l1;
300  }//l1 will be our f, l2 our g
301  list M;
302  for (i = 2; i<size(f); i++)
303  {//finding common factors of f and g...
304    for (j=2; j<size(g);j++)
305    {//... with g
306      if (f[i] == g[j])
307      {//we have an equal pair
308        M = M + list(list(i,j));
309      }//we have an equal pair
310    }//... with g
311  }//finding common factors of f and g...
312  if (g[1]==f[1])
313  {//Checking for the first elements to be equal
314    M = M + list(list(1,1));
315  }//Checking for the first elements to be equal
316  if (g[size(g)]==f[size(f)])
317  {//Checking for the last elements to be equal
318    M = M + list(list(size(f),size(g)));
319  }//Checking for the last elements to be equal
320  list result;//= list(list());
321  while(size(M)>0)
322  {//set of equal pairs is not empty
323    temp = M[1];
324    temppos = 1;
325    for (i = 2; i<=size(M); i++)
326    {//finding the minimal element of M
327      if (M[i][1]<=temp[1])
328      {//a possible candidate that is smaller than temp could have been found
329        if (M[i][1]==temp[1])
330        {//In this case we must look at the second number
331          if (M[i][2]< temp[2])
332          {//the candidate is smaller
333            temp = M[i];
334            temppos = i;
335          }//the candidate is smaller
336        }//In this case we must look at the second number
337        else
338        {//The candidate is definately smaller
339          temp = M[i];
340          temppos = i;
341        }//The candidate is definately smaller
342      }//a possible candidate that is smaller than temp could have been found
343    }//finding the minimal element of M
344    M = delete(M, temppos);
345    if(temp[1]>1)
346    {//There are factors to combine before the equal factor
347      if (temp[1]<size(f))
348      {//The most common case
349        //first the combinations ignoring common factors
350        pre = merge_icf(list(f[1..(temp[1]-1)]),list(g[1..(temp[2]-1)]),limits);
351        post = merge_icf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
352        for (i = 1; i <= size(pre); i++)
353        {//all possible pre's...
354          for (j = 1; j<= size(post); j++)
355          {//...combined with all possible post's
356            candidate = pre[i]+list(f[temp[1]])+post[j];
357            if (limitcheck(candidate,limits))
358            {
359              result = result + list(candidate);
360            }
361          }//...combined with all possible post's
362        }//all possible pre's...
363        //Now the combinations with respect to common factors
364        post = merge_cf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
365        if (size(post)>0)
366        {//There are factors to combine
367          for (i = 1; i <= size(pre); i++)
368          {//all possible pre's...
369            for (j = 1; j<= size(post); j++)
370            {//...combined with all possible post's
371              candidate= pre[i]+list(f[temp[1]])+post[j];
372              if (limitcheck(candidate,limits))
373              {
374                result = result + list(candidate);
375              }
376            }//...combined with all possible post's
377          }//all possible pre's...
378        }//There are factors to combine
379      }//The most common case
380      else
381      {//the last factor is the common one
382        pre = merge_icf(list(f[1..(temp[1]-1)]),list(g[1..(temp[2]-1)]),limits);
383        for (i = 1; i<= size(pre); i++)
384        {//iterating over the possible pre-factors
385          candidate = pre[i]+list(f[temp[1]]);
386          if (limitcheck(candidate,limits))
387          {
388            result = result + list(candidate);
389          }
390        }//iterating over the possible pre-factors
391      }//the last factor is the common one
392    }//There are factors to combine before the equal factor
393    else
394    {//There are no factors to combine before the equal factor
395      if (temp[1]<size(f))
396      {//Just a check for security
397        //first without common factors
398        post=merge_icf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
399        for (i = 1; i<=size(post); i++)
400        {
401          candidate = list(f[temp[1]])+post[i];
402          if (limitcheck(candidate,limits))
403          {
404            result = result + list(candidate);
405          }
406        }
407        //Now with common factors
408        post = merge_cf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
409        if(size(post)>0)
410        {//we could find other combinations
411          for (i = 1; i<=size(post); i++)
412          {
413            candidate = list(f[temp[1]])+post[i];
414            if (limitcheck(candidate,limits))
415            {
416              result = result + list(candidate);
417            }
418          }
419        }//we could find other combinations
420      }//Just a check for security
421    }//There are no factors to combine before the equal factor
422  }//set of equal pairs is not empty
423  for (i = 1; i <= size(result); i++)
424  {//delete those combinations, who have an entry with degree less or equal 0
425    for (j = 1; j<=size(result[i]);j++)
426    {//Delete entry if there is a zero or an integer as a factor
427      if (deg(result[i][j]) <= 0)
428      {//found one
429        result = delete(result,i);
430        i--;
431        break;
432      }//found one
433    }//Delete entry if there is a zero as factor
434  }//delete those combinations, who have an entry with degree less or equal 0
435  return(result);
436}//proc merge_cf
437
438
439//==================================================*
440//merges two sets of factors
441
442static proc mergence(list l1, list l2, intvec limits)
443"
444DEPRECATED
445"
446{//Procedure mergence
447  list g;
448  list f;
449  int k; int i; int j;
450  list F = list();
451  list G = list();
452  list tempEntry;
453  list comb;
454  if (size(l2)<=size(l1))
455  {//l1 will be our g, l2 our f
456    g = l1;
457    f = l2;
458  }//l1 will be our g, l2 our f
459  else
460  {//l1 will be our f, l2 our g
461    g = l2;
462    f = l1;
463  }//l1 will be our f, l2 our g
464  if (size(f)==1 or size(g)==1)
465  {//One of them just has one entry
466    if (size(f)== 1) {f = list(1) + f;}
467    if (size(g) == 1) {g = list(1) + g;}
468  }//One of them just has one entry
469  //first, we need to add some latent -1's to the list f and to the list g in order
470  //to get really all possibilities of combinations later
471  for (i=1;i<=size(f)-1;i++)
472  {//first iterator
473    for (j=i+1;j<=size(f);j++)
474    {//second iterator
475      tempEntry = f;
476      tempEntry[i] = (-1)*tempEntry[i];
477      tempEntry[j] = (-1)*tempEntry[j];
478      F = F + list(tempEntry);
479    }//secont iterator
480  }//first iterator
481  F = F + list(f);
482  //And now same game with g
483  for (i=1;i<=size(g)-1;i++)
484  {//first iterator
485    for (j=i+1;j<=size(g);j++)
486    {//second iterator
487      tempEntry = g;
488      tempEntry[i] = (-1)*tempEntry[i];
489      tempEntry[j] = (-1)*tempEntry[j];
490      G = G + list(tempEntry);
491    }//secont iterator
492  }//first iterator
493  G = G + list(g);
494  //Done with that
495
496  list result;
497  for (i = 1; i<=size(F); i++)
498  {//Iterate over all entries in F
499    for (j = 1;j<=size(G);j++)
500    {//Same with G
501      comb = combinekfinlf(F[i],2,limits);
502      for (k = 1; k<= size(comb);k++)
503      {//for all possibilities of combinations of the factors of f
504        result = result + merge_cf(comb[k],G[j],limits);
505        result = result + merge_icf(comb[k],G[j],limits);
506        result = delete_dublicates_noteval(result);
507      }//for all possibilities of combinations of the factors of f
508    }//Same with G
509  }//Iterate over all entries in F
510  return(result);
511}//Procedure mergence
512
513
514//==================================================
515//Checks, whether a list of factors doesn't exceed the given limits
516static proc limitcheck(list g, intvec limits)
517"
518DEPRECATED
519"
520{//proc limitcheck
521  int i;
522  if (size(limits)!=3)
523  {//check the input
524    return(0);
525  }//check the input
526  if(size(g)==0)
527  {
528    return(0);
529  }
530  def prod = product(g);
531  intvec iv11 = intvec(1,1);
532  intvec iv10 = intvec(1,0);
533  intvec iv01 = intvec(0,1);
534  def limg = intvec(deg(prod,iv11) ,deg(prod,iv10),deg(prod,iv01));
535  for (i = 1; i<=size(limg);i++)
536  {//the final check
537    if(limg[i]>limits[i])
538    {
539      return(0);
540    }
541  }//the final check
542  return(1);
543}//proc limitcheck
544
545
546//==================================================*
547//one factorization of a homogeneous polynomial
548//in the first Weyl Algebra
549static proc homogfacFirstWeyl(poly h)
550"USAGE: homogfacFirstWeyl(h); h is a homogeneous polynomial in the
551 first Weyl algebra with respect to the weight vector [-1,1]
552RETURN: list
553PURPOSE: Computes a factorization of a homogeneous polynomial h with
554  respect to the weight vector [-1,1] in the first Weyl algebra
555THEORY: @code{homogfacFirstWeyl} returns a list with a factorization of the given,
556 [-1,1]-homogeneous polynomial. If the degree of the polynomial is k with
557 k positive, the last k entries in the output list are the second
558 variable. If k is positive, the last k entries will be x. The other
559 entries will be irreducible polynomials of degree zero or 1 resp. -1.
560SEE ALSO: homogfacFirstWeyl_all
561"{//proc homogfacFirstWeyl
562  int p = printlevel-voice+2;//for dbprint
563  def r = basering;
564  poly hath;
565  int i; int j;
566  string dbprintWhitespace = "";
567  for (i = 1; i<=voice;i++)
568  {dbprintWhitespace = dbprintWhitespace + " ";}
569  intvec ivm11 = intvec(-1,1);
570  if (!homogwithorder(h,ivm11))
571  {//The given polynomial is not homogeneous
572    ERROR("Given polynomial was not [-1,1]-homogeneous");
573    return(list());
574  }//The given polynomial is not homogeneous
575  if (h==0)
576  {
577    return(list(0));
578  }
579  list result;
580  int m = deg(h,ivm11);
581  dbprint(p,dbprintWhitespace +" Splitting the polynomial in A_0 and A_k-Part");
582  if (m!=0)
583  {//The degree is not zero
584    if (m <0)
585    {//There are more x than y
586      hath = lift(var(1)^(-m),h)[1,1];
587      for (i = 1; i<=-m; i++)
588      {
589        result = result + list(var(1));
590      }
591    }//There are more x than y
592    else
593    {//There are more y than x
594      hath = lift(var(2)^m,h)[1,1];
595      for (i = 1; i<=m;i++)
596      {
597        result = result + list(var(2));
598      }
599    }//There are more y than x
600  }//The degree is not zero
601  else
602  {//The degree is zero
603    hath = h;
604  }//The degree is zero
605  dbprint(p,dbprintWhitespace+" Done");
606  //beginning to transform x^i*y^i in theta(theta-1)...(theta-i+1)
607  list mons;
608  dbprint(p,dbprintWhitespace+" Putting the monomials in the A_0-part in a list.");
609  for(i = 1; i<=size(hath);i++)
610  {//Putting the monomials in a list
611    mons = mons+list(hath[i]);
612  }//Putting the monomials in a list
613  dbprint(p,dbprintWhitespace+" Done");
614  dbprint(p,dbprintWhitespace+" Mapping this monomials to K[theta]");
615  ring tempRing = 0,(x,y,theta),dp;
616  setring tempRing;
617  map thetamap = r,x,y;
618  list mons = thetamap(mons);
619  poly entry;
620  for (i = 1; i<=size(mons);i++)
621  {//transforming the monomials as monomials in theta
622    entry = leadcoef(mons[i]);
623    for (j = 0; j<leadexp(mons[i])[2];j++)
624    {
625      entry = entry * (theta-j);
626    }
627    mons[i] = entry;
628  }//transforming the monomials as monomials in theta
629  dbprint(p,dbprintWhitespace+" Done");
630  dbprint(p,dbprintWhitespace+" Factorize the A_0-Part in K[theta]");
631  list azeroresult = factorize(sum(mons));
632  dbprint(p,dbprintWhitespace+" Successful");
633  list azeroresult_return_form;
634  for (i = 1; i<=size(azeroresult[1]);i++)
635  {//rewrite the result of the commutative factorization
636    for (j = 1; j <= azeroresult[2][i];j++)
637    {
638      azeroresult_return_form = azeroresult_return_form + list(azeroresult[1][i]);
639    }
640  }//rewrite the result of the commutative factorization
641  dbprint(p,dbprintWhitespace+" Mapping back to A_0.");
642  setring(r);
643  map finalmap = tempRing,var(1),var(2),var(1)*var(2);
644  list tempresult = finalmap(azeroresult_return_form);
645  dbprint(p,dbprintWhitespace+"Successful.");
646  for (i = 1; i<=size(tempresult);i++)
647  {//factorizations of theta resp. theta +1
648    if(tempresult[i]==var(1)*var(2))
649    {
650      tempresult = insert(tempresult,var(1),i-1);
651      i++;
652      tempresult[i]=var(2);
653    }
654    if(tempresult[i]==var(2)*var(1))
655    {
656      tempresult = insert(tempresult,var(2),i-1);
657      i++;
658      tempresult[i]=var(1);
659    }
660  }//factorizations of theta resp. theta +1
661  result = tempresult+result;
662  return(result);
663}//proc homogfacFirstWeyl
664/* example */
665/* { */
666/*      "EXAMPLE:";echo=2; */
667/*      ring R = 0,(x,y),Ws(-1,1); */
668/*      def r = nc_algebra(1,1); */
669/*      setring(r); */
670/*      poly h = (x^2*y^2+1)*(x^4); */
671/*      homogfacFirstWeyl(h); */
672/* } */
673
674//==================================================
675//Computes all possible homogeneous factorizations
676static proc homogfacFirstWeyl_all(poly h)
677"USAGE: homogfacFirstWeyl_all(h); h is a homogeneous polynomial in the first Weyl algebra
678 with respect to the weight vector [-1,1]
679RETURN: list
680PURPOSE: Computes all factorizations of a homogeneous polynomial h with respect
681  to the weight vector [-1,1] in the first Weyl algebra
682THEORY: @code{homogfacFirstWeyl} returns a list with all factorization of the given,
683 homogeneous polynomial. It uses the output of homogfacFirstWeyl and permutes
684 its entries with respect to the commutation rule. Furthermore, if a
685 factor of degree zero is irreducible in K[  heta], but reducible in
686 the first Weyl algebra, the permutations of this element with the other
687 entries will also be computed.
688SEE ALSO: homogfacFirstWeyl
689"{//proc HomogfacFirstWeylAll
690  int p=printlevel-voice+2;//for dbprint
691  intvec iv11= intvec(1,1);
692  if (deg(h,iv11) <= 0 )
693  {//h is a constant
694    dbprint(p,"Given polynomial was not homogeneous");
695    return(list(list(h)));
696  }//h is a constant
697  def r = basering;
698  list one_hom_fac; //stands for one homogeneous factorization
699  int i; int j; int k;
700  string dbprintWhitespace = "";
701  for (i = 1; i<=voice;i++)
702  {dbprintWhitespace = dbprintWhitespace + " ";}
703  intvec ivm11 = intvec(-1,1);
704  dbprint(p,dbprintWhitespace +" Calculate one homogeneous factorization using homogfacFirstWeyl");
705  //Compute again a homogeneous factorization
706  one_hom_fac = homogfacFirstWeyl(h);
707  dbprint(p,dbprintWhitespace +"Successful");
708  if (size(one_hom_fac) == 0)
709  {//there is no homogeneous factorization or the polynomial was not homogeneous
710    return(list());
711  }//there is no homogeneous factorization or the polynomial was not homogeneous
712  //divide list in A0-Part and a list of x's resp. y's
713  list list_not_azero = list();
714  list list_azero;
715  list k_factor;
716  int is_list_not_azero_empty = 1;
717  int is_list_azero_empty = 1;
718  k_factor = list(one_hom_fac[1]);
719  if (absValue(deg(h,ivm11))<size(one_hom_fac)-1)
720  {//There is a nontrivial A_0-part
721    list_azero = one_hom_fac[2..(size(one_hom_fac)-absValue(deg(h,ivm11)))];
722    is_list_azero_empty = 0;
723  }//There is a nontrivial A_0 part
724  dbprint(p,dbprintWhitespace +" Combine x,y to xy in the factorization again.");
725  for (i = 1; i<=size(list_azero)-1;i++)
726  {//in homogfacFirstWeyl, we factorized theta, and this will be made undone
727    if (list_azero[i] == var(1))
728    {
729      if (list_azero[i+1]==var(2))
730      {
731        list_azero[i] = var(1)*var(2);
732        list_azero = delete(list_azero,i+1);
733      }
734    }
735    if (list_azero[i] == var(2))
736    {
737      if (list_azero[i+1]==var(1))
738      {
739        list_azero[i] = var(2)*var(1);
740        list_azero = delete(list_azero,i+1);
741      }
742    }
743  }//in homogfacFirstWeyl, we factorized theta, and this will be made undone
744  dbprint(p,dbprintWhitespace +" Done");
745  if(deg(h,ivm11)!=0)
746  {//list_not_azero is not empty
747    list_not_azero =
748      one_hom_fac[(size(one_hom_fac)-absValue(deg(h,ivm11))+1)..size(one_hom_fac)];
749    is_list_not_azero_empty = 0;
750  }//list_not_azero is not empty
751  //Map list_azero in K[theta]
752  dbprint(p,dbprintWhitespace +" Map list_azero to K[theta]");
753  ring tempRing = 0,(x,y,theta), dp;
754  setring(tempRing);
755  poly entry;
756  map thetamap = r,x,y;
757  if(!is_list_not_azero_empty)
758  {//Mapping in Singular is only possible, if the list before
759    //contained at least one element of the other ring
760    list list_not_azero = thetamap(list_not_azero);
761  }//Mapping in Singular is only possible, if the list before
762  //contained at least one element of the other ring
763  if(!is_list_azero_empty)
764  {//Mapping in Singular is only possible, if the list before
765    //contained at least one element of the other ring
766    list list_azero= thetamap(list_azero);
767  }//Mapping in Singular is only possible, if the list before
768  //contained at least one element of the other ring
769  list k_factor = thetamap(k_factor);
770  list tempmons;
771  dbprint(p,dbprintWhitespace +" Done");
772  for(i = 1; i<=size(list_azero);i++)
773  {//rewrite the polynomials in A1 as polynomials in K[theta]
774    tempmons = list();
775    for (j = 1; j<=size(list_azero[i]);j++)
776    {
777      tempmons = tempmons + list(list_azero[i][j]);
778    }
779    for (j = 1 ; j<=size(tempmons);j++)
780    {
781      entry = leadcoef(tempmons[j]);
782      for (k = 0; k < leadexp(tempmons[j])[2];k++)
783      {
784        entry = entry*(theta-k);
785      }
786      tempmons[j] = entry;
787    }
788    list_azero[i] = sum(tempmons);
789  }//rewrite the polynomials in A1 as polynomials in K[theta]
790  //Compute all permutations of the A0-part
791  dbprint(p,dbprintWhitespace +" Compute all permutations of the A_0-part with the first resp.
792the snd. variable");
793  list result;
794  int shift_sign;
795  int shift;
796  poly shiftvar;
797  if (size(list_not_azero)!=0)
798  {//Compute all possibilities to permute the x's resp. the y's in the list
799    if (list_not_azero[1] == x)
800    {//h had a negative weighted degree
801      shift_sign = 1;
802      shiftvar = x;
803    }//h had a negative weighted degree
804    else
805    {//h had a positive weighted degree
806      shift_sign = -1;
807      shiftvar = y;
808    }//h had a positive weighted degree
809    result = permpp(list_azero + list_not_azero);
810    for (i = 1; i<= size(result); i++)
811    {//adjust the a_0-parts
812      shift = 0;
813      for (j=1; j<=size(result[i]);j++)
814      {
815        if (result[i][j]==shiftvar)
816        {
817          shift = shift + shift_sign;
818        }
819        else
820        {
821          result[i][j] = subst(result[i][j],theta,theta + shift);
822        }
823      }
824    }//adjust the a_0-parts
825  }//Compute all possibilities to permute the x's resp. the y's in the list
826  else
827  {//The result is just all the permutations of the a_0-part
828    result = permpp(list_azero);
829  }//The result is just all the permutations of the a_0 part
830  if (size(result)==0)
831  {
832    return(result);
833  }
834  dbprint(p,dbprintWhitespace +" Done");
835  dbprint(p,dbprintWhitespace +" Searching for theta resp. theta+1 in the list and fact. them");
836  //Now we are going deeper and search for theta resp. theta + 1, substitute
837  //them by xy resp. yx and go on permuting
838  int found_theta;
839  int thetapos;
840  list leftpart;
841  list rightpart;
842  list lparts;
843  list rparts;
844  list tempadd;
845  for (i = 1; i<=size(result) ; i++)
846  {//checking every entry of result for theta or theta +1
847    found_theta = 0;
848    for(j=1;j<=size(result[i]);j++)
849    {
850      if (result[i][j]==theta)
851      {//the jth entry is theta and can be written as x*y
852        thetapos = j;
853        result[i]= insert(result[i],x,j-1);
854        j++;
855        result[i][j] = y;
856        found_theta = 1;
857        break;
858      }//the jth entry is theta and can be written as x*y
859      if(result[i][j] == theta +1)
860      {
861        thetapos = j;
862        result[i] = insert(result[i],y,j-1);
863        j++;
864        result[i][j] = x;
865        found_theta = 1;
866        break;
867      }
868    }
869    if (found_theta)
870    {//One entry was theta resp. theta +1
871      leftpart = result[i];
872      leftpart = leftpart[1..thetapos];
873      rightpart = result[i];
874      rightpart = rightpart[(thetapos+1)..size(rightpart)];
875      lparts = list(leftpart);
876      rparts = list(rightpart);
877      //first deal with the left part
878      if (leftpart[thetapos] == x)
879      {
880        shift_sign = 1;
881        shiftvar = x;
882      }
883      else
884      {
885        shift_sign = -1;
886        shiftvar = y;
887      }
888      for (j = size(leftpart); j>1;j--)
889      {//drip x resp. y
890        if (leftpart[j-1]==shiftvar)
891        {//commutative
892          j--;
893          continue;
894        }//commutative
895        if (deg(leftpart[j-1],intvec(-1,1,0))!=0)
896        {//stop here
897          break;
898        }//stop here
899        //Here, we can only have a a0- part
900        leftpart[j] = subst(leftpart[j-1],theta, theta + shift_sign);
901        leftpart[j-1] = shiftvar;
902        lparts = lparts + list(leftpart);
903      }//drip x resp. y
904      //and now deal with the right part
905      if (rightpart[1] == x)
906      {
907        shift_sign = 1;
908        shiftvar = x;
909      }
910      else
911      {
912        shift_sign = -1;
913        shiftvar = y;
914      }
915      for (j = 1 ; j < size(rightpart); j++)
916      {
917        if (rightpart[j+1] == shiftvar)
918        {
919          j++;
920          continue;
921        }
922        if (deg(rightpart[j+1],intvec(-1,1,0))!=0)
923        {
924          break;
925        }
926        rightpart[j] = subst(rightpart[j+1], theta, theta - shift_sign);
927        rightpart[j+1] = shiftvar;
928        rparts = rparts + list(rightpart);
929      }
930      //And now, we put all possibilities together
931      tempadd = list();
932      for (j = 1; j<=size(lparts); j++)
933      {
934        for (k = 1; k<=size(rparts);k++)
935        {
936          tempadd = tempadd + list(lparts[j]+rparts[k]);
937        }
938      }
939      tempadd = delete(tempadd,1); // The first entry is already in the list
940      result = result + tempadd;
941      continue; //We can may be not be done already with the ith entry
942    }//One entry was theta resp. theta +1
943  }//checking every entry of result for theta or theta +1
944  dbprint(p,dbprintWhitespace +" Done");
945  //map back to the basering
946  dbprint(p,dbprintWhitespace +" Mapping back everything to the basering");
947  setring(r);
948  map finalmap = tempRing, var(1), var(2),var(1)*var(2);
949  list result = finalmap(result);
950  for (i=1; i<=size(result);i++)
951  {//adding the K factor
952    result[i] = k_factor + result[i];
953  }//adding the k-factor
954  dbprint(p,dbprintWhitespace +" Done");
955  dbprint(p,dbprintWhitespace +" Delete double entries in the list.");
956  result = delete_dublicates_noteval(result);
957  dbprint(p,dbprintWhitespace +" Done");
958  return(result);
959}//proc HomogfacFirstWeylAll
960/* example */
961/* { */
962/*      "EXAMPLE:";echo=2; */
963/*      ring R = 0,(x,y),Ws(-1,1); */
964/*      def r = nc_algebra(1,1); */
965/*      setring(r); */
966/*      poly h = (x^2*y^2+1)*(x^4); */
967/*      homogfacFirstWeyl_all(h); */
968/* } */
969
970//==================================================*
971//Computes all permutations of a given list
972static proc perm(list l)
973"
974DEPRECATED
975"
976{//proc perm
977  int i; int j;
978  list tempresult;
979  list result;
980  if (size(l)==0)
981  {
982    return(list());
983  }
984  if (size(l)==1)
985  {
986    return(list(l));
987  }
988  for (i = 1; i<=size(l); i++ )
989  {
990    tempresult = perm(delete(l,i));
991    for (j = 1; j<=size(tempresult);j++)
992    {
993      tempresult[j] = list(l[i])+tempresult[j];
994    }
995    result = result+tempresult;
996  }
997  return(result);
998}//proc perm
999
1000//==================================================
1001//computes all permutations of a given list by
1002//ignoring equal entries (faster than perm)
1003static proc permpp(list l)
1004"
1005INPUT: A list with entries of a type, where the ==-operator is defined
1006OUTPUT: A list with all permutations of this given list.
1007"
1008{//proc permpp
1009  int i; int j;
1010  list tempresult;
1011  list l_without_double;
1012  list l_without_double_pos;
1013  int double_entry;
1014  list result;
1015  if (size(l)==0)
1016  {
1017    return(list());
1018  }
1019  if (size(l)==1)
1020  {
1021    return(list(l));
1022  }
1023  for (i = 1; i<=size(l);i++)
1024  {//Filling the list with unique entries
1025    double_entry = 0;
1026    for (j = 1; j<=size(l_without_double);j++)
1027    {
1028      if (l_without_double[j] == l[i])
1029      {
1030        double_entry = 1;
1031        break;
1032      }
1033    }
1034    if (!double_entry)
1035    {
1036      l_without_double = l_without_double + list(l[i]);
1037      l_without_double_pos = l_without_double_pos + list(i);
1038    }
1039  }//Filling the list with unique entries
1040  for (i = 1; i<=size(l_without_double); i++ )
1041  {
1042    tempresult = permpp(delete(l,l_without_double_pos[i]));
1043    for (j = 1; j<=size(tempresult);j++)
1044    {
1045      tempresult[j] = list(l_without_double[i])+tempresult[j];
1046    }
1047    result = result+tempresult;
1048  }
1049  return(result);
1050}//proc permpp
1051
1052//==================================================
1053//factorization of the first Weyl Algebra
1054
1055//The following procedure just serves the purpose to
1056//transform the input into an appropriate input for
1057//the procedure sfacwa, where the ring must contain the
1058//variables in a certain order.
1059proc facFirstWeyl(poly h)
1060"USAGE: facFirstWeyl(h); h a polynomial in the first Weyl algebra
1061RETURN: list
1062PURPOSE: compute all factorizations of a polynomial in the first Weyl algebra
1063THEORY: Implements the new algorithm by A. Heinle and V. Levandovskyy, see the thesis of A. Heinle
1064ASSUME: basering is the first Weyl algebra
1065NOTE: Every entry of the output list is a list with factors for one possible factorization.
1066The first factor is always a constant (1, if no nontrivial constant could be excluded).
1067EXAMPLE: example facFirstWeyl; shows examples
1068SEE ALSO: facSubWeyl, testNCfac, facFirstShift
1069"{//proc facFirstWeyl
1070  //Definition of printlevel variable
1071  int p = printlevel-voice+2;
1072  int i;
1073  string dbprintWhitespace = "";
1074  for (i = 1; i<=voice;i++)
1075  {dbprintWhitespace = dbprintWhitespace + " ";}
1076  dbprint(p,dbprintWhitespace +" Checking if the given algebra is a Weyl algebra");
1077  //Redefine the ring in my standard form
1078  if (!isWeyl())
1079  {//Our basering is not the Weyl algebra
1080    ERROR("Ring was not the first Weyl algebra");
1081    return(list());
1082  }//Our basering is not the Weyl algebra
1083  dbprint(p,dbprintWhitespace +" Successful");
1084  dbprint(p,dbprintWhitespace +" Checking, if the given ring is the first Weyl algebra");
1085  if(nvars(basering)!=2)
1086  {//Our basering is the Weyl algebra, but not the first
1087    ERROR("Ring is not the first Weyl algebra");
1088    return(list());
1089  }//Our basering is the Weyl algebra, but not the first
1090
1091  //A last check before we start the real business: Is h already given as a polynomial just
1092  //in one variable?
1093  if (deg(h,intvec(1,0))== 0 or deg(h,intvec(0,1)) == 0)
1094  {//h is in K[x] or in K[d]
1095    if (deg(h,intvec(1,0))== 0 and deg(h,intvec(0,1)) == 0)
1096    {//We just have a constant
1097      return(list(list(h)));
1098    }//We just have a constant
1099    dbprint(p,dbprintWhitespace+"Polynomial was given in one variable.
1100Performing commutative factorization.");
1101    int theCommVar;
1102    if (deg(h,intvec(1,0)) == 0)
1103    {//The second variable is the variable to factorize
1104      theCommVar = 2;
1105    }//The second variable is the variable to factorize
1106    else{theCommVar = 1;}
1107    def r = basering;
1108    ring tempRing = 0,(var(theCommVar)),dp;
1109    if (theCommVar == 1){map mapToCommutative = r,var(1),1;}
1110    else {map mapToCommutative = r,1,var(1);}
1111    poly h = mapToCommutative(h);
1112    list tempResult = factorize(h);
1113    list result = list(list());
1114    int j;
1115    for (i = 1; i<=size(tempResult[1]); i++)
1116    {
1117      for (j = 1; j<=tempResult[2][i]; j++)
1118      {
1119        result[1] = result[1] + list(tempResult[1][i]);
1120      }
1121    }
1122    //mapping back
1123    setring(r);
1124    map mapBackFromCommutative = tempRing,var(theCommVar);
1125    def result = mapBackFromCommutative(result);
1126    dbprint(p,dbprintWhitespace+"result:");
1127    dbprint(p,result);
1128    dbprint(p,dbprintWhitespace+"Computing all permutations of this factorization");
1129    poly constantFactor = result[1][1];
1130    result[1] = delete(result[1],1);//Deleting the constant factor
1131    result=permpp(result[1]);
1132    for (i = 1; i<=size(result);i++)
1133    {//Insert constant factor
1134      result[i] = insert(result[i],constantFactor);
1135    }//Insert constant factor
1136    dbprint(p,dbprintWhitespace+"Done.");
1137    return(result);
1138  }//h is in K[x] or in K[d]
1139
1140
1141  dbprint(p,dbprintWhitespace +" Successful");
1142  list result = list();
1143  int j; int k; int l; //counter
1144  if (ringlist(basering)[6][1,2] == -1) //manual of ringlist will tell you why
1145  {
1146    dbprint(p,dbprintWhitespace +" positions of the variables have to be switched");
1147    def r = basering;
1148    ring tempRing = ringlist(r)[1][1],(x,y),Ws(-1,1); // very strange:
1149    // setting Wp(-1,1) leads to SegFault; to clarify why!!!
1150    def NTR = nc_algebra(1,1);
1151    setring NTR ;
1152    map transf = r, var(2), var(1);
1153    dbprint(p,dbprintWhitespace +" Successful");
1154    list resulttemp = sfacwa(h);
1155    setring(r);
1156    map transfback = NTR, var(2),var(1);
1157    result = transfback(resulttemp);
1158  }
1159  else
1160  {
1161    dbprint(p, dbprintWhitespace +" factorization of the polynomial with the routine sfacwa");
1162    result = sfacwa(h);
1163    dbprint(p,dbprintWhitespace +" Done");
1164  }
1165  dbprint(p,dbprintWhitespace +" recursively check factors for irreducibility");
1166  list recursivetemp;
1167  int changedSomething;
1168  for(i = 1; i<=size(result);i++)
1169  {//recursively factorize factors
1170    if(size(result[i])>2)
1171    {//Nontrivial factorization
1172      for (j=2;j<=size(result[i]);j++)
1173      {//Factorize every factor
1174        recursivetemp = facFirstWeyl(result[i][j]);
1175        //if(size(recursivetemp)>1)
1176        //{//we have a nontrivial factorization
1177        changedSomething = 0;
1178        for(k=1; k<=size(recursivetemp);k++)
1179        {//insert factorized factors
1180          if(size(recursivetemp[k])>2)
1181          {//nontrivial
1182            changedSomething = 1;
1183            result = insert(result,result[i],i);
1184            for(l = size(recursivetemp[k]);l>=2;l--)
1185            {
1186              result[i+1] = insert(result[i+1],recursivetemp[k][l],j);
1187            }
1188            result[i+1] = delete(result[i+1],j);
1189          }//nontrivial
1190        }//insert factorized factors
1191        if (changedSomething)
1192        {
1193          result = delete(result,i);
1194        }
1195        //}//we have a nontrivial factorization
1196      }//Factorize every factor
1197    }//Nontrivial factorization
1198  }//recursively factorize factors
1199  dbprint(p,dbprintWhitespace +" Done");
1200  if (size(result)==0)
1201  {//only the trivial factorization could be found
1202    result = list(list(1,h));
1203  }//only the trivial factorization could be found
1204  //now, refine the possible redundant list
1205  return( delete_dublicates_noteval(result) );
1206}//proc facFirstWeyl
1207example
1208{
1209  "EXAMPLE:";echo=2;
1210  ring R = 0,(x,y),dp;
1211  def r = nc_algebra(1,1);
1212  setring(r);
1213  poly h = (x^2*y^2+x)*(x+1);
1214  facFirstWeyl(h);
1215}
1216
1217//////////////////////////////////////////////////
1218/////BRANDNEW!!!!////////////////////
1219//////////////////////////////////////////////////
1220
1221static proc sfacwa(poly h)
1222"INPUT: A polynomial h in the first Weyl algebra
1223OUTPUT: A list of factorizations, where the factors might still be reducible.
1224ASSUMPTIONS:
1225- Our basering is the first Weyl algebra; the x is the first variable,
1226  the differential operator the second.
1227"
1228{//proc sfacwa
1229  int i; int j; int k;
1230  int p = printlevel-voice+2;
1231  string dbprintWhitespace = "";
1232  number commonCoefficient = content(h);
1233  for (i = 1; i<=voice;i++)
1234  {dbprintWhitespace = dbprintWhitespace + " ";}
1235  dbprint(p,dbprintWhitespace + " Extracting homogeneous left and right factors");
1236  if(homogwithorder(h,intvec(-1,1)))
1237  {//we are already dealing with a -1,1 homogeneous poly
1238    dbprint(p,dbprintWhitespace+" Given polynomial is -1,1 homogeneous. Start homog.
1239fac. and ret. its result");
1240    return(homogfacFirstWeyl_all(h));
1241  }//we are already dealing with a -1,1 homogeneous poly
1242  list resulttemp = extractHomogeneousDivisors(h/commonCoefficient);
1243  //resulttemp = resulttemp + list(list(h/commonCoefficient));
1244  list inhomogeneousFactorsToFactorize;
1245  int isAlreadyInInhomogList;
1246  dbprint(p,dbprintWhitespace +" Done");
1247  dbprint(p,dbprintWhitespace +" Making Set of inhomogeneous polynomials we have to factorize.");
1248  for (i = 1; i<=size(resulttemp); i++)
1249  {//Going through all different kinds of factorizations where we extracted homogeneous factors
1250    for (j = 1;j<=size(resulttemp[i]);j++)
1251    {//searching for the inhomogeneous factor
1252      if (!homogwithorder(resulttemp[i][j],intvec(-1,1)))
1253      {//We have found our candidate
1254        isAlreadyInInhomogList = 0;
1255        for (k = 1; k<=size(inhomogeneousFactorsToFactorize);k++)
1256        {//Checking if our candidate is already in our tofactorize-list
1257          if (inhomogeneousFactorsToFactorize[k]==resulttemp[i][j])
1258          {//The candidate was already in the list
1259            isAlreadyInInhomogList = 1;
1260            break;
1261          }//The candidate was already in the list
1262        }//Checking if our candidate is already in our tofactorize-list
1263        if (!isAlreadyInInhomogList)
1264        {
1265          inhomogeneousFactorsToFactorize=inhomogeneousFactorsToFactorize + list(resulttemp[i][j]);
1266        }
1267      }//We have found our candidate
1268    }//searching for the inhomogeneous factor
1269  }//Going through all different kinds of factorizations where we extracted homogeneous factors
1270  dbprint(p,dbprintWhitespace +" Done");
1271  dbprint(p,dbprintWhitespace+ "Factorizing the different occuring inhomogeneous factors");
1272  for (i = 1; i<= size(inhomogeneousFactorsToFactorize); i++)
1273  {//Factorizing all kinds of inhomogeneous factors
1274    inhomogeneousFactorsToFactorize[i] = sfacwa2(inhomogeneousFactorsToFactorize[i]);
1275    for (j = 1; j<=size(inhomogeneousFactorsToFactorize[i]);j++)
1276    {//Deleting the leading coefficient since we don't need him
1277      if (deg(inhomogeneousFactorsToFactorize[i][j][1],intvec(1,1))==0)
1278      {
1279        inhomogeneousFactorsToFactorize[i][j] = delete(inhomogeneousFactorsToFactorize[i][j],1);
1280      }
1281    }//Deleting the leading coefficient since we don't need him
1282  }//Factorizing all kinds of inhomogeneous factors
1283  dbprint(p,dbprintWhitespace +" Done");
1284  dbprint(p,dbprintWhitespace +" Putting the factorizations in the lists");
1285  list result;
1286  int posInhomogPoly;
1287  int posInhomogFac;
1288  for (i = 1; i<=size(resulttemp); i++)
1289  {//going through all by now calculated factorizations
1290    for (j = 1;j<=size(resulttemp[i]); j++)
1291    {//Finding the inhomogeneous factor
1292      if (!homogwithorder(resulttemp[i][j],intvec(-1,1)))
1293      {//Found it
1294        posInhomogPoly = j;
1295        break;
1296      }//Found it
1297    }//Finding the inhomogeneous factor
1298    for (k = 1; k<=size(inhomogeneousFactorsToFactorize);k++)
1299    {//Finding the matching inhomogeneous factorization we already determined
1300      if(product(inhomogeneousFactorsToFactorize[k][1]) == resulttemp[i][j])
1301      {//found it
1302        posInhomogFac = k;
1303        break;
1304      }//Found it
1305    }//Finding the matching inhomogeneous factorization we already determined
1306    for (j = 1; j <= size(inhomogeneousFactorsToFactorize[posInhomogFac]); j++)
1307    {
1308      result = insert(result, resulttemp[i]);
1309      result[1] = delete(result[1],posInhomogPoly);
1310      for (k =size(inhomogeneousFactorsToFactorize[posInhomogFac][j]);k>=1; k--)
1311      {//Inserting factorizations
1312        result[1] = insert(result[1],inhomogeneousFactorsToFactorize[posInhomogFac][j][k],
1313                           posInhomogPoly-1);
1314      }//Inserting factorizations
1315    }
1316  }//going through all by now calculated factorizations
1317  dbprint(p,dbprintWhitespace +" Done");
1318  result = delete_dublicates_noteval(result);
1319  for (i = 1; i<=size(result);i++)
1320  {//Putting the content everywhere
1321    result[i] = insert(result[i],commonCoefficient);
1322  }//Putting the content everywhere
1323  return(result);
1324}//proc sfacwa
1325
1326static proc sfacwa2(poly h)
1327"
1328Subprocedure of sfacwa
1329Assumptions:
1330- h is not in K[x] or in K[d], or even in K. These cases are caught by the input
1331- The coefficients are integer values and the gcd of the coefficients is 1
1332"
1333{//proc sfacwa2
1334  int p=printlevel-voice+2; // for dbprint
1335  int i;
1336  string dbprintWhitespace = "";
1337  for (i = 1; i<=voice;i++)
1338  {dbprintWhitespace = dbprintWhitespace + " ";}
1339  intvec ivm11 = intvec(-1,1);
1340  intvec iv11 = intvec(1,1);
1341  intvec iv10 = intvec(1,0);
1342  intvec iv01 = intvec(0,1);
1343  intvec iv1m1 = intvec(1,-1);
1344  poly p_max; poly p_min; poly q_max; poly q_min;
1345  map invo = basering,-var(1),var(2);
1346  list calculatedRightFactors;
1347  if(homogwithorder(h,ivm11))
1348  {//Unnecessary how we are using it, but if one wants to use it on its own, we are stating it here
1349    dbprint(p,dbprintWhitespace+" Given polynomial is -1,1 homogeneous.
1350Start homog. fac. and ret. its result");
1351    return(homogfacFirstWeyl_all(h));
1352  }//Unnecessary how we are using it, but if one wants to use it on its own, we are stating it here
1353  list result = list();
1354  int j; int k; int l;
1355  dbprint(p,dbprintWhitespace+" Computing the degree-limits of the factorization");
1356  //end finding the limits
1357  dbprint(p,dbprintWhitespace+" Computing the maximal and the minimal
1358homogeneous part of the given polynomial");
1359  list M = computeCombinationsMinMaxHomog(h);
1360  dbprint(p,dbprintWhitespace+" Done.");
1361  dbprint(p,dbprintWhitespace+" Filtering invalid combinations in M.");
1362  for (i = 1 ; i<= size(M); i++)
1363  {//filter valid combinations
1364    if (product(M[i]) == h)
1365    {//We have one factorization
1366      result = result + divides(M[i][1],h,invo,1);
1367      dbprint(p,dbprintWhitespace+"Result list updated:");
1368      dbprint(p,dbprintWhitespace+string(result));
1369      M = delete(M,i);
1370      continue;
1371    }//We have one factorization
1372  }//filter valid combinations
1373  dbprint(p,dbprintWhitespace+"Done.");
1374  dbprint(p,dbprintWhitespace+"The size of M is "+string(size(M)));
1375  for (i = 1; i<=size(M); i++)
1376  {//Iterate over all first combinations (p_max + p_min)(q_max + q_min)
1377    dbprint(p,dbprintWhitespace+" Combination No. "+string(i)+" in M:" );
1378    p_max = jet(M[i][1],deg(M[i][1],ivm11),ivm11)-jet(M[i][1],deg(M[i][1],ivm11)-1,ivm11);
1379    p_min = jet(M[i][1],deg(M[i][1],iv1m1),iv1m1)-jet(M[i][1],deg(M[i][1],iv1m1)-1,iv1m1);
1380    q_max = jet(M[i][2],deg(M[i][2],ivm11),ivm11)-jet(M[i][2],deg(M[i][2],ivm11)-1,ivm11);
1381    q_min = jet(M[i][2],deg(M[i][2],iv1m1),iv1m1)-jet(M[i][2],deg(M[i][2],iv1m1)-1,iv1m1);
1382    dbprint(p,dbprintWhitespace+" pmax = "+string(p_max));
1383    dbprint(p,dbprintWhitespace+" pmin = "+string(p_min));
1384    dbprint(p,dbprintWhitespace+" qmax = "+string(q_max));
1385    dbprint(p,dbprintWhitespace+" qmin = "+string(q_min));
1386    //Check, whether p_max + p_min or q_max and q_min are already left or right divisors.
1387    if (divides(p_min + p_max,h,invo))
1388    {
1389      dbprint(p,dbprintWhitespace+" Got one result.");
1390      result = result + divides(p_min + p_max,h,invo,1);
1391    }
1392    else
1393    {
1394      if (divides(q_min + q_max,h,invo))
1395      {
1396        dbprint(p,dbprintWhitespace+" Got one result.");
1397        result = result + divides(q_min + q_max, h , invo, 1);
1398      }
1399    }
1400    //Now the check, if deg(p_max) = deg(p_min)+1 (and the same with q_max and q_min)
1401
1402    if (deg(p_max, ivm11) == deg(p_min, ivm11) +1 or  deg(q_max, ivm11) == deg(q_min, ivm11) +1 )
1403    {//Therefore, p_max + p_min must be a left factor or we can dismiss the combination
1404      dbprint(p,dbprintWhitespace+" There are no homogeneous parts we can put between
1405pmax and pmin resp. qmax and qmin.");
1406      //TODO: Prove, that then also a valid right factor is not possible
1407      M = delete(M,i);
1408      continue;
1409    }//Therefore, p_max + p_min must be a left factor or we can dismiss the combination
1410
1411    //Done with the Check
1412
1413    //If we come here, there are still homogeneous parts to be added to p_max + p_min
1414    //AND to q_max and q_min in
1415    //order to obtain a real factor
1416    //We use the procedure determineRestOfHomogParts to find our q.
1417    dbprint(p,dbprintWhitespace+" Solving for the other homogeneous parts in q");
1418    calculatedRightFactors = determineRestOfHomogParts(p_max,p_min,q_max,q_min,h);
1419    dbprint(p,dbprintWhitespace+" Done with it. Found "+string(size(calculatedRightFactors))
1420            +" solutions.");
1421    for (j = 1; j<=size(calculatedRightFactors);j++)
1422    {//Check out whether we really have right factors of h in calculatedRightFactors
1423      if (divides(calculatedRightFactors[j],h,invo))
1424      {
1425        result = result + divides(calculatedRightFactors[j],h,invo,1);
1426      }
1427      else
1428      {
1429        dbprint(p,"Solution for max and min homog found, but not a divisor of h");
1430        //TODO: Proof, why this can happen.
1431      }
1432    }//Check out whether we really have right factors of h in calculatedRightFactors
1433  }//Iterate over all first combinations (p_max + p_min)(q_max + q_min)
1434
1435
1436  result = delete_dublicates_noteval(result);
1437  //print(M);
1438  if (size(result) == 0)
1439  {//no factorization found
1440    result = list(list(h));
1441  }//no factorization found
1442  return(result);
1443}//proc sfacwa2
1444
1445static proc determineRestOfHomogParts(poly pmax, poly pmin, poly qmax, poly qmin, poly h)
1446"INPUT: Polynomials p_max, p_min, q_max, q_min and h. The maximum homogeneous part h_max of h is
1447 given by p_max*pmin, the minimum homogeneous part h_min of h is given by p_min*q_min.
1448OUTPUT: A list of right factors q of h that have q_max and q_min as their maximum respectively
1449 minimum homogeneous part. Empty list, if those elements are not existent
1450ASSUMPTIONS:
1451 - deg(p_max,intvec(-1,1))>deg(p_min,intvec(-1,1)) +1
1452 - deg(q_max,intvec(-1,1))>deg(q_min,intvec(-1,1)) +1
1453 - p_max*q_max = h_max
1454 - p_min*q_min = h_min
1455 - The basering is the first Weyl algebra
1456"
1457{//proc determineRestOfHomogParts
1458  int p=printlevel-voice+2; // for dbprint
1459  string dbprintWhitespace = "";
1460  int i;
1461  for (i = 1; i<=voice;i++)
1462  {dbprintWhitespace = dbprintWhitespace + " ";}
1463  int kappa = Min(intvec(deg(h,intvec(1,0)), deg(h,intvec(0,1))));
1464  def R = basering;
1465  int n1 = deg(pmax,intvec(-1,1));
1466  int nk = -deg(pmin,intvec(1,-1));
1467  int m1 = deg(qmax,intvec(-1,1));
1468  int ml = -deg(qmin,intvec(1,-1));
1469  int j; int k;
1470  ideal mons;
1471
1472  dbprint(p,dbprintWhitespace+" Extracting zero homog. parts of pmax, qmax, pmin, qmin and h.");
1473  //Extracting the zero homogeneous part of the given polynomials
1474  ideal pandqZero = pmax,pmin,qmax,qmin;
1475  if (n1 > 0){pandqZero[1] = lift(var(2)^n1,pmax)[1,1];}
1476  else{if (n1 < 0){pandqZero[1] = lift(var(1)^(-n1),pmax)[1,1];}
1477    else{pandqZero[1] = pmax;}}
1478  if (nk > 0){pandqZero[2] = lift(var(2)^nk,pmin)[1,1];}
1479  else{if (nk < 0){pandqZero[2] = lift(var(1)^(-nk),pmin)[1,1];}
1480    else{pandqZero[2] = pmin;}}
1481  if (m1 > 0){pandqZero[3] = lift(var(2)^m1,qmax)[1,1];}
1482  else{if (m1 < 0){pandqZero[3] = lift(var(1)^(-m1),qmax)[1,1];}
1483    else{pandqZero[3] = qmax;}}
1484  if (ml > 0){pandqZero[4] = lift(var(2)^ml,qmin)[1,1];}
1485  else{if (ml < 0){pandqZero[4] = lift(var(1)^(-ml),qmin)[1,1];}
1486    else{pandqZero[4] = qmin;}}
1487  list hZeroinR = homogDistribution(h);
1488  for (i = 1; i<=size(hZeroinR);i++)
1489  {//Extracting the zero homogeneous parts of the homogeneous summands of h
1490    if (hZeroinR[i][1] > 0){hZeroinR[i][2] = lift(var(2)^hZeroinR[i][1],hZeroinR[i][2])[1,1];}
1491    if (hZeroinR[i][1] < 0){hZeroinR[i][2] = lift(var(1)^(-hZeroinR[i][1]),hZeroinR[i][2])[1,1];}
1492  }//Extracting the zero homogeneous parts of the homogeneous summands of h
1493  dbprint(p,dbprintWhitespace+" Done!");
1494  //Moving everything into the ring K[theta]
1495  dbprint(p,dbprintWhitespace+" Moving everything into the ring K[theta]");
1496  ring KTheta = 0,(x,d,theta),dp;
1497  map thetamap = R, x, d;
1498  poly entry;
1499  ideal mons;
1500  ideal pandqZero;
1501  list hZeroinKTheta;
1502  setring(R);
1503
1504  //Starting with p and q
1505  for (k=1; k<=4; k++)
1506  {//Transforming pmax(0),qmax(0),pmin(0),qmin(0) in theta-polys
1507    mons = ideal();
1508    for(i = 1; i<=size(pandqZero[k]);i++)
1509    {//Putting the monomials in a list
1510      mons[size(mons)+1] = pandqZero[k][i];
1511    }//Putting the monomials in a list
1512    setring(KTheta);
1513    mons = thetamap(mons);
1514    for (i = 1; i<=size(mons);i++)
1515    {//transforming the monomials as monomials in theta
1516      entry = leadcoef(mons[i]);
1517      for (j = 0; j<leadexp(mons[i])[2];j++)
1518      {
1519        entry = entry * (theta-j);
1520      }
1521      mons[i] = entry;
1522    }//transforming the monomials as monomials in theta
1523    pandqZero[size(pandqZero)+1] = sum(mons);
1524    setring(R);
1525  }//Transforming pmax(0),qmax(0),pmin(0),qmin(0) in theta-polys
1526
1527  //Now hZero
1528  for (k = size(hZeroinR); k>= 1;k--)
1529  {//Transforming the different homogeneous parts of h into polys in K[theta]
1530    mons = ideal();
1531    for(i = 1; i<=size(hZeroinR[k][2]);i++)
1532    {//Putting the monomials in a list
1533      mons[size(mons)+1] = hZeroinR[k][2][i];
1534    }//Putting the monomials in a list
1535    setring(KTheta);
1536    mons = thetamap(mons);
1537    for (i = 1; i<=size(mons);i++)
1538    {//transforming the monomials as monomials in theta
1539      entry = leadcoef(mons[i]);
1540      for (j = 0; j<leadexp(mons[i])[2];j++)
1541      {
1542        entry = entry * (theta-j);
1543      }
1544      mons[i] = entry;
1545    }//transforming the monomials as monomials in theta
1546    hZeroinKTheta = hZeroinKTheta + list(sum(mons));
1547    setring(R);
1548  }//Transforming the different homogeneous parts of h into polys in K[theta]
1549  dbprint(p,dbprintWhitespace+" Done!");
1550  //Making the solutionRing
1551  ring solutionRing = 0,(theta,q(0..(kappa+1)*(m1-ml-1)-1)),lp;
1552  dbprint(p,dbprintWhitespace+" Our solution ring is given by "+ string(solutionRing));
1553  //mapping the different ps and qs and HZeros
1554  dbprint(p,dbprintWhitespace+" Setting up our solution system.");
1555  list ps;
1556  ideal pandqZero = imap(KTheta,pandqZero);
1557  ps[1] = list(n1,pandqZero[1]);
1558  ps[n1-nk+1] = list(nk,pandqZero[2]);
1559  for (i = 2; i<=n1-nk; i++)
1560  {
1561    ps[i] = list(n1-i+1,0);
1562  }
1563  list qs;
1564  qs[1] = list(m1,pandqZero[3]);
1565  qs[m1-ml+1] = list(ml,pandqZero[4]);
1566  for (i = 2; i<=m1-ml; i++)
1567  {
1568    qs[i] = list(m1-i+1,0);
1569    for (j = 0; j<=kappa; j++)
1570    {
1571      qs[i][2] = qs[i][2] + q((i-2)*(kappa+1)+j)*theta^j;
1572    }
1573  }
1574  list hZero = imap(KTheta,hZeroinKTheta);
1575  for (i = 1; i<=size(hZero); i++)
1576  {
1577    hZero[i] = list(n1+m1-i+1,hZero[i]);
1578  }
1579
1580  //writing and solving the system
1581  list lhs;
1582  lhs[1] = list(ps[1][2],1);
1583  list rhs;
1584  rhs[n1-nk+1] = list(ps[size(ps)][2],1);
1585  for (i = 2; i<= n1-nk+1;i++)
1586  {
1587    lhs[i] = list(hZero[i][2],subst(qs[1][2],theta,theta+n1-i+1)*gammaForTheta(ps[i][1],qs[1][1]));
1588    rhs[n1-nk-i+2] = list(hZero[size(hZero)-i+1][2],subst(qs[m1-ml+1][2],theta,
1589                          theta+nk+i-1)*gammaForTheta(ps[n1-nk-i+2][1],qs[m1-ml+1][1]));
1590    for (j = 1; j<i; j++)
1591    {
1592      for (k = 1; k<=size(qs);k++)
1593      {
1594        if(ps[j][1]+qs[k][1] == hZero[i][1])
1595        {
1596          lhs[i][1] = lhs[i][1]*lhs[j][2];
1597          lhs[i][2] = lhs[i][2]*lhs[j][2];
1598          lhs[i][1] = lhs[i][1]-lhs[j][1]*subst(qs[k][2],theta, theta + n1- j +1)
1599            *gammaForTheta(ps[j][1],qs[k][1]);
1600        }
1601        if(ps[n1-nk+2-j][1] + qs[m1-ml+2-k][1] ==hZero[size(hZero)-i+1][1])
1602        {
1603          rhs[n1-nk-i+2][1] = rhs[n1-nk-i+2][1]*rhs[n1-nk+2-j][2];
1604          rhs[n1-nk-i+2][2] = rhs[n1-nk-i+2][2]*rhs[n1-nk+2-j][2];
1605          rhs[n1-nk-i+2][1] = rhs[n1-nk-i+2][1]-rhs[n1-nk+2-j][1]*subst(qs[m1-ml+2-k][2],theta,
1606                             theta + nk -j+1)*gammaForTheta(ps[n1-nk+2-j][1],qs[m1-ml+2-k][1]);
1607        }
1608      }
1609    }
1610  }
1611  list eqs;
1612  poly tempgcd;
1613  poly templhscoeff;
1614  poly temprhscoeff;
1615  for (i = 2; i<=n1-nk;i++)
1616  {
1617    if (gcd(rhs[i][2],lhs[i][2]) == 1)
1618    {
1619      eqs = eqs + list(lhs[i][1]*rhs[i][2] -rhs[i][1]*lhs[i][2]);
1620    }
1621    else
1622    {
1623      tempgcd = gcd(rhs[i][2],lhs[i][2]);
1624      templhscoeff = quotient(rhs[i][2],tempgcd)[1];
1625      temprhscoeff = quotient(lhs[i][2],tempgcd)[1];
1626      eqs = eqs + list(lhs[i][1]*templhscoeff -rhs[i][1]*temprhscoeff);
1627    }
1628  }
1629  matrix tempCoefMatrix;
1630  ideal solutionSystemforqs;
1631  for (i= 1; i<=size(eqs); i++)
1632  {
1633    tempCoefMatrix = coef(eqs[i],theta);
1634    solutionSystemforqs = solutionSystemforqs + ideal(submat(tempCoefMatrix,intvec(2),
1635                                                             intvec(1..ncols(tempCoefMatrix))));
1636  }
1637  dbprint(p,dbprintWhitespace+" Solution system for the coefficients of q is given by:");
1638  dbprint(p,solutionSystemforqs);
1639  option(redSB);
1640  dbprint(p,dbprintWhitespace+" Calculating reduced Groebner Basis of that system.");
1641  solutionSystemforqs = std(solutionSystemforqs);
1642  dbprint(p,dbprintWhitespace+" Done!, the solution for the system is:");
1643  dbprint(p,dbprintWhitespace+string(solutionSystemforqs));
1644  if(vdim(std(solutionSystemforqs+theta))==0)
1645  {//No solution in this case. Return the empty list
1646    dbprint(p,dbprintWhitespace+"The Groebner Basis of the solution system was <1>.");
1647    setring(R);
1648    return(list());
1649  }//No solution in this case. Return the empty list
1650  if(vdim(std(solutionSystemforqs+theta))==-1)
1651  {//My conjecture is that this would never happen
1652    //ERROR("This is an counterexample to your conjecture. We have infinitely many solutions");
1653    //TODO: See, what we would do here
1654    dbprint(p,dbprintWhitespace+"There are infinitely many solution to this system.
1655We will return the empty list.");
1656    setring(R);
1657    return(list());
1658  }//My conjecture is that this would never happen
1659  else
1660  {//We have finitely many solutions
1661    if(vdim(std(solutionSystemforqs+theta))==1)
1662    {//exactly one solution
1663      for (i = 2; i<= size(qs)-1;i++)
1664      {
1665        qs[i][2] = NF(qs[i][2],solutionSystemforqs);
1666      }
1667      setring(R);
1668      map backFromSolutionRing = solutionRing,var(1)*var(2);
1669      list qs = backFromSolutionRing(qs);
1670      list result = list(0);
1671      for (i = 1; i<=size(qs); i++)
1672      {
1673        if (qs[i][1]>0){qs[i][2] = qs[i][2]*var(2)^qs[i][1];}
1674        if (qs[i][1]<0){qs[i][2] = qs[i][2]*var(1)^(-qs[i][1]);}
1675        result[1] = result[1] + qs[i][2];
1676      }
1677      dbprint(p,dbprintWhitespace+"Found one unique solution. Returning the result.");
1678      return(result);
1679    }//exactly one solution
1680    else
1681    {//We have more than one solution, but finitely many
1682      dbprint(p,dbprintWhitespace+"Finitely many, but more than one solution.
1683Right now the conjecture is that this cannot happen.");
1684      dbprint(p,dbprintWhitespace+"Yay to counterexample :-) We can have more than one solution.");
1685      //TODO: Some theoretical work why this can never happan
1686      return(list());
1687    }//We have more than one solution, but finitely many
1688  }//We have finitely many solutions
1689}//proc determineRestOfHomogParts
1690
1691static proc gammaForTheta(int j1,int j2)
1692"
1693INPUT: Two integers j1 and j2
1694OUTPUT: A polynomial in the first variable of the given ring. It calculates the following function:
1695   / 1,                                                if j1,j2>0 or j1,j2 <= 0
1696   | prod_{kappa = 0}^{|j1|-1}(var(1)-kappa),          if j1<0, j2>0, |j1|<=|j2|
1697gamma_{j1,j2}:= <  prod_{kappa = 0}^{j2-1}(var(1)-kappa-|j1|+|j2|),  if j1<0, j2>0, |j1|>|j2|
1698   | prod_{kappa = 1}^{j1}(var(1)+kappa),              if j1>0, j2<0, |j1|<=|j2|
1699   \ prod_{kappa = 1}^{|j2|}(\var(1)+kappa+|j1|-|j2|), if j1>0, j2<0, |j1|>|j2|
1700ASSUMPTION:
1701- Ring has at least one variable
1702"
1703{//gammaForTheta
1704  if (j1<=0 && j2 <=0) {return(1);}
1705  if (j1>=0 && j2 >=0){return(1);}
1706  poly result;
1707  int i;
1708  if (j1<0 && j2>0)
1709  {//case 2 or 3 from description above
1710    if (absValue(j1)<=absValue(j2))
1711    {//Case 2 holds here
1712      result = 1;
1713      for (i = 0;i<absValue(j1);i++)
1714      {
1715        result = result*(var(1)-i);
1716      }
1717      return(result);
1718    }//Case 2 holds here
1719    else
1720    {//Case 3 holds here
1721      result = 1;
1722      for (i = 0; i<j2; i++)
1723      {
1724        result = result*(var(1)-i-absValue(j1)+absValue(j2));
1725      }
1726      return(result);
1727    }//Case 3 holds here
1728  }//case 2 or 3 from description above
1729  else
1730  {//Case 4 or 5 from description above hold
1731    if (absValue(j1)<=absValue(j2))
1732    {//Case 4 holds
1733      result = 1;
1734      for (i = 1; i<=j1; i++)
1735      {
1736        result = result*(var(1)+i);
1737      }
1738      return(result);
1739    }//Case 4 holds
1740    else
1741    {//Case 5 holds
1742      result = 1;
1743      for (i = 1; i<=absValue(j2); i++)
1744      {
1745        result = result*(var(1)+i+absValue(j1)-absValue(j2));
1746      }
1747      return(result);
1748    }//Case 5 holds
1749  }//Case 4 or 5 from description above hold
1750}//gammaForTheta
1751
1752static proc extractHomogeneousDivisors(poly h)
1753"INPUT: A polynomial h in the first Weyl algebra
1754OUTPUT: If h is homogeneous, then all factorizations of h are returned.
1755 If h is inhomogeneous, then a list l is returned whose entries
1756 are again lists k = [k_1,...,k_n], where k_1*...*k_n = h and there
1757 exists an i in {1,...,n}, such that k_i is inhomogeneous and there
1758 is no homogeneous polynomial that divides this k_i neither from the
1759 left nor from the right. All the other entries in k are homogeneous
1760 polynomials.
1761"
1762{//extractHomogeneousDivisors
1763  int p=printlevel-voice+2; // for dbprint
1764  string dbprintWhitespace = "";
1765  int i; int j; int k; int l;
1766  for (i = 1; i<=voice;i++)
1767  {dbprintWhitespace = dbprintWhitespace + " ";}
1768  if (homogwithorder(h,intvec(-1,1)))
1769  {//given polynomial was homogeneous already
1770    dbprint(p,dbprintWhitespace+"Polynomial was homogeneous. Just returning all factorizations.");
1771    return(homogfacFirstWeyl_all(h));
1772  }//given polynomial was homogeneous already
1773  list result;
1774  dbprint(p,dbprintWhitespace+"Calculating list with all homogeneous left divisors extracted");
1775  list leftDivisionPossibilities = extractHomogeneousDivisorsLeft(h);
1776  dbprint(p,dbprintWhitespace+"Done. The result is:");
1777  dbprint(p,leftDivisionPossibilities);
1778  dbprint(p,dbprintWhitespace+"Calculating list with all homogeneous Right divisors extracted");
1779  list rightDivisionPossibilities = extractHomogeneousDivisorsRight(h);
1780  dbprint(p,dbprintWhitespace+"Done. The result is:");
1781  dbprint(p,rightDivisionPossibilities);
1782  list tempList;
1783  dbprint(p,dbprintWhitespace+"Calculating remaining right and left homogeneous divisors");
1784  for (i = 1; i<=size(leftDivisionPossibilities); i++)
1785  {//iterating through the list with extracted left divisors
1786    tempList = extractHomogeneousDivisorsRight
1787      (leftDivisionPossibilities[i][size(leftDivisionPossibilities[i])]);
1788    leftDivisionPossibilities[i] = delete(leftDivisionPossibilities[i],
1789                                          size(leftDivisionPossibilities[i]));
1790    for (j=1;j<=size(tempList);j++)
1791    {//Updating the list for Result
1792      tempList[j] = leftDivisionPossibilities[i] + tempList[j];
1793    }//Updating the list for Result
1794    result = result + tempList;
1795  }//iterating through the list with extracted left divisors
1796  for (i = 1; i<=size(rightDivisionPossibilities); i++)
1797  {//iterating through the list with extracted left divisors
1798    tempList = extractHomogeneousDivisorsLeft(rightDivisionPossibilities[i][1]);
1799    rightDivisionPossibilities[i] = delete(rightDivisionPossibilities[i],1);
1800    for (j=1;j<=size(tempList);j++)
1801    {//Updating the list for Result
1802      tempList[j] =  tempList[j]+rightDivisionPossibilities[i];
1803    }//Updating the list for Result
1804    result = result + tempList;
1805  }//iterating through the list with extracted left divisors
1806  dbprint(p,dbprintWhitespace+"Done");
1807  int posInhomog;
1808  poly hath = 1;
1809  list tempResult;
1810  dbprint(p,dbprintWhitespace+"Checking if we can swap left resp. right
1811divisors and updating result.");
1812  for (i = 1; i<= size(result); i++)
1813  {//Checking if we can swap left resp. right divisors
1814    for (j = 1; j<=size(result[i]);j++)
1815    {//finding the position of the inhomogeneous element in the list
1816      if(!homogwithorder(result[i][j],intvec(-1,1)))
1817      {
1818        posInhomog = j;
1819        break;
1820      }
1821    }//finding the position of the inhomogeneous element in the list
1822    hath = result[i][posInhomog];
1823    for(j=posInhomog-1;j>=1;j--)
1824    {
1825      hath = result[i][j]*hath;
1826      tempList = extractHomogeneousDivisorsRight(hath);
1827      if(size(tempList[1])==1)
1828      {//We could not swap this element to the right
1829        break;
1830      }//We could not swap this element to the right
1831      dbprint(p,dbprintWhitespace+"A swapping (left) of an element was possible");
1832      for(k = 1; k<=size(tempList);k++)
1833      {
1834        tempResult = insert(tempResult,result[i]);
1835        for (l = j;l<=posInhomog;l++)
1836        {
1837          tempResult[1] = delete(tempResult[1],j);
1838        }
1839        for (l = size(tempList[k]);l>=1;l--)
1840        {
1841          tempResult[1] = insert(tempResult[1],tempList[k][l],j-1);
1842        }
1843      }
1844    }
1845    hath = result[i][posInhomog];
1846    for(j=posInhomog+1;j<=size(result[i]);j++)
1847    {
1848      hath = hath*result[i][j];
1849      tempList = extractHomogeneousDivisorsLeft(hath);
1850      if(size(tempList[1])==1)
1851      {//We could not swap this element to the right
1852        break;
1853      }//We could not swap this element to the right
1854      dbprint(p,dbprintWhitespace+"A swapping (right) of an element was possible");
1855      for(k = 1; k<=size(tempList);k++)
1856      {
1857        tempResult = insert(tempResult,result[i]);
1858        for (l=posInhomog; l<=j;l++)
1859        {
1860          tempResult[1] = delete(tempResult[1],posInhomog);
1861        }
1862        for (l = size(tempList[k]);l>=1;l--)
1863        {
1864          tempResult[1] = insert(tempResult[1],tempList[k][l],posInhomog-1);
1865        }
1866      }
1867    }
1868  }//Checking if we can swap left resp. right divisors
1869  result = result + tempResult;
1870  result = delete_dublicates_noteval(result);
1871  return(result);
1872}//extractHomogeneousDivisors
1873
1874static proc extractHomogeneousDivisorsLeft(poly h)
1875"INPUT: A polynomial h in the first Weyl algebra
1876OUTPUT: If h is homogeneous, then all factorizations of h are returned.
1877 If h is inhomogeneous, then a list l is returned whose entries
1878 are again lists k = [k_1,...,k_n], where k_1*...*k_n = h.
1879 The entry k_n is inhomogeneous and has no other homogeneous
1880 left divisors any more.
1881 All the other entries in k are homogeneous
1882 polynomials.
1883"
1884{//extractHomogeneousDivisorsLeft
1885  int p=printlevel-voice+2; // for dbprint
1886  string dbprintWhitespace = "";
1887  int i;int j; int k;
1888  list result;
1889  poly hath;
1890  list recResult;
1891  map invo = basering,-var(1),var(2);
1892  for (i = 1; i<=voice;i++)
1893  {dbprintWhitespace = dbprintWhitespace + " ";}
1894  if (homogwithorder(h,intvec(-1,1)))
1895  {//given polynomial was homogeneous already
1896    dbprint(p,dbprintWhitespace+"Polynomial was homogeneous. Just returning all factorizations.");
1897    return(homogfacFirstWeyl_all(h));
1898  }//given polynomial was homogeneous already
1899  list hlist = homogDistribution(h);
1900  dbprint(p,dbprintWhitespace+ " Computing factorizations of all homogeneous summands.");
1901  for (i = 1; i<= size(hlist); i++)
1902  {
1903    hlist[i] = homogfacFirstWeyl_all(hlist[i][2]);
1904    if (size(hlist[i][1])==1)
1905    {//One homogeneous part just has a trivial factorization
1906      if(hlist[i][1][1] == 0)
1907      {
1908        hlist = delete(hlist,i);
1909        continue;
1910      }
1911      else
1912      {
1913        return(list(list(h)));
1914      }
1915    }//One homogeneous part just has a trivial factorization
1916  }
1917  dbprint(p,dbprintWhitespace+ " Done.");
1918  dbprint(p,dbprintWhitespace+ " Trying to find Left divisors");
1919  list alreadyConsideredCandidates;
1920  poly candidate;
1921  int isCandidate;
1922  for (i = 1; i<=size(hlist[1]);i++)
1923  {//Finding candidates for homogeneous left divisors of h
1924    candidate = hlist[1][i][2];
1925    isCandidate = 0;
1926    for (j=1;j<=size(alreadyConsideredCandidates);j++)
1927    {
1928      if(alreadyConsideredCandidates[j] == candidate)
1929      {
1930        isCandidate =1;
1931        break;
1932      }
1933    }
1934    if(isCandidate)
1935    {
1936      i++;
1937      continue;
1938    }
1939    else
1940    {
1941      alreadyConsideredCandidates = alreadyConsideredCandidates + list(candidate);
1942    }
1943    dbprint(p,dbprintWhitespace+"Checking if "+string(candidate)+" is a homogeneous left divisor");
1944    for (j = 2; j<=size(hlist);j++)
1945    {//Iterating through the other homogeneous parts
1946      isCandidate = 0;
1947      for(k=1; k<=size(hlist[j]);k++)
1948      {
1949        if(hlist[j][k][2]==candidate)
1950        {
1951          isCandidate = 1;
1952          break;
1953        }
1954      }
1955      if(!isCandidate)
1956      {
1957        break;
1958      }
1959    }//Iterating through the other homogeneous parts
1960    if(isCandidate)
1961    {//candidate was really a left divisor
1962      dbprint(p,dbprintWhitespace+string(candidate)+" is a homogeneous left divisor");
1963      hath = involution(lift(involution(candidate,invo),involution(h,invo))[1,1],invo);
1964      recResult = extractHomogeneousDivisorsLeft(hath);
1965      for (j = 1; j<=size(recResult); j++)
1966      {
1967        recResult[j] = insert(recResult[j],candidate);
1968      }
1969      result = result + recResult;
1970    }//Candidate was really a left divisor
1971  }//Finding candidates for homogeneous left divisors of h
1972  if (size(result)==0)
1973  {
1974    return(list(list(h)));
1975  }
1976  return(result);
1977}//extractHomogeneousDivisorsLeft
1978
1979static proc extractHomogeneousDivisorsRight(poly h)
1980"INPUT: A polynomial h in the first Weyl algebra
1981OUTPUT: If h is homogeneous, then all factorizations of h are returned.
1982 If h is inhomogeneous, then a list l is returned whose entries
1983 are again lists k = [k_1,...,k_n], where k_1*...*k_n = h.
1984 The entry k_1 is inhomogeneous and has no other homogeneous
1985 right divisors any more.
1986 All the other entries in k are homogeneous
1987 polynomials.
1988"
1989{//extractHomogeneousDivisorsRight
1990  int p=printlevel-voice+2; // for dbprint
1991  string dbprintWhitespace = "";
1992  int i;int j; int k;
1993  list result;
1994  poly hath;
1995  list recResult;
1996  for (i = 1; i<=voice;i++)
1997  {dbprintWhitespace = dbprintWhitespace + " ";}
1998  if (homogwithorder(h,intvec(-1,1)))
1999  {//given polynomial was homogeneous already
2000    dbprint(p,dbprintWhitespace+"Polynomial was homogeneous. Just returning all factorizations.");
2001    return(homogfacFirstWeyl_all(h));
2002  }//given polynomial was homogeneous already
2003  list hlist = homogDistribution(h);
2004  dbprint(p,dbprintWhitespace+ " Computing factorizations of all homogeneous summands.");
2005  for (i = 1; i<= size(hlist); i++)
2006  {
2007    hlist[i] = homogfacFirstWeyl_all(hlist[i][2]);
2008    if (size(hlist[i][1])==1)
2009    {//One homogeneous part just has a trivial factorization
2010      if(hlist[i][1][1] == 0)
2011      {
2012        hlist = delete(hlist,i);
2013        continue;
2014      }
2015      else
2016      {
2017        return(list(list(h)));
2018      }
2019    }//One homogeneous part just has a trivial factorization
2020  }
2021  dbprint(p,dbprintWhitespace+ " Done.");
2022  dbprint(p,dbprintWhitespace+ " Trying to find right divisors");
2023  list alreadyConsideredCandidates;
2024  poly candidate;
2025  int isCandidate;
2026  for (i = 1; i<=size(hlist[1]);i++)
2027  {//Finding candidates for homogeneous left divisors of h
2028    candidate = hlist[1][i][size(hlist[1][i])];
2029    isCandidate = 0;
2030    for (j=1;j<=size(alreadyConsideredCandidates);j++)
2031    {
2032      if(alreadyConsideredCandidates[j] == candidate)
2033      {
2034        isCandidate =1;
2035        break;
2036      }
2037    }
2038    if(isCandidate)
2039    {
2040      i++;
2041      continue;
2042    }
2043    else
2044    {
2045      alreadyConsideredCandidates = alreadyConsideredCandidates + list(candidate);
2046    }
2047    dbprint(p,dbprintWhitespace+"Checking if "+string(candidate)+" is a homogeneous r-divisor");
2048    for (j = 2; j<=size(hlist);j++)
2049    {//Iterating through the other homogeneous parts
2050      isCandidate = 0;
2051      for(k=1; k<=size(hlist[j]);k++)
2052      {
2053        if(hlist[j][k][size(hlist[j][k])]==candidate)
2054        {
2055          isCandidate = 1;
2056          break;
2057        }
2058      }
2059      if(!isCandidate)
2060      {
2061        break;
2062      }
2063    }//Iterating through the other homogeneous parts
2064    if(isCandidate)
2065    {//candidate was really a left divisor
2066      dbprint(p,dbprintWhitespace+string(candidate)+" is a homogeneous right divisor");
2067      hath = lift(candidate,h)[1,1];
2068      recResult = extractHomogeneousDivisorsRight(hath);
2069      for (j = 1; j<=size(recResult); j++)
2070      {
2071        recResult[j] = insert(recResult[j],candidate,size(recResult[j]));
2072      }
2073      result = result + recResult;
2074    }//Candidate was really a left divisor
2075  }//Finding candidates for homogeneous left divisors of h
2076  if (size(result)==0)
2077  {
2078    result = list(list(h));
2079  }
2080  return(result);
2081}//extractHomogeneousDivisorsLeft
2082
2083static proc fromZeroHomogToThetaPoly(poly h)
2084"
2085//DEPRECATED
2086INPUT: A polynomial h in the first Weyl algebra, homogeneous of degree 0
2087 OUTPUT: The ring Ktheta with a polynomial result representing h as polynomial in
2088  theta
2089 ASSUMPTIONS:
2090- h is homogeneous of degree 0 with respect to the [-1,1] weight vector
2091- The basering is the first Weyl algebra
2092"
2093{//proc fromZeroHomogToThetaPoly
2094  int i; int j;
2095  list mons;
2096  if(!homogwithorder(h,intvec(-1,1)))
2097  {//Input not a homogeneous polynomial causes an error
2098    ERROR("The input was not a homogeneous polynomial");
2099  }//Input not a homogeneous polynomial causes an error
2100  if(deg(h,intvec(-1,1))!=0)
2101  {//Input does not have degree 0
2102    ERROR("The input did not have degree 0");
2103  }//Input does not have degree 0
2104  for(i = 1; i<=size(h);i++)
2105  {//Putting the monomials in a list
2106    mons = mons+list(h[i]);
2107  }//Putting the monomials in a list
2108  ring KTheta = 0,(x,y,theta),dp;
2109  setring KTheta;
2110  map thetamap = r,x,y;
2111  list mons = thetamap(mons);
2112  poly entry;
2113  for (i = 1; i<=size(mons);i++)
2114  {//transforming the monomials as monomials in theta
2115    entry = leadcoef(mons[i]);
2116    for (j = 0; j<leadexp(mons[i])[2];j++)
2117    {
2118      entry = entry * (theta-j);
2119    }
2120    mons[i] = entry;
2121  }//transforming the monomials as monomials in theta
2122  poly result = sum(mons);
2123  keepring KTheta;
2124}//proc fromZeroHomogToThetaPoly
2125
2126static proc fromHomogDistributionListToPoly(list l)
2127"returns the corresponding polynomial to a given output of homogDistribution"
2128{//proc fromHomogDistributionListToPoly
2129  poly result = 0;
2130  int i;
2131  for (i = 1; i<=size(l);i++)
2132  {
2133    result = result + l[i][2];
2134  }
2135  return(result);
2136}//proc fromHomogDistributionListToPoly
2137
2138static proc divides(poly p1, poly p2,map invo, list #)
2139  "Tests, whether p1 divides p2 either from left or from right. The involution invo is needed
2140for checking both sides. The optional argument is needed in order to also return the other factor.
2141RETURN: If no optional argument is given, it will just return 1 or 0.
2142 Otherwise a list with at least one element
2143 Case 1: p1 does not divide p2 from any side. Then the output will be the empty list.
2144 Case 2: p2 does divide p2 from one side at least.
2145  Then it returns a list with tuples p,q, such that p or q equals p1 and
2146  pq = p2.
2147ASSUMPTIONS: - The map invo is an involution on the basering."
2148{//proc divides
2149  list result = list();
2150  poly tempfactor;
2151  if (involution(reduce(involution(p2,invo),std(involution(ideal(p1),invo))),invo)==0)
2152  {//p1 is a left divisor
2153    if(size(#)==0){return(1);}
2154    tempfactor = involution(lift(involution(p1,invo),involution(p2,invo))[1,1],invo);
2155    if (leadcoef(p1)<0 && leadcoef(tempfactor)<0)
2156    {//both have a negative leading coefficient
2157      result = result +list(list(1,-p1, -tempfactor));
2158    }//both have a negative leading coefficient
2159    else
2160    {
2161      if (leadcoef(p1)*leadcoef(tempfactor)<0)
2162      {//One of them has a negative leading coefficient
2163        if (leadcoef(p1)<0)
2164        {
2165          result = result + list(list(-1,-p1,tempfactor));
2166        }
2167        else
2168        {
2169          result = result + list(list(-1,p1,-tempfactor));
2170        }
2171      }//One of them has a negative leading coefficient
2172      else
2173      {//no negative coefficient at all
2174        result = result + list(list(1,p1,tempfactor));
2175      }//no negative coefficient at all
2176    }
2177  }//p1 is a left divisor
2178
2179  if (reduce(p2,std(ideal(p1))) == 0)
2180  {//p1 is  a right divisor
2181    if(size(#)==0){return(1);}
2182    tempfactor = lift(p1, p2)[1,1];
2183    if (leadcoef(p1)<0 && leadcoef(tempfactor)<0)
2184    {//both have a negative leading coefficient
2185      result = result +list(list(1, -tempfactor,-p1));
2186    }//both have a negative leading coefficient
2187    else
2188    {
2189      if (leadcoef(p1)*leadcoef(tempfactor)<0)
2190      {//One of them has a negative leading coefficient
2191        if (leadcoef(p1)<0)
2192        {
2193          result = result + list(list(-1,tempfactor,-p1));
2194        }
2195        else
2196        {
2197          result = result + list(list(-1,-tempfactor,p1));
2198        }
2199      }//One of them has a negative leading coefficient
2200      else
2201      {//no negative coefficient at all
2202        result = result + list(list(1,tempfactor,p1));
2203      }//no negative coefficient at all
2204    }
2205  }//p1 is already a right divisor
2206  if (size(#)==0){return(0);}
2207  return(result);
2208}//proc divides
2209
2210static proc computeCombinationsMinMaxHomog(poly h)
2211"Input: A polynomial h in the first Weyl Algebra
2212Output: Combinations of the form (p_max + p_min)(q_max + q_min), such that p_max, p_min,
2213 q_max and q_min are homogeneous and p_max*q_max equals the maximal homogeneous
2214 part in h, and p_max * q_max equals the minimal homogeneous part in h.
2215 h is not homogeneous.
2216"{//proc computeCombinationsMinMaxHomog
2217  intvec ivm11 = intvec(-1,1);
2218  intvec iv11 = intvec(1,1);
2219  intvec iv10 = intvec(1,0);
2220  intvec iv01 = intvec(0,1);
2221  intvec iv1m1 = intvec(1,-1);
2222  poly maxh = jet(h,deg(h,ivm11),ivm11)-jet(h,deg(h,ivm11)-1,ivm11);
2223  poly minh = jet(h,deg(h,iv1m1),iv1m1)-jet(h,deg(h,iv1m1)-1,iv1m1);
2224  list f1 = homogfacFirstWeyl_all(maxh);
2225  list f2 = homogfacFirstWeyl_all(minh);
2226  list result = list();
2227  int i;
2228  int j;
2229  //TODOs: Nur die kombinieren, die auch wirklich eine brauchbare Kombination sind.
2230  //Also, wir duerfen nicht aus den Geraden herausfliegen
2231  list pqmax = list();
2232  list pqmin = list();
2233  list tempList = list();
2234
2235  //First, we are going to deal with our most hated guys: The Coefficients.
2236  //
2237  list coeffTuplesMax = getAllCoeffTuplesComb(factorizeInt(int(f1[1][1])));
2238  //We can assume without loss of generality, that p_max has a
2239  //nonnegative leading coefficient
2240  for (i = 1; i<=size(coeffTuplesMax);i++)
2241  {//Deleting all tuples with negative entries for p_max
2242    if (coeffTuplesMax[i][1]<0)
2243    {
2244      coeffTuplesMax = delete(coeffTuplesMax,i);
2245      continue;
2246    }
2247  }//Deleting all tuples with negative entries for p_max
2248  list coeffTuplesMin = getAllCoeffTuplesComb(factorizeInt(int(f2[1][1])));
2249
2250  //Now, we will be actally dealing with the Combinations.
2251  //Let's start with the pqmax
2252  if (size(f1[1]) == 1)
2253  {//the maximal homogeneous factor is a constant
2254    pqmax = coeffTuplesMax;
2255  }//the maximal homogeneous factor is a constant
2256  else
2257  {//the maximal homogeneous factor is not a constant
2258    for (i = 1; i<=size(f1); i++)
2259    {//We can forget about the first coefficient now. Therefore we will delete him from the list.
2260      f1[i] = delete(f1[i],1);
2261      if(size(f1[i])==1)
2262      {//trivial thing
2263        for (j = 1; j<=size(coeffTuplesMax); j++)
2264        {
2265          pqmax = pqmax + list(list(coeffTuplesMax[j][1],coeffTuplesMax[j][2]*f1[i][1]));
2266          pqmax = pqmax + list(list(coeffTuplesMax[j][1]*f1[i][1],coeffTuplesMax[j][2]));
2267        }
2268        f1 = delete(f1,i);
2269        continue;
2270      }//trivial thing
2271    }//We can forget about the first coefficient now. Therefore we will delete him from the list.
2272    if (size(f1)>0)
2273    {
2274      tempList = getAllCombOfHomogFact(f1);
2275      for (i = 1; i<=size(tempList); i++)
2276      {//Every combination combined with the coefficient possibilities
2277        for (j = 1; j<=size(coeffTuplesMax); j++)
2278        {//iterating through the possible coefficient choices
2279          pqmax = pqmax + list(list(coeffTuplesMax[j][1]*tempList[i][1],
2280                                    coeffTuplesMax[j][2]*tempList[i][2]));
2281        }//iterating through the possible coefficient choices
2282      }//Every combination combined with the coefficient possibilities
2283      for (i = 1; i<=size(coeffTuplesMax); i++)
2284      {
2285        pqmax = pqmax + list(list(coeffTuplesMax[i][1],maxh/coeffTuplesMax[i][1]));
2286        pqmax = pqmax + list(list(maxh/coeffTuplesMax[i][2],coeffTuplesMax[i][2]));
2287      }
2288    }
2289  }//the maximal homogeneous factor is not a constant
2290  //Now we go to pqmin
2291  if (size(f2[1]) == 1)
2292  {//the minimal homogeneous factor is a constant
2293    pqmin = coeffTuplesMin;
2294  }//the minimal homogeneous factor is a constant
2295  else
2296  {//the minimal homogeneous factor is not a constant
2297    for (i = 1; i<=size(f2); i++)
2298    {//We can forget about the first coefficient now. Therefore we will delete him from the list.
2299      f2[i] = delete(f2[i],1);
2300      if(size(f2[i])==1)
2301      {//trivial thing
2302        for (j = 1; j<=size(coeffTuplesMin); j++)
2303        {
2304          pqmin = pqmin + list(list(coeffTuplesMin[j][1],coeffTuplesMin[j][2]*f2[i][1]));
2305          pqmin = pqmin + list(list(coeffTuplesMin[j][1]*f2[i][1],coeffTuplesMin[j][2]));
2306        }
2307        f2 = delete(f2,i);
2308        continue;
2309      }
2310    }//We can forget about the first coefficient now. Therefore we will delete him from the list.
2311    if(size(f2)>0)
2312    {
2313      tempList = getAllCombOfHomogFact(f2);
2314      for (i = 1; i<=size(tempList); i++)
2315      {//Every combination combined with the coefficient possibilities
2316        for (j = 1; j<=size(coeffTuplesMin); j++)
2317        {//iterating through the possible coefficient choices
2318          pqmin = pqmin + list(list(coeffTuplesMin[j][1]*tempList[i][1],
2319                                    coeffTuplesMin[j][2]*tempList[i][2]));
2320        }//iterating through the possible coefficient choices
2321      }//Every combination combined with the coefficient possibilities
2322      for (i = 1; i<=size(coeffTuplesMin); i++)
2323      {
2324        pqmin = pqmin + list(list(coeffTuplesMin[i][1],minh/coeffTuplesMin[i][1]));
2325        pqmin = pqmin + list(list(minh/coeffTuplesMin[i][2],coeffTuplesMin[i][2]));
2326      }
2327    }
2328  }//the minimal homogeneous factor is not a constant
2329
2330  //and now we combine them together to obtain all possibilities.
2331  for (i = 1; i<=size(pqmax); i++)
2332  {//iterate over the maximal homogeneous combination possibilities
2333    for (j = 1; j<=size(pqmin); j++)
2334    {//iterate over the minimal homogeneous combiniation possibilities
2335      if (deg(pqmax[i][1], ivm11)>=deg(pqmin[j][1],ivm11) and deg(pqmax[i][2],
2336                                                                  ivm11)>=deg(pqmin[j][2],ivm11))
2337      {
2338        if (pqmax[i][1]+pqmin[j][1]!=0 and pqmax[i][2]+pqmin[j][2]!=0)
2339        {
2340
2341          if (deg(h,ivm11)<=deg(h-(pqmax[i][1]+pqmin[j][1])*(pqmax[i][2]+pqmin[j][2]),ivm11))
2342          {
2343            j++;
2344            continue;
2345          }
2346          if (deg(h,iv1m1)<=deg(h-(pqmax[i][1]+pqmin[j][1])*(pqmax[i][2]+pqmin[j][2]),iv1m1))
2347          {
2348            j++;
2349            continue;
2350          }
2351          result = result +list(list(pqmax[i][1]+pqmin[j][1],pqmax[i][2]+pqmin[j][2]));
2352        }
2353      }
2354    }//iterate over the minimal homogeneous combiniation possibilities
2355  }//iterate over the maximal homogeneous combination possibilities
2356  //Now deleting double entries
2357  result = delete_dublicates_noteval(result);
2358  return(result);
2359}//proc computeCombinationsMinMaxHomog
2360
2361static proc getAllCombOfHomogFact(list l)
2362"Gets called in computeCombinationsMinMaxHomog. It gets a list of different homogeneous
2363factorizations of
2364one homogeneous polynomial and returns the possibilities to combine them into two factors.
2365Assumptions:
2366- The list does not contain the first coefficient.
2367- The list contains at least one list with two elements."
2368{//proc getAllCombOfHomogFact
2369  list result;
2370  list leftAndRightHandSides;
2371  int i; int j;
2372  list tempset;
2373  if (size(l)==1 and size(l[1])==2)
2374  {
2375    result = result + list(list(l[1][1],l[1][2]));
2376    return(result);
2377  }
2378  leftAndRightHandSides = getPossibilitiesForRightSides(l);
2379  for (i = 1; i<=size(leftAndRightHandSides); i++)
2380  {
2381    result =result+list(list(leftAndRightHandSides[i][1],product(leftAndRightHandSides[i][2][1])));
2382    //tidy up the right hand sides, because, if it is just one irreducible factor, we are done
2383    for (j = 1; j<=size(leftAndRightHandSides[i][2]);j++)
2384    {//Tidy up right hand sides
2385      if (size(leftAndRightHandSides[i][2][j])<2)
2386      {//Element can be dismissed
2387        leftAndRightHandSides[i][2] = delete(leftAndRightHandSides[i][2],j);
2388        continue;
2389      }//Element can be dismissed
2390    }//Tidy up right hand sides
2391    if (size(leftAndRightHandSides[i][2])>0)
2392    {
2393      tempset = getAllCombOfHomogFact(leftAndRightHandSides[i][2]);
2394      for (j = 1; j<=size(tempset);j++)
2395      {//multiplying the first factor with the left hand side
2396        result = result + list(list(leftAndRightHandSides[i][1]*tempset[j][1],tempset[j][2]));
2397      }//multiplying the first factor with the left hand side
2398    }
2399  }
2400  return(result);
2401}//proc getAllCombOfHomogFact
2402
2403static proc getPossibilitiesForRightSides(list l)
2404"Given a list of different factorizations l, this function returns a list of the form
2405(a,{(a_2,...,a_n)| (a,a_2,...,a_n) in A})"
2406{//getPossibilitiesForRightSide
2407  list templ = l;
2408  list result;
2409  poly firstElement;
2410  list rightSides;
2411  list tempRightSide;
2412  int i; int j;
2413  while (size(templ)>0)
2414  {
2415    firstElement = templ[1][1];
2416    rightSides = list();
2417    for (i = 1; i<= size(templ); i++)
2418    {
2419      if (templ[i][1] == firstElement)
2420      {//save the right sides
2421        tempRightSide = list();
2422        for (j = 2; j<=size(templ[i]);j++)
2423        {
2424          tempRightSide = tempRightSide + list(templ[i][j]);
2425        }
2426        if (size(tempRightSide)!=0)
2427        {
2428          rightSides = rightSides + list(tempRightSide);
2429        }
2430        templ = delete(templ,i);
2431        continue;
2432      }//save the right sides
2433    }
2434    result = result + list(list(firstElement,rightSides));
2435  }
2436  return(result);
2437}//getPossibilitiesForRightSide
2438
2439static proc getAllCoeffTuplesComb(list l)"
2440Given the output of factorizeInt ((a_1,...,a_n),(i_1,...,i_n)) , it returns all possible tuples
2441of the set {(a,b) | There exists an real N!=emptyset subset of {1,...,n}, such that
2442a = prod_{i \in N}a_i, b=prod_{i \not\in N} a_i}
2443Assumption: The list is sorted from smallest integer to highest.
2444- it is not the factorization of 0.
2445"
2446{//proc getAllCoeffTuplesComb
2447  list result;
2448  if (l[1][1] == 0)
2449  {
2450    ERROR("getAllCoeffTuplesComb: Zero Coefficients as leading and Tail Coeffs?
2451That is not possible. Something went wrong.");
2452  }
2453  if (size(l[1]) == 1)
2454  {//Trivial Factorization, just 1
2455    if (l[1][1] == 1)
2456    {
2457      return(list(list(1,1),list(-1,-1)));
2458    }
2459    else
2460    {
2461      return(list(list(-1,1),list(1,-1)));
2462    }
2463  }//Trivial Factorization, just 1
2464  if (size(l[1]) == 2 and l[2][2]==1)
2465  {//Just a prime number
2466    if (l[1][1] == 1)
2467    {
2468      result = list(list(l[1][2],1),list(1,l[1][2]));
2469      result = result + list(list(-l[1][2],-1),list(-1,-l[1][2]));
2470      return(result);
2471    }
2472    else
2473    {
2474      result = list(list(l[1][2],-1),list(1,-l[1][2]));
2475      result = result + list(list(-l[1][2],1),list(-1,l[1][2]));
2476      return(result);
2477    }
2478  }//Just a prime number
2479  //Now comes the interesting case: a product of primes
2480  list tempPrimeFactors;
2481  list tempPowersOfThem;
2482  int i;
2483  for (i = 2; i<=size(l[1]);i++)
2484  {//Removing the starting 1 or -1 to get the N's
2485    tempPrimeFactors[i-1] = l[1][i];
2486    tempPowersOfThem[i-1] = l[2][i];
2487  }//Removing the starting 1 or -1 to get the N's
2488  list Ns = getAllSubsetsN(list(tempPrimeFactors,tempPowersOfThem));
2489  list tempTuples;
2490  number productOfl = multiplyFactIntOutput(l);
2491  if (productOfl<0){productOfl = -productOfl;}
2492  tempTuples = tempTuples + list(list(1,productOfl),list(productOfl,1));
2493  for (i = 1; i<=size(Ns); i++)
2494  {
2495    if (productOfl/Ns[i]>Ns[i])
2496    {//TODO: BEWEISEN, dass das die einzigen Combos sind
2497      tempTuples = tempTuples + list(list(Ns[i],productOfl/Ns[i]),list(productOfl/Ns[i],Ns[i]));
2498    }//TODO: BEWEISEN, dass das die einzigen Combos sind
2499    if (productOfl/Ns[i]==Ns[i])
2500    {
2501      tempTuples = tempTuples + list(list(Ns[i],Ns[i]));
2502    }
2503  }
2504  //And now, it just remains to get the -1s and 1-s correctly to the tuples
2505  list tempEntry;
2506  if (l[1][1] == 1)
2507  {
2508    for (i = 1; i<=size(tempTuples);i++)
2509    {//Adding everything to result
2510      tempEntry = tempTuples[i];
2511      result = result + list(tempEntry);
2512      result = result + list(list(-tempEntry[1], -tempEntry[2]));
2513    }//Adding everyThing to Result
2514  }
2515  else
2516  {
2517    for (i = 1; i<=size(tempTuples);i++)
2518    {//Adding everything to result
2519      tempEntry = tempTuples[i];
2520      result = result + list(list(tempEntry[1],-tempEntry[2]));
2521      result = result + list(list(-tempEntry[1], tempEntry[2]));
2522    }//Adding everyThing to Result
2523  }
2524  return(result);
2525}//proc getAllCoeffTuplesComb
2526
2527static proc contains(list l, int elem)
2528"Assumption: l is sorted"
2529{//Binary Search in list
2530  if (size(l)<=1)
2531  {
2532    if(size(l) == 0){return(0);}
2533    if (l[1]!=elem){return(0);}
2534    else{return(1);}
2535  }
2536  int imax = size(l);
2537  int imin = 1;
2538  int imid;
2539  while(imax >= imin)
2540  {
2541    imid = (imin + imax)/2;
2542    if (l[imid] == elem){return(1);}
2543    if (l[imid] <elem) {imin = imid +1;}
2544    else{imax = imid -1;}
2545  }
2546  return(0)
2547    }//Binary Search in list
2548
2549static proc getAllSubsetsN(list l)
2550"
2551Assumptions:
2552- The list is containing two lists. They can be assumed to be outputs of the function
2553factorizeInt. They have at least one entry. If it is exactly one entry, the second intvec should
2554contain a value at least 2.
2555  "
2556{
2557  list primeFactors=l[1];
2558  list powersOfThem = l[2];
2559  int i;int j;
2560  //Casting the entries to be numbers
2561  for (i=1; i<=size(primeFactors); i++)
2562  {
2563    primeFactors[i] = number(primeFactors[i]);
2564    powersOfThem[i] = number(powersOfThem[i]);
2565  }
2566
2567  //Done
2568  list result;
2569  list tempPrimeFactors;
2570  list tempPowersOfThem;
2571  list tempset;
2572  if (sum(powersOfThem) <=2)
2573  {//Easy Case
2574    return(list(primeFactors[1]));
2575  }//Easy Case
2576  if (size(primeFactors)==1)
2577  {//Also Easy Case
2578    for (j = 1; j<powersOfThem[1]; j++)
2579    {
2580      result = result + list(primeFactors[1]^j);
2581    }
2582    return(result);
2583  }//Also Easy Case
2584  for (i = 1; i<= size(primeFactors); i++)
2585  {//Going through every entry
2586    result = result + list(primeFactors[i]);
2587    if (i == size(primeFactors))
2588    {
2589      for (j = 1;j<powersOfThem[i];j++)
2590      {
2591        result = result + list (primeFactors[i]^j);
2592      }
2593      break;
2594    }
2595    if (powersOfThem[i]==1)
2596    {
2597      for (j = i+1;j<=size(primeFactors);j++)
2598      {
2599        tempPrimeFactors[j-i] = primeFactors[j];
2600        tempPowersOfThem[j-i] = powersOfThem[j];
2601      }
2602    }
2603    else
2604    {
2605      for (j = i; j<=size(primeFactors);j++)
2606      {
2607        tempPrimeFactors[j-i+1] = primeFactors[j];
2608        tempPowersOfThem[j-i+1] = powersOfThem[j];
2609        tempPowersOfThem[1] = tempPowersOfThem[1]-1;
2610      }
2611    }
2612    tempset = getAllSubsetsN(list(tempPrimeFactors,tempPowersOfThem));
2613    for (j = 1; j<=size(tempset); j++)
2614    {
2615      result = result +list((tempset[j])*(primeFactors[i]));
2616    }
2617  }//Going through every entry
2618  result = sort(result)[1];
2619  result = delete_dublicates_noteval(result);
2620  return(result);
2621}
2622
2623static proc multiplyFactIntOutput(list l)
2624"Given the output of factorizeInt, this method computes the product of it."
2625{//proc multiplyFactIntOutput
2626  int i;
2627  number result = 1;
2628  for (i = 1; i<=size(l[1]); i++)
2629  {
2630    result = result*(l[1][i])^(l[2][i]);
2631  }
2632  return(result);
2633}//proc multiplyFactIntOutput
2634
2635static proc fromListToIntvec(list l)
2636"Converter from List to intvec"
2637{
2638  intvec result; int i;
2639  for (i = 1; i<=size(l); i++)
2640  {
2641    result[i] = l[i];
2642  }
2643  return(result);
2644}
2645
2646static proc fromIntvecToList(intvec l)"
2647Converter from intvec to list"
2648{//proc fromIntvecToList
2649  list result = list();
2650  int i;
2651  for (i = size(l); i>=1; i--)
2652  {
2653    result = insert(result, l[i]);
2654  }
2655  return(result);
2656}//proc fromIntvecToList
2657
2658
2659static proc factorizeInt(number n)
2660"Given an integer n, factorizeInt computes its factorization. The output is a list
2661containing two intvecs. The first contains the prime factors, the second its powers.
2662ASSUMPTIONS:
2663- n is given as integer number
2664"{
2665  if (n==0)
2666  {return(list(list(0),list(1)));}
2667  int i;
2668  list temp = primefactors(n);
2669  if (n<0)
2670  {list result = list(list(-1),list(1));}
2671  else
2672  {list result = list(list(1),list(1));}
2673  result[1] = result[1] + temp[1];
2674  result[2] = result[2] + temp[2];
2675  return(result);
2676}
2677
2678
2679static proc homogDistribution(poly h)
2680"Input: A polynomial in the first Weyl Algebra.
2681  Output: A two-dimensional list of the following form. Every sublist contains exactly two entries.
2682   One for the Z-degree of the corresponding homogeneous part (integer), and the homogeneous
2683   polynomial itself, and those sublists are oredered by ascending degree.
2684   For example a call of homogDistribution(x+d+1) would have the output
2685   [1]:
2686     [1]:
2687       -1
2688     [2]:
2689       x
2690   [2]:
2691     [1]:
2692       0
2693     [2]:
2694       1
2695   [3]:
2696     [1]:
2697       1
2698     [2]:
2699       d
2700"{//homogDistribution
2701  if (h == 0)
2702  {//trivial case where input is 0
2703    return(list(list(0,0)));
2704  }//trivial case where input is 0
2705  if (!isWeyl())
2706  {//Our basering is not the Weyl algebra
2707    ERROR("Ring was not the first Weyl algebra");
2708    return(list());
2709  }//Our basering is not the Weyl algebra
2710  if(nvars(basering)!=2)
2711  {//Our basering is the Weyl algebra, but not the first
2712    ERROR("Ring is not the first Weyl algebra");
2713    return(list());
2714  }//Our basering is the Weyl algebra, but not the first
2715  intvec ivm11 = intvec(-1,1);
2716  intvec iv1m1 = intvec(1,-1);
2717  poly tempH = h;
2718  poly minh;
2719  list result = list();
2720  int nextExpectedDegree = -deg(tempH,iv1m1);
2721  while (tempH != 0)
2722  {
2723    minh = jet(tempH,deg(tempH,iv1m1),iv1m1)-jet(tempH,deg(tempH,iv1m1)-1,iv1m1);
2724    while (deg(minh,ivm11)>nextExpectedDegree)
2725    {//filling empty homogeneous spaces with 0
2726      result = result + list(list(nextExpectedDegree,0));
2727      nextExpectedDegree = nextExpectedDegree +1;
2728    }//filling empty homogeneous spaces with 0
2729    result = result + list(list(deg(minh,ivm11),minh));
2730    tempH = tempH - minh;
2731    nextExpectedDegree = nextExpectedDegree +1;
2732  }
2733  return(result);
2734}//homogDistribution
2735
2736static proc countHomogParts(poly h)
2737"Counts the homogeneous parts of a given polynomial h"
2738{
2739  int i;
2740  list outPutHD = homogDistribution(h);
2741  int result = 0;
2742  for (i = 1; i <=size(outPutHD); i++)
2743  {
2744    if (outPutHD[i][2] != 0){result++;}
2745  }
2746  return(result);
2747}
2748
2749//////////////////////////////////////////////////
2750/////BRANDNEW!!!!////////////////////
2751//////////////////////////////////////////////////
2752
2753//==================================================
2754/*Singular has no way implemented to test polynomials
2755  for homogenity with respect to a weight vector.
2756  The following procedure does exactly this*/
2757static proc homogwithorder(poly h, intvec weights)
2758{//proc homogwithorder
2759  if(size(weights) != nvars(basering))
2760  {//The user does not know how many variables the current ring has
2761    return(0);
2762  }//The user does not know how many variables the current ring has
2763  int i;
2764  int dofp = deg(h,weights); //degree of polynomial
2765  for (i = 1; i<=size(h);i++)
2766  {
2767    if (deg(h[i],weights)!=dofp)
2768    {
2769      return(0);
2770    }
2771  }
2772  return(1);
2773}//proc homogwithorder
2774
2775//==================================================
2776//Testfac: Given a list with different factorizations of
2777// one polynomial, the following procedure checks
2778// whether they all refer to the same polynomial.
2779// If they do, the output will be a list, that contains
2780// the product of each factorization. If not, the empty
2781// list will be returned.
2782// If the optional argument # is given (i.e. the polynomial
2783// which is factorized by the elements of the given list),
2784// then we look, if the entries are factorizations of p
2785// and if not, a list with the products subtracted by p
2786// will be returned
2787proc testNCfac(list l, list #)
2788"USAGE: testNCfac(l[,p,b]); l is a list, p is an optional poly, b is 1 or 0
2789RETURN: Case 1: No optional argument. In this case the output is 1, if the
2790  entries in the given list represent the same polynomial or 0
2791  otherwise.
2792 Case 2: One optional argument p is given. In this case it returns 1,
2793  if all the entries in l are factorizations of p, otherwise 0.
2794 Case 3: Second optional b is given. In this case a list is returned
2795  containing the difference between the product of each entry in
2796  l and p.
2797ASSUME: basering is the first Weyl algebra, the entries of l are polynomials
2798PURPOSE: Checks whether a list of factorizations contains factorizations of
2799  the same element in the first Weyl algebra
2800THEORY: @code{testNCfac} multiplies out each factorization and checks whether
2801 each factorization was a factorization of the same element.
2802@* - if there is only a list given, the output will be 0, if it
2803     does not contain factorizations of the same element. Otherwise the output
2804     will be 1.
2805@* - if there is a polynomial in the second argument, then the procedure checks
2806     whether the given list contains factorizations of this polynomial. If it
2807     does, then the output depends on the third argument. If it is not given,
2808     the procedure will check whether the factorizations in the list
2809     l are associated to this polynomial and return either 1 or 0, respectively.
2810     If the third argument is given, the output will be a list with
2811     the length of the given one and in each entry is the product of one
2812     entry in l subtracted by the polynomial.
2813EXAMPLE: example testNCfac; shows examples
2814SEE ALSO: facFirstWeyl, facSubWeyl, facFirstShift
2815"{//proc testfac
2816  int p = printlevel - voice + 2;
2817  int i;
2818  string dbprintWhitespace = "";
2819  for (i = 1; i<=voice;i++)
2820  {dbprintWhitespace = dbprintWhitespace + " ";}
2821  dbprint(p,dbprintWhitespace + " Checking the input");
2822  if (size(l)==0)
2823  {//The empty list is given
2824    dbprint(p,dbprintWhitespace + " Given list was empty");
2825    return(list());
2826  }//The empty list is given
2827  if (size(#)>2)
2828  {//We want max. two optional arguments
2829    dbprint(p,dbprintWhitespace + " More than two optional arguments");
2830    return(list());
2831  }//We want max. two optional arguments
2832  dbprint(p,dbprintWhitespace + " Done");
2833  list result;
2834  int j;
2835  if (size(#)==0)
2836  {//No optional argument is given
2837    dbprint(p,dbprintWhitespace + " No optional arguments");
2838    int valid = 1;
2839    for (i = size(l);i>=1;i--)
2840    {//iterate over the elements of the given list
2841      if (size(result)>0)
2842      {
2843        if (product(l[i])!=result[size(l)-i])
2844        {
2845          valid = 0;
2846          break;
2847        }
2848      }
2849      result = insert(result, product(l[i]));
2850    }//iterate over the elements of the given list
2851    return(valid);
2852  }//No optional argument is given
2853  else
2854  {
2855    dbprint(p,dbprintWhitespace + " Optional arguments are given.");
2856    int valid = 1;
2857    for (i = size(l);i>=1;i--)
2858    {//iterate over the elements of the given list
2859      if (product(l[i])!=#[1])
2860      {
2861        valid = 0;
2862      }
2863      result = insert(result, product(l[i])-#[1]);
2864    }//iterate over the elements of the given list
2865    if(size(#)==2)
2866    {
2867      dbprint(p,dbprintWhitespace + " A third argument is given. Output is a list now.");
2868      return(result);
2869    }
2870    return(valid);
2871  }
2872}//proc testfac
2873example
2874{
2875  "EXAMPLE:";echo=2;
2876  ring r = 0,(x,y),dp;
2877  def R = nc_algebra(1,1);
2878  setring R;
2879  poly h = (x^2*y^2+1)*(x^2);
2880  def t1 = facFirstWeyl(h);
2881  //fist a correct list
2882  testNCfac(t1);
2883  //now a correct list with the factorized polynomial
2884  testNCfac(t1,h);
2885  //now we put in an incorrect list without a polynomial
2886  t1[3][3] = y;
2887  testNCfac(t1);
2888  // take h as additional input
2889  testNCfac(t1,h);
2890  // take h as additional input and output list of differences
2891  testNCfac(t1,h,1);
2892}
2893//==================================================
2894//Procedure facSubWeyl:
2895//This procedure serves the purpose to compute a
2896//factorization of a given polynomial in a ring, whose subring
2897//is the first Weyl algebra. The polynomial must only contain
2898//the two arguments, which are also given by the user.
2899
2900proc facSubWeyl(poly h, X, D)
2901"USAGE:  facSubWeyl(h,x,y); h, X, D polynomials
2902RETURN: list
2903ASSUME: X and D are variables of a basering, which satisfy DX = XD +1.
2904@* That is,  they generate the copy of the first Weyl algebra in a basering.
2905@* Moreover, h is a polynomial in X and D only.
2906PURPOSE: compute factorizations of the polynomial, which depends on X and D.
2907EXAMPLE: example facSubWeyl; shows examples
2908SEE ALSO: facFirstWeyl, testNCfac, facFirstShift
2909"{
2910  int p = printlevel - voice + 2;
2911  dbprint(p," Start initial Checks of the input.");
2912  // basering can be anything having a Weyl algebra as subalgebra
2913  def @r = basering;
2914  //We begin to check the input for assumptions
2915  // which are: X,D are vars of the basering,
2916  if ( (isVar(X)!=1) || (isVar(D)!=1) || (size(X)>1) || (size(D)>1) ||
2917       (leadcoef(X) != number(1)) || (leadcoef(D) != number(1)) )
2918  {
2919    ERROR("expected pure variables as generators of a subalgebra");
2920  }
2921  // Weyl algebra:
2922  poly w = D*X-X*D-1; // [D,X]=1
2923  poly u = D*X-X*D+1; // [X,D]=1
2924  if (u*w!=0)
2925  {
2926    // that is no combination gives Weyl
2927    ERROR("2nd and 3rd argument do not generate a Weyl algebra");
2928  }
2929  // one of two is correct
2930  int isReverted = 0; // Reverted Weyl if dx=xd-1 holds
2931  if (u==0)
2932  {
2933    isReverted = 1;
2934  }
2935  // else: do nothing
2936  // DONE with assumptions, Input successfully checked
2937  dbprint(p," Successful");
2938  intvec lexpofX = leadexp(X);
2939  intvec lexpofD = leadexp(D);
2940  int varnumX=1;
2941  int varnumD=1;
2942  while(lexpofX[varnumX] != 1)
2943  {
2944    varnumX++;
2945  }
2946  while(lexpofD[varnumD] != 1)
2947  {
2948    varnumD++;
2949  }
2950  /* VL : to add printlevel stuff */
2951  dbprint(p," Change positions of the two variables in the list, if needed");
2952  if (isReverted)
2953  {
2954    ring firstweyl = 0,(var(varnumD),var(varnumX)),dp;
2955    def Firstweyl = nc_algebra(1,1);
2956    setring Firstweyl;
2957    ideal M = 0:nvars(@r);
2958    M[varnumX]=var(2);
2959    M[varnumD]=var(1);
2960    map Q = @r,M;
2961    poly h= Q(h);
2962  }
2963  else
2964  { // that is unReverted
2965    ring firstweyl = 0,(var(varnumX),var(varnumD)),dp;
2966    def Firstweyl = nc_algebra(1,1);
2967    setring Firstweyl;
2968    poly h= imap(@r,h);
2969  }
2970  dbprint(p," Done!");
2971  list result = facFirstWeyl(h);
2972  setring @r;
2973  list result;
2974  if (isReverted)
2975  {
2976    // map swap back
2977    ideal M; M[1] = var(varnumD); M[2] = var(varnumX);
2978    map S = Firstweyl, M;
2979    result = S(result);
2980  }
2981  else
2982  {
2983    // that is unReverted
2984    result = imap(Firstweyl,result);
2985  }
2986  return(result);
2987}//proc facSubWeyl
2988example
2989{
2990  "EXAMPLE:";echo=2;
2991  ring r = 0,(x,y,z),dp;
2992  matrix D[3][3]; D[1,3]=-1;
2993  def R = nc_algebra(1,D); // x,z generate Weyl subalgebra
2994  setring R;
2995  poly h = (x^2*z^2+x)*x;
2996  list fact1 = facSubWeyl(h,x,z);
2997  // compare with facFirstWeyl:
2998  ring s = 0,(z,x),dp;
2999  def S = nc_algebra(1,1); setring S;
3000  poly h = (x^2*z^2+x)*x;
3001  list fact2 = facFirstWeyl(h);
3002  map F = R,x,0,z;
3003  list fact1 = F(fact1); // it is identical to list fact2
3004  testNCfac(fact1); // check the correctness again
3005}
3006//==================================================
3007
3008//==================================================
3009//************From here: Shift-Algebra**************
3010//==================================================
3011//==================================================*
3012//one factorization of a homogeneous polynomial
3013//in the first Shift Algebra
3014static proc homogfacFirstShift(poly h)
3015{//proc homogfacFirstShift
3016  int p=printlevel-voice+2; //for dbprint
3017  def r = basering;
3018  poly hath;
3019  intvec iv01 = intvec(0,1);
3020  int i; int j;
3021  string dbprintWhitespace = "";
3022  for (i = 1; i<=voice;i++)
3023  {dbprintWhitespace = dbprintWhitespace + " ";}
3024  if (!homogwithorder(h,iv01))
3025  {//The given polynomial is not homogeneous
3026    ERROR("The given polynomial is not homogeneous.");
3027    return(list());
3028  }//The given polynomial is not homogeneous
3029  if (h==0)
3030  {
3031    return(list(0));
3032  }
3033  list result;
3034  int m = deg(h,iv01);
3035  dbprint(p,dbprintWhitespace+" exclude the homogeneous part of deg. 0");
3036  if (m>0)
3037  {//The degree is not zero
3038    hath = lift(var(2)^m,h)[1,1];
3039    for (i = 1; i<=m;i++)
3040    {
3041      result = result + list(var(2));
3042    }
3043  }//The degree is not zero
3044  else
3045  {//The degree is zero
3046    hath = h;
3047  }//The degree is zero
3048  ring tempRing = 0,(x),dp;
3049  setring tempRing;
3050  map thetamap = r,x,1;
3051  poly hath = thetamap(hath);
3052  dbprint(p,dbprintWhitespace+" Factorize it using commutative factorization.");
3053  list azeroresult = factorize(hath);
3054  list azeroresult_return_form;
3055  for (i = 1; i<=size(azeroresult[1]);i++)
3056  {//rewrite the result of the commutative factorization
3057    for (j = 1; j <= azeroresult[2][i];j++)
3058    {
3059      azeroresult_return_form = azeroresult_return_form + list(azeroresult[1][i]);
3060    }
3061  }//rewrite the result of the commutative factorization
3062  setring(r);
3063  map finalmap = tempRing,var(1);
3064  list tempresult = finalmap(azeroresult_return_form);
3065  result = tempresult+result;
3066  return(result);
3067}//proc homogfacFirstShift
3068
3069//==================================================
3070//Computes all possible homogeneous factorizations
3071static proc homogfacFirstShift_all(poly h)
3072{//proc HomogfacFirstShiftAll
3073  int p=printlevel-voice+2; //for dbprint
3074  intvec iv11 = intvec(1,1);
3075  if (deg(h,iv11) <= 0 )
3076  {//h is a constant
3077    return(list(list(h)));
3078  }//h is a constant
3079  def r = basering;
3080  list one_hom_fac; //stands for one homogeneous factorization
3081  int i; int j; int k;
3082  string dbprintWhitespace = "";
3083  for (i = 1; i<=voice;i++)
3084  {dbprintWhitespace = dbprintWhitespace + " ";}
3085  int shiftcounter;
3086  //Compute again a homogeneous factorization
3087  dbprint(p,dbprintWhitespace+" Computing one homog. factorization of the polynomial");
3088  one_hom_fac = homogfacFirstShift(h);
3089  one_hom_fac = delete(one_hom_fac,1);
3090  if (size(one_hom_fac) == 0)
3091  {//there is no homogeneous factorization or the polynomial was not homogeneous
3092    return(list());
3093  }//there is no homogeneous factorization or the polynomial was not homogeneous
3094  dbprint(p,dbprintWhitespace+" Permuting the 0-homogeneous part with the s");
3095  list result = permpp(one_hom_fac);
3096  for (i = 1; i<=size(result);i++)
3097  {
3098    shiftcounter = 0;
3099    for (j = 1; j<=size(result[i]); j++)
3100    {
3101      if (result[i][j]==var(2))
3102      {
3103        shiftcounter++;
3104      }
3105      else
3106      {
3107        result[i][j] = subst(result[i][j], var(1), var(1)-shiftcounter);
3108      }
3109    }
3110    result[i] = insert(result[i],1);
3111  }
3112  dbprint(p,dbprintWhitespace+" Deleting double entries in the resulting list");
3113  result = delete_dublicates_noteval(result);
3114  return(result);
3115}//proc HomogfacFirstShiftAll
3116
3117//==================================================
3118//factorization of the first Shift Algebra
3119proc facFirstShift(poly h)
3120"USAGE: facFirstShift(h); h a polynomial in the first shift algebra
3121RETURN: list
3122PURPOSE: compute all factorizations of a polynomial in the first shift algebra
3123THEORY: Implements the new algorithm by A. Heinle and V. Levandovskyy, see the thesis of A. Heinle
3124ASSUME: basering is the first shift algebra
3125NOTE: Every entry of the output list is a list with factors for one possible factorization.
3126EXAMPLE: example facFirstShift; shows examples
3127SEE ALSO: testNCfac, facFirstWeyl, facSubWeyl
3128"{//facFirstShift
3129  int p = printlevel - voice + 2;
3130  int i;
3131  string dbprintWhitespace = "";
3132  for (i = 1; i<=voice;i++)
3133  {dbprintWhitespace = dbprintWhitespace + " ";}
3134  dbprint(p,dbprintWhitespace +" Checking the input.");
3135  if(nvars(basering)!=2)
3136  {//Our basering is the Shift algebra, but not the first
3137    ERROR("Basering is not the first shift algebra");
3138    return(list());
3139  }//Our basering is the Shift algebra, but not the first
3140  def r = basering;
3141  setring r;
3142  list LR = ringlist(r);
3143  number @n = leadcoef(LR[5][1,2]);
3144  poly @p = LR[6][1,2];
3145  if  ( @n!=number(1) )
3146  {
3147    ERROR("Basering is not the first shift algebra");
3148    return(list());
3149  }
3150  dbprint(p,dbprintWhitespace +" Done");
3151  list result = list();
3152  int j; int k; int l; //counter
3153  // create a ring with the ordering which makes shift algebra
3154  // graded
3155  // def r = basering; // done before
3156  ring tempRing = LR[1][1],(x,s),(a(0,1),Dp);
3157  def tempRingnc = nc_algebra(1,s);
3158  setring r;
3159  // information on relations
3160  if (@p == -var(1)) // reverted shift algebra
3161  {
3162    dbprint(p,dbprintWhitespace +" Reverted shift algebra. Swaping variables in Ringlist");
3163    setring(tempRingnc);
3164    map transf = r, var(2), var(1);
3165    setring(r);
3166    map transfback = tempRingnc, var(2),var(1);
3167    //    result = transfback(resulttemp);
3168  }
3169  else
3170  {
3171    if ( @p == var(2)) // usual shift algebra
3172    {
3173      setring(tempRingnc);
3174      map transf = r, var(1), var(2);
3175      //    result = facshift(h);
3176      setring(r);
3177      map transfback = tempRingnc, var(1),var(2);
3178    }
3179    else
3180    {
3181      ERROR("Basering is not the first shift algebra");
3182      return(list());
3183    }
3184  }
3185  // main calls
3186  setring(tempRingnc);
3187  dbprint(p,dbprintWhitespace +" Factorize the given polynomial with the subroutine sFacShift");
3188  list resulttemp = sFacShift(transf(h));
3189  dbprint(p,dbprintWhitespace +" Successful");
3190  setring(r);
3191  result = transfback(resulttemp);
3192  return( delete_dublicates_noteval(result) );
3193}//facFirstShift
3194example
3195{
3196  "EXAMPLE:";echo=2;
3197  ring R = 0,(x,s),dp;
3198  def r = nc_algebra(1,s);
3199  setring(r);
3200  poly h = (s^2*x+x)*s;
3201  facFirstShift(h);
3202}
3203
3204static proc sFacShift(poly h)
3205"
3206USAGE: A static procedure to factorize a polynomial in the first Shift algebra, where all the
3207       validity checks were made in advance.
3208INPUT:  A polynomial h in the first Shift Algebra.
3209OUTPUT: A list of different factorizations of h, where the factors are irreducible
3210ASSUMPTIONS:
3211 - The basering is the first Shift algebra and has n as first, and s as second variable, i.e. we
3212   have var(2)*var(1) = var(1)*var(2)+1
3213THEORY: If the given polynomial h is [0,1]-homogeneous, the routines for homogeneous factorizations
3214 are called. Otherwise we map the polynomial into the first Weyl algebra (the first shift
3215 algebra is a subring of the first Weyl algebra), and use facFirstWeyl to factorize it. Later
3216 we map the factors back, if possible.
3217"
3218{//proc sFacShift
3219  int p = printlevel - voice + 2;
3220  int i; int j ;
3221  string dbprintWhitespace = "";
3222  number commonCoefficient = content(h);
3223  for (i = 1; i<=voice;i++)
3224  {dbprintWhitespace = dbprintWhitespace + " ";}
3225  //Checking if given polynomial is homogeneous
3226  if(homogwithorder(h,intvec(0,1)))
3227  {//The given polynomial is [0,1]-homogeneous
3228    dbprint(p,dbprintWhitespace+"The polynomial is [0,1]-homogeneous. Returning the
3229homogeneous factorization");
3230    return(homogfacFirstShift_all(h));
3231  }//The given polynomial is [0,1]-homogeneous
3232
3233  //---------- Start of interesting part ----------
3234
3235  dbprint(p,dbprintWhitespace+"Mapping the polynomial h into the first Weyl algebra.");
3236  poly temph = h/commonCoefficient;
3237  def ourBaseRing = basering;
3238  ring tempWeylAlgebraComm = 0,(x,d),dp;
3239  def tempWeylAlgebra = nc_algebra(1,1);
3240  setring(tempWeylAlgebra);
3241  map shiftMap = ourBaseRing, x*d, d;
3242  poly h = shiftMap(temph);
3243  dbprint(p,dbprintWhitespace+"Successful! The polynomial in the Weyl algebra is "+string(h));
3244  dbprint(p,dbprintWhitespace+"Factorizing the polynomial in the first Weyl algebra");
3245  list factorizationInWeyl = facFirstWeyl(h);
3246  dbprint(p,dbprintWhitespace+"Successful! The factorization is given by:");
3247  dbprint(p,factorizationInWeyl);
3248  list validCombinations;
3249
3250  dbprint(p,dbprintWhitespace+"Now we will map this back to the shift algebra and filter
3251valid results");
3252  //-Now we map the results back to the shift algebra. But first, we need to combine them properly.
3253  for (i = 1; i<=size(factorizationInWeyl); i++)
3254  {//Deleting the first Coefficient factor
3255    factorizationInWeyl[i] = delete(factorizationInWeyl[i],1);
3256    validCombinations = validCombinations + combineNonnegative(factorizationInWeyl[i]);
3257  }//Deleting the first Coefficient factor
3258  if (size(validCombinations) == 0)
3259  {//There are no valid combinations, therefore we can directly say, that h is irreducible
3260    setring(ourBaseRing);
3261    return(list(list(commonCoefficient, h/commonCoefficient)));
3262  }//There are no valid combinations, therefore we can directly say, that h is irreducible
3263  validCombinations = delete_dublicates_noteval(validCombinations);
3264  setring(ourBaseRing);
3265  map backFromWeyl = tempWeylAlgebra, var(1),var(2);
3266  list validCombinations = backFromWeyl(validCombinations);
3267  for (i = 1; i<=size(validCombinations); i++)
3268  {
3269    for (j = 1; j<=size(validCombinations[i]);j++)
3270    {
3271      setring(tempWeylAlgebra);
3272      fromWeylToShiftPoly(validCombinations[i][j],ourBaseRing);
3273      validCombinations[i][j] = result;
3274      kill result;
3275      kill tempResult;
3276      kill zeroPoly;
3277      kill fromWeyl;
3278    }
3279  }
3280  for (i = 1; i<=size(validCombinations); i++)
3281  {//Adding the common factor in the first position of the list
3282    validCombinations[i] = insert(validCombinations[i],commonCoefficient);
3283  }//Adding the common factor in the first position of the list
3284  dbprint(dbprintWhitespace+"Done.");
3285  //mapping
3286  return(validCombinations);
3287}//proc sFacShift
3288
3289static proc combineNonnegative(list l)
3290"
3291USAGE: In sFacShift, when we want to map back the results of the factorization of the polynomial in
3292       the first Weyl algebra to the shift algebra. We need to recombine the factors such that
3293       we can map it back to the shift algebra without any problems.
3294INPUT: A list l containing one factorization of a polynomial in the first Weyl algebra. For example
3295       for the polynomial (1+x)*(1+x+d) we would have the list [1,x+1,x+d+1].
3296OUTPUT:If we can map every factor without a problem back to the shift algebra (i.e. if the smallest
3297 homogeneous summand of every factor is of nonnegative degree), a list containing the same
3298 list as given in the input is returned.
3299 If otherwise some factors cause problems, we consider every possible combination (i.e.
3300 products of the factors) and extract those where all factors have a smallest homogeneous
3301 summand of nonnegative degree.
3302ASSUMPTIONS:
3303 - Weyl algebra is given, and we have var(2)*var(1)=var(1)*var(2) +1
3304"
3305{//combineNonnegative
3306  int p = printlevel - voice + 2;
3307  int i;
3308  string dbprintWhitespace = "";
3309  for (i = 1; i<=voice;i++)
3310  {dbprintWhitespace = dbprintWhitespace + " ";}
3311  //First the easy case: all of the factors fulfill the condition of mapping to shift:
3312  dbprint(p,dbprintWhitespace+"Checking, if the given factors
3313can already be mapped without a problem.");
3314  int isValid = 1;
3315  for (i = 1; i<=size(l);i++)
3316  {//Checking for every entry if the condition is fulfilled.
3317    if (deg(l[i],intvec(1,-1))>0)
3318    {//Found one, where it is not fulfilled
3319      isValid = 0;
3320      break;
3321    }//Found one, where it is not fulfilled
3322  }//Checking for every entry if the condition is fulfilled.
3323  dbprint(p,dbprintWhitespace+"Done.");
3324  if (isValid)
3325  {//We can map every factor to the shift algebra and do not need to combine anything
3326    dbprint(p,dbprintWhitespace+"They can be mapped. Therefore we return them directly.");
3327    return(list(l));
3328  }//We can map every factor to the shift algebra and do not need to combine anything
3329  dbprint(p,dbprintWhitespace+"They cannot be mapped. Looking for valid combinations.");
3330  //Starting with the case, where l only consists of 1 or two elements.
3331  if(size(l)<=2)
3332  {//The case where we won't call the function a second time
3333    if (deg(product(l),intvec(1,-1))>0)
3334    {//No way of a valid combination
3335      return(list());
3336    }//No way of a valid combination
3337    else
3338    {//The product is the only possible and valid combination
3339      return(list(list(product(l))));
3340    }//The product is the only possible and valid combination
3341  }//The case where we won't call the function a second time
3342  //---------- Easy pre-stuff done. now we combine the factors.----------
3343  int pos;
3344  int j; int k;
3345  dbprint(p,dbprintWhitespace+"Making combinations of two.");
3346  list combinationsOfTwo = combinekfinlf(l,2);
3347  dbprint(p,dbprintWhitespace+"Done. Now checking, if there are valid ones in between.");
3348  list result;
3349  list validLHS;
3350  list validRHS;
3351  for (i = 1; i<=size(combinationsOfTwo); i++)
3352  {//go through all combinations and detect the valid ones
3353    if(deg(combinationsOfTwo[i][1],intvec(1,-1))>0 or deg(combinationsOfTwo[i][2],intvec(1,-1))>0)
3354    {//No chance, so no further treatment needed
3355      i++;
3356      continue;
3357    }//No chance, so no further treatment needed
3358    for (pos = 1; pos<=size(l);pos++)
3359    {//find the position where the combination splits
3360      if (product(l[1..pos]) == combinationsOfTwo[i][1])
3361      {//Found the position
3362        break;
3363      }//Found the position
3364    }//find the position where the combination splits
3365    dbprint(p,dbprintWhitespace+"Calling combineNonnegative recursively with argument " +
3366            string(list(l[1..pos])));
3367    validLHS = combineNonnegative(list(l[1..pos]));
3368    dbprint(p,dbprintWhitespace+"Calling combineNonnegative recursively with argument " +
3369            string(list(l[pos+1..size(l)])));
3370    validRHS = combineNonnegative(list(l[pos+1..size(l)]));
3371    for (j = 1; j<=size(validLHS); j++)
3372    {//Combining the left hand side valid combnations...
3373      for (k = 1; k<=size(validRHS); k++)
3374      {//... with the right hand side valid combinations
3375        result = insert(result, validLHS[j]+validRHS[k]);
3376      }//... with the right hand side valid combinations
3377    }//Combining the left hand side valid combnations...
3378  }//go through all combinations and detect the valid ones
3379  result = delete_dublicates_noteval(result);
3380  dbprint(p,dbprintWhitespace+"Done.");
3381  return(result);
3382}//combineNonnegative
3383
3384static proc fromWeylToShiftPoly(poly h, sAlgebra)
3385"
3386USAGE: Given a polynomial in the first Weyl algebra, this method returns it -- if possible --
3387       as an element in the first shift algebra, which is given in the method header.
3388INPUT: A polynomial h, and the first shift algebra as a ring
3389OUTPUT: The correct mapping in the shift Algebra
3390ASSUMPTIONS:
3391 - The lowest [-1,1]-homogeneous summand of h is of nonnegative degree
3392 - The shift algebra is given in the way that var(2)*var(1) = (var(1)+1)*var(2)
3393"
3394{//fromWeylToShiftPoly
3395  int p = printlevel - voice + 2;
3396  int i;
3397  string dbprintWhitespace = "";
3398  for (i = 1; i<=voice;i++)
3399  {dbprintWhitespace = dbprintWhitespace + " ";}
3400  if (deg(h,intvec(1,-1))>0)
3401  {//Wrong input polynomial
3402    ERROR("The lowest [-1,1] homogeneous summand of "+string(h)+" is of negative degree.");
3403  }//Wrong input polynomial
3404  def ourHomeBase = basering;
3405  list hDist = homogDistribution(h);
3406  setring(sAlgebra);
3407  poly result = 0;
3408  poly tempResult;
3409  poly zeroPoly;
3410  map fromWeyl = ourHomeBase, var(1), var(2);
3411  setring(ourHomeBase);
3412  poly zeroPoly;
3413  poly tempZeroPoly;
3414  int j; int k;
3415  int derDeg;
3416  for (i = 1; i<=size(hDist);i++)
3417  {
3418    derDeg = hDist[i][1];
3419    setring(sAlgebra);
3420    tempResult = 1;
3421    setring(ourHomeBase);
3422    zeroPoly = lift(d^derDeg, hDist[i][2])[1,1];
3423    for (j = 1; j<=size(zeroPoly); j++)
3424    {
3425      tempZeroPoly = zeroPoly[j];
3426      setring(sAlgebra);
3427      zeroPoly = fromWeyl(tempZeroPoly);
3428      tempResult = tempResult * leadcoef(zeroPoly);
3429      setring(ourHomeBase);
3430      for (k = 1; k<=deg(zeroPoly[j],intvec(0,1));k++)
3431      {
3432        setring(sAlgebra);
3433        tempResult = tempResult*(var(1)-(k-1));
3434        setring(ourHomeBase);
3435      }
3436      setring(sAlgebra);
3437      result = result + tempResult*var(2)^derDeg;
3438      tempResult = 1;
3439      setring(ourHomeBase);
3440    }
3441  }
3442  setring(sAlgebra);
3443  keepring(sAlgebra);
3444}//fromWeylToShiftPoly
3445
3446static proc refineFactList(list L)
3447{
3448  // assume: list L is an output of factorization proc
3449  // doing: remove doubled entries
3450  int s = size(L); int sm;
3451  int i,j,k,cnt;
3452  list M, U, A, B;
3453  A = L;
3454  k = 0;
3455  cnt  = 1;
3456  for (i=1; i<=s; i++)
3457  {
3458    if (size(A[i]) != 0)
3459    {
3460      M = A[i];
3461      //      "probing with"; M; i;
3462      B[cnt] = M; cnt++;
3463      for (j=i+1; j<=s; j++)
3464      {
3465        if ( isEqualList(M,A[j]) )
3466        {
3467          k++;
3468          // U consists of intvecs with equal pairs
3469          U[k] = intvec(i,j);
3470          A[j] = 0;
3471        }
3472      }
3473    }
3474  }
3475  kill A,U,M;
3476  return(B);
3477}
3478example
3479{
3480  "EXAMPLE:";echo=2;
3481  ring R = 0,(x,s),dp;
3482  def r = nc_algebra(1,1);
3483  setring(r);
3484  list l,m;
3485  l = list(1,s2+1,x,s,x+s);
3486  m = l,list(1,s,x,s,x),l;
3487  refineFactList(m);
3488}
3489
3490static proc isEqualList(list L, list M)
3491{
3492  // int boolean: 1=yes, 0 =no : test whether two lists are identical
3493  int s = size(L);
3494  if (size(M)!=s) { return(0); }
3495  int j=1;
3496  while ( (L[j]==M[j]) && (j<s) )
3497  {
3498    j++;
3499  }
3500  if (L[j]==M[j])
3501  {
3502    return(1);
3503  }
3504  return(0);
3505}
3506example
3507{
3508  "EXAMPLE:";echo=2;
3509  ring R = 0,(x,s),dp;
3510  def r = nc_algebra(1,1);
3511  setring(r);
3512  list l,m;
3513  l = list(1,s2+1,x,s,x+s);
3514  m = l;
3515  isEqualList(m,l);
3516}
3517
3518
3519//////////////////////////////////////////////////
3520// Q-WEYL-SECTION
3521//////////////////////////////////////////////////
3522
3523//==================================================
3524//A function to get the i'th triangular number
3525static proc triangNum(int n)
3526{
3527  if (n == 0)
3528  {
3529    return(0);
3530  }
3531  return (n*(n+1) div 2);
3532}
3533
3534//==================================================*
3535//one factorization of a homogeneous polynomial
3536//in the first Q Weyl Algebra
3537proc homogfacFirstQWeyl(poly h)
3538"USAGE: homogfacFirstQWeyl(h); h is a homogeneous polynomial in the
3539 first q-Weyl algebra with respect to the weight vector [-1,1]
3540RETURN: list
3541PURPOSE: Computes a factorization of a homogeneous polynomial h with
3542  respect to the weight vector [-1,1] in the first q-Weyl algebra
3543THEORY: @code{homogfacFirstQWeyl} returns a list with a factorization of the given,
3544 [-1,1]-homogeneous polynomial. If the degree of the polynomial is k with
3545 k positive, the last k entries in the output list are the second
3546 variable. If k is positive, the last k entries will be x. The other
3547 entries will be irreducible polynomials of degree zero or 1 resp. -1.
3548SEE ALSO: homogfacFirstQWeyl_all
3549"{//proc homogfacFirstQWeyl
3550  int p = printlevel-voice+2;//for dbprint
3551  def r = basering;
3552  poly hath;
3553  int i; int j;
3554  string dbprintWhitespace = "";
3555  for (i = 1; i<=voice;i++)
3556  {dbprintWhitespace = dbprintWhitespace + " ";}
3557  intvec ivm11 = intvec(-1,1);
3558  if (!homogwithorder(h,ivm11))
3559  {//The given polynomial is not homogeneous
3560    ERROR("Given polynomial was not [-1,1]-homogeneous");
3561    return(list());
3562  }//The given polynomial is not homogeneous
3563  if (h==0)
3564  {
3565    return(list(0));
3566  }
3567  list result;
3568  int m = deg(h,ivm11);
3569  dbprint(p,dbprintWhitespace+" Splitting the polynomial in A_0 and A_k-Part");
3570  if (m!=0)
3571  {//The degree is not zero
3572    if (m <0)
3573    {//There are more x than y
3574      hath = lift(var(1)^(-m),h)[1,1];
3575      for (i = 1; i<=-m; i++)
3576      {
3577        result = result + list(var(1));
3578      }
3579    }//There are more x than y
3580    else
3581    {//There are more y than x
3582      hath = lift(var(2)^m,h)[1,1];
3583      for (i = 1; i<=m;i++)
3584      {
3585        result = result + list(var(2));
3586      }
3587    }//There are more y than x
3588  }//The degree is not zero
3589  else
3590  {//The degree is zero
3591    hath = h;
3592  }//The degree is zero
3593  dbprint(p," Done");
3594  //beginning to transform x^i*y^i in theta(theta-1)...(theta-i+1)
3595  list mons;
3596  dbprint(p," Putting the monomials in the A_0-part in a list.");
3597  for(i = 1; i<=size(hath);i++)
3598  {//Putting the monomials in a list
3599    mons = mons+list(hath[i]);
3600  }//Putting the monomials in a list
3601  dbprint(p," Done");
3602  dbprint(p," Mapping this monomials to K(q)[theta]");
3603  //Now, map to the commutative ring with theta:
3604  list tempRingList = ringlist(r);
3605  tempRingList[2] = insert(tempRingList[2],"theta",2); //New variable theta = x*d
3606  tempRingList = delete(tempRingList,5);
3607  tempRingList = delete(tempRingList,5); //The ring should now be commutative
3608  def tempRing = ring(tempRingList);
3609  setring tempRing;
3610  map thetamap = r,var(1),var(2);
3611  list mons = thetamap(mons);
3612  poly entry;
3613  poly tempSummand;
3614  for (i = 1; i<=size(mons);i++)
3615  {//transforming the monomials as monomials in theta
3616    entry = 1;//leadcoef(mons[i]) * q^(-triangNum(leadexp(mons[i])[2]-1));
3617    for (j = 0; j<leadexp(mons[i])[2];j++)
3618    {
3619      tempSummand = (par(1)^j-1)/(par(1)-1);
3620      entry = entry * theta-tempSummand*entry;
3621    }
3622    //entry;
3623    //leadcoef(mons[i]) * q^(-triangNum(leadexp(mons[i])[2]-1));
3624    mons[i] = entry*leadcoef(mons[i]) * par(1)^(-triangNum(leadexp(mons[i])[2]-1));
3625  }//transforming the monomials as monomials in theta
3626  dbprint(p," Done");
3627  dbprint(p," Factorize the A_0-Part in K[theta]");
3628  list azeroresult = factorize(sum(mons));
3629  dbprint(p," Successful");
3630  list azeroresult_return_form;
3631  for (i = 1; i<=size(azeroresult[1]);i++)
3632  {//rewrite the result of the commutative factorization
3633    for (j = 1; j <= azeroresult[2][i];j++)
3634    {
3635      azeroresult_return_form = azeroresult_return_form + list(azeroresult[1][i]);
3636    }
3637  }//rewrite the result of the commutative factorization
3638  dbprint(p," Mapping back to A_0.");
3639  setring(r);
3640  map finalmap = tempRing,var(1),var(2),var(1)*var(2);
3641  list tempresult = finalmap(azeroresult_return_form);
3642  dbprint(p,"Successful.");
3643  for (i = 1; i<=size(tempresult);i++)
3644  {//factorizations of theta resp. theta +1
3645    if(tempresult[i]==var(1)*var(2))
3646    {
3647      tempresult = insert(tempresult,var(1),i-1);
3648      i++;
3649      tempresult[i]=var(2);
3650    }
3651    if(tempresult[i]==var(2)*var(1))
3652    {
3653      tempresult = insert(tempresult,var(2),i-1);
3654      i++;
3655      tempresult[i]=var(1);
3656    }
3657  }//factorizations of theta resp. theta +1
3658  result = tempresult+result;
3659  //Correction of the result in the special q-Case:
3660  for (j = 2 ; j<= size(result);j++)
3661  {//Div the whole Term by the leading coefficient and multiply it to the first entry in result[i]
3662    result[1] = result[1] * leadcoef(result[j]);
3663    result[j] = 1/leadcoef(result[j]) * result[j];
3664  }//Div the whole Term by the leading coefficient and multiply it to the first entry in result[i]
3665  return(result);
3666}//proc homogfacFirstQWeyl
3667example
3668{
3669  "EXAMPLE:";echo=2;
3670  ring R = (0,q),(x,d),dp;
3671  def r = nc_algebra (q,1);
3672  setring(r);
3673  poly h = q^25*x^10*d^10+q^16*(q^4+q^3+q^2+q+1)^2*x^9*d^9+
3674    q^9*(q^13+3*q^12+7*q^11+13*q^10+20*q^9+26*q^8+30*q^7+
3675    31*q^6+26*q^5+20*q^4+13*q^3+7*q^2+3*q+1)*x^8*d^8+
3676    q^4*(q^9+2*q^8+4*q^7+6*q^6+7*q^5+8*q^4+6*q^3+
3677     4*q^2+2q+1)*(q^4+q^3+q^2+q+1)*(q^2+q+1)*x^7*d^7+
3678    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+
3679    (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+
3680    6*x^3*d^3+24;
3681  homogfacFirstQWeyl(h);
3682}
3683
3684//==================================================
3685//Computes all possible homogeneous factorizations for an element in the first Q-Weyl Algebra
3686proc homogfacFirstQWeyl_all(poly h)
3687"USAGE: homogfacFirstQWeyl_all(h); h is a homogeneous polynomial in the first q-Weyl algebra
3688 with respect to the weight vector [-1,1]
3689RETURN: list
3690PURPOSE: Computes all factorizations of a homogeneous polynomial h with respect
3691  to the weight vector [-1,1] in the first q-Weyl algebra
3692THEORY: @code{homogfacFirstQWeyl} returns a list with all factorization of the given,
3693 homogeneous polynomial. It uses the output of homogfacFirstQWeyl and permutes
3694 its entries with respect to the commutation rule. Furthermore, if a
3695 factor of degree zero is irreducible in K[  heta], but reducible in
3696 the first q-Weyl algebra, the permutations of this element with the other
3697 entries will also be computed.
3698SEE ALSO: homogfacFirstQWeyl
3699"{//proc HomogfacFirstQWeylAll
3700  int p=printlevel-voice+2;//for dbprint
3701  intvec iv11= intvec(1,1);
3702  if (deg(h,iv11) <= 0 )
3703  {//h is a constant
3704    dbprint(p,"Given polynomial was not homogeneous");
3705    return(list(list(h)));
3706  }//h is a constant
3707  def r = basering;
3708  list one_hom_fac; //stands for one homogeneous factorization
3709  int i; int j; int k;
3710  intvec ivm11 = intvec(-1,1);
3711  dbprint(p," Calculate one homogeneous factorization using homogfacFirstQWeyl");
3712  //Compute again a homogeneous factorization
3713  one_hom_fac = homogfacFirstQWeyl(h);
3714  dbprint(p,"Successful");
3715  if (size(one_hom_fac) == 0)
3716  {//there is no homogeneous factorization or the polynomial was not homogeneous
3717    return(list());
3718  }//there is no homogeneous factorization or the polynomial was not homogeneous
3719  //divide list in A0-Part and a list of x's resp. y's
3720  list list_not_azero = list();
3721  list list_azero;
3722  list k_factor;
3723  int is_list_not_azero_empty = 1;
3724  int is_list_azero_empty = 1;
3725  k_factor = list(one_hom_fac[1]);
3726  if (absValue(deg(h,ivm11))<size(one_hom_fac)-1)
3727  {//There is a nontrivial A_0-part
3728    list_azero = one_hom_fac[2..(size(one_hom_fac)-absValue(deg(h,ivm11)))];
3729    is_list_azero_empty = 0;
3730  }//There is a nontrivial A_0 part
3731  dbprint(p," Combine x,y to xy in the factorization again.");
3732  for (i = 1; i<=size(list_azero)-1;i++)
3733  {//in homogfacFirstQWeyl, we factorized theta, and this will be made undone
3734    if (list_azero[i] == var(1))
3735    {
3736      if (list_azero[i+1]==var(2))
3737      {
3738        list_azero[i] = var(1)*var(2);
3739        list_azero = delete(list_azero,i+1);
3740      }
3741    }
3742    if (list_azero[i] == var(2))
3743    {
3744      if (list_azero[i+1]==var(1))
3745      {
3746        list_azero[i] = var(2)*var(1);
3747        list_azero = delete(list_azero,i+1);
3748      }
3749    }
3750  }//in homogfacFirstQWeyl, we factorized theta, and this will be made undone
3751  dbprint(p," Done");
3752  if(deg(h,ivm11)!=0)
3753  {//list_not_azero is not empty
3754    list_not_azero =
3755      one_hom_fac[(size(one_hom_fac)-absValue(deg(h,ivm11))+1)..size(one_hom_fac)];
3756    is_list_not_azero_empty = 0;
3757  }//list_not_azero is not empty
3758  //Map list_azero in K[theta]
3759  dbprint(p," Map list_azero to K[theta]");
3760  //Now, map to the commutative ring with theta:
3761  list tempRingList = ringlist(r);
3762  tempRingList[2] = insert(tempRingList[2],"theta",2); //New variable theta = x*d
3763  tempRingList = delete(tempRingList,5);
3764  tempRingList = delete(tempRingList,5); //The ring should now be commutative
3765  def tempRing = ring(tempRingList);
3766  setring(tempRing);
3767  poly entry;
3768  map thetamap = r,var(1),var(2);
3769  if(!is_list_not_azero_empty)
3770  {//Mapping in Singular is only possible, if the list before
3771    //contained at least one element of the other ring
3772    list list_not_azero = thetamap(list_not_azero);
3773  }//Mapping in Singular is only possible, if the list before
3774  //contained at least one element of the other ring
3775  if(!is_list_azero_empty)
3776  {//Mapping in Singular is only possible, if the list before
3777    //contained at least one element of the other ring
3778    list list_azero= thetamap(list_azero);
3779  }//Mapping in Singular is only possible, if the list before
3780  //contained at least one element of the other ring
3781  list k_factor = thetamap(k_factor);
3782  list tempmons;
3783  dbprint(p," Done");
3784  for(i = 1; i<=size(list_azero);i++)
3785  {//rewrite the polynomials in A1 as polynomials in K[theta]
3786    tempmons = list();
3787    for (j = 1; j<=size(list_azero[i]);j++)
3788    {
3789      tempmons = tempmons + list(list_azero[i][j]);
3790    }
3791    for (j = 1 ; j<=size(tempmons);j++)
3792    {
3793      //entry = leadcoef(tempmons[j]);
3794      entry = leadcoef(tempmons[j]) * par(1)^(-triangNum(leadexp(tempmons[j])[2]-1));
3795      for (k = 0; k < leadexp(tempmons[j])[2];k++)
3796      {
3797        entry = entry*(theta-(par(1)^k-1)/(par(1)-1));
3798      }
3799      tempmons[j] = entry;
3800    }
3801    list_azero[i] = sum(tempmons);
3802  }//rewrite the polynomials in A1 as polynomials in K[theta]
3803  //Compute all permutations of the A0-part
3804  dbprint(p," Compute all permutations of the A_0-part with the first resp. the snd. variable");
3805  list result;
3806  int shift_sign;
3807  int shift;
3808  poly shiftvar;
3809  if (size(list_not_azero)!=0)
3810  {//Compute all possibilities to permute the x's resp. the y's in the list
3811    if (list_not_azero[1] == x)
3812    {//h had a negative weighted degree
3813      shift_sign = 1;
3814      shiftvar = x;
3815    }//h had a negative weighted degree
3816    else
3817    {//h had a positive weighted degree
3818      shift_sign = -1;
3819      shiftvar = y;
3820    }//h had a positive weighted degree
3821    result = permpp(list_azero + list_not_azero);
3822    for (i = 1; i<= size(result); i++)
3823    {//adjust the a_0-parts
3824      shift = 0;
3825      for (j=1; j<=size(result[i]);j++)
3826      {
3827        if (result[i][j]==shiftvar)
3828        {
3829          shift = shift + shift_sign;
3830        }
3831        else
3832        {
3833          if (shift < 0)
3834          {//We have two distict formulas for x and y. In this case use formula for y
3835            if (shift == -1)
3836            {
3837              result[i][j] = subst(result[i][j],theta,1/par(1)*(theta - 1));
3838            }
3839            else
3840            {
3841              result[i][j] =
3842                subst(result[i][j],
3843                      theta,
3844                      1/par(1)*((theta - 1)/par(1)^(absValue(shift)-1)
3845                                - (par(1)^(shift +2)-par(1))/(1-par(1))));
3846            }
3847          }//We have two distict formulas for x and y. In this case use formula for y
3848          if (shift > 0)
3849          {//We have two distict formulas for x and y. In this case use formula for x
3850            if (shift == 1)
3851            {
3852              result[i][j] = subst(result[i][j],theta,par(1)*theta + 1);
3853            }
3854            else
3855            {
3856              result[i][j] =
3857                subst(result[i][j],
3858                      theta,par(1)^shift*theta+(par(1)^shift-1)/(par(1)-1));
3859            }
3860          }//We have two distict formulas for x and y. In this case use formula for x
3861        }
3862      }
3863    }//adjust the a_0-parts
3864  }//Compute all possibilities to permute the x's resp. the y's in the list
3865  else
3866  {//The result is just all the permutations of the a_0-part
3867    result = permpp(list_azero);
3868  }//The result is just all the permutations of the a_0 part
3869  if (size(result)==0)
3870  {
3871    return(result);
3872  }
3873  dbprint(p," Done");
3874  dbprint(p," Searching for theta resp. theta + 1 in the list and factorize them");
3875  //Now we are going deeper and search for theta resp. theta + 1, substitute
3876  //them by xy resp. yx and go on permuting
3877  int found_theta;
3878  int thetapos;
3879  list leftpart;
3880  list rightpart;
3881  list lparts;
3882  list rparts;
3883  list tempadd;
3884  for (i = 1; i<=size(result) ; i++)
3885  {//checking every entry of result for theta or theta +1
3886    found_theta = 0;
3887    for(j=1;j<=size(result[i]);j++)
3888    {
3889      if (result[i][j]==theta)
3890      {//the jth entry is theta and can be written as x*y
3891        thetapos = j;
3892        result[i]= insert(result[i],x,j-1);
3893        j++;
3894        result[i][j] = y;
3895        found_theta = 1;
3896        break;
3897      }//the jth entry is theta and can be written as x*y
3898      if(result[i][j] == par(1)*theta +1)
3899      {
3900        thetapos = j;
3901        result[i] = insert(result[i],y,j-1);
3902        j++;
3903        result[i][j] = x;
3904        found_theta = 1;
3905        break;
3906      }
3907    }
3908    if (found_theta)
3909    {//One entry was theta resp. theta +1
3910      leftpart = result[i];
3911      leftpart = leftpart[1..thetapos];
3912      rightpart = result[i];
3913      rightpart = rightpart[(thetapos+1)..size(rightpart)];
3914      lparts = list(leftpart);
3915      rparts = list(rightpart);
3916      //first deal with the left part
3917      if (leftpart[thetapos] == x)
3918      {
3919        shift_sign = 1;
3920        shiftvar = x;
3921      }
3922      else
3923      {
3924        shift_sign = -1;
3925        shiftvar = y;
3926      }
3927      for (j = size(leftpart); j>1;j--)
3928      {//drip x resp. y
3929        if (leftpart[j-1]==shiftvar)
3930        {//commutative
3931          j--;
3932          continue;
3933        }//commutative
3934        if (deg(leftpart[j-1],intvec(-1,1,0))!=0)
3935        {//stop here
3936          break;
3937        }//stop here
3938        //Here, we can only have a a0- part
3939        if (shift_sign<0)
3940        {
3941          leftpart[j] = subst(leftpart[j-1],theta, 1/par(1)*(theta +shift_sign));
3942        }
3943        if (shift_sign>0)
3944        {
3945          leftpart[j] = subst(leftpart[j-1],theta, par(1)*theta + shift_sign);
3946        }
3947        leftpart[j-1] = shiftvar;
3948        lparts = lparts + list(leftpart);
3949      }//drip x resp. y
3950      //and now deal with the right part
3951      if (rightpart[1] == x)
3952      {
3953        shift_sign = 1;
3954        shiftvar = x;
3955      }
3956      else
3957      {
3958        shift_sign = -1;
3959        shiftvar = y;
3960      }
3961      for (j = 1 ; j < size(rightpart); j++)
3962      {
3963        if (rightpart[j+1] == shiftvar)
3964        {
3965          j++;
3966          continue;
3967        }
3968        if (deg(rightpart[j+1],intvec(-1,1,0))!=0)
3969        {
3970          break;
3971        }
3972        if (shift_sign<0)
3973        {
3974          rightpart[j] = subst(rightpart[j+1], theta, par(1)*theta - shift_sign);
3975        }
3976        if (shift_sign>0)
3977        {
3978          rightpart[j] = subst(rightpart[j+1], theta, 1/par(1)*(theta - shift_sign));
3979        }
3980        rightpart[j+1] = shiftvar;
3981        rparts = rparts + list(rightpart);
3982      }
3983      //And now, we put all possibilities together
3984      tempadd = list();
3985      for (j = 1; j<=size(lparts); j++)
3986      {
3987        for (k = 1; k<=size(rparts);k++)
3988        {
3989          tempadd = tempadd + list(lparts[j]+rparts[k]);
3990        }
3991      }
3992      tempadd = delete(tempadd,1); // The first entry is already in the list
3993      result = result + tempadd;
3994      continue; //We can may be not be done already with the ith entry
3995    }//One entry was theta resp. theta +1
3996  }//checking every entry of result for theta or theta +1
3997  dbprint(p," Done");
3998  //map back to the basering
3999  dbprint(p," Mapping back everything to the basering");
4000  setring(r);
4001  map finalmap = tempRing, var(1), var(2),var(1)*var(2);
4002  list result = finalmap(result);
4003  for (i=1; i<=size(result);i++)
4004  {//adding the K factor
4005    result[i] = k_factor + result[i];
4006  }//adding the k-factor
4007  dbprint(p," Done");
4008  dbprint(p," Delete double entries in the list.");
4009  result = delete_dublicates_noteval(result);
4010  dbprint(p," Done");
4011  return(result);
4012}//proc HomogfacFirstQWeylAll
4013example
4014{
4015  "EXAMPLE:";echo=2;
4016  ring R = (0,q),(x,d),dp;
4017  def r = nc_algebra (q,1);
4018  setring(r);
4019  poly h = q^25*x^10*d^10+q^16*(q^4+q^3+q^2+q+1)^2*x^9*d^9+
4020    q^9*(q^13+3*q^12+7*q^11+13*q^10+20*q^9+26*q^8+30*q^7+
4021    31*q^6+26*q^5+20*q^4+13*q^3+7*q^2+3*q+1)*x^8*d^8+
4022    q^4*(q^9+2*q^8+4*q^7+6*q^6+7*q^5+8*q^4+6*q^3+
4023    4*q^2+2q+1)*(q^4+q^3+q^2+q+1)*(q^2+q+1)*x^7*d^7+
4024    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+
4025    (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+
4026    6*x^3*d^3+24;
4027  homogfacFirstQWeyl_all(h);
4028}
4029
4030//TODO: FirstQWeyl check the parameters...
4031
4032//==================================================
4033// EASY EXAMPLES FOR WEYL ALGEBRA
4034//==================================================
4035/*
4036  Easy and fast example polynomials where one can find factorizations: K<x,d |dx=xd+1>
4037  (x^2+d)*(x^2+d);
4038  (x^2+x)*(x^2+d);
4039  (x^3+x+1)*(x^4+d*x+2);
4040  (x^2*d+d)*(d+x*d);
4041  d^3+x*d^3+2*d^2+2*(x+1)*d^2+d+(x+2)*d; //Example 5 Grigoriev-Schwarz.
4042  (d+1)*(d+1)*(d+x*d); //Landau Example projected to the first dimension.
4043*/
4044
4045//==================================================
4046//Some Bugs(fixed)/hard examples from Martin Lee:
4047//==================================================
4048// ex1, ex2
4049/*
4050ring s = 0,(x,d),Ws(-1,1);
4051def S = nc_algebra(1,1); setring S;
4052poly a = 10x5d4+26x4d5+47x5d2-97x4d3; //Not so hard any more... Done in around 4 minutes
4053def l= facFirstWeyl (a); l;
4054kill l;
4055poly b = -5328x8d5-5328x7d6+720x9d2+720x8d3-16976x7d4-38880x6d5
4056-5184x7d3-5184x6d4-3774x5d5+2080x8d+5760x7d2-6144x6d3-59616x5d4
4057+3108x3d6-4098x6d2-25704x5d3-21186x4d4+8640x6d-17916x4d3+22680x2d5
4058+2040x5d-4848x4d2-9792x3d3+3024x2d4-10704x3d2-3519x2d3+34776xd4
4059+12096xd3+2898d4-5040x2d+8064d3+6048d2; //Still very hard... But it seems to be only because of the
4060//combinatorial explosion
4061def l= facFirstWeyl (b); l;
4062
4063// ex3: there was difference in answers => fixed
4064LIB "ncfactor.lib";
4065ring r = 0,(x,y,z),dp;
4066matrix D[3][3]; D[1,3]=-1;
4067def R = nc_algebra(1,D);
4068setring R;
4069poly g= 7*z4*x+62*z3+26*z;
4070def l1= facSubWeyl (g, x, z);
4071l1;
4072//---- other ring
4073ring s = 0,(x,z),dp;
4074def S = nc_algebra(1,-1); setring S;
4075poly g= 7*z4*x+62*z3+26*z;
4076def l2= facFirstWeyl (g);
4077l2;
4078map F = R,x,0,z;
4079list l1 = F(l1);
4080l1;
4081//---- so the answers look different, check them!
4082testNCfac(l2); // ok
4083testNCfac(l1); // was not ok, but now it's been fixed!!!
4084
4085// selbst D und X so vertauschen dass sie erfuellt ist : ist gemacht
4086
4087*/
4088
4089/*
4090// bug from M Lee
4091LIB "ncfactor.lib";
4092ring s = 0,(z,x),dp;
4093def S = nc_algebra(1,1); setring S;
4094poly f= -60z4x2-54z4-56zx3-59z2x-64;
4095def l= facFirstWeyl (f);
4096l; // before: empty list; after fix: 1 entry, f is irreducible
4097poly g = 75z3x2+92z3+24;
4098def l= facFirstWeyl (g);
4099l; //before: empty list, now: correct
4100*/
4101
4102/* more things from Martin Lee; fixed
4103ring R = 0,(x,s),dp;
4104def r = nc_algebra(1,s);
4105setring(r);
4106poly h = (s2*x+x)*s;
4107h= h* (x+s);
4108def l= facFirstShift(h);
4109l; // contained doubled entries: not anymore, fixed!
4110
4111ring R = 0,(x,s),dp;
4112def r = nc_algebra(1,-1);
4113setring(r);
4114poly h = (s2*x+x)*s;
4115h= h* (x+s);
4116def l= facFirstWeyl(h);
4117l; // contained doubled entries: not anymore, fixed!
4118
4119*/
4120
4121//======================================================================
4122//Examples from TestSuite that are terminating in a reasonable time.
4123//======================================================================
4124
4125//Counter example for old Algorithm, but now working:
4126/*
4127ring R = 0,(x,d),dp;
4128def r = nc_algebra(1,1);
4129setring(r);
4130LIB "ncfactor.lib";
4131poly h = (1+x^2*d)^4;
4132list lsng = facFirstWeyl(h);
4133print(lsng);
4134*/
4135
4136//Example 2.7. from Master thesis
4137/*
4138ring R = 0,(x,d),dp;
4139def r = nc_algebra(1,1);
4140setring(r);
4141LIB "ncfactor.lib";
4142poly h = (xdd + xd+1+ (xd+5)*x)*(((x*d)^2+1)*d + xd+3+ (xd+7)*x);
4143list lsng = facFirstWeyl(h);
4144print(lsng);
4145 */
4146
4147//Example with high combinatorial income
4148/*
4149ring R = 0,(x,d),dp;
4150def r = nc_algebra(1,1);
4151setring(r);
4152LIB "ncfactor.lib";
4153poly h = (xdddd + (xd+1)*d*d+ (xd+5)*x*d*d)*(((x*d)^2+1)*d*x*x + (xd+3)*x*x+ (xd+7)*x*x*x);
4154list lsng = facFirstWeyl(h);
4155print(lsng);
4156 */
4157
4158//Once a bug, now working
4159/*
4160ring R = 0,(x,d),dp;
4161def r = nc_algebra(1,1);
4162setring(r);
4163LIB "ncfactor.lib";
4164poly h = (x^2*d^2+x)*(x+1);
4165list lsng = facFirstWeyl(h);
4166print(lsng);
4167*/
4168
4169//Another one of that kind
4170/*
4171ring R = 0,(x,d),dp;
4172def r = nc_algebra(1,1);
4173setring(r);
4174LIB "ncfactor.lib";
4175poly h = (x*d*d + (x*d)^5 +x)*((x*d+1)*d-(x*d-1)^5+x);
4176list lsng = facFirstWeyl(h);
4177print(lsng);
4178 */
4179
4180//Example of Victor for Shift Algebra
4181/*
4182ring s = 0,(n,Sn),dp;
4183def S = nc_algebra(1,Sn); setring S;
4184LIB "ncfactor.lib";
4185list lsng = facFirstShift(n^2*Sn^2+3*n*Sn^2-n^2+2*Sn^2-3*n-2);
4186print(lsng);
4187 */
4188
4189//Interesting example, as there are actually also some complex solutions to it:
4190/*
4191ring R = 0,(x,d),dp;
4192def r = nc_algebra(1,1);
4193setring(r);
4194LIB "/Users/albertheinle/Studium/forschung/ncfactor/versionen/ncfactor.lib";
4195poly h =(x^3+x+1)*(x^4+d*x+2);//Example for finitely many, but more than one solution in between.
4196list lsng = facFirstWeyl(h);
4197print(lsng);
4198 */
4199
4200//Another one of that kind:
4201/*
4202ring R = 0,(x,d),dp;
4203def r = nc_algebra(1,1);
4204setring(r);
4205LIB "ncfactor.lib";
4206poly h =(x^2+d)*(x^2+d);//Example for finitely many, but more than one solution in between.
4207list lsng = facFirstWeyl(h);
4208print(lsng);
4209*/
4210
4211//Example by W. Koepf:
4212/*
4213ring R = 0,(x,d),dp;
4214def r = nc_algebra(1,1);
4215setring(r);
4216LIB "ncfactor.lib";
4217poly h = (x^4-1)*x*d^2+(1+7*x^4)*d+8*x^3;
4218list lsng = facFirstWeyl(h);
4219print(lsng);
4220 */
4221
4222//Shift Example from W. Koepf
4223/*
4224ring R = 0,(n,s),dp;
4225def r = nc_algebra(1,s);
4226setring(r);
4227LIB "ncfactor.lib";
4228poly h = n*(n+1)*s^2-2*n*(n+100)*s+(n+99)*(n+100);
4229list lsng = facFirstShift(h);
4230print(lsng);
4231 */
4232
4233//Tsai Example... Once hard, now easy...
4234/*
4235ring R = 0,(x,d),dp;
4236def r = nc_algebra(1,1);
4237setring(r);
4238LIB "ncfactor.lib";
4239poly h = (x^6+2*x^4-3*x^2)*d^2-(4*x^5-4*x^4-12*x^2-12*x)*d + (6*x^4-12*x^3-6*x^2-24*x-12);
4240list lsng =facFirstWeyl(h);
4241print(lsng);
4242 */
4243
4244//======================================================================
4245// Hard examples not yet calculatable in feasible amount of time
4246//======================================================================
4247
4248//Also a counterexample for REDUCE. Very long Groebner basis computation in between.
4249/*
4250ring R = 0,(x,d),dp;
4251def r = nc_algebra(1,1);
4252setring(r);
4253LIB "ncfactor.lib";
4254poly h = (d^4+x^2+dx+x)*(d^2+x^4+xd+d);
4255list lsng = facFirstWeyl(h);
4256print(lsng);
4257*/
4258
4259//Example from the Mainz-Group
4260/*
4261ring R = 0,(x,d),dp;
4262def r = nc_algebra(1,1);
4263setring(r);
4264poly dop6 = 1/35*x^4*(27-70*x+35*x^2)+ 1/35*x*(32+152*x+100*x^2-59*x^3+210*x^4+105*x^5)*d+
4265(-10368/35-67056/35*x-35512/7*x^2-50328/7*x^3-40240/7*x^4-2400*x^5-400*x^6)*d^2+
4266(-144/35*(x+1)*(1225*x^5+11025*x^4+37485*x^3+61335*x^2+50138*x+16584)-6912/35*(x+2)*
4267(x+1)*(105*x^4+1155*x^3+4456*x^2+7150*x+4212) -27648/35*(x+3)*(x+1)*(35*x^2+350*x+867)*
4268(x+2)^2)*d^3;
4269LIB "ncfactor.lib";
4270printlevel = 5;
4271facFirstWeyl(dop6);
4272$;*/
4273
4274//Another Mainz Example:
4275/*
4276LIB "ncfactor.lib";
4277ring R = 0,(x,d),dp;
4278def r = nc_algebra(1,1);
4279setring(r);
4280poly dopp = 82547*x^4*d^4+60237*x^3*d^3+26772*x^5*d^5+2231*x^6*d^6+x*(1140138*
4281x^2*d^2-55872*x*d-3959658*x^3*d^3-8381805*x^4*d^4-3089576*x^5*d^5-274786*
4282x^6*d^6)+x^2*(-16658622*x*d-83427714*x^2*d^2-19715033*x^3*d^3+78915395*x^4
4283*d^4+35337930*x^5*d^5+3354194*x^6*d^6)+x^3*(-99752472-1164881352*x*d+
42844408536996*x^2*d^2+11774185985*x^3*d^3+5262196786*x^4*d^4+1046030561/2*x^5*
4285d^5-10564451/2*x^6*d^6)+x^4*(-1925782272+21995375398*x*d+123415803356*x^2*
4286d^2+302465300831/2*x^3*d^3+34140803907/2*x^4*d^4-15535653409*x^5*d^5-\
42872277687768*x^6*d^6)+x^5*(71273525520+691398212366*x*d+901772633569*x^2*d^2+
42882281275427069*x^3*d^3+2944352819911/2*x^4*d^4+836872370039/4*x^5*d^5+
42899066399237/4*x^6*d^6)+x^6*(2365174430376+9596715855542*x*d+29459572469704*x^
42902*d^2+92502197003786*x^3*d^3+65712473180525*x^4*d^4+13829360193674*x^5*d^5
4291+3231449477251/4*x^6*d^6)+x^7*(26771079436836+117709870166226*x*d+
4292821686455179082*x^2*d^2+1803972139232179*x^3*d^3+1083654460691481*x^4*d^4+
4293858903621851785/4*x^5*d^5+50096565802957/4*x^6*d^6)+x^8*(179341727601960+
42942144653944040630*x*d+13123246960284302*x^2*d^2+41138357917778169/2*x^3*d^3+
429520605819587976401/2*x^4*d^4+3677396642905423/2*x^5*d^5+402688260229369/4*x^6
4296*d^6)+x^9*(2579190935961288+43587063726809764*x*d+157045086382352387*x^2*d^
42972+172175668477370223*x^3*d^3+138636285385875407/2*x^4*d^4+10707836398626232*
4298x^5*d^5+529435530567584*x^6*d^6)+x^10*(41501953525903392+558336731465626084*
4299x*d+1407267553543222268*x^2*d^2+1153046693323226808*x^3*d^3+
4300372331468563656085*x^4*d^4+48654019090240214*x^5*d^5+2114661191282167*x^6*d
4301^6)+x^11*(364526077273381884+4158060401095928464*x*d+8646807662899324262*x^2*
4302d^2+5914675753405705400*x^3*d^3+1631934058875116005*x^4*d^4+
4303187371894330537204*x^5*d^5+7366806367019734*x^6*d^6)+x^12*(
43041759850321214603648+18265471270535733520*x*d+34201910114871110912*x^2*d^2+
430521265221434709398152*x^3*d^3+5437363546219595036*x^4*d^4+594029113431041060*
4306x^5*d^5+22881659624561644*x^6*d^6)+x^13*(4648382639403200688+
430745699084277107816096*x*d+81049061578449009384*x^2*d^2+48858488665016574368*x
4308^3*d^3+12515362110098721444*x^4*d^4+1412152747420021048*x^5*d^5+
430957196947123984972*x^6*d^6)+x^14*(5459369397960020544+55837825300341621824*x*
4310d+105671876924055409696*x^2*d^2+71551727420848766624*x^3*d^3+
431121094786205096577808*x^4*d^4+2695663190297032192*x^5*d^5+118791751565613264*
4312x^6*d^6)+x^15*(1023333653580043776+47171127937488813824*x*d+
4313157258351906685700352*x^2*d^2+145765192195300531840*x^3*d^3+
431449876215785510342176*x^4*d^4+6647374188802036864*x^5*d^5+287310278455067312*
4315x^6*d^6)+x^16*(11960091747366236160+250326608568269289472*x*d+
4316677587171115580981248*x^2*d^2+538246374825683603456*x^3*d^3+
4317161380433451548754048*x^4*d^4+19149099315354950144*x^5*d^5+
4318746433247985092544*x^6*d^6)+x^17*(42246252365448668160+657220532737851248640*
4319x*d+1531751689216283911680*x^2*d^2+1090829514212206064640*x^3*d^3+
4320299280728709430851840*x^4*d^4+32932767387222323200*x^5*d^5+
43211202281367574179840*x^6*d^6)+x^18*(6239106101942784000+320638742839606579200*
4322x*d+873857213570556364800*x^2*d^2+645649080101933721600*x^3*d^3+
4323177008238160627276800*x^4*d^4+19165088507111475200*x^5*d^5+
4324683600826675660800*x^6*d^6)+x^19*(-60440251454613504000-476055211197689856000
4325*x*d-733497382597635072000*x^2*d^2-386038662982742016000*x^3*d^3-\
432683361486778142976000*x^4*d^4-7524999543181824000*x^5*d^5-232189492987008000*
4327x^6*d^6)+x^20*(1578562930483200000+12628503443865600000*x*d+
432819732036631040000000*x^2*d^2+10523752869888000000*x^3*d^3+
43292302070940288000000*x^4*d^4+210475057397760000*x^5*d^5+6577345543680000*x^6*
4330d^6);
4331printlevel = 3;
4332facFirstWeyl(dopp);
4333*/
4334
4335
4336
4337//Hard Example by Viktor:
4338/*
4339  ring r = 0,(x,d), (dp);
4340def R = nc_algebra(1,1);
4341setring R;
4342LIB "ncfactor.lib";
4343poly t = x; poly D =d;
4344poly p = 2*t^2*D^8-6*t*D^8+2*t^2*D^7+8*t*D^7+12*D^7-2*t^4*D^6+6*t^3*D^6+12*t*D^6-20*D^6
4345-2*t^4*D^5-8*t^3*D^5-4*t^2*D^5+12*t*D^5-28*D^5-12*t^3*D^4-4*t^2*D^4-4*t*D^4-24*D^4+4*t^4*D^3
4346-12*t^3*D^3+2*t^2*D^3-18*t*D^3+16*D^3+6*t^4*D^2-2*t^3*D^2+2*t^2*D^2-2*t*D^2+44*D^2+2*t^4*D
4347+12*t^3*D+2*t*D+4*t^3-8;
4348list lsng = facFirstWeyl(p);
4349print(lsng);
4350*/
Note: See TracBrowser for help on using the repository browser.