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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef _mapunimi_h_
00036 #define _mapunimi_h_
00037
00038 #include <string>
00039 #include <iostream>
00040 #include <sstream>
00041 #include "maptype.h"
00042
00043
00044 #include "interval/doubleInterval.h"
00045
00046
00047 namespace unifexp {
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 template <class numType>
00059 class mapUnimodalIntv: public mapType<numType>
00060 {
00061 public:
00062
00063
00064
00065 mapUnimodalIntv (const numType &_gamma1, const numType &_gamma2 = 1);
00066
00067
00068 std::string name () const;
00069
00070
00071 int countCritical () const;
00072
00073
00074 numType criticalPoint (int n) const;
00075
00076
00077 numType leftBound () const;
00078
00079
00080 numType rightBound () const;
00081
00082
00083 void image (const numType &x1, const numType &x2,
00084 numType &y1, numType &y2) const;
00085
00086
00087
00088 numType minLogDerivative (const numType &x1, const numType &x2,
00089 const numType &y1, const numType &y2) const;
00090
00091 private:
00092
00093 interval gamma;
00094
00095
00096 interval log2gamma;
00097
00098
00099
00100
00101 numType gammaRoot (numType x, bool upperBound) const;
00102
00103 };
00104
00105
00106
00107 template <class numType>
00108 inline mapUnimodalIntv<numType>::mapUnimodalIntv (const numType &_gamma1,
00109 const numType &_gamma2):
00110 gamma (interval (_gamma1, _gamma1) / interval (_gamma2, _gamma2)),
00111 log2gamma (log (gamma * 2))
00112 {
00113 return;
00114 }
00115
00116 template <class numType>
00117 inline std::string mapUnimodalIntv<numType>::name () const
00118 {
00119 std::ostringstream nameStr;
00120 nameStr << "unimodal-intv-" << gamma. leftBound ();
00121 return nameStr. str ();
00122 }
00123
00124 template <class numType>
00125 inline int mapUnimodalIntv<numType>::countCritical () const
00126 {
00127 return 1;
00128 }
00129
00130 template <class numType>
00131 inline numType mapUnimodalIntv<numType>::criticalPoint (int n) const
00132 {
00133 return 0.0;
00134 }
00135
00136 template <class numType>
00137 inline numType mapUnimodalIntv<numType>::leftBound () const
00138 {
00139 return -1;
00140 }
00141
00142 template <class numType>
00143 inline numType mapUnimodalIntv<numType>::rightBound () const
00144 {
00145 return 1;
00146 }
00147
00148 template <class numType>
00149 inline numType mapUnimodalIntv<numType>::gammaRoot (numType x,
00150 bool upperBound) const
00151 {
00152
00153 const numType zero (0);
00154 if (x == zero)
00155 return zero;
00156
00157
00158 if (x < zero)
00159 x = -x;
00160
00161
00162 if (upperBound)
00163 return exp (log (interval (x, x)) / gamma). rightBound ();
00164 else
00165 return exp (log (interval (x, x)) / gamma). leftBound ();
00166
00167 }
00168
00169 template <class numType>
00170 inline void mapUnimodalIntv<numType>::image (const numType &x1,
00171 const numType &x2, numType &y1, numType &y2) const
00172 {
00173 if (x2 < x1)
00174 throw "Image computation: Wrong interval for 'x'.";
00175 if ((x1 <= 0) && (0 <= x2))
00176 {
00177 const numType x = (-x1 < x2) ? x2 : -x1;
00178 y1 = -(this -> paramMax);
00179 y2 = (power (interval (x, x), gamma) * 2 -
00180 this -> paramMin). rightBound ();
00181 }
00182 else
00183 {
00184 interval img = power ((x2 < 0) ? interval (-x2, -x1) :
00185 interval (x1, x2), gamma) * 2 -
00186 interval (this -> paramMin, this -> paramMax);
00187 y1 = img. leftBound ();
00188 y2 = img. rightBound ();
00189 }
00190 capd::rounding::DoubleRounding::roundNearest ();
00191 return;
00192 }
00193
00194 template <class numType>
00195 inline numType mapUnimodalIntv<numType>::minLogDerivative (const numType &x1,
00196 const numType &x2, const numType &y1, const numType &y2) const
00197 {
00198
00199 if (x2 < x1)
00200 throw "MinLogDerivative: Wrong interval for 'x'.";
00201 if (y2 < y1)
00202 throw "MinLogDerivative: Wrong interval for 'y'.";
00203 if (((x1 < 0) || (x1 == 0)) && ((x2 == 0) || (0 < x2)))
00204 throw "MinLogDerivative: The interval contains zero.";
00205
00206
00207
00208
00209
00210 numType result;
00211 if (gamma. rightBound () < 1)
00212 {
00213 const numType sum = ((interval (y2, y2) +
00214 this -> paramMax) / 2). rightBound ();
00215 const numType preImg = (0 < sum) ?
00216 gammaRoot (sum, true) : 0;
00217 const numType x = (0 < x1) ? x2 : -x1;
00218 const numType endPoint = (x < preImg) ? x : preImg;
00219 result = (log2gamma + (gamma - 1) *
00220 log (interval (endPoint, endPoint))). leftBound ();
00221 }
00222 else
00223 {
00224 const numType sum = ((interval (y1, y1) +
00225 this -> paramMin) / 2). leftBound ();
00226 if ((sum < 0) || (sum == 0))
00227 throw "MinLogDerivative: Zero in the preimage.";
00228 const numType preImg = (0 < sum) ?
00229 gammaRoot (sum, false) : 0;
00230 const numType x = (0 < x1) ? x1 : -x2;
00231 const numType endPoint = (x < preImg) ? preImg : x;
00232 result = (log2gamma + (gamma - 1) *
00233 log (interval (endPoint, endPoint))). leftBound ();
00234 }
00235 capd::rounding::DoubleRounding::roundNearest ();
00236 return result;
00237 }
00238
00239
00240 }
00241
00242 #endif // _mapunimi_h_
00243
00244
00245