00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #if !defined(_xyzzy_delta_hxx_)
00022 # define _xyzzy_delta_hxx_
00023
00024 #include <utility>
00025 #include "xyzzy/slist.hxx"
00026 #include "xyzzy/array.hxx"
00027
00028 namespace xyzzy
00029 {
00030
00031 using std::pair;
00032
00033 class TDeltaDouble
00034 {
00035 public:
00036 static void setTrace(bool on);
00037
00038 static void dumpTrace(const char *fname);
00039
00040 protected:
00041 static void addDelta(double d);
00042
00043 static bool m_stDoTrace;
00044
00045 private:
00046 static PTSlist<double> m_stList;
00047 };
00048
00049 template<typename TR>
00050 class PTDelta : private TDeltaDouble
00051 {
00052 public:
00053 explicit PTDelta()
00054 {}
00055
00056 PTDelta(double gold, TR rev)
00057 : m_dat(gold, rev)
00058 {
00059 delta(*this);
00060 }
00061
00062 PTDelta(double gold)
00063 : m_dat(gold, gold)
00064 {}
00065
00066 const PTDelta&
00067 operator =(double gold)
00068 {
00069 m_dat.first = gold;
00070 m_dat.second = gold;
00071 return *this;
00072 }
00073
00074 const PTDelta&
00075 operator =(const PTDelta& r)
00076 {
00077 if (this != &r)
00078 {
00079 m_dat.first = r.gold();
00080 m_dat.second = r.rev();
00081 delta(*this);
00082 }
00083 return *this;
00084 }
00085
00086 double gold() const
00087 {
00088 return m_dat.first;
00089 }
00090
00091 TR rev() const
00092 {
00093 return m_dat.second;
00094 }
00095
00096 static void toDouble(const PTArray<PTDelta<TR> > &r, PTArray<double> &dbl,
00097 bool rev = true)
00098 {
00099 const int N = r.length();
00100 for (int i = 0; i < N; i++)
00101 {
00102 const PTDelta<TR> &ri = r[i];
00103 dbl[i] = rev ? (double)ri.rev() : (double)ri.gold();
00104 if (rev && m_stDoTrace)
00105 {
00106 delta(ri);
00107 }
00108 }
00109 }
00110
00111 const PTDelta& operator +=(const PTDelta& r);
00112
00113 const PTDelta& operator *=(const PTDelta& r);
00114
00115 private:
00116 pair<double, TR> m_dat;
00117
00118 static void delta(const PTDelta &r)
00119 {
00120 if (m_stDoTrace)
00121 addDelta(r.rev() - r.gold());
00122 }
00123 };
00124
00125 template<typename TR>
00126 PTDelta<TR>
00127 operator +(const PTDelta<TR> &a, const PTDelta<TR> &b)
00128 {
00129 double y2 = a.gold() + b.gold();
00130 TR y1 = a.rev() + b.rev();
00131 return PTDelta<TR>(y2, y1);
00132 }
00133
00134 template<typename TR>
00135 PTDelta<TR>
00136 operator *(const PTDelta<TR> &a, const PTDelta<TR> &b)
00137 {
00138 double y2 = a.gold() * b.gold();
00139 TR y1 = a.rev() * b.rev();
00140 return PTDelta<TR>(y2, y1);
00141 }
00142
00143 template<typename TR>
00144 const PTDelta<TR>&
00145 PTDelta<TR>::operator +=(const PTDelta& r)
00146 {
00147 this->operator=(*this + r);
00148 return *this;
00149 }
00150
00151 template<typename TR>
00152 const PTDelta<TR>&
00153 PTDelta<TR>::operator *=(const PTDelta& r)
00154 {
00155 this->operator=(*this * r);
00156 return *this;
00157 }
00158
00159 }
00160 #endif //_xyzzy_delta_hxx_