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 _ISLP_EVALUATOR_H_
00029 #define _ISLP_EVALUATOR_H_
00030
00031 #include <coconut_config.h>
00032 #include <evaluator.h>
00033 #include <model.h>
00034 #include <eval_main.h>
00035 #include <linalg.h>
00036 #include <math.h>
00037 #include <api_exception.h>
00038
00039 using namespace vgtl;
00040
00041 namespace coco {
00042
00044
00048 struct func_islp_return_type
00049 {
00050 double f;
00051 interval rg;
00052 interval fi;
00053 };
00054
00056
00058 typedef bool (*prep_islp_evaluator)();
00059 typedef func_islp_return_type (*func_islp_evaluator)(
00060 const std::vector<interval>* __x, const variable_indicator& __v,
00061 std::vector<interval>& __islp_data);
00062 typedef std::vector<interval>& (*islp_evaluator)(
00063 const std::vector<interval>& __d_dat,
00064 const variable_indicator& __v);
00066
00068
00074 class prep_islp_eval : public
00075 cached_forward_evaluator_base<std::vector<std::vector<interval> >*,
00076 expression_node, bool, expression_const_walker>
00077 {
00078 private:
00080 typedef cached_forward_evaluator_base<std::vector<std::vector<interval> >*,
00081 expression_node,bool,expression_const_walker> _Base;
00082
00083 public:
00087 prep_islp_eval(std::vector<std::vector<interval> >& __d,
00088 unsigned int _num_of_nodes)
00089 {
00090 eval_data = &__d;
00091 if((*eval_data).size() < _num_of_nodes)
00092 (*eval_data).insert((*eval_data).end(),
00093 _num_of_nodes-(*eval_data).size(), std::vector<interval>());
00094 }
00095
00097 prep_islp_eval(const prep_islp_eval& __x) { eval_data = __x.eval_data; }
00098
00100 ~prep_islp_eval() {}
00101
00103 bool is_cached(const expression_node& __data)
00104 {
00105 return (*eval_data)[__data.node_num].size() > 0;
00106 }
00107
00109 int initialize(const expression_node& __data)
00110 {
00111 (*eval_data)[__data.node_num].insert((*eval_data)[__data.node_num].end(),
00112 __data.n_children, interval(-COCO_INF,COCO_INF));
00113 return 1;
00114 }
00115
00117
00119 void initialize() { return; }
00120
00121 void retrieve_from_cache(const expression_node& __data) { return; }
00122
00123 void calculate(const expression_node& __data) { return; }
00124
00125 int update(bool __rval) { return 0; }
00126
00127 int update(const expression_node& __data, bool __rval)
00128 { return 0; }
00129
00130 bool calculate_value(bool eval_all) { return true; }
00132 };
00133
00134
00135
00136
00138
00142 struct func_islp_eval_type
00143 {
00144 const std::vector<double>* z;
00145 const std::vector<interval>* range;
00146 std::vector<double>* f;
00147 std::vector<std::vector<interval> >* islp_data;
00148 const model* mod;
00149 union { void *p; interval_st d; unsigned int info; } u;
00151 func_islp_return_type r;
00152 unsigned int n;
00153 };
00154
00156
00162 class func_islp_eval : public
00163 cached_forward_evaluator_base<func_islp_eval_type, expression_node,
00164 func_islp_return_type, expression_const_walker>
00165 {
00166 private:
00168 typedef cached_forward_evaluator_base<func_islp_eval_type,expression_node,
00169 func_islp_return_type, expression_const_walker> _Base;
00170
00171 protected:
00174 bool is_cached(const node_data_type& __data)
00175 {
00176 if(__data.operator_type == EXPRINFO_LIN ||
00177 __data.operator_type == EXPRINFO_QUAD)
00178 return true;
00179 else
00180 #if 0
00181 if(__data.n_parents > 1 && __data.n_children > 0 &&
00182 v_ind->match(__data.var_indicator()))
00183 return true;
00184 else
00185 #endif
00186 return false;
00187 }
00188
00189 public:
00196 func_islp_eval(const std::vector<double>& __z,
00197 const std::vector<interval>& __rg,
00198 const variable_indicator& __v, const model& __m,
00199 std::vector<std::vector<interval> >& __d,
00200 std::vector<double>& __f) : _Base()
00201 {
00202 eval_data.z = &__z;
00203 eval_data.range = &__rg;
00204 eval_data.f = &__f;
00205 eval_data.islp_data = &__d;
00206 eval_data.mod = &__m;
00207 eval_data.n = 0;
00208 eval_data.r.f = 0;
00209 eval_data.r.rg = 0;
00210 eval_data.r.fi = 0;
00211 v_ind = &__v;
00212 }
00213
00215 func_islp_eval(const func_islp_eval& __x) : _Base(__x) {}
00216
00218 ~func_islp_eval() {}
00219
00221 expression_const_walker short_cut_to(const expression_node& __data)
00222 { return eval_data.mod->node(0); }
00223
00227 void new_point(const std::vector<double>& __x, const variable_indicator& __v)
00228 {
00229 eval_data.z = &__x;
00230 v_ind = &__v;
00231 }
00232
00236 void new_range(const std::vector<interval>& __rg,
00237 const variable_indicator& __v)
00238 {
00239 eval_data.range = &__rg;
00240 v_ind = &__v;
00241 }
00242
00244
00245 void initialize() { return; }
00246
00247 int initialize(const expression_node& __data)
00248 {
00249 eval_data.n = 0;
00250 if(__data.ev != NULL && (*__data.ev)[FUNC_ISLP_EVALUATOR] != NULL)
00251
00252 {
00253 eval_data.r = (*(func_islp_evaluator)(*__data.ev)[FUNC_ISLP_EVALUATOR])
00254 (eval_data.range, *v_ind,
00255 (*eval_data.islp_data)[__data.node_num]);
00256 return 0;
00257 }
00258 else
00259 {
00260 switch(__data.operator_type)
00261 {
00262 case EXPRINFO_MAX:
00263 case EXPRINFO_MIN:
00264 eval_data.u.info = 0;
00265
00266 case EXPRINFO_SUM:
00267 case EXPRINFO_INVERT:
00268 eval_data.r.fi = eval_data.r.f = __data.params.nd();
00269 break;
00270 case EXPRINFO_PROD:
00271 eval_data.r.rg = eval_data.r.fi = eval_data.r.f = __data.params.nd();
00272 break;
00273 case EXPRINFO_IN:
00274 case EXPRINFO_AND:
00275 case EXPRINFO_NOGOOD:
00276 eval_data.r.fi = eval_data.r.f = 1.;
00277 break;
00278 case EXPRINFO_ALLDIFF:
00279 eval_data.u.p = (void*) new std::vector<interval>;
00280 ((std::vector<interval>*)eval_data.u.p)->reserve(__data.n_children);
00281
00282 case EXPRINFO_MEAN:
00283 case EXPRINFO_IF:
00284 case EXPRINFO_OR:
00285 case EXPRINFO_NOT:
00286 case EXPRINFO_COUNT:
00287 case EXPRINFO_SCPROD:
00288 eval_data.r.fi = eval_data.r.f = 0.;
00289 break;
00290 case EXPRINFO_NORM:
00291 eval_data.r.fi = eval_data.r.f = 0.;
00292 eval_data.u.info = 0;
00293 break;
00294 case EXPRINFO_LEVEL:
00295 eval_data.u.p = (void*) new std::vector<interval>;
00296 ((std::vector<interval>*)eval_data.u.p)->reserve(__data.n_children);
00297 eval_data.r.fi = eval_data.r.f = 0.;
00298 break;
00299 case EXPRINFO_DET:
00300 case EXPRINFO_PSD:
00301
00302 break;
00303 case EXPRINFO_COND:
00304 case EXPRINFO_FEM:
00305 case EXPRINFO_MPROD:
00306
00307 break;
00308 }
00309 return 1;
00310 }
00311 }
00312
00313 void calculate(const expression_node& __data)
00314 {
00315 if(__data.operator_type > 0)
00316 {
00317 #if 0
00318
00319 eval_data.r.f = __data.f_evaluate(-1, __data.params.nn(), *eval_data.z,
00320 *v_ind, eval_data.r.f, 0,
00321 &((*eval_data.islp_data)[__data.node_num]));
00322 #endif
00323 }
00324 }
00325
00326 void retrieve_from_cache(const expression_node& __data)
00327 {
00328
00329 if(__data.operator_type == EXPRINFO_LIN)
00330 {
00331 const linalg::matrix<double>::Row& lrw(eval_data.mod->lin[__data.params.nn()]);
00332 linalg::matrix<double>::Row::const_iterator _x, _e;
00333
00334 eval_data.r.f = linalg::linalg_dot(lrw,*eval_data.z,0.);
00335 eval_data.r.fi = interval(0.);
00336 for(_x = lrw.begin(); _x != _e; ++_x)
00337 eval_data.r.fi += (*eval_data.z)[_x.index()] * interval(*_x);
00338 }
00339 else if(__data.operator_type == EXPRINFO_QUAD)
00340 {
00341 throw nyi_exception("func_islp_eval: QUAD");
00342 }
00343 else
00344 eval_data.r.f = (*eval_data.f)[__data.node_num];
00345 eval_data.r.rg = (*eval_data.range)[__data.node_num];
00346 }
00347
00348 int update(const func_islp_return_type& __rval)
00349 {
00350 eval_data.r = __rval;
00351 return 0;
00352 }
00353
00354 int update(const expression_node& __data,
00355 const func_islp_return_type& __rval)
00356 {
00357 int ret = 0;
00358 interval __x;
00359 if(__data.operator_type < 0)
00360 {
00361 switch(__data.operator_type)
00362 {
00363 case EXPRINFO_CONSTANT:
00364 eval_data.r.rg = eval_data.r.f = __data.params.nd();
00365
00366 break;
00367 case EXPRINFO_VARIABLE:
00368 eval_data.r.fi = eval_data.r.f = (*eval_data.z)[__data.params.nn()];
00369 eval_data.r.rg = (*eval_data.range)[__data.node_num];
00370
00371 break;
00372 case EXPRINFO_SUM:
00373 case EXPRINFO_MEAN:
00374 { double h = __data.coeffs[eval_data.n];
00375 eval_data.r.f += h*__rval.f;
00376 (*eval_data.islp_data)[__data.node_num][eval_data.n++] = h;
00377 eval_data.r.fi += h*(__rval.fi-__rval.f+interval(__rval.f));
00378 }
00379 break;
00380 case EXPRINFO_PROD:
00381 {
00382 (*eval_data.islp_data)[__data.node_num][eval_data.n] =
00383 eval_data.r.rg;
00384
00385 eval_data.r.fi *= __rval.f;
00386 eval_data.r.fi += eval_data.r.rg*(__rval.fi-__rval.f);
00387
00388 eval_data.r.f *= __rval.f;
00389 eval_data.r.rg *= __rval.rg;
00390
00391 for(int i = eval_data.n-1; i >= 0; i--)
00392 (*eval_data.islp_data)[__data.node_num][i] *= __rval.f;
00393 }
00394 ++eval_data.n;
00395 break;
00396 case EXPRINFO_MONOME:
00397 throw nyi_exception("func_islp_eval: MONOME");
00398 #if 0
00399 if(eval_data.n == 0)
00400 {
00401 int n = __data.params.n()[0];
00402 if(n != 0)
00403 {
00404 eval_data.r = __power(__data.coeffs[0], __rval, n);
00405 (*eval_data.id_data)[__data.node_num][0] =
00406 n*__power(__data.coeffs[0], __rval, n-1)*__data.coeffs[0];
00407 }
00408 else
00409 {
00410 eval_data.r = 1;
00411 (*eval_data.id_data)[__data.node_num][0] = 0;
00412 }
00413 }
00414 else
00415 {
00416 int n = __data.params.n()[eval_data.n];
00417 if(n != 0)
00418 {
00419 __x = __power(__data.coeffs[eval_data.n], __rval, n-1)*
00420 __data.coeffs[eval_data.n];
00421 (*eval_data.id_data)[__data.node_num][eval_data.n] =
00422 eval_data.r*n*__x;
00423 __x = __power(__data.coeffs[eval_data.n], __rval, n);
00424 eval_data.r *= __x;
00425 for(int i = eval_data.n-1; i >= 0; i--)
00426 (*eval_data.id_data)[__data.node_num][i] *= __x;
00427 }
00428 else
00429 (*eval_data.id_data)[__data.node_num][eval_data.n] = 0;
00430 }
00431 ++eval_data.n;
00432
00433 if(eval_data.n == __data.n_children)
00434 eval_data.r.intersect((*eval_data.range)[__data.node_num]);
00435 #endif
00436 break;
00437 case EXPRINFO_MAX:
00438
00439 { double h = __rval.f * __data.coeffs[eval_data.n];
00440 if(h >= eval_data.r.f)
00441 {
00442 if(h > eval_data.r.f)
00443 (*eval_data.islp_data)[__data.node_num][eval_data.u.info] = 0;
00444 (*eval_data.islp_data)[__data.node_num][eval_data.n] =
00445 __data.coeffs[eval_data.n];
00446 eval_data.r.f = h;
00447 eval_data.r.fi = h;
00448 eval_data.u.info = eval_data.n;
00449 }
00450 else
00451 {
00452 (*eval_data.islp_data)[__data.node_num][eval_data.n] = 0;
00453 }
00454 }
00455 ++eval_data.n;
00456 break;
00457 case EXPRINFO_MIN:
00458
00459 { double h = __rval.f * __data.coeffs[eval_data.n];
00460 if(h <= eval_data.r.f)
00461 {
00462 if(h < eval_data.r.f)
00463 (*eval_data.islp_data)[__data.node_num][eval_data.u.info] = 0;
00464 (*eval_data.islp_data)[__data.node_num][eval_data.n] =
00465 __data.coeffs[eval_data.n];
00466 eval_data.r.f = h;
00467 eval_data.r.fi = h;
00468 eval_data.u.info = eval_data.n;
00469 }
00470 else
00471 {
00472 (*eval_data.islp_data)[__data.node_num][eval_data.n] = 0;
00473 }
00474 }
00475 ++eval_data.n;
00476 break;
00477 case EXPRINFO_SCPROD:
00478 throw nyi_exception("func_islp_eval: SCPROD");
00479 #if 0
00480 { interval h = __data.coeffs[eval_data.n]*__rval;
00481
00482
00483 if(eval_data.n & 1)
00484 {
00485 eval_data.r += eval_data.u.d*h;
00486 (*eval_data.id_data)[__data.node_num][eval_data.n] =
00487 eval_data.u.d*__data.coeffs[eval_data.n-1];
00488 (*eval_data.id_data)[__data.node_num][eval_data.n-1] =
00489 h*__data.coeffs[eval_data.n];
00490 }
00491 else
00492 eval_data.u.d = h;
00493 }
00494 eval_data.n++;
00495
00496 if(eval_data.n == __data.n_children)
00497 eval_data.r.intersect((*eval_data.range)[__data.node_num]);
00498 #endif
00499 break;
00500 case EXPRINFO_NORM:
00501 throw nyi_exception("func_islp_eval: NORM");
00502 #if 0
00503 { interval h = __data.coeffs[eval_data.n]*__rval;
00504 eval_data.r += sqr(h);
00505 (*eval_data.id_data)[__data.node_num][eval_data.n-1] =
00506 2*h*__data.coeffs[eval_data.n];
00507 }
00508 eval_data.n++;
00509
00510 if(eval_data.n == __data.n_children)
00511 eval_data.r.intersect((*eval_data.range)[__data.node_num]);
00512 #endif
00513 break;
00514 case EXPRINFO_INVERT:
00515 { interval __h;
00516 eval_data.r.f /= __rval.f;
00517 (*eval_data.islp_data)[__data.node_num][0] = __h =
00518 eval_data.r.f/__rval.rg;
00519 eval_data.r.fi /= __rval.f;
00520 eval_data.r.fi += __h*(__rval.fi-__rval.f);
00521 }
00522 break;
00523 case EXPRINFO_DIV:
00524 if(eval_data.n++ == 0)
00525 {
00526 eval_data.r.f = __rval.f;
00527 eval_data.r.fi = __rval.fi-__rval.f;
00528 }
00529 else
00530 {
00531 double h = 1/__rval.f;
00532 interval __h, __k;
00533 __k = eval_data.r.f;
00534 eval_data.r.f *= __data.params.nd()*h;
00535 __h = __data.params.nd();
00536 __h /= __rval.f;
00537 (*eval_data.islp_data)[__data.node_num][0] = __h;
00538 eval_data.r.fi *= __h;
00539 __h *= -(*eval_data.range)[__data.node_num];
00540 (*eval_data.islp_data)[__data.node_num][1] = __h;
00541 eval_data.r.fi += __h*(__rval.fi-__rval.f);
00542 eval_data.r.fi += __data.params.nd()*__k/__rval.f;
00543 }
00544 break;
00545 case EXPRINFO_SQUARE:
00546 { interval __h;
00547 double h = __data.coeffs[0]*__rval.f+__data.params.nd();
00548 eval_data.r.f = h*h;
00549 (*eval_data.islp_data)[__data.node_num][0] = __h =
00550 (h+__data.coeffs[0]*(__rval.rg+__data.params.nd()))*
00551 __data.coeffs[0];
00552 eval_data.r.fi = __rval.f;
00553 eval_data.r.fi *= __data.coeffs[0];
00554 eval_data.r.fi += __data.params.nd();
00555 eval_data.r.fi = sqr(eval_data.r.fi);
00556 eval_data.r.fi += __h*(__rval.fi-__rval.f);
00557 }
00558 break;
00559 case EXPRINFO_INTPOWER:
00560 { int hl = __data.params.nn();
00561 if(hl == 0)
00562 {
00563 eval_data.r.f = 1;
00564 (*eval_data.islp_data)[__data.node_num][0] = 0;
00565 eval_data.r.fi = 1;
00566 }
00567 else
00568 {
00569 double kl = __data.coeffs[0]*__rval.f;
00570 interval km = __data.coeffs[0]*__rval.rg;
00571 interval _h_k = interval(__rval.f)*__data.coeffs[0];
00572 interval _h_h;
00573 switch(hl)
00574 {
00575 case 1:
00576 eval_data.r.f = kl;
00577 (*eval_data.islp_data)[__data.node_num][0] = __data.coeffs[0];
00578 _h_h = 0;
00579 break;
00580 case 2:
00581 eval_data.r.f = kl*kl;
00582 _h_h = (*eval_data.islp_data)[__data.node_num][0] =
00583 __data.coeffs[0]*(kl+km);
00584 _h_k = sqr(_h_k);
00585 break;
00586 case -1:
00587 eval_data.r.f = 1/kl;
00588 _h_h = (*eval_data.islp_data)[__data.node_num][0] =
00589 -__data.coeffs[0]/(kl*km);
00590 _h_k = 1./_h_k;
00591 break;
00592 case -2:
00593 {
00594
00595
00596
00597 double h = 1/kl;
00598 double k = h*h;
00599 eval_data.r.f = k;
00600 interval _h;
00601
00602 _h = -((km.inf()+kl)*k)/(km.inf()*km.inf());
00603 _h.hullwith(-((km.sup()+kl)*k)/(km.sup()*km.sup()));
00604 if(_h.contains(-2*eval_data.r.f))
00605 _h.hullwith(0.25/(h*k));
00606 _h_h = (*eval_data.islp_data)[__data.node_num][0] =
00607 _h*__data.coeffs[0];
00608 _h_k = 1./sqr(_h_k);
00609 }
00610 break;
00611 default:
00612 if(hl > 0)
00613 {
00614 if(hl & 1)
00615 {
00616
00617 interval _h = (hl+0.0)*ipow(km,hl-1);
00618 _h_h = (*eval_data.islp_data)[__data.node_num][0] =
00619 _h*__data.coeffs[0];
00620 }
00621 else
00622 {
00623 interval i1, i2;
00624 double up;
00625
00626 i1 = km.sup();
00627 if(kl != km.sup())
00628 {
00629 i1.ipow(hl);
00630 i2 = kl;
00631 i2.ipow(hl);
00632 i1 -= i2;
00633 i1 /= (km.sup()-kl);
00634 }
00635 else
00636 {
00637 i1.ipow(hl-1);
00638 i1 *= hl;
00639 }
00640 up = i1.sup();
00641
00642 i1 = km.inf();
00643 if(kl != km.inf())
00644 {
00645 i1.ipow(hl);
00646 if(kl == km.sup())
00647 {
00648 i2 = kl;
00649 i2.ipow(hl);
00650 }
00651 i1 -= i2;
00652 i1 /= (km.inf()-kl);
00653 }
00654 else
00655 {
00656 i1.ipow(hl-1);
00657 i1 *= hl;
00658 }
00659 i1 = i1.inf();
00660
00661 _h_h = (*eval_data.islp_data)[__data.node_num][0] =
00662 __data.coeffs[0]*interval(i1.inf(),up);
00663 }
00664 }
00665 else
00666 {
00667 if((-hl) & 1)
00668 {
00669
00670 interval _h = (hl+0.0)*ipow(km,hl-1);
00671 _h_h = (*eval_data.islp_data)[__data.node_num][0] =
00672 _h*__data.coeffs[0];
00673 }
00674 else
00675 {
00676
00677 interval _h = (hl+0.0)*ipow(km,hl-1);
00678 _h_h = (*eval_data.islp_data)[__data.node_num][0] =
00679 _h*__data.coeffs[0];
00680 }
00681 }
00682 _h_k = ipow(_h_k, hl);
00683 break;
00684 }
00685 eval_data.r.fi = _h_h*(__rval.fi-__rval.f)+_h_k;
00686 }
00687 }
00688 break;
00689 case EXPRINFO_SQROOT:
00690 { double h = std::sqrt(__data.coeffs[0]*__rval.f+__data.params.nd());
00691 interval _h = sqrt(__data.coeffs[0]*__rval.rg+__data.params.nd());
00692 eval_data.r.f = h;
00693 _h = (*eval_data.islp_data)[__data.node_num][0] = __data.coeffs[0]/
00694 (h+_h);
00695 eval_data.r.fi = (__rval.fi-__rval.f)*_h+
00696 sqrt(__data.coeffs[0]*interval(__rval.f)+__data.params.nd());
00697 }
00698 break;
00699 case EXPRINFO_ABS:
00700 { double h = __data.coeffs[0]*__rval.f+__data.params.nd();
00701 interval _h = __data.coeffs[0]*__rval.rg+__data.params.nd();
00702 eval_data.r.f = fabs(h);
00703 if(_h.inf() >= 0 && h >= 0)
00704 _h = __data.coeffs[0];
00705 else if(_h.sup() <= 0 && h <= 0)
00706 _h = -__data.coeffs[0];
00707 else if(h > 0)
00708 {
00709 interval _lo,_up;
00710 if(_h.sup() < 0)
00711 _up = (interval(_h.sup())+h)/(h-_h.sup());
00712 else
00713 _up = 1.;
00714 _lo = (interval(_h.inf())+h)/(h-_h.inf());
00715 _h = __data.coeffs[0]*interval(_lo.inf(), _up.sup());
00716 }
00717 else if(h < 0)
00718 {
00719 interval _lo,_up;
00720 if(_h.inf() > 0)
00721 _lo = (interval(_h.inf())+h)/(h-_h.inf());
00722 else
00723 _lo = -1.;
00724 _up = (interval(_h.sup())+h)/(h-_h.sup());
00725 _h = __data.coeffs[0]*interval(_lo.inf(), _up.sup());
00726 }
00727 else
00728 _h = interval(-__data.coeffs[0],__data.coeffs[0]);
00729 (*eval_data.islp_data)[__data.node_num][0] = _h;
00730 eval_data.r.fi = (__rval.fi-__rval.f)*_h+
00731 abs(__data.coeffs[0]*interval(__rval.f)+__data.params.nd());
00732 }
00733 break;
00734 case EXPRINFO_POW:
00735
00736 if(eval_data.n++ == 0)
00737 {
00738 eval_data.r.f = __rval.f;
00739 eval_data.r.fi = __rval.fi-__rval.f;
00740 eval_data.r.rg = __rval.rg;
00741 }
00742 else
00743 {
00744 double hh = __rval.f*__data.coeffs[1];
00745 if(hh == 0)
00746 {
00747 (*eval_data.islp_data)[__data.node_num][0] = 0;
00748 (*eval_data.islp_data)[__data.node_num][1] = 0;
00749 eval_data.r.f = 1;
00750 eval_data.r.fi = 1;
00751 }
00752 else
00753 {
00754 interval _hh = __rval.rg*__data.coeffs[0];
00755 interval _hf = interval(eval_data.r.f)*__data.coeffs[0]+
00756 __data.params.nd();
00757
00758 eval_data.r.f *= __data.coeffs[0];
00759 eval_data.r.f += __data.params.nd();
00760 eval_data.r.rg *= __data.coeffs[0];
00761 eval_data.r.rg += __data.params.nd();
00762
00763 double h = std::pow(eval_data.r.f, hh);
00764 interval _h = __rval.rg*pow(eval_data.r.rg, __rval.rg-1.)*
00765 __data.coeffs[0];
00766 eval_data.r.fi *= _h;
00767 eval_data.r.fi += pow(_hf,interval(__rval.f)*__data.coeffs[1]);
00768
00769 (*eval_data.islp_data)[__data.node_num][0] = _h;
00770
00771 _h = (*eval_data.islp_data)[__data.node_num][1] =
00772 log(eval_data.r.rg)*pow(eval_data.r.rg,__rval.rg)*
00773 __data.coeffs[1];
00774 eval_data.r.f = h;
00775 eval_data.r.fi += (__rval.fi-__rval.f)*_h;
00776 }
00777 }
00778 break;
00779 case EXPRINFO_EXP:
00780 { double k = __rval.f*__data.coeffs[0]+__data.params.nd();
00781 double h = std::exp(k);
00782 interval _h = __rval.rg*__data.coeffs[0]+__data.params.nd();
00783 interval _lo(_h.inf());
00784 interval _up(_h.sup());
00785 _lo = (exp(_lo)-h)/(_lo-k);
00786 _up = (exp(_up)-h)/(_up-k);
00787 eval_data.r.f = h;
00788 _h = (*eval_data.islp_data)[__data.node_num][0] =
00789 interval(_lo.inf(),_up.sup())*__data.coeffs[0];
00790 eval_data.r.fi = (__rval.fi-__rval.f)*_h+
00791 exp(__data.coeffs[0]*interval(__rval.f)+__data.params.nd());
00792 }
00793 break;
00794 case EXPRINFO_LOG:
00795 { double k = __rval.f*__data.coeffs[0]+__data.params.nd();
00796 double h = std::log(k);
00797 interval _h = __rval.rg*__data.coeffs[0]+__data.params.nd();
00798 interval _lo(_h.sup());
00799 interval _up(_h.inf());
00800 _lo = (log(_lo)-h)/(_lo-k);
00801 _up = (log(_up)-h)/(_up-k);
00802 eval_data.r.f = h;
00803 _h = (*eval_data.islp_data)[__data.node_num][0] =
00804 interval(_lo.inf(),_up.sup())*__data.coeffs[0];
00805 eval_data.r.fi = (__rval.fi-__rval.f)*_h+
00806 log(__data.coeffs[0]*interval(__rval.f)+__data.params.nd());
00807 }
00808 break;
00809 case EXPRINFO_SIN:
00810
00811 { double k = __rval.f*__data.coeffs[0]+__data.params.nd();
00812 double h = std::sin(k);
00813 interval _h = __rval.rg*__data.coeffs[0]+__data.params.nd();
00814 eval_data.r.f = h;
00815 _h = (*eval_data.islp_data)[__data.node_num][0] =
00816 cos(_h)*__data.coeffs[0];
00817 eval_data.r.fi = (__rval.fi-__rval.f)*_h+
00818 sin(__data.coeffs[0]*interval(__rval.f)+__data.params.nd());
00819 }
00820 break;
00821 case EXPRINFO_COS:
00822
00823 { double k = __rval.f*__data.coeffs[0]+__data.params.nd();
00824 double h = std::cos(k);
00825 interval _h = __rval.rg*__data.coeffs[0]+__data.params.nd();
00826 eval_data.r.f = h;
00827 _h = (*eval_data.islp_data)[__data.node_num][0] =
00828 -sin(_h)*__data.coeffs[0];
00829 eval_data.r.fi = (__rval.fi-__rval.f)*_h+
00830 cos(__data.coeffs[0]*interval(__rval.f)+__data.params.nd());
00831 }
00832 break;
00833 case EXPRINFO_ATAN2:
00834
00835 if(eval_data.n++ == 0)
00836 {
00837 eval_data.r.f = __rval.f;
00838 eval_data.r.fi = __rval.fi-__rval.f;
00839 eval_data.r.rg = __rval.rg;
00840 }
00841 else
00842 {
00843 double hh = __rval.f * __data.coeffs[1];
00844 interval _hh = __rval.rg * __data.coeffs[1];
00845 eval_data.r.f *= __data.coeffs[0];
00846 eval_data.r.rg *= __data.coeffs[0];
00847
00848 interval _h = sqr(eval_data.r.rg)+sqr(__rval.rg);
00849 interval _j;
00850
00851 _j = (*eval_data.islp_data)[__data.node_num][0] =
00852 __data.coeffs[0]*_hh/_h;
00853 eval_data.r.fi *= _j;
00854
00855 _j = (*eval_data.islp_data)[__data.node_num][1] =
00856 -__data.coeffs[1]*eval_data.r.rg/_h;
00857 eval_data.r.fi += _j*(__rval.fi*__data.coeffs[1]-hh);
00858
00859 eval_data.r.fi += atan2(interval(eval_data.r.f),interval(hh));
00860 eval_data.r.f = std::atan2(eval_data.r.f, hh);
00861 }
00862 break;
00863 case EXPRINFO_GAUSS:
00864
00865 { double k = (__rval.f*__data.coeffs[0]-__data.params.d()[0])/
00866 __data.params.d()[1];
00867 double h = std::exp(-k*k);
00868 interval _h = (__rval.rg*__data.coeffs[0]-__data.params.d()[0])/
00869 __data.params.d()[1];
00870 eval_data.r.f = h;
00871 _h = (*eval_data.islp_data)[__data.node_num][0] =
00872 -2.*_h*exp(-sqr(_h))*__data.coeffs[0]/__data.params.d()[1];
00873 interval _k = (interval(__rval.f)*__data.coeffs[0]-
00874 __data.params.d()[0])/__data.params.d()[1];
00875 eval_data.r.fi = (__rval.fi-__rval.f)*_h+exp(-sqr(_k));
00876 }
00877 break;
00878 case EXPRINFO_POLY:
00879 throw nyi_exception("func_islp_eval: POLY");
00880 break;
00881 case EXPRINFO_LIN:
00882 case EXPRINFO_QUAD:
00883
00884 break;
00885 case EXPRINFO_IN:
00886 throw nyi_exception("func_islp_eval: IN");
00887 #if 0
00888 {
00889 __x = __data.coeffs[eval_data.n]*__rval;
00890 const interval& i(__data.params.i()[eval_data.n]);
00891 if(i.disjoint(__x))
00892 {
00893 eval_data.r = -1.;
00894 ret = -1;
00895 std::vector<interval>& r((*eval_data.id_data)[__data.node_num]);
00896 r.erase(r.begin(),r.end());
00897 r.insert(r.end(),__data.n_children,interval(0.));
00898 }
00899 else
00900 {
00901 if(!i.superset(__x))
00902 {
00903 if(i.sup() == __x.inf() || i.inf() == __x.sup())
00904 {
00905
00906 eval_data.r = interval(-1.,0.);
00907 if(i.sup() == __x.inf())
00908 (*eval_data.id_data)[__data.node_num][eval_data.n] =
00909 interval(-COCO_INF,0.);
00910 else
00911 (*eval_data.id_data)[__data.node_num][eval_data.n] =
00912 interval(0.,COCO_INF);
00913 }
00914 else
00915 {
00916
00917 if(eval_data.r.sup() > 0)
00918 eval_data.r = interval(-1.,1.);
00919
00920 if(i.subset(__x))
00921 (*eval_data.id_data)[__data.node_num][eval_data.n] =
00922 interval(-COCO_INF,COCO_INF);
00923 else if(__x.contains(i.inf()))
00924 (*eval_data.id_data)[__data.node_num][eval_data.n] =
00925 interval(0.,COCO_INF);
00926 else
00927 (*eval_data.id_data)[__data.node_num][eval_data.n] =
00928 interval(-COCO_INF,0.);
00929 }
00930 }
00931 else if(i.inf() == __x.inf() || i.sup() == __x.sup())
00932
00933
00934 {
00935 if(eval_data.r.inf() == 1.)
00936 {
00937 if(__x.is_thin())
00938 eval_data.r = 0.;
00939 else
00940 eval_data.r = interval(0.,1.);
00941 }
00942 else if(__x.is_thin() && eval_data.r.inf() == 0.)
00943 eval_data.r = 0.;
00944 if(__x.inf() == __x.sup())
00945 (*eval_data.id_data)[__data.node_num][eval_data.n] = 0;
00946 else if(i.inf() == __x.inf() && i.sup() == __x.sup())
00947 (*eval_data.id_data)[__data.node_num][eval_data.n] =
00948 interval(-COCO_INF,COCO_INF);
00949 else if(i.inf() == __x.inf())
00950 (*eval_data.id_data)[__data.node_num][eval_data.n] =
00951 interval(0.,COCO_INF);
00952 else
00953 (*eval_data.id_data)[__data.node_num][eval_data.n] =
00954 interval(-COCO_INF,0.);
00955 }
00956 else
00957
00958 (*eval_data.id_data)[__data.node_num][eval_data.n] = 0;
00959 }
00960 }
00961 eval_data.n++;
00962 #endif
00963 break;
00964 case EXPRINFO_IF:
00965 throw nyi_exception("func_islp_eval: IF");
00966 #if 0
00967 __x = __rval * __data.coeffs[eval_data.n];
00968 if(eval_data.n == 0)
00969 {
00970 const interval& i(__data.params.ni());
00971 if(i.superset(__x))
00972 {
00973 eval_data.u.info = 0;
00974 (*eval_data.id_data)[__data.node_num][0] = 0;
00975 (*eval_data.id_data)[__data.node_num][2] = 0;
00976 }
00977 else if(i.disjoint(__x))
00978 {
00979 eval_data.u.info = 1;
00980 (*eval_data.id_data)[__data.node_num][0] = 0;
00981 (*eval_data.id_data)[__data.node_num][1] = 0;
00982 ret = 1;
00983 }
00984 else
00985 eval_data.u.info = 1;
00986 }
00987 else if(eval_data.n == 1)
00988 {
00989 eval_data.r = __x;
00990 (*eval_data.id_data)[__data.node_num][1] = __data.coeffs[1];
00991 if(eval_data.u.info == 0)
00992 ret = -1;
00993 }
00994 else
00995 {
00996 if(eval_data.u.info == 1)
00997 eval_data.r = __x;
00998 else
00999 {
01000 eval_data.r = eval_data.r.hull(__x);
01001 (*eval_data.id_data)[__data.node_num][0] =
01002 interval(-COCO_INF,COCO_INF);
01003 }
01004 (*eval_data.id_data)[__data.node_num][2] = __data.coeffs[2];
01005 }
01006 if(eval_data.n == 2 || ret == -1)
01007 eval_data.r.intersect((*eval_data.range)[__data.node_num]);
01008 else
01009 eval_data.n += 1+ret;
01010 #endif
01011 break;
01012 case EXPRINFO_AND:
01013 throw nyi_exception("func_islp_eval: AND");
01014 #if 0
01015 { __x = __data.coeffs[eval_data.n]*__rval;
01016 const interval& i(__data.params.i()[eval_data.n]);
01017 if(i.disjoint(__x))
01018 {
01019 eval_data.r = 0;
01020 std::vector<interval>& r((*eval_data.id_data)[__data.node_num]);
01021 r.erase(r.begin(),r.end());
01022 r.insert(r.end(),__data.n_children,interval(0.));
01023 ret = -1;
01024 }
01025 else if(!i.superset(__x))
01026 {
01027 double lo = 0, hi = 0;
01028 if(eval_data.r != 0)
01029 eval_data.r = interval(0.,1.);
01030 if(__x.inf() < i.inf())
01031 hi = COCO_INF;
01032 if(__x.sup() > i.sup())
01033 lo = -COCO_INF;
01034 (*eval_data.id_data)[__data.node_num][eval_data.n] =
01035 interval(lo,hi);
01036 }
01037 else
01038 (*eval_data.id_data)[__data.node_num][eval_data.n] = 0;
01039 }
01040 eval_data.n++;
01041
01042 if(eval_data.n == __data.n_children)
01043 eval_data.r.intersect((*eval_data.range)[__data.node_num]);
01044 #endif
01045 break;
01046 case EXPRINFO_OR:
01047 throw nyi_exception("func_islp_eval: OR");
01048 #if 0
01049 { __x = __data.coeffs[eval_data.n]*__rval;
01050 const interval& i(__data.params.i()[eval_data.n]);
01051 if(i.superset(__x))
01052 {
01053 eval_data.r = 1;
01054 std::vector<interval>& r((*eval_data.id_data)[__data.node_num]);
01055 r.erase(r.begin(),r.end());
01056 r.insert(r.end(),__data.n_children,interval(0.));
01057 ret = -1;
01058 }
01059 else if(!i.disjoint(__x))
01060 {
01061 if(eval_data.r != 0)
01062 eval_data.r = interval(0.,1.);
01063 double lo = 0, hi = 0;
01064 if(__x.inf() < i.inf())
01065 hi = COCO_INF;
01066 if(__x.sup() > i.sup())
01067 lo = -COCO_INF;
01068 (*eval_data.id_data)[__data.node_num][eval_data.n] =
01069 interval(lo,hi);
01070 }
01071 else
01072 (*eval_data.id_data)[__data.node_num][eval_data.n] = 0;
01073 }
01074 eval_data.n++;
01075
01076 if(eval_data.n == __data.n_children)
01077 eval_data.r.intersect((*eval_data.range)[__data.node_num]);
01078 #endif
01079 break;
01080 case EXPRINFO_NOT:
01081 throw nyi_exception("func_islp_eval: NOT");
01082 #if 0
01083 { __x = __data.coeffs[0]*__rval;
01084 const interval& i(__data.params.ni());
01085 if(i.superset(__x))
01086 {
01087 eval_data.r = 0;
01088 (*eval_data.id_data)[__data.node_num][0] = 0;
01089 }
01090 else if(i.disjoint(__x))
01091 {
01092 eval_data.r = 1;
01093 (*eval_data.id_data)[__data.node_num][0] = 0;
01094 }
01095 else
01096 {
01097 eval_data.r = interval(0.,1.);
01098 double lo = 0, hi = 0;
01099 if(__x.inf() < i.inf())
01100 lo = -COCO_INF;
01101 if(__x.sup() > i.sup())
01102 hi = COCO_INF;
01103 (*eval_data.id_data)[__data.node_num][0] = interval(lo,hi);
01104 }
01105 eval_data.r.intersect((*eval_data.range)[__data.node_num]);
01106 }
01107 #endif
01108 break;
01109 case EXPRINFO_IMPLIES:
01110 throw nyi_exception("func_islp_eval: IMPLIES");
01111 #if 0
01112 { const interval& i(__data.params.i()[eval_data.n]);
01113 __x = __rval * __data.coeffs[eval_data.n];
01114 if(eval_data.n == 0)
01115 {
01116 if(i.disjoint(__x))
01117 {
01118 eval_data.r = 1.;
01119 (*eval_data.id_data)[__data.node_num][0] = 0;
01120 (*eval_data.id_data)[__data.node_num][1] = 0;
01121 ret = -1;
01122 }
01123 else if(!i.superset(__x))
01124 {
01125 eval_data.r = interval(0.,1.);
01126 double lo = 0, hi = 0;
01127 if(__x.inf() < i.inf())
01128 lo = -COCO_INF;
01129 if(__x.sup() > i.sup())
01130 hi = COCO_INF;
01131 (*eval_data.id_data)[__data.node_num][0] = interval(lo,hi);
01132 }
01133 else
01134 {
01135 eval_data.r = interval(0.);
01136 (*eval_data.id_data)[__data.node_num][0] = 0;
01137 }
01138 }
01139 else
01140 {
01141 if(i.superset(__x))
01142 {
01143 eval_data.r = 1.;
01144 (*eval_data.id_data)[__data.node_num][0] = 0;
01145 (*eval_data.id_data)[__data.node_num][1] = 0;
01146 }
01147 else if(!i.disjoint(__x))
01148 {
01149 eval_data.r = interval(0.,1.);
01150 double lo = 0, hi = 0;
01151 if(__x.inf() < i.inf())
01152 hi = COCO_INF;
01153 if(__x.sup() > i.sup())
01154 lo = -COCO_INF;
01155 (*eval_data.id_data)[__data.node_num][0] = interval(lo,hi);
01156 }
01157 else
01158 (*eval_data.id_data)[__data.node_num][1] = 0;
01159 eval_data.r.intersect((*eval_data.range)[__data.node_num]);
01160 }
01161 ++eval_data.n;
01162 }
01163 #endif
01164 break;
01165 case EXPRINFO_COUNT:
01166 throw nyi_exception("func_islp_eval: COUNT");
01167 #if 0
01168 { __x = __data.coeffs[eval_data.n]*__rval;
01169 const interval& i(__data.params.i()[eval_data.n]);
01170 if(i.superset(__x))
01171 {
01172 eval_data.r += 1;
01173 (*eval_data.id_data)[__data.node_num][eval_data.n] = 0;
01174 }
01175 else if(!i.disjoint(__x))
01176 {
01177 eval_data.r += interval(0.,1.);
01178 double lo = 0, hi = 0;
01179 if(__x.inf() < i.inf())
01180 hi = COCO_INF;
01181 if(__x.sup() > i.sup())
01182 lo = -COCO_INF;
01183 (*eval_data.id_data)[__data.node_num][eval_data.n] =
01184 interval(lo,hi);
01185 }
01186 else
01187 (*eval_data.id_data)[__data.node_num][eval_data.n] = 0;
01188 }
01189 eval_data.n++;
01190
01191 if(eval_data.n == __data.n_children)
01192 eval_data.r.intersect((*eval_data.range)[__data.node_num]);
01193 #endif
01194 break;
01195 case EXPRINFO_ALLDIFF:
01196 throw nyi_exception("func_islp_eval: ALLDIFF");
01197 #if 0
01198 { int i;
01199 std::vector<interval>::const_iterator _b;
01200 __x = __data.coeffs[eval_data.n]*__rval;
01201 (*eval_data.id_data)[__data.node_num][eval_data.n] = 0;
01202 for(_b = ((std::vector<interval>*)eval_data.u.p)->begin(), i = 0;
01203 _b != ((std::vector<interval>*)eval_data.u.p)->end(); ++_b, ++i)
01204 {
01205 interval __h = abs(__x-*_b);
01206 if(__h.sup() <= __data.params.nd())
01207 {
01208 eval_data.r = 0;
01209 std::vector<interval>& r((*eval_data.id_data)[__data.node_num]);
01210 r.erase(r.begin(),r.end());
01211 r.insert(r.end(),__data.n_children,interval(0.));
01212 ret = -1;
01213 break;
01214 }
01215 else if(__h.inf() <= __data.params.nd())
01216 {
01217 eval_data.r = interval(0.,1.);
01218 (*eval_data.id_data)[__data.node_num][eval_data.n] =
01219 interval(-COCO_INF,COCO_INF);
01220 (*eval_data.id_data)[__data.node_num][i] =
01221 interval(-COCO_INF,COCO_INF);
01222 }
01223 }
01224 if(ret != -1)
01225 ((std::vector<interval>*) eval_data.u.p)->push_back(__x);
01226 }
01227 eval_data.n++;
01228 if(eval_data.n == __data.n_children || ret == -1)
01229 {
01230 if(eval_data.r == 1.)
01231 {
01232 std::vector<interval>& r((*eval_data.id_data)[__data.node_num]);
01233 r.erase(r.begin(),r.end());
01234 r.insert(r.end(),__data.n_children,interval(0.));
01235 }
01236 delete (std::vector<interval>*) eval_data.u.p;
01237 eval_data.r.intersect((*eval_data.range)[__data.node_num]);
01238 }
01239 #endif
01240 break;
01241 case EXPRINFO_HISTOGRAM:
01242 throw nyi_exception("func_islp_eval: HISTOGRAM");
01243 break;
01244 case EXPRINFO_LEVEL:
01245 throw nyi_exception("func_islp_eval: LEVEL");
01246 #if 0
01247 {
01248
01249
01250
01251 int lo = 0;
01252 int hi = 0;
01253 __x = __data.coeffs[eval_data.n]*__rval;
01254 interval _h;
01255
01256
01257 if(hi != INT_MAX)
01258 {
01259 while(hi < __data.params.im().nrows())
01260 {
01261 _h = __data.params.im()[hi][eval_data.n];
01262 if(_h.superset(__x))
01263 break;
01264 hi++;
01265 }
01266 if(hi == __data.params.im().nrows())
01267 hi = INT_MAX;
01268 }
01269
01270 if(lo != INT_MAX)
01271 {
01272 while(lo < __data.params.im().nrows())
01273 {
01274 _h = __data.params.im()[lo][eval_data.n];
01275 if(!_h.disjoint(__x))
01276 break;
01277 lo++;
01278 }
01279 if(lo == __data.params.im().nrows())
01280 lo = INT_MAX;
01281 }
01282 ((std::vector<interval>*)eval_data.u.p)->
01283 push_back(interval(lo+0.,hi+0.));
01284 eval_data.r = interval(min(eval_data.r.inf(),lo+0.),
01285 max(eval_data.r.sup(),hi+0.));
01286 }
01287 eval_data.n++;
01288 if(eval_data.n == __data.n_children)
01289 {
01290 std::vector<interval>& v(*((std::vector<interval>*)eval_data.u.p));
01291 for(int i = 0; i < __data.n_children; ++i)
01292 {
01293 if(v.is_thin() || v.sup() < eval_data.r.inf())
01294 (*eval_data.id_data)[__data.node_num][i] = 0;
01295 else
01296 (*eval_data.id_data)[__data.node_num][i] =
01297 interval(0.,COCO_INF);
01298 }
01299 delete (std::vector<interval>*)eval_data.u.p;
01300 eval_data.r.intersect((*eval_data.range)[__data.node_num]);
01301 }
01302 #endif
01303 break;
01304 case EXPRINFO_NEIGHBOR:
01305 throw nyi_exception("func_islp_eval: NEIGHBOR");
01306 #if 0
01307
01308
01309
01310
01311
01312 (*eval_data.id_data)[__data.node_num][eval_data.n] =
01313 interval(-COCO_INF,COCO_INF);
01314 if(eval_data.n == 0)
01315 eval_data.r = __data.coeffs[0]*__rval;
01316 else
01317 {
01318 interval h = eval_data.r;
01319 eval_data.r = 0;
01320 __x = __data.coeffs[1]*__rval;
01321 for(unsigned int i = 0; i < __data.params.n().size(); i+=2)
01322 {
01323 if(h == __data.params.n()[i]+0. &&
01324 __x == __data.params.n()[i+1]+0.)
01325 {
01326 eval_data.r = 1;
01327 break;
01328 }
01329 else if(h.contains(__data.params.n()[i]+0.) &&
01330 __x.contains(__data.params.n()[i+1]+0.))
01331 {
01332 eval_data.r = interval(0.,1.);
01333 break;
01334 }
01335 }
01336 }
01337 eval_data.n++;
01338 if(eval_data.n == __data.n_children)
01339 eval_data.r.intersect((*eval_data.range)[__data.node_num]);
01340 #endif
01341 break;
01342 case EXPRINFO_NOGOOD:
01343 throw nyi_exception("func_islp_eval: NOGOOD");
01344 #if 0
01345
01346 (*eval_data.id_data)[__data.node_num][eval_data.n] =
01347 interval(-COCO_INF,COCO_INF);
01348 __x = __data.coeffs[eval_data.n]*__rval;
01349 if(eval_data.r != 0.)
01350 {
01351 if(!__x.contains(__data.params.n()[eval_data.n]+0.))
01352 {
01353 eval_data.r = 0.;
01354 ret = -1;
01355 }
01356 else if(__x != __data.params.n()[eval_data.n]+0.)
01357 eval_data.r = interval(0.,1.);
01358 }
01359 eval_data.n++;
01360 if(eval_data.n == __data.n_children)
01361 eval_data.r.intersect((*eval_data.range)[__data.node_num]);
01362 #endif
01363 break;
01364 case EXPRINFO_EXPECTATION:
01365 throw nyi_exception("func_islp_eval: EXPECTATION");
01366 break;
01367 case EXPRINFO_INTEGRAL:
01368 throw nyi_exception("func_islp_eval: INTEGRAL");
01369 break;
01370 case EXPRINFO_LOOKUP:
01371 case EXPRINFO_PWLIN:
01372 case EXPRINFO_SPLINE:
01373 case EXPRINFO_PWCONSTLC:
01374 case EXPRINFO_PWCONSTRC:
01375 throw nyi_exception("func_islp_eval: Table Operations");
01376 break;
01377 case EXPRINFO_DET:
01378 case EXPRINFO_COND:
01379 case EXPRINFO_PSD:
01380 case EXPRINFO_MPROD:
01381 case EXPRINFO_FEM:
01382 throw nyi_exception("func_islp_eval: Matrix Operations");
01383 break;
01384 case EXPRINFO_RE:
01385 case EXPRINFO_IM:
01386 case EXPRINFO_ARG:
01387 case EXPRINFO_CPLXCONJ:
01388 throw nyi_exception("func_islp_eval: Complex Operations");
01389 break;
01390 case EXPRINFO_CMPROD:
01391 case EXPRINFO_CGFEM:
01392 throw nyi_exception("func_islp_eval: Const Matrix Operations");
01393 break;
01394 default:
01395 throw api_exception(apiee_evaluator,
01396 std::string("func_islp_eval: unknown function type ")+
01397 convert_to_str(__data.operator_type));
01398 break;
01399 }
01400 }
01401 else if(__data.operator_type > 0)
01402 {
01403 #if 0
01404
01405
01406 eval_data.r.f = __data.f_evaluate(eval_data.n++, __data.params.nn(),
01407 *eval_data.z, *v_ind, eval_data.r.f, __rval,
01408 &(*eval_data.islp_data)[__data.node_num]);
01409 #endif
01410 }
01411
01412 (*eval_data.f)[__data.node_num] = eval_data.r.f;
01413 if(__data.n_children == 1 || (eval_data.n == __data.n_children &&
01414 __data.n_children > 0))
01415 eval_data.r.rg = (*eval_data.range)[__data.node_num];
01416 return ret;
01417 }
01418
01419 func_islp_return_type calculate_value(bool eval_all)
01420 {
01421 return eval_data.r;
01422 }
01424 };
01425
01427
01431 struct islp_eval_type
01432 {
01433 std::vector<std::vector<interval> >* islp_data;
01434 std::vector<std::vector<interval> >* islp_cache;
01435 std::vector<interval>* islp_vec;
01436 const model* mod;
01437 interval mult;
01438 interval mult_trans;
01439 unsigned int child_n;
01440 };
01441
01443
01448 class islp_eval : public
01449 cached_backward_evaluator_base<islp_eval_type,expression_node,bool,
01450 expression_const_walker>
01451 {
01452 private:
01454 typedef cached_backward_evaluator_base<islp_eval_type,expression_node,
01455 bool,expression_const_walker> _Base;
01456
01457 protected:
01460 bool is_cached(const node_data_type& __data)
01461 {
01462 if(eval_data.islp_cache && __data.n_parents > 1 && __data.n_children > 0
01463 && (*eval_data.islp_cache)[__data.node_num].size() > 0 &&
01464 v_ind->match(__data.var_indicator()))
01465 {
01466 return true;
01467 }
01468 else
01469 return false;
01470 }
01471
01472 public:
01481 islp_eval(std::vector<std::vector<interval> >& __slp_data,
01482 variable_indicator& __v, const model& __m,
01483 std::vector<std::vector<interval > >* __d,
01484 std::vector<interval>& __islp)
01485 {
01486 eval_data.islp_data = &__slp_data;
01487 eval_data.islp_cache = __d;
01488 eval_data.islp_vec = &__islp;
01489 eval_data.mod = &__m;
01490 eval_data.mult_trans = 1;
01491 eval_data.mult = 0;
01492 v_ind = &__v;
01493 }
01494
01496 islp_eval(const islp_eval& __d) { eval_data = __d.eval_data; }
01497
01499 ~islp_eval() {}
01500
01504 void new_point(std::vector<std::vector<interval> >& __slp_data,
01505 const variable_indicator& __v)
01506 {
01507 eval_data.islp_data = &__slp_data;
01508 v_ind = &__v;
01509 }
01510
01512 void new_result(std::vector<interval>& __islp)
01513 {
01514 eval_data.islp_vec = &__islp;
01515 }
01516
01518 void set_mult(interval scal)
01519 {
01520 eval_data.mult_trans = scal;
01521 }
01522 public:
01523
01525 expression_const_walker short_cut_to(const expression_node& __data)
01526 { return eval_data.mod->node(0); }
01527
01529
01530
01531 void initialize()
01532 {
01533 eval_data.child_n = 0;
01534 }
01535
01536
01537 int calculate(const expression_node& __data)
01538 {
01539 if(__data.operator_type == EXPRINFO_CONSTANT)
01540 return 0;
01541 else if(__data.operator_type == EXPRINFO_VARIABLE)
01542 {
01543
01544 (*eval_data.islp_vec)[__data.params.nn()] += eval_data.mult_trans;
01545 return 0;
01546 }
01547 else if(__data.operator_type == EXPRINFO_LIN)
01548 {
01549 const linalg::matrix<double>::Row& lrw(eval_data.mod->lin[__data.params.nn()]);
01550 linalg::matrix<double>::Row::const_iterator _x, _e;
01551 _e = lrw.end();
01552 for(_x = lrw.begin(); _x != _e; ++_x)
01553 (*eval_data.islp_vec)[_x.index()] += *_x * eval_data.mult_trans;
01554 return 0;
01555 }
01556 else if(__data.operator_type == EXPRINFO_QUAD)
01557 {
01558 throw nyi_exception("islp_evaluator: QUAD");
01559 return 0;
01560 }
01561 else if(__data.ev && (*__data.ev)[DER_EVALUATOR])
01562
01563 {
01564 std::vector<interval> __h = (*(islp_evaluator)(*__data.ev)[ISLP_EVALUATOR])(
01565 (*eval_data.islp_data)[__data.node_num], *v_ind);
01566
01567 for(unsigned int i = 0; i <= (*eval_data.islp_vec).size(); ++i)
01568 (*eval_data.islp_vec)[i] += eval_data.mult*__h[i];
01569 return 0;
01570 }
01571 else if(eval_data.mult_trans.inf() == 0 && eval_data.mult_trans.sup() == 0)
01572
01573 return 0;
01574 else
01575 {
01576 eval_data.child_n = 1;
01577 eval_data.mult = eval_data.mult_trans;
01578 if(__data.n_parents > 1 && __data.n_children > 0 && eval_data.islp_cache)
01579 {
01580 eval_data.mult_trans = (*eval_data.islp_data)[__data.node_num][0];
01581 }
01582 else
01583 eval_data.mult_trans *= (*eval_data.islp_data)[__data.node_num][0];
01584 return 1;
01585 }
01586 }
01587
01588
01589 void cleanup(const expression_node& __data)
01590 {
01591
01592 if(__data.n_parents > 1 && __data.n_children > 0 && eval_data.islp_cache
01593 && (*eval_data.islp_cache)[__data.node_num].size() == 0)
01594 {
01595 (*eval_data.islp_cache)[__data.node_num] = *eval_data.islp_vec;
01596 for(unsigned int i = 0; i <= (*eval_data.islp_vec).size(); ++i)
01597 (*eval_data.islp_vec)[i] *= eval_data.mult;
01598 }
01599 }
01600
01601 void retrieve_from_cache(const expression_node& __data)
01602 {
01603
01604 for(unsigned int i = 0; i <= (*eval_data.islp_vec).size(); ++i)
01605 (*eval_data.islp_vec)[i] = eval_data.mult_trans *
01606 (*eval_data.islp_cache)[__data.node_num][i];
01607 }
01608
01609 int update(const bool& __rval)
01610 {
01611 eval_data.child_n++;
01612 return 0;
01613 }
01614
01615
01616 int update(const expression_node& __data, const bool& __rval)
01617 {
01618 if(__data.n_children == 0)
01619 return 0;
01620 if(__data.n_parents > 1 && __data.n_children > 0 && eval_data.islp_cache)
01621 {
01622 if(eval_data.child_n < __data.n_children)
01623 eval_data.mult_trans =
01624 (*eval_data.islp_data)[__data.node_num][eval_data.child_n];
01625 }
01626 else if(eval_data.child_n < __data.n_children)
01627 {
01628 eval_data.mult_trans = eval_data.mult *
01629 (*eval_data.islp_data)[__data.node_num][eval_data.child_n];
01630 }
01631 eval_data.child_n++;
01632 return 0;
01633 }
01634
01635 bool calculate_value(bool eval_all)
01636 {
01637 return true;
01638 }
01640 };
01641
01642 }
01643
01644 #endif