function findeigenvalues(funcName,tol) % FINDEIGENVALUES This function will set up a Graphical Object % which can be used to find the eigenvalues of some % specified Schrodinger equation. It does this by % a binary search method, and the user must supply % an upper and lower bound for the calculation. % The call to this function is: % findeigenvalues(funcName,tol) % tol : tolerance for the calculation (default 0.0001) % funcName : the name of the function (a string) which % calculates the getjunction at x=0 between two halves of % the wave function. Both variables are optional. % This package could be used to find a zero of any % function of one variable, but it is designed to be % used in the Introduction to Quantum Theory % course. Therefore if it is not explicitly passed, % the variable funcName is assumed to be: 'getjunction'. % At the end, the value E, for which: 'funcName'(E) = 0, % will appear on the screen, and will be stored in an % array called 'spectrum' in the command workspace. %-------------------------------------------------------------------- % Open the GUI environment %-------------------------------------------------------------------- % Make sure the object containing all the global variables is open. setglobals('Hidden'); set(0,'ShowHiddenHandles','on'); %-------------------------------------------------------------------- % Test the entry information is in order %-------------------------------------------------------------------- global psi; % To share results with function 'funcName' % Set up default variables if they weren't explicitly passed. if nargin==0, funcName = 'getjunction'; end; % The variable funcName is used on different entry modes. switch funcName case {'DoTheHunt','ShowYmax','ShowYmin',... 'ClearDisplay','ExportResult','Exit'} action = funcName; otherwise action = 'Initialize'; if nargin<2, tol = 0.0001; end; end; % ------------------------------------------------------------------ % INITIALIZE THE GRAPHICAL USER INTERFACE % ------------------------------------------------------------------ if strcmp(action,'Initialize') % --------------------------------------------------- % Reopen the finder object or make a new one % --------------------------------------------------- tealColor = [0.0,0.57,0.50]; lightColor = [0.0 0.73 0.60]; h_figs = get(0,'children'); Hf_hunt = findobj(h_figs,'flat','tag',funcName); % Note: the finder is tagged with the funcName. % If it's not there the figure will have to be initialized. if length(Hf_hunt)==0 Hf_hunt = figure('color',tealColor,... 'units','normalized', ... 'position',[0.36 0.70 0.60 0.23],... 'Name','Eigenvalue finder',... 'HandleVisibility','off',... 'Tag',funcName,... 'NumberTitle','off'); % ------------------------------------------------ % Set up objects on first GUI input frame % All the handles are saved in the variable "handles" % The upper frame hndl_dummy = uicontrol(Hf_hunt,... 'style','frame',... 'backgroundcolor',tealColor,... 'units','normalized',... 'position',[0.03 0.50 0.80 0.45]); % The label for xMax hndl_dummy = uicontrol(Hf_hunt,... 'style','text',... 'backgroundcolor',tealColor, ... 'units','normalized',... 'position',[0.05 0.75 0.30 0.15],... 'string','Enter an upper bound'); % The input for xMax handles.xmax = uicontrol(Hf_hunt,... 'Style','edit',... 'units','normalized',... 'position',[0.37 0.75 0.20 0.15]); % The button for yMax handles.bmax = uicontrol(Hf_hunt,... 'Style','pushbutton',... 'backgroundcolor',tealColor,... 'units','normalized',... 'position',[0.30 0.55 0.28 0.15],... 'string','Calculate the function:'); % The value of yMax handles.ymax = uicontrol(Hf_hunt,... 'Style','text',... 'backgroundcolor',lightColor,... 'units','normalized',... 'position',[0.60 0.55 0.20 0.15]); % ------------------------------------------------ % Set up objects on second GUI input frame % The lower frame hndl_dummy = uicontrol(Hf_hunt,... 'style','frame',... 'backgroundcolor',tealColor,... 'units','normalized',... 'position',[0.03 0.00 0.80 0.45]); % The label for xMin hndl_dummy = uicontrol(Hf_hunt,... 'style','text',... 'backgroundcolor',tealColor, ... 'units','normalized',... 'position',[0.05 0.25 0.30 0.15],... 'string','Enter an lower bound'); % The input for xMin handles.xmin = uicontrol(Hf_hunt,... 'Style','edit',... 'units','normalized',... 'position',[0.37 0.25 0.20 0.15]); % The button for yMin handles.bmin = uicontrol(Hf_hunt,... 'Style','pushbutton',... 'backgroundcolor',tealColor,... 'units','normalized',... 'position',[0.30 0.05 0.28 0.15],... 'string','Calculate the function:'); % The value of yMin handles.ymin= uicontrol(Hf_hunt,... 'Style','text',... 'backgroundcolor',lightColor,... 'units','normalized',... 'position',[0.60 0.05 0.20 0.15]); % ------------------------------------------------ % Set up objects on right hand GUI input frame % The right frame hndl_dummy = uicontrol(Hf_hunt,... 'style','frame',... 'backgroundcolor',tealColor,... 'units','normalized',... 'position',[0.86 0.00 0.14 0.95]); % The button to hunt handles.bhunt = uicontrol(Hf_hunt,... 'Style','pushbutton',... 'backgroundcolor',tealColor,... 'units','normalized',... 'position',[0.88 0.71 0.10 0.18],... 'string','Hunt'); % The button to Export the solution handles.bexpt = uicontrol(Hf_hunt,... 'Style','pushbutton',... 'backgroundcolor',tealColor,... 'units','normalized',... 'position',[0.88 0.49 0.10 0.18],... 'string','Export'); % The button to clear the display handles.bclr = uicontrol(Hf_hunt,... 'Style','pushbutton',... 'backgroundcolor',tealColor,... 'units','normalized',... 'position',[0.88 0.27 0.10 0.18],... 'string','Clear'); % The button to escape handles.besc = uicontrol(Hf_hunt,... 'Style','pushbutton',... 'backgroundcolor',tealColor,... 'units','normalized',... 'position',[0.88 0.05 0.10 0.18],... 'string','Close'); % ------------------------------------------------ % Re-open the wave solution graph, or open a new one handles.grph = OpenSolutionGraph; % This is in the SUBSIDIARY FUNCTION section % If the solution is to be plotted, the handle to its % figure will be stored as the 16th handle. % ------------------------------------------------ % Store other handles and passed variables for use in callBacks handles.tol = tol; % NOTE: The variable 'tol' is stored as the 17th handle. % The name of the function is stored in the 'tag' % of the figure. It can't be stored in 'userdata'. handles.E = 0; % The final result of the search is stored as % the 18th handle so it can be displayed later. set(Hf_hunt,'userdata',handles); % ------------------------------------------------ % Set up the callBack events for data entry buttons inputMaxCall = ... ['findeigenvalues(''ShowYmax'');']; set(handles.xmax,'callBack',inputMaxCall); set(handles.bmax,'callBack',inputMaxCall); inputMinCall = ... ['findeigenvalues(''ShowYmin'');']; set(handles.xmin,'callBack',inputMinCall); set(handles.bmin,'callBack',inputMinCall); % ------------------------------------------------ % Set up the callBack events for control buttons huntCall = ... ['findeigenvalues(''DoTheHunt'');']; set(handles.bhunt,'callBack',huntCall); ExportCall = ... ['findeigenvalues(''ExportResult'');']; set(handles.bexpt,'callBack',ExportCall); clearCall = ... ['findeigenvalues(''ClearDisplay'');']; set(handles.bclr,'callBack',clearCall); closeCall = ... ['set(0,''ShowHiddenHandles'',''on'');'... 'close;'... 'set(0,''ShowHiddenHandles'',''off'');']; set(handles.besc, 'callBack',closeCall); % ------------------------------------------------ else % if length(Hf_hunt)~=0, tolerance might have changed Hf_hunt = gcf; handles = get(gcf,'userdata'); if nargin>1 handles.tol = tol; set(gcf,'userdata',handles); end; end; figure(Hf_hunt); end; % if strcmp(action,'initialize') % ------------------------------------------------------------------ % PART 2: HUNT FOR THE ZERO % ------------------------------------------------------------------ if strcmp(action,'DoTheHunt') Hf_hunt = gcf; handles = get(gcf,'userdata'); tol = handles.tol; funcName = get(gcf,'tag'); OpenSolutionGraph; % --------------------------------------------------- % Check appropriate bounds are entered % --------------------------------------------------- OKtoProceed = 1; xMaxStr = get(handles.xmax,'string'); xMinStr = get(handles.xmin,'string'); if (isempty(xMaxStr))|(isempty(xMinStr)), warndlg('Both bounds have not been entered.'); OKtoProceed = 0; else xMax = str2num(get(handles.xmax,'string')); yMax = str2num(get(handles.ymax,'string')); xMin = str2num(get(handles.xmin,'string')); yMin = str2num(get(handles.ymin,'string')); if yMax*yMin>0, warndlg('Both endpoints have the same sign.'); OKtoProceed = 0; end; end; % --------------------------------------------------- % Narrow the bounds by binary chop % --------------------------------------------------- if OKtoProceed==1 for counter=1:25 xNew = (xMin + xMax)/2; yNew = feval(funcName,xNew,'show'); if (yNew*yMin>0), xMin=xNew; yMin=yNew; end; if (yNew*yMin==0), break, end; if (yNew*yMin<0), xMax=xNew; yMax=yNew; end; if (abs(xMax-xMin)