///|
/// Finite capacity includes customers in service. Exponential abandonment
/// acts only on waiting customers, not on those already in service.
pub(all) struct FiniteQueue {
arrival : Double
service : Double
servers : Int
capacity : Int
abandonment : Double
} derive(Debug, ToJson)
///|
pub(all) struct FiniteMetrics {
states : Array[Double]
mean_system : Double
mean_queue : Double
mean_busy : Double
blocked_fraction : Double
admitted_rate : Double
service_rate : Double
abandon_rate : Double
mean_residence : Double
} derive(Debug, ToJson)
///|
pub fn FiniteQueue::analyze(
self : FiniteQueue,
) -> FiniteMetrics raise QueueError {
rate(self.arrival, "arrival")
rate(self.service, "service")
positive(self.service, "service")
rate(self.abandonment, "abandonment")
servers(self.servers)
if self.capacity < self.servers || self.capacity > 10000 {
raise Limit("finite capacity must be between server count and 10000")
}
let birth = Array::make(self.capacity, self.arrival)
let death = Array::makei(self.capacity, i => {
let n = i + 1
n.min(self.servers).to_double() * self.service +
(n - self.servers).max(0).to_double() * self.abandonment
})
// Per-state total rates are sums of individually valid input rates;
// stationary_birth_death applies its public rate bound as well.
let states = stationary_birth_death(birth, death)
let mut mean_system = 0.0
let mut mean_queue = 0.0
let mut mean_busy = 0.0
for n in 0..