I'm writing a piece of code that requires me to define multiple functions using seperate m-files. The trouble that I run into, however, is that these functions use their own workspaces separate from the base workspace. I need each of these functions to access and altar the base workspace. I could care less if they have their own workspace, since everything can be done in the base workspace.
I have tried using evalin, as well as assignin. These work fine until a reach a point where I have a FOR loop. The loops refuse to allow me to index an array in any workspace other than the m-file's workspace. So I either have the problem of not accessing the base workspace at all, or only being able to access it in a completely nonuseful fashion.
Does anyone have any suggestions on how to import the entire base workspace into a function? Or at least some sort of work-around that allows access to the base workspace. Any help here would be greatly appreciated. Thank you in advance.
the cleanest way
- do NOT alter another workspace within a function...
- create a function with input/output arguments...
- using an i/o structure typically saves you from having to change (too many) of
these arguments as you can simply ad another field...
- ML has several containers, which, however, typically are used in contexts such as
- callback functions...
and do not really help in your case...
us
I have created functions with input/output arguments. The problem is the inputs are variables imported into the base workspace using uiimport. These inputs vary in length depending upon the specific file that I am importing (ie A1,A2,...An). Until I am able to input all of the variables from the base workspace into the first function, the i/o structure does me no good, since I cannot import the variables to begin with as they are not pre-defined.
In programs predecessor everything worked just fine. It wasn't GUI based, so I didn't have to define any of these functions as functions with specific i/o's. I created an object with uiimport. Does it make sense to use this objects callback in these other functions? Thank you for your help.
but - using UIIMPORT should make the task easy...
- just employ the syntax
s=uiimport(...);
use S as an input arg
and access your vars by S.var1 ... S.varN within your functions
just a thought
us
This seems to be putting me on the right track. Thank you again for your help. I am fairly new to matlab so some of your answers are bringing new questions forward.
Does the variable S preserve the information found by using uiimport? This seems to save a new variable, S. However, this doesn't seem to allow me to use the who() function to search for specific variables loaded with uiimport that are now part of S.
Maybe there is another way to access these specific files and I'm too narrow sighted to see through my original solution? Again thank you for all of the help.
I'm Sorry I must have glossed over the S.var..S.varN. However, I still run into the problem that who('S.var*') is not returning the entire subset of var* that I need. In fact, it doesn't return any. So my question still stands; how do I access these variables now without using who()?
Thank you
> Does the variable S preserve the information found by using uiimport? This seems to save a new variable, S. However, this doesn't seem to allow me to use the who() function to search for specific variables loaded with uiimport that are now part of S.
==================
But why would you want to use who() specifically to do this search?
You can see which variables have been loaded by displaying S at the command line,
e.g.,
>> S.a=1; S.b=4; S.c=7; S.d=9;
>> S
S =
a: 1
b: 4
c: 7
d: 9
You can also use the fieldnames(S) command to see programmatically what fields belong to S .
Failing all that, you could use my structvars() FEX submission
http://www.mathworks.com/matlabcentral/fileexchange/26216-structure-fields-to-variables
to "poof" the fields of S into the workspace of your function, as in the following
>> clear a b c d
>> eval(structvars(S).')
>> a,b,c,d
a =
1
b =
4
c =
7
d =
9
This is, however, a highly discouraged coding practice, and not the recommended mode of use of the tool.
one of the solutions
s.a=pi;
s.bb=magic(3);
fn=fieldnames(s)
sc=struct2cell(s)
%{
% fn = % <- field names packed into CELLs
'a'
'bb'
% sc = % <- field content packed into CELLs
[ 3.1416]
[3x3 double]
%}
us
I have two issues which cause me to need the use of the who() function.
The first is that the imported files contain not only a variable number of A1..An, but they also contain about 6 different file types (these are converted into .mat files from another piece of data collection software, which is why specifically these need to be imported).
The second issue is that each An file is a 3201x2 array that needs to be analyzed. So I need to first get a function to recognize the imported variables, then get it to find the necessary variables within those imported variables. Those are then analyzed and indexed by another piece of code. When I import more files everything is erased and replaced with the new data needing to be analyzed.
My code had been
Afiles = who('A*');
nchannels = length(Afiles);
A = zeros(1,2);
frequencies = 0;
for i = 1:nchannels
A = eval(['A' num2str(i) '_' num2str(i)])
freq = A(:,1);
alllevels(:,1) = A(:,2);
end
which worked fine until I turned this thing into a function (which was necessary to build the GUI). I am going to try your method even though it is highly discouraged because I can't think of another way.
but - using the STRUCT approach makes this a simple chore...
% read your file's content into S...
% - simulate some data
s.a1=1*ones(3,2);
s.a2=2*ones(4,2);
s.bb=3*ones(5,2);
% the engine
fn=fieldnames(s);
nf=numel(fn);
for i=1:nf
frq=s.(fn{i})(:,1); % <- get 1.st col from signal S.X
lev=s.(fn{i})(:,2); % <- get 2nd col from signal S.X
% use FRQ/LEV for your computation(s)...
end
us
% the (last!) result
disp([frq,lev])
%{
3 3
3 3
3 3
3 3
3 3
%}
us
That does make it a much simpler task. Thank you again for your help
As shown this works. However, when I make this a function with i/o parameters it refuses to acknowledge the variable S.
function [outputs] = data(S)
exactly what you have
end
i get
??? Input argument "S" is undefined
Error in ==> data
fn = fieldnames(S);
I've checked to make sure that S is in fact in the workspace. It is, but my new i/o function doesn't like it. I have no idea what is wrong. Thanks for your help.
Is this what you want?
ImportedVarNames=fieldnames(S);
ix=strmatch('A',ImportedVarNames);
Afiles = ImportedVarNames(ix);
nchannels = length(Afiles);
A = zeros(1,2);
frequencies = 0;
for i = 1:nchannels
A=S.(Afiles{i});
well...
does - whoever calls DATA - know about S?
eg, a skeleton...
% M-file: mfun.m
function r=mfun(varargin)
s=uiinput(...); % <- get your data
r=comp_data(s); % <- use your data
end
function r=comp_data(s)
% loop...
% r=...
end
us
That code is excellent. Once again, however, when I turn the whole thing into an i/o function
function [outputs] = data(S)
**your code**
end
my m file doesn't recognize the variable S. I've made sure its in the workspace. This runs back to the original problem that I tried to overcome by creating the variable S using uiimport. I'm really stumped. Its probably an easy fix, but I'm to fried to see it. Thank you again for all of your help. This is giving me a lot more insight into matlab.
I've been assuming all along that you are creating S using uiiimport and either passing it to data() or else calling S=uiimport(...) inside data() directly.
Either way, if you're sure S is in the workspace of data(), what do you mean when you say your "mfile doesn't recognize" it. If it's in the workspace, your mfile is recognizing it by definition....
That looks like its the issue. I think this is finally resolved...
I hope so anyway. Thank you for all of your help
I'm probably just making a really stupid rookie mistake here. What I have is
function gui
function importbutton_Callback(source,eventdata)
assignin('base','S',uiimport)
end
function calculate
function [] = data(S)
*code you've helped me with*
end
end
end
Thank you for all of the help you given me so far. If you could shed any more light on this it would be greatly appreciated.
>
> I'm probably just making a really stupid rookie mistake here. What I have is
>
> function gui
>
> function importbutton_Callback(source,eventdata)
> assignin('base','S',uiimport)
> end
>
> function calculate
>
> function [] = data(S)
>
> *code you've helped me with*
>
> end
>
> end
>
> end
It's a little hard to diagnose because you've trimmed your code down to your function definitions only with no indication of where these functions are called.
However, one thing leaps out: assignin('base','S',uiimport) creates the variable S in the *base* workspace (the one at the command line). At no point is S apparently passed to the workspace of gui() or any of the functions nested within it (so of course they cannot process it).
I'm guessing that when you said you "made sure S was in the workspace" you were checking the workspace at the command line and not the workspace of the functions???
sorry, but you REALLY should read the getting-started-doc...
- this snippet cannot work...
function gui
function importbutton_Callback(source,eventdata)
% assignin('base','S',uiimport) % <- S is known in the base *ONLY*...
S=uiimport(...);
set(0,'userdata',S); % <- use one of the containers...
end
function calculate
% function [] = data(S)
function data(varargin) % <- keep this for 'later'...
S=get(0,'userdata'); % <- retrieve S...
*code you've helped me with*
end
end
end
us
Clearly I'm in a bit over my head. I appreciate your patience with me. I've modified the code and got it to this point:
function gui
function[S] = import_Callback
S = uiimport;
set(0,'userdata',S)
end
function calculate
function [outputs] = data(varargin)
S = get(0,'userdata');
ImportedVarNames = fieldnames(S);
ix = strmatch('G',ImportedVarNames);
Gfiles = ImportedVarNames(ix);
nchannels = length(Gfiles);
G = zeros(1,2);
frequencies = 0;
for i = 1:nchannels
G = S.(Gfiles{i});
freq = G(:,1);
alllevels(:,1) = G(:,2);
end
end
end
end
The issue I now run into is
??? Input argument nchannels is undefined
when I do some error checking I see that nchannels is correct, so everything that you guys have helped me with is working correctly, but for some reason there is a disconnect between nchannels and the nchannels within the for loop. Any ideas?
Thanks again for all of your help and patience.
based on the (innocent) snippet you show CSSM, the error message does not make sense as NCHANNELS is nowhere used as an input arg...
hence, you do NOT show the whole pic...
the least you should do: show the whole output of the error message...
us
Error in ==> data at 7
for i=1:nchannels
Error in ==> gui>calculate_Callback at 125
data
Nevermind the last post. The error was not in data, but rather another function