echo on
clear
%    Informações sobre o arquivo de entrada
methodsNo    = 2;     % Número de métodos
propNo       = 7;     % Número de propriedades
errorRatesNo = 2;     % Número de taxas de erro
patternsNo   = 438;   % Número de padrões
columnsNo = propNo + errorRatesNo * methodsNo;

%   Melhores configurações para as 8 saídas
lr = fopen('taxApr.txt');
learnRate = fscanf(lr,'%f', [1, 84])';

qn = fopen('qntdNeur.txt');
qntHidNeur = fscanf(qn,'%d', [1, 84])';

la = fopen('algApr.txt');
learnAlg = textscan(la,'%s');

echo off

inputFile = fopen('beagle_hmc.txt');
data = fscanf(inputFile,'%f',[columnsNo, patternsNo]);

% %   Normalização
% for i = 1 : columnsNo
%     maxValue = max(data(i,:));
%     minValue = min(data(i,:));
%     for j = 1: patternsNo
%         data(i, j) = (data(i, j) - minValue)/(maxValue - minValue);
%     end
% end

trainValidPatternsNo = 438 - 86;
trainingPatternsNo = ceil(trainValidPatternsNo * 2/3);
validationPatternsNo = floor(trainValidPatternsNo * 1/3);
testPatternsNo = 86;

inputNo = 2;
outputNo = 1;
totalNo = 3;

resultado = fopen('Resultado.txt','w+t');
result = zeros (testPatternsNo*120,8);
count = 1;

str2(:,1) = cellstr(learnAlg{1});

%

%   Montagem dos conjuntos de dados de treinamento e de teste
for fold = 1:120
    
    fileName = strcat('ids_teste_individuo_fold_', int2str(fold), '.txt');
    
    fprintf('%s', fileName);
    
    file = fopen(fileName);
    fileData = fscanf(file,'%d',[1, 86]);
    
    testPatterns = data(:, fileData);
    trainValidPatterns = data;
    trainValidPatterns(:, fileData) = [];
    
    c = 0;
    g = 1;
    
    for ia = 1 : propNo - 1
        for ib = (ia + 1) : propNo
			for o = 1: errorRatesNo * methodsNo
                trainValidPat = [trainValidPatterns(ia, :); trainValidPatterns(ib, :); trainValidPatterns(o + propNo, :)];
				testPat = [testPatterns(ia, :); testPatterns(ib, :); testPatterns(o + propNo, :)];

				trainingPatterns = trainValidPat(1:totalNo, 1:trainingPatternsNo);
				trainingInputs = trainingPatterns(1:inputNo, 1:trainingPatternsNo);
				trainingOutputs = trainingPatterns((inputNo + 1):totalNo, 1:trainingPatternsNo);

				validationPatterns = trainValidPat(1:totalNo, (trainingPatternsNo + 1):(trainingPatternsNo + validationPatternsNo));
				validationInputs = validationPatterns(1:inputNo, 1:validationPatternsNo);
				validationOutputs = validationPatterns((inputNo + 1):totalNo, 1:validationPatternsNo);

				testInputs = testPat(1:inputNo, 1:testPatternsNo);
				testOutputs = testPat((inputNo + 1):totalNo, 1:testPatternsNo);

				la = char(str2(g));

				network = newff(trainingInputs,trainingOutputs, qntHidNeur(g),{'tansig','tansig'},la,'learngd','mse');
				% intervalMatrix                   : indica que todas as entradas possuem valores na faixa entre 0 e 1
				% [qhn errorRatesNo*methodsNo]     : indica a quantidade de nodos escondidos e de saida da rede
				% {af,af}                          : indica que os nodos das camadas escondida e de saida terao determinada funcao de ativação 
				% la,'learngd'                     : indica que o treinamento vai ser feito com gradiente descendente (backpropagation)
				% 'mse'                            : indica que o erro a ser utilizado vai ser MSE (média dos erros quadraticos)

				% Inicializa os pesos da rede criada
				network = init(network);

				%   Parametros do treinamento
				rede.trainParam.epochs   = 1000;                % Maximo numero de iteracoes
				rede.trainParam.lr       = learnRate(g);     % Taxa de aprendizado
				rede.trainParam.goal     = 0;                   % Criterio de minimo erro de treinamento
				rede.trainParam.max_fail = 5;                   % Criterio de quantidade maxima de falhas na validacao
				rede.trainParam.min_grad = 0;                   % Criterio de gradiente minimo
				rede.trainParam.show     = NaN;                 % Iteracoes entre exibicoes na tela (preenchendo com 'NaN', nao exibe na tela)
				rede.trainParam.time     = inf;                 % Tempo maximo (em segundos) para o treinamento

				validationSet.P = validationInputs;          % Entradas da validacao
				validationSet.T = validationOutputs;   % Saídas desejadas da validacao

				%   Treinando a rede
				[newNetwork,performance,outputs,errors] = train(network,trainingInputs,trainingOutputs,[],[],validationSet);
				% newNetwork   : rede apos treinamento
				% performance  : apresenta os seguintes resultados
				%              desempenho.perf  - vetor com os erros de treinamento de todas as iteracoes 
				%              desempenho.vperf - vetor com os erros de validacao de todas as iteracoes 
				%              desempenho.epoch - vetor com as iteracoes efetuadas
				% outputs      : matriz contendo as saidas da rede para cada padrao de treinamento
				% errors       : matriz contendo os erros para cada padrao de treinamento

				%    Testando a rede
				[testOutput,Pf,Af,testErrors,testPerformance] = sim(newNetwork,testInputs,[],[],testOutputs);
				% testOutputs     : matriz contendo as saidas da rede para cada padrao de teste
				% Pf,Af           : matrizes utilizadas apenas quando se usam delays)
				% testErrors      : matriz contendo os erros para cada padrao de teste
				% testPerformance : erro de teste (neste exemplo,
				% escolheu-se erro MSE)

				result(count:(testPatternsNo*fold), c+o) = testOutput;
            end
            c = c + 4;
            g = g + 1;
        end
    end
    count = count + testPatternsNo;
end

%Imprimindo resultado
for i = 1 : testPatternsNo*120
    fprintf(resultado, '%3.9f ', result(i, :));
    fprintf(resultado, '\n');
end
fclose(resultado);
    
