LCOV - code coverage report
Current view: top level - builds/barbot/Cosmos/src/ModelGenerator - HaslFormula.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 200 293 68.3 %
Date: 2021-06-16 15:43:28 Functions: 17 23 73.9 %

          Line data    Source code
       1             : /*******************************************************************************
       2             :  *                                                                             *
       3             :  * Cosmos:(C)oncept et (O)utils (S)tatistique pour les (Mo)deles               *
       4             :  * (S)tochastiques                                                             *
       5             :  *                                                                             *
       6             :  * Copyright (C) 2009-2012 LSV & LACL                                          *
       7             :  * Authors: Paolo Ballarini Benoît Barbot & Hilal Djafri                       *
       8             :  * Website: http://www.lsv.ens-cachan.fr/Software/cosmos                       *
       9             :  *                                                                             *
      10             :  * This program is free software; you can redistribute it and/or modify        *
      11             :  * it under the terms of the GNU General Public License as published by        *
      12             :  * the Free Software Foundation; either version 3 of the License, or           *
      13             :  * (at your option) any later version.                                         *
      14             :  *                                                                             *
      15             :  * This program is distributed in the hope that it will be useful,             *
      16             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of              *
      17             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               *
      18             :  * GNU General Public License for more details.                                *
      19             :  *                                                                             *
      20             :  * You should have received a copy of the GNU General Public License along     *
      21             :  * with this program; if not, write to the Free Software Foundation, Inc.,     *
      22             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.                 *
      23             :  * file parameters.hpp                                                         *
      24             :  * Created by Benoit Barbot on 12/12/12.                                       *
      25             :  *******************************************************************************
      26             :  */
      27             : 
      28             : #include <iostream>
      29             : #include <limits>
      30             : #include <boost/math/distributions/normal.hpp>
      31             : #include <boost/math/distributions/binomial.hpp>
      32             : 
      33             : #include "HaslFormula.hpp"
      34             : #include "parameters.hpp"
      35             : 
      36             : /**
      37             :  * Trivial confidence interval containing all R.
      38             :  */
      39         215 : ConfInt::ConfInt(){
      40         215 :     mean = 0;
      41         215 :     low = - std::numeric_limits<double>::infinity();
      42         215 :     up = std::numeric_limits<double>::infinity();
      43         215 :     min = - std::numeric_limits<double>::infinity();
      44         215 :     max = std::numeric_limits<double>::infinity();
      45         215 :     conf = 1;
      46         215 : }
      47             : 
      48             : /**
      49             :  * Symetric confidence interval
      50             :  * @param meanArg is the middle of the confidence interval
      51             :  * @param width is the width of the confidence interval
      52             :  * @param min the smallest value observed
      53             :  * @param max the maximal value observed
      54             :  */
      55        1916 : ConfInt::ConfInt(double meanArg,double width,double minval,double maxval,double c){
      56        1916 :     mean = meanArg;
      57        1916 :     low = meanArg - width/2;
      58        1916 :     up = meanArg + width/2;
      59        1916 :     min= minval;
      60        1916 :     max= maxval;
      61        1916 :     conf=c;
      62        1916 : }
      63             : 
      64             : /**
      65             :  * Asymetric confidence interval.
      66             :  * @param meanArg is the mean of the confidence interval it is not necessary
      67             :  * the middle of the confidence interval if the distribution is not symetric
      68             :  * and is not approximated by the normal distribution wich is symetric.
      69             :  * @param lowArg the Lower bound of the confidence interval.
      70             :  * @param upArg the Upper bound of the confidence interval.
      71             :  * @param min the smallest value observed
      72             :  * @param max the maximal value observed
      73             :  */
      74          87 : ConfInt::ConfInt(double meanArg,double lowArg,double upArg,double minval,double maxval,double c){
      75          87 :     mean = meanArg;
      76          87 :     low = lowArg;
      77          87 :     up = upArg;
      78          87 :     min= minval;
      79          87 :     max= maxval;
      80          87 :     conf =c;
      81          87 : }
      82             : 
      83        2235 : ConfInt::~ConfInt(){}
      84             : 
      85             : /**
      86             :  * Return the width of a confidence interval
      87             :  */
      88        4349 : double ConfInt::width(){
      89        4349 :     return (up-low);
      90             : }
      91             : 
      92          93 : ConfInt & ConfInt::operator+=(const ConfInt& rhs){
      93          93 :     low += rhs.low;
      94          93 :     mean += rhs.mean;
      95          93 :     up += rhs.up;
      96          93 :     min += rhs.min;
      97          93 :     max += rhs.max;
      98          93 :     conf = conf +rhs.conf -1;
      99          93 :     return *this;
     100             : }
     101             : 
     102           0 : ConfInt & ConfInt::operator-=(const ConfInt& rhs){
     103           0 :     low -= rhs.up;
     104           0 :     mean -= rhs.mean;
     105           0 :     up -= rhs.low;
     106           0 :     min -= rhs.max;
     107           0 :     max -= rhs.min;
     108           0 :     conf = conf +rhs.conf -1;
     109           0 :     return *this;
     110             : }
     111             : 
     112         173 : ConfInt & ConfInt::operator*=(const ConfInt& rhs){
     113         173 :     mean = mean*rhs.mean;
     114         346 :     low = fmin(fmin(low*rhs.low,up*rhs.up),
     115         346 :                fmin(low*rhs.up,up*rhs.low));
     116         346 :     up = fmax(fmax(low*rhs.low,up*rhs.up),
     117         346 :               fmax(low*rhs.up,up*rhs.low));
     118         346 :     min = fmin(fmin(min*rhs.min,max*rhs.max),
     119         346 :                fmin(min*rhs.max,max*rhs.min));
     120         346 :     max = fmax(fmax(min*rhs.min,max*rhs.max),
     121         346 :                fmax(min*rhs.max,max*rhs.min));
     122         173 :     conf = conf +rhs.conf -1;
     123         173 :     return *this;
     124             : }
     125             : 
     126           5 : ConfInt & ConfInt::operator/=(const ConfInt& rhs){
     127           5 :     mean /= rhs.mean;
     128             : 
     129           5 :     if(rhs.low * rhs.up<=0){
     130           0 :         low = - std::numeric_limits<double>::infinity();
     131           0 :         up = std::numeric_limits<double>::infinity();
     132             :     } else {
     133           5 :         if(rhs.low > 0){
     134           5 :             low /= rhs.up;
     135           5 :             up /= rhs.low;
     136             :         }else{
     137           0 :             low /= rhs.low;
     138           0 :             up  /= rhs.up;
     139             :         }
     140             :     }
     141           5 :     if(rhs.min * rhs.max<=0){
     142           0 :         min = - std::numeric_limits<double>::infinity();
     143           0 :         max = std::numeric_limits<double>::infinity();
     144             :     } else {
     145           5 :         if(rhs.min > 0){
     146           5 :             min /= rhs.max;
     147           5 :             max /= rhs.min;
     148             :         }else{
     149           0 :             min /= rhs.min;
     150           0 :             max  /= rhs.max;
     151             :         }
     152             :     }
     153           5 :     conf = conf +rhs.conf -1;
     154           5 :     return *this;
     155             : }
     156             : 
     157             : /**
     158             :  * Build an HASL formula with the PROB,EXISTS,ALLS operators.
     159             :  * Compute exact confidence interval.
     160             :  */
     161           9 : HaslFormulasTop::HaslFormulasTop(const HaslType t){
     162           9 :     assert( t==PROBABILITY || t==EXISTS || t== NOTALLS);
     163           9 :     TypeOp = t;
     164           9 :     Level =0;
     165           9 :     Value =0;
     166           9 :     Value2=0;
     167           9 :     Algebraic = 0;
     168           9 :     left = NULL;
     169           9 :     right = NULL;
     170           9 : }
     171             : 
     172             : /**
     173             :  * Build an HASL formula with the PROB,EXISTS,ALLS operators.
     174             :  * Compute exact confidence interval.
     175             :  */
     176           0 : HaslFormulasTop::HaslFormulasTop(const HaslType t,size_t al){
     177           0 :     assert( t==PROBCOND);
     178           0 :     TypeOp = t;
     179           0 :     Level =0;
     180           0 :     Value =0;
     181           0 :     Value2=0;
     182           0 :     Algebraic = al;
     183           0 :     left = NULL;
     184           0 :     right = NULL;
     185           0 : }
     186             : 
     187             : /**
     188             :  * Build a CONSTANT Hasl formula.
     189             :  * @param v the value of the constant
     190             :  */
     191           3 : HaslFormulasTop::HaslFormulasTop(double v1,double v2,double l){
     192           3 :     TypeOp = CONSTANT;
     193           3 :     Level = l;
     194           3 :     Value = v1;
     195           3 :     Value2= v2;
     196           3 :     Algebraic = 0;
     197           3 :     left = NULL;
     198           3 :     right = NULL;
     199           3 : }
     200             : 
     201             : /**
     202             :  * Build an HASL formula computing the expected value of a subformula.
     203             :  * Use the approximation to the normal low to compute the confidence interval
     204             :  * @param al the index of the sub formula return by the simulator.
     205             :  * @param l the confidence level of the confidence interval.
     206             :  */
     207         203 : HaslFormulasTop::HaslFormulasTop(size_t al){
     208         203 :     TypeOp = EXPECTANCY;
     209         203 :     Level = 0;
     210         203 :     Value = 0;
     211         203 :     Value2 = 0;
     212         203 :     Algebraic = al;
     213         203 :     left = NULL;
     214         203 :     right = NULL;
     215         203 : }
     216             : 
     217             : /**
     218             :  * Build an HASL formula testing if the probability of accepting a run is above some threshold.
     219             :  * In this setting the confidence level is the probability of type
     220             :  * I and type II errors.
     221             :  * @param p is the threshold.
     222             :  * @param delta is the half width of the indiference region.
     223             :  */
     224           0 : HaslFormulasTop::HaslFormulasTop(double p, double delta){
     225           0 :     TypeOp = HYPOTHESIS ;
     226           0 :     Level = 0;
     227           0 :     Value = p -delta;
     228           0 :     Value2= p + delta;
     229           0 :     Algebraic = 0;
     230           0 :     left = NULL;
     231           0 :     right = NULL;
     232           0 : }
     233             : 
     234             : 
     235             : /*
     236             :  * Build an Hasl formula of a given type as a tree with two descendant.
     237             :  * @param t is the type of the node either HASL_PLUS, HASL_TIME or HASL_DIV.
     238             :  * @param l The left Hasl Formula.
     239             :  * @param r the right Hasl formula.
     240             :  */
     241           3 : HaslFormulasTop::HaslFormulasTop(HaslType t, HaslFormulasTop* l,HaslFormulasTop* r){
     242           3 :     TypeOp = t;
     243           3 :     Algebraic = 0;
     244           3 :     Level = 0;
     245           3 :     Value = 0;
     246           3 :     Value2= 0;
     247           3 :     left = l;
     248           3 :     right = r;
     249           3 : }
     250             : 
     251             : /**
     252             :  * Destructor call destructor recusively on descendant if neaded.
     253             :  */
     254           0 : HaslFormulasTop::~HaslFormulasTop(){
     255           0 :     if(!left) delete left;
     256           0 :     if(!right) delete right;
     257           0 : }
     258             : 
     259             : /**
     260             :  * This method return true if a haslformula is constant.
     261             :  * This is usfull to know if a subformula have a confidence level
     262             :  * different than 1.
     263             :  */
     264           6 : bool HaslFormulasTop::isConstant(){
     265           6 :     switch (TypeOp) {
     266             :         case CONSTANT:
     267           4 :             return true;
     268             : 
     269             :         case HASL_PLUS:
     270             :         case HASL_TIME:
     271             :         case HASL_DIV:
     272           1 :             return (left->isConstant() && right->isConstant());
     273             :         default:
     274           1 :             return false;
     275             :     }
     276             : }
     277             : 
     278             : /**
     279             :  * This function set the confidence level of an HASL formula.
     280             :  * When the fomula contain
     281             :  * @param l The confidence level
     282             :  */
     283         217 : void HaslFormulasTop::setLevel(double l){
     284         217 :     switch (TypeOp) {
     285             :         case HYPOTHESIS:
     286             :         case PROBABILITY:
     287             :         case PROBCOND:
     288           7 :             Level = l;
     289           7 :             break;
     290             : 
     291             :         case EXPECTANCY:
     292             :         case CDF_PART:
     293             :         case PDF_PART:
     294             :         case RE_Likelyhood:
     295         201 :             Level = l;
     296         201 :             Value = quantile(boost::math::normal() , 0.5 + l / 2.0);
     297         201 :             break;
     298             : 
     299             :         case RE_AVG://temporary
     300           4 :             Level = l;
     301             :             //Here we divide the error by two because half the error come from the bernoulli evaluation.
     302           4 :             Value = quantile(boost::math::normal() , 0.75 + l / 4.0);
     303           4 :             break;
     304             : 
     305             :         case RE_Continuous:
     306           2 :             Level = l;
     307           2 :             Value = quantile(boost::math::normal() , 0.75 + l / 4.0);
     308           2 :             break;
     309             : 
     310             :         case CONSTANT:
     311           0 :             break;
     312             : 
     313             :         case HASL_PLUS:
     314             :         case HASL_MINUS:
     315             :         case HASL_TIME:
     316             :         case HASL_DIV:
     317           3 :             Level=l;
     318           3 :             if (left->isConstant()){right->setLevel(l);}
     319           1 :             else if (right->isConstant()){left->setLevel(l);}
     320             :             else{
     321             :                 //We need to increase the condidence level on each subformula
     322           0 :                 left->setLevel((1+l)/2);
     323           0 :                 right->setLevel((1+l)/2);
     324             :             }
     325           3 :             break;
     326             :         case NOTALLS:
     327             :         case EXISTS:
     328           0 :             Level =1;
     329           0 :             break;
     330             : 
     331             :         default:
     332           0 :             std::cerr << "Fail to parse Hasl Formula"<< std::endl;
     333           0 :             exit(EXIT_FAILURE);
     334             :     }
     335         217 : }
     336             : 
     337             : 
     338           0 : void HaslFormulasTop::computeChernoff(){
     339           0 :     double b = 0.0;
     340           0 :     for(let it : P.HaslFormulas) b = fmax(b,it->bound());
     341           0 :     if(b== INFINITY){
     342           0 :         std::cerr << "Cannot use Chernoff-Hoeffding bounds: no bounds on the computed value" << std::endl;
     343           0 :         exit(EXIT_FAILURE);
     344             :     }
     345           0 :     if(P.MaxRuns== (unsigned long)-1){
     346           0 :         P.MaxRuns = (int)(2.0*2.0*2.0*b*b/(P.Width*P.Width) * log(2/(1-P.Level)));
     347           0 :     }else if(P.Width == 0){
     348           0 :         P.Width = 2.0*b * sqrt( (2.0/P.MaxRuns) * log(2.0/(1.0-P.Level)));
     349           0 :     }else if(P.Level ==0){
     350           0 :         P.Level = (1.0 - (2.0* fmin(0.5 ,exp( (double)P.MaxRuns * P.Width*P.Width / (-2.0*2.0*2.0*b*b)))));
     351             :     }
     352           0 : }
     353             : 
     354             : 
     355             : /**
     356             :  * The function eval compute confidence interval for the HASL formula
     357             :  * from the simualation result return by the simulators.
     358             :  * It always return a confdience interval containing a confidence level
     359             :  * Depending of the context it should be interpreted differently.
     360             :  * In sequential setting, one should check that the intervals satisfy the
     361             :  * stopping criteria.
     362             :  * In static setting, one should check independantly the number of sample to
     363             :  * decide whether the simulation should be stopped.
     364             :  *
     365             :  * Some remarks about the estimation of the confidence interval adopted here
     366             :  * Let \f$ l \f$ =ConfLevel, the confidence level
     367             :  * \f$ l=1-alpha \f$
     368             :  * Let \f$ w \f$ = ConfWidth, the size of the confidence interval
     369             :  */
     370        2009 : ConfInt HaslFormulasTop::eval(const BatchR &batch)const{
     371        2009 :     switch (TypeOp) {
     372             :         case PROBABILITY:
     373             : 
     374             :             //if (P.Width ==0)// In static setting use exact binomial computation
     375             :             {
     376             :                 /*
     377             :                  * Here we used the boost library for computing the binomial
     378             :                  * confidence interval.
     379             :                  * According to boost documentation the algorithme used is
     380             :                  * Clopper-person:
     381             :                  * Clopper, C. J. and Pearson, E. S. (1934). The use of confidence or fiducial limits illustrated in the case of the binomial. Biometrika 26 404-413.
     382             :                  */
     383          77 :                 double mean = (double)batch.Isucc / (double)batch.I;
     384          77 :                 double l = boost::math::binomial_distribution<>::find_lower_bound_on_p(batch.I,batch.Isucc, (1-Level)/2);
     385          77 :                 double u = boost::math::binomial_distribution<>::find_upper_bound_on_p(batch.I,batch.Isucc, (1-Level)/2);
     386             : 
     387          77 :                 if(batch.Isucc ==0)return ConfInt(mean,l,u,0.0,0.0,Level);
     388          75 :                 if(batch.Isucc == batch.I)return ConfInt(mean,l,u,1.0,1.0,Level);
     389             : 
     390          75 :                 return ConfInt(mean,l,u,0.0,1.0,Level);
     391             :             } // In Sequential case fall back to show robin algorithm
     392             : 
     393             :             // NO BREAK on purpose here !
     394             :         case PROBCOND:
     395             :         {
     396             :             //Same as PROB but with a more specific constraint
     397           0 :             double mean = (double)batch.bernVar[Algebraic] / (double)batch.Isucc;
     398           0 :             double l = boost::math::binomial_distribution<>::find_lower_bound_on_p(batch.Isucc,batch.bernVar[Algebraic], (1-Level)/2);
     399           0 :             double u = boost::math::binomial_distribution<>::find_upper_bound_on_p(batch.Isucc,batch.bernVar[Algebraic], (1-Level)/2);
     400             : 
     401           0 :             if(batch.bernVar[Algebraic] ==0)return ConfInt(mean,l,u,0.0,0.0,Level);
     402           0 :             if(batch.bernVar[Algebraic] == batch.Isucc)return ConfInt(mean,l,u,1.0,1.0,Level);
     403             : 
     404           0 :             return ConfInt(mean,l,u,0.0,1.0,Level);
     405             : 
     406             :         }
     407             : 
     408             :             /*
     409             :              * Here Gaussian confidence interval are computed.
     410             :              * Let \f$ \mu \f$ the value to estimate, and \f$ x \f$ the
     411             :              * estimation of \f$ \mu \f$
     412             :              * then \f$ \mathbb{P}( \mu \in [x-\frac{w}{2} , x+\frac{w}{2}]) = 1-alpha  \f$
     413             :              *
     414             :              * The gaussian confidence interval is given by :
     415             :              * \f$  [x-z(1-\frac{alpha}{2}) * \frac{StandardDeviation~ }
     416             :              * { \sqrt{NumberOfObservations}} ,
     417             :              *         x+z(1-\frac{alpha}{2}) * \frac{StandardDeviation~}
     418             :              * { \sqrt{NumberOfObservations}}] \f$
     419             :              * with : \f$ z(1-\frac{alpha}{2})=z(1-\frac{1-l}{2}) = z(0.5+\frac{l}{2}) \f$
     420             :              *
     421             :              * \f$ StandartDeviation~ = \sqrt{ Variance +\frac{1}{n} } \f$
     422             :              * This correction come from the Chows and Robbin algorithm to ensure
     423             :              * The correctness of the stopping condition.
     424             :              *
     425             :              * We use the boost library: quantile(boost::math::normal() , level)
     426             :              * to compute quantile of the normal low. Its value have been stored
     427             :              * in Value by the function setLevel.
     428             :              */
     429             :         case EXPECTANCY:
     430             :         case CDF_PART:
     431             :         case PDF_PART:
     432             :         {
     433             :         //No accepting trajectory the condidence interval is R.
     434        1884 :         if(batch.Isucc==0)return ConfInt();
     435             : 
     436        1883 :         double mean = batch.Mean[Algebraic]/batch.Isucc;
     437        1883 :         double m2 = batch.M2[Algebraic]/batch.Isucc;
     438        1883 :         double variance = m2 - mean * mean;
     439             : 
     440        1883 :         if(P.Width!=0){ //P.width =0 indicate static setting
     441        1883 :             variance += 1.0/batch.Isucc;
     442             :             //Here the +1 come from the Chows and Robbin algorithm in Sequential setting
     443             :         }
     444             : 
     445        1883 :         double width = 2 * Value * sqrt(variance/(batch.Isucc -1));
     446             : 
     447        1883 :         return ConfInt(mean,width,batch.Min[Algebraic],batch.Max[Algebraic],Level);
     448             :         }
     449             : 
     450             :         case RE_Likelyhood:
     451             :         {
     452             :         //No accepting trajectory the condidence interval is R.
     453           8 :         if(batch.Isucc==0)return ConfInt();
     454           8 :         double mean = batch.Mean[Algebraic]/batch.Isucc;
     455           8 :         double m2 = batch.M2[Algebraic]/batch.Isucc;
     456             : 
     457             :         //If the variance is equal to 0 numerical instability can make it a negative number.
     458           8 :         double variance = fmax(0,m2 - mean * mean);
     459             : 
     460           8 :         double width = 2 * Value * sqrt(variance/batch.Isucc);
     461             : 
     462           8 :         return ConfInt(mean,width,batch.Min[Algebraic],batch.Max[Algebraic],Level);
     463             :         }
     464             : 
     465             :         case RE_AVG://temporary
     466             :         {
     467             :         //No accepting trajectory => the condidence interval is R.
     468           8 :         if(batch.Isucc==0)return ConfInt();
     469             : 
     470           8 :         double mean = (double)batch.Isucc / (double)batch.I;
     471           8 :         double l = boost::math::binomial_distribution<>::find_lower_bound_on_p(batch.I,batch.Isucc, (1-Level)/2);
     472           8 :         double u = boost::math::binomial_distribution<>::find_upper_bound_on_p(batch.I,batch.Isucc, (1-Level)/2);
     473           8 :         double mean2 = batch.Mean[Algebraic]/batch.Isucc;
     474           8 :         double m2 = batch.M2[Algebraic]/batch.Isucc;
     475           8 :         double variance = fmax(0,m2 - mean2 * mean2);
     476           8 :         double width = Value * sqrt(variance/batch.Isucc);
     477             : 
     478             :         return ConfInt(mean*mean2,
     479           8 :                        (mean2 - width)*l,
     480          16 :                        (mean2 + width)*u,0.0,1.0 * batch.Max[Algebraic],Level );
     481             :         }
     482             : 
     483             :         case RE_Continuous:
     484             :         {
     485             :         /*
     486             :          * Only used by the rare event engine in for countinuous bounded
     487             :          * Until property. This case apply the uniformization method.
     488             :          * The simulator returns the estimate of each \mu_u as well
     489             :          * as the Poisson probabilities computed using Fox-glynn algorithm.
     490             :          *
     491             :          */
     492             :         //batch.print();
     493           2 :         size_t N = batch.Mean.size()/2;
     494           2 :         std::cout << "tablelength = "<< batch.Mean.size() << std::endl;
     495           2 :         double error = 1- Level;
     496           2 :         double LevelN = 1- error/(N+2);
     497           2 :         double ValueN = quantile(boost::math::normal() , (1+LevelN)/2);
     498             : 
     499           4 :         ConfInt totalInt = ConfInt(0.0,0.0,0.0,0.0,Level);
     500           4 :         ConfInt likelyhood = ConfInt(0.0,0.0,0.0,0.0,Level);
     501           4 :         ConfInt reacheabilityprob =  ConfInt(0.0,0.0,0.0,0.0,Level);
     502           4 :         ConfInt poisson = ConfInt(0.0,0.0,0.0,0.0,Level);
     503             : 
     504           2 :         if(P.verbose>1)std::cerr << "i,\tsucc,\tbatch,\tMean,\tM2,\tMin,\tMax,\tPoisson" << std::endl;
     505           2 :         if(P.verbose>1)std::cerr << "continuous step:\t" << P.continuousStep <<  std::endl;
     506          86 :         for(size_t i=0; i< N; i++){
     507          84 :             int i2 = (i>0 && P.continuousStep>1.0 )? i-1 : i;
     508             : 
     509             :             //evaluate the likelyhood:
     510          84 :             likelyhood.mean = batch.Mean[2*i+1]/batch.Mean[2*i];
     511          84 :             double var = (batch.M2[2*i+1]/batch.Mean[2*i]) - pow((batch.Mean[2*i+1]/batch.Mean[2*i]),2);
     512          84 :             double widthN = 0.0;
     513          84 :             if(var>0)widthN = 2* ValueN * sqrt(var/batch.Mean[2*i]);
     514          84 :             likelyhood.low = batch.Min[2*i2+1];
     515          84 :             likelyhood.up = batch.Max[2*i+1];  //likelyhood->mean + widthN/2.0;
     516          84 :             likelyhood.min = batch.Min[2*i2+1];
     517          84 :             likelyhood.max = batch.Max[2*i+1];
     518             : 
     519             :             //evaluate probability to reach final state:
     520          84 :             reacheabilityprob.mean = batch.Mean[2*i]/batch.M2[2*i];
     521          84 :             reacheabilityprob.low = boost::math::binomial_distribution<>::find_lower_bound_on_p(batch.M2[2*i2],batch.Mean[2*i2], (1-LevelN)/2);
     522          84 :             reacheabilityprob.up = boost::math::binomial_distribution<>::find_upper_bound_on_p(batch.M2[2*i],batch.Mean[2*i], (1-LevelN)/2);
     523          84 :             reacheabilityprob.min = 0.0;
     524          84 :             reacheabilityprob.max = 1.0;
     525             :             //evaluate poisson:
     526          84 :             poisson.mean = batch.Min[2*i];
     527          84 :             poisson.low = (1-Value2)*batch.Min[2*i];
     528          84 :             poisson.up = batch.Min[2*i];
     529          84 :             poisson.min=poisson.low;
     530          84 :             poisson.max=poisson.max;
     531             : 
     532          84 :             if(P.verbose>1){
     533          84 :                 std::cout << "i: " << i<< "\tsucc: "<< batch.Mean[2*i]<< "\tLikelyhood: "  << likelyhood.mean << "\t[" << likelyhood.low<<";"<<likelyhood.up << "]\twidth: "<< widthN <<"\tpoisson: " << batch.Min[2*i] << "\tconfint: ["<< poisson.low <<";"<< poisson.up << "]";
     534          84 :                 std::cerr << i << ",\t" << batch.Mean[2*i] << ",\t" << batch.M2[2*i] << ",\t" << batch.Mean[2*i+1]/batch.Mean[2*i] << ",\t" << batch.M2[2*i+1]/batch.Mean[2*i] << ",\t" << batch.Min[2*i+1] << ",\t" << batch.Max[2*i+1] << ",\t" << batch.Mean[2*i] << std::endl;
     535             :             }
     536             : 
     537             :             //Multiply the three confidence interval:
     538          84 :             poisson *= likelyhood;
     539          84 :             poisson *= reacheabilityprob;
     540             : 
     541          84 :             if(P.verbose>1){
     542          84 :                 std::cout << "\tresult: ["<< poisson.low <<";"<< poisson.up << "]" << std::endl;
     543             :             }
     544             : 
     545             : 
     546             :             //Add the confidence interval to the total one.
     547             :             //if(poisson->width() < 1.0)
     548          84 :             totalInt += poisson;
     549             : 
     550             :         }
     551             : 
     552             :         //Add the error made on the left of the truncation point.
     553             :         ConfInt leftTruncationError =
     554           4 :         ConfInt(0.0,0.0,batch.Mean[1]/batch.M2[0]* Value2/2,0,batch.Mean[1]/batch.M2[0]* Value2/2,Level);
     555             : 
     556             :         //Add the error made on the rigth trucation point TODO!
     557           4 :         ConfInt rightTruncationError = ConfInt(0.0,0.0,0.0,0.0,Level);
     558             : 
     559           2 :         totalInt += leftTruncationError;
     560           2 :         totalInt += rightTruncationError;
     561             : 
     562           2 :         return totalInt;
     563             :         }
     564             : 
     565             :         case HYPOTHESIS:
     566             :         {
     567             :         /*
     568             :          * Implementation of the SPRT.
     569             :          *  Value < Value2
     570             :          *  Value <= p <= Value2 => Indiferrence region
     571             :          * H0 = { Value2 < p  <= 1    } => p0=Value2
     572             :          * H1 = { 0      <= p < Value } => p1=Value
     573             :          *
     574             :          * To comply with the architecture of cosmos requiring confidence
     575             :          * interval this function also return confidence interval.
     576             :          * Let l be the minimal confidence level for wich either H0 or H1 is
     577             :          * accepted
     578             :          * return [0,Value2] with confidence level l when H0 is accepted
     579             :          * return [Value, 1] with confidence level l when H1 is accepted
     580             :          *
     581             :          * The stopping criterion is reached when l is greater than the expected
     582             :          * level. This stopping criterion is exaclty the one of
     583             :          * A. Wald. Sequential tests of statistical hypotheses.
     584             :          * The Annals of Mathematical Statistics, 16(2):117–186, 06 1945.
     585             :          */
     586             : 
     587           0 :         const double alog = log((1-Value)/(1-Value2));
     588           0 :         const double blog = log(Value/Value2);
     589             : 
     590           0 :         double loglikelyhoodRatio = alog * (double)(batch.I - batch.Isucc) + blog * (double)batch.Isucc;
     591             : 
     592             : 
     593             :         //std::cerr << "[" << blog << "  --  " << loglikelyhoodRatio << "  --  " << alog << "]" << std::endl;
     594           0 :         double l = 1- 1/(1+ exp(fabs(loglikelyhoodRatio)));
     595             :         
     596           0 :         if(loglikelyhoodRatio <= 0){ //Accept H0
     597           0 :             return ConfInt((double)batch.Isucc/(double)batch.I, Value ,1,0.0,1.0,l);
     598             :         }else{
     599           0 :             return ConfInt((double)batch.Isucc/(double)batch.I, 0 ,Value2,0.0,1.0,l);
     600             :         }
     601             :         }
     602             :             
     603             :         case CONSTANT:
     604          15 :             return ConfInt(Value,Value2,Value-Value2/2.0,Value+Value2/2.0,1.0);
     605             :             
     606             :         case HASL_PLUS:
     607           5 :             return (left->eval(batch) += right->eval(batch));
     608             :             
     609             :         case HASL_MINUS:
     610           0 :             return (left->eval(batch) -= right->eval(batch));
     611             :             
     612             :         case HASL_TIME:
     613           5 :             return (left->eval(batch) *= right->eval(batch));
     614             :             
     615             :         case HASL_DIV:
     616           5 :             return (left->eval(batch) /= right->eval(batch));
     617             :             
     618             :         case EXISTS:
     619           0 :             if ( batch.Isucc > 0) return ConfInt(1.0,1.0,1.0,0.0,1.0,1.0);
     620           0 :             else return ConfInt(0.0,0.0,1.0,0.0,0.0,1.0);
     621             :         case NOTALLS:
     622           0 :             if ( batch.Isucc < batch.I) return ConfInt(1.0,1.0,1.0,0.0,1.0,1.0);
     623           0 :             else return ConfInt(0.0,0.0,1.0,0.0,0.0,1.0);
     624             :             
     625             :             
     626             :         default:
     627           0 :             std::cerr << "Fail to parse Hasl Formula"<< std::endl;
     628           0 :             exit(EXIT_FAILURE);
     629             :     }
     630             : }
     631             : 
     632           0 : double HaslFormulasTop::bound()const{
     633           0 :     switch (TypeOp) {
     634             :         case PROBABILITY:
     635             :         case PROBCOND:
     636           0 :             return 0.5;
     637             :             
     638             :         case EXPECTANCY:
     639             :         case CDF_PART:
     640             :         case PDF_PART:
     641             :         case RE_AVG:
     642             :         case RE_Continuous:
     643           0 :             return std::numeric_limits<double>::infinity();
     644             :             
     645             :         case CONSTANT:
     646           0 :             return fabs(Value);
     647             :             
     648             :         case HASL_PLUS:
     649             :         {
     650           0 :         double v1 = left->bound();
     651           0 :         double v2 = right->bound();
     652           0 :         return (fmax(v1,v2));
     653             :         }
     654             :             
     655             :         case HASL_TIME:
     656             :         {
     657           0 :         double v1 = left->bound();
     658           0 :         double v2 = right->bound();
     659           0 :         return (v1*v2);
     660             :         }
     661             :             
     662             :         case HASL_DIV:
     663             :         {
     664           0 :         return (std::numeric_limits<double>::infinity());
     665             :         }
     666             :             
     667             :         default:
     668           0 :             std::cerr << "Fail to parse Hasl Formula"<< std::endl;
     669           0 :             exit(EXIT_FAILURE);
     670             :     }
     671         105 : }

Generated by: LCOV version 1.13