clear all; clc; close all;
tic
%% vstupni obrazy pro optimalizaci
% vstupni obraz

   obr1 = rgb2gray(imread('oko.jpg'));
   load('oko.mat')

% obr2 = rgb2gray(obr2);
%    obr2= rgb2gray(imread('obraz1.jpg'));

   cil = obr2;


ub = [10 10];
lb = [-10 -10];


%% hledani 1.lok. minima



alfa = 1;
beta = 0.5;
simplex = [0 0;1 0; 0 1]; %počáteční hodnota

 ub = [10 10];
 lb = [-10 -10];     % nastaneni hranice


vzdalenost = 10;


while vzdalenost > 0.1;
    scatter(simplex(:,1),simplex(:,2));
%     pause();
     disp('.')
     
    for i = 1:3
        hodnota(i) = TransPodobn(obr1, cil,simplex(i,:));
    end
disp('..')
    [maxhod nejhorsi] = max(hodnota);   % najdi nejhorsi bod
    [minhod nejlepsi] = min(hodnota);   % najdi nejlepsi bod

    simplexz = simplex;
    simplexz(nejhorsi, :) = []; % smaz prislusny radek s nejhorsi bodem

    c = (simplexz(1,:)+simplexz(2,:))./2; % poloha teziste
disp('...')
    xt = c + (alfa.*(c-simplex(nejhorsi,:))); % transformuj nejhorsi bod

    hodnotaxt = TransPodobn(obr1, cil,xt); % zjisti hodnotu v trasnformovanem bodu

    porovnani =  hodnotaxt < hodnota; % hodnoty porovnej
disp('....')
    kontrakce = 0;

    if porovnani(nejhorsi) == 0; % jestli novy bod nema mensi hodnotu nez puvodne
        xt = c + (beta.*(simplex(nejhorsi,:) - c));  % tak bod kontrahuj
        hodnotaxt = TransPodobn(obr1, cil,xt);
        if xt > hodnotaxt       % pokud je kontrahovany bod stale vetsi nez puvodni
            nejbod = simplex(nejlepsi, :);  % najdi nejlepsi bod
            simplexy = simplex;
            simplexy(nejlepsi,:) = [];
            
            for i = 1:2; % a k nemu kontrahuj zbyvajici body
                xt(i,:) = nejbod + beta.*(simplexy(i,:)-nejbod);
            end
        disp('.....')
            simplex = [nejbod; xt]; % sloz novy simplex
            kontrakce = 1;
        end
    end

    if kontrakce == 0; % pokud v kontrakci nebyl setaveny novy simplex
        simplex(nejhorsi,:) = xt;   % tak ho sestav
    end
    disp('......')
    vzdalenost = sqrt(((simplex(1,1))-(simplex(2,1)))^2+((simplex(1,2)-(simplex(2,2))))^2);
    vzdalenost = vzdalenost + sqrt(((simplex(1,1))-(simplex(3,1)))^2+((simplex(1,2)-(simplex(3,2))))^2);
%     disp('.')
end


% aa=TransPodobn(obr1, cil,([simplex(1) simplex(2)]));
% bb=TransPodobn(obr1, cil,([simplex(3) simplex(4)]));
% cc=TransPodobn(obr1, cil,([simplex(5) simplex(6)]));
% ccc=[aa bb cc];
% 
% 
% 
%   pozice = find(ccc==min(ccc));
% 
%   if pozice == 1;
%       lok_min = [simplex(1) simplex(2)];
%   elseif pozice == 2;
%       lok_min = [simplex(3) simplex(4)];
%   elseif pozice == 3
%       lok_min = [simplex(5) simplex(6)];
%   end

 


   lok_min = mean(simplex);   %vypocet lok_min z prumeru
   
   disp('nalezeno prvni lok.min.')



%% Hledání lok. min na virt. fci a pak na puvodni fci



tunel = 0;
while tunel <= 3
    
alfa = 1;
beta = 0.5;

disp('nacteny nove hodnoty')
simplex = [lok_min; (lok_min + [0.5 0]); (lok_min + [0 0.5])]; %počáteční hodnota na virt. fci




vzdalenost = 10;


while vzdalenost > 0.1;
    scatter(simplex(:,1),simplex(:,2));
%     pause();
       disp('a') 
    for j = 1:3
        hodnota(j) = VirtualniFce(obr1, cil, lok_min, simplex(j,:));
    end
disp('b')
    [maxhod nejhorsi] = max(hodnota);   % najdi nejhorsi bod
    [minhod nejlepsi] = min(hodnota);   % najdi nejlepsi bod
disp('c')
    simplexz = simplex;
    simplexz(nejhorsi, :) = []; % smaz prislusny radek s nejhorsi bodem
disp('d')
    c = (simplexz(1,:)+simplexz(2,:))./2; % poloha teziste

    xt = c + (alfa.*(c-simplex(nejhorsi,:))); % transformuj nejhorsi bod
disp('e')
    hodnotaxt = VirtualniFce(obr1,cil,lok_min,xt); % zjisti hodnotu v trasnformovanem bodu
disp('f')
    porovnani =  hodnotaxt < hodnota; % hodnoty porovnej

    kontrakce = 0;
disp('g')
    if porovnani(nejhorsi) == 0; % jestli novy bod nema mensi hodnotu nez puvodne
        xt = c + (beta.*(simplex(nejhorsi,:) - c));  % tak bod kontrahuj
        disp('h')
        hodnotaxt = VirtualniFce(obr1, cil, lok_min,xt);
        if xt > hodnotaxt       % pokud je kontrahovany bod stale vetsi nez puvodni
            nejbod = simplex(nejlepsi, :);  % najdi nejlepsi bod
            simplexy = simplex;
            simplexy(nejlepsi,:) = [];
            disp('i')
            for k = 1:2; % a k nemu kontrahuj zbyvajici body
                xt(k,:) = nejbod + beta.*(simplexy(k,:)-nejbod);
            end
        disp('j')
            simplex = [nejbod; xt]; % sloz novy simplex
            kontrakce = 1;
        end
    end
disp('k')
    if kontrakce == 0; % pokud v kontrakci nebyl setaveny novy simplex
        simplex(nejhorsi,:) = xt;   % tak ho sestav
   
    
%nesmi prekrocit prostor, jinak konec

        if simplex(1) > ub(1) || simplex(2) > ub(2) ||...        
            simplex(1) < lb(1) || simplex(2) < lb(2)||...
          simplex(3) > ub(1) || simplex(4) > ub(2) ||...
            simplex(3) < lb(1) || simplex(4) < lb(2)||...  
        simplex(5) > ub(1) || simplex(6) > ub(2) ||...
            simplex(5) < lb(1) || simplex(6) < lb(2);
            
        tunel = 4;
        gl_min = lok_min;               % posledni anlezene lok_min je gl_min
        end
        while tunel > 3
            
             fval = TransPodobn(obr1, cil,lok_min);    % vypocet funkcni hodnoty v lok_min
             fprintf('globalni minimum je: %f\n',fval);            
             fprintf('parametry globalniho minima jsou: %d\n',lok_min);

toc

            return
        end             
    end
    
    
    disp('l')
    vzdalenost = sqrt(((simplex(1,1))-(simplex(2,1)))^2+((simplex(1,2)-(simplex(2,2))))^2);
    vzdalenost = vzdalenost + sqrt(((simplex(1,1))-(simplex(3,1)))^2+((simplex(1,2)-(simplex(3,2))))^2);
%     disp('.')

   
end

% aa=TransPodobn(obr1, cil,([simplex(1) simplex(2)]));
% bb=TransPodobn(obr1, cil,([simplex(3) simplex(4)]));
% cc=TransPodobn(obr1, cil,([simplex(5) simplex(6)]));
% ccc=[aa bb cc];
% % dd=min(min(ccc));
% 
% 
%   pozice = find(ccc==min(ccc));
% 
%   if pozice == 1;
%       lok_min2 = [simplex(1) simplex(2)];
%   elseif pozice == 2;
%       lok_min2 = [simplex(3) simplex(4)];
%   elseif pozice == 3
%       lok_min2 = [simplex(5) simplex(6)];
%   end


    lok_min2 = mean(simplex);  % pokud neprekroci prostor, pak lok_min2 je nalezene lok_min na virt.fci
  
    disp('nalezeno lok min na virtualni')
    
    if lok_min2(1) <= ub(1) && lok_min2(2) <= ub(2) && lok_min2(1) >= lb(1) && lok_min2(2) >= lb(2)  
        disp('tunelovani uspesne');
        tunel = tunel + 1;
      
         simplex = [lok_min2; (lok_min2 + [0.2 0]); (lok_min2 + [0 0.2])];  %nova poc. hodnota pro nalezeni lok_min na puvodni fci
         alfa = 1;
         beta = 0.5;
        
         
        vzdalenost = 10;
        

            while vzdalenost > 0.1;
                   scatter(simplex(:,1),simplex(:,2));
            %     pause();
     
     disp('e');
                  for m = 1:3
                         hodnota(m) = TransPodobn(obr1, cil,simplex(m,:));
                  end

                 [maxhod nejhorsi] = max(hodnota);   % najdi nejhorsi bod
                 [minhod nejlepsi] = min(hodnota);   % najdi nejlepsi bod
disp('ee');
                  simplexz = simplex;
                 simplexz(nejhorsi, :) = []; % smaz prislusny radek s nejhorsi bodem

                 c = (simplexz(1,:)+simplexz(2,:))./2; % poloha teziste

                xt = c + (alfa.*(c-simplex(nejhorsi,:))); % transformuj nejhorsi bod

                hodnotaxt = TransPodobn(obr1, cil,xt); % zjisti hodnotu v trasnformovanem bodu

                porovnani =  hodnotaxt < hodnota; % hodnoty porovnej
disp('eee');
                kontrakce = 0;

                     if porovnani(nejhorsi) == 0; % jestli novy bod nema mensi hodnotu nez puvodne
                           xt = c + (beta.*(simplex(nejhorsi,:) - c));  % tak bod kontrahuj
                           hodnotaxt = TransPodobn(obr1, cil, xt);
                           if xt > hodnotaxt % pokud je kontrahovany bod stale vetsi nez puvodni
                                nejbod = simplex(nejlepsi, :);  % najdi nejlepsi bod
                                simplexy = simplex;
                                simplexy(nejlepsi,:) = [];
            disp('eeee');
                                for n = 1:2; % a k nemu kontrahuj zbyvajici body
                                    xt(n,:) = nejbod + beta.*(simplexy(n,:)-nejbod);
                                end
        
                                simplex = [nejbod; xt]; % sloz novy simplex
                                kontrakce = 1;
                           end
                     end

                     if kontrakce == 0; % pokud v kontrakci nebyl setaveny novy simplex
                        simplex(nejhorsi,:) = xt;   % tak ho sestav
                     end
    disp('eeeee');
                     vzdalenost = sqrt(((simplex(1,1))-(simplex(2,1)))^2+((simplex(1,2)-(simplex(2,2))))^2);
                     vzdalenost = vzdalenost + sqrt(((simplex(1,1))-(simplex(3,1)))^2+((simplex(1,2)-(simplex(3,2))))^2);
    

                      lok_min = mean(simplex);

% aa=TransPodobn(obr1, cil,([simplex(1) simplex(2)]));
% bb=TransPodobn(obr1, cil,([simplex(3) simplex(4)]));
% cc=TransPodobn(obr1, cil,([simplex(5) simplex(6)]));
% ccc=[aa bb cc];
% % dd=min(min(ccc));
% 
% 
%   pozice = find(ccc==min(ccc));
% 
%   if pozice == 1;
%       lok_min = [simplex(1) simplex(2)];
%   elseif pozice == 2;
%       lok_min = [simplex(3) simplex(4)];
%   elseif pozice == 3
%       lok_min = [simplex(5) simplex(6)];
%   end
%              
             end 
             disp('nalezeno 2.lok.min') % nalezeno nove lok_min na puvodni fci
%              pause()
    else
      tunel = 4;
      gl_min = lok_min(end);
    end
end
    
% end


 fval = TransPodobn(obr1, cil,lok_min); % funkční hodnota v poslednim anlezenem lok_min

toc

%% vystup

fprintf('globalni minimum je: %f\n',fval);
fprintf('parametry globalniho minima jsou: %d\n',lok_min);
