function varargout = TMDesign(varargin)

gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @TMDesign_OpeningFcn, ...
                   'gui_OutputFcn',  @TMDesign_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
function TMDesign_OpeningFcn(hObject, eventdata, handles, varargin)

handles.output = hObject;
Initial(hObject, eventdata, handles) ;
guidata(hObject, handles);
function varargout = TMDesign_OutputFcn(~, ~, handles) 

varargout{1} = handles.output;

function Initial(~, ~, handles) 
global MainDir minM minK minC maxM maxK maxC RBF_value
clc;
RBF_value=1;
MainDir=pwd;
cd(MainDir);
GMData=readtable('GM_List.txt');
set(handles.GMList,'Data',GMData{:,2:3});
set(handles.GMList,'RowName',GMData{:,1});
minM=str2double(get(handles.Mmin,'String'));
minK=str2double(get(handles.Kmin,'String'));
minC=str2double(get(handles.Cmin,'String'));
maxM=str2double(get(handles.Mmax,'String'));
maxK=str2double(get(handles.Kmax,'String'));
maxC=str2double(get(handles.Cmax,'String'));
function ReadGM_Callback(hObject, eventdata, handles)%#ok
global MainDir
[GMName,GMPath]=uigetfile('*.txt','Select the GroundMotion .txt file');
cd(MainDir);
GMfile=[GMPath,GMName];
GMData=readtable(GMfile);
set(handles.GMList,'Data',GMData{:,2:3});
set(handles.GMList,'RowName',GMData{:,1});
function GMList_CellSelectionCallback(hObject, eventdata, handles)%#ok
global Dt NStep GMName MainDir 
Index=eventdata.Indices(1);
GM_Data=get(handles.GMList,'Data');
Dt=GM_Data(Index,1);
NStep=GM_Data(Index,2);
GMNames=get(handles.GMList,'RowName');
GMName=GMNames{Index};
set(handles.GM_Name,'String',GMName);
x=Dt:Dt:NStep*Dt;
cd(MainDir);
GM_Path=['GroundM\',GMName,'.txt'];
Acc=readtable(GM_Path);
y=Acc.Var1;
axes(handles.axes_GM);
plot(x',y,'color','red')
function noTMD_Callback(hObject, eventdata, handles)%#ok
set(handles.MTMD,'Enable','Off');
set(handles.KTMD,'Enable','Off');
set(handles.CTMD,'Enable','Off');
function withTMD_Callback(hObject, eventdata, handles)%#ok
set(handles.MTMD,'Enable','on');
set(handles.KTMD,'Enable','on');
set(handles.CTMD,'Enable','on');
function Create_Input
global Dt NStep GMName MainDir MTMD KTMD CTMD
m1=['set GM ',GMName];              
m2=['set NStep ',num2str(NStep)];           
m3=['set Dt ',num2str(Dt)];              
m4=['set MTMD ',MTMD,'; # kg.s2/m'];
m5=['set KTMD ',KTMD,'; # kg/m  '];
m6=['set CTMD ',CTMD,'; # kg.s/m'];
m=char(m1,m2,m3,m4,m5,m6);
cd(MainDir);dlmwrite('Input.tcl',m,'');
function Run_OPS_Callback(hObject, eventdata, handles)%#ok
global MTMD KTMD CTMD MainDir GMName
TMD_Status=get(handles.withTMD,'Value');
MTMD=get(handles.MTMD,'String');
KTMD=get(handles.KTMD,'String');
CTMD=get(handles.CTMD,'String');
Create_Input;
Drift=zeros(1,9);
if TMD_Status==1
    cd(MainDir);
    dos('opensees.exe Run-withTMD.tcl');
    pathoutput=[MainDir,'\output\',GMName,'\M',MTMD,'-K',KTMD,'-C',CTMD,'\EnvDrift.out'];
    Answer=dlmread(pathoutput);
    for i=1:9
        Drift(i)=Answer(3,i*2);
    end
    maxDrift=max(Drift);
    set(handles.Driftmax,'String',num2str(maxDrift));
else
    cd(MainDir);
    dos('opensees.exe Run-noTMD.tcl'); 
    pathoutput=[MainDir,'\output\',GMName,'\no-TMD\EnvDrift.out'];
    Answer=dlmread(pathoutput);
    for i=1:9
        Drift(i)=Answer(3,i*2);
    end
    maxDrift=max(Drift);
    set(handles.Driftmax,'String',num2str(maxDrift));    
end

function z=Drift(x)
% global MainDir GMName MTMD KTMD CTMD
% MTMD=num2str(round(x(1)));
% KTMD=num2str(round(x(2)));
% CTMD=num2str(round(x(3)));
% Create_Input;
% Dr=zeros(1,9);
% cd(MainDir);dos('opensees.exe Run-withTMD.tcl');
%     pathoutput=[MainDir,'\output\',GMName,'\M',MTMD,'-K',KTMD,'-C',CTMD,'\EnvDrift.out'];
%     Answer=dlmread(pathoutput);
%     for i=1:9
%         Dr(i)=Answer(3,i*2);
%     end
%     z=max(Dr);
z=x(1)+x(2)+x(3);
function RunGA_Callback(hObject, eventdata, handles)%#ok
global minM minK minC maxM maxK maxC
%% Define Hadaf and Paramets
Hadaf=@Drift;       % Objective Function
N=3;                % Num variables

maxIt=str2double(get(handles.maxIt,'String'));      % Maximun Iteration
pC=str2double(get(handles.Cross,'String'));         % Crossover Percent
pM=str2double(get(handles.Mutate,'String'));        % Mutate percent
NP=str2double(get(handles.NPopulation,'String'));   %Number of Population

nC=2*round(pC*NP/2);
nM=round(pM*NP);

minN=[minM minK minC];
maxN=[maxM maxK maxC];

NSize=[1 N];            % Number of Variable Size Matrix

%% Initialization
Afrad.Pos=[];
Afrad.Val=[];
pop=repmat(Afrad,NP,1);
for i=1:NP
    pop(i).Pos=unifrnd(minN,maxN,NSize);
    pop(i).Val=Hadaf(pop(i).Pos);
end
% Sort Population
Vals=[pop.Val];
[Vals,So]=sort(Vals);
pop=pop(So);
WorstVal=Vals(end);

%% GA Loop
SP=10;
axes(handles.axes_GA);
for it=1:maxIt
    Vals=[pop.Val];
    P=exp(-SP*Vals/WorstVal);
    P=P/sum(P);
    
%% Create Crossover Population
pop2=repmat(Afrad,nC/2,2);
for Cross=1:nC/2
    % Selection Parents
    C=cumsum(P);
    i1=find(rand<=C,1);
    i2=find(rand<=C,1);
    
%     i1=randi([1 NP]);
%     i2=randi([1 NP]);
    
    p1=pop(i1);
    p2=pop(i2);
    
    % Crossover Function
    alpha=rand;
    x1=p1.Pos;
    x2=p2.Pos;
    ch1.Pos=alpha.*x1+(1-alpha).*x2;
    ch2.Pos=alpha.*x2+(1-alpha).*x1;

    ch1.Val=Hadaf(ch1.Pos);
    ch2.Val=Hadaf(ch2.Pos); 
    
    pop2(Cross,1)=ch1;
    pop2(Cross,2)=ch2;
    
end
pop2=pop2(:);

%% Create Mutation Population
 pop3=repmat(Afrad,nM,1);
 for Mu=1:nM
    i=randi([1 NP]);
    p=pop(i);
    x=p.Pos;
    j=randi([1 N]);
    
    r=unifrnd(-1,1);
    y1=x-minN;
    y2=maxN-x;
    if r<0
        x(j)=x(j)+r*y1(j);
    else
        x(j)=x(j)+r*y2(j);
    end
    q.Pos=x;
    q.Val=Hadaf(q.Pos);
    pop3(Mu)=q;
 end


%% Sumation Population

    % Merge
    pop=[pop
        pop2
        pop3];
    
    % Sort
    Vals=[pop.Val];
    [Vals, so]=sort(Vals);
    pop=pop(so);
    
    % Delete Extra
    pop=pop(1:NP);
    BestVal(it)=Vals(1);
    
    % Update WorstVal
    WorstVal=max(WorstVal,Vals(end));
    
%% Results
BestSol=pop(1);
pause(0.0001);
semilogy(BestVal,'r','LineWidth',2);
hold off;
xlabel('Generation (Iteration)');

MKC=BestSol.Pos;
set(handles.Mopt,'String',num2str(MKC(1)));
set(handles.Kopt,'String',num2str(MKC(2)));
set(handles.Copt,'String',num2str(MKC(3)));

end

function RBFtype_Callback(hObject, eventdata, handles)
global RBF_value
RBF_value=1;
set(handles.Epoch_txt,'Enable','off');
set(handles.Epoch_num,'Enable','off');

set(handles.Valid_txt,'Enable','off');
set(handles.Valid_num,'Enable','off');

set(handles.Spread_txt,'Enable','on');
set(handles.Spread_num,'Enable','on');

set(handles.TrFunc_txt,'Enable','off');
set(handles.TrFunc_list,'Enable','off');
function MLPtype_Callback(hObject, eventdata, handles)
global RBF_value
RBF_value=0;
set(handles.Epoch_txt,'Enable','on');
set(handles.Epoch_num,'Enable','on');

set(handles.Valid_txt,'Enable','on');
set(handles.Valid_num,'Enable','on');

set(handles.Spread_txt,'Enable','off');
set(handles.Spread_num,'Enable','off');

set(handles.TrFunc_txt,'Enable','on');
set(handles.TrFunc_list,'Enable','on');

function Training_Callback(hObject, eventdata, handles)
global RBF_value minM maxM minK maxK minC maxC MainDir GMName
    lins=5;Counter=0;
% Create Input and Target
    Input=zeros(3,lins^3);
    Target=zeros(1,lins^3);
    
    gamM=(maxM-minM)/(lins-1);
    gamK=(maxK-minK)/(lins-1);
    gamC=(maxC-minC)/(lins-1);
    
    for Mt=minM:gamM:maxM
        for Kt=minK:gamK:maxK
            for Ct=minC:gamC:maxC
                Dr=zeros(1,9);
                Counter=Counter+1;
                Input(1,Counter)=Mt;
                Input(2,Counter)=Kt;
                Input(3,Counter)=Ct; 
   pathoutput=[MainDir,'\output\',GMName,'\M',num2str(Mt),'-K',num2str(Kt),'-C',num2str(Ct),'\Envdrift.out'];
                Answer=dlmread(pathoutput);
                for i=1:9
                    Dr(i)=Answer(3,i*2);
                end
                Target(1,Counter)=max(Dr);
            end
        end
    end
        MaxN=str2double(get(handles.Neuron_num,'String'));
if RBF_value==1
%     clc;
    Goal=0;
    Spread=str2double(get(handles.Spread_num,'String'));
    
%     net=newrb(Input,Target, Goal,Spread,MaxN);
    net=newrbe(Input,Target,Spread);

    txtTitle='max Drift in SAC9 with RBF Network';
else
    numtrain=get(handles.TrFunc_list,'Value');
    switch numtrain
        case 1
            trainFcn='trainlm';
        case 2
            trainFcn='trainbr';            
        case 3
            trainFcn='trainscg';            
    end
            
    net=fitnet(MaxN,trainFcn);
    
    net.TrainParam.Epochs=str2double(get(handles.Epoch_num,'String'));
    net.TrainParam.Max_Fail=str2double(get(handles.Valid_num,'String'));
    
    net=train(net,Input,Target);
    txtTitle='max Drift in SAC9 with MLP Network';
end
    Output=net(Input);
    performance=perform(net,Target,Output)
   figure
   plot(Output,'b');
   hold on;
   plot(Target,'r:');
   legend('Output','Target');
   title(txtTitle);
   set(handles.Training,'Value',0);
