most-queue 1.57__tar.gz → 1.59__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 (161) hide show
  1. {most_queue-1.57 → most_queue-1.59}/PKG-INFO +2 -1
  2. {most_queue-1.57 → most_queue-1.59}/most_queue/general/plots.py +3 -3
  3. {most_queue-1.57/most_queue/misc → most_queue-1.59/most_queue/sim}/__init__.py +0 -0
  4. {most_queue-1.57/most_queue/sim → most_queue-1.59/most_queue/sim/networks}/__init__.py +0 -0
  5. {most_queue-1.57/most_queue/sim/utils → most_queue-1.59/most_queue/theory}/__init__.py +0 -0
  6. {most_queue-1.57/most_queue/theory → most_queue-1.59/most_queue/theory/batch}/__init__.py +0 -0
  7. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/fifo/mgn_takahasi.py +18 -11
  8. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/negative/mgn_disaster.py +71 -0
  9. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/negative/mgn_rcs.py +72 -0
  10. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/priority/preemptive/m_ph_n_busy_approx.py +52 -193
  11. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/vacations/m_h2_h2warm.py +2 -0
  12. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/vacations/mgn_with_h2_delay_cold_warm.py +32 -1
  13. {most_queue-1.57 → most_queue-1.59}/pyproject.toml +3 -2
  14. most_queue-1.59/requirements.txt +169 -0
  15. {most_queue-1.57 → most_queue-1.59}/setup.py +10 -10
  16. most_queue-1.59/tests/cold_warm_delay_params.yaml +52 -0
  17. {most_queue-1.57 → most_queue-1.59}/tests/test_m_ph_n_prty.py +1 -4
  18. {most_queue-1.57 → most_queue-1.59}/tests/test_mgn_rcs.py +3 -5
  19. most_queue-1.59/tests/test_mgn_with_h2_delay_cold_warm_one_shot.py +171 -0
  20. {most_queue-1.57 → most_queue-1.59}/tutorials/queue_sim.ipynb +1 -1
  21. most_queue-1.59/works/vacations/base_parameters.yaml +52 -0
  22. most_queue-1.59/works/vacations/channels.py +69 -0
  23. most_queue-1.59/works/vacations/cooling.py +164 -0
  24. most_queue-1.59/works/vacations/cooling_delay.py +173 -0
  25. most_queue-1.59/works/vacations/main.py +60 -0
  26. most_queue-1.59/works/vacations/run_one_calc_vs_sim.py +146 -0
  27. most_queue-1.59/works/vacations/service.py +75 -0
  28. most_queue-1.59/works/vacations/utilization.py +74 -0
  29. most_queue-1.59/works/vacations/utils.py +142 -0
  30. most_queue-1.59/works/vacations/warmup.py +166 -0
  31. most_queue-1.57/requirements.txt +0 -7
  32. most_queue-1.57/works/negative_queues/__init__.py +0 -0
  33. {most_queue-1.57 → most_queue-1.59}/.gitignore +0 -0
  34. {most_queue-1.57 → most_queue-1.59}/LICENSE +0 -0
  35. {most_queue-1.57 → most_queue-1.59}/README.md +0 -0
  36. {most_queue-1.57 → most_queue-1.59}/assets/queue_long.png +0 -0
  37. {most_queue-1.57 → most_queue-1.59}/deploy.txt +0 -0
  38. {most_queue-1.57 → most_queue-1.59}/docs/Makefile +0 -0
  39. {most_queue-1.57 → most_queue-1.59}/docs/make.bat +0 -0
  40. {most_queue-1.57 → most_queue-1.59}/docs/source/conf.py +0 -0
  41. {most_queue-1.57 → most_queue-1.59}/docs/source/index.rst +0 -0
  42. {most_queue-1.57 → most_queue-1.59}/docs/source/modules.rst +0 -0
  43. {most_queue-1.57 → most_queue-1.59}/docs/source/most_queue.rst +0 -0
  44. {most_queue-1.57 → most_queue-1.59}/docs/source/most_queue.sim.rst +0 -0
  45. {most_queue-1.57 → most_queue-1.59}/docs/source/most_queue.theory.rst +0 -0
  46. {most_queue-1.57 → most_queue-1.59}/googleb31d3dccb40f969f.html +0 -0
  47. {most_queue-1.57 → most_queue-1.59}/most_queue/__init__.py +0 -0
  48. {most_queue-1.57 → most_queue-1.59}/most_queue/general/__init__.py +0 -0
  49. {most_queue-1.57 → most_queue-1.59}/most_queue/general/distribution_params.py +0 -0
  50. {most_queue-1.57 → most_queue-1.59}/most_queue/general/interfaces.py +0 -0
  51. {most_queue-1.57 → most_queue-1.59}/most_queue/general/tables.py +0 -0
  52. {most_queue-1.57 → most_queue-1.59}/most_queue/misc/approx_cdf_make.py +0 -0
  53. {most_queue-1.57 → most_queue-1.59}/most_queue/misc/calc_v_pls.py +0 -0
  54. {most_queue-1.57 → most_queue-1.59}/most_queue/misc/compare_fj_calc.py +0 -0
  55. {most_queue-1.57 → most_queue-1.59}/most_queue/misc/flow_sum.py +0 -0
  56. {most_queue-1.57 → most_queue-1.59}/most_queue/misc/test_weibull.py +0 -0
  57. {most_queue-1.57 → most_queue-1.59}/most_queue/misc/vacations_paper_utils.py +0 -0
  58. {most_queue-1.57 → most_queue-1.59}/most_queue/rand_distribution.py +0 -0
  59. {most_queue-1.57 → most_queue-1.59}/most_queue/sim/base.py +0 -0
  60. {most_queue-1.57 → most_queue-1.59}/most_queue/sim/batch.py +0 -0
  61. {most_queue-1.57 → most_queue-1.59}/most_queue/sim/finite_source.py +0 -0
  62. {most_queue-1.57 → most_queue-1.59}/most_queue/sim/flow_sum.py +0 -0
  63. {most_queue-1.57 → most_queue-1.59}/most_queue/sim/fork_join.py +0 -0
  64. {most_queue-1.57 → most_queue-1.59}/most_queue/sim/fork_join_delta.py +0 -0
  65. {most_queue-1.57 → most_queue-1.59}/most_queue/sim/impatient.py +0 -0
  66. {most_queue-1.57 → most_queue-1.59}/most_queue/sim/negative.py +0 -0
  67. {most_queue-1.57 → most_queue-1.59}/most_queue/sim/networks/priority_network.py +0 -0
  68. {most_queue-1.57 → most_queue-1.59}/most_queue/sim/priority.py +0 -0
  69. {most_queue-1.57/most_queue/sim/networks → most_queue-1.59/most_queue/sim/utils}/__init__.py +0 -0
  70. {most_queue-1.57 → most_queue-1.59}/most_queue/sim/utils/distribution_utils.py +0 -0
  71. {most_queue-1.57 → most_queue-1.59}/most_queue/sim/utils/exceptions.py +0 -0
  72. {most_queue-1.57 → most_queue-1.59}/most_queue/sim/utils/phase.py +0 -0
  73. {most_queue-1.57 → most_queue-1.59}/most_queue/sim/utils/qs_queue.py +0 -0
  74. {most_queue-1.57 → most_queue-1.59}/most_queue/sim/utils/servers.py +0 -0
  75. {most_queue-1.57 → most_queue-1.59}/most_queue/sim/utils/stats_update.py +0 -0
  76. {most_queue-1.57 → most_queue-1.59}/most_queue/sim/utils/tasks.py +0 -0
  77. {most_queue-1.57 → most_queue-1.59}/most_queue/sim/vacations.py +0 -0
  78. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/batch/mm1.py +0 -0
  79. {most_queue-1.57/most_queue/theory/batch → most_queue-1.59/most_queue/theory/closed}/__init__.py +0 -0
  80. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/closed/engset.py +0 -0
  81. {most_queue-1.57/most_queue/theory/closed → most_queue-1.59/most_queue/theory/fifo}/__init__.py +0 -0
  82. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/fifo/ek_d_n.py +0 -0
  83. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/fifo/gi_m_1.py +0 -0
  84. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/fifo/gi_m_n.py +0 -0
  85. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/fifo/m_d_n.py +0 -0
  86. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/fifo/mg1.py +0 -0
  87. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/fifo/mmnr.py +0 -0
  88. {most_queue-1.57/most_queue/theory/fifo → most_queue-1.59/most_queue/theory/fork_join}/__init__.py +0 -0
  89. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/fork_join/m_m_n.py +0 -0
  90. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/fork_join/split_join.py +0 -0
  91. {most_queue-1.57/most_queue/theory/fork_join → most_queue-1.59/most_queue/theory/impatience}/__init__.py +0 -0
  92. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/impatience/mm1.py +0 -0
  93. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/negative/mg1_disasters.py +0 -0
  94. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/negative/mg1_rcs.py +0 -0
  95. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/negative/structs.py +0 -0
  96. {most_queue-1.57/most_queue/theory/impatience → most_queue-1.59/most_queue/theory/networks}/__init__.py +0 -0
  97. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/networks/network_viewer.py +0 -0
  98. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/networks/open_network.py +0 -0
  99. {most_queue-1.57/most_queue/theory/networks → most_queue-1.59/most_queue/theory/priority}/__init__.py +0 -0
  100. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/priority/mgn_invar_approx.py +0 -0
  101. {most_queue-1.57/most_queue/theory/priority → most_queue-1.59/most_queue/theory/priority/non_preemptive}/__init__.py +0 -0
  102. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/priority/non_preemptive/mg1.py +0 -0
  103. {most_queue-1.57/most_queue/theory/priority/non_preemptive → most_queue-1.59/most_queue/theory/priority/preemptive}/__init__.py +0 -0
  104. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/priority/preemptive/mg1.py +0 -0
  105. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/priority/preemptive/mmn_2cls_pr_busy_approx.py +0 -0
  106. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/priority/preemptive/mmn_3cls_busy_approx.py +0 -0
  107. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/r_example.gexf +0 -0
  108. {most_queue-1.57/most_queue/theory/priority/preemptive → most_queue-1.59/most_queue/theory/utils}/__init__.py +0 -0
  109. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/utils/binom_probs.py +0 -0
  110. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/utils/busy_periods.py +0 -0
  111. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/utils/conditional.py +0 -0
  112. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/utils/conv.py +0 -0
  113. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/utils/diff5dots.py +0 -0
  114. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/utils/flow_sum.py +0 -0
  115. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/utils/passage_time.py +0 -0
  116. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/utils/q_poisson_arrival_calc.py +0 -0
  117. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/utils/student_stat.py +0 -0
  118. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/utils/transforms.py +0 -0
  119. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/utils/weibull.py +0 -0
  120. {most_queue-1.57/most_queue/theory/utils → most_queue-1.59/most_queue/theory/vacations}/__init__.py +0 -0
  121. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/vacations/mg1_warm_calc.py +0 -0
  122. {most_queue-1.57 → most_queue-1.59}/most_queue/theory/vacations/mmn_with_h2_cold_and_h2_warmup.py +0 -0
  123. {most_queue-1.57/most_queue/theory/vacations → most_queue-1.59/tests}/__init__.py +0 -0
  124. {most_queue-1.57 → most_queue-1.59}/tests/test_base_qs_sim.py +0 -0
  125. {most_queue-1.57 → most_queue-1.59}/tests/test_batch.py +0 -0
  126. {most_queue-1.57 → most_queue-1.59}/tests/test_ek_d_n.py +0 -0
  127. {most_queue-1.57 → most_queue-1.59}/tests/test_engset.py +0 -0
  128. {most_queue-1.57 → most_queue-1.59}/tests/test_fj_delta.py +0 -0
  129. {most_queue-1.57 → most_queue-1.59}/tests/test_fj_im.py +0 -0
  130. {most_queue-1.57 → most_queue-1.59}/tests/test_gi_m_1_calc.py +0 -0
  131. {most_queue-1.57 → most_queue-1.59}/tests/test_gi_m_n_calc.py +0 -0
  132. {most_queue-1.57 → most_queue-1.59}/tests/test_impatience.py +0 -0
  133. {most_queue-1.57 → most_queue-1.59}/tests/test_m_d_n_calc.py +0 -0
  134. {most_queue-1.57 → most_queue-1.59}/tests/test_m_h2_h2warm.py +0 -0
  135. {most_queue-1.57 → most_queue-1.59}/tests/test_mg1_calc.py +0 -0
  136. {most_queue-1.57 → most_queue-1.59}/tests/test_mg1_disaster.py +0 -0
  137. {most_queue-1.57 → most_queue-1.59}/tests/test_mg1_rcs.py +0 -0
  138. {most_queue-1.57 → most_queue-1.59}/tests/test_mg1_warmup.py +0 -0
  139. {most_queue-1.57 → most_queue-1.59}/tests/test_mgn_disaster.py +0 -0
  140. {most_queue-1.57 → most_queue-1.59}/tests/test_mgn_tt.py +0 -0
  141. {most_queue-1.57 → most_queue-1.59}/tests/test_mgn_with_h2_delay_cold_warm.py +0 -0
  142. {most_queue-1.57 → most_queue-1.59}/tests/test_mmn3_pnz_cox_approx.py +0 -0
  143. {most_queue-1.57 → most_queue-1.59}/tests/test_mmn_h2cold_h2warm.py +0 -0
  144. {most_queue-1.57 → most_queue-1.59}/tests/test_mmn_prty_pnz_approx.py +0 -0
  145. {most_queue-1.57 → most_queue-1.59}/tests/test_network_im_prty.py +0 -0
  146. {most_queue-1.57 → most_queue-1.59}/tests/test_qs_sim.py +0 -0
  147. {most_queue-1.57 → most_queue-1.59}/tests/test_qs_sim_prty.py +0 -0
  148. {most_queue-1.57 → most_queue-1.59}/tests/units/h2_params_cv_greater_than_exp.png +0 -0
  149. {most_queue-1.57 → most_queue-1.59}/tests/units/h2_params_cv_less_than_exp.png +0 -0
  150. {most_queue-1.57 → most_queue-1.59}/tests/units/test_busy_moments_calc.py +0 -0
  151. {most_queue-1.57 → most_queue-1.59}/tests/units/test_conditionals.py +0 -0
  152. {most_queue-1.57 → most_queue-1.59}/tests/units/test_h2_params_cv.py +0 -0
  153. {most_queue-1.57 → most_queue-1.59}/tests/units/test_queue_types.py +0 -0
  154. {most_queue-1.57 → most_queue-1.59}/tutorials/m_h2_h2warm.ipynb +0 -0
  155. {most_queue-1.57 → most_queue-1.59}/tutorials/mgn_takahasi_takami.ipynb +0 -0
  156. {most_queue-1.57 → most_queue-1.59}/tutorials/network_with_priorities.ipynb +0 -0
  157. {most_queue-1.57 → most_queue-1.59}/tutorials/priority_queue.ipynb +0 -0
  158. {most_queue-1.57/tests → most_queue-1.59/works}/__init__.py +0 -0
  159. {most_queue-1.57/works → most_queue-1.59/works/negative_queues}/__init__.py +0 -0
  160. {most_queue-1.57 → most_queue-1.59}/works/negative_queues/work_mgn_disasters.py +0 -0
  161. {most_queue-1.57 → most_queue-1.59}/works/negative_queues/work_mgn_rcs.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: most_queue
3
- Version: 1.57
3
+ Version: 1.59
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>
@@ -34,6 +34,7 @@ Requires-Dist: matplotlib
34
34
  Requires-Dist: networkx
35
35
  Requires-Dist: numpy
36
36
  Requires-Dist: pandas
37
+ Requires-Dist: pyyaml
37
38
  Requires-Dist: scipy==1.13.0
38
39
  Requires-Dist: tqdm
39
40
  Description-Content-Type: text/markdown
@@ -42,11 +42,11 @@ def plot_sim_vs_calc_moments(xs: list[float], sim_results: list[float],
42
42
  errors = [100 * (w_sim - w_tt) / w_tt for w_sim,
43
43
  w_tt in zip(sim_results, calc_results)]
44
44
 
45
- ax.plot(xs, errors)
45
+ ax.plot(xs, errors, color='black')
46
46
  ax.set_ylabel(r"$\varepsilon$, %")
47
47
  else:
48
- ax.plot(xs, sim_results, label="Sim")
49
- ax.plot(xs, calc_results, label="Calc")
48
+ ax.plot(xs, sim_results, label="Sim", color='black', linestyle='--')
49
+ ax.plot(xs, calc_results, label="Calc", color='black')
50
50
  if is_waiting_time:
51
51
  ax.set_ylabel(r"$\omega_{1}$")
52
52
  else:
@@ -68,6 +68,10 @@ class MGnCalc:
68
68
  self.D = []
69
69
  self.Y = []
70
70
 
71
+ self.big_g = []
72
+ self.big_ag = []
73
+ self.big_bg = []
74
+
71
75
  self.w = None
72
76
 
73
77
  def _fill_cols(self):
@@ -109,13 +113,13 @@ class MGnCalc:
109
113
  for j in range(1, self.N): # for all levels except the first.
110
114
 
111
115
  # b':
112
- self.b1[j] = np.dot(self.t[j - 1], self.AG[j])
116
+ self.b1[j] = np.dot(self.t[j - 1], self.big_ag[j])
113
117
 
114
118
  # b":
115
119
  if j != (self.N - 1):
116
- self.b2[j] = np.dot(self.t[j + 1], self.BG[j])
120
+ self.b2[j] = np.dot(self.t[j + 1], self.big_bg[j])
117
121
  else:
118
- self.b2[j] = np.dot(self.t[j - 1], self.BG[j])
122
+ self.b2[j] = np.dot(self.t[j - 1], self.big_bg[j])
119
123
 
120
124
  c = self._calculate_c(j)
121
125
 
@@ -128,7 +132,7 @@ class MGnCalc:
128
132
 
129
133
  if self.R and j == (self.N - 1):
130
134
  tA = np.dot(self.t[j - 1], self.A[j - 1])
131
- tag = np.dot(tA, self.G[j])
135
+ tag = np.dot(tA, self.big_g[j])
132
136
  tag_sum = 0
133
137
  for t_i in range(tag.shape[1]):
134
138
  tag_sum += tag[0, t_i]
@@ -142,6 +146,9 @@ class MGnCalc:
142
146
 
143
147
  self.x[0] = (1.0 + 0.0j) / self.z[1]
144
148
 
149
+ self.t[0] = self.x[0] * \
150
+ (np.dot(self.t[1], self.B[1]).dot(self.big_g[0]))
151
+
145
152
  x_max1 = np.max(self.x)
146
153
 
147
154
  if self.verbose:
@@ -266,22 +273,22 @@ class MGnCalc:
266
273
  self.D.append(self._build_big_d_matrix(i))
267
274
 
268
275
  def _calc_g_matrices(self):
269
- self.G = []
276
+ self.big_g = []
270
277
  for j in range(0, self.N):
271
- self.G.append(np.linalg.inv(self.D[j] - self.C[j]))
278
+ self.big_g.append(np.linalg.inv(self.D[j] - self.C[j]))
272
279
 
273
280
  def _calc_ag_matrices(self):
274
- self.AG = [0]
281
+ self.big_ag = [0]
275
282
  for j in range(1, self.N):
276
- self.AG.append(np.dot(self.A[j - 1], self.G[j]))
283
+ self.big_ag.append(np.dot(self.A[j - 1], self.big_g[j]))
277
284
 
278
285
  def _calc_bg_matrices(self):
279
- self.BG = [0]
286
+ self.big_bg = [0]
280
287
  for j in range(1, self.N):
281
288
  if j != (self.N - 1):
282
- self.BG.append(np.dot(self.B[j + 1], self.G[j]))
289
+ self.big_bg.append(np.dot(self.B[j + 1], self.big_g[j]))
283
290
  else:
284
- self.BG.append(np.dot(self.B[j], self.G[j]))
291
+ self.big_bg.append(np.dot(self.B[j], self.big_g[j]))
285
292
 
286
293
  def _calc_support_matrices(self):
287
294
  self._calc_g_matrices()
@@ -340,3 +340,74 @@ class MGnNegativeDisasterCalc(MGnCalc):
340
340
  v_broken = self.get_v_broken()
341
341
  w = self.get_w()
342
342
  return NegativeArrivalsResults(p=p, v=v, v_served=v_served, v_broken=v_broken, w=w)
343
+
344
+ def run(self):
345
+ """
346
+ Run the algorithm.
347
+ """
348
+
349
+ self._fill_cols()
350
+ self._fill_t_b()
351
+ self._build_matrices()
352
+ self._initial_probabilities()
353
+
354
+ self.b1[0][0, 0] = 0.0 + 0.0j
355
+ self.b2[0][0, 0] = 0.0 + 0.0j
356
+ x_max1 = np.max(self.x)
357
+ x_max2 = 0.0 + 0.0j
358
+
359
+ self._calc_support_matrices()
360
+
361
+ self.num_of_iter_ = 0 # number of iterations
362
+
363
+ while np.fabs(x_max2.real - x_max1.real) >= self.e1:
364
+ x_max2 = x_max1
365
+ self.num_of_iter_ += 1
366
+
367
+ for j in range(1, self.N): # for all levels except the first.
368
+
369
+ # b':
370
+ self.b1[j] = np.dot(self.t[j - 1], self.big_ag[j])
371
+
372
+ # b":
373
+ if j != (self.N - 1):
374
+ self.b2[j] = np.dot(self.t[j + 1], self.big_bg[j])
375
+ else:
376
+ self.b2[j] = np.dot(self.t[j - 1], self.big_bg[j])
377
+
378
+ c = self._calculate_c(j)
379
+
380
+ x_znam = np.dot(c, self.b1[j]) + self.b2[j]
381
+ self.x[j] = 0.0 + 0.0j
382
+ for k in range(x_znam.shape[1]):
383
+ self.x[j] += x_znam[0, k]
384
+
385
+ self.x[j] = (1.0 + 0.0j) / self.x[j]
386
+
387
+ if self.R and j == (self.N - 1):
388
+ tA = np.dot(self.t[j - 1], self.A[j - 1])
389
+ tag = np.dot(tA, self.big_g[j])
390
+ tag_sum = 0
391
+ for t_i in range(tag.shape[1]):
392
+ tag_sum += tag[0, t_i]
393
+ self.z[j] = 1.0 / tag_sum
394
+ self.t[j] = self.z[j] * tag
395
+
396
+ else:
397
+ self.z[j] = np.dot(c, self.x[j])
398
+ self.t[j] = np.dot(self.z[j], self.b1[j]) + \
399
+ np.dot(self.x[j], self.b2[j])
400
+
401
+ self.x[0] = (1.0 + 0.0j) / self.z[1]
402
+
403
+ # Why ????
404
+ self.t[0] = self.x[0] * \
405
+ (np.dot(self.t[1], self.B[1]).dot(self.big_g[0]))
406
+
407
+ x_max1 = np.max(self.x)
408
+
409
+ if self.verbose:
410
+ print(f"End iter # {self.num_of_iter_}")
411
+
412
+ self._calculate_p()
413
+ self._calculate_y()
@@ -4,6 +4,7 @@ Calculate M/H2/n queue with negative jobs with RCS discipline,
4
4
  """
5
5
 
6
6
  import numpy as np
7
+ import math
7
8
 
8
9
  from most_queue.rand_distribution import H2Distribution, H2Params
9
10
  from most_queue.theory.fifo.mgn_takahasi import MGnCalc
@@ -206,3 +207,74 @@ class MGnNegativeRCSCalc(MGnCalc):
206
207
  (num - i) * self.mu[0] + i * self.mu[1]
207
208
 
208
209
  return output
210
+
211
+ def run(self):
212
+ """
213
+ Run the algorithm.
214
+ """
215
+
216
+ self._fill_cols()
217
+ self._fill_t_b()
218
+ self._build_matrices()
219
+ self._initial_probabilities()
220
+
221
+ self.b1[0][0, 0] = 0.0 + 0.0j
222
+ self.b2[0][0, 0] = 0.0 + 0.0j
223
+ x_max1 = np.max(self.x)
224
+ x_max2 = 0.0 + 0.0j
225
+
226
+ self._calc_support_matrices()
227
+
228
+ self.num_of_iter_ = 0 # number of iterations
229
+
230
+ while math.fabs(x_max2.real - x_max1.real) >= self.e1:
231
+ x_max2 = x_max1
232
+ self.num_of_iter_ += 1
233
+
234
+ for j in range(1, self.N): # for all levels except the first.
235
+
236
+ # b':
237
+ self.b1[j] = np.dot(self.t[j - 1], self.big_ag[j])
238
+
239
+ # b":
240
+ if j != (self.N - 1):
241
+ self.b2[j] = np.dot(self.t[j + 1], self.big_bg[j])
242
+ else:
243
+ self.b2[j] = np.dot(self.t[j - 1], self.big_bg[j])
244
+
245
+ c = self._calculate_c(j)
246
+
247
+ x_znam = np.dot(c, self.b1[j]) + self.b2[j]
248
+ self.x[j] = 0.0 + 0.0j
249
+ for k in range(x_znam.shape[1]):
250
+ self.x[j] += x_znam[0, k]
251
+
252
+ self.x[j] = (1.0 + 0.0j) / self.x[j]
253
+
254
+ if self.R and j == (self.N - 1):
255
+ tA = np.dot(self.t[j - 1], self.A[j - 1])
256
+ tag = np.dot(tA, self.big_g[j])
257
+ tag_sum = 0
258
+ for t_i in range(tag.shape[1]):
259
+ tag_sum += tag[0, t_i]
260
+ self.z[j] = 1.0 / tag_sum
261
+ self.t[j] = self.z[j] * tag
262
+
263
+ else:
264
+ self.z[j] = np.dot(c, self.x[j])
265
+ self.t[j] = np.dot(self.z[j], self.b1[j]) + \
266
+ np.dot(self.x[j], self.b2[j])
267
+
268
+ self.x[0] = (1.0 + 0.0j) / self.z[1]
269
+
270
+ # Why?, because t[0] = [1.0] always
271
+ # self.t[0] = self.x[0] * \
272
+ # (np.dot(self.t[1], self.B[1]).dot(self.big_g[0]))
273
+
274
+ x_max1 = np.max(self.x)
275
+
276
+ if self.verbose:
277
+ print(f"End iter # {self.num_of_iter_}")
278
+
279
+ self._calculate_p()
280
+ self._calculate_y()
@@ -7,21 +7,22 @@ import math
7
7
 
8
8
  import numpy as np
9
9
 
10
- from most_queue.rand_distribution import Cox2Params, CoxDistribution, H2Distribution
10
+ from most_queue.rand_distribution import CoxDistribution, H2Distribution
11
+ from most_queue.theory.fifo.mgn_takahasi import MGnCalc
11
12
  from most_queue.theory.utils.passage_time import PassageTimeCalculation
12
13
 
13
14
 
14
- class MPhNPrty:
15
+ class MPhNPrty(MGnCalc):
15
16
  """
16
17
  Calculation of M/PH, M/n queue with two classes of requests and absolute priority
17
18
  using the Takahashi-Takagi numerical method based on the approximation
18
19
  of the busy-time distribution by a Cox second-order distribution.
19
20
  """
20
21
 
21
- def __init__(self, mu_L: float, cox_param_H: Cox2Params, l_L: float, l_H: float, n: int, N: int = 250,
22
+ def __init__(self, mu_L: float, b_high: list[float], l_L: float, l_H: float, n: int, N: int = 250,
22
23
  accuracy: float = 1e-8, max_iter: int = 300, is_cox: bool = True,
23
24
  approx_ee: float = 0.1, approx_e: float = 0.5, is_fitting: bool = True,
24
- verbose: bool = True):
25
+ buffer=None, verbose: bool = True, dtype="c16"):
25
26
  """
26
27
  Calculation of M/PH, M/n queue with two classes of requests and absolute priority
27
28
  based on the Takahashi-Takagi numerical method based on the approximation
@@ -30,8 +31,7 @@ class MPhNPrty:
30
31
  :param l_L: intensity of the arrivals with low priority,
31
32
  :param l_H: intensity of the arrivals with high priority,
32
33
  :param mu_L: intensity of service for low-priority requests,
33
- :param cox_param_H: params of Cox2 (H2) approximation
34
- of service time for high priority jobs
34
+ :param b_high: list of E[X^k], k =1,2,3 for service time for high priority jobs
35
35
  :param N: number of levels (stages)
36
36
  :param accuracy: accuracy parameter for stopping the iteration
37
37
  :param max_iter: maximum number of iterations
@@ -39,21 +39,21 @@ class MPhNPrty:
39
39
  of low-priority jobs, otherwise use H2 distribution.
40
40
  :param approx_ee, approx_e: approximation paramters
41
41
  """
42
- # self.dt = np.dtype("f8")
43
- self.dt = np.dtype("c16")
44
- self.n = n # number of channels
45
42
 
46
- self.N = N
47
- self.e1 = accuracy
43
+ super().__init__(n=n, l=0, b=b_high, buffer=buffer,
44
+ N=N, accuracy=accuracy, dtype=dtype, verbose=verbose)
45
+
48
46
  self.l_L = l_L
49
47
  self.l_H = l_H
50
48
  self.mu_L = mu_L
49
+
50
+ cox_param_H = CoxDistribution.get_params(b_high)
51
+
51
52
  self.mu1_H = cox_param_H.mu1
52
53
  self.mu2_H = cox_param_H.mu2
53
54
  self.p_H = cox_param_H.p1
54
55
  self.max_iter = max_iter
55
56
  self.is_cox = is_cox
56
- self.verbose = verbose
57
57
  self.approx_ee = approx_ee
58
58
  self.approx_e = approx_e
59
59
  self.is_fitting = is_fitting
@@ -67,49 +67,9 @@ class MPhNPrty:
67
67
 
68
68
  self.cols = [] * N
69
69
 
70
- # Takahasi-Takagi method parameters
71
-
72
- self.t = []
73
- self.b1 = []
74
- self.b2 = []
75
- self.x = [0.0 + 0.0j] * N
76
- self.z = [0.0 + 0.0j] * N
77
-
78
- # Probabilities of system states
79
- self.p = [0.0 + 0.0j] * N
80
-
81
70
  self.run_iterations_num_ = 0
82
71
  self.p_iteration_num_ = 0
83
-
84
- # Transition matrices
85
- self.A = []
86
- self.B = []
87
- self.C = []
88
- self.D = []
89
- self.Y = []
90
-
91
- # Cols depends on number of channels. cols = number of all microstates transitions
92
- # from Cox2 to level
93
- self.cols_length_ = 2 * self.n ** 2
94
- for i in range(self.n):
95
- self.cols_length_ += i + 1
96
-
97
- for i in range(N):
98
- self.t.append(np.zeros((1, self.cols_length_), dtype=self.dt))
99
- self.b1.append(np.zeros((1, self.cols_length_), dtype=self.dt))
100
- self.b2.append(np.zeros((1, self.cols_length_), dtype=self.dt))
101
- self.x.append(np.zeros((1, self.cols_length_), dtype=self.dt))
102
-
103
- self._build_matrices()
104
- self._initial_probabilities()
105
-
106
- def get_p(self) -> list[float]:
107
- """
108
- Get probabilities of states.
109
- Returns:
110
- list: Probabilities of states.
111
- """
112
- return [prob.real for prob in self.p]
72
+ self.cols_length_ = 0
113
73
 
114
74
  def get_low_class_v1(self) -> float:
115
75
  """
@@ -123,85 +83,20 @@ class MPhNPrty:
123
83
  l1 += p_real[i] * i
124
84
  return l1 / self.l_L
125
85
 
126
- def run(self):
127
- """
128
- Run calculation. The calculation algorithm does not depend on the structure of matrices.
129
- """
130
- self.b1[0][0, 0] = 0.0 + 0.0j
131
- self.b2[0][0, 0] = 0.0 + 0.0j
132
-
133
- is_ave = False
134
-
135
- iter_num = 0
136
- self.run_iterations_num_ = 0
137
- if is_ave:
138
- x_ave1 = 0.0 + 0.0j
139
- x_ave2 = 0.0 + 0.0j
140
- for i in range(self.N):
141
- x_ave1 += self.x[i]
142
- x_ave1 /= self.N
143
- else:
144
-
145
- x_ave1 = 0.0
146
- x_ave2 = 0.0
147
- for i in range(self.N):
148
- if self.x[i].real > x_ave1:
149
- x_ave1 = self.x[i].real
150
-
151
- while math.fabs(x_ave2.real - x_ave1.real) >= self.e1 and iter_num < self.max_iter:
152
- if self.verbose:
153
- print(f"Start numeric iteration {iter_num}")
154
- iter_num += 1
155
- x_ave2 = x_ave1
156
- for j in range(1, self.N): # по всем ярусам, кроме первого.
157
-
158
- G = np.linalg.inv(self.D[j] - self.C[j])
159
- # b':
160
- self.b1[j] = np.dot(self.t[j - 1], np.dot(self.A[j - 1], G))
161
-
162
- # b":
163
- if j != (self.N - 1):
164
- self.b2[j] = np.dot(
165
- self.t[j + 1], np.dot(self.B[j + 1], G))
166
- else:
167
- self.b2[j] = np.dot(self.t[j - 1], np.dot(self.B[j], G))
168
-
169
- c = self._calculate_c(j)
170
-
171
- x_znam = np.dot(c, self.b1[j]) + self.b2[j]
172
- self.x[j] = 0.0 + 0.0j
173
- for k in range(x_znam.shape[1]):
174
- self.x[j] += x_znam[0, k]
175
-
176
- self.x[j] = 1.0 / self.x[j]
177
-
178
- self.z[j] = np.dot(c, self.x[j])
179
- self.t[j] = np.dot(self.z[j], self.b1[j]) + \
180
- np.dot(self.x[j], self.b2[j])
181
-
182
- self.x[0] = 1.0 / self.z[1]
183
-
184
- t1B1 = np.dot(self.t[1], self.B[1])
185
- self.t[0] = np.dot(self.x[0], t1B1)
186
- self.t[0] = np.dot(self.t[0], np.linalg.inv(self.D[0] - self.C[0]))
187
-
188
- if is_ave:
189
- x_ave1 = 0.0 + 0.0j
190
- for i in range(self.N):
191
- x_ave1 += self.x[i]
192
- x_ave1 /= self.N
193
-
194
- else:
195
- x_ave1 = 0.0
196
- for i in range(self.N):
197
- if self.x[i].real > x_ave1:
198
- x_ave1 = self.x[i].real
86
+ def _fill_cols(self):
87
+ # Cols depends on number of channels. cols = number of all microstates transitions
88
+ # from Cox2 to level
89
+ self.cols_length_ = 2 * self.n ** 2
90
+ for i in range(self.n):
91
+ self.cols_length_ += i + 1
199
92
 
200
- self.run_iterations_num_ = iter_num
201
- self._calculate_p()
202
- self._calculate_y()
93
+ def _fill_t_b(self):
94
+ for _i in range(self.N):
95
+ self.t.append(np.zeros((1, self.cols_length_), dtype=self.dt))
96
+ self.b1.append(np.zeros((1, self.cols_length_), dtype=self.dt))
97
+ self.b2.append(np.zeros((1, self.cols_length_), dtype=self.dt))
203
98
 
204
- def _build_A_for_busy_periods(self, num):
99
+ def _build_big_a_for_busy_periods(self, num):
205
100
  """
206
101
  Forms the matrix A at level num for calculating the Busy Period at a given level number.
207
102
  :param num: level number
@@ -214,7 +109,7 @@ class MPhNPrty:
214
109
  col = num + 1
215
110
  row = num + 1
216
111
  else:
217
- output = self.A_for_busy[self.n]
112
+ output = self.big_a_for_busy[self.n]
218
113
  return output
219
114
 
220
115
  output = np.zeros((row, col), dtype=self.dt)
@@ -223,7 +118,7 @@ class MPhNPrty:
223
118
  output[i, i] = self.l_H
224
119
  return output
225
120
 
226
- def _build_B_for_busy_periods(self, num):
121
+ def _build_big_b_for_busy_periods(self, num):
227
122
  """
228
123
  Forms the matrix B at level num for calculating the Busy Period at a given level number.
229
124
  :param num: level number
@@ -239,10 +134,10 @@ class MPhNPrty:
239
134
  col = num
240
135
  row = num
241
136
  output = np.zeros((row, col), dtype=self.dt)
242
- output[:, :self.n] = self.B_for_busy[self.n]
137
+ output[:, :self.n] = self.big_b_for_busy[self.n]
243
138
  return output
244
139
  else:
245
- output = self.B_for_busy[self.n + 1]
140
+ output = self.big_b_for_busy[self.n + 1]
246
141
  return output
247
142
 
248
143
  output = np.zeros((row, col), dtype=self.dt)
@@ -256,7 +151,7 @@ class MPhNPrty:
256
151
  output[i + 1, i] = (i + 1) * mu2
257
152
  return output
258
153
 
259
- def _build_C_for_busy_periods(self, num):
154
+ def _build_big_c_for_busy_periods(self, num):
260
155
  """
261
156
  Forms the matrix C at level num for calculating the Busy Period at a given level number.
262
157
  :param num: level number
@@ -269,7 +164,7 @@ class MPhNPrty:
269
164
  col = num + 1
270
165
  row = num + 1
271
166
  else:
272
- output = self.C_for_busy[self.n]
167
+ output = self.big_c_for_busy[self.n]
273
168
  return output
274
169
 
275
170
  output = np.zeros((row, col), dtype=self.dt)
@@ -281,7 +176,7 @@ class MPhNPrty:
281
176
  output[i, i + 1] = (num - i) * mu1 * pH
282
177
  return output
283
178
 
284
- def _build_D_for_busy_periods(self, num):
179
+ def _build_big_d_for_busy_periods(self, num):
285
180
  """
286
181
  Forms the matrix D at level num for calculating the Busy Period at a given level number.
287
182
  :param num: level number
@@ -291,7 +186,7 @@ class MPhNPrty:
291
186
  col = num + 1
292
187
  row = num + 1
293
188
  else:
294
- output = self.D_for_busy[self.n]
189
+ output = self.big_d_for_busy[self.n]
295
190
  return output
296
191
 
297
192
  output = np.zeros((row, col), dtype=self.dt)
@@ -302,14 +197,14 @@ class MPhNPrty:
302
197
  sumC = 0.0 + 0.0j
303
198
 
304
199
  for j in range(col):
305
- sumA += self.A_for_busy[num][i, j]
200
+ sumA += self.big_a_for_busy[num][i, j]
306
201
 
307
202
  if num != 0:
308
203
  for j in range(col - 1):
309
- sumB += self.B_for_busy[num][i, j]
204
+ sumB += self.big_b_for_busy[num][i, j]
310
205
 
311
206
  for j in range(col):
312
- sumC += self.C_for_busy[num][i, j]
207
+ sumC += self.big_c_for_busy[num][i, j]
313
208
 
314
209
  output[i, i] = sumA + sumB + sumC
315
210
 
@@ -320,19 +215,19 @@ class MPhNPrty:
320
215
  Calculate the busy periods for all levels.
321
216
  """
322
217
 
323
- self.A_for_busy = []
324
- self.B_for_busy = []
325
- self.C_for_busy = []
326
- self.D_for_busy = []
218
+ self.big_a_for_busy = []
219
+ self.big_b_for_busy = []
220
+ self.big_c_for_busy = []
221
+ self.big_d_for_busy = []
327
222
 
328
223
  for i in range(self.n + 2):
329
- self.A_for_busy.append(self._build_A_for_busy_periods(i))
330
- self.B_for_busy.append(self._build_B_for_busy_periods(i))
331
- self.C_for_busy.append(self._build_C_for_busy_periods(i))
332
- self.D_for_busy.append(self._build_D_for_busy_periods(i))
224
+ self.big_a_for_busy.append(self._build_big_a_for_busy_periods(i))
225
+ self.big_b_for_busy.append(self._build_big_b_for_busy_periods(i))
226
+ self.big_c_for_busy.append(self._build_big_c_for_busy_periods(i))
227
+ self.big_d_for_busy.append(self._build_big_d_for_busy_periods(i))
333
228
 
334
- pass_time = PassageTimeCalculation(self.A_for_busy, self.B_for_busy,
335
- self.C_for_busy, self.D_for_busy, is_clx=True, is_verbose=self.verbose)
229
+ pass_time = PassageTimeCalculation(self.big_a_for_busy, self.big_b_for_busy,
230
+ self.big_c_for_busy, self.big_d_for_busy, is_clx=True, is_verbose=self.verbose)
336
231
  pass_time.calc()
337
232
 
338
233
  self.pnz_num_ = self.n ** 2
@@ -422,42 +317,6 @@ class MPhNPrty:
422
317
  p0_min = p0_
423
318
  self.p_iteration_num_ = iter
424
319
 
425
- def _calculate_y(self):
426
- for i in range(self.N):
427
- self.Y.append(np.dot(self.p[i], self.t[i]))
428
-
429
- def _build_matrices(self):
430
- """
431
- Builds matrices A, B, C and D for the system.
432
- """
433
- for i in range(self.N):
434
- self.A.append(self._build_big_a_matrix(i))
435
- self.B.append(self._build_big_b_matrix(i))
436
- self.C.append(self._build_big_c_matrix(i))
437
- self.D.append(self._build_big_d_matrix(i))
438
-
439
- def _calculate_c(self, j):
440
- """
441
- Calculates the value of variable c, participating in the calculation
442
- """
443
- chisl = 0.0 + 0.0j
444
- znam = 0.0 + 0.0j
445
- znam2 = 0.0 + 0.0j
446
-
447
- m = np.dot(self.b2[j], self.B[j])
448
- for k in range(m.shape[1]):
449
- chisl += m[0, k]
450
-
451
- m = np.dot(self.b1[j], self.B[j])
452
- for k in range(m.shape[1]):
453
- znam2 += m[0, k]
454
-
455
- m = np.dot(self.t[j - 1], self.A[j - 1])
456
- for k in range(m.shape[1]):
457
- znam += m[0, k]
458
-
459
- return chisl / (znam - znam2)
460
-
461
320
  def _build_big_a_matrix(self, num: int):
462
321
  """
463
322
  Forms the matrix A(L) at a given level number
@@ -556,22 +415,22 @@ class MPhNPrty:
556
415
  l_start = 1
557
416
  l_end = 0
558
417
  for i in range(1, self.n):
559
- rows = self.B_for_busy[i].shape[0]
560
- cols = self.B_for_busy[i].shape[1]
418
+ rows = self.big_b_for_busy[i].shape[0]
419
+ cols = self.big_b_for_busy[i].shape[1]
561
420
  for r in range(rows):
562
421
  for c in range(cols):
563
- output[l_start + r, l_end + c] = self.B_for_busy[i][r, c]
422
+ output[l_start + r, l_end + c] = self.big_b_for_busy[i][r, c]
564
423
  l_start += i + 1
565
424
  l_end += i
566
425
 
567
426
  # C_for_busy
568
427
  l_start = 1
569
428
  for i in range(1, self.n):
570
- rows = self.C_for_busy[i].shape[0]
571
- cols = self.C_for_busy[i].shape[1]
429
+ rows = self.big_c_for_busy[i].shape[0]
430
+ cols = self.big_c_for_busy[i].shape[1]
572
431
  for r in range(rows):
573
432
  for c in range(cols):
574
- output[l_start + r, l_start + c] = self.C_for_busy[i][r, c]
433
+ output[l_start + r, l_start + c] = self.big_c_for_busy[i][r, c]
575
434
  l_start += i + 1
576
435
 
577
436
  l_start = 0
@@ -407,6 +407,8 @@ class MH2nH2Warm:
407
407
  else:
408
408
  self.x[0] = 1.0 / self.z[1]
409
409
 
410
+ self.t[0] = self.x[0]*(np.dot(self.t[1], self.B[1]).dot(self.G[0]))
411
+
410
412
  x_max1 = 0.0 + 0.0j
411
413
  for i in range(self.N):
412
414
  if self.x[i].real > x_max1.real: