% Construction d'un réseau de neurones

% Les entrées et cibles
nb_val=0.2*size(entree_1,2);
nb_val=floor(nb_val);
nb_test=0.1*size(entree_1,2);
nb_test=floor(nb_test);

entree=entree_1(:,1:end-nb_val-nb_test);
entree_2=entree_comp(:,1:end-nb_val-nb_test);
% entree=[entree;entree_2];
cible=sortie(1:end-nb_val-nb_test);
entree_seq=con2seq(entree);
entree_2_seq=con2seq(entree_2);
entree_seq=[entree_seq;entree_2_seq];
cible_seq=con2seq(cible);

% Les entrées validation
entree_v=entree_1(:,end-nb_val-nb_test-1:end-nb_test);
entree_2_v=entree_comp(:,end-nb_val-nb_test-1:end-nb_test);
% entree_v=[entree_v;entree_2_v];
cible_v=sortie(end-nb_val-nb_test-1:end-nb_test);
entree_seq_v=con2seq(entree_v);
entree_2_seq_v=con2seq(entree_2_v);
val.P=[entree_seq_v;entree_2_seq_v];
val.T=con2seq(cible_v);

% Les entrées tests
entree_t=entree_1(:,end-nb_test-1:end);
entree_2_t=entree_comp(:,end-nb_test-1:end);
% entree_t=[entree_t;entree_2_t];
cible_t=sortie(end-nb_test-1:end);
entree_seq_t=con2seq(entree_t);
entree_2_seq_t=con2seq(entree_2_t);
entree_seq_t=[entree_seq_t;entree_2_seq_t];
cible_seq_t=con2seq(cible_t);

% Ouverture d'un réseau vierge et idenfication
mynet=network;

% Nombre de vecteurs d'entrée et nombre de couches totales
mynet.numInputs = 2;
mynet.numLayers = 2;

% Connexions de biais pour chaque couche et initialisation
mynet.biasConnect = [1; 1];% ; 1; 1; 1
mynet.biases{1}.initFcn='rands';
mynet.biases{2}.initFcn='rands';
mynet.biases{1}.learnFcn='learngdm';
mynet.biases{2}.learnFcn='learngdm';

% Connexions des couches aux vecteurs d'entrée et initialisation
mynet.inputConnect = [1 1;0 0]; %1 1;0 0; 0 0;
mynet.inputWeights{1,1}.initFcn='rands';
mynet.inputWeights{1,2}.initFcn='rands';
mynet.inputWeights{1,1}.learnFcn='learngdm';
mynet.inputWeights{1,2}.learnFcn='learngdm';

% Connexions des couches entre elles et initialisation
mynet.layerConnect = [0 0;1 0];% [0 0 0 0 0; 0 0 0 0 0;1 1 0 0 0; 1 1 0 0 0;0 0 1 1 0];
mynet.layerWeights{2,1}.initFcn='rands';
mynet.layerWeights{2,1}.learnFcn='learngdm';

% Connexions des couches à la sortie du réseau et au vecteur cible
mynet.outputConnect = [0 1];%0 0 0
mynet.targetConnect = [0 1];% 0 0 0

% Définition des entreés
% Intervalle de variation au cours du temps de chaque composante du vecteur d'entrée
% entree=mapminmax(entree);
inter=zeros(size(entree,1),2);
for i=1:size(entree,1)
    inter(i,:)=[min(entree(i,:)) max(entree(i,:))];
end;
mynet.inputs{1}.range = inter;

inter_2=zeros(size(entree_2,1),2);
for i=1:size(entree_2,1)
    inter_2(i,:)=[min(entree_2(i,:)) max(entree_2(i,:))];
end;
mynet.inputs{2}.range = inter_2;

% Définition des couches
% Nombre de neurones, fonction de transfert, initialisation
% mynet.layers{1}.size=25;
mynet.layers{1}.transferFcn='logsig';
mynet.layers{1}.initFcn = 'initwb';

% mynet.layers{2}.size=15;
% mynet.layers{2}.transferFcn='logsig';
mynet.layers{2}.initFcn = 'initwb';

% mynet.layers{3}.size=5;
% mynet.layers{3}.transferFcn='logsig';
% mynet.layers{3}.initFcn = 'initnw';
%
% mynet.layers{4}.size=5;
% mynet.layers{4}.transferFcn='logsig';
% mynet.layers{4}.initFcn = 'initnw';
%
% mynet.layers{5}.transferFcn='logsig';
% mynet.layers{5}.initFcn = 'initnw';

% récurrence des entrées et des couches
% mynet.inputweights{1,1}.delays=0:2;

% mynet.inputweights{1,2}.delays=0:1;

% mynet.layerweights{1,1}.delays=1;
% mynet.layerweights{2,9}.delays=1;
% mynet.layerweights{3,9}.delays=1;
% mynet.layerweights{4,9}.delays=1;

% Paramètres du réseau
% Algo d'initialisation, fonction de performance et algo d'apprentissage
mynet.initFcn = 'initlay';
% mynet.performFcn = 'msereg';
% mynet.trainFcn = 'trainlm';
%
% % Paramètres de l'algo d'apprentissage
% mynet.trainParam.goal=1e-4;
% mynet.trainParam.epochs=10000;
% mynet.trainParam.show=NaN;

% Optimisation du réseau
nbn=3:1:7;%10:2:30
perform= [1 2 3 4 5];%[1 2 3 4 5]
fcn=5;%5:1:8 [1 2 3 4 5 8 9 11]
lr=[1e-6 5e-6 1e-5 5e-5 1e-4];%[1e-6 5e-6 1e-5 5e-5 1e-4];
mc=[1e-8 5e-8 1e-7 5e-7 1e-6];%[1e-8 5e-8 1e-7 5e-7 1e-6];

direc=zeros(size(nbn,2),size(fcn,2),size(perform,2));
direc_pred=zeros(size(nbn,2),size(fcn,2),size(perform,2));
direc_unit=zeros(size(nbn,2),size(fcn,2),size(perform,2));
direc_t=zeros(size(nbn,2),size(fcn,2),size(perform,2));
direc_pred_t=zeros(size(nbn,2),size(fcn,2),size(perform,2));
direc_unit_t=zeros(size(nbn,2),size(fcn,2),size(perform,2));

for i=1:size(nbn,2)
    for j=1:size(fcn,2)
        for k=1:size(perform,2)
            for l=1:size(lr,2)
                for m=1:size(mc,2)

                    mynet.layers{1}.size=nbn(i);

                    if fcn(j)==1
                        mynet.trainFcn = 'trainbr';
                    elseif fcn(j)==2
                        mynet.trainFcn = 'trainbfg';
                    elseif fcn(j)==3
                        mynet.trainFcn = 'trainscg';
                    elseif fcn(j)==4
                        mynet.trainFcn = 'traingd';
                    elseif fcn(j)==5
                        mynet.trainFcn = 'trainlm';
                    elseif fcn(j)==6
                        mynet.trainFcn = 'traingda';
                    elseif fcn(j)==7
                        mynet.trainFcn = 'traingdm';
                    elseif fcn(j)==8
                        mynet.trainFcn = 'traingdx';
                    elseif fcn(j)==9
                        mynet.trainFcn = 'trainrp';
                    elseif fcn(j)==10
                        mynet.trainFcn = 'trainr';
                    elseif fcn(j)==11
                        mynet.adaptFcn = 'trains';
                    end;
                    
                    % Paramètres de l'algo d'apprentissage
                    if fcn(j)==7 
                        mynet.trainParam.goal=1e-8;
                        mynet.trainParam.epochs=2000;
                        mynet.trainParam.show=NaN;
                        mynet.trainParam.lr=lr(l);
                        mynet.trainParam.mc=mc(m);   
                    elseif fcn(j)==3 
                        mynet.trainParam.goal=1e-8;
                        mynet.trainParam.epochs=20000;
                        mynet.trainParam.show=NaN;
                        mynet.trainParam.sigma=lr(l);
                        mynet.trainParam.lambda=mc(m); 
                    elseif fcn(j)==11
                        mynet.adaptParam.passes=20000;
%                         mynet.adaptParam.goal=1e-8;
%                         mynet.adaptParam.epochs=10000;
%                         mynet.adaptParam.show=NaN;
                    else
                        mynet.trainParam.goal=1e-8;
                        mynet.trainParam.epochs=2000;
                        mynet.trainParam.show=NaN;                        
                    end;

                    if perform(k)==1
                        mynet.performFcn = 'mae';
                    elseif perform(k)==2
                        mynet.performFcn = 'mse';
                    elseif perform(k)==3
                        mynet.performFcn = 'msereg';
                    elseif perform(k)==4
                        mynet.performFcn = 'mseregec';
                    elseif perform(k)==5
                        mynet.performFcn = 'sse';
                    end;
                    
                    if fcn(j)==11
                        mynet.biases{1}.learnParam.lr=lr(l);
                        mynet.biases{2}.learnParam.lr=lr(l);
                        mynet.inputWeights{1,1}.learnParam.lr=lr(l);
                        mynet.inputWeights{1,2}.learnParam.lr=lr(l);
                        mynet.layerWeights{2,1}.learnParam.lr=lr(l);

                        mynet.biases{1}.learnParam.mc=mc(m);
                        mynet.biases{2}.learnParam.mc=mc(m);
                        mynet.inputWeights{1,1}.learnParam.mc=mc(m);
                        mynet.inputWeights{1,2}.learnParam.mc=mc(m);
                        mynet.layerWeights{2,1}.learnParam.mc=mc(m);
                    end;
                    % Initialisation
                    mynet = init(mynet);

                    % Entrainement
                    if fcn(j)~=11
                        mynet = train(mynet,entree_seq,cible_seq);%,[],[],val
                    else
                        mynet = adapt(mynet,entree_seq,cible_seq);
                    end;
                    n_out=sim(mynet,entree_seq);
                    n_out=cell2mat(n_out);
                    diff=sign(n_out)-sign(cible);
                    signe=1-nnz(diff)/(size(diff,2));
                    diff2=sign(n_out(2:end)-cible(1:end-1))-sign(cible(2:end)-cible(1:end-1));
                    direc(i,j,k,l,m)=1-nnz(diff2)/(size(diff2,2));
                    diff3=sign(n_out(2:end)-n_out(1:end-1))-sign(cible(2:end)-cible(1:end-1));
                    direc_pred(i,j,k,l,m)=1-nnz(diff3)/(size(diff3,2));
                    diff4=n_out-cible;
                    for ii=1:size(diff4,2)
                        if abs(diff4(ii))<0.4
                            diff4(ii)=0;
                        end;
                    end;
                    direc_unit(i,j,k,l,m)=1-nnz(diff4)/(size(diff4,2));

                    % Test
                    n_out_t=sim(mynet,entree_seq_t);
                    n_out_t=cell2mat(n_out_t);
                    diff_t=sign(n_out_t)-sign(cible_t);
                    signe_t=1-nnz(diff_t)/(size(diff_t,2));
                    diff2_t=sign(n_out_t(2:end)-cible_t(1:end-1))-sign(cible_t(2:end)-cible_t(1:end-1));
                    direc_t(i,j,k,l,m)=1-nnz(diff2_t)/(size(diff2_t,2));
                    diff3_t=sign(n_out_t(2:end)-n_out_t(1:end-1))-sign(cible_t(2:end)-cible_t(1:end-1));
                    direc_pred_t(i,j,k,l,m)=1-nnz(diff3_t)/(size(diff3_t,2));
                    diff4_t=n_out_t-cible_t;
                    for ii=1:size(diff4_t,2)
                        if abs(diff4_t(ii))<0.4
                            diff4_t(ii)=0;
                        end;
                    end;
                    direc_unit_t(i,j,k,l,m)=1-nnz(diff4_t)/(size(diff4_t,2));
                    save('essai_1');
                end;
            end;
        end;
    end;
end;

hold off;
plot([n_out n_out_t]);
hold on;
plot([cible cible_t],'r');



