using evalin to evaluate a function in the base workspace - matlab

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.

Related

Linking input file with variable stored in it to several function files

I have code which is in multiple function files, input to these functions are stored in one file called inputfile.m(script file), in which I assigned some constant values to the inputs. These values act as a input to several function files named degree_eq.m(function file).
How I can write the code so that every time of execution, function files takes the required inputs from the inputfile.m.
Let's say you have two functions, one with your inputs (inputfile) and one where you do stuff (do_stuff).
function [a,b,c] = inputfile()
%define your constants
a=10;
b=100;
c=8.3;
function z = do_stuff()
[a, b, c] = inputfile() %takes the inputs from inputfile.m
z = a*c - b;
You can exploit the fact that matlab variables are persistent outside their scope. Lets say you have 6 constants a,b,c,d,e,f defined in input file. So what can be done is, write a top script called top.m which would be something like
inputfile
degree_eq1(a,b,c)
degree_eq2(c,d,e)
A third approach (combining Nirvedh Meshram and qbzenker answers) is to call an input script inside your MATLAB functions.
The advantage is that you do not have to specify which parameters are needed from or specified in your input script, but this is a disadvantage too, because the needed inputs are not made explicit. So, it is much more error prone. I only recommend this approach for a large number of input variables.
inputfile.m:
a = 5;
b = 8;
c = 10;
degree_eq.m:
function d = degree_eq()
inputfile;
d = a + b + c;
end
As an alternative, you can specify which input file to use:
degree_eq.m:
function d = degree_eq(inputFilename)
eval(inputFilename);
d = a + b + c;
end
and call it as follows:
degree_eq('inputfile');

Retrieve name of output arguments within a function

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"

Why are the values passed to a method saved as an object?

I have a class with a scheduler function that is supposed to insert characters into a cell array:
classdef timeline < handle
properties
schedule
i
%other properties
end
methods
%other functions
function t = timeline()
%other initializations
t.schedule = cell(1,738);
t.i = 1;
end
function scheduler(t, g, fT)
if nargin == 2
fT = t.i;
end
if strcmp(g,'science')
'science' % eclipse occurs after
for j = (fT+t.sTime+1) : (fT+t.sTime+1+t.eTime)
t.schedule{j} = 'e';
end
elseif strcmp(g,'pass')
'pass' % science occurs 2 hrs after end
for j = (fT) : (fT+t.pTime)
t.schedule{j} = 'p'
end
for j = (fT+t.pTime+121) : (fT+t.pTime+120+t.sTime)
t.schedule{j} = 's';
end
scheduler(t, 'science', fT+t.pTime+120);
end
end
end
end
In the command window, I define my object t = timeline() and a mode g = 'pass' and then call the scheduler, t.scheduler(t,g).
It doesn't change the schedule property. What's going on inside the if statements to write the schedule isn't the problem I am concerned with. I put outputs in each part of the if statement, and found that strcmp is returning false and skipping over the whole block. So, I added a break point in the scheduler function, and found that for some reason g is passed to the function as another timeline object instead of the string 'pass'. Why is this?
When you call a method for an object you can use dot notation or function notation. Dot notation means you call the method using the dot operator on the object instance. For example,
obj.methodName(args);
In function notation you pass the object instance variable as the first argument to the method. For example,
methodName(obj, args);
Both the above calls are equivalent and call the same method in the object. In both the calls MATLAB passes obj as input to the method. Note the absence of obj as an argument in the dot notation. In dot notation obj, is added as an input argument before your args. In your code you are mixing both of these options. So you got two obj arguments for your method.
Relevant documentation is at http://www.mathworks.com/help/matlab/matlab_oop/method-invocation.html

Passing command lines to function to evaluate in Matlab

I have a function which is very open-ended that I use in several different applications. Instead of changing it everytime, I would like to pass several command lines as input for the function to evaluate using something like the eval function.
Thus, for example, my argument would be:
str={'a=32;
b=a+3*a^2+pi;
c=sin(a)+cos(b)^2;'}
then I could call the function with str as an argument:
x=func(str)
these lines would be evaluated inside the function
how?
Thanks alot!
I think #Daniel is right that function handles are the way forward. Based on your example, this is how you'd do it:
function x = testfun( a, bfun, cfun )
b = bfun(a);
c = cfun(a, b);
x = a + b + c;
end
Then you'd call it like this:
x = testfun( 32, #(a)(a+3*a^2+pi), #(a,b)(sin(a)+cos(b)^2) );

How can I make global a variable in a function m.file?

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