def delay_prob_sample_exp_dm1(theta: float, t: int, delay: int, lamb: float, rate: float, a: float, sample_size: int) -> float: if 1 / lamb >= rate: raise ParameterOutOfBounds( (f"The arrivals' long term rate={1 / lamb} has to be smaller than " f"the service's long term rate={rate}")) if theta <= 0: raise ParameterOutOfBounds(f"theta={theta} must be > 0") if a <= 1: raise ParameterOutOfBounds(f"base a={a} must be >0") res = 0.0 for j in range(sample_size): sum_i = 0.0 for i in range(t + 1): sum_i += a**(np.exp( theta * f_sample(i=i, s=t + delay, t=t, lamb=lamb, rate=rate))) res += sum_i res /= sample_size return res
def delay_prob_taylor_exp_dm1(theta: float, t: int, delay: int, lamb: float, rate: float, a: float) -> float: if 1 / lamb >= rate: raise ParameterOutOfBounds( ("The arrivals' long term rate {0} has to be smaller than" "the service's long term rate {1}").format(1 / lamb, rate)) if theta <= 0: raise ParameterOutOfBounds("theta = {0} must be > 0".format(theta)) if a <= 1: raise ParameterOutOfBounds("base a={0} must be >0".format(a)) sum_j = 0.0 for _i in range(t + 1): try: summand = f_exp( theta=theta, i=_i, s=t + delay, t=t, lamb=lamb, rate=rate, a=a ) + 0.5 * f_double_prime( theta=theta, i=_i, s=t + delay, t=t, lamb=lamb, rate=rate, a=a) * var_dm1(delta_time=t - _i, lamb=lamb) except (FloatingPointError, OverflowError): summand = inf sum_j += summand return log(sum_j) / log(a)
def delay_prob_lower_exp_dm1(theta: float, t: int, delay: int, lamb: float, rate: float, a: float) -> float: if 1 / lamb >= rate: raise ParameterOutOfBounds( (f"The arrivals' long term rate {1 / lamb} has to be smaller than" f"the service's long term rate {rate}")) if theta <= 0: raise ParameterOutOfBounds(f"theta = {theta} must be > 0") if a <= 1: raise ParameterOutOfBounds(f"base a = {a} must be >1") sum_j = 0.0 for _i in range(t + 1): try: summand = f_exp(theta=theta, i=_i, s=t + delay, t=t, lamb=lamb, rate=rate, a=a) except (FloatingPointError, OverflowError): summand = inf sum_j += summand return np.log(sum_j) / np.log(a)
def stability_check(arr: Arrival, ser: Server, theta: float, indep=True, p=1.0, q=1.0) -> None: if indep: # if (arr.rho(theta=theta) < 0 or ser.rho(theta=theta) < 0 # or arr.sigma(theta=theta) < 0 or ser.sigma(theta=theta) < 0): # raise ParameterOutOfBounds("parameters must be positive") if arr.rho(theta=theta) >= ser.rho(theta=theta): raise ParameterOutOfBounds( f"The arrivals' rho={arr.rho(theta=theta)} has to be " f"smaller than the service's rho={ser.rho(theta=theta)}") else: # if (arr.rho(theta=p * theta) < 0 or ser.rho(theta=q * theta) < 0 # or arr.sigma(theta=p * theta) < 0 # or ser.sigma(theta=q * theta) < 0): # raise ParameterOutOfBounds("parameters must be positive") if arr.rho(theta=p * theta) >= ser.rho(theta=q * theta): raise ParameterOutOfBounds( f"The arrivals' rho={arr.rho(theta=p * theta)} has to be " f"smaller than the service's rho={ser.rho(theta=q * theta)}")
def rho(self, theta: float) -> float: if theta <= 0: raise ParameterOutOfBounds(f"theta = {theta} must be > 0") if theta >= self.mu: raise ParameterOutOfBounds(f"theta = {theta} must" f"be < mu = {self.mu}") return self.m * self.lamb / (self.mu - theta)
def sigma(self, theta: float) -> float: if theta <= 0: raise ParameterOutOfBounds(f"theta={theta} must be > 0") if theta >= self.decay: raise ParameterOutOfBounds(f"theta={theta} must " f"be < decay={self.decay}") return (self.m / theta) * log(1 + self.factor_m * theta / (self.decay - theta))
def rho(self, theta: float) -> float: # here, theta can simply be replaced by l * theta l_theta = self.l_power * theta if self.arr.rho(l_theta) < 0 or self.ser.rho(l_theta) < 0: raise ParameterOutOfBounds("Check rho's sign") if self.arr.rho(l_theta) >= self.ser.rho(l_theta): raise ParameterOutOfBounds( "The arrivals' rho has to be smaller than the service's rho") return self.arr.rho(l_theta)
def sigma(self, theta: float) -> float: if theta <= 0: raise ParameterOutOfBounds(f"theta = {theta} must be > 0") if theta >= self.decay: raise ParameterOutOfBounds("theta {0} must be < decay {1}".format( theta, self.decay)) theta_over_decay = theta / self.decay return (self.n / theta) * log( (self.factor_m**theta_over_decay) / (1 - theta_over_decay))
def rho(self, theta: float) -> float: """ rho(theta) :param theta: mgf parameter """ if theta <= 0: raise ParameterOutOfBounds(f"theta = {theta} must be > 0") if theta >= self.lamb: raise ParameterOutOfBounds( f"theta = {theta} must be < lambda = {self.lamb}") return (self.n / theta) * log(self.lamb / (self.lamb - theta))
def mgf_fbm(theta: float, delta_time: int, lamb: float, sigma: float, hurst: float) -> float: if theta <= 0: raise ParameterOutOfBounds(f"theta = {theta} must be > 0") if sigma <= 0: raise ParameterOutOfBounds(f"sigma = {sigma} must be > 0") if hurst <= 0 or hurst >= 1: raise ParameterOutOfBounds(f"Hurst = {hurst} must be in (0, 1)") return exp(lamb * theta * delta_time + (0.5 * (sigma * theta)**2) * delta_time**(2 * hurst))
def get_p_n(p_list) -> float: """ :param p_list: first p_1, ..., p_n in generalized Hoelder inequality :return: last p_n """ inv_p = [0.0] * len(p_list) for i in range(len(p_list)): if p_list[i] <= 1.0: raise ParameterOutOfBounds(f"p={p_list[i]} must be >1") inv_p[i] = 1.0 / p_list[i] if sum(inv_p) >= 1: raise ParameterOutOfBounds(f"p_i's are too small") return 1.0 / (1.0 - sum(inv_p))
def rho(self, theta: float) -> float: """ rho(theta) :param theta: mgf parameter """ if theta <= 0: raise ParameterOutOfBounds(f"theta = {theta} must be > 0") if theta >= self.beta_rate: raise ParameterOutOfBounds( f"theta = {theta} must be < beta = {self.beta_rate}") return (self.m * self.alpha_shape / theta) * log( self.beta_rate / (self.beta_rate - theta))
def backlog(arr: Arrival, ser: Service, theta: float, prob_b: float, tau=1.0, indep=True, p=1.0) -> float: """Implements stationary bound method""" if indep: p = 1.0 q = get_q(p=p, indep=indep) rho_a_p = arr.rho(theta=p * theta) sigma_a_p = arr.sigma(theta=p * theta) rho_s_q = ser.rho(theta=q * theta) sigma_s_q = ser.sigma(theta=q * theta) if rho_a_p >= rho_s_q: raise ParameterOutOfBounds( f"The arrivals' rho {rho_a_p} has to be smaller than" f"the service's rho {rho_s_q}") rho_arr_ser = rho_a_p - rho_s_q sigma_arr_ser = sigma_a_p + sigma_s_q if arr.is_discrete(): log_part = log(prob_b * (1 - exp(theta * rho_arr_ser))) return sigma_arr_ser - log_part / theta else: log_part = log(prob_b * (1 - exp(theta * tau * rho_arr_ser))) return tau * rho_a_p + sigma_arr_ser - log_part / theta
def output_power(arr: Arrival, ser: Service, theta: float, delta_time: int, l_power=1.0) -> float: """Implements stationary bound method""" if l_power < 1.0: l_power = 1.0 # raise ParameterOutOfBounds("l must be >= 1") l_theta = l_power * theta if arr.rho(theta=l_theta) >= ser.rho(theta=l_theta): raise ParameterOutOfBounds( f"The arrivals' rho {arr.rho(theta)} has to be smaller than" f"the service's rho {ser.rho(theta)}") sigma_l_arr_ser = arr.sigma(theta=l_theta) + ser.sigma(theta=l_theta) rho_l_arr_ser = arr.rho(theta=l_theta) - ser.rho(theta=l_theta) if arr.is_discrete(): numerator = exp(theta * arr.rho(theta=l_theta) * delta_time) * exp( theta * sigma_l_arr_ser) denominator = (1 - exp(l_theta * rho_l_arr_ser))**(1 / l_power) else: numerator = exp(theta * arr.rho(theta=l_theta) * (delta_time + 1)) * exp(theta * sigma_l_arr_ser) denominator = (1 - exp(l_theta * rho_l_arr_ser))**(1 / l_power) try: return numerator / denominator except ZeroDivisionError: return inf
def rho(self, theta: float) -> float: if theta <= 0: raise ParameterOutOfBounds(f"theta = {theta} must be > 0") bb = theta * self.burst - self.mu - self.lamb return 0.5 * self.n * (bb + sqrt( (bb**2) + 4 * self.mu * theta * self.burst)) / theta
def rho(self, theta: float) -> float: """ :param theta: mgf parameter :return: rho(theta) """ p_theta = self.p * theta q_theta = self.q * theta if self.arr.rho(p_theta) < 0 or self.ser.rho(q_theta) < 0: raise ParameterOutOfBounds("The rhos must be >= 0") if self.arr.rho(p_theta) >= self.ser.rho(q_theta): raise ParameterOutOfBounds( "The arrivals' rho has to be smaller than the service's rho") return self.arr.rho(p_theta)
def rho(self, theta): p_theta = self.p * theta q_theta = self.q * theta if self.ser.rho(q_theta) < 0 or self.arr.rho(p_theta) < 0: raise ParameterOutOfBounds("The rhos must be > 0") return self.ser.rho(q_theta) - self.arr.rho(p_theta)
def rho(self, theta: float) -> float: arr_1_rho_p_theta = self.arr1.rho(self.p * theta) arr_2_rho_q_theta = self.arr2.rho(self.q * theta) if arr_1_rho_p_theta < 0 or arr_2_rho_q_theta < 0: raise ParameterOutOfBounds("The rhos must be >= 0") return arr_1_rho_p_theta + arr_2_rho_q_theta
def rho(self, theta: float) -> float: """ rho(theta) :param theta: mgf parameter """ if theta <= 0: raise ParameterOutOfBounds(f"theta = {theta} must be > 0") return (self.m / theta) * self.lamb * (exp(theta) - 1)
def rho(self, theta: float) -> float: if theta <= 0: raise ParameterOutOfBounds(f"theta = {theta} must be > 0") off_on = self.stay_off + self.stay_on * exp(theta * self.burst) sqrt_part = sqrt(off_on**2 - 4 * (self.stay_off + self.stay_on - 1) * exp(theta * self.burst)) return log(0.5 * (off_on + sqrt_part)) / theta
def rho(self, theta: float) -> float: """ rho(theta) :param theta: mgf parameter """ if theta <= 0: raise ParameterOutOfBounds(f"theta = {theta} must be > 0") return self.m * self.rho_single
def rho(self, theta: float) -> float: for i in range(len(self.arr_list)): if self.arr_list[i].rho(self.p_list[i] * theta) < 0: raise ParameterOutOfBounds("The rhos must be > 0") res = 0.0 for i in range(len(self.arr_list)): res += self.arr_list[i].rho(self.p_list[i] * theta) return res
def rho(self, theta): if (isinstance(self.ser, RateLatencyServer) and isinstance(self.cross_arr, DetermTokenBucket)): residual_rate = self.ser.rate - self.cross_arr.arr_rate if residual_rate <= 0: raise ParameterOutOfBounds("The residual rate must be > 0") return residual_rate arr_rho_p_theta = self.cross_arr.rho(theta=self.p * theta) ser_rho_q_theta = self.ser.rho(theta=self.q * theta) residual_rate = ser_rho_q_theta - arr_rho_p_theta if residual_rate <= 0: raise ParameterOutOfBounds("The residual rate must be > 0") return residual_rate
def rho(self, theta: float) -> float: if isinstance(self.ser1, RateLatencyServer) and isinstance( self.ser2, RateLatencyServer): return min(self.ser1.rate, self.ser2.rate) ser_1_rho_p = self.ser1.rho(self.p * theta) ser_2_rho_q = self.ser2.rho(self.q * theta) if ser_1_rho_p < 0 or ser_2_rho_q < 0: raise ParameterOutOfBounds("The rhos must be > 0") if not is_equal(ser_1_rho_p, ser_2_rho_q): return min(ser_1_rho_p, ser_2_rho_q) else: if self.delta < 0 or ser_1_rho_p - self.delta <= 0: raise ParameterOutOfBounds("Residual rate must be > 0") return ser_1_rho_p - self.delta
def fifo_delay(token_bucket_constant: TokenBucketConstant, constant_rate: ConstantRate) -> int: """DNC FIFO Delay Bound""" if token_bucket_constant.rho(1.0) >= constant_rate.rate: raise ParameterOutOfBounds( "The arrivals' rho {0} has to be smaller than" " the service's rho {1}".format(token_bucket_constant.rho(1.0), constant_rate.rate)) return int(ceil(token_bucket_constant.sigma() / constant_rate.rate))
def sigma(self, theta: float) -> float: if theta <= 0: raise ParameterOutOfBounds("theta = {0} must be > 0".format(theta)) try: return log(1.0 + sqrt(2 * pi * self.n * (self.sigma_single**2)) * theta * exp(0.5 * self.n * (self.sigma_single**2) * (theta**2))) / theta except OverflowError: return inf
def rho(self, theta: float) -> float: res = 0.0 if self.indep: for arrival in self.arr_list: rho_i = arrival.rho(theta) if rho_i < 0: raise ParameterOutOfBounds("The rhos must be >= 0") res += rho_i else: for i, arr in enumerate(self.arr_list): rho_i = arr.rho(self.p_list[i] * theta) if rho_i < 0: raise ParameterOutOfBounds("The rhos must be >= 0") res += rho_i return res
def rho(self, theta: float) -> float: if theta <= 0: raise ParameterOutOfBounds(f"theta = {theta} must be > 0") if self.stay_on <= 0.0 or self.stay_on >= 1.0: raise ValueError(f"p_stay_on = {self.stay_on} must be in (0,1)") if self.stay_off <= 0.0 or self.stay_off >= 1.0: raise ValueError(f"p_stay_off = {self.stay_off} must be in (0,1)") off_on = self.stay_off + self.stay_on * exp(theta * self.peak_rate) sqrt_part = sqrt(off_on**2 - 4 * (self.stay_off + self.stay_on - 1) * exp(theta * self.peak_rate)) rho_mmoo_disc = log(0.5 * (off_on + sqrt_part)) if rho_mmoo_disc < 0: raise ParameterOutOfBounds("rho must be >= 0") return rho_mmoo_disc / theta
def mgf_regulated_arrive(theta: float, delta_time: int, sigma_single: float, rho_single: float, n=1) -> float: if theta <= 0: raise ParameterOutOfBounds(f"theta = {theta} must be > 0") rho_delta = rho_single * delta_time return 1 + rho_delta / (sigma_single + rho_delta) * ( exp(theta * n * (sigma_single + rho_delta)) - 1)
def get_q(p: float) -> float: """ :param p: Hoelder p :return: q """ if p <= 1.0: raise ParameterOutOfBounds(f"p={p} must be >1") # 1/p + 1/q = 1 # 1/q = (p - 1) / p return p / (p - 1.0)