Добавил:
Периодически делаю учебные работы по предметам ЛЭТИ и выгружаю их сюда для пополнения базы, с которой можно будет свериться. Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
0
Добавлен:
11.01.2026
Размер:
5.46 Кб
Скачать
import random
import math
import matplotlib.pyplot as plt
import numpy as np
import time


class MyRandom:
    def __init__(self, r, K, A, c, m):
        self.r = r
        self.K = K
        self.A = A
        self.c = c
        self.m = m
        if (len(K) != r or len(A) != r):
            raise Exception

    def next(self):
        x = sum([self.K[i] * self.A[i] for i in range(self.r)]) % self.m
        self.A.pop(0)
        self.A.append(x)

        return x / self.m


def gamma_variate(k):  # Г(k, 1)
    if k <= 0:
        raise ValueError("k must be > 0")

    if k < 1.0:
        u = rand.next()
        return gamma_variate(k + 1.0) * (u ** (1.0 / k))

    d = k - 1.0 / 3.0
    c = 1.0 / math.sqrt(9.0 * d)

    while True:
        u1 = rand.next()
        u2 = rand.next()
        z = math.sqrt(-2.0 * math.log(u1)) * math.cos(2.0 * math.pi * u2)

        v = 1.0 + c * z
        if v <= 0:
            continue
        v = v ** 3

        u = rand.next()
        if u < 1.0 - 0.0331 * (z ** 4):
            return d * v
        if math.log(u) < 0.5 * z * z + d * (1.0 - v + math.log(v)):
            return d * v


def beta_variate(alpha, beta):
    if alpha <= 0.0 or beta <= 0.0:
        raise ValueError("alpha, beta must be > 0")

    x = gamma_variate(alpha)
    y = gamma_variate(beta)
    return x / (x + y)


N = 10000
X = []

random.seed(time.time())
r = 8
K = [random.randint(0, 2000) for _ in range(r)]
A = [random.randint(0, 2**16) for _ in range(r)]
rand = MyRandom(r, K, A, 946785, 2**32)

# Exponential
print("Exponential")
lambda_exp = 0.5
X.clear()
for i in range(N):
    z = rand.next()
    X.append(-1 / lambda_exp * math.log(z))

M_expected = 1 / lambda_exp
D_expected = 1 / (lambda_exp ** 2)
M = sum(X) / N
D = sum([x ** 2 for x in X]) / N - M ** 2
M_delta = abs((M - M_expected) / M_expected) * 100
D_delta = abs((D - D_expected) / D_expected) * 100
print(f"Эмпирические: {M = :.3f}, {D = :.3f}")
print(f"Теоретические: M = {M_expected:.3f}, D = {D_expected:.3f}")
print(f"Относительные погрешности: δM = {M_delta:.2f} %, δD = {D_delta:.2f} %")

plt.hist(X, bins=30, weights=np.ones_like(X) / len(X))
plt.savefig("ms3.exponential.svg")
plt.show()


# Uniform
print("\nUniform")

A_uni = -4
B_uni = 10
X.clear()
for i in range(N):
    z = rand.next()
    X.append(A_uni + (B_uni - A_uni) * z)

M_expected = A_uni + (B_uni - A_uni) / 2
D_expected = (B_uni - A_uni) ** 2 / 12
M = sum(X) / N
D = sum([x ** 2 for x in X]) / N - M ** 2
M_delta = abs((M - M_expected) / M_expected) * 100
D_delta = abs((D - D_expected) / D_expected) * 100
print(f"Эмпирические: {M = :.3f}, {D = :.3f}")
print(f"Теоретические: M = {M_expected:.3f}, D = {D_expected:.3f}")
print(f"Относительные погрешности: δM = {M_delta:.2f} %, δD = {D_delta:.2f} %")

plt.hist(X, bins=B_uni*8, weights=np.ones_like(X) / len(X))
plt.savefig("ms3.uniform.svg")
plt.show()


# Erlang
print("\nErlang")

k_erl = 6
lambda_erl = 0.5
X.clear()
for i in range(N):
    X.append(-1 / lambda_erl * math.log(math.prod(rand.next()
                                                  for j in range(k_erl))))

M_expected = k_erl / lambda_erl
D_expected = k_erl / (lambda_erl ** 2)
M = sum(X) / N
D = sum([x ** 2 for x in X]) / N - M ** 2
M_delta = abs((M - M_expected) / M_expected) * 100
D_delta = abs((D - D_expected) / D_expected) * 100
print(f"Эмпирические: {M = :.3f}, {D = :.3f}")
print(f"Теоретические: M = {M_expected:.3f}, D = {D_expected:.3f}")
print(f"Относительные погрешности: δM = {M_delta:.2f} %, δD = {D_delta:.2f} %")

plt.hist(X, bins=30, weights=np.ones_like(X) / len(X))
plt.savefig("ms3.erlang.svg")
plt.show()


# Standard Normal
print("\nStandard Normal")

X.clear()
for i in range(N // 2):
    z1 = rand.next()
    z2 = rand.next()
    X.append(math.sqrt(-2 * math.log(z1)) * math.cos(2 * math.pi * z2))
    X.append(math.sqrt(-2 * math.log(z1)) * math.sin(2 * math.pi * z2))

M_expected = 0
D_expected = 1
M = sum(X) / N
D = sum([x ** 2 for x in X]) / N - M ** 2
D_delta = abs((D - D_expected) / D_expected) * 100
print(f"Эмпирические: {M = :.3f}, {D = :.3f}")
print(f"Теоретические: M = {M_expected:.3f}, D = {D_expected:.3f}")
print(f"Относительные погрешности: δD = {D_delta:.2f} %")

plt.hist(X, bins=40, weights=np.ones_like(X) / len(X))
plt.subplots_adjust(top=0.99, bottom=0.08, left=0.08, right=0.92)
plt.savefig("ms3.normal.svg")
plt.show()


# Beta
print("\nBeta")
alpha = 0.5
beta = 0.5
X = [beta_variate(alpha, beta) for _ in range(N)]


M_expected = alpha / (alpha + beta)
D_expected = (alpha * beta) / ((alpha + beta) ** 2 * (alpha + beta + 1))
M = sum(X) / N
D = sum([x ** 2 for x in X]) / N - M ** 2
M_delta = abs((M - M_expected) / M_expected) * 100
D_delta = abs((D - D_expected) / D_expected) * 100
print(f"Эмпирические: {M = :.3f}, {D = :.3f}")
print(f"Теоретические: M = {M_expected:.3f}, D = {D_expected:.3f}")
print(f"Относительные погрешности: δM = {M_delta:.2f} %, δD = {D_delta:.2f} %")

plt.hist(X, bins=40, weights=np.ones_like(X) / len(X))
plt.savefig("ms3.Beta.svg")
plt.show()
Соседние файлы в папке Вариант_Бета-распределение