GiNaCRA  0.6.4
MultivariateTermMR.cpp
Go to the documentation of this file.
00001 
00002 #include "MultivariateTermMR.h"
00003 
00004 namespace GiNaCRA
00005 {
00006     const MultivariateTermMR MultivariateTermMR::lcmdivt( const MultivariateMonomialMR& m1 ) const
00007     {
00008         if( m1.mExponents.empty() )
00009             return MultivariateTermMR( *this );
00010 
00011         vui_cIt t1it  = mExponents.begin();
00012         vui_cIt m1it  = m1.mExponents.begin();
00013 
00014         vui_cIt t1end = mExponents.end();
00015         vui_cIt m1end = m1.mExponents.end();
00016         unsigned tdeg = 0;
00017         MultivariateTermMR newMon( mExponents.size() + m1.mExponents.size() );
00018         newMon.mCoeff = mCoeff.inverse();
00019         while( true )
00020         {
00021             while( t1it->first == m1it->first )
00022             {
00023                 unsigned deg = std::max( t1it->second, m1it->second ) - t1it->second;
00024                 if( deg != 0 )
00025                 {
00026                     newMon.mExponents.push_back( pui( t1it->first, deg ));
00027                     tdeg += deg;
00028                 }
00029                 ++t1it;
00030                 ++m1it;
00031                 if( t1it == t1end )
00032                 {
00033                     newMon.mExponents.insert( newMon.mExponents.end(), m1it, m1end );
00034                     newMon.mTotDeg = std::accumulate( m1it, m1end, tdeg, plus_second() );
00035                     return newMon;
00036                 }
00037                 if( m1it == m1end )
00038                 {
00039                     newMon.mTotDeg = tdeg;
00040                     return newMon;
00041                 }
00042             }
00043             while( t1it->first < m1it->first )
00044             {
00045                 ++t1it;
00046                 if( t1it == t1end )
00047                 {
00048                     newMon.mExponents.insert( newMon.mExponents.end(), m1it, m1end );
00049                     newMon.mTotDeg = std::accumulate( m1it, m1end, tdeg, plus_second() );
00050                     return newMon;
00051                 }
00052             }
00053             while( t1it->first > m1it->first )
00054             {
00055                 newMon.mExponents.push_back( *m1it );
00056                 tdeg += m1it->second;
00057                 ++m1it;
00058                 if( m1it == m1end )
00059                 {
00060                     newMon.mTotDeg = tdeg;
00061                     return newMon;
00062                 }
00063             }
00064         }
00065     }
00066 
00067     bool MultivariateTermMR::dividable( const MultivariateTermMR& denom ) const
00068     {
00069         if( denom.mExponents.empty() )
00070             return true;
00071         if( mTotDeg < denom.mTotDeg )
00072             return false;
00073 
00074         vui_cIt t1it  = mExponents.begin();
00075         vui_cIt m1it  = denom.mExponents.begin();
00076         vui_cIt t1end = mExponents.end();
00077         vui_cIt m1end = denom.mExponents.end();
00078 
00079         //is it dividable?
00080 
00081         while( true )
00082         {
00083             while( t1it->first == m1it->first )
00084             {
00085                 if( t1it->second < m1it->second )
00086                     return false;
00087                 ++t1it;
00088                 ++m1it;
00089                 if( m1it == m1end )
00090                     return true;
00091                 if( t1it == t1end )
00092                     return false;
00093             }
00094             while( t1it->first < m1it->first )
00095             {
00096                 ++t1it;
00097                 if( t1it == t1end )
00098                     return false;
00099             }
00100             if( t1it->first > m1it->first )
00101                 return false;
00102         }
00103 
00104         return true;
00105     }
00106 
00107     std::pair<MultivariateTermMR, bool> MultivariateTermMR::divby( const MultivariateTermMR& denom ) const
00108     {
00109         if( denom.mExponents.empty() )
00110             return std::pair<const MultivariateTermMR, bool>( MultivariateTermMR( *this, mCoeff / denom.mCoeff ), true );
00111 
00112         if( !dividable( denom ))
00113             return std::pair<const MultivariateTermMR, bool>( MultivariateTermMR(), false );
00114             // yes it is dividable.
00115 
00116         vui_cIt t1it              = mExponents.begin();
00117         vui_cIt m1it              = denom.mExponents.begin();
00118         vui_cIt t1end             = mExponents.end();
00119         vui_cIt m1end             = denom.mExponents.end();
00120 
00121         MultivariateTermMR newMon = MultivariateTermMR( mExponents.size() );
00122         newMon.mTotDeg            = mTotDeg - denom.tdeg();
00123         newMon.mCoeff             = mCoeff / denom.mCoeff;
00124 
00125         while( true )
00126         {
00127             while( t1it->first == m1it->first )
00128             {
00129                 unsigned deg = t1it->second - m1it->second;
00130                 if( deg != 0 )
00131                 {
00132                     newMon.mExponents.push_back( pui( t1it->first, deg ));
00133                 }
00134                 ++t1it;
00135                 ++m1it;
00136                 if( m1it == m1end )
00137                 {    // if t1it == t1end than also m1it == m1end
00138                     newMon.mExponents.insert( newMon.mExponents.end(), t1it, t1end );
00139                     return std::pair<const MultivariateTermMR, bool>( MultivariateTermMR( newMon ), true );
00140                 }
00141             }
00142 
00143             while( t1it->first < m1it->first )
00144             {
00145                 newMon.mExponents.push_back( *t1it );
00146                 ++t1it;
00147             }
00148         }
00149         return std::pair<const MultivariateTermMR, bool>( newMon, true );
00150     }
00151 
00152     bool operator ==( const MultivariateTermMR& t1, const MultivariateTermMR& t2 )
00153     {
00154         return (t1.mCoeff == t2.mCoeff) && ((MultivariateMonomialMR)t1 == (MultivariateMonomialMR)t2);
00155     }
00156 
00157     const MultivariateTermMR operator *( const MultivariateTermMR& t1, const MultivariateTermMR& t2 )
00158     {
00159         return MultivariateTermMR( (MultivariateMonomialMR)t1 * (MultivariateMonomialMR)t2, t1.mCoeff * t2.mCoeff );
00160     }
00161 
00162     const MultivariateTermMR operator *( const MultivariateTermMR& t1, const MultivariateMonomialMR& m1 )
00163     {
00164         return MultivariateTermMR( (MultivariateMonomialMR)t1 * m1, t1.mCoeff );
00165     }
00166 
00167     const MultivariateTermMR operator *( const MultivariateMonomialMR& m1, const MultivariateTermMR& t1 )
00168     {
00169         return t1 * m1;
00170     }
00171 
00172     std::ostream& operator <<( std::ostream& os, const MultivariateTermMR& rhs )
00173     {
00174         return os << rhs.mCoeff << (MultivariateMonomialMR)rhs;
00175     }
00176 }