GiNaCRA
0.6.4
|
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