function varargout = Gaussian_Quad(varargin) % GAUSSIAN_QUAD Application M-file for Gaussian_Quad.fig % FIG = GAUSSIAN_QUAD launch Gaussian_Quad GUI. % GAUSSIAN_QUAD('callback_name', ...) invoke the named callback. % Last Modified by GUIDE v2.5 03-Oct-2004 22:18:00 if nargin == 0 % LAUNCH GUI fig = openfig(mfilename,'reuse'); % Generate a structure of handles to pass to callbacks, and store it. handles = guihandles(fig); % Initialization of fcn_data = [indexfcn,a,b,c1,c2] handles.indexfcn = 1; handles.const_a = 0; handles.const_b = pi; handles.const_c1 = 1; handles.const_c2 = 1; handles.fcn_data = [handles.indexfcn,handles.const_a,handles.const_b,handles.const_c1,handles.const_c2]; % Initialization of quad_data = [n_init,doubles] handles.const_n_init = 2; handles.const_double = 4; handles.increment = 1; handles.quad_data = [handles.const_n_init,handles.const_double,handles.increment]; handles; guidata(fig, handles); if nargout > 0 varargout{1} = fig; end elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK try if (nargout) [varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard else feval(varargin{:}); % FEVAL switchyard end catch disp(lasterr); end end %| ABOUT CALLBACKS: %| GUIDE automatically appends subfunction prototypes to this file, and %| sets objects' callback properties to call them through the FEVAL %| switchyard above. This comment describes that mechanism. %| %| Each callback subfunction declaration has the following form: %| (H, EVENTDATA, HANDLES, VARARGIN) %| %| The subfunction name is composed using the object's Tag and the %| callback type separated by '_', e.g. 'slider2_Callback', %| 'figure1_CloseRequestFcn', 'axis1_ButtondownFcn'. %| %| H is the callback object's handle (obtained using GCBO). %| %| EVENTDATA is empty, but reserved for future use. %| %| HANDLES is a structure containing handles of components in GUI using %| tags as fieldnames, e.g. handles.figure1, handles.slider2. This %| structure is created at GUI startup using GUIHANDLES and stored in %| the figure's application data using GUIDATA. A copy of the structure %| is passed to each callback. You can store additional information in %| this structure at GUI startup, and you can change the structure %| during callbacks. Call guidata(h, handles) after changing your %| copy to replace the stored original so that subsequent callbacks see %| the updates. Type "help guihandles" and "help guidata" for more %| information. %| %| VARARGIN contains any extra arguments you have passed to the %| callback. Specify the extra arguments by editing the callback %| property in the inspector. By default, GUIDE sets the property to: %| ('', gcbo, [], guidata(gcbo)) %| Add any extra arguments after the last argument, before the final %| closing parenthesis. % -------------------------------------------------------------------- % --- Executes on selection change in ChooseIntegrand. function ChooseIntegrand_Callback(h, eventdata, handles) % h handle to ChooseIntegrand (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(h,'String') returns ChooseIntegrand contents as cell array % contents{get(h,'Value')} returns selected item from ChooseIntegrand % disp('ChooseIntegrand_Callback - Begin') indexfcn = get(h,'Value'); a = handles.const_a; b = handles.const_b; c1 = handles.const_c1; c2 = handles.const_c2; handles.fcn_data = [indexfcn,a,b,c1,c2]; guidata(h,handles); % Save the handles structure after adding data % disp('ChooseIntegrand_Callback - End') % -------------------------------------------------------------------- % --- Executes during object creation, after setting all properties. function ChooseIntegrand_CreateFcn(h, eventdata, handles) % h handle to ChooseIntegrand (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 set(h,'BackgroundColor','white'); else set(h,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end % -------------------------------------------------------------------- function varargout = LeftEndEditText_Callback(h, eventdata, handles, varargin) % disp('LeftEndEditText_Callback - Begin') const_a = eval(get(handles.LeftEndEditText,'string')); handles.const_a = const_a; handles.fcn_data = [handles.indexfcn,handles.const_a, handles.const_b, handles.const_c1, handles.const_c2]; guidata(h,handles); Gaussian_Quad('ChooseIntegrand_Callback',handles.ChooseIntegrand,[],guidata(handles.ChooseIntegrand)) % disp('LeftEndEditText_Callback - End') % -------------------------------------------------------------------- function varargout = RightEndEditText_Callback(h, eventdata, handles, varargin) % disp('RightEndEditText_Callback - Begin') const_b = eval(get(handles.RightEndEditText,'string')); handles.const_b = const_b; handles.fcn_data = [handles.indexfcn,handles.const_a, handles.const_b, handles.const_c1, handles.const_c2]; guidata(h,handles); Gaussian_Quad('ChooseIntegrand_Callback',handles.ChooseIntegrand,[],guidata(handles.ChooseIntegrand)) % disp('RightEndEditText_Callback - End') % -------------------------------------------------------------------- function varargout = Constant_c1_EditText_Callback(h, eventdata, handles, varargin) const_c1 = eval(get(handles.Constant_c1_EditText,'string')); handles.const_c1 = const_c1; handles.fcn_data = [handles.indexfcn,handles.const_a, handles.const_b, handles.const_c1, handles.const_c2]; guidata(h,handles); Gaussian_Quad('ChooseIntegrand_Callback',handles.ChooseIntegrand,[],guidata(handles.ChooseIntegrand)) % -------------------------------------------------------------------- function varargout = Constant_c2_EditText_Callback(h, eventdata, handles, varargin) % disp('Constant_c2_EditText_Callback - Begin') const_c2 = eval(get(handles.Constant_c2_EditText,'string')); handles.const_c2 = const_c2; handles.fcn_data = [handles.indexfcn,handles.const_a, handles.const_b, handles.const_c1, handles.const_c2]; guidata(h,handles); Gaussian_Quad('ChooseIntegrand_Callback',handles.ChooseIntegrand,[],guidata(handles.ChooseIntegrand)) % disp('Constant_c2_EditText_Callback - End') % -------------------------------------------------------------------- function varargout = PlotPushbutton_Callback(h, eventdata, handles, varargin) % disp('PlotPushbutton_Callback - Begin') f_data = handles.fcn_data; indexfcn = f_data(1); a = f_data(2); b = f_data(3); c1 = f_data(4); c2 = f_data(5); x = a:(b-a)/100:b ; y = fcn(x,f_data); axes(handles.axes1) plot(x,y) grid on % disp('PlotPushbutton_Callback - End') % -------------------------------------------------------------------- function varargout = Choose_Ninit_Callback(h, eventdata, handles, varargin) % disp('Choose_Ninit_Callback - Begin') const_n_init = eval(get(handles.Choose_Ninit,'string')); handles.const_n_init = const_n_init; handles.quad_data = [handles.const_n_init,handles.const_double,handles.increment]; guidata(h,handles); Gaussian_Quad('ChooseIntegrand_Callback',handles.ChooseIntegrand,[],guidata(handles.ChooseIntegrand)) % disp('Choose_Ninit_Callback - End') % -------------------------------------------------------------------- function varargout = ChooseDoubles_Callback(h, eventdata, handles, varargin) % disp('ChooseDoubles_Callback - Begin') const_double = eval(get(handles.ChooseDoubles,'string')); handles.const_double = const_double; handles.quad_data = [handles.const_n_init,handles.const_double,handles.increment]; guidata(h,handles); Gaussian_Quad('ChooseIntegrand_Callback',handles.ChooseIntegrand,[],guidata(handles.ChooseIntegrand)) % disp('ChooseDoubles_Callback - End') % -------------------------------------------------------------------- function varargout = IntegrationOutput_Callback(h, eventdata, handles, varargin) % -------------------------------------------------------------------- function varargout = file_menu_Callback(h, eventdata, handles, varargin) if isempty(get(handles.axes1,'Children')) set(handles.print_submenu,'Enable','off') else set(handles.print_submenu,'Enable','on') end % -------------------------------------------------------------------- function varargout = print_submenu_Callback(h, eventdata, handles, varargin) h_invisible = figure('visible','off'); hax = copyobj(handles.axes1,h_invisible); set(hax,'units',get(0,'defaultaxesunits'),'position',get(0,'defaultaxesposition')) print(h_invisible,'-depsc','gaussian_quad_graph') close(h_invisible); disp('The graph is stored under the name "gaussian_quad_graph.eps"') % -------------------------------------------------------------------- function varargout = table_submenu_Callback(h, eventdata, handles, varargin) % Load data from handles structure StringData = handles.StringData; fid = fopen('output_Gauss_Quad','w'); disp('The table is saved under the name "output_Gauss_Quad"') [num_rows,num_cols] = size(StringData); for i=1:num_rows fprintf(fid,'%c',StringData(i,1:num_cols)); fprintf(fid,'\n'); end fclose(fid); % -------------------------------------------------------------------- function varargout = close_submenu_Callback(h, eventdata, handles, varargin) delete(handles.figure1) % -------------------------------------------------------------------- function Help_GUI_Callback(hObject, eventdata, handles) % hObject handle to Help_GUI (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) Gaussian_Quad_Help % -------------------------------------------------------------------- % --- Executes during object creation, after setting all properties. function Choose_Ninit_CreateFcn(hObject, eventdata, handles) % hObject handle to Choose_Ninit (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 set(hObject,'BackgroundColor','white'); else set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end % -------------------------------------------------------------------- function arithmetic_increment_Callback(h, eventdata, handles) % h handle to arithmetic_increment (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(h,'String') returns contents of arithmetic_increment as text % str2double(get(h,'String')) returns contents of arithmetic_increment as a double % disp('arithmetic_increment_Callback - Begin') increment = eval(get(handles.arithmetic_increment,'string')); handles.increment = increment; handles.quad_data = [handles.const_n_init,handles.const_double,handles.increment]; guidata(h,handles); Gaussian_Quad('ChooseIntegrand_Callback',handles.ChooseIntegrand,[],guidata(handles.ChooseIntegrand)) % disp('arithmetic_increment_Callback - End') % -------------------------------------------------------------------- % --- Executes during object creation, after setting all properties. function arithmetic_increment_CreateFcn(hObject, eventdata, handles) % hObject handle to arithmetic_increment (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 set(hObject,'BackgroundColor','white'); else set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end % -------------------------------------------------------------------- function varargout = GQ_Geometric_Callback(h, eventdata, handles, varargin) % disp('GQ_Geometric_Callback - Begin') handles.method = 'geometric'; quad_data = handles.quad_data; n_init = quad_data(1); doubles = quad_data(2); increment = quad_data(3); n_vec = n_init*2.^[0:doubles]; handles.n_vec = n_vec; guidata(h,handles); Calculate_Integral(h,handles); Gaussian_Quad('ChooseIntegrand_Callback',handles.ChooseIntegrand,[],guidata(handles.ChooseIntegrand)) % disp('GQ_Geometric_Callback - End') % -------------------------------------------------------------------- function varargout = GQ_Arithmetic_Callback(h, eventdata, handles, varargin) % disp('GQ_Arithmetic_Callback - Begin') handles.method = 'arithmetic'; quad_data = handles.quad_data; n_init = quad_data(1); doubles = quad_data(2); increment = quad_data(3); n_vec = n_init + increment*[0:doubles]; handles.n_vec = n_vec; guidata(h,handles); Calculate_Integral(h,handles); Gaussian_Quad('ChooseIntegrand_Callback',handles.ChooseIntegrand,[],guidata(handles.ChooseIntegrand)) % disp('GQ_Arithmetic_Callback - End') % -------------------------------------------------------------------- function Calculate_Integral(h,handles) % disp('Calculate_Integral - Begin') f_data = handles.fcn_data; quad_data = handles.quad_data; doubles = quad_data(2); n_vec = handles.n_vec; celldata = cellstr(num2str(zeros(doubles+3,1))); [integral,difference,ratio_diff]=gauss_quad(f_data,quad_data,n_vec); celldata(1) = cellstr(' Gaussian quadrature output'); % Calculate true errors and their ratios. true_integral = true_value(f_data); true_error = true_integral - integral; error_ratio = zeros(size(integral)); if doubles > 0 for i=2:doubles+1 if true_error(i) ~= 0 error_ratio(i) = true_error(i-1)./true_error(i); else error_ratio(i) = inf; end end end celldata(2) = cellstr(' n I_n difference ratio true error ratio'); for j=0:doubles n = n_vec(j+1); celldata(j+3) = cellstr(sprintf('%5i%23.14e%13.3e%13.3e%13.3e%13.3e',... n,integral(j+1),difference(j+1),ratio_diff(j+1),true_error(j+1),error_ratio(j+1))); end handles.StringData = char(celldata); guidata(h,handles); set(handles.IntegrationOutput,'string',handles.StringData); % disp('Calculate_Integral - End') % -------------------------------------------------------------------- function [integral,difference,ratio]=gauss_quad(f_data,quad_data,n_vec) % % function [integral,difference,ratio]=gauss_quad(f_data,quad_data,n_vec) % % This uses Gaussian quadrature with n node points, to % integrate the function f over the interval [a,b]. The % values of n used are taken from the input vector n_vec. % The corresponding numerical integrals are returned in the % vector integral. The differences of successive numerical % integrals are returned in the vector difference: % difference(i) = integral(i)-integral(i-1), i=2,...,doubles % The entries in ratio give the rate of decrease in these % differences. % % In using this program, define the integrand using the % function given below. % Set problem parameters n0 = quad_data(1); doubles = quad_data(2); % Initialize output vectors. integral = zeros(doubles+1,1); difference = zeros(doubles+1,1); ratio = zeros(doubles+1,1); % Do the Gaussian quadrature. for j=0:doubles n = n_vec(j+1); integral(j+1) = gaussint(n,f_data); end % Calculate the differences of the successive % Gaussian quadrature integrals and the ratio % of decrease in these differences. if doubles > 0 difference(2:doubles+1) = integral(2:doubles+1)-integral(1:doubles); end if doubles > 1 for i=3:doubles+1 if difference(i) ~= 0 ratio(i) = difference(i-1)/difference(i); else ratio(i) = inf; end end end % -------------------------------------------------------------------- function val=gaussint(n,f_data) % [val,bp,wf]=gaussint(fun,a,b,n) integrates % a function from a to b using an n-point % Gauss rule which is exact for a polynomial % of degree 2*n-1. Concepts on page 93 of % 'Methods of Numerical Integration' by % Philip Davis and Philip Rabinowitz yield % the base points and weight factors. % % a,b - integration limits % n - order of formula % val - value of the integral % bp,wf - Gauss base points and weight factors on [-1,1] a = f_data(2); b = f_data(3); u = (1:n-1)./sqrt((2*(1:n-1)).^2-1); [vc,bp] = eig(diag(u,-1)+diag(u,1)); [bp,k] = sort(diag(bp)); wf = 2*vc(1,k)'.^2; x = (a+b)/2+((b-a)/2)*bp; f = fcn(x,f_data)*(b-a)/2; val = wf(:)'*f(:); % ======================================================== % ======================================================== % ======================================================== % % This is the place to add new functions to the GUI. You must % also make a change in the "ChooseIntegrand" portion of the fig file, % adding the name of the new function to the list shown when % the table is activated. % -------------------------------------------------------------------- function fcn_val = fcn(x,f_data) indexfcn = f_data(1); a = f_data(2); b = f_data(3); c1 = f_data(4); c2 = f_data(5); switch indexfcn case 1 % f(x) = sin(c1*x) fcn_val = sin(c1*x); case 2 % f(x) = cos(c1*x) fcn_val = cos(c1*x); case 3 % f(x) = exp(c1*x) fcn_val = exp(c1*x); case 4 % f(x) = abs(x)^c1 : Need c1 > -1 unless a >= 0. if c1 <= -1 & ((a <= 0 & b >= 0)) disp('Error in f(x) = abs(x)^c1 : Need c1 > -1') fcn_val = zeros(size(x)); return end L = length(x); fcn_val = zeros(size(x)); for i=1:L if c1 < 0 & x(i) == 0 fcn_val(i) = 0; else fcn_val(i) = abs(x(i))^c1; end end case 5 % f(x) = 1/(c1+sin(x)) if c1 <= 1 disp('Error in f(x) = 1/(c1+sin(x)) : Need c1 > 1') fcn_val = zeros(size(x)); return end fcn_val = 1./(c1+sin(x)); case 6 % f(x) = exp(c1*x)*cos(c2*x) fcn_val = exp(c1*x).*cos(c2*x); case 7 % f(x) = 1/(c1 + (x-c2)^2) if c1 <= 0 disp('Error in f(x) = 1/(c1 + (x-c2)^2) : Need c1 > 0') fcn_val = zeros(size(x)); return end fcn_val = 1./(c1 + (x-c2).^2); end % -------------------------------------------------------------------- function ans = true_value(f_data) indexfcn = f_data(1); a = f_data(2); b = f_data(3); c1 = f_data(4); c2 = f_data(5); switch indexfcn case 1 % f(x) = sin(c1*x) ans = (cos(c1*a)-cos(c1*b))/c1; case 2 % f(x) = cos(x) ans = (sin(c1*b)-sin(c1*a))/c1; case 3 % f(x) = exp(c1*x) ans = (exp(c1*b)-exp(c1*a))/c1; case 4 % f(x) = abs(x)^c1 : Use only on [a,b] with a >= 0. if b < 0 ans = ((-a)^(c1+1) - (-b)^(c1+1))/(c1+1); elseif a >= 0 ans = (b^(c1+1) - a^(c1+1))/(c1+1); else ans = (b^(c1+1)+(-a)^(c1+1))/(c1+1); end case 5 % f(x) = 1/(c1+sin(x)) % Check whether b-a is longer than 2*pi. If so, reduce the length of % the interval to have the length be less than 2*pi. Later add in an % appropriate amount to compensate the integral. k = floor((b-a)/(2*pi) + 10*eps); b_mod = b - 2*pi*k; if -pi-10*eps <= a & b_mod <= pi+10*eps a_mod = a; neg = 0; elseif b_mod > pi+10*eps a_mod = b_mod - 2*pi; b_mod = a; neg = 1; elseif a < -pi-10*eps a_mod = b_mod; b_mod = a + 2*pi; neg = 1; end temp1 = GFcn(b_mod,c1) - GFcn(a_mod,c1); if neg == 1 | k > 0 temp2 = 2*pi/sqrt(c1*c1 - 1); end if neg == 1 temp1 = temp2 - temp1; end if k > 0 ans = temp1 + k*temp2; else ans = temp1; end case 6 % f(x) = exp(c1*x)*cos(c2*x) temp1 = (c1*cos(b*c2)+c2*sin(b*c2))*exp(b*c1); temp2 = (c1*cos(a*c2)+c2*sin(a*c2))*exp(a*c1); ans = (temp1-temp2)/(c1^2+c2^2); case 7 % f(x) = 1/(c1 + (x-c2)^2) con = sqrt(c1); temp1 = atan((b-c2)/con); temp2 = atan((a-c2)/con); ans = (1/con)*(temp1 - temp2); end % -------------------------------------------------------------------- function ans = GFcn(x,c) % % This evaluates the anti-derivative of the integrand 1/(c1+sin(x)). % It is restricted to the case that -pi <= x <= pi. Also, the % parameter c is required to satisfy c > 1. % temp1 = sqrt(c*c-1); temp2 = atan(1/temp1); if -pi+10*eps < x & x < pi-10*eps temp3 = c*tan(x/2) + 1; temp4 = atan(temp3/temp1); ans = (2/temp1)*(temp4 - temp2); elseif abs(x+pi) < 20*eps ans = (-2/temp1)*(pi/2 + temp2); elseif abs(x-pi) < 20*eps ans = (2/temp1)*(pi/2 - temp2); else disp('GFcn: x is outside of [-pi,pi]') end