source: git/kernel/old.Poly.h @ 6a9f2e

fieker-DuValspielwiese
Last change on this file since 6a9f2e was 737a68, checked in by Oleksandr Motsak <motsak@…>, 13 years ago
CHG: moved libpolys/polys/polys.h to kernel/polys.h & updated includes ADD: moved (definition of) currRing/rChangeCurrRing to kernel/polys.cc!?
  • Property mode set to 100644
File size: 14.1 KB
RevLine 
[341696]1//$Id$
[90be05]2
[3c7942]3
4
5#ifndef POLYCPP_HEADER
6#define POLYCPP_HEADER
[599326]7#include <kernel/mod2.h>
8#include <kernel/IIntvec.h>
[210e07]9#include <coeffs/numbers.h>
[599326]10#include <kernel/Number.h>
11#include <kernel/febase.h>
[737a68]12#include <kernel/polys.h>
[210e07]13#include <polys/monomials/ring.h>
[90be05]14
15
[3c7942]16#include <boost/shared_ptr.hpp>
[90be05]17
18#include <vector>
[e604cd]19#include <exception>
20using std::exception;
[90be05]21
[3c7942]22#define BOOST_DISABLE_THREADS
[90be05]23
[e604cd]24class DifferentDomainException: public exception{
25
26};
27class ExceptionBasedErrorHandler{
28    public:
29        static const bool handleErrors=true;
30        static void handleDifferentRing(ring r, ring s){
31        PrintS("throwing");
32        throw DifferentDomainException();
33    }
34};
[90be05]35
[3c7942]36//PolyImpl is a 08/15 poly wrapper
37//Poly wraps around PolyImpl with reference counting using boost
[8457864]38class TrivialErrorHandler{
39    public:
[e604cd]40    static const bool handleErrors=false;
41    static void handleDifferentRing(ring r, ring s){
[8457864]42    }
43};
[7f4d50]44typedef TrivialErrorHandler MyErrorHandler;
[3c7942]45class PolyImpl{
[8457864]46  template <poly_variant,class,class> friend class PolyBase;
47  //friend class PolyBase<POLY_VARIANT_RING,Poly,TrivialErrorHandler>;
48  //friend class PolyBase<POLY_VARIANT_MODUL,Vector, TrivialErrorHandler>;
[c1e4cd]49  //friend class PolyBase<POLY_VARIANT_MODUL>;
[4e2486]50  friend class Poly;
[82f499]51  friend class Vector;
[f28d81]52  //friend class Number;
53 protected:
54  poly getInternalReference() const{
55    return p;
56  }
[3c7942]57 public:
58  ring getRing() const{
[7f4d50]59    return r.get();
[3c7942]60  }
[d964f9]61  friend inline bool operator==(const Poly& p1, const Poly& p2);
[451a9a]62  friend inline bool operator==(const Vector& p1, const Vector& p2);
[3c7942]63  friend PolyImpl operator+(const PolyImpl& p1, const PolyImpl& n2);
64  friend PolyImpl operator-(const PolyImpl& p1, const PolyImpl& n2);
65  friend PolyImpl operator/(const PolyImpl& p1, const PolyImpl& n2);
66  friend PolyImpl operator*(const PolyImpl& p1, const PolyImpl& n2);
67  friend bool operator==(const PolyImpl& p1, const PolyImpl& n2);
68  friend PolyImpl operator+(const PolyImpl& p1, int n2);
69  friend PolyImpl operator-(const PolyImpl& p1, int n2);
70  friend PolyImpl operator/(const PolyImpl& p1, int n2);
71  friend PolyImpl operator*(const PolyImpl& p1, int n2);
72  friend bool operator==(const PolyImpl& p1, int n2);
[a9c606]73  Number leadCoef(){
[7f4d50]74    return Number(p->coef,r.get());
[a9c606]75  }
[3c7942]76  PolyImpl& operator=(const PolyImpl& p2){
77    //durch Reihenfolge Selbstzuweisungen berücksichtigt
78    if (this==&p2) return *this;
[7f4d50]79    poly pc=p_Copy(p2.p,p2.r.get());
[a171c0]80    if(r!=NULL)
[7f4d50]81      p_Delete(&p,r.get());
[3c7942]82    r=p2.r;
83    p=pc;
84    return *this;
85  }
86  PolyImpl operator-(){
87    PolyImpl t(*this);
[7f4d50]88    t.p=p_Copy(p,r.get());
89    t.p=p_Neg(t.p,r.get());
[3c7942]90    return t;
91  }
92  PolyImpl& operator+=(const PolyImpl & p2){
93    if (r!=p2.r){
94      Werror("not the same ring");
95      return *this;
96    }
97    if (this==&p2){
[7f4d50]98      number two=n_Init(2,r.get());
99      p_Mult_nn(p,two,r.get());
[3c7942]100      return *this;
101    }
[7f4d50]102    p=p_Add_q(p,p_Copy(p2.p,p2.r.get()),r.get());
[3c7942]103   
104    return *this;
105  }
106  PolyImpl& operator*=(const PolyImpl & p2){
107    if (r!=p2.r){
108      Werror("not the same ring");
109      return *this;
110    }
111    if (this==&p2){
[7f4d50]112      poly pc=p_Copy(p,r.get());
113      p=p_Mult_q(p,p2.p,r.get());
[3c7942]114      return *this;
115    }
[7f4d50]116    p=p_Mult_q(p,p_Copy(p2.p,p2.r.get()),r.get());
[3c7942]117    return *this;
118  }
[f28d81]119  PolyImpl& operator*=(const Number & n){
120    if (r!=n.r){
121      Werror("not the same ring");
122      return *this;
123    }
124   
[7f4d50]125    p=p_Mult_nn(p,n.n,r.get());
[f28d81]126    return *this;
127  }
[3c7942]128  PolyImpl& operator-=(const PolyImpl & p2){
129    if (r!=p2.r){
130      Werror("not the same ring");
131      return *this;
132    }
133    if (this==&p2){
[7f4d50]134      p_Delete(&p,r.get());
[3c7942]135      p=NULL;
136      return *this;
137    }
138
[7f4d50]139    poly pc=p_Copy(p2.p,p2.r.get());
140    pc=p_Neg(pc,r.get());
141    p=p_Add_q(p,pc,r.get());
[3c7942]142
143   
144    return *this;
145  }
146
147
148  PolyImpl& operator=(int n){
149 
[7f4d50]150    p_Delete(&p,r.get());
151    p=p_ISet(n,r.get());
[3c7942]152    return *this;
153 
154  }
155 
156
157  PolyImpl(){
158    r=currRing;
159    p=NULL;
160  }
161  PolyImpl(const PolyImpl & p){
162    r=p.r;
[7f4d50]163    this->p=p_Copy(p.p,r.get());
[3c7942]164  }
[7f4d50]165  PolyImpl(poly p, intrusive_ptr<ip_sring> r){
166    this->p=p_Copy(p,r.get());
[3c7942]167    this->r=r;
168  }
[7f4d50]169  PolyImpl(poly p, intrusive_ptr<ip_sring> r,int){
[90be05]170    this->p=p;
171    this->r=r;
172  }
[7f4d50]173  PolyImpl(int n, intrusive_ptr<ip_sring> r){
174    this->p=p_ISet(n,r.get());
[3c7942]175    this->r=r;
176  }
[49c9e43]177  PolyImpl(const Number & n){
178   
[547474]179    r=n.r.get();
[7f4d50]180    this->p=p_NSet(n_Copy(n.n,r.get()),r.get());
[49c9e43]181   
182  }
[3c7942]183  explicit PolyImpl(int n){
184    r=currRing;
[7f4d50]185    this->p=p_ISet(n,r.get());
[3c7942]186  }
187  void print(){
[7f4d50]188    p_Write(p,r.get(),r.get());
[3c7942]189  }
190
191  virtual ~PolyImpl(){
[a171c0]192    if (r!=NULL)
[7f4d50]193      p_Delete(&p,r.get());
[3c7942]194  }
195
196 protected:
197  poly p;
[7f4d50]198  intrusive_ptr<ip_sring> r;
[3c7942]199
200};
201
[c300eca]202inline PolyImpl operator+(const PolyImpl &p1, const PolyImpl& p2){
[3c7942]203  PolyImpl erg(p1);
204  erg+=p2;
205  return erg;
206}
[c300eca]207inline PolyImpl operator*(const PolyImpl &p1, const PolyImpl& p2){
[3c7942]208  PolyImpl erg(p1);
209  erg*=p2;
210  return erg;
211}
[c300eca]212inline PolyImpl operator-(const PolyImpl &p1, const PolyImpl& p2){
[3c7942]213  PolyImpl erg(p1);
214  erg-=p2;
215  return erg;
216}
[547474]217
[3c7942]218
219
[c300eca]220inline PolyImpl operator+(const PolyImpl &p1, int p2){
[3c7942]221  PolyImpl erg(p1);
[7f4d50]222  erg+=PolyImpl(p2,p1.r.get());
[3c7942]223  return erg;
224}
[c300eca]225inline PolyImpl operator*(const PolyImpl &p1, int p2){
[3c7942]226  PolyImpl erg(p1);
[7f4d50]227  erg*=PolyImpl(p2,p1.r.get());
[3c7942]228  return erg;
229}
[c300eca]230inline PolyImpl operator-(const PolyImpl &p1, int p2){
[3c7942]231  PolyImpl erg(p1);
232  erg-=PolyImpl(p2,p1.r);
233  return erg;
234}
235
[547474]236
[c300eca]237inline PolyImpl operator+(int p1, const PolyImpl& p2){
[3c7942]238  PolyImpl erg(p2);
239  return erg+=PolyImpl(p1,p2.getRing());
240}
241
[c300eca]242inline PolyImpl operator*(int p1, const PolyImpl& p2){
[3c7942]243  PolyImpl erg(p2);
244  return erg*=PolyImpl(p1,p2.getRing());
245}
[547474]246
[3c7942]247using namespace boost;
248
[90be05]249
250template<class T> class ConstTermReference{
251 private:
252  ring r;
253  poly t;
254 public:
[ef1452]255  operator T() const {
[90be05]256    return T(p_Head(t,r),r);
257  }
258  ConstTermReference(poly p, ring r){
259    this->t=p;
260    this->r=r;
261  }
[a9c606]262  bool isConstant() const{
263    return p_LmIsConstant(t,r);
264  }
[90be05]265 
266};
[6bfb0e]267
[90be05]268template<class T> class PolyInputIterator:
[e2eba5]269public std::iterator<std::input_iterator_tag,T,int, shared_ptr<const T>,ConstTermReference<T> >
[90be05]270{
271
272 
273 private:
274  poly t;
275  ring r;
276  public:
277  bool operator==(const PolyInputIterator& t2){
278    return t2.t==t;
279  }
280  bool operator!=(const PolyInputIterator& t2){
281    return t2.t!=t;
282  }
283  PolyInputIterator(poly p, ring r){
284    t=p;
285    this->r=r;
286  }
287  PolyInputIterator(const PolyInputIterator& it){
288    t=it.t;
289    r=it.r;
290  }
291  PolyInputIterator& operator++(){
292    t=t->next;
293    return *this;
294  }
295  PolyInputIterator operator++(int){
296    PolyInputIterator it(*this);
297    ++(*this);
298    return it;
299  }
300  const ConstTermReference<T> operator*(){
301    return ConstTermReference<T> (t,r);
302  }
[e2eba5]303  shared_ptr<const T> operator->(){
304    return shared_ptr<const T>(new T(p_Head(t,r),r,0));
[90be05]305  }
306
307};
[ecbe9f7]308
[8457864]309template<poly_variant variant, class create_type_input, class error_handle_traits> class PolyBase{
310 private:
311    typedef PolyBase<variant,create_type_input,error_handle_traits> ThisType;
[3c7942]312 public:
[244fa5]313  poly as_poly() const{
[7f4d50]314    return p_Copy(ptr->p,ptr->getRing());
[b6e761]315  }
[e604cd]316  template<class T> void checkIsSameRing(T& p){
317    if (error_handle_traits::handleErrors){
318                 if (p.getRing()!=this->getRing()){
319   error_handle_traits::handleDifferentRing(
320    this->getRing(),
321    p.getRing()
322   );
323        }
324    }
325  }
[c1e4cd]326  typedef create_type_input create_type;
327  typedef PolyInputIterator<create_type> iterator;
[5139d6]328  Intvec leadExp(){
329    int nvars=rVar(ptr->r);
330    Intvec res(nvars);
331    for(int i=0;i<nvars;i++){
[7f4d50]332      res[i]=p_GetExp(ptr->p,i+1,ptr->getRing());
[5139d6]333    }
334    return res;
335  } 
[3c7942]336  void copy_on_write(){
337    if (!ptr.unique()){
338      ptr.reset(new PolyImpl(*ptr));
339    }
340  }
[e2eba5]341  void print() const {
[3c7942]342    ptr->print();
343  }
[f28d81]344  //* ressource managed by Singular
[52a99a7]345  char* c_string() const{
[3c7942]346
[7f4d50]347    return p_String(ptr->p,ptr->getRing(),ptr->getRing());
[f28d81]348  }
[3c7942]349
[ecbe9f7]350  PolyBase(ring r=currRing):ptr(new PolyImpl((poly) NULL,r)){
[3c7942]351  }
[6bfb0e]352
[ecbe9f7]353  PolyBase(const char* c, ring r=currRing):ptr(new PolyImpl((poly)NULL,r)){
[f28d81]354    //p_Read takes no const so do
355    char* cp=(char*) omalloc((strlen(c)+1)*sizeof(char));
356    strcpy(cp,c);
357    p_Read(cp,ptr->p,r);
358    omfree(cp);
[49c9e43]359  }
[ecbe9f7]360  PolyBase(const PolyBase&p):ptr(p.ptr){
[49c9e43]361  }
[c1e4cd]362
[6bfb0e]363
364
365  PolyBase& operator+=(const PolyBase& p2){
[e604cd]366    checkIsSameRing(p2);
[3c7942]367    copy_on_write();
[b4e3724]368    *ptr += *p2.ptr;
369   
370    return *this;
371  }
[fd283f]372  PolyBase& operator*=(const Poly & p2);
[ecbe9f7]373  PolyBase& operator*=(Number n){
[f28d81]374    copy_on_write();
375    *ptr *=n;
376   
377    return *this;
378  }
[3c7942]379  /*  void print(){
380     StringSetS("");
381     write();
[a610ee]382     PrintS(StringAppendS(""));
[3c7942]383     }*/
[ecbe9f7]384  virtual ~PolyBase(){}
[6bfb0e]385  PolyBase(poly p, ring r):ptr(new PolyImpl(p_Copy(p,r),r)){
[90be05]386  }
[ecbe9f7]387  PolyBase(poly p, ring r,int):ptr(new PolyImpl(p,r,0)){
[90be05]388  }
[e2eba5]389  /*Poly(Poly& p){
[90be05]390    ptr=p.ptr;
[e2eba5]391    }*/
[49c9e43]392
[c1e4cd]393  PolyInputIterator<create_type> begin(){
[7f4d50]394    return PolyInputIterator<create_type>(ptr->p,ptr->getRing());
[90be05]395  }
[c1e4cd]396  PolyInputIterator<create_type> end(){
[7f4d50]397    return PolyInputIterator<create_type>(NULL, ptr->getRing());
[90be05]398  }
[a9c606]399  ring getRing() const{
[f28d81]400    return ptr->getRing();
401  }
[9ec8a1]402  int lmTotalDegree() const{
403    return pTotaldegree(ptr->p);
404  }
[a9c606]405  Number leadCoef(){
406    return ptr->leadCoef();
407  }
[3ece2b]408  create_type operator-(){
409    create_type erg(*this);
[7f4d50]410    erg*=Number(-1,ptr->getRing());
[3ece2b]411    return erg;
412  }
[3c7942]413 protected:
[9ec8a1]414 
[ecbe9f7]415  PolyBase(PolyImpl& impl):ptr(&impl){
[3c7942]416   
417  }
[f28d81]418  poly getInternalReference(){
419    return ptr->getInternalReference();
420  }
[6bfb0e]421 protected:
[9ec8a1]422
[3c7942]423  shared_ptr<PolyImpl> ptr;
[547474]424
[3c7942]425};
[6bfb0e]426
[7f4d50]427class Poly: public PolyBase<POLY_VARIANT_RING, Poly, MyErrorHandler>{
[8457864]428 private:
[7f4d50]429    typedef PolyBase<POLY_VARIANT_RING, Poly,MyErrorHandler> Base;
[9ec8a1]430  friend class Vector;
[7f4d50]431  friend class PolyBase<POLY_VARIANT_MODUL,Vector,MyErrorHandler>;
[6bfb0e]432 public:
[c1e4cd]433
[8457864]434  Poly(ring r=currRing):Base ((poly)NULL,r,0){
[6bfb0e]435  }
[8457864]436  Poly(int n, ring r=currRing):Base(*(new PolyImpl(n,r))){
[6bfb0e]437   
438  }
[8457864]439  Poly(const char* c, ring r=currRing):Base(c,r){
[6bfb0e]440
441  }
[8457864]442  Poly(const Base& p):Base(p){
[6bfb0e]443  }
444 
[8457864]445  Poly(const Number& n):Base(*(new PolyImpl(n))){
[6bfb0e]446   
[4e2486]447  }
[8457864]448  Poly(poly p, ring r):Base(p,r){
[4e2486]449   
450  }
[8457864]451  Poly(poly p, ring r, int):Base(p,r,0){
[6bfb0e]452  }
[8457864]453  Poly(const std::vector<int>& v, ring r=currRing):Base(*(new PolyImpl((poly) NULL,r))){
[6bfb0e]454    unsigned int i;
455    int s=v.size();
456    poly p=p_ISet(1,r);
457    for(i=0;i<v.size();i++){
458      pSetExp(p,i+1,v[i]);
459    }
460    pSetm(p);
461    ptr.reset(new PolyImpl(p,r));
462  }
463  /*  Poly& operator+=(const Number& n){
464  Poly p2(n);
[c1e4cd]465  ((PolyBase<POLY_VARIANT_RING, Poly>&) (*this))+=p2;
[6bfb0e]466  return *this;
467  }*/
468  Poly& operator+=(const Poly& p ){
469
[8457864]470    ((Base&)*this)+=p;
[6bfb0e]471    return *this;
472  }
[8457864]473  Poly& operator+=(const Base& p ){
[6bfb0e]474
[8457864]475    ((Base&)*this)+=p;
[6bfb0e]476    return *this;
477  }
[d964f9]478  friend inline bool operator==(const Poly& p1, const Poly& p2);
[c1e4cd]479
[82f499]480};
[7f4d50]481class Vector: public PolyBase<POLY_VARIANT_MODUL, Vector, MyErrorHandler>{
[8457864]482 private:
[7f4d50]483    typedef PolyBase<POLY_VARIANT_MODUL, Vector, MyErrorHandler> Base;
[82f499]484 public:
485
[8457864]486  Vector(ring r=currRing):Base ((poly)NULL,r,0){
[82f499]487  }
[8457864]488  Vector(int n, ring r=currRing):Base(*(new PolyImpl(n,r))){
[82f499]489   
490  }
[8457864]491  Vector(const char* c, ring r=currRing):Base(c,r){
[82f499]492
493  }
[8457864]494  Vector(const Base& p):Base(p){
[82f499]495  }
496 
[9ec8a1]497
[8457864]498  Vector(poly p, ring r):Base(p,r){
[82f499]499   
500  }
[8457864]501  Vector(poly p, ring r, int):Base(p,r,0){
[82f499]502  }
[8457864]503  Vector(std::vector<int> v, ring r=currRing):Base(*(new PolyImpl((poly) NULL,r))){
[82f499]504    unsigned int i;
505    int s=v.size();
506    poly p=p_ISet(1,r);
507    for(i=0;i<v.size();i++){
508      pSetExp(p,i+1,v[i]);
509    }
510    pSetm(p);
511    ptr.reset(new PolyImpl(p,r));
512  }
513  /*  Poly& operator+=(const Number& n){
514  Poly p2(n);
515  ((PolyBase<POLY_VARIANT_MODUL, Poly>&) (*this))+=p2;
516  return *this;
517  }*/
518  Vector& operator+=(const Vector& p ){
519
[8457864]520    ((Base&)*this)+=p;
[82f499]521    return *this;
522  }
[8457864]523  Vector& operator+=(const Base& p ){
[82f499]524
[8457864]525    ((Base&)*this)+=p;
[82f499]526    return *this;
527  }
[451a9a]528  friend inline bool operator==(const Vector& p1, const Vector& p2);
[6bfb0e]529};
[c1e4cd]530
[6bfb0e]531//typedef Poly PolyBase<POLY_VARIANT_RING>::create_type;
[c1e4cd]532/*template <poly_variant v, class c> inline PolyBase<v> operator+(const PolyBase<v,c>& p1, const PolyBase<v,c>& p2){
[3c7942]533    PolyImpl* res=new PolyImpl(*p1.ptr);
534    *res+=*p2.ptr;
[c1e4cd]535    return(PolyBase<v,c>(*res));
536    }*/
[4e2486]537/*template <poly_variant v> inline PolyBase<v> operator*(const PolyBase<v>& p1, const PolyBase<v>& p2){
[b4e3724]538    PolyImpl* res=new PolyImpl(*p1.ptr);
539    *res *= *p2.ptr;
[ecbe9f7]540    return(PolyBase<v> (*res));
[4e2486]541    }*/
[c1e4cd]542/*template <class c> inline PolyBase<POLY_VARIANT_MODUL> operator*(const PolyBase<POLY_VARIANT_MODUL>& p1, const Number& n){
[4e2486]543  PolyBase<POLY_VARIANT_MODUL> erg(p1);
544  erg*=n;
545  return erg;
[c1e4cd]546  }*/
[c300eca]547inline Poly operator*(const Poly& p, const Poly& p2){
[4e2486]548  Poly erg=p;
549  erg*=p2;
550  return erg;
[49c9e43]551}
[c300eca]552inline Vector operator*(const Number& n, const Vector& v){
[3ffba4f]553  Vector res=v;
554  res*=n;
555  return res;
556}
[096124]557
558//assumes monomials commute with numbers
[8457864]559template <poly_variant variant, class create_type, class error_traits> 
560  inline typename PolyBase<variant,create_type, error_traits>::create_type
[096124]561  operator*
562  (const Number& n, 
[8457864]563   const PolyBase<variant,create_type, class error_tratis>& p)
[096124]564{
[8457864]565  typename PolyBase<variant, create_type,error_traits>::create_type erg(p);
[096124]566  erg*=n;
567  return erg;
568}
569
[c300eca]570inline Vector operator*(const Poly& p, const Vector& v){
[9ec8a1]571  Vector res(v);
572  res*=p;
573  return res;
574}
[c300eca]575inline Poly operator+(const Poly& p1, const Number& n){
[82f499]576 Poly f(p1);
577  f+=n;
[6bfb0e]578  return f;
[82f499]579  }
[d964f9]580inline bool operator==(const Poly& p1, const Poly& p2){
581  ring r1=p1.getRing();
582  ring r2=p2.getRing();
583  if (r1!=r2) return false;
584  return p_EqualPolys(p1.ptr->p,p2.ptr->p,r1);
585}
[451a9a]586inline bool operator==(const Vector& p1, const Vector& p2){
587  ring r1=p1.getRing();
588  ring r2=p2.getRing();
589  if (r1!=r2) return false;
590  return p_EqualPolys(p1.ptr->p,p2.ptr->p,r1);
591}
[8457864]592template <poly_variant variant, class create_type,class error_traits> 
593  inline typename PolyBase<variant,create_type,error_traits>::create_type
[82f499]594  operator+
[8457864]595  (const PolyBase<variant,create_type,error_traits>& b1, 
596   const PolyBase<variant,create_type,error_traits>& b2)
[82f499]597{
[8457864]598  typename PolyBase<variant, create_type, error_traits>::create_type erg(b1);
[82f499]599  erg+=b2;
600  return erg;
[6bfb0e]601}
[c300eca]602inline Vector unitVector(int i,ring r=currRing){
[9ec8a1]603  poly p=p_ISet(1,r);
604  p_SetComp(p,i,r);
605  return Vector(p,r,0);
606}
[624179]607inline Poly operator*(const Number& n, const Poly & p){
608  Poly res=p;
609  res*=n;
610  return res;
611}
[8457864]612template <poly_variant variant, class create_type, class error_traits> 
[fd283f]613   
[8457864]614inline PolyBase<variant, create_type, error_traits>& 
615PolyBase<variant, create_type, error_traits>::operator*=(const Poly & p2){
[fd283f]616    copy_on_write();
617    *ptr *= *p2.ptr;
618   
619    return *this;
620  }
[3c7942]621#endif
Note: See TracBrowser for help on using the repository browser.