diff --git a/src/LGenBase/EPTF_CLL_LGenBase_ConfigDefinitions.ttcn b/src/LGenBase/EPTF_CLL_LGenBase_ConfigDefinitions.ttcn index c73ad437784c9d52127303c0f1ef7a6eb1ba4af3..4943dda52fd1fcceab67aec4086953c29c0b2173 100644 --- a/src/LGenBase/EPTF_CLL_LGenBase_ConfigDefinitions.ttcn +++ b/src/LGenBase/EPTF_CLL_LGenBase_ConfigDefinitions.ttcn @@ -1693,11 +1693,13 @@ group FSM{ // - static - // - random - // - randomGauss - + // - randomBates - /////////////////////////////////////////////////////////// type union EPTF_LGenBase_FSMTimerParameters{ EPTF_LGenBase_FSMTimerParamsStatic static, EPTF_LGenBase_FSMTimerParamsRandom random, - EPTF_LGenBase_FSMTimerParamsRandomGauss randomGauss + EPTF_LGenBase_FSMTimerParamsRandomGauss randomGauss, + EPTF_LGenBase_FSMTimerParamsRandomBates randomBates } /////////////////////////////////////////////////////////// @@ -1732,13 +1734,13 @@ group FSM{ // Data type for declaring parameters of a timer of a given FSM table. // // Elements: - // name - *charstring* - The name of the timer. Used in FSM declarations // timeoutMin - *float* - The minimal time in sec when the timer times out from its start // timeoutMax - *float* - The maximal time in sec when the timer times out from its start // // Detailed Comments: // The timer times out randomly after a delay between the // minimal and maximal timeout values. + // The random values follow the uniform distribution. /////////////////////////////////////////////////////////// type record EPTF_LGenBase_FSMTimerParamsRandom{ float timeoutMin, @@ -1752,9 +1754,8 @@ group FSM{ // Data type for declaring parameters of a timer of a given FSM table. // // Elements: - // name - *charstring* - The name of the timer. Used in FSM declarations - // timeoutMin - *float* - The minimal time in sec when the timer times out from its start - // timeoutMax - *float* - The maximal time in sec when the timer times out from its start + // mean - *float* - The mean value of the Gauss distribution + // deviation - *float* - The deviation value of the Gauss distribution // // Detailed Comments: // The timer times out randomly after a delay between the @@ -1766,6 +1767,28 @@ group FSM{ float deviation } + /////////////////////////////////////////////////////////// + // Type: EPTF_LGenBase_FSMTimerParamsRandomBates + // + // Purpose: + // Data type for declaring parameters of a timer of a given FSM table. + // + // Elements: + // tmin - *float* - The minimal time in sec when the timer times out from its start + // tmax - *float* - The maximal time in sec when the timer times out from its start + // n - *integer* - The number of uniformly distributed random numbers on the [tmin,tmax] interval to use + // + // Detailed Comments: + // The timer times out randomly after a delay between the + // minimal and maximal timeout values. The random values + // follow the Bates distribution: the mean of n independent uniformly distributed random variables on the interval [min,max]. + /////////////////////////////////////////////////////////// + type record EPTF_LGenBase_FSMTimerParamsRandomBates{ + float tmin, + float tmax, + integer n + } + /////////////////////////////////////////////////////////// // Type: EPTF_LGenBase_FsmTimer // diff --git a/src/LGenBase/EPTF_CLL_LGenBase_ConfigFunctions.ttcn b/src/LGenBase/EPTF_CLL_LGenBase_ConfigFunctions.ttcn index 9ef97a79bf450eae95a4536c9d636841938db17b..983d46197c4a38e98ba65804814f88550837c63c 100644 --- a/src/LGenBase/EPTF_CLL_LGenBase_ConfigFunctions.ttcn +++ b/src/LGenBase/EPTF_CLL_LGenBase_ConfigFunctions.ttcn @@ -7447,6 +7447,21 @@ group PrivateFunctions{ f_EPTF_Base_assert(%definitionId&": The mean value of FSM timer "&pl_timers[vl_i].name& " of table "& pl_fsm.name& " must be a positive value instead of "&float2str(pl_timers[vl_i].timerParams.randomGauss.mean), pl_timers[vl_i].timerParams.randomGauss.mean > 0.0) + }else if (ischosen(pl_timers[vl_i].timerParams.randomBates)){ + f_EPTF_Base_assert(%definitionId&": The minimal timeout value of FSM timer "&pl_timers[vl_i].name& + " of table "& pl_fsm.name& + " must be a positive value instead of "&float2str(pl_timers[vl_i].timerParams.randomBates.tmin),pl_timers[vl_i].timerParams.randomBates.tmin >= 0.0) + f_EPTF_Base_assert(%definitionId&": The maximal timeout value of FSM timer "&pl_timers[vl_i].name& + " of table "& pl_fsm.name& + " must be a positive value instead of "&float2str(pl_timers[vl_i].timerParams.randomBates.tmax),pl_timers[vl_i].timerParams.randomBates.tmax >= 0.0) + f_EPTF_Base_assert(%definitionId&": The maximal timeout value ("& + float2str(pl_timers[vl_i].timerParams.randomBates.tmax)&") of FSM timer "&pl_timers[vl_i].name& + " of table "& pl_fsm.name& + " must be greater than the minimal timeout value: "&float2str(pl_timers[vl_i].timerParams.randomBates.tmin), + pl_timers[vl_i].timerParams.randomBates.tmax >= pl_timers[vl_i].timerParams.randomBates.tmin) + f_EPTF_Base_assert(%definitionId&": The n value of FSM timer "&pl_timers[vl_i].name& + " of table "& pl_fsm.name& + " must be a positive integer value instead of "&int2str(pl_timers[vl_i].timerParams.randomBates.n), pl_timers[vl_i].timerParams.randomBates.n > 0) }else { f_EPTF_Base_assert(%definitionId&": Unknown FSM timer parameter type " & log2str(pl_timers[vl_i].timerParams), false); diff --git a/src/LGenBase/EPTF_CLL_LGenBase_Definitions.ttcn b/src/LGenBase/EPTF_CLL_LGenBase_Definitions.ttcn index a245141fd20f32f3fd514074b7e202ed5f1be2e6..af64f75c1087a495c6b5a9072c9ed2fbbf990d60 100644 --- a/src/LGenBase/EPTF_CLL_LGenBase_Definitions.ttcn +++ b/src/LGenBase/EPTF_CLL_LGenBase_Definitions.ttcn @@ -2159,11 +2159,25 @@ group FsmTables { /////////////////////////////////////////////////////////// type record of EPTF_LGenBase_CompactFsmTable EPTF_LGenBase_CompactFsmTableList; + /////////////////////////////////////////////////////////// + // Type: EPTF_LGenBase_FSMTimerType + // + // Purpose: + // Data type to define possible FSM Timer types + // For the parameters of the FSM timers see + // + // Elements: + // static: timeouts after the given time + // random: the timeout period follows a uniform distribution on the given interval + // randomGauss: the timeout period follows the normal (=Gauss) distribution with the given mean and deviation + // randomBates: the timeout period follows the Bates distribution: the mean of n independent uniformly distributed random variables on the given interval + /////////////////////////////////////////////////////////// type enumerated EPTF_LGenBase_FSMTimerType { static(0), random, - randomGauss + randomGauss, + randomBates }; //TODO New random timer datatype diff --git a/src/LGenBase/EPTF_CLL_LGenBase_EventHandlingExternalFunctions.cc b/src/LGenBase/EPTF_CLL_LGenBase_EventHandlingExternalFunctions.cc index 7320ac3fe3ba58657fa90ecf736f8b6b559594ef..a274a9beee4022e53df2901591da7705d8a5c0e1 100644 --- a/src/LGenBase/EPTF_CLL_LGenBase_EventHandlingExternalFunctions.cc +++ b/src/LGenBase/EPTF_CLL_LGenBase_EventHandlingExternalFunctions.cc @@ -108,6 +108,22 @@ FLOAT f__EPTF__LGenBase__rnd__normal(const FLOAT& mean, const FLOAT& deviation) return FLOAT(normal1 * (double)deviation + (double)mean); }//f__EPTF__LGenBase__rnd__normal + +FLOAT f__EPTF__LGenBase__rnd__bates(const FLOAT& min, const FLOAT& max, const INTEGER& n) +{ + if (n<1) {return min;} + + double uniform_sum=0.0; + double bates; + + for(int i=0; i 1.0) { bates = 1.0; } // cannot be smaller than 0 + + return FLOAT(bates * (double)max + (1.0-bates) * (double)min); +}//f__EPTF__LGenBase__rnd__bates } //... diff --git a/src/LGenBase/EPTF_CLL_LGenBase_ExternalFunctions.ttcn b/src/LGenBase/EPTF_CLL_LGenBase_ExternalFunctions.ttcn index 97b1559e83b84c248e10478d06dcd9bed653ff2e..eba6cb34e8c59c4942f236669c724cf0c0b69c61 100644 --- a/src/LGenBase/EPTF_CLL_LGenBase_ExternalFunctions.ttcn +++ b/src/LGenBase/EPTF_CLL_LGenBase_ExternalFunctions.ttcn @@ -77,4 +77,16 @@ external function f_EPTF_LGenBase_rnd_normal( in float mean, in float deviation) return float; +//================================================== + +// Name: f_EPTF_LGenBase_rnd_bates +// Description: Generates Bates distribution on the [min,max] interval +// using the mean of n uniformly distributed numbers on the [min,max] interval +// Used by: tc_EPTF_LGenBase_Test_rnd_bates +//================================================== +external function f_EPTF_LGenBase_rnd_bates( + in float min, + in float max, + in integer n) +return float; } // end of module diff --git a/src/LGenBase/EPTF_CLL_LGenBase_StepFunctions.ttcn b/src/LGenBase/EPTF_CLL_LGenBase_StepFunctions.ttcn index 2788699d3ca94d237ce4a57d0e4b6ff3b274a27b..54406c05b63140db9d9578ab0b76f729d3cb47cf 100644 --- a/src/LGenBase/EPTF_CLL_LGenBase_StepFunctions.ttcn +++ b/src/LGenBase/EPTF_CLL_LGenBase_StepFunctions.ttcn @@ -163,6 +163,11 @@ return float{ return f_EPTF_LGenBase_rnd_normal( pl_FSMTimerParam.randomGauss.mean, pl_FSMTimerParam.randomGauss.deviation); + } else if (ischosen(pl_FSMTimerParam.randomBates)) { + return f_EPTF_LGenBase_rnd_bates( + pl_FSMTimerParam.randomBates.tmin, + pl_FSMTimerParam.randomBates.tmax, + pl_FSMTimerParam.randomBates.n); } //cannot reach this line return -1.0; diff --git a/test/LGenBase/EPTF_LGenBase_Test_TestcasesR9.ttcn b/test/LGenBase/EPTF_LGenBase_Test_TestcasesR9.ttcn index 9f5a65da89cabc5dd1025d285175d823a5166047..0b54393f1090d30bde28bdd16dd709c22bca8ffc 100644 --- a/test/LGenBase/EPTF_LGenBase_Test_TestcasesR9.ttcn +++ b/test/LGenBase/EPTF_LGenBase_Test_TestcasesR9.ttcn @@ -920,7 +920,7 @@ group LimitExecution{ } group fsmTimer{ - const integer c_gaussTimerSingle_densitySlides := 20; + const integer c_testTimerSingle_densitySlides := 20; modulepar float c_FsmTimer_tMin := 0.1; modulepar float c_FsmTimer_tMax := 0.9; @@ -928,17 +928,21 @@ group fsmTimer{ type record of EPTF_LGenBase_Test_RandomTimer EPTF_LGenBase_Test_RandomTimerList; type record EPTF_LGenBase_Test_GaussTimer { float mean, float deviation }; type record of EPTF_LGenBase_Test_GaussTimer EPTF_LGenBase_Test_GaussTimerList; + type record EPTF_LGenBase_Test_BatesTimer { float tmin, float tmax, integer n }; + type record of EPTF_LGenBase_Test_BatesTimer EPTF_LGenBase_Test_BatesTimerList; modulepar EPTF_FloatList c_FsmTimers_static := {0.1, 0.9}; modulepar EPTF_LGenBase_Test_RandomTimerList c_FsmTimers_random := {{0.1, 0.6}, {0.4, 0.9}}; modulepar EPTF_LGenBase_Test_GaussTimerList c_FsmTimers_gauss := {{0.3, 0.02}, {0.7, 0.04}}; + modulepar EPTF_LGenBase_Test_BatesTimerList c_FsmTimers_bates := {{0.1, 0.6, 2}, {0.4, 0.9, 10}}; modulepar integer tsp_staticTimerSingle_startCount := 1000; modulepar integer tsp_randomTimerSingle_startCount := 1000; modulepar integer tsp_gaussTimerSingle_startCount := 1000; + modulepar integer tsp_batesTimerSingle_startCount := 1000; - const charstring c_FsmTimer_gaussTimerFSMName := "c_gaussTimerFSM"; - const charstring c_FsmTimer_gaussTimerDensityStatName := "timeoutDistribution"; - const charstring c_FsmTimer_gaussTimerDeviationStatName := "timeoutDeviation"; + const charstring c_FsmTimer_testTimerFSMName := "c_testTimerFSM"; + const charstring c_FsmTimer_testTimerDensityStatName := "timeoutDistribution"; + const charstring c_FsmTimer_testTimerDeviationStatName := "timeoutDeviation"; template EPTF_LGenBase_ScenarioTypeDeclarator t_FsmTimer_Scenario( //in integer pl_entitySuccCount, in float pl_cps := 1.0, @@ -948,7 +952,7 @@ group fsmTimer{ { {"TC1",{ {target := {cpsToReach := pl_cps}}, - {fsmList := {c_FsmTimer_gaussTimerFSMName}}, + {fsmList := {c_FsmTimer_testTimerFSMName}}, {entityFinishConditions := {}}, {trafficStartFinish := pl_conditionList}, {trafficFinishedActions := {{testFinished := {} }}}, @@ -966,9 +970,9 @@ group fsmTimer{ const charstring c_FsmTimer_gaussTimer1Name := "gaussTimer1"; const charstring c_FsmTimer_gaussTimer2Name := "gaussTimer2"; - const charstring c_FsmTimer_gaussTimer_timerStartStepName := "gaussTimerStartStep"; + const charstring c_FsmTimer_testTimer_timerStartStepName := "testTimerStartStep"; - function f_LGenBase_Test_gaussTimer_startTimerStep(in EPTF_LGenBase_TestStepArgs pl_ptr) + function f_LGenBase_Test_testTimer_startTimerStep(in EPTF_LGenBase_TestStepArgs pl_ptr) runs on EPTF_LGenBase_Test_CT { var integer vl_timerToStart := pl_ptr.eIdx; pl_ptr.refContext.fRefArgs := {vl_timerToStart}; @@ -1002,6 +1006,13 @@ group fsmTimer{ // FIXME? pl_min := 0.0; pl_max := pl_fsmTimerList[i].timerParams.randomGauss.mean * 2.0; + } else if(ischosen(pl_fsmTimerList[i].timerParams.randomBates)) { + if(pl_fsmTimerList[i].timerParams.randomBates.tmin < pl_min) { + pl_min := pl_fsmTimerList[i].timerParams.randomBates.tmin; + } + if(pl_fsmTimerList[i].timerParams.randomBates.tmax > pl_max) { + pl_max := pl_fsmTimerList[i].timerParams.randomBates.tmax; + } } else { setverdict(inconc, "unsupported timer param "&log2str(pl_fsmTimerList[i].timerParams)); f_EPTF_Base_stop(none); @@ -1035,7 +1046,7 @@ group fsmTimer{ } var EPTF_LGenBase_FsmTableDeclarator c_FsmTimer_fsm := { - name := c_FsmTimer_gaussTimerFSMName, + name := c_FsmTimer_testTimerFSMName, fsmParams :={ {stateList := {"idle", "running"}}, {fsmTimerList := pl_fsmTimerList}, @@ -1061,7 +1072,7 @@ group fsmTimer{ scope := FSM }, { - name := c_FsmTimer_gaussTimerDensityStatName, + name := c_FsmTimer_testTimerDensityStatName, providerVarName := "timeoutVar", targetVarName := "", statMeasParams := { @@ -1070,7 +1081,7 @@ group fsmTimer{ scale := { min := pl_timerRangeMin, max := pl_timerRangeMax, - n := c_gaussTimerSingle_densitySlides, + n := c_testTimerSingle_densitySlides, scale := linear } } @@ -1079,7 +1090,7 @@ group fsmTimer{ scope := FSM }, { - name := c_FsmTimer_gaussTimerDeviationStatName, + name := c_FsmTimer_testTimerDeviationStatName, providerVarName := "timeoutVar", targetVarName := "", statMeasParams := { @@ -1099,7 +1110,7 @@ group fsmTimer{ cellRow :={ statedCellRow := {{ inState := { state := "idle"}, cell :={{ - {c_FsmTimer_gaussTimer_timerStartStepName, omit}, + {c_FsmTimer_testTimer_timerStartStepName, omit}, {c_EPTF_LGenBase_stepName_fsmResetChrono,{statMeasName := "timeoutChrono"}}, {c_EPTF_LGenBase_stepName_fsmStartChrono,{statMeasName := "timeoutChrono"}} }, @@ -1128,10 +1139,10 @@ group fsmTimer{ } - f_EPTF_LGenBase_init("gaussTimerTest"); - f_EPTF_LGenBase_declareBehaviorType("gaussTimer", -1, null, null, null, null); - f_EPTF_LGenBase_declareEntityType("et1", {"gaussTimer"}); - f_EPTF_LGenBase_declareStep("gaussTimer", {c_FsmTimer_gaussTimer_timerStartStepName, refers(f_LGenBase_Test_gaussTimer_startTimerStep)}) + f_EPTF_LGenBase_init("timerTest"); + f_EPTF_LGenBase_declareBehaviorType("testTimer_BT", -1, null, null, null, null); + f_EPTF_LGenBase_declareEntityType("et1", {"testTimer_BT"}); + f_EPTF_LGenBase_declareStep("testTimer_BT", {c_FsmTimer_testTimer_timerStartStepName, refers(f_LGenBase_Test_testTimer_startTimerStep)}) f_EPTF_LGenBase_declareFSMTable(c_FsmTimer_fsm); f_EPTF_LGenBase_createEntityGroup({"eg1", "et1", pl_eGrpSize}); f_EPTF_LGenBase_declareScenarioType3(valueof(t_FsmTimer_Scenario(/*pl_entitySuccCount,*/ pl_cps, pl_conditionList))); @@ -1145,8 +1156,8 @@ group fsmTimer{ for ( var integer vl_i := 0; vl_i < pl_eGrpSize ; vl_i := vl_i+1 ) { //Get timeout values - var integer vl_statId := f_EPTF_LGenBase_fsmStatMeasIdOfFSM(vl_i, 0, c_FsmTimer_gaussTimerDensityStatName); - var integer vl_statId2 := f_EPTF_LGenBase_fsmStatMeasIdOfFSM(vl_i, 0, c_FsmTimer_gaussTimerDeviationStatName); + var integer vl_statId := f_EPTF_LGenBase_fsmStatMeasIdOfFSM(vl_i, 0, c_FsmTimer_testTimerDensityStatName); + var integer vl_statId2 := f_EPTF_LGenBase_fsmStatMeasIdOfFSM(vl_i, 0, c_FsmTimer_testTimerDeviationStatName); f_EPTF_StatMeasure_getStat_density(vl_statId, pl_distribution[vl_i]); f_EPTF_StatMeasure_getStat_standardDev(vl_statId2, pl_deviationList[vl_i]); f_EPTF_StatMeasure_getStat_standardDev_mean(vl_statId2, pl_meanList[vl_i]); @@ -1263,6 +1274,46 @@ group fsmTimer{ f_EPTF_Base_stop(pass); } + function f_LGenBase_Test_batesTimer( + in integer pl_eGrpSize, + in EPTF_LGenBase_FsmTimerList pl_fsmTimerList) + runs on EPTF_LGenBase_Test_CT + { + var EPTF_IntegerArray2D vl_distribution; + var EPTF_FloatList vl_meanList; + var EPTF_FloatList vl_deviationList; + var float vl_cps := (1.0/c_FsmTimer_tMax) * int2float(pl_eGrpSize); + var float vl_min := 0.0, vl_max := 0.0; + f_LGenBase_Test_getTimerRange(pl_fsmTimerList, vl_min, vl_max); + f_LGenBase_Test_fsmTimerTest( + pl_eGrpSize := pl_eGrpSize, + pl_cps := vl_cps, + pl_conditionList := {{nrOfExecStart := {tsp_batesTimerSingle_startCount, {}} }}, + pl_timeout := (int2float(tsp_batesTimerSingle_startCount) / vl_cps) + 5.0, + pl_fsmTimerList := pl_fsmTimerList, + pl_timerRangeMin := vl_min, + pl_timerRangeMax := vl_max, + pl_distribution := vl_distribution, + pl_meanList := vl_meanList, + pl_deviationList := vl_deviationList) + log(vl_distribution); + log(vl_meanList); + log(vl_deviationList); + + for(var integer i:=0; i vl_max){ + vl_max := vl_newrnd; + } + + f_EPTF_StatMeasure_addData_density(vl_density_stat, vl_newrnd); + f_EPTF_StatMeasure_addData_standardDev(vl_measure_stat, vl_newrnd); + } + + var float vl_m; + f_EPTF_StatMeasure_getStat_standardDev_mean(vl_measure_stat, vl_m); + var float vl_d; + f_EPTF_StatMeasure_getStat_standardDev(vl_measure_stat, vl_d); + //vl_d := f_sqrtF(vl_d); + var EPTF_FloatList vl_density; + f_EPTF_StatMeasure_getStat_normalized_density(vl_density_stat, vl_density); + action("density function: ", vl_density); + action("Measured mean: ", vl_m); + action("Measured variance: ", vl_d); + action("Min num: ", vl_min); + action("Max num: ", vl_max); + action("Expected mean: ", vl_mean); + action("Expected variance: ", vl_dev); + + f_LGenBase_Test_checkDeviation(vl_mean, vl_m, vl_dev, vl_d, vl_tolerance); + + } + + /////////////////////////////////////////////////////////// + // Testcase: tc_EPTF_LGenBase_Test_rnd_bates_basic + // + // Purpose: + // This positive test tests f_EPTF_LGenBase_rnd_bates function with different n values. + // + // Action: + // It generates a given number of random numbers with the defined min/ max and n. + // It stores the generated numbers with the help of StatMeasure and in the end it + // determines the mean and the deviation of the stored list of random numbers. + // It checks Bates distribution for different n values. + // + // Expected Result: + // The calculated numbers should be equal with the expected values for Bates distribution + // between a given tolerance limit. + // + /////////////////////////////////////////////////////////// + testcase tc_EPTF_LGenBase_Test_rnd_bates_basic() + runs on EPTF_StatMeasure_CT{ + + f_EPTF_StatMeasure_init_CT("Bates_Test_Basic"); + + f_EPTF_LGenBase_Test_rnd_bates( + pl_tmin := 2.0, + pl_tmax := 14.0, + pl_n := 1 + ) + + f_EPTF_LGenBase_Test_rnd_bates( + pl_tmin := 2.0, + pl_tmax := 14.0, + pl_n := 2 + ) + + f_EPTF_LGenBase_Test_rnd_bates( + pl_tmin := 2.0, + pl_tmax := 14.0, + pl_n := 5 + ) + + f_EPTF_LGenBase_Test_rnd_bates( + pl_tmin := 2.0, + pl_tmax := 14.0, + pl_n := 10 + ) + + f_EPTF_LGenBase_Test_rnd_bates( + pl_tmin := 2.0, + pl_tmax := 14.0, + pl_n := 100 + ) + + f_EPTF_Base_stop(pass); + } + +} // group fsmTimer //HN77446 group tcTypeName{ @@ -1927,10 +2197,13 @@ control{ execute(tc_LGenBase_Test_randomTimerParallel()); execute(tc_LGenBase_Test_gaussTimerSingle()); execute(tc_LGenBase_Test_gaussTimerParallel()); + execute(tc_LGenBase_Test_batesTimerSingle()); + execute(tc_LGenBase_Test_batesTimerParallel()); */ execute(tc_EPTF_LGenBase_Test_rnd_normal_basic()); execute(tc_EPTF_LGenBase_Test_rnd_normal_multiple_gen()); execute(tc_EPTF_LGenBase_Test_rnd_normal_multiple_gen_rnd_order()); + execute(tc_EPTF_LGenBase_Test_rnd_bates_basic()); execute(tc_LGenBase_Test_LimitedExecution_reportingFinish()) execute(tc_LGenBase_Test_LimitedExecution_reportingFinish_Unlimit());