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