

#if defined(HAVE_MAC_DIRS) || defined(__MWERKS__)
#include <LiDIA:base_dense_power_serie.h>

#else
#include <LiDIA/base_dense_power_serie.h>
#endif


  //
  // ***** constructors / destructor
  //

  template < class T >
  base_dense_power_serie< T >::
  base_dense_power_serie ()
   {
      debug_handler ( "base_dense_power_serie< T >",
		      "base_dense_power_serie()" ) ;

      coeff = new math_vector< T > ;
      max_num_coeff = 0 ;
   }


  template < class T >
  base_dense_power_serie< T >::
  base_dense_power_serie ( const T & elem, lidia_size_t l )
   {
      debug_handler ( "base_dense_power_serie< T >",
		      "base_dense_power_serie(const T&,lidia_size_t)" ) ;

      T   zero_elem ;
      lidia_size_t i, prec  ;

      max_num_coeff = 0 ;
      zero_elem.assign_zero () ;

      if ( l < 0 || elem == zero_elem )
       {
          first = l ;
          last  = l ;
          coeff = new math_vector< T > ;
          coeff->set_capacity ( 1 ) ;
          (*coeff)[0] = zero_elem ;
       }
      else
       {
          prec  =  l+1 ;
          first = 0 ;
          last  = l ;
          coeff = new math_vector< T > ;
          coeff->set_capacity ( prec ) ;
          (*coeff)[0] = elem ;

          for ( i = 1 ; i < prec ; i++ )
               (*coeff)[i] = zero_elem ;
       }
   }


  template < class T >
  base_dense_power_serie< T >::
  base_dense_power_serie ( const base_vector< T > & c, lidia_size_t f )
   {
      debug_handler ( "base_dense_power_serie< T >",
		      "base_dense_power_serie(const base_vector< T >&,lidia_size_t)" ) ;

      coeff = new math_vector< T > ;      
      max_num_coeff = 0 ;

      lidia_size_t prec, start ;
      lidia_size_t i ;
      T zero_T ;

      zero_T.assign_zero () ;
      prec   = c.size() ;
      start  = prec ;


      // find index of the first non-zero element in c

      for ( i = 0 ; i < prec && start == prec ; i ++ )
       {
	   if ( c[i] != zero_T )
	       start = i ;
       }
      

      // all elements are zero

      if ( start == prec )
       {
	  assign_zero ( f + prec - 1 ) ;
       }

      // a non-zero element was found

      else
       {
	  coeff->set_capacity ( prec - start ) ;
	  first = f + start ;
	  last  = f + prec - 1 ;

	  for ( i = start ; i < prec ; i++ )
	   {
	       (*coeff)[i-start] = c[i] ;
	   }
       }
   }


  template < class T >
  base_dense_power_serie< T >::
  base_dense_power_serie ( const base_dense_power_serie< T > & a )
   {
      debug_handler ( "base_dense_power_serie< T >", 
		      "base_dense_power_serie(const base_dense_power_serie< T >&)" ) ;

      lidia_size_t non_zero_index ;

      coeff = new math_vector< T > ;
      max_num_coeff = a.max_num_coeff ;

      if ( a.is_zero (non_zero_index) )
       {
	  assign_zero ( a.last ) ;
       }
      else 
       {
	  first = a.first + non_zero_index ;
	  last	= a.last ;

	  coeff->set_capacity ( (a.coeff)->size() - non_zero_index ) ;
	  coeff->assign ( 0, *(a.coeff), non_zero_index, (a.coeff)->size()-1 ) ;
       }
   }


  template < class T >
  base_dense_power_serie< T >::
  ~base_dense_power_serie ()
   {
      debug_handler ( "base_dense_power_serie< T >",
		      "~base_dense_power_serie()" ) ;

      coeff->kill() ;
      delete coeff  ;
   }



  //
  // ***** utility routines *****
  //

  template < class T >
  bool
  base_dense_power_serie< T >::
  is_zero ( lidia_size_t & non_zero_index ) const
   {
      debug_handler ( "base_dense_power_serie< T >", "is_zero()" ) ;
      lidia_size_t i, prec ;
      bool rc ;

      if ( coeff->size() == 0 )
          lidia_error_handler ( "base_dense_power_serie< T >::is_zero()",
                           "Serie is not initialized.") ;

      non_zero_index = -1 ;
      prec = coeff->size () ;

      for ( i = 0 ; i < prec && non_zero_index == -1 ; i++ )
       {
	  if ( ! ((*coeff)[i].is_zero()) )
	    non_zero_index = i ;
       }

      if ( non_zero_index == -1 )
          rc = true ;
      else
          rc = false ;

      return (rc) ;
   }

  template < class T >
  bool
  base_dense_power_serie< T >::
  is_zero () const
   {
      debug_handler ( "base_dense_power_serie< T >", "is_zero()" ) ;
      lidia_size_t i, prec ;
      lidia_size_t non_zero_index ;
      bool rc ;

      if ( coeff->size() == 0 )
          lidia_error_handler ( "base_dense_power_serie< T >::is_zero()",
                           "Serie is not initialized.") ;

      non_zero_index = -1 ;
      prec = coeff->size () ;

      for ( i = 0 ; i < prec && non_zero_index == -1 ; i++ )
       {
	  if ( ! (*coeff)[i].is_zero() )
	    non_zero_index = i ;
       }

      if ( non_zero_index == -1 )
          rc = true ;
      else
          rc = false ;

      return (rc) ;
   }



  template < class T >
  bool
  base_dense_power_serie< T >::
  is_one ()
   {
      debug_handler ( "base_dense_power_serie< T >", "is_one()" ) ;
      lidia_size_t i, prec ;
      lidia_size_t non_zero_index ;
      bool rc ;

      if ( coeff->size() == 0 )
          lidia_error_handler ( "base_dense_power_serie< T >::is_one()",
			        "Serie is not initialized.") ;

      if ( last < 0 )
          rc = false ;
      else if ( ! (*coeff)[0].is_one () )
          rc = false ;
      else
       {
	  non_zero_index = -1 ;
	  prec = coeff->size () ;

	  for ( i = 1 ; i < prec && non_zero_index == -1 ; i++ )
	   {
	      if ( ! (*coeff)[i].is_zero() )
	          non_zero_index = i ;
	   }

	  if ( non_zero_index == -1 )
              rc = true ;
	  else
              rc = false ;
       }

      return (rc) ;
   }



 
  /* The function allocate() controls the memory-allocation for coeff.
     The calling function demands cp coefficients to be allocated at least.
     If the user has defined an upper bound (max_num_coeff) for the
     number of allocated coefficients and cp exceeds this bound, exactly
     cp elements will be allocated. Otherwise the function tries
     to allocate n_cp = max(2*old-capacity,cp) elements. If this value
     is greater than max_num_coeff, max_num_coeff coefficients will be
     allocated.
     Although this function controls the memory allocation for coeff,
     it is sometimes necessary to allocate memory for a math_vector *c
     with *c = *coeff; this is the reason for the existence of argument c
     (see function set_coeff(,,)).     
  */
     
  template < class T >
  void
  base_dense_power_serie< T >::
  allocate ( lidia_size_t cp, math_vector< T > * c )
   {
      debug_handler ( "base_dense_power_serie< T >", "allocate(lidia_size_t,math_vector< T >*)" ) ;

      lidia_size_t n_cp = c->capacity() ;

      if ( cp > n_cp )
       {
	  n_cp = (n_cp<<1) ;

	  if ( cp > n_cp ) 
	      n_cp = cp ;

	  if ( max_num_coeff != 0 )
           {       
              if ( cp > max_num_coeff )
	       {
	          warning_handler ( "base_dense_power_serie< T >::allocate(lidia_size_t,math_vector< T >*",
	                            "Number of allocated coefficients exceeds user-defined upper bound." ) ;
		  n_cp = cp ;
	       }
	      else
	       {
		 if ( n_cp > max_num_coeff ) 
		     n_cp = max_num_coeff ;
	       }
	   }

	  c->set_capacity ( n_cp );
       }
   }

     
  template < class T >
  lidia_size_t 
  base_dense_power_serie< T >::
  get_first ( void ) const
   {
      debug_handler ( "base_dense_power_serie< T >", "get_first" ) ;

      lidia_size_t non_zero_index ;

      if ( is_zero (non_zero_index) )
          return last ;
      else
        return first + non_zero_index ;
   }

  
  template < class T >
  lidia_size_t
  base_dense_power_serie< T >::
  get_last  ( void ) const
   {
      debug_handler ( "base_dense_power_serie< T >", "get_last"  ) ;

      if ( coeff->size() == 0 )
          lidia_error_handler ( "base_dense_power_serie< T >::get_last()",
                           "Serie is not initialized.") ;
      return last ;
   }


  template < class T >
  void
  base_dense_power_serie< T >::
  reduce_last ( lidia_size_t l )
   {
      debug_handler ( "base_dense_power_serie< T >", "reduce_last(lidia_size_t)" ) ;

      if ( coeff->size() == 0 )
       {
          warning_handler ( "base_dense_power_serie< T >::reduce_last(lidia_size_t)",
                            "Serie is not initialized, setting failed.") ;
       }
      else if ( l > last )
       {
          lidia_error_handler ( "base_dense_power_serie< T >::reduce_last(lidia_size_t)",
                          "New value of last is too big, setting failed.") ;
       }
      else
       {
          if ( l >= first )
           {
              last = l ;
              coeff->set_size ( (last-first+1) ) ;
           }
          else
           {
              assign_zero ( l ) ;
           }
       }
   }




  //
  // ***** coefficient handling *****
  //

  template < class T >
  void
  base_dense_power_serie< T >::
  get_coeff ( T & elem, lidia_size_t e )
   {
        debug_handler ( "base_dense_power_serie< T >", "get_coeff(T&,lidia_size_t)" ) ;

        if ( coeff->size() == 0 )
         {
            lidia_error_handler ( "base_dense_power_serie< T >::get_coeff(T&,lidia_size_t)",
                            "Serie is not initialized.") ;
         }
        else if ( e > last )
         {
            lidia_error_handler ( "base_dense_power_serie< T >::get_coeff(T&,lidia_size_t)",
                            "Exponent e is too big." ) ;
         }
        else if ( e < first )
         {
            elem.assign_zero () ;
         }
        else
         {
            elem = (*coeff)[ e - first ] ;
         }
   }


  template < class T >
  void
  base_dense_power_serie< T >::
  get ( base_vector< T > & c )
   {
        debug_handler ( "base_dense_power_serie< T >", "get(math_vector< T >&)" ) ;

        if ( coeff->size() == 0 )
            lidia_error_handler ( "base_dense_power_serie< T >::get(math_vector< T >&)",
                            "Serie is not initialized.") ;

	lidia_size_t non_zero_index ;

	if ( is_zero (non_zero_index) ) 
	 {
	    c.set_capacity (1) ;
	    c[0].assign_zero () ;
	 }
	else
	 {
	   c.set_capacity ( coeff->size() - non_zero_index ) ;
	   c.assign ( 0, *coeff, non_zero_index, coeff->size() - 1 ) ;
	 }
   }

  template < class T >
  void
  base_dense_power_serie< T >::
  get ( T * & c, lidia_size_t & sz )
   {
        debug_handler ( "base_dense_power_serie< T >", "get(T *&, lidia_szie_t&)" ) ;

        if ( coeff->size() == 0 )
            lidia_error_handler ( "base_dense_power_serie< T >::get(T*&)",
				  "Serie is not initialized.") ;
	lidia_size_t non_zero_index ;
        lidia_size_t i;

        if ( c != nil )
	 {
            delete [] c;
	    c = nil;
	 }

	if ( is_zero (non_zero_index) )
	 {
	    c = new T [1];
	    c[0].assign_zero();
	    sz = 1;
	 }
	else
	 {
	   sz = coeff->size();
	   c = new T [ sz - non_zero_index ];

	   for ( i = non_zero_index ; i < sz ; i++ )
               c[i-non_zero_index] = (*coeff)[i];

	   sz = sz - non_zero_index;
	 }
   }


  template < class T >
  void
  base_dense_power_serie< T >::
  set_coeff ( const T & elem, lidia_size_t e )
   {
      debug_handler ( "base_dense_power_serie< T >", "set_coeff(const T&,lidia_size_t)" ) ;
      set_coeff ( elem, e, *this ) ;
   }


  template < class T >
  void
  base_dense_power_serie< T >::
  set_coeff ( const T & elem, lidia_size_t e, const base_dense_power_serie< T > & a )
   {
      debug_handler ( "base_dense_power_serie< T >", "set_coeff(const T&,lidia_size_t,base_dense_power_serie&)" ) ;

      math_vector< T > *A ;
      lidia_size_t aprec ;
      int ident ;

      A     = a.coeff   ;
      aprec = A->size() ;

      if ( &a == this )
          ident = 1 ;
      else
          ident = 0 ;

      if ( aprec == 0 )
       {
          first = e ;
          last  = e ;
	  allocate ( 1, coeff ) ;
          (*coeff)[0] = elem ;
       }
      else if ( e > a.last )
       {
	  if ( a.is_zero () )
	   {
	      allocate ( 1, coeff ) ;
	      (*coeff)[0] = elem ;
	      first = e ;
	      last  = e ;
           }
	  else
	   {
	      T zero_elem ;
	      lidia_size_t i, new_prec ;

	      zero_elem.assign_zero () ;
	      new_prec = aprec +  (e - a.last) ;
	      allocate ( new_prec, coeff ) ;

              last  = e ;
              (*coeff)[ new_prec - 1 ] = elem ;

              new_prec -- ;

              for ( i = aprec ; i < new_prec ; i++ )
                   (*coeff)[i] = zero_elem ;

              if ( !ident )
               {
                  first = a.first ;
                   coeff->assign ( 0, *A, 0, aprec-1 ) ;
               }
	    }
       }
      else if ( e < a.first )
       {
          if ( ! elem.is_zero () )
           {
	      if ( a.is_zero () )
	       {
		  T zero_elem ;
		  lidia_size_t i, prec ;

		  zero_elem.assign_zero () ;
		  prec = a.first - e + 1 ;

		  allocate ( prec, coeff ) ;

		  (*coeff)[0] = elem ;

		  for ( i = 1 ; i < prec ; i++ )
		       (*coeff)[i] = zero_elem ;

		  first = e ;
		  last  = a.last ;
	       }
	      else
	       {
                  math_vector< T > *h ;

                  if ( ident )
                      h = new math_vector< T > ;
                  else
                      h = coeff ;

                  T zero_elem ;
                  lidia_size_t i, new_prec ;
                  lidia_size_t new_added ;

		  zero_elem.assign_zero () ;
		  new_added =  (a.first - e) ;
                  new_prec = aprec + new_added ;
                  allocate ( new_prec, h ) ;

                  (*h)[0] = elem ;

                  for ( i = 1 ; i < new_added ; i++ )
                       (*h)[i] = zero_elem ;

	          h->set_size ( new_added ) ;
                  h->concat ( *h, *A ) ;

                  first = e ;

                  if ( ident )
                   {
                      delete coeff ;
                      coeff = h ;
                   }
                  else
                      last = a.last ;
                }
           }
          else if ( !ident ) // assign this = a
           {
              first  = a.first ;
              last   = a.last  ;
              *coeff = *A ;
           }
       }
      else // a.first <= e <= a.last
       {
          T zero_elem ;

	  zero_elem.assign_zero () ;

          if ( e == a.first && elem == zero_elem )
           {
              lidia_size_t delta = 1 ;
              lidia_size_t sz    = aprec ;

              while ( delta < sz )
               {
                 if ( (*A)[delta] == zero_elem )
                     delta++ ;
                 else
                     sz = delta ;
               }

              if ( delta == aprec )
               {
                  assign_zero ( a.last ) ;
               }
              else
               {
                 if ( ident )
                  {
                     coeff->shift_left( delta, delta ) ;
                     first += delta ;
                  }
                 else
                  {
                     allocate ( aprec-delta, coeff ) ;
                     first = a.first + delta ;
                     last  = a.last ;
                     coeff->assign ( 0, *A, delta, aprec-1 ) ;
                  }
               }
           }
          else // e != a.first || elem != 0
           {
             if ( !ident )
              {
                 first  = a.first ;
                 last   = a.last ;
                 *coeff = *A ;
              }

              (*coeff)[ e - first ] = elem ;
           }
       }
   }


  template < class T >
  void
  base_dense_power_serie< T >::
  set ( base_vector< T > & c, lidia_size_t f )
   {
        debug_handler ( "base_dense_power_serie< T >", "set(const math_vector< T >&,lidia_size_t)" ) ;

        lidia_size_t delta ;
        lidia_size_t sz = c.size() ;

        T zero_elem ;

	zero_elem.assign_zero () ;

        if ( sz == 0 )
         {
           warning_handler ( "base_dense_power_serie< T >::set(const math_vector< T >&,lidia_size_t)",
                             "Argument math_vector< T > not initialized, setting failed!" ) ;
         }
        else if ( c[0] == zero_elem )
         {
            delta = 1 ;

            while ( delta < sz )
             {
                if ( c[delta] == zero_elem )
                    delta++ ;
                 else
                   sz = delta ;
             }

            sz = c.size() ;

            if ( delta == sz )
             {
                assign_zero ( f + sz - 1 ) ;
             }
            else
             {
                coeff->set_capacity( sz - delta ) ;
                coeff->assign      ( 0, c, delta, sz-1 ) ;
                first =  f + delta  ;
                last  =  f + sz - 1 ;
             }
         }
        else
         {
            *coeff = c ;
            first  = f ;
            last   =  f + sz - 1 ;
         }
   }

  template < class T >
  void
  base_dense_power_serie< T >::
  set ( const T *c, lidia_size_t prec, lidia_size_t f )
   {
        debug_handler ( "base_dense_power_serie< T >", "set(const T*,lidia_size_t,lidia_size_t)" ) ;

        lidia_size_t i ;
        lidia_size_t delta ;
        lidia_size_t sz = prec ;

        if ( sz == 0 || c == nil )
         {
            warning_handler ( "base_dense_power_serie< T >::set(const T*,lidia_size_t,lidia_size_t)",
                              "Argument T* not initialized, setting failed!" ) ;
         }
        else if ( c[0] == 0 )
         {
            delta = 1 ;

            while ( delta < sz )
             {
                if ( c[delta] == 0 )
                    delta++ ;
                 else
                   sz = delta ;
             }

            sz = prec ;

            if ( delta == sz )
             {
                assign_zero ( f + sz - 1 ) ;
             }
            else
             {
                coeff->set_capacity( sz - delta ) ;

                first =  f + delta  ;
                last  =  f + sz - 1 ;

                for ( i = 0 ; delta < sz ; i++, delta++ )
                 {
                     (*coeff)[i] = c[delta] ;
                 }
             }
         }
        else
         {
            first  = f ;
            last   =  f + sz - 1 ;

            coeff->set_capacity ( sz ) ;

            for ( i = 0 ; i < sz ; i++ )
             {
                 (*coeff)[i] = c[i] ;
             }
         }
   }

  template < class T >
  void
  base_dense_power_serie< T >::
  set ( const T & elem, lidia_size_t l )
   {
       debug_handler ( "base_dense_power_serie< T >", "set(T&,lidia_size_t)" ) ;

       T    zero_elem ;
       lidia_size_t  i, prec ;

       zero_elem.assign_zero () ;

       if ( elem == zero_elem || l < 0 )
        {
           assign_zero ( l ) ;
        }
       else
        {
           prec  =  l+1 ;
           first = 0 ;
           last  = l ;
           coeff->set_capacity ( prec ) ;

           (*coeff)[0] = elem ;

           for ( i = 1 ; i < prec ; i++ )
                (*coeff)[i] = zero_elem ;
        }
   }



  //
  // ***** more utility functions *****
  //


  template < class T >
  void
  base_dense_power_serie< T >::
  clear ()
   {
        debug_handler ( "base_dense_power_serie< T >", "clear()" ) ;

        coeff->set_capacity (0) ;
        max_num_coeff = 0 ;
   }


  template < class T >
  void
  base_dense_power_serie< T >::
  normalize ()
   {
        debug_handler ( "base_dense_power_serie< T >", "normalize()" ) ;

        if ( coeff->size() == 0 )
         {
            warning_handler ( "base_dense_power_serie< T >::normalize()",
                              "Serie is not initialized, normalization failed." ) ;
         }
        else if ( first > last )
         {
            warning_handler ( "base_dense_power_serie< T >::normalize()",
                              "first is greater than last, normalization failed." ) ;
         }
        else
         {
	    lidia_size_t non_zero_index ;

	    if ( is_zero (non_zero_index) )
	        assign_zero (last) ;
	    else
	     {
	        if ( non_zero_index != 0 )
		    coeff->shift_left ( non_zero_index, non_zero_index ) ;

		coeff->set_capacity ( (last - first) + 1 - non_zero_index ) ;
		first += non_zero_index ;
	     }
         }
   }

  template < class T >
  void
  base_dense_power_serie< T >::
  set_max_num_of_coeff ( lidia_size_t sz )
   {
       debug_handler ( "base_dense_power_serie< T >", "set_max_num_of_coeff(lidia_size_t)" ) ;

       if ( sz <= 0 )
        {
	   warning_handler ( "base_dense_power_serie< T >::set_max_num_of_coeff(lidia_size_t)",
			     "Ignoring non-positive size." ) ;
	}
       else
           max_num_coeff = sz ;
   }


  template < class T >
  lidia_size_t
  base_dense_power_serie< T >::
  get_max_num_of_coeff ()
   {
       debug_handler ( "base_dense_power_serie< T >", "get_max_num_of_coeff()" ) ;
       return (max_num_coeff) ;
   }


  template < class T >
  void
  base_dense_power_serie< T >::
  clear_max_num_of_coeff ()
   {
       debug_handler ( "base_dense_power_serie< T >", "clear_max_num_of_coeff(lidia_size_t)" ) ;
       max_num_coeff = 0 ;
   }




  // 
  // ***** subscripting *****
  // 


  // Returns the coefficient with exponent e.
  // This operator can only be used for
  // reading - operations. The exponent e must be
  // smaller than or equal to last; otherwise
  // the lidia_error_handler() is called.

  template < class T >
  const T
  base_dense_power_serie< T >::
  operator[] ( lidia_size_t e ) const
   {
        debug_handler ( "base_dense_power_serie< T >", "operator[]" ) ;

        if ( coeff->size() == 0 )
         {
            lidia_error_handler ( "base_dense_power_serie< T >::operator[]",
                            "Serie is not initialized.") ;
            return (T) 0 ;
         }
        else if ( e > last )
         {
            lidia_error_handler ( "base_dense_power_serie< T >::operator[]",
                            "Exponent e exceeds last." ) ;
            return (T) 0 ;
         }
        else if ( e < first )
         {
            return (T) 0 ;
         }
        else
         {
            return (*coeff)[ e - first ] ;
         }
   }


  // Returns the coefficient with exponent e.
  // This operator should only be used for
  // writing - operations, because if the exponents e
  // exceeds last or falls below first, new coefficients are allocated,
  // initialized with zero and last or first is set to zero, respectively.

  template < class T >
  T &
  base_dense_power_serie< T >::
  operator() ( lidia_size_t e )
   {
        debug_handler ( "base_dense_power_serie< T >", "operator()" ) ;

        if ( coeff->size() == 0 )
         {
	    assign_zero ( e ) ;
	    return (*coeff)[0] ;
         }
        else if ( e > last )
         {
	    T zero_elem ;
	    lidia_size_t prec, i  ;
	    lidia_size_t new_prec ;

	    zero_elem.assign_zero () ;
            prec      = last - first + 1  ;
            new_prec  = prec + (e - last) ;

            allocate ( new_prec, coeff ) ;

            for ( i = prec ; i < new_prec ; i++ )
                 (*coeff)[i] = zero_elem ;

	    last = e ;

	    return (*coeff)[ e - first ] ;
         }
        else if ( e < first )
         {
	    lidia_size_t delta, i ;
	    math_vector< T > *c ;

	    c = new math_vector< T > ;
	    delta = first - e ;
	    c->set_capacity ( coeff->size() + delta ) ;

	    for ( i = 0 ; i < delta ; i++ )
	       (*c)[i].assign_zero () ;

	    c->assign ( delta, *coeff, 0, coeff->size() -1 ) ;

	    delete coeff ;
	    coeff = c ;
	    first = e ;

            return (*coeff)[0] ;
         }
        else
         {
            return (*coeff)[ e - first ] ;
         }
   }






  // ************************************************
  // *********** representation of 0 * x^f **********
  // **(internal rep.: prec==1, coeff[0]==0, n==f) **
  // ************************************************


  template < class T >
  void
  base_dense_power_serie< T >::
  assign_zero ( lidia_size_t f )
   {
      debug_handler ( "base_dense_power_serie< T >", "assign_zero(lidia_size_t)" ) ;

      first = f ;
      last  = f ;
      coeff->set_capacity ( 1 ) ;
      (*coeff)[0].assign_zero () ;
   }

  template < class T >
  void
  base_dense_power_serie< T >::
  assign_one ( lidia_size_t l )
   {
      debug_handler ( "base_dense_power_serie< T >", "assign_one(lidia_size_t)" ) ;

      if ( l < 0 )
       {
          assign_zero ( l ) ;
       }
      else
       {
          lidia_size_t i, prec ;

          prec  = l+1 ;
          first = 0 ;
          last  = l ;
          coeff->set_capacity ( prec ) ;
          (*coeff)[0].assign_one () ;

          for ( i = 1 ; i < prec ; i++ )
               (*coeff)[i].assign_zero () ;
       }
   }



  // ************************************************
  // ************ assignment - operator *************
  // ************************************************

  template < class T >
  const base_dense_power_serie< T > &
  base_dense_power_serie< T >::
  operator= ( const base_dense_power_serie< T > & a )
   {
      debug_handler ( "base_dense_power_serie< T >", "operator=(const base_dense_power_serie< T >&)" ) ;

      if ( this != &a )
       {
	  lidia_size_t non_zero_index ;

	  if ( a.is_zero (non_zero_index) ) 
	   {
	      assign_zero (a.last) ;
	   }
	  else
	   {
	      coeff->set_capacity ( (a.coeff)->size() - non_zero_index ) ;
	      coeff->assign ( 0, *(a.coeff), non_zero_index, (a.coeff)->size() -1 ) ;
	      first = a.first + non_zero_index ;
	      last  = a.last ;
	   }
       }

      return *this ;
   }


  template < class T >
  const base_dense_power_serie< T > &
  base_dense_power_serie< T >::
  operator= ( const base_sparse_power_serie< T > & a )
   {
      debug_handler ( "base_dense_power_serie< T >", "operator=(const base_sparse_power_serie< T >&)" ) ;

      if ( a.is_zero () )
       {
          assign_zero ( a.get_last() ) ;
       }
      else
       {
          lidia_size_t  prec, i  ;

          // initialize variables

          first = a.get_first () ;
          last  = a.get_last  () ;


          // compute precision of the dense serie

          prec =   last - first + 1    ;
          coeff->set_capacity ( prec ) ;


          // copy coefficients 

          for ( i = first ; i <= last ; i++ )
           {
               (*coeff)[i-first] = a[i] ;
	   }

          // check number of allocated elements

          if ( max_num_coeff != 0 && prec > max_num_coeff )
              warning_handler ( "base_dense_power_serie< T >::assign(const base_sparse_power_serie&)",
                                "Number of allocated coefficients exceeds user-defined upper bound." ) ;
      }

      return (*this) ;
   }


  // ************************************************
  // *************** cast - operator ****************
  // ************************************************

  template < class T >
  base_dense_power_serie< T >::
  operator base_sparse_power_serie< T >()
   {
     debug_handler ( "base_dense_power_serie< T >", "operator base_sparse_power_serie< T >()" ) ;
     return base_sparse_power_serie< T > ( *coeff, first ) ;
   }



  // ************************************************
  // **************** comparisons *******************
  // ************************************************

  template < class T >
  bool
  base_dense_power_serie< T >::
  operator== ( const base_dense_power_serie< T > & a ) const
   {
      debug_handler ( "base_dense_power_serie< T >", "operator==(base_dense_power_serie&)" ) ;

      if ( (a.coeff)->size() == 0 || coeff->size() == 0 )
          lidia_error_handler ( "base_dense_power_serie< T >::operator==(const base_dense_power_serie< T >&)",
                           "Serie is not initialized.") ;

      lidia_size_t non_zero_index_a ;
      lidia_size_t non_zero_index_t ;
      bool  a_zero, t_zero ;
      bool  rc ;

      t_zero = is_zero (non_zero_index_t) ;
      a_zero = a.is_zero (non_zero_index_a) ;
      
      if ( a_zero != t_zero )
          rc = false ;
      else if ( a_zero && t_zero )
          if ( last == a.last )
              rc = true ;
          else
	      rc = false ;
      else
       {
	 if ( last != a.last || (first+non_zero_index_t) != (a.first+non_zero_index_a) )
	     rc = false ;
	 else
	  {
	     lidia_size_t prec_t ;
	     lidia_size_t i, j ;

	     prec_t = last - first + 1 ;
	     rc = 1 ;

	     for ( i = non_zero_index_t, j = non_zero_index_a ; i < prec_t && rc == true ; i++, j++ )
	        if ( (*coeff)[i] != (*(a.coeff))[j] )
		   rc = false ;
	  }
       }

      return rc ;
   }


  template < class T >
  bool
  base_dense_power_serie< T >::
  operator!= ( const base_dense_power_serie< T > & a ) const
   {
      debug_handler ( "base_dense_power_serie< T >", "operator!=(base_dense_power_serie&)" ) ;

      if ( operator==(a) == true ) 
          return false ;
      else
          return true ;
   }


  //
  // ***** input / output *****
  //

  template < class T >  
  int
  base_dense_power_serie< T >::
  read ( istream & in )
   {
      debug_handler ( "base_dense_power_serie< T >",
                      "read(istream&)" ) ;
      
      math_vector< T > *tmp ;
      char c  ;
      int  rc ;
      T zero_elem ;

      in >> ws >> c ;

      if ( c != '[' )
       {
          lidia_error_handler ( "base_dense_power_serie< T >::read(istream&)",
                          "Invalid input format ('[' expected) for base_dense_power_serie< T >." ) ;
       }
      else
       {
          in >> ws >> first ;

              tmp = new math_vector< T > ;

              in >> ws >> (*tmp) ;

              if ( tmp->size() == 0 )
               {
                   delete tmp ;
                   lidia_error_handler ( "base_dense_power_serie< T >::read(istream&)",
                                   "Input does not contain any coefficient." ) ;
               }
              else
               {
                  if ( (*tmp)[0].is_zero() )
                   {
                      set ( *tmp, first ) ;
                      delete tmp ;
                   }
                  else
                   {
                      delete coeff ;
                      coeff = tmp ;
                      last = first + coeff->size() - 1 ;
                   }

                  in >> ws >> c ;

                  if ( c != ']' )
                   {
                     lidia_error_handler ( "base_dense_power_serie< T >::read(istream&)",
                                     "Invalid input format (']' expected) for base_dense_power_serie< T >." ) ;
                   }
               }
	}

      for ( rc = 0 ; rc < 0 ; ) {}
      return (rc) ;
   }


  template < class T >
  void
  base_dense_power_serie< T >::
  write ( ostream & out ) const
   {
     debug_handler ( "base_dense_power_serie", "write(ostream&)" ) ;
     lidia_size_t non_zero_index ;
     lidia_size_t i ;

     if ( is_zero (non_zero_index) )
      {
         out << "[ " << last << " " << "[ " << (*coeff)[0] << " ] " << " ]" ;
      }
     else
      {
	 out << "[ " << first+non_zero_index << " " << "[ " ;

	 for ( i = non_zero_index ; i < coeff->size() ; i++ )
	  out << (*coeff)[i] << " " ;

	 out << "] ]" ;
      }
   }


  // 
  // ***** miscellaneous *****
  // 

  template < class T >
  void
  base_dense_power_serie< T >::
  multiply_by_xn ( lidia_size_t n )
   {
       debug_handler ( "base_dense_power_serie< T >",
                       "multiply_by_xn(lidia_size_t)" ) ;
       first += n ;
       last  += n ;
   }


  template < class T >
  void
  base_dense_power_serie< T >::
  compose ( lidia_size_t n )
   {
       debug_handler ( "base_dense_power_serie< T >",
                       "compose(lidia_size_t)" ) ;
       lidia_size_t prec ;
       lidia_size_t i, j ;

       T zero_elem ;


       prec = coeff->size() ;

       coeff->set_capacity (prec*n);

       first *= n ;
       last  *= n ;

       for ( i = prec-1 ; i >= 0 ; i-- )
	{
	  (*coeff)[i*n] = (*coeff)[i] ;
	}

       zero_elem.assign_zero () ;

       for ( i = 0 ; i < prec ; i++ )
          for ( j = 1 ; j < n ; j++ )
	   {
	     (*coeff)[j+i*n] = zero_elem ;
	   }
   }


/*
  template < class T >
  void
  randomize ( base_dense_power_serie< T > & a, lidia_size_t f, lidia_size_t l, const T & coeff_bound )
   {
       debug_handler ( "base_dense_power_serie< T >",
                       "randomize(base_dense_power_serie< T >&,lidia_size_t,lidia_size_t)" ) ;

       lidia_size_t prec =  (l - f + 1) ;
       lidia_size_t i ;

       T tmp ;

       math_vector< T > * A = a.coeff ;

       if ( prec <= 0 )
        {
           lidia_error_handler ( "base_dense_power_serie< T >::randomize(base_dense_power_serie&,lidia_size_t,lidia_size_t,T&)",
                           "Non positive number of coefficients!" ) ;
        }
       else
        {
           a.first = f ;
           a.last  = l ;

           A->set_capacity ( prec ) ;

           for ( i = 0 ; i < prec ; i++ )
            {
                (*A)[i] = randomize ( coeff_bound ) ;
            }

           if ( (*A)[0].is_zero () )
            {
               (*A)[0].assign_one () ;
            }
        }
   }
*/


  // 
  // ***** arithmetic via friend functions *****
  // 

  template < class T >
  void
  base_dense_power_serie< T >::
  add ( const base_dense_power_serie< T > & a,
        const base_dense_power_serie< T > & b)
    {
       debug_handler ( "base_dense_power_serie< T >",
                       "add(base_dense_power_serie< T >&,base_dense_power_serie< T >&,base_dense_power_serie< T >&" ) ;

       lidia_size_t na, nb, nres ;
       lidia_size_t pa, pb, pres ;
       lidia_size_t l , u , i ;

       int  end, ident ;

       math_vector< T > *res   ;
       math_vector< T > *X, *Y ;
       T  z ;

       na = a.first ;
       nb = b.first ;
       pa = (a.coeff)->size() ;
       pb = (b.coeff)->size() ;

       // check for invalid arguments

       if ( pa == 0 || pb == 0 )
        {
           lidia_error_handler ( "base_dense_power_serie< T >::add(base_dense_power_serie< T >&,base_dense_power_serie< T >,base_dense_power_serie< T >&",
                           "Arguments not initialized." ) ;
        }

       /* coefficients don't overlap -> the sum is given by the serie with
          the smaller start exponent */

       else if ( na + pa <= nb )
        {
               *this = a ;
        }
       else if ( nb + pb <= na )
        {
               *this = b ;
        }

       /* the coefficients overlap -> compute sum ( stored in res ) */

       else
        {
           ident = 0 ;

           /* check whether input alias output */

           if ( ( this != &a ) && ( this != &b ) )
            {
               res = coeff ;
            }
           else
            {
               ident = 1 ;
               res   = new math_vector< T > ;
            }

           /* determine the serie with the smaller start exponent */

           nres =  na < nb ? na : nb ;

           if ( nres == na )
            {
               l    = nb - na  ;
               pres =  ( l + (( pa-l < pb) ? pa-l : pb) ) ;
               X    = a.coeff ;
               Y    = b.coeff ;
            }
           else
            {
               l    = na - nb  ;
               pres =  ( l + ((pb-l < pa) ? pb-l : pa) ) ;
               X    = b.coeff ;
               Y    = a.coeff ;
            }

           /* different start exponents */

           if ( l > 0 )
            {
               /* set length of the vector of coefficients of res */

               res->set_capacity ( pres ) ;

               /* The first coefficients of the result are given by
                  the coefficients of the serie with the smaller
                  start exponent up to the point the overlapping
                  of the coefficients begins. */

               for ( i=0; i<l; i++ )
                {
                   res->assign ( 0, *X, 0, l-1 ) ;
                }

               /* From the beginning of the overlapping up to the length
                  of the result (pres) the coefficients are added. */

               for ( i=l; i<pres; i++ )
                {
                   ::add ( (*res)[i], (*X)[i], (*Y)[i-l] ) ;
                }
            }

           /* same start exponents */

           else
            {
               pres = pa < pb ? pa : pb ;
               X    = a.coeff ;
               Y    = b.coeff ;

               i = end = 0 ;

               /* ignore leading zero */

               ::add ( z, (*X)[0], (*Y)[0] ) ;

               while ( ( z == 0 ) && !end )
                {
                   if ( i == pres - 1 )
                    {
                       end = 1 ;
                    }
                   else
                    {
                       i++ ;
                       ::add ( z, (*X)[i], (*Y)[i] ) ;
                    }
                }

               /* compute result */

               nres = na + i ;

               l    = i ;
               u    = pres ;
               pres = pres - i ;


               /* set length of the vector of coefficients of res */

               res->set_capacity ( pres ) ;


               /* add coefficients */

               for ( i=l; i<u; i++ )
                {
                   ::add ( (*res)[i-l], (*X)[i], (*Y)[i] ) ;
                }

           }  /* end else - same start exponent */

          first = nres ;
          last  = nres + pres - 1 ;

          if ( ident )
           {
              delete coeff ;
              coeff = res ;
           }

       } /* end else - overlapping */
  }


  template < class T >
  void
  base_dense_power_serie < T >::
  add ( const base_dense_power_serie< T > & a,
        const T & b )
    {
       debug_handler ( "base_dense_power_serie< T >",
                       "add(base_dense_power_serie< T >&,base_dense_power_serie< T >&,T&)" ) ;

       math_vector< T > *A = a.coeff ;
       T x ;

       // check for invalid arguments

       if ( A->size() == 0 )
        {
           lidia_error_handler ( "base_dense_power_serie< T >::add(base_dense_power_serie< T >&,base_dense_power_serie< T >&,T&)",
                           "Argument not initialized." ) ;
        }


       // add a and b * x^0 + O(x^a.last)

       else if ( a.last >= 0 )
        {
           if ( a.first > 0 )
               x = b ;
           else
               x = (*A)[-a.first] + b ;

           set_coeff ( x, 0, a ) ;
        }
       else
           *this = a ;
    }


  template < class T >
  void
  base_dense_power_serie< T >::
  add ( const T & b,
        const base_dense_power_serie< T > & a )
    {
       debug_handler ( "base_dense_power_serie< T >",
                       "add(base_dense_power_serie< T >&,T&,base_dense_power_serie< T >&)" ) ;

       math_vector< T > *A = a.coeff ;
       T x ;


       // check for invalid arguments

       if ( A->size() == 0 )
        {
           lidia_error_handler ( "base_dense_power_serie< T >::add(base_dense_power_serie< T >&,T&,base_dense_power_serie< T >&)",
                           "Argument not initialized." ) ;
        }


       // add a and b * x^0 + O(x^a.last)

       else if ( a.last >= 0 )
        {
           if ( a.first > 0 )
               x = b ;
           else
               x = b + (*A)[-a.first] ;

           set_coeff ( x, 0, a ) ;
        }
       else
           *this = a ;
    }



  template < class T >
  void
  base_dense_power_serie< T >::
  subtract ( const base_dense_power_serie< T > & a,
             const base_dense_power_serie< T > & b )
    {
       debug_handler ( "base_dense_power_serie< T >",
                       "subtract(base_dense_power_serie< T >&,base_dense_power_serie< T >,base_dense_power_serie< T >&" ) ;

       lidia_size_t na, nb, nres ;
       lidia_size_t pa, pb, pres ;
       lidia_size_t l, u, i ;
       int end, ident ;

       math_vector< T > *res   ;
       math_vector< T > *X, *Y ;
       T  z ;

       na = a.first ;
       nb = b.first ;
       pa = (a.coeff)->size() ;
       pb = (b.coeff)->size() ;


       // check for invalid arguments

       if ( pa == 0 || pb == 0 )
        {
           lidia_error_handler ( "base_dense_power_serie< T >::subtract(base_dense_power_serie< T >&,base_dense_power_serie< T >,base_dense_power_serie< T >&",
                           "Arguments not initialized." ) ;
        }

       /* coefficients don't overlap -> the result is given by the serie with
          the smaller start exponent */

       else if ( na + pa <= nb )
        {
               *this = a ;
        }
       else if ( nb + pb <= na )
        {
               *this = b ;
        }

       /* the coefficients overlap -> compute difference ( stored in res ) */

       else
        {
           ident = 0;

           /* check whether input alias output */

           if ( ( this != &a ) && ( this != &b ) )
            {
               res = coeff;
            }
           else
            {
               ident = 1;
               res   = new math_vector< T > ;
            }

           /* determine the serie with the smaller start exponent */

           nres = na < nb ? na : nb ;

           if ( nres == na )
            {
               l    = nb - na ;
               pres =  ( l + ((pa-l < pb) ? pa-l : pb) ) ;
               X    = a.coeff;
               Y    = b.coeff;
            }
           else
            {
               l    = na - nb ;
               pres =  ( l + ((pb-l < pa) ? pb-l : pa) ) ;
               X    = b.coeff;
               Y    = a.coeff;
            }

           /* different start exponents */

           if ( l > 0 )
            {
               /* set length of the vector of coefficients of res */

               res->set_capacity ( pres ) ;

               /* The first coefficients of the result are given by
                  the coefficients of the serie with the smaller
                  start exponent up to the point the overlapping
                  of the coefficients begins. */

               if ( X == a.coeff )

                  for ( i=0; i<l; i++ )
                   {
                       res->assign ( 0, *X, 0, l-1 ) ;
                   }
               else

                  for ( i=0; i<l; i++ )
                   {
                      ::negate ( (*res)[i], (*X)[i] ) ;
                   }

               /* From the beginning of the overlapping up to the length
                  of the result (pres) the coefficients are subtracted. */

               if ( X == a.coeff )
                {
                   for ( i=l; i<pres; i++ )
                    {
                       ::subtract ( (*res)[i], (*X)[i], (*Y)[i-l] ) ;
                    }
                }
               else
                {
                   for ( i=l; i<pres; i++ )
                    {
                       ::subtract ( (*res)[i], (*Y)[i-l], (*X)[i] ) ;
                    }
                }
            }

           /* same start exponents */

           else
            {
               pres = pa < pb ? pa : pb ;
               X    = a.coeff;
               Y    = b.coeff;

               i = end = 0;

               /* ignore leading zero */

               if ( X == a.coeff )
                {
                   ::subtract ( z, (*X)[0], (*Y)[0] ) ;

                   while ( ( z == 0 ) && !end )
                    {
                       if ( i == pres - 1 )
                        {
                           end = 1;
                        }
                       else
                        {
                           i++;
                           ::subtract ( z, (*X)[i], (*Y)[i] ) ;
                        }
                    }
                 }
                else
                 {
                    ::subtract ( z, (*Y)[0], (*X)[0] ) ;

                    while ( ( z == 0 ) && !end )
                     {
                        if ( i == pres - 1 )
                         {
                            end = 1;
                         }
                        else
                         {
                            i++;
                            ::subtract ( z, (*Y)[i], (*X)[i] ) ;
                         }
                     }
                 }


               /* compute result */

               nres = na + i;

               l    = i;
               u    = pres;
               pres = pres - i;

               /* set length of the vector of coefficients of res */

               res->set_capacity ( pres ) ;

               /* subtract coefficients */

               if ( X == a.coeff )
                {
                   for ( i=l; i<u; i++ )
                    {
                       ::subtract ( (*res)[i-l], (*X)[i], (*Y)[i] ) ;
                    }
                }
               else
                {
                   for ( i=l; i<u; i++ )
                    {
                       ::subtract ( (*res)[i-l], (*Y)[i], (*X)[i] ) ;
                    }
                }

           }  /* end else - same start exponents */

           first = nres ;
           last  = nres + pres - 1 ;

           if ( ident )
            {
               delete coeff ;
               coeff = res ;
            }

       } /* end else - overlapping */
  }


  template < class T >
  void
  base_dense_power_serie< T >::
  subtract ( const base_dense_power_serie< T > & a,
             const T & b )
    {
       debug_handler ( "base_dense_power_serie< T >",
                       "subtract(base_dense_power_serie< T >&,base_dense_power_serie< T >&,T&)" ) ;

       math_vector< T > *A = a.coeff ;
       T x ;


       // check for invalid arguments

       if ( A->size() == 0 )
        {
           lidia_error_handler ( "base_dense_power_serie< T >::subtract(base_dense_power_serie< T >&,base_dense_power_serie< T >&,T&)",
                           "Argument not initialized." ) ;
        }


       // subtract a and b * x^0 + O(x^a.last)

       else if ( a.last >= 0 )
        {
           if ( a.first > 0 )
               ::negate ( x, b ) ;
           else
               ::subtract ( x, (*A)[-a.first], b ) ;

           set_coeff ( x, 0, a ) ;
        }
       else
           *this = a ;
    }


  template < class T >
  void
  base_dense_power_serie< T >::
  subtract ( const T & b,
             const base_dense_power_serie< T > & a )
    {
       debug_handler ( "base_dense_power_serie< T >",
                       "subtract(base_dense_power_serie< T >&,T&,base_dense_power_serie< T >&)" ) ;

       math_vector< T > *A = a.coeff ;
       T x ;


       // check for invalid arguments

       if ( A->size() == 0 )
        {
           lidia_error_handler ( "base_dense_power_serie< T >::subtract(base_dense_power_serie< T >&,T&,base_dense_power_serie< T >&)",
                           "Argument not initialized." ) ;
        }


       // subtract b * x^0 + O(x^a.last) and a

       else if ( a.last >= 0 )
        {
           if ( a.first > 0 )
               ::negate ( x, b ) ;
           else
               ::subtract ( x, (*A)[-a.first], b ) ;

           set_coeff ( x, 0, a ) ;
           this->negate (*this) ;
        }
       else
         this->negate(a) ;
    }





  template < class T >
  void
  base_dense_power_serie< T >::
  multiply ( const base_dense_power_serie< T > & a,
             const T & b )
    {
       debug_handler ( "base_dense_power_serie< T >",
                       "multiply(base_dense_power_serie< T >&,base_dense_power_serie< T >&,T&)" ) ;

       math_vector< T > *A = a.coeff ;
       math_vector< T > *C = coeff ;

       lidia_size_t pa = A->size() ;
       lidia_size_t i ;


       // check for invalid arguments

       if ( pa == 0 )
        {
           lidia_error_handler ( "base_dense_power_serie< T >::multiply(base_dense_power_serie< T >&,base_dense_power_serie< T >&,T&)",
                           "Argument not initialized." ) ;
        }


       // multiply with b

       if ( b.is_zero() )
        {
           C->set_capacity ( 1 ) ;
           (*C)[0].assign_zero () ;
           first = a.last ;
           last  = a.last ;
        }
       else
        {
           C->set_capacity ( pa ) ;

           for ( i = 0 ; i < pa ; i++ )
                ::multiply ( (*C)[i], (*A)[i], b ) ;

           first = a.first ;
           last  = a.last  ;
        }
    }


  template < class T >
  void
  base_dense_power_serie< T >::
  multiply ( const T & b,
             const base_dense_power_serie< T > & a )
    {
       debug_handler ( "base_dense_power_serie< T >",
                       "multiply(base_dense_power_serie< T >&,T&,base_dense_power_serie< T >&)" ) ;

       math_vector< T > *A = a.coeff ;
       math_vector< T > *C = coeff ;

       lidia_size_t pa = A->size() ;
       lidia_size_t i ;


       // check for invalid arguments

       if ( pa == 0 )
        {
           lidia_error_handler ( "base_dense_power_serie< T >::multiply(base_dense_power_serie< T >&,T&,base_dense_power_serie< T >&)",
                           "Argument not initialized." ) ;
        }


       // multiply with b

       if ( b.is_zero () )
        {
           C->set_capacity ( 1 ) ;
           (*C)[0].assign_zero () ;
           first = a.last ;
           last  = a.last ;
        }
       else
        {
           C->set_capacity ( pa ) ;

           for ( i = 0 ; i < pa ; i++ )
                ::multiply ( (*C)[i], b, (*A)[i] ) ;

           first = a.first ;
           last  = a.last  ;
        }
    }


  template < class T >
  void
  base_dense_power_serie< T >::
  divide ( const base_dense_power_serie< T > & a,
           const T & b )
    {
       debug_handler ( "base_dense_power_serie< T >",
                       "divide(base_dense_power_serie< T >&,base_dense_power_serie< T >&,T&)" ) ;
       T x ;

       invert ( x, b ) ;
       this->multiply ( a, x ) ;
    }



  template < class T >
  void
  base_dense_power_serie< T >::
  negate ( const base_dense_power_serie< T >& a )
    {
       debug_handler ( "base_dense_power_serie< T >",
                       "negate(base_dense_power_serie< T >&,base_dense_power_serie< T >&)" ) ;

       math_vector< T > *C = coeff ;
       math_vector< T > *A = a.coeff ;

       lidia_size_t pa = A->size() ;
       lidia_size_t i ;


       // check for invalid argument

       if ( pa == 0 )
        {
           lidia_error_handler ( "base_dense_power_serie< T >::negate(base_dense_power_serie< T >&,base_dense_power_serie< T >&)",
                           "Argument not initialized." ) ;
        }


       // negate coefficients

       C->set_capacity ( pa ) ;

       for ( i = 0 ; i < pa ; i++ )
            ::negate ( (*C)[i], (*A)[i] ) ;

       first = a.first ;
       last  = a.last  ;
    }




  // ************************************************
  // *************** miscellaneous ******************
  // ************************************************

  template < class T >
  void
  base_dense_power_serie< T >::
  swap ( base_dense_power_serie< T >& a )
    {
       debug_handler ( "base_dense_power_serie< T >",
                       "swap(base_dense_power_serie< T >&,const base_dense_power_serie< T >&)" ) ;

       if ( this != &a )
        {
           lidia_size_t      tmp_lidia_size_t ;
           math_vector< T > *tmp_base ;

           tmp_lidia_size_t = first  ;
           first    = a.first  ;
           a.first  = tmp_lidia_size_t ;

           tmp_lidia_size_t = last   ;
           last     = a.last   ;
           a.last   = tmp_lidia_size_t ;

           tmp_base = coeff  ;
           coeff    = a.coeff  ;
           a.coeff  = tmp_base ;
        }
    }


