1## Copyright (C) 2014, 2019 Moreno Marzolla
2##
3## This file is part of the queueing toolbox.
4##
5## The queueing toolbox is free software: you can redistribute it and/or
6## modify it under the terms of the GNU General Public License as
7## published by the Free Software Foundation, either version 3 of the
8## License, or (at your option) any later version.
9##
10## The queueing toolbox is distributed in the hope that it will be
11## useful, but WITHOUT ANY WARRANTY; without even the implied warranty
12## of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13## General Public License for more details.
14##
15## You should have received a copy of the GNU General Public License
16## along with the queueing toolbox. If not, see <http://www.gnu.org/licenses/>.
17
18## -*- texinfo -*-
19##
20## @deftypefn {Function File} {@var{B} =} engset (@var{A}, @var{m}, @var{n})
21##
22## @cindex Engset loss formula
23##
24## Evaluate the Engset loss formula.
25##
26## The Engset formula computes the blocking probability
27## @math{P_b(A,m,n)} for a system with a finite population of @math{n}
28## users, @math{m} identical servers, no queue, individual service
29## rate @math{\mu}, individual arrival rate @math{\lambda} (i.e., the
30## time until a user tries to request service is exponentially
31## distributed with mean @math{1/\lambda}), and offered load
32## @math{A=\lambda/\mu}.
33##
34## @tex
35## @math{P_b(A, m, n)} is defined for @math{n > m} as:
36##
37## $$
38## P_b(A, m, n) = {{\displaystyle{A^m {n \choose m}}} \over {\displaystyle{\sum_{k=0}^m A^k {n \choose k}}}}
39## $$
40##
41## and is 0 if @math{n @leq{} m}.
42## @end tex
43##
44## @strong{INPUTS}
45##
46## @table @code
47##
48## @item @var{A}
49## Offered load, defined as @math{A = \lambda / \mu} where
50## @math{\lambda} is the mean arrival rate and @math{\mu} the mean
51## service rate of each individual server (real, @math{A > 0}).
52##
53## @item @var{m}
54## Number of identical servers (integer, @math{m @geq{} 1}). Default @math{m = 1}
55##
56## @item @var{n}
57## Number of requests (integer, @math{n @geq{} 1}). Default @math{n = 1}
58##
59## @end table
60##
61## @strong{OUTPUTS}
62##
63## @table @code
64##
65## @item @var{B}
66## The value @math{P_b(A, m, n)}
67##
68## @end table
69##
70## @var{A}, @var{m} or @math{n} can be vectors, and in this case, the
71## results will be vectors as well.
72##
73## @strong{REFERENCES}
74##
75## @itemize
76## @item
77## G. Zeng, @cite{Two common properties of the Erlang-B function, Erlang-C function, and Engset blocking function}, Mathematical and Computer Modelling, Volume 37, Issues 12-13, June 2003, Pages 1287-1296
78## @end itemize
79##
80## @seealso{erlangb, erlangc}
81##
82## @end deftypefn
83
84## Author: Moreno Marzolla <moreno.marzolla(at)unibo.it>
85## Web: http://www.moreno.marzolla.name/
86function P = engset(A, m, n)
87  if ( nargin < 1 || nargin > 3 )
88    print_usage();
89  endif
90
91  ( isnumeric(A) && all( A(:) > 0 ) ) || error("A must be positive");
92
93  if ( nargin < 2 )
94    m = 1;
95  else
96    ( isnumeric(m) && all( fix(m(:)) == m(:)) && all( m(:) > 0 ) ) || error("m must be a positive integer");
97  endif
98
99  if ( nargin < 3 )
100    n = 1;
101  else
102    ( isnumeric(n) && all( fix(n(:)) == n(:)) && all( n(:) > 0 ) ) || error("n must be a positive integer");
103  endif
104
105  [err A m n] = common_size(A, m, n);
106  if ( err )
107    error("parameters are not of common size");
108  endif
109
110  P = arrayfun( @__engset_compute, A, m, n);
111endfunction
112
113## Compute P_b(A,m,n) recursively
114function P = __engset_compute(A, m, n)
115  if ( m >= n )
116    P = 0.0;
117  else
118    P = 1.0;
119    for i = 1:m
120      P=(A*(n-i)*P)/(i+A*(n-i)*P);
121    endfor
122  endif
123endfunction
124
125%!test
126%! fail("erlangb(1, -1)", "positive");
127%! fail("erlangb(-1, 1)", "positive");
128%! fail("erlangb(1, 0)", "positive");
129%! fail("erlangb(0, 1)", "positive");
130%! fail("erlangb('foo',1)", "positive");
131%! fail("erlangb(1,'bar')", "positive");
132%! fail("erlangb([1 1],[1 1 1])","common size");
133
134