I made global a variable in main m.file and used that variable in a function m.file and I had no problem. But, I wanna make global a variable in function m.file and use that variable in main m.file.
For this aim, I wrote:
function cost=MY_Fun(X)
global m
.
.
end
in function m.file, and wrote "global m" in main m.file. But, I get m=[]! How can I do that, so that the main m.file could correctly find the "m" value?
In the main script, if you are using m before the function call to MY_Fun, it would be empty. But after it, would have the value assigned inside MY_Fun. m would get the value from MY_Fun, only after the function gets called from the main script. The following codes might help you understand.
Main Script
global m
m_before_fun = m
cost1=MY_Fun(1);
m_after_fun = m
Function
function cost=MY_Fun(X)
%%// Declare m as a global variable
global m
%%// Assign some value to m
m = 10;
cost = 1;
return; %%// I prefer RETURN to END
Output
m_before_fun =
[]
m_after_fun =
10
Related
It is possible to use the function inputname to retrieve the workspace variable name passed in the call to the currently executing function. However, is there any equivalent function to obtain the name of the output arguments specified in the call to the currently executing function?
Imagine I have the following function:
function [a,b,c] = test(x)
disp([ouputname(1),ouputname(2),ouputname(3)])
end
When running this function:
[my,name,is] = test(x)
The expected result should be:
mynameis
Simply: no there isn't.
Complicated: Matlab code is "compiled" on run-time, and there is no way, that it knows [my,name,is] before it returns the result of test(x).
Workaround: if you want to ensure, that the strings used within the function are equal to the variables returned to the workspace, you can do the following using assignin:
function test(x, varnames)
a = 1;
outputname{1} = varnames{1};
assigin('base', outputname{1}, a)
...
c = 3;
outputname{3} = varnames{3};
assigin('base', outputname{3}, c)
disp([outputname{:}])
end
and call your function like:
text(x,{'my','name','is'})
and you will have exactly this variables in your workspace afterwards and your function output:
"mynameis"
I am trying to allow a function to have access to the base workspace using the evalin function, but I am having trouble. Here is a simple example:
My main code:
A = 1;
B = 2
evalin('base','[ C ] = FUN(B)');
C
My Function:
function [C ] = FUN( B )
C = A + B;
end
My error:
Undefined function or variable 'A'.
Error in FUN (line 4)
C = A + B;
Error in Test (line 4)
evalin('base','[ C ] = FUN(B)');
So, the function is not being evaluated in the base workspace because it does not know what the value of A is.
Can anyone suggest something? I have a lot of variables that I need to access in several functions and I don't want to pass them and I don't want to use global variables.
Thanks!
From the evalin documentation,
evalin(ws, expression) executes expression, a string containing any valid MATLABĀ® expression, in the context of the workspace ws. ws can have a value of 'base' or 'caller' to denote the MATLAB base workspace or the workspace of the caller function.
So the line of code
evalin('base','[ C ] = FUN(B)');
evaluates only the line of code
[ C ] = FUN(B)
in the context of the base workspace. It does not evaluate the body of the function within the context of the base workspace. So the error that you are observing makes sense.
Is there a particular reason why you don't want to pass the variables in to the function? Why do you have several variables in the base (?) workspace, or do you just have several variables within a main function?
If the latter, you could use nested functions to have access to the variables declared in the caller (function) workspace. For example, suppose you have a main function like
function main()
A = 1;
B = 2;
C = FUN();
function [C] = FUN()
C = A + B;
end
end
The function FUN has access to both A and B and so you don't have to pass in any arguments.
An alternative to passing in several different inputs, is to just pass in a structure that has different fields that your function can access at will. Using the above example, we could do the following
function main()
A = 1;
B = 2;
data.A = A;
data.B = B;
C = FUN(data);
end
function [C] = FUN(data)
C = data.A + data.B;
end
In this case, the function FUN can be a function within its own file or declared after main. Again, we only pass in one argument that has all the data that the function needed.
Actually Evalin function is used to take data from base workspace:
Syntax is :
evalin('base','variable')
Evalin function is used in the function .
For example see the below function
function [out1 out2 out3]=main_fun(in1,in2)
out1=in1+in2;
out2=in1-in2;
in3=evalin('base','in3');
in4=evalin('base','in4');
out3=in3+in4;
end
Here out3 value will have the sum of in3 and in4 from workspace.
out1 and out2 will have the sum and difference of in1 and in2 from current function workspace.
Suppose the matrix is A which is in a m file new1.m . Now I want to access this matrix to another m file new2.m . How can it be done ?
Your question is a little nonspecific, but I'll try to answer.
There are several ways to do this,
Assuming that you have a m-file (script) named 'new1' with (for example) A = rand(4) in it. You could just run it in new2.m before you want to use A
new1;
B = 2*A;
Note that new1 will return all the other variables assigned in it, flooding your workspace. Perhaps not a problem, but if so, you could just clear them with
clear var1 var2 var2 etc.
Another way is to make new1 into a function and return (only) A
function A = new1()
but I'm guessing that might ruin some other purposes of new1.
In that case you could return A only if the function is called with a special input argument (for example 'getA')
function new1(varargin)
...
... % some code
...
if nargin && strcmp(varargin{1},'getA')
assignin('caller','A',A);
end
And so from new2, just call the function.
new1('getA');
I'm having some trouble with local functions within my code so I've pasted a simple example below:
function [avg,testvar] = test(x) %Warning
n = length(x);
avg = mymean(x,n);
end
function [a,testvar] = mymean(v,n)
a = sum(v)/n;
testvar=123;
end
One can probably see what I'm attempting; to pass testvar out of the local functions. However Matlab returns the warning:
"The function return value 'testvar' might be unset"
with respect to the line I've commented "%Warning".
What's the best way of getting around this?
You need to specify the value of the second output of test(). Otherwise how can MATLAB know what its value is supposed to be? It doesn't know the second output of mymean() should be routed to the second output of test(). Perhaps this will solve your problem.
function [avg,testvar] = test(x) %Warning
n = length(x);
[avg, testvar] = mymean(x,n);
end
function [a,testvar] = mymean(v,n)
a = sum(v)/n;
testvar=123;
end
The variables between brackets after function are the output variables.
In your first function, you did not assign any value to testvar hence the warning. If you add testvar = 123; in the first function, the warning goes away. Or you can remove testvar from the output variables, leaving:
function avg = test(x)
I'm pretty new to MATLAB and I have a simple question. What if I have the following structured functions:
function[A] = test(A)
test1(A);
test2(A);
end
function test1(A)
#% do something with A
end
function test2(A)
#% do something else with the newly modified A
end
How do I pass around A from function to function keeping it's modified nature? (Suppose A is a matrix)
EDIT: let's make the situation a little simpler. Suppose my main function is:
function[a]=test(a)
test1(a);
#%test2(a);
end
and test1() is defined as:
function[a] = test1(a)
a=5;
end
Then, I call the function test with test(3), and I want it to report ans = 5, yet it still reports ans = 3.
Thanks!
Variables in MATLAB are passed using "call by value" (with some exceptions), so any value that you pass to a function and modify has to be returned from the function and either placed in a new variable or the old variable overwritten. Returning the value of a variable from a function is simple: you just place the variable name in the output argument list for the function.
For your example, you would do this:
function A = test(A)
A = test1(A); %# Overwrite A with value returned from test1
A = test2(A); %# Overwrite A with value returned from test2
end
function A = test1(A) %# Pass in A and return a modified A
#% Modify A
end
function A = test2(A) %# Pass in A and return a modified A
#% Modify A
end
One thing to be aware of is variable scope. Every function has its own workspace to store its own local variables, so there are actually 3 unique A variables in the above example: one in the workspace of test, one in the workspace of test1, and one in the workspace of test2. Just because they are named the same doesn't mean they all share the same value.
For example, when you call test1 from test, the value stored in the variable A in test is copied to the variable A in test1. When test1 modifies its local copy of A, the value of A in test is unchanged. To update the value of A in test, the return value from test1 has to be copied to it.
Return the object from the function and then pass it on to the next function.