Variable variables in Matlab - matlab

I have 30 txt files with data
And I want to create on the fly vectors from that files with the name of "file name"
pathforindependents = 'C:\MatLab\independent\'
independents = dir(fullfile(pathforindependents,'ind*.txt'))
for i = 1:length(independents)
filename = independents(i).name;
r=regexp(filename,'\.','split');
qnumber = r(2)
qtitle=r(3)
qpath = strcat(pathforindependents,filename)
qdata = load(qpath)
mtrxPrefix = 'mtrx_';
v = strcat(mtrxPrefix,qtitle);
eval(???????????????????????)
end
But I dont know how can I do it. No matter what I try Matlab gives me "Undefined function 'eval' for input arguments of type 'cell'." Error?
My data file structure is like
ind.01.AGE.txt
0
1
0
0
0
1
1
0
1
...
At the end I want to reach this
mtrx_AGE =
0
1
0
0
0
1
1
0
1
...
How can I do it ? Thank you.

To put the variables in the base workspace, use assignin:
assignin('base', v, qdata);
As you can see in the assignin documentation, for certain assignment cases you may want to use evalin.

you can use fields within structures with sprintf to name variables on the fly:
for i = 1:100
my_struct.(sprintf('A%s%i','filename',i)) = i^2
end
would make
my_struct.Afilename1 = 1
my_struct.Afilename2 = 4
my_struct.Afilename3 = 9

Read Mathworks TechNote 1103 on why you should avoid using EVAL the way you do. Alternatives include cell arrays or structures.

Related

What is meant by "too many output arguments"?

I run this code, but I have an error in "error function".
The error message I get it:
Error using error
Too many output arguments.
Does anyone know what is the problem?
w=2*rand(3,4)-1; % Randomly choosen between -1 and 1
x=[ 5 55 14 32; 4 4 84 5; 4 31 9 4; 4 45 99 2]; % Desired outputs
d=[ 1, 1, 0 ; 0, 1, 0 ; 0, 0, 1 ];
for j1=1:3,
yi=w'*x(:,j1); % Network output
y=sign(yi);
if sum(y-d(1,:)') > 0
error = error+1
end
end
The variable error is not defined and is used before defining it. As it is not defined.....it is taking the inbuilt matlab function error. Don't use the variable names as MATLAB inbuilt funcitons. You rename this variable as some other variable name, say myerror. Don't forget to initialize it. Check the below example code.
for i = 1:10
error = error+1 ;
end
The above code shows error Too many output arguments. Because the code takes error is inbuilt function, as it is not initialized.
error = 0 ;
for i = 1:10
error = error+1 ;
end
The above works, as we have initialized error, code will not take the inbuilt function.
But the above is not suggested. Never overwrite the existing functions in matlab as variable names. The below is suggested.
myerror = 0 ;
for i = 1:10
myerror = myerror+1 ;
end
I suspect that the source of your problem is because error is a MATLAB function and you try to use it as a variable, hence the error message "Error using error". Change your variable name to something like my_error or similar, and it should work.

looping over a list of file names in Matlab

Probably a really simple question - but I can't seem to figure it out for Matlab. I would like to import data from a list of files, and save the resulting matrices with a name derived from the original file name. There's quite a few files, so I would like to use a for loop.
In BASH I would write something like:
For sample in apple orange guava jackfruit;
do
"$sample"_matrix = someimportfunction("$sample".txt);
done
I can import the files one at a time with dlmread, I just can't figure out how to loop over the names, sort of the matlab equivelent of $.
Many thanks for any suggestions!
I think the code snippet below may do exactly what you want.
Of course, you need the files apple.txt etcetera, with numbers in them
for sample = {'apple', 'orange', 'guava', 'jackfruit'}
matrix.(sample{1}) = load([sample{1},'.txt']);
end
matrix = matrix
I get the following output:
matrix =
scalar structure containing the fields:
apple = 1 2 3
orange =
1 2
4 5
guava =
1 1 1
0 0 0
jackfruit = 17
Let's say your files are in the folder "sfolder".
Files = dir('sfolder');
num_files = length(Files);
for i=1:num_files
fid = fopen(Files(i).name); %do whatever you want now
end
This will help you go through each file in a particular directory.

Find substring in cell array of numbers and strings

I have a cell array consisting of numbers, strings, and empty arrays. I want to find the position (linear or indexed) of all cells containing a string in which a certain substring of interest appears.
mixedCellArray = {
'adpo' 2134 []
0 [] 'daesad'
'xxxxx' 'dp' 'dpdpd'
}
If the substring of interest is 'dp', then I should get the indices for three cells.
The only solutions I can find work when the cell array contains only strings:
http://www.mathworks.com/matlabcentral/answers/2015-find-index-of-cells-containing-my-string
http://www.mathworks.com/matlabcentral/newsreader/view_thread/255090
One work-around is to find all cells not containing strings, and fill them with '', as hinted by this posting. Unfortunately, my approach requires a variation of that solution, probably something like cellfun('ischar',mixedCellArray). This causes the error:
Error using cellfun
Unknown option.
Thanks for any suggestions on how to figure out the error.
I've posted this to usenet
EDUCATIONAL AFTERNOTE: For those who don't have Matlab at home, and end up bouncing back and forth between Matlab and Octave. I asked above why cellfun doesn't accept 'ischar' as its first argument. The answer turns out to be that the argument must be a function handle in Matlab, so you really need to pass #ischar. There are some functions whose names can be passed as strings, for backward compatibility, but ischar is not one of them.
How about this one-liner:
>> mixedCellArray = {'adpo' 2134 []; 0 [] 'daesad'; 'xxxxx' 'dp' 'dpdpd'};
>> index = cellfun(#(c) ischar(c) && ~isempty(strfind(c, 'dp')), mixedCellArray)
index =
3×3 logical array
1 0 0
0 0 0
0 1 1
You could get by without the ischar(c) && ..., but you will likely want to keep it there since strfind will implicitly convert any numeric values/arrays into their equivalent ASCII characters to do the comparison. That means you could get false positives, as in this example:
>> C = {65, 'A'; 'BAD' [66 65 68]} % Note there's a vector in there
C =
2×2 cell array
[ 65] 'A'
'BAD' [1×3 double]
>> index = cellfun(#(c) ~isempty(strfind(c, 'A')), C) % Removed ischar(c) &&
index =
2×2 logical array
1 1 % They all match!
1 1
Just use a loop, testing with ischar and contains (added in R2016b). The various *funs are basically loops and, in general, do not offer any performance advantage over the explicit loop.
mixedCellArray = {'adpo' 2134 []; 0 [] 'daesad'; 'xxxxx' 'dp' 'dpdpd'};
querystr = 'dp';
test = false(size(mixedCellArray));
for ii = 1:numel(mixedCellArray)
if ischar(mixedCellArray{ii})
test(ii) = contains(mixedCellArray{ii}, querystr);
end
end
Which returns:
test =
3×3 logical array
1 0 0
0 0 0
0 1 1
Edit:
If you don't have a MATLAB version with contains you can substitute a regex:
test(ii) = ~isempty(regexp(mixedCellArray{ii}, querystr, 'once'));
z=cellfun(#(x)strfind(x,'dp'),mixedCellArray,'un',0);
idx=cellfun(#(x)x>0,z,'un',0);
find(~cellfun(#isempty,idx))
Here is a solution from the usenet link in my original post:
>> mixedCellArray = {
'adpo' 2134 []
0 [] 'daesad'
'xxxxx' 'dp' 'dpdpd'
}
mixedCellArray =
'adpo' [2134] []
[ 0] [] 'daesad'
'xxxxx' 'dp' 'dpdpd'
>> ~cellfun( #isempty , ...
cellfun( #(x)strfind(x,'dp') , ...
mixedCellArray , ...
'uniform',0) ...
)
ans =
1 0 0
0 0 0
0 1 1
The inner cellfun is able to apply strfind to even numerical cells because, I presume, Matlab treats numerical arrays and strings the same way. A string is just an array of numbers representing the character codes. The outer cellfun identifies all cells for which the inner cellfun found a match, and the prefix tilde turns that into all cells for which there was NO match.
Thanks to dpb.

Give each variable a name based on an already existing logical-ID vector (MATLAB)

I have length(C) number of variables. Each index represents a uniqe type of variable (in my optimization model), e.g. wheter it is electricity generation, transmission line capacity etc..
However, I have a logical vector with the same length as C (all variables) indicating if it is e.g. generation:
% length(genoidx)=length(C), i.e. the number of variables
genoidx = [1 1 1 1 1 1 0 0 ... 1 1 1 1 1 1 0 0]
In this case, there are 6 generators in 2 time steps, amounting to 12 variables.
I want to name each variable to get a better overview of the output from the optimization model, f.ex. like this:
% This is only a try on pseudo coding
varname = cell(length(C),1)
varname(genoidx) = 'geno' (1 2 3 4 5 6 ... 1 2 3 4 5 6)
varname(lineidx) = 'line' (...
Any suggestions on how to name the variables in C with string and number, based on logical ID-vector?
Thanks!
Using dynamic names is maybe OK for the seeing the results of a calculation in the workspace, but I wouldn't use them if any code is ever going to read them.
You can use the assignin('base') function to do this.
I'm not quite sure what your pseudo code is attempting to do, but you could do something like:
>> varname={'aaa','bbb','ccc','ddd'}
varname =
'aaa' 'bbb' 'ccc' 'ddd'
>> genoidx=logical([1,0,1,1])
genoidx =
1 0 1 1
>> assignin('base', sprintf('%s_',varname{genoidx}), 22)
which would create the variable aaa_ccc_ddd_ in the workspace and assign the number 22 to it.
Alternatively you could use an expression like:
sum(genoidx.*(length(genoidx):-1:1))
to calculate a decimal value and index a cell array of bespoke names:
>> varname={'aaa','bbb','ccc','ddd','eee','fff','ggg','hhh'}
varname =
'aaa' 'bbb' 'ccc' 'ddd' 'eee' 'fff' 'ggg' 'hhh'
>> assignin('base', varname{sum(genoidx.*(length(genoidx):-1:1))}, 33)
which would create the variable ggg and assign 33 to it.

MATLAB error - ??? Attempt to reference field of non-structure array

I'm writing an insertion sort in MATLAB. I called my function like this:
>> A = [5 4 3 2 1]
A =
5 4 3 2 1
>> insertion_sort(A)
but when I run it I get the error
??? Attempt to reference field of non-structure array.
Error in ==> insertion_sort at 6
for j=2:original.length
Here's my original code:
function sorted = insertion_sort(original)
for j=2:original.length
key = original(j);
i = j-1;
while i > 0 && original(i) > key
original(i+1) = original(i);
i = i-1;
end
original(i+1) = key;
end
sorted = original;
end
Anyone know what I'm doing wrong?
Try numel(original) instead of original.length. MatLab matrices are primitive types, not objects, and they don't have a length property.
You want to use numel(original) instead of original.length. Fundamental data types don't have a length method, so MATLAB mistakenly thinks you are trying to access a field named length in a structure, which original is not.