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