Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

base/Expression

Go to the documentation of this file.
00001 /* **-*-c++-*-**************************************************************
00002   Copyright (C)2002 David Jung <opensim@pobox.com>
00003 
00004   This program/file is free software; you can redistribute it and/or modify
00005   it under the terms of the GNU General Public License as published by
00006   the Free Software Foundation; either version 2 of the License, or
00007   (at your option) any later version.
00008   
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU General Public License for more details. (http://www.gnu.org)
00013   
00014   You should have received a copy of the GNU General Public License
00015   along with this program; if not, write to the Free Software
00016   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017   
00018   $Id: Expression 1029 2004-02-11 20:45:54Z jungd $
00019   $Revision: 1.23 $
00020   $Date: 2004-02-11 15:45:54 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
00022  
00023 ****************************************************************************/
00024 
00025 #ifndef _BASE_EXPRESSION_
00026 #define _BASE_EXPRESSION_
00027 
00028 #include <base/base>
00029 #include <base/ReferencedObject>
00030 #include <base/Serializable>
00031 #include <base/Serializer>
00032 #include <base/Vector>
00033 #include <base/Matrix>
00034 
00035 #include <base/ExpressionNode>
00036 #include <base/ConstantExpression>
00037 #include <base/VariableExpression>
00038 #include <base/NegateExpression>
00039 #include <base/SumExpression>
00040 #include <base/DifferenceExpression>
00041 #include <base/ProductExpression>
00042 #include <base/QuotientExpression>
00043 #include <base/SinExpression>
00044 #include <base/CosExpression>
00045 
00046 #ifdef USE_BOOST_UBLAS
00047 #include <boost/numeric/ublas/vector.hpp>
00048 #endif
00049 
00050 namespace base {
00051 
00052 #ifdef USE_BOOST_UBLAS
00053 
00054 namespace ublas = boost::numeric::ublas; // alias
00055 
00056 // A Matrix|Vector of Expressions
00057 typedef ublas::matrix<Expression> ExpressionMatrix;
00058 typedef ublas::vector<Expression> ExpressionVector;
00059 
00060 #else
00061 typedef matrix<Expression> ExpressionMatrix;
00062 typedef vector<Expression> ExpressionVector;
00063 #endif
00064 
00065 
00066 //
00067 // An expression that can be evaluated with a parameter Vector
00068 //  and differentiated. Has value semantics.
00069 //  (represented as an ExpressionNode tree)
00070 
00071 class Expression : public Serializable
00072 {
00073   friend  void base::setIdentity( ExpressionMatrix& A );
00074   friend class VariableIndexer;
00075 
00076 public:
00077   Expression();
00078   Expression(Real constant);
00079   Expression(const Expression& e);
00080   Expression(const String& exprString); ///< construct from string - e.g. '2.3*cos(p[0])+p[2]/(4*p[1])'
00081 
00082   virtual String className() const { return String("Expression"); }
00083 
00084   Real       evaluate(const Vector& params) const;
00085   Expression differentiate( Expression withRespectTo ) const;
00086 
00087   void simplify(); ///< simplify the expression (constant sub-expression evaluation, common sub-expression elimination etc.)
00088   void operationCounts(Int& addsub, Int& multdiv, Int& trig) const; ///< calculate operation counts for evaluating the expression (added to args)
00089 
00090   String toString() const;
00091 
00092   struct VariableIndexer { Expression operator[](Int i) const; };
00093 
00094   static VariableIndexer p; ///< p[i] is an Expression that evaluates to the variable params[i]
00095 
00096   Expression& operator=(const Expression& e) { expr = e.expr; return *this; }
00097   Expression& operator+=(const Expression& e);
00098   Expression& operator-=(const Expression& e);
00099   Expression& operator*=(const Expression& e);
00100   Expression& operator/=(const Expression& e);
00101   Expression& negate();
00102   Expression& sin();
00103   Expression& cos();
00104 
00105   virtual void serialize(Serializer& s);
00106 
00107 protected:
00108   Expression(ref<ExpressionNode> expr)
00109     : expr(expr) {}
00110 
00111   ref<ExpressionNode> expr; ///< root of ExpressionNode tree
00112 
00113   // Simplification helper methods
00114   ref<ExpressionNode> simplifyConstantExpressions(ref<ExpressionNode> expr); ///< evaluate and replace constant expression subtrees with a single ConstantExpression
00115 
00116   // expression string parsing methods
00117   static bool peek(const String& s, Int pos, String next);
00118   inline static bool peek(const String& s, Int pos, String::value_type c) 
00119                    { if (pos<s.size()) return (s[pos] == c); else return false; }
00120   static SInt index(const String& s, Int& pos);
00121   static Real real(const String& s, Int& pos);
00122   
00123   static Expression expression(const String& s, Int& pos);
00124   static Expression term(const String& s, Int& pos);
00125   static Expression prod(const String& s, Int& pos);
00126   
00127   
00128   // Serialization helpers
00129   Serializable::SerializableDerivedInstantiator<SumExpression> sumInstantiator;
00130   Serializable::SerializableDerivedInstantiator<DifferenceExpression> differenceInstantiator;
00131   Serializable::SerializableDerivedInstantiator<ProductExpression> productInstantiator;
00132   Serializable::SerializableDerivedInstantiator<QuotientExpression> quotientInstantiator;
00133   Serializable::SerializableDerivedInstantiator<NegateExpression> negateInstantiator;
00134   Serializable::SerializableDerivedInstantiator<SinExpression> sinInstantiator;
00135   Serializable::SerializableDerivedInstantiator<CosExpression> cosInstantiator;
00136   Serializable::SerializableDerivedInstantiator<ConstantExpression> constantInstantiator;
00137   Serializable::SerializableDerivedInstantiator<VariableExpression> variableInstantiator;
00138 };
00139 
00140 
00141 inline std::ostream& operator<<(std::ostream& out, const Expression& e) // Output
00142 { return (out << e.toString()); }
00143 
00144 
00145 
00146 // function operators/operations
00147 inline Expression operator+(const Expression& lhs, const Expression& rhs)
00148 { Expression r(lhs); r+= rhs; return r; }
00149 
00150 inline Expression operator-(const Expression& lhs, const Expression& rhs)
00151 { Expression r(lhs); r-= rhs; return r; }
00152 
00153 inline Expression operator*(const Expression& lhs, const Expression& rhs)
00154 { Expression r(lhs); r*= rhs; return r; }
00155 
00156 inline Expression operator/(const Expression& lhs, const Expression& rhs)
00157 { Expression r(lhs); r/= rhs; return r; }
00158 
00159 inline Expression operator-(const Expression& e)
00160 { Expression r(e); r.negate(); return r; }
00161 
00162 inline Expression sin(const Expression& angle)
00163 { Expression r(angle); r.sin(); return r; }
00164 
00165 inline Expression cos(const Expression& angle)
00166 { Expression r(angle); r.cos(); return r; }
00167 
00168 
00169 
00170 // Functions for Matrix|Vector of Expressions
00171 
00172 #ifdef USE_BOOST_UBLAS
00173 
00174 inline ExpressionVector operator*(const ExpressionMatrix& A, const ExpressionVector& x)
00175 { return ublas::prod(A,x); }
00176 
00177 inline const base::ExpressionMatrix operator*( const ExpressionMatrix A, const ExpressionMatrix B)
00178 { return ublas::prod(A,B); }
00179 
00180 #else
00181 
00182 inline ExpressionVector operator*(const ExpressionMatrix& A, const ExpressionVector& x)
00183 {
00184   Assert(A.cols() == x.size());
00185   
00186   ExpressionVector r(A.rows());
00187 
00188   for(Int i=0; i<A.rows(); i++) {
00189     r(i) = 0;
00190     for(Int k=0; k<A.cols(); k++)
00191       r(i) += A(i,k) * x(k);
00192   }
00193  
00194   return r;
00195 }
00196 
00197 inline const base::ExpressionMatrix operator*( const ExpressionMatrix A, const ExpressionMatrix B)
00198 { ExpressionMatrix r(A); r*=B; return r; }
00199 
00200 
00201 #endif
00202 
00203 /// convert a Matrix into an ExpressionMatrix (of constant Expressions)
00204 ExpressionMatrix toExpressionMatrix(const base::Matrix& m);
00205 
00206 
00207 
00208 inline std::ostream& operator<<(std::ostream& out, const ExpressionMatrix& m) // Output
00209 { 
00210   for(Int r=0; r<m.size1(); r++) {
00211     for(Int c=0; c<m.size2(); c++) {
00212       out << m(r,c) << " ";
00213     }
00214     out << "\n";
00215   }
00216   return out;
00217 }
00218 
00219 inline std::ostream& operator<<(std::ostream& out, const ExpressionVector& v) // Output
00220 { 
00221   out << "[";
00222   for(Int i=0; i<v.size(); i++)
00223     out << v[i] << ((i!=v.size()-1)?",":"]");
00224   return out;
00225 }
00226 
00227 void base::simplify( ExpressionMatrix& m );
00228 base::Matrix base::evaluate( const ExpressionMatrix& m, const Vector& params );
00229 
00230 
00231 inline void base::operationCounts( ExpressionMatrix m, Int& addsub, Int& multdiv, Int& trig ) {
00232   for ( Int r=0; r < m.size1(); r++ ) {
00233     for ( Int c=0; c < m.size2(); c++ ) {
00234       m(r,c).operationCounts(addsub,multdiv,trig);
00235     }
00236   }
00237   return;
00238 }
00239 
00240 
00241 inline void base::serialize(base::Serializer& s, ExpressionMatrix& m)
00242 {
00243   Int rows(m.size1());
00244   Int cols(m.size2());
00245   s(rows,"rows");
00246   s(cols,"cols");
00247   if (s.isInput()) m.resize(rows,cols);
00248   for ( Int r=0; r < m.size1(); r++ ) 
00249     for ( Int c=0; c < m.size2(); c++ ) 
00250       s(m(r,c));
00251 }
00252 
00253 
00254 inline void base::serialize(base::Serializer& s, ExpressionVector& v)
00255 {
00256   Int dim(v.size());
00257   s(dim,"dim");
00258   if (s.isInput()) v.resize(dim);
00259   for ( Int i=0; i < v.size(); i++ ) 
00260     s(v[i]);
00261 }
00262 
00263 
00264 
00265 } // base
00266 
00267 #endif
00268 

Generated on Thu Jul 29 15:56:05 2004 for OpenSim by doxygen 1.3.6