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

% Last Modified by GUIDE v2.5 02-Aug-2012 12:06:28

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


% --- Executes just before interp_GUI is made visible.
function interp_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 interp_GUI (see VARARGIN)

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

% Update handles structure
guidata(hObject, handles);

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

% P R E S E T S %
global nodes
nodes = 10;
set(handles.node,'string',10)
global f
f = @(x) 1./(x.^2+1);
set(handles.funct,'string',' 1./(x.^2+1)')

global arr
arr = [];

set(handles.uipanel1,'SelectedObject',[])
axes(handles.equi)
axis off
axes(handles.cheby)
axis off
axes(handles.custom)
axis off
axes(handles.error)
axis off

set(handles.radiobutton1, 'Value', 1.0);
t = -5:0.01:5;
x_equi = linspace(-5,5,nodes);
plot(handles.error,t, abs(f(t) - lagrangepoly(x_equi,f(x_equi), t)),'r-');

global switcher 
switcher = 4;

pushbutton1_Callback(hObject, eventdata, handles)


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


% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global f
global nodes
n = nodes;
t = [-5:0.01:5];

x_equi = linspace(-5,5,n);
x_cheby = 5*cos( (2* (0:n-1)+1) / (2*n) * pi );

% Create equispaced plot in proper axes
plot(handles.equi,t,f(t),'b',t, lagrangepoly(x_equi,f(x_equi), t),'r',x_equi,f(x_equi),'ko')

% Create cheby plot in proper axes
plot(handles.cheby,t,f(t),'b',t,lagrangepoly(x_cheby,f(x_cheby), t),'r',x_cheby,f(x_cheby),'ko')

% Create custom plot in proper axes
reset_Callback(hObject, eventdata, handles)

% --- Executes on button press in radiobutton1.
function radiobutton1_Callback(hObject, eventdata, handles)
% hObject    handle to radiobutton1 (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 radiobutton1


% --- Executes on button press in radiobutton2.
function radiobutton2_Callback(hObject, eventdata, handles)
% hObject    handle to radiobutton2 (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 radiobutton2


% --- Executes on button press in radiobutton3.
function radiobutton3_Callback(hObject, eventdata, handles)
% hObject    handle to radiobutton3 (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 radiobutton3


% --- Executes on mouse press over axes background.
function custom_ButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to custom (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --- Executes on mouse press over figure background.
function figure1_ButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global arr
global f
global switcher

[x, ~] = ginput(1);
if( x < 5 && x > -5 )
    arr = [arr x];
    t = [-5:0.01:5];
    b = plot(handles.custom,t,f(t),'b',t,lagrangepoly(arr,f(arr), t),'r',arr,f(arr),'ko');
    set(b,'hittest','off');
    set(handles.custom,'hittest','off');
    if switcher == 3
        plot(handles.error,t,abs(f(t)- lagrangepoly(arr,f(arr), t)),'r-');
    end
end


% --- Executes on button press in reset.
function reset_Callback(hObject, eventdata, handles)
% hObject    handle to reset (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global arr
global f
global switcher
delete(allchild(handles.custom));
arr = [];

t = [-5:0.01:5];
axes(handles.custom);
a = plot(t,f(t),'b');
set(a,'hittest','off');
set(handles.custom,'hittest','off');
if switcher == 3
    plot(handles.error,t,abs(f(t)- lagrangepoly(arr,f(arr), t)),'r-');
end   


% --- Executes when selected object is changed in uipanel1.
function uipanel1_SelectionChangeFcn(hObject, eventdata, handles)
% hObject    handle to the selected object in uipanel1 
% eventdata  structure with the following fields (see UIBUTTONGROUP)
%	EventName: string 'SelectionChanged' (read only)
%	OldValue: handle of the previously selected object or empty if none was selected
%	NewValue: handle of the currently selected object
% handles    structure with handles and user data (see GUIDATA)
global f
global arr
global nodes 
global switcher
n = nodes;
t = [-5:0.01:5]; 
x_cheby = 5*cos( (2* (0:n-1)+1) / (2*n) * pi );
x_equi = linspace(-5,5,n);

switch get(eventdata.NewValue,'Tag') % Get Tag of selected object. 
    case 'radiobutton1' 
       switcher = 1;
       plot(handles.error,t, abs(f(t) - lagrangepoly(x_equi,f(x_equi), t)),'r-');
    case 'radiobutton2' 
       switcher = 2;
       plot(handles.error,t, abs(f(t) - lagrangepoly(x_cheby,f(x_cheby), t)),'r-');
    case 'radiobutton3' 
       switcher = 3;
       plot(handles.error,t,abs(f(t)- lagrangepoly(arr,f(arr), t)),'r-');
    otherwise
        
end


% --- Executes on button press in close.
function close_Callback(hObject, eventdata, handles)
% hObject    handle to close (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);



function funct_Callback(hObject, eventdata, handles)
% hObject    handle to funct (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 funct as text
%        str2double(get(hObject,'String')) returns contents of funct as a double
global f
try
    str = get(hObject,'string');
    f = inline(str,'x');
    f(-1:0.1:1); % should give exception if the function is wrong
catch err
    waitfor(...
    msgbox([err.message ' Resorting to default...'],...
    'Error','error','modal'));
    set(hObject,'string','1./(x.^2+1)');
    f=@(x)(1./(x.^2+1));
end


% --- Executes during object creation, after setting all properties.
function funct_CreateFcn(hObject, eventdata, handles)
% hObject    handle to funct (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 node_Callback(hObject, eventdata, handles)
% hObject    handle to node (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 node as text
%        str2double(get(hObject,'String')) returns contents of node as a double
global nodes
try
    str = get(hObject,'string');
    nodes = str2double(str);
    assert(~isnan(nodes) && ~isempty(str) && ~isinf(nodes) && ... 
    ceil(nodes)==nodes && nodes > 0 && nodes < 15,...
    'Incorrect number of nodes. Must be a positive integer less than 15.');
catch err
    waitfor(msgbox([ err.message ' Resorting to default'],...
        'Error','error','modal'));
    set(hObject,'String','10');
    nodes=10;
end

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


% THE FOLLOWING FUNCTION IS BASED ON "LAGRANGEPOLY" BY DANIEL ELLIS
%
% Copyright (c) 2009, Daniel Ellis
% All rights reserved.
% 
% Redistribution and use in source and binary forms, with or without 
% modification, are permitted provided that the following conditions are 
% met:
% 
%     * Redistributions of source code must retain the above copyright 
%       notice, this list of conditions and the following disclaimer.
%     * Redistributions in binary form must reproduce the above copyright 
%       notice, this list of conditions and the following disclaimer in 
%       the documentation and/or other materials provided with the distribution
%     * Neither the name of the Columbia University nor the names 
%       of its contributors may be used to endorse or promote products derived 
%       from this software without specific prior written permission.
%       
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
% POSSIBILITY OF SUCH DAMAGE.
function [pol,xroots,yroots] = lagrangepoly(x,y,xsampling)
% Make sure that x and y are row vectors!

n = length(x);
pvals = zeros(n,n);

% Calculate poly weights for each order
for i = 1:n
  temp = poly(x((1:n) ~= i));
  % scale 
  pvals(i,:) = temp./polyval(temp,x(i));
end

pol = y*pvals;

if nargin == 3
  ysampling = polyval(pol,xsampling);
  pol = ysampling;
end

if nargout > 1
  xroots = roots(((n-1):-1:1).*pol(1:(n-1)));
  if nargout > 2
    % calculate values at pts of 0 derivative
    yroots = polyval(pol,xroots);
  end
end
