%  This code was originally developed by The Center for Engineering Applications &
%  Technology Solution (CEATS), Ho Chi Minh City, Open University, Vietnam.
%  https://ceats.ou.edu.vn/us/ 
%  programming: Hoang-Le Minh
%
%  paper:Optimization of high-rise concrete structure using a sequence design based on a proposed surrogate model
%        (PSM) and Finite element (FE) model updating
%
%    
%  Hoang-Le Minh, Thanh Sang-To, Binh Le-Van, Thanh Cuong-Le
%
%  Email: hoang.lm@ou.edu.vn, cuong.lt@ou.edu.vn
%
%  Journal: Archives of Civil and Mechanical Engineering

clear all
clc
clear;
clc;
load('input_section.txt')
load ('output_DD.txt')
load ('output_nonDD.txt')
input_data = input_section;

% Normalize the data so that the denominator is 1
output_model_1= output_nonDD(1,:)./max(output_nonDD(1,:)); % Max displacement _model 1
output_model_2= output_nonDD(2,:)./max(output_nonDD(2,:)); % Max drift _model 2
output_model_3 = output_DD(1,:)./ max(output_DD(1,:));
temp = output_DD;
temp(1,:) = []; % Remove first row from matrix
output_model_4 = temp./ max(max([temp]));

%% DNN training process
% output_data_DD = output_DD;
% output_DD_driff = [output_data_nonDD; output_data_DD] 
% nntool

%% --- Define network architecture for model 1 ------------------
input = input_data;
target = output_model_1 ;

% Create a Fitting Network
hiddenLayerSize = [50 100 50]; % Define the number of layers and neurons in each layer
net = fitnet(hiddenLayerSize);

% Set up Division of Data for Training, Validation, Testing
net.divideParam.trainRatio = 70/100;
net.divideParam.valRatio = 15/100;
net.divideParam.testRatio = 15/100;

%% --- Define training parameters

% net.trainFcn = 'traingdx'; % Gradient descent with momentum and adaptive learning rate backpropagation
% net.trainFcn = 'traingdm'; % Gradient descent with momentum backpropagation
net.trainFcn = 'traingda'; % Gradient descent with backpropagation
% net.trainFcn = 'traingd'; % Gradient descent 

net.trainParam.epochs = 2000; % — Maximum number of epochs to train. Default = 1000
net.trainParam.goal = 1e-5; % — Performance goal. Default = 0
net.trainParam.lr = 0.01; % — Learning rate. Default = 0.01
net.trainParam.lr_inc = 1.05; % — Learning rate increase factor. Default = 1.05
net.trainParam.lr_dec = 0.7; % — Learning rate decrease factor. Default = 0.7
net.trainParam.max_fail = 10; % — Max validation failures. Default = 6
net.trainParam.max_perf_inc = 1.04; % — Max performance increase. Default = 1.04
net.trainParam.mc = 0.1; % — Momentum constant. Default = 0.9
net.trainParam.min_grad = 1e-5; % — Minimum performance gradient. Default = 1e-5
net.trainParam.show % — Epochs between display updates. Default = 25
net.trainParam.showCommandLine; % — Show command-line output. Default = false
net.trainParam.showWindow; % — Show training GUI window. Default = true
net.trainParam.time; % — Max training time (seconds). Default = inf

% Train the Network
for i = 1:1
    [net,tr] = train(net,input,target);
end

figure (1)
plotperform(tr);
ax.XAxis.FontSize = 20;
ax.YAxis.FontSize = 20;

% Test the Network
outputs_model_1 = net(input);
errors = gsubtract(outputs_model_1,target);
performance = perform(net,target,outputs_model_1)

% View the Network
network_model_1 = net;
train_parameters = tr;

% Export DNN model results
train_parameters.best_perf;  % Best training performance
train_parameters.best_tperf; % Best testing performance
train_parameters.best_vperf; % Best validation performance

%% Plot regression results for model 1
%% Training
train_num     = size(train_parameters.trainInd,2);
predict_train = network_model_1(input(:,1:train_num));
figure (2)
plotregression(target(:,1:train_num),predict_train,'Train data')

%% Validation
valid_test = size(train_parameters.valInd,2);
valid_num = train_num + valid_test;
predict_train = network_model_1(input(:, train_num:valid_num ));
figure (3)
plotregression(target(:,train_num:valid_num),predict_train,'Valid data')

%% Test
train_test = size(train_parameters.testInd,2);
test_num = valid_num + train_test;
predict_train = network_model_1(input(:,valid_num:test_num));
figure (4)
plotregression(target(:,valid_num:test_num),predict_train,'Test data');

%% All data
predict_all = network_model_1(input);
figure (5)
plotregression(target,predict_all,'All data');
