iproute2/netem/paretonormal.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: NIST-PD */
   2/*
   3 * Paretoormal distribution table generator
   4 *
   5 * This distribution is simply .25*normal + .75*pareto; a combination
   6 * which seems to match experimentally observed distributions reasonably
   7 *  well, but is computationally easy to handle.
   8 * The entries represent a scaled inverse of the cumulative distribution
   9 * function.
  10 *
  11 * Taken from the uncopyrighted NISTnet code.
  12 */
  13#include <stdio.h>
  14#include <stdlib.h>
  15#include <string.h>
  16#include <math.h>
  17#include <limits.h>
  18#include <malloc.h>
  19
  20#include <linux/types.h>
  21#include <linux/pkt_sched.h>
  22
  23#define TABLESIZE       16384
  24#define TABLEFACTOR     NETEM_DIST_SCALE
  25
  26static double
  27normal(double x, double mu, double sigma)
  28{
  29        return .5 + .5*erf((x-mu)/(sqrt(2.0)*sigma));
  30}
  31
  32static const double a=3.0;
  33
  34static int
  35paretovalue(int i)
  36{
  37        double dvalue;
  38
  39        i = 65536-4*i;
  40        dvalue = (double)i/(double)65536;
  41        dvalue = 1.0/pow(dvalue, 1.0/a);
  42        dvalue -= 1.5;
  43        dvalue *= (4.0/3.0)*(double)TABLEFACTOR;
  44        if (dvalue > 32767)
  45                dvalue = 32767;
  46        return (int)rint(dvalue);
  47}
  48
  49int
  50main(int argc, char **argv)
  51{
  52        int i,n;
  53        double x;
  54        double table[TABLESIZE+1];
  55
  56        for (x = -10.0; x < 10.05; x += .00005) {
  57                i = rint(TABLESIZE*normal(x, 0.0, 1.0));
  58                table[i] = x;
  59        }
  60        printf(
  61"# This is the distribution table for the paretonormal distribution.\n"
  62        );
  63
  64        for (i = n = 0; i < TABLESIZE; i += 4) {
  65                int normvalue, parvalue, value;
  66
  67                normvalue = (int) rint(table[i]*TABLEFACTOR);
  68                parvalue = paretovalue(i);
  69
  70                value = (normvalue+3*parvalue)/4;
  71                if (value < SHRT_MIN) value = SHRT_MIN;
  72                if (value > SHRT_MAX) value = SHRT_MAX;
  73
  74                printf(" %d", value);
  75                if (++n == 8) {
  76                        putchar('\n');
  77                        n = 0;
  78                }
  79        }
  80
  81        return 0;
  82}
  83