source: git/kernel/Poly.h @ 6b4fbf7

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