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 _DER_EVALUATOR_H_
00029 #define _DER_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_d_evaluator)();
00048 typedef double (*func_d_evaluator)(const std::vector<double>* __x,
00049 const variable_indicator& __v,
00050 std::vector<double>& __d_data);
00051 typedef std::vector<double>& (*der_evaluator)(const std::vector<double>& __d_dat,
00052 const variable_indicator& __v);
00054
00056
00062 class prep_d_eval : public
00063 cached_forward_evaluator_base<std::vector<std::vector<double> >*, expression_node, bool, expression_const_walker>
00064 {
00065 private:
00067 typedef cached_forward_evaluator_base<std::vector<std::vector<double> >*,
00068 expression_node,bool,expression_const_walker> _Base;
00069
00070 public:
00074 prep_d_eval(std::vector<std::vector<double> >& __d,
00075 unsigned int _num_of_nodes)
00076 {
00077 eval_data = &__d;
00078 if((*eval_data).size() < _num_of_nodes)
00079 (*eval_data).insert((*eval_data).end(),
00080 _num_of_nodes-(*eval_data).size(), std::vector<double>());
00081 }
00082
00084 prep_d_eval(const prep_d_eval& __x) { eval_data = __x.eval_data; }
00085
00087 ~prep_d_eval() {}
00088
00090 bool is_cached(const expression_node& __data)
00091 {
00092 return (*eval_data)[__data.node_num].size() > 0;
00093 }
00094
00096 int initialize(const expression_node& __data)
00097 {
00098 (*eval_data)[__data.node_num].insert((*eval_data)[__data.node_num].end(),
00099 __data.n_children, 0);
00100 return 1;
00101 }
00102
00104
00106 void retrieve_from_cache(const expression_node& __data) { return; }
00107
00108 void initialize() { return; }
00109
00110 void calculate(const expression_node& __data) { return; }
00111
00112 int update(bool __rval) { return 0; }
00113
00114 int update(const expression_node& __data, bool __rval)
00115 { return 0; }
00116
00117 bool calculate_value(bool eval_all) { return true; }
00119 };
00120
00122
00126 struct func_d_eval_type
00127 {
00128 const std::vector<double>* x;
00129 std::vector<double>* f_cache;
00130 std::vector<std::vector<double> >* d_data;
00131 const model* mod;
00132 union { void* p; double d; } u;
00133 double r;
00134 unsigned int n,
00135 info;
00136 };
00137
00139
00145 class func_d_eval : public
00146 cached_forward_evaluator_base<func_d_eval_type, expression_node,
00147 double, expression_const_walker>
00148 {
00149 private:
00151 typedef cached_forward_evaluator_base<func_d_eval_type,expression_node,
00152 double, expression_const_walker> _Base;
00153
00154 protected:
00157 bool is_cached(const node_data_type& __data)
00158 {
00159 if(__data.operator_type == EXPRINFO_LIN ||
00160 __data.operator_type == EXPRINFO_QUAD)
00161 return true;
00162 if(eval_data.f_cache && __data.n_parents > 1 && __data.n_children > 0 &&
00163 v_ind->match(__data.var_indicator()))
00164 return true;
00165 else
00166 return false;
00167 }
00168
00169 private:
00172 double __power(double __coeff, double __x, int __exp)
00173 {
00174 if(__exp == 0)
00175 return 1.;
00176 else
00177 {
00178 double k = __coeff*__x;
00179 switch(__exp)
00180 {
00181 case 1:
00182 return k;
00183 break;
00184 case 2:
00185 return k*k;
00186 break;
00187 case -1:
00188 return 1./k;
00189 break;
00190 case -2:
00191 return 1./(k*k);
00192 break;
00193 default:
00194 if(__exp & 1)
00195 {
00196 if(k < 0)
00197 return -std::pow(-k, __exp);
00198 else
00199 return std::pow(k, __exp);
00200 }
00201 else
00202 return std::pow(fabs(k), __exp);
00203 break;
00204 }
00205 }
00206
00207 return 0.;
00208 }
00209
00212 void __calc_max(double h, const expression_node& __data)
00213 {
00214 if(h >= eval_data.r)
00215 {
00216 (*eval_data.d_data)[__data.node_num][eval_data.info] = 0;
00217 if(h > eval_data.r)
00218 (*eval_data.d_data)[__data.node_num][eval_data.n] =
00219 __data.coeffs[eval_data.n];
00220 else
00221
00222 (*eval_data.d_data)[__data.node_num][eval_data.n] = 0;
00223 eval_data.r = h;
00224 eval_data.info = eval_data.n;
00225 }
00226 else
00227 {
00228 (*eval_data.d_data)[__data.node_num][eval_data.n] = 0;
00229 }
00230 }
00231
00232 public:
00238 func_d_eval(const std::vector<double>& __x, const variable_indicator& __v,
00239 const model& __m, std::vector<std::vector<double> >& __d,
00240 std::vector<double>* __c) : _Base()
00241 {
00242 eval_data.x = &__x;
00243 eval_data.f_cache = __c;
00244 eval_data.mod = &__m;
00245 eval_data.d_data = &__d;
00246 eval_data.n = 0;
00247 eval_data.r = 0;
00248 eval_data.u.d = 0;
00249 v_ind = &__v;
00250 }
00251
00253 func_d_eval(const func_d_eval& __x) : _Base(__x) {}
00254
00256 ~func_d_eval() {}
00257
00259 expression_const_walker short_cut_to(const expression_node& __data)
00260 { return eval_data.mod->node(0); }
00261
00265 void new_point(const std::vector<double>& __x, const variable_indicator& __v)
00266 {
00267 eval_data.x = &__x;
00268 v_ind = &__v;
00269 }
00270
00272
00273 void initialize() { return; }
00274
00275 int initialize(const expression_node& __data)
00276 {
00277 eval_data.n = 0;
00278 if(__data.ev != NULL && (*__data.ev)[FUNC_D_EVALUATOR] != NULL)
00279
00280 {
00281 eval_data.r =
00282 (*(func_d_evaluator)(*__data.ev)[FUNC_D_EVALUATOR])(eval_data.x,
00283 *v_ind, (*eval_data.d_data)[__data.node_num]);
00284 return 0;
00285 }
00286 else
00287 {
00288 switch(__data.operator_type)
00289 {
00290 case EXPRINFO_MAX:
00291 case EXPRINFO_MIN:
00292 eval_data.info = 0;
00293
00294 case EXPRINFO_SUM:
00295 case EXPRINFO_PROD:
00296 case EXPRINFO_INVERT:
00297 eval_data.r = __data.params.nd();
00298 break;
00299 case EXPRINFO_IN:
00300 case EXPRINFO_AND:
00301 case EXPRINFO_NOGOOD:
00302 eval_data.r = 1.;
00303 break;
00304 case EXPRINFO_ALLDIFF:
00305 eval_data.u.p = (void*) new std::vector<double>;
00306 ((std::vector<double>*)eval_data.u.p)->reserve(__data.n_children);
00307
00308 case EXPRINFO_MEAN:
00309 case EXPRINFO_IF:
00310 case EXPRINFO_OR:
00311 case EXPRINFO_NOT:
00312 case EXPRINFO_COUNT:
00313 case EXPRINFO_SCPROD:
00314 case EXPRINFO_LEVEL:
00315 eval_data.r = 0.;
00316 break;
00317 case EXPRINFO_NORM:
00318 eval_data.info = 0;
00319 eval_data.r = 0.;
00320 break;
00321 case EXPRINFO_DET:
00322 case EXPRINFO_PSD:
00323
00324 break;
00325 case EXPRINFO_COND:
00326 case EXPRINFO_FEM:
00327 case EXPRINFO_MPROD:
00328
00329 break;
00330 }
00331 return 1;
00332 }
00333 }
00334
00335 void calculate(const expression_node& __data)
00336 {
00337 if(__data.operator_type > 0)
00338 {
00339 eval_data.r = __data.f_evaluate(-1, __data.params.nn(), *eval_data.x,
00340 *v_ind, eval_data.r, 0,
00341 &((*eval_data.d_data)[__data.node_num]));
00342 }
00343 }
00344
00345 void retrieve_from_cache(const expression_node& __data)
00346 {
00347
00348 if(__data.operator_type == EXPRINFO_LIN)
00349 eval_data.r = linalg::linalg_dot(eval_data.mod->lin[__data.params.nn()],
00350 *eval_data.x,0.);
00351 else if(__data.operator_type == EXPRINFO_QUAD)
00352 {
00353 std::vector<double> irslt = *eval_data.x;
00354 unsigned int r = __data.params.m().nrows();
00355
00356
00357 irslt.push_back(0);
00358 linalg::linalg_matvec(__data.params.m(), irslt, irslt);
00359 irslt.pop_back();
00360
00361 eval_data.r = linalg::linalg_dot(__data.params.m()[r-1], *eval_data.x, 0.);
00362
00363 eval_data.r += linalg::linalg_dot(irslt,*eval_data.x,0.);
00364
00365 linalg::linalg_add(linalg_scale(__data.params.m()[r-1], 0.5), irslt,
00366 (*eval_data.d_data)[__data.node_num]);
00367 }
00368 else
00369 eval_data.r = (*eval_data.f_cache)[__data.node_num];
00370 }
00371
00372 int update(const double& __rval)
00373 {
00374 eval_data.r = __rval;
00375 return 0;
00376 }
00377
00378 int update(const expression_node& __data, const double& __rval)
00379 {
00380 int ret = 0;
00381 double __x;
00382 if(__data.operator_type < 0)
00383 {
00384 switch(__data.operator_type)
00385 {
00386 case EXPRINFO_CONSTANT:
00387 eval_data.r = __data.params.nd();
00388
00389 break;
00390 case EXPRINFO_VARIABLE:
00391 eval_data.r = (*eval_data.x)[__data.params.nn()];
00392
00393 break;
00394 case EXPRINFO_SUM:
00395 case EXPRINFO_MEAN:
00396 { double h = __data.coeffs[eval_data.n];
00397 eval_data.r += h*__rval;
00398 (*eval_data.d_data)[__data.node_num][eval_data.n++] = h;
00399 }
00400 break;
00401 case EXPRINFO_PROD:
00402 if(eval_data.n == 0)
00403 {
00404 eval_data.r *= __rval;
00405 (*eval_data.d_data)[__data.node_num][0] = __data.params.nd();
00406 }
00407 else
00408 {
00409 (*eval_data.d_data)[__data.node_num][eval_data.n] = eval_data.r;
00410 eval_data.r *= __rval;
00411 for(int i = eval_data.n-1; i >= 0; i--)
00412 (*eval_data.d_data)[__data.node_num][i] *= __rval;
00413 }
00414 ++eval_data.n;
00415 break;
00416 case EXPRINFO_MONOME:
00417 if(eval_data.n == 0)
00418 {
00419 int n = __data.params.n()[0];
00420 if(n != 0)
00421 {
00422 __x = __power(__data.coeffs[0], __rval, n-1)*__data.coeffs[0];
00423 eval_data.r = __x*__rval;
00424 (*eval_data.d_data)[__data.node_num][0] = n*__x;
00425 }
00426 else
00427 {
00428 (*eval_data.d_data)[__data.node_num][0] = 0;
00429 eval_data.r = 1.;
00430 }
00431 }
00432 else
00433 {
00434 int n = __data.params.n()[eval_data.n];
00435 if(n != 0)
00436 {
00437 __x = __power(__data.coeffs[eval_data.n], __rval, n-1)*
00438 __data.coeffs[eval_data.n];
00439 (*eval_data.d_data)[__data.node_num][eval_data.n] =
00440 eval_data.r*n*__x;
00441 __x *= __rval;
00442 eval_data.r *= __x;
00443 for(int i = eval_data.n-1; i >= 0; i--)
00444 (*eval_data.d_data)[__data.node_num][i] *= __x;
00445 }
00446 else
00447 (*eval_data.d_data)[__data.node_num][eval_data.n] = 0;
00448 }
00449 ++eval_data.n;
00450 break;
00451 case EXPRINFO_MAX:
00452 __calc_max(__rval * __data.coeffs[eval_data.n], __data);
00453 ++eval_data.n;
00454 break;
00455 case EXPRINFO_MIN:
00456 { double h = __rval * __data.coeffs[eval_data.n];
00457 if(h <= eval_data.r)
00458 {
00459 (*eval_data.d_data)[__data.node_num][eval_data.info] = 0;
00460 if(h < eval_data.r)
00461 (*eval_data.d_data)[__data.node_num][eval_data.n] =
00462 __data.coeffs[eval_data.n];
00463 else
00464
00465 (*eval_data.d_data)[__data.node_num][eval_data.n] = 0;
00466 eval_data.r = h;
00467 eval_data.info = eval_data.n;
00468 }
00469 else
00470 {
00471 (*eval_data.d_data)[__data.node_num][eval_data.n] = 0;
00472 }
00473 }
00474 ++eval_data.n;
00475 break;
00476 case EXPRINFO_SCPROD:
00477 { double h = __data.coeffs[eval_data.n]*__rval;
00478
00479
00480 if(eval_data.n & 1)
00481 {
00482 eval_data.r += eval_data.u.d*h;
00483 (*eval_data.d_data)[__data.node_num][eval_data.n] =
00484 eval_data.u.d*__data.coeffs[eval_data.n-1];
00485 (*eval_data.d_data)[__data.node_num][eval_data.n-1] =
00486 h*__data.coeffs[eval_data.n];
00487 }
00488 else
00489 eval_data.u.d = h;
00490 }
00491 eval_data.n++;
00492 break;
00493 case EXPRINFO_NORM:
00494 if(__data.params.nd() == COCO_INF)
00495 __calc_max(fabs(__rval * __data.coeffs[eval_data.n]), __data);
00496 else
00497 {
00498 double h = __data.coeffs[eval_data.n]*fabs(__rval);
00499 double O = std::pow(h, __data.params.nd()-1);
00500 eval_data.r += O*h;
00501 (*eval_data.d_data)[__data.node_num][eval_data.n] = O;
00502 }
00503 eval_data.n++;
00504 if(eval_data.n == __data.n_children &&
00505 __data.params.nd() != COCO_INF)
00506 {
00507 double h = std::pow(eval_data.r,1./(__data.params.nd())-1.);
00508 for(unsigned int i = 0; i < eval_data.n; ++i)
00509 (*eval_data.d_data)[__data.node_num][eval_data.n] *= h;
00510 eval_data.r = std::pow(eval_data.r,1./(__data.params.nd()));
00511 }
00512 break;
00513 case EXPRINFO_INVERT:
00514 { double h = 1/__rval;
00515 eval_data.r *= h;
00516 (*eval_data.d_data)[__data.node_num][0] = -__data.params.nd()*h*h;
00517 }
00518 break;
00519 case EXPRINFO_DIV:
00520 if(eval_data.n++ == 0)
00521 eval_data.r = __rval;
00522 else
00523 {
00524 double h = 1/__rval;
00525 eval_data.r *=
00526 (*eval_data.d_data)[__data.node_num][0] = __data.params.nd()*h;
00527 (*eval_data.d_data)[__data.node_num][1] = -eval_data.r*h;
00528 }
00529 break;
00530 case EXPRINFO_SQUARE:
00531 { double h = __data.coeffs[0]*__rval+__data.params.nd();
00532 eval_data.r = h*h;
00533 (*eval_data.d_data)[__data.node_num][0] = 2*h*__data.coeffs[0];
00534 }
00535 break;
00536 case EXPRINFO_INTPOWER:
00537 { int hl = __data.params.nn();
00538 if(hl == 0)
00539 {
00540 eval_data.r = 1;
00541 (*eval_data.d_data)[__data.node_num][0] = 0;
00542 }
00543 else
00544 {
00545 double kl = __data.coeffs[0]*__rval;
00546 switch(hl)
00547 {
00548 case 1:
00549 eval_data.r = kl;
00550 (*eval_data.d_data)[__data.node_num][0] = __data.coeffs[0];
00551 break;
00552 case 2:
00553 eval_data.r = kl*kl;
00554 (*eval_data.d_data)[__data.node_num][0] =
00555 2*kl*__data.coeffs[0];
00556 break;
00557 case -1:
00558 { double h = 1/kl;
00559 eval_data.r = h;
00560 (*eval_data.d_data)[__data.node_num][0] =
00561 -h*h*__data.coeffs[0];
00562 }
00563 break;
00564 case -2:
00565 { double h = 1/kl;
00566 double k = h*h;
00567 eval_data.r = k;
00568 (*eval_data.d_data)[__data.node_num][0] =
00569 -2*h*k*__data.coeffs[0];
00570 }
00571 break;
00572 default:
00573 { double h;
00574 if(hl & 1)
00575 h = std::pow(fabs(kl), hl-1);
00576 else
00577 {
00578 if(kl < 0)
00579 h = -std::pow(-kl, hl-1);
00580 else
00581 h = std::pow(kl, hl-1);
00582 }
00583 eval_data.r = h*kl;
00584 (*eval_data.d_data)[__data.node_num][0] =
00585 hl*h*__data.coeffs[0];
00586 }
00587 break;
00588 }
00589 }
00590 }
00591 break;
00592 case EXPRINFO_SQROOT:
00593 { double h = std::sqrt(__data.coeffs[0]*__rval+__data.params.nd());
00594 eval_data.r = h;
00595 (*eval_data.d_data)[__data.node_num][0] = 0.5*__data.coeffs[0]/h;
00596 }
00597 break;
00598 case EXPRINFO_ABS:
00599 { double h = __data.coeffs[0]*__rval+__data.params.nd();
00600 eval_data.r = fabs(h);
00601 (*eval_data.d_data)[__data.node_num][0] =
00602 h > 0 ? __data.coeffs[0] : (h < 0 ? -__data.coeffs[0] : 0);
00603 }
00604 break;
00605 case EXPRINFO_POW:
00606 { double hh = __rval * __data.coeffs[eval_data.n];
00607 if(eval_data.n++ == 0)
00608 eval_data.r = hh+__data.params.nd();
00609 else
00610 {
00611 if(hh == 0)
00612 {
00613 (*eval_data.d_data)[__data.node_num][0] = 0;
00614 (*eval_data.d_data)[__data.node_num][1] =
00615 std::log(eval_data.r)*__data.coeffs[1];
00616 eval_data.r = 1;
00617 }
00618 else
00619 {
00620 double h = std::pow(eval_data.r, hh);
00621
00622 (*eval_data.d_data)[__data.node_num][0] =
00623 hh*std::pow(eval_data.r, hh-1)*__data.coeffs[0];
00624 (*eval_data.d_data)[__data.node_num][1] =
00625 std::log(eval_data.r)*h*__data.coeffs[1];
00626 eval_data.r = h;
00627 }
00628 }
00629 }
00630 break;
00631 case EXPRINFO_EXP:
00632 { double h = std::exp(__rval*__data.coeffs[0]+__data.params.nd());
00633 eval_data.r = h;
00634 (*eval_data.d_data)[__data.node_num][0] = h*__data.coeffs[0];
00635 }
00636 break;
00637 case EXPRINFO_LOG:
00638 { double h = __rval*__data.coeffs[0]+__data.params.nd();
00639 eval_data.r = std::log(h);
00640 (*eval_data.d_data)[__data.node_num][0] = __data.coeffs[0]/h;
00641 }
00642 break;
00643 case EXPRINFO_SIN:
00644 { double h = __rval*__data.coeffs[0]+__data.params.nd();
00645 eval_data.r = std::sin(h);
00646 (*eval_data.d_data)[__data.node_num][0] =
00647 __data.coeffs[0]*std::cos(h);
00648 }
00649 break;
00650 case EXPRINFO_COS:
00651 { double h = __rval*__data.coeffs[0]+__data.params.nd();
00652 eval_data.r = std::cos(h);
00653 (*eval_data.d_data)[__data.node_num][0] =
00654 -__data.coeffs[0]*std::sin(h);
00655 }
00656 break;
00657 case EXPRINFO_ATAN2:
00658 { double hh = __rval * __data.coeffs[eval_data.n];
00659 if(eval_data.n++ == 0)
00660 eval_data.r = hh;
00661 else
00662 { double h = eval_data.r;
00663 h *= h;
00664 h += hh*hh;
00665 (*eval_data.d_data)[__data.node_num][0] = __data.coeffs[0]*hh/h;
00666 (*eval_data.d_data)[__data.node_num][1] =
00667 -__data.coeffs[1]*eval_data.r/h;
00668 eval_data.r = std::atan2(eval_data.r,hh);
00669 }
00670 }
00671 break;
00672 case EXPRINFO_GAUSS:
00673 { double h = (__data.coeffs[0]*__rval-__data.params.d()[0])/
00674 __data.params.d()[1];
00675 double k = std::exp(-h*h);
00676 eval_data.r = k;
00677 (*eval_data.d_data)[__data.node_num][0] =
00678 -2*__data.coeffs[0]*k*h/__data.params.d()[1];
00679 }
00680 break;
00681 case EXPRINFO_POLY:
00682 throw nyi_exception("func_d_evaluator: POLY");
00683 break;
00684 case EXPRINFO_LIN:
00685 case EXPRINFO_QUAD:
00686
00687 break;
00688 case EXPRINFO_IN:
00689 {
00690 __x = __data.coeffs[eval_data.n]*__rval;
00691 const interval& i(__data.params.i()[eval_data.n]);
00692 if(eval_data.r != -1 && i.contains(__x))
00693 {
00694 if(eval_data.r == 1 && (__x == i.inf() || __x == i.sup()))
00695 eval_data.r = 0;
00696 }
00697 else
00698 {
00699 eval_data.r = -1;
00700 ret = -1;
00701 }
00702 }
00703
00704 if(eval_data.n == 0)
00705 {
00706 std::vector<double>& v((*eval_data.d_data)[__data.node_num]);
00707 v.erase(v.begin(),v.end());
00708 v.insert(v.begin(),__data.n_children,0.);
00709 }
00710 eval_data.n++;
00711 break;
00712 case EXPRINFO_IF:
00713 __x = __rval * __data.coeffs[eval_data.n];
00714 if(eval_data.n == 0)
00715 {
00716 const interval& i(__data.params.ni());
00717 if(!i.contains(__x))
00718 {
00719 ret = 1;
00720 (*eval_data.d_data)[__data.node_num][1] = 0.;
00721 }
00722 else
00723 (*eval_data.d_data)[__data.node_num][2] = 0.;
00724 (*eval_data.d_data)[__data.node_num][0] = 0.;
00725 }
00726 else
00727 {
00728 eval_data.r = __x;
00729 (*eval_data.d_data)[__data.node_num][eval_data.n] =
00730 __data.coeffs[eval_data.n];
00731 ret = -1;
00732 }
00733 eval_data.n += ret+1;
00734 break;
00735 case EXPRINFO_AND:
00736 { __x = __data.coeffs[eval_data.n]*__rval;
00737 const interval& i(__data.params.i()[eval_data.n]);
00738 if(eval_data.r == 1 && !i.contains(__x))
00739 {
00740 eval_data.r = 0;
00741 ret = -1;
00742 }
00743 }
00744
00745 if(eval_data.n == 0)
00746 {
00747 std::vector<double>& v((*eval_data.d_data)[__data.node_num]);
00748 v.erase(v.begin(),v.end());
00749 v.insert(v.begin(),__data.n_children,0.);
00750 }
00751 eval_data.n++;
00752 break;
00753 case EXPRINFO_OR:
00754 { __x = __data.coeffs[eval_data.n]*__rval;
00755 const interval& i(__data.params.i()[eval_data.n]);
00756 if(eval_data.r == 0 && i.contains(__x))
00757 {
00758 eval_data.r = 1;
00759 ret = -1;
00760 }
00761 }
00762
00763 if(eval_data.n == 0)
00764 {
00765 std::vector<double>& v((*eval_data.d_data)[__data.node_num]);
00766 v.erase(v.begin(),v.end());
00767 v.insert(v.begin(),__data.n_children,0.);
00768 }
00769 eval_data.n++;
00770 break;
00771 case EXPRINFO_NOT:
00772 { __x = __data.coeffs[0]*__rval;
00773 const interval& i(__data.params.ni());
00774 if(i.contains(__x))
00775 eval_data.r = 0;
00776 else
00777 eval_data.r = 1;
00778
00779 (*eval_data.d_data)[__data.node_num][0] = 0.;
00780 }
00781 break;
00782 case EXPRINFO_IMPLIES:
00783 { const interval& i(__data.params.i()[eval_data.n]);
00784 __x = __rval * __data.coeffs[eval_data.n];
00785 if(eval_data.n == 0)
00786 {
00787 if(!i.contains(__x))
00788 {
00789 eval_data.r = 1;
00790 ret = -1;
00791 }
00792
00793 (*eval_data.d_data)[__data.node_num][0] = 0.;
00794 (*eval_data.d_data)[__data.node_num][1] = 0.;
00795 }
00796 else
00797 eval_data.r = i.contains(__x) ? 1 : 0;
00798 ++eval_data.n;
00799 }
00800 break;
00801 case EXPRINFO_COUNT:
00802 { __x = __data.coeffs[eval_data.n]*__rval;
00803 const interval& i(__data.params.i()[eval_data.n]);
00804 if(i.contains(__x))
00805 eval_data.r += 1;
00806 }
00807
00808 if(eval_data.n == 0)
00809 {
00810 std::vector<double>& v((*eval_data.d_data)[__data.node_num]);
00811 v.erase(v.begin(),v.end());
00812 v.insert(v.begin(),__data.n_children,0.);
00813 }
00814 eval_data.n++;
00815 break;
00816 case EXPRINFO_ALLDIFF:
00817 { __x = __data.coeffs[eval_data.n]*__rval;
00818 for(std::vector<double>::const_iterator _b =
00819 ((std::vector<double>*)eval_data.u.p)->begin();
00820 _b != ((std::vector<double>*)eval_data.u.p)->end(); ++_b)
00821 {
00822 if(fabs(__x-*_b) <= __data.params.nd())
00823 {
00824 eval_data.r = 0;
00825 ret = -1;
00826 break;
00827 }
00828 }
00829 if(ret != -1)
00830 ((std::vector<double>*) eval_data.u.p)->push_back(__x);
00831 }
00832
00833 if(eval_data.n == 0)
00834 {
00835 std::vector<double>& v((*eval_data.d_data)[__data.node_num]);
00836 v.erase(v.begin(),v.end());
00837 v.insert(v.begin(),__data.n_children,0.);
00838 }
00839 eval_data.n++;
00840 if(eval_data.n == __data.n_children || ret == -1)
00841 delete (std::vector<double>*) eval_data.u.p;
00842 break;
00843 case EXPRINFO_HISTOGRAM:
00844 throw nyi_exception("func_d_evaluator: HISTOGRAM");
00845 break;
00846 case EXPRINFO_LEVEL:
00847 { int h = (int)eval_data.r;
00848 __x = __data.coeffs[eval_data.n]*__rval;
00849 interval _h;
00850
00851 if(h != INT_MAX)
00852 {
00853 while(h < __data.params.im().nrows())
00854 {
00855 _h = __data.params.im()[h][eval_data.n];
00856 if(_h.contains(__x))
00857 break;
00858 h++;
00859 }
00860 if(h == __data.params.im().nrows())
00861 {
00862 ret = -1;
00863 eval_data.r = INT_MAX;
00864 }
00865 else
00866 eval_data.r = h;
00867 }
00868 }
00869
00870 if(eval_data.n == 0)
00871 {
00872 std::vector<double>& v((*eval_data.d_data)[__data.node_num]);
00873 v.erase(v.begin(),v.end());
00874 v.insert(v.begin(),__data.n_children,0.);
00875 }
00876 eval_data.n++;
00877 break;
00878 case EXPRINFO_NEIGHBOR:
00879 if(eval_data.n == 0)
00880 eval_data.r = __data.coeffs[0]*__rval;
00881 else
00882 {
00883 double h = eval_data.r;
00884 eval_data.r = 0;
00885 __x = __data.coeffs[1]*__rval;
00886 for(unsigned int i = 0; i < __data.params.n().size(); i+=2)
00887 {
00888 if(h == __data.params.n()[i] && __x == __data.params.n()[i+1])
00889 {
00890 eval_data.r = 1;
00891 break;
00892 }
00893 }
00894 }
00895
00896 if(eval_data.n == 0)
00897 {
00898 std::vector<double>& v((*eval_data.d_data)[__data.node_num]);
00899 v.erase(v.begin(),v.end());
00900 v.insert(v.begin(),__data.n_children,0.);
00901 }
00902 eval_data.n++;
00903 break;
00904 case EXPRINFO_NOGOOD:
00905 {
00906 __x = __data.coeffs[eval_data.n]*__rval;
00907 if(eval_data.r == 0 || __data.params.n()[eval_data.n] != __x)
00908 {
00909 eval_data.r = 0;
00910 ret = -1;
00911 }
00912 }
00913
00914 if(eval_data.n == 0)
00915 {
00916 std::vector<double>& v((*eval_data.d_data)[__data.node_num]);
00917 v.erase(v.begin(),v.end());
00918 v.insert(v.begin(),__data.n_children,0.);
00919 }
00920 eval_data.n++;
00921 break;
00922 case EXPRINFO_EXPECTATION:
00923 throw nyi_exception("func_d_evaluator: EXPECTATION");
00924 break;
00925 case EXPRINFO_INTEGRAL:
00926 throw nyi_exception("func_d_evaluator: INTEGRAL");
00927 break;
00928 case EXPRINFO_LOOKUP:
00929 case EXPRINFO_PWLIN:
00930 case EXPRINFO_SPLINE:
00931 case EXPRINFO_PWCONSTLC:
00932 case EXPRINFO_PWCONSTRC:
00933 throw nyi_exception("func_d_evaluator: Table Operations");
00934 break;
00935 case EXPRINFO_DET:
00936 case EXPRINFO_COND:
00937 case EXPRINFO_PSD:
00938 case EXPRINFO_MPROD:
00939 case EXPRINFO_FEM:
00940 throw nyi_exception("func_d_evaluator: Matrix Operations");
00941 break;
00942 case EXPRINFO_RE:
00943 case EXPRINFO_IM:
00944 case EXPRINFO_ARG:
00945 case EXPRINFO_CPLXCONJ:
00946 throw nyi_exception("func_d_evaluator: Complex Operations");
00947 break;
00948 case EXPRINFO_CMPROD:
00949 case EXPRINFO_CGFEM:
00950 throw nyi_exception("func_d_evaluator: Const Matrix Operations");
00951 break;
00952 default:
00953 throw api_exception(apiee_evaluator,
00954 std::string("func_d_evaluator: unknown function type ")+
00955 convert_to_str(__data.operator_type));
00956 break;
00957 }
00958 }
00959 else if(__data.operator_type > 0)
00960
00961 eval_data.r = __data.f_evaluate(eval_data.n++, __data.params.nn(),
00962 *eval_data.x, *v_ind, eval_data.r, __rval,
00963 &(*eval_data.d_data)[__data.node_num]);
00964
00965 if(eval_data.f_cache && __data.n_parents > 1 && __data.n_children > 0)
00966 (*eval_data.f_cache)[__data.node_num] = eval_data.r;
00967 return ret;
00968 }
00969
00970 double calculate_value(bool eval_all)
00971 {
00972 return eval_data.r;
00973 }
00975 };
00976
00978
00982 struct der_cache
00983 {
00984 std::vector<double>* d;
00985 bool v;
00986 }
00987
00989
00993 struct der_eval_type
00994 {
00995 std::vector<func_cache>* f_data;
00996 std::vector<der_cache>* d_data;
00997 std::vector<double>* grad_vec;
00998 const model* mod;
00999 double mult;
01000 double mult_trans;
01001 unsigned int child_n;
01002 };
01003
01005
01010 class der_eval : public
01011 cached_backward_evaluator_base<der_eval_type,expression_node,bool,
01012 expression_const_walker>
01013 {
01014 private:
01016 typedef cached_backward_evaluator_base<der_eval_type,expression_node,
01017 bool,expression_const_walker> _Base;
01018
01019 protected:
01022 bool is_cached(const node_data_type& __data)
01023 {
01024 return false;
01025 }
01026
01027 public:
01036 der_eval(std::vector<func_cache>& __func_data, variable_indicator& __v,
01037 const model& __m, std::vector<std::vector<double > >* __d,
01038 std::vector<double>& __grad)
01039 {
01040 eval_data.f_data = &__func_data;
01041 eval_data.d_data = __d;
01042 eval_data.mod = &__m;
01043 eval_data.grad_vec = &__grad;
01044 eval_data.mult_trans = 1;
01045 eval_data.mult = 0;
01046 v_ind = &__v;
01047 }
01048
01050 der_eval(const der_eval& __d) { eval_data = __d.eval_data; }
01051
01053 ~der_eval() {}
01054
01058 void new_point(std::vector<func_cache>& __func_data,
01059 const variable_indicator& __v)
01060 {
01061 eval_data.f_data = &__func_data;
01062 v_ind = &__v;
01063 if(eval_data.d_data)
01064 for(int i=0; i<eval_data.mod->number_of_nodes(); ++i)
01065 (*eval_data.cache)[i].v = false;
01066 }
01067
01069 void new_result(std::vector<double>& __grad)
01070 {
01071 eval_data.grad_vec = &__grad;
01072 }
01073
01075 void set_mult(double scal)
01076 {
01077 eval_data.mult_trans = scal;
01078 }
01079
01080 public:
01081
01083 expression_const_walker short_cut_to(const expression_node& __data)
01084 { return eval_data.mod->node(0); }
01085
01087
01088
01089 void initialize()
01090 {
01091 eval_data.child_n = 0;
01092 }
01093
01094
01095 int calculate(const expression_node& __data)
01096 {
01097
01098 if(!(*eval_data.d_data)[__data.node_num].v)
01099 {
01100 double __x;
01101 if(__data.operator_type < 0)
01102 {
01103 std::vector<double>& d_data((*eval_data.d_data)[__data.node_num].d);
01104 node_ptr cw(eval_data.mod->node(__data.node_num));
01105 double __rval;
01106
01107 switch(__data.operator_type)
01108 {
01109 case EXPRINFO_CONSTANT:
01110
01111 break;
01112 case EXPRINFO_VARIABLE:
01113
01114 break;
01115 case EXPRINFO_SUM:
01116 case EXPRINFO_MEAN:
01117 std::copy(__data.coeffs.begin(), __data.coeffs.end(),
01118 std::back_inserter(d_data));
01119 break;
01120 case EXPRINFO_PROD:
01121 {
01122 children_iterator ce(cw->child_end());
01123 unsigned int n(__data.n_children), nc(0);
01124 d_data.reserve(n);
01125 node_ptr cc;
01126 double b(__data.params.nd());
01127 for(children_iterator ci = cw->child_begin(); ci != ce; ++ci)
01128 {
01129 cc = cw >> ci;
01130 __rval = (*eval_data.f_data)[cc->node_num].f;
01131 d_data.push_back(b);
01132 for(int i = nc-1; i>=0; --i)
01133 d_data[i] *= __rval;
01134 b *= __rval;
01135 nc++;
01136 }
01137 }
01138 break;
01139 case EXPRINFO_MONOME:
01140 {
01141 children_iterator ce(cw->child_end());
01142 unsigned int n(__data.n_children), nc(0);
01143 int exp;
01144 d_data.reserve(n);
01145 node_ptr cc;
01146 double b(1.), vv;
01147 for(children_iterator ci = cw->child_begin(); ci != ce; ++ci)
01148 {
01149 exp = __data.params.n()[nc];
01150 if(exp != 0)
01151 {
01152 cc = cw >> ci;
01153 __rval = (*eval_data.f_data)[cc->node_num].f;
01154 vv = func_eval::__power(__data.coeffs[nc], __rval, exp-1)*
01155 __data.coeffs[nc];
01156 d_data.push_back(b*exp*vv);
01157 vv *= __rval;
01158 for(int i = nc-1; i>=0; --i)
01159 d_data[i] *= vv;
01160 b *= vv;
01161 }
01162 else
01163 d_data.push_back(0);
01164 nc++;
01165 }
01166 }
01167 break;
01168 case EXPRINFO_MAX:
01169
01170 __calc_max(__rval * __data.coeffs[eval_data.n], __data);
01171 ++eval_data.n;
01172 break;
01173 case EXPRINFO_MIN:
01174
01175 {
01176 double h = __rval * __data.coeffs[eval_data.n];
01177 if(h <= eval_data.r)
01178 {
01179 (*eval_data.d_data)[__data.node_num][eval_data.info] = 0;
01180 if(h < eval_data.r)
01181 (*eval_data.d_data)[__data.node_num][eval_data.n] =
01182 __data.coeffs[eval_data.n];
01183 else
01184
01185 (*eval_data.d_data)[__data.node_num][eval_data.n] = 0;
01186 eval_data.r = h;
01187 eval_data.info = eval_data.n;
01188 }
01189 else
01190 {
01191 (*eval_data.d_data)[__data.node_num][eval_data.n] = 0;
01192 }
01193 }
01194 ++eval_data.n;
01195 break;
01196 case EXPRINFO_SCPROD:
01197
01198 { double h = __data.coeffs[eval_data.n]*__rval;
01199
01200
01201 if(eval_data.n & 1)
01202 {
01203 eval_data.r += eval_data.u.d*h;
01204 (*eval_data.d_data)[__data.node_num][eval_data.n] =
01205 eval_data.u.d*__data.coeffs[eval_data.n-1];
01206 (*eval_data.d_data)[__data.node_num][eval_data.n-1] =
01207 h*__data.coeffs[eval_data.n];
01208 }
01209 else
01210 eval_data.u.d = h;
01211 }
01212 eval_data.n++;
01213 break;
01214 case EXPRINFO_NORM:
01215
01216 if(__data.params.nd() == COCO_INF)
01217 __calc_max(fabs(__rval * __data.coeffs[eval_data.n]), __data);
01218 else
01219 {
01220 double h = __data.coeffs[eval_data.n]*fabs(__rval);
01221 double O = std::pow(h, __data.params.nd()-1);
01222 eval_data.r += O*h;
01223 (*eval_data.d_data)[__data.node_num][eval_data.n] = O;
01224 }
01225 eval_data.n++;
01226 if(eval_data.n == __data.n_children &&
01227 __data.params.nd() != COCO_INF)
01228 {
01229 double h = std::pow(eval_data.r,1./(__data.params.nd())-1.);
01230 for(unsigned int i = 0; i < eval_data.n; ++i)
01231 (*eval_data.d_data)[__data.node_num][eval_data.n] *= h;
01232 eval_data.r = std::pow(eval_data.r,1./(__data.params.nd()));
01233 }
01234 break;
01235 case EXPRINFO_INVERT:
01236 cw >>= cw->child_begin();
01237 __rval = (*eval_data.f_data)[cw->node_num].f;
01238 { double h = 1/__rval;
01239 d_data[0] = -__data.params.nd()*h*h;
01240 }
01241 break;
01242 case EXPRINFO_DIV:
01243 {
01244 children_iterator ci(cw->child_begin());
01245 node_ptr cc = cw >> ci;
01246 __rval = (*eval_data.f_data)[cc->node_num].f;
01247 ++ci;
01248 cc = cw >> ci;
01249 double h = 1/(*eval_data.f_data)[cc->node_num].f;
01250 d_data[0] = __data.params.nd()*h;
01251 d_data[1] = __rval*h;
01252 }
01253 break;
01254 case EXPRINFO_SQUARE:
01255 cw >>= cw->child_begin();
01256 __rval = (*eval_data.f_data)[cw->node_num].f;
01257 { double h = __data.coeffs[0]*__rval+__data.params.nd();
01258 d_data[0] = 2*h*__data.coeffs[0];
01259 }
01260 break;
01261 case EXPRINFO_INTPOWER:
01262 cw >>= cw->child_begin();
01263 __rval = (*eval_data.f_data)[cw->node_num].f;
01264 { int hl = __data.params.nn();
01265 if(hl == 0)
01266 {
01267 d_data[0] = 0;
01268 }
01269 else
01270 {
01271 double kl = __data.coeffs[0]*__rval;
01272 switch(hl)
01273 {
01274 case 1:
01275 d_data[0] = __data.coeffs[0];
01276 break;
01277 case 2:
01278 d_data[0] = 2*kl*__data.coeffs[0];
01279 break;
01280 case -1:
01281 { double h = 1/kl;
01282 d_data[0] = -h*h*__data.coeffs[0];
01283 }
01284 break;
01285 case -2:
01286 { double h = 1/kl;
01287 double k = h*h;
01288 d_data[0] = -2*h*k*__data.coeffs[0];
01289 }
01290 break;
01291 default:
01292 { double h;
01293 if(hl & 1)
01294 h = std::pow(fabs(kl), hl-1);
01295 else
01296 {
01297 if(kl < 0)
01298 h = -std::pow(-kl, hl-1);
01299 else
01300 h = std::pow(kl, hl-1);
01301 }
01302 d_data[0] = hl*h*__data.coeffs[0];
01303 }
01304 break;
01305 }
01306 }
01307 }
01308 break;
01309 case EXPRINFO_SQROOT:
01310 cw >>= cw->child_begin();
01311 __rval = (*eval_data.f_data)[cw->node_num].f;
01312 { double h = std::sqrt(__data.coeffs[0]*__rval+__data.params.nd());
01313 d_data[0] = 0.5*__data.coeffs[0]/h;
01314 }
01315 break;
01316 case EXPRINFO_ABS:
01317 cw >>= cw->child_begin();
01318 __rval = (*eval_data.f_data)[cw->node_num].f;
01319 { double h = __data.coeffs[0]*__rval+__data.params.nd();
01320 d_data[0] = h > 0 ? __data.coeffs[0] : (h < 0 ? -__data.coeffs[0] : 0);
01321 }
01322 break;
01323 case EXPRINFO_POW:
01324
01325 { double hh = __rval * __data.coeffs[eval_data.n];
01326 if(eval_data.n++ == 0)
01327 eval_data.r = hh+__data.params.nd();
01328 else
01329 {
01330 if(hh == 0)
01331 {
01332 (*eval_data.d_data)[__data.node_num][0] = 0;
01333 (*eval_data.d_data)[__data.node_num][1] =
01334 std::log(eval_data.r)*__data.coeffs[1];
01335 eval_data.r = 1;
01336 }
01337 else
01338 {
01339 double h = std::pow(eval_data.r, hh);
01340
01341 (*eval_data.d_data)[__data.node_num][0] =
01342 hh*std::pow(eval_data.r, hh-1)*__data.coeffs[0];
01343 (*eval_data.d_data)[__data.node_num][1] =
01344 std::log(eval_data.r)*h*__data.coeffs[1];
01345 eval_data.r = h;
01346 }
01347 }
01348 }
01349 break;
01350 case EXPRINFO_EXP:
01351 { double h = std::exp(__rval*__data.coeffs[0]+__data.params.nd());
01352 eval_data.r = h;
01353 (*eval_data.d_data)[__data.node_num][0] = h*__data.coeffs[0];
01354 }
01355 break;
01356 case EXPRINFO_LOG:
01357 { double h = __rval*__data.coeffs[0]+__data.params.nd();
01358 eval_data.r = std::log(h);
01359 (*eval_data.d_data)[__data.node_num][0] = __data.coeffs[0]/h;
01360 }
01361 break;
01362 case EXPRINFO_SIN:
01363 { double h = __rval*__data.coeffs[0]+__data.params.nd();
01364 eval_data.r = std::sin(h);
01365 (*eval_data.d_data)[__data.node_num][0] =
01366 __data.coeffs[0]*std::cos(h);
01367 }
01368 break;
01369 case EXPRINFO_COS:
01370 { double h = __rval*__data.coeffs[0]+__data.params.nd();
01371 eval_data.r = std::cos(h);
01372 (*eval_data.d_data)[__data.node_num][0] =
01373 -__data.coeffs[0]*std::sin(h);
01374 }
01375 break;
01376 case EXPRINFO_ATAN2:
01377 { double hh = __rval * __data.coeffs[eval_data.n];
01378 if(eval_data.n++ == 0)
01379 eval_data.r = hh;
01380 else
01381 { double h = eval_data.r;
01382 h *= h;
01383 h += hh*hh;
01384 (*eval_data.d_data)[__data.node_num][0] = __data.coeffs[0]*hh/h;
01385 (*eval_data.d_data)[__data.node_num][1] =
01386 -__data.coeffs[1]*eval_data.r/h;
01387 eval_data.r = std::atan2(eval_data.r,hh);
01388 }
01389 }
01390 break;
01391 case EXPRINFO_GAUSS:
01392 { double h = (__data.coeffs[0]*__rval-__data.params.d()[0])/
01393 __data.params.d()[1];
01394 double k = std::exp(-h*h);
01395 eval_data.r = k;
01396 (*eval_data.d_data)[__data.node_num][0] =
01397 -2*__data.coeffs[0]*k*h/__data.params.d()[1];
01398 }
01399 break;
01400 case EXPRINFO_POLY:
01401 throw nyi_exception("func_d_evaluator: POLY");
01402 break;
01403 case EXPRINFO_LIN:
01404 case EXPRINFO_QUAD:
01405
01406 break;
01407 case EXPRINFO_IN:
01408 {
01409 __x = __data.coeffs[eval_data.n]*__rval;
01410 const interval& i(__data.params.i()[eval_data.n]);
01411 if(eval_data.r != -1 && i.contains(__x))
01412 {
01413 if(eval_data.r == 1 && (__x == i.inf() || __x == i.sup()))
01414 eval_data.r = 0;
01415 }
01416 else
01417 {
01418 eval_data.r = -1;
01419 ret = -1;
01420 }
01421 }
01422
01423 if(eval_data.n == 0)
01424 {
01425 std::vector<double>& v((*eval_data.d_data)[__data.node_num]);
01426 v.erase(v.begin(),v.end());
01427 v.insert(v.begin(),__data.n_children,0.);
01428 }
01429 eval_data.n++;
01430 break;
01431 case EXPRINFO_IF:
01432 __x = __rval * __data.coeffs[eval_data.n];
01433 if(eval_data.n == 0)
01434 {
01435 const interval& i(__data.params.ni());
01436 if(!i.contains(__x))
01437 {
01438 ret = 1;
01439 (*eval_data.d_data)[__data.node_num][1] = 0.;
01440 }
01441 else
01442 (*eval_data.d_data)[__data.node_num][2] = 0.;
01443 (*eval_data.d_data)[__data.node_num][0] = 0.;
01444 }
01445 else
01446 {
01447 eval_data.r = __x;
01448 (*eval_data.d_data)[__data.node_num][eval_data.n] =
01449 __data.coeffs[eval_data.n];
01450 ret = -1;
01451 }
01452 eval_data.n += ret+1;
01453 break;
01454 case EXPRINFO_AND:
01455 { __x = __data.coeffs[eval_data.n]*__rval;
01456 const interval& i(__data.params.i()[eval_data.n]);
01457 if(eval_data.r == 1 && !i.contains(__x))
01458 {
01459 eval_data.r = 0;
01460 ret = -1;
01461 }
01462 }
01463
01464 if(eval_data.n == 0)
01465 {
01466 std::vector<double>& v((*eval_data.d_data)[__data.node_num]);
01467 v.erase(v.begin(),v.end());
01468 v.insert(v.begin(),__data.n_children,0.);
01469 }
01470 eval_data.n++;
01471 break;
01472 case EXPRINFO_OR:
01473 { __x = __data.coeffs[eval_data.n]*__rval;
01474 const interval& i(__data.params.i()[eval_data.n]);
01475 if(eval_data.r == 0 && i.contains(__x))
01476 {
01477 eval_data.r = 1;
01478 ret = -1;
01479 }
01480 }
01481
01482 if(eval_data.n == 0)
01483 {
01484 std::vector<double>& v((*eval_data.d_data)[__data.node_num]);
01485 v.erase(v.begin(),v.end());
01486 v.insert(v.begin(),__data.n_children,0.);
01487 }
01488 eval_data.n++;
01489 break;
01490 case EXPRINFO_NOT:
01491 { __x = __data.coeffs[0]*__rval;
01492 const interval& i(__data.params.ni());
01493 if(i.contains(__x))
01494 eval_data.r = 0;
01495 else
01496 eval_data.r = 1;
01497
01498 (*eval_data.d_data)[__data.node_num][0] = 0.;
01499 }
01500 break;
01501 case EXPRINFO_IMPLIES:
01502 { const interval& i(__data.params.i()[eval_data.n]);
01503 __x = __rval * __data.coeffs[eval_data.n];
01504 if(eval_data.n == 0)
01505 {
01506 if(!i.contains(__x))
01507 {
01508 eval_data.r = 1;
01509 ret = -1;
01510 }
01511
01512 (*eval_data.d_data)[__data.node_num][0] = 0.;
01513 (*eval_data.d_data)[__data.node_num][1] = 0.;
01514 }
01515 else
01516 eval_data.r = i.contains(__x) ? 1 : 0;
01517 ++eval_data.n;
01518 }
01519 break;
01520 case EXPRINFO_COUNT:
01521 { __x = __data.coeffs[eval_data.n]*__rval;
01522 const interval& i(__data.params.i()[eval_data.n]);
01523 if(i.contains(__x))
01524 eval_data.r += 1;
01525 }
01526
01527 if(eval_data.n == 0)
01528 {
01529 std::vector<double>& v((*eval_data.d_data)[__data.node_num]);
01530 v.erase(v.begin(),v.end());
01531 v.insert(v.begin(),__data.n_children,0.);
01532 }
01533 eval_data.n++;
01534 break;
01535 case EXPRINFO_ALLDIFF:
01536 { __x = __data.coeffs[eval_data.n]*__rval;
01537 for(std::vector<double>::const_iterator _b =
01538 ((std::vector<double>*)eval_data.u.p)->begin();
01539 _b != ((std::vector<double>*)eval_data.u.p)->end(); ++_b)
01540 {
01541 if(fabs(__x-*_b) <= __data.params.nd())
01542 {
01543 eval_data.r = 0;
01544 ret = -1;
01545 break;
01546 }
01547 }
01548 if(ret != -1)
01549 ((std::vector<double>*) eval_data.u.p)->push_back(__x);
01550 }
01551
01552 if(eval_data.n == 0)
01553 {
01554 std::vector<double>& v((*eval_data.d_data)[__data.node_num]);
01555 v.erase(v.begin(),v.end());
01556 v.insert(v.begin(),__data.n_children,0.);
01557 }
01558 eval_data.n++;
01559 if(eval_data.n == __data.n_children || ret == -1)
01560 delete (std::vector<double>*) eval_data.u.p;
01561 break;
01562 case EXPRINFO_HISTOGRAM:
01563 throw nyi_exception("func_d_evaluator: HISTOGRAM");
01564 break;
01565 case EXPRINFO_LEVEL:
01566 { int h = (int)eval_data.r;
01567 __x = __data.coeffs[eval_data.n]*__rval;
01568 interval _h;
01569
01570 if(h != INT_MAX)
01571 {
01572 while(h < __data.params.im().nrows())
01573 {
01574 _h = __data.params.im()[h][eval_data.n];
01575 if(_h.contains(__x))
01576 break;
01577 h++;
01578 }
01579 if(h == __data.params.im().nrows())
01580 {
01581 ret = -1;
01582 eval_data.r = INT_MAX;
01583 }
01584 else
01585 eval_data.r = h;
01586 }
01587 }
01588
01589 if(eval_data.n == 0)
01590 {
01591 std::vector<double>& v((*eval_data.d_data)[__data.node_num]);
01592 v.erase(v.begin(),v.end());
01593 v.insert(v.begin(),__data.n_children,0.);
01594 }
01595 eval_data.n++;
01596 break;
01597 case EXPRINFO_NEIGHBOR:
01598 if(eval_data.n == 0)
01599 eval_data.r = __data.coeffs[0]*__rval;
01600 else
01601 {
01602 double h = eval_data.r;
01603 eval_data.r = 0;
01604 __x = __data.coeffs[1]*__rval;
01605 for(unsigned int i = 0; i < __data.params.n().size(); i+=2)
01606 {
01607 if(h == __data.params.n()[i] && __x == __data.params.n()[i+1])
01608 {
01609 eval_data.r = 1;
01610 break;
01611 }
01612 }
01613 }
01614
01615 if(eval_data.n == 0)
01616 {
01617 std::vector<double>& v((*eval_data.d_data)[__data.node_num]);
01618 v.erase(v.begin(),v.end());
01619 v.insert(v.begin(),__data.n_children,0.);
01620 }
01621 eval_data.n++;
01622 break;
01623 case EXPRINFO_NOGOOD:
01624 {
01625 __x = __data.coeffs[eval_data.n]*__rval;
01626 if(eval_data.r == 0 || __data.params.n()[eval_data.n] != __x)
01627 {
01628 eval_data.r = 0;
01629 ret = -1;
01630 }
01631 }
01632
01633 if(eval_data.n == 0)
01634 {
01635 std::vector<double>& v((*eval_data.d_data)[__data.node_num]);
01636 v.erase(v.begin(),v.end());
01637 v.insert(v.begin(),__data.n_children,0.);
01638 }
01639 eval_data.n++;
01640 break;
01641 case EXPRINFO_EXPECTATION:
01642 throw nyi_exception("func_d_evaluator: EXPECTATION");
01643 break;
01644 case EXPRINFO_INTEGRAL:
01645 throw nyi_exception("func_d_evaluator: INTEGRAL");
01646 break;
01647 case EXPRINFO_LOOKUP:
01648 case EXPRINFO_PWLIN:
01649 case EXPRINFO_SPLINE:
01650 case EXPRINFO_PWCONSTLC:
01651 case EXPRINFO_PWCONSTRC:
01652 throw nyi_exception("func_d_evaluator: Table Operations");
01653 break;
01654 case EXPRINFO_DET:
01655 case EXPRINFO_COND:
01656 case EXPRINFO_PSD:
01657 case EXPRINFO_MPROD:
01658 case EXPRINFO_FEM:
01659 throw nyi_exception("func_d_evaluator: Matrix Operations");
01660 break;
01661 case EXPRINFO_RE:
01662 case EXPRINFO_IM:
01663 case EXPRINFO_ARG:
01664 case EXPRINFO_CPLXCONJ:
01665 throw nyi_exception("func_d_evaluator: Complex Operations");
01666 break;
01667 case EXPRINFO_CMPROD:
01668 case EXPRINFO_CGFEM:
01669 throw nyi_exception("func_d_evaluator: Const Matrix Operations");
01670 break;
01671 default:
01672 throw api_exception(apiee_evaluator,
01673 std::string("func_d_evaluator: unknown function type ")+
01674 convert_to_str(__data.operator_type));
01675 break;
01676 }
01677 }
01678 else if(__data.operator_type > 0)
01679
01680 eval_data.r = __data.f_evaluate(eval_data.n++, __data.params.nn(),
01681 *eval_data.x, *v_ind, eval_data.r, __rval,
01682 &(*eval_data.d_data)[__data.node_num]);
01683 (*eval_data.d_data)[__data.node_num].v = true;
01684 }
01685 if(__data.operator_type == EXPRINFO_CONSTANT)
01686 return 0;
01687 else if(__data.operator_type == EXPRINFO_VARIABLE)
01688 {
01689
01690 (*eval_data.grad_vec)[__data.params.nn()] += eval_data.mult_trans;
01691 return 0;
01692 }
01693 else if(__data.operator_type == EXPRINFO_LIN)
01694 {
01695 linalg::linalg_add(linalg_scale(eval_data.mod->lin[__data.params.nn()], eval_data.mult_trans),
01696 *eval_data.grad_vec,*eval_data.grad_vec);
01697 return 0;
01698 }
01699 else if(__data.operator_type == EXPRINFO_QUAD)
01700 {
01701 linalg::linalg_ssum(*eval_data.grad_vec, 2*eval_data.mult_trans,
01702 (*eval_data.d_data)[__data.node_num]);
01703 return 0;
01704 }
01705 else if(__data.ev && (*__data.ev)[DER_EVALUATOR])
01706
01707 {
01708 linalg::linalg_ssum(*eval_data.grad_vec, eval_data.mult,
01709 (*(der_evaluator)(*__data.ev)[DER_EVALUATOR])(
01710 (*eval_data.d_data)[__data.node_num], *v_ind));
01711 return 0;
01712 }
01713 else if(eval_data.mult_trans == 0)
01714
01715 return 0;
01716 else
01717 {
01718 eval_data.child_n = 1;
01719 eval_data.mult = eval_data.mult_trans;
01720 if(__data.n_parents > 1 && __data.n_children > 0 && eval_data.d_data)
01721 {
01722 eval_data.mult_trans = (*eval_data.d_data)[__data.node_num][0];
01723 }
01724 else
01725 eval_data.mult_trans *= (*eval_data.d_data)[__data.node_num][0];
01726 return 1;
01727 }
01728 }
01729
01730
01731 void cleanup(const expression_node& __data)
01732 {
01733
01734 if(__data.n_parents > 1 && __data.n_children > 0 && eval_data.d_data
01735 && (*eval_data.d_data)[__data.node_num].size() == 0)
01736 {
01737 (*eval_data.d_data)[__data.node_num] = *eval_data.grad_vec;
01738 linalg::linalg_smult(*eval_data.grad_vec, eval_data.mult);
01739 }
01740 }
01741
01742 void retrieve_from_cache(const expression_node& __data)
01743 {
01744
01745 linalg::linalg_ssum(*eval_data.grad_vec, eval_data.mult_trans,
01746 (*eval_data.d_data)[__data.node_num].d);
01747 }
01748
01749 int update(const bool& __rval)
01750 {
01751 eval_data.child_n++;
01752 return 0;
01753 }
01754
01755
01756 int update(const expression_node& __data, const bool& __rval)
01757 {
01758 if(__data.n_children == 0)
01759 return 0;
01760 if(__data.n_parents > 1 && __data.n_children > 0 && eval_data.d_data)
01761 {
01762 if(eval_data.child_n < __data.n_children)
01763 eval_data.mult_trans =
01764 (*eval_data.d_data)[__data.node_num][eval_data.child_n];
01765 }
01766 else if(eval_data.child_n < __data.n_children)
01767 {
01768 eval_data.mult_trans = eval_data.mult *
01769 (*eval_data.d_data)[__data.node_num][eval_data.child_n];
01770 }
01771 eval_data.child_n++;
01772 return 0;
01773 }
01774
01775 bool calculate_value(bool eval_all)
01776 {
01777 return true;
01778 }
01780 };
01781
01782 }
01783
01784 #endif