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 _IDERF_EVALUATOR_H_
00028 #define _IDERF_EVALUATOR_H_
00029
00030 #include <coconut_config.h>
00031 #include <evaluator.h>
00032 #include <expression.h>
00033 #include <model.h>
00034 #include <eval_main.h>
00035 #include <linalg.h>
00036 #include <math.h>
00037 #include <api_exception.h>
00038
00039 using namespace vgtl;
00040
00041 namespace coco {
00042
00044
00048 struct iderf_ret_type
00049 {
00050 interval f;
00051 linalg::sparse_vector<interval> g;
00052 };
00053
00055 typedef iderf_ret_type (*iderf_evaluator)(const std::vector<interval>* __x,
00056 const variable_indicator& __v);
00057
00059
00063 struct iderf_eval_type
00064 {
00065 const std::vector<interval>* x;
00066 const std::vector<interval>* range;
00067 std::vector<iderf_ret_type>* cache;
00068
00069
00070 const model* mod;
00071 union { void *p; interval_st d; int info; } u;
00073 iderf_ret_type r;
00074 unsigned int n;
00075 bool do_intersect;
00076 };
00077
00079
00085 class iderf_eval : public
00086 cached_forward_evaluator_base<iderf_eval_type,expression_node,iderf_ret_type,
00087 expression_const_walker>
00088 {
00089 private:
00091 typedef cached_forward_evaluator_base<iderf_eval_type,expression_node,
00092 iderf_ret_type,expression_const_walker> _Base;
00093
00095 typedef linalg::sparse_vector<interval> _IGRAD;
00096
00097 protected:
00100 bool is_cached(const node_data_type& __data)
00101 {
00102 if(__data.operator_type == EXPRINFO_LIN ||
00103 __data.operator_type == EXPRINFO_QUAD)
00104 return true;
00105 else
00106 return false;
00107 #if 0
00108 if(eval_data.cache && __data.n_parents > 1 && __data.n_children > 0)
00109 return true;
00110 else
00111 return false;
00112 #endif
00113 }
00114
00115 private:
00118 interval __power(double __coeff, const interval &__x, int __exp)
00119 {
00120 if(__exp == 0)
00121 return 1.;
00122 else
00123 {
00124 interval k = __coeff*__x;
00125 switch(__exp)
00126 {
00127 case 1:
00128 return k;
00129 break;
00130 case 2:
00131 return sqr(k);
00132 break;
00133 case -1:
00134 return 1./k;
00135 break;
00136 case -2:
00137 return 1./sqr(k);
00138 break;
00139 default:
00140 return ipow(k, __exp);
00141 break;
00142 }
00143 }
00144 return 0;
00145 }
00146
00147 public:
00155 iderf_eval(const std::vector<interval>& __x, const std::vector<interval>& __rg,
00156 const variable_indicator& __v, const model& __m,
00157 std::vector<iderf_ret_type>* __c, bool do_i = true)
00158 : _Base()
00159 {
00160 eval_data.x = &__x;
00161 eval_data.range = &__rg;
00162 eval_data.cache = __c;
00163 eval_data.mod = &__m;
00164 eval_data.u.d = 0.;
00165 v_ind = &__v;
00166 eval_data.n = 0;
00167 eval_data.do_intersect = do_i;
00168 }
00169
00171 iderf_eval(const iderf_eval& __v) : _Base(__v) {}
00172
00174 ~iderf_eval() {}
00175
00177 expression_const_walker short_cut_to(const expression_node& __data)
00178 { return eval_data.mod->node(0); }
00179
00183 void new_box(const std::vector<interval>& __x, const variable_indicator& __v)
00184 {
00185 eval_data.x = &__x;
00186 v_ind = &__v;
00187 }
00188
00190
00191 void initialize() { return; }
00192
00193 int initialize(const expression_node& __data)
00194 {
00195 eval_data.n = 0;
00196 if(__data.ev && (*__data.ev)[FUNC_IDER_FORWARD])
00197
00198 {
00199 eval_data.r =
00200 (*(iderf_evaluator)(*__data.ev)[FUNC_IDER_FORWARD])(eval_data.x,
00201 *v_ind);
00202 return 0;
00203 }
00204 else
00205 {
00206 switch(__data.operator_type)
00207 {
00208 case EXPRINFO_SUM:
00209 case EXPRINFO_PROD:
00210 case EXPRINFO_MAX:
00211 case EXPRINFO_MIN:
00212 case EXPRINFO_INVERT:
00213 case EXPRINFO_DIV:
00214 eval_data.r.f = __data.params.nd();
00215 break;
00216 case EXPRINFO_MONOME:
00217 case EXPRINFO_IN:
00218 case EXPRINFO_AND:
00219 case EXPRINFO_NOGOOD:
00220 eval_data.r.f = 1.;
00221 break;
00222 case EXPRINFO_ALLDIFF:
00223 eval_data.u.p = (void*) new std::vector<interval>;
00224 ((std::vector<interval>*)eval_data.u.p)->reserve(__data.n_children);
00225
00226 case EXPRINFO_MEAN:
00227 case EXPRINFO_IF:
00228 case EXPRINFO_OR:
00229 case EXPRINFO_NOT:
00230 case EXPRINFO_COUNT:
00231 case EXPRINFO_SCPROD:
00232 case EXPRINFO_NORM:
00233 case EXPRINFO_LEVEL:
00234 eval_data.r.f = 0.;
00235 break;
00236 case EXPRINFO_DET:
00237 case EXPRINFO_PSD:
00238
00239 break;
00240 case EXPRINFO_COND:
00241 case EXPRINFO_FEM:
00242 case EXPRINFO_MPROD:
00243
00244 break;
00245 }
00246 unsigned int numvar = eval_data.mod->number_of_variables();
00247 eval_data.r.g = _IGRAD(numvar);
00248 return 1;
00249 }
00250 }
00251
00252 void calculate(const expression_node& __data)
00253 {
00254 if(__data.operator_type > 0)
00255 {
00256 throw nyi_exception(std::string("No user defined evaluators for forward interval derivatives"));
00257
00258
00259 }
00260 if(eval_data.do_intersect)
00261 {
00262 eval_data.r.f.intersectwith(__data.f_bounds);
00263 eval_data.r.f.intersectwith((*eval_data.range)[__data.node_num]);
00264 }
00265 }
00266
00267 void retrieve_from_cache(const expression_node& __data)
00268 {
00269 if(__data.operator_type == EXPRINFO_LIN)
00270 {
00271 const linalg::matrix<double>::Row& lrw(eval_data.mod->lin[__data.params.nn()]);
00272 linalg::matrix<double>::Row::const_iterator _x, _e;
00273
00274 eval_data.r.f = interval(0.);
00275 for(_x = lrw.begin(); _x != _e; ++_x)
00276 {
00277 eval_data.r.f += (*eval_data.x)[_x.index()] * *_x;
00278 eval_data.r.g[_x.index()] = *_x;
00279 }
00280 }
00281 else if(__data.operator_type == EXPRINFO_QUAD)
00282 {
00283 throw nyi_exception("int_evaluator: QUAD");
00284 }
00285 else
00286 eval_data.r = (*eval_data.cache)[__data.node_num];
00287 }
00288
00289 int update(const iderf_ret_type& __rval)
00290 {
00291 eval_data.r = __rval;
00292 return 0;
00293 }
00294
00295 int update(const expression_node& __data, const iderf_ret_type& __rval)
00296 {
00297 interval __x;
00298 int ret = 0;
00299 unsigned int nn;
00300 linalg::sparse_vector<interval>::const_iterator rval_it;
00301
00302 if(__data.operator_type < 0)
00303 {
00304 switch(__data.operator_type)
00305 {
00306 case EXPRINFO_CONSTANT:
00307 eval_data.r.f = __data.params.nd();
00308 break;
00309 case EXPRINFO_VARIABLE:
00310 nn = __data.params.nn();
00311 eval_data.r.f = (*eval_data.x)[nn];
00312 eval_data.r.g[nn] = 1.;
00313
00314 break;
00315 case EXPRINFO_SUM:
00316 case EXPRINFO_MEAN:
00317 {
00318 eval_data.r.f += __data.coeffs[eval_data.n]*__rval.f;
00319 linalg::sparse_vector<interval> g(__rval.g);
00320 g *= interval(__data.coeffs[eval_data.n]);
00321 eval_data.r.g += g;
00322
00323
00324
00325
00326
00327 break;
00328 }
00329 case EXPRINFO_PROD:
00330 {
00331
00332 linalg::sparse_vector<interval> g(__rval.g);
00333 eval_data.r.g *= __rval.f;
00334 g *= eval_data.r.f;
00335 eval_data.r.g += g;
00336
00337
00338
00339
00340
00341 eval_data.r.f *= __rval.f;
00342
00343 break;
00344 }
00345 case EXPRINFO_MONOME:
00346
00347
00348
00349
00350
00351
00352 throw nyi_exception("iderf_evaluator: MONOME");
00353 break;
00354 case EXPRINFO_MAX:
00355
00356
00357
00358 throw nyi_exception("iderf_evaluator: MAX");
00359 break;
00360 case EXPRINFO_MIN:
00361
00362
00363
00364 throw nyi_exception("iderf_evaluator: MIN");
00365 break;
00366 case EXPRINFO_SCPROD:
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 throw nyi_exception("iderf_evaluator: SCPROD");
00377 break;
00378 case EXPRINFO_NORM:
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 throw nyi_exception("iderf_evaluator: NORM");
00393 break;
00394 case EXPRINFO_INVERT:
00395 {
00396 eval_data.r.f /= __rval.f;
00397 interval h = -__data.params.nd()/sqr(__rval.f);
00398 eval_data.r.g = __rval.g;
00399 eval_data.r.g *= h;
00400
00401
00402
00403
00404
00405 break;
00406 }
00407 case EXPRINFO_DIV:
00408 {
00409
00410
00411 if(eval_data.n == 0)
00412 {
00413 eval_data.r.f *= __rval.f;
00414 eval_data.r.g = __rval.g;
00415 eval_data.r.g *= interval(__data.params.nd());
00416 }
00417 else
00418 {
00419 eval_data.r.f /= __rval.f;
00420 if(eval_data.do_intersect)
00421 {
00422 eval_data.r.f.intersectwith(__data.f_bounds);
00423 eval_data.r.f.intersectwith((*eval_data.range)[__data.node_num]);
00424 }
00425
00426 for(rval_it = __rval.g.begin(); rval_it != __rval.g.end(); ++rval_it)
00427 {
00428 eval_data.r.g[rval_it.index()] -= eval_data.r.f*(*rval_it);
00429 }
00430 linalg::sparse_vector<interval>::iterator jt;
00431 for(jt = eval_data.r.g.begin(); jt != eval_data.r.g.end(); ++jt)
00432 {
00433 *jt /= __rval.f;
00434 }
00435 }
00436 break;
00437 }
00438 case EXPRINFO_SQUARE:
00439 {
00440 interval h = __data.coeffs[0]*__rval.f+__data.params.nd();
00441 eval_data.r.f = sqr(h);
00442 h *= 2*__data.coeffs[0];
00443 eval_data.r.g = __rval.g;
00444 eval_data.r.g *= h;
00445 break;
00446 }
00447 case EXPRINFO_INTPOWER:
00448 {
00449 eval_data.r.f = __power(__data.coeffs[0], __rval.f, __data.params.nn());
00450 interval h = __power(__data.coeffs[0], __rval.f, __data.params.nn()-1)*
00451 __data.coeffs[0]*__data.params.nn();
00452 eval_data.r.g = __rval.g;
00453 eval_data.r.g *= h;
00454 break;
00455 }
00456 case EXPRINFO_SQROOT:
00457 {
00458 eval_data.r.f = sqrt(__data.coeffs[0]*__rval.f+__data.params.nd());
00459 interval h = __data.coeffs[0]/(2*eval_data.r.f);
00460 eval_data.r.g = __rval.g;
00461 eval_data.r.g *= h;
00462 break;
00463 }
00464 case EXPRINFO_ABS:
00465
00466 throw nyi_exception("iderf_evaluator: ABS");
00467 break;
00468 case EXPRINFO_POW:
00469
00470
00471
00472
00473
00474
00475
00476 throw nyi_exception("iderf_evaluator: POW");
00477 break;
00478 case EXPRINFO_EXP:
00479 {
00480 eval_data.r.f = exp(__rval.f*__data.coeffs[0]+__data.params.nd());
00481 interval h = eval_data.r.f*__data.coeffs[0];
00482 eval_data.r.g = __rval.g;
00483 eval_data.r.g *= h;
00484 break;
00485 }
00486 case EXPRINFO_LOG:
00487 {
00488 interval h = __rval.f*__data.coeffs[0]+__data.params.nd();
00489 eval_data.r.f = log(h);
00490 eval_data.r.g = __rval.g;
00491 eval_data.r.g *= __data.coeffs[0]/h;
00492 break;
00493 }
00494 case EXPRINFO_SIN:
00495 {
00496 interval h = __rval.f*__data.coeffs[0]+__data.params.nd();
00497 eval_data.r.f = sin(h);
00498 eval_data.r.g = __rval.g;
00499 eval_data.r.g *= __data.coeffs[0]*cos(h);
00500 break;
00501 }
00502 case EXPRINFO_COS:
00503 {
00504 interval h = __rval.f*__data.coeffs[0]+__data.params.nd();
00505 eval_data.r.f = cos(h);
00506 eval_data.r.g = __rval.g;
00507 eval_data.r.g *= -__data.coeffs[0]*sin(h);
00508 break;
00509 }
00510 case EXPRINFO_ATAN2:
00511
00512
00513
00514
00515
00516
00517
00518 throw nyi_exception("iderf_evaluator: ATAN2");
00519 break;
00520 case EXPRINFO_GAUSS:
00521 {
00522 interval h = (__data.coeffs[0]*__rval.f-__data.params.d()[0])/
00523 __data.params.d()[1];
00524 eval_data.r.f = gauss(h);
00525 eval_data.r.g = __rval.g;
00526 eval_data.r.g *= -2*__data.coeffs[0]*eval_data.r.f*h/__data.params.d()[1];
00527 break;
00528 }
00529 case EXPRINFO_POLY:
00530 throw nyi_exception("int_evaluator: POLY");
00531 break;
00532 case EXPRINFO_LIN:
00533 case EXPRINFO_QUAD:
00534
00535 break;
00536 case EXPRINFO_IN:
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573 throw nyi_exception("iderf_evaluator: IN");
00574 break;
00575 case EXPRINFO_IF:
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604 throw nyi_exception("iderf_evaluator: IF");
00605 break;
00606 case EXPRINFO_AND:
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622 throw nyi_exception("iderf_evaluator: AND");
00623 break;
00624 case EXPRINFO_OR:
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 throw nyi_exception("iderf_evaluator: OR");
00640 break;
00641 case EXPRINFO_NOT:
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651 throw nyi_exception("iderf_evaluator: NOT");
00652 break;
00653 case EXPRINFO_IMPLIES:
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678 throw nyi_exception("iderf_evaluator: IMPLIES");
00679 break;
00680 case EXPRINFO_COUNT:
00681
00682
00683
00684
00685
00686
00687
00688
00689 throw nyi_exception("iderf_evaluator: COUNT");
00690 break;
00691 case EXPRINFO_ALLDIFF:
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713 throw nyi_exception("iderf_evaluator: ALLDIFF");
00714 break;
00715 case EXPRINFO_HISTOGRAM:
00716 throw nyi_exception("iderf_evaluator: HISTOGRAM");
00717 break;
00718 case EXPRINFO_LEVEL:
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759 throw nyi_exception("iderf_evaluator: LEVEL");
00760 break;
00761 case EXPRINFO_NEIGHBOR:
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789 throw nyi_exception("iderf_evaluator: NEIGHBOR");
00790 break;
00791 case EXPRINFO_NOGOOD:
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804 throw nyi_exception("iderf_evaluator: NOGOOD");
00805 break;
00806 case EXPRINFO_EXPECTATION:
00807 throw nyi_exception("iderf_evaluator: EXPECTATION");
00808 break;
00809 case EXPRINFO_INTEGRAL:
00810 throw nyi_exception("iderf_evaluator: INTEGRAL");
00811 break;
00812 case EXPRINFO_LOOKUP:
00813 case EXPRINFO_PWLIN:
00814 case EXPRINFO_SPLINE:
00815 case EXPRINFO_PWCONSTLC:
00816 case EXPRINFO_PWCONSTRC:
00817 throw nyi_exception("iderf_evaluator: Table Operations");
00818 break;
00819 case EXPRINFO_DET:
00820 case EXPRINFO_COND:
00821 case EXPRINFO_PSD:
00822 case EXPRINFO_MPROD:
00823 case EXPRINFO_FEM:
00824 throw nyi_exception("iderf_evaluator: Matrix Operations");
00825 break;
00826 case EXPRINFO_RE:
00827 case EXPRINFO_IM:
00828 case EXPRINFO_ARG:
00829 case EXPRINFO_CPLXCONJ:
00830 throw nyi_exception("iderf_evaluator: Complex Operations");
00831 break;
00832 case EXPRINFO_CMPROD:
00833 case EXPRINFO_CGFEM:
00834 throw nyi_exception("iderf_evaluator: Const Matrix Operations");
00835 break;
00836 default:
00837 throw api_exception(apiee_evaluator,
00838 std::string("iderf_evaluator: unknown function type ")+
00839 convert_to_str(__data.operator_type));
00840 break;
00841 }
00842 eval_data.n++;
00843 }
00844 else if(__data.operator_type > 0)
00845 {
00846 throw nyi_exception(std::string("No user defined evaluators for forward interval derivatives"));
00847
00848
00849
00850
00851
00852 }
00853
00854
00855 if(eval_data.cache)
00856 (*eval_data.cache)[__data.node_num] = eval_data.r;
00857 return ret;
00858 }
00859
00860 iderf_ret_type calculate_value(bool eval_all)
00861 {
00862 return eval_data.r;
00863 }
00865 };
00866
00867 }
00868
00869 #endif