I have an array of cells, for example,
cells = {'a', 'b', 'c', d', 'e'};
which is inside a for loop of 1 to 5.
I want to create a variable from a to e depending on the loop index, as 1 to a, 2 to b...
When I try (i is the for index),
eval(cells{i}) = values; it gives me the error,
Undefined function or method 'eval' for input arguments of type 'a'
Here the answer:
eval(sprintf([cells{i} '=values;']))
And you can remove the ; if you want to see the display in command window.
In answer to your comment :
cells = {'a', 'b', 'c', 'd', 'e'};
values = 4;
i = 1;
eval(sprintf([cells{i} '=values;']))
This works perfectly fine on my computer, and i get no warning or error messages.
when calling eval, all arguments must be strings, so convert your cell elements to strings first.
eval([ cellstr(cells{i}) ' = values;']))
Related
I need to generate all possible subset from a character array in MATLAB with reduced execution time.
For example:
input='ABCA';
output ='A',
'B',
'C',
'AB',
'BC',
'CA',
'ABC',
'BCA',
'ABCA'
You can find all these subsets using straight-forward loops. I don't know if it is worth-while vectorizing these, as any vectorization will require large intermediate arrays.
With a random input of 500 characters, and maxLen at 20, I got 4207817 unique substrings. It took my computer (with MATLAB R2017a) 12 seconds to find these. Whether that is fast enough or not is up to you, but I would not bother further optimizing this.
input = 'ABCA';
maxLen = 4;
subsets = {};
for len = 1:maxLen
subs = cell(1,numel(input)-len+1);
for start = 1:numel(subs)
subs{start} = input(start:start+len-1);
end
subs = unique(subs);
subsets = [subsets,subs];
end
disp(subsets)
Output:
'A' 'B' 'C' 'AB' 'BC' 'CA' 'ABC' 'BCA' 'ABCA'
If it is important to preserve the order of the substrings, then add the 'stable' argument to the unique call:
subs = unique(subs,'stable');
For example, for input = 'AFCB';, the output without 'stable' is:
'A' 'B' 'C' 'F' 'AF' 'CB' 'FC' 'AFC' 'FCB' 'AFCB'
and with 'stable' it is:
'A' 'F' 'C' 'B' 'AF' 'FC' 'CB' 'AFC' 'FCB' 'AFCB'
I have in Matlab the following cells containing various combinations of the letters a,b,c,d
%all combinations containing 'a' and/or 'b'
G1={'a', 'ab', 'ac', 'ad', 'abc', 'acd', 'abd', 'abcd', 'b', 'bc', 'bd', 'bcd'};
%all combinations containing 'c' and/or 'd'
G2={'c', 'ac', 'bc', 'cd', 'abc', 'acd', 'bcd', 'abcd', 'd', 'ad', 'bd', 'abd'};
%all combinations containing 'c'
G3={'c', 'ac', 'bc', 'cd', 'acd', 'abd', 'bcd', 'abcd'};
I then construct a cell all of dimension
allsize=size(G1,2)*size(G2,2)*size(G3,2);
containing all possible ways to match one element of G1 with one element of G2 with one element of G3.
all=cell(allsize,3);
count=0;
for h=1:size(G1,2)
for k=1:size(G2,2);
for j=1:size(G3,2);
count=count+1;
all(count,1)=G1(h);
all(count,2)=G2(k);
all(count,3)=G3(j);
end
end
end
Question: I want to construct a vector check of dimension allsize x 1 such that check(l)=1 if [all(l,1) contains a and all(l,2) contains c] or [all(l,1) contains b and all(l,2) contains d], and zero otherwise.
I am having problems in writing the if condition
check=zeros(allsize,1);
for l=1:allsize
%if [all(l,1) contains a and all(l,2) contains c] or [all(l,1) contains b and all(l,2) contains d]
check(l)=1;
%end
end
Could you kindly provide some help?
(For the if statement, always best to show what you tried rather than some pseudo code , however...)
Firstly using all as a variable name is bad - it's an important built-in function and one you may want to use... I've renamed it allG below. But you probably want something like this:
check(l) = (any(allG{l,1}=='a') && any(allG{l,2}=='c')) || ...
(any(allG{l,1}=='b') && any(allG{l,2}=='d'))
Note I haven't used an if statement, since the right hand side evaluates to a logical value (a true/false value) which can be generally used in the same way as 1 and 0...
Also above we're treating the strings as arrays of characters, so something like 'abcd'=='b' returns a [0 1 0 0] logical array... We then use any() to see if any of the values are 1 (true).
Check: http://www.scala-lang.org/docu/files/collections-api/collections_40.html
It says ArrayBuffer takes linear time when requesting tail. However, it is much faster when appending
My understanding is that an ArrayBuffer is simply a dynamic array.
How come appending is amortised constant time but getting the last element takes linear time?
tail is not the last element, it is all elements but the first. You want last.
Seq('a', 'b', 'c').head // 'a'
Seq('a', 'b', 'c').tail // Seq('b', 'c')
Seq('a', 'b', 'c').init // Seq('a', 'b')
Seq('a', 'b', 'c').last // 'c'
I have a matrix with population data and a vector that makes reference to each type of data example, age, country, gender, height, ethnicity.
I need to in a part of the code, use those strings as char 1x1. I thougnt in making some relation as
variables = {'age', 'a';
'gender', 'b';
'country', 'c';
'height', 'd';
'ethnicity', 'e'};
I would like something that any time I use the leters, 'a', 'b', 'c', 'd' or 'e', the code understands that I want to use 'age', 'gender', 'country', 'height' or 'ehtnicity', respectively.
how could I do this?
thanks!
You have two options:
A more common method is to use a structure:
codes.a = 'age';
codes.b = 'gender';
...
So anytime you need a code, just get the value of the equivalent structure member:
character_you_typed = 'a';
getfield(codes, character_you_typed)
or (based on #Amro 's comment below):
codes.(character_you_typed)
This method does not restrict you to one-character keys. Another method is to use the recently added Map container with a 'char' key:
codes = containers.Map('KeyType', 'char');
codes('a') = 'age';
codes('b') = 'gender';
...
Then:
character_you_typed = 'a';
codes(character_you_typed)
The second method looks much better, but unfortunately you are restricted to a single character for the keys.
I am trying to compare two cell arrays, 1x160 (a) and 80x1(b). My cell arrays consist of cells which have a number of strings inside. I wanna compare each string ans see if they are equal, then if they are equal, insert to new array, or insert 0 otherwise. I can't find any function for that. I tried 'isequal','strfind' and others. All of them give me next error message:
If any of the input arguments are cell arrays, the first must be a
cell array of strings and the second must be a character array.
Here is my code!
function [inter]=Intersect2(a,b)
int=cell(0);
b2=[b;b];
for i=1:length(a)
if a{i,1}==b2{i,1}(1) ( or 'isequal','strfind')
int{i}=a{i};
else
int{i}=0;
end
end
There are many ways to compare character arrays, one of which is strcmp.
We'll use cellfun as well to avoid looping.
a = {'Dude', 'I', 'am', 'a', 'moose'};
b = {'Well', 'I', 'am', 'a', 'mouse'};
index = cellfun(#strcmp, a, b);
This will compare each element of a against the corresponding element in b, returning a logical array index that is 1 when the elements match and 0 when they do not.
Use this to assign matching values:
int = cell(1, length(a));
int(index) = a(index);
int =
[] 'I' 'am' 'a' []
You can extend this concept to find the set intersection if you wish.