%--------------------------------------------------%
% LINEAR ANALYSIS IN GUI FORM BY SVEND BERTEL STEFFENSEN 01022014
% PRESS F5 TO RUN GUI, FILL IN THE BOXES AND YOU ARE SET!
% WILL PLOT EACH TIME YOU MANIPULATE THE R-BAR
% TO WIPE FIGURES - DEACTIVATE 'Bifurcation Diag' POINTS AND MANIPULATE R-BAR
% THE GOVERNING FUNCTION IS THE LAST FUNCTION IN THIS SCRIPT
% HOPE YOU ENJOY THE CODE!

% UPDATED 2016
% ELIMINATED NEED FOR SYMBOLIC TOOL PACKAGE
% ADDED DEFAULT VALUES FOR FAST USE
%--------------------------------------------------%
function Lin_Analysis_1D_GUI_SBS
clear all
close all
clc

% CREATE AND THEN HIDE THE GUI AS IT IS BEING CONSTRUCTED
f = figure('Visible','off','Position',[360,500,450,285]);

% OFFSET ON VALUE PANEL UI OBJECTS
Mul_off_y = -50;

% CONSTRUCT THE GUI COMPONENTS
rval_slider = uicontrol('Style','slider',...
'String','rval','Position',[15,50,70,25],...
'Callback',{@rvalslider_Callback},'Tooltipstring',sprintf(['Slide to change value of r in defined interval\n'...
'NOTE: Changing the bar will automatically apply values']));

rval_text = uicontrol('Style','text',...
'String','','Position',[15,35,50,15],'Tooltipstring','Current value of r',...
'Tag','R_Value');


rval_min_edit = uicontrol('Style','edit',...
'String','','Tag','rmin','Position',[15,220+Mul_off_y,20,15],...
'Callback',{@rval_min_edit_Callback},'Tooltipstring','Min value of r',...
    'String','-2','Value',-2);

rval_max_edit = uicontrol('Style','edit',...
'String','','Tag','rmax','Position',[115,220+Mul_off_y,20,15],...
'Callback',{@rval_max_edit_Callback},'Tooltipstring','Max value of r',...
    'String','2','Value',2);

rval_step_edit = uicontrol('Style','edit',...
'String','','Tag','rstep','Position',[65,220+Mul_off_y,20,15],...
'Callback',{@rval_step_edit_Callback},'Tooltipstring','Step value of r',...
    'String','0.1','Value',0.1);

xval_min_edit = uicontrol('Style','edit',...
'String','','Tag','xmin','Position',[15,170+Mul_off_y,20,15],...
'Callback',{@xval_min_edit_Callback},'Tooltipstring','Min value of x',...
    'String','-2','Value',-2);

xval_max_edit = uicontrol('Style','edit',...
'String','','Tag','xmax','Position',[115,170+Mul_off_y,20,15],...
'Callback',{@xval_max_edit_Callback},'Tooltipstring','Max value of x',...
    'String','2','Value',2);

xval_step_edit = uicontrol('Style','edit',...
'String','','Tag','xstep','Position',[65,170+Mul_off_y,20,15],...
'Callback',{@xval_step_edit_Callback},'Tooltipstring','Step value of x',...
    'String','0.1','Value',0.1);

apply_xval_pushbutton = uicontrol('Style','pushbutton',...
'String','Apply values','Tag','xapply','Position',[35,150+Mul_off_y,80,15],...
'Callback',{@apply_xval_pushbutton_Callback},'Tooltipstring','Applies selected x-interval to expression above');

express_edit = uicontrol('Style','edit',...
'String','','Tag','express','Position',[35,260+Mul_off_y,80,15],...
'Callback',{@express_edit_Callback},'Tooltipstring','Expression of x and r,  f(x,r) ');

wipe_radiobutton = uicontrol('Style','radiobutton',...
'String','Bifurcation Diag','Tag','wipe','Position',[100,50,65,15],...
'Callback',{@wipe_radiobutton_Callback},'Tooltipstring',...
'Click "on" and vary r slider to create bifurcation diagram','BackgroundColor',[0.8 0.8 0.8]);

sensi_edit = uicontrol('Style','edit',...
'String','0.0001','Tag','sensi','Position',[10,10,40,15],...
'Callback',{@sensi_edit_Callback},'Tooltipstring',...
sprintf(['Parameter determining when to define fixed points\n' 'WARNING: Edit only if expected fixed points do not appear or multiple fixed points appear for one value']),...
'Value',0.0001);


yval_min_edit = uicontrol('Style','edit',...
'String','-10','Tag','ymin','Position',[60,10,40,15],...
'Callback',{@yval_min_edit_Callback},'Tooltipstring',...
sprintf(['Lower bound on the y-axis on the standard plot\n' 'NOTE: Is not an essential parameter']),'Value',-10);

yval_max_edit = uicontrol('Style','edit',...
'String','10','Tag','ymax','Position',[110,10,40,15],...
'Callback',{@yval_max_edit_Callback},'Tooltipstring',...
'Upper bound on the y-axis on the standard plot','Value',10);


axes1 = axes('Units','pixels','Position',[200,160,200,90],'Tag','axes1');
xlabel('\bf{x}','interpreter','latex','FontSize',16);
ylabel('$\bf{f(x,r)}$','interpreter','latex','FontSize',16);
title('Standard Plot','FontWeight','Bold')
axes2 = axes('Units','pixels','Position',[200,30,200,90],'Tag','axes2');
xlabel('\bf{r}','interpreter','latex','FontSize',16)
ylabel('$\bf{f(x,r)=0}$','interpreter','latex','FontSize',16)
title('Bifurcation Plot','FontWeight','Bold')



% CONSTRUCTS OBJECTS NOT TO BE INCLUDED IN THE MASTER STRUCT
rmin_pos=get(rval_min_edit,'Position');
txt_rmin = annotation(f,'textbox','String','r_{min}','Units','pixels','Position',...
    [rmin_pos(1)-10 rmin_pos(2)-1 rmin_pos(3)*2 rmin_pos(4)*2.2],'HorizontalAlignment',...
    'Center','FontWeight','bold','BackgroundColor',[0.6 0.6 0.6]);

rmax_pos=get(rval_max_edit,'Position');
txt_rmax = annotation(f,'textbox','String','r_{max}','Units','pixels','Position',...
    [rmax_pos(1)-10 rmax_pos(2)-1 rmax_pos(3)*2 rmax_pos(4)*2.2],'HorizontalAlignment',...
    'Center','FontWeight','bold','BackgroundColor',[0.6 0.6 0.6]);

rstep_pos=get(rval_step_edit,'Position');
txt_rstep = annotation(f,'textbox','String','r_{step}','Units','pixels','Position',...
    [rstep_pos(1)-10 rstep_pos(2)-1 rstep_pos(3)*2 rstep_pos(4)*2.2],...
    'FontWeight','bold','HorizontalAlignment','Center','BackgroundColor',[0.6 0.6 0.6]);

xmin_pos=get(xval_min_edit,'Position');
txt_xmin = annotation(f,'textbox','String','x_{min}','Units','pixels','Position',...
    [xmin_pos(1)-10 xmin_pos(2)-1 xmin_pos(3)*2 xmin_pos(4)*2.2],'HorizontalAlignment',...
    'Center','FontWeight','bold','BackgroundColor',[0.7 0.7 0.7]);

xmax_pos=get(xval_max_edit,'Position');
txt_xmax = annotation(f,'textbox','String','x_{max}','Units','pixels','Position',...
    [xmax_pos(1)-10 xmax_pos(2)-1 xmax_pos(3)*2 xmax_pos(4)*2.2],'HorizontalAlignment',...
    'Center','FontWeight','bold','BackgroundColor',[0.7 0.7 0.7]);

xstep_pos=get(xval_step_edit,'Position');
txt_xstep = annotation(f,'textbox','String','x_{step}','Units','pixels','Position',...
    [xstep_pos(1)-10 xstep_pos(2)-1 xstep_pos(3)*2 xstep_pos(4)*2.2],'HorizontalAlignment',...
    'Center','FontWeight','bold','BackgroundColor',[0.7 0.7 0.7]);

express_pos=get(express_edit,'Position');
txt_express = annotation(f,'textbox','String','Function f(x,r)','Units','pixels','Position',...
    [express_pos(1)-10 express_pos(2)-1 express_pos(3)*1.25 express_pos(4)*2.2],'HorizontalAlignment',...
    'Center','FontWeight','bold','BackgroundColor',[0.5 0.5 0.5]);

rslider_pos=get(rval_slider,'Position');
txt_rslider = annotation(f,'textbox','String','Slider for r values','Units','pixels','Position',...
    [rslider_pos(1)-8 rslider_pos(2)-20 rslider_pos(3)*1.2 rslider_pos(4)*2.5],...
    'HorizontalAlignment','Center','FontWeight','bold','BackgroundColor',[0.8 0.8 0.8]);


txt_title = annotation(f,'textbox','String','1D Bifurcation Analyser 2016','Units','pixels','Position',...
    [0,270,260,15],'HorizontalAlignment','Left','BackgroundColor',get(f,'color'),'EdgeColor','none',...
    'FontWeight','Bold','FontSize',18);

txt_author = annotation(f,'textbox','String','By Svend Bertel Dahl-Jensen','Units','pixels','Position',...
    [350,0,180,15],'HorizontalAlignment','Left','BackgroundColor',get(f,'color'),'EdgeColor','none',...
    'FontWeight','Bold','FontSize',8);

txt_legend1 = annotation(f,'textbox','String',sprintf(['Unstable']),'Units','pixels','Position',...
    [410,155,40,15],'HorizontalAlignment','Left','BackgroundColor',[1 0 0],'EdgeColor',[0 0 0],...
    'FontWeight','Bold','FontSize',8);
pos_leg1 = get(txt_legend1,'Position');
txt_legend2 = annotation(f,'textbox','String',sprintf(['Stable']),'Units','pixels','Position',...
    [410,pos_leg1(2)-20,40,15],'HorizontalAlignment','Left','BackgroundColor',[0.3 0.3 1],'EdgeColor',[0 0 0],...
    'FontWeight','Bold','FontSize',8);
txt_legend3 = annotation(f,'textbox','String',sprintf(['Tangent']),'Units','pixels','Position',...
    [410,pos_leg1(2)-40,40,15],'HorizontalAlignment','Left','BackgroundColor',[0 1 0],'EdgeColor',[0 0 0],...
    'FontWeight','Bold','FontSize',8);


% CONSTRUCTS THE MASTER STRUCTURE
Master_Struct = struct(get(rval_slider,'String'),rval_slider,get(rval_min_edit,'Tag'),rval_min_edit,...
    get(rval_max_edit,'Tag'),rval_max_edit,get(rval_step_edit,'Tag'),rval_step_edit,get(axes1,'Tag'),axes1,...
    get(xval_min_edit,'Tag'),xval_min_edit,get(xval_max_edit,'Tag'),xval_max_edit,get(xval_step_edit,'Tag'),...
    xval_step_edit,get(apply_xval_pushbutton,'Tag'),apply_xval_pushbutton,get(express_edit,'Tag'),express_edit,...
    get(axes2,'Tag'),axes2,get(wipe_radiobutton,'Tag'),wipe_radiobutton,get(sensi_edit,'Tag'),sensi_edit,...
    get(rval_text,'Tag'),rval_text,'Curr_Func',[],get(yval_min_edit,'Tag'),yval_min_edit,...
    get(yval_max_edit,'Tag'),yval_max_edit);


% INITIALIZE THE GUI
% CHANGE UNITS TO 'normalized' SO GUI COMPONENTS RESIZE AUTOMATICALLY
set([rval_slider,rval_min_edit,rval_max_edit,rval_step_edit,xval_min_edit,...
    xval_max_edit,xval_step_edit,apply_xval_pushbutton,express_edit,axes1,axes2,...
    wipe_radiobutton,sensi_edit,rval_text,txt_rmin,txt_rmax,txt_rstep,...
    txt_xmin,txt_xmax,txt_xstep,txt_express,txt_title,txt_author,...
    txt_rslider,txt_legend1,txt_legend2,txt_legend3,yval_min_edit...
    yval_max_edit],'Units','normalized');


% ASSIGN THE NAME OF THE GUI TO APPEAR IN THE WINDOW TITLE
set(f,'Name','Liniar Analysis 1D')
% MOVE THE GUI TO THE CENTER OF THE SCREEN
set(f,'Position',[300 151 706 425])
movegui(f,'center')
% MAKE THE GUID VISIBLE AFTER CONSTRUCTION
set(f,'Visible','on');


% DEFINE INTERACTION FUNCTIONS WHEN THE USER INTERFACES WITH THE EDITALBE - 
% GUI COMPONENENTS, THE FUNCTIONS BELOW ARE NESTED FUNCTION TO MAIN
function rvalslider_Callback(MyOwn,eventdata)
set(Master_Struct.R_Value,'String',['r = ' num2str(get(MyOwn,'Value'))])
apply_xval_pushbutton_Callback
end

function rval_min_edit_Callback(MyOwn,eventdata)
val_to_set = str2num(get(MyOwn,'String'));
set(Master_Struct.rval,'Min',val_to_set);
end
    
function rval_max_edit_Callback(MyOwn,eventdata)
val_to_set = str2num(get(MyOwn,'String'));
set(Master_Struct.rval,'Max',val_to_set);
end

function xval_step_edit_Callback(MyOwn,eventdata)
set(MyOwn,'Value',str2num(get(MyOwn,'String')));
end

function xval_min_edit_Callback(MyOwn,eventdata)
set(MyOwn,'Value',str2num(get(MyOwn,'String')));
end

function xval_max_edit_Callback(MyOwn,eventdata)
set(MyOwn,'Value',str2num(get(MyOwn,'String')));
end

function rval_step_edit_Callback(MyOwn,eventdata)
val_to_set = str2num(get(MyOwn,'String'));
set(Master_Struct.rval,'SliderStep',[val_to_set*0.1 val_to_set]);
end


function apply_xval_pushbutton_Callback(MyOwn,eventdata)

A_fun = Master_Struct.Curr_Func;
xmin = get(Master_Struct.xmin,'Value');
xstep = get(Master_Struct.xstep,'Value');
xmax = get(Master_Struct.xmax,'Value');
x_int = xmin:xstep:xmax;
r_val = get(Master_Struct.rval,'Value');
ymin = get(Master_Struct.ymin,'Value');
ymax = get(Master_Struct.ymax,'Value');

plot(axes1,x_int,A_fun(r_val,x_int),'b-')
set(Master_Struct.axes1,'XLim',[xmin xmax])
set(Master_Struct.axes1,'YLim',[ymin ymax])
line([xmin 0; xmax 0],[0 -ymin;0 ymax],'Color',[0 0 0],'Parent',axes1)
xlabel('\bf{x}','interpreter','latex','FontSize',16,'Parent',axes1);
ylabel('$\bf{f(x,r)}$','interpreter','latex','FontSize',16,'Parent',axes1);
title('Standard Plot','FontWeight','Bold','Parent',axes1)

% CALLS THE EXTERNAL FUNCTION
ExpressionEvalFunc(x_int,r_val,A_fun,Master_Struct)



end

function express_edit_Callback(MyOwn,eventdata)    
express = get(MyOwn,'String');
Master_Struct.Curr_Func = @(r,x) eval(express); 
end

function wipe_radiobutton_Callback(MyOwn,eventdata)
end

function sensi_edit_Callback(MyOwn,eventdata)
set(MyOwn,'Value',str2num(get(MyOwn,'String')));
end

function yval_min_edit_Callback(MyOwn,eventdata)
val_to_set = str2num(get(MyOwn,'String'));
set(Master_Struct.ymin,'Value',val_to_set);
end
    
function yval_max_edit_Callback(MyOwn,eventdata)
val_to_set = str2num(get(MyOwn,'String'));
set(Master_Struct.ymax,'Value',val_to_set);
end





% END OF MAIN FUNCTION
end


% EXTERNAL FUNCTION GRAPHICALLY FINDING AND DETERMINING TYPE OF FIXED POINTS
function ExpressionEvalFunc(x_list,r_val,fun,handles)

% SENSITIVITY PARAMETER
sen = get(handles.sensi,'Value');

f_x = fun(r_val,x_list);

% LOOP GRAPHICALLY FINDS FIXED POINTS AND DETERMINES STABILITY
c=0;
for k=2:length(f_x)-1
if abs(f_x(k))<sen
low=k-1;
hgh=k+1;
f_x_sgn_low = sign(f_x(low));
f_x_sgn_hgh = sign(f_x(hgh));
else
low=k;
hgh=k+1;
f_x_sgn_low = sign(f_x(low));
f_x_sgn_hgh = sign(f_x(hgh));
end

inter_f_x = f_x_sgn_low + f_x_sgn_hgh;
   
    if inter_f_x==0
    c=c+1;    
    inter_coor1(c) = x_list(low);
    inter_coor2(c) = x_list(hgh);
    if sign(f_x(low))==-1 && sign(f_x(hgh))==1   
    ext_type(c)=2;
    elseif sign(f_x(low))==1 && sign(f_x(hgh))==-1        
    ext_type(c)=1;
    end
    elseif abs(f_x(k))<sen    
    c=c+1;    
    inter_coor1(c) = x_list(low);
    inter_coor2(c) = x_list(hgh);
    ext_type(c)=0;
    end
end

if c>0
[ext_type ext_odr ] = sort(ext_type);
inter_coor1 = inter_coor1(ext_odr);
inter_coor2 = inter_coor2(ext_odr);
end


% PLOTS FIXED POINTS (IF ANY) AND THEIR STABILITY
h=0;
hold on
if c>0
while h<length(inter_coor1)
h=h+1;
    if ext_type(h)==2 
    point = plot((inter_coor1(h)+inter_coor2(h))/2,0,'Marker','*','color','r');
    set(point,'Parent',handles.axes1)
    elseif ext_type(h)==1
    point = plot((inter_coor1(h)+inter_coor2(h))/2,0,'Marker','*','color','b');
    set(point,'Parent',handles.axes1)
    elseif ext_type(h)==0
    point =plot((inter_coor1(h)+inter_coor2(h))/2,0,'Marker','*','color','g');    
    set(point,'Parent',handles.axes1)
    end
end
end
hold off

% WIPES WINDOW IF handle = 0;
if get(handles.wipe,'Value')==0
delete(findall(handles.axes2,'Tag','FPoint'))
end

% PLOTS AXES LINES
line([get(handles.rval,'Min') get(handles.rval,'Max')],[0 0],'color',[0 0 0],'Parent',handles.axes2);
line([0 0],[min(x_list) max(x_list)],'color',[0 0 0],'Parent',handles.axes2);


% PLOTS THE BIFURCATION PLOT
h=0;
hold on
if c>0
while h<length(inter_coor1)
h=h+1;
    if ext_type(h)==2 
    point = plot(r_val,(inter_coor1(h)+inter_coor2(h))/2,'Marker','.','color','r','Tag','FPoint');
    set(point,'Parent',handles.axes2)
    elseif ext_type(h)==1
    point = plot(r_val,(inter_coor1(h)+inter_coor2(h))/2,'Marker','.','color','b','Tag','FPoint');
    set(point,'Parent',handles.axes2)
    elseif ext_type(h)==0
    point = plot(r_val,(inter_coor1(h)+inter_coor2(h))/2,'Marker','.','color','g','Tag','FPoint');    
    set(point,'Parent',handles.axes2)
    end
end
end
xlabel(handles.axes2,'\bf{r}','interpreter','latex','FontSize',16)
ylabel(handles.axes2,'$\bf{f(x,r)=0}$','interpreter','latex','FontSize',16)
title(handles.axes2,'Bifurcation Plot','FontWeight','bold')
hold off
end







