# An Introduction to the Mathematical Theory of Waves

### Roger Knobel (view profile)

20 Aug 2002 (Updated )

Companion Software

wvfour2(action)
function wvfour2(action)
%WVFOUR2  Visual construction of Fourier sine series
%
%         <DESCRIPTION>
%         wvfour2 is a graphical interface for constructing Fourier sine series
%         approximations of a function f(x) by manually adjusting coefficients
%         c(n) of
%
%               sum( c(n) sin(n Pi x), n=1:N)
%
%         <TO RUN>
%         Type wvfour2 at the MATLAB prompt with no arguments.
%
%         <TO USE>
%         Once started, two plot areas are shown.  On the bottom is a graph of
%         coefficients c(1),c(2),c(3),... which are used to define the function
%
%              S(x) = c(1)sin(Pi x) + c(2)sin(2Pi x) + c(2)sin(3Pi x) + ...
%
%         The values of c(n) can be changed by clicking on the graph of c(n).
%
%         On top are the graphs of the default function f(x) and S(x).  By
%         clicking on the lower plot area to change the values of c(n), the
%         resulting change in S(x) is displayed in the top graph.  By watching
%         the changes in S(x), one can attempt to adjust the coefficients c(n)
%         so that S(x) approximates f(x).
%
%         Set Coefficient Buttons:
%
%           All Zero - sets all c(n) back to 0
%           Actual   - sets all c(n) to the actual Fourier sine series coefficients
%
%
%           Hide - hides the actual Fourier sine coefficients from the bottom plot.
%           Show - displays the actual Fourier sine coefficients on the bottom
%                  plot in addition to the values of c(n)
%

% Created: 6/95 by R. Knobel
% Requires: MATLAB 4.2(c) - MATLAB 5.2

if nargin < 1
action = 'start';
end

if ~strcmp(action,'start'),
handles = get(gcf,'UserData');
hFunction = handles(1);
hAxes1 = handles(2);
hAxes2 = handles(3);
hPlot1a = handles(4);
hPlot1b = handles(5);
hHide = handles(6);
hShow = handles(7);

handles = get(hAxes2,'UserData');
hPlot2a = handles(1,:);
hPlot2b = handles(2,:);

end;

% Number of terms to use in the truncated series. Used by most actions

Max_terms = 10;

if strcmp(action,'start'),

bgcolor = 'black';
fgcolor = 'white';

set(gcf, ...
'NumberTitle','off', ...
'Name','Constructing Fourier Sine Series', ...
'BackingStore','off',...
'Units','normalized',...
'Color',bgcolor);

% The CONSOLE frame

top   =0.95;
bottom=0.05;
left  =0.87;
right =0.97;
btnHt =0.08;
btnWid=0.10;
space =0.02;

frmPos=[left-space bottom-space right-left+2*space top-bottom+2*space];
uicontrol( ...
'Style','frame', ...
'Units','normalized', ...
'Position',frmPos, ...
'ForegroundColor','white',...
'BackgroundColor','black');

% Buttons to set the adjustable coefficients to All Zero or to their
% Actual Fourier sine series values

uicontrol( ...
'Style','Frame',...
'Units','normalized',...
'Position',[left-.01 .71 btnWid+.02 .20],...
'BackgroundColor','black',...
'ForegroundColor','white');
uicontrol( ...
'Style','Text',...
'Units','normalized',...
'Position',[left .84 btnWid .05],...
'String','Set Coeff',...
'ForegroundColor','red',...
'BackgroundColor','black');
uicontrol( ...
'Style','Push', ...
'Units','normalized', ...
'Position',[left .79 btnWid .05],...
'String','All Zero',...
'CallBack','wvfour2(''setcoeffzero'')');
uicontrol( ...
'Style','Push',...
'Units','normalized',...
'Position',[left .72 btnWid .05],...
'String','Actual',...
'CallBack','wvfour2(''setcoeffactual'')');

%==========================================
%  To Hide or Show Actual Coefficients with the adjustable coefficients

uicontrol( ...
'Style','Frame',...
'Units','normalized',...
'Position',[left-.01 .36 btnWid+.02 .24],...
'BackgroundColor','black',...
'ForegroundColor','white');
uicontrol( ...
'Style','Text',...
'Units','normalized',...
'Position',[left .47 btnWid .10],...
'String','Actual Coeff',...
'Backgroundcolor','black',...
'Foregroundcolor','red');
hHide = uicontrol(...
'String','Hide',...
'Units','normalized',...
'Position',[left .42 btnWid .05],...
'Value',1,...
'CallBack','wvfour2(''actualhide'')',...
'BackgroundColor',[.8 .8 .8]);
hShow = uicontrol(...
'String','Show',...
'Units','normalized',...
'Position',[left .37 btnWid .05],...
'Value',0,...
'CallBack','wvfour2(''actualshow'')',...
'BackgroundColor',[.8 .8 .8]);

% The Restart button

uicontrol( ...
'Style','push', ...
'Units','normalized', ...
'Position',[left bottom+btnHt+space btnWid btnHt], ...
'String','Restart', ...
'Callback','wvfour2(''restart'')');

% The CLOSE button

uicontrol('Style','Pushbutton', ...
'Units','normalized',...
'Position',[left bottom btnWid btnHt], ...
'Callback','wvfour2(''close'')',...
'String','Close');

% Field in middle of screen to enter f(x)

f = 'x*(1-x)';

uicontrol('Style','text',...
'Units','normalized',...
'Position',[.23 .48 .10 .045],...
'BackgroundColor',bgcolor,...
'ForegroundColor',fgcolor,...
'String','f(x) = ');
hFunction=uicontrol(...
'Style','edit',...
'Units','normalized',...
'Position',[.33 .48 .25 .045],...
'BackgroundColor','white',...
'ForegroundColor','black',...
'String',f);

%========================================
% Setup Initial Plot Areas

% Top axis contains the plots of f(x) (green) and the
% Fourier approx (yellow)

hAxes1 = axes(...
'Position',[.10 .62 .70 .30],...
'XLim',[0 1],...
'YLim',[0 1],...
'XColor',fgcolor,...
'YColor',fgcolor,...
'Color',bgcolor);
hold on;
xlabel('x');
ylabel('f(x)');
title('Green - f(x)    Yellow - Constructed Fourier Sine Series','Color',fgcolor);
hPlot1a = plot(0,0,'g','EraseMode','xor');
hPlot1b = plot(0,0,'y','EraseMode','xor');

% Bottom axis contains the plots of the Fourier coeff for f(x) (green)
% and the movable coeff (yellow).  A blue dashed line along y=0
% is also drawn for reference.

hAxes2 = axes(...
'Position',[.10 .12 .70 .30],...
'XLim',[0 Max_terms],...
'YLim',[0,1],...
'XColor',fgcolor,...
'YColor',fgcolor,...
'Color',bgcolor,...
'ButtonDownFcn', 'wvfour2(''click'')' );
hold on;
xlabel('Click on plot to move values of c(n)');
ylabel('Coefficients of sin(n*Pi*x)');
for k=1:Max_terms
hPlot2a(k) = plot(k,0,'go','EraseMode','xor',...
'Visible','off',...
'Interruptible','yes',...
'ButtonDownFcn','wvfour2(''click'')');
hPlot2b(k) = plot(k,0,'yo','EraseMode','xor',...
'ButtonDownFcn','wvfour2(''click'')');
end;

handles = [hPlot2a;hPlot2b];
set(hAxes2,'UserData',handles);

plot([0 Max_terms], [0 0], 'w:', 'EraseMode','xor',...
'ButtonDownFcn','wvfour2(''click'')');

handles = [hFunction hAxes1 hAxes2 hPlot1a hPlot1b hHide hShow];
set(gcf,'UserData',handles);

% Start the plots

wvfour2('restart')

elseif strcmp(action,'restart'),

% Recompute Fourier coefficients

x = linspace(0,1,100);
f = get(hFunction,'String');
l = length(f);
for k = fliplr(find((f=='^') | (f=='*') | (f=='/')))
if ~strcmp(f(k-1),'.')
f = [f(1:k-1) '.' f(k:l)];
l = l+1;
end
end
vector_f = f;

for k=1:Max_terms,
integrand = ['(' vector_f ').* sin(pi*' num2str(k) '*x)'];
sin_coeff(k) = 2*sum( eval(integrand) ) / 100;
end;

% Recompute axis limits for upper plot

y = eval(vector_f);
if length(y)==1,
y = y*ones(size(x));
end;

a = min(y);
b = max(y);
scale = b-a;
if scale==0,
scale=1;
end;

min_y = min([0 a-.1*scale]);
max_y = max([0 b+.1*scale]);
set(hAxes1, 'YLim',[min_y max_y]);

% Plot original function (this stays fixed unless restarted)

set(hPlot1a, 'XData',x,'YData',y);

% Recompute axis limits for lower plot

b = max( abs(sin_coeff) );
if b==0,
b = 0.1;
end;

min_y = -1.3*b;
max_y =  1.3*b;
set(hAxes2, 'YLim',[min_y max_y]);

% Plot the actual Fourier coeff of f(x).
% These are hidden until the Show radio button is pushed.

for k=1:Max_terms
set(hPlot2a(k),'YData',sin_coeff(k),'Visible','off')
end;
set(hHide,'Value',1)
set(hShow,'Value',0)

for k=1:Max_terms
set(hPlot2b(k),'YData',0);
end;

wvfour2('draw')

elseif strcmp(action,'click'),

% Get (x,y) coordinates of mouse click

pt=get(gca,'currentpoint');
x =pt(1,1);
y =pt(1,2);

% Determine nearest value of n to the x coordinate
% (within limits)

n = round(x);
if n<1
n = 1;
elseif n > Max_terms
n = Max_terms;
end;

% Move Coeff(n) up/down to the height of the click

coeff = y;
y_limits = get(hAxes2,'YLim');
if coeff<y_limits(1)
coeff = y_limits(1);
elseif coeff>y_limits(2)
coeff = y_limits(2);
end;

% Redraw figures

set(hPlot2b(n),'YData',coeff);
wvfour2('draw')

elseif strcmp(action,'draw')

% Redraw Fourier Series plot in top graph

x = linspace(0,1,100);
y = zeros( size(x) );
for k=1:Max_terms,
coeff = get(hPlot2b(k),'YData');
y = y + coeff * sin(k*pi*x);
end;
set(hPlot1b,'XData',x,'YData',y)

% Redraw Fourier coefficients in lower graph
%
%for k=1:Max_terms,
%   set(hPlot2b(k), 'YData', Coeff(k));
%end;

elseif strcmp(action(1:4),'setc'),

if strcmp(action,'setcoeffzero')
for k=1:Max_terms
set(hPlot2b(k),'YData',0);
end;
elseif strcmp(action,'setcoeffactual')
for k=1:Max_terms
true_coeff = get(hPlot2a(k),'YData');
set(hPlot2b(k),'YData',true_coeff);
end;
end;

wvfour2('draw')

elseif strcmp(action(1:4),'actu'),

% Show or hide the actual Fourier coefficients.

if strcmp(action,'actualhide')
for k=1:Max_terms
set(hPlot2a(k),'Visible','off')
end;
set(hHide,'Value',1)
set(hShow,'Value',0)
elseif strcmp(action,'actualshow'),
for k=1:Max_terms
set(hPlot2a(k),'Visible','on')
end;
set(hHide,'Value',0)
set(hShow,'Value',1)
end;

elseif strcmp(action,'close'),

close

end