# -*- coding: utf-8 -*-
'''
Модуль с функцией получения нейросетевой модели БФ
'''
from Tools import *
from DataIO import *
from Calculation import *
from Graphic import *

def kind_AF(W, F, outputFile, kind):
    '''
    Функция позволяет получить нейросетевую модель БФ, используя пороговую или логистическую ФА
    :param W: начальные весовые коэффициенты
    :param F: знаечния БФ
    :param outputFile: имя файла выхода
    :param kind: вид ФА: threshold - пороговая, logistics - логистическая
    :param return: none
    '''
    X = bin_generation(4) # генерируем вектора для 4-х переменных
    nu = 0.3 # норма обучения
    E = 1 # необходимо для начала цикла прохода по эпохам
    k = -1 # необходимо для начала отсчёта эпох

    arrayE = list() # список всех суммарнах квадратичных ошибок
    arrayK = list() # список всех эпох
    Y = list() # вектор для хранения полученного реального выхода текущей эпохи

    file = open(outputFile, 'w') # открываем файла для записи выходных данных

    # осуществляется смена эпох, пока не будет достигнула нулевая ошибка
    while E != 0:
        # увеличиваем количество эпох +1
        k += 1

        # запоминаем последние полученные весовые коэффициенты на случай получения нулевой ошибки
        prev_W = list(W)

        # проверим, достигается ли нулевая ошибка на последних найденных весовых коэффициентах
        for (x, f) in zip(X, F):
            # 1) считаем net
            n = net(W, x)

            # 2) считаем реальный выход
            y = actual_NN(n)
            Y.append(y)

            # 3) считаем ошибку дельта
            d = delta(f, y)

        # 5) посчитаем суммарную квадратичную ошибку
        E = totalError(Y, F)

        # запишем полученные данные в файл
        write_Data(file, k, Y, prev_W, E)

        Y = list() # очистим вектор от полученных данных

        # в случае, если ошибка не свелась к 0 выполним перерасчёт весовых коэффициентов
        if E != 0:

            for (x,f) in zip(X, F):

                # 1) считаем net
                n = net(W, x)

                # 2) считаем реальный выход
                y = actual_NN(n)

                # 3) считаем ошибку дельта
                d = delta(f, y)

                # 4) пересчитываем W
                W = recount_W(W, x, d, n, nu, kind)

        # добавим номер рассчитанной эпохи и найденную для неё среднеквадратичную ошибку
        arrayK.append(k)
        arrayE.append(E)

    # построим график зависимости среднеквадратичной ошибки от эпохи
    drawGraph(arrayE, arrayK, outputFile)
