///|
/// Finite-source M/M/c/c loss model. Idle sources attempt at per_source rate;
/// busy sources do not. Time-full probability differs from arrival blocking.
pub(all) struct Engset {
sources : Int
channels : Int
per_source : Double
service : Double
} derive(Debug, ToJson)
///|
pub(all) struct EngsetMetrics {
states : Array[Double]
mean_busy : Double
time_full : Double
arrival_blocking : Double
attempted_rate : Double
carried_rate : Double
} derive(Debug, ToJson)
///|
pub fn Engset::analyze(self : Engset) -> EngsetMetrics raise QueueError {
if self.sources < 1 ||
self.sources > 10000 ||
self.channels < 0 ||
self.channels > self.sources {
raise Limit("Engset sources 1..10000, channels 0..sources")
}
rate(self.per_source, "per-source attempt rate")
rate(self.service, "service")
positive(self.service, "service")
let birth = Array::makei(self.channels, n => {
(self.sources - n).to_double() * self.per_source
})
let death = Array::makei(self.channels, n => {
(n + 1).to_double() * self.service
})
let states = stationary_birth_death(birth, death)
let mut mean_busy = 0.0
let mut attempt_weight = 0.0
for n in 0..