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.

711 lines
23 KiB

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