most-queue 1.59__tar.gz → 1.61__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of most-queue might be problematic. Click here for more details.

Files changed (165) hide show
  1. {most_queue-1.59 → most_queue-1.61}/.gitignore +1 -1
  2. {most_queue-1.59 → most_queue-1.61}/PKG-INFO +1 -1
  3. {most_queue-1.59 → most_queue-1.61}/most_queue/general/distribution_params.py +9 -0
  4. {most_queue-1.59 → most_queue-1.61}/most_queue/rand_distribution.py +125 -0
  5. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/fifo/mgn_takahasi.py +61 -1
  6. most_queue-1.61/most_queue/theory/utils/residual.py +19 -0
  7. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/utils/transforms.py +3 -0
  8. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/vacations/mgn_with_h2_delay_cold_warm.py +6 -3
  9. {most_queue-1.59 → most_queue-1.61}/pyproject.toml +1 -1
  10. {most_queue-1.59 → most_queue-1.61}/setup.py +1 -1
  11. {most_queue-1.59 → most_queue-1.61}/tests/test_mgn_tt.py +4 -1
  12. most_queue-1.61/tests/units/test_tt_up_probs.py +48 -0
  13. most_queue-1.61/tests/units/test_weibull.py +29 -0
  14. {most_queue-1.59 → most_queue-1.61}/tutorials/queue_sim.ipynb +1 -1
  15. most_queue-1.61/works/negative_queues/base_parameters.yaml +21 -0
  16. most_queue-1.61/works/negative_queues/work_mgn_negatives.py +303 -0
  17. most_queue-1.61/works/vacations/__init__.py +0 -0
  18. {most_queue-1.59 → most_queue-1.61}/works/vacations/main.py +1 -1
  19. most_queue-1.59/most_queue/misc/test_weibull.py +0 -37
  20. most_queue-1.59/most_queue/theory/utils/weibull.py +0 -155
  21. most_queue-1.59/works/negative_queues/work_mgn_disasters.py +0 -358
  22. most_queue-1.59/works/negative_queues/work_mgn_rcs.py +0 -358
  23. {most_queue-1.59 → most_queue-1.61}/LICENSE +0 -0
  24. {most_queue-1.59 → most_queue-1.61}/README.md +0 -0
  25. {most_queue-1.59 → most_queue-1.61}/assets/queue_long.png +0 -0
  26. {most_queue-1.59 → most_queue-1.61}/deploy.txt +0 -0
  27. {most_queue-1.59 → most_queue-1.61}/docs/Makefile +0 -0
  28. {most_queue-1.59 → most_queue-1.61}/docs/make.bat +0 -0
  29. {most_queue-1.59 → most_queue-1.61}/docs/source/conf.py +0 -0
  30. {most_queue-1.59 → most_queue-1.61}/docs/source/index.rst +0 -0
  31. {most_queue-1.59 → most_queue-1.61}/docs/source/modules.rst +0 -0
  32. {most_queue-1.59 → most_queue-1.61}/docs/source/most_queue.rst +0 -0
  33. {most_queue-1.59 → most_queue-1.61}/docs/source/most_queue.sim.rst +0 -0
  34. {most_queue-1.59 → most_queue-1.61}/docs/source/most_queue.theory.rst +0 -0
  35. {most_queue-1.59 → most_queue-1.61}/googleb31d3dccb40f969f.html +0 -0
  36. {most_queue-1.59 → most_queue-1.61}/most_queue/__init__.py +0 -0
  37. {most_queue-1.59 → most_queue-1.61}/most_queue/general/__init__.py +0 -0
  38. {most_queue-1.59 → most_queue-1.61}/most_queue/general/interfaces.py +0 -0
  39. {most_queue-1.59 → most_queue-1.61}/most_queue/general/plots.py +0 -0
  40. {most_queue-1.59 → most_queue-1.61}/most_queue/general/tables.py +0 -0
  41. {most_queue-1.59 → most_queue-1.61}/most_queue/misc/approx_cdf_make.py +0 -0
  42. {most_queue-1.59 → most_queue-1.61}/most_queue/misc/calc_v_pls.py +0 -0
  43. {most_queue-1.59 → most_queue-1.61}/most_queue/misc/compare_fj_calc.py +0 -0
  44. {most_queue-1.59 → most_queue-1.61}/most_queue/misc/flow_sum.py +0 -0
  45. {most_queue-1.59 → most_queue-1.61}/most_queue/misc/vacations_paper_utils.py +0 -0
  46. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/__init__.py +0 -0
  47. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/base.py +0 -0
  48. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/batch.py +0 -0
  49. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/finite_source.py +0 -0
  50. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/flow_sum.py +0 -0
  51. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/fork_join.py +0 -0
  52. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/fork_join_delta.py +0 -0
  53. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/impatient.py +0 -0
  54. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/negative.py +0 -0
  55. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/networks/__init__.py +0 -0
  56. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/networks/priority_network.py +0 -0
  57. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/priority.py +0 -0
  58. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/utils/__init__.py +0 -0
  59. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/utils/distribution_utils.py +0 -0
  60. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/utils/exceptions.py +0 -0
  61. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/utils/phase.py +0 -0
  62. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/utils/qs_queue.py +0 -0
  63. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/utils/servers.py +0 -0
  64. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/utils/stats_update.py +0 -0
  65. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/utils/tasks.py +0 -0
  66. {most_queue-1.59 → most_queue-1.61}/most_queue/sim/vacations.py +0 -0
  67. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/__init__.py +0 -0
  68. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/batch/__init__.py +0 -0
  69. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/batch/mm1.py +0 -0
  70. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/closed/__init__.py +0 -0
  71. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/closed/engset.py +0 -0
  72. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/fifo/__init__.py +0 -0
  73. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/fifo/ek_d_n.py +0 -0
  74. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/fifo/gi_m_1.py +0 -0
  75. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/fifo/gi_m_n.py +0 -0
  76. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/fifo/m_d_n.py +0 -0
  77. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/fifo/mg1.py +0 -0
  78. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/fifo/mmnr.py +0 -0
  79. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/fork_join/__init__.py +0 -0
  80. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/fork_join/m_m_n.py +0 -0
  81. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/fork_join/split_join.py +0 -0
  82. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/impatience/__init__.py +0 -0
  83. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/impatience/mm1.py +0 -0
  84. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/negative/mg1_disasters.py +0 -0
  85. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/negative/mg1_rcs.py +0 -0
  86. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/negative/mgn_disaster.py +0 -0
  87. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/negative/mgn_rcs.py +0 -0
  88. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/negative/structs.py +0 -0
  89. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/networks/__init__.py +0 -0
  90. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/networks/network_viewer.py +0 -0
  91. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/networks/open_network.py +0 -0
  92. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/priority/__init__.py +0 -0
  93. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/priority/mgn_invar_approx.py +0 -0
  94. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/priority/non_preemptive/__init__.py +0 -0
  95. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/priority/non_preemptive/mg1.py +0 -0
  96. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/priority/preemptive/__init__.py +0 -0
  97. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/priority/preemptive/m_ph_n_busy_approx.py +0 -0
  98. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/priority/preemptive/mg1.py +0 -0
  99. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/priority/preemptive/mmn_2cls_pr_busy_approx.py +0 -0
  100. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/priority/preemptive/mmn_3cls_busy_approx.py +0 -0
  101. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/r_example.gexf +0 -0
  102. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/utils/__init__.py +0 -0
  103. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/utils/binom_probs.py +0 -0
  104. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/utils/busy_periods.py +0 -0
  105. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/utils/conditional.py +0 -0
  106. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/utils/conv.py +0 -0
  107. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/utils/diff5dots.py +0 -0
  108. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/utils/flow_sum.py +0 -0
  109. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/utils/passage_time.py +0 -0
  110. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/utils/q_poisson_arrival_calc.py +0 -0
  111. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/utils/student_stat.py +0 -0
  112. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/vacations/__init__.py +0 -0
  113. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/vacations/m_h2_h2warm.py +0 -0
  114. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/vacations/mg1_warm_calc.py +0 -0
  115. {most_queue-1.59 → most_queue-1.61}/most_queue/theory/vacations/mmn_with_h2_cold_and_h2_warmup.py +0 -0
  116. {most_queue-1.59 → most_queue-1.61}/requirements.txt +0 -0
  117. {most_queue-1.59 → most_queue-1.61}/tests/__init__.py +0 -0
  118. {most_queue-1.59 → most_queue-1.61}/tests/cold_warm_delay_params.yaml +0 -0
  119. {most_queue-1.59 → most_queue-1.61}/tests/test_base_qs_sim.py +0 -0
  120. {most_queue-1.59 → most_queue-1.61}/tests/test_batch.py +0 -0
  121. {most_queue-1.59 → most_queue-1.61}/tests/test_ek_d_n.py +0 -0
  122. {most_queue-1.59 → most_queue-1.61}/tests/test_engset.py +0 -0
  123. {most_queue-1.59 → most_queue-1.61}/tests/test_fj_delta.py +0 -0
  124. {most_queue-1.59 → most_queue-1.61}/tests/test_fj_im.py +0 -0
  125. {most_queue-1.59 → most_queue-1.61}/tests/test_gi_m_1_calc.py +0 -0
  126. {most_queue-1.59 → most_queue-1.61}/tests/test_gi_m_n_calc.py +0 -0
  127. {most_queue-1.59 → most_queue-1.61}/tests/test_impatience.py +0 -0
  128. {most_queue-1.59 → most_queue-1.61}/tests/test_m_d_n_calc.py +0 -0
  129. {most_queue-1.59 → most_queue-1.61}/tests/test_m_h2_h2warm.py +0 -0
  130. {most_queue-1.59 → most_queue-1.61}/tests/test_m_ph_n_prty.py +0 -0
  131. {most_queue-1.59 → most_queue-1.61}/tests/test_mg1_calc.py +0 -0
  132. {most_queue-1.59 → most_queue-1.61}/tests/test_mg1_disaster.py +0 -0
  133. {most_queue-1.59 → most_queue-1.61}/tests/test_mg1_rcs.py +0 -0
  134. {most_queue-1.59 → most_queue-1.61}/tests/test_mg1_warmup.py +0 -0
  135. {most_queue-1.59 → most_queue-1.61}/tests/test_mgn_disaster.py +0 -0
  136. {most_queue-1.59 → most_queue-1.61}/tests/test_mgn_rcs.py +0 -0
  137. {most_queue-1.59 → most_queue-1.61}/tests/test_mgn_with_h2_delay_cold_warm.py +0 -0
  138. {most_queue-1.59 → most_queue-1.61}/tests/test_mgn_with_h2_delay_cold_warm_one_shot.py +0 -0
  139. {most_queue-1.59 → most_queue-1.61}/tests/test_mmn3_pnz_cox_approx.py +0 -0
  140. {most_queue-1.59 → most_queue-1.61}/tests/test_mmn_h2cold_h2warm.py +0 -0
  141. {most_queue-1.59 → most_queue-1.61}/tests/test_mmn_prty_pnz_approx.py +0 -0
  142. {most_queue-1.59 → most_queue-1.61}/tests/test_network_im_prty.py +0 -0
  143. {most_queue-1.59 → most_queue-1.61}/tests/test_qs_sim.py +0 -0
  144. {most_queue-1.59 → most_queue-1.61}/tests/test_qs_sim_prty.py +0 -0
  145. {most_queue-1.59 → most_queue-1.61}/tests/units/h2_params_cv_greater_than_exp.png +0 -0
  146. {most_queue-1.59 → most_queue-1.61}/tests/units/h2_params_cv_less_than_exp.png +0 -0
  147. {most_queue-1.59 → most_queue-1.61}/tests/units/test_busy_moments_calc.py +0 -0
  148. {most_queue-1.59 → most_queue-1.61}/tests/units/test_conditionals.py +0 -0
  149. {most_queue-1.59 → most_queue-1.61}/tests/units/test_h2_params_cv.py +0 -0
  150. {most_queue-1.59 → most_queue-1.61}/tests/units/test_queue_types.py +0 -0
  151. {most_queue-1.59 → most_queue-1.61}/tutorials/m_h2_h2warm.ipynb +0 -0
  152. {most_queue-1.59 → most_queue-1.61}/tutorials/mgn_takahasi_takami.ipynb +0 -0
  153. {most_queue-1.59 → most_queue-1.61}/tutorials/network_with_priorities.ipynb +0 -0
  154. {most_queue-1.59 → most_queue-1.61}/tutorials/priority_queue.ipynb +0 -0
  155. {most_queue-1.59 → most_queue-1.61}/works/__init__.py +0 -0
  156. {most_queue-1.59 → most_queue-1.61}/works/negative_queues/__init__.py +0 -0
  157. {most_queue-1.59 → most_queue-1.61}/works/vacations/base_parameters.yaml +0 -0
  158. {most_queue-1.59 → most_queue-1.61}/works/vacations/channels.py +0 -0
  159. {most_queue-1.59 → most_queue-1.61}/works/vacations/cooling.py +0 -0
  160. {most_queue-1.59 → most_queue-1.61}/works/vacations/cooling_delay.py +0 -0
  161. {most_queue-1.59 → most_queue-1.61}/works/vacations/run_one_calc_vs_sim.py +0 -0
  162. {most_queue-1.59 → most_queue-1.61}/works/vacations/service.py +0 -0
  163. {most_queue-1.59 → most_queue-1.61}/works/vacations/utilization.py +0 -0
  164. {most_queue-1.59 → most_queue-1.61}/works/vacations/utils.py +0 -0
  165. {most_queue-1.59 → most_queue-1.61}/works/vacations/warmup.py +0 -0
@@ -162,4 +162,4 @@ cython_debug/
162
162
 
163
163
  .vscode
164
164
 
165
- /works/results/
165
+ works/negative_queues/results/*
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: most_queue
3
- Version: 1.59
3
+ Version: 1.61
4
4
  Summary: Software package for calculation and simulation of queuing systems
5
5
  Project-URL: Homepage, https://github.com/xabarov/most-queue
6
6
  Author-email: Xabarov Roman <xabarov1985@gmail.com>
@@ -35,6 +35,15 @@ class GammaParams:
35
35
  g: list[float] | None = None
36
36
 
37
37
 
38
+ @dataclass
39
+ class WeibullParams:
40
+ """
41
+ Weibull distribution parameters.
42
+ """
43
+ k: float # Shape parameter
44
+ W: float # Scale parameter
45
+
46
+
38
47
  @dataclass
39
48
  class GaussianParams:
40
49
  """
@@ -16,10 +16,135 @@ from most_queue.general.distribution_params import (
16
16
  H2Params,
17
17
  ParetoParams,
18
18
  UniformParams,
19
+ WeibullParams
19
20
  )
20
21
  from most_queue.general.interfaces import Distribution
21
22
 
22
23
 
24
+ class Weibull(Distribution):
25
+ """
26
+ Class for working with the Weibull distribution
27
+ """
28
+
29
+ def __init__(self, params: WeibullParams, generator=None):
30
+ """
31
+ :param params: WeibullParams object containing shape parameter (k) and scale parameter (T)
32
+ :param generator: random number generator. If None, np.random is used.
33
+ """
34
+
35
+ self.k = params.k
36
+ self.W = params.W
37
+ self.params = params
38
+ self.type = 'Weibull'
39
+ self.generator = generator
40
+
41
+ @staticmethod
42
+ def generate_static(params: WeibullParams, generator=None):
43
+ """
44
+ Generates a random number according to the Weibull distribution.
45
+ """
46
+ if generator:
47
+ p = generator.random()
48
+ else:
49
+ p = np.random.rand()
50
+ return math.pow(-math.log(p)*params.W, -1 / params.k)
51
+
52
+ def generate(self) -> float:
53
+ """
54
+ Generates a random number according to the Weibull distribution.
55
+ """
56
+
57
+ return self.generate_static(self.params, self.generator)
58
+
59
+ @staticmethod
60
+ def calc_theory_moments(params: WeibullParams, num: int) -> list[float]:
61
+ """
62
+ Calculates theoretical moments of the distribution up to the specified order.
63
+ :param params: WeibullParams parameters for the distribution.
64
+ :param num: number of moments to calculate.
65
+ :return: list[float]
66
+ """
67
+ f = [0.0]*num
68
+ for i in range(num):
69
+ f[i] = math.gamma(1 + i/params.k) * math.pow(params.W, i/params.k)
70
+ return f
71
+
72
+ @staticmethod
73
+ def get_params(moments: list[float]) -> WeibullParams:
74
+ """
75
+ Parameter selection for the distribution based
76
+ on initial moments of the distribution
77
+
78
+ params:
79
+ moments: initial moments of the random variable
80
+
81
+ return:
82
+ WeibullParams
83
+
84
+ """
85
+ a = moments[1] / (moments[0] * moments[0])
86
+ u0 = math.log(2 * a) / (2.0 * math.log(2))
87
+ ee = 1e-6
88
+ u1 = (1.0 / (2 * math.log(2))) * math.log(
89
+ a * math.sqrt(math.pi) * math.gamma(u0 + 1) / math.gamma(u0 + 0.5))
90
+ delta = u1 - u0
91
+ while math.fabs(delta) > ee:
92
+ u1 = (1.0 / (2 * math.log(2))) * math.log(
93
+ a * math.sqrt(math.pi) * math.gamma(u0 + 1) / math.gamma(u0 + 0.5))
94
+ delta = u1 - u0
95
+ u0 = u1
96
+ k = 1 / u1
97
+ big_w = math.pow(moments[0] / math.gamma(u1 + 1), k)
98
+
99
+ return WeibullParams(k=k, W=big_w)
100
+
101
+ @staticmethod
102
+ def get_params_by_mean_and_coev(f1: float, coev: float) -> WeibullParams:
103
+ """
104
+ Subselect parameters of Weibull distribution by the given mean and coefficient of variation.
105
+ Args:
106
+ f1 (float): The first parameter of the Weibull distribution.
107
+ coev (float): The coefficient of variation.
108
+ Returns:
109
+ WeibullParams
110
+ """
111
+
112
+ f = [0, 0, 0]
113
+ alpha = 1 / (coev ** 2)
114
+ f[0] = f1
115
+ f[1] = pow(f[0], 2) * (pow(coev, 2) + 1)
116
+ f[2] = f[1] * f[0] * (1.0 + 2 / alpha)
117
+
118
+ return Weibull.get_params(f)
119
+
120
+ @staticmethod
121
+ def get_tail(params: WeibullParams, t: float) -> float:
122
+ """
123
+ Calculate the tail probability of a Weibull distribution at a given value.
124
+ Args:
125
+ params (WeibullParams): The parameters of Weibull distribution
126
+ t: The value at which to calculate the tail probability.
127
+ """
128
+ k = params.k
129
+ big_w = params.W
130
+
131
+ return math.exp(-math.pow(t, k) / big_w)
132
+
133
+ @staticmethod
134
+ def get_cdf(params: WeibullParams, t: float) -> float:
135
+ """
136
+ Calculate the cumulative distribution function (CDF) of a Weibull distribution for a given set of values.
137
+ Args:
138
+ params (WeibullParams): The parameters of Weibull distribution
139
+ t: The value at which to calculate the cdf probability.
140
+
141
+ """
142
+ k = params.k
143
+ big_w = params.W
144
+
145
+ return 1.0 - math.exp(-math.pow(t, k) / big_w)
146
+
147
+
23
148
  class NormalDistribution(Distribution):
24
149
  """
25
150
  Gaussian distribution. Generates random numbers from a normal (Gaussian) distribution.
@@ -6,6 +6,8 @@ import math
6
6
  import numpy as np
7
7
 
8
8
  from most_queue.rand_distribution import H2Distribution
9
+ from most_queue.theory.utils.transforms import lst_exp
10
+ from scipy.misc import derivative
9
11
 
10
12
 
11
13
  class MGnCalc:
@@ -163,7 +165,7 @@ class MGnCalc:
163
165
  """
164
166
  return [prob.real for prob in self.p]
165
167
 
166
- def get_w(self) -> list[float]:
168
+ def get_w(self, derivate=False) -> list[float]:
167
169
  """
168
170
  Get the waiting time moments
169
171
  """
@@ -173,6 +175,12 @@ class MGnCalc:
173
175
 
174
176
  w = [0.0] * 3
175
177
 
178
+ if derivate:
179
+ for i in range(3):
180
+ w[i] = derivative(self._calc_w_lst, 0,
181
+ dx=1e-3 / self.b[0], n=i + 1, order=9)
182
+ return np.array([-w[0], w[1].real, -w[2]])
183
+
176
184
  for j in range(1, len(self.p) - self.n):
177
185
  w[0] += j * self.p[self.n + j]
178
186
  for j in range(2, len(self.p) - self.n):
@@ -191,6 +199,7 @@ class MGnCalc:
191
199
  """
192
200
  Get the sojourn time moments
193
201
  """
202
+
194
203
  w = self.get_w()
195
204
  b0 = self.b[0]
196
205
  b1 = self.b[1]
@@ -407,3 +416,54 @@ class MGnCalc:
407
416
  output[i, i] = self.l + (num - i) * self.mu[0] + i * self.mu[1]
408
417
 
409
418
  return output
419
+
420
+ def _calc_up_probs(self, from_level):
421
+
422
+ b_matrix = self.B[from_level]
423
+ low_level_size = self.cols[from_level - 1]
424
+ high_level_size = self.cols[from_level]
425
+
426
+ probs = np.zeros((high_level_size, low_level_size), dtype=self.dt)
427
+
428
+ for i in range(high_level_size):
429
+ for j in range(low_level_size):
430
+ if from_level != 1:
431
+ probs[i, j] = b_matrix[i, j] / sum(b_matrix[i, :])
432
+ else:
433
+ probs[i, j] = b_matrix[i, 0] / sum(b_matrix[i, :])
434
+
435
+ return probs
436
+
437
+ def _get_key_numbers(self, level):
438
+ key_numbers = []
439
+ if level >= self.n:
440
+ for i in range(level + 1):
441
+ key_numbers.append((self.n - i, i))
442
+ else:
443
+ for i in range(level + 1):
444
+ key_numbers.append((level - i, i))
445
+ return np.array(key_numbers, dtype=self.dt)
446
+
447
+ def _calc_w_lst(self, s):
448
+
449
+ w = 0
450
+
451
+ key_numbers = self._get_key_numbers(self.n)
452
+
453
+ a = np.array(
454
+ [lst_exp(key_numbers[j][0] * self.mu[0] + key_numbers[j][1] * self.mu[1], s) for j in
455
+ range(self.n + 1)])
456
+
457
+ up_transition_mrx = self._calc_up_probs(self.n+1) # (n + 1 x n + 1)
458
+
459
+ for k in range(self.n, self.N):
460
+
461
+ Pa = np.linalg.matrix_power(
462
+ up_transition_mrx * a, k - self.n) # n+1 x n+1
463
+
464
+ Ys = [self.Y[k][0, i] for i in range(self.n + 1)]
465
+ aPa = np.dot(Pa, a)
466
+ for i in range(self.n + 1):
467
+ w += Ys[i] * aPa[i]
468
+
469
+ return w
@@ -0,0 +1,19 @@
1
+ import numpy as np
2
+
3
+
4
+ def lst_residual(lst_original: callable, b1: float, s: float) -> float:
5
+ """
6
+ Calculate the Laplace-Stieltjes transform of a residual distribution.
7
+ """
8
+ return (1-lst_original(s))/(b1*s)
9
+
10
+
11
+ def get_b_residual(b_original: list[float]) -> list[float]:
12
+ """
13
+ Calculate the initial moments E[X^k] for k=0,1,...,n-1 of a residual distribution.
14
+ b_res1 = E[X^2]/(2*E[X])
15
+ """
16
+ b_res = np.zeros(len(b_original)-1)
17
+ for i in range(len(b_original)-1):
18
+ b_res[i] = b_original[i+1]/((i+2)*b_original[0])
19
+ return b_res
@@ -25,3 +25,6 @@ def lst_gamma(gamma_params: GammaParams, s: float) -> float:
25
25
  Calculate the Laplace-Stieltjes transform of a gamma distribution.
26
26
  """
27
27
  return math.pow(gamma_params.mu/(s+gamma_params.mu), gamma_params.alpha)
28
+
29
+
30
+
@@ -144,11 +144,14 @@ class MGnH2ServingColdWarmDelay:
144
144
 
145
145
  probs = np.zeros((self.n + 1), dtype=self.dt)
146
146
 
147
- # servers are not busy, when system in [0,0] state, in cooling, cooling delay and warming up states.
147
+ # servers are not busy, when system in [0,0] state, in cooling, and warming up states.
148
148
 
149
- probs[0] += self.Y[0][0, 0] + self.Y[0][0, 1] + \
150
- self.Y[0][0, 2] + self.Y[0][0, 3] + self.Y[0][0, 4]
149
+ probs[0] += self.Y[0][0, 0] + self.Y[0][0, 3] + self.Y[0][0, 4]
151
150
 
151
+ # when cooling delay, 1 server is running
152
+
153
+ probs[1] += self.Y[0][0, 1] + self.Y[0][0, 2]
154
+
152
155
  for k in range(1, self.n):
153
156
  probs[k] += np.sum(self.Y[k][0, 2:k+3])
154
157
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "most_queue"
7
- version = "1.59"
7
+ version = "1.61"
8
8
  authors = [
9
9
  { name="Xabarov Roman", email="xabarov1985@gmail.com" },
10
10
  ]
@@ -1,7 +1,7 @@
1
1
  from setuptools import find_packages, setup
2
2
 
3
3
  setup(name='most-queue',
4
- version='1.59',
4
+ version='1.61',
5
5
  description='Software package for calculation and simulation of queuing systems',
6
6
  author='Xabarov Roman',
7
7
  author_email='xabarov1985@gmail.com',
@@ -15,6 +15,7 @@ from most_queue.general.tables import probs_print, times_print
15
15
  from most_queue.rand_distribution import GammaDistribution
16
16
  from most_queue.sim.base import QsSim
17
17
  from most_queue.theory.fifo.mgn_takahasi import MGnCalc
18
+ import numpy as np
18
19
 
19
20
  ARRIVAL_RATE = 1.0
20
21
  NUM_OF_JOBS = 300000
@@ -45,6 +46,7 @@ def test_mgn_tt():
45
46
  # get numerical calculation results
46
47
  p_tt = tt.get_p()
47
48
  v_tt = tt.get_v()
49
+
48
50
  tt_time = time.process_time() - tt_start
49
51
  # also can find out how many iterations were required
50
52
  num_of_iter = tt.num_of_iter_
@@ -87,7 +89,8 @@ def test_mgn_tt():
87
89
 
88
90
  times_print(v_sim, v_tt, False)
89
91
 
90
- assert 100*abs(v_tt[0] - v_sim[0])/max(v_tt[0], v_sim[0]) < 10
92
+ assert np.allclose(v_sim, v_tt, rtol=5e-1), "The results of the simulation and Takahasi-Takami method do not match!"
93
+
91
94
 
92
95
 
93
96
  if __name__ == "__main__":
@@ -0,0 +1,48 @@
1
+ """
2
+ Testing the Takahasi-Takami method for calculating an M/H2/n queue
3
+
4
+ When the coefficient of variation of service time is less than 1,
5
+ the parameters of the approximating H2 distribution
6
+ are complex, which does not prevent obtaining meaningful results.
7
+
8
+ For verification, simulation is used.
9
+
10
+ """
11
+ import math
12
+
13
+ from most_queue.general.tables import print_mrx
14
+ from most_queue.theory.fifo.mgn_takahasi import MGnCalc
15
+
16
+ ARRIVAL_RATE = 1.0
17
+ NUM_OF_JOBS = 300000
18
+ NUM_OF_CHANNELS = 3
19
+ UTILIZATION = 0.7
20
+ SERVICE_TIME_CV = 1.2
21
+
22
+
23
+ def test_calc_up_probs():
24
+ """
25
+ Testing the Takahasi-Takami method calculation of up-probabilities
26
+ """
27
+
28
+ # calculate initial moments of service time based
29
+ # on the given average and coefficient of variation
30
+ b = [0.0] * 3
31
+ alpha = 1 / (SERVICE_TIME_CV ** 2)
32
+ b[0] = NUM_OF_CHANNELS * UTILIZATION / \
33
+ ARRIVAL_RATE # average service time
34
+ b[1] = math.pow(b[0], 2) * (math.pow(SERVICE_TIME_CV, 2) + 1)
35
+ b[2] = b[1] * b[0] * (1.0 + 2 / alpha)
36
+
37
+ # run Takahasi-Takami method
38
+ tt = MGnCalc(NUM_OF_CHANNELS, ARRIVAL_RATE, b)
39
+ tt.run()
40
+
41
+ for i in range(1, NUM_OF_CHANNELS+2):
42
+ probs_mrx = tt._calc_up_probs(i)
43
+
44
+ print_mrx(probs_mrx)
45
+
46
+
47
+ if __name__ == "__main__":
48
+ test_calc_up_probs()
@@ -0,0 +1,29 @@
1
+ """
2
+ Test Weibull distribution
3
+ """
4
+ import matplotlib.pyplot as plt
5
+ import numpy as np
6
+
7
+ from most_queue.rand_distribution import Weibull
8
+
9
+ if __name__ == "__main__":
10
+
11
+ MEAN = 1.0
12
+ coevs = [1.0, 2.1, 3.2]
13
+
14
+ fig, ax = plt.subplots()
15
+
16
+ for coev in coevs:
17
+ params = Weibull.get_params_by_mean_and_coev(MEAN, coev)
18
+
19
+ print(
20
+ f"Weibull params at CV= {coev:1.3f}: k = {params.k:1.3f} W = {params.W:1.3f}")
21
+ ts = np.linspace(0, 3 * coevs[len(coevs)-1], 100)
22
+ dfr = [Weibull.get_tail(params, t) for t in ts]
23
+
24
+ ax.plot(ts, dfr, label=f"$\\nu$ = {coev:1.1f}")
25
+
26
+ ax.set_xlabel('t')
27
+ ax.set_ylabel('Tail')
28
+ plt.legend()
29
+ plt.show()
@@ -370,7 +370,7 @@
370
370
  "name": "python",
371
371
  "nbconvert_exporter": "python",
372
372
  "pygments_lexer": "ipython3",
373
- "version": "3.10.12"
373
+ "version": "3.12.3"
374
374
  }
375
375
  },
376
376
  "nbformat": 4,
@@ -0,0 +1,21 @@
1
+ accuracy: 1e-10
2
+ arrival_rate:
3
+ positive: 1.0
4
+ negative: 0.5
5
+ num_of_jobs: 300000
6
+ service:
7
+ cv:
8
+ base: 1.2
9
+ min: 0.3
10
+ max: 3
11
+ num_points: 20
12
+ channels:
13
+ base: 3
14
+ min: 1
15
+ max: 10
16
+ utilization:
17
+ base: 0.7
18
+ min: 0.1
19
+ max: 0.9
20
+ num_points: 20
21
+