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