# An Introduction to the Mathematical Theory of Waves

### Roger Knobel (view profile)

20 Aug 2002 (Updated )

Companion Software

wvstring(action)
```function wvstring(action)
%WVSTRING Animation of waves on a semi-infinite string.
%
%         <DESCRIPTION>
%         wvstring is a graphical interface for animating D'Alembert's
%         solution of the wave equation on a semi-infinite string with given
%         initial displacement and anti-derivative of initial velocity:
%
%                 u_tt = u_xx,  x > 0, t>0
%                 u(x,0) = f(x)
%                 u_t(x,0) = G'(x)
%
%                 u(0,t) = 0 OR u_x(0,t) = 0
%
%         <TO RUN>
%         Type wvstring at the MATLAB prompt.
%
%         <TO USE>
%         Once started, controls of the animation may be set:
%
%             Time t   -  Animate the solution u(x,t) over the time interval t0<t<t1
%             Range x  -  Plot u(x,t) in the ux-plane over the interval x0<x<x1
%             Animation - Slider to adjust the speed of animation.
%             Boundary  - Radio control to select either a string with pinned
%                         end (u(0,t)=0) or free end (u_x(0,t)=0).
%             f(x)      - Field to define the initial string position u(x,0)
%             G(x)      - Field to define the antiderivative of the initial
%                         string velocity.
%
%         Once set, press the PLAY button to animate.  The animation can
%         then be PAUSED and RESUMED by pressing the PLAY button.

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

if nargin < 1
action = 'start';
end

if ~strcmp(action,'start'),
handles=get(gcf,'UserData');
hPlot = handles(1);
hAxes = handles(2);
hRing = handles(3);
hInitialPos = handles(4);
hInitialVelocity = handles(5);
hXmin = handles(6);
hXmax = handles(7);
hTmin = handles(8);
hTmax = handles(9);
hSpeed = handles(10);
hBC1 = handles(11);
hBC2 = handles(12);
hPlay = handles(13);
end;

C = 1;   % string speed for now.  Have it a uicontrol later.

if strcmp(action,'start'),

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

figure;
set(gcf, ...
'NumberTitle','off', ...
'Name','D''Alembert''s Semi-Infinite String', ...
'backingstore','off',...
'Units','normalized',...
'Color',bgcolor);

% Control Panel

top      =0.95;
bottom   =0.05;
left     =0.82;
btnWid   =0.13;
btnHt    =0.06;
spacing  =0.02;
frmBorder=0.02;
frmPos=[.79 .05 btnWid+3*frmBorder .92];
uicontrol( ...
'Style','frame', ...
'Units','normalized', ...
'Position', frmPos, ...
'ForegroundColor',fgcolor,...
'BackgroundColor',bgcolor);

%  Time Interval

uicontrol( ...
'Style','text',...
'Units','normalized',...
'Position', [.81 .905 .15 .04],...
'BackgroundColor',bgcolor,...
'ForegroundColor','red',...
'String','Time t');

uicontrol( 'Style','text',...
'Units','normalized',...
'Position', [.81 .86 .08 .04],...
'BackgroundColor',bgcolor,...
'ForegroundColor',fgcolor,...
'String','Initial');
min_t = 0;
hTmin=uicontrol( ...
'Style','edit',...
'Units','normalized',...
'Position', [.89 .86 .07 .04],...
'BackgroundColor','white',...
'ForegroundColor','black',...
'String',num2str(min_t));

uicontrol( 'Style','text',...
'Units','normalized',...
'Position', [.81 .81 .08 .04],...
'BackgroundColor',bgcolor,...
'ForegroundColor',fgcolor,...
'String','Final');
max_t = 10;
hTmax=uicontrol( ...
'Style','edit',...
'Units','normalized',...
'Position', [.89 .81 .07 .04],...
'BackgroundColor','white',...
'ForegroundColor','black',...
'String',num2str(max_t));

% X Interval

uicontrol( ...
'Style','text',...
'Units','normalized',...
'Position', [.81 .73 .15 .04],...
'BackgroundColor',bgcolor,...
'ForegroundColor','red',...
'String','Range x');

uicontrol( 'Style','text',...
'Units','normalized',...
'Position', [.81 .68 .06 .04],...
'BackgroundColor',bgcolor,...
'ForegroundColor',fgcolor,...
'String','Min');
min_x = 0;
hXmin=uicontrol( ...
'Style','edit',...
'Units','normalized',...
'Position', [.87 .68 .09 .04],...
'BackgroundColor','white',...
'ForegroundColor','black',...
'String',num2str(min_x));

uicontrol( 'Style','text',...
'Units','normalized',...
'Position', [.81 .63 .06 .04],...
'BackgroundColor',bgcolor,...
'ForegroundColor',fgcolor,...
'String','Max');
max_x = 10;
hXmax=uicontrol( ...
'Style','edit',...
'Units','normalized',...
'Position', [.87 .63 .09 .04],...
'BackgroundColor','white',...
'ForegroundColor','black',...
'String',num2str(max_x));

% Animation Speed Control

uicontrol(...
'Style','text',...
'Units','normalized',...
'Position',[.81 .55 .15 .04],...
'BackgroundColor',bgcolor,...
'ForegroundColor','red',...
'String','Animation');

min_frames= 1;
max_frames= 50;
speed     = 25;
hSpeed=uicontrol( ...
'Style','slider',...
'Units','normalized',...
'Position',[.81 .50 .15 .04],...
'Value',speed,...
'Max',max_frames,...
'Min',min_frames);
uicontrol(...
'Style','text',...
'Units','normalized',...
'Position',[.805 .46 .06 .04],...
'BackgroundColor',bgcolor,...
'ForegroundColor',fgcolor,...
'String','Fast');
uicontrol(...
'Style','text',...
'Units','normalized',...
'Position',[.91 .46 .055 .04],...
'BackgroundColor',bgcolor,...
'ForegroundColor',fgcolor,...
'String','Slow');

uicontrol(...
'Style','frame',...
'Units','normalized',...
'Position',[.81 .3 .15 .14],...
'BackGround',bgcolor,...
'ForeGround','red');
uicontrol(...
'Style','text',...
'String','Boundary',...
'Units','normalized',...
'Position',[.84 .39 .11 .04],...
'BackGround',bgcolor,...
'ForeGround',fgcolor);
hBC1 = uicontrol(...
'String','u(0,t)=0',...
'BackGround',bgcolor,...
'ForeGround',fgcolor,...
'Units','normalized',...
'Position',[left .35 btnWid .04],...
'Value',1,...
'CallBack','wvstring(''bc1'')');
hBC2 = uicontrol(...
'String','u_x(0,t)=0',...
'BackGround',bgcolor,...
'ForeGround',fgcolor,...
'Units','normalized',...
'Position',[left .31 btnWid .04],...
'CallBack','wvstring(''bc2'')');

% Play/Pause/Restart Button

hPlay = uicontrol( ...
'Style','push', ...
'Units','normalized', ...
'Position',[left .12+btnHt  btnWid btnHt], ...
'String','Play', ...
'Interruptible','yes',...
'Callback', 'wvstring(''play_click'')' );

% Close Button

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

% Fields to define initial position and velocity

f = 'exp( -(x-3)^2)';
uicontrol( ...
'Style','text',...
'Unit','normalized',...
'Position',[.03 .06 .10 .05],...
'BackgroundColor',bgcolor,...
'ForegroundColor','red',...
'String','Initial');
uicontrol( ...
'Style','text',...
'Unit','normalized',...
'Position',[.03 .02 .10 .05],...
'BackgroundColor',bgcolor,...
'ForegroundColor','red',...
'String','Position');
uicontrol( ...
'Style','text',...
'Unit','normalized',...
'Position',[.13 .04 .10 .05],...
'BackgroundColor',bgcolor,...
'ForegroundColor',fgcolor,...
'String','f(x) =');
hInitialPos = uicontrol(...
'Style','edit',...
'Units','normalized',...
'Position',[.23 .04 .15 .05],...
'BackgroundColor','white',...
'ForegroundColor','black',...
'String',f);

G = '0';
uicontrol('Style','text',...
'Units','normalized',...
'Position',[.40 .10 .15 .05],...
'BackgroundColor',bgcolor,...
'ForegroundColor','red',...
'String','Antiderivative');
uicontrol('Style','text',...
'Units','normalized',...
'Position',[.40 .06 .10 .05],...
'BackgroundColor',bgcolor,...
'ForegroundColor','red',...
'String','of Initial');
uicontrol('Style','text',...
'Units','normalized',...
'Position',[.40 .02 .10 .05],...
'BackgroundColor',bgcolor,...
'ForegroundColor','red',...
'String','Velocity');
uicontrol('Style','text',...
'Units','normalized',...
'Position',[.50 .04 .10 .05],...
'BackgroundColor',bgcolor,...
'ForegroundColor',fgcolor,...
'String','G(x) =');

hInitialVelocity = uicontrol(...
'Style','edit',...
'Units','normalized',...
'Position',[.6 .04 .15 .05],...
'BackgroundColor','white',...
'ForegroundColor','black',...
'String',G);

% Setup main plot area

hAxes = axes(...
'Units','normalized',...
'Position',[.12 .28 .6 .6],...
'XLim',[min_x max_x],...
'YLim',[0 1],...
'Color',bgcolor,...
'XColor',fgcolor,...
'YColor',fgcolor);
hold on;
xlabel('x');
ylabel('u');

hRing = plot(min_x,0,'ro','EraseMode','xor');
hPlot = plot(min_x,0,'y','EraseMode','xor');

handles=[hPlot hAxes hRing hInitialPos hInitialVelocity hXmin hXmax ...
hTmin hTmax hSpeed hBC1 hBC2 hPlay];
set(gcf,'UserData',handles);

wvstring('restart')

elseif strcmp(action,'restart'),

f     = get(hInitialPos,'String');
G     = get(hInitialVelocity,'String');
min_t = str2num(get(hTmin,'String'));
max_t = str2num(get(hTmax,'String'));
min_x = str2num(get(hXmin,'String'));
max_x = str2num(get(hXmax,'String'));

x = linspace(min_x,max_x,50);
delx = x(2)-x(1);

if isempty(findstr(f,'x')),
f = [f ' .* ones(size(x))'];
end;
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;
y1 = eval(vector_f);
max_f = max(abs(y1(:)));

if isempty(findstr(G,'x')),
G = [G ' .* ones(size(x))'];
end;
l = length(G);
for k = fliplr(find((G=='^') | (G=='*') | (G=='/')))
if ~strcmp(G(k-1),'.')
G = [G(1:k-1) '.' G(k:l)];
l = l+1;
end
end
vector_G = G;
y2 = eval(vector_G);
max_G = max(abs(y2(:)));

max_u = 1.1*(max_f + max_G + eps);

[a m] = min( abs(x) );
set(hAxes, 'XLim',[min_x max_x], 'YLim',[-max_u max_u]);
set(hRing, 'YData',y1(m))
set(hPlot, 'XData',x,'YData',y1);

set(hPlay,'String','Play')

elseif strcmp(action,'move'),

one_over_2c = 1/(2*C);

min_x = str2num(get(hXmin,'String'));
max_x = str2num(get(hXmax,'String'));
x     = linspace(min_x,max_x,100);
X     = x;
[a m] = min( abs(x) );

min_t = str2num(get(hTmin,'String'));
max_t = str2num(get(hTmax,'String'));
speed = get(hSpeed,'Value');
frames= fix(speed * (max_t - min_t));
del_t  = (max_t - min_t) / frames;

f     = get(hInitialPos,'String');
G     = get(hInitialVelocity,'String');

if isempty(findstr(f,'x')),
f = [f ' .* ones(size(x))'];
end;
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;

if isempty(findstr(G,'x')),
G = [G ' .* ones(size(x))'];
end;
l = length(G);
for k = fliplr(find((G=='^') | (G=='*') | (G=='/')))
if ~strcmp(G(k-1),'.')
G = [G(1:k-1) '.' G(k:l)];
l = l+1;
end
end
vector_G = G;

set(hPlay,'String','Pause')

if get(hBC1,'Value')==1,

for j=1:frames,

t = min_t + j*del_t;
x = X + C*t;
y1 = eval(vector_f);
y2 = eval(vector_G);
u1 = .5*y1 + one_over_2c * y2;

x = X - C*t;
x_pos = x>=0; % full( spones(.5 * ( x + abs(x)) ));
x_neg = x<=0; % full( spones(.5 * ( x - abs(x)) ));
y1 = eval(vector_f);
y2 = eval(vector_G);
u2 = ( .5*y1 - one_over_2c * y2 ) .* x_pos;

x = -x;
y1 = eval(vector_f);
y2 = eval(vector_G);
u3 = ( -.5*y1 - one_over_2c * y2) .* x_neg;

u = u1 + u2 + u3;
set(hPlot,'XData',X,'YData',u)
set(hRing,'YData',0)
pause(0.01)

while strcmp(get(hPlay,'String'),'Resume'),
pause(0.01)
end

end

elseif get(hBC2,'Value')==1,

for j=1:frames,

t = min_t + j*del_t;
x = X + C*t;
y1 = eval(vector_f);
y2 = eval(vector_G);
u1 = .5*y1 + one_over_2c * y2;

x = X - C*t;
x_pos = x>=0; % full( spones(.5 * ( x + abs(x)) ));
x_neg = x<=0; % full( spones(.5 * ( x - abs(x)) ));
y1 = eval(vector_f);
y2 = eval(vector_G);
u2 = ( .5*y1 - one_over_2c * y2 ) .* x_pos;

x = -x;
y1 = eval(vector_f);
y2 = eval(vector_G);
u3 = ( .5*y1 + one_over_2c * y2) .* x_neg;

x  = zeros(size(y2));
y1 = eval(vector_f);
y2 = eval(vector_G);
u4 = -2*one_over_2c * y2 .* x_neg;

u = u1 + u2 + u3 + u4;
set(hRing,'YData',u(m))
set(hPlot,'XData',X,'YData',u)
pause(0.01)

while strcmp(get(hPlay,'String'),'Resume'),
pause(0.01)
end

end

end;

set(hPlay','String','Restart')

elseif strcmp(action,'play_click')

cur_string = get(hPlay,'String');

if strcmp(cur_string,'Restart'),
wvstring('restart')
elseif strcmp(cur_string,'Play'),
wvstring('move')
elseif strcmp(cur_string,'Pause'),
set(hPlay,'String','Resume')
elseif strcmp(cur_string,'Resume')
set(hPlay,'String','Pause')
end;

elseif strcmp(action(1:2),'bc'),

if strcmp(action,'bc1'),
set(hBC1,'Value',1);
set(hBC2,'Value',0);
else
set(hBC1,'Value',0);
set(hBC2,'Value',1);
end;

elseif strcmp(action,'close'),

close

end
```