source: git/Singular/LIB/ncfactor.lib @ 6e40beb

fieker-DuValspielwiese
Last change on this file since 6e40beb was 06a7af8, checked in by Viktor Levandovskyy <levandov@…>, 14 years ago
*levandov: factorization in the 1st Weyl algebra by Albert Heinle, RWTH Aachen git-svn-id: file:///usr/local/Singular/svn/trunk@13303 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100755
File size: 35.9 KB
Line 
1////////////////////////////////////////////////////////////////////////////////////////////////////
2version = "$Id: ncfactor.lib, v 1.00 2010/02/15 10:06 heinle Exp $";
3category="Noncommutative";
4info="
5LIBRARY: ncfactor.lib   Tools for factorization in the first Weyl algebra
6AUTHORS: Albert Heinle,     albert.heinle@rwth-aachen.de
7
8MAIN PROCEDURES:
9homogfac(h);         computes one factorization of a homogeneous polynomial h
10homogfac_all(h);     computes all factorizations of a homogeneous polynomial h
11facwa(h);            computes all factorizations of an inhomogeneous polynomial h
12
13/* ring R = 0,(x,y),Ws(-1,1); */
14/* def r = nc_algebra(1,1); */
15/* setring(r); */
16";
17LIB "general.lib";
18LIB "nctools.lib";
19LIB "involut.lib";
20
21////////////////////////////////////////////////////////////////////////////////////////////////////
22//==================================================*
23//deletes double-entries in a list of factorization
24//without evaluating the product.
25static proc delete_dublicates_noteval(list l)
26{//proc delete_dublicates_noteval
27     list result= l;
28     int j; int k; int i;
29     int deleted = 0;
30     int is_equal;
31     for (i = 1; i<= size(l); i++)
32     {//Iterate over the different factorizations
33          for (j = i+1; j<= size(l); j++)
34          {//Compare the i'th factorization to the j'th
35               if (size(l[i])!= size(l[j]))
36               {//different sizes => not equal
37                    j++;
38                    continue;
39               }//different sizes => not equal
40               is_equal = 1;
41               for (k = 1; k <= size(l[i]);k++)
42               {//Compare every entry
43                    if (l[i][k]!=l[j][k])
44                    {
45                         is_equal = 0;
46                         break;
47                    }
48               }//Compare every entry
49               if (is_equal == 1)
50               {//Delete this entry, because there is another equal one int the list
51                    result = delete(result, i-deleted);
52                    deleted = deleted+1;
53                    break;
54               }//Delete this entry, because there is another equal one int the list
55          }//Compare the i'th factorization to the j'th
56     }//Iterate over the different factorizations
57     return(result);
58}//proc delete_dublicates_noteval
59
60//==================================================
61//deletes the double-entries in a list with
62//evaluating the products
63static proc delete_dublicates_eval(list l)
64{//proc delete_dublicates_eval
65     list result=l;
66     int j; int k; int i;
67     int deleted = 0;
68     int is_equal;
69     for (i = 1; i<= size(result); i++)
70     {//Iterating over all elements in result
71          for (j = i+1; j<= size(result); j++)
72          {//comparing with the other elements
73               if (product(result[i]) == product(result[j]))
74               {//There are two equal results; throw away that one with the smaller size
75                    if (size(result[i])>=size(result[j]))
76                    {//result[i] has more entries
77                         result = delete(result,j);
78                         continue;
79                    }//result[i] has more entries
80                    else
81                    {//result[j] has more entries
82                         result = delete(result,i);
83                         i--;
84                         break;
85                    }//result[j] has more entries
86               }//There are two equal results; throw away that one with the smaller size
87          }//comparing with the other elements
88     }//Iterating over all elements in result
89     return(result);
90}//proc delete_dublicates_eval
91
92
93//==================================================*
94//given a list of factors g and a desired size nof, the following
95//procedure combines the factors, such that we recieve a
96//list of the length nof.
97static proc combinekfinlf(list g, int nof, intvec limits) //nof stands for "number of factors"
98{//Procedure combinekfinlf
99     list result;
100     int i; int j; int k; //iteration variables
101     list fc; //fc stands for "factors combined"
102     list temp; //a temporary store for factors
103     def nofgl = size(g); //nofgl stands for "number of factors of the given list"
104     if (nofgl == 0)
105     {//g was the empty list
106          return(result);
107     }//g was the empty list
108     if (nof <= 0)
109     {//The user wants to recieve a negative number or no element as a result
110          return(result);
111     }//The user wants to recieve a negative number or no element as a result
112     if (nofgl == nof)
113     {//There are no factors to combine
114          if (limitcheck(g,limits))
115          {
116               result = result + list(g);
117          }
118          return(result);
119     }//There are no factors to combine
120     if (nof == 1)
121     {//User wants to get just one factor
122          if (limitcheck(list(product(g)),limits))
123          {
124               result = result + list(list(product(g)));
125          }
126          return(result);
127     }//User wants to get just one factor
128     for (i = nof; i > 1; i--)
129     {//computing the possibilities that have at least one original factor from g
130          for (j = i; j>=1; j--)
131          {//shifting the window of combinable factors to the left
132               fc = combinekfinlf(list(g[(j)..(j+nofgl - i)]),nof - i + 1,limits); //fc stands for "factors combined"
133               for (k = 1; k<=size(fc); k++)
134               {//iterating over the different solutions of the smaller problem
135                    if (j>1)
136                    {//There are g_i before the combination
137                         if (j+nofgl -i < nofgl)
138                         {//There are g_i after the combination
139                              temp = list(g[1..(j-1)]) + fc[k] + list(g[(j+nofgl-i+1)..nofgl]);
140                         }//There are g_i after the combination
141                         else
142                         {//There are no g_i after the combination
143                              temp = list(g[1..(j-1)]) + fc[k];
144                         }//There are no g_i after the combination
145                    }//There are g_i before the combination
146                    if (j==1)
147                    {//There are no g_i before the combination
148                         if (j+ nofgl -i <nofgl)
149                         {//There are g_i after the combination
150                              temp = fc[k]+ list(g[(j + nofgl - i +1)..nofgl]);
151                         }//There are g_i after the combination
152                    }//There are no g_i before the combination
153                    if (limitcheck(temp,limits))
154                    {
155                         result = result + list(temp);
156                    }
157               }//iterating over the different solutions of the smaller problem
158          }//shifting the window of combinable factors to the left
159     }//computing the possibilities that have at least one original factor from g
160     for (i = 2; i<=nofgl/nof;i++)
161     {//getting the other possible results
162          result = result + combinekfinlf(list(product(list(g[1..i])))+list(g[(i+1)..nofgl]),nof,limits);
163     }//getting the other possible results
164     result = delete_dublicates_noteval(result);
165     return(result);
166}//Procedure combinekfinlf
167
168
169//==================================================*
170//merges two sets of factors ignoring common
171//factors
172static proc merge_icf(list l1, list l2, intvec limits)
173{//proc merge_icf
174     list g;
175     list f;
176     int i; int j;
177     if (size(l1)==0)
178     {
179          return(list());
180     }
181     if (size(l2)==0)
182     {
183          return(list());
184     }
185     if (size(l2)<=size(l1))
186     {//l1 will be our g, l2 our f
187          g = l1;
188          f = l2;
189     }//l1 will be our g, l2 our f
190     else
191     {//l1 will be our f, l2 our g
192          g = l2;
193          f = l1;
194     }//l1 will be our f, l2 our g
195     def result = combinekfinlf(g,size(f),limits);
196     for (i = 1 ; i<= size(result); i++)
197     {//Adding the factors of f to every possibility listed in temp
198          for (j = 1; j<= size(f); j++)
199          {
200               result[i][j] = result[i][j]+f[j];
201          }
202          if(!limitcheck(result[i],limits))
203          {
204               result = delete(result,i);
205               i--;
206          }
207     }//Adding the factors of f to every possibility listed in temp
208     return(result);
209}//proc merge_icf
210
211//==================================================*
212//merges two sets of factors with respect to the occurrence
213//of common factors
214static proc merge_cf(list l1, list l2, intvec limits)
215{//proc merge_cf
216     list g;
217     list f;
218     int i; int j;
219     list pre;
220     list post;
221     list candidate;
222     list temp;
223     int temppos;
224     if (size(l1)==0)
225     {//the first list is empty
226          return(list());
227     }//the first list is empty
228     if(size(l2)==0)
229     {//the second list is empty
230          return(list());
231     }//the second list is empty
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     list M;
243     for (i = 2; i<size(f); i++)
244     {//finding common factors of f and g...
245        for (j=2; j<size(g);j++)
246        {//... with g
247             if (f[i] == g[j])
248             {//we have an equal pair
249                  M = M + list(list(i,j));
250             }//we have an equal pair
251        }//... with g
252     }//finding common factors of f and g...
253     if (g[1]==f[1])
254     {//Checking for the first elements to be equal
255          M = M + list(list(1,1));
256     }//Checking for the first elements to be equal
257     if (g[size(g)]==f[size(f)])
258     {//Checking for the last elements to be equal
259          M = M + list(list(size(f),size(g)));
260     }//Checking for the last elements to be equal
261     list result;//= list(list());
262     while(size(M)>0)
263     {//set of equal pairs is not empty
264          temp = M[1];
265          temppos = 1;
266          for (i = 2; i<=size(M); i++)
267          {//finding the minimal element of M
268               if (M[i][1]<=temp[1])
269               {//a possible candidate that is smaller than temp could have been found
270                    if (M[i][1]==temp[1])
271                    {//In this case we must look at the second number
272                         if (M[i][2]< temp[2])
273                         {//the candidate is smaller
274                              temp = M[i];
275                              temppos = i;
276                         }//the candidate is smaller
277                    }//In this case we must look at the second number
278                    else
279                    {//The candidate is definately smaller
280                         temp = M[i];
281                         temppos = i;
282                    }//The candidate is definately smaller
283               }//a possible candidate that is smaller than temp could have been found
284          }//finding the minimal element of M
285          M = delete(M, temppos);
286          if(temp[1]>1)
287          {//There are factors to combine before the equal factor
288               if (temp[1]<size(f))
289               {//The most common case
290                    //first the combinations ignoring common factors
291                    pre = merge_icf(list(f[1..(temp[1]-1)]),list(g[1..(temp[2]-1)]),limits);
292                    post = merge_icf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
293                    for (i = 1; i <= size(pre); i++)
294                    {//all possible pre's...
295                         for (j = 1; j<= size(post); j++)
296                         {//...combined with all possible post's
297                              candidate = pre[i]+list(f[temp[1]])+post[j];
298                              if (limitcheck(candidate,limits))
299                              {
300                                   result = result + list(candidate);
301                              }
302                         }//...combined with all possible post's
303                    }//all possible pre's...
304                    //Now the combinations with respect to common factors
305                    post = merge_cf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
306                    if (size(post)>0)
307                    {//There are factors to combine
308                         for (i = 1; i <= size(pre); i++)
309                         {//all possible pre's...
310                              for (j = 1; j<= size(post); j++)
311                              {//...combined with all possible post's
312                                   candidate= pre[i]+list(f[temp[1]])+post[j];
313                                   if (limitcheck(candidate,limits))
314                                   {
315                                        result = result + list(candidate);
316                                   }
317                              }//...combined with all possible post's
318                         }//all possible pre's...
319                    }//There are factors to combine
320               }//The most common case
321               else
322               {//the last factor is the common one
323                    pre = merge_icf(list(f[1..(temp[1]-1)]),list(g[1..(temp[2]-1)]),limits);
324                    for (i = 1; i<= size(pre); i++)
325                    {//iterating over the possible pre-factors
326                         candidate = pre[i]+list(f[temp[1]]);
327                         if (limitcheck(candidate,limits))
328                         {
329                              result = result + list(candidate);
330                         }
331                    }//iterating over the possible pre-factors
332               }//the last factor is the common one
333          }//There are factors to combine before the equal factor
334          else
335          {//There are no factors to combine before the equal factor
336               if (temp[1]<size(f))
337               {//Just a check for security
338                    //first without common factors
339                    post=merge_icf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
340                    for (i = 1; i<=size(post); i++)
341                    {
342                         candidate = list(f[temp[1]])+post[i];
343                         if (limitcheck(candidate,limits))
344                         {
345                              result = result + list(candidate);
346                         }
347                    }
348                    //Now with common factors
349                    post = merge_cf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
350                    if(size(post)>0)
351                    {//we could find other combinations
352                         for (i = 1; i<=size(post); i++)
353                         {
354                              candidate = list(f[temp[1]])+post[i];
355                              if (limitcheck(candidate,limits))
356                              {
357                                   result = result + list(candidate);
358                              }
359                         }
360                    }//we could find other combinations
361               }//Just a check for security
362          }//There are no factors to combine before the equal factor
363     }//set of equal pairs is not empty
364     return(result);
365}//proc merge_cf
366
367
368//==================================================*
369//merges two sets of factors
370
371static proc mergence(list l1, list l2, intvec limits)
372{//Procedure mergence
373     list g;
374     list f;
375     int l; int k;
376     list F;
377     if (size(l2)<=size(l1))
378     {//l1 will be our g, l2 our f
379          g = l1;
380          f = l2;
381     }//l1 will be our g, l2 our f
382     else
383     {//l1 will be our f, l2 our g
384          g = l2;
385          f = l1;
386     }//l1 will be our f, l2 our g
387     list result;
388     for (l = size(f); l>=1; l--)
389     {//all possibilities to combine the factors of f
390          F = combinekfinlf(f,l,limits);
391          for (k = 1; k<= size(F);k++)
392          {//for all possibilities of combinations of the factors of f
393               result = result + merge_cf(F[k],g,limits);
394               result = result + merge_icf(F[k],g,limits);
395          }//for all possibilities of combinations of the factors of f
396     }//all possibilities to combine the factors of f
397     return(result);
398}//Procedure mergence
399
400
401//==================================================
402//Checks, whether a list of factors doesn't exceed the given limits
403static proc limitcheck(list g, intvec limits)
404{//proc limitcheck
405     int i;
406     if (size(limits)!=3)
407     {//check the input
408          return(0);
409     }//check the input
410     if(size(g)==0)
411     {
412          return(0);
413     }
414     def prod = product(g);
415     def limg = intvec(deg(prod,intvec(1,1)) ,deg(prod,intvec(1,0)),deg(prod,intvec(0,1)));
416     for (i = 1; i<=size(limg);i++)
417     {//the final check
418          if(limg[i]>limits[i])
419          {
420               return(0);
421          }
422     }//the final check
423     return(1);
424}//proc limitcheck
425
426
427//==================================================*
428//one factorization of a homogeneous polynomial
429//in the first Weyl Algebra
430proc homogfac(poly h)
431"USAGE: homogfac(h); h is a homogeneous polynomial in the first Weyl algebra with respect to the weight vector [-1,1]
432RETURN: list
433PURPOSE: Computes a factorization of a homogeneous polynomial h with respect to the weight vector [-1,1] in the first Weyl algebra
434THEORY: @code{homogfac} returns a list with a factorization of the given, homogeneous polynomial. If the degree of the polynomial is k with k positive, the last k entries in the output list are the second variable. If k is positive, the last k entries will be x. The other entries will be irreducible polynomials of degree zero or 1 resp. -1.
435EXAMPLE: example homogfac; shows examples
436SEE ALSO: homogfac_all
437"{//proc homogfac
438     if (!isWeyl())
439     {//Our basering is not the Weyl algebra
440          return(list());
441     }//Our basering is not the Weyl algebra
442     if(nvars(basering)!=2)
443     {//Our basering is the Weyl algebra, but not the first
444          return(list());
445     }//Our basering is the Weyl algebra, but not the first
446     def r = basering;
447     poly hath;
448     int i; int j;
449     if (!homogwithorder(h,intvec(-1,1)))
450     {//The given polynomial is not homogeneous
451          return(list());
452     }//The given polynomial is not homogeneous
453     if (h==0)
454     {
455          return(list(0));
456     }
457     list result;
458     int m = deg(h,intvec(-1,1));
459     if (m!=0)
460     {//The degree is not zero
461          if (m <0)
462          {//There are more x than y
463               hath = lift(var(1)^(-m),h)[1,1];
464               for (i = 1; i<=-m; i++)
465               {
466                    result = result + list(var(1));
467               }
468          }//There are more x than y
469          else
470          {//There are more y than x
471               hath = lift(var(2)^m,h)[1,1];
472               for (i = 1; i<=m;i++)
473               {
474                    result = result + list(var(2));
475               }
476          }//There are more y than x
477     }//The degree is not zero
478     else
479     {//The degree is zero
480          hath = h;
481     }//The degree is zero
482     //beginning to transform x^i*y^i in teta(teta-1)...(teta-i+1)
483     list mons;
484     for(i = 1; i<=size(hath);i++)
485     {//Putting the monomials in a list
486          mons = mons+list(hath[i]);
487     }//Putting the monomials in a list
488     ring tempRing = 0,(x,y,teta),dp;
489     setring tempRing;
490     map tetamap = r,x,y;
491     list mons = tetamap(mons);
492     poly entry;
493     for (i = 1; i<=size(mons);i++)
494     {//transforming the monomials as monomials in theta
495          entry = leadcoef(mons[i]);
496          for (j = 0; j<leadexp(mons[i])[2];j++)
497          {
498               entry = entry * (teta-j);
499          }
500          mons[i] = entry;
501     }//transforming the monomials as monomials in theta
502     list azeroresult = factorize(sum(mons));
503     list azeroresult_return_form;
504     for (i = 1; i<=size(azeroresult[1]);i++)
505     {//rewrite the result of the commutative factorization
506          for (j = 1; j <= azeroresult[2][i];j++)
507          {
508               azeroresult_return_form = azeroresult_return_form + list(azeroresult[1][i]);
509          }
510     }//rewrite the result of the commutative factorization
511     setring(r);
512     map finalmap = tempRing,var(1),var(2),var(1)*var(2);
513     list tempresult = finalmap(azeroresult_return_form);
514     for (i = 1; i<=size(tempresult);i++)
515     {//factorizations of theta resp. theta +1
516          if(tempresult[i]==var(1)*var(2))
517          {
518               tempresult = insert(tempresult,var(1),i-1);
519               i++;
520               tempresult[i]=var(2);
521          }
522          if(tempresult[i]==var(2)*var(1))
523          {
524               tempresult = insert(tempresult,var(2),i-1);
525               i++;
526               tempresult[i]=var(1);
527          }
528     }//factorizations of theta resp. theta +1
529     result = tempresult+result;
530     return(result);
531}//proc homogfac
532example
533{
534     "EXAMPLE:";echo=2;
535     ring R = 0,(x,y),Ws(-1,1);
536     def r = nc_algebra(1,1);
537     setring(r);
538     poly h = (x^2*y^2+1)*(x^4);
539     homogfac(h);
540}
541
542//==================================================
543//Computes all possible homogeneous factorizations
544proc homogfac_all(poly h)
545"USAGE: homogfac_all(h); h is a homogeneous polynomial in the first Weyl algebra with respect to the weight vector [-1,1]
546RETURN: list
547PURPOSE: Computes all factorizations of a homogeneous polynomial h with respect to the weight vector [-1,1] in the first Weyl algebra
548THEORY: @code{homogfac} returns a list with all factorization of the given, homogeneous polynomial. It uses the output of homogfac and permutes its entries with respect to the commutation rule. Furthermore, if a factor of degree zero is irreducible in K[\theta], but reducible in the first Weyl algebra, the permutations of this element with the other entries will also be computed.
549EXAMPLE: example homogfac; shows examples
550SEE ALSO: homogfac
551"{//proc HomogFacAll
552     if (deg(h,intvec(1,1)) <= 0 )
553     {//h is a constant
554          return(list(list(h)));
555     }//h is a constant
556     if (!isWeyl())
557     {//Our basering is not the Weyl algebra
558          return(list());
559     }//Our basering is not the Weyl algebra
560     if(nvars(basering)!=2)
561     {//Our basering is the Weyl algebra, but not the first
562          return(list());
563     }//Our basering is the Weyl algebra, but not the first
564     def r = basering;
565     list one_hom_fac; //stands for one homogeneous factorization
566     int i; int j; int k;
567     //Compute again a homogeneous factorization
568     one_hom_fac = homogfac(h);
569     if (size(one_hom_fac) == 0)
570     {//there is no homogeneous factorization or the polynomial was not homogeneous
571          return(list());
572     }//there is no homogeneous factorization or the polynomial was not homogeneous
573     //divide list in A0-Part and a list of x's resp. y's
574     list list_not_azero = list();
575     list list_azero;
576     list k_factor;
577     int is_list_not_azero_empty = 1;
578     int is_list_azero_empty = 1;
579     k_factor = list(one_hom_fac[1]);
580     if (absValue(deg(h,intvec(-1,1)))<size(one_hom_fac)-1)
581     {//There is a nontrivial A_0-part
582          list_azero = one_hom_fac[2..(size(one_hom_fac)-absValue(deg(h,intvec(-1,1))))];
583          is_list_azero_empty = 0;
584     }//There is a nontrivial A_0 part
585     for (i = 1; i<=size(list_azero)-1;i++)
586     {//in homogfac, we factorized theta, and this will be made undone
587          if (list_azero[i] == var(1))
588          {
589               if (list_azero[i+1]==var(2))
590               {
591                    list_azero[i] = var(1)*var(2);
592                    list_azero = delete(list_azero,i+1);
593               }
594          }
595          if (list_azero[i] == var(2))
596          {
597               if (list_azero[i+1]==var(1))
598               {
599                    list_azero[i] = var(2)*var(1);
600                    list_azero = delete(list_azero,i+1);
601               }
602          }
603     }//in homogfac, we factorized theta, and this will be made undone
604     if(deg(h,intvec(-1,1))!=0)
605     {//list_not_azero is not empty
606          list_not_azero = one_hom_fac[(size(one_hom_fac)-absValue(deg(h,intvec(-1,1)))+1)..size(one_hom_fac)];
607          is_list_not_azero_empty = 0;
608     }//list_not_azero is not empty
609     //Map list_azero in K[theta]
610     ring tempRing = 0,(x,y,theta), dp;
611     setring(tempRing);
612     poly entry;
613     map thetamap = r,x,y;
614     if(!is_list_not_azero_empty)
615     {//Mapping in Singular is only possible, if the list before contained at least one element of the other ring
616          list list_not_azero = thetamap(list_not_azero);
617     }//Mapping in Singular is only possible, if the list before contained at least one element of the other ring
618     if(!is_list_azero_empty)
619     {//Mapping in Singular is only possible, if the list before contained at least one element of the other ring
620          list list_azero= thetamap(list_azero);
621     }//Mapping in Singular is only possible, if the list before contained at least one element of the other ring
622     list k_factor = thetamap(k_factor);
623     list tempmons;
624     for(i = 1; i<=size(list_azero);i++)
625     {//rewrite the polynomials in A1 as polynomials in K[theta]
626          tempmons = list();
627          for (j = 1; j<=size(list_azero[i]);j++)
628          {
629               tempmons = tempmons + list(list_azero[i][j]);
630          }
631          for (j = 1 ; j<=size(tempmons);j++)
632          {
633               entry = leadcoef(tempmons[j]);
634               for (k = 0; k < leadexp(tempmons[j])[2];k++)
635               {
636                    entry = entry*(theta-k);
637               }
638               tempmons[j] = entry;
639          }
640          list_azero[i] = sum(tempmons);
641     }//rewrite the polynomials in A1 as polynomials in K[theta]
642     //Compute all permutations of the A0-part
643     list result;
644     int shift_sign;
645     int shift;
646     poly shiftvar;
647     if (size(list_not_azero)!=0)
648     {//Compute all possibilities to permute the x's resp. the y's in the list
649          if (list_not_azero[1] == x)
650          {//h had a negative weighted degree
651               shift_sign = 1;
652               shiftvar = x;
653          }//h had a negative weighted degree
654          else
655          {//h had a positive weighted degree
656               shift_sign = -1;
657               shiftvar = y;
658          }//h had a positive weighted degree
659          result = permpp(list_azero + list_not_azero);
660          for (i = 1; i<= size(result); i++)
661          {//adjust the a_0-parts
662               shift = 0;
663               for (j=1; j<=size(result[i]);j++)
664               {
665                    if (result[i][j]==shiftvar)
666                    {
667                         shift = shift + shift_sign;
668                    }
669                    else
670                    {
671                         result[i][j] = subst(result[i][j],theta,theta + shift);
672                    }
673               }
674          }//adjust the a_0-parts
675     }//Compute all possibilities to permute the x's resp. the y's in the list
676     else
677     {//The result is just all the permutations of the a_0-part
678          result = permpp(list_azero);
679     }//The result is just all the permutations of the a_0 part
680     if (size(result)==0)
681     {
682          return(result);
683     }
684     //Now we are going deeper and search for theta resp. theta + 1, substitute them by xy resp. yx and go on permuting
685     int found_theta;
686     int thetapos;
687     list leftpart;
688     list rightpart;
689     list lparts;
690     list rparts;
691     list tempadd;
692     for (i = 1; i<=size(result) ; i++)
693     {//checking every entry of result for theta or theta +1
694          found_theta = 0;
695          for(j=1;j<=size(result[i]);j++)
696          {
697               if (result[i][j]==theta)
698               {//the jth entry is theta and can be written as x*y
699                    thetapos = j;
700                    result[i]= insert(result[i],x,j-1);
701                    j++;
702                    result[i][j] = y;
703                    found_theta = 1;
704                    break;
705               }//the jth entry is theta and can be written as x*y
706               if(result[i][j] == theta +1)
707               {
708                    thetapos = j;
709                    result[i] = insert(result[i],y,j-1);
710                    j++;
711                    result[i][j] = x;
712                    found_theta = 1;
713                    break;
714               }
715          }
716          if (found_theta)
717          {//One entry was theta resp. theta +1
718               leftpart = result[i];
719               leftpart = leftpart[1..thetapos];
720               rightpart = result[i];
721               rightpart = rightpart[(thetapos+1)..size(rightpart)];
722               lparts = list(leftpart);
723               rparts = list(rightpart);
724               //first deal with the left part
725               if (leftpart[thetapos] == x)
726               {
727                    shift_sign = 1;
728                    shiftvar = x;
729               }
730               else
731               {
732                    shift_sign = -1;
733                    shiftvar = y;
734               }
735               for (j = size(leftpart); j>1;j--)
736               {//drip x resp. y
737                    if (leftpart[j-1]==shiftvar)
738                    {//commutative
739                         j--;
740                         continue;
741                    }//commutative
742                    if (deg(leftpart[j-1],intvec(-1,1,0))!=0)
743                    {//stop here
744                         break;
745                    }//stop here
746                    //Here, we can only have a a0- part
747                    leftpart[j] = subst(leftpart[j-1],theta, theta + shift_sign);
748                    leftpart[j-1] = shiftvar;
749                    lparts = lparts + list(leftpart);
750                }//drip x resp. y
751                //and now deal with the right part
752                if (rightpart[1] == x)
753                {
754                     shift_sign = 1;
755                     shiftvar = x;
756                }
757                else
758                {
759                     shift_sign = -1;
760                     shiftvar = y;
761                }
762                for (j = 1 ; j < size(rightpart); j++)
763                {
764                     if (rightpart[j+1] == shiftvar)
765                     {
766                          j++;
767                          continue;
768                     }
769                     if (deg(rightpart[j+1],intvec(-1,1,0))!=0)
770                     {
771                          break;
772                     }
773                     rightpart[j] = subst(rightpart[j+1], theta, theta - shift_sign);
774                     rightpart[j+1] = shiftvar;
775                     rparts = rparts + list(rightpart);
776                }
777                //And now, we put all possibilities together
778                tempadd = list();
779                for (j = 1; j<=size(lparts); j++)
780                {
781                   for (k = 1; k<=size(rparts);k++)
782                   {
783                              tempadd = tempadd + list(lparts[j]+rparts[k]);
784                   }
785                }
786                tempadd = delete(tempadd,1); // The first entry is already in the list
787                result = result + tempadd;
788                continue; //We can may be not be done already with the ith entry
789          }//One entry was theta resp. theta +1
790     }//checking every entry of result for theta or theta +1
791     //map back to the basering
792     setring(r);
793     map finalmap = tempRing, var(1), var(2),var(1)*var(2);
794     list result = finalmap(result);
795     for (i=1; i<=size(result);i++)
796     {//adding the K factor
797          result[i] = k_factor + result[i];
798     }//adding the k-factor
799     result = delete_dublicates_noteval(result);
800     return(result);
801}//proc HomogFacAll
802example
803{
804     "EXAMPLE:";echo=2;
805     ring R = 0,(x,y),Ws(-1,1);
806     def r = nc_algebra(1,1);
807     setring(r);
808     poly h = (x^2*y^2+1)*(x^4);
809     homogfac_all(h);
810}
811
812//==================================================*
813//Computes all permutations of a given list
814static proc perm(list l)
815{//proc perm
816     int i; int j;
817     list tempresult;
818     list result;
819     if (size(l)==0)
820     {
821          return(list());
822     }
823     if (size(l)==1)
824     {
825          return(list(l));
826     }
827     for (i = 1; i<=size(l); i++ )
828     {
829          tempresult = perm(delete(l,i));
830          for (j = 1; j<=size(tempresult);j++)
831          {
832               tempresult[j] = list(l[i])+tempresult[j];
833          }
834          result = result+tempresult;
835     }
836     return(result);
837}//proc perm
838
839//==================================================
840//computes all permutations of a given list by
841//ignoring equal entries (faster than perm)
842static proc permpp(list l)
843{//proc permpp
844     int i; int j;
845     list tempresult;
846     list l_without_double;
847     list l_without_double_pos;
848     int double_entry;
849     list result;
850     if (size(l)==0)
851     {
852          return(list());
853     }
854     if (size(l)==1)
855     {
856          return(list(l));
857     }
858     for (i = 1; i<=size(l);i++)
859     {//Filling the list with unique entries
860          double_entry = 0;
861          for (j = 1; j<=size(l_without_double);j++)
862          {
863               if (l_without_double[j] == l[i])
864               {
865                    double_entry = 1;
866                    break;
867               }
868          }
869          if (!double_entry)
870          {
871               l_without_double = l_without_double + list(l[i]);
872               l_without_double_pos = l_without_double_pos + list(i);
873          }
874     }//Filling the list with unique entries
875     for (i = 1; i<=size(l_without_double); i++ )
876     {
877          tempresult = permpp(delete(l,l_without_double_pos[i]));
878          for (j = 1; j<=size(tempresult);j++)
879          {
880               tempresult[j] = list(l_without_double[i])+tempresult[j];
881          }
882          result = result+tempresult;
883     }
884     return(result);
885}//proc permpp
886
887//==================================================
888//factorization of the first Weyl Algebra
889proc facwa(poly h)
890"USAGE: facwa(h); h is a polynomial in the first Weyl algebra
891RETURN: list
892PURPOSE: Computes a factorization of a polynomial h in the first Weyl algebra
893THEORY: @code{homogfac} returns a list with some factorizations of the given polynomial. The possibilities of the factorization of the highest homogeneous part and those of the lowest will be merged.
894EXAMPLE: example facwa; shows examples
895SEE ALSO: homogfac_all, homogfac
896"{//proc facwa
897     if(homogwithorder(h,intvec(-1,1)))
898     {
899          return(homogfac_all(h));
900     }
901     //Redefine the ring in my standard form
902     if (!isWeyl())
903     {//Our basering is not the Weyl algebra
904          return(list());
905     }//Our basering is not the Weyl algebra
906     if(nvars(basering)!=2)
907     {//Our basering is the Weyl algebra, but not the first
908          return(list());
909     }//Our basering is the Weyl algebra, but not the first
910     def r = basering;
911     map invo = basering,-var(1),var(2);
912     int i; int j; int k;
913     intvec limits = deg(h,intvec(1,1)) ,deg(h,intvec(1,0)),deg(h,intvec(0,1));
914     def prod;
915     //end finding the limits
916     poly maxh = jet(h,deg(h,intvec(-1,1)),intvec(-1,1))-jet(h,deg(h,intvec(-1,1))-1,intvec(-1,1));
917     poly minh = jet(h,deg(h,intvec(1,-1)),intvec(1,-1))-jet(h,deg(h,intvec(1,-1))-1,intvec(1,-1));
918     list result;
919     list temp;
920     list homogtemp;
921     list M; list hatM;
922     list f1 = homogfac_all(maxh);
923     list f2 = homogfac_all(minh);
924     int is_equal;
925     poly hath;
926     for (i = 1; i<=size(f1);i++)
927     {//Merge all combinations
928          for (j = 1; j<=size(f2); j++)
929          {
930               M = M + mergence(f1[i],f2[j],limits);
931          }
932     }//Merge all combinations
933     for (i = 1 ; i<= size(M); i++)
934     {//filter valid combinations
935          if (product(M[i]) == h)
936          {//We have one factorization
937               result = result + list(M[i]);
938               M = delete(M,i);
939               continue;
940          }//We have one factorization
941          else
942          {
943               if (deg(h,intvec(-1,1))<=deg(h-product(M[i]),intvec(-1,1)))
944               {
945                    M = delete(M,i);
946                    continue;
947               }
948               if (deg(h,intvec(1,-1))<=deg(h-product(M[i]),intvec(1,-1)))
949               {
950                    M = delete(M,i);
951                    continue;
952               }
953          }
954     }//filter valid combinations
955     M = delete_dublicates_eval(M);
956     while(size(M)>0)
957     {//work on the elements of M
958          hatM = list();
959          for(i = 1; i<=size(M); i++)
960          {//iterate over all elements of M
961               hath = h-product(M[i]);
962               temp = list();
963               //First check for common inhomogeneous factors between hath and h
964               if (involution(NF(involution(hath,invo), std(involution(ideal(M[i][1]),invo))),invo)==0)
965               {//hath and h have a common factor on the left
966                    j = 1;
967                    f1 = M[i];
968                    if (j+1<=size(f1))
969                    {//Checking for more than one common factor
970                         while(involution(NF(involution(hath,invo),std(involution(ideal(product(f1[1..(j+1)])),invo))),invo)==0)
971                         {
972                              if (j+1<size(f1))
973                              {
974                                   j++;
975                              }
976                              else
977                              {
978                                   break;
979                              }
980                         }
981                    }//Checking for more than one common factor
982                    f2 = list(f1[1..j])+list(involution(lift(involution(product(f1[1..j]),invo),involution(hath,invo))[1,1],invo));
983                    temp = temp + merge_cf(f2,f1,limits);
984               }//hath and h have a common factor on the left
985               if (reduce(hath, std(ideal(M[i][size(M[i])])))==0)
986               {//hath and h have a common factor on the right
987                    j = size(M[i]);
988                    f1 = M[i];
989                    if (j-1>0)
990                    {//Checking for more than one factor
991                         while(reduce(hath,std(ideal(product(f1[(j-1)..size(f1)]))))==0)
992                         {
993                              if (j-1>1)
994                              {
995                                   j--;
996                              }
997                              else
998                              {
999                                   break;
1000                              }
1001                         }
1002                    }//Checking for more than one factor
1003                    f2 = list(lift(product(f1[j..size(f1)]),hath)[1,1])+list(f1[j..size(f1)]);
1004                    temp = temp + merge_cf(f2,M[i],limits);
1005               }//hath and h have a common factor on the right
1006               //and now the homogeneous
1007               maxh = jet(hath,deg(hath,intvec(-1,1)),intvec(-1,1))-jet(hath,deg(hath,intvec(-1,1))-1,intvec(-1,1));
1008               minh = jet(hath,deg(hath,intvec(1,-1)),intvec(1,-1))-jet(hath,deg(hath,intvec(1,-1))-1,intvec(1,-1));
1009               f1 = homogfac_all(maxh);
1010               f2 = homogfac_all(minh);
1011               for (j = 1; j<=size(f1);j++)
1012               {
1013                    for (k=1; k<=size(f2);k++)
1014                    {
1015                         homogtemp = mergence(f1[j],f2[k],limits);
1016                    }
1017               }
1018               for (j = 1; j<= size(homogtemp); j++)
1019               {
1020                    temp = temp + mergence(homogtemp[j],M[i],limits);
1021               }
1022               for (j = 1; j<=size(temp); j++)
1023               {//filtering invalid entries in temp
1024                    if(product(temp[j])==h)
1025                    {//This is already a result
1026                         result = result + list(temp[j]);
1027                         temp = delete(temp,j);
1028                         continue;
1029                    }//This is already a result
1030                    if (deg(hath,intvec(-1,1))<=deg(hath-product(temp[j]),intvec(-1,1)))
1031                    {
1032                         temp = delete(temp,j);
1033                         continue;
1034                    }
1035               }//filtering invalid entries in temp
1036               hatM = hatM + temp;
1037          }//iterate over all elements of M
1038          M = hatM;
1039          for (i = 1; i<=size(M);i++)
1040          {//checking for complete factorizations
1041               if (h == product(M[i]))
1042               {
1043                    result = result + list(M[i]);
1044                    M = delete(M,i);
1045                    continue;
1046               }
1047          }//checking for complete factorizations
1048          M = delete_dublicates_eval(M);
1049     }//work on the elements of M
1050     //In the case, that there is none, write a constant factor before the factor of interest.
1051     for (i = 1 ; i<=size(result);i++)
1052     {//add a constant factor
1053          if (deg(result[i][1],intvec(1,1))!=0)
1054          {
1055               result[i] = insert(result[i],1);
1056          }
1057     }//add a constant factor
1058     result = delete_dublicates_noteval(result);
1059     return(result);
1060}//proc facwa
1061example
1062{
1063     "EXAMPLE:";echo=2;
1064     ring R = 0,(x,y),Ws(-1,1);
1065     def r = nc_algebra(1,1);
1066     setring(r);
1067     poly h = (x^2*y^2+x)*x;
1068     facwa(h);
1069}
1070
1071//==================================================
1072/*Singular has no way implemented to test polynomials
1073 for homogenity with respect to a weight vector.
1074 The following procedure does exactly this*/
1075static proc homogwithorder(poly h, intvec weights)
1076{//proc homogwithorder
1077     if(size(weights) != nvars(basering))
1078     {//The user does not know how many variables the current ring has
1079          return(0);
1080     }//The user does not know how many variables the current ring has
1081     int i;
1082     int dofp = deg(h,weights); //degree of polynomial
1083     for (i = 1; i<=size(h);i++)
1084     {
1085          if (deg(h[i],weights)!=dofp)
1086          {
1087               return(0);
1088          }
1089     }
1090     return(1);
1091}//proc homogwithorder
1092/*
1093Example polynomials where one can find factorizations
1094(x^2+y)*(x^2+y);
1095(x^2+x)*(x^2+y);
1096(x^3+x+1)*(x^4+y*x+2);
1097(x^2*y+y)*(y+x*y);
1098y^3+x*y^3+2*y^2+2*(x+1)*y^2+y+(x+2)*y; //Example 5 Gregoriev Schwarz.
1099(y+1)*(y+1)*(y+x*y); //Landau Example projected to the first dimension.
1100 */
Note: See TracBrowser for help on using the repository browser.