Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ЛР / ЛР2 / SM_LR2

.py
Скачиваний:
3
Добавлен:
25.06.2023
Размер:
5.44 Кб
Скачать
from matplotlib import pyplot as plt
import numpy as np



def ploting_normal_distribution(mu, sigma, intervals = [], weights = []):
    '''Построение графика нормального распрелеоения'''
    if len(intervals) != 0 and len(weights) != 0:
        plt.hist(intervals[:-1], intervals, weights = weights)
    f = lambda x : 1 / (sigma * np.sqrt(2*np.pi)) * np.exp(-(x-mu)**2/(2*sigma**2))
    x = np.linspace(mu-4*sigma, mu+4*sigma, 100) #Генерируем список из кол. элементов
    plt.plot(x, f(x), label='f(x)=1/(sigma*np.sqrt(2*np.pi))*\nnp.exp(-(x-mu)**2/(2*sigma**2)\n mu={} sigma={}'.format(mu, sigma), color='red')
    plt.title("График нормального распределения")
    plt.xlabel("x")
    plt.ylabel("y")
    plt.legend()
    plt.show()


def ploting_ME_Disp(matexp, mu, disp, sigma, N_array):
    fig, axis = plt.subplots(1, 2, figsize=(10, 5))
    fig.suptitle('Статистика')
    #Рисуем график МО
    axis[0].plot(N_array, [mu for i in range(0, len(N_array))], color='red', label='Теоретическое значение')
    axis[0].plot(N_array, matexp, label='Рассчитанное значение')
    axis[0].set_title('Мат ожидание')
    axis[0].set_xlabel('Размер выборки')
    axis[0].legend()
    # Рисуем график дисперсии
    sigma **=2
    axis[1].plot(N_array, [sigma for i in range(0, len(N_array))], color='red', label='Теоретическое значение')
    axis[1].plot(N_array, disp, label='Рассчитанное значение')
    axis[1].set_title('Дисперсия')
    axis[1].set_xlabel('Размер выборки')
    axis[1].legend()
    plt.show()


def norm_random(mu, sigma, N):
    '''Функция создающая случайные числа для нормального распределения'''
    alpha = [] # Список сгенерированных чисел
    for i in range(0, N//2+1):
        R1 = np.random.uniform(0,1) # Случайная величина R[i]
        R2 = np.random.uniform(0,1) # Случайная величина R[i+1]
        alpha.append(mu + sigma * np.sqrt(-2*np.log(R1)) * np.sin(2*np.pi*R2))
        alpha.append(mu + sigma * np.sqrt(-2*np.log(R1)) * np.cos(2*np.pi*R2))
    return alpha[:N]


def slicearray(array, intervals_cnt):
    '''Функция для разбивки списка на интервалы и подсчета кол. попаданий'''
    interval=[] #список интервалов
    entries = [] #список кол. попаданий
    x_min, x_max = min(array), max(array)
    delta = (x_max - x_min) / intervals_cnt
    #заполняем список интервалов
    for x in range (intervals_cnt+1):
        interval.append(x_min + delta * x)
    for i in range(intervals_cnt):
        entries.append(sum(True for x in array if interval[i] < x <= interval[i+1]))
    return interval, entries, x_min, x_max, delta


def plotiong_norm_hist(mu, sigma, intervals_cnt = 10, step = 1, minNi=100):
    '''Создание набора данных выборки для построения графика'''
    A = []                      # Массив выборки - пустой
    x_max, x_min = 0, 0         # Верхняя и нижняя границы
    delta = 0                   # Длительность интервалов
    N = 0                       # Кол-во элементов выборки
    intervals = [x_min, x_max]  # Интервалы
    Ni = [0]                    # Элементов попалов интервал
    matexp, disp = [], []       # Список МО и Дисперсии при разных N
    N_array = []                # Список N для которых расчитаны МО и Дисперсии

    while True:
        N += step
        A_new = norm_random(mu, sigma, step)
        A.extend(A_new)

        for i in range(len(intervals) - 1): # Добавление новых элементов в соответствующии им интервалы
            Ni[i] += sum(True for x in A_new if intervals[i] < x <= intervals[i+1])

        if (N - sum(Ni)) / N > 0.01:    # Проверка процента чисел выходящих за пределы текущих интервалов
            intervals, Ni, x_min, x_max, delta = slicearray(A, intervals_cnt)

        #Считаем МО и Дисперсию
        matexp.append(np.mean(A))
        disp.append(np.var(A))
        N_array.append(N)
        # print(N, Ni, np.mean(A), np.var(A)) # Тестовый вывод
        
        if min(Ni) >= minNi: break    # Проверка что все интервалы содержат минимум minNi элементов
    print(N, Ni, intervals, sep='\n')

    Y = [cnt / (N * delta) for cnt in Ni]
    ploting_normal_distribution(mu, sigma, intervals, Y)
    return matexp, disp, N_array
    

def main():
    mu, sigma = -1, 5
    ploting_normal_distribution(mu, sigma)
    matexp, disp, mat = plotiong_norm_hist(mu, sigma, intervals_cnt = 10, step = 100, minNi = 100)
    ploting_ME_Disp(matexp, mu, disp, sigma, mat)
    return 0

if __name__ == "__main__":
	main()
Соседние файлы в папке ЛР2