source: git/libpolys/polys/PolyEnumerator.h @ 644b31

spielwiese
Last change on this file since 644b31 was dc79bd, checked in by Oleksandr Motsak <motsak@…>, 12 years ago
Major Update for Enumerators + Fixes for Algrbraic & Transcendental extensions General: chg: cleanup + documentation + additional assumes Enumerators: chg: some polish on Enumerators add: CRecursivePolyCoeffsEnumerator<ConverterPolicy> for recursive treatment of converted coeffs as Enumerators Coeffs: chg: use mpz_lcm for readability in nlClearDenominators + cleanup add: nlClear*NoPositiveLead variants should not make LC positive chg: all nlClear* are not static in order to be usable from alg / trans exts. fix: fixed a bug in ndClearContent AlgExt: add: nCoeff_is_Q_algext for checking an alg. ext. of Q add: naClear* for alg. ext. over Q NOTE: coeffs are polynomials in Q[a] - one should simply consider each of them recursively as a collection of numbers... NOTE: compute GCDs over Alg. Ext... + gcds of (int.) numbers!? NOTE: trying to be conform with older Singular: no negative leading coeff. normalization chg: Alg. Ext: use singclap_*gcd (instead of Frank's gcd-stuff) p_poly: add: p_Cleardenom_n/p_Cleardenom also clear content afterwards... chg: major and minor changes to p_Content/p_Cleardenom_n/p_Cleardenom + cleanup add: additionally trying to assure positive leading coeff. after p_Content/p_Cleardenom_n(/p_Cleardenom?) NOTE: which should not be needed as n_ClearDenominators/n_ClearContent are supposed to assure that themselves! add: more assumes to p_polys.cc NOTE: massive usage of enumerators form p_* causes problems - only doing that for Q_a()! NOTE: do -normalization over Q(x...) TransExt: add: ntClear* for trans. ext's fix: correct ntGetDenom/ntGetNumerator (thanks to pSubstPar), NOTE: no negative denominator out of ntGetNumerator/ntGetDenom! add: first inefficient ntClearContent/Q and ntClearDenominators/Q & F_p impl. NOTE: careful with the use of nlClear* ! (only over Q!) add: added ntTest to transext.cc on most in/outs + use ntInit(poly)! NOTE: trying to fix the monic-poly-gcd problem in ntClearDenominators!
  • Property mode set to 100644
File size: 6.6 KB
Line 
1// -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2/*****************************************************************************\
3 * Computer Algebra System SINGULAR   
4\*****************************************************************************/
5/** @file PolyEnumerator.h
6 *
7 * Concrete implementation of enumerators over polynomials
8 *
9 * @author Oleksandr Motsak
10 *
11 *
12 **/
13/*****************************************************************************/
14
15#ifndef POLYENUMERATOR_H
16#define POLYENUMERATOR_H
17
18// include basic definitions
19#include <coeffs/Enumerator.h>
20#include <polys/monomials/monomials.h>
21#include <reporter/reporter.h> // for assume etc.
22
23/** @class CBasePolyEnumerator
24 *
25 * Base polynomial enumerator for simple iteration over terms of polynomials.
26 *
27 * Note that the first element desn't exist directly after Reset() call.
28 *
29 * The class doesn't inherit from IAccessor and thus doesn't override Current().
30 *
31 * @sa IBaseEnumerator, @sa CPolyCoeffsEnumerator
32 */
33class CBasePolyEnumerator: public virtual IBaseEnumerator
34{
35  template <class T>
36  friend class CRecursivePolyCoeffsEnumerator;
37  private:
38    poly m_poly; ///< essentially immutable original iterable object
39   
40    static const spolyrec m_prevposition_struct; ///< tag for "-1" position
41
42  protected:
43    poly m_position; ///< current position in the iterable object
44
45  public:
46    virtual bool IsValid() const
47    {
48      // not -1 or past the end position?
49      return (m_position != NULL) && (m_position != &m_prevposition_struct);
50    }
51
52
53    /// Reset this polynomial Enumerator with a different input polynomial
54    void Reset(poly p)
55    {
56      m_poly = p;
57      m_position = const_cast<poly>(&m_prevposition_struct);
58      assume( !IsValid() ); 
59    }
60
61    /// This enumerator is an empty polynomial by default
62    CBasePolyEnumerator(poly p = NULL):
63        IBaseEnumerator(), m_poly(p), m_position(const_cast<poly>(&m_prevposition_struct))
64    {
65      assume( !IsValid() ); 
66    }
67   
68    /// Sets the position marker to the leading term.
69    virtual void Reset()
70    {
71      m_position = const_cast<poly>(&m_prevposition_struct);
72      assume( !IsValid() ); 
73    }
74
75
76    /// Advances the position to the next term of the polynomial.
77    /// returns true if the position marker was successfully advanced to the
78    /// next term which can be used;
79    /// false if the position marker has passed the end of the
80    /// polynomial.
81    virtual bool MoveNext()
82    {
83      assume( m_position != NULL );
84
85      {
86        const poly p_next = pNext(m_position);
87
88        if (p_next != NULL) // not the last term?
89        {
90          m_position = p_next;
91          assume( IsValid() );
92          return true;
93        }
94      }
95     
96      if (m_position == &m_prevposition_struct) // -1 position?
97      {
98        assume( !IsValid() );
99        m_position = m_poly;
100        return (m_position != NULL);
101      }
102
103      // else: past the end (or an empty polynomial)
104      m_position = NULL;
105      assume( !IsValid() );
106      return false;
107    }
108};
109
110
111/// This is the interface we use in coeffs.h for ClearDenominators and
112/// ClearContent.
113typedef IEnumerator<number> IPolyCoeffsEnumerator;
114
115/** @class CPolyCoeffsEnumerator
116 *
117 * This is a polynomial enumerator for simple iteration over
118 * coefficients of polynomials.
119 *
120 * It is required to inherit this class from IEnumerator<number> for
121 * its use in coeffs and implement IAccessor<number> interface.
122 *
123 * Note also the virtual multiple inheritance due to the diamond
124 * problem of inheriting both CBasePolyEnumerator and IEnumerator<T>
125 * from IBaseEnumerator.
126 *
127 * @sa CBasePolyEnumerator, @sa IEnumerator
128 */
129class CPolyCoeffsEnumerator: public CBasePolyEnumerator, public virtual IPolyCoeffsEnumerator
130{
131  public:
132    CPolyCoeffsEnumerator(poly p): CBasePolyEnumerator(p) {}
133   
134    /// Gets the current element in the collection (read and write).
135    virtual IPolyCoeffsEnumerator::reference Current()
136    {
137      assume( IsValid() );
138      return pGetCoeff(m_position);     
139    }
140
141    /// Gets the current element in the collection (read only).
142    virtual IPolyCoeffsEnumerator::const_reference Current() const
143    {
144      assume( IsValid() );
145      return pGetCoeff(m_position);
146    }
147};
148
149
150struct NAConverter
151{
152  static inline poly convert(const number& n)
153  {
154    // suitable for alg. ext. numbers that are just polys actually
155    return (poly)n;
156  }
157};
158
159/// go into polynomials over an alg. extension recursively
160template <class ConverterPolicy>
161class CRecursivePolyCoeffsEnumerator: public IPolyCoeffsEnumerator
162{
163  private:
164    IPolyCoeffsEnumerator& m_global_enumerator; ///< iterates the input polynomial
165    CBasePolyEnumerator m_local_enumerator; ///< iterates the current coeff. of m_global_enumerator
166
167  protected:
168    virtual bool IsValid() const
169    {
170      return m_global_enumerator.IsValid() &&  m_local_enumerator.IsValid();
171    }   
172   
173  public:
174   
175    /// NOTE: carefull: don't destruct the input enumerator before doing it with this one...
176    /// this also changes the original IPolyCoeffsEnumerator& itr!
177    CRecursivePolyCoeffsEnumerator(IPolyCoeffsEnumerator& itr): m_global_enumerator(itr), m_local_enumerator(NULL) {}
178
179    virtual bool MoveNext()
180    {
181      if( m_local_enumerator.MoveNext() )
182        return true;
183
184      if( !m_global_enumerator.MoveNext() ) // at the end of the main input polynomial?
185        return false;
186
187      // TODO: make the following changeable (metaprogramming: use policy?),
188      // leave the following as default option...
189      poly p = ConverterPolicy::convert(m_global_enumerator.Current()); // Assumes that these numbers are just polynomials!
190      assume( p != NULL );
191
192      // the followig actually needs CPolyCoeffsEnumerator
193      m_local_enumerator.Reset( p ); // -1 position in p :: to be skipped now!
194
195      if( m_local_enumerator.MoveNext() ) // should be true
196        return true;
197
198      assume( FALSE ); return MoveNext(); // this should not happen as p should be non-zero, but just in case...
199    }
200   
201    virtual void Reset()
202    {
203      m_global_enumerator.Reset();
204      m_local_enumerator.Reset(NULL);
205    }
206
207    /// Gets the current element in the collection (read and write).
208    virtual IPolyCoeffsEnumerator::reference Current()
209    {
210      assume( IsValid() );
211      return pGetCoeff(m_local_enumerator.m_position);
212    }
213
214    /// Gets the current element in the collection (read only).
215    virtual IPolyCoeffsEnumerator::const_reference Current() const
216    {
217      assume( IsValid() );
218      return pGetCoeff(m_local_enumerator.m_position);
219    }
220};
221
222
223#endif
224/* #ifndef POLYENUMERATOR_H */
225
226// Vi-modeline: vim: filetype=c:syntax:shiftwidth=2:tabstop=8:textwidth=0:expandtab
227
Note: See TracBrowser for help on using the repository browser.