00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00027 #ifndef _CINT_EVALUATOR_H_
00028 #define _CINT_EVALUATOR_H_
00029
00030 #include <coconut_config.h>
00031 #include <evaluator.h>
00032 #include <expression.h>
00033 #include <model.h>
00034 #include <eval_main.h>
00035 #include <linalg.h>
00036 #include <math.h>
00037 #include <cinterval.h>
00038
00039 using namespace vgtl;
00040
00041 typedef cinterval (*cinterval_evaluator)(const std::vector<cinterval>* __x,
00042 const variable_indicator& __v);
00043
00044 struct cinterval_eval_type
00045 {
00046 const std::vector<cinterval>* x;
00047 std::vector<cinterval>* cache;
00048 const model* mod;
00049 void *p;
00050 cinterval d;
00051 int info;
00052 cinterval r;
00053 unsigned int n;
00054 };
00055
00056 class cinterval_eval : public
00057 cached_forward_evaluator_base<cinterval_eval_type,expression_node,cinterval,
00058 model::walker>
00059 {
00060 private:
00061 typedef cached_forward_evaluator_base<cinterval_eval_type,expression_node,
00062 cinterval,model::walker> _Base;
00063
00064 protected:
00065 bool is_cached(const node_data_type& __data)
00066 {
00067 if(__data.operator_type == EXPRINFO_LIN ||
00068 __data.operator_type == EXPRINFO_QUAD)
00069 return true;
00070 else
00071 return false;
00072 #if 0
00073 if(eval_data.cache && __data.n_parents > 1 && __data.n_children > 0)
00074 return true;
00075 else
00076 return false;
00077 #endif
00078 }
00079
00080 private:
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 public:
00111 cinterval_eval(const std::vector<cinterval>& __x, const variable_indicator& __v,
00112 const model& __m, std::vector<cinterval>* __c) : _Base()
00113 {
00114 eval_data.x = &__x;
00115 eval_data.cache = __c;
00116 eval_data.mod = &__m;
00117 eval_data.d = 0.;
00118 eval_data.p = NULL;
00119 v_ind = &__v;
00120 eval_data.n = 0;
00121 }
00122
00123 cinterval_eval(const cinterval_eval& __v) : _Base(__v) {}
00124
00125 ~cinterval_eval() {}
00126
00127 model::walker short_cut_to(const expression_node& __data)
00128 { return eval_data.mod->node(0); }
00129
00130 void initialize() { return; }
00131
00132 int initialize(const expression_node& __data)
00133 {
00134 if(__data.ev && (*__data.ev)[FUNC_CRANGE])
00135
00136 {
00137 eval_data.r =
00138 (*(cinterval_evaluator)(*__data.ev)[FUNC_CRANGE])(eval_data.x,
00139 *v_ind);
00140 return 0;
00141 }
00142 else
00143 {
00144 switch(__data.operator_type)
00145 {
00146 case EXPRINFO_SUM:
00147 case EXPRINFO_PROD:
00148 case EXPRINFO_MAX:
00149 case EXPRINFO_MIN:
00150 case EXPRINFO_INVERT:
00151 case EXPRINFO_DIV:
00152 eval_data.r = __data.params.nd();
00153 break;
00154 case EXPRINFO_MONOME:
00155 case EXPRINFO_IN:
00156 case EXPRINFO_AND:
00157 case EXPRINFO_NOGOOD:
00158 eval_data.r = 1.;
00159 break;
00160 case EXPRINFO_ALLDIFF:
00161 eval_data.p = (void*) new std::vector<cinterval>;
00162 ((std::vector<cinterval>*)eval_data.p)->reserve(__data.n_children);
00163
00164 case EXPRINFO_MEAN:
00165 case EXPRINFO_IF:
00166 case EXPRINFO_OR:
00167 case EXPRINFO_NOT:
00168 case EXPRINFO_COUNT:
00169 case EXPRINFO_SCPROD:
00170 case EXPRINFO_NORM:
00171 case EXPRINFO_LEVEL:
00172 eval_data.r = 0.;
00173 break;
00174 case EXPRINFO_DET:
00175 case EXPRINFO_PSD:
00176
00177 break;
00178 case EXPRINFO_COND:
00179 case EXPRINFO_FEM:
00180 case EXPRINFO_MPROD:
00181
00182 break;
00183 }
00184 return 1;
00185 }
00186 }
00187
00188 void calculate(const expression_node& __data)
00189 {
00190 if(__data.operator_type > 0)
00191 {
00192 eval_data.r = __data.i_evaluate(-1, __data.params.nn(), *eval_data.x,
00193 *v_ind, eval_data.r, cintval(0.0), NULL);
00194 }
00195 eval_data.r.intersect(__data.f_bounds);
00196 }
00197
00198 void retrieve_from_cache(const expression_node& __data)
00199 {
00200 if(__data.operator_type == EXPRINFO_LIN)
00201 {
00202 const matrix<double>::Row& lrw(eval_data.mod->lin[__data.params.nn()]);
00203 matrix<double>::Row::const_iterator _x, _e;
00204
00205 eval_data.r = cinterval(0.);
00206 for(_x = lrw.begin(); _x != _e; ++_x)
00207 eval_data.r += (*eval_data.x)[_x.index()] * *_x;
00208 }
00209 else if(__data.operator_type == EXPRINFO_QUAD)
00210 {
00211 throw "Interval Evaluation of QUAD: NYI!";
00212 }
00213 else
00214 eval_data.r = (*eval_data.cache)[__data.node_num];
00215 }
00216
00217 int update(const cinterval& __rval)
00218 {
00219 eval_data.r = __rval;
00220 return 0;
00221 }
00222
00223 int update(const expression_node& __data, const cinterval& __rval)
00224 {
00225 cinterval __x;
00226 int ret = 0;
00227 if(__data.operator_type < 0)
00228 {
00229 switch(__data.operator_type)
00230 {
00231 case EXPRINFO_CONSTANT:
00232 eval_data.r = __data.params.nd();
00233 break;
00234 case EXPRINFO_VARIABLE:
00235 eval_data.r = (*eval_data.x)[__data.params.nn()];
00236 break;
00237 case EXPRINFO_SUM:
00238 case EXPRINFO_MEAN:
00239 eval_data.r += __data.coeffs[eval_data.n++]*__rval;
00240 break;
00241 case EXPRINFO_PROD:
00242
00243 eval_data.r *= __rval;
00244 if(eval_data.r == 0.) ret = -1;
00245 break;
00246 case EXPRINFO_MONOME:
00247
00248 eval_data.r *= __power(__data.coeffs[eval_data.n], __rval,
00249 __data.params.n()[eval_data.n]);
00250 if(eval_data.r == 0.) ret = -1;
00251 eval_data.n++;
00252 break;
00253 case EXPRINFO_MAX:
00254
00255 { cinterval h = __rval * __data.coeffs[eval_data.n++];
00256 eval_data.r = imax(eval_data.r, h);
00257 }
00258 break;
00259 case EXPRINFO_MIN:
00260
00261 { cinterval h = __rval * __data.coeffs[eval_data.n++];
00262 eval_data.r = imin(eval_data.r, h);
00263 }
00264 break;
00265 case EXPRINFO_SCPROD:
00266 { cinterval h = __data.coeffs[eval_data.n]*__rval;
00267
00268
00269 if(eval_data.n & 1)
00270 eval_data.r += __data.coeffs[eval_data.n]*__rval*h;
00271 else
00272 eval_data.d = h;
00273 }
00274 eval_data.n++;
00275 break;
00276 case EXPRINFO_NORM:
00277 if(__data.params.nd() != 2.)
00278 {
00279 std::cerr << "Non-euclidean norms NYI" << std::endl;
00280 throw "NYI";
00281 }
00282 else
00283 {
00284 cinterval h = __data.coeffs[eval_data.n++]*__rval;
00285 eval_data.r += sqr(h);
00286 }
00287 if(eval_data.n == __data.n_children && __data.params.nd() == 2.)
00288 eval_data.r = sqrt(eval_data.r);
00289 break;
00290 case EXPRINFO_INVERT:
00291 eval_data.r /= __rval;
00292 break;
00293 case EXPRINFO_DIV:
00294
00295
00296 if(eval_data.n == 0)
00297 eval_data.r *= __rval;
00298 else
00299 eval_data.r /= __rval;
00300 ++eval_data.n;
00301 break;
00302 case EXPRINFO_SQUARE:
00303 { cinterval h = __data.coeffs[0]*__rval+__data.params.nd();
00304 eval_data.r = sqr(h);
00305 }
00306 break;
00307 case EXPRINFO_INTPOWER:
00308 eval_data.r = __power(__data.coeffs[0], __rval, __data.params.nn());
00309 break;
00310 case EXPRINFO_SQROOT:
00311 eval_data.r = sqrt(__data.coeffs[0]*__rval+__data.params.nd());
00312 break;
00313 case EXPRINFO_ABS:
00314 eval_data.r = abs(__data.coeffs[0]*__rval+__data.params.nd());
00315 break;
00316 case EXPRINFO_POW:
00317 { cinterval h = __rval * __data.coeffs[eval_data.n];
00318 if(eval_data.n == 0)
00319 eval_data.r = h+__data.params.nd();
00320 else
00321 eval_data.r = pow(eval_data.r, h);
00322 }
00323 ++eval_data.n;
00324 break;
00325 case EXPRINFO_EXP:
00326 eval_data.r = exp(__rval*__data.coeffs[0]+__data.params.nd());
00327 break;
00328 case EXPRINFO_LOG:
00329 eval_data.r = log(__rval*__data.coeffs[0]+__data.params.nd());
00330 break;
00331 case EXPRINFO_SIN:
00332 eval_data.r = sin(__rval*__data.coeffs[0]+__data.params.nd());
00333 break;
00334 case EXPRINFO_COS:
00335 eval_data.r = cos(__rval*__data.coeffs[0]+__data.params.nd());
00336 break;
00337 case EXPRINFO_ATAN2:
00338 { cinterval h = __rval * __data.coeffs[eval_data.n];
00339 if(eval_data.n == 0)
00340 eval_data.r = h;
00341 else
00342 eval_data.r = atan2(eval_data.r, h);
00343 ++eval_data.n;
00344 }
00345 break;
00346 case EXPRINFO_GAUSS:
00347 { cinterval h = (__data.coeffs[0]*__rval-__data.params.d()[0])/
00348 __data.params.d()[1];
00349 eval_data.r = gauss(h);
00350 }
00351 break;
00352 case EXPRINFO_POLY:
00353 std::cerr << "Polynomes NYI" << std::endl;
00354 throw "NYI";
00355 break;
00356 case EXPRINFO_LIN:
00357 case EXPRINFO_QUAD:
00358
00359 break;
00360 case EXPRINFO_IN:
00361 {
00362 __x = __data.coeffs[eval_data.n]*__rval;
00363 const cinterval& i(__data.params.i()[eval_data.n]);
00364 if(i.disjoint(__x))
00365 {
00366 eval_data.r = -1.;
00367 ret = -1;
00368 }
00369 else if(eval_data.r != cinterval(-1.))
00370 {
00371 if(!i.superset(__x))
00372 {
00373 if(i.sup() == __x.inf() || i.inf() == __x.sup())
00374
00375 eval_data.r = cinterval(-1.,0.);
00376 else if(eval_data.r.sup() > 0)
00377 eval_data.r = cinterval(-1.,1.);
00378 }
00379 else if(i.inf() == __x.inf() || i.sup() == __x.sup())
00380
00381
00382 {
00383 if(eval_data.r.inf() == 1.)
00384 {
00385 if(__x.is_thin())
00386 eval_data.r = 0.;
00387 else
00388 eval_data.r = cinterval(0.,1.);
00389 }
00390 else if(__x.is_thin() && eval_data.r.inf() == 0.)
00391 eval_data.r = 0.;
00392 }
00393
00394 }
00395 }
00396 eval_data.n++;
00397 break;
00398 case EXPRINFO_IF:
00399 __x = __rval * __data.coeffs[eval_data.n];
00400 if(eval_data.n == 0)
00401 {
00402 const cinterval& i(__data.params.ni());
00403 if(i.superset(__x))
00404 eval_data.info = 0;
00405 else if(i.disjoint(__x))
00406 {
00407 eval_data.info = 1;
00408 ret = 1;
00409 }
00410 else
00411 eval_data.info = 2;
00412 }
00413 else if(eval_data.n == 1)
00414 {
00415 eval_data.r = __x;
00416 if(eval_data.info == 0)
00417 ret = -1;
00418 }
00419 else
00420 {
00421 if(eval_data.info == 1)
00422 eval_data.r = __x;
00423 else
00424 eval_data.r = eval_data.r.hull(__x);
00425 }
00426 eval_data.n += ret+1;
00427 break;
00428 case EXPRINFO_AND:
00429 { __x = __data.coeffs[eval_data.n]*__rval;
00430 const cinterval& i(__data.params.i()[eval_data.n]);
00431 if(eval_data.r != 0.)
00432 {
00433 if(i.disjoint(__x))
00434 {
00435 eval_data.r = 0;
00436 ret = -1;
00437 }
00438 else if(!i.superset(__x))
00439 eval_data.r = cinterval(0.,1.);
00440
00441 }
00442 }
00443 eval_data.n++;
00444 break;
00445 case EXPRINFO_OR:
00446 { __x = __data.coeffs[eval_data.n]*__rval;
00447 const cinterval& i(__data.params.i()[eval_data.n]);
00448 if(eval_data.r != 1.)
00449 {
00450 if(i.superset(__x))
00451 {
00452 eval_data.r = 1;
00453 ret = -1;
00454 }
00455 else if(!i.disjoint(__x))
00456 eval_data.r = cinterval(0.,1.);
00457 }
00458 }
00459 eval_data.n++;
00460 break;
00461 case EXPRINFO_NOT:
00462 { __x = __data.coeffs[0]*__rval;
00463 const cinterval& i(__data.params.ni());
00464 if(i.superset(__x))
00465 eval_data.r = 0;
00466 else if(i.disjoint(__x))
00467 eval_data.r = 1;
00468 else
00469 eval_data.r = cinterval(0.,1.);
00470 }
00471 break;
00472 case EXPRINFO_IMPLIES:
00473 { const cinterval& i(__data.params.i()[eval_data.n]);
00474 __x = __rval * __data.coeffs[eval_data.n];
00475 if(eval_data.n == 0)
00476 {
00477 if(i.disjoint(__x))
00478 {
00479 eval_data.r = 1.;
00480 ret = -1;
00481 }
00482 else if(!i.superset(__x))
00483 eval_data.r = cinterval(0.,1.);
00484 else
00485 eval_data.r = cinterval(0.);
00486 }
00487 else
00488 {
00489 if(i.superset(__x))
00490 eval_data.r = 1.;
00491 else if(!i.disjoint(__x))
00492 eval_data.r = cinterval(0.,1.);
00493
00494 }
00495 ++eval_data.n;
00496 }
00497 break;
00498 case EXPRINFO_COUNT:
00499 { __x = __data.coeffs[eval_data.n]*__rval;
00500 const cinterval& i(__data.params.i()[eval_data.n]);
00501 if(i.superset(__x))
00502 eval_data.r += 1;
00503 else if(!i.disjoint(__x))
00504 eval_data.r += cinterval(0.,1.);
00505 }
00506 eval_data.n++;
00507 break;
00508 case EXPRINFO_ALLDIFF:
00509 { __x = __data.coeffs[eval_data.n]*__rval;
00510 for(std::vector<cinterval>::const_iterator _b =
00511 ((std::vector<cinterval>*)eval_data.p)->begin();
00512 _b != ((std::vector<cinterval>*)eval_data.p)->end(); ++_b)
00513 {
00514 cinterval __h = abs(__x-*_b);
00515 if(__h.sup() <= __data.params.nd())
00516 {
00517 eval_data.r = 0;
00518 ret = -1;
00519 break;
00520 }
00521 else if(__h.inf() <= __data.params.nd())
00522 eval_data.r = cinterval(0.,1.);
00523 }
00524 if(ret != -1)
00525 ((std::vector<cinterval>*) eval_data.p)->push_back(__x);
00526 }
00527 eval_data.n++;
00528 if(eval_data.n == __data.n_children || ret == -1)
00529 delete (std::vector<cinterval>*) eval_data.p;
00530 break;
00531 case EXPRINFO_HISTOGRAM:
00532 std::cerr << "int_evaluator: histogram NYI" << std::endl;
00533 throw "NYI";
00534 break;
00535 case EXPRINFO_LEVEL:
00536 { int lo = (int)eval_data.r.inf();
00537 int hi = (int)eval_data.r.sup();
00538 __x = __data.coeffs[eval_data.n]*__rval;
00539 cinterval _h;
00540
00541
00542 if(hi != INT_MAX)
00543 {
00544 while(hi < __data.params.im().nrows())
00545 {
00546 _h = __data.params.im()[hi][eval_data.n];
00547 if(_h.superset(__x))
00548 break;
00549 hi++;
00550 }
00551 if(hi == __data.params.im().nrows())
00552 hi = INT_MAX;
00553 }
00554
00555 if(lo != INT_MAX)
00556 {
00557 while(lo < __data.params.im().nrows())
00558 {
00559 _h = __data.params.im()[lo][eval_data.n];
00560 if(!_h.disjoint(__x))
00561 break;
00562 lo++;
00563 }
00564 if(lo == __data.params.im().nrows())
00565 lo = INT_MAX;
00566 }
00567 if(hi == INT_MAX && lo == INT_MAX)
00568 {
00569 eval_data.r = INT_MAX;
00570 ret = -1;
00571 }
00572 else
00573 eval_data.r = cinterval(lo+0.,hi+0.);
00574 }
00575 eval_data.n++;
00576 break;
00577 case EXPRINFO_NEIGHBOR:
00578
00579
00580
00581 if(eval_data.n == 0)
00582 eval_data.r = __data.coeffs[0]*__rval;
00583 else
00584 {
00585 cinterval h = eval_data.r;
00586 eval_data.r = 0;
00587 __x = __data.coeffs[1]*__rval;
00588 for(unsigned int i = 0; i < __data.params.n().size(); i+=2)
00589 {
00590 if(h == __data.params.n()[i]+0. &&
00591 __x == __data.params.n()[i+1]+0.)
00592 {
00593 eval_data.r = 1;
00594 break;
00595 }
00596 else if(h.contains(__data.params.n()[i]+0.) &&
00597 __x.contains(__data.params.n()[i+1]+0.))
00598 {
00599 eval_data.r = cinterval(0.,1.);
00600 break;
00601 }
00602 }
00603 }
00604 eval_data.n++;
00605 break;
00606 case EXPRINFO_NOGOOD:
00607 __x = __data.coeffs[eval_data.n]*__rval;
00608 if(eval_data.r != 0.)
00609 {
00610 if(!__x.contains(__data.params.n()[eval_data.n]+0.))
00611 {
00612 eval_data.r = 0.;
00613 ret = -1;
00614 }
00615 else if(__x != __data.params.n()[eval_data.n]+0.)
00616 eval_data.r = cinterval(0.,1.);
00617 }
00618 eval_data.n++;
00619 break;
00620 case EXPRINFO_EXPECTATION:
00621 std::cerr << "int_evaluator: E NYI" << std::endl;
00622 throw "NYI";
00623 break;
00624 case EXPRINFO_INTEGRAL:
00625 std::cerr << "int_evaluator: INT NYI" << std::endl;
00626 throw "NYI";
00627 break;
00628 case EXPRINFO_LOOKUP:
00629 case EXPRINFO_PWLIN:
00630 case EXPRINFO_SPLINE:
00631 case EXPRINFO_PWCONSTLC:
00632 case EXPRINFO_PWCONSTRC:
00633 std::cerr << "int_evaluator: Table Operations NYI" << std::endl;
00634 throw "NYI";
00635 break;
00636 case EXPRINFO_DET:
00637 case EXPRINFO_COND:
00638 case EXPRINFO_PSD:
00639 case EXPRINFO_MPROD:
00640 case EXPRINFO_FEM:
00641 std::cerr << "int_evaluator: Matrix Operations NYI" << std::endl;
00642 throw "NYI";
00643 break;
00644 case EXPRINFO_RE:
00645 case EXPRINFO_IM:
00646 case EXPRINFO_ARG:
00647 case EXPRINFO_CPLXCONJ:
00648 std::cerr << "int_evaluator: Complex Numbers NYI" << std::endl;
00649 throw "NYI";
00650 break;
00651 case EXPRINFO_CMPROD:
00652 case EXPRINFO_CGFEM:
00653 std::cerr << "int_evaluator: Const Matrix Operations NYI" << std::endl;
00654 throw "NYI";
00655 break;
00656 default:
00657 std::cerr << "int_evaluator: unknown function type " <<
00658 __data.operator_type << std::endl;
00659 throw "Programming error";
00660 break;
00661 }
00662 }
00663 else if(__data.operator_type > 0)
00664
00665 eval_data.r = __data.i_evaluate(eval_data.n++, __data.params.nn(),
00666 *eval_data.x, *v_ind, eval_data.r, __rval, NULL);
00667
00668
00669 if(eval_data.cache)
00670 (*eval_data.cache)[__data.node_num] = eval_data.r;
00671 return ret;
00672 }
00673
00674 cinterval calculate_value(bool eval_all)
00675 {
00676 return eval_data.r;
00677 }
00678 };
00679
00680 #endif