butools.queues.QBDQueue ======================= .. currentmodule:: butools.queues .. np:function:: QBDQueue .. list-table:: :widths: 25 150 * - Matlab: - :code:`Ret = QBDQueue(B, L, F, L0, ...)` * - Mathematica: - :code:`Ret = QBDQueue[B, L, F, L0, ...]` * - Python/Numpy: - :code:`Ret = QBDQueue(B, L, F, L0, ...)` Returns various performane measures of a continuous time QBD queue. QBD queues have a background continuous time Markov chain with generator Q whose the transitions can be partitioned into three sets: transitions accompanied by an arrival of a new job (F, forward), transitions accompanied by the service of the current job in the server (B, backward) and internal transitions (L, local). Thus we have Q=B+L+F. L0 is the matrix of local transition rates if the queue is empty. Parameters ---------- B : matrix, shape(N,N) Transitions of the background process accompanied by the service of the current job in the server L : matrix, shape(N,N) Internal transitions of the background process that do not generate neither arrival nor service F : matrix, shape(N,N) Transitions of the background process accompanied by an arrival of a new job L0 : matrix, shape(N,N) Internal transitions of the background process when there are no jobs in the queue further parameters : The rest of the function parameters specify the options and the performance measures to be computed. The supported performance measures and options in this function are: +----------------+--------------------+----------------------------------------+ | Parameter name | Input parameters | Output | +================+====================+========================================+ | "ncMoms" | Number of moments | The moments of the number of customers | +----------------+--------------------+----------------------------------------+ | "ncDistr" | Upper limit K | The distribution of the number of | | | | customers from level 0 to level K-1 | +----------------+--------------------+----------------------------------------+ | "ncDistrMG" | None | The vector-matrix parameters of the | | | | matrix-geometric distribution of the | | | | number of customers in the system | +----------------+--------------------+----------------------------------------+ | "ncDistrDPH" | None | The vector-matrix parameters of the | | | | matrix-geometric distribution of the | | | | number of customers in the system, | | | | converted to a discrete PH | | | | representation | +----------------+--------------------+----------------------------------------+ | "stMoms" | Number of moments | The sojourn time moments | +----------------+--------------------+----------------------------------------+ | "stDistr" | A vector of points | The sojourn time distribution at the | | | | requested points (cummulative, cdf) | +----------------+--------------------+----------------------------------------+ | "stDistrME" | None | The vector-matrix parameters of the | | | | matrix-exponentially distributed | | | | sojourn time distribution | +----------------+--------------------+----------------------------------------+ | "stDistrPH" | None | The vector-matrix parameters of the | | | | matrix-exponentially distributed | | | | sojourn time distribution, converted | | | | to a continuous PH representation | +----------------+--------------------+----------------------------------------+ | "prec" | The precision | Numerical precision used as a stopping | | | | condition when solving the | | | | matrix-quadratic equation | +----------------+--------------------+----------------------------------------+ (The quantities related to the number of customers in the system include the customer in the server, and the sojourn time related quantities include the service times as well) Returns ------- Ret : list of the performance measures Each entry of the list corresponds to a performance measure requested. If there is just a single item, then it is not put into a list. Notes ----- "ncDistrMG" and "stDistrMG" behave much better numerically than "ncDistrDPH" and "stDistrPH". Examples ======== For Matlab: >>> B = [6., 1., 0.; 0., 4., 1.; 2., 0., 0.]; >>> F = [0., 1., 1.; 5., 0., 0.; 1., 3., 0.]; >>> L = [-14., 3., 2.; 0., -14., 4.; 3., 1., -10.]; >>> L0 = L+B; >>> disp(L0); -8 4 2 0 -10 5 5 1 -10 >>> [ncd, ncm] = QBDQueue(B, L, F, L0, 'ncDistr', 11, 'ncMoms', 5); >>> disp(ncd); Columns 1 through 8 0.29094 0.20433 0.14547 0.10358 0.073709 0.052461 0.037338 0.026574 Columns 9 through 11 0.018913 0.013461 0.0095805 >>> disp(ncm); 2.46 14.608 128.88 1515.9 22288 >>> [alphap, Ap] = QBDQueue(B, L, F, L0, 'ncDistrDPH'); >>> disp(alphap); 0.28256 0.22386 0.20264 >>> disp(Ap); 0.11832 0.4103 0.18373 0.196 0.19477 0.32261 0.27566 0.22146 0.21229 >>> [alpha, A] = QBDQueue(B, L, F, L0, 'ncDistrMG'); >>> disp(alpha); 0.042581 -0.27854 0.94503 >>> disp(A); -0.0056928 -0.63242 1.3313 0.069475 -0.36133 0.99875 0.037353 -0.21854 0.8924 >>> ncdFromDPH = PmfFromDPH(alphap, Ap, (0:1:10)); >>> disp(ncdFromDPH); Columns 1 through 8 0.29094 0.20433 0.14547 0.10358 0.073709 0.052461 0.037338 0.026574 Columns 9 through 11 0.018913 0.013461 0.0095805 >>> ncmFromMG = MomentsFromMG(alpha, A, 5); >>> disp(ncmFromMG); 2.46 14.608 128.88 1515.9 22288 >>> [std, stm] = QBDQueue(B, L, F, L0, 'stDistr', (0.:0.1:1.), 'stMoms', 5); >>> disp(std); Columns 1 through 8 1.1102e-16 0.14225 0.25715 0.35489 0.43933 0.51262 0.5763 0.63165 Columns 9 through 11 0.67977 0.72161 0.75797 >>> disp(stm); 0.70236 1.0017 2.1463 6.1325 21.903 >>> [betap, Bp] = QBDQueue(B, L, F, L0, 'stDistrPH'); >>> disp(betap); Columns 1 through 8 0.52899 0 0 0 0.35507 0 0 0 Column 9 0.11594 >>> disp(Bp); Columns 1 through 8 -12.591 2.362 0.50976 4.2349 0.39366 0.084961 3 0 2.001 -12.662 0.95667 0.3335 4.2231 0.15944 0 3 2.8354 0.93483 -13.595 0.47257 0.15581 4.0674 0 0 5 0 0 -13.061 1.5746 0.33984 4.2349 0.39366 0 5 0 1.334 -13.108 0.63778 0.3335 4.2231 0 0 5 1.8903 0.62322 -13.73 0.47257 0.15581 4.4697 0.78732 0.16992 4 0 0 -10 0 0.667 4.4461 0.31889 0 4 0 0 -10 0.94514 0.31161 4.1349 0 0 4 0 0 Column 9 0 0 3 0.084961 0.15944 4.0674 0 0 -10 >>> [beta, B] = QBDQueue(B, L, F, L0, 'stDistrME'); >>> disp(beta); Columns 1 through 8 0.17391 0.47826 -0.71739 0.71739 -1.2391 1.2391 -1.2391 0.52174 Column 9 1.0652 >>> disp(B); Columns 1 through 8 -12.591 -0.41431 -3.408 2.165 -13.136 15 -13.409 12.066 0.5517 -13.315 -8.0386 7.3408 -10.01 10.714 -6.3994 0.033031 0.20504 -1.8844 -15.359 1.8939 -4.0612 3.4626 -0.19879 0.022021 -0.28868 1.3811 -2.5957 -11.073 -3.7559 3.4626 -1.3717 -3.2512 0.48659 -1.3755 -1.3906 5.4522 -17.351 -1.5374 2.853 -3.4525 1.5997 -0.77852 -1.6145 5.5725 -4.1872 -15.012 -0.7327 0.5475 1.0779 -2.1431 1.8972 1.9933 -1.6703 0.26853 -14.463 0.5475 2.0033 -1.9938 1.8972 1.9933 -5.9052 4.3998 -4.3594 -9.4525 0.59557 0.82156 -1.1028 4.9933 -6.4916 4.9354 -4.3085 0.5475 Column 9 1.3431 6.6716 4.4477 8.8939 9.8705 9.8705 9.8705 9.8705 -0.12955 >>> stdFromPH = CdfFromPH(betap, Bp, (0.:0.1:1.)); >>> disp(stdFromPH); Columns 1 through 8 1.1102e-16 0.14225 0.25715 0.35489 0.43933 0.51262 0.5763 0.63165 Columns 9 through 11 0.67977 0.72161 0.75797 >>> stmFromME = MomentsFromME(beta, B, 5); >>> disp(stmFromME); 0.70236 1.0017 2.1463 6.1325 21.903 For Mathematica: >>> B = {{6., 1., 0.},{0., 4., 1.},{2., 0., 0.}}; >>> F = {{0., 1., 1.},{5., 0., 0.},{1., 3., 0.}}; >>> L = {{-14., 3., 2.},{0., -14., 4.},{3., 1., -10.}}; >>> L0 = L+B; >>> Print[L0]; {{-8., 4., 2.}, {0., -10., 5.}, {5., 1., -10.}} >>> {ncd, ncm} = QBDQueue[B, L, F, L0, "ncDistr", 11, "ncMoms", 5]; "Final Residual Error for G: "1.249000902703301*^-16 "Final Residual Error for R: "8.326672684688674*^-17 >>> Print[ncd]; {0.29093602691449844, 0.2043276077989581, 0.14546751846779368, 0.10357801953919166, 0.07370933599101509, 0.0524613602236208, 0.037337898930337544, 0.02657416066003302, 0.018913402582327217, 0.013461073324799929, 0.009580534061633792} >>> Print[ncm]; {2.460029520212033, 14.60791905179449, 128.87860443055757, 1515.888454046844, 22287.969412532402} >>> {alphap, Ap} = QBDQueue[B, L, F, L0, "ncDistrDPH"]; "Final Residual Error for G: "1.249000902703301*^-16 "Final Residual Error for R: "8.326672684688674*^-17 >>> Print[alphap]; {0.28256467199124746, 0.22386225497958323, 0.2026370461146711} >>> Print[Ap]; {{0.11831531605275415, 0.41029505226571794, 0.18373196776426398}, {0.19600449960093794, 0.19477428983994485, 0.32260956940537433}, {0.2756583766062947, 0.2214649539635013, 0.2122872279368174}} >>> {alpha, A} = QBDQueue[B, L, F, L0, "ncDistrMG"]; "Final Residual Error for G: "1.249000902703301*^-16 "Final Residual Error for R: "8.326672684688674*^-17 >>> Print[alpha]; {0.042581006723761944, -0.27854425286936896, 0.9450272192311088} >>> Print[A]; {{-0.005692752239919885, -0.6324216674588319, 1.3312918216215348}, {0.06947485017082566, -0.3613333778272245, 0.9987453751370272}, {0.037353395792620064, -0.21853933991282004, 0.8924029638966606}} >>> ncdFromDPH = PmfFromDPH[alphap, Ap, Range[0,10,1]]; >>> Print[ncdFromDPH]; {0.29093602691449827, 0.2043276077989581, 0.14546751846779366, 0.10357801953919163, 0.07370933599101509, 0.0524613602236208, 0.03733789893033755, 0.026574160660033017, 0.018913402582327217, 0.013461073324799929, 0.009580534061633792} >>> ncmFromMG = MomentsFromMG[alpha, A, 5]; >>> Print[ncmFromMG]; {2.4600295202120344, 14.607919051794505, 128.87860443055771, 1515.8884540468462, 22287.969412532442} >>> {std, stm} = QBDQueue[B, L, F, L0, "stDistr", Range[0.,1.,0.1], "stMoms", 5]; "Final Residual Error for G: "1.249000902703301*^-16 "Final Residual Error for R: "8.326672684688674*^-17 >>> Print[std]; {-2.220446049250313*^-16, 0.1422502687156617, 0.257145752951746, 0.35488604834530724, 0.4393330753410507, 0.5126194621799739, 0.5763000198215283, 0.6316534259881905, 0.6797734673117404, 0.7216066395715914, 0.7579746780193366} >>> Print[stm]; {0.702356254321406, 1.0017175985977291, 2.1462963079180923, 6.1325315761778585, 21.90316181223906} >>> {betap, Bp} = QBDQueue[B, L, F, L0, "stDistrPH"]; "Final Residual Error for G: "1.249000902703301*^-16 "Final Residual Error for R: "8.326672684688674*^-17 >>> Print[betap]; {0.5289855072463769, 0., 0., 0., 0.35507246376811596, 0., 0., 0., 0.11594202898550725} >>> Print[Bp]; {{-12.590793810464493, 2.361969158122816, 0.5097641466892873, 4.2348676982559175, 0.39366152635380264, 0.08496069111488122, 3., 0., 0.}, {2.0010093466117524, -12.661585604321022, 0.956667718183873, 0.3335015577686254, 4.223069065946496, 0.15944461969731216, 0., 3., 0.}, {2.8354199578367134, 0.9348326530713538, -13.595359582237387, 0.47256999297278557, 0.15580544217855896, 4.067440069627102, 0., 0., 3.}, {5., 0., 0., -13.060529206976328, 1.5746461054152106, 0.3398427644595249, 4.2348676982559175, 0.39366152635380264, 0.08496069111488122}, {0., 5., 0., 1.3340062310745016, -13.107723736214014, 0.6377784787892486, 0.3335015577686254, 4.223069065946496, 0.15944461969731216}, {0., 0., 5., 1.8902799718911423, 0.6232217687142358, -13.730239721491591, 0.47256999297278557, 0.15580544217855896, 4.067440069627102}, {4.469735396511836, 0.7873230527076053, 0.16992138222976244, 4., 0., 0., -10., 0., 0.}, {0.6670031155372508, 4.446138131892993, 0.3188892393946243, 0., 4., 0., 0., -10., 0.}, {0.9451399859455711, 0.3116108843571179, 4.1348801392542045, 0., 0., 4., 0., 0., -10.}} >>> {beta, B} = QBDQueue[B, L, F, L0, "stDistrME"]; "Final Residual Error for G: "1.249000902703301*^-16 "Final Residual Error for R: "8.326672684688674*^-17 >>> Print[beta]; {0.17391304347826098, 0.4782608695652174, -0.7173913043478262, 0.7173913043478262, -1.239130434782609, 1.239130434782609, -1.239130434782609, 0.5217391304347829, 1.065217391304348} >>> Print[B]; {{-12.590793810464493, -0.4143079390446338, -3.4079678715964405, 2.165044054462539, -13.135614274299147, 15., -13.409206189535507, 12.066062929481042, 1.3431432600544637}, {0.5517026304648383, -13.31487770573633, -8.038587534717966, 7.340812756512537, -10.010346278592026, 10.71360053252702, -6.399351616213842, 0.03303146474052099, 6.671571630027232}, {0.20503537103555214, -1.884385705275542, -15.359058356478641, 1.8938751710083572, -4.061197338939663, 3.462593438602556, -0.19879434118212647, 0.022020976493681843, 4.447714420018154}, {-0.28868062527080385, 1.3811139661569207, -2.5957222593063154, -11.072961911866576, -3.7559458603857516, 3.462593438602556, -1.371745011542437, -3.2511664850390023, 8.893852551911149}, {0.48658568115248757, -1.3754727933458817, -1.3906370069902225, 5.452192557308922, -17.35130544262314, -1.537406561397444, 2.8529886820342716, -3.4524984742617457, 9.870450847557183}, {1.5997319672256904, -0.7785202333216761, -1.6144942169993, 5.572472782556839, -4.187199250885652, -15.012243707418406, -0.7327033789210926, 0.5475015257382534, 9.870450847557183}, {1.0778774878655475, -2.143055839126959, 1.8972066351776808, 1.9933318607527575, -1.6702917941051352, 0.2685286269197684, -14.462943100412684, 0.5475015257382534, 9.870450847557183}, {2.0032584178625217, -1.9938176991209073, 1.8972066351776808, 1.9933318607527575, -5.905159492361053, 4.399819340414528, -4.359366115651527, -9.452498474261745, 9.870450847557183}, {0.5955687292136896, 0.8215616781767565, -1.1027933648223192, 4.9933318607527575, -6.4916348275412075, 4.935419429169031, -4.308490869225876, 0.5475015257382534, -0.12954915244281562}} >>> stdFromPH = CdfFromPH[betap, Bp, Range[0.,1.,0.1]]; >>> Print[stdFromPH]; {-2.220446049250313*^-16, 0.14225026871566182, 0.25714575295174624, 0.354886048345307, 0.4393330753410508, 0.5126194621799739, 0.576300019821528, 0.6316534259881904, 0.6797734673117404, 0.7216066395715919, 0.7579746780193367} >>> stmFromME = MomentsFromME[beta, B, 5]; >>> Print[stmFromME]; {0.7023562543214075, 1.0017175985977365, 2.1462963079181128, 6.132531576177928, 21.903161812239368} For Python/Numpy: >>> B = ml.matrix([[6., 1., 0.],[0., 4., 1.],[2., 0., 0.]]) >>> F = ml.matrix([[0., 1., 1.],[5., 0., 0.],[1., 3., 0.]]) >>> L = ml.matrix([[-14., 3., 2.],[0., -14., 4.],[3., 1., -10.]]) >>> L0 = L+B >>> print(L0) [[ -8. 4. 2.] [ 0. -10. 5.] [ 5. 1. -10.]] >>> ncd, ncm = QBDQueue(B, L, F, L0, "ncDistr", 11, "ncMoms", 5) Final Residual Error for G: 9.71445146547e-17 Final Residual Error for R: 1.11022302463e-16 >>> print(ncd) [ 0.29094 0.20433 0.14547 0.10358 0.07371 0.05246 0.03734 0.02657 0.01891 0.01346 0.00958] >>> print(ncm) [2.4600295202120317, 14.607919051794482, 128.87860443055746, 1515.8884540468425, 22287.969412532377] >>> alphap, Ap = QBDQueue(B, L, F, L0, "ncDistrDPH") Final Residual Error for G: 9.71445146547e-17 Final Residual Error for R: 1.11022302463e-16 >>> print(alphap) [[ 0.28256 0.22386 0.20264]] >>> print(Ap) [[ 0.11832 0.4103 0.18373] [ 0.196 0.19477 0.32261] [ 0.27566 0.22146 0.21229]] >>> alpha, A = QBDQueue(B, L, F, L0, "ncDistrMG") Final Residual Error for G: 9.71445146547e-17 Final Residual Error for R: 1.11022302463e-16 >>> print(alpha) [[ 0.04258 -0.27854 0.94503]] >>> print(A) [[-0.00569 -0.63242 1.33129] [ 0.06947 -0.36133 0.99875] [ 0.03735 -0.21854 0.8924 ]] >>> ncdFromDPH = PmfFromDPH(alphap, Ap, np.arange(0,11.0,1)) >>> print(ncdFromDPH) [ 0.29094 0.20433 0.14547 0.10358 0.07371 0.05246 0.03734 0.02657 0.01891 0.01346 0.00958] >>> ncmFromMG = MomentsFromMG(alpha, A, 5) >>> print(ncmFromMG) [2.4600295202120313, 14.607919051794475, 128.87860443055737, 1515.8884540468407, 22287.969412532337] >>> std, stm = QBDQueue(B, L, F, L0, "stDistr", np.arange(0.,1.1,0.1), "stMoms", 5) Final Residual Error for G: 9.71445146547e-17 Final Residual Error for R: 1.11022302463e-16 >>> print(std) [ 1.11022e-16 1.42250e-01 2.57146e-01 3.54886e-01 4.39333e-01 5.12619e-01 5.76300e-01 6.31653e-01 6.79773e-01 7.21607e-01 7.57975e-01] >>> print(stm) [0.70235625432140525, 1.0017175985977307, 2.1462963079180937, 6.1325315761778585, 21.903161812239034] >>> betap, Bp = QBDQueue(B, L, F, L0, "stDistrPH") Final Residual Error for G: 9.71445146547e-17 Final Residual Error for R: 1.11022302463e-16 >>> print(betap) [[ 0.52899 0. 0. 0. 0.35507 0. 0. 0. 0.11594]] >>> print(Bp) [[-12.59079 2.36197 0.50976 4.23487 0.39366 0.08496 3. 0. 0. ] [ 2.00101 -12.66159 0.95667 0.3335 4.22307 0.15944 0. 3. 0. ] [ 2.83542 0.93483 -13.59536 0.47257 0.15581 4.06744 0. 0. 3. ] [ 5. 0. 0. -13.06053 1.57465 0.33984 4.23487 0.39366 0.08496] [ 0. 5. 0. 1.33401 -13.10772 0.63778 0.3335 4.22307 0.15944] [ 0. 0. 5. 1.89028 0.62322 -13.73024 0.47257 0.15581 4.06744] [ 4.46974 0.78732 0.16992 4. 0. 0. -10. 0. 0. ] [ 0.667 4.44614 0.31889 0. 4. 0. 0. -10. 0. ] [ 0.94514 0.31161 4.13488 0. 0. 4. 0. 0. -10. ]] >>> beta, B = QBDQueue(B, L, F, L0, "stDistrME") Final Residual Error for G: 9.71445146547e-17 Final Residual Error for R: 1.11022302463e-16 >>> print(beta) [[ 0.17391 0.47826 -0.71739 0.71739 -1.23913 1.23913 -1.23913 0.52174 1.06522]] >>> print(B) [[-12.59079 -0.41431 -3.40797 2.16504 -13.13561 15. -13.40921 12.06606 1.34314] [ 0.5517 -13.31488 -8.03859 7.34081 -10.01035 10.7136 -6.39935 0.03303 6.67157] [ 0.20504 -1.88439 -15.35906 1.89388 -4.0612 3.46259 -0.19879 0.02202 4.44771] [ -0.28868 1.38111 -2.59572 -11.07296 -3.75595 3.46259 -1.37175 -3.25117 8.89385] [ 0.48659 -1.37547 -1.39064 5.45219 -17.35131 -1.53741 2.85299 -3.4525 9.87045] [ 1.59973 -0.77852 -1.61449 5.57247 -4.1872 -15.01224 -0.7327 0.5475 9.87045] [ 1.07788 -2.14306 1.89721 1.99333 -1.67029 0.26853 -14.46294 0.5475 9.87045] [ 2.00326 -1.99382 1.89721 1.99333 -5.90516 4.39982 -4.35937 -9.4525 9.87045] [ 0.59557 0.82156 -1.10279 4.99333 -6.49163 4.93542 -4.30849 0.5475 -0.12955]] >>> stdFromPH = CdfFromPH(betap, Bp, np.arange(0.,1.1,0.1)) >>> print(stdFromPH) [ 1.11022e-16 1.42250e-01 2.57146e-01 3.54886e-01 4.39333e-01 5.12619e-01 5.76300e-01 6.31653e-01 6.79773e-01 7.21607e-01 7.57975e-01] >>> stmFromME = MomentsFromME(beta, B, 5) >>> print(stmFromME) [0.70235625432140614, 1.001717598597732, 2.1462963079180968, 6.1325315761778718, 21.903161812239095]