/*****************************************************************************\ * Computer Algebra System SINGULAR \*****************************************************************************/ /** @file DegreePattern.h * * This file provides a class to handle degree patterns. * * @author Martin Lee * **/ /*****************************************************************************/ #ifndef DEGREE_PATTERN_H #define DEGREE_PATTERN_H // #include "config.h" #include "cf_assert.h" #include "canonicalform.h" #include "cf_iter.h" #include "templates/ftmpl_functions.h" #include "gfops.h" /** @class DegreePattern DegreePattern.h "factory/DegreePattern.h" * * DegreePattern provides a functionality to create, intersect and refine * degree patterns. * * */ class DegreePattern { private: struct Pattern { int m_refCounter; ///< reference counter int m_length; ///< length of m_pattern int* m_pattern; ///< some array containing the degree pattern /// construct a Pattern from an int Pattern(int n): m_refCounter(1), m_length(n), m_pattern( new int[n]) {}; /// default constructor Pattern(): m_refCounter(1), m_length(0), m_pattern(NULL) {}; }* m_data; /// clear m_data void release() { ASSERT ( m_data != NULL, "non-null pointer expected"); ASSERT ( m_data->m_refCounter == 0, "ref count of 0 expected"); if( m_data->m_pattern != NULL ) delete[] m_data->m_pattern; m_data->m_pattern = NULL; delete m_data; m_data = NULL; } /// initialise a DegreePattern void init( int n ) { ASSERT ( m_data != NULL, "non-null pointer expected" ); ASSERT( m_data->m_refCounter > 0, "ref count > 0 expected" ); if( (--m_data->m_refCounter) < 1 ) release(); m_data = new Pattern(n); } /// getter /// /// @return @a getPattern returns a degree pattern inline int* getPattern() const { ASSERT( m_data != NULL, "non-null pointer expected" ); ASSERT( m_data->m_pattern != NULL, "non-null pointer expected" ); return m_data->m_pattern; } public: /// getter /// /// @return @a getLength returns the length of the degree pattern inline int getLength() const { ASSERT( m_data != NULL, "non-null pointer expected" ); return m_data->m_length; } /// operator [] /// /// @return @a operator[] returns the element at @a index inline int operator[] (const int index ///< [in] some int >= 0, < getLength() ) const { ASSERT( m_data != NULL, "non-null pointer expected" ); ASSERT( index >= 0 && index < getLength(), "bad index" ); ASSERT( getPattern() != NULL, "non-null pointer expected" ); return getPattern()[index]; } /// operator [] /// /// @return @a operator[] sets the element at @a index inline int& operator[] (const int index ///< [in] some int >= 0, < getLength() ) { ASSERT( m_data != NULL, "non-null pointer expected" ); ASSERT( index >= 0 && index < getLength(), "bad index" ); ASSERT( getPattern() != NULL, "non-null pointer expected" ); return getPattern()[index]; } /// default constructor DegreePattern(): m_data( new Pattern() ){} /// copy constructor DegreePattern (const DegreePattern& degPat ///< [in] some degree pattern ): m_data( degPat.m_data ) { ASSERT( degPat.m_data != NULL, "non-null pointer expected" ); m_data->m_refCounter++; }; /// construct a degree pattern from a list of (univariate) polys DegreePattern (const CFList& l ///< [in] some list of (univariate) polys ); /// assignment DegreePattern& operator= (const DegreePattern& degPat ///< [in] some degree ///< pattern ) { ASSERT( m_data != NULL, "non-null pointer expected" ); ASSERT( degPat.m_data != NULL, "non-null pointer expected" ); if( m_data != degPat.m_data ) { m_data = degPat.m_data; m_data->m_refCounter++; } return *this; } /// destructor ~DegreePattern () { ASSERT( m_data != NULL, "non-null pointer expected" ); if( (--m_data->m_refCounter) < 1 ) release(); } /// find an element @a x /// /// @return @a find returns the index + 1 of @a x, if @a x is an element of /// the degree pattern, 0 otherwise int find (const int x ///< [in] some int ) const { if (getLength() == 0) return 0; for (int i= 0; i < getLength(); i++) if ((*this)[i] == x) return i + 1; return 0; }; /// intersect two degree patterns void intersect (const DegreePattern& degPat ///< [in] some degree pattern ); /// Refine a degree pattern. Assumes that (*this)[0]:= @a d is the degree /// of the poly to be factored. Now for every other entry @a a there should be /// some entry @a b such that @a a+b= d. Elements which do not satisfy this /// relation are removed. void refine (); }; #endif /* DEGREE_PATTERN_H */