00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 #ifndef _BASE_EXPRESSIONNODE_
00026 #define _BASE_EXPRESSIONNODE_
00027 
00028 #include <base/base>
00029 #include <base/ReferencedObject>
00030 #include <base/Serializable>
00031 #include <base/Serializer>
00032 #include <base/Vector>
00033 
00034 
00035 namespace base {
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 class ExpressionNode : public ReferencedObject, public Serializable
00044 {
00045 public:
00046   ExpressionNode() 
00047     : valueCached(false), derivCached(false) {}
00048 
00049   enum NodeType { Sum, Difference, Product, Quotient,
00050                   Negative, Constant, Variable,
00051                   Sine, Cosine,
00052                   Leaf=1024, UnaryOp = 2048, BinaryOp = 4096 };
00053 
00054   virtual NodeType type() const = 0; 
00055   bool isOperator() const { return (isUnaryOp() || isBinaryOp()); }
00056   bool isUnaryOp()  const { return Int(type() & UnaryOp); }
00057   bool isBinaryOp() const { return Int(type() & BinaryOp); }
00058   NodeType opType() const { return NodeType(Int(type()) & Int(Leaf-1)); }
00059 
00060   Real evaluate(const Vector& params) const 
00061     { 
00062       if (!valueCached)
00063         cacheValue(params);
00064       return value;
00065     }
00066 
00067   ref<ExpressionNode> differentiate( Int withRespectToIndex ) const 
00068     {   
00069       if (!(derivCached && (withRespectToIndex == derivWithRespToIndex)))
00070         cacheDerivative(withRespectToIndex);
00071       if (!derivative) { Assert(derivative); }
00072       return derivative;
00073     }
00074 
00075   virtual String toString() const = 0;
00076 
00077 protected:
00078   virtual void cacheValue(const Vector& params) const = 0; 
00079   virtual void resetCache() const = 0; 
00080 
00081   mutable bool valueCached;
00082   mutable Real value;
00083 
00084   virtual void cacheDerivative(Int withRespectToIndex) const = 0; 
00085   virtual void resetDerivCached() const = 0; 
00086 
00087   mutable bool derivCached;
00088   mutable Int derivWithRespToIndex;
00089   mutable ref<ExpressionNode> derivative;
00090 
00091   virtual void operationCounts(Int& addsub, Int& multdiv, Int& trig) const = 0;
00092 
00093   friend class BinaryOpExpression;
00094   friend class UnaryOpExpression;
00095   friend class Expression;
00096 };
00097 
00098 
00099 inline std::ostream& operator<<(std::ostream& out, const ExpressionNode& e) 
00100 { return (out << e.toString()); }
00101 
00102 
00103 } 
00104 
00105 #endif
00106