MATLAB Answers

Declaring 'many' variables from work space into function workspace

54 views (last 30 days)
John Carbett
John Carbett on 2 Feb 2011
Hi
I have created a function and I want to import variables declared in workspace in to my function workspace. Does anyone know how to do that without having to declare all the variables as global? This is because there are many variables so it might be impractical to use that method.
Many thanks in advance
  3 Comments
Siddharth Shankar
Siddharth Shankar on 2 Feb 2011
If you're using the method I suggested in an Embedded MATLAB Block, then could you try declaring the EVALIN and LOAD functions as extrinsic? For example:
eml.extrinsic('evalin','load');
You need to remember that Embedded MATLAB is a subset of MATLAB so the EML.EXTRINSIC call forces the specified functions to be dispatched to MATLAB for execution.
Besides, if you're dealing with an Embedded MATLAB function, why not just use the "From Workspace" block in Simulink? If you combined all your variables into a single struct, then you could just use the "From Workspace" block to get this structure into your Embedded MATLAB Block as an input (Via the "From Workspace" block).

Sign in to comment.

Answers (5)

Matt Fig
Matt Fig on 2 Feb 2011
Usually one should pass the variables in via the argument list. Other ways of making magic are generally frowned upon with good reason. If it is too much for you to do it the normal way, you could create a structure of all the variables to pass in to your function.
T = whos;
for ii = 1:length(T),eval(['R.',T(ii).name,'=',T(ii).name,';']);end
Now R is a structure who's fieldnames are the variable names in your base workspace. So you pass R and use structure addressing to access the variables.
If even this is too tedious, and you must have access to the exact same variable names in a function, you could do something at the beginning of your function, like in this function:
function [] = myfunc()
% Get all base workspace variables into this function.
T = evalin('base','whos');
for ii = 1:length(T)
C_ = evalin('base',[T(ii).name ';']);
eval([T(ii).name,'=C_;']);
end
clear T C_ ii
whos % This should match base workspace call to WHOS.
  3 Comments
Vishesh Vatsal
Vishesh Vatsal on 4 Sep 2013
what if the function is an ode45 state function (odefun)? can it accept new variables?

Sign in to comment.


Siddharth Shankar
Siddharth Shankar on 2 Feb 2011
A very simple (but effective) way to do this is to use EVALIN to save the necessary variables in the base workspace to a MAT file, and then simply load the variables into your function workspace by calling LOAD from within the function. For example:
% These commands must be executed from inside your function
evalin('base','save myvars.mat');
load myvars.mat

Jan
Jan on 2 Feb 2011
A clean and secure method is to use all needed variables as input. Defining a function "many" inputs might confusing, because a confused order of inputs will be hard to find. It might be more stable to copy the variables as fields of a struct and forward the single struct to the function as input:
% Either create the struct manually:
S.v1 = v1;
S.v2 = v2;
S.v3 = v3;
% etc
YourFunction(S)
Then you can access the fields under the same names as the variables.
A programmatical approach can be applied, if the variables can be identified by a special pattern of the name. e.g. all variable names start with 'v_':
list = who('v_*');
for iVar = 1:length(list)
S.(list{iVar}) = eval(list{iVar});
end
This is a fairly secure usage of EVAL, because it is sure, that it operates on variable names only. If you get the list by WHO without specifying a pattern, care for not inserting "S" as "S.S" into itself.
This method is better than calling EVALIN('caller', list{i}) inside the function, because the data are at least transported as inupt argument, such that the used method is obvious if you inspect the code.
  1 Comment
Jan
Jan on 2 Feb 2011
Sorry: Typing this message blind and fix the typos afterwards took 32 minutes. In this time I could not use my browser, such that I've not seen, that there are equivalent answers already. Let me use the opportunity to repeat: Please, TMW, disable the "preview" immediately and update it after a manuall triggering (button press) only. This interface wastes my time and the time of all, who are willing to support this service.

Sign in to comment.


Paulo Silva
Paulo Silva on 2 Feb 2011
This file does the reverse of what you want, just change it to fit your purpose http://www.mathworks.com/matlabcentral/fileexchange/24121

Kenneth Eaton
Kenneth Eaton on 2 Feb 2011
Yet another option is to design your function to accept a variable length input argument list, pass any variables you want to it, and use the functions INPUTNAME and EVAL to initialize those variables within your function. Here's a sample function that accepts 2 inputs, then any number of additional inputs which it creates variables from:
function output = my_fcn(input1,input2,varargin)
for iInput = 3:nargin
eval([inputname(iInput) ' = varargin{' int2str(iInput-2) '};']);
end
%# Do all your other processing here...
end
The first three lines will loop over any additional variables passed in, get the names of these variables, then create variables with the same names and values inside the function. For example, if you call this function as follows:
out = my_fcn(in1,in2,a,b,c);
Then you will have three additional variables a, b, and c inside your function with the same values as those outside your function.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!