This question already has an answer here:
How to disable the progress bar when using the nlfilter function in Matlab?
(1 answer)
Closed 5 years ago.
I'm using a code in Matlab composed of a large number of nested functions. A large number of these functions show progressbars. Is there any Matlab command or any possibility to disable progressbars showing, without having to locate and comment/remove all the lines where they are called from?
I assume from your comments you mean you have lots of functions calling waitbar.
You could overload the 'waitbar' function with your own waitbar.m ensuring its higher on the searchpath. Although this is not usually a good idea and may cause problems in the future when you (or anyone else you uses your codes) do want to use the waitbar and it doesn't appear.
Another (preferable in my view) way to disable it is to create your own intermediate function where you can toggle on/off the waitbar:
function h = mywaitbar ( varargin )
% preallocate output
h = [];
% use an internal persistent variable
persistent active
% by default set to true
if isempty ( active ); active = true; end
% Check to see if its a control call
if nargin == 1 && ischar ( varargin{1} )
% is it a call to disable it?
if strcmp ( varargin{1}, '**disable**' )
active = false;
else
active = true;
end
return
end
if active
h = waitbar ( varargin{:} );
end
end
The downside to this is that you will need to find and replace all your waitbar commands with the new function 'waitbar', but this is a one time only action.
Then disable all future calls to waitbar by:
mywaitbar ( '**disable**' )
Run your codes and no waitbar will be shown. The use of a peristent variable will keep the status until you restart Matlab (or you invoke clear all). To stop 'clear all' resetting it you can use mlock in the function.
To reenable the waitbar:
mywaitbar ( '**enable**' )
To test it use the following code:
for ii=1:10
h = mywaitbar ( ii );
fprintf ( 'test with waitbar %i\n', ii);
end
Now disable the waitbar capability:
mywaitbar ( '**disable**' )
for ii=1:10
h = mywaitbar ( ii );
fprintf ( 'test with waitbar disabled %i\n', ii);
end
You will see that the code above runs with no waitbar being shown.
Related
I have an external function say "external_func" (seperate .m file)
Inside this function a while loop is called, and this while loop update a variabl named "update_prog"
Now I will pass this value into the GUIDE using
assignin('base', 'update_prog', update_prog); % passing to workspace
I am making this
"update_prog" as global variable and calling it into GUIDE .m file
function pb1_Callback(hObject, eventdata, handles)
global update_prog
% hObject handle to pb1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% else
% set(handles.pb1,'enable','on');
% end
% update_prog first value prints, but it wont updates as the loop in external_func goes on.
drawnow;
set(handles.slider1,'Value',update_prog)
external_func;
so here in the GUIDE .m file I can get the value
"update_prog" but it wont keep up with the while loop. I used "drawnow" but its of no use.
How can I refine this value "update_prog" as the while loop in the "external_func" goes through multiple iterations. [Note: The updated values are there in the callback function of GUIDE, but unless there is a callback the callback function wont update the "update_prog"], so how can I acheive this real-time update inside a call_back function.
[Note: passing the variables through function input is not possible here in my case, so I am looking for alternatives]
Edit1: please consider this link, which has an exampleWhich may clarify you what I am trying to acheive
What I am doing here is
Passing the variable(which is being updated in the while loop of the externel function) into GUI.
I will use this variable to show the progress on the progress bar(Slider).
What is the problem?
1. The variable inside the GUI callback(Consdier I will press a push button and then it will call the function with while loop) will put the updated values into the set(handles.slider,'Value',variable)
By doing this I cant move the slider.
Why?
Callback updates the variable only when I press the push button, next all the updates to the variable will not be updated, so progress bar/slider wont move.
I wouldn't recommend to pass your variable in 3 steps with an intermediate workspace (external->base workspace->GUI). I would rather recommend to pass your variable directly (external->GUI).
Each Matlab figure offers a space to store variables (Application Data) of any type. I would suggest reading the article Share Data Among Callbacks and read the documentation for the 3 functions:
guidata
setappdata
getappdata
This way will offer you much more control over the scope of your variables and you won't need any global declaration.
Below is an example of a simple gui. The gui declare the variable in it's user space (with setappdata), then uses a timer to periodically read this variable (with getappdata).
The external function do whatever you want it to do (just a random number in the example), then to update the variable you use the same setappdata. The only thing you need for that is the handle of the main GUI figure, so in the example I give it as input of the external function.
The GUI also has two buttons to start and stop the update.
The code for the main example GUI 'theGui.m' is :
function h = theGui
%// basic GUI with 2 buttons and 1 slider
h.fig = figure('Position',[433 434 500 100],'Menubar','none','CloseRequestFcn',#my_closefcn) ;
h.sld = uicontrol('Style','Slider','Position',[20 20 460 20]) ;
h.btnStart = uicontrol('Style','pushbutton','String','Start updating','Callback',#btnStart_callback,'Position',[20 50 200 30]);
h.btnStop = uicontrol('Style','pushbutton','String','Stop updating','Callback',#btnStop_callback,'Position',[280 50 200 30],'Max',1,'Min',0);
%// Define the timer
h.t = timer ;
h.t.Period = 0.1 ; %// 0.1s refresh interval
h.t.TimerFcn = {#timer_callback,h.fig} ;
h.t.ExecutionMode = 'fixedSpacing' ;
%// initialise the variable to update in the GUI appdata
update_prog = 0 ;
setappdata( h.fig , 'update_prog' , update_prog ) ;
%// save handles
guidata( h.fig , h );
function btnStart_callback(hobj,~)
h = guidata( hobj ) ; %// retrieve handles
if strcmp('off',h.t.Running) %// Start timer (only if not already running)
start(h.t)
end
function btnStop_callback(hobj,~)
h = guidata( hobj ) ; %// retrieve handles
stop(h.t) %// Stop timer
function timer_callback(~,~,hfig)
update_prog = getappdata( hfig , 'update_prog' ) ; %// retrieve the 'update_prog' variable value
h = guidata( hfig ) ; %// retrieve handles
set(h.sld , 'Value' , update_prog) ; %// update the slider object with the retrieved value
function my_closefcn(hobj,~)
%// this function is only to clean up when the GUI will be closed.
%// It is recommended to delete the timer manually
h = guidata( hobj ) ; %// retrieve handles
stop(h.t) %// Stop timer (in case it is still running)
delete(h.t) ; %// delete the timer
delete(h.fig) ; %// destroy the figure
And the code for external_func.m
function external_func( guiMainFigureHandle )
%// This function will only generate random numbers and push them into the
%// variable 'update_prog' contained in the GUI appdata.
%// This is why this function NEEDS the handle of the gui to be able to
%// access the Application Data space of the gui.
for k = 1:100
randomValue = rand(1) ; %// generate a random value
hfig = ancestor( guiMainFigureHandle , 'figure' ) ; %// make sure the handle provided is the top level figure
setappdata( hfig , 'update_prog' , randomValue) ; %// update the variable value
pause(0.1) ;
end
Edit:
I place this in edit instead of changing the code above because I don't recommend messing with the root object if you don't need to. But in your case it can be a way round your problem.
If your external function doesn't have access to the GUI, it can always update a part of memory which is available for all the programs running in a given Matlab session, namely the root object. The handle for it is reserved and is the same for any program: 0 (although since v2014b there is another way to invoke it : groot, it is still always the same handle for all Matlab).
So in the example above, in theGui.m, use instead:
setappdata( 0 , 'update_prog' , update_prog ) ;
in the main routine, then in the subfunction function timer_callback(~,~,hfig), use:
update_prog = getappdata( 0 , 'update_prog' ) ; %// retrieve the 'update_prog' variable
And your function external_func() doesn't need any extra argument, the update only needs one line:
setappdata( 0 , 'update_prog' , update_prog) ; %// update the variable value
I "suspect" that your update_prog variable in the base workspace is not a global (you must define it to be global in every workspace that you want to use it).
Since your using globals (there are many better ways to do this - but thats not your question) - why don't you simply define the update_prog variable to be global in your external_func function (replace the assign call).
edit put a drawnow in your external_func function. That way when you click on the button it will update.
edit 3
I think I know what you want to do, try this example and see if it does what you want - updated to show how you find the slider object in your code and update inside your loop:
function mygui
% create a figure
f = figure;
% create a uicontrol slider - note that I give it a tag.
uicontrol ( 'style', 'slider', 'Position', [0 200 200 40], 'tag', 'MYSLIDER', 'backgroundcolor', 'white', 'parent', f );
% create a push button which we can press to update
uicontrol ( 'string', 'Press 2 start', 'callback', #(a,b)myLoop(), 'Position', [0 0 200 50] )
end
% This replicates your "external_func" function.
function myLoop()
% since you cant pass in any var -> you need to find the slider object
% you can do this by using findobj and search for the tag of the item
uic = findobj ( 0, 'tag', 'MYSLIDER' );
% find the figure handle (only needed for this demo)
f = ancestor ( uic, 'figure' );
% initialise the value which will be used to update the slider
count = 0;
% create your loop
while ishandle(f)
% incrememt the count variable -> this will end up on the slider value
count = count + 1e-5;
% reset count if > 1 -> so the slider cant go out of range.
if count >= 1
count = 0;
end
set ( uic, 'Value', count );
% initiate a drawnow -> this allows matlab to process GUI events
drawnow();
end
end
The downside of this is you insert a drawnow in your loop -> which could slow it down somewhat.
If this doesn't fix your problem you need to explain better what you want to do... (in my view)
I have a GUI and I want to repeat some process from the time the given key is pressed until the key is released.
I know how to do some process once when the key is pressed. But is there any way how to for example display random number every second until the key is released?
Thank you for your answers.
Jaja
You can attach a timer to your figure, start it with the KeyPressFcn and stop it with the KeyReleaseFcn.
The example below will create a figure, and display a random number in the console as long as the key f is pressed.
function h=keypressdemo
h.fig = figure ;
%// set up the timer
h.t = timer ;
h.t.Period = 1 ;
h.t.ExecutionMode = 'fixedRate' ;
h.t.TimerFcn = #timer_calback ;
%// set up the Key functions
set( h.fig , 'keyPressFcn' , #keyPressFcn_calback ) ;
set( h.fig , 'keyReleaseFcn' , #keyReleaseFcn_calback ) ;
guidata( h.fig ,h)
function timer_calback(~,~)
disp( rand(1) )
function keyPressFcn_calback(hobj,evt)
if strcmp(evt.Key,'f')
h = guidata(hobj) ;
%// necessary to check if the timer is already running
%// otherwise the automatic key repetition tries to start
%// the timer multiple time, which produces an error
if strcmp(h.t.Running,'off')
start(h.t)
end
end
function keyReleaseFcn_calback(hobj,evt)
if strcmp(evt.Key,'f')
h = guidata(hobj) ;
stop(h.t)
end
This is a simple timer mode and the callback function take a lot less time than the interval so no problem to expect here. If you want whatever function to re-execute itself right after it's finished (kind of infinite loop), you can set that up by changing the executionmode of the timer (read the timer documentation for examples.
However, be aware that if your callback execute permanently and consume all the (matlab unique) thread ressource, your GUI might become less responsive.
I am cycling through various cells in Matlab by hand in a script (let's call it foo.m):
%%
%Code for cell 1
%%
%Code for cell 2
From the command line of Matlab, I would like to be able to selectively run the code in cell 2. The documentation only has instructions for how to do it interactively (e.g., place the cursor in the appropriate cell, then blah blah). I would like something for the command line so I can do something like foo.runCell(1) to run the code in cell 1 above.
If there is no way to do it, I will just split the cells up into separate scripts/functions. This is less convenient, as I am in a 'grind out prototype very quickly' mode of coding, so want everything in one file for now.
Dev-iL has provided a good answer using java etc... I will provide an alternative here which does not use java or the editor, but reads the file and evals the statements when requested.
For this to work it has a pre-requirement that the file has been saved (which I appreciate is not a pre-requisite of running cells/codeBlocks interactively).
Anyway I thought this was a "quirky" question and thought I'd add have a go at an answer.
Here is my script (cellScript.m) which contains code blocks (Note I have given each block a name after the "%%":
%Note: for this method your NOT allowed to put comments at the end of lines
%% cellA
disp ( 'running cell A' );
disp ( 'finished cell A' );
%% cellB
disp ( 'running cell B' );
disp ( 'finished cell B' );
%% cellC
disp ( 'running cell C' );
for ii=1:100
aa(ii) = randi(1);
end
% cells can have comments
disp ( 'past 1st coment' );
% cells comments can be indented
disp ( 'past indented comment' );
%{
block
comment
%}
disp ( 'past block comment' );
% cells can have comments
% multiple lines of comments
% not lined up
%
%and empty
disp ( 'past multiple lines of comments' );
disp ( 'finished cell C' );
%% cellD
disp ( 'running cell D' );
disp ( 'finished cell D' );
%% cellE
disp ( 'running cell E' );
disp ( 'finished cell E' );
I have created a class which does the job requested (I called it cellRunner.m )
classdef cellRunner < handle
properties ( SetAccess = private )
fileName
fileInfo
cellInfo
cellNames = {};
end
methods
function obj = cellRunner ( file ) % constructor
if nargin == 0
obj.fileName = 'cellScript.m'; % default file for testing
else
obj.fileName = file; % store user file
end
obj.parseFile(); % read the file into memory
end
function obj = parseFile ( obj )
if ~isempty ( obj.fileInfo ) % on parsing check to see if its been parsed before
if isequal ( obj.fileInfo, dir ( obj.fileName ) ) % Check date stamp (has cell file been modified
% disp ( 'file not changed - reading skipped' ); % if not skip
% reading
return
end
end
obj.fileInfo = dir ( obj.fileName ); % store file info
fid = fopen ( obj.fileName ); % open file for reading
if fid ~= -1
index = 0; % this is the index of each cell
inCell = false; % has it found a cell to start reading
lines = cell(0);
while ( true )
line = fgetl ( fid ); % read the line in the file
if line == -1; break; end % check for the end of the file
sLine = strtrim ( line ); % trim any white space
if length ( sLine ) > 2 && strcmp ( sLine(1:2), '%%' ) % check to see if its the start of a cell
if index > 0 % Store the last cell data
obj.cellInfo{index} = lines; % in class to run when required
end
index = index + 1; % increment the index
obj.cellNames{index} = strtrim ( sLine(3:end) ); % save the name of the cell
lines = cell(0); % re-initialise the lines var
inCell = true; % the start of the cells have been found
elseif inCell % if reading a cell array
lines{end+1} = line; % add each line to the lines var
end
end
if index > 0 % make sure and save the last cell when finished reading
obj.cellInfo{index} = lines;
end
fclose ( fid );
else
error ( 'cellRunner:fileError', 'unable to read file' );
end
end
function obj = runCell ( obj, arg )
% obj.runCell ( 'cellName' );
% obj.runCell ( index );
obj.parseFile(); % check that the file hasn't been changed
if ischar ( arg ) % if user provided a char then search for it
index = strcmp ( arg, obj.cellNames ); % find the index
if ~any ( index ) % check it was found
error ( 'cellRunner:notFound', '%s not found', arg );
end
else
index = arg; % if index is an integer (not checked - assumed if not char)
if index < 1 || index > length ( obj.cellInfo ) % check integer is valid
error ( 'cellRunner:notFound', 'Index %d not found', arg );
end
end
commands = obj.cellInfo{index}{1}; % start to build the command to execute.
inBlock = false;
for ii=2:length(obj.cellInfo{index}) % loop around - ignoring any commented lines.
nextLine = strtrim ( obj.cellInfo{index}{ii} );
if inBlock
if length ( nextLine ) == 2 && strcmp ( nextLine, '%}' );
inBlock = false;
end
continue
end
if length ( nextLine ) == 2 && strcmp ( nextLine, '%{' );
inBlock = true;
continue
end
if length ( nextLine ) >= 1 && strcmp ( nextLine(1), '%' )
continue;
end
commands = sprintf ( '%s;%s', commands, obj.cellInfo{index}{ii} ); % build a parge string to eval
end
evalin('base',commands); % eval the expression in the base workspace.
end
end
end
The code is then used as follows:
obj.cellRunner();
% Individual cells can be run in two ways:
% By providing the name of the cell (the string after the %%)
obj.runCell ( 'cellC' );
% By providing the index
obj.runCell ( 3 );
Note Recall the file must be saved for this to work.
Sample run:
whos
obj = cellRunner ( 'cellScript.m' );
obj.runCell ( 'cellC' );
running cell C
past 1st coment
past indented comment
past block comment
past multiple lines of comments
finished cell C
whos
Name Size Bytes Class Attributes
aa 1x100 800 double
ans 1x1 112 cellRunner
ii 1x1 8 double
obj 1x1 112 cellRunner
Note 1 - Why handle class? I inherit from the handle class because I only want one copy of my file data that has been read - see answer 1 in this question for an excellent overview of when to use value/handle classes.
This is my ugly code that does what you asked for.
Despite my best attempts, I was unable to find the way to make it work "properly" (i.e. without simulating key presses). It is my hope that this will facilitate somebody else's attempts to find the way to do it right. Anyway, here goes:
runCodeSectionInFile.m:
function runCodeSectionInFile(scriptFullPath,sectionNum)
%// TIP: You can use "which('scriptName')" to obtain the full path of a
%// script on your MATLAB path.
%%% // Temporary Workaround
import java.awt.Robot; %// part of temporary workaround
import java.awt.event.*; %// part of temporary workaround
RoboKey = Robot; %// part of temporary workaround
RoboKey.setAutoDelay(10);%// part of temporary workaround
%% // Test if the needed components are available (optional)
if ~matlab.desktop.editor.isEditorAvailable || ...
~com.mathworks.mde.editor.codepad.Codepad.isCodepadEnabled
error('MATLAB editor is N\A');
end
%% // Open and\or switch to the script file
%// Test if script is opened:
if ~matlab.desktop.editor.isOpen(scriptFullPath)
scriptDoc = matlab.desktop.editor.openDocument(scriptFullPath);
else %// in case the script is open, get a handle to it, and save it:
scriptDoc = matlab.desktop.editor.findOpenDocument(scriptFullPath);
%// Save the script before running (optional):
scriptDoc.save;
end
scriptDoc.goToLine(0); %// Position the cursor at the beginning of the file
%// NOTE1: - uses zero based indexing!
jEd = com.mathworks.mlservices.MLEditorServices.getEditorApplication ...
.openEditorForExistingFile(java.io.File(scriptFullPath));
jEd.getTextComponent.grabFocus; drawnow; %// part of temp fix
%// NOTE2: most of the above can be replaced with:
%// EDITOROBJ = matlab.desktop.editor.openAndGoToLine(FILENAME,LINENUM);
%% // Get the Codepad and the LineManager handles:
jCm = com.mathworks.mde.editor.codepad.CodepadActionManager ...
.getCodepadActionManager(jEd);
jCp = jEd.getProperty('Codepad');
jLm = jCp.getLineManager(jEd.getTextComponent,jCm);
%% // Advance to the desired section
jAc = com.mathworks.mde.editor.codepad.CodepadAction.CODEPAD_NEXT_CELL;
%// 'next-cell' Action
for ind1=1:sectionNum-1 %// click "advance" several times
%// <somehowExecute(jAc) OR jCp.nextCell() >
RoboKey.keyPress(KeyEvent.VK_CONTROL); %// part of temporary workaround
RoboKey.keyPress(KeyEvent.VK_DOWN); %// part of temporary workaround
end
RoboKey.keyRelease(KeyEvent.VK_DOWN); %// part of temporary workaround
RoboKey.keyRelease(KeyEvent.VK_CONTROL); %// part of temporary workaround
%% Execute section - equivalent to clicking "Run Section" once
jAc = com.mathworks.mde.editor.codepad.CodepadAction.CODEPAD_EVALUATE_CELL;
%// 'eval-cell' Action
%// <somehowExecute(jAc); OR jCp.evalCurrentCell(true) >
RoboKey.keyPress(KeyEvent.VK_CONTROL); %// part of temporary workaround
RoboKey.keyPress(KeyEvent.VK_ENTER); %// part of temporary workaround
RoboKey.keyRelease(KeyEvent.VK_CONTROL); %// part of temporary workaround
%% // Close the file (optional)
jEd.close;
%% // Return focus to the command line:
com.mathworks.mde.cmdwin.CmdWin.getInstance.grabFocus;
testScript.m:
%% // This is code block one
disp('This is section one');
%% // This is code block two
disp('This is section two');
%% // This is code block three
disp('This is section three');
To run the demo, simply put both files in the same folder, make sure it's on your path (or cd), and do runCodeSectionInFile(which('testScript.m'),1). This results in the following:
>> runCodeSectionInFile(which('testScript.m'),1)
This is section one
>> runCodeSectionInFile(which('testScript.m'),2)
This is section two
>> runCodeSectionInFile(which('testScript.m'),3)
This is section three
You may also need to adjust the RoboKey.setAutoDelay(10); to a larger number if you get NPE.
Sources:
A long-gone MATLAB blog post.
Some old question I posted and its answers.
P.S.
I wrote this on 2014b. Other (older) versions may need adjustments...
Edit1:
I have managed to uncover another piece of this puzzle by finding handles to the Codepad object and its TaggedLineManager. The current problem is the fact that most Codepad methods must be run on the EDT (something like a "UI thread", i.e. originate from interactions with the interface).
In order to run a particular section from a file using command line, you can use
echodemo(filename, index of section)
MATLAB documentation
I have built a GUI in matlab using GUIDE, and added keyboard shortcuts to some actions using the WindowKeyPressFcn callback function of my figure. my problem is that I want to use the spacebar as one of the shortcut keys, but it already has a preset usage: it activates the currently selected control (i.e. same as clicking the selected button).
While I can trigger my intended action just fine on the spacebar key through the callback, I found no way to remove this additional unwanted functionality. The result is two actions being performed - the one I programmed and the unintended button press, which creates a mess. The bottom line is that I can't use the spacebar as a shortcut. Is there any way to turn this functionality off or bypass it somehow? Perhaps something that will stop the key-press from reaching the GUI after it is handled by my callback?
I'd prefer a documented Matlab way but if that's not possible, java hacks are welcome as well.
AFAIK the unwanted behaviour is more OS releated than Matlab related and I know of no wway to remove it, however you can work around it.
One way to do this is to check in your pushbutton callback what was the last key pressed, you do this by adding a KeyPressFcn to your pushbutton. I have created a simple example below:
function spacebarTest
% create a figure
hFig = figure ( 'KeyPressFcn', #KeyPress );
% create a uicontrol
uicontrol ( 'style', 'pushbutton', 'Callback', #PushButton, 'KeyPressFcn', #KeyPress );
% store the last key pressed information in the fiure handle
userData.lastKey = '';
set ( hFig, 'userData', userData );
end
function KeyPress ( obj, event )
% obtain the handle for the figure
hFig = ancestor ( obj, 'figure' );
% extract the user data
userData = get ( hFig, 'userData' );
% store the last key in the user data
userData.lastKey = event.Key;
% update the figure handle user data
set ( hFig, 'userData', userData );
disp ( 'spacebar shortcut' );
end
function PushButton ( obj, event )
% get the figure handle
hFig = ancestor ( obj, 'figure' );
% extract the user data
userData = get ( hFig, 'userData' );
% check if spacebar was the last key pressed
if strcmp ( userData.lastKey, 'space' ); return; end
disp ( 'running callback - push me' );
end
One problem with this is that it still "looks" like your button has been pressed, although the callback has not run. To resolve this you would need to stop the button ever gaining focus which you would need to replace your uicontrol button with a JButton (java) and use the FocusGainedCallback
I've got a small MATLAB function I'm attempting to run by calling it from the command line, as follows:
>> [x, y , true_HF, max_F]=main (10)
However, when run, I end up with an error:
??? Input argument "HF" is undefined.
Searching online has yielded a bunch of results for people forgetting the argument, which I don't believe I'm doing (I'm a newb at this stuff).
For reference, my "main" function:
function [ x, y, true_HF, max_F ] = main(HF)
global Data
Data = [];
close all
true_HF = fzero ( diff_L, HF );
[x,y] = find_xy ( true_HF );
final_graphs()
max_F = max_force ( y, true_HF );
end
Additionally, a "whos" prior to the offending line (That is, "true_HF = fzero ( diff_L, HF );"), shows that the variable HF is set.
Any MATLAB geniuses out there who know what I'm doing wrong?
Perhaps there are other functions with the same name that are higher on your path:
>> which main -all
Here's three ideas to try:
First, I occasionally run into an issue where the function called from the command line is the previous version. Make sure you've saved the file. For instance if you had originally written the file with the first line
function [ x, y, true_HF, max_F ] = main(other_variable, HF)
You'd have to save to call main(10) else, you'd get the undefined HF message
The second possibility: if you have re-saved it, then check to make sure the copy you're editing is in the current directory for the command window. Having several functions with the same name separated into different folders can lead to some unexpected behavior. Just keep this in mind if you're working with, for example, ~/new_function/main.m as well as ~/old_function/main.m.
Lastly, you can check if the call to fzero is valid by making the following changes for testing purposes only:
function [ x, y, true_HF, max_F ] = main(HF)
%% <- "%%" starts a new cell in the program
HF = 10 % type this in for testing purposes
% commented out because we are going to evaluate the code inside the current workspace
% global Data
% Data = [];
close all
true_HF = fzero ( diff_L, HF ); % diff_L will have to be in the current workspace variables
[x,y] = find_xy ( true_HF );
final_graphs()
max_F = max_force ( y, true_HF );
%% <- end the cell
end
Now, with your cursor in between the two "%%" signs press ctrl-return. This will evaluate the code in the cell (the code between the two "%%").
Let us know about your progress.
--Andrew