GiNaCRA  0.6.4
Constraint.cpp
Go to the documentation of this file.
00001 /*
00002  * GiNaCRA - GiNaC Real Algebra package
00003  * Copyright (C) 2010-2012  Ulrich Loup, Joachim Redies, Sebastian Junges
00004  *
00005  * This file is part of GiNaCRA.
00006  *
00007  * GiNaCRA is free software: you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation, either version 3 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * GiNaCRA is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with GiNaCRA.  If not, see <http://www.gnu.org/licenses/>.
00019  *
00020  */
00021 
00022 
00023 //#define GINACRA_CONSTRAINT_DEBUG
00024 
00025 #include "Constraint.h"
00026 #include "utilities.h"
00027 
00028 using std::cout;
00029 using std::endl;
00030 using GiNaC::add;
00031 using GiNaC::ex;
00032 using GiNaC::const_iterator;
00033 using GiNaC::is_exactly_a;
00034 using GiNaC::ex_to;
00035 using GiNaC::is_rational_polynomial;
00036 using GiNaC::ZERO_SIGN;
00037 
00046 namespace GiNaCRA
00047 {
00049     // Con- and destructors //
00051 
00053     // Operations //
00055 
00056     bool Constraint::satisfiedBy( const RealAlgebraicPoint& r ) const
00057     {
00058         if( mVariables.size() > r.dim() )
00059             throw invalid_argument( "Dimension of the real algebraic point is less than and the number of variables to be substituted." );
00060         vector<RealAlgebraicNumberIRPtr> numbersIR = vector<RealAlgebraicNumberIRPtr>( mVariables.size() );    // shall contain only interval-represented components after the preprocessing
00061         vector<symbol> variablesIR = vector<symbol>( mVariables.size() );    // shall contain the variable indices corresponding to the components of rInterval
00062         int j = 0;    // the counter of interval representations
00063         ex pEx = mPoly;
00064         // Preprocessing: substitute all NumericRepresentation occurrences of r directly in the constraint
00065         for( unsigned i = 0; i < mVariables.size(); ++i )
00066         {
00067             RealAlgebraicNumberNRPtr rNumeric = std::tr1::dynamic_pointer_cast<RealAlgebraicNumberNR>( r.at( i ));
00068             if( rNumeric == 0 )
00069             {
00070                 numbersIR[j]   = std::tr1::dynamic_pointer_cast<RealAlgebraicNumberIR>( r.at( i ));    // safe here
00071                 variablesIR[j] = mVariables.at( i );
00072                 ++j;
00073                 continue;
00074             }
00075 #ifdef GINACRA_CONSTRAINT_DEBUG
00076             cout << "Substitute " << mVariables.at( i ) << " with " << *rNumeric << " in " << pEx << "... ";
00077 #endif
00078             pEx = pEx.subs( mVariables.at( i ) == static_cast<numeric>(*rNumeric) );
00079 #ifdef GINACRA_CONSTRAINT_DEBUG
00080             cout << pEx << endl;
00081 #endif
00082 
00083         }
00084         if( is_exactly_a<numeric>( pEx ))
00085             return mNegated ? GiNaC::sgn( ex_to<numeric>( pEx )) != mSign : GiNaC::sgn( ex_to<numeric>( pEx )) == mSign;
00086         numbersIR.resize( j );
00087         variablesIR.resize( j );
00088 #ifdef GINACRA_CONSTRAINT_DEBUG
00089         cout << "Multi-IR sign check on " << pEx << ": " << endl;
00090         for( unsigned k = 0; k != numbersIR.size(); ++k )
00091             cout << "  " << *numbersIR[k] << " vs. " << variablesIR[k] << endl;
00092 #endif
00093         return mNegated ? RealAlgebraicNumberFactory::evaluateIR( UnivariatePolynomial( pEx, variablesIR.back() ),
00094                                                                   numbersIR,
00095                                                                   variablesIR )->
00096                                                                       sgn() != mSign : RealAlgebraicNumberFactory::evaluateIR( UnivariatePolynomial(
00097                                                                           pEx, variablesIR.back() ),
00098                                                                                                                                numbersIR,
00099                                                                                                                                variablesIR )->
00100                                                                                                                                    sgn() == mSign;
00101     }
00102 
00104     // Auxiliary methods //
00106 
00107     const vector<symbol> Constraint::checkVariables( const Polynomial& p, const vector<symbol>& v ) const throw ( invalid_argument )
00108     {
00109         if( is_exactly_a<add>( p ))
00110         {
00111             for( const_iterator i = p.begin(); i != p.end(); ++i )    // iterate through the summands
00112             {
00113                 ex coefficient = ex( 1 );
00114                 ex monomial    = ex( 1 );
00115                 GiNaC::isolateByVariables( *i, v, coefficient, monomial );
00116                 if( !is_exactly_a<numeric>( coefficient ))
00117                     throw invalid_argument( "Given polynomial contains unspecified variables." );
00118             }
00119         }
00120         else
00121         {
00122             ex coefficient = ex( 1 );
00123             ex monomial    = ex( 1 );
00124             GiNaC::isolateByVariables( p, v, coefficient, monomial );
00125             if( !is_exactly_a<numeric>( coefficient ))
00126                 throw invalid_argument( "Given polynomial contains unspecified variables." );
00127         }
00128         return v;
00129     }
00130 
00131 }    // namespace GiNaCRA
00132