Changeset fa85ef in git


Ignore:
Timestamp:
Oct 8, 2010, 9:44:27 PM (14 years ago)
Author:
Viktor Levandovskyy <levandov@…>
Branches:
(u'fieker-DuVal', '117eb8c30fc9e991c4decca4832b1d19036c4c65')(u'spielwiese', '38077648e7239f98078663eb941c3c979511150a')
Children:
1e33d5df4b2c03f3879e5b15e65274116be26b6b
Parents:
cc6f7a79d5d975a00b14db3835c4b6c0f13c5553
Message:
*levandov: reworked docs, bugs fixed etc

git-svn-id: file:///usr/local/Singular/svn/trunk@13439 2c84dea3-7e68-4137-9b89-c4e89433aadc
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Singular/LIB/ncfactor.lib

    rcc6f7a rfa85ef  
    33category="Noncommutative";
    44info="
    5 LIBRARY: ncfactor.lib   Tools for factorization in the first Weyl algebra
     5LIBRARY: ncfactor.lib  Tools for factorization in some noncommutative algebras
    66AUTHORS: Albert Heinle,     albert.heinle@rwth-aachen.de
     7@*       Viktor Levandovskyy,     levandov@math.rwth-aachen.de
     8OVERVIEW: In this library, new methods for factorization on polynomials
     9
     10are implemented for two algebras over a field K. Recall, that
     11
     12the first Weyl algebra over K is generated by x,d obeying the relation d*x=x*d+1.
     13
     14The first shift algebra over K is generated by x,s obeying the relation s*x=x*s+s.
    715
    816PROCEDURES:
     
    1018testNCfac(l[,h]);   tests factorizations from a given list for correctness
    1119facSubWeyl(h,X,D);  factorization in the first Weyl algebra as a subalgebra
     20facFirstShift(h);   factorization in the first shift algebra
    1221";
    1322
     
    1726LIB "freegb.lib"; // for isVar
    1827
    19 /* ring R = 0,(x,y),Ws(-1,1); */
    20 /* def r = nc_algebra(1,1); */
    21 /* setring(r); */
     28proc tst_ncfactor()
     29{
     30  example facFirstWeyl;
     31  example facFirstShift;
     32  example facSubWeyl;
     33  example testNCfac;
     34}
    2235
    2336/////////////////////////////////////////////////////
     
    2740static proc delete_dublicates_noteval(list l)
    2841{//proc delete_dublicates_noteval
    29      list result= l;
    30      int j; int k; int i;
    31      int deleted = 0;
    32      int is_equal;
    33      for (i = 1; i<= size(l); i++)
    34      {//Iterate over the different factorizations
    35           for (j = i+1; j<= size(l); j++)
    36           {//Compare the i'th factorization to the j'th
    37                if (size(l[i])!= size(l[j]))
    38                {//different sizes => not equal
    39                     j++;
    40                     continue;
    41            }//different sizes => not equal
    42            is_equal = 1;
    43            for (k = 1; k <= size(l[i]);k++)
    44            {//Compare every entry
    45             if (l[i][k]!=l[j][k])
    46             {
    47              is_equal = 0;
    48              break;
    49             }
    50            }//Compare every entry
    51            if (is_equal == 1)
    52            {//Delete this entry, because there is another equal one int the list
    53             result = delete(result, i-deleted);
    54             deleted = deleted+1;
    55             break;
    56            }//Delete this entry, because there is another equal one int the list
    57       }//Compare the i'th factorization to the j'th
    58      }//Iterate over the different factorizations
    59      return(result);
     42  list result= l;
     43  int j; int k; int i;
     44  int deleted = 0;
     45  int is_equal;
     46  for (i = 1; i<= size(l); i++)
     47  {//Iterate over the different factorizations
     48    for (j = i+1; j<= size(l); j++)
     49    {//Compare the i'th factorization to the j'th
     50      if (size(l[i])!= size(l[j]))
     51      {//different sizes => not equal
     52        j++;
     53        continue;
     54      }//different sizes => not equal
     55      is_equal = 1;
     56      for (k = 1; k <= size(l[i]);k++)
     57      {//Compare every entry
     58        if (l[i][k]!=l[j][k])
     59        {
     60          is_equal = 0;
     61          break;
     62        }
     63      }//Compare every entry
     64      if (is_equal == 1)
     65      {//Delete this entry, because there is another equal one int the list
     66        result = delete(result, i-deleted);
     67        deleted = deleted+1;
     68        break;
     69      }//Delete this entry, because there is another equal one int the list
     70    }//Compare the i'th factorization to the j'th
     71  }//Iterate over the different factorizations
     72  return(result);
    6073}//proc delete_dublicates_noteval
    6174
     
    6578static proc delete_dublicates_eval(list l)
    6679{//proc delete_dublicates_eval
    67      list result=l;
    68      int j; int k; int i;
    69      int deleted = 0;
    70      int is_equal;
    71      for (i = 1; i<= size(result); i++)
    72      {//Iterating over all elements in result
    73       for (j = i+1; j<= size(result); j++)
    74       {//comparing with the other elements
    75            if (product(result[i]) == product(result[j]))
    76            {//There are two equal results; throw away that one with the smaller size
    77             if (size(result[i])>=size(result[j]))
    78             {//result[i] has more entries
    79              result = delete(result,j);
    80              continue;
    81             }//result[i] has more entries
    82             else
    83             {//result[j] has more entries
    84              result = delete(result,i);
    85              i--;
    86              break;
    87             }//result[j] has more entries
    88            }//There are two equal results; throw away that one with the smaller size
    89       }//comparing with the other elements
    90      }//Iterating over all elements in result
    91      return(result);
     80  list result=l;
     81  int j; int k; int i;
     82  int deleted = 0;
     83  int is_equal;
     84  for (i = 1; i<= size(result); i++)
     85  {//Iterating over all elements in result
     86    for (j = i+1; j<= size(result); j++)
     87    {//comparing with the other elements
     88      if (product(result[i]) == product(result[j]))
     89      {//There are two equal results; throw away that one with the smaller size
     90        if (size(result[i])>=size(result[j]))
     91        {//result[i] has more entries
     92          result = delete(result,j);
     93          continue;
     94        }//result[i] has more entries
     95        else
     96        {//result[j] has more entries
     97          result = delete(result,i);
     98          i--;
     99          break;
     100        }//result[j] has more entries
     101      }//There are two equal results; throw away that one with the smaller size
     102    }//comparing with the other elements
     103  }//Iterating over all elements in result
     104  return(result);
    92105}//proc delete_dublicates_eval
    93106
     
    99112static proc combinekfinlf(list g, int nof, intvec limits) //nof stands for "number of factors"
    100113{//Procedure combinekfinlf
    101      list result;
    102      int i; int j; int k; //iteration variables
    103      list fc; //fc stands for "factors combined"
    104      list temp; //a temporary store for factors
    105      def nofgl = size(g); //nofgl stands for "number of factors of the given list"
    106      if (nofgl == 0)
    107      {//g was the empty list
    108       return(result);
    109      }//g was the empty list
    110      if (nof <= 0)
    111      {//The user wants to recieve a negative number or no element as a result
    112       return(result);
    113      }//The user wants to recieve a negative number or no element as a result
    114      if (nofgl == nof)
    115      {//There are no factors to combine
    116       if (limitcheck(g,limits))
    117       {
    118            result = result + list(g);
    119       }
    120       return(result);
    121      }//There are no factors to combine
    122      if (nof == 1)
    123      {//User wants to get just one factor
    124       if (limitcheck(list(product(g)),limits))
    125       {
    126            result = result + list(list(product(g)));
    127       }
    128       return(result);
    129      }//User wants to get just one factor
    130      for (i = nof; i > 1; i--)
    131      {//computing the possibilities that have at least one original factor from g
    132       for (j = i; j>=1; j--)
    133       {//shifting the window of combinable factors to the left
    134            fc = combinekfinlf(list(g[(j)..(j+nofgl - i)]),nof - i + 1,limits); //fc stands for "factors combined"
    135            for (k = 1; k<=size(fc); k++)
    136            {//iterating over the different solutions of the smaller problem
    137             if (j>1)
    138             {//There are g_i before the combination
    139              if (j+nofgl -i < nofgl)
    140              {//There are g_i after the combination
    141                   temp = list(g[1..(j-1)]) + fc[k] + list(g[(j+nofgl-i+1)..nofgl]);
    142              }//There are g_i after the combination
    143              else
    144              {//There are no g_i after the combination
    145                   temp = list(g[1..(j-1)]) + fc[k];
    146              }//There are no g_i after the combination
    147             }//There are g_i before the combination
    148             if (j==1)
    149             {//There are no g_i before the combination
    150              if (j+ nofgl -i <nofgl)
    151              {//There are g_i after the combination
    152                   temp = fc[k]+ list(g[(j + nofgl - i +1)..nofgl]);
    153              }//There are g_i after the combination
    154             }//There are no g_i before the combination
    155             if (limitcheck(temp,limits))
    156             {
    157              result = result + list(temp);
    158             }
    159            }//iterating over the different solutions of the smaller problem
    160       }//shifting the window of combinable factors to the left
    161      }//computing the possibilities that have at least one original factor from g
    162      for (i = 2; i<=nofgl/nof;i++)
    163      {//getting the other possible results
    164       result = result + combinekfinlf(list(product(list(g[1..i])))+list(g[(i+1)..nofgl]),nof,limits);
    165      }//getting the other possible results
    166      result = delete_dublicates_noteval(result);
    167      return(result);
     114  list result;
     115  int i; int j; int k; //iteration variables
     116  list fc; //fc stands for "factors combined"
     117  list temp; //a temporary store for factors
     118  def nofgl = size(g); //nofgl stands for "number of factors of the given list"
     119  if (nofgl == 0)
     120  {//g was the empty list
     121    return(result);
     122  }//g was the empty list
     123  if (nof <= 0)
     124  {//The user wants to recieve a negative number or no element as a result
     125    return(result);
     126  }//The user wants to recieve a negative number or no element as a result
     127  if (nofgl == nof)
     128  {//There are no factors to combine
     129    if (limitcheck(g,limits))
     130    {
     131      result = result + list(g);
     132    }
     133    return(result);
     134  }//There are no factors to combine
     135  if (nof == 1)
     136  {//User wants to get just one factor
     137    if (limitcheck(list(product(g)),limits))
     138    {
     139      result = result + list(list(product(g)));
     140    }
     141    return(result);
     142  }//User wants to get just one factor
     143  for (i = nof; i > 1; i--)
     144  {//computing the possibilities that have at least one original factor from g
     145    for (j = i; j>=1; j--)
     146    {//shifting the window of combinable factors to the left
     147      //fc below stands for "factors combined"
     148      fc = combinekfinlf(list(g[(j)..(j+nofgl - i)]),nof - i + 1,limits);
     149      for (k = 1; k<=size(fc); k++)
     150      {//iterating over the different solutions of the smaller problem
     151        if (j>1)
     152        {//There are g_i before the combination
     153          if (j+nofgl -i < nofgl)
     154          {//There are g_i after the combination
     155            temp = list(g[1..(j-1)]) + fc[k] + list(g[(j+nofgl-i+1)..nofgl]);
     156          }//There are g_i after the combination
     157          else
     158          {//There are no g_i after the combination
     159            temp = list(g[1..(j-1)]) + fc[k];
     160          }//There are no g_i after the combination
     161        }//There are g_i before the combination
     162        if (j==1)
     163        {//There are no g_i before the combination
     164          if (j+ nofgl -i <nofgl)
     165          {//There are g_i after the combination
     166            temp = fc[k]+ list(g[(j + nofgl - i +1)..nofgl]);
     167          }//There are g_i after the combination
     168        }//There are no g_i before the combination
     169        if (limitcheck(temp,limits))
     170        {
     171          result = result + list(temp);
     172        }
     173      }//iterating over the different solutions of the smaller problem
     174    }//shifting the window of combinable factors to the left
     175  }//computing the possibilities that have at least one original factor from g
     176  for (i = 2; i<=nofgl/nof;i++)
     177  {//getting the other possible results
     178    result = result + combinekfinlf(list(product(list(g[1..i])))+list(g[(i+1)..nofgl]),nof,limits);
     179  }//getting the other possible results
     180  result = delete_dublicates_noteval(result);
     181  return(result);
    168182}//Procedure combinekfinlf
    169183
     
    174188static proc merge_icf(list l1, list l2, intvec limits)
    175189{//proc merge_icf
    176      list g;
    177      list f;
    178      int i; int j;
    179      if (size(l1)==0)
    180      {
    181       return(list());
    182      }
    183      if (size(l2)==0)
    184      {
    185       return(list());
    186      }
    187      if (size(l2)<=size(l1))
    188      {//l1 will be our g, l2 our f
    189       g = l1;
    190       f = l2;
    191      }//l1 will be our g, l2 our f
    192      else
    193      {//l1 will be our f, l2 our g
    194       g = l2;
    195       f = l1;
    196      }//l1 will be our f, l2 our g
    197      def result = combinekfinlf(g,size(f),limits);
    198      for (i = 1 ; i<= size(result); i++)
    199      {//Adding the factors of f to every possibility listed in temp
    200       for (j = 1; j<= size(f); j++)
    201       {
    202            result[i][j] = result[i][j]+f[j];
    203       }
    204       if(!limitcheck(result[i],limits))
    205       {
    206            result = delete(result,i);
    207            i--;
    208       }
    209      }//Adding the factors of f to every possibility listed in temp
    210      return(result);
     190  list g;
     191  list f;
     192  int i; int j;
     193  if (size(l1)==0)
     194  {
     195    return(list());
     196  }
     197  if (size(l2)==0)
     198  {
     199    return(list());
     200  }
     201  if (size(l2)<=size(l1))
     202  {//l1 will be our g, l2 our f
     203    g = l1;
     204    f = l2;
     205  }//l1 will be our g, l2 our f
     206  else
     207  {//l1 will be our f, l2 our g
     208    g = l2;
     209    f = l1;
     210  }//l1 will be our f, l2 our g
     211  def result = combinekfinlf(g,size(f),limits);
     212  for (i = 1 ; i<= size(result); i++)
     213  {//Adding the factors of f to every possibility listed in temp
     214    for (j = 1; j<= size(f); j++)
     215    {
     216      result[i][j] = result[i][j]+f[j];
     217    }
     218    if(!limitcheck(result[i],limits))
     219    {
     220      result = delete(result,i);
     221      i--;
     222    }
     223  }//Adding the factors of f to every possibility listed in temp
     224  return(result);
    211225}//proc merge_icf
    212226
     
    216230static proc merge_cf(list l1, list l2, intvec limits)
    217231{//proc merge_cf
    218      list g;
    219      list f;
    220      int i; int j;
    221      list pre;
    222      list post;
    223      list candidate;
    224      list temp;
    225      int temppos;
    226      if (size(l1)==0)
    227      {//the first list is empty
    228       return(list());
    229      }//the first list is empty
    230      if(size(l2)==0)
    231      {//the second list is empty
    232       return(list());
    233      }//the second list is empty
    234      if (size(l2)<=size(l1))
    235      {//l1 will be our g, l2 our f
    236       g = l1;
    237       f = l2;
    238      }//l1 will be our g, l2 our f
    239      else
    240      {//l1 will be our f, l2 our g
    241       g = l2;
    242       f = l1;
    243      }//l1 will be our f, l2 our g
    244      list M;
    245      for (i = 2; i<size(f); i++)
    246      {//finding common factors of f and g...
     232  list g;
     233  list f;
     234  int i; int j;
     235  list pre;
     236  list post;
     237  list candidate;
     238  list temp;
     239  int temppos;
     240  if (size(l1)==0)
     241  {//the first list is empty
     242    return(list());
     243  }//the first list is empty
     244  if(size(l2)==0)
     245  {//the second list is empty
     246    return(list());
     247  }//the second list is empty
     248  if (size(l2)<=size(l1))
     249  {//l1 will be our g, l2 our f
     250    g = l1;
     251    f = l2;
     252  }//l1 will be our g, l2 our f
     253  else
     254  {//l1 will be our f, l2 our g
     255    g = l2;
     256    f = l1;
     257  }//l1 will be our f, l2 our g
     258  list M;
     259  for (i = 2; i<size(f); i++)
     260  {//finding common factors of f and g...
    247261    for (j=2; j<size(g);j++)
    248262    {//... with g
    249          if (f[i] == g[j])
    250          {//we have an equal pair
    251           M = M + list(list(i,j));
    252          }//we have an equal pair
     263      if (f[i] == g[j])
     264      {//we have an equal pair
     265        M = M + list(list(i,j));
     266      }//we have an equal pair
    253267    }//... with g
    254      }//finding common factors of f and g...
    255      if (g[1]==f[1])
    256      {//Checking for the first elements to be equal
    257       M = M + list(list(1,1));
    258      }//Checking for the first elements to be equal
    259      if (g[size(g)]==f[size(f)])
    260      {//Checking for the last elements to be equal
    261       M = M + list(list(size(f),size(g)));
    262      }//Checking for the last elements to be equal
    263      list result;//= list(list());
    264      while(size(M)>0)
    265      {//set of equal pairs is not empty
    266       temp = M[1];
    267       temppos = 1;
    268       for (i = 2; i<=size(M); i++)
    269       {//finding the minimal element of M
    270            if (M[i][1]<=temp[1])
    271            {//a possible candidate that is smaller than temp could have been found
    272             if (M[i][1]==temp[1])
    273             {//In this case we must look at the second number
    274              if (M[i][2]< temp[2])
    275                      {//the candidate is smaller
    276                               temp = M[i];
    277                               temppos = i;
    278                          }//the candidate is smaller
    279                     }//In this case we must look at the second number
    280                     else
    281                     {//The candidate is definately smaller
    282                          temp = M[i];
    283                          temppos = i;
    284                     }//The candidate is definately smaller
    285                }//a possible candidate that is smaller than temp could have been found
    286           }//finding the minimal element of M
    287           M = delete(M, temppos);
    288           if(temp[1]>1)
    289           {//There are factors to combine before the equal factor
    290                if (temp[1]<size(f))
    291                {//The most common case
    292                     //first the combinations ignoring common factors
    293                     pre = merge_icf(list(f[1..(temp[1]-1)]),list(g[1..(temp[2]-1)]),limits);
    294                     post = merge_icf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
    295                     for (i = 1; i <= size(pre); i++)
    296                     {//all possible pre's...
    297                          for (j = 1; j<= size(post); j++)
    298                          {//...combined with all possible post's
    299                               candidate = pre[i]+list(f[temp[1]])+post[j];
    300                               if (limitcheck(candidate,limits))
    301                               {
    302                                    result = result + list(candidate);
    303                               }
    304                          }//...combined with all possible post's
    305                     }//all possible pre's...
    306                     //Now the combinations with respect to common factors
    307                     post = merge_cf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
    308                     if (size(post)>0)
    309                     {//There are factors to combine
    310                          for (i = 1; i <= size(pre); i++)
    311                          {//all possible pre's...
    312                               for (j = 1; j<= size(post); j++)
    313                               {//...combined with all possible post's
    314                                    candidate= pre[i]+list(f[temp[1]])+post[j];
    315                                    if (limitcheck(candidate,limits))
    316                                    {
    317                                         result = result + list(candidate);
    318                                    }
    319                               }//...combined with all possible post's
    320                          }//all possible pre's...
    321                     }//There are factors to combine
    322                }//The most common case
    323                else
    324                {//the last factor is the common one
    325                     pre = merge_icf(list(f[1..(temp[1]-1)]),list(g[1..(temp[2]-1)]),limits);
    326                     for (i = 1; i<= size(pre); i++)
    327                     {//iterating over the possible pre-factors
    328                          candidate = pre[i]+list(f[temp[1]]);
    329                          if (limitcheck(candidate,limits))
    330                          {
    331                               result = result + list(candidate);
    332                          }
    333                     }//iterating over the possible pre-factors
    334                }//the last factor is the common one
    335           }//There are factors to combine before the equal factor
    336           else
    337           {//There are no factors to combine before the equal factor
    338                if (temp[1]<size(f))
    339                {//Just a check for security
    340                     //first without common factors
    341                     post=merge_icf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
    342                     for (i = 1; i<=size(post); i++)
    343                     {
    344                          candidate = list(f[temp[1]])+post[i];
    345                          if (limitcheck(candidate,limits))
    346                          {
    347                               result = result + list(candidate);
    348                          }
    349                     }
    350                     //Now with common factors
    351                     post = merge_cf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
    352                     if(size(post)>0)
    353                     {//we could find other combinations
    354                          for (i = 1; i<=size(post); i++)
    355                          {
    356                               candidate = list(f[temp[1]])+post[i];
    357                               if (limitcheck(candidate,limits))
    358                               {
    359                                    result = result + list(candidate);
    360                               }
    361                          }
    362                     }//we could find other combinations
    363                }//Just a check for security
    364           }//There are no factors to combine before the equal factor
    365      }//set of equal pairs is not empty
    366      return(result);
     268  }//finding common factors of f and g...
     269  if (g[1]==f[1])
     270  {//Checking for the first elements to be equal
     271    M = M + list(list(1,1));
     272  }//Checking for the first elements to be equal
     273  if (g[size(g)]==f[size(f)])
     274  {//Checking for the last elements to be equal
     275    M = M + list(list(size(f),size(g)));
     276  }//Checking for the last elements to be equal
     277  list result;//= list(list());
     278  while(size(M)>0)
     279  {//set of equal pairs is not empty
     280    temp = M[1];
     281    temppos = 1;
     282    for (i = 2; i<=size(M); i++)
     283    {//finding the minimal element of M
     284      if (M[i][1]<=temp[1])
     285      {//a possible candidate that is smaller than temp could have been found
     286        if (M[i][1]==temp[1])
     287        {//In this case we must look at the second number
     288          if (M[i][2]< temp[2])
     289          {//the candidate is smaller
     290            temp = M[i];
     291            temppos = i;
     292          }//the candidate is smaller
     293        }//In this case we must look at the second number
     294        else
     295        {//The candidate is definately smaller
     296          temp = M[i];
     297          temppos = i;
     298        }//The candidate is definately smaller
     299      }//a possible candidate that is smaller than temp could have been found
     300    }//finding the minimal element of M
     301    M = delete(M, temppos);
     302    if(temp[1]>1)
     303    {//There are factors to combine before the equal factor
     304      if (temp[1]<size(f))
     305      {//The most common case
     306        //first the combinations ignoring common factors
     307        pre = merge_icf(list(f[1..(temp[1]-1)]),list(g[1..(temp[2]-1)]),limits);
     308        post = merge_icf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
     309        for (i = 1; i <= size(pre); i++)
     310        {//all possible pre's...
     311          for (j = 1; j<= size(post); j++)
     312          {//...combined with all possible post's
     313            candidate = pre[i]+list(f[temp[1]])+post[j];
     314            if (limitcheck(candidate,limits))
     315            {
     316              result = result + list(candidate);
     317            }
     318          }//...combined with all possible post's
     319        }//all possible pre's...
     320        //Now the combinations with respect to common factors
     321        post = merge_cf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
     322        if (size(post)>0)
     323        {//There are factors to combine
     324          for (i = 1; i <= size(pre); i++)
     325          {//all possible pre's...
     326            for (j = 1; j<= size(post); j++)
     327            {//...combined with all possible post's
     328              candidate= pre[i]+list(f[temp[1]])+post[j];
     329              if (limitcheck(candidate,limits))
     330              {
     331                result = result + list(candidate);
     332              }
     333            }//...combined with all possible post's
     334          }//all possible pre's...
     335        }//There are factors to combine
     336      }//The most common case
     337      else
     338      {//the last factor is the common one
     339        pre = merge_icf(list(f[1..(temp[1]-1)]),list(g[1..(temp[2]-1)]),limits);
     340        for (i = 1; i<= size(pre); i++)
     341        {//iterating over the possible pre-factors
     342          candidate = pre[i]+list(f[temp[1]]);
     343          if (limitcheck(candidate,limits))
     344          {
     345            result = result + list(candidate);
     346          }
     347        }//iterating over the possible pre-factors
     348      }//the last factor is the common one
     349    }//There are factors to combine before the equal factor
     350    else
     351    {//There are no factors to combine before the equal factor
     352      if (temp[1]<size(f))
     353      {//Just a check for security
     354        //first without common factors
     355        post=merge_icf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
     356        for (i = 1; i<=size(post); i++)
     357        {
     358          candidate = list(f[temp[1]])+post[i];
     359          if (limitcheck(candidate,limits))
     360          {
     361            result = result + list(candidate);
     362          }
     363        }
     364        //Now with common factors
     365        post = merge_cf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
     366        if(size(post)>0)
     367        {//we could find other combinations
     368          for (i = 1; i<=size(post); i++)
     369          {
     370            candidate = list(f[temp[1]])+post[i];
     371            if (limitcheck(candidate,limits))
     372            {
     373              result = result + list(candidate);
     374            }
     375          }
     376        }//we could find other combinations
     377      }//Just a check for security
     378    }//There are no factors to combine before the equal factor
     379  }//set of equal pairs is not empty
     380  return(result);
    367381}//proc merge_cf
    368382
     
    373387static proc mergence(list l1, list l2, intvec limits)
    374388{//Procedure mergence
    375      list g;
    376      list f;
    377      int l; int k;
    378      list F;
    379      if (size(l2)<=size(l1))
    380      {//l1 will be our g, l2 our f
    381           g = l1;
    382           f = l2;
    383      }//l1 will be our g, l2 our f
    384      else
    385      {//l1 will be our f, l2 our g
    386           g = l2;
    387           f = l1;
    388      }//l1 will be our f, l2 our g
    389      list result;
    390      for (l = size(f); l>=1; l--)
    391      {//all possibilities to combine the factors of f
    392           F = combinekfinlf(f,l,limits);
    393           for (k = 1; k<= size(F);k++)
    394           {//for all possibilities of combinations of the factors of f
    395                result = result + merge_cf(F[k],g,limits);
    396                result = result + merge_icf(F[k],g,limits);
    397           }//for all possibilities of combinations of the factors of f
    398      }//all possibilities to combine the factors of f
    399      return(result);
     389  list g;
     390  list f;
     391  int l; int k;
     392  list F;
     393  if (size(l2)<=size(l1))
     394  {//l1 will be our g, l2 our f
     395    g = l1;
     396    f = l2;
     397  }//l1 will be our g, l2 our f
     398  else
     399  {//l1 will be our f, l2 our g
     400    g = l2;
     401    f = l1;
     402  }//l1 will be our f, l2 our g
     403  list result;
     404  for (l = size(f); l>=1; l--)
     405  {//all possibilities to combine the factors of f
     406    F = combinekfinlf(f,l,limits);
     407    for (k = 1; k<= size(F);k++)
     408    {//for all possibilities of combinations of the factors of f
     409      result = result + merge_cf(F[k],g,limits);
     410      result = result + merge_icf(F[k],g,limits);
     411    }//for all possibilities of combinations of the factors of f
     412  }//all possibilities to combine the factors of f
     413  return(result);
    400414}//Procedure mergence
    401415
     
    405419static proc limitcheck(list g, intvec limits)
    406420{//proc limitcheck
    407      int i;
    408      if (size(limits)!=3)
    409      {//check the input
    410           return(0);
    411      }//check the input
    412      if(size(g)==0)
    413      {
    414           return(0);
    415      }
    416      def prod = product(g);
    417      def limg = intvec(deg(prod,intvec(1,1)) ,deg(prod,intvec(1,0)),deg(prod,intvec(0,1)));
    418      for (i = 1; i<=size(limg);i++)
    419      {//the final check
    420           if(limg[i]>limits[i])
    421           {
    422                return(0);
    423           }
    424      }//the final check
    425      return(1);
     421  int i;
     422  if (size(limits)!=3)
     423  {//check the input
     424    return(0);
     425  }//check the input
     426  if(size(g)==0)
     427  {
     428    return(0);
     429  }
     430  def prod = product(g);
     431  def limg = intvec(deg(prod,intvec(1,1)) ,deg(prod,intvec(1,0)),deg(prod,intvec(0,1)));
     432  for (i = 1; i<=size(limg);i++)
     433  {//the final check
     434    if(limg[i]>limits[i])
     435    {
     436      return(0);
     437    }
     438  }//the final check
     439  return(1);
    426440}//proc limitcheck
    427441
     
    430444//one factorization of a homogeneous polynomial
    431445//in the first Weyl Algebra
    432 static proc homogfac(poly h)
    433 "USAGE: homogfac(h); h is a homogeneous polynomial in the
     446static proc homogfacFirstWeyl(poly h)
     447"USAGE: homogfacFirstWeyl(h); h is a homogeneous polynomial in the
    434448        first Weyl algebra with respect to the weight vector [-1,1]
    435449RETURN: list
    436450PURPOSE: Computes a factorization of a homogeneous polynomial h with
    437451         respect to the weight vector [-1,1] in the first Weyl algebra
    438 THEORY: @code{homogfac} returns a list with a factorization of the given,
     452THEORY: @code{homogfacFirstWeyl} returns a list with a factorization of the given,
    439453        [-1,1]-homogeneous polynomial. If the degree of the polynomial is k with
    440454        k positive, the last k entries in the output list are the second
    441455        variable. If k is positive, the last k entries will be x. The other
    442456        entries will be irreducible polynomials of degree zero or 1 resp. -1.
    443 SEE ALSO: homogfac_all
    444 "{//proc homogfac
    445      def r = basering;
    446      poly hath;
    447      int i; int j;
    448      if (!homogwithorder(h,intvec(-1,1)))
    449      {//The given polynomial is not homogeneous
    450           return(list());
    451      }//The given polynomial is not homogeneous
    452      if (h==0)
    453      {
    454           return(list(0));
    455      }
    456      list result;
    457      int m = deg(h,intvec(-1,1));
    458      if (m!=0)
    459      {//The degree is not zero
    460           if (m <0)
    461           {//There are more x than y
    462                hath = lift(var(1)^(-m),h)[1,1];
    463                for (i = 1; i<=-m; i++)
    464                {
    465                     result = result + list(var(1));
    466                }
    467           }//There are more x than y
    468           else
    469           {//There are more y than x
    470                hath = lift(var(2)^m,h)[1,1];
    471                for (i = 1; i<=m;i++)
    472                {
    473                     result = result + list(var(2));
    474                }
    475           }//There are more y than x
    476      }//The degree is not zero
    477      else
    478      {//The degree is zero
    479           hath = h;
    480      }//The degree is zero
    481      //beginning to transform x^i*y^i in teta(teta-1)...(teta-i+1)
    482      list mons;
    483      for(i = 1; i<=size(hath);i++)
    484      {//Putting the monomials in a list
    485           mons = mons+list(hath[i]);
    486      }//Putting the monomials in a list
    487      ring tempRing = 0,(x,y,teta),dp;
    488      setring tempRing;
    489      map tetamap = r,x,y;
    490      list mons = tetamap(mons);
    491      poly entry;
    492      for (i = 1; i<=size(mons);i++)
    493      {//transforming the monomials as monomials in theta
    494           entry = leadcoef(mons[i]);
    495           for (j = 0; j<leadexp(mons[i])[2];j++)
    496           {
    497                entry = entry * (teta-j);
    498           }
    499           mons[i] = entry;
    500      }//transforming the monomials as monomials in theta
    501      list azeroresult = factorize(sum(mons));
    502      list azeroresult_return_form;
    503      for (i = 1; i<=size(azeroresult[1]);i++)
    504      {//rewrite the result of the commutative factorization
    505           for (j = 1; j <= azeroresult[2][i];j++)
    506           {
    507                azeroresult_return_form = azeroresult_return_form + list(azeroresult[1][i]);
    508           }
    509      }//rewrite the result of the commutative factorization
    510      setring(r);
    511      map finalmap = tempRing,var(1),var(2),var(1)*var(2);
    512      list tempresult = finalmap(azeroresult_return_form);
    513      for (i = 1; i<=size(tempresult);i++)
    514      {//factorizations of theta resp. theta +1
    515           if(tempresult[i]==var(1)*var(2))
    516           {
    517                tempresult = insert(tempresult,var(1),i-1);
    518                i++;
    519                tempresult[i]=var(2);
    520           }
    521           if(tempresult[i]==var(2)*var(1))
    522           {
    523                tempresult = insert(tempresult,var(2),i-1);
    524                i++;
    525                tempresult[i]=var(1);
    526           }
    527      }//factorizations of theta resp. theta +1
    528      result = tempresult+result;
    529      return(result);
    530 }//proc homogfac
     457SEE ALSO: homogfacFirstWeyl_all
     458"{//proc homogfacFirstWeyl
     459  def r = basering;
     460  poly hath;
     461  int i; int j;
     462  if (!homogwithorder(h,intvec(-1,1)))
     463  {//The given polynomial is not homogeneous
     464    return(list());
     465  }//The given polynomial is not homogeneous
     466  if (h==0)
     467  {
     468    return(list(0));
     469  }
     470  list result;
     471  int m = deg(h,intvec(-1,1));
     472  if (m!=0)
     473  {//The degree is not zero
     474    if (m <0)
     475    {//There are more x than y
     476      hath = lift(var(1)^(-m),h)[1,1];
     477      for (i = 1; i<=-m; i++)
     478      {
     479        result = result + list(var(1));
     480      }
     481    }//There are more x than y
     482    else
     483    {//There are more y than x
     484      hath = lift(var(2)^m,h)[1,1];
     485      for (i = 1; i<=m;i++)
     486      {
     487        result = result + list(var(2));
     488      }
     489    }//There are more y than x
     490  }//The degree is not zero
     491  else
     492  {//The degree is zero
     493    hath = h;
     494  }//The degree is zero
     495  //beginning to transform x^i*y^i in theta(theta-1)...(theta-i+1)
     496  list mons;
     497  for(i = 1; i<=size(hath);i++)
     498  {//Putting the monomials in a list
     499    mons = mons+list(hath[i]);
     500  }//Putting the monomials in a list
     501  ring tempRing = 0,(x,y,theta),dp;
     502  setring tempRing;
     503  map thetamap = r,x,y;
     504  list mons = thetamap(mons);
     505  poly entry;
     506  for (i = 1; i<=size(mons);i++)
     507  {//transforming the monomials as monomials in theta
     508    entry = leadcoef(mons[i]);
     509    for (j = 0; j<leadexp(mons[i])[2];j++)
     510    {
     511      entry = entry * (theta-j);
     512    }
     513    mons[i] = entry;
     514  }//transforming the monomials as monomials in theta
     515  list azeroresult = factorize(sum(mons));
     516  list azeroresult_return_form;
     517  for (i = 1; i<=size(azeroresult[1]);i++)
     518  {//rewrite the result of the commutative factorization
     519    for (j = 1; j <= azeroresult[2][i];j++)
     520    {
     521      azeroresult_return_form = azeroresult_return_form + list(azeroresult[1][i]);
     522    }
     523  }//rewrite the result of the commutative factorization
     524  setring(r);
     525  map finalmap = tempRing,var(1),var(2),var(1)*var(2);
     526  list tempresult = finalmap(azeroresult_return_form);
     527  for (i = 1; i<=size(tempresult);i++)
     528  {//factorizations of theta resp. theta +1
     529    if(tempresult[i]==var(1)*var(2))
     530    {
     531      tempresult = insert(tempresult,var(1),i-1);
     532      i++;
     533      tempresult[i]=var(2);
     534    }
     535    if(tempresult[i]==var(2)*var(1))
     536    {
     537      tempresult = insert(tempresult,var(2),i-1);
     538      i++;
     539      tempresult[i]=var(1);
     540    }
     541  }//factorizations of theta resp. theta +1
     542  result = tempresult+result;
     543  return(result);
     544}//proc homogfacFirstWeyl
    531545/* example */
    532546/* { */
     
    536550/*      setring(r); */
    537551/*      poly h = (x^2*y^2+1)*(x^4); */
    538 /*      homogfac(h); */
     552/*      homogfacFirstWeyl(h); */
    539553/* } */
    540554
    541555//==================================================
    542556//Computes all possible homogeneous factorizations
    543 static proc homogfac_all(poly h)
    544 "USAGE: homogfac_all(h); h is a homogeneous polynomial in the first Weyl algebra
     557static proc homogfacFirstWeyl_all(poly h)
     558"USAGE: homogfacFirstWeyl_all(h); h is a homogeneous polynomial in the first Weyl algebra
    545559        with respect to the weight vector [-1,1]
    546560RETURN: list
    547561PURPOSE: Computes all factorizations of a homogeneous polynomial h with respect
    548562         to the weight vector [-1,1] in the first Weyl algebra
    549 THEORY: @code{homogfac} returns a list with all factorization of the given,
    550         homogeneous polynomial. It uses the output of homogfac and permutes
     563THEORY: @code{homogfacFirstWeyl} returns a list with all factorization of the given,
     564        homogeneous polynomial. It uses the output of homogfacFirstWeyl and permutes
    551565        its entries with respect to the commutation rule. Furthermore, if a
    552566        factor of degree zero is irreducible in K[\theta], but reducible in
    553567        the first Weyl algebra, the permutations of this element with the other
    554568        entries will also be computed.
    555 SEE ALSO: homogfac
    556 "{//proc HomogFacAll
    557      if (deg(h,intvec(1,1)) <= 0 )
    558      {//h is a constant
    559           return(list(list(h)));
    560      }//h is a constant
    561      def r = basering;
    562      list one_hom_fac; //stands for one homogeneous factorization
    563      int i; int j; int k;
    564      //Compute again a homogeneous factorization
    565      one_hom_fac = homogfac(h);
    566      if (size(one_hom_fac) == 0)
    567      {//there is no homogeneous factorization or the polynomial was not homogeneous
    568           return(list());
    569      }//there is no homogeneous factorization or the polynomial was not homogeneous
    570      //divide list in A0-Part and a list of x's resp. y's
    571      list list_not_azero = list();
    572      list list_azero;
    573      list k_factor;
    574      int is_list_not_azero_empty = 1;
    575      int is_list_azero_empty = 1;
    576      k_factor = list(one_hom_fac[1]);
    577      if (absValue(deg(h,intvec(-1,1)))<size(one_hom_fac)-1)
    578      {//There is a nontrivial A_0-part
    579           list_azero = one_hom_fac[2..(size(one_hom_fac)-absValue(deg(h,intvec(-1,1))))];
    580           is_list_azero_empty = 0;
    581      }//There is a nontrivial A_0 part
    582      for (i = 1; i<=size(list_azero)-1;i++)
    583      {//in homogfac, we factorized theta, and this will be made undone
    584           if (list_azero[i] == var(1))
    585           {
    586                if (list_azero[i+1]==var(2))
    587                {
    588                     list_azero[i] = var(1)*var(2);
    589                     list_azero = delete(list_azero,i+1);
    590                }
    591           }
    592           if (list_azero[i] == var(2))
    593           {
    594                if (list_azero[i+1]==var(1))
    595                {
    596                     list_azero[i] = var(2)*var(1);
    597                     list_azero = delete(list_azero,i+1);
    598                }
    599           }
    600      }//in homogfac, we factorized theta, and this will be made undone
    601      if(deg(h,intvec(-1,1))!=0)
    602      {//list_not_azero is not empty
    603           list_not_azero = one_hom_fac[(size(one_hom_fac)-absValue(deg(h,intvec(-1,1)))+1)..size(one_hom_fac)];
    604           is_list_not_azero_empty = 0;
    605      }//list_not_azero is not empty
    606      //Map list_azero in K[theta]
    607      ring tempRing = 0,(x,y,theta), dp;
    608      setring(tempRing);
    609      poly entry;
    610      map thetamap = r,x,y;
    611      if(!is_list_not_azero_empty)
    612      {//Mapping in Singular is only possible, if the list before contained at least one element of the other ring
    613           list list_not_azero = thetamap(list_not_azero);
    614      }//Mapping in Singular is only possible, if the list before contained at least one element of the other ring
    615      if(!is_list_azero_empty)
    616      {//Mapping in Singular is only possible, if the list before contained at least one element of the other ring
    617           list list_azero= thetamap(list_azero);
    618      }//Mapping in Singular is only possible, if the list before contained at least one element of the other ring
    619      list k_factor = thetamap(k_factor);
    620      list tempmons;
    621      for(i = 1; i<=size(list_azero);i++)
    622      {//rewrite the polynomials in A1 as polynomials in K[theta]
    623           tempmons = list();
    624           for (j = 1; j<=size(list_azero[i]);j++)
    625           {
    626                tempmons = tempmons + list(list_azero[i][j]);
    627           }
    628           for (j = 1 ; j<=size(tempmons);j++)
    629           {
    630                entry = leadcoef(tempmons[j]);
    631                for (k = 0; k < leadexp(tempmons[j])[2];k++)
    632                {
    633                     entry = entry*(theta-k);
    634                }
    635                tempmons[j] = entry;
    636           }
    637           list_azero[i] = sum(tempmons);
    638      }//rewrite the polynomials in A1 as polynomials in K[theta]
    639      //Compute all permutations of the A0-part
    640      list result;
    641      int shift_sign;
    642      int shift;
    643      poly shiftvar;
    644      if (size(list_not_azero)!=0)
    645      {//Compute all possibilities to permute the x's resp. the y's in the list
    646           if (list_not_azero[1] == x)
    647           {//h had a negative weighted degree
    648                shift_sign = 1;
    649                shiftvar = x;
    650           }//h had a negative weighted degree
    651           else
    652           {//h had a positive weighted degree
    653                shift_sign = -1;
    654                shiftvar = y;
    655           }//h had a positive weighted degree
    656           result = permpp(list_azero + list_not_azero);
    657           for (i = 1; i<= size(result); i++)
    658           {//adjust the a_0-parts
    659                shift = 0;
    660                for (j=1; j<=size(result[i]);j++)
    661                {
    662                     if (result[i][j]==shiftvar)
    663                     {
    664                          shift = shift + shift_sign;
    665                     }
    666                     else
    667                     {
    668                          result[i][j] = subst(result[i][j],theta,theta + shift);
    669                     }
    670                }
    671           }//adjust the a_0-parts
    672      }//Compute all possibilities to permute the x's resp. the y's in the list
    673      else
    674      {//The result is just all the permutations of the a_0-part
    675           result = permpp(list_azero);
    676      }//The result is just all the permutations of the a_0 part
    677      if (size(result)==0)
    678      {
    679           return(result);
    680      }
    681      //Now we are going deeper and search for theta resp. theta + 1, substitute them by xy resp. yx and go on permuting
    682      int found_theta;
    683      int thetapos;
    684      list leftpart;
    685      list rightpart;
    686      list lparts;
    687      list rparts;
    688      list tempadd;
    689      for (i = 1; i<=size(result) ; i++)
    690      {//checking every entry of result for theta or theta +1
    691           found_theta = 0;
    692           for(j=1;j<=size(result[i]);j++)
    693           {
    694                if (result[i][j]==theta)
    695                {//the jth entry is theta and can be written as x*y
    696                     thetapos = j;
    697                     result[i]= insert(result[i],x,j-1);
    698                     j++;
    699                     result[i][j] = y;
    700                     found_theta = 1;
    701                     break;
    702                }//the jth entry is theta and can be written as x*y
    703                if(result[i][j] == theta +1)
    704                {
    705                     thetapos = j;
    706                     result[i] = insert(result[i],y,j-1);
    707                     j++;
    708                     result[i][j] = x;
    709                     found_theta = 1;
    710                     break;
    711                }
    712           }
    713           if (found_theta)
    714           {//One entry was theta resp. theta +1
    715                leftpart = result[i];
    716                leftpart = leftpart[1..thetapos];
    717                rightpart = result[i];
    718                rightpart = rightpart[(thetapos+1)..size(rightpart)];
    719                lparts = list(leftpart);
    720                rparts = list(rightpart);
    721                //first deal with the left part
    722                if (leftpart[thetapos] == x)
    723                {
    724                     shift_sign = 1;
    725                     shiftvar = x;
    726                }
    727                else
    728                {
    729                     shift_sign = -1;
    730                     shiftvar = y;
    731                }
    732                for (j = size(leftpart); j>1;j--)
    733                {//drip x resp. y
    734                     if (leftpart[j-1]==shiftvar)
    735                     {//commutative
    736                          j--;
    737                          continue;
    738                     }//commutative
    739                     if (deg(leftpart[j-1],intvec(-1,1,0))!=0)
    740                     {//stop here
    741                          break;
    742                     }//stop here
    743                     //Here, we can only have a a0- part
    744                     leftpart[j] = subst(leftpart[j-1],theta, theta + shift_sign);
    745                     leftpart[j-1] = shiftvar;
    746                     lparts = lparts + list(leftpart);
    747                 }//drip x resp. y
    748                 //and now deal with the right part
    749                 if (rightpart[1] == x)
    750                 {
    751                      shift_sign = 1;
    752                      shiftvar = x;
    753                 }
    754                 else
    755                 {
    756                      shift_sign = -1;
    757                      shiftvar = y;
    758                 }
    759                 for (j = 1 ; j < size(rightpart); j++)
    760                 {
    761                      if (rightpart[j+1] == shiftvar)
    762                      {
    763                           j++;
    764                           continue;
    765                      }
    766                      if (deg(rightpart[j+1],intvec(-1,1,0))!=0)
    767                      {
    768                           break;
    769                      }
    770                      rightpart[j] = subst(rightpart[j+1], theta, theta - shift_sign);
    771                      rightpart[j+1] = shiftvar;
    772                      rparts = rparts + list(rightpart);
    773                 }
    774                 //And now, we put all possibilities together
    775                 tempadd = list();
    776                 for (j = 1; j<=size(lparts); j++)
    777                 {
    778                         for (k = 1; k<=size(rparts);k++)
    779                    {
    780                               tempadd = tempadd + list(lparts[j]+rparts[k]);
    781                    }
    782                 }
    783                 tempadd = delete(tempadd,1); // The first entry is already in the list
    784                 result = result + tempadd;
    785                 continue; //We can may be not be done already with the ith entry
    786           }//One entry was theta resp. theta +1
    787      }//checking every entry of result for theta or theta +1
    788      //map back to the basering
    789      setring(r);
    790      map finalmap = tempRing, var(1), var(2),var(1)*var(2);
    791      list result = finalmap(result);
    792      for (i=1; i<=size(result);i++)
    793      {//adding the K factor
    794           result[i] = k_factor + result[i];
    795      }//adding the k-factor
    796      result = delete_dublicates_noteval(result);
    797      return(result);
    798 }//proc HomogFacAll
     569SEE ALSO: homogfacFirstWeyl
     570"{//proc HomogfacFirstWeylAll
     571  if (deg(h,intvec(1,1)) <= 0 )
     572  {//h is a constant
     573    return(list(list(h)));
     574  }//h is a constant
     575  def r = basering;
     576  list one_hom_fac; //stands for one homogeneous factorization
     577  int i; int j; int k;
     578  //Compute again a homogeneous factorization
     579  one_hom_fac = homogfacFirstWeyl(h);
     580  if (size(one_hom_fac) == 0)
     581  {//there is no homogeneous factorization or the polynomial was not homogeneous
     582    return(list());
     583  }//there is no homogeneous factorization or the polynomial was not homogeneous
     584  //divide list in A0-Part and a list of x's resp. y's
     585  list list_not_azero = list();
     586  list list_azero;
     587  list k_factor;
     588  int is_list_not_azero_empty = 1;
     589  int is_list_azero_empty = 1;
     590  k_factor = list(one_hom_fac[1]);
     591  if (absValue(deg(h,intvec(-1,1)))<size(one_hom_fac)-1)
     592  {//There is a nontrivial A_0-part
     593    list_azero = one_hom_fac[2..(size(one_hom_fac)-absValue(deg(h,intvec(-1,1))))];
     594    is_list_azero_empty = 0;
     595  }//There is a nontrivial A_0 part
     596  for (i = 1; i<=size(list_azero)-1;i++)
     597  {//in homogfacFirstWeyl, we factorized theta, and this will be made undone
     598    if (list_azero[i] == var(1))
     599    {
     600      if (list_azero[i+1]==var(2))
     601      {
     602        list_azero[i] = var(1)*var(2);
     603        list_azero = delete(list_azero,i+1);
     604      }
     605    }
     606    if (list_azero[i] == var(2))
     607    {
     608      if (list_azero[i+1]==var(1))
     609      {
     610        list_azero[i] = var(2)*var(1);
     611        list_azero = delete(list_azero,i+1);
     612      }
     613    }
     614  }//in homogfacFirstWeyl, we factorized theta, and this will be made undone
     615  if(deg(h,intvec(-1,1))!=0)
     616  {//list_not_azero is not empty
     617    list_not_azero =
     618      one_hom_fac[(size(one_hom_fac)-absValue(deg(h,intvec(-1,1)))+1)..size(one_hom_fac)];
     619    is_list_not_azero_empty = 0;
     620  }//list_not_azero is not empty
     621  //Map list_azero in K[theta]
     622  ring tempRing = 0,(x,y,theta), dp;
     623  setring(tempRing);
     624  poly entry;
     625  map thetamap = r,x,y;
     626  if(!is_list_not_azero_empty)
     627  {//Mapping in Singular is only possible, if the list before
     628    //contained at least one element of the other ring
     629    list list_not_azero = thetamap(list_not_azero);
     630  }//Mapping in Singular is only possible, if the list before
     631  //contained at least one element of the other ring
     632  if(!is_list_azero_empty)
     633  {//Mapping in Singular is only possible, if the list before
     634    //contained at least one element of the other ring
     635    list list_azero= thetamap(list_azero);
     636  }//Mapping in Singular is only possible, if the list before
     637  //contained at least one element of the other ring
     638  list k_factor = thetamap(k_factor);
     639  list tempmons;
     640  for(i = 1; i<=size(list_azero);i++)
     641  {//rewrite the polynomials in A1 as polynomials in K[theta]
     642    tempmons = list();
     643    for (j = 1; j<=size(list_azero[i]);j++)
     644    {
     645      tempmons = tempmons + list(list_azero[i][j]);
     646    }
     647    for (j = 1 ; j<=size(tempmons);j++)
     648    {
     649      entry = leadcoef(tempmons[j]);
     650      for (k = 0; k < leadexp(tempmons[j])[2];k++)
     651      {
     652        entry = entry*(theta-k);
     653      }
     654      tempmons[j] = entry;
     655    }
     656    list_azero[i] = sum(tempmons);
     657  }//rewrite the polynomials in A1 as polynomials in K[theta]
     658  //Compute all permutations of the A0-part
     659  list result;
     660  int shift_sign;
     661  int shift;
     662  poly shiftvar;
     663  if (size(list_not_azero)!=0)
     664  {//Compute all possibilities to permute the x's resp. the y's in the list
     665    if (list_not_azero[1] == x)
     666    {//h had a negative weighted degree
     667      shift_sign = 1;
     668      shiftvar = x;
     669    }//h had a negative weighted degree
     670    else
     671    {//h had a positive weighted degree
     672      shift_sign = -1;
     673      shiftvar = y;
     674    }//h had a positive weighted degree
     675    result = permpp(list_azero + list_not_azero);
     676    for (i = 1; i<= size(result); i++)
     677    {//adjust the a_0-parts
     678      shift = 0;
     679      for (j=1; j<=size(result[i]);j++)
     680      {
     681        if (result[i][j]==shiftvar)
     682        {
     683          shift = shift + shift_sign;
     684        }
     685        else
     686        {
     687          result[i][j] = subst(result[i][j],theta,theta + shift);
     688        }
     689      }
     690    }//adjust the a_0-parts
     691  }//Compute all possibilities to permute the x's resp. the y's in the list
     692  else
     693  {//The result is just all the permutations of the a_0-part
     694    result = permpp(list_azero);
     695  }//The result is just all the permutations of the a_0 part
     696  if (size(result)==0)
     697  {
     698    return(result);
     699  }
     700  //Now we are going deeper and search for theta resp. theta + 1, substitute
     701  //them by xy resp. yx and go on permuting
     702  int found_theta;
     703  int thetapos;
     704  list leftpart;
     705  list rightpart;
     706  list lparts;
     707  list rparts;
     708  list tempadd;
     709  for (i = 1; i<=size(result) ; i++)
     710  {//checking every entry of result for theta or theta +1
     711    found_theta = 0;
     712    for(j=1;j<=size(result[i]);j++)
     713    {
     714      if (result[i][j]==theta)
     715      {//the jth entry is theta and can be written as x*y
     716        thetapos = j;
     717        result[i]= insert(result[i],x,j-1);
     718        j++;
     719        result[i][j] = y;
     720        found_theta = 1;
     721        break;
     722      }//the jth entry is theta and can be written as x*y
     723      if(result[i][j] == theta +1)
     724      {
     725        thetapos = j;
     726        result[i] = insert(result[i],y,j-1);
     727        j++;
     728        result[i][j] = x;
     729        found_theta = 1;
     730        break;
     731      }
     732    }
     733    if (found_theta)
     734    {//One entry was theta resp. theta +1
     735      leftpart = result[i];
     736      leftpart = leftpart[1..thetapos];
     737      rightpart = result[i];
     738      rightpart = rightpart[(thetapos+1)..size(rightpart)];
     739      lparts = list(leftpart);
     740      rparts = list(rightpart);
     741      //first deal with the left part
     742      if (leftpart[thetapos] == x)
     743      {
     744        shift_sign = 1;
     745        shiftvar = x;
     746      }
     747      else
     748      {
     749        shift_sign = -1;
     750        shiftvar = y;
     751      }
     752      for (j = size(leftpart); j>1;j--)
     753      {//drip x resp. y
     754        if (leftpart[j-1]==shiftvar)
     755        {//commutative
     756          j--;
     757          continue;
     758        }//commutative
     759        if (deg(leftpart[j-1],intvec(-1,1,0))!=0)
     760        {//stop here
     761          break;
     762        }//stop here
     763        //Here, we can only have a a0- part
     764        leftpart[j] = subst(leftpart[j-1],theta, theta + shift_sign);
     765        leftpart[j-1] = shiftvar;
     766        lparts = lparts + list(leftpart);
     767      }//drip x resp. y
     768      //and now deal with the right part
     769      if (rightpart[1] == x)
     770      {
     771        shift_sign = 1;
     772        shiftvar = x;
     773      }
     774      else
     775      {
     776        shift_sign = -1;
     777        shiftvar = y;
     778      }
     779      for (j = 1 ; j < size(rightpart); j++)
     780      {
     781        if (rightpart[j+1] == shiftvar)
     782        {
     783          j++;
     784          continue;
     785        }
     786        if (deg(rightpart[j+1],intvec(-1,1,0))!=0)
     787        {
     788          break;
     789        }
     790        rightpart[j] = subst(rightpart[j+1], theta, theta - shift_sign);
     791        rightpart[j+1] = shiftvar;
     792        rparts = rparts + list(rightpart);
     793      }
     794      //And now, we put all possibilities together
     795      tempadd = list();
     796      for (j = 1; j<=size(lparts); j++)
     797      {
     798        for (k = 1; k<=size(rparts);k++)
     799        {
     800          tempadd = tempadd + list(lparts[j]+rparts[k]);
     801        }
     802      }
     803      tempadd = delete(tempadd,1); // The first entry is already in the list
     804      result = result + tempadd;
     805      continue; //We can may be not be done already with the ith entry
     806    }//One entry was theta resp. theta +1
     807  }//checking every entry of result for theta or theta +1
     808  //map back to the basering
     809  setring(r);
     810  map finalmap = tempRing, var(1), var(2),var(1)*var(2);
     811  list result = finalmap(result);
     812  for (i=1; i<=size(result);i++)
     813  {//adding the K factor
     814    result[i] = k_factor + result[i];
     815  }//adding the k-factor
     816  result = delete_dublicates_noteval(result);
     817  return(result);
     818}//proc HomogfacFirstWeylAll
    799819/* example */
    800820/* { */
     
    804824/*      setring(r); */
    805825/*      poly h = (x^2*y^2+1)*(x^4); */
    806 /*      homogfac_all(h); */
     826/*      homogfacFirstWeyl_all(h); */
    807827/* } */
    808828
     
    811831static proc perm(list l)
    812832{//proc perm
    813      int i; int j;
    814      list tempresult;
    815      list result;
    816      if (size(l)==0)
    817      {
    818           return(list());
    819      }
    820      if (size(l)==1)
    821      {
    822           return(list(l));
    823      }
    824      for (i = 1; i<=size(l); i++ )
    825      {
    826           tempresult = perm(delete(l,i));
    827           for (j = 1; j<=size(tempresult);j++)
    828           {
    829                tempresult[j] = list(l[i])+tempresult[j];
    830           }
    831           result = result+tempresult;
    832      }
    833      return(result);
     833  int i; int j;
     834  list tempresult;
     835  list result;
     836  if (size(l)==0)
     837  {
     838    return(list());
     839  }
     840  if (size(l)==1)
     841  {
     842    return(list(l));
     843  }
     844  for (i = 1; i<=size(l); i++ )
     845  {
     846    tempresult = perm(delete(l,i));
     847    for (j = 1; j<=size(tempresult);j++)
     848    {
     849      tempresult[j] = list(l[i])+tempresult[j];
     850    }
     851    result = result+tempresult;
     852  }
     853  return(result);
    834854}//proc perm
    835855
     
    839859static proc permpp(list l)
    840860{//proc permpp
    841      int i; int j;
    842      list tempresult;
    843      list l_without_double;
    844      list l_without_double_pos;
    845      int double_entry;
    846      list result;
    847      if (size(l)==0)
    848      {
    849           return(list());
    850      }
    851      if (size(l)==1)
    852      {
    853           return(list(l));
    854      }
    855      for (i = 1; i<=size(l);i++)
    856      {//Filling the list with unique entries
    857           double_entry = 0;
    858           for (j = 1; j<=size(l_without_double);j++)
    859           {
    860                if (l_without_double[j] == l[i])
    861                {
    862                     double_entry = 1;
    863                     break;
    864                }
    865           }
    866           if (!double_entry)
    867           {
    868                l_without_double = l_without_double + list(l[i]);
    869                l_without_double_pos = l_without_double_pos + list(i);
    870           }
    871      }//Filling the list with unique entries
    872      for (i = 1; i<=size(l_without_double); i++ )
    873      {
    874           tempresult = permpp(delete(l,l_without_double_pos[i]));
    875           for (j = 1; j<=size(tempresult);j++)
    876           {
    877                tempresult[j] = list(l_without_double[i])+tempresult[j];
    878           }
    879           result = result+tempresult;
    880      }
    881      return(result);
     861  int i; int j;
     862  list tempresult;
     863  list l_without_double;
     864  list l_without_double_pos;
     865  int double_entry;
     866  list result;
     867  if (size(l)==0)
     868  {
     869    return(list());
     870  }
     871  if (size(l)==1)
     872  {
     873    return(list(l));
     874  }
     875  for (i = 1; i<=size(l);i++)
     876  {//Filling the list with unique entries
     877    double_entry = 0;
     878    for (j = 1; j<=size(l_without_double);j++)
     879    {
     880      if (l_without_double[j] == l[i])
     881      {
     882        double_entry = 1;
     883        break;
     884      }
     885    }
     886    if (!double_entry)
     887    {
     888      l_without_double = l_without_double + list(l[i]);
     889      l_without_double_pos = l_without_double_pos + list(i);
     890    }
     891  }//Filling the list with unique entries
     892  for (i = 1; i<=size(l_without_double); i++ )
     893  {
     894    tempresult = permpp(delete(l,l_without_double_pos[i]));
     895    for (j = 1; j<=size(tempresult);j++)
     896    {
     897      tempresult[j] = list(l_without_double[i])+tempresult[j];
     898    }
     899    result = result+tempresult;
     900  }
     901  return(result);
    882902}//proc permpp
    883903
     
    890910//variables in a certain order.
    891911proc facFirstWeyl(poly h)
    892 "USAGE: facFirstWeyl(h); h a poly
     912"USAGE: facFirstWeyl(h); h a polynomial in the first Weyl algebra
    893913RETURN: list
    894914PURPOSE: compute all factorizations of a polynomial in the first Weyl algebra
    895915THEORY: Implements the new algorithm by A. Heinle and V. Levandovskyy, see the thesis of A. Heinle
    896916ASSUME: basering in the first Weyl algebra
     917NOTE: Every entry of the output list is a list with factors for one possible factorization.
     918The first factor is always a constant (1, if no nontrivial constant could be excluded).
    897919EXAMPLE: example facFirstWeyl; shows examples
    898 SEE ALSO: facSubWeyl, testNCfac
     920SEE ALSO: facSubWeyl, testNCfac, facFirstShift
    899921"{//proc facFirstWeyl
    900       //Redefine the ring in my standard form
    901      if (!isWeyl())
    902      {//Our basering is not the Weyl algebra
    903           return(list());
    904      }//Our basering is not the Weyl algebra
    905      if(nvars(basering)!=2)
    906      {//Our basering is the Weyl algebra, but not the first
    907           return(list());
    908      }//Our basering is the Weyl algebra, but not the first
    909      if (ringlist(basering)[6][1,2] == -1) //manual of ringlist will tell you why
    910      {
    911           def r = basering;
    912           ring tempRing = ringlist(r)[1][1],(x,y),Ws(-1,1);
    913           def tempRingnc = nc_algebra(1,1);
    914           setring(tempRingnc);
    915           map transf = r, var(2), var(1);
    916           list result = sfacwa(transf(h));
    917           setring(r);
    918           map transfback = tempRingnc, var(2),var(1);
    919           return(transfback(result));
    920      }
    921      else { return(sfacwa(h));}
     922  //Redefine the ring in my standard form
     923  if (!isWeyl())
     924  {//Our basering is not the Weyl algebra
     925    return(list());
     926  }//Our basering is not the Weyl algebra
     927  if(nvars(basering)!=2)
     928  {//Our basering is the Weyl algebra, but not the first
     929    return(list());
     930  }//Our basering is the Weyl algebra, but not the first
     931  list result = list();
     932  int i;int j; int k; int l; //counter
     933  if (ringlist(basering)[6][1,2] == -1) //manual of ringlist will tell you why
     934  {
     935    def r = basering;
     936    ring tempRing = ringlist(r)[1][1],(x,y),Ws(-1,1); // very strange:
     937    // setting Wp(-1,1) leads to SegFault; to clarify why!!!
     938    def NTR = nc_algebra(1,1);
     939    setring NTR ;
     940    map transf = r, var(2), var(1);
     941    list resulttemp = sfacwa(transf(h));
     942    setring(r);
     943    map transfback = NTR, var(2),var(1);
     944    result = transfback(resulttemp);
     945  }
     946  else { result = sfacwa(h);}
     947  list recursivetemp;
     948  for(i = 1; i<=size(result);i++)
     949  {//recursively factorize factors
     950    if(size(result[i])>2)
     951    {//Nontrivial factorization
     952      for (j=2;j<=size(result[i]);j++)
     953      {//Factorize every factor
     954        recursivetemp = facFirstWeyl(result[i][j]);
     955        if(size(recursivetemp)>1)
     956        {//we have a nontrivial factorization
     957          for(k=1; k<=size(recursivetemp);k++)
     958          {//insert factorized factors
     959            if(size(recursivetemp[k])>2)
     960            {//nontrivial
     961              result = insert(result,result[i],i);
     962              for(l = size(recursivetemp[k]);l>=2;l--)
     963              {
     964                result[i+1] = insert(result[i+1],recursivetemp[k][l],j);
     965              }
     966              result[i+1] = delete(result[i+1],j);
     967            }//nontrivial
     968          }//insert factorized factors
     969        }//we have a nontrivial factorization
     970      }//Factorize every factor
     971    }//Nontrivial factorization
     972  }//recursively factorize factors
     973  if (size(result)==0)
     974  {//only the trivial factorization could be found
     975    result = list(list(1,h));
     976  }//only the trivial factorization could be found
     977  return(result);
    922978}//proc facFirstWeyl
    923979example
    924980{
    925      "EXAMPLE:";echo=2;
    926      ring R = 0,(x,y),dp;
    927      def r = nc_algebra(1,1);
    928      setring(r);
    929      poly h = (x^2*y^2+x)*(x+1);
    930      facFirstWeyl(h);
     981  "EXAMPLE:";echo=2;
     982  ring R = 0,(x,y),dp;
     983  def r = nc_algebra(1,1);
     984  setring(r);
     985  poly h = (x^2*y^2+x)*(x+1);
     986  facFirstWeyl(h);
    931987}
    932988
     
    940996        homogeneous part and those of the lowest will be merged. If during this
    941997        procedure a factorization of the polynomial occurs, it will be added to
    942         the output list. For a more detailled description visit
    943         @url{http://math.rwth-aachen.de/\~Albert.Heinle}
    944 SEE ALSO: homogfac_all, homogfac
     998        the output list. For a more detailed description visit
     999        @url{http://www.math.rwth-aachen.de/\~Albert.Heinle}
     1000SEE ALSO: homogfacFirstWeyl_all, homogfacFirstWeyl
    9451001"{//proc sfacwa
    946      if(homogwithorder(h,intvec(-1,1)))
    947      {
    948           return(homogfac_all(h));
    949      }
    950      def r = basering;
    951      map invo = basering,-var(1),var(2);
    952      int i; int j; int k;
    953      intvec limits = deg(h,intvec(1,1)) ,deg(h,intvec(1,0)),deg(h,intvec(0,1));
    954      def prod;
    955      //end finding the limits
    956      poly maxh = jet(h,deg(h,intvec(-1,1)),intvec(-1,1))-jet(h,deg(h,intvec(-1,1))-1,intvec(-1,1));
    957      poly minh = jet(h,deg(h,intvec(1,-1)),intvec(1,-1))-jet(h,deg(h,intvec(1,-1))-1,intvec(1,-1));
    958      list result;
    959      list temp;
    960      list homogtemp;
    961      list M; list hatM;
    962      list f1 = homogfac_all(maxh);
    963      list f2 = homogfac_all(minh);
    964      int is_equal;
    965      poly hath;
    966      for (i = 1; i<=size(f1);i++)
    967      {//Merge all combinations
    968           for (j = 1; j<=size(f2); j++)
    969           {
    970                M = M + mergence(f1[i],f2[j],limits);
    971           }
    972      }//Merge all combinations
    973      for (i = 1 ; i<= size(M); i++)
    974      {//filter valid combinations
    975           if (product(M[i]) == h)
    976           {//We have one factorization
    977                result = result + list(M[i]);
    978                M = delete(M,i);
    979                continue;
    980           }//We have one factorization
    981           else
    982           {
    983                if (deg(h,intvec(-1,1))<=deg(h-product(M[i]),intvec(-1,1)))
    984                {
    985                     M = delete(M,i);
    986                     continue;
    987                }
    988                if (deg(h,intvec(1,-1))<=deg(h-product(M[i]),intvec(1,-1)))
    989                {
    990                     M = delete(M,i);
    991                     continue;
    992                }
    993           }
    994      }//filter valid combinations
    995      M = delete_dublicates_eval(M);
    996      while(size(M)>0)
    997      {//work on the elements of M
    998           hatM = list();
    999           for(i = 1; i<=size(M); i++)
    1000           {//iterate over all elements of M
    1001                hath = h-product(M[i]);
    1002                temp = list();
    1003                //First check for common inhomogeneous factors between hath and h
    1004                if (involution(NF(involution(hath,invo), std(involution(ideal(M[i][1]),invo))),invo)==0)
    1005                {//hath and h have a common factor on the left
    1006                     j = 1;
    1007                     f1 = M[i];
    1008                     if (j+1<=size(f1))
    1009                     {//Checking for more than one common factor
    1010                          while(involution(NF(involution(hath,invo),std(involution(ideal(product(f1[1..(j+1)])),invo))),invo)==0)
    1011                          {
    1012                               if (j+1<size(f1))
    1013                               {
    1014                                    j++;
    1015                               }
    1016                               else
    1017                               {
    1018                                    break;
    1019                               }
    1020                          }
    1021                     }//Checking for more than one common factor
    1022                     f2 = list(f1[1..j])+list(involution(lift(involution(product(f1[1..j]),invo),involution(hath,invo))[1,1],invo));
    1023                     temp = temp + merge_cf(f2,f1,limits);
    1024                }//hath and h have a common factor on the left
    1025                if (reduce(hath, std(ideal(M[i][size(M[i])])))==0)
    1026                {//hath and h have a common factor on the right
    1027                     j = size(M[i]);
    1028                     f1 = M[i];
    1029                     if (j-1>0)
    1030                     {//Checking for more than one factor
    1031                          while(reduce(hath,std(ideal(product(f1[(j-1)..size(f1)]))))==0)
    1032                          {
    1033                               if (j-1>1)
    1034                               {
    1035                                    j--;
    1036                               }
    1037                               else
    1038                               {
    1039                                    break;
    1040                               }
    1041                          }
    1042                     }//Checking for more than one factor
    1043                          f2 = list(lift(product(f1[j..size(f1)]),hath)[1,1])+list(f1[j..size(f1)]);
    1044                     temp = temp + merge_cf(f2,M[i],limits);
    1045                }//hath and h have a common factor on the right
    1046                //and now the homogeneous
    1047                maxh = jet(hath,deg(hath,intvec(-1,1)),intvec(-1,1))-jet(hath,deg(hath,intvec(-1,1))-1,intvec(-1,1));
    1048                minh = jet(hath,deg(hath,intvec(1,-1)),intvec(1,-1))-jet(hath,deg(hath,intvec(1,-1))-1,intvec(1,-1));
    1049                f1 = homogfac_all(maxh);
    1050                f2 = homogfac_all(minh);
    1051                for (j = 1; j<=size(f1);j++)
    1052                {
    1053                     for (k=1; k<=size(f2);k++)
    1054                     {
    1055                          homogtemp = mergence(f1[j],f2[k],limits);
    1056                     }
    1057                }
    1058                for (j = 1; j<= size(homogtemp); j++)
    1059                {
    1060                     temp = temp + mergence(homogtemp[j],M[i],limits);
    1061                }
    1062                for (j = 1; j<=size(temp); j++)
    1063                {//filtering invalid entries in temp
    1064                     if(product(temp[j])==h)
    1065                     {//This is already a result
    1066                          result = result + list(temp[j]);
    1067                          temp = delete(temp,j);
    1068                          continue;
    1069                     }//This is already a result
    1070                     if (deg(hath,intvec(-1,1))<=deg(hath-product(temp[j]),intvec(-1,1)))
    1071                     {
    1072                          temp = delete(temp,j);
    1073                          continue;
    1074                     }
    1075                }//filtering invalid entries in temp
    1076                hatM = hatM + temp;
    1077           }//iterate over all elements of M
    1078           M = hatM;
    1079           for (i = 1; i<=size(M);i++)
    1080           {//checking for complete factorizations
    1081                if (h == product(M[i]))
    1082                {
    1083                     result = result + list(M[i]);
    1084                     M = delete(M,i);
    1085                     continue;
    1086                }
    1087           }//checking for complete factorizations
    1088           M = delete_dublicates_eval(M);
    1089      }//work on the elements of M
    1090      //In the case, that there is none, write a constant factor before the factor of interest.
    1091      for (i = 1 ; i<=size(result);i++)
    1092      {//add a constant factor
    1093           if (deg(result[i][1],intvec(1,1))!=0)
    1094           {
    1095                result[i] = insert(result[i],1);
    1096           }
    1097      }//add a constant factor
    1098      result = delete_dublicates_noteval(result);
    1099      return(result);
     1002  if(homogwithorder(h,intvec(-1,1)))
     1003  {
     1004    return(homogfacFirstWeyl_all(h));
     1005  }
     1006  def r = basering;
     1007  map invo = basering,-var(1),var(2);
     1008  int i; int j; int k;
     1009  intvec limits = deg(h,intvec(1,1)) ,deg(h,intvec(1,0)),deg(h,intvec(0,1));
     1010  def prod;
     1011  //end finding the limits
     1012  poly maxh = jet(h,deg(h,intvec(-1,1)),intvec(-1,1))-jet(h,deg(h,intvec(-1,1))-1,intvec(-1,1));
     1013  poly minh = jet(h,deg(h,intvec(1,-1)),intvec(1,-1))-jet(h,deg(h,intvec(1,-1))-1,intvec(1,-1));
     1014  list result;
     1015  list temp;
     1016  list homogtemp;
     1017  list M; list hatM;
     1018  list f1 = homogfacFirstWeyl_all(maxh);
     1019  list f2 = homogfacFirstWeyl_all(minh);
     1020  int is_equal;
     1021  poly hath;
     1022  for (i = 1; i<=size(f1);i++)
     1023  {//Merge all combinations
     1024    for (j = 1; j<=size(f2); j++)
     1025    {
     1026      M = M + mergence(f1[i],f2[j],limits);
     1027    }
     1028  }//Merge all combinations
     1029  for (i = 1 ; i<= size(M); i++)
     1030  {//filter valid combinations
     1031    if (product(M[i]) == h)
     1032    {//We have one factorization
     1033      result = result + list(M[i]);
     1034      M = delete(M,i);
     1035      continue;
     1036    }//We have one factorization
     1037    else
     1038    {
     1039      if (deg(h,intvec(-1,1))<=deg(h-product(M[i]),intvec(-1,1)))
     1040      {
     1041        M = delete(M,i);
     1042        continue;
     1043      }
     1044      if (deg(h,intvec(1,-1))<=deg(h-product(M[i]),intvec(1,-1)))
     1045      {
     1046        M = delete(M,i);
     1047        continue;
     1048      }
     1049    }
     1050  }//filter valid combinations
     1051  M = delete_dublicates_eval(M);
     1052  while(size(M)>0)
     1053  {//work on the elements of M
     1054    hatM = list();
     1055    for(i = 1; i<=size(M); i++)
     1056    {//iterate over all elements of M
     1057      hath = h-product(M[i]);
     1058      temp = list();
     1059      //First check for common inhomogeneous factors between hath and h
     1060      if (involution(NF(involution(hath,invo), std(involution(ideal(M[i][1]),invo))),invo)==0)
     1061      {//hath and h have a common factor on the left
     1062        j = 1;
     1063        f1 = M[i];
     1064        if (j+1<=size(f1))
     1065        {//Checking for more than one common factor
     1066          while(involution(NF(involution(hath,invo),std(involution(ideal(product(f1[1..(j+1)])),invo))),invo)==0)
     1067          {
     1068            if (j+1<size(f1))
     1069            {
     1070              j++;
     1071            }
     1072            else
     1073            {
     1074              break;
     1075            }
     1076          }
     1077        }//Checking for more than one common factor
     1078        f2 = list(f1[1..j])+list(involution(lift(involution(product(f1[1..j]),invo),involution(hath,invo))[1,1],invo));
     1079        temp = temp + merge_cf(f2,f1,limits);
     1080      }//hath and h have a common factor on the left
     1081      if (reduce(hath, std(ideal(M[i][size(M[i])])))==0)
     1082      {//hath and h have a common factor on the right
     1083        j = size(M[i]);
     1084        f1 = M[i];
     1085        if (j-1>0)
     1086        {//Checking for more than one factor
     1087          while(reduce(hath,std(ideal(product(f1[(j-1)..size(f1)]))))==0)
     1088          {
     1089            if (j-1>1)
     1090            {
     1091              j--;
     1092            }
     1093            else
     1094            {
     1095              break;
     1096            }
     1097          }
     1098        }//Checking for more than one factor
     1099        f2 = list(lift(product(f1[j..size(f1)]),hath)[1,1])+list(f1[j..size(f1)]);
     1100        temp = temp + merge_cf(f2,M[i],limits);
     1101      }//hath and h have a common factor on the right
     1102      //and now the homogeneous
     1103      maxh = jet(hath,deg(hath,intvec(-1,1)),intvec(-1,1))-jet(hath,deg(hath,intvec(-1,1))-1,intvec(-1,1));
     1104      minh = jet(hath,deg(hath,intvec(1,-1)),intvec(1,-1))-jet(hath,deg(hath,intvec(1,-1))-1,intvec(1,-1));
     1105      f1 = homogfacFirstWeyl_all(maxh);
     1106      f2 = homogfacFirstWeyl_all(minh);
     1107      for (j = 1; j<=size(f1);j++)
     1108      {
     1109        for (k=1; k<=size(f2);k++)
     1110        {
     1111          homogtemp = mergence(f1[j],f2[k],limits);
     1112        }
     1113      }
     1114      for (j = 1; j<= size(homogtemp); j++)
     1115      {
     1116        temp = temp + mergence(homogtemp[j],M[i],limits);
     1117      }
     1118      for (j = 1; j<=size(temp); j++)
     1119      {//filtering invalid entries in temp
     1120        if(product(temp[j])==h)
     1121        {//This is already a result
     1122          result = result + list(temp[j]);
     1123          temp = delete(temp,j);
     1124          continue;
     1125        }//This is already a result
     1126        if (deg(hath,intvec(-1,1))<=deg(hath-product(temp[j]),intvec(-1,1)))
     1127        {
     1128          temp = delete(temp,j);
     1129          continue;
     1130        }
     1131      }//filtering invalid entries in temp
     1132      hatM = hatM + temp;
     1133    }//iterate over all elements of M
     1134    M = hatM;
     1135    for (i = 1; i<=size(M);i++)
     1136    {//checking for complete factorizations
     1137      if (h == product(M[i]))
     1138      {
     1139        result = result + list(M[i]);
     1140        M = delete(M,i);
     1141        continue;
     1142      }
     1143    }//checking for complete factorizations
     1144    M = delete_dublicates_eval(M);
     1145  }//work on the elements of M
     1146  //In the case, that there is none, write a constant factor before the factor of interest.
     1147  for (i = 1 ; i<=size(result);i++)
     1148  {//add a constant factor
     1149    if (deg(result[i][1],intvec(1,1))!=0)
     1150    {
     1151      result[i] = insert(result[i],1);
     1152    }
     1153  }//add a constant factor
     1154  result = delete_dublicates_noteval(result);
     1155  return(result);
    11001156}//proc sfacwa
    11011157
     
    11031159//==================================================
    11041160/*Singular has no way implemented to test polynomials
    1105  for homogenity with respect to a weight vector.
    1106  The following procedure does exactly this*/
     1161  for homogenity with respect to a weight vector.
     1162  The following procedure does exactly this*/
    11071163static proc homogwithorder(poly h, intvec weights)
    11081164{//proc homogwithorder
    1109      if(size(weights) != nvars(basering))
    1110      {//The user does not know how many variables the current ring has
    1111           return(0);
    1112      }//The user does not know how many variables the current ring has
    1113      int i;
    1114      int dofp = deg(h,weights); //degree of polynomial
    1115      for (i = 1; i<=size(h);i++)
    1116      {
    1117           if (deg(h[i],weights)!=dofp)
    1118           {
    1119                return(0);
    1120           }
    1121      }
    1122      return(1);
     1165  if(size(weights) != nvars(basering))
     1166  {//The user does not know how many variables the current ring has
     1167    return(0);
     1168  }//The user does not know how many variables the current ring has
     1169  int i;
     1170  int dofp = deg(h,weights); //degree of polynomial
     1171  for (i = 1; i<=size(h);i++)
     1172  {
     1173    if (deg(h[i],weights)!=dofp)
     1174    {
     1175      return(0);
     1176    }
     1177  }
     1178  return(1);
    11231179}//proc homogwithorder
    11241180
     
    11541210     by the multiplied candidate for its factorization.
    11551211EXAMPLE: example testNCfac; shows examples
    1156 SEE ALSO: facFirstWeyl, facSubWeyl
     1212SEE ALSO: facFirstWeyl, facSubWeyl, facFirstShift
    11571213"{//proc testfac
    1158      if (size(l)==0)
    1159      {//The empty list is given
    1160           return(list());
    1161      }//The empty list is given
    1162      if (size(#)>1)
    1163      {//We want max. one optional argument
    1164           return(list());
    1165      }//We want max. one optional argument
    1166      list result;
    1167      int i; int j;
    1168      if (size(#)==0)
    1169      {//No optional argument is given
    1170           int valid = 1;
    1171           for (i = size(l);i>=1;i--)
    1172           {//iterate over the elements of the given list
    1173                if (size(result)>0)
    1174                {
    1175                     if (product(l[i])!=result[size(l)-i])
    1176                     {
    1177                          valid = 0;
    1178                          break;
    1179                     }
    1180                }
    1181                result = insert(result, product(l[i]));
    1182           }//iterate over the elements of the given list
    1183           if (valid)
    1184           {
    1185                return(result);
    1186           }
    1187           return(list());
    1188      }//No optional argument is given
    1189      else
    1190      {
    1191           int valid = 1;
    1192           for (i = size(l);i>=1;i--)
    1193           {//iterate over the elements of the given list
    1194                if (product(l[i])!=#[1])
    1195                {
    1196                     valid = 0;
    1197                }
    1198                result = insert(result, product(l[i]));
    1199           }//iterate over the elements of the given list
    1200           if (valid)
    1201           {
    1202                return(result);
    1203           }
    1204           for (i = 1 ; i<= size(result);i++)
    1205           {//subtract p from every entry in result
    1206                result[i] = result[i] - #[1];
    1207           }//subtract p from every entry in result
    1208           return(result);
    1209      }
     1214  if (size(l)==0)
     1215  {//The empty list is given
     1216    return(list());
     1217  }//The empty list is given
     1218  if (size(#)>1)
     1219  {//We want max. one optional argument
     1220    return(list());
     1221  }//We want max. one optional argument
     1222  list result;
     1223  int i; int j;
     1224  if (size(#)==0)
     1225  {//No optional argument is given
     1226    int valid = 1;
     1227    for (i = size(l);i>=1;i--)
     1228    {//iterate over the elements of the given list
     1229      if (size(result)>0)
     1230      {
     1231        if (product(l[i])!=result[size(l)-i])
     1232        {
     1233          valid = 0;
     1234          break;
     1235        }
     1236      }
     1237      result = insert(result, product(l[i]));
     1238    }//iterate over the elements of the given list
     1239    if (valid)
     1240    {
     1241      return(result);
     1242    }
     1243    return(list());
     1244  }//No optional argument is given
     1245  else
     1246  {
     1247    int valid = 1;
     1248    for (i = size(l);i>=1;i--)
     1249    {//iterate over the elements of the given list
     1250      if (product(l[i])!=#[1])
     1251      {
     1252        valid = 0;
     1253      }
     1254      result = insert(result, product(l[i]));
     1255    }//iterate over the elements of the given list
     1256    if (valid)
     1257    {
     1258      return(result);
     1259    }
     1260    for (i = 1 ; i<= size(result);i++)
     1261    {//subtract p from every entry in result
     1262      result[i] = result[i] - #[1];
     1263    }//subtract p from every entry in result
     1264    return(result);
     1265  }
    12101266}//proc testfac
    12111267example
    12121268{
    1213      "EXAMPLE:";echo=2;
    1214      ring r = 0,(x,y),dp;
    1215      def R = nc_algebra(1,1);
    1216      setring R;
    1217      poly h = (x^2*y^2+1)*(x^2);
    1218      def t1 = facFirstWeyl(h);
    1219      //fist a correct list
    1220      testNCfac(t1);
    1221      //now a correct list with the factorized polynomial
    1222      testNCfac(t1,h);
    1223      //now we put in an incorrect list without a polynomial
    1224      t1[3][3] = y;
    1225      testNCfac(t1);
    1226      //and last but not least we take h as additional input
    1227      testNCfac(t1,h);
     1269  "EXAMPLE:";echo=2;
     1270  ring r = 0,(x,y),dp;
     1271  def R = nc_algebra(1,1);
     1272  setring R;
     1273  poly h = (x^2*y^2+1)*(x^2);
     1274  def t1 = facFirstWeyl(h);
     1275  //fist a correct list
     1276  testNCfac(t1);
     1277  //now a correct list with the factorized polynomial
     1278  testNCfac(t1,h);
     1279  //now we put in an incorrect list without a polynomial
     1280  t1[3][3] = y;
     1281  testNCfac(t1);
     1282  //and last but not least we take h as additional input
     1283  testNCfac(t1,h);
    12281284}
    12291285//==================================================
     
    12371293"USAGE:  facSubWeyl(h,x,y); h, X, D polynomials
    12381294RETURN: list
    1239 ASSUME: X and D are variables of a basering, which satisfy DX = XD +1.
     1295ASSUME: X and D are variables of a basering, which satisfy DX = XD +1. 
    12401296@* That is,  they generate the copy of the first Weyl algebra in a basering.
    12411297@* Moreover, h is a polynomial in X and D only.
    12421298PURPOSE: compute factorizations of the polynomial, which depends on X and D.
    12431299EXAMPLE: example facSubWeyl; shows examples
    1244 SEE ALSO: facFirstWeyl, testNCfac
     1300SEE ALSO: facFirstWeyl, testNCfac, facFirstShift
    12451301"{
    1246 //proc facSubWeyl
    1247 // basering can be anything having a Weyl algebra as subalgebra
    1248      def r = basering;
    1249      //We begin to check the input for assumptions
    1250      // which are: X,D are vars of the basering,
    1251      if ( (isVar(X)!=1) || (isVar(D)!=1) || (size(X)>1) || (size(D)>1) ||
    1252           (leadcoef(X) != number(1)) || (leadcoef(D) != number(1)) )
    1253      {
    1254        ERROR("expected pure variables as generators of a subalgebra");
    1255      }
    1256      // Weyl algebra:
    1257      poly w = D*X-X*D-1; // [D,X]=1
    1258      poly u = D*X-X*D+1; // [X,D]=1
    1259      if (u*w!=0)
    1260      {
    1261        // that is no combination gives Weyl
    1262        ERROR("2nd and 3rd argument do not generate a Weyl algebra");
    1263      }
    1264      // one of two is correct
    1265      if (u==0)
    1266      {
    1267        // hence w != 0, swap X<->D
    1268        w = D; D=X; X=w;
    1269      }
    1270      // DONE with assumptions
    1271      //Input successfully checked
    1272      intvec lexpofX = leadexp(X);
    1273      intvec lexpofD = leadexp(D);
    1274      int varnumX=1;
    1275      int varnumD=1;
    1276      while(lexpofX[varnumX] != 1)
    1277      {
    1278           varnumX++;
    1279      }
    1280      while(lexpofD[varnumD] != 1)
    1281      {
    1282           varnumD++;
    1283      }
    1284 /* VL: it's not clear what you do here!!! I comment out */
    1285      //     lexpofX = lexpofX +1;
    1286      //      lexpofX[varnumX] = 0;
    1287      //      lexpofX[varnumD] = 0;
    1288      //      if (deg(h,lexpofX)!=0)
    1289      //      {
    1290      //           return(list());
    1291      //      }
    1292 /* VL : to add printlevel stuff */
    1293 
    1294      ring firstweyl = 0,(var(varnumX),var(varnumD)),dp;
    1295      def Firstweyl = nc_algebra(1,1);
    1296      setring Firstweyl;
    1297      poly h = imap(r,h);
    1298      list result = facFirstWeyl(h);
    1299      setring r;
    1300      list result = imap(Firstweyl,result);
    1301      return(result);
     1302  //proc facSubWeyl
     1303  // basering can be anything having a Weyl algebra as subalgebra
     1304  def @r = basering;
     1305  //We begin to check the input for assumptions
     1306  // which are: X,D are vars of the basering,
     1307  if ( (isVar(X)!=1) || (isVar(D)!=1) || (size(X)>1) || (size(D)>1) ||
     1308       (leadcoef(X) != number(1)) || (leadcoef(D) != number(1)) )
     1309  {
     1310    ERROR("expected pure variables as generators of a subalgebra");
     1311  }
     1312  // Weyl algebra:
     1313  poly w = D*X-X*D-1; // [D,X]=1
     1314  poly u = D*X-X*D+1; // [X,D]=1
     1315  if (u*w!=0)
     1316  {
     1317    // that is no combination gives Weyl
     1318    ERROR("2nd and 3rd argument do not generate a Weyl algebra");
     1319  }
     1320  // one of two is correct
     1321  int isReverted = 0; // Reverted Weyl if dx=xd-1 holds
     1322  if (u==0)
     1323  {
     1324    // hence w != 0, swap X<->D later
     1325    isReverted = 1;
     1326    //    w = D; D=X; X=w;
     1327  }
     1328  // else: do nothing
     1329  // DONE with assumptions       
     1330  //Input successfuy checked
     1331  intvec lexpofX = leadexp(X);
     1332  intvec lexpofD = leadexp(D);
     1333  int varnumX=1;
     1334  int varnumD=1;
     1335  while(lexpofX[varnumX] != 1)
     1336  {
     1337    varnumX++;
     1338  }
     1339  while(lexpofD[varnumD] != 1)
     1340  {
     1341    varnumD++;
     1342  }
     1343  /* VL: it's not clear what you do here!!! I comment out */
     1344  //     lexpofX = lexpofX +1;
     1345  //      lexpofX[varnumX] = 0;
     1346  //      lexpofX[varnumD] = 0;
     1347  //      if (deg(h,lexpofX)!=0)
     1348  //      {
     1349  //           return(list());
     1350  //      }
     1351  /* VL : to add printlevel stuff */
     1352
     1353  if (isReverted)
     1354  {
     1355    ring firstweyl = 0,(var(varnumD),var(varnumX)),dp;
     1356    def Firstweyl = nc_algebra(1,1); 
     1357    setring Firstweyl;
     1358    ideal M = 0:nvars(@r);
     1359    M[varnumX]=var(2);
     1360    M[varnumD]=var(1);
     1361    map Q = @r,M;
     1362    poly h= Q(h);
     1363  }
     1364  else
     1365  { // that is unReverted
     1366    ring firstweyl = 0,(var(varnumX),var(varnumD)),dp;
     1367    def Firstweyl = nc_algebra(1,1);
     1368    setring Firstweyl;
     1369    poly h= imap(@r,h);
     1370  }
     1371  list result = facFirstWeyl(h);
     1372  setring @r;
     1373  list result;
     1374  if (isReverted)
     1375  {
     1376    // map swap back
     1377    ideal M; M[1] = var(varnumD); M[2] = var(varnumX);
     1378    map S = Firstweyl, M;
     1379    result = S(result);
     1380  }
     1381  else
     1382  {
     1383    // that is unReverted
     1384    result = imap(Firstweyl,result);
     1385  }
     1386  return(result);
    13021387}//proc facSubWeyl
    13031388example
    13041389{
    1305      "EXAMPLE:";echo=2;
    1306      ring r = 0,(x,y,z),dp;
    1307      matrix D[3][3]; D[1,3]=-1;
    1308      def R = nc_algebra(1,D); // x,z generate Weyl subalgebra
    1309      setring R;
    1310      poly h = (x^2*z^2+x)*x;
    1311      list fact1 = facSubWeyl(h,x,z); fact1[2];
    1312      poly test1 = fact1[2][2]; // for testing
    1313      // compare with facFirstWeyl:
    1314      ring s = 0,(z,x),dp;
    1315      def S = nc_algebra(1,1); setring S;
    1316      poly h = (x^2*z^2+x)*x;
    1317      list fact2 = facFirstWeyl(h); fact2[2];
    1318      poly test2 = fact2[2][2]; // for testing
    1319      map F = R,x,z;
    1320      F(test1) - test2; // they are identical
     1390  "EXAMPLE:";echo=2;
     1391  ring r = 0,(x,y,z),dp;
     1392  matrix D[3][3]; D[1,3]=-1;
     1393  def R = nc_algebra(1,D); // x,z generate Weyl subalgebra
     1394  setring R;
     1395  poly h = (x^2*z^2+x)*x;
     1396  list fact1 = facSubWeyl(h,x,z);
     1397  // compare with facFirstWeyl:
     1398  ring s = 0,(z,x),dp;
     1399  def S = nc_algebra(1,1); setring S;
     1400  poly h = (x^2*z^2+x)*x;
     1401  list fact2 = facFirstWeyl(h);
     1402  map F = R,x,0,z;
     1403  list fact1 = F(fact1); // it is identical to list fact2
     1404  testNCfac(fact1); // check the correctness again
    13211405}
    13221406//==================================================
     1407
     1408//==================================================
     1409//************From here: Shift-Algebra**************
     1410                         //==================================================
     1411
     1412                         //==================================================*
     1413                         //one factorization of a homogeneous polynomial
     1414                         //in the first Shift Algebra
     1415static proc homogfacFirstShift(poly h)
     1416{//proc homogfacFirstShift
     1417  def r = basering;
     1418  poly hath;
     1419  int i; int j;
     1420  if (!homogwithorder(h,intvec(0,1)))
     1421  {//The given polynomial is not homogeneous
     1422    return(list());
     1423  }//The given polynomial is not homogeneous
     1424  if (h==0)
     1425  {
     1426    return(list(0));
     1427  }
     1428  list result;
     1429  int m = deg(h,intvec(0,1));
     1430  if (m>0)
     1431  {//The degree is not zero
     1432    hath = lift(var(2)^m,h)[1,1];
     1433    for (i = 1; i<=m;i++)
     1434    {
     1435      result = result + list(var(2));
     1436    }
     1437  }//The degree is not zero
     1438  else
     1439  {//The degree is zero
     1440    hath = h;
     1441  }//The degree is zero
     1442  ring tempRing = 0,(x),dp;
     1443  setring tempRing;
     1444  map thetamap = r,x,1;
     1445  poly hath = thetamap(hath);
     1446  list azeroresult = factorize(hath);
     1447  list azeroresult_return_form;
     1448  for (i = 1; i<=size(azeroresult[1]);i++)
     1449  {//rewrite the result of the commutative factorization
     1450    for (j = 1; j <= azeroresult[2][i];j++)
     1451    {
     1452      azeroresult_return_form = azeroresult_return_form + list(azeroresult[1][i]);
     1453    }
     1454  }//rewrite the result of the commutative factorization
     1455  setring(r);
     1456  map finalmap = tempRing,var(1);
     1457  list tempresult = finalmap(azeroresult_return_form);
     1458  result = tempresult+result;
     1459  return(result);
     1460}//proc homogfacFirstShift
     1461
     1462//==================================================
     1463//Computes all possible homogeneous factorizations
     1464static proc homogfacFirstShift_all(poly h)
     1465{//proc HomogfacFirstShiftAll
     1466  if (deg(h,intvec(1,1)) <= 0 )
     1467  {//h is a constant
     1468    return(list(list(h)));
     1469  }//h is a constant
     1470  def r = basering;
     1471  list one_hom_fac; //stands for one homogeneous factorization
     1472  int i; int j; int k;
     1473  int shiftcounter;
     1474  //Compute again a homogeneous factorization
     1475  one_hom_fac = homogfacFirstShift(h);
     1476  one_hom_fac = delete(one_hom_fac,1);
     1477  if (size(one_hom_fac) == 0)
     1478  {//there is no homogeneous factorization or the polynomial was not homogeneous
     1479    return(list());
     1480  }//there is no homogeneous factorization or the polynomial was not homogeneous
     1481  list result = permpp(one_hom_fac);
     1482  for (i = 1; i<=size(result);i++)
     1483  {
     1484    shiftcounter = 0;
     1485    for (j = 1; j<=size(result[i]); j++)
     1486    {
     1487      if (result[i][j]==var(2))
     1488      {
     1489        shiftcounter++;
     1490      }
     1491      else
     1492      {
     1493        result[i][j] = subst(result[i][j], var(1), var(1)-shiftcounter);
     1494      }
     1495    }
     1496    result[i] = insert(result[i],1);
     1497  }
     1498  result = delete_dublicates_noteval(result);
     1499  return(result);
     1500}//proc HomogfacFirstShiftAll
     1501
     1502//==================================================
     1503//factorization of the first Shift Algebra
     1504proc facFirstShift(poly h)
     1505"USAGE: facFirstShift(h); h a polynomial in the first shift algebra
     1506RETURN: list
     1507PURPOSE: compute all factorizations of a polynomial in the first shift algebra
     1508THEORY: Implements the new algorithm by A. Heinle and V. Levandovskyy, see the thesis of A. Heinle
     1509ASSUME: basering in the first shift algebra
     1510NOTE: Every entry of the output list is a list with factors for one possible factorization.
     1511EXAMPLE: example facFirstShift; shows examples
     1512SEE ALSO: testNCfac, facFirstWeyl, facSubWeyl
     1513"{//facFirstShift
     1514  if(nvars(basering)!=2)
     1515  {//Our basering is the Shift algebra, but not the first
     1516    ERROR("Basering is not the first shift algebra");
     1517    return(list());
     1518  }//Our basering is the Shift algebra, but not the first
     1519  def r = basering;
     1520  setring r;
     1521  list LR = ringlist(r);
     1522  number @n = leadcoef(LR[5][1,2]);
     1523  poly @p = LR[6][1,2];
     1524  if  ( @n!=number(1) )
     1525  {
     1526    ERROR("Basering is not the first shift algebra");
     1527    return(list());
     1528  }
     1529  list result = list();
     1530  int i;int j; int k; int l; //counter
     1531  // create a ring with the ordering which makes shift algebra
     1532  // graded
     1533  // def r = basering; // done before
     1534  ring tempRing = LR[1][1],(x,s),(a(0,1),Dp);
     1535  def tempRingnc = nc_algebra(1,s);
     1536  setring r;
     1537  // information on relations
     1538  if (@p == -var(1)) // reverted shift algebra
     1539  {
     1540    setring(tempRingnc);
     1541    map transf = r, var(2), var(1);
     1542    setring(r);
     1543    map transfback = tempRingnc, var(2),var(1);
     1544    //    result = transfback(resulttemp);
     1545  }
     1546  else
     1547  {
     1548    if ( @p == var(2)) // usual shift algebra
     1549    {
     1550      setring(tempRingnc);
     1551      map transf = r, var(1), var(2);
     1552      //    result = facshift(h);
     1553      setring(r);
     1554      map transfback = tempRingnc, var(1),var(2);
     1555    }
     1556    else
     1557    {
     1558      ERROR("Basering is not the first shift algebra");
     1559      return(list());
     1560    }
     1561  }
     1562  // main calls
     1563  setring(tempRingnc);
     1564  list resulttemp = facshift(transf(h));
     1565  setring(r);
     1566  result = transfback(resulttemp);
     1567
     1568  list recursivetemp;
     1569  for(i = 1; i<=size(result);i++)
     1570  {//recursively factorize factors
     1571    if(size(result[i])>2)
     1572    {//Nontrivial factorization
     1573      for (j=2;j<=size(result[i]);j++)
     1574      {//Factorize every factor
     1575        recursivetemp = facFirstShift(result[i][j]);
     1576        if(size(recursivetemp)>1)
     1577        {//we have a nontrivial factorization
     1578          for(k=1; k<=size(recursivetemp);k++)
     1579          {//insert factorized factors
     1580            if(size(recursivetemp[k])>2)
     1581            {//nontrivial
     1582              result = insert(result,result[i],i);
     1583              for(l = size(recursivetemp[k]);l>=2;l--)
     1584              {
     1585                result[i+1] = insert(result[i+1],recursivetemp[k][l],j);
     1586              }
     1587              result[i+1] = delete(result[i+1],j);
     1588            }//nontrivial
     1589          }//insert factorized factors
     1590        }//we have a nontrivial factorization
     1591      }//Factorize every factor
     1592    }//Nontrivial factorization
     1593  }//recursively factorize factors
     1594  return(result);
     1595}//facFirstShift
     1596example
     1597{
     1598  "EXAMPLE:";echo=2;
     1599  ring R = 0,(x,s),dp;
     1600  def r = nc_algebra(1,s);
     1601  setring(r);
     1602  poly h = (s^2*x+x)*s;
     1603  facFirstShift(h);
     1604}
     1605
     1606static proc facshift(poly h)
     1607"USAGE: facshift(h); h is a polynomial in the first Shift algebra
     1608RETURN: list
     1609PURPOSE: Computes a factorization of a polynomial h in the first Shift algebra
     1610THEORY: @code{facshift} returns a list with some factorizations of the given
     1611        polynomial. The possibilities of the factorization of the highest
     1612        homogeneous part and those of the lowest will be merged. If during this
     1613        procedure a factorization of the polynomial occurs, it will be added to
     1614        the output list. For a more detailled description visit
     1615        @url{http://math.rwth-aachen.de/\~Albert.Heinle}
     1616SEE ALSO: homogfacFirstShift_all, homogfacFirstShift
     1617"{//proc facshift
     1618  if(homogwithorder(h,intvec(0,1)))
     1619  {
     1620    return(homogfacFirstShift_all(h));
     1621  }
     1622  def r = basering;
     1623  map invo = basering,-var(1),-var(2);
     1624  int i; int j; int k;
     1625  intvec limits = deg(h,intvec(1,1)) ,deg(h,intvec(1,0)),deg(h,intvec(0,1));
     1626  def prod;
     1627  //end finding the limits
     1628  poly maxh = jet(h,deg(h,intvec(0,1)),intvec(0,1))-jet(h,deg(h,intvec(0,1))-1,intvec(0,1));
     1629  poly minh = jet(h,deg(h,intvec(0,-1)),intvec(0,-1))-jet(h,deg(h,intvec(0,-1))-1,intvec(0,-1));
     1630  list result;
     1631  list temp;
     1632  list homogtemp;
     1633  list M; list hatM;
     1634  list f1 = homogfacFirstShift_all(maxh);
     1635  list f2 = homogfacFirstShift_all(minh);
     1636  int is_equal;
     1637  poly hath;
     1638  for (i = 1; i<=size(f1);i++)
     1639  {//Merge all combinations
     1640    for (j = 1; j<=size(f2); j++)
     1641    {
     1642      M = M + mergence(f1[i],f2[j],limits);
     1643    }
     1644  }//Merge all combinations
     1645  for (i = 1 ; i<= size(M); i++)
     1646  {//filter valid combinations
     1647    if (product(M[i]) == h)
     1648    {//We have one factorization
     1649      result = result + list(M[i]);
     1650      M = delete(M,i);
     1651      continue;
     1652    }//We have one factorization
     1653    else
     1654    {
     1655      if (deg(h,intvec(0,1))<=deg(h-product(M[i]),intvec(0,1)))
     1656      {
     1657        M = delete(M,i);
     1658        continue;
     1659      }
     1660      if (deg(h,intvec(0,-1))<=deg(h-product(M[i]),intvec(0,-1)))
     1661      {
     1662        M = delete(M,i);
     1663        continue;
     1664      }
     1665    }
     1666  }//filter valid combinations
     1667  M = delete_dublicates_eval(M);
     1668  while(size(M)>0)
     1669  {//work on the elements of M
     1670    hatM = list();
     1671    for(i = 1; i<=size(M); i++)
     1672    {//iterate over all elements of M
     1673      hath = h-product(M[i]);
     1674      temp = list();
     1675      //First check for common inhomogeneous factors between hath and h
     1676      if (involution(NF(involution(hath,invo), std(involution(ideal(M[i][1]),invo))),invo)==0)
     1677      {//hath and h have a common factor on the left
     1678        j = 1;
     1679        f1 = M[i];
     1680        if (j+1<=size(f1))
     1681        {//Checking for more than one common factor
     1682          while(involution(NF(involution(hath,invo),std(involution(ideal(product(f1[1..(j+1)])),invo))),invo)==0)
     1683          {
     1684            if (j+1<size(f1))
     1685            {
     1686              j++;
     1687            }
     1688            else
     1689            {
     1690              break;
     1691            }
     1692          }
     1693        }//Checking for more than one common factor
     1694        if (deg(product(f1[1..j]),intvec(1,1))!=0)
     1695        {
     1696          f2 = list(f1[1..j])+list(involution(lift(involution(product(f1[1..j]),invo),involution(hath,invo))[1,1],invo));
     1697        }
     1698        else
     1699        {
     1700          f2 = list(f1[1..j])+list(involution(lift(product(f1[1..j]),involution(hath,invo))[1,1],invo));
     1701        }
     1702        temp = temp + merge_cf(f2,f1,limits);
     1703      }//hath and h have a common factor on the left
     1704      if (reduce(hath, std(ideal(M[i][size(M[i])])))==0)
     1705      {//hath and h have a common factor on the right
     1706        j = size(M[i]);
     1707        f1 = M[i];
     1708        if (j-1>0)
     1709        {//Checking for more than one factor
     1710          while(reduce(hath,std(ideal(product(f1[(j-1)..size(f1)]))))==0)
     1711          {
     1712            if (j-1>1)
     1713            {
     1714              j--;
     1715            }
     1716            else
     1717            {
     1718              break;
     1719            }
     1720          }
     1721        }//Checking for more than one factor
     1722        f2 = list(lift(product(f1[j..size(f1)]),hath)[1,1])+list(f1[j..size(f1)]);
     1723        temp = temp + merge_cf(f2,M[i],limits);
     1724      }//hath and h have a common factor on the right
     1725      //and now the homogeneous
     1726      maxh = jet(hath,deg(hath,intvec(0,1)),intvec(0,1))-jet(hath,deg(hath,intvec(0,1))-1,intvec(0,1));
     1727      minh = jet(hath,deg(hath,intvec(0,-1)),intvec(0,-1))-jet(hath,deg(hath,intvec(0,-1))-1,intvec(0,-1));
     1728      f1 = homogfacFirstShift_all(maxh);
     1729      f2 = homogfacFirstShift_all(minh);
     1730      for (j = 1; j<=size(f1);j++)
     1731      {
     1732        for (k=1; k<=size(f2);k++)
     1733        {
     1734          homogtemp = mergence(f1[j],f2[k],limits);
     1735        }
     1736      }
     1737      for (j = 1; j<= size(homogtemp); j++)
     1738      {
     1739        temp = temp + mergence(homogtemp[j],M[i],limits);
     1740      }
     1741      for (j = 1; j<=size(temp); j++)
     1742      {//filtering invalid entries in temp
     1743        if(product(temp[j])==h)
     1744        {//This is already a result
     1745          result = result + list(temp[j]);
     1746          temp = delete(temp,j);
     1747          continue;
     1748        }//This is already a result
     1749        if (deg(hath,intvec(0,1))<=deg(hath-product(temp[j]),intvec(0,1)))
     1750        {
     1751          temp = delete(temp,j);
     1752          continue;
     1753        }
     1754      }//filtering invalid entries in temp
     1755      hatM = hatM + temp;
     1756    }//iterate over all elements of M
     1757    M = hatM;
     1758    for (i = 1; i<=size(M);i++)
     1759    {//checking for complete factorizations
     1760      if (h == product(M[i]))
     1761      {
     1762        result = result + list(M[i]);
     1763        M = delete(M,i);
     1764        continue;
     1765      }
     1766    }//checking for complete factorizations
     1767    M = delete_dublicates_eval(M);
     1768  }//work on the elements of M
     1769  //In the case, that there is none, write a constant factor before the factor of interest.
     1770  for (i = 1 ; i<=size(result);i++)
     1771  {//add a constant factor
     1772    if (deg(result[i][1],intvec(1,1))!=0)
     1773    {
     1774      result[i] = insert(result[i],1);
     1775    }
     1776  }//add a constant factor
     1777  result = delete_dublicates_noteval(result);
     1778  return(result);
     1779}//proc facshift
     1780
    13231781/*
    1324 Example polynomials where one can find factorizations
    1325 (x^2+y)*(x^2+y);
    1326 (x^2+x)*(x^2+y);
    1327 (x^3+x+1)*(x^4+y*x+2);
    1328 (x^2*y+y)*(y+x*y);
    1329 y^3+x*y^3+2*y^2+2*(x+1)*y^2+y+(x+2)*y; //Example 5 Gregoriev Schwarz.
    1330 (y+1)*(y+1)*(y+x*y); //Landau Example projected to the first dimension.
    1331  */
     1782  Example polynomials where one can find factorizations
     1783  (x^2+y)*(x^2+y);
     1784  (x^2+x)*(x^2+y);
     1785  (x^3+x+1)*(x^4+y*x+2);
     1786  (x^2*y+y)*(y+x*y);
     1787  y^3+x*y^3+2*y^2+2*(x+1)*y^2+y+(x+2)*y; //Example 5 Grigoriev-Schwarz.
     1788  (y+1)*(y+1)*(y+x*y); //Landau Example projected to the first dimension.
     1789*/
     1790
     1791static proc bugFromMLee()
     1792{
     1793  LIB "ncfactor.lib";
     1794  ring s = 0,(z,x),dp;
     1795  def S = nc_algebra(1,1); setring S;
     1796  poly f= -60z4x2-54z4-56zx3-59z2x-64;
     1797  option(prot); option(mem);
     1798  def l= facFirstWeyl (f);
     1799  l; // before: empty list; after fix: 1 entry, f is irreducible
     1800  poly g = 75z3x2+92z3+24;
     1801  def l= facFirstWeyl (g);
     1802  l; //before: empty list
     1803}
     1804
     1805/* very hard things from Martin Lee:
     1806// ex1, ex2
     1807ring s = 0,(z,x),Ws(-1,1);
     1808def S = nc_algebra(1,1); setring S;
     1809poly a = 10z5x4+26z4x5+47z5x2-97z4x3; //Abgebrochen nach einer Stunde; yes, it takes long
     1810def l= facFirstWeyl (a); l;
     1811kill l;
     1812poly b = -5328z8x5-5328z7x6+720z9x2+720z8x3-16976z7x4-38880z6x5-5184z7x3-5184z6x4-3774z5x5+2080z8x+5760z7x2-6144z6x3-59616z5x4+3108z3x6-4098z6x2-25704z5x3-21186z4x4+8640z6x-17916z4x3+22680z2x5+2040z5x-4848z4x2-9792z3x3+3024z2x4-10704z3x2-3519z2x3+34776zx4+12096zx3+2898x4-5040z2x+8064x3+6048x2; //Abgebrochen nach 1.5 Stunden; seems to be very complicated
     1813def l= facFirstWeyl (b); l;
     1814
     1815// ex3: there was difference in answers => fixed
     1816LIB "ncfactor.lib";
     1817ring r = 0,(x,y,z),dp;
     1818matrix D[3][3]; D[1,3]=-1;
     1819def R = nc_algebra(1,D);
     1820setring R;
     1821poly g= 7*z4*x+62*z3+26*z;
     1822def l1= facSubWeyl (g, x, z);
     1823l1;
     1824//---- other ring
     1825ring s = 0,(x,z),dp;
     1826def S = nc_algebra(1,-1); setring S;
     1827poly g= 7*z4*x+62*z3+26*z;
     1828def l2= facFirstWeyl (g);
     1829l2;
     1830map F = R,x,0,z;
     1831list l1 = F(l1);
     1832l1;
     1833//---- so the answers look different, check them!
     1834testNCfac(l2); // ok
     1835testNCfac(l1); // was not ok, but now it's been fixed!!!
     1836
     1837// selbst D und X so vertauschen dass sie erfuellt ist : ist gemacht
     1838
     1839*/
Note: See TracChangeset for help on using the changeset viewer.