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
00028 #ifndef _EXPRESSION_HPP_
00029 #define _EXPRESSION_HPP_
00030
00031 #include <api_exception.h>
00032
00033 namespace coco {
00034
00035 class expression_node::parents_compare :
00036 public std::binary_function<expression_node, expression_node, bool>
00037 {
00038 public:
00040 bool operator()(const expression_node& __x, const expression_node& __y)
00041 const
00042 {
00043 if(__x.operator_type == __y.operator_type)
00044 {
00045 switch(__x.operator_type)
00046 {
00047 case EXPRINFO_GHOST:
00048 if(__x.node_num != __y.node_num)
00049 return __x.node_num < __y.node_num;
00050 break;
00051 case EXPRINFO_VARIABLE:
00052 if(__x.params.nn() != __y.params.nn())
00053 return __x.params.nn() < __y.params.nn();
00054 break;
00055 case EXPRINFO_CONSTANT:
00056 if(__x.params.is_allocated() != __y.params.is_allocated())
00057 return __x.params.is_allocated() < __y.params.is_allocated();
00058 if(__x.params.is_allocated())
00059 {
00060 if(__x.params.d() != __y.params.d())
00061 return __x.params.d() < __y.params.d();
00062 }
00063 else
00064 {
00065 if(__x.params.nd() != __y.params.nd())
00066 return __x.params.nd() < __y.params.nd();
00067 }
00068 break;
00069 }
00070 if(__x.n_children == __y.n_children)
00071 return __x.node_num < __y.node_num;
00072 return __x.n_children < __y.n_children;
00073 }
00074 return __x.operator_type < __y.operator_type;
00075 }
00076 };
00077
00078 class expression_node::children_compare :
00079 public std::binary_function<expression_node, expression_node, bool>
00080 {
00081 public:
00083 bool operator()(const expression_node& __x, const expression_node& __y)
00084 const
00085 {
00086 if(__x.sem.degree != __y.sem.degree)
00087 return __x.sem.degree < __y.sem.degree;
00088 if(__x.sem.dim != __y.sem.dim)
00089 return __x.sem.dim < __y.sem.dim;
00090 if(__x.operator_type == __y.operator_type)
00091 {
00092 switch(__x.operator_type)
00093 {
00094 case EXPRINFO_GHOST:
00095 if(__x.node_num != __y.node_num)
00096 return __x.node_num < __y.node_num;
00097 break;
00098 case EXPRINFO_VARIABLE:
00099 if(__x.params.nn() != __y.params.nn())
00100 return __x.params.nn() < __y.params.nn();
00101 break;
00102 case EXPRINFO_CONSTANT:
00103 if(__x.params.is_allocated() != __y.params.is_allocated())
00104 return __x.params.is_allocated() < __y.params.is_allocated();
00105 if(__x.params.is_allocated())
00106 {
00107 if(__x.params.d() != __y.params.d())
00108 return __x.params.d() < __y.params.d();
00109 }
00110 else
00111 {
00112 if(__x.params.nd() != __y.params.nd())
00113 return __x.params.nd() < __y.params.nd();
00114 }
00115 break;
00116 }
00117 if(__x.n_children == __y.n_children)
00118 return __x.node_num < __y.node_num;
00119 return __x.n_children < __y.n_children;
00120 }
00121 return __x.operator_type < __y.operator_type;
00122 }
00123 };
00124
00125 class expression_node::parents_compare_eq :
00126 public std::binary_function<expression_node, expression_node, bool>
00127 {
00128 public:
00130 bool operator()(const expression_node& __x, const expression_node& __y)
00131 const
00132 {
00133 if(__x.n_children != __y.n_children)
00134 return false;
00135 if(__x.operator_type == __y.operator_type)
00136 {
00137 switch(__x.operator_type)
00138 {
00139 case EXPRINFO_GHOST:
00140 return __x.node_num == __y.node_num;
00141 break;
00142 case EXPRINFO_VARIABLE:
00143 return __x.params.nn() == __y.params.nn();
00144 break;
00145 case EXPRINFO_CONSTANT:
00146 if(__x.params.is_allocated() != __y.params.is_allocated())
00147 return false;
00148 if(__x.params.is_allocated())
00149 return __x.params.d() == __y.params.d();
00150 else
00151 return __x.params.nd() == __y.params.nd();
00152 break;
00153 case EXPRINFO_SUM:
00154 case EXPRINFO_MAX:
00155 case EXPRINFO_MIN:
00156 case EXPRINFO_SQUARE:
00157 case EXPRINFO_SQROOT:
00158 case EXPRINFO_ABS:
00159 case EXPRINFO_POW:
00160 case EXPRINFO_EXP:
00161 case EXPRINFO_LOG:
00162 case EXPRINFO_SIN:
00163 case EXPRINFO_COS:
00164 if(__x.params.nd() != __y.params.nd())
00165 return false;
00166
00167 case EXPRINFO_ATAN2:
00168 {
00169 std::vector<double>::const_iterator _bx, _by;
00170
00171 for(_bx = __x.coeffs.begin(), _by = __y.coeffs.begin();
00172 _bx != __x.coeffs.end(); ++_bx, ++_by)
00173 {
00174 if(*_bx != *_by) return false;
00175 }
00176 }
00177 break;
00178 case EXPRINFO_PROD:
00179 case EXPRINFO_INVERT:
00180 case EXPRINFO_DIV:
00181 if(__x.params.nd() != __y.params.nd())
00182 return false;
00183 break;
00184 case EXPRINFO_INTPOWER:
00185 if(__x.params.nn() != __y.params.nn() ||
00186 __x.coeffs[0] != __y.coeffs[0])
00187 return false;
00188 break;
00189 case EXPRINFO_GAUSS:
00190 if(__x.params.d()[0] != __y.params.d()[0] ||
00191 __x.params.d()[1] != __y.params.d()[1] ||
00192 __x.coeffs[0] != __y.coeffs[0])
00193 return false;
00194 break;
00195 case EXPRINFO_POLY:
00196 throw nyi_exception("expression_node::parents_compare_eq: POLY");
00197 break;
00198 case EXPRINFO_LIN:
00199 case EXPRINFO_QUAD:
00200 return false;
00201 default:
00202 throw api_exception(apiee_internal,
00203 std::string("expression_node::parents_compare_eq: unknown function type ")+convert_to_str(__x.operator_type));
00204 return false;
00205 break;
00206 }
00207 return true;
00208 }
00209 return false;
00210 }
00211 };
00212
00214 inline bool expression_node::operator<(const expression_node& __x) const
00215 {
00216 return this->node_num < __x.node_num;
00217 }
00218
00224 class expression_print_visitor : public preorder_visitor<expression_node, int>
00225 {
00227 int n;
00229 int nnum;
00231 std::ostream& o;
00233 std::vector<bool>* printed;
00234 public:
00237 expression_print_visitor(std::vector<bool>& __p, std::ostream& __o = std::cout)
00238 : o(__o)
00239 { printed = &__p; }
00241 expression_print_visitor(const expression_print_visitor& __p) : o(__p.o)
00242 { n = __p.n; nnum = __p.nnum; printed = __p.printed; }
00244 ~expression_print_visitor() {}
00245
00247
00248 bool preorder(const expression_node &r)
00249 { n = 0;
00250 nnum = r.node_num;
00251 if((int)(*printed).size() <= nnum)
00252 (*printed).insert((*printed).end(), nnum - (*printed).size()+1,
00253 false);
00254 if(!(*printed)[nnum])
00255 {
00256 (*printed)[nnum] = true;
00257 o << r;
00258 }
00259 else
00260 return false;
00261 return true;
00262 }
00263 int vvalue() { return -1; }
00264 int value() { return nnum; }
00265 void collect(const expression_node &r, int __r)
00266 {
00267 if(__r >= 0)
00268 {
00269 o << "<E> " << r.node_num << ' ' << __r << ' ' <<
00270 r.coeffs[n] << std::endl;
00271 n++;
00272 }
00273 }
00275 };
00276
00279 inline std::ostream& __wr_interval(std::ostream& o, const interval& __i)
00280 {
00281 if(__i.inf() != -COCO_INF || __i.sup() != COCO_INF)
00282 {
00283 o << "[";
00284 if(__i.inf() == -COCO_INF)
00285 o << "-I";
00286 else
00287 o << __i.inf();
00288 o << ",";
00289 if(__i.sup() == COCO_INF)
00290 o << "I";
00291 else
00292 o << __i.sup();
00293 o << "]";
00294 }
00295 return o;
00296 }
00297
00298 }
00299
00300 #endif