You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

713 lines
24 KiB

25 years ago
  1. // Univariate Polynomials.
  2. #ifndef _CL_UNIVPOLY_H
  3. #define _CL_UNIVPOLY_H
  4. #include "cl_object.h"
  5. #include "cl_ring.h"
  6. #include "cl_malloc.h"
  7. #include "cl_proplist.h"
  8. #include "cl_symbol.h"
  9. #include "cl_V.h"
  10. #include "cl_io.h"
  11. // To protect against mixing elements of different polynomial rings, every
  12. // polynomial carries its ring in itself.
  13. class cl_heap_univpoly_ring;
  14. class cl_univpoly_ring : public cl_ring {
  15. public:
  16. // Default constructor.
  17. cl_univpoly_ring ();
  18. // Constructor. Takes a cl_heap_univpoly_ring*, increments its refcount.
  19. cl_univpoly_ring (cl_heap_univpoly_ring* r);
  20. // Private constructor. Doesn't increment the refcount.
  21. cl_univpoly_ring (cl_private_thing);
  22. // Copy constructor.
  23. cl_univpoly_ring (const cl_univpoly_ring&);
  24. // Assignment operator.
  25. cl_univpoly_ring& operator= (const cl_univpoly_ring&);
  26. // Automatic dereferencing.
  27. cl_heap_univpoly_ring* operator-> () const
  28. { return (cl_heap_univpoly_ring*)heappointer; }
  29. };
  30. // Copy constructor and assignment operator.
  31. CL_DEFINE_COPY_CONSTRUCTOR2(cl_univpoly_ring,cl_ring)
  32. CL_DEFINE_ASSIGNMENT_OPERATOR(cl_univpoly_ring,cl_univpoly_ring)
  33. // Normal constructor for `cl_univpoly_ring'.
  34. inline cl_univpoly_ring::cl_univpoly_ring (cl_heap_univpoly_ring* r)
  35. : cl_ring ((cl_private_thing) (cl_inc_pointer_refcount((cl_heap*)r), r)) {}
  36. // Private constructor for `cl_univpoly_ring'.
  37. inline cl_univpoly_ring::cl_univpoly_ring (cl_private_thing p)
  38. : cl_ring (p) {}
  39. // Operations on univariate polynomial rings.
  40. inline bool operator== (const cl_univpoly_ring& R1, const cl_univpoly_ring& R2)
  41. { return (R1.pointer == R2.pointer); }
  42. inline bool operator!= (const cl_univpoly_ring& R1, const cl_univpoly_ring& R2)
  43. { return (R1.pointer != R2.pointer); }
  44. inline bool operator== (const cl_univpoly_ring& R1, cl_heap_univpoly_ring* R2)
  45. { return (R1.pointer == R2); }
  46. inline bool operator!= (const cl_univpoly_ring& R1, cl_heap_univpoly_ring* R2)
  47. { return (R1.pointer != R2); }
  48. // Representation of a univariate polynomial.
  49. class _cl_UP /* cf. _cl_ring_element */ {
  50. public:
  51. cl_gcpointer rep; // vector of coefficients, a cl_V_any
  52. // Default constructor.
  53. _cl_UP ();
  54. public: /* ugh */
  55. // Constructor.
  56. _cl_UP (const cl_heap_univpoly_ring* R, const cl_V_any& r) : rep (as_cl_private_thing(r)) { (void)R; }
  57. _cl_UP (const cl_univpoly_ring& R, const cl_V_any& r) : rep (as_cl_private_thing(r)) { (void)R; }
  58. public:
  59. // Conversion.
  60. CL_DEFINE_CONVERTER(_cl_ring_element)
  61. public: // Ability to place an object at a given address.
  62. void* operator new (size_t size) { return cl_malloc_hook(size); }
  63. void* operator new (size_t size, _cl_UP* ptr) { (void)size; return ptr; }
  64. void operator delete (void* ptr) { cl_free_hook(ptr); }
  65. };
  66. class cl_UP /* cf. cl_ring_element */ : public _cl_UP {
  67. protected:
  68. cl_univpoly_ring _ring; // polynomial ring (references the base ring)
  69. public:
  70. const cl_univpoly_ring& ring () const { return _ring; }
  71. private:
  72. // Default constructor.
  73. cl_UP ();
  74. public: /* ugh */
  75. // Constructor.
  76. cl_UP (const cl_univpoly_ring& R, const cl_V_any& r)
  77. : _cl_UP (R,r), _ring (R) {}
  78. cl_UP (const cl_univpoly_ring& R, const _cl_UP& r)
  79. : _cl_UP (r), _ring (R) {}
  80. public:
  81. // Conversion.
  82. CL_DEFINE_CONVERTER(cl_ring_element)
  83. // Destructive modification.
  84. void set_coeff (uintL index, const cl_ring_element& y);
  85. void finalize();
  86. // Evaluation.
  87. const cl_ring_element operator() (const cl_ring_element& y) const;
  88. // Debugging output.
  89. void debug_print () const;
  90. public: // Ability to place an object at a given address.
  91. void* operator new (size_t size) { return cl_malloc_hook(size); }
  92. void* operator new (size_t size, cl_UP* ptr) { (void)size; return ptr; }
  93. void operator delete (void* ptr) { cl_free_hook(ptr); }
  94. };
  95. // Ring operations.
  96. struct _cl_univpoly_setops /* cf. _cl_ring_setops */ {
  97. // print
  98. void (* fprint) (cl_heap_univpoly_ring* R, cl_ostream stream, const _cl_UP& x);
  99. // equality
  100. // (Be careful: This is not well-defined for polynomials with
  101. // floating-point coefficients.)
  102. cl_boolean (* equal) (cl_heap_univpoly_ring* R, const _cl_UP& x, const _cl_UP& y);
  103. };
  104. struct _cl_univpoly_addops /* cf. _cl_ring_addops */ {
  105. // 0
  106. const _cl_UP (* zero) (cl_heap_univpoly_ring* R);
  107. cl_boolean (* zerop) (cl_heap_univpoly_ring* R, const _cl_UP& x);
  108. // x+y
  109. const _cl_UP (* plus) (cl_heap_univpoly_ring* R, const _cl_UP& x, const _cl_UP& y);
  110. // x-y
  111. const _cl_UP (* minus) (cl_heap_univpoly_ring* R, const _cl_UP& x, const _cl_UP& y);
  112. // -x
  113. const _cl_UP (* uminus) (cl_heap_univpoly_ring* R, const _cl_UP& x);
  114. };
  115. struct _cl_univpoly_mulops /* cf. _cl_ring_mulops */ {
  116. // 1
  117. const _cl_UP (* one) (cl_heap_univpoly_ring* R);
  118. // canonical homomorphism
  119. const _cl_UP (* canonhom) (cl_heap_univpoly_ring* R, const cl_I& x);
  120. // x*y
  121. const _cl_UP (* mul) (cl_heap_univpoly_ring* R, const _cl_UP& x, const _cl_UP& y);
  122. // x^2
  123. const _cl_UP (* square) (cl_heap_univpoly_ring* R, const _cl_UP& x);
  124. // x^y, y Integer >0
  125. const _cl_UP (* expt_pos) (cl_heap_univpoly_ring* R, const _cl_UP& x, const cl_I& y);
  126. };
  127. struct _cl_univpoly_modulops {
  128. // scalar multiplication x*y
  129. const _cl_UP (* scalmul) (cl_heap_univpoly_ring* R, const cl_ring_element& x, const _cl_UP& y);
  130. };
  131. struct _cl_univpoly_polyops {
  132. // degree
  133. sintL (* degree) (cl_heap_univpoly_ring* R, const _cl_UP& x);
  134. // monomial
  135. const _cl_UP (* monomial) (cl_heap_univpoly_ring* R, const cl_ring_element& x, uintL e);
  136. // coefficient (0 if index>degree)
  137. const cl_ring_element (* coeff) (cl_heap_univpoly_ring* R, const _cl_UP& x, uintL index);
  138. // create new polynomial, bounded degree
  139. const _cl_UP (* create) (cl_heap_univpoly_ring* R, sintL deg);
  140. // set coefficient in new polynomial
  141. void (* set_coeff) (cl_heap_univpoly_ring* R, _cl_UP& x, uintL index, const cl_ring_element& y);
  142. // finalize polynomial
  143. void (* finalize) (cl_heap_univpoly_ring* R, _cl_UP& x);
  144. // evaluate, substitute an element of R
  145. const cl_ring_element (* eval) (cl_heap_univpoly_ring* R, const _cl_UP& x, const cl_ring_element& y);
  146. };
  147. #if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 8) // workaround two g++-2.7.0 bugs
  148. #define cl_univpoly_setops _cl_univpoly_setops
  149. #define cl_univpoly_addops _cl_univpoly_addops
  150. #define cl_univpoly_mulops _cl_univpoly_mulops
  151. #define cl_univpoly_modulops _cl_univpoly_modulops
  152. #define cl_univpoly_polyops _cl_univpoly_polyops
  153. #else
  154. typedef const _cl_univpoly_setops cl_univpoly_setops;
  155. typedef const _cl_univpoly_addops cl_univpoly_addops;
  156. typedef const _cl_univpoly_mulops cl_univpoly_mulops;
  157. typedef const _cl_univpoly_modulops cl_univpoly_modulops;
  158. typedef const _cl_univpoly_polyops cl_univpoly_polyops;
  159. #endif
  160. // Representation of a univariate polynomial ring.
  161. class cl_heap_univpoly_ring /* cf. cl_heap_ring */ : public cl_heap {
  162. SUBCLASS_cl_heap_ring()
  163. private:
  164. cl_property_list properties;
  165. protected:
  166. cl_univpoly_setops* setops;
  167. cl_univpoly_addops* addops;
  168. cl_univpoly_mulops* mulops;
  169. cl_univpoly_modulops* modulops;
  170. cl_univpoly_polyops* polyops;
  171. protected:
  172. cl_ring _basering; // the coefficients are elements of this ring
  173. public:
  174. const cl_ring& basering () const { return _basering; }
  175. public:
  176. // Low-level operations.
  177. void _fprint (cl_ostream stream, const _cl_UP& x)
  178. { setops->fprint(this,stream,x); }
  179. cl_boolean _equal (const _cl_UP& x, const _cl_UP& y)
  180. { return setops->equal(this,x,y); }
  181. const _cl_UP _zero ()
  182. { return addops->zero(this); }
  183. cl_boolean _zerop (const _cl_UP& x)
  184. { return addops->zerop(this,x); }
  185. const _cl_UP _plus (const _cl_UP& x, const _cl_UP& y)
  186. { return addops->plus(this,x,y); }
  187. const _cl_UP _minus (const _cl_UP& x, const _cl_UP& y)
  188. { return addops->minus(this,x,y); }
  189. const _cl_UP _uminus (const _cl_UP& x)
  190. { return addops->uminus(this,x); }
  191. const _cl_UP _one ()
  192. { return mulops->one(this); }
  193. const _cl_UP _canonhom (const cl_I& x)
  194. { return mulops->canonhom(this,x); }
  195. const _cl_UP _mul (const _cl_UP& x, const _cl_UP& y)
  196. { return mulops->mul(this,x,y); }
  197. const _cl_UP _square (const _cl_UP& x)
  198. { return mulops->square(this,x); }
  199. const _cl_UP _expt_pos (const _cl_UP& x, const cl_I& y)
  200. { return mulops->expt_pos(this,x,y); }
  201. const _cl_UP _scalmul (const cl_ring_element& x, const _cl_UP& y)
  202. { return modulops->scalmul(this,x,y); }
  203. sintL _degree (const _cl_UP& x)
  204. { return polyops->degree(this,x); }
  205. const _cl_UP _monomial (const cl_ring_element& x, uintL e)
  206. { return polyops->monomial(this,x,e); }
  207. const cl_ring_element _coeff (const _cl_UP& x, uintL index)
  208. { return polyops->coeff(this,x,index); }
  209. const _cl_UP _create (sintL deg)
  210. { return polyops->create(this,deg); }
  211. void _set_coeff (_cl_UP& x, uintL index, const cl_ring_element& y)
  212. { polyops->set_coeff(this,x,index,y); }
  213. void _finalize (_cl_UP& x)
  214. { polyops->finalize(this,x); }
  215. const cl_ring_element _eval (const _cl_UP& x, const cl_ring_element& y)
  216. { return polyops->eval(this,x,y); }
  217. // High-level operations.
  218. void fprint (cl_ostream stream, const cl_UP& x)
  219. {
  220. if (!(x.ring() == this)) cl_abort();
  221. _fprint(stream,x);
  222. }
  223. cl_boolean equal (const cl_UP& x, const cl_UP& y)
  224. {
  225. if (!(x.ring() == this)) cl_abort();
  226. if (!(y.ring() == this)) cl_abort();
  227. return _equal(x,y);
  228. }
  229. const cl_UP zero ()
  230. {
  231. return cl_UP(this,_zero());
  232. }
  233. cl_boolean zerop (const cl_UP& x)
  234. {
  235. if (!(x.ring() == this)) cl_abort();
  236. return _zerop(x);
  237. }
  238. const cl_UP plus (const cl_UP& x, const cl_UP& y)
  239. {
  240. if (!(x.ring() == this)) cl_abort();
  241. if (!(y.ring() == this)) cl_abort();
  242. return cl_UP(this,_plus(x,y));
  243. }
  244. const cl_UP minus (const cl_UP& x, const cl_UP& y)
  245. {
  246. if (!(x.ring() == this)) cl_abort();
  247. if (!(y.ring() == this)) cl_abort();
  248. return cl_UP(this,_minus(x,y));
  249. }
  250. const cl_UP uminus (const cl_UP& x)
  251. {
  252. if (!(x.ring() == this)) cl_abort();
  253. return cl_UP(this,_uminus(x));
  254. }
  255. const cl_UP one ()
  256. {
  257. return cl_UP(this,_one());
  258. }
  259. const cl_UP canonhom (const cl_I& x)
  260. {
  261. return cl_UP(this,_canonhom(x));
  262. }
  263. const cl_UP mul (const cl_UP& x, const cl_UP& y)
  264. {
  265. if (!(x.ring() == this)) cl_abort();
  266. if (!(y.ring() == this)) cl_abort();
  267. return cl_UP(this,_mul(x,y));
  268. }
  269. const cl_UP square (const cl_UP& x)
  270. {
  271. if (!(x.ring() == this)) cl_abort();
  272. return cl_UP(this,_square(x));
  273. }
  274. const cl_UP expt_pos (const cl_UP& x, const cl_I& y)
  275. {
  276. if (!(x.ring() == this)) cl_abort();
  277. return cl_UP(this,_expt_pos(x,y));
  278. }
  279. const cl_UP scalmul (const cl_ring_element& x, const cl_UP& y)
  280. {
  281. if (!(y.ring() == this)) cl_abort();
  282. return cl_UP(this,_scalmul(x,y));
  283. }
  284. sintL degree (const cl_UP& x)
  285. {
  286. if (!(x.ring() == this)) cl_abort();
  287. return _degree(x);
  288. }
  289. const cl_UP monomial (const cl_ring_element& x, uintL e)
  290. {
  291. return cl_UP(this,_monomial(x,e));
  292. }
  293. const cl_ring_element coeff (const cl_UP& x, uintL index)
  294. {
  295. if (!(x.ring() == this)) cl_abort();
  296. return _coeff(x,index);
  297. }
  298. const cl_UP create (sintL deg)
  299. {
  300. return cl_UP(this,_create(deg));
  301. }
  302. void set_coeff (cl_UP& x, uintL index, const cl_ring_element& y)
  303. {
  304. if (!(x.ring() == this)) cl_abort();
  305. _set_coeff(x,index,y);
  306. }
  307. void finalize (cl_UP& x)
  308. {
  309. if (!(x.ring() == this)) cl_abort();
  310. _finalize(x);
  311. }
  312. const cl_ring_element eval (const cl_UP& x, const cl_ring_element& y)
  313. {
  314. if (!(x.ring() == this)) cl_abort();
  315. return _eval(x,y);
  316. }
  317. // Property operations.
  318. cl_property* get_property (const cl_symbol& key)
  319. { return properties.get_property(key); }
  320. void add_property (cl_property* new_property)
  321. { properties.add_property(new_property); }
  322. // Constructor.
  323. cl_heap_univpoly_ring (const cl_ring& r, cl_univpoly_setops*, cl_univpoly_addops*, cl_univpoly_mulops*, cl_univpoly_modulops*, cl_univpoly_polyops*);
  324. // This class is intented to be subclassable, hence needs a virtual destructor.
  325. virtual ~cl_heap_univpoly_ring () {}
  326. private:
  327. virtual void dummy ();
  328. };
  329. #define SUBCLASS_cl_heap_univpoly_ring() \
  330. SUBCLASS_cl_heap_ring()
  331. // Lookup or create the "standard" univariate polynomial ring over a ring r.
  332. extern const cl_univpoly_ring cl_find_univpoly_ring (const cl_ring& r);
  333. //CL_REQUIRE(cl_UP_unnamed)
  334. // Lookup or create a univariate polynomial ring with a named variable over r.
  335. extern const cl_univpoly_ring cl_find_univpoly_ring (const cl_ring& r, const cl_symbol& varname);
  336. //CL_REQUIRE(cl_UP_named)
  337. CL_REQUIRE(cl_UP)
  338. // Runtime typing support.
  339. extern cl_class cl_class_univpoly_ring;
  340. // Operations on polynomials.
  341. // Output.
  342. inline void fprint (cl_ostream stream, const cl_UP& x)
  343. { x.ring()->fprint(stream,x); }
  344. CL_DEFINE_PRINT_OPERATOR(cl_UP)
  345. // Add.
  346. inline const cl_UP operator+ (const cl_UP& x, const cl_UP& y)
  347. { return x.ring()->plus(x,y); }
  348. // Negate.
  349. inline const cl_UP operator- (const cl_UP& x)
  350. { return x.ring()->uminus(x); }
  351. // Subtract.
  352. inline const cl_UP operator- (const cl_UP& x, const cl_UP& y)
  353. { return x.ring()->minus(x,y); }
  354. // Equality.
  355. inline bool operator== (const cl_UP& x, const cl_UP& y)
  356. { return x.ring()->equal(x,y); }
  357. inline bool operator!= (const cl_UP& x, const cl_UP& y)
  358. { return !x.ring()->equal(x,y); }
  359. // Compare against 0.
  360. inline cl_boolean zerop (const cl_UP& x)
  361. { return x.ring()->zerop(x); }
  362. // Multiply.
  363. inline const cl_UP operator* (const cl_UP& x, const cl_UP& y)
  364. { return x.ring()->mul(x,y); }
  365. // Squaring.
  366. inline const cl_UP square (const cl_UP& x)
  367. { return x.ring()->square(x); }
  368. // Exponentiation x^y, where y > 0.
  369. inline const cl_UP expt_pos (const cl_UP& x, const cl_I& y)
  370. { return x.ring()->expt_pos(x,y); }
  371. // Scalar multiplication.
  372. #if 0 // less efficient
  373. inline const cl_UP operator* (const cl_I& x, const cl_UP& y)
  374. { return y.ring()->mul(y.ring()->canonhom(x),y); }
  375. inline const cl_UP operator* (const cl_UP& x, const cl_I& y)
  376. { return x.ring()->mul(x.ring()->canonhom(y),x); }
  377. #endif
  378. inline const cl_UP operator* (const cl_I& x, const cl_UP& y)
  379. { return y.ring()->scalmul(y.ring()->basering()->canonhom(x),y); }
  380. inline const cl_UP operator* (const cl_UP& x, const cl_I& y)
  381. { return x.ring()->scalmul(x.ring()->basering()->canonhom(y),x); }
  382. inline const cl_UP operator* (const cl_ring_element& x, const cl_UP& y)
  383. { return y.ring()->scalmul(x,y); }
  384. inline const cl_UP operator* (const cl_UP& x, const cl_ring_element& y)
  385. { return x.ring()->scalmul(y,x); }
  386. // Degree.
  387. inline sintL degree (const cl_UP& x)
  388. { return x.ring()->degree(x); }
  389. // Coefficient.
  390. inline const cl_ring_element coeff (const cl_UP& x, uintL index)
  391. { return x.ring()->coeff(x,index); }
  392. // Destructive modification.
  393. inline void set_coeff (cl_UP& x, uintL index, const cl_ring_element& y)
  394. { x.ring()->set_coeff(x,index,y); }
  395. inline void finalize (cl_UP& x)
  396. { x.ring()->finalize(x); }
  397. inline void cl_UP::set_coeff (uintL index, const cl_ring_element& y)
  398. { ring()->set_coeff(*this,index,y); }
  399. inline void cl_UP::finalize ()
  400. { ring()->finalize(*this); }
  401. // Evaluation. (No extension of the base ring allowed here for now.)
  402. inline const cl_ring_element cl_UP::operator() (const cl_ring_element& y) const
  403. {
  404. return ring()->eval(*this,y);
  405. }
  406. // Derivative.
  407. extern const cl_UP deriv (const cl_UP& x);
  408. // Ring of uninitialized elements.
  409. // Any operation results in a run-time error.
  410. extern const cl_univpoly_ring cl_no_univpoly_ring;
  411. extern cl_class cl_class_no_univpoly_ring;
  412. CL_REQUIRE(cl_UP_no_ring)
  413. inline cl_univpoly_ring::cl_univpoly_ring ()
  414. : cl_ring (as_cl_private_thing(cl_no_univpoly_ring)) {}
  415. inline _cl_UP::_cl_UP ()
  416. : rep ((cl_private_thing) cl_combine(cl_FN_tag,0)) {}
  417. inline cl_UP::cl_UP ()
  418. : _cl_UP (), _ring () {}
  419. // Debugging support.
  420. #ifdef CL_DEBUG
  421. extern int cl_UP_debug_module;
  422. static void* const cl_UP_debug_dummy[] = { &cl_UP_debug_dummy,
  423. &cl_UP_debug_module
  424. };
  425. #endif
  426. #endif /* _CL_UNIVPOLY_H */
  427. // Templates for univariate polynomials of complex/real/rational/integers.
  428. #ifdef notyet
  429. // Unfortunately, this is not usable now, because of gcc-2.7 bugs:
  430. // - A template inline function is not inline in the first function that
  431. // uses it.
  432. // - Argument matching bug: User-defined conversions are not tried (or
  433. // tried with too low priority) for template functions w.r.t. normal
  434. // functions. For example, a call expt_pos(cl_UP_specialized<cl_N>,int)
  435. // is compiled as expt_pos(const cl_UP&, const cl_I&) instead of
  436. // expt_pos(const cl_UP_specialized<cl_N>&, const cl_I&).
  437. // It will, however, be usable when gcc-2.8 is released.
  438. #if defined(_CL_UNIVPOLY_COMPLEX_H) || defined(_CL_UNIVPOLY_REAL_H) || defined(_CL_UNIVPOLY_RATIONAL_H) || defined(_CL_UNIVPOLY_INTEGER_H)
  439. #ifndef _CL_UNIVPOLY_AUX_H
  440. // Normal univariate polynomials with stricter static typing:
  441. // `class T' instead of `cl_ring_element'.
  442. template <class T> class cl_univpoly_specialized_ring;
  443. template <class T> class cl_UP_specialized;
  444. template <class T> class cl_heap_univpoly_specialized_ring;
  445. template <class T>
  446. class cl_univpoly_specialized_ring : public cl_univpoly_ring {
  447. public:
  448. // Default constructor.
  449. cl_univpoly_specialized_ring () : cl_univpoly_ring () {}
  450. // Copy constructor.
  451. cl_univpoly_specialized_ring (const cl_univpoly_specialized_ring&);
  452. // Assignment operator.
  453. cl_univpoly_specialized_ring& operator= (const cl_univpoly_specialized_ring&);
  454. // Automatic dereferencing.
  455. cl_heap_univpoly_specialized_ring<T>* operator-> () const
  456. { return (cl_heap_univpoly_specialized_ring<T>*)heappointer; }
  457. };
  458. // Copy constructor and assignment operator.
  459. template <class T>
  460. _CL_DEFINE_COPY_CONSTRUCTOR2(cl_univpoly_specialized_ring<T>,cl_univpoly_specialized_ring,cl_univpoly_ring)
  461. template <class T>
  462. CL_DEFINE_ASSIGNMENT_OPERATOR(cl_univpoly_specialized_ring<T>,cl_univpoly_specialized_ring<T>)
  463. template <class T>
  464. class cl_UP_specialized : public cl_UP {
  465. public:
  466. const cl_univpoly_specialized_ring<T>& ring () const { return The(cl_univpoly_specialized_ring<T>)(_ring); }
  467. // Conversion.
  468. CL_DEFINE_CONVERTER(cl_ring_element)
  469. // Destructive modification.
  470. void set_coeff (uintL index, const T& y);
  471. void finalize();
  472. // Evaluation.
  473. const T operator() (const T& y) const;
  474. public: // Ability to place an object at a given address.
  475. void* operator new (size_t size) { return cl_malloc_hook(size); }
  476. void* operator new (size_t size, cl_UP_specialized<T>* ptr) { (void)size; return ptr; }
  477. void operator delete (void* ptr) { cl_free_hook(ptr); }
  478. };
  479. template <class T>
  480. class cl_heap_univpoly_specialized_ring : public cl_heap_univpoly_ring {
  481. SUBCLASS_cl_heap_univpoly_ring()
  482. // High-level operations.
  483. void fprint (cl_ostream stream, const cl_UP_specialized<T>& x)
  484. {
  485. cl_heap_univpoly_ring::fprint(stream,x);
  486. }
  487. cl_boolean equal (const cl_UP_specialized<T>& x, const cl_UP_specialized<T>& y)
  488. {
  489. return cl_heap_univpoly_ring::equal(x,y);
  490. }
  491. const cl_UP_specialized<T> zero ()
  492. {
  493. return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::zero());
  494. }
  495. cl_boolean zerop (const cl_UP_specialized<T>& x)
  496. {
  497. return cl_heap_univpoly_ring::zerop(x);
  498. }
  499. const cl_UP_specialized<T> plus (const cl_UP_specialized<T>& x, const cl_UP_specialized<T>& y)
  500. {
  501. return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::plus(x,y));
  502. }
  503. const cl_UP_specialized<T> minus (const cl_UP_specialized<T>& x, const cl_UP_specialized<T>& y)
  504. {
  505. return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::minus(x,y));
  506. }
  507. const cl_UP_specialized<T> uminus (const cl_UP_specialized<T>& x)
  508. {
  509. return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::uminus(x));
  510. }
  511. const cl_UP_specialized<T> one ()
  512. {
  513. return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::one());
  514. }
  515. const cl_UP_specialized<T> canonhom (const cl_I& x)
  516. {
  517. return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::canonhom(x));
  518. }
  519. const cl_UP_specialized<T> mul (const cl_UP_specialized<T>& x, const cl_UP_specialized<T>& y)
  520. {
  521. return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::mul(x,y));
  522. }
  523. const cl_UP_specialized<T> square (const cl_UP_specialized<T>& x)
  524. {
  525. return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::square(x));
  526. }
  527. const cl_UP_specialized<T> expt_pos (const cl_UP_specialized<T>& x, const cl_I& y)
  528. {
  529. return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::expt_pos(x,y));
  530. }
  531. const cl_UP_specialized<T> scalmul (const T& x, const cl_UP_specialized<T>& y)
  532. {
  533. return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::scalmul(x,y));
  534. }
  535. sintL degree (const cl_UP_specialized<T>& x)
  536. {
  537. return cl_heap_univpoly_ring::degree(x);
  538. }
  539. const cl_UP_specialized<T> monomial (const T& x, uintL e)
  540. {
  541. return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::monomial(cl_ring_element(cl_C_ring??,x),e));
  542. }
  543. const T coeff (const cl_UP_specialized<T>& x, uintL index)
  544. {
  545. return The(T)(cl_heap_univpoly_ring::coeff(x,index));
  546. }
  547. const cl_UP_specialized<T> create (sintL deg)
  548. {
  549. return The2(cl_UP_specialized<T>)(cl_heap_univpoly_ring::create(deg));
  550. }
  551. void set_coeff (cl_UP_specialized<T>& x, uintL index, const T& y)
  552. {
  553. cl_heap_univpoly_ring::set_coeff(x,index,cl_ring_element(cl_C_ring??,y));
  554. }
  555. void finalize (cl_UP_specialized<T>& x)
  556. {
  557. cl_heap_univpoly_ring::finalize(x);
  558. }
  559. const T eval (const cl_UP_specialized<T>& x, const T& y)
  560. {
  561. return The(T)(cl_heap_univpoly_ring::eval(x,cl_ring_element(cl_C_ring??,y)));
  562. }
  563. private:
  564. // No need for any constructors.
  565. cl_heap_univpoly_specialized_ring ();
  566. };
  567. // Lookup of polynomial rings.
  568. template <class T>
  569. inline const cl_univpoly_specialized_ring<T> cl_find_univpoly_ring (const cl_specialized_number_ring<T>& r)
  570. { return The(cl_univpoly_specialized_ring<T>) (cl_find_univpoly_ring((const cl_ring&)r)); }
  571. template <class T>
  572. inline const cl_univpoly_specialized_ring<T> cl_find_univpoly_ring (const cl_specialized_number_ring<T>& r, const cl_symbol& varname)
  573. { return The(cl_univpoly_specialized_ring<T>) (cl_find_univpoly_ring((const cl_ring&)r,varname)); }
  574. // Operations on polynomials.
  575. // Add.
  576. template <class T>
  577. inline const cl_UP_specialized<T> operator+ (const cl_UP_specialized<T>& x, const cl_UP_specialized<T>& y)
  578. { return x.ring()->plus(x,y); }
  579. // Negate.
  580. template <class T>
  581. inline const cl_UP_specialized<T> operator- (const cl_UP_specialized<T>& x)
  582. { return x.ring()->uminus(x); }
  583. // Subtract.
  584. template <class T>
  585. inline const cl_UP_specialized<T> operator- (const cl_UP_specialized<T>& x, const cl_UP_specialized<T>& y)
  586. { return x.ring()->minus(x,y); }
  587. // Multiply.
  588. template <class T>
  589. inline const cl_UP_specialized<T> operator* (const cl_UP_specialized<T>& x, const cl_UP_specialized<T>& y)
  590. { return x.ring()->mul(x,y); }
  591. // Squaring.
  592. template <class T>
  593. inline const cl_UP_specialized<T> square (const cl_UP_specialized<T>& x)
  594. { return x.ring()->square(x); }
  595. // Exponentiation x^y, where y > 0.
  596. template <class T>
  597. inline const cl_UP_specialized<T> expt_pos (const cl_UP_specialized<T>& x, const cl_I& y)
  598. { return x.ring()->expt_pos(x,y); }
  599. // Scalar multiplication.
  600. // Need more discrimination on T ??
  601. template <class T>
  602. inline const cl_UP_specialized<T> operator* (const cl_I& x, const cl_UP_specialized<T>& y)
  603. { return y.ring()->mul(y.ring()->canonhom(x),y); }
  604. template <class T>
  605. inline const cl_UP_specialized<T> operator* (const cl_UP_specialized<T>& x, const cl_I& y)
  606. { return x.ring()->mul(x.ring()->canonhom(y),x); }
  607. template <class T>
  608. inline const cl_UP_specialized<T> operator* (const T& x, const cl_UP_specialized<T>& y)
  609. { return y.ring()->scalmul(x,y); }
  610. template <class T>
  611. inline const cl_UP_specialized<T> operator* (const cl_UP_specialized<T>& x, const T& y)
  612. { return x.ring()->scalmul(y,x); }
  613. // Coefficient.
  614. template <class T>
  615. inline const T coeff (const cl_UP_specialized<T>& x, uintL index)
  616. { return x.ring()->coeff(x,index); }
  617. // Destructive modification.
  618. template <class T>
  619. inline void set_coeff (cl_UP_specialized<T>& x, uintL index, const T& y)
  620. { x.ring()->set_coeff(x,index,y); }
  621. template <class T>
  622. inline void finalize (cl_UP_specialized<T>& x)
  623. { x.ring()->finalize(x); }
  624. template <class T>
  625. inline void cl_UP_specialized<T>::set_coeff (uintL index, const T& y)
  626. { ring()->set_coeff(*this,index,y); }
  627. template <class T>
  628. inline void cl_UP_specialized<T>::finalize ()
  629. { ring()->finalize(*this); }
  630. // Evaluation. (No extension of the base ring allowed here for now.)
  631. template <class T>
  632. inline const T cl_UP_specialized<T>::operator() (const T& y) const
  633. {
  634. return ring()->eval(*this,y);
  635. }
  636. // Derivative.
  637. template <class T>
  638. inline const cl_UP_specialized<T> deriv (const cl_UP_specialized<T>& x)
  639. { return The(cl_UP_specialized<T>)(deriv((const cl_UP&)x)); }
  640. #endif /* _CL_UNIVPOLY_AUX_H */
  641. #endif
  642. #endif