function varargout = PID_Controller(varargin)

global sys_tf sys_ss sys_fd_P sys_fd_PD sys_fd_PI sys_fd_PID
global a_dou b_dou c_dou d_dou
global sys_final_P sys_final_PI sys_final_PD sys_final_PID

% PID_CONTROLLER M-file for PID_Controller.fig
%      PID_CONTROLLER, by itself, creates a new PID_CONTROLLER or raises the existing
%      singleton*.
%
%      H = PID_CONTROLLER returns the handle to a new PID_CONTROLLER or the handle to
%      the existing singleton*.
%
%      PID_CONTROLLER('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in PID_CONTROLLER.M with the given input arguments.
%
%      PID_CONTROLLER('Property','Value',...) creates a new PID_CONTROLLER or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before PID_Controller_OpeningFunction gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to PID_Controller_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help PID_Controller

% Last Modified by GUIDE v2.5 04-Sep-2008 09:14:05

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @PID_Controller_OpeningFcn, ...
                   'gui_OutputFcn',  @PID_Controller_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
% End initialization code - DO NOT EDIT

% --- Executes just before PID_Controller is made visible.
function PID_Controller_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to PID_Controller (see VARARGIN)

% Choose default command line output for PID_Controller
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes PID_Controller wait for user response (see UIRESUME)
% uiwait(handles.figure1);

% --- Outputs from this function are returned to the command line.
function varargout = PID_Controller_OutputFcn(hObject, eventdata, handles)
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;

% --- Executes on button press in ss_pushb.
function ss_pushb_Callback(hObject, eventdata, handles)
% hObject    handle to ss_pushb (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%====================== Values from Radio Button ======================
ss_pushbutton = get (handles.ss_radiob,'Value');
tf_pushbutton = get (handles.tf_radiob,'Value');

%================= Implementing State Space Model ====================
if ss_pushbutton == get(handles.ss_radiob,'Max')

    a = get(handles.A_edit,'String');
    global a_dou
    a_dou = str2num(a);

    b= get(handles.B_edit,'String');
    global b_dou
    b_dou = str2num(b);

    c= get(handles.C_edit,'String');
    global c_dou
    c_dou = str2num(c);

    d= get(handles.D_edit,'String');
    global d_dou
    d_dou = str2num(d);

    %================= Error If Either A,B,C or D is empty ================

    if isempty(a_dou) || isempty(b_dou) || isempty(c_dou) || isempty(d_dou)
        errordlg('Please enter all A,B,C and D in correct format');
    end

    %======= Error If the State Space Model is not correct ================
    [r1 c1] = size(a_dou);
    [r2 c2] = size(c_dou);
    [r3 c3] = size(b_dou);
    [r4 c4] = size(d_dou);
        if c1 ~= c2
            errordlg('Please Enter Valid State Space Model');
        end
        if r1 ~= r3
            errordlg('Please Enter Valid State Space Model');
        end
        if c3 ~= c4
            errordlg('Please Enter Valid State Space Model');
        end

    global sys_ss
    sys_ss = ss(a_dou,b_dou,c_dou,d_dou);            % State Space Model

     [s t]= step(sys_ss);
     axes(handles.axes1)
     plot(t,s),grid on

    %================= Error If State Space Button is not selected ========
else
    errordlg('Select "State Space"');
end

    %======================= Time Response ================================

%     sys_s = tf(a_dou,b_dou,c_dou,d_dou)
%     sys_s = tf(n,d)
    sys_s= tf(sys_ss);
    [num,den] = tfdata(sys_s);
    [r c] = size(den{1,1});

    if c ~= 3
        set(handles.MOS_text,'String','Approximation Not Valid');
        set(handles.PTS_text,'String','Approximation Not Valid');
        set(handles.STS_text,'String','Approximation Not Valid');
    end

    roots_sys = roots(den{1,1});
    roots_sys_str = num2str(roots_sys);

    set(handles.ROS_text,'String',roots_sys_str);

    den_sp = den{1,1}(1,3);
    wn = sqrt(den_sp);
    den_sp2 = den{1,1}(1,2);
    b = den_sp2/(2*wn);
    [r c] = size(den{1,1});

    if b<=1 && num{1,1}(1,end-1) == 0 && c == 3
        MOS = exp(-(b*pi)/(sqrt(1-b^2)))*100;
        MOS_str = num2str(MOS);
        MOS_real = strcat(MOS_str,' %');
        set(handles.MOS_text,'String',MOS_real);

        PTS = pi/(wn*(sqrt(1-b^2)));
        PTS_str = num2str(PTS);
        PTS_real = strcat(PTS_str,' Sec');
        set(handles.PTS_text,'String',PTS_real);

        STS = 4/(b*wn);
        STS_str = num2str(STS);
        STS_real = strcat(STS_str,' Sec');
        set(handles.STS_text,'String',STS_real);
    else
        set(handles.MOS_text,'String','Approximation Not Valid');
        set(handles.PTS_text,'String','Approximation Not Valid');
        set(handles.STS_text,'String','Approximation Not Valid');
    end

%==========================================================================

function A_edit_Callback(hObject, eventdata, handles)
% hObject    handle to A_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of A_edit as text
%        str2double(get(hObject,'String')) returns contents of A_edit as a double

% --- Executes during object creation, after setting all properties.
function A_edit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to A_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function B_edit_Callback(hObject, eventdata, handles)
% hObject    handle to B_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of B_edit as text
%        str2double(get(hObject,'String')) returns contents of B_edit as a double

% --- Executes during object creation, after setting all properties.
function B_edit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to B_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function C_edit_Callback(hObject, eventdata, handles)
% hObject    handle to C_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of C_edit as text
%        str2double(get(hObject,'String')) returns contents of C_edit as a double

% --- Executes during object creation, after setting all properties.
function C_edit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to C_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function D_edit_Callback(hObject, eventdata, handles)
% hObject    handle to D_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of D_edit as text
%        str2double(get(hObject,'String')) returns contents of D_edit as a double

% --- Executes during object creation, after setting all properties.
function D_edit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to D_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in tf_pushb.
function tf_pushb_Callback(hObject, eventdata, handles)
% hObject    handle to tf_pushb (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%====================== Values from Radio Button ======================
ss_pushbutton = get (handles.ss_radiob,'Value');
tf_pushbutton = get (handles.tf_radiob,'Value');

%================= Implementing Transfer Function ====================

if tf_pushbutton == get(handles.tf_radiob,'Max')

    num= get (handles.num_edit,'string');
    num_dou = str2num(num);

    den= get (handles.den_edit,'string');
    den_dou = str2num(den);

    %================= Error If Either Num or Den is empty  ====================
    if isempty(num_dou) || isempty(den_dou)
        errordlg('Please enter in right format, For Example Num = [1 2] or Den = [1 2 3]');
    end
    % =====================================================================

    global sys_tf
    sys_tf = tf(num_dou,den_dou);            % Transfer Function

    [s t]= step(sys_tf);
    axes(handles.axes1)
    plot(t,s),grid on

    %================= Error If Transfer Function Button is not selected=======

else
    errordlg('Select "Transfer Function');
end

    %======================= Time Response ================================

    [num,den] = tfdata(sys_tf);
    [r c] = size(den{1,1});

    if c ~= 3
        set(handles.MOS_text,'String','Approximation Not Valid');
        set(handles.PTS_text,'String','Approximation Not Valid');
        set(handles.STS_text,'String','Approximation Not Valid');
    end

    roots_sys = roots(den{1,1});
    roots_sys_str = num2str(roots_sys);

    set(handles.ROS_text,'String',roots_sys_str);

    den_sp = den{1,1}(1,3);
    wn = sqrt(den_sp);
    den_sp2 = den{1,1}(1,2);
    b = den_sp2/(2*wn);
    [r c] = size(den{1,1});

    if b<=1 && num{1,1}(1,end-1) == 0 && c == 3
        MOS = exp(-(b*pi)/(sqrt(1-b^2)))*100;
        MOS_str = num2str(MOS);
        MOS_real = strcat(MOS_str,' %');
        set(handles.MOS_text,'String',MOS_real);

        PTS = pi/(wn*(sqrt(1-b^2)));
        PTS_str = num2str(PTS);
        PTS_real = strcat(PTS_str,' Sec');
        set(handles.PTS_text,'String',PTS_real);

        STS = 4/(b*wn);
        STS_str = num2str(STS);
        STS_real = strcat(STS_str,' Sec');
        set(handles.STS_text,'String',STS_real);
    else
        set(handles.MOS_text,'String','Approximation Not Valid');
        set(handles.PTS_text,'String','Approximation Not Valid');
        set(handles.STS_text,'String','Approximation Not Valid');
    end
%==========================================================================

function num_edit_Callback(hObject, eventdata, handles)
% hObject    handle to num_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of num_edit as text
%        str2double(get(hObject,'String')) returns contents of num_edit as a double

% --- Executes during object creation, after setting all properties.
function num_edit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to num_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function den_edit_Callback(hObject, eventdata, handles)
% hObject    handle to den_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of den_edit as text
%        str2double(get(hObject,'String')) returns contents of den_edit as a double

% --- Executes during object creation, after setting all properties.
function den_edit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to den_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on selection change in PID_popupmenu.
function PID_popupmenu_Callback(hObject, eventdata, handles)
% hObject    handle to PID_popupmenu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns PID_popupmenu contents as cell array
%        contents{get(hObject,'Value')} returns selected item from PID_popupmenu

% --- Executes during object creation, after setting all properties.
function PID_popupmenu_CreateFcn(hObject, eventdata, handles)
% hObject    handle to PID_popupmenu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function Kp_edit_Callback(hObject, eventdata, handles)
% hObject    handle to Kp_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of Kp_edit as text
%        str2double(get(hObject,'String')) returns contents of Kp_edit as a double

% --- Executes during object creation, after setting all properties.
function Kp_edit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to Kp_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function Ki_edit_Callback(hObject, eventdata, handles)
% hObject    handle to Ki_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of Ki_edit as text
%        str2double(get(hObject,'String')) returns contents of Ki_edit as a double

% --- Executes during object creation, after setting all properties.
function Ki_edit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to Ki_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function Kd_edit_Callback(hObject, eventdata, handles)
% hObject    handle to Kd_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of Kd_edit as text
%        str2double(get(hObject,'String')) returns contents of Kd_edit as a double

% --- Executes during object creation, after setting all properties.
function Kd_edit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to Kd_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in PID_pushb.
function PID_pushb_Callback(hObject, eventdata, handles)
% hObject    handle to PID_pushb (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%===== Values from Controller popup menu and Responses menu ===============

value = get(handles.PID_popupmenu,'Value');

%====================== Values from Radio Button ======================

ss_pushbutton = get (handles.ss_radiob,'Value');
tf_pushbutton = get (handles.tf_radiob,'Value');

%==================== Selecting Only Proportional Controller %===============

if value == 1
    value_str = get(handles.Kp_edit,'String');
    value_dou = str2num (value_str);

    if tf_pushbutton == get(handles.tf_radiob,'Max');

        global sys_tf
        sys_final_P = sys_tf * value_dou;
        global sys_fd_P
        sys_fd_P = feedback(sys_final_P,1);

    end

    if ss_pushbutton == get(handles.ss_radiob,'Max')

        %================= Error If Either A,B,C or D is empty ================
    global a_dou b_dou c_dou d_dou
    if isempty(a_dou) || isempty(b_dou) || isempty(c_dou) || isempty(d_dou)
        errordlg('Please enter all A,B,C and D in correct format');
    end

    %======= Error If the State Space Model is not correct ================
    [r1 c1] = size(a_dou);
    [r2 c2] = size(c_dou);
    [r3 c3] = size(b_dou);
    [r4 c4] = size(d_dou);
        if c1 ~= c2
            errordlg('Please Enter Valid State Space Model');
        end
        if r1 ~= r3
            errordlg('Please Enter Valid State Space Model');
        end
        if c3 ~= c4
            errordlg('Please Enter Valid State Space Model');
        end
        %==================================================================
        global a_dou b_dou c_dou d_dou
        [num den] = ss2tf(a_dou, b_dou ,c_dou ,d_dou);
        sys_tf_ss = tf(num,den);
        sys_final_P = sys_tf_ss * value_dou;
        global sys_fd_P
        sys_fd_P = feedback(sys_final_P,1);

    end

        [s t]= step(sys_final_P);
        axes(handles.axes5)
        plot(t,s),grid on
        set(handles.OLSR_text,'String','P Controller');

        global sys_fd_P
        [s t]= step(sys_fd_P);
        axes(handles.axes6)
        plot(t,s),grid on
        set(handles.CLSR_text,'String','P Controller');

end

%==================== Selecting Proportional Integral Controller ===============

if value == 2
    value_str = get(handles.Kp_edit,'String');
    value_dou = str2num (value_str);

    value_strPi = get(handles.Ki_edit,'String');
    value_douPi = str2num (value_strPi);
    value_tfpi = tf(value_douPi,[1 0]);

    if tf_pushbutton == get(handles.tf_radiob,'Max')

        global sys_tf
        PI = value_dou + value_tfpi;
        sys_final_PI = sys_tf * PI;
        global sys_fd_PI
        sys_fd_PI = feedback(sys_final_PI,1);

    end

    if ss_pushbutton == get(handles.ss_radiob,'Max')

         %================= Error If Either A,B,C or D is empty ================
    global a_dou b_dou c_dou d_dou
    if isempty(a_dou) || isempty(b_dou) || isempty(c_dou) || isempty(d_dou)
        errordlg('Please enter all A,B,C and D in correct format');
    end

    %======= Error If the State Space Model is not correct ================
    [r1 c1] = size(a_dou);
    [r2 c2] = size(c_dou);
    [r3 c3] = size(b_dou);
    [r4 c4] = size(d_dou);
        if c1 ~= c2
            errordlg('Please Enter Valid State Space Model');
        end
        if r1 ~= r3
            errordlg('Please Enter Valid State Space Model');
        end
        if c3 ~= c4
            errordlg('Please Enter Valid State Space Model');
        end
        %==================================================================
        global a_dou b_dou c_dou d_dou
        [num den] = ss2tf(a_dou, b_dou ,c_dou ,d_dou);
        sys_tf_ss = tf(num,den);
        PI = value_dou + value_tfpi;
        sys_final_PI = sys_tf_ss * PI;
        global sys_fd_PI
        sys_fd_PI = feedback(sys_final_PI,1);
    end

     [s t]= step(sys_fd_PI);
     axes(handles.axes6)
     plot(t,s),grid on
     set(handles.CLSR_text,'String','PI Controller');

     [s t]= step(sys_final_PI);
     axes(handles.axes5)
     plot(t,s),grid on
     set(handles.OLSR_text,'String','PI Controller');

end

%==================== Selecting Proportional Derivative Controller ===============

if value == 3
    value_str = get(handles.Kp_edit,'String');
    value_dou = str2num (value_str);

    value_strPd = get(handles.Kd_edit,'String');
    value_douPd = str2num (value_strPd);
    value_tfpd = tf([value_douPd 0],1);

    if tf_pushbutton == get(handles.tf_radiob,'Max')

        global sys_tf
        PD = value_dou + value_tfpd;
        sys_final_PD = sys_tf * PD;
        global sys_fd_PD
        sys_fd_PD = feedback(sys_final_PD,1);
    end

    if ss_pushbutton == get(handles.ss_radiob,'Max')

         %================= Error If Either A,B,C or D is empty ================
    global a_dou b_dou c_dou d_dou
    if isempty(a_dou) || isempty(b_dou) || isempty(c_dou) || isempty(d_dou)
        errordlg('Please enter all A,B,C and D in correct format');
    end

    %======= Error If the State Space Model is not correct ================
    [r1 c1] = size(a_dou);
    [r2 c2] = size(c_dou);
    [r3 c3] = size(b_dou);
    [r4 c4] = size(d_dou);
        if c1 ~= c2
            errordlg('Please Enter Valid State Space Model');
        end
        if r1 ~= r3
            errordlg('Please Enter Valid State Space Model');
        end
        if c3 ~= c4
            errordlg('Please Enter Valid State Space Model');
        end
        %==================================================================
        global a_dou b_dou c_dou d_dou
        [num den] = ss2tf(a_dou, b_dou ,c_dou ,d_dou);
        sys_tf_ss = tf(num,den);
        PD = value_dou + value_tfpd;
        sys_final_PD = sys_tf_ss * PD;
        global sys_fd_PD
        sys_fd_PD = feedback(sys_final_PD,1);
    end

    [s t]= step(sys_fd_PD);
    axes(handles.axes6)
    plot(t,s),grid on
    set(handles.CLSR_text,'String','PD Controller');

    [s t]= step(sys_final_PD);
    axes(handles.axes5)
    plot(t,s),grid on
    set(handles.OLSR_text,'String','PD Controller');
end

%==================== Selecting PID Controller ===============

if value == 4
    value_str = get(handles.Kp_edit,'String');
    value_dou = str2num (value_str);

    value_strPd = get(handles.Kd_edit,'String');
    value_douPd = str2num (value_strPd);
    value_tfpd = tf([value_douPd 0],1);

    value_strPi = get(handles.Ki_edit,'String');
    value_douPi = str2num (value_strPi);
    value_tfpi = tf(value_douPi,[1 0]);

     if tf_pushbutton == get(handles.tf_radiob,'Max')

        global sys_tf
        PID = value_dou + value_tfpi + value_tfpd;
        sys_final_PID = sys_tf * PID;
        global sys_fd_PID
        sys_fd_PID = feedback(sys_final_PID,1);
    end

    if ss_pushbutton == get(handles.ss_radiob,'Max')

         %================= Error If Either A,B,C or D is empty ================
    global a_dou b_dou c_dou d_dou
    if isempty(a_dou) || isempty(b_dou) || isempty(c_dou) || isempty(d_dou)
        errordlg('Please enter all A,B,C and D in correct format');
    end

    %======= Error If the State Space Model is not correct ================
    [r1 c1] = size(a_dou);
    [r2 c2] = size(c_dou);
    [r3 c3] = size(b_dou);
    [r4 c4] = size(d_dou);
        if c1 ~= c2
            errordlg('Please Enter Valid State Space Model');
        end
        if r1 ~= r3
            errordlg('Please Enter Valid State Space Model');
        end
        if c3 ~= c4
            errordlg('Please Enter Valid State Space Model');
        end
        %==================================================================
        global a_dou b_dou c_dou d_dou
        [num den] = ss2tf(a_dou, b_dou ,c_dou ,d_dou);
        sys_tf_ss = tf(num,den);
        PID = value_dou + value_tfpi + value_tfpd;
        sys_final_PID = sys_tf_ss * PID;
        global sys_fd_PID
        sys_fd_PID = feedback(sys_final_PID,1);
    end

    [s t]= step(sys_fd_PID);
    axes(handles.axes6)
    plot(t,s),grid on
    set(handles.CLSR_text,'String','PID Controller');

    [s t]= step(sys_final_PID);
    axes(handles.axes5)
    plot(t,s),grid on
    set(handles.OLSR_text,'String','PID Controller');

end
% --------------------------------------------------------------------
function SRWC_Callback(hObject, eventdata, handles)
% hObject    handle to SRWC (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%====================== Values from Radio Button ======================
tf_pushbutton = get (handles.tf_radiob,'Value');
ss_pushbutton = get(handles.ss_radiob,'Value');

%================= Error If both Options Selected ====================
if ss_pushbutton == get(handles.ss_radiob,'Max') && tf_pushbutton == get(handles.tf_radiob,'Max')
    errordlg('Select One Option from "State Space" or "Transfer Function"');
end

%================= Error If both were not Selected ===================
if ss_pushbutton == get(handles.ss_radiob,'Min') && tf_pushbutton == get(handles.tf_radiob,'Min')
    errordlg('First Enter either "State Space" or "Transfer Function"');
end

%================= Implementing Transfer Function ====================
if tf_pushbutton == get(handles.tf_radiob,'Max') && ss_pushbutton == get(handles.ss_radiob,'Min')
    num= get (handles.num_edit,'string');
    num_dou = str2num(num);

    den= get (handles.den_edit,'string');
    den_dou = str2num(den);

    %================= Error If Either Num or Den is empty ==============
    if isempty(num_dou) || isempty(den_dou)
        errordlg('Please Enter "Transfer Function"');
    end

    sys_tf = tf(num_dou,den_dou);
    figure
    step(sys_tf),title('Step Response Without Controller'),grid on
end

%================= Implementing State Space Model ====================

if ss_pushbutton == get(handles.ss_radiob,'Max') && tf_pushbutton == get(handles.tf_radiob,'Min')

    a= get(handles.A_edit,'String');
    a_dou = str2num(a);

    b= get(handles.B_edit,'String');
    b_dou = str2num(b);

    c= get(handles.C_edit,'String');
    c_dou = str2num(c);

    d= get(handles.D_edit,'String');
    d_dou = str2num(d);

    %================= Error If Either A,B,C or D is empty ==============

    if isempty(a_dou) || isempty(b_dou) || isempty(c_dou) || isempty(d_dou)
        errordlg('Please enter all A,B,C and D');
    end

    sys_ss = ss(a_dou,b_dou,c_dou,d_dou);
    figure
    step(sys_ss),title('Step Response Without Controller'),grid on
end

% --------------------------------------------------------------------
function IRWC_Callback(hObject, eventdata, handles)
% hObject    handle to IRWC (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%====================== Values from Radio Button ======================
tf_pushbutton = get (handles.tf_radiob,'Value');
ss_pushbutton = get(handles.ss_radiob,'Value');

%================= Error If both were not Selected ===================
if ss_pushbutton == get(handles.ss_radiob,'Min') && tf_pushbutton == get(handles.tf_radiob,'Min')
    errordlg('First Enter either "State Space" or "Transfer Function"');
end

%================= Implementing Transfer Function ====================
if tf_pushbutton == get(handles.tf_radiob,'Max') && ss_pushbutton == get(handles.ss_radiob,'Min')
    num= get (handles.num_edit,'string');
    num_dou = str2num(num);

    den= get (handles.den_edit,'string');
    den_dou = str2num(den);

    %================= Error If Either Num or Den is empty ==============
    if isempty(num_dou) || isempty(den_dou)
        errordlg('Please Enter "Transfer Function"');
    end

    sys_tf = tf(num_dou,den_dou);
    figure
    Impulse(sys_tf),title('Impulse Response Without Controller'),grid on
end

%================= Implementing State Space Model ====================

if ss_pushbutton == get(handles.ss_radiob,'Max') && tf_pushbutton == get(handles.tf_radiob,'Min')

    a= get(handles.A_edit,'String');
    a_dou = str2num(a);

    b= get(handles.B_edit,'String');
    b_dou = str2num(b);

    c= get(handles.C_edit,'String');
    c_dou = str2num(c);

    d= get(handles.D_edit,'String');
    d_dou = str2num(d);

    %================= Error If Either A,B,C or D is empty ==============

    if isempty(a_dou) || isempty(b_dou) || isempty(c_dou) || isempty(d_dou)
        errordlg('Please enter all A,B,C and D')
    end

    sys_ss = ss(a_dou,b_dou,c_dou,d_dou);
    figure
    impulse(sys_ss),title('Impulse Response Without Controller'),grid on
end
% --------------------------------------------------------------------
function PZMWC_Callback(hObject, eventdata, handles)
% hObject    handle to PZMWC (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%====================== Values from Radio Button ======================
tf_pushbutton = get (handles.tf_radiob,'Value');
ss_pushbutton = get(handles.ss_radiob,'Value');

%================= Implementing Transfer Function ====================
if tf_pushbutton == get(handles.tf_radiob,'Max') && ss_pushbutton == get(handles.ss_radiob,'Min')
    num= get (handles.num_edit,'string');
    num_dou = str2num(num);

    den= get (handles.den_edit,'string');
    den_dou = str2num(den);

    %================= Error If Either Num or Den is empty ==============
    if isempty(num_dou) || isempty(den_dou)
        errordlg('Please Enter "Transfer Function"');
    end

    sys_tf = tf(num_dou,den_dou);
    figure
    pzmap(sys_tf),title('Pole Zero Map Without Controller'),grid on
end

%================= Implementing State Space Model ====================

if ss_pushbutton == get(handles.ss_radiob,'Max') && tf_pushbutton == get(handles.tf_radiob,'Min')

    a= get(handles.A_edit,'String');
    a_dou = str2num(a);

    b= get(handles.B_edit,'String');
    b_dou = str2num(b);

    c= get(handles.C_edit,'String');
    c_dou = str2num(c);

    d= get(handles.D_edit,'String');
    d_dou = str2num(d);

    %================= Error If Either A,B,C or D is empty ==============

    if isempty(a_dou) || isempty(b_dou) || isempty(c_dou) || isempty(d_dou)
        errordlg('Please enter all A,B,C and D')
    end

    sys_ss = ss(a_dou,b_dou,c_dou,d_dou);
    figure
    pzmap(sys_ss),title('Pole Zero Map Without Controller'),grid on
end
%=====================================================================

% --------------------------------------------------------------------
function SRC_Callback(hObject, eventdata, handles)
% hObject    handle to SRC (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

value = get(handles.PID_popupmenu,'Value');

if value == 1
    global sys_fd_P
    figure,step(sys_fd_P),title('Step Response With Proportional Controller'),grid on
end

if value == 2
    global sys_fd_PI
    figure,step(sys_fd_PI),title('Step Response With Proportional Integral Controller'),grid on
end

if value == 3
    global sys_fd_PD
    figure,step(sys_fd_PD),title('Step Response With Proportional Derivative Controller'),grid on
end

if value == 4
    global sys_fd_PID
    figure,step(sys_fd_PID),title('Step Response With PID Controller'),grid on
end

% --------------------------------------------------------------------
function IRC_Callback(hObject, eventdata, handles)
% hObject    handle to IRC (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

value = get(handles.PID_popupmenu,'Value');

if value == 1
    global sys_fd_P
    figure,impulse(sys_fd_P),title('Impulse Response With Proportional Controller'),grid on
end

if value == 2
    global sys_fd_PI
    figure,impulse(sys_fd_PI),title('Impulse Response With Proportional Integral Controller'),grid on
end

if value == 3
    global sys_fd_PD
    figure,impulse(sys_fd_PD),title('Impulse Response With Proportional Derivative Controller'),grid on
end

if value == 4
    global sys_fd_PID
    figure,impulse(sys_fd_PID),title('Impulse Response With PID Controller'),grid on
end

% --------------------------------------------------------------------
function PZMC_Callback(hObject, eventdata, handles)
% hObject    handle to PZMC (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

value = get(handles.PID_popupmenu,'Value');

if value == 1
    global sys_fd_P
    figure,pzmap(sys_fd_P),title('Pole Zero Map With Proportional Controller'),grid on
end

if value == 2
    global sys_fd_PI
    figure,pzmap(sys_fd_PI),title('Pole Zero Map With Proportional Integral Controller'),grid on
end

if value == 3
    global sys_fd_PD
    figure,pzmap(sys_fd_PD),title('Pole Zero Map With Proportional Derivative Controller'),grid on
end

if value == 4
    global sys_fd_PID
    figure,pzmap(sys_fd_PID),title('Pole Zero Map With PID Controller'),grid on
end

% --------------------------------------------------------------------
function BPWC_Callback(hObject, eventdata, handles)
% hObject    handle to BPWC (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%====================== Values from Radio Button ======================
tf_pushbutton = get (handles.tf_radiob,'Value');
ss_pushbutton = get(handles.ss_radiob,'Value');

%================= Error If both were not Selected ===================
if ss_pushbutton == get(handles.ss_radiob,'Min') && tf_pushbutton == get(handles.tf_radiob,'Min')
    errordlg('First Enter either "State Space" or "Transfer Function"');
end

%================= Implementing Transfer Function ====================
if tf_pushbutton == get(handles.tf_radiob,'Max') && ss_pushbutton == get(handles.ss_radiob,'Min')
    num= get (handles.num_edit,'string');
    num_dou = str2num(num);

    den= get (handles.den_edit,'string');
    den_dou = str2num(den);

    %================= Error If Either Num or Den is empty ================
    if isempty(num_dou) || isempty(den_dou)
        errordlg('Please Enter "Transfer Function"');
    end

    sys_tf = tf(num_dou,den_dou);
    figure
    bode(sys_tf),title('Bode Diagram Without Controller'),grid on
end

%================= Implementing State Space Model =========================

if ss_pushbutton == get(handles.ss_radiob,'Max') && tf_pushbutton == get(handles.tf_radiob,'Min')

    a= get(handles.A_edit,'String');
    a_dou = str2num(a);

    b= get(handles.B_edit,'String');
    b_dou = str2num(b);

    c= get(handles.C_edit,'String');
    c_dou = str2num(c);

    d= get(handles.D_edit,'String');
    d_dou = str2num(d);

    %================= Error If Either A,B,C or D is empty ================

    if isempty(a_dou) || isempty(b_dou) || isempty(c_dou) || isempty(d_dou)
        errordlg('Please enter all A,B,C and D');
    end

    sys_ss = ss(a_dou,b_dou,c_dou,d_dou);
    figure
    bode(sys_ss),title('Bode Diagram Without Controller'),grid on
end
%=====================================================================
% --------------------------------------------------------------------
function NPWC_Callback(hObject, eventdata, handles)
% hObject    handle to NPWC (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%====================== Values from Radio Button ======================
tf_pushbutton = get (handles.tf_radiob,'Value');
ss_pushbutton = get(handles.ss_radiob,'Value');

%================= Error If both were not Selected ===================
if ss_pushbutton == get(handles.ss_radiob,'Min') && tf_pushbutton == get(handles.tf_radiob,'Min')
    errordlg('First Enter either "State Space" or "Transfer Function"');
end

%================= Implementing Transfer Function ====================
if tf_pushbutton == get(handles.tf_radiob,'Max') && ss_pushbutton == get(handles.ss_radiob,'Min')
    num= get (handles.num_edit,'string');
    num_dou = str2num(num);

    den= get (handles.den_edit,'string');
    den_dou = str2num(den);

    %================= Error If Either Num or Den is empty ==============
    if isempty(num_dou) || isempty(den_dou)
        errordlg('Please Enter "Transfer Function"');
    end

    sys_tf = tf(num_dou,den_dou);
    figure
    nyquist(sys_tf),title('Nyquist Plot Without Controller'),grid on
end

%================= Implementing State Space Model ====================

if ss_pushbutton == get(handles.ss_radiob,'Max') && tf_pushbutton == get(handles.tf_radiob,'Min')

    a= get(handles.A_edit,'String');
    a_dou = str2num(a);

    b= get(handles.B_edit,'String');
    b_dou = str2num(b);

    c= get(handles.C_edit,'String');
    c_dou = str2num(c);

    d= get(handles.D_edit,'String');
    d_dou = str2num(d);

    %================= Error If Either A,B,C or D is empty ==============

    if isempty(a_dou) || isempty(b_dou) || isempty(c_dou) || isempty(d_dou)
        errordlg('Please enter all A,B,C and D');
    end

    sys_ss = ss(a_dou,b_dou,c_dou,d_dou);
    figure
    nyquist(sys_ss),title('Nyquist Plot Without Controller'),grid on
end
%=====================================================================

% --------------------------------------------------------------------
function NCWC_Callback(hObject, eventdata, handles)
% hObject    handle to NCWC (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%====================== Values from Radio Button ======================
tf_pushbutton = get (handles.tf_radiob,'Value');
ss_pushbutton = get(handles.ss_radiob,'Value');

%================= Error If both were not Selected ===================
if ss_pushbutton == get(handles.ss_radiob,'Min') && tf_pushbutton == get(handles.tf_radiob,'Min')
    errordlg('First Enter either "State Space" or "Transfer Function"');
end

%================= Implementing Transfer Function ====================
if tf_pushbutton == get(handles.tf_radiob,'Max') && ss_pushbutton == get(handles.ss_radiob,'Min')
    num= get (handles.num_edit,'string');
    num_dou = str2num(num);

    den= get (handles.den_edit,'string');
    den_dou = str2num(den);

    %================= Error If Either Num or Den is empty ==============
    if isempty(num_dou) || isempty(den_dou)
        errordlg('Please Enter "Transfer Function"');
    end

    sys_tf = tf(num_dou,den_dou);
    figure
    nichols(sys_tf),title('Nichols Chat Without Controller'),grid on
end

%================= Implementing State Space Model ====================

if ss_pushbutton == get(handles.ss_radiob,'Max') && tf_pushbutton == get(handles.tf_radiob,'Min')

    a= get(handles.A_edit,'String');
    a_dou = str2num(a);

    b= get(handles.B_edit,'String');
    b_dou = str2num(b);

    c= get(handles.C_edit,'String');
    c_dou = str2num(c);

    d= get(handles.D_edit,'String');
    d_dou = str2num(d);

    %================= Error If Either A,B,C or D is empty ==============

    if isempty(a_dou) || isempty(b_dou) || isempty(c_dou) || isempty(d_dou)
        errordlg('Please enter all A,B,C and D');
    end

    sys_ss = ss(a_dou,b_dou,c_dou,d_dou);
    figure
    nichols(sys_ss),title('Nichols Chat Without Controller'),grid on
end
%=====================================================================

% --------------------------------------------------------------------
function BPC_Callback(hObject, eventdata, handles)
% hObject    handle to BPC (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

value = get(handles.PID_popupmenu,'Value');

if value == 1
    global sys_fd_P
    figure,bode(sys_fd_P),title('Bode Plot With Proportional Controller'),grid on
end

if value == 2
    global sys_fd_PI
    figure,bode(sys_fd_PI),title('Bode Plot With Proportional Integral Controller'),grid on
end

if value == 3
    global sys_fd_PD
    figure,bode(sys_fd_PD),title('Bode Plot With Proportional Derivative Controller'),grid on
end

if value == 4
    global sys_fd_PID
    figure,bode(sys_fd_PID),title('Bode Plot With PID Controller'),grid on
end

% --------------------------------------------------------------------
function NPC_Callback(hObject, eventdata, handles)
% hObject    handle to NPC (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

value = get(handles.PID_popupmenu,'Value');

if value == 1
    global sys_fd_P
    figure,nyquist(sys_fd_P),title('Nyquist Plot With Proportional Controller'),grid on
end

if value == 2
    global sys_fd_PI
    figure,nyquist(sys_fd_PI),title('Nyquist Plot With Proportional Integral Controller'),grid on
end

if value == 3
    global sys_fd_PD
    figure,nyquist(sys_fd_PD),title('Nyquist Plot With Proportional Derivative Controller'),grid on
end

if value == 4
    global sys_fd_PID
    figure,nyquist(sys_fd_PID),title('Nyquist Plot With PID Controller'),grid on
end

% --------------------------------------------------------------------
function NCC_Callback(hObject, eventdata, handles)
% hObject    handle to NCC (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

value = get(handles.PID_popupmenu,'Value');

if value == 1
    global sys_fd_P
    figure,nichols(sys_fd_P),title('Nichols ChartWith Proportional Controller'),grid on
end

if value == 2
    global sys_fd_PI
    figure,nichols(sys_fd_PI),title('Nichols Chart With Proportional Integral Controller'),grid on
end

if value == 3
    global sys_fd_PD
    figure,nichols(sys_fd_PD),title('Nichols Chart With Proportional Derivative Controller'),grid on
end

if value == 4
    global sys_fd_PID
    figure,nichols(sys_fd_PID),title('Nichols Chart With PID Controller'),grid on
end

% --------------------------------------------------------------------
function RLWC_Callback(hObject, eventdata, handles)
% hObject    handle to RLWC (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%====================== Values from Radio Button ======================
tf_pushbutton = get (handles.tf_radiob,'Value');
ss_pushbutton = get(handles.ss_radiob,'Value');

%================= Error If both Options Selected ====================
if ss_pushbutton == get(handles.ss_radiob,'Max') && tf_pushbutton == get(handles.tf_radiob,'Max')
    errordlg('Select One Option from "State Space" or "Transfer Function"');
end

%================= Error If both were not Selected ===================
if ss_pushbutton == get(handles.ss_radiob,'Min') && tf_pushbutton == get(handles.tf_radiob,'Min')
    errordlg('First Enter either "State Space" or "Transfer Function"');
end

%================= Implementing Transfer Function ====================
if tf_pushbutton == get(handles.tf_radiob,'Max') && ss_pushbutton == get(handles.ss_radiob,'Min')
    num= get (handles.num_edit,'string');
    num_dou = str2num(num);

    den= get (handles.den_edit,'string');
    den_dou = str2num(den);

    %================= Error If Either Num or Den is empty ==============
    if isempty(num_dou) || isempty(den_dou)
        errordlg('Please Enter "Transfer Function"');
    end

    sys_tf = tf(num_dou,den_dou);
    figure
    rlocus(sys_tf),title('Root Locus Without Controller')
end

%================= Implementing State Space Model ====================

if ss_pushbutton == get(handles.ss_radiob,'Max') && tf_pushbutton == get(handles.tf_radiob,'Min')

    a= get(handles.A_edit,'String');
    a_dou = str2num(a);

    b= get(handles.B_edit,'String');
    b_dou = str2num(b);

    c= get(handles.C_edit,'String');
    c_dou = str2num(c);

    d= get(handles.D_edit,'String');
    d_dou = str2num(d);

    %================= Error If Either A,B,C or D is empty ==============

    if isempty(a_dou) || isempty(b_dou) || isempty(c_dou) || isempty(d_dou)
        errordlg('Please enter all A,B,C and D');
    end

    sys_ss = ss(a_dou,b_dou,c_dou,d_dou);
    figure
    rlocus(sys_ss),title('Root Locus Without Controller'),grid on
end

% --------------------------------------------------------------------
function RLC_Callback(hObject, eventdata, handles)
% hObject    handle to RLC (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

value = get(handles.PID_popupmenu,'Value');

if value == 1
    global sys_fd_P
    figure,rlocus(sys_fd_P),title('Root Locus With Proportional Controller')
end

if value == 2
    global sys_fd_PI
    figure,rlocus(sys_fd_PI),title('Root Locus With Proportional Integral Controller')
end

if value == 3
    global sys_fd_PD
    figure,rlocus(sys_fd_PD),title('Root Locus With Proportional Derivative Controller')
end

if value == 4
    global sys_fd_PID
    figure,rlocus(sys_fd_PID),title('Root Locus With PID Controller')
end

% --------------------------------------------------------------------

function Untitled_2_Callback(hObject, eventdata, handles)
% hObject    handle to Untitled_2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% --------------------------------------------------------------------
function Untitled_3_Callback(hObject, eventdata, handles)
% hObject    handle to Untitled_3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% --------------------------------------------------------------------
function Untitled_4_Callback(hObject, eventdata, handles)
% hObject    handle to Untitled_4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% --------------------------------------------------------------------

% --- Executes on selection change in TAFR_popupmenu.
function TAFR_popupmenu_Callback(hObject, eventdata, handles)
% hObject    handle to TAFR_popupmenu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns TAFR_popupmenu contents as cell array
%        contents{get(hObject,'Value')} returns selected item from TAFR_popupmenu

% --- Executes during object creation, after setting all properties.
function TAFR_popupmenu_CreateFcn(hObject, eventdata, handles)
% hObject    handle to TAFR_popupmenu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in TAFR_pushb.
function TAFR_pushb_Callback(hObject, eventdata, handles)
% hObject    handle to TAFR_pushb (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% =============== Values from Pop Up menus (Controller and Responses)======

value_response = get(handles.TAFR_popupmenu,'Value');
value = get(handles.PID_popupmenu,'Value');

% =========================================================================

% ========================Proportional Controller =========================
if value ==1

    % ==================== Time Response ==================================

    if value_response == 1
        set(handles.MOlabel_text,'String','Maximum Overshoot >');
        set(handles.PTlabel_text,'String','Peak Time >');
        set(handles.STlabel_text,'String','Settling Time >');

        global sys_fd_P
        order_sys = order(sys_fd_P);
        order_sys_str = num2str(order_sys);
        set(handles.Order_text,'String',order_sys_str);

        [num,den] = tfdata(sys_fd_P);
        [r c] = size(den{1,1});

        if c ~= 3
            set(handles.MO_text,'String','Approximation Not Valid');
            set(handles.PT_text,'String','Approximation Not Valid');
            set(handles.ST_text,'String','Approximation Not Valid');
        end

        roots_sys = roots(den{1,1});
        roots_sys_str = num2str(roots_sys);

        set(handles.roots_text,'String',roots_sys_str);
        den_sp = den{1,1}(1,3);
        wn = sqrt(den_sp);
        den_sp2 = den{1,1}(1,2);
        b = den_sp2/(2*wn);

        if b<=1 && num{1,1}(1,end-1) == 0 && c==3
            MO = exp(-(b*pi)/(sqrt(1-b^2)))*100;
            MO_str = num2str(MO);
            MO_real = strcat(MO_str,' %');
            set(handles.MO_text,'String',MO_real);

            PT = pi/(wn*(sqrt(1-b^2)));
            PT_str = num2str(PT);
            PT_real = strcat(PT_str,' Sec');
            set(handles.PT_text,'String',PT_real);

            ST = 4/(b*wn);
            ST_str = num2str(ST);
            ST_real = strcat(ST_str,' Sec');
            set(handles.ST_text,'String',ST_real);

        else
            set(handles.MO_text,'String','Approximation Not Valid');
            set(handles.PT_text,'String','Approximation Not Valid');
            set(handles.ST_text,'String','Approximation Not Valid');
        end
    end
    % ====================== Frequncy Response ============================

    if value_response ==2
        set(handles.MOlabel_text,'String','Gain Margin >');
        set(handles.PTlabel_text,'String','Phase Margin >');
        set(handles.STlabel_text,'String','Bandwidth >');

        global sys_fd_P
        order_sys = order(sys_fd_P);
        order_sys_str = num2str(order_sys);
        set(handles.Order_text,'String',order_sys_str);

        band = bandwidth(sys_fd_P);
        band_str = num2str(band);
        set(handles.ST_text,'String',band_str);

        [gm pm wcg wcp]=margin (sys_fd_P);
        gm_str = num2str(gm);
        set(handles.MO_text,'String',gm_str);

        pm_str = num2str(pm);
        set(handles.PT_text,'String',pm_str);
    end
end

% ================Proportional Integral Controller ========================

if value ==2

    % ==================== Time Response ==================================

    if value_response == 1
        set(handles.MOlabel_text,'String','Maximum Overshoot >');
        set(handles.PTlabel_text,'String','Peak Time >');
        set(handles.STlabel_text,'String','Settling Time >');

        global sys_fd_PI
        order_sys = order(sys_fd_PI);
        order_sys_str = num2str(order_sys);
        set(handles.Order_text,'String',order_sys_str);

        [num,den] = tfdata(sys_fd_PI);
        [r c] = size(den{1,1});

        if c ~= 3
            set(handles.MO_text,'String','Approximation Not Valid');
            set(handles.PT_text,'String','Approximation Not Valid');
            set(handles.ST_text,'String','Approximation Not Valid');
        end

        roots_sys = roots(den{1,1});
        roots_sys_str = num2str(roots_sys);

        set(handles.roots_text,'String',roots_sys_str);
        den_sp = den{1,1}(1,3);
        wn = sqrt(den_sp);
        den_sp2 = den{1,1}(1,2);
        b = den_sp2/(2*wn);

        if b<=1 && num{1,1}(1,end-1) == 0 && c==3
            MO = exp(-(b*pi)/(sqrt(1-b^2)))*100;
            MO_str = num2str(MO);
            MO_real = strcat(MO_str,' %');
            set(handles.MO_text,'String',MO_real);

            PT = pi/(wn*(sqrt(1-b^2)));
            PT_str = num2str(PT);
            PT_real = strcat(PT_str,' Sec');
            set(handles.PT_text,'String',PT_real);

            ST = 4/(b*wn);
            ST_str = num2str(ST);
            ST_real = strcat(ST_str,' Sec');
            set(handles.ST_text,'String',ST_real);

        else
            set(handles.MO_text,'String','Approximation Not Valid');
            set(handles.PT_text,'String','Approximation Not Valid');
            set(handles.ST_text,'String','Approximation Not Valid');
        end
    end

    % ==================== Frequency Response =============================

    if value_response ==2
        set(handles.MOlabel_text,'String','Gain Margin >');
        set(handles.PTlabel_text,'String','Phase Margin >');
        set(handles.STlabel_text,'String','Bandwidth >');

        global sys_fd_PI
        order_sys = order(sys_fd_PI);
        order_sys_str = num2str(order_sys);
        set(handles.Order_text,'String',order_sys_str);

        band = bandwidth(sys_fd_PI);
        band_str = num2str(band);
        set(handles.ST_text,'String',band_str);

        [gm pm wcg wcp]=margin (sys_fd_PI);
        gm_str = num2str(gm);
        set(handles.MO_text,'String',gm_str);

        pm_str = num2str(pm);
        set(handles.PT_text,'String',pm_str);
    end
end

% ================Proportional Integral Controller =========================

if value ==3

     % ==================== Time Response ==================================

     if value_response == 1
        set(handles.MOlabel_text,'String','Maximum Overshoot >');
        set(handles.PTlabel_text,'String','Peak Time >');
        set(handles.STlabel_text,'String','Settling Time >');

        global sys_fd_PD
        order_sys = order(sys_fd_PD);
        order_sys_str = num2str(order_sys);
        set(handles.Order_text,'String',order_sys_str);

        [num,den] = tfdata(sys_fd_PD);
        [r c] = size(den{1,1});

        if c ~= 3
            set(handles.MO_text,'String','Approximation Not Valid');
            set(handles.PT_text,'String','Approximation Not Valid');
            set(handles.ST_text,'String','Approximation Not Valid');
        end

        roots_sys = roots(den{1,1});
        roots_sys_str = num2str(roots_sys);

        set(handles.roots_text,'String',roots_sys_str);
        den_sp = den{1,1}(1,3);
        wn = sqrt(den_sp);
        den_sp2 = den{1,1}(1,2);
        b = den_sp2/(2*wn);

        if b<=1 && num{1,1}(1,end-1) == 0 && c==3
            MO = exp(-(b*pi)/(sqrt(1-b^2)))*100;
            MO_str = num2str(MO);
            MO_real = strcat(MO_str,' %');
            set(handles.MO_text,'String',MO_real);

            PT = pi/(wn*(sqrt(1-b^2)));
            PT_str = num2str(PT);
            PT_real = strcat(PT_str,' Sec');
            set(handles.PT_text,'String',PT_real);

            ST = 4/(b*wn);
            ST_str = num2str(ST);
            ST_real = strcat(ST_str,' Sec');
            set(handles.ST_text,'String',ST_real);

        else
            set(handles.MO_text,'String','Approximation Not Valid');
            set(handles.PT_text,'String','Approximation Not Valid');
            set(handles.ST_text,'String','Approximation Not Valid');
        end
     end

     % ==================== Frequency Response ============================

     if value_response ==2
         set(handles.MOlabel_text,'String','Gain Margin >');
         set(handles.PTlabel_text,'String','Phase Margin >');
         set(handles.STlabel_text,'String','Bandwidth >');

         global sys_fd_PD
         order_sys = order(sys_fd_PD);
         order_sys_str = num2str(order_sys);
         set(handles.Order_text,'String',order_sys_str);

         band = bandwidth(sys_fd_PD);
         band_str = num2str(band);
         set(handles.ST_text,'String',band_str);

         [gm pm wcg wcp]=margin (sys_fd_PD);
         gm_str = num2str(gm);
         set(handles.MO_text,'String',gm_str);

         pm_str = num2str(pm);
         set(handles.PT_text,'String',pm_str);

     end
end

% ================Proportional Integral Derivative Controller =============

if value ==4

     % ==================== Time Response =================================

     if value_response == 1
        set(handles.MOlabel_text,'String','Maximum Overshoot >');
        set(handles.PTlabel_text,'String','Peak Time >');
        set(handles.STlabel_text,'String','Settling Time >');

        global sys_fd_PID
        order_sys = order(sys_fd_PID);
        order_sys_str = num2str(order_sys);
        set(handles.Order_text,'String',order_sys_str);

        [num,den] = tfdata(sys_fd_PID);
        [r c] = size(den{1,1});

        if c ~= 3
            set(handles.MO_text,'String','Approximation Not Valid');
            set(handles.PT_text,'String','Approximation Not Valid');
            set(handles.ST_text,'String','Approximation Not Valid');
        end

        roots_sys = roots(den{1,1});
        roots_sys_str = num2str(roots_sys);

        set(handles.roots_text,'String',roots_sys_str);
        den_sp = den{1,1}(1,3);
        wn = sqrt(den_sp);
        den_sp2 = den{1,1}(1,2);
        b = den_sp2/(2*wn);

        if b<=1 && num{1,1}(1,end-1) == 0 && c==3
            MO = exp(-(b*pi)/(sqrt(1-b^2)))*100;
            MO_str = num2str(MO);
            MO_real = strcat(MO_str,' %');
            set(handles.MO_text,'String',MO_real);

            PT = pi/(wn*(sqrt(1-b^2)));
            PT_str = num2str(PT);
            PT_real = strcat(PT_str,' Sec');
            set(handles.PT_text,'String',PT_real);

            ST = 4/(b*wn);
            ST_str = num2str(ST);
            ST_real = strcat(ST_str,' Sec');
            set(handles.ST_text,'String',ST_real);

        else
            set(handles.MO_text,'String','Approximation Not Valid');
            set(handles.PT_text,'String','Approximation Not Valid');
            set(handles.ST_text,'String','Approximation Not Valid');
        end
     end

     % ==================== Frequency Response ============================

     if value_response == 2
         set(handles.MOlabel_text,'String','Gain Margin >');
         set(handles.PTlabel_text,'String','Phase Margin >');
         set(handles.STlabel_text,'String','Bandwidth >');

         global sys_fd_PID
         order_sys = order(sys_fd_PID);
         order_sys_str = num2str(order_sys);
         set(handles.Order_text,'String',order_sys_str);

         band = bandwidth(sys_fd_PID);
         band_str = num2str(band);
         set(handles.ST_text,'String',band_str);

         [gm pm wcg wcp]=margin (sys_fd_PID);
         gm_str = num2str(gm);
         set(handles.MO_text,'String',gm_str);

         pm_str = num2str(pm);
         set(handles.PT_text,'String',pm_str);
     end
end


%% about
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                           setup.m
% This file contains all the simulation parameters that can be tuned by the
% user for different test cases. The code in any of the other files
% shouldn't be varied for trying differennt test cases.
%
% Author : Ajinkya Khade, askhade@ncsu.edu
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if ~license('test','optimization_toolbox')
    error('Optimization Toolbox License is needed for running this program.')
end
%% Time parameters

tau  = 0.5;                 % in s, time-lag of lower-level controller
ts   = 0.1;                 % in s, sampling time of system
tsim = 10;                  % in s, simulation time

%% Constraints

% Input
g = 9.81;

umin = -0.5*g;              % in m/s^2, maximum deceleration
umax = 0.25*g;              % in m/s^2, maximum acceleration

% Constraint Modes
% 0 = no constraints; 1 = all;
ineqMode = 1;               % 2 = input constraint only
eqMode   = 1;

chkInputBoundFlag = true;	% input saturation
%% MPC Parameters

% Horizons
Np = 100;                    % Prediction Horizon
Nc = 100;                    % Control Horizon

% Weighting Matrices
Q = eye(3);                  % state weighting matrix
R = eye(1);                  % input weighting matrix
S = eye(3);                  % terminal state weights

%% Initial Conditions
% Legend -
% e0 - initial error vector
%
% sivdMode -
%       0 - SIVD varies linearly with reference trajectory
%       1 - SIVD varies dynamically with range rate
%
% sivdPlotMode -
%       0 - Position is plotted with respect to origin of refrence frame only
%       1 - Position is plotted with respect to tracking vehicle also

e0 = [-110; 30; 0];
sivdMode = 0;
sivdPlotMode = false;

% For Stalled Target Vehicle
a = 0;         % m/s^2
v0 = 0;        % m/s
vdes = 0;      % m/s
Xref = getXref(a, v0, vdes, ts, tsim);      % generate reference trajectory for tracking vehicle

%% Sweep Parameters & Plot Specific Parameters
%
% Legend -
% sweepParamName - names of parameters over which a sweep is being
%                  performed for the required analysis
% sweepParamVals - sets of values to sweep over for the sweepParams
% sweepParamDisp - names to display for the different cases in the sweep
% legendMode     -
%       1 - concatenates name of sweep parameter to display name
%       2 - uses display name as is
% e0             - initial error vector

% Fig 2
sweepParamName = {'ineqMode','chkInputBoundFlag'};
sweepParamVals = {0,false;...
                  0,true;...
                  2,false};
sweepParamDisp = {'unlimited deceleration', ...
                  'saturated deceleration', ...
                  'constrained deceleration'};
legendMode = 2;
e0 = [-110; 30; 0];

% % Fig 3
% sweepParamName = {'sivdMode'};
% sweepParamVals = {0;1};
% sweepParamDisp = {'constant sivd','dynamic sivd'};
% legendMode = 2;
% sivdPlotMode = true;

% % Fig 4
% sweepParamName = {'tau'};
% sweepParamVals = {0.5;0.4;0.6};
% sweepParamDisp = {'0.5','0.4','0.6'};
% legendMode = 1;

% % Fig 5
% e0 = [-110; 10; 0];
% sweepParamName = {'Nc'};
% sweepParamVals = {25;50;75;100};
% sweepParamDisp = {'25','50','75','100'};
% legendMode = 1;

% % Fig 6
% e0 = [-50; 5; 0];
% sweepParamName = {'Q'};
% sweepParamVals = {diag([1  100 1]); ...
%                   eye(3); ...
%                   diag([100 1  1])};
% sweepParamDisp = {'Q_{Vel} = 100*Q_{Pos}'; ...
%                   'Q_{Vel} = Q_{Pos}'; ...
%                   'Q_{Pos} = 100*Q_{Vel}'};
% legendMode = 2;

% % Fig 7
% a = 2;          %m/s^2
% v0 = 10;        % m/s
% vdes = 29;      % m/s
% Xref = getXref(a, v0, vdes, ts, tsim);
%
% e0 = [-50; 20; 0];
% sweepParamName = {'tau'};
% sweepParamVals = {0.25;0.5;0.75};
% sweepParamDisp = {'0.25';'0.5';'0.75'};
% % sweepParamVals = {0.5};
% % sweepParamDisp = {'0.5'};
% legendMode = 1;


%==============================================================================
% This code is part of the Matlab-based toolbox
% FAIR - Flexible Algorithms for Image Registration.
% For details see
% - https://github.com/C4IR and
% - http://www.siam.org/books/fa06/
%==============================================================================
%
% function[x,r] = mfJacobi(x,b,para,steps)
%
% Jacobi smoother for multigrid, see mfvcycle
%==============================================================================

function[x,r] = mfJacobi(x,b,para,steps)

if nargin == 0;
  MGsolver;
  x = 'endOfMinimalExample';
  return;
end;

% n = length(b);
[r,D] = mfAy(x,para);
r     = b - r;

for i=1:steps,
  ss = D\r;
  x = x + para.MGomega*ss;   %x = rmnspace(x,para.Z);
  r = b - mfAy(x,para);      %r = b - rmnspace(mfAu(x,para),para.Z);
%     his(i) = norm(r)/norm(b);
%    figure(2); plot(r); pause
end;

%  figure(1); clf; plot(his);
%  mfilename, keyboard
%==============================================================================


function rho12=rho12(h)
sldata;
limitpoints;
slopes;
rho12=rho1*(T12(h)/T1)^-(1+(g/(m12*R)));


function varargout = imRAG(img, varargin)
%IMRAG Region adjacency graph of a label image
%
%   Usage:
%   ADJ = imRAG(LBLMAP);
%   [NODES, ADJ] = imRAG(LBLMAP);
%   [NODES, ADJ, BNDINDS] = imRAG(LBLMAP);
%
%   ADJ = imRAG(LBLMAP);
%   computes region adjacency graph of the 2D or 3D image LBLMAP.
%   The result is a N-by-2 array, containing 2 indices for each couple of
%   neighbor regions. Two regions are considered as neighbor if they are
%   separated by a black (i. e. with color 0) pixel in the horizontal or
%   vertical direction.
%   ADJ has the format [LBL1 LBL2], LBL1 and LBL2 being vertical arrays the
%   same size.
%
%   LBL1 is given in ascending order, LBL2 is given in ascending order for
%   each LBL1. Ex:
%   [1 2]
%   [1 3]
%   [1 4]
%   [2 3]
%   [2 5]
%   [3 4]
%
%   [NODES, ADJ] = imRAG(LBLMAP);
%   Return two arrays: the first one is a [N-by-2] array containing
%   centroids of the N label region, and ADJ is the adjacency list as
%   previously described.
%   For 3D images, the nodes array is [N-by-3].
%
%   [NODES, ADJ, BNDINDS] = imRAG(LBLMAP);
%   (only for 2D arrays) Also returns for each pair of adjacent regions the
%   linear indices of the boundary pixels or voxels (located in between the
%   two regions). BNDINDS is a cell array with as many cells as the number
%   of rows of the ADJ result.
%
%   ... = imRAG(LBLMAP, GAP);
%   Specifies the gap to use between regions. Default is 1, corresponding
%   to regions connected when they are separating by a single 0 pixel or
%   voxel.
%   Using a GAP equal to 0 may be useful when there is no separation
%   between regions. In this case, the result corresponds to the detection
%   of 4-adjacent regions.
%   Using values of GAP larger than 1 allows for detecting adjacent regions
%   when they are separated by more space. However, some adjacencies may be
%   missed in case of thin structures (See algorithm below).
%
%   Example
%     % Simple example on 2D array
%     img = zeros([7 7]);
%     img(2:3, 2:3) = 1; img(5:6, 2:3) = 2;
%     img(2:3, 5:6) = 3; img(5:6, 5:6) = 4;
%     img
%     img =
%          0     0     0     0     0     0     0
%          0     1     1     0     3     3     0
%          0     1     1     0     3     3     0
%          0     0     0     0     0     0     0
%          0     2     2     0     4     4     0
%          0     2     2     0     4     4     0
%          0     0     0     0     0     0     0
%     imRAG(img)
%     ans =
%          1     2
%          1     3
%          2     4
%          3     4
%
%     % Compute the Skeleton of Influence Zone of disjoint regions
%     % (requires image processing toolbox)
%     % read and display an image with several objects
%     img = imread('coins.png');
%     figure(1); clf;
%     imshow(img); hold on;
%     % compute the Skeleton by influence zones using watershed
%     bin = imfill(img>100, 'holes');
%     dist = bwdist(bin);
%     wat = watershed(dist, 4);
%     % compute overlay image for display
%     tmp = uint8(double(img).*(wat>0));
%     ovr = uint8(cat(3, max(img, uint8(255*(wat==0))), tmp, tmp));
%     imshow(ovr);
%     % show the resulting graph
%     [n, e] = imRAG(wat);
%     for i = 1:size(e, 1)
%         plot(n(e(i,:), 1), n(e(i,:), 2), 'linewidth', 4, 'color', 'g');
%     end
%     plot(n(:,1), n(:,2), 'bo', 'markerfacecolor', 'b');
%
%
%   % Create a basic 3D image with labels, and compute RAG
%     germs = [50 50 50;...
%         20 20 20;80 20 20;20 80 20;80 80 20; ...
%         20 20 80;80 20 80;20 80 80;80 80 80];
%     img = zeros([100 100 100]);
%     for i = 1:size(germs, 1)
%         img(germs(i,1), germs(i,2), germs(i,3)) = 1;
%     end
%     wat = watershed(bwdist(img), 6);
%     [n, e] = imRAG(wat);
%     figure; drawGraph(n, e);
%     view(3);
%
%
%   Algorithms
%   The adjacencies are computed by computing the pairs of pixels or voxels
%   with different values and separated by a given distance in each main
%   direction of the image. When values are different, they areassumed to
%   correspond to the labels of two adjacent regions.
%   Adjacencies are detected in the X and Y directions for 3D images, and
%   in the X, Y and Z directions for 3D images. There is no detection of
%   adjacency in diagonal directions.
%
%   An alternative algorithm would be to compute the result of dilation for
%   each region, and detect which labels intersect the dilated region.
%   The number of image processing operations may be very large, ususally
%   resulting in much slower processing time. The following code computes
%   RAG using a 5-by-5 square for detecting adjacent regions:
%     inds = unique(img)
%     inds(inds == 0) = [];
%     adjList = zeros(0, 2);
%     for i = 1:length(inds)
%         mask = imdilate(img == inds(i), ones(5, 5));
%         neighs = unique(img(mask));
%         neighs = neighs(~ismember(neighs, [0 i]));
%         adjList = [adjList; repmat(i, length(neighs), 1) neighs];
%     end
%     adjList = unique(sort(adjList, 2), 'rows');
%   Note that more adjacencies may be detected compared to with the imRAG
%   function.
%

% ------
% Author: David Legland
% e-mail: david.legland@inra.fr
% Created: 2004-02-20,
% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas.

%   History
%   2007-10-12 update doc
%   2007-10-17 add example
%   2010-03-08 replace calls to regionprops by local centroid computation
%   2010-07-29 update doc
%   2012-07-20 remove the use of "diff", using less memory
%   2017-07-31 return output also when nargin == 0, sort labels in 3D

%% Initialisations

% size of image
dim = size(img);

% number of dimensions
nd = length(dim);

% Number of background pixels or voxels between two regions
% gap = 0 -> regions are contiguous
% gap = 1 -> there is a 1-pixel large line or surface between two adjacent
% 	pixels, for example the result of a watershed
gap = 1;
if ~isempty(varargin) && isnumeric(varargin{1})
    gap = varargin{1};
end
shift = gap + 1;

% flag indicating whether edge indices should be computed
computeEdgeInds = nargout > 2;
if computeEdgeInds && gap ~= 1
    error('imRAG:wrongGapValue', ...
        'Edge indices can only be computed for gap equal to 1');
end

if nd == 2
    %% First direction of 2D image

    % identify transitions
    [i1, i2] = find(img(1:end-shift,:) ~= img((shift+1):end, :));

	% get values of consecutive changes
	val1 = img(sub2ind(dim, i1, i2));
	val2 = img(sub2ind(dim, i1+shift, i2));

    % keep only changes not involving background, ordered such that n1 < n2
    inds = val1 ~= 0 & val2 ~= 0 & val1 ~= val2;
    edges = sort([val1(inds) val2(inds)], 2);

    % keep array of positions as linear indices
    if computeEdgeInds
        posD1 = sub2ind(dim, i1(inds)+1, i2(inds));
    end

    %% Second direction of 2D image

    % identify transitions
    [i1, i2] = find(img(:, 1:end-shift) ~= img(:, (shift+1):end));

	% get values of consecutive changes
	val1 = img(sub2ind(dim, i1, i2));
	val2 = img(sub2ind(dim, i1, i2+shift));

    % keep only changes not involving background, ordered such that n1 < n2
    inds = val1 ~= 0 & val2 ~= 0 & val1 ~= val2;
    edges = [edges ; sort([val1(inds) val2(inds)], 2)];

    if computeEdgeInds
        % keep array of positions as linear indices
        posD2 = sub2ind(dim, i1(inds), i2(inds)+1);
        posList = [posD1 ; posD2];
    end

elseif nd == 3
    %% First direction of 3D image

    % identify transitions
    [i1, i2, i3] = ind2sub(dim-[shift 0 0], ...
        find(img(1:end-shift,:,:) ~= img((shift+1):end,:,:)));

	% get values of consecutive changes
	val1 = img(sub2ind(dim, i1, i2, i3));
	val2 = img(sub2ind(dim, i1+shift, i2, i3));

    % keep only changes not involving background
    inds = val1 ~= 0 & val2 ~= 0 & val1 ~= val2;
    edges = unique(sort([val1(inds) val2(inds)], 2), 'rows');

    if computeEdgeInds
        % keep array of positions as linear indices
        posD1 = sub2ind(dim, i1(inds)+1, i2(inds), i3(inds));
    end

    %% Second direction of 3D image

    % identify transitions
    [i1, i2, i3] = ind2sub(dim-[0 shift 0], ...
        find(img(:,1:end-shift,:) ~= img(:,(shift+1):end,:)));

	% get values of consecutive changes
	val1 = img(sub2ind(dim, i1, i2, i3));
	val2 = img(sub2ind(dim, i1, i2+shift, i3));

    % keep only changes not involving background
    inds = val1 ~= 0 & val2 ~= 0 & val1 ~= val2;
    edges = [edges; unique(sort([val1(inds) val2(inds)], 2), 'rows')];

    if computeEdgeInds
        % keep array of positions as linear indices
        posD2 = sub2ind(dim, i1(inds), i2(inds)+1, i3(inds));
    end

    %% Third direction of 3D image

    % identify transitions
    [i1, i2, i3] = ind2sub(dim-[0 0 shift], ...
        find(img(:,:,1:end-shift) ~= img(:,:,(shift+1):end)));

	% get values of consecutive changes
	val1 = img(sub2ind(dim, i1, i2, i3));
    val2 = img(sub2ind(dim, i1, i2, i3+shift));

    % keep only changes not involving background
    inds = val1 ~= 0 & val2 ~= 0 & val1 ~= val2;
    edges = [edges; unique(sort([val1(inds) val2(inds)], 2), 'rows')];

    if computeEdgeInds
        % keep array of positions as linear indices
        posD3 = sub2ind(dim, i1(inds), i2(inds), i3(inds)+1);
        posList = [posD1 ; posD2 ; posD3];
    end
end

% remove double edges, keeping in indsC indices of merged edge for each
% original edge
[edges, indsA, indsC] = unique(edges, 'rows'); %#ok<ASGLU>

if computeEdgeInds
    nEdges = size(edges, 1);
    edgeInds = cell(nEdges, 1);
    for iEdge = 1:nEdges
        inds = indsC == iEdge;
        edgeInds{iEdge} = unique(posList(inds));
    end
end

%% Output processing

if nargout <= 1
    varargout{1} = edges;

else
    % Also compute region centroids
    N = max(img(:));
    points = zeros(N, nd);
    labels = unique(img);
    labels(labels==0) = [];

    if nd == 2
        % compute 2D centroids
        for i = 1:length(labels)
            label = labels(i);
            [iy, ix] = ind2sub(dim, find(img==label));
            points(label, 1) = mean(ix);
            points(label, 2) = mean(iy);
        end
    else
        % compute 3D centroids
        for i = 1:length(labels)
            label = labels(i);
            [iy, ix, iz] = ind2sub(dim, find(img==label));
            points(label, 1) = mean(ix);
            points(label, 2) = mean(iy);
            points(label, 3) = mean(iz);
        end
    end

    % setup output arguments
    varargout{1} = points;
    varargout{2} = edges;

    % eventually returns the position of edges as third output argument
    if nargout > 2
        varargout{3} = edgeInds;
    end
end


function [At,b,c,K] = opti2sedumi(prob)
%OPTI2SEDUMI  Converts an OPTI Problem (f,A,b,sdcone) to SeDuMi Format
% [At,b,c,K] = opti2sedumi(prob)

%   Copyright (C) 2013 Jonathan Currie (IPL)

%Check not already in sedumi format
if(isfield(prob,'sdcone') && ~isempty(prob.sdcone) && isstruct(prob.sdcone))
    At = getSDMIField(prob.sdcone,'At','A');
    b  = getSDMIField(prob.sdcone,'b','B');
    c  = getSDMIField(prob.sdcone,'c','C');
    K  = getSDMIField(prob.sdcone,'K','k');
    return;
end

%Check we have a linear f
if(~isfield(prob,'f') || isempty(prob.f) || ~isnumeric(prob.f))
    error('The SDP to convert must have a linear objective f in prob.f');
end
b = -prob.f; ndec = length(b);

%Convert linear constraints to general format
if(~isempty(prob.rl) || ~isempty(prob.ru))
    [AA,bb,Aeq,beq] = row2gen(prob.A,prob.rl,prob.ru);
else
    AA = prob.A; bb = prob.b; Aeq = prob.Aeq; beq = prob.beq;
end
%Convert all constraints and bounds to linear inequalities
[At,c] = inequal(AA,bb,Aeq,beq,prob.lb,prob.ub);
K.l = size(At,1);

%Check for Semidefinite constraints, concat as required
if(~isempty(prob.sdcone))
    if(iscell(prob.sdcone))
        for i = 1:length(prob.sdcone)
            chkSDDim(prob.sdcone{i},ndec,i);
            K.s(i) = sqrt(size(prob.sdcone{i},1));
            c = [c;-prob.sdcone{i}(:,1)]; %#ok<AGROW>
            At = [At;-prob.sdcone{i}(:,2:end)]; %#ok<AGROW>
        end
    else
        chkSDDim(prob.sdcone,ndec,1);
        K.s = sqrt(size(prob.sdcone,1));
        c = [c;-prob.sdcone(:,1)];
        At = [At;-prob.sdcone(:,2:end)];
    end
end

%Check for quadratic constraints
if(~isempty(prob.Q)), optiwarn('opti:sedumiQC','Currently quadratic constraints are not converted to SeDuMi format'); end

function chkSDDim(cone,ndec,i)
if(size(cone,2) ~= ndec+1)
    error('Semidefinite Cone %d does not have the correct number of columns',i);
end
dim = sqrt(size(cone,1));
if(floor(dim) ~= dim)
    error('Semidefinite Cone %d does not have the correct number of rows to form a square matrix');
end

function val = getSDMIField(conestr,f1,f2)
if(isfield(conestr,f1))
    val = conestr.(f1);
elseif(isfield(prob.sdcone,f2))
    val = conestr.(f2);
else
    error('It appears the problem is already in SeDuMi format, but OPTI could not find prob.sdcone.%s',f1);
end


function calpak_test77 ( )

%*****************************************************************************80
%
%% CALPAK_TEST77 tests YMDF_TO_WEEKDAY_ENGLISH.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 April 2013
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'CALPAK_TEST77\n' );
  fprintf ( 1, '  For the English calendar:\n' );
  fprintf ( 1, '  YMDF_TO_WEEKDAY_ENGLISH returns the day of the week.\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  JED   YMDF    Day of the week\n' );
  fprintf ( 1, '\n' );

  i = 0;

  while ( 1 )

    i = i + 1;
    jed1 = jed_test ( i );

    if ( jed1 < 0 )
      break
    end

    jed2 = jed_to_next_noon ( jed1 );

    [ y1, m1, d1, f1 ] = jed_to_ymdf_english ( jed2 );
    s1 = ymdf_to_s_english ( y1, m1, d1, f1 );

    w2 = ymdf_to_weekday_english ( y1, m1, d1, f1 );
    s2 = weekday_to_name_common ( w2 );

    fprintf ( 1, '  %11.2f  %20s  %2d  %20s\n', jed2, s1, w2, s2 );

  end

  return
end


  function d = max_percent_diff(s1, s2, varargin)
%|function d = max_percent_diff(s1, s2, [options])
%|
%| compute the "maximum percent difference" between two signals: s1, s2
%| options
%|	1		use both arguments as the normalizer
%|	string		print this
%|
%| Copyright 2000-9-16, Jeff Fessler, University of Michigan

if nargin == 1 && streq(s1, 'test'), max_percent_diff_test, return, end
if nargin < 2, ir_usage, end

base = '';

if ischar(s1)
	t1 = s1;
	s1 = evalin('caller', t1);
	base = [caller_name ': '];
else
	t1 = inputname(1);
end
if ischar(s2)
	t2 = s2;
	s2 = evalin('caller', t2);
else
	t2 = inputname(2);
end

use_both = 0;
doprint = (nargout == 0);
while (length(varargin))
	arg1 = varargin{1};
	if isnumeric(varargin{1})
		use_both = 1;
		varargin = {varargin{2:end}};
		continue
	end

	if ischar(arg1)
		doprint = 1;
		base = [arg1 ': '];
		varargin = {varargin{2:end}};
		continue
	end
end

% first check that we have comparable signals!
if ~isequal(size(s1), size(s2))
	printm(['size(%s) = %s'], inputname(1), mat2str(size(s1)))
	printm(['size(%s) = %s'], inputname(2), mat2str(size(s2)))
	error 'dimension mismatch'
end

if any(isnan(s1(:)))
	warn([mfilename ': NaN values in %s in %s!?'], t1, caller_name)
end
if any(isnan(s2(:)))
	warn([mfilename ': NaN values in %s in %s!?'], t2, caller_name)
end
s1 = doubles(s1);
s2 = doubles(s2);

if use_both
	denom = max(abs([s1(:); s2(:)]));
	if ~denom
		d = 0;
	else
		d = max(abs(s1(:)-s2(:))) / denom;
	end
else
	denom = max(abs(s1(:)));
	if ~denom
		denom = max(abs(s2(:)));
	end
	if ~denom
		d = 0;
	else
		d = max(abs(s1(:)-s2(:))) / denom;
	end
end

d = full(d) * 100;

if doprint
	printf([base 'max_percent_diff(%s, %s) = %g%%'], t1, t2, d)
	if ~nargout
		clear d
	end
end

%
% max_percent_diff_test
%
function max_percent_diff_test
v1 = [0 1000];
v2 = [0 1001];
max_percent_diff([0 1000], [1 1000])
max_percent_diff(v1, v2, 'numeric')
max_percent_diff '[0 1000]' '[1 1000]'


%% Demo to show the results of the Ultrametric Contour Map obtained by MCG
clear all;close all;home;

% Read an input image
I = imread(fullfile(root_dir, 'demos','101087.jpg'));

tic;
% Test the 'fast' version, which takes around 3 seconds in mean
ucm2_scg = im2ucm(I,'fast');
toc;

tic;
% Test the 'accurate' version, which tackes around 25 seconds in mean
ucm2_mcg = im2ucm(I,'accurate');
toc;

%% Show UCM results (dilated for visualization)
figure;
subplot(1,3,1)
imshow(I), title('Image')

subplot(1,3,2)
imshow(imdilate(ucm2_scg,strel(ones(3))),[]), title('Fast UCM (SCG)')

subplot(1,3,3)
imshow(imdilate(ucm2_mcg,strel(ones(3))),[]), title('Accurate UCM (MCG)')


function x = fgplvmOptimisePoint(model, x, y, display, iters)

% FGPLVMOPTIMISEPOINT Optimise the postion of a latent point.
% FORMAT
% DESC optimises the location of a single point in latent space
% given an initialisation and an observed data point. Note that it
% ignores any dynamics present in the model.
% ARG model : the model for which the point will be optimised.
% ARG x : the initialisation of the point in the latent space.
% ARG y : the observed data point for which the latent point is to
% be optimised.
% ARG display : whether or not to display the iterations of the
% optimisation (default: true)
% ARG iters : maximum number of iterations for the optimisation
% (default 2000).
% RETURN x : the optimised location in the latent space.
%
% COPYRIGHT : Neil D. Lawrence, 2005, 2006
%
% SEEALSO : fgplvmCreate, fgplvmOptimiseSequence, fgplvmPointObjective, fgplvmPointGradient

% FGPLVM

if nargin < 5
  iters = 2000;
  if nargin < 4
    display = true;
  end
end

options = optOptions;
if display
  options(1) = 1;
  options(9) = 1;
end
options(14) = iters;

if isfield(model, 'optimiser')
  optim = str2func(model.optimiser);
else
  optim = str2func('scg');
end

if strcmp(func2str(optim), 'optimiMinimize')
  % Carl Rasmussen's minimize function
  x = optim('fgplvmPointObjectiveGradient', x, options, model, y);
else
  % NETLAB style optimization.
  x = optim('fgplvmPointObjective', x,  options, ...
            'fgplvmPointGradient', model, y);
end


%%***************************************************************************
%% blkeig: compute eigenvalue decomposition of a cell array
%%         whose contents are square matrices or the diagonal
%%         of a diagonal matrix.
%%
%% [d,V] = blkeig(blk,X);
%%
%% SDPT3: version 3.1
%% Copyright (c) 1997 by
%% K.C. Toh, M.J. Todd, R.H. Tutuncu
%% Last Modified: 16 Sep 2004
%%***************************************************************************

function [d,V] = blkeig(blk,X)

spdensity = 0.5;

if ~iscell(X);
    if strcmp(blk{1},'s');
        blktmp = blk{2};
        if (length(blktmp) == 1);
            if (nargout == 1);
                d = eig(full(X));
            elseif (nargout == 2);
                [V,d] = eig(full(X));
                d = diag(d);
            end
        else
            if (nargout == 2);
                V = sparse(length(X),length(X));
            end
            d = zeros(sum(blktmp),1);
            xx = mexsvec(blk,X,0);
            blktmp2 = blktmp.*(blktmp+1)/2;
            s2 = [0, cumsum(blktmp2)];
            blksub{1,1} = 's'; blksub{1,2} = 0;
            s = [0, cumsum(blktmp)];
            for i = 1:length(blktmp)
                pos = s(i)+1 : s(i+1);
                blksub{2} = blktmp(i);
                Xsub = mexsmat(blksub,xx(s2(i)+1:s2(i+1)),0);
                if (nargout == 1);
                    lam = eig(Xsub);
                elseif (nargout == 2);
                    [evec,lam] = eig(Xsub);
                    lam = diag(lam);
                    V(pos,pos) = sparse(evec); %#ok
                end
                d(pos,1) = lam;
            end
        end
        n2 = sum(blktmp.*blktmp);
        if (nargout == 2);
            if (nnz(V) <= spdensity*n2);
                V = sparse(V);
            else
                V = full(V);
            end
        end
    elseif strcmp(blk{1},'l');
        if (nargout == 2);
            V = ones(size(X)); d = X;
        elseif (nargout == 1);
            d = X;
        end
    end
else
    if (nargout == 2);
        V = cell(size(X));  d = cell(size(X));
        for p = 1:size(blk,1);
            [d{p},V{p}] = blkeig(blk(p,:),X{p});
        end
    elseif (nargout == 1);
        d = cell(size(X));
        for p = 1:size(blk,1);
            d{p} = blkeig(blk(p,:),X{p});
        end
    end
end
%%***************************************************************************


function [ new_pop ] = selection(old_pop, new_pop)
%   Applies tournament selection to generate a child population
%   We did not vectorize this function as we want to keep this procedure
%   separate from those of the crossover and the mutation. Otherwise
%   implementation of different kind of selection strategy will not be
%   straight forward.

global nreal ;
global nbin ;
global nbits ;
global min_binvar ;
global max_binvar ;
global pcross_bin ;
global min_realvar ;
global max_realvar ;
global pcross_real ;
global eta_c ;

[popsize,~] = size(old_pop);

old_pop =  old_pop(randperm(end),:);
% old_pop =  shuffle(old_pop); % SLOW !!!
for i = 1:4:popsize
    p1i = tournament(old_pop,i,  i+1);
    p2i = tournament(old_pop,i+2,i+3);
    if(nreal > 0)
        [c1, c2] = real_cross(old_pop(p1i,1:nreal), ...
                                old_pop(p2i,1:nreal), ...
                                pcross_real, eta_c, ...
                                min_realvar, max_realvar);
    elseif(nbin > 0)
        [c1, c2] = bin_cross_two_point(old_pop(p1i, 1:sum(nbits)), ...
                                old_pop(p2i, 1:sum(nbits)), ...
                                nbits, pcross_bin);
    end
    new_pop(i,  1:nreal) = c1 ;
    new_pop(i+1,1:nreal) = c2 ;
    p1i = tournament(old_pop,i,  i+1);
    p2i = tournament(old_pop,i+2,i+3);
    if(nreal > 0)
            [c1, c2] = real_cross(old_pop(p1i,1:nreal), ...
                                    old_pop(p2i,1:nreal), ...
                                    pcross_real, eta_c, ...
                                    min_realvar, max_realvar);
    elseif(nbin > 0)
            [c1, c2] = bin_cross_two_point(old_pop(p1i,1:sum(nbits)), ...
                                    old_pop(p2i,1:sum(nbits)), ...
                                    pcross_bin);
    end
    new_pop(i+2,1:nreal) = c1 ;
    new_pop(i+3,1:nreal) = c2 ;
end
end

function [shuffled_pop] = shuffle(pop)
%   This function uses the legacy rng for shuffling,
%   but too slow.
    [popsize,cols] = size(pop);
    shuffled_pop = zeros(popsize,cols);
    for i = 1:popsize
        shuffled_pop(i,:) = pop(rnd(1,popsize),:);
    end
end


function L = hash2landmark(H)
% L = hash2landmark(H)
%  Convert a set of <time hash> pairs ready from store
%  into a set of 4-entry landmarks <t1 f1 f2 dt>.
%  If H is 3 cols, first col (song ID) is discarded.
% 2008-12-29 Dan Ellis dpwe@ee.columbia.edu

% Hash value is 20 bits: 8 bits of F1, 6 bits of F2-F1, 6 bits of delta-T

%H = uint32(L(:,1));
%F1 = rem(round(L(:,2)),2^7);
%F2 = rem(round(L(:,4)),2^7);
%DT = rem(abs(round(L(:,3) - L(:,1))), 2^6);
%H = [H,uint32(F1*(2^13)+F2*(2^6)+DT)];

if size(H,2) == 3
  H = H(:,[2 3]);
end

H1 = H(:,1);
H2 = double(H(:,2));
F1 = floor(H2/(2^12));
H2 = H2 - (2^12)*F1;
F1 = F1 + 1;
DF = floor(H2/(2^6));
H2 = H2 - (2^6)*DF;
if DF > 2^5
  DF = DF-2^6;
end
F2 = F1+DF;

DT = H2;

L = [H1,F1,F2,DT];


function [F,X] = spm_fp_display_density(M,x)
% Quiver plot of flow and equilibrium density
% FORMAT [F,X] = spm_fp_display_density(M,x)
%
% M   - model specifying flow; M(1).f;
% x   - cell array of domain or support
%
% F   - flow
% X   - evaluation points
%__________________________________________________________________________
% Copyright (C) 2005-2013 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: spm_fp_display_density.m 5219 2013-01-29 17:07:07Z spm $

% evaluation points and equilibria
%--------------------------------------------------------------------------
n             = length(x);
[M0,q0,X,x,F] = spm_fp(M,x);

% flow fields
%--------------------------------------------------------------------------
for i = 1:n
    f(i,:) = F(i,:)/max(eps + abs(F(i,:)));
end

% flow and density
%==========================================================================
f  = f';

% eliminate first state if 3-D
%--------------------------------------------------------------------------
if n == 3
    q     = q0;
    q     = squeeze(sum(q,1));
    q     = squeeze(sum(q,1));
    [m,j] = max(q);
    q0    = squeeze(sum(q0,3));
    k     = find(X(:,3) == x{3}(j));
    X     = X(k,[1 2]);
    f     = f(k,[1 2]);
    x     =   x([1 2]);
end

% thin out arrows for quiver
%--------------------------------------------------------------------------
k     = 1;
for i = 1:2
    nx = length(x{i});
    d  = fix(nx/16);
    k  = kron(k,kron(ones(1,nx/d),sparse(1,1,1,1,d)));
end
k     =  find(k);

% flow and density
%--------------------------------------------------------------------------
imagesc(x{1},x{2},1 - q0'), hold on

quiver(X(k,1),X(k,2),f(k,1),f(k,2),'r'),  hold off
axis square xy
drawnow


function [M, P, B, A, PS] = matrix(disc, dim, domain)
%MATRIX    Convert operator to matrix using COLLOC discretization.
%   MATRIX(DISC) uses the parameters in DISC to discretize DISC.source as a
%   matrix using COLLOC.
%
%   MATRIX(DISC, DIM, DOMAIN) overrides the native 'dimension' and 'domain'
%   properties in DISC.
%
%   [PA, P, B, A, PS] = MATRIX(...) returns the projection matrix P, the
%   boundary matrix B, the unprojected cell array of square discretizations A,
%   and the projected conversion matrices PS.
%
% See also INSTANTIATE.

% Copyright 2017 by The University of Oxford and The Chebfun Developers.
% See http://www.chebfun.org/ for Chebfun information.

% Parse inputs
if ( nargin > 1 )
    disc.dimension = dim;
end
if ( nargin > 2 )
    disc.domain = domain;
end

% Check subinterval compatibility of domain and dimension.
if ( (length(disc.domain) - 1) ~= length(disc.dimension) )
    if ( length(disc.dimension == 1 ) )
        dim = disc.dimension;
        dom = disc.domain;
        disc.dimension = repmat(dim,1,length(dom)-1);
    else
        error('CHEBFUN:OPDISCRETIZATION:matrix:subIntDim', ...
            'Must specify one dimension value for each subinterval.')
    end
end

if ( nargout > 1 && ~isa(disc.source, 'linop') )
    error('CHEBFUN:OPDISCRETIZATION:matrix:matrix', ...
        'MATRIX() of a %s can only return one output.', class(disc.source))
end

if ( any(isinf(disc.domain)) )
    error('CHEBFUN:OPDISCRETIZATION:matrix:isinf', ...
        'Discretization on unbounded domains is not supported.');
end

% Construct a square representation of each block individually and
% store in a cell array.
[A, S] = instantiate(disc);

% We want output on different format depending on whether the source L is a
% LINOP or something else (typically a standard CHEBMATRIX):
if ( isa(disc.source, 'linop') )

    % Project rows down, and record the projection matrix as well.
    [PA, P, PS] = reduce(disc, A, S);

    % Get constraints:
    B = getConstraints(disc);

    % This should restore squareness to the final matrix.
    M = [ B ; PA ];

else

    % Everything should be of the same dimension.
    if ( iscell(A) )
        M = cell2mat(A);
    else
        M = A;
    end

end

end


function sudoku_test06 ( )

%*****************************************************************************80
%
%% SUDOKU_TEST06 demonstrates SUDOKU_ROTATE.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 February 2006
%
%  Author:
%
%    John Burkardt
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'SUDOKU_TEST06:\n' );
  fprintf ( 1, '  SUDOKU_ROTATE rotates a Sudoku by 90 degrees;\n' );

  s = [ ...
       3,4,1,9,2,7,5,6,8; ...
       6,9,2,1,8,5,7,3,4; ...
       8,5,7,4,6,3,1,9,2; ...
       1,3,4,2,9,6,8,7,5; ...
       2,7,8,5,3,4,6,1,9; ...
       5,6,9,7,1,8,4,2,3; ...
       4,2,5,3,7,1,9,8,6; ...
       9,1,6,8,4,2,3,5,7; ...
       7,8,3,6,5,9,2,4,1];

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Here is the initial Sudoku puzzle:\n' );
  fprintf ( 1, '\n' );

  sudoku_print ( s );

  s = sudoku_rotate ( s );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Here is the rotated Sudoku:\n' );
  fprintf ( 1, '\n' );

  sudoku_print ( s );

  s = sudoku_rotate ( s );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Here is the rotated Sudoku:\n' );
  fprintf ( 1, '\n' );

  sudoku_print ( s );

  s = sudoku_rotate ( s );

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Here is the rotated Sudoku:\n' );
  fprintf ( 1, '\n' );

  sudoku_print ( s );

  return
end


function title = p07_title ( )

%*****************************************************************************80
%
%% P07_TITLE returns the title of problem p07.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    06 August 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, string TITLE, the title of the problem.
%
  title = 'f(x) = exp ( 2 x ) if x < 0.5, 0 otherwise';

  return
end


% example_mri_rf_spsp
% This script is an example of spectral-spatial pulse design for
% through-plane phase precompensatory slice selection for T2*-weighted
% functional MR, based on our publication:
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Spectral-spatial RF pulse design script, based on "Spectral-spatial RF
% pulse design for through-plane phase precompensatory slice selection for
% T2*-weighted functional MRI", Chun-yu Yip et al, Magnetic Resonance in
% Medicine, May 2009.  doi 10.1002/mrm.21938
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Written by Chun-yu Yip, University of Michigan, Ann Arbor, 4/1/2009
%
% Running this script requires that the entire image reconstruction toolbox
% by Professor Jeffrey A. Fessler be installed first:
%
% http://web.eecs.umich.edu/~fessler/code/index.html
%
% You can conveniently download the whole package at
%
% http://www.eecs.umich.edu/~fessler/irt/fessler.tgz
%
% and use the unix command 'tar' to retrieve the files and folders.
% Use the "setup.m" command in the toolbox to set up paths first.

% Load pulse design parameters into matlab structures kp, rfp, iop.
if ~isvar('kp'), printm 'Loading parameters...'
	[kp, iop, rfp] = example_spsp_param1();
	iop.writetofile_scanner = false; % comment out to create scanner files
%	iop.writetofile_sim = true;
end

% Design z-gradient waveform, based on parameters in kp.
if ~isvar('gz'), printm 'Designing z gradient waveform...'
	[kp gz kz kf t] = compute_gz_spsp(kp);

	if 1 % display gradient waveform
		clf, pl = @(i) subplot(340+i);
		pl(1)
		plot(t*1000, gz), axis tight
		xlabel('time (msec)')
		ylabel('g/cm')
		title('Gz waveform')
		grid
	drawnow
	end
end

% Design complex-valued RF waveform iteratively using conjugate gradient
if ~isvar('b'), printm 'Computing RF pulse waveform...'
	[b d f z mm] = compute_rf_spsp_mgh(kp, rfp, gz, kz, kf);

	ir_mri_rf_spsp_plot(b, gz, d, f, z, mm, t) % display results
	drawnow

	% Write computed waveforms to files for simulation and/or scanner.
	if iop.writetofile_scanner || iop.writetofile_sim
		iop.waveformfilespath = './o/'; % put output in a subdirectory
		if ~exist(iop.waveformfilespath, 'dir')
			fail('must create output directory "%s"', iop.waveformfilespath)
		end
		write2files_spsp(kp, rfp, iop, gz, b);
	end
end

% Perform Bloch simulation in SPSP space
if ~isvar('mresult'), printm 'Performing Bloch simulation...'
	mresult = dosim7_spsp(kp, rfp, iop);
end


function inspect_menu_viewpoint

% Some of the FT_PLOT_XXX functions that return a 3D object support a
% right-mouse-click context menu with which you can select
% top/bottom/left/right/front/back. This functionality requires that the object being
% plotted has a known coordinate system.

% note that the objects don't really go together, so it does not fit 100%

figure

%%

elec = ft_read_sens('GSN-HydroCel-128.sfp');
elec = ft_convert_units(elec, 'mm');
elec.coordsys = 'ras';

ft_plot_sens(elec, 'label', 'label'); axis off

%%

mesh = ft_read_headshape('cortex_8196.surf.gii');
mesh.coordsys = 'mni';

ft_plot_mesh(mesh, 'facealpha', 0.5, 'unit', 'mm')
lighting gouraud

%%
% dipole pointing to anterior and superior

ft_plot_dipole([40 0 50], [0 1 1], 'coordsys', 'ras', 'unit', 'mm', 'axes', true)

%%

ft_plot_topo3d(elec.elecpos, elec.elecpos(:,3), 'coordsys', 'ras', 'unit', 'mm', 'axes', true)