source: git/kernel/polys.cc @ 18296c

fieker-DuValspielwiese
Last change on this file since 18296c was ea9bd5, checked in by Hans Schoenemann <hannes@…>, 5 years ago
add: p_DivRem
  • Property mode set to 100644
File size: 7.9 KB
Line 
1#include "kernel/mod2.h"
2
3#include "misc/options.h"
4
5#include "polys.h"
6#include "kernel/ideals.h"
7#include "kernel/ideals.h"
8#include "polys/clapsing.h"
9#include "polys/clapconv.h"
10
11/// Widely used global variable which specifies the current polynomial ring for Singular interpreter and legacy implementatins.
12/// @Note: one should avoid using it in newer designs, for example due to possible problems in parallelization with threads.
13VAR ring  currRing = NULL;
14
15void rChangeCurrRing(ring r)
16{
17  //------------ set global ring vars --------------------------------
18  currRing = r;
19  if( r != NULL )
20  {
21    rTest(r);
22    //------------ global variables related to coefficients ------------
23    assume( r->cf!= NULL );
24    nSetChar(r->cf);
25    //------------ global variables related to polys
26    p_SetGlobals(r); // also setting TEST_RINGDEP_OPTS
27    //------------ global variables related to factory -----------------
28  }
29}
30
31poly p_Divide(poly p, poly q, const ring r)
32{
33  assume(q!=NULL);
34  if (q==NULL)
35  {
36    WerrorS("div. by 0");
37    return NULL;
38  }
39  if (p==NULL)
40  {
41    p_Delete(&q,r);
42    return NULL;
43  }
44  if (pNext(q)!=NULL)
45  { /* This means that q != 0 consists of at least two terms*/
46    if (rIsLPRing(r))
47    {
48      WerrorS("not implemented for letterplace rings");
49      return NULL;
50    }
51    if(p_GetComp(p,r)==0)
52    {
53      if((rFieldType(r)==n_transExt)
54      &&(convSingTrP(p,r))
55      &&(convSingTrP(q,r)))
56      {
57        poly res=singclap_pdivide(p, q, r);
58        p_Delete(&p,r);
59        p_Delete(&q,r);
60        return res;
61      }
62      else if ((r->cf->convSingNFactoryN!=ndConvSingNFactoryN)
63      &&(!rField_is_Ring(r)))
64      {
65        poly res=singclap_pdivide(p, q, r);
66        p_Delete(&p,r);
67        p_Delete(&q,r);
68        return res;
69      }
70      else
71      {
72        ideal vi=idInit(1,1); vi->m[0]=q;
73        ideal ui=idInit(1,1); ui->m[0]=p;
74        ideal R; matrix U;
75        ring save_ring=currRing;
76        if (r!=currRing) rChangeCurrRing(r);
77        int save_opt;
78        SI_SAVE_OPT1(save_opt);
79        si_opt_1 &= ~(Sy_bit(OPT_PROT));
80        ideal m = idLift(vi,ui,&R, FALSE,TRUE,TRUE,&U);
81        SI_RESTORE_OPT1(save_opt);
82        if (r!=save_ring) rChangeCurrRing(save_ring);
83        matrix T = id_Module2formatedMatrix(m,1,1,r);
84        p=MATELEM(T,1,1); MATELEM(T,1,1)=NULL;
85        id_Delete((ideal *)&T,r);
86        id_Delete((ideal *)&U,r);
87        id_Delete(&R,r);
88        //vi->m[0]=NULL; ui->m[0]=NULL;
89        id_Delete(&vi,r);
90        id_Delete(&ui,r);
91        return p;
92      }
93    }
94    else
95    {
96      int comps=p_MaxComp(p,r);
97      ideal I=idInit(comps,1);
98      poly h;
99      int i;
100      // conversion to a list of polys:
101      while (p!=NULL)
102      {
103        i=p_GetComp(p,r)-1;
104        h=pNext(p);
105        pNext(p)=NULL;
106        p_SetComp(p,0,r);
107        I->m[i]=p_Add_q(I->m[i],p,r);
108        p=h;
109      }
110      // division and conversion to vector:
111      h=NULL;
112      p=NULL;
113      for(i=comps-1;i>=0;i--)
114      {
115        if (I->m[i]!=NULL)
116        {
117          if((rFieldType(r)==n_transExt)
118          &&(convSingTrP(I->m[i],r))
119          &&(convSingTrP(q,r)))
120          {
121            h=singclap_pdivide(I->m[i],q,r);
122          }
123          else if ((r->cf->convSingNFactoryN!=ndConvSingNFactoryN)
124          &&(!rField_is_Ring(r)))
125            h=singclap_pdivide(I->m[i],q,r);
126          else
127          {
128            ideal vi=idInit(1,1); vi->m[0]=q;
129            ideal ui=idInit(1,1); ui->m[0]=I->m[i];
130            ideal R; matrix U;
131            ring save_ring=currRing;
132            if (r!=currRing) rChangeCurrRing(r);
133            int save_opt;
134            SI_SAVE_OPT1(save_opt);
135            si_opt_1 &= ~(Sy_bit(OPT_PROT));
136            ideal m = idLift(vi,ui,&R, FALSE,TRUE,TRUE,&U);
137            SI_RESTORE_OPT1(save_opt);
138            if (r!=save_ring) rChangeCurrRing(save_ring);
139            if (idIs0(R))
140            {
141              matrix T = id_Module2formatedMatrix(m,1,1,r);
142              p=MATELEM(T,1,1); MATELEM(T,1,1)=NULL;
143              id_Delete((ideal *)&T,r);
144            }
145            else p=NULL;
146            id_Delete((ideal*)&U,r);
147            id_Delete(&R,r);
148            vi->m[0]=NULL; ui->m[0]=NULL;
149            id_Delete(&vi,r);
150            id_Delete(&ui,r);
151          }
152          p_SetCompP(h,i+1,r);
153          p=p_Add_q(p,h,r);
154        }
155      }
156      id_Delete(&I,r);
157      p_Delete(&q,r);
158      return p;
159    }
160  }
161  else
162  { /* This means that q != 0 consists of just one term,
163       or that r is over a coefficient ring. */
164#ifdef HAVE_RINGS
165    if (!rField_is_Domain(r))
166    {
167      WerrorS("division only defined over coefficient domains");
168      return NULL;
169    }
170    if (pNext(q)!=NULL)
171    {
172      WerrorS("division over a coefficient domain only implemented for terms");
173      return NULL;
174    }
175#endif
176    return p_DivideM(p,q,r);
177  }
178  return NULL;
179}
180
181poly p_DivRem(poly p, poly q, poly &rest, const ring r)
182{
183  assume(q!=NULL);
184  rest=NULL;
185  if (q==NULL)
186  {
187    WerrorS("div. by 0");
188    return NULL;
189  }
190  if (p==NULL)
191  {
192    p_Delete(&q,r);
193    return NULL;
194  }
195  if (rIsLPRing(r))
196  {
197    WerrorS("not implemented for letterplace rings");
198    return NULL;
199  }
200  if(p_GetComp(p,r)==0)
201  {
202    if((rFieldType(r)==n_transExt)
203    &&(convSingTrP(p,r))
204    &&(convSingTrP(q,r)))
205    {
206      poly res=singclap_pdivide(p, q, r);
207      rest=singclap_pmod(p,q,r);
208      p_Delete(&p,r);
209      p_Delete(&q,r);
210      return res;
211    }
212    else if ((r->cf->convSingNFactoryN!=ndConvSingNFactoryN)
213    &&(!rField_is_Ring(r)))
214    {
215      poly res=singclap_pdivide(p, q, r);
216      rest=singclap_pmod(p,q,r);
217      p_Delete(&p,r);
218      p_Delete(&q,r);
219      return res;
220    }
221    else
222    {
223      ideal vi=idInit(1,1); vi->m[0]=q;
224      ideal ui=idInit(1,1); ui->m[0]=p;
225      ideal R; matrix U;
226      ring save_ring=currRing;
227      if (r!=currRing) rChangeCurrRing(r);
228      int save_opt;
229      SI_SAVE_OPT1(save_opt);
230      si_opt_1 &= ~(Sy_bit(OPT_PROT));
231      ideal m = idLift(vi,ui,&R, FALSE,TRUE,TRUE,&U);
232      SI_RESTORE_OPT1(save_opt);
233      if (r!=save_ring) rChangeCurrRing(save_ring);
234      matrix T = id_Module2formatedMatrix(m,1,1,r);
235      p=MATELEM(T,1,1); MATELEM(T,1,1)=NULL;
236      id_Delete((ideal *)&T,r);
237      T = id_Module2formatedMatrix(R,1,1,r);
238      rest=MATELEM(T,1,1); MATELEM(T,1,1)=NULL;
239      id_Delete((ideal *)&T,r);
240      id_Delete((ideal *)&U,r);
241      id_Delete(&R,r);
242      //vi->m[0]=NULL; ui->m[0]=NULL;
243      id_Delete(&vi,r);
244      id_Delete(&ui,r);
245      return p;
246    }
247  }
248  return NULL;
249}
250
251poly singclap_gcd ( poly f, poly g, const ring r )
252{
253  poly res=NULL;
254
255  if (f!=NULL)
256  {
257    //if (r->cf->has_simple_Inverse) p_Norm(f,r);
258    if (rField_is_Zp(r)) p_Norm(f,r);
259    else                 p_Cleardenom(f, r);
260  }
261  if (g!=NULL)
262  {
263    //if (r->cf->has_simple_Inverse) p_Norm(g,r);
264    if (rField_is_Zp(r)) p_Norm(g,r);
265    else                 p_Cleardenom(g, r);
266  }
267  else         return f; // g==0 => gcd=f (but do a p_Cleardenom/pNorm)
268  if (f==NULL) return g; // f==0 => gcd=g (but do a p_Cleardenom/pNorm)
269  if(!rField_is_Ring(r)
270  && (p_IsConstant(f,r)
271  ||p_IsConstant(g,r)))
272  {
273    res=p_One(r);
274  }
275  else if (r->cf->convSingNFactoryN!=ndConvSingNFactoryN)
276  {
277    res=singclap_gcd_r(f,g,r);
278  }
279  else
280  {
281    ideal I=idInit(2,1);
282    I->m[0]=f;
283    I->m[1]=p_Copy(g,r);
284    intvec *w=NULL;
285    ring save_ring=currRing;
286    if (r!=currRing) rChangeCurrRing(r);
287    int save_opt;
288    SI_SAVE_OPT1(save_opt);
289    si_opt_1 &= ~(Sy_bit(OPT_PROT));
290    ideal S1=idSyzygies(I,testHomog,&w);
291    if (w!=NULL) delete w;
292    // expect S1->m[0]=(-g/gcd,f/gcd)
293    if (IDELEMS(S1)!=1) WarnS("error in syzygy computation for GCD");
294    int lp;
295    p_TakeOutComp(&S1->m[0],1,&res,&lp,r);
296    p_Delete(&S1->m[0],r);
297    // GCD is g divided iby (-g/gcd):
298    res=p_Divide(g,res,r);
299    // restore, r, opt:
300    SI_RESTORE_OPT1(save_opt);
301    if (r!=save_ring) rChangeCurrRing(save_ring);
302    // clean the result
303    res=p_Cleardenom(res,r);
304    p_Content(res,r);
305    return res;
306  }
307  p_Delete(&f, r);
308  p_Delete(&g, r);
309  return res;
310}
Note: See TracBrowser for help on using the repository browser.