function TCM_gauss

% TCM_GAUSS Interactive illustration of the approximation of a
% two-dimensional integral over a rectangle by the Gauss quadrature.
%
%   TCM_GAUSS_2D illustrates the approximation of a two-dimensional integral
%   over an rectangular domain by bivariate Gauss quadrature. It is
%   derived as tensor product of the one-dimensional quadrature which
%   uses the zeros of the Legendre polynomials as integration points and
%   their integrals as weights.
%
%   EXAMPLES
%
%   Basic Example: The Gauss quadrature of coordinate degree n is exact for
%   polynomials of degree < 2n.
%
%   Analytic Function: The Gauss quadrature converges very fast for
%   analytic functions.
% 
%   Non-smooth Function: The convergence for non-analytical functions may be
%   very slow.
%
%   To investigate other cases, insert a function in the corresponding field.
%
%   TCM_GAUSS is part of the <a href="http://www2.imng.uni-stuttgart.de/LstNumGeoMod/TCM/">TCM</a> project.
%   Related course materials can be found at <a href="http://www.mathematics-online.org/inhalt/aussage/aussage1484/">Mathematics Online</a>.

% Authors: Florian Martin, Lars von Wolff
% Last updated: 27.03.2017

% Initialize data
TCM_Data.fun = @(x,y) x.^2+y.^2;  
TCM_Data.funstring = '@(x,y) x.^2+y.^2';
TCM_Data.x = NaN;
TCM_Data.xi = 0;
TCM_Data.w = 0;
TCM_Data.intpara = [];
TCM_Data.rect = [0 1 0 1];
TCM_Data.N = 1;
TCM_Data.sum = 1;
TCM_Data.exact = 0;

% Do not delete these Variables
TCM_Data.plot_window = [-2 1 0 3];
TCM_Data.LmbMenuString = '';
TCM_Data.examples = {'Basic example','Analytic Function','Non-smooth Function'};

% Layout:
% ---------------------------------------
% |               Title                 |
% | ------------ --------- ------------ |
% | | Settings | |Buttons| | Feedback | |
% | ------------ --------- ------------ |
% | ----------------------------------- |
% | |           Axis (Plot)           | |
% | ----------------------------------- |
% | Info-Button         Hint            |
% ---------------------------------------
% Initialize Layout:
TCM_UI.TitleHeightMin = 10;        % minimal height of the title
TCM_UI.TitleHeightMax = 32;        % maximal height of the title
TCM_UI.HintHeightMin = 8;          % minimal height of the hint
TCM_UI.HintHeightMax = 15;         % maximal height of the hint
TCM_UI.SettingsHeightMin = 40;     % minimal height of the feedback, buttons and 
                                   % setting panel
TCM_UI.SettingsHeightMax = 70;     % maximal height of the feedback, buttons and 
                                   % setting panel
TCM_UI.SettingsRatio = 4.5;          % aspect ratio of the settings  
                                   % (increase if more settings needed)
TCM_UI.ButtonsRatio = 1.4;         % aspect ratio of the Buttons panel
TCM_UI.FeedbackRatio = 3.4;        % aspect ratio of the feedback
TCM_UI.AxisHeightTarget = 0.73;    % desired fraction of figure 
                                   % used for the plot
TCM_UI.InfoPortion = 1/8;          % Portion of the Info Button in the last  
                                   % line 
TCM_UI.Title = 'Bivariate Gauss Quadrature';
TCM_UI.mono = get(0,'FixedWidthFontName');
% Strings for generating the information window
TCM_UI.Author = 'F. Martin and L. von Wolff';
TCM_UI.Date = '27.03.2017';
TCM_UI.Web = 'http://www.mathematics-online.org/inhalt/aussage/aussage1484/';
      
CreateUI();

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% UI-Elements in Settings %%%%%%%%%%%%%%%%%%%%
% Text for Function
TCM_UI.funtext = uicontrol('Units','normalized','Parent',TCM_UI.settingspanel, ...
        'BackgroundColor',get(gcf,'Color'), ...
        'FontUnits','normalized','FontSize',0.67,...
        'HorizontalAlignment','left', ...
	'Position',[.01,.70,.29,.30],...
	'String','Function:',...
	'Style','text');

% Input for Function
TCM_UI.funinput=uicontrol('Units','normalized', 'Parent',TCM_UI.settingspanel, ...
        'BackgroundColor',get(gcf,'Color'), ...
        'FontWeight','bold',...
        'FontUnits','normalized','FontSize',0.65,'FontName',TCM_UI.mono,...
        'HorizontalAlignment','left', ...
	'Position',[.30,.70,.69,.30],...
	'String','',...
	'Style','edit',...
	'Callback',@function_update);

% Text for integral rectangle
TCM_UI.recttext = uicontrol('Units','normalized', 'Parent',TCM_UI.settingspanel, ...
        'BackgroundColor',get(gcf,'Color'), ...
        'FontUnits','normalized','FontSize',0.67,...
        'HorizontalAlignment','left', ...
	'Position',[.01,.35,.29,.30],...
	'String','Rectangle:',...
	'Style','text');

% Input the integral rectangle
TCM_UI.rectinput=uicontrol('Units','normalized', 'Parent',TCM_UI.settingspanel, ...
        'BackgroundColor',get(gcf,'Color'), ...
        'FontWeight','bold',...
        'FontUnits','normalized','FontSize',0.65,'FontName',TCM_UI.mono,...
        'HorizontalAlignment','left', ...
	'Position',[.30,.35,.69,.30],...
	'String','[0,1]',...
	'Style','edit','Callback',@rectangle_update);

% Text for degree
TCM_UI.degtext = uicontrol('Units','normalized', 'Parent',TCM_UI.settingspanel, ...
        'BackgroundColor',get(gcf,'Color'), ...
        'FontUnits','normalized','FontSize',0.67,...
        'HorizontalAlignment','left', ...
	'Position',[.01,.00,.3,.30],...
	'String','Degree:',...
	'Style','text');

% Input the degree
TCM_UI.deginput=uicontrol('Units','normalized', 'Parent',TCM_UI.settingspanel, ...
        'BackgroundColor',get(gcf,'Color'), ...
        'FontWeight','bold',...
        'FontUnits','normalized','FontSize',0.65,'FontName',TCM_UI.mono,...
        'HorizontalAlignment','left', ...
	'Position',[.30,.00,.3,.30],...
	'String','1',...
	'Style','edit','Callback',@degree_update);

%%%%%%%%%%%%%%%%%%%%%%%%% UI-Elements in Buttons Panel %%%%%%%%%%%%%%%%%%%%
% Reset-Button
TCM_UI.reset=uicontrol('Units','normalized','Parent',TCM_UI.buttonspanel, ...
	'BackgroundColor',get(gcf,'Color'), ...
	'String','Reset', ...
    'FontUnits','normalized','FontSize',0.7,...
	'Position',[.01,.70,.98,.30], ...
	'Callback',@reset,...
	'Style','pushbutton');

% Example button
TCM_UI.examples=uicontrol('Units','normalized','Parent',TCM_UI.buttonspanel, ...
	'BackgroundColor',get(gcf,'Color'), ...
	'String','Examples', ...
    'FontUnits','normalized','FontSize',0.7,...
	'Position',[.01,.35,.98,.30], 'Callback',@OpenExampleMenu,...
	'Style','pushbutton');

% Next-Button
TCM_UI.next=uicontrol('Units','normalized','Parent',TCM_UI.buttonspanel, ...
	'BackgroundColor',get(gcf,'Color'), ...
	'String','Next', ...
    'FontUnits','normalized','FontSize',0.7,...
	'Position',[.01,.0,.98,.30], ...
	'Callback',@next,...
	'Style','pushbutton');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% UI-Elements in Feedback %%%%%%%%%%%%%%%%%%%%
% Text for the approximated value
TCM_UI.apptext=uicontrol('Units','normalized','Parent',TCM_UI.feedbackpanel,...
        'BackgroundColor',get(gcf,'Color'), ...
        'HorizontalAlignment','left', ...
        'FontUnits','normalized','FontSize',0.7,...
	'Position',[.01,.7,.9,.3],...
	'String','Approximation: NaN',...
	'Style','text');

% Text for error
TCM_UI.errortext=uicontrol('Units','normalized','Parent',TCM_UI.feedbackpanel,...
        'BackgroundColor',get(gcf,'Color'), ...
        'HorizontalAlignment','left',...
        'FontUnits','normalized','FontSize',0.7,...
	'Position',[.01,.35,.9,.3],...
	'String','Error: NaN',...
	'Style','text');

% Text for warning
TCM_UI.reltext=uicontrol('Units','normalized','Parent',TCM_UI.feedbackpanel,...
        'BackgroundColor',get(gcf,'Color'), ...
        'HorizontalAlignment','left',  'ForegroundColor','red',...
        'FontUnits','normalized','FontSize',0.7,...
	'Position',[.01,.01,.9,.3],...
	'String','Reference value not reliable.',...
	'Style','text','visible','off');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% UI-Elements in Axis %%%%%%%%%%%%%%%%%%%%%%%%
% Axis for Function display
TCM_UI.ax=axes('Position',[.05,.1,.45,.85],'Parent',TCM_UI.axispanel);
axis(TCM_UI.ax,'equal');
TCM_UI.modification = uicontextmenu('Callback',@reset_zoom_limits);  
TCM_UI.mpan = uimenu('Parent',TCM_UI.modification,'Label','Enable pan',...
        'Callback',@axis_context);
TCM_UI.mzoomi = uimenu('Parent',TCM_UI.modification,'Label','Enable zoom in',...
    'Callback',@axis_context); 
TCM_UI.mzoomo = uimenu('Parent',TCM_UI.modification,'Label','Enable zoom out',...
        'Callback',@axis_context); 
TCM_UI.ax.UIContextMenu = TCM_UI.modification;

% functions for smoothless zooming and panning
panfun = pan(TCM_UI.fig);
panfun.UIContextMenu = TCM_UI.modification;
set(panfun,'ActionPostCallback',@pan_modify);
zoomfun = zoom(TCM_UI.fig);
zoomfun.UIContextMenu = TCM_UI.modification; 
set(zoomfun,'ActionPostCallback',@zoom_modify);
set(zoomfun,'ButtonDownFilter',@set_zoom_limits);
set(zoomfun,'RightClickAction','PostContextMenu');
set(findall(TCM_UI.fig,'tag','Exploration.Pan'),'enable','off');
set(findall(TCM_UI.fig,'tag','Exploration.ZoomOut'),'enable','off');
set(findall(TCM_UI.fig,'tag','Exploration.ZoomIn'),'enable','off');

% Second axis for a 3D plot with its own Contextmenu
TCM_UI.ax2=axes('Position',[.55,.1,.44,.85],'Parent',TCM_UI.axispanel);
linkaxes([TCM_UI.ax, TCM_UI.ax2], 'xy');
axis equal
TCM_UI.rotatemenu = uicontextmenu;
TCM_UI.rotate = uimenu('Parent',TCM_UI.rotatemenu,'Label','Enable rotate',...
        'Callback',@axis2_context);
TCM_UI.ax2.UIContextMenu = TCM_UI.rotatemenu;
rotatefun = rotate3d(TCM_UI.ax2);
rotatefun.UIContextMenu = TCM_UI.rotatemenu;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Start the program %%%%%%%%%%%%%%%%%%%%%%%%%%
changeexample(1);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%% Callback functions %%%%%%%%%%%%%%%%%%%%%%%%%%%

% new function input
function function_update(varargin)
TCM_Data.fun = eval(get(TCM_UI.funinput,'String'));
TCM_Data.fun = @(x,y) TCM_Data.fun(x,y) + 0*x;
warning off
warning('reset');
TCM_Data.exact = integral2(TCM_Data.fun,TCM_Data.rect(1),TCM_Data.rect(2),TCM_Data.rect(3),TCM_Data.rect(4),...
    'AbsTol',1e-12,'RelTol',1e-12);
[~,warnid] = lastwarn;
if isequal(warnid,'MATLAB:integral2:maxFunEvalsFail')
    TCM_UI.reltext.Visible = 'on';
else
    TCM_UI.reltext.Visible = 'off';
end
warning on
reset;
end

% rectangle input
function rectangle_update(varargin)
rect = eval(get(TCM_UI.rectinput,'String'));
h = diff(rect);
if h(1) > 0 && h(3) > 0
    TCM_Data.rect = rect;
    TCM_Data.plot_window = TCM_Data.rect + [-h(1)/8 h(1)/8 -h(3)/8 h(3)/8];
    TCM_Data.exact = integral2(TCM_Data.fun,TCM_Data.rect(1),TCM_Data.rect(2),TCM_Data.rect(3),TCM_Data.rect(4),...
        'AbsTol',1e-12,'RelTol',1e-12);
    [~,warnid] = lastwarn;
    if isequal(warnid,'MATLAB:integral2:maxFunEvalsFail')
        TCM_UI.reltext.Visible = 'on';
    else
        TCM_UI.reltext.Visible = 'off';
    end
    warning on
else
    set(TCM_UI.rectinput,'String',['[' num2str(TCM_Data.rect) ']']);
end
reset;
end

% degree update
function degree_update(varargin)
n = str2double(get(TCM_UI.deginput,'String'));
if n > 0 && mod(2,1) == 0 && n < 21
    [TCM_Data.w,TCM_Data.xi] = gausspar(n);
else
    set(TCM_UI.deginput,'String',num2str(numel(TCM_Data.w)));
end
reset;
end

% refresh all data from UI
function reset(varargin)
set(TCM_UI.errortext,'String','Error: NaN');
set(TCM_UI.apptext,'String','Approximation: NaN');
TCM_Data.x = [TCM_Data.rect(1:2);TCM_Data.rect(3:4)];
window_disable.Label = 'Disable pan';
axis_context(window_disable);
axis2_context(window_disable);
myplot;
end

% button next pressed
function next(varargin)
TCM_Data.x = linspace(TCM_Data.rect(1),TCM_Data.rect(2),numel(TCM_Data.x(1,:))+1);
TCM_Data.x(2,:) = linspace(TCM_Data.rect(3),TCM_Data.rect(4),numel(TCM_Data.x(1,:)));
myplot;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% kernel functions %%%%%%%%%%%%%%%%%%%%%%%%%%%
% compute the integration points
function integration_points(varargin)
TCM_Data.intpara = zeros(3,(size(TCM_Data.x,2)-1)^2*numel(TCM_Data.w)^2);
d1 = diff(TCM_Data.x(1,:)); d2 = diff(TCM_Data.x(2,:));
w1 = TCM_Data.w*d1; w2 = TCM_Data.w*d2;
xi1 = TCM_Data.xi*d1+repmat(TCM_Data.x(1,1:end-1),numel(TCM_Data.w),1);
xi2 = TCM_Data.xi*d2+repmat(TCM_Data.x(2,1:end-1),numel(TCM_Data.w),1);

[p,q] = meshgrid(xi1,xi2);
TCM_Data.intpara(1:2,:) = [p(:)';q(:)'];
[p,q] = meshgrid(w1,w2);
TCM_Data.intpara(3,:) = p(:)'.*q(:)';
end

% plot function
function myplot
integration_points();
axes(TCM_UI.ax)
cla reset; hold on; axis equal

hx = TCM_Data.plot_window(2) - TCM_Data.plot_window(1);
x = linspace(TCM_Data.plot_window(1)-hx,TCM_Data.plot_window(2)+hx,100);
hy = TCM_Data.plot_window(4) - TCM_Data.plot_window(3);
y = linspace(TCM_Data.plot_window(3)-hy,TCM_Data.plot_window(4)+hy,100);
[X,Y] = meshgrid(x(x>=TCM_Data.plot_window(1) & x<=TCM_Data.plot_window(2)),...
    y(y>=TCM_Data.plot_window(3) & y<=TCM_Data.plot_window(4)));
f = TCM_Data.fun(X,Y);

if ~isempty(get(TCM_UI.ax2, 'Children'))
    [az,el]=view(TCM_UI.ax2);
else
    az = NaN;
end
cla(TCM_UI.ax2,'reset');
im = abs(imag(f))>10^-8;
f(im) = NaN;
f(~inpolygon(X,Y,TCM_Data.rect([1 2 2 1 1]),TCM_Data.rect([3 3 4 4 3]))) = NaN;
s = surf(TCM_UI.ax2,X,Y,f,'EdgeColor','none','LineStyle','none','FaceLighting','phong','FaceAlpha',0.6);
s.UIContextMenu = TCM_UI.rotatemenu;
shading(TCM_UI.ax2,'interp');
hold(TCM_UI.ax2,'on');
xlim(TCM_UI.ax2,[TCM_Data.plot_window(1) TCM_Data.plot_window(2)]);
ylim(TCM_UI.ax2,[TCM_Data.plot_window(3) TCM_Data.plot_window(4)]);
if ~isnan(az)
    view(TCM_UI.ax2,az,el);
end

plot(TCM_Data.rect([1 2 2 1 1]),TCM_Data.rect([3 3 4 4 3]),'black','LineWidth',1);
for i=1:size(TCM_Data.x,2)
    plot(TCM_Data.x(1,[i i]),TCM_Data.rect([3 4]),'--black');
end
for i=1:size(TCM_Data.x,2)
    plot(TCM_Data.rect([1 2]),TCM_Data.x(2,[i i]),'--black');
end
plot(TCM_Data.intpara(1,:),TCM_Data.intpara(2,:),'xblack');

limz = zlim(TCM_UI.ax2);
plot3(TCM_UI.ax2,TCM_Data.rect([1 2 2 1 1]),TCM_Data.rect([3 3 4 4 3]),limz(1)*ones(1,5),'black','LineWidth',1);
plot3(TCM_UI.ax2,TCM_Data.intpara(1,:),TCM_Data.intpara(2,:),limz(1)*ones(size(TCM_Data.intpara(2,:))),'xblack');
for i=1:size(TCM_Data.intpara,2)
    plot3(TCM_UI.ax2,TCM_Data.intpara(1,[i i]),TCM_Data.intpara(2,[i i]),...
        [limz(1); TCM_Data.fun(TCM_Data.intpara(1,i),TCM_Data.intpara(2,i))],'--black');
end
int = sum(TCM_Data.fun(TCM_Data.intpara(1,:),TCM_Data.intpara(2,:)).*TCM_Data.intpara(3,:));

set(TCM_UI.apptext,'String',sprintf('Approximation: %5.3e',int));
set(TCM_UI.errortext,'String',sprintf('Error: %5.3e',abs(int-TCM_Data.exact)));

SetWindowLimits
UpdateHinttext
end

% Update the Hinttext
function UpdateHinttext
LmbString = 'Next = Increase number of rectangles. ';  
if(numel(TCM_Data.LmbMenuString) == 0)
    set(TCM_UI.hinttext,'String',[LmbString 'Right Mouse = Access window menu.']);
else
    set(TCM_UI.hinttext,'String',[TCM_Data.LmbMenuString 'Right Mouse = Access window menu.']);
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%% example functions %%%%%%%%%%%%%%%%%%%%%%%%%%%

function CreateExampleMenu
TCM_UI.UICexamples = uicontextmenu;
for i=1:numel(TCM_Data.examples)
    uimenu('Parent',TCM_UI.UICexamples,'Label',TCM_Data.examples{i},'Callback',{@changeexample,i});
end
end

function OpenExampleMenu(varargin)
TCM_UI.examples.Units = 'pixels';
TCM_UI.buttonspanel.Units = 'pixels';
TCM_UI.UICexamples.Position = TCM_UI.examples.Position(1:2) + TCM_UI.buttonspanel.Position(1:2);
TCM_UI.examples.Units = 'normalized';
TCM_UI.buttonspanel.Units = 'points';
TCM_UI.UICexamples.Visible = 'on';
end
 
              
function changeexample(varargin)  
switch varargin{numel(varargin)}
    case 1
        set(TCM_UI.funinput,'String','@(x,y) x.^2-y.^5'); 
        function_update;
        set(TCM_UI.rectinput,'String','[0 3 0 2]');
        rectangle_update;
        set(TCM_UI.deginput,'String','2');
        degree_update;
    case 2
        set(TCM_UI.funinput,'String','@(x,y) sin(pi*x)+exp(cos(pi*y))'); 
        function_update;
        set(TCM_UI.rectinput,'String','[0 2 0 2]');
        rectangle_update;
        set(TCM_UI.deginput,'String','2');
        degree_update;
    case 3
        set(TCM_UI.rectinput,'String','[0 1 0 1]');
        rectangle_update;
        set(TCM_UI.funinput,'String','@(x,y) sqrt(x)./(1+x.*y)'); 
        function_update;
        set(TCM_UI.deginput,'String','2');
        degree_update;
end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% zoom functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% function for updating the internal plot window
function zoom_modify(varargin)
if max(abs(TCM_Data.plot_window-axis(TCM_UI.ax)))< 10^-10
    ZoomOut;
end
pan_modify;
end

function pan_modify(varargin)
TCM_Data.plot_window = axis(TCM_UI.ax);
myplot;
end

% functions for proper zooming in (prevent double-click zoom out)
function [flag] = set_zoom_limits(varargin)
if(strcmp(TCM_UI.fig.SelectionType,'open'))
    flag = true;
else
    flag = false;
end
end

function reset_zoom_limits(varargin)
SetWindowLimits;
end

% handling the axis context menu
function axis_context(varargin)
zoom(TCM_UI.fig, 'off'); pan(TCM_UI.fig, 'off');
mode_strings = {'pan','zoom in','zoom out'};
status_strings = {'Enable ','Disable '};
switch varargin{1}.Label(1:7)
    case 'Enable '
        mode = strcmp(varargin{1}.Label(8:end),mode_strings);
        TCM_Data.LmbMenuString = ['Left Mouse = ' mode_strings{mode} ' the window. '];
        set(TCM_UI.mpan,'Label',horzcat(status_strings{mode(1)+1},mode_strings{1}));
        set(TCM_UI.mzoomi,'Label',horzcat(status_strings{mode(2)+1},mode_strings{2}));
        set(TCM_UI.mzoomo,'Label',horzcat(status_strings{mode(3)+1},mode_strings{3}));
        split_mode = strsplit(mode_strings{mode},' ');
        if numel(split_mode) == 1
            pan(TCM_UI.fig, 'on');
        else
            zoomh = zoom(TCM_UI.fig);
            zoomh.Enable = 'on';
            zoomh.Direction = split_mode{2};
        end
    case 'Disable'
        TCM_Data.LmbMenuString = '';
        set(TCM_UI.mpan,'Label','Enable pan');
        set(TCM_UI.mzoomi,'Label','Enable zoom in');
        set(TCM_UI.mzoomo,'Label','Enable zoom out');     
end
UpdateHinttext;
end

function axis2_context(varargin)
if strcmp(varargin{1}.Label,'Enable rotate')
    set(TCM_UI.rotate,'Label','Disable rotate');
    TCM_Data.LmbMenuString = 'Left Mouse = Rotate the Box. ';
    rotate3d(TCM_UI.ax2,'on');
else
    rotate3d(TCM_UI.ax2,'off');
    set(TCM_UI.rotate,'Label','Enable rotate');
    TCM_Data.LmbMenuString = '';
end
UpdateHinttext;
end

function SetWindowLimits
ZoomOut;
xlim(TCM_UI.ax,[TCM_Data.plot_window(1) TCM_Data.plot_window(2)]);
ylim(TCM_UI.ax,[TCM_Data.plot_window(3) TCM_Data.plot_window(4)]);
end

function ZoomOut
hx = TCM_Data.plot_window(2) - TCM_Data.plot_window(1);
hy = TCM_Data.plot_window(4) - TCM_Data.plot_window(3);
xlim(TCM_UI.ax,[TCM_Data.plot_window(1)-hx/2 TCM_Data.plot_window(2)+hx/2]);
ylim(TCM_UI.ax,[TCM_Data.plot_window(3)-hy/2 TCM_Data.plot_window(4)+hy/2]);
zoom(TCM_UI.fig, 'reset');
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% layout functions %%%%%%%%%%%%%%%%%%%%%%%%%%%

% functions for creating the different UI-Parts and managing the resize of
% the window
function CreateUI
TCM_UI.fig = figure('Visible','off', 'Units','points','Toolbar','none',...
    'SizeChangedFcn',@calculate_layout,...
    'numbertitle','off','name',TCM_UI.Title);
TCM_UI.titletext = uicontrol('Units','points','BackgroundColor',TCM_UI.fig.Color, ...
	'HorizontalAlignment','center',  'FontWeight','bold', ...
    'FontUnits','normalized',        'FontSize',0.8,...
	'String',TCM_UI.Title,        'Style','text');
TCM_UI.hinttext = uicontrol('Units','points','BackgroundColor',TCM_UI.fig.Color, ...
    'HorizontalAlignment','right',...
    'FontUnits','normalized',        'FontSize',0.63,...
	'String','','Style','text');
TCM_UI.infobutton=uicontrol('Units','points', ...
	'BackgroundColor',TCM_UI.fig.Color, ...
	'String','Info', 'HorizontalAlignment','left',...
    'FontUnits','normalized','FontSize',0.7,...
	'Callback',@information,'Style','pushbutton');
TCM_UI.feedbackpanel = uipanel('Units','points','BackgroundColor',TCM_UI.fig.Color,'BorderType','none');
TCM_UI.buttonspanel = uipanel('Units','points','BackgroundColor',TCM_UI.fig.Color,'BorderType','none');
TCM_UI.settingspanel = uipanel('Units','points','BackgroundColor',TCM_UI.fig.Color,'BorderType','none');
TCM_UI.axispanel = uipanel('Units','points','BackgroundColor',TCM_UI.fig.Color,'BorderType','none');
CreateExampleMenu
TCM_UI.fig.Visible= 'on';
end


function calculate_layout(varargin) 
figpos = TCM_UI.fig.Position;
WMax = TCM_UI.SettingsHeightMax*(TCM_UI.SettingsRatio + TCM_UI.FeedbackRatio + TCM_UI.ButtonsRatio);
WMin = TCM_UI.SettingsHeightMin*(TCM_UI.SettingsRatio + TCM_UI.FeedbackRatio + TCM_UI.ButtonsRatio);
HMax = TCM_UI.TitleHeightMax + TCM_UI.HintHeightMax;
HMin = TCM_UI.TitleHeightMin + TCM_UI.HintHeightMin;

wratio = max(0,min(1,(min(figpos(3),1.3*figpos(4))-WMin)/(WMax-WMin)));
XCoords = [1,0,0,0,0,0,0,figpos(3)];
SWidth =      wratio*TCM_UI.SettingsHeightMax*TCM_UI.SettingsRatio...
        + (1-wratio)*TCM_UI.SettingsHeightMin*TCM_UI.SettingsRatio;
BWidth =      wratio*TCM_UI.SettingsHeightMax*TCM_UI.ButtonsRatio...
        + (1-wratio)*TCM_UI.SettingsHeightMin*TCM_UI.ButtonsRatio; 
FWidth =      wratio*TCM_UI.SettingsHeightMax*TCM_UI.FeedbackRatio...
        + (1-wratio)*TCM_UI.SettingsHeightMin*TCM_UI.FeedbackRatio; 
RemWidth = figpos(3)-3-SWidth-FWidth-BWidth;
XCoords(2) = max(1,0.3*RemWidth);
XCoords(3) = XCoords(2) + 1 + SWidth;
XCoords(4) = XCoords(3) + max(0,0.2*RemWidth);
XCoords(5) = XCoords(4) + 1 + BWidth;
XCoords(6) = XCoords(5) + max(0,0.2*RemWidth);
XCoords(7) = XCoords(6) + 1 + FWidth;
SHeight = wratio*TCM_UI.SettingsHeightMax + (1-wratio)*TCM_UI.SettingsHeightMin;
if(HMin > min(figpos(4),0.9*figpos(3))*(1-TCM_UI.AxisHeightTarget)-5-SHeight)
    hratio = 0;
elseif(HMax <  min(figpos(4),0.9*figpos(3))*(1-TCM_UI.AxisHeightTarget)-5-SHeight)
    hratio = 1;
else
    hratio = (( min(figpos(4),0.9*figpos(3))*(1-TCM_UI.AxisHeightTarget)-5-SHeight)  -HMin)/(HMax-HMin);
end
YCoords = [1,0,0,0,figpos(4)-1];
YCoords(2) = YCoords(1) + 1 + hratio*TCM_UI.HintHeightMax     + (1-hratio)*TCM_UI.HintHeightMin;
YCoords(4) = YCoords(5) - 1 - hratio*TCM_UI.TitleHeightMax    - (1-hratio)*TCM_UI.TitleHeightMin;
YCoords(3) = YCoords(4) - 1 - SHeight;
TCM_UI.titletext.Position =     [XCoords(1)+1,  YCoords(4)+1,  XCoords(8)-XCoords(1)-1,  YCoords(5)-YCoords(4)-1];
TCM_UI.settingspanel.Position = [XCoords(2)+1,  YCoords(3)+1,  XCoords(3)-XCoords(2)-1,  YCoords(4)-YCoords(3)-1];
TCM_UI.buttonspanel.Position =  [XCoords(4)+1,  YCoords(3)+1,  XCoords(5)-XCoords(4)-1,  YCoords(4)-YCoords(3)-1];
TCM_UI.feedbackpanel.Position = [XCoords(6)+1,  YCoords(3)+1,  XCoords(7)-XCoords(6)-1,  YCoords(4)-YCoords(3)-1];
TCM_UI.axispanel.Position =     [XCoords(1)+1,  YCoords(2)+1,  XCoords(8)-XCoords(1)-1,  max(0,YCoords(3)-YCoords(2)-1)];
TmpXCoord = TCM_UI.InfoPortion*(XCoords(8)-XCoords(1)-1);
TCM_UI.infobutton.Position =    [XCoords(1)+1,  YCoords(1)+1,  TmpXCoord-XCoords(1)-1,   YCoords(2)-YCoords(1)-1];
TCM_UI.hinttext.Position =      [TmpXCoord+1,   YCoords(1)+1,  XCoords(8)-TmpXCoord-1,   YCoords(2)-YCoords(1)-1];
end

% function for opening the information webpage
function information(varargin)
pos = TCM_UI.fig.OuterPosition;
infodialog = dialog('Name','Information','Units','points',...
    'OuterPosition',[pos(1)+pos(3)/4 pos(2)+pos(4)/4 pos(3)/2 pos(4)/2]);
uicontrol('Units','normalized', 'Parent',infodialog, ...
        'FontUnits','normalized', 'FontSize',0.67,...
        'HorizontalAlignment','center', 'Position',[.01,.6,.98,.15],...
	'String','Mathematics Online Link', 'Style','text',...
    'ForegroundColor','blue','ButtonDownFcn',@linkfun,...
    'Enable','inactive');
uicontrol('Units','normalized', 'Parent',infodialog, ...
        'FontUnits','normalized', 'FontSize',0.4,...
        'HorizontalAlignment','center', 'Position',[.01,.4,.98,.15],...
	'String',{horzcat('Created by ',TCM_UI.Author,'.');horzcat('Version: ',TCM_UI.Date)} , 'Style','text');
end

function linkfun(varargin)
web(TCM_UI.Web)
end

function [w,x]=gausspar(n)
switch(n)
case 1
x=[0.5]';
w=[1]';
case 2
x=[0.21132486540518711774,0.78867513459481288226]';
w=[0.5,0.5]';
case 3
x=[0.11270166537925831148,0.5,0.88729833462074168852]';
w=[0.27777777777777777778,0.44444444444444444445,0.27777777777777777777]';
case 4
x=[0.06943184420297371239,0.3300094782075718676,0.6699905217924281324,0.93056815579702628761]';
w=[0.1739274225687269287,0.3260725774312730713,0.32607257743127307132,0.1739274225687269287]';
case 5
x=[0.0469100770306680036,0.23076534494715845448,0.5,0.76923465505284154552,0.9530899229693319964]';
w=[0.11846344252809454376,0.23931433524968323402,0.28444444444444444444,0.23931433524968323402,0.11846344252809454376]';
case 6
x=[0.0337652428984239861,0.16939530676686774317,0.38069040695840154568,0.61930959304159845432,0.83060469323313225683,0.9662347571015760139]';
w=[0.08566224618958517253,0.18038078652406930376,0.2339569672863455237,0.2339569672863455237,0.18038078652406930378,0.085662246189585172525]';
case 7
x=[0.02544604382862073774,0.12923440720030278007,0.29707742431130141654,0.5,0.70292257568869858346,0.87076559279969721993,0.97455395617137926226]';
w=[0.06474248308443484663,0.13985269574463833395,0.19091502525255947246,0.20897959183673469388,0.19091502525255947248,0.13985269574463833394,0.064742483084434846635]';
case 8
x=[0.01985507175123188416,0.1016667612931866302,0.23723379504183550709,0.40828267875217509753,0.59171732124782490247,0.76276620495816449291,0.8983332387068133698,0.98014492824876811584]';
w=[0.050614268145188129575,0.11119051722668723528,0.15685332293894364368,0.18134189168918099147,0.18134189168918099149,0.15685332293894364368,0.11119051722668723526,0.05061426814518812958]';
case 9
x=[0.01591988024618695508,0.08198444633668210285,0.19331428364970480134,0.33787328829809553548,0.5,0.66212671170190446452,0.80668571635029519866,0.91801555366331789715,0.98408011975381304492]';
w=[0.040637194180787205985,0.090324080347428702035,0.13030534820146773115,0.15617353852000142006,0.16511967750062988157,0.15617353852000142004,0.13030534820146773116,0.09032408034742870204,0.04063719418078720598]';
case 10
x=[0.01304673574141413996,0.06746831665550774464,0.16029521585048779688,0.2833023029353764046,0.42556283050918439456,0.57443716949081560544,0.7166976970646235954,0.83970478414951220312,0.93253168334449225536,0.98695326425858586004]';
w=[0.033335672154344068793,0.074725674575290296575,0.10954318125799102198,0.13463335965499817755,0.14776211235737643508,0.14776211235737643508,0.13463335965499817756,0.10954318125799102199,0.074725674575290296575,0.033335672154344068792]';
case 11
x=[0.0108856709269715036,0.05646870011595235046,0.13492399721297533796,0.24045193539659409204,0.36522842202382751384,0.5,0.63477157797617248616,0.75954806460340590796,0.86507600278702466204,0.94353129988404764954,0.9891143290730284964]';
w=[0.02783428355808683324,0.06279018473245231228,0.09314510546386712571,0.11659688229599523996,0.13140227225512333109,0.13646254338895031536,0.1314022722551233311,0.11659688229599523996,0.09314510546386712571,0.06279018473245231231,0.027834283558086833246]';
case 12
x=[0.00921968287664037466,0.04794137181476257166,0.11504866290284765648,0.20634102285669127635,0.31608425050090990312,0.43738329574426554226,0.56261670425573445774,0.68391574949909009688,0.79365897714330872365,0.88495133709715234352,0.95205862818523742834,0.99078031712335962534]';
w=[0.02358766819325591361,0.05346966299765921543,0.080039164271673113165,0.10158371336153296088,0.1167462682691774044,0.1245735229067013925,0.1245735229067013925,0.11674626826917740438,0.10158371336153296088,0.08003916427167311317,0.053469662997659215475,0.023587668193255913596]';
case 13
x=[0.00790847264070592526,0.0412008003885110174,0.0992109546333450436,0.17882533027982988968,0.27575362448177657356,0.38477084202243260296,0.5,0.61522915797756739704,0.72424637551822342644,0.82117466972017011032,0.9007890453666549564,0.9587991996114889826,0.99209152735929407474]';
w=[0.02024200238265793975,0.046060749918864223992,0.06943675510989361923,0.089072990380972869135,0.10390802376844425115,0.11314159013144861918,0.1162757766154369551,0.1131415901314486192,0.10390802376844425115,0.08907299038097286914,0.06943675510989361924,0.046060749918864223952,0.02024200238265793976]';
case 14
x=[0.00685809565159383058,0.03578255816821324133,0.0863993424651175034,0.15635354759415726492,0.24237568182092295402,0.34044381553605511978,0.44597252564632816896,0.55402747435367183104,0.65955618446394488022,0.75762431817907704598,0.84364645240584273508,0.9136006575348824966,0.96421744183178675867,0.99314190434840616942]';
w=[0.017559730165875931516,0.040079043579880104897,0.06075928534395159235,0.07860158357909676728,0.09276919873896890688,0.10259923186064780196,0.10763192673157889511,0.10763192673157889511,0.10259923186064780198,0.09276919873896890688,0.07860158357909676728,0.060759285343951592355,0.040079043579880104898,0.017559730165875931515]';
case 15
x=[0.00600374098975728576,0.03136330379964704784,0.0758967082947863919,0.13779113431991497629,0.21451391369573057623,0.30292432646121831505,0.39940295300128273885,0.5,0.60059704699871726115,0.69707567353878168495,0.78548608630426942377,0.86220886568008502371,0.9241032917052136081,0.96863669620035295216,0.99399625901024271424]';
w=[0.015376620998058634172,0.035183023744054062367,0.053579610233585967515,0.069785338963077157225,0.08313460290849696678,0.09308050000778110551,0.099215742663555788225,0.10128912096278063644,0.099215742663555788235,0.09308050000778110551,0.08313460290849696678,0.069785338963077157215,0.053579610233585967515,0.035183023744054062358,0.015376620998058634178]';
case 16
x=[0.0052995325041750337,0.02771248846338371196,0.06718439880608412806,0.12229779582249848305,0.19106187779867812578,0.27099161117138630683,0.35919822461037054338,0.45249374508118127991,0.54750625491881872009,0.64080177538962945662,0.72900838882861369317,0.80893812220132187422,0.87770220417750151695,0.93281560119391587194,0.97228751153661628804,0.9947004674958249663]';
w=[0.013576229705877047414,0.03112676196932394647,0.047579255841246392407,0.062314485627766936035,0.07479799440828836604,0.084578259697501269095,0.091301707522461794435,0.09472530522753424813,0.094725305227534248135,0.091301707522461794445,0.084578259697501269105,0.07479799440828836605,0.062314485627766936025,0.047579255841246392403,0.031126761969323946431,0.013576229705877047423]';
case 17
x=[0.00471226234279133216,0.02466223911561611939,0.05988042313650704894,0.10924299805159929654,0.17116442039165461708,0.24365473145676151606,0.32438411827306184235,0.41075790925207607208,0.5,0.58924209074792392792,0.67561588172693815765,0.75634526854323848394,0.82883557960834538292,0.89075700194840070346,0.94011957686349295106,0.97533776088438388061,0.99528773765720866784]';
w=[0.012074151434273965985,0.027729764686993600543,0.04251807415858959044,0.055941923596701985555,0.067568184234262736635,0.07702288053840514404,0.084002051078225022255,0.088281352683496323155,0.08972323517810326272,0.08828135268349632316,0.08400205107822502225,0.07702288053840514404,0.067568184234262736635,0.055941923596701985555,0.042518074158589590438,0.027729764686993600569,0.012074151434273965978]';
case 18
x=[0.00421741578953452664,0.02208802521430112241,0.0536987667512221304,0.09814752051373844216,0.15415647846982339606,0.2201145844630262327,0.29412441926857867698,0.3740568871542472452,0.45761249347913234938,0.54238750652086765062,0.6259431128457527548,0.70587558073142132302,0.7798854155369737673,0.84584352153017660394,0.90185247948626155784,0.9463012332487778696,0.97791197478569887759,0.99578258421046547336]';
w=[0.010808006763241655152,0.02485727444748489824,0.03821286512744452825,0.05047102205314358278,0.061277603355739230095,0.07032145733532532559,0.07734233756313262246,0.08213824187291636148,0.084571191481571795915,0.08457119148157179593,0.082138241872916361485,0.077342337563132622465,0.070321457335325325605,0.061277603355739230085,0.050471022053143582785,0.038212865127444528265,0.024857274447484898226,0.010808006763241655158]';
case 19
x=[0.0037965780782077984,0.01989592393258498458,0.04842204819259104918,0.08864267173142858751,0.13951691133238531069,0.19972734766915948826,0.26771462931201952714,0.341717950018185084,0.41982067717988731206,0.5,0.58017932282011268794,0.658282049981814916,0.73228537068798047286,0.80027265233084051174,0.86048308866761468931,0.91135732826857141249,0.95157795180740895082,0.98010407606741501542,0.9962034219217922016]';
w=[0.009730894114863238523,0.022407113382849800152,0.034522271368820613274,0.045745010811224999732,0.05578332277366699737,0.064376981269668113845,0.071303351086803305885,0.076383021032929833405,0.07948442169697717383,0.080527224924391847985,0.079484421696977173825,0.076383021032929833395,0.071303351086803305885,0.064376981269668113845,0.05578332277366699736,0.045745010811224999728,0.034522271368820613292,0.022407113382849800169,0.009730894114863238517]';
case 20
x=[0.0034357004074525376,0.01801403636104310436,0.04388278587433704706,0.0804415140888905883,0.1268340467699246037,0.18197315963674248728,0.244566499024586451,0.31314695564229021966,0.38610707442917746096,0.46173673943325133312,0.53826326056674866688,0.61389292557082253904,0.68685304435770978034,0.755433500975413549,0.81802684036325751272,0.8731659532300753963,0.9195584859111094117,0.95611721412566295294,0.98198596363895689564,0.9965642995925474624]';
w=[0.008807003569576059146,0.020300714900193470692,0.031336024167054531796,0.041638370788352374368,0.050965059908620217515,0.059097265980759208665,0.065844319224588313445,0.071048054659191025655,0.07458649323630187339,0.07637669356536292535,0.07637669356536292535,0.07458649323630187339,0.071048054659191025665,0.065844319224588313445,0.05909726598075920867,0.050965059908620217515,0.041638370788352374363,0.031336024167054531784,0.020300714900193470666,0.0088070035695760591535]';
end
end

end
