Can we configure MATLAB let variable have minium local scope? - matlab

Can we configure MATLAB let variable have minium local scope?
I want matlab something similiar like C below.
% after some configure ...
for i=1:1:100
a=i*i
end
% here we can not using 'a' any more for it have local scope in for loop.
Why I want it becase the scope in whole script sometimes leds to bug hard to find.
For example:
% get accumulate of b via 100 times of x_0
b=0;
for i=1:1:100
x0=100
b=b+x0
end
% get accumulate of a via 100 times of x_0
a=0
for i=1:1:100
x_0=200
a=a+x0 %mistype x_0 to x0, and hard to find
end
Thanks advance.

I don't think there is any way to force a local scope in a script/loop. However, you can create a function, in a separate file or in the same file. Each function will have it's own local scope. So for your example you can create a file myScript.m with the following:
% get accumulate of b via 100 times of x_0
accum_b(100)
% get accumulate of a via 100 times of x_0
accum_a(200)
function a = accum_a(x0)
a = 0;
for k = 1:100
a = a + x0;
end
end
function b = accum_b(x0)
b = 0;
for k = 1:100
b = b + x0;
end
end
In this particular example, you can of course call the accum_a function twice, with different x0 inputs. But each function you define in a file will have it's own local scope, and will thus result in an error when mistyping x_0/x0.

Related

Body of this Matlab function works, but not the function itself (interp1 error)

I've written the following piece of subcode (with parameters commented) for an Euler policy iteration algorithm. When I try to run the body of the function (everything below global) for say, a1 = 1, it works, and returns a scalar. However, when I call the function as euler_diff_test(1), I get an error. (Pasted below)
function diff = euler_diff_test(a1)
%the following comments are example parameters. They are in the global line originally.
% r = 0.2, a = 0.5, y = 1.1, a_grid = linspace(0.5,7,100)
%policy_guess = zeros(2,N);
%policy_guess(1,:) = 0.3*a_grid;
%policy_guess(2,:) = 0.3*a_grid;
% M = zeros(2,2); %M for markov transition kernel
% M(1,1) = p;
% M(2,2) = p;
% M(2,1) = 1-p;
% M(1,2) = 1-p;
% j = 1
global r a y a_grid policy_guess M j;
c = (1+r)*a + y - a1; %consumption formula
if c<=1e-02 %don't care about consumption being negative
diff = 888888888888888888888;
else
policy_func = interp1(a_grid', policy_guess', a1, 'linear');
diff = 1/c - beta*(1+r)*(1 ./ policy_func)*M(j,:)';
end
end
Error Reads:
Any help is much appreciated!
The problem is that you dont understand globals nor how they work!
You seem to be doing something like:
N=100; p=0.1;
r = 0.2, a = 0.5, y = 1.1, a_grid = linspace(0.5,7,100)
policy_guess = zeros(2,N);
policy_guess(1,:) = 0.3*a_grid;
policy_guess(2,:) = 0.3*a_grid;
M = zeros(2,2); %M for markov transition kernel
M(1,1) = p;
M(2,2) = p;
M(2,1) = 1-p;
M(1,2) = 1-p;
euler_diff_test(1)
And this is causing the error you show. Of course it is!
First, you need to learn what a global is and what worskpaces are. Each fucntion has its own worskpace or "scope". That means that only variables defined within the workspace are visible by the function itself.
A global variable is one that exist for all workspaces, and everyone can modify it. You seem to want all those variables defined outside the function, inside your function. But realise! when the variables are defined, they are not global. The function starts, and in its first line, it does only know about the existence of a1. Then, later, you define a bunch of variables as global, that the function did not know about. So what does the function do? just create them empty, for you.
If you want your the variables that you create in the main script scope to be global, you need to declare them as global then, not inside the function. So cut your line global ... from the fucntion, and put it on top of the script where you declare all your variables, i.e. on top of
% here!
N=100; p=0.1;
...
in my example.
Now, the important stuff: Global variables are bad. When you have globals, you don't know who modifies, and its super easy to lost track of what is happening to them, because every function that uses a variable a will modify the global a, so its a pain to debug. Almost no one uses globals because of this. The best way is to pass them to the function as input, i.e. define your function as:
function diff = euler_diff_test(a1,r, a, y, a_grid, policy_guess, M, j)

Memory-Allocation for function calls of form x = f(x) in MATLAB

In my code, I have lots of places where I invoke functions of the form
X = f(X)
and X can be a rather large matrix. In my special case, I have mostly calls like
X = feval(somefunc, X)
or
X = obj.myfunc(X)
It would be bad if, every time the function is called, there is new space allocated for X. Is MATLAB smart enough to deal with such function calls? Is there a way to tell?
The answer to this question helps would help very much with a design descision. I like to program in object oriented style and if MATLAB is not smart enough for this, it might pay off for me to add another member for X in the class, although I would rather not do this otherwise.
Whether a copy is made of the input arguments or not when calling a function in MATLAB depends upon what happens inside of the function.
MATLAB uses a system referred to as copy-on-write. This means that if you pass a large variable to a function as an input, as long as you do not modify the variable within that function, the variable will not be copied into the workspace of the function and the function will instead read the data from it's current location in memory.
function Y = func(X)
Y = X + 1;
end
If you are modifying the variable within the function, then a copy of the input variable is made and placed into the local workspace of the function.
function X = func(X)
X = X + 1;
end
There is more information on Loren's Mathworks blog.
An easy way to determine if a copy of the data is made or not is to use the undocumented format debug mode which will show you where the data for a given variable is stored in memory.
format debug
%// Create a variable a and show where debug info
a = [1,2]
%// Structure address = 141f567f0
%// m = 1
%// n = 2
%// pr = 7f9540b85e20
%// pi = 0
%// 1 2
%// Assign b = a but don't modify
b = a
%// Structure address = 141f567f0
%// m = 1
%// n = 2
%// pr = 7f9540b85e20 <= POINTER TO DATA REMAINED UNCHANGED
%// pi = 0
%// 1 2
%// Modify (Will create a new copy)
b = b + 1
%// Structure address = 141f55b40
%// m = 1
%// n = 2
%// pr = 7f953bcf1a20 <= POINTER TO DATA CHANGED (COPY)
%// pi = 0
%// 2 3
If you prefer you can use this little anonymous function I've created to inspect the memory location of any particular variable.
memoryLocation = #(x)regexp(evalc('disp(x)'), '(?<=pr\s*=\s*)[a-z0-9]*', 'match')
a = [1,2];
memoryLocation(a)
%// 7f9540b85e20
b = a;
memoryLocation(b)
%// 7f9540b85e20
b = b + 1;
memoryLocation(b)
%// 7f953bcf1a20
As a bit of a side-note, I would recommend against using feval throughout your code and instead just use the function names directly.

How can i save previous value of variable in Matlab Function

Hello I would like to know how to save the previous value of an output variable in a matlab function.
function y = fcn(x,d,yp)
yp=0; %here I want to initialize this value just at the start of simulation
if (x-yp<=d)
y=x;
else
y=yp + d;
end
yp=y; % here i want to load output value
Thanks for your help
Make yp persistent
function y = fcn(x,d,varargin)
persistent yp
if nargin>2
yp = varargin{1};
end
...
yp=y;
end
Since yp is persistent now next time you will call the function yp will already hold the value of y you calculated previously. The only problem is not to override it by yp=0 as you have currently.
I replaced yp in the list of function arguments with varargin which holds optional arguments. The first time you call fcn you should call it as y = fcn(x,d,0), where the zero will be passed to yp inside the function. Next time you should call it without the third argument not to override the value yp holds (i.e. y = fcn(x,d).
In addition to persistent variables, you can also save the value in a nested function and return a handle to that function:
function fun = fcn(yp0)
yp = yp0; % declared in the main function scope
fun = #(x,d) update(x,d); % function handle stores the value a yp above and updates below.
function y = update(x,d)
if (x-yp<=d)
y=x;
else
y=yp + d;
end
yp = y; % updated down here
end
end
And then you would use it like
fun = fcn(yp0);
y = fun(x,d);
I use this instead of persistent variables when I notice a performance increase from not checking the initialization of persistent variables.
Using a persistent variable is the correct way to go, but as you found out, you cannot use varargin in a MATLAB Function block. The trick is to check whether the variable is empty or not, as in:
function y = fcn(x,d,yp)
persistent yp
if isempty(yp)
yp=0; %only if yp is empty, i.e. at the beginning of the simulation
end
if (x-yp<=d)
y=x;
else
y=yp + d;
end
yp=y; % here i want to load output value

Update a M.file variables from command windows in Matlab?

I have a simple but interesting question. i tired hard to google it but my google got upset and giving me the same results...
i wanted to know is it possible to Update a constant variable form workspace command..
A Simple Example:
function y =StupidQuestion
a = 10; % some value
b =[5,6,7;1,2,8]; % some value
y = b*a % some operation
I forget to tell you that we can do it with simulink block by using below command
set_param('obj', 'parameter1', value1, 'parameter2', value2, ...)
i Want to use the assigned value for 3 weeks and without any reason i wants to change my values [a,b] to other but through command windows. any Idea. Waiting for your interesting Reply...................
You can set defaults for the inputs:
function y = foo(a,b)
if nargin < 1 || isempty(a), a = 10; end
if nargin < 2 || isempty(b), b = [5,6,7;1,2,8]; end
y = b*a
end
You can call foo() without inputs (and it will use the defaults for a and b) or supply your own values as: foo(12), foo(12,[10,20]), foo([],[23,23]), etc...
A possible way is to save some variables in an external file. Note that in this case a and b are only in the function workspace (you won't see their values unless you load the contents of test.mat separately). I'm passing the filename in rather than hard-coding it in case you need to switch between multiple settings.
Personally I would prefer to have a human-readable data file, but the concept remains the same (you'd just need some parser function which returned values for a and b given a file).
a = 10; % some value
b =[5,6,7;1,2,8]; % some value
save('test.mat','a','b');
clear a b;
function y = savedvariables(filename)
load(filename);
y = b*a; % some operation
end
y = savedvariables('test.mat');

How to use a variable outside a PARFOR loop in MATLAB?

In MATLAB, I have a variable proba and I have a parfor loop as showing below:
parfor f = 1:N
proba = (1/M)*ones(1, M);
% rest of the code
end
pi_proba = proba;
MATLAB said that: "The temporary variable 'proba' is used after the PARFOR loop, but its value is nondeterministic"
I do not understand how to correct this error. I need to use a parallel loop and I need proba after the loop. How to do this?
When using parfor the classes are classified according to these categories. Make sure every variable matches one of these categories. For non-writing access to proba a Broadcast-Variable would be the best choice:
proba = (1/M)*ones(1, M);
parfor f = 1:N
% rest of the code
end
pi_proba = proba;
In case of writing access within the loop, a sliced variable is nessecary:
proba=cell(1,N)
parfor f = 1:N
%now use proba{f} inside the loop
proba{f}=(1/M)*ones(1, M);
% rest of the code
end
%get proba from whatever iteration you want
pi_proba = proba{N};