Question regarding the scope of my global variable {matlab} - matlab

i'm trying to do an assignment for my class and the undo button click should reload the previous transformation applied onto the image in case i wish to go back.
The golabal variable is defined in the start of the code
function LoadimgBtn_Callback(hObject, eventdata, handles)
% hObject handle to LoadimgBtn (see GCBO)
[filename,pathname]=uigetfile('C:\Users\hassan\Desktop\DIP PROJECT IMGS\MonoChrome
Images\*.jpg;*.png;*.jpeg');
file_path=strcat(pathname,filename);
og_img=imread(file_path);
axes(handles.org_img);
imshow(og_img);
prev_img=og_img;
axes(handles.intr_img);
imshow(prev_img);
As observed the global variable prev_img is utlized perfectly here however when i try to use the same variable in my undo code there is an error thrown that the variable does not exist.
function UndoBtn_Callback(hObject, eventdata, handles)
axes(handles.intr_img);
imshow(prev_img);
I wish to utilize the same variable through the global variable method.

you need to call the global variable again in your function code
function UndoBtn_Callback(hObject, eventdata, handles)
axes(handles.intr_img);
global prev_img % declaring a global variable "again"
imshow(prev_img);
Otherwise, you are overshadowing the global varibale with a local variable of the same name. (remember that you can also define function with the same name as a matlab function e.g. sum.) The thing is, that matlab does not know, that you want the variable to be global. The same is true for persistent variables.
Once you define a global variable in your function, matlab checks if this (global) variable already exists and if it has already a value.
You may want to have a look in the matlab-docs if my explanation wasn't intuitive enough.
To clear a global variable, you need to call clearvars -global or clear all or clear global
To clear a global variable from all workspaces, use clear global variable.
To clear a global variable from the current workspace but not other workspaces, use clear variable.

Apparently in mat lab every time you use a global variable you have to re declare it within the scope of a function as well.
I am not sure however I think it creates a local instance of the variable with the same name if i do no explicitly mention the keyword global within the scope of the function as i was doing so before.
in my case i had to mention global at two locations and it works.

Related

How to clear persistent variables in sub-functions

I have a script that calls a function, which is written in separate file and contains sub-functions that are inner to main function only. In one of my sub-functions, I have persistent variable that I would like to clear every time I run the main script. How can I do so? In addition, I have breakpoints through my code, and I would prefer to keep them while I clear the persistent variable - how that can be done?
MainScript.m script:
clear variables;
for iterNum=1:5
dataOut = MyMainFunction(iterNum);
end
disp(dataOut);
MyMainFunction code:
function dataOut = MyMainFunction(iterNum)
if (iterNum==1)
clear MySubFunction;
end
dataOut = MySubFunction();
end
function dataOut = MySubFunction()
persistent idx;
if isempty(idx)
idx=1;
end
dataOut=idx;
idx=idx+1;
end
I would like to clear "idx" persistent variable every time that I run MainScript.m, but of course to keep that variable as long as the script is running.
Thanks, John
The easiest way I see is to call clear followed the function name:
clear MySubFunction
instead of
clear variables;
This should clear all the persistent variables in that particular function. This will probably have the side effect of removing the stored JIT'd copy of it, causing it to be reparsed the next time it is invoked.
You can use munlock if you previously mlock'ed your function.
OR
You can define a special set of parameters in your function that are designed to solely clear the persistent variable, and you call the function with this syntax at the beginning of your main file.
Unfortunately, the other answer is partially incorrect - it is NOT possible to clear persistent variables in a sub-function using clear MySubFunction.
To quote an answer by a MathWorks staff member,
Only top level or main functions (with the same name as the file) may be cleared. To clear any local or nested function the main function must be cleared and that can't be done while the main function (or any other function in the file) is running.
and
Only whole m files can be cleared from memory. The entire file is managed as a unit so sub functions can't be cleared without clearing the main function.
As such, your options are to
separate the sub-function into its own m-file, or
clear the entire MyMainFunction from within MainScript.m, or
follow Ratbert's second suggestion, i.e. instead of using clear, give MySubFunction an additional argument that tells it to reset the persistent variables by itself

GUIDE in MATLAB

I am trying to build a program in MATLAB and I am using edit boxes but I want the value that the user will enter to be used later on from another function. So should I use the global variables or is there another way?
I tried to define the global variables outside the function but is not working.
I tried to define it inside the function and then call it from another function but it says that it is undefined. Is there a way that I can do that?
I am just using
function edit1_Callback(hObject, eventdata, handles)
str2double (get (hObject,'String'));
Thanks!! :)
If you want to store data within a Matlab-GUI, you can use the handles-structure like this:
handles.myVar=123;
%after this dont forget to save it (yes, this is a bit annoying):
guidata(hObject, handles);
later on, within another callback for example, you can find this data within the handles-struct:
handles.myVar

Reading GUI Data from a Matlab Script File

I created a GUI named SCADA and I added a boolean variable called StatusData which is a flag that that is set to false when the GUI is launched
handles.StatusData=false;
guidata(handles.output,handles);
I press a button and then a function is called which executes continuously (the function has infinite loop). After some time I press another button which sets the StatusData to true.
handles.StatusData=true;
guidata(handles.output,handles);
Now, I need to access the StatusData from the callback function (the same function I mentioned above), In order to acheieve this I sent the handle as a parameter when I called that function. Now, When the pressed the button that changes the StatusData, the data in the actual handle changes but I cannot access the updated StatusData as the function is already called.
How can I access the updated handle of GUI without sending it as a parameter.
Thanks
You can just pass in the hObject parameter to your function instead, and retrieve your value when it's needed using guidata; i.e.,
function some_callback(hObject, handles, ...)
myLoopingFunction(hObject, ...);
function myLoopingFunction(hObject, ...)
for someVar = something
% Update handles structure
handles = guidata(hObject);
end
Alternatively you could create a handle object and put that in the handles structure; e.g.,
% In a separate file:
classdef uiState < handle
% Probably should give this class a less general name...
properties
StatusData
end
end
% In your UI file:
function some_callback(hObject, handles, ...)
handles.state = uiState();
handles.state.StatusData = false;
% Now, when you modify handles.StatusData, the version used by
% myLoopingFunction will also be updated, because they point to
% the same object!
myLoopingFunction(handles.state);
function myLoopingFunction(state, ...)
for someVar = something
% Now you just have to check state.StatusData
end
For simple cases, I'd use the first method. For more complicated situations, where several parameters must be kept track of and they interact in complex ways, I would use the second. The second is also useful if you have a large chunk of data in some variable and want to stop it from being copied into every call to the UI.
Personally, for a complex UI I would usually create some application class that keeps track of the user interface (and provides a command-line interface to it) and make sure that was always available to my UI, but that is a bit like using a sledgehammer to open a jam jar in this simple case.

Matlab: Real global variables [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Declaring a global variable in MATLAB
Currently my matlab code is in one big script file with no internal functions. I would like to have functions declared within my script, to make my code more readable and reuse code etc. This in itself is not difficult in matlab, e.g.
Example 1:
function main()
myfunc('goat');
end
function myfunc(x)
fprintf(x);
end
My problem is that I have a biig datafile, which I want to load only once, such that I can re-run my code during development without spending time on re-loading the data. This is not a problem in my current framework with one big script with no internal functions. One solution is to have two matlab script files. One for loading data and then calling the functions in another script.
However in the above example 1 a true global variable declaration will not work, and I am forced load the biig file every time I run the script. What I would like to do can be shown in two examples:
Example 2:
% Global variable
if ~exist('data',var)
data = load biigdatafile.mat; %FAILS, outside function.
end
function main()
myfunc('goat');
end
function myfunc(x)
fprintf(x);
end
Example 3:
function main()
% Global variable
if ~exist('data',var)
global data; % Is not really global after whole script is completed.
data = load biigdatafile.mat;
end
myfunc('goat');
end
function myfunc(x)
fprintf(x);
end
So my question is how to declare a true global variable as in example 2, where I load my data once to stay in workspace, while calling my functions inside one script?
Use input arguments, that's what they're made for
You could just use arguments to the main function, load the dataset once into the base workspace and call your function with that dataset as an argument. If any subfunctions also use the dataset, pass it along
function main(data)
if nargin<1
disp('hey, you forgot to supply the dataset!');
end
% do your stuff
showData(data);
end
and then in the base workspace:
Data = load('biigdatafile.mat');
main(Data);
Use persistent variables
persistent X Y Z defines X, Y, and Z as variables that are local to the function in which they are declared; yet their values are retained in memory between calls to the function. Persistent variables are similar to global variables because the MATLAB software creates permanent storage for both. They differ from global variables in that persistent variables are known only to the function in which they are declared.
So you could easily use:
function main()
persistent data;
if isempty(data)
disp('loading dataset');
data=load('biigdatafile.mat');
end
% do your stuff
showData(data);
end
First time you call this function on a cleared base workspace or cleared function*, the dataset will be loaded. Every next time (when the function hasn't been edited), the dataset will already/still be in memory.
I usually do this when I'm just using one dataset; it's tedious to always load the dataset and when testing a function, it's also easier to just press F5.
* when is a function cleared you might ask?
Whenever you clear or modify a function that is in memory, MATLAB also clears all persistent variables declared by that function. To keep a function in memory until MATLAB quits, use mlock.
Global variables have to be declared everywhere they are used. Just add the global data to whereever you need it, and it will work.
It is not a duplicate of declaring global variables in matlab. A global var is only accesible to all functions, but when the script is complete, the global variables are gone and I need to read them into memory again.
What I need is to move the local variable into the base workspace and then access it again during other function calls. I actually solved it myself, just now with this code
function main()
try
Data = evalin('base','Data'); % Move back from base workspace
fprintf('Already loaded...\n');
catch
fprintf('Loading data...');
data = load biigdatafile.mat;
assignin('base', 'Data', Data); % Move to base workspace
fprintf('Ok\n');
end
showDocID(Data{1});
end
function showData(Data)
fprintf(['Data: "' Data '"\n']);
end

Clear from workspace base

I've toto.m + model.mdl
from a function toto.m , I open model which load variable in workspace
after closing model I want to clear variables loaded in workspace
is there a way to do that without using clear all?
function toto
model = 'model1';
open_system(model1);
close_system(model1);
end
when I run the function the workspace isn't cleared , how could I clear variable only used by model without using clear all ?
You can use clear followed by a list of variables, for example clear a b c. However, I don't know whether there is a method that clears all the variables declared in a given script, though you can always use functions so all the variables in the scope of the function will be cleared when it ends.
If you want to clear all variables except those that existed already before running the script, you can temporarily store these already existing variable names and run clear afterwards using:
already_existing_vars = who;
% your actual script ...
% ...
% clear variables created in this script
vars_to_clear = setdiff(who,already_existing_vars);
clear(vars_to_clear{:},'vars_to_clear')