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