Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-19 08:08:33

0001 // Univariate Polynomials.
0002 
0003 #ifndef _CL_UNIVPOLY_H
0004 #define _CL_UNIVPOLY_H
0005 
0006 #include "cln/object.h"
0007 #include "cln/ring.h"
0008 #include "cln/malloc.h"
0009 #include "cln/proplist.h"
0010 #include "cln/symbol.h"
0011 #include "cln/V.h"
0012 #include "cln/io.h"
0013 
0014 namespace cln {
0015 
0016 // To protect against mixing elements of different polynomial rings, every
0017 // polynomial carries its ring in itself.
0018 
0019 class cl_heap_univpoly_ring;
0020 
0021 class cl_univpoly_ring : public cl_ring {
0022 public:
0023     // Default constructor.
0024     cl_univpoly_ring ();
0025     // Constructor. Takes a cl_heap_univpoly_ring*, increments its refcount.
0026     cl_univpoly_ring (cl_heap_univpoly_ring* r);
0027     // Private constructor. Doesn't increment the refcount.
0028     cl_univpoly_ring (cl_private_thing);
0029     // Copy constructor.
0030     cl_univpoly_ring (const cl_univpoly_ring&);
0031     // Assignment operator.
0032     cl_univpoly_ring& operator= (const cl_univpoly_ring&);
0033     // Automatic dereferencing.
0034     cl_heap_univpoly_ring* operator-> () const
0035     { return (cl_heap_univpoly_ring*)heappointer; }
0036 };
0037 // Copy constructor and assignment operator.
0038 CL_DEFINE_COPY_CONSTRUCTOR2(cl_univpoly_ring,cl_ring)
0039 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_univpoly_ring,cl_univpoly_ring)
0040 
0041 // Normal constructor for `cl_univpoly_ring'.
0042 inline cl_univpoly_ring::cl_univpoly_ring (cl_heap_univpoly_ring* r)
0043     : cl_ring ((cl_private_thing) (cl_inc_pointer_refcount((cl_heap*)r), r)) {}
0044 // Private constructor for `cl_univpoly_ring'.
0045 inline cl_univpoly_ring::cl_univpoly_ring (cl_private_thing p)
0046     : cl_ring (p) {}
0047 
0048 // Operations on univariate polynomial rings.
0049 
0050 inline bool operator== (const cl_univpoly_ring& R1, const cl_univpoly_ring& R2)
0051 { return (R1.pointer == R2.pointer); }
0052 inline bool operator!= (const cl_univpoly_ring& R1, const cl_univpoly_ring& R2)
0053 { return (R1.pointer != R2.pointer); }
0054 inline bool operator== (const cl_univpoly_ring& R1, cl_heap_univpoly_ring* R2)
0055 { return (R1.pointer == R2); }
0056 inline bool operator!= (const cl_univpoly_ring& R1, cl_heap_univpoly_ring* R2)
0057 { return (R1.pointer != R2); }
0058 
0059 // Representation of a univariate polynomial.
0060 
0061 class _cl_UP /* cf. _cl_ring_element */ {
0062 public:
0063     cl_gcpointer rep; // vector of coefficients, a cl_V_any
0064     // Default constructor.
0065     _cl_UP ();
0066 public: /* ugh */
0067     // Constructor.
0068     _cl_UP (const cl_heap_univpoly_ring* R, const cl_V_any& r) : rep (as_cl_private_thing(r)) { (void)R; }
0069     _cl_UP (const cl_univpoly_ring& R, const cl_V_any& r) : rep (as_cl_private_thing(r)) { (void)R; }
0070 public:
0071     // Conversion.
0072     CL_DEFINE_CONVERTER(_cl_ring_element)
0073 public: // Ability to place an object at a given address.
0074     void* operator new (size_t size) { return malloc_hook(size); }
0075     void* operator new (size_t size, void* ptr) { (void)size; return ptr; }
0076     void operator delete (void* ptr) { free_hook(ptr); }
0077 };
0078 
0079 class cl_UP /* cf. cl_ring_element */ : public _cl_UP {
0080 protected:
0081     cl_univpoly_ring _ring; // polynomial ring (references the base ring)
0082 public:
0083     const cl_univpoly_ring& ring () const { return _ring; }
0084 private:
0085     // Default constructor.
0086     cl_UP ();
0087 public: /* ugh */
0088     // Constructor.
0089     cl_UP (const cl_univpoly_ring& R, const cl_V_any& r)
0090         : _cl_UP (R,r), _ring (R) {}
0091     cl_UP (const cl_univpoly_ring& R, const _cl_UP& r)
0092         : _cl_UP (r), _ring (R) {}
0093 public:
0094     // Conversion.
0095     CL_DEFINE_CONVERTER(cl_ring_element)
0096     // Destructive modification.
0097     void set_coeff (uintL index, const cl_ring_element& y);
0098     void finalize();
0099     // Evaluation.
0100     const cl_ring_element operator() (const cl_ring_element& y) const;
0101     // Debugging output.
0102     void debug_print () const;
0103 public: // Ability to place an object at a given address.
0104     void* operator new (size_t size) { return malloc_hook(size); }
0105     void* operator new (size_t size, void* ptr) { (void)size; return ptr; }
0106     void operator delete (void* ptr) { free_hook(ptr); }
0107 };
0108 
0109 
0110 // Ring operations.
0111 
0112 struct _cl_univpoly_setops /* cf. _cl_ring_setops */ {
0113     // print
0114     void (* fprint) (cl_heap_univpoly_ring* R, std::ostream& stream, const _cl_UP& x);
0115     // equality
0116     // (Be careful: This is not well-defined for polynomials with
0117     // floating-point coefficients.)
0118     bool (* equal) (cl_heap_univpoly_ring* R, const _cl_UP& x, const _cl_UP& y);
0119 };
0120 struct _cl_univpoly_addops /* cf. _cl_ring_addops */ {
0121     // 0
0122     const _cl_UP (* zero) (cl_heap_univpoly_ring* R);
0123     bool (* zerop) (cl_heap_univpoly_ring* R, const _cl_UP& x);
0124     // x+y
0125     const _cl_UP (* plus) (cl_heap_univpoly_ring* R, const _cl_UP& x, const _cl_UP& y);
0126     // x-y
0127     const _cl_UP (* minus) (cl_heap_univpoly_ring* R, const _cl_UP& x, const _cl_UP& y);
0128     // -x
0129     const _cl_UP (* uminus) (cl_heap_univpoly_ring* R, const _cl_UP& x);
0130 };
0131 struct _cl_univpoly_mulops /* cf. _cl_ring_mulops */ {
0132     // 1
0133     const _cl_UP (* one) (cl_heap_univpoly_ring* R);
0134     // canonical homomorphism
0135     const _cl_UP (* canonhom) (cl_heap_univpoly_ring* R, const cl_I& x);
0136     // x*y
0137     const _cl_UP (* mul) (cl_heap_univpoly_ring* R, const _cl_UP& x, const _cl_UP& y);
0138     // x^2
0139     const _cl_UP (* square) (cl_heap_univpoly_ring* R, const _cl_UP& x);
0140     // x^y, y Integer >0
0141     const _cl_UP (* expt_pos) (cl_heap_univpoly_ring* R, const _cl_UP& x, const cl_I& y);
0142 };
0143 struct _cl_univpoly_modulops {
0144     // scalar multiplication x*y
0145     const _cl_UP (* scalmul) (cl_heap_univpoly_ring* R, const cl_ring_element& x, const _cl_UP& y);
0146 };
0147 struct _cl_univpoly_polyops {
0148     // degree
0149     sintL (* degree) (cl_heap_univpoly_ring* R, const _cl_UP& x);
0150     // low degree
0151     sintL (* ldegree) (cl_heap_univpoly_ring* R, const _cl_UP& x);
0152     // monomial
0153     const _cl_UP (* monomial) (cl_heap_univpoly_ring* R, const cl_ring_element& x, uintL e);
0154     // coefficient (0 if index>degree)
0155     const cl_ring_element (* coeff) (cl_heap_univpoly_ring* R, const _cl_UP& x, uintL index);
0156     // create new polynomial, bounded degree
0157     const _cl_UP (* create) (cl_heap_univpoly_ring* R, sintL deg);
0158     // set coefficient in new polynomial
0159     void (* set_coeff) (cl_heap_univpoly_ring* R, _cl_UP& x, uintL index, const cl_ring_element& y);
0160     // finalize polynomial
0161     void (* finalize) (cl_heap_univpoly_ring* R, _cl_UP& x);
0162     // evaluate, substitute an element of R
0163     const cl_ring_element (* eval) (cl_heap_univpoly_ring* R, const _cl_UP& x, const cl_ring_element& y);
0164 };
0165   typedef const _cl_univpoly_setops  cl_univpoly_setops;
0166   typedef const _cl_univpoly_addops  cl_univpoly_addops;
0167   typedef const _cl_univpoly_mulops  cl_univpoly_mulops;
0168   typedef const _cl_univpoly_modulops  cl_univpoly_modulops;
0169   typedef const _cl_univpoly_polyops  cl_univpoly_polyops;
0170 
0171 // Representation of a univariate polynomial ring.
0172 
0173 class cl_heap_univpoly_ring /* cf. cl_heap_ring */ : public cl_heap {
0174     SUBCLASS_cl_heap_ring()
0175 private:
0176     cl_property_list properties;
0177 protected:
0178     cl_univpoly_setops* setops;
0179     cl_univpoly_addops* addops;
0180     cl_univpoly_mulops* mulops;
0181     cl_univpoly_modulops* modulops;
0182     cl_univpoly_polyops* polyops;
0183 protected:
0184     cl_ring _basering;  // the coefficients are elements of this ring
0185 public:
0186     const cl_ring& basering () const { return _basering; }
0187 public:
0188     // Low-level operations.
0189     void _fprint (std::ostream& stream, const _cl_UP& x)
0190         { setops->fprint(this,stream,x); }
0191     bool _equal (const _cl_UP& x, const _cl_UP& y)
0192         { return setops->equal(this,x,y); }
0193     const _cl_UP _zero ()
0194         { return addops->zero(this); }
0195     bool _zerop (const _cl_UP& x)
0196         { return addops->zerop(this,x); }
0197     const _cl_UP _plus (const _cl_UP& x, const _cl_UP& y)
0198         { return addops->plus(this,x,y); }
0199     const _cl_UP _minus (const _cl_UP& x, const _cl_UP& y)
0200         { return addops->minus(this,x,y); }
0201     const _cl_UP _uminus (const _cl_UP& x)
0202         { return addops->uminus(this,x); }
0203     const _cl_UP _one ()
0204         { return mulops->one(this); }
0205     const _cl_UP _canonhom (const cl_I& x)
0206         { return mulops->canonhom(this,x); }
0207     const _cl_UP _mul (const _cl_UP& x, const _cl_UP& y)
0208         { return mulops->mul(this,x,y); }
0209     const _cl_UP _square (const _cl_UP& x)
0210         { return mulops->square(this,x); }
0211     const _cl_UP _expt_pos (const _cl_UP& x, const cl_I& y)
0212         { return mulops->expt_pos(this,x,y); }
0213     const _cl_UP _scalmul (const cl_ring_element& x, const _cl_UP& y)
0214         { return modulops->scalmul(this,x,y); }
0215     sintL _degree (const _cl_UP& x)
0216         { return polyops->degree(this,x); }
0217     sintL _ldegree (const _cl_UP& x)
0218         { return polyops->ldegree(this,x); }
0219     const _cl_UP _monomial (const cl_ring_element& x, uintL e)
0220         { return polyops->monomial(this,x,e); }
0221     const cl_ring_element _coeff (const _cl_UP& x, uintL index)
0222         { return polyops->coeff(this,x,index); }
0223     const _cl_UP _create (sintL deg)
0224         { return polyops->create(this,deg); }
0225     void _set_coeff (_cl_UP& x, uintL index, const cl_ring_element& y)
0226         { polyops->set_coeff(this,x,index,y); }
0227     void _finalize (_cl_UP& x)
0228         { polyops->finalize(this,x); }
0229     const cl_ring_element _eval (const _cl_UP& x, const cl_ring_element& y)
0230         { return polyops->eval(this,x,y); }
0231     // High-level operations.
0232     void fprint (std::ostream& stream, const cl_UP& x)
0233     {
0234         if (!(x.ring() == this)) throw runtime_exception();
0235         _fprint(stream,x);
0236     }
0237     bool equal (const cl_UP& x, const cl_UP& y)
0238     {
0239         if (!(x.ring() == this)) throw runtime_exception();
0240         if (!(y.ring() == this)) throw runtime_exception();
0241         return _equal(x,y);
0242     }
0243     const cl_UP zero ()
0244     {
0245         return cl_UP(this,_zero());
0246     }
0247     bool zerop (const cl_UP& x)
0248     {
0249         if (!(x.ring() == this)) throw runtime_exception();
0250         return _zerop(x);
0251     }
0252     const cl_UP plus (const cl_UP& x, const cl_UP& y)
0253     {
0254         if (!(x.ring() == this)) throw runtime_exception();
0255         if (!(y.ring() == this)) throw runtime_exception();
0256         return cl_UP(this,_plus(x,y));
0257     }
0258     const cl_UP minus (const cl_UP& x, const cl_UP& y)
0259     {
0260         if (!(x.ring() == this)) throw runtime_exception();
0261         if (!(y.ring() == this)) throw runtime_exception();
0262         return cl_UP(this,_minus(x,y));
0263     }
0264     const cl_UP uminus (const cl_UP& x)
0265     {
0266         if (!(x.ring() == this)) throw runtime_exception();
0267         return cl_UP(this,_uminus(x));
0268     }
0269     const cl_UP one ()
0270     {
0271         return cl_UP(this,_one());
0272     }
0273     const cl_UP canonhom (const cl_I& x)
0274     {
0275         return cl_UP(this,_canonhom(x));
0276     }
0277     const cl_UP mul (const cl_UP& x, const cl_UP& y)
0278     {
0279         if (!(x.ring() == this)) throw runtime_exception();
0280         if (!(y.ring() == this)) throw runtime_exception();
0281         return cl_UP(this,_mul(x,y));
0282     }
0283     const cl_UP square (const cl_UP& x)
0284     {
0285         if (!(x.ring() == this)) throw runtime_exception();
0286         return cl_UP(this,_square(x));
0287     }
0288     const cl_UP expt_pos (const cl_UP& x, const cl_I& y)
0289     {
0290         if (!(x.ring() == this)) throw runtime_exception();
0291         return cl_UP(this,_expt_pos(x,y));
0292     }
0293     const cl_UP scalmul (const cl_ring_element& x, const cl_UP& y)
0294     {
0295         if (!(y.ring() == this)) throw runtime_exception();
0296         return cl_UP(this,_scalmul(x,y));
0297     }
0298     sintL degree (const cl_UP& x)
0299     {
0300         if (!(x.ring() == this)) throw runtime_exception();
0301         return _degree(x);
0302     }
0303     sintL ldegree (const cl_UP& x)
0304     {
0305         if (!(x.ring() == this)) throw runtime_exception();
0306         return _ldegree(x);
0307     }
0308     const cl_UP monomial (const cl_ring_element& x, uintL e)
0309     {
0310         return cl_UP(this,_monomial(x,e));
0311     }
0312     const cl_ring_element coeff (const cl_UP& x, uintL index)
0313     {
0314         if (!(x.ring() == this)) throw runtime_exception();
0315         return _coeff(x,index);
0316     }
0317     const cl_UP create (sintL deg)
0318     {
0319         return cl_UP(this,_create(deg));
0320     }
0321     void set_coeff (cl_UP& x, uintL index, const cl_ring_element& y)
0322     {
0323         if (!(x.ring() == this)) throw runtime_exception();
0324         _set_coeff(x,index,y);
0325     }
0326     void finalize (cl_UP& x)
0327     {
0328         if (!(x.ring() == this)) throw runtime_exception();
0329         _finalize(x);
0330     }
0331     const cl_ring_element eval (const cl_UP& x, const cl_ring_element& y)
0332     {
0333         if (!(x.ring() == this)) throw runtime_exception();
0334         return _eval(x,y);
0335     }
0336     // Property operations.
0337     cl_property* get_property (const cl_symbol& key)
0338         { return properties.get_property(key); }
0339     void add_property (cl_property* new_property)
0340         { properties.add_property(new_property); }
0341 // Constructor.
0342     cl_heap_univpoly_ring (const cl_ring& r, cl_univpoly_setops*, cl_univpoly_addops*, cl_univpoly_mulops*, cl_univpoly_modulops*, cl_univpoly_polyops*);
0343     ~cl_heap_univpoly_ring () {}
0344 };
0345 #define SUBCLASS_cl_heap_univpoly_ring() \
0346   SUBCLASS_cl_heap_ring()
0347 
0348 
0349 // Lookup or create the "standard" univariate polynomial ring over a ring r.
0350 extern const cl_univpoly_ring find_univpoly_ring (const cl_ring& r);
0351 
0352 // Lookup or create a univariate polynomial ring with a named variable over r.
0353 extern const cl_univpoly_ring find_univpoly_ring (const cl_ring& r, const cl_symbol& varname);
0354 
0355 class cl_UP_init_helper
0356 {
0357     static int count;
0358 public:
0359     cl_UP_init_helper();
0360     ~cl_UP_init_helper();
0361 };
0362 static cl_UP_init_helper cl_UP_init_helper_instance;
0363 
0364 
0365 // Operations on polynomials.
0366 
0367 // Output.
0368 inline void fprint (std::ostream& stream, const cl_UP& x)
0369     { x.ring()->fprint(stream,x); }
0370 CL_DEFINE_PRINT_OPERATOR(cl_UP)
0371 
0372 // Add.
0373 inline const cl_UP operator+ (const cl_UP& x, const cl_UP& y)
0374     { return x.ring()->plus(x,y); }
0375 
0376 // Negate.
0377 inline const cl_UP operator- (const cl_UP& x)
0378     { return x.ring()->uminus(x); }
0379 
0380 // Subtract.
0381 inline const cl_UP operator- (const cl_UP& x, const cl_UP& y)
0382     { return x.ring()->minus(x,y); }
0383 
0384 // Equality.
0385 inline bool operator== (const cl_UP& x, const cl_UP& y)
0386     { return x.ring()->equal(x,y); }
0387 inline bool operator!= (const cl_UP& x, const cl_UP& y)
0388     { return !x.ring()->equal(x,y); }
0389 
0390 // Compare against 0.
0391 inline bool zerop (const cl_UP& x)
0392     { return x.ring()->zerop(x); }
0393 
0394 // Multiply.
0395 inline const cl_UP operator* (const cl_UP& x, const cl_UP& y)
0396     { return x.ring()->mul(x,y); }
0397 
0398 // Squaring.
0399 inline const cl_UP square (const cl_UP& x)
0400     { return x.ring()->square(x); }
0401 
0402 // Exponentiation x^y, where y > 0.
0403 inline const cl_UP expt_pos (const cl_UP& x, const cl_I& y)
0404     { return x.ring()->expt_pos(x,y); }
0405 
0406 // Scalar multiplication.
0407 #if 0 // less efficient
0408 inline const cl_UP operator* (const cl_I& x, const cl_UP& y)
0409     { return y.ring()->mul(y.ring()->canonhom(x),y); }
0410 inline const cl_UP operator* (const cl_UP& x, const cl_I& y)
0411     { return x.ring()->mul(x.ring()->canonhom(y),x); }
0412 #endif
0413 inline const cl_UP operator* (const cl_I& x, const cl_UP& y)
0414     { return y.ring()->scalmul(y.ring()->basering()->canonhom(x),y); }
0415 inline const cl_UP operator* (const cl_UP& x, const cl_I& y)
0416     { return x.ring()->scalmul(x.ring()->basering()->canonhom(y),x); }
0417 inline const cl_UP operator* (const cl_ring_element& x, const cl_UP& y)
0418     { return y.ring()->scalmul(x,y); }
0419 inline const cl_UP operator* (const cl_UP& x, const cl_ring_element& y)
0420     { return x.ring()->scalmul(y,x); }
0421 
0422 // Degree.
0423 inline sintL degree (const cl_UP& x)
0424     { return x.ring()->degree(x); }
0425 
0426 // Low degree.
0427 inline sintL ldegree (const cl_UP& x)
0428     { return x.ring()->ldegree(x); }
0429 
0430 // Coefficient.
0431 inline const cl_ring_element coeff (const cl_UP& x, uintL index)
0432     { return x.ring()->coeff(x,index); }
0433 
0434 // Destructive modification.
0435 inline void set_coeff (cl_UP& x, uintL index, const cl_ring_element& y)
0436     { x.ring()->set_coeff(x,index,y); }
0437 inline void finalize (cl_UP& x)
0438     { x.ring()->finalize(x); }
0439 inline void cl_UP::set_coeff (uintL index, const cl_ring_element& y)
0440     { ring()->set_coeff(*this,index,y); }
0441 inline void cl_UP::finalize ()
0442     { ring()->finalize(*this); }
0443 
0444 // Evaluation. (No extension of the base ring allowed here for now.)
0445 inline const cl_ring_element cl_UP::operator() (const cl_ring_element& y) const
0446 {
0447     return ring()->eval(*this,y);
0448 }
0449 
0450 // Derivative.
0451 extern const cl_UP deriv (const cl_UP& x);
0452 
0453 
0454 // Ring of uninitialized elements.
0455 // Any operation results in a run-time error.
0456 
0457 extern const cl_univpoly_ring cl_no_univpoly_ring;
0458 extern cl_class cl_class_no_univpoly_ring;
0459 
0460 class cl_UP_no_ring_init_helper
0461 {
0462     static int count;
0463 public:
0464     cl_UP_no_ring_init_helper();
0465     ~cl_UP_no_ring_init_helper();
0466 };
0467 static cl_UP_no_ring_init_helper cl_UP_no_ring_init_helper_instance;
0468 
0469 inline cl_univpoly_ring::cl_univpoly_ring ()
0470     : cl_ring (as_cl_private_thing(cl_no_univpoly_ring)) {}
0471 inline _cl_UP::_cl_UP ()
0472     : rep ((cl_private_thing) cl_combine(cl_FN_tag,0)) {}
0473 inline cl_UP::cl_UP ()
0474     : _cl_UP (), _ring () {}
0475 
0476 
0477 // Debugging support.
0478 #ifdef CL_DEBUG
0479 extern int cl_UP_debug_module;
0480 CL_FORCE_LINK(cl_UP_debug_dummy, cl_UP_debug_module)
0481 #endif
0482 
0483 }  // namespace cln
0484 
0485 #endif /* _CL_UNIVPOLY_H */
0486 
0487 namespace cln {
0488 
0489 // Templates for univariate polynomials of complex/real/rational/integers.
0490 
0491 #ifdef notyet
0492 // Unfortunately, this is not usable now, because of gcc-2.7 bugs:
0493 // - A template inline function is not inline in the first function that
0494 //   uses it.
0495 // - Argument matching bug: User-defined conversions are not tried (or
0496 //   tried with too low priority) for template functions w.r.t. normal
0497 //   functions. For example, a call expt_pos(cl_UP_specialized<cl_N>,int)
0498 //   is compiled as expt_pos(const cl_UP&, const cl_I&) instead of
0499 //   expt_pos(const cl_UP_specialized<cl_N>&, const cl_I&).
0500 // It will, however, be usable when gcc-2.8 is released.
0501 
0502 #if defined(_CL_UNIVPOLY_COMPLEX_H) || defined(_CL_UNIVPOLY_REAL_H) || defined(_CL_UNIVPOLY_RATIONAL_H) || defined(_CL_UNIVPOLY_INTEGER_H)
0503 #ifndef _CL_UNIVPOLY_AUX_H
0504 
0505 // Normal univariate polynomials with stricter static typing:
0506 // `class T' instead of `cl_ring_element'.
0507 
0508 template <class T> class cl_univpoly_specialized_ring;
0509 template <class T> class cl_UP_specialized;
0510 template <class T> class cl_heap_univpoly_specialized_ring;
0511 
0512 template <class T>
0513 class cl_univpoly_specialized_ring : public cl_univpoly_ring {
0514 public:
0515     // Default constructor.
0516     cl_univpoly_specialized_ring () : cl_univpoly_ring () {}
0517     // Copy constructor.
0518     cl_univpoly_specialized_ring (const cl_univpoly_specialized_ring&);
0519     // Assignment operator.
0520     cl_univpoly_specialized_ring& operator= (const cl_univpoly_specialized_ring&);
0521     // Automatic dereferencing.
0522     cl_heap_univpoly_specialized_ring<T>* operator-> () const
0523     { return (cl_heap_univpoly_specialized_ring<T>*)heappointer; }
0524 };
0525 // Copy constructor and assignment operator.
0526 template <class T>
0527 _CL_DEFINE_COPY_CONSTRUCTOR2(cl_univpoly_specialized_ring<T>,cl_univpoly_specialized_ring,cl_univpoly_ring)
0528 template <class T>
0529 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_univpoly_specialized_ring<T>,cl_univpoly_specialized_ring<T>)
0530 
0531 template <class T>
0532 class cl_UP_specialized : public cl_UP {
0533 public:
0534     const cl_univpoly_specialized_ring<T>& ring () const { return The(cl_univpoly_specialized_ring<T>)(_ring); }
0535     // Conversion.
0536     CL_DEFINE_CONVERTER(cl_ring_element)
0537     // Destructive modification.
0538     void set_coeff (uintL index, const T& y);
0539     void finalize();
0540     // Evaluation.
0541     const T operator() (const T& y) const;
0542 public: // Ability to place an object at a given address.
0543     void* operator new (size_t size) { return malloc_hook(size); }
0544     void* operator new (size_t size, void* ptr) { (void)size; return ptr; }
0545     void operator delete (void* ptr) { free_hook(ptr); }
0546 };
0547 
0548 template <class T>
0549 class cl_heap_univpoly_specialized_ring : public cl_heap_univpoly_ring {
0550     SUBCLASS_cl_heap_univpoly_ring()
0551     // High-level operations.
0552     void fprint (std::ostream& stream, const cl_UP_specialized<T>& x)
0553     {
0554         cl_heap_univpoly_ring::fprint(stream,x);
0555     }
0556     bool equal (const cl_UP_specialized<T>& x, const cl_UP_specialized<T>& y)
0557     {
0558         return cl_heap_univpoly_ring::equal(x,y);
0559     }
0560     const cl_UP_specialized<T> zero ()
0561     {
0562         return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::zero());
0563     }
0564     bool zerop (const cl_UP_specialized<T>& x)
0565     {
0566         return cl_heap_univpoly_ring::zerop(x);
0567     }
0568     const cl_UP_specialized<T> plus (const cl_UP_specialized<T>& x, const cl_UP_specialized<T>& y)
0569     {
0570         return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::plus(x,y));
0571     }
0572     const cl_UP_specialized<T> minus (const cl_UP_specialized<T>& x, const cl_UP_specialized<T>& y)
0573     {
0574         return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::minus(x,y));
0575     }
0576     const cl_UP_specialized<T> uminus (const cl_UP_specialized<T>& x)
0577     {
0578         return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::uminus(x));
0579     }
0580     const cl_UP_specialized<T> one ()
0581     {
0582         return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::one());
0583     }
0584     const cl_UP_specialized<T> canonhom (const cl_I& x)
0585     {
0586         return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::canonhom(x));
0587     }
0588     const cl_UP_specialized<T> mul (const cl_UP_specialized<T>& x, const cl_UP_specialized<T>& y)
0589     {
0590         return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::mul(x,y));
0591     }
0592     const cl_UP_specialized<T> square (const cl_UP_specialized<T>& x)
0593     {
0594         return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::square(x));
0595     }
0596     const cl_UP_specialized<T> expt_pos (const cl_UP_specialized<T>& x, const cl_I& y)
0597     {
0598         return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::expt_pos(x,y));
0599     }
0600     const cl_UP_specialized<T> scalmul (const T& x, const cl_UP_specialized<T>& y)
0601     {
0602         return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::scalmul(x,y));
0603     }
0604     sintL degree (const cl_UP_specialized<T>& x)
0605     {
0606         return cl_heap_univpoly_ring::degree(x);
0607     }
0608     sintL ldegree (const cl_UP_specialized<T>& x)
0609     {
0610         return cl_heap_univpoly_ring::ldegree(x);
0611     }
0612     const cl_UP_specialized<T> monomial (const T& x, uintL e)
0613     {
0614         return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::monomial(cl_ring_element(cl_C_ring??,x),e));
0615     }
0616     const T coeff (const cl_UP_specialized<T>& x, uintL index)
0617     {
0618         return The(T)(cl_heap_univpoly_ring::coeff(x,index));
0619     }
0620     const cl_UP_specialized<T> create (sintL deg)
0621     {
0622         return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::create(deg));
0623     }
0624     void set_coeff (cl_UP_specialized<T>& x, uintL index, const T& y)
0625     {
0626         cl_heap_univpoly_ring::set_coeff(x,index,cl_ring_element(cl_C_ring??,y));
0627     }
0628     void finalize (cl_UP_specialized<T>& x)
0629     {
0630         cl_heap_univpoly_ring::finalize(x);
0631     }
0632     const T eval (const cl_UP_specialized<T>& x, const T& y)
0633     {
0634         return The(T)(cl_heap_univpoly_ring::eval(x,cl_ring_element(cl_C_ring??,y)));
0635     }
0636 private:
0637     // No need for any constructors.
0638     cl_heap_univpoly_specialized_ring ();
0639 };
0640 
0641 // Lookup of polynomial rings.
0642 template <class T>
0643 inline const cl_univpoly_specialized_ring<T> find_univpoly_ring (const cl_specialized_number_ring<T>& r)
0644 { return The(cl_univpoly_specialized_ring<T>) (find_univpoly_ring((const cl_ring&)r)); }
0645 template <class T>
0646 inline const cl_univpoly_specialized_ring<T> find_univpoly_ring (const cl_specialized_number_ring<T>& r, const cl_symbol& varname)
0647 { return The(cl_univpoly_specialized_ring<T>) (find_univpoly_ring((const cl_ring&)r,varname)); }
0648 
0649 // Operations on polynomials.
0650 
0651 // Add.
0652 template <class T>
0653 inline const cl_UP_specialized<T> operator+ (const cl_UP_specialized<T>& x, const cl_UP_specialized<T>& y)
0654     { return x.ring()->plus(x,y); }
0655 
0656 // Negate.
0657 template <class T>
0658 inline const cl_UP_specialized<T> operator- (const cl_UP_specialized<T>& x)
0659     { return x.ring()->uminus(x); }
0660 
0661 // Subtract.
0662 template <class T>
0663 inline const cl_UP_specialized<T> operator- (const cl_UP_specialized<T>& x, const cl_UP_specialized<T>& y)
0664     { return x.ring()->minus(x,y); }
0665 
0666 // Multiply.
0667 template <class T>
0668 inline const cl_UP_specialized<T> operator* (const cl_UP_specialized<T>& x, const cl_UP_specialized<T>& y)
0669     { return x.ring()->mul(x,y); }
0670 
0671 // Squaring.
0672 template <class T>
0673 inline const cl_UP_specialized<T> square (const cl_UP_specialized<T>& x)
0674     { return x.ring()->square(x); }
0675 
0676 // Exponentiation x^y, where y > 0.
0677 template <class T>
0678 inline const cl_UP_specialized<T> expt_pos (const cl_UP_specialized<T>& x, const cl_I& y)
0679     { return x.ring()->expt_pos(x,y); }
0680 
0681 // Scalar multiplication.
0682 // Need more discrimination on T ??
0683 template <class T>
0684 inline const cl_UP_specialized<T> operator* (const cl_I& x, const cl_UP_specialized<T>& y)
0685     { return y.ring()->mul(y.ring()->canonhom(x),y); }
0686 template <class T>
0687 inline const cl_UP_specialized<T> operator* (const cl_UP_specialized<T>& x, const cl_I& y)
0688     { return x.ring()->mul(x.ring()->canonhom(y),x); }
0689 template <class T>
0690 inline const cl_UP_specialized<T> operator* (const T& x, const cl_UP_specialized<T>& y)
0691     { return y.ring()->scalmul(x,y); }
0692 template <class T>
0693 inline const cl_UP_specialized<T> operator* (const cl_UP_specialized<T>& x, const T& y)
0694     { return x.ring()->scalmul(y,x); }
0695 
0696 // Coefficient.
0697 template <class T>
0698 inline const T coeff (const cl_UP_specialized<T>& x, uintL index)
0699     { return x.ring()->coeff(x,index); }
0700 
0701 // Destructive modification.
0702 template <class T>
0703 inline void set_coeff (cl_UP_specialized<T>& x, uintL index, const T& y)
0704     { x.ring()->set_coeff(x,index,y); }
0705 template <class T>
0706 inline void finalize (cl_UP_specialized<T>& x)
0707     { x.ring()->finalize(x); }
0708 template <class T>
0709 inline void cl_UP_specialized<T>::set_coeff (uintL index, const T& y)
0710     { ring()->set_coeff(*this,index,y); }
0711 template <class T>
0712 inline void cl_UP_specialized<T>::finalize ()
0713     { ring()->finalize(*this); }
0714 
0715 // Evaluation. (No extension of the base ring allowed here for now.)
0716 template <class T>
0717 inline const T cl_UP_specialized<T>::operator() (const T& y) const
0718 {
0719     return ring()->eval(*this,y);
0720 }
0721 
0722 // Derivative.
0723 template <class T>
0724 inline const cl_UP_specialized<T> deriv (const cl_UP_specialized<T>& x)
0725     { return The(cl_UP_specialized<T>)(deriv((const cl_UP&)x)); }
0726 
0727 
0728 #endif /* _CL_UNIVPOLY_AUX_H */
0729 #endif
0730 
0731 #endif /* notyet */
0732 
0733 }  // namespace cln