function varargout = IB_LU_GUI(varargin)
% IB_LU_GUI M-file for IB_LU_GUI.fig
%      IB_LU_GUI, by itself, creates a new IB_LU_GUI or raises the existing
%      singleton*.
%
%      H = IB_LU_GUI returns the handle to a new IB_LU_GUI or the handle to
%      the existing singleton*.
%
%      IB_LU_GUI('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in IB_LU_GUI.M with the given input arguments.
%
%      IB_LU_GUI('Property','Value',...) creates a new IB_LU_GUI or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before IB_LU_GUI_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to IB_LU_GUI_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 IB_LU_GUI

% Last Modified by GUIDE v2.5 31-Aug-2012 10:23:35

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


% --- Executes just before IB_LU_GUI is made visible.
function IB_LU_GUI_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 IB_LU_GUI (see VARARGIN)
clear global
% Choose default command line output for IB_LU_GUI
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes IB_LU_GUI wait for user response (see UIRESUME)
% uiwait(handles.figure1);
global tol;
global count;
global reenterA;
global A_k;
global n;
global L;
global U;
global structure;

structure = 0;
reenterA = 0;
count=1;

n=5;
A_k=rand(n);
set(handles.inpmatA,'String',sprintf('rand(%d)',n));

L = zeros(n);
U = zeros(n);

colourmatrix(handles.axes3,A_k,A_k)
    
tol = 1e-8;


axis(handles.axes1,'off');
axis(handles.axes2,'off');
axis(handles.axes3,'off');

end



% --- Outputs from this function are returned to the command line.
function varargout = IB_LU_GUI_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;
end


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


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




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

% --- Executes on button press in pushbutton_next.
function pushbutton_next_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton_next (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global count;
global n;
global reenterA;

if reenterA == 0;
    if count < n
       switch2ax1(handles)
       switch2ax2(handles)
       switch2ax3(handles)
       count = count + 1;
       set(handles.counter,'String',count);
    elseif count == n;
       set(handles.counter,'String',count);
       switch2ax1(handles)
       switch2ax2(handles)
       set(handles.text9,'String','Finished!');
       set(handles.pushbutton_next,'String','Finished!');
       set(handles.pushbutton_next,'Enable','off');
       delete(allchild(handles.axes3));
    end
end
end

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



function inpmatA_Callback(hObject, eventdata, handles)
% hObject    handle to inpmatA (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 inpmatA as text
%        str2double(get(hObject,'String')) returns contents of inpmatA as a double
global A_k;
global L;
global U;
global reenterA;
global n;
global count;
count=1;
%Reset everything
reenterA = 1;
set(handles.pushbutton_next,'string','Next');
set(handles.text9,'string','');
set(handles.counter,'string','1');
delete(allchild(handles.axes1))
delete(allchild(handles.axes2))
delete(allchild(handles.axes3))

try
    str = get(hObject,'String');
    matr = str2num(str);
    [n,m] = size(matr);
    assert(ndims(matr)==2 && n==m && n >= 2 && n <= 50 && isreal(matr),...
    'A must be a real square matrix of size at least 2 and at most 50!');

    A_k=matr;
    colourmatrix(handles.axes3,A_k,A_k);
    L = zeros(n);
    U = zeros(n);
    reenterA = 0;
    set(handles.pushbutton_next,'Enable','on');
catch err
    set(handles.pushbutton_next,'Enable','off');
    h=msgbox(err.message,'Error','error','modal');
    waitfor(h);
end
end

% --- Executes during object creation, after setting all properties.
function inpmatA_CreateFcn(hObject, eventdata, handles)
% hObject    handle to inpmatA (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
end


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

% Hint: get(hObject,'Value') returns toggle state of checkbox1
global reenterA
global structure
global A_k
global L
global U
global count
global n
if reenterA == 1
    %Problem with input matrix, do nothing!
else
    structure = get(hObject,'value');
    if count > 1;
        colourmatrix(handles.axes1,L,L)
        colourmatrix(handles.axes2,U,U)
    end
    if count < n
        colourmatrix(handles.axes3,A_k,A_k)
    end
end    
end

function switch2ax1(handles)

global L;
global A_k;
global count;
global n;

if count <= n
    if A_k(count,count) == 0
            h=msgbox(...
            'A does not have an LU factorisation without pivoting',...
            'Error','error','modal');
            waitfor(h);
            count=n-1;
            n=0; % ensure that count > n
            set(handles.pushbutton_next,'Enable','off');
    else
        L(:,count) = A_k(:,count)./A_k(count,count);
        colourmatrix(handles.axes1,L,L);
    end
end
end

function switch2ax2(handles)

global U;
global A_k;
global count;
global n;

if count <= n
    U(count,:) = A_k(count,:);

    colourmatrix(handles.axes2,U,U);
end
end

function switch2ax3(handles)

global L;
global U;
global A_k;
global count;
global n;

if count <= n
    A_k = A_k - L(:,count)*U(count,:);

    colourmatrix(handles.axes3,A_k,A_k)
end
end

function[A] = matrix_bwrg(M,Q)
%M must be a square matrix.
global tol;
[n,~] = size(M);

A=zeros(n);

for i = 1:n;
    for j = 1:n;
        if abs(M(i,j) - Q(i,j)) >  tol
           A(i,j) = 0.5;
        else
            if abs(M(i,j)) < tol;
                A(i,j) = 1;
            else
                A(i,j) = 0;
            end
        end
    end
end

end


function colourmatrix(ax,mat,matprevious)
[n,~] = size(mat);
global tol
global structure

% correct signs of zeros in mat
for i = 1:size(mat);
    for j = 1:size(mat);
        if abs(mat(i,j)) < tol
            mat(i,j) = 0;
        end
    end
end

textStrings = num2str(mat(:),'%0.1f'); % Create strings from matrix values 
textStrings = strtrim(cellstr(textStrings)); % Remove any space padding 

B = matrix_bwrg(mat,matprevious);

h=imshow(B,[0 1],'Parent',ax);            % Plot the image 
set(h,'HitTest','off');

if structure == 0
    [x,y] = meshgrid(1:n);   % Create x and y coordinates for the strings 


    hStrings = text(x(:),y(:),textStrings(:),...      % Plot the strings 
                    'HorizontalAlignment','center',...
                    'Parent',ax,...
                    'FontUnits','Normalized',...
                    'HitTest','off');

    textColors = repmat(B(:)==0,1,3); % Choose white or black for the 
                                      % text color of the strings so 
                                      % they can be easily seen over 
                                      % the background color 
    % The trick: first compare with zero to flip 1 to 0, 0 and 0.5 to 1.
    % Then repeat value 3 times horizonally to get a color.
    
    set(hStrings,{'Color'},num2cell(textColors,2)); % Change text colors
end
set(ax,'XTick',[],...  % Change the axes tick marks 
       'YTick',[]);
axis(ax,'image');

end
