1 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License as published by 4 * the Free Software Foundation; either version 2 of the License, or 5 * (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 15 * 16 * Authors : Benjamin GAUTHIER - 24 Mar 2004 17 * Joseph BANINO 18 * Olivier JACQUES 19 * Richard GAYRAUD 20 * From Hewlett Packard Company. 21 */ 22 23 #ifndef __STAT_H__ 24 #define __STAT_H__ 25 26 27 #define TIME_LENGTH 64 28 #define DEFAULT_FILE_NAME (char*)"dumpFile" 29 #define DEFAULT_EXTENSION (char*)".csv" 30 31 #define MAX_CHAR_BUFFER_SIZE 1024 32 33 #include <ctime> 34 #include <vector> 35 #include <string> 36 #include <sys/time.h> 37 #include <time.h> 38 #include <iostream> 39 #include <fstream> 40 #include <stdio.h> 41 42 #ifdef HAVE_GSL 43 #include <gsl/gsl_rng.h> 44 #include <gsl/gsl_randist.h> 45 #include <gsl/gsl_cdf.h> 46 #endif 47 48 #include "variables.hpp" 49 50 using namespace std; 51 52 /* 53 __________________________________________________________________________ 54 55 C S t a t C L A S S 56 __________________________________________________________________________ 57 */ 58 59 /** 60 * This class provides some means to compute and display statistics. 61 * This is a singleton class. 62 */ 63 64 class CStat 65 { 66 public: 67 68 std::vector<int> error_codes; 69 70 /* 71 * This struct is used for repartition table 72 * border max is the max value allow for this range 73 * nbInThisBorder is the counter of value in this range 74 */ 75 typedef struct _T_dynamicalRepartition { 76 unsigned int borderMax; 77 unsigned long nbInThisBorder; 78 } T_dynamicalRepartition; 79 80 typedef struct _T_value_rtt { 81 double date ; 82 int rtd_no ; 83 double rtt ; 84 } T_value_rtt, *T_pValue_rtt ; 85 86 /** 87 * Actions on counters 88 */ 89 enum E_Action { 90 E_NO_ACTION, 91 E_CREATE_OUTGOING_CALL, 92 E_CREATE_INCOMING_CALL, 93 E_CALL_FAILED, 94 E_CALL_SUCCESSFULLY_ENDED, 95 E_RESET_C_COUNTERS, 96 E_RESET_PD_COUNTERS, 97 E_RESET_PL_COUNTERS, 98 E_ADD_CALL_DURATION, 99 E_ADD_RESPONSE_TIME_DURATION, 100 E_FAILED_CANNOT_SEND_MSG, 101 E_FAILED_MAX_UDP_RETRANS, 102 E_FAILED_TCP_CONNECT, 103 E_FAILED_TCP_CLOSED, 104 E_FAILED_UNEXPECTED_MSG, 105 E_FAILED_CALL_REJECTED, 106 E_FAILED_CMD_NOT_SENT, 107 E_FAILED_REGEXP_DOESNT_MATCH, 108 E_FAILED_REGEXP_SHOULDNT_MATCH, 109 E_FAILED_REGEXP_HDR_NOT_FOUND, 110 E_FAILED_OUTBOUND_CONGESTION, 111 E_FAILED_TIMEOUT_ON_RECV, 112 E_FAILED_TIMEOUT_ON_SEND, 113 E_OUT_OF_CALL_MSGS, 114 E_WATCHDOG_MAJOR, 115 E_WATCHDOG_MINOR, 116 E_DEAD_CALL_MSGS, 117 E_FATAL_ERRORS, 118 E_WARNING, 119 E_RETRANSMISSION, 120 E_AUTO_ANSWERED, 121 E_ADD_GENERIC_COUNTER 122 }; 123 /** 124 * Counters management 125 */ 126 enum E_CounterName { 127 // Per-Scenario Counters 128 // Cumulative counters 129 CPT_C_IncomingCallCreated, 130 CPT_C_OutgoingCallCreated, 131 CPT_C_SuccessfulCall, 132 CPT_C_FailedCall, 133 CPT_C_CurrentCall, 134 CPT_C_CurrentCallPeak, 135 CPT_C_CurrentCallPeakTime, 136 CPT_C_NbOfCallUsedForAverageCallLength, 137 CPT_C_AverageCallLength_Sum, 138 CPT_C_AverageCallLength_Squares, 139 CPT_C_FailedCallCannotSendMessage, 140 CPT_C_FailedCallMaxUdpRetrans, 141 CPT_C_FailedCallTcpConnect, 142 CPT_C_FailedCallTcpClosed, 143 CPT_C_FailedCallUnexpectedMessage, 144 CPT_C_FailedCallCallRejected, 145 CPT_C_FailedCallCmdNotSent, 146 CPT_C_FailedCallRegexpDoesntMatch, 147 CPT_C_FailedCallRegexpShouldntMatch, 148 CPT_C_FailedCallRegexpHdrNotFound, 149 CPT_C_FailedOutboundCongestion, 150 CPT_C_FailedTimeoutOnRecv, 151 CPT_C_FailedTimeoutOnSend, 152 CPT_C_Retransmissions, 153 154 // Periodic Display counter 155 CPT_PD_IncomingCallCreated, // must be first (RESET_PD_COUNTER macro) 156 CPT_PD_OutgoingCallCreated, 157 CPT_PD_SuccessfulCall, 158 CPT_PD_FailedCall, 159 CPT_PD_CurrentCallPeak, 160 CPT_PD_CurrentCallPeakTime, 161 CPT_PD_NbOfCallUsedForAverageCallLength, 162 CPT_PD_AverageCallLength_Sum, 163 CPT_PD_AverageCallLength_Squares, 164 CPT_PD_NbOfCallUsedForAverageResponseTime, 165 CPT_PD_NbOfCallUsedForAverageResponseTime_2, // This must match or exceed MAX_RTD_INFO 166 CPT_PD_NbOfCallUsedForAverageResponseTime_3, // This must match or exceed MAX_RTD_INFO 167 CPT_PD_NbOfCallUsedForAverageResponseTime_4, // This must match or exceed MAX_RTD_INFO 168 CPT_PD_NbOfCallUsedForAverageResponseTime_5, // This must match or exceed MAX_RTD_INFO 169 CPT_PD_AverageResponseTime_Sum, 170 CPT_PD_AverageResponseTime_Sum_2, 171 CPT_PD_AverageResponseTime_Sum_3, 172 CPT_PD_AverageResponseTime_Sum_4, 173 CPT_PD_AverageResponseTime_Sum_5, 174 CPT_PD_AverageResponseTime_Squares, 175 CPT_PD_AverageResponseTime_Squares_2, 176 CPT_PD_AverageResponseTime_Squares_3, 177 CPT_PD_AverageResponseTime_Squares_4, 178 CPT_PD_AverageResponseTime_Squares_5, 179 CPT_PD_FailedCallCannotSendMessage, 180 CPT_PD_FailedCallMaxUdpRetrans, 181 CPT_PD_FailedCallTcpConnect, 182 CPT_PD_FailedCallTcpClosed, 183 CPT_PD_FailedCallUnexpectedMessage, 184 CPT_PD_FailedCallCallRejected, 185 CPT_PD_FailedCallCmdNotSent, 186 CPT_PD_FailedCallRegexpDoesntMatch, 187 CPT_PD_FailedCallRegexpShouldntMatch, 188 CPT_PD_FailedCallRegexpHdrNotFound, 189 CPT_PD_FailedOutboundCongestion, 190 CPT_PD_FailedTimeoutOnRecv, 191 CPT_PD_FailedTimeoutOnSend, 192 CPT_PD_Retransmissions, 193 194 // Periodic logging counter 195 CPT_PL_IncomingCallCreated, // must be first (RESET_PL_COUNTER macro) 196 CPT_PL_OutgoingCallCreated, 197 CPT_PL_SuccessfulCall, 198 CPT_PL_FailedCall, 199 CPT_PL_CurrentCallPeak, 200 CPT_PL_CurrentCallPeakTime, 201 CPT_PL_NbOfCallUsedForAverageCallLength, 202 CPT_PL_AverageCallLength_Sum, 203 /* The squares let us compute the standard deviation. */ 204 CPT_PL_AverageCallLength_Squares, 205 CPT_PL_NbOfCallUsedForAverageResponseTime, 206 CPT_PL_NbOfCallUsedForAverageResponseTime_2, 207 CPT_PL_NbOfCallUsedForAverageResponseTime_3, 208 CPT_PL_NbOfCallUsedForAverageResponseTime_4, 209 CPT_PL_NbOfCallUsedForAverageResponseTime_5, 210 CPT_PL_AverageResponseTime_Sum, 211 CPT_PL_AverageResponseTime_Sum_2, 212 CPT_PL_AverageResponseTime_Sum_3, 213 CPT_PL_AverageResponseTime_Sum_4, 214 CPT_PL_AverageResponseTime_Sum_5, 215 CPT_PL_AverageResponseTime_Squares, 216 CPT_PL_AverageResponseTime_Squares_2, 217 CPT_PL_AverageResponseTime_Squares_3, 218 CPT_PL_AverageResponseTime_Squares_4, 219 CPT_PL_AverageResponseTime_Squares_5, 220 CPT_PL_FailedCallCannotSendMessage, 221 CPT_PL_FailedCallMaxUdpRetrans, 222 CPT_PL_FailedCallTcpConnect, 223 CPT_PL_FailedCallTcpClosed, 224 CPT_PL_FailedCallUnexpectedMessage, 225 CPT_PL_FailedCallCallRejected, 226 CPT_PL_FailedCallCmdNotSent, 227 CPT_PL_FailedCallRegexpDoesntMatch, 228 CPT_PL_FailedCallRegexpShouldntMatch, 229 CPT_PL_FailedCallRegexpHdrNotFound, 230 CPT_PL_FailedOutboundCongestion, 231 CPT_PL_FailedTimeoutOnRecv, 232 CPT_PL_FailedTimeoutOnSend, 233 CPT_PL_Retransmissions, 234 235 E_NB_COUNTER, 236 237 // Global Counters 238 // Cumulative counters 239 CPT_G_C_OutOfCallMsgs, 240 CPT_G_C_DeadCallMsgs, 241 CPT_G_C_FatalErrors, 242 CPT_G_C_Warnings, 243 CPT_G_C_WatchdogMajor, 244 CPT_G_C_WatchdogMinor, 245 CPT_G_C_AutoAnswered, 246 // Periodic Display counter 247 CPT_G_PD_OutOfCallMsgs, 248 CPT_G_PD_DeadCallMsgs, 249 CPT_G_PD_FatalErrors, 250 CPT_G_PD_Warnings, 251 CPT_G_PD_WatchdogMajor, 252 CPT_G_PD_WatchdogMinor, 253 CPT_G_PD_AutoAnswered, // must be last (RESET_PD_COUNTER) 254 255 // Periodic logging counter 256 CPT_G_PL_OutOfCallMsgs, 257 CPT_G_PL_DeadCallMsgs, 258 CPT_G_PL_FatalErrors, 259 CPT_G_PL_Warnings, 260 CPT_G_PL_WatchdogMajor, 261 CPT_G_PL_WatchdogMinor, 262 CPT_G_PL_AutoAnswered, // must be last (RESET_PL_COUNTER) 263 264 E_NB_G_COUNTER 265 }; 266 267 /* 268 ** exported methods 269 */ 270 271 /** 272 * Constructor. 273 */ 274 CStat (); 275 276 /** 277 * Destructor. 278 */ 279 ~CStat (); 280 281 282 /** 283 * Delete the single instance of the class. 284 * 285 * Only one instance of CStat exists in the component. This 286 * instance is deleted when the close method is called. 287 */ 288 void close (); 289 290 /** 291 * ComputeStat Methods are used to modify counter value 292 * It's the main interface to update counter 293 * 294 * @return 0 if the action is known 295 * -1 else 296 */ 297 int computeStat (E_Action P_action); 298 int computeStat (E_Action P_action, unsigned long P_value); 299 int computeStat (E_Action P_action, unsigned long P_value, int which); 300 301 /* This works for global counters and does not require an instance. */ 302 static int globalStat (E_Action P_action); 303 304 /** 305 * ComputeRtt Methods are used to calculate the response time 306 */ 307 void computeRtt ( unsigned long long P_start_time, unsigned long long P_stop_time, int which); 308 309 /** 310 * GetStat Method is used to retrieve a counter value 311 * 312 * @return the counter value 313 **/ 314 unsigned long long GetStat (E_CounterName P_counter); 315 316 /* Get the current start time. */ 317 void getStartTime(struct timeval *t); 318 319 /** 320 * formatTime. 321 * 322 * This method converts a struct timeval parameter into a printable string 323 * in the format given in parameter. 324 * 325 * @param P_tv. 326 * @return a pointer on a static string containing formated time 327 */ 328 static char* formatTime (struct timeval* P_tv, bool with_epoch = false); 329 330 /** 331 * setRepartitionCallLength 332 * - set the unsigned int table passed in parameter as the repartition table 333 * for call length. This is done by calling the initRepartition methode on 334 * the M_CallLengthRepartition variable. 335 * - set the char* list of int (must be separeted with coma as the 336 * repartition table for call length 337 * This is done by calling the createIntegerTable to transform the char* 338 * list into unsigned int list. Then the initRepartition methode is 339 * call with the created unsigned int list and the M_CallLengthRepartition 340 * variable 341 * 342 * setRepartitionResponseTime 343 * Same than setRepartitionCallLength with the variable 344 * M_ResponseTimeRepartition variableinstead of M_CallLengthRepartition 345 * variable 346 */ 347 void setRepartitionCallLength (unsigned int* repartition, int nombre); 348 void setRepartitionCallLength (char * liste); 349 void setRepartitionResponseTime (unsigned int* repartition, int nombre); 350 void setRepartitionResponseTime (char * liste); 351 352 /* define the file name to use to dump statistic in file */ 353 void setFileName(const char* name); 354 void setFileName(const char* name, const char* extension); 355 void initRtt(const char* name, const char* extension, unsigned long P_value); 356 357 /** 358 * Display data periodically updated on screen. 359 */ 360 void displayData (FILE *f); 361 void displayStat(FILE *f); 362 void displayRepartition(FILE *f); 363 void displayRtdRepartition (FILE *f, int which); 364 365 /** 366 * Dump data periodically in the file M_FileName 367 */ 368 void dumpData (); 369 370 void dumpDataRtt (); 371 372 /** 373 * initialize the class variable member 374 */ 375 int init(); 376 377 /** 378 * computeDiffTimeInMs. 379 * 380 * This method calculates elaped time in ms 381 * 382 * @param tf = final date 383 * @param ti = initial date 384 * 385 * @return number of ms between the 2 dates 386 */ 387 static long computeDiffTimeInMs (struct timeval* tf, struct timeval* ti); 388 389 /** 390 * msToHHMMSS. 391 * 392 * This converts an unsigned long containing a number of ms 393 * into a string expressing the same value in format HH:MM:SS. 394 * 395 * @param P_ms. 396 * 397 * @return a pointer on a static string containing formated time 398 */ 399 static char* msToHHMMSS (unsigned long P_ms); 400 401 /** 402 * msToHHMMSSmm. 403 * 404 * This converts an unsigned long containing a number of ms 405 * into a string expressing the same value in format HH:MM:SS:mmm. 406 * 407 * @param P_ms. 408 * 409 * @return a pointer on a static string containing formated time 410 */ 411 static char* msToHHMMSSus (unsigned long P_ms); 412 413 /* Get a counter ID by name. */ 414 int findCounter(const char *counter, bool alloc); 415 int findRtd(const char *name, bool start); 416 void validateRtds(); 417 int nRtds(); 418 419 private: 420 unsigned long long M_counters[E_NB_COUNTER]; 421 static unsigned long long M_G_counters[E_NB_G_COUNTER - E_NB_COUNTER]; 422 423 #define GENERIC_C 0 424 #define GENERIC_PD 1 425 #define GENERIC_PL 2 426 #define GENERIC_TYPES 3 427 unsigned long long *M_genericCounters; 428 429 str_int_map M_genericMap; 430 int_str_map M_revGenericMap; 431 int_str_map M_genericDisplay; 432 433 str_int_map rtd_started; 434 str_int_map rtd_stopped; 435 436 #define RTD_COUNT 0 437 #define RTD_SUM 1 438 #define RTD_SUMSQ 2 439 #define RTD_TYPES 3 440 unsigned long long *M_rtdInfo; 441 str_int_map M_rtdMap; 442 int_str_map M_revRtdMap; 443 444 T_dynamicalRepartition** M_ResponseTimeRepartition; 445 T_dynamicalRepartition* M_CallLengthRepartition; 446 int M_SizeOfResponseTimeRepartition; 447 int M_SizeOfCallLengthRepartition; 448 struct timeval M_startTime; 449 struct timeval M_pdStartTime; 450 struct timeval M_plStartTime; 451 452 bool M_headerAlreadyDisplayed; 453 char* M_fileName; 454 ofstream* M_outputStream; 455 456 bool M_headerAlreadyDisplayedRtt ; 457 char* M_fileNameRtt ; 458 ofstream* M_outputStreamRtt ; 459 double M_time_ref ; 460 461 T_pValue_rtt M_dumpRespTime ; 462 unsigned int M_counterDumpRespTime ; 463 unsigned long M_report_freq_dumpRtt ; 464 465 /** 466 * initRepartition 467 * This methode is used to create the repartition table with a table of 468 * unsigned int the reparition is created like following, with Vi the given 469 * value in the table 470 * 0 <= x < V1 471 * V1 <= x < V2 472 * ... 473 * Vn-1 <= x < Vn 474 * x >= Vn 475 * So the repartition table have the size n+1 if the given table has a size 476 * of n */ 477 void initRepartition(unsigned int* repartition, int nombre, 478 T_dynamicalRepartition ** tabRepartition, int* nbTab); 479 480 /** 481 * createIntegerTable 482 * this method try to create a table of unsigned int with the list of char* 483 * passed in parameters 484 * if it succed, it's return true (1) 485 * else it's return false (0) 486 */ 487 int createIntegerTable(char * P_listeStr, 488 unsigned int ** listeInteger, 489 int * sizeOfList); 490 491 /** 492 * isWellFormed 493 * this method check if the char* passed in parameter in really a list of 494 * integer separated with comma. 495 * if yes, it's return true (1) 496 * else, it's return false (0) 497 */ 498 int isWellFormed(char * P_listeStr, int * nombre); 499 500 /** 501 * updateRepartition 502 * The method looks for the place to set the value passed in parameter 503 * Once found, the associated counter is incremented 504 */ 505 void updateRepartition( T_dynamicalRepartition* tabRepart, 506 int sizeOfTab, 507 unsigned long value); 508 509 /** 510 * resetRepartition 511 * Zeros out all repartition counters. 512 */ 513 void resetRepartition(T_dynamicalRepartition* P_tabReport, 514 int P_sizeOfTab); 515 /** 516 * displayRepartition 517 * Display the repartition passed in parameter at the screen 518 */ 519 void displayRepartition(FILE *f, 520 T_dynamicalRepartition * tabRepartition, 521 int sizeOfTab); 522 523 /** 524 * sRepartitionHeader 525 * return a string with the range description of the given repartition 526 */ 527 char* sRepartitionHeader(T_dynamicalRepartition * tabRepartition, 528 int sizeOfTab, 529 const char* P_repartitionName); 530 531 /** 532 * sRepartitionInfo 533 * return a string with the number of value in the differente range of the 534 * given repartition 535 */ 536 char* sRepartitionInfo(T_dynamicalRepartition * tabRepartition, 537 int sizeOfTab); 538 539 /** 540 * UpdateAverageCounter 541 * This methode compute the real moyenne with the passed value on the given 542 * counter 543 */ 544 void updateAverageCounter(E_CounterName P_SumCounter, 545 E_CounterName P_NbOfCallUsed, 546 E_CounterName P_Squares, 547 unsigned long P_value); 548 549 /** 550 * computeStdev 551 * This method computes the standard deviation using our recorded mean 552 * and recorded mean square. 553 */ 554 double computeStdev(E_CounterName P_SumCounter, 555 E_CounterName P_NbOfCallUsed, 556 E_CounterName P_Squares); 557 558 /** 559 * computeMean 560 * This method computes the recorded sum and count. 561 */ 562 double computeMean(E_CounterName P_SumCounter, 563 E_CounterName P_NbOfCallUsed); 564 565 double computeRtdMean(int which, int type); 566 double computeRtdStdev(int which, int type); 567 568 /** 569 * Effective C++ 570 * 571 * To prevent public copy ctor usage: no implementation 572 */ 573 CStat (const CStat&); 574 575 /** 576 * Effective C++ 577 * 578 * To prevent public operator= usage: no implementation 579 */ 580 CStat& operator=(const CStat&); 581 }; 582 583 /** 584 * This abstract class provides the ability to sample from a distribution. 585 */ 586 class CSample 587 { 588 public: 589 virtual double sample() = 0; 590 virtual int textDescr(char *s, int len) = 0; 591 virtual int timeDescr(char *s, int len) = 0; 592 virtual double cdfInv(double percentile) = 0; 593 virtual ~CSample(); 594 private: 595 }; 596 597 /* Always return a fixed value for the sample. */ 598 class CFixed : public CSample 599 { 600 public: 601 CFixed(double value); 602 double sample(); 603 int textDescr(char *s, int len); 604 int timeDescr(char *s, int len); 605 double cdfInv(double percentile); 606 private: 607 double value; 608 }; 609 610 /* Return the default scenario duration. */ 611 class CDefaultPause : public CSample 612 { 613 public: 614 CDefaultPause(); 615 double sample(); 616 int textDescr(char *s, int len); 617 int timeDescr(char *s, int len); 618 double cdfInv(double percentile); 619 private: 620 }; 621 622 /* Uniform distribution. */ 623 class CUniform : public CSample 624 { 625 public: 626 CUniform(double min, double max); 627 double sample(); 628 int textDescr(char *s, int len); 629 int timeDescr(char *s, int len); 630 double cdfInv(double percentile); 631 private: 632 double min, max; 633 }; 634 635 #ifdef HAVE_GSL 636 /* Normal distribution. */ 637 class CNormal : public CSample 638 { 639 public: 640 CNormal(double mean, double stdev); 641 double sample(); 642 int textDescr(char *s, int len); 643 int timeDescr(char *s, int len); 644 double cdfInv(double percentile); 645 protected: 646 double mean, stdev; 647 gsl_rng *rng; 648 }; 649 650 /* Lognormal distribution. */ 651 class CLogNormal : public CNormal 652 { 653 public: CLogNormal(double mean,double stdev)654 CLogNormal(double mean, double stdev) : CNormal(mean, stdev) {}; 655 double sample(); 656 int textDescr(char *s, int len); 657 int timeDescr(char *s, int len); 658 double cdfInv(double percentile); 659 }; 660 661 /* Exponential distribution. */ 662 class CExponential : public CSample 663 { 664 public: 665 CExponential(double mean); 666 double sample(); 667 int textDescr(char *s, int len); 668 int timeDescr(char *s, int len); 669 double cdfInv(double percentile); 670 private: 671 double mean; 672 gsl_rng *rng; 673 }; 674 675 /* Weibull distribution. */ 676 class CWeibull : public CSample 677 { 678 public: 679 CWeibull(double lambda, double k); 680 double sample(); 681 int textDescr(char *s, int len); 682 int timeDescr(char *s, int len); 683 double cdfInv(double percentile); 684 private: 685 double lambda, k; 686 gsl_rng *rng; 687 }; 688 689 /* Pareto distribution. */ 690 class CPareto : public CSample 691 { 692 public: 693 CPareto(double k, double xsubm); 694 double sample(); 695 int textDescr(char *s, int len); 696 int timeDescr(char *s, int len); 697 double cdfInv(double percentile); 698 protected: 699 double k, xsubm; 700 gsl_rng *rng; 701 }; 702 703 /* Generalized Pareto distribution. */ 704 class CGPareto : public CSample 705 { 706 public: 707 CGPareto(double shape, double scale, double location); 708 double sample(); 709 int textDescr(char *s, int len); 710 int timeDescr(char *s, int len); 711 double cdfInv(double percentile); 712 protected: 713 double shape, scale, location; 714 gsl_rng *rng; 715 }; 716 717 718 /* Gamma distribution. */ 719 class CGamma : public CSample 720 { 721 public: 722 CGamma(double k, double theta); 723 double sample(); 724 int textDescr(char *s, int len); 725 int timeDescr(char *s, int len); 726 double cdfInv(double percentile); 727 protected: 728 double k, theta; 729 gsl_rng *rng; 730 }; 731 732 /* Negative Binomial distribution. */ 733 class CNegBin : public CSample 734 { 735 public: 736 CNegBin(double p, double n); 737 double sample(); 738 int textDescr(char *s, int len); 739 int timeDescr(char *s, int len); 740 double cdfInv(double percentile); 741 protected: 742 double p, n; 743 gsl_rng *rng; 744 }; 745 #endif 746 747 #endif // __STAT_H__ 748