source: git/libpolys/polys/PolyEnumerator.h

spielwiese
Last change on this file was aadd638, checked in by Hans Schoenemann <hannes@…>, 7 years ago
use include ".." for singular related .h, p7
  • Property mode set to 100644
File size: 6.6 KB
RevLine 
[975db18]1// -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2/*****************************************************************************\
[fea494]3 * Computer Algebra System SINGULAR
[975db18]4\*****************************************************************************/
5/** @file PolyEnumerator.h
[fea494]6 *
[975db18]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
[aadd638]19#include "coeffs/Enumerator.h"
20#include "polys/monomials/monomials.h"
21#include "reporter/reporter.h" // for assume etc.
[975db18]22
23/** @class CBasePolyEnumerator
[fea494]24 *
[9952bd]25 * Base polynomial enumerator for simple iteration over terms of polynomials.
[975db18]26 *
[9952bd]27 * Note that the first element desn't exist directly after Reset() call.
[fea494]28 *
[9952bd]29 * The class doesn't inherit from IAccessor and thus doesn't override Current().
[975db18]30 *
31 * @sa IBaseEnumerator, @sa CPolyCoeffsEnumerator
32 */
33class CBasePolyEnumerator: public virtual IBaseEnumerator
34{
[dc79bd]35  template <class T>
36  friend class CRecursivePolyCoeffsEnumerator;
[975db18]37  private:
[dc79bd]38    poly m_poly; ///< essentially immutable original iterable object
[fea494]39
[9952bd]40    static const spolyrec m_prevposition_struct; ///< tag for "-1" position
[975db18]41
42  protected:
[9952bd]43    poly m_position; ///< current position in the iterable object
44
[dc79bd]45  public:
[9952bd]46    virtual bool IsValid() const
[975db18]47    {
[9952bd]48      // not -1 or past the end position?
49      return (m_position != NULL) && (m_position != &m_prevposition_struct);
50    }
[dc79bd]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);
[fea494]58      assume( !IsValid() );
[dc79bd]59    }
60
61    /// This enumerator is an empty polynomial by default
62    CBasePolyEnumerator(poly p = NULL):
[9952bd]63        IBaseEnumerator(), m_poly(p), m_position(const_cast<poly>(&m_prevposition_struct))
64    {
[fea494]65      assume( !IsValid() );
[9952bd]66    }
[fea494]67
[975db18]68    /// Sets the position marker to the leading term.
[9952bd]69    virtual void Reset()
70    {
71      m_position = const_cast<poly>(&m_prevposition_struct);
[fea494]72      assume( !IsValid() );
[9952bd]73    }
[975db18]74
[dc79bd]75
[975db18]76    /// Advances the position to the next term of the polynomial.
77    /// returns true if the position marker was successfully advanced to the
[9952bd]78    /// next term which can be used;
[975db18]79    /// false if the position marker has passed the end of the
80    /// polynomial.
81    virtual bool MoveNext()
82    {
83      assume( m_position != NULL );
[9952bd]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      }
[fea494]95
[9952bd]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;
[975db18]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
[fea494]116 *
[975db18]117 * This is a polynomial enumerator for simple iteration over
[9952bd]118 * coefficients of polynomials.
[fea494]119 *
[975db18]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:
[dc79bd]132    CPolyCoeffsEnumerator(poly p): CBasePolyEnumerator(p) {}
[fea494]133
[975db18]134    /// Gets the current element in the collection (read and write).
135    virtual IPolyCoeffsEnumerator::reference Current()
136    {
[9952bd]137      assume( IsValid() );
[fea494]138      return pGetCoeff(m_position);
[975db18]139    }
140
141    /// Gets the current element in the collection (read only).
142    virtual IPolyCoeffsEnumerator::const_reference Current() const
143    {
[9952bd]144      assume( IsValid() );
[975db18]145      return pGetCoeff(m_position);
146    }
147};
148
[dc79bd]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();
[fea494]171    }
172
[dc79bd]173  public:
[fea494]174
[dc79bd]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    }
[fea494]200
[dc79bd]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
[fea494]223#endif
[975db18]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.