I have one matrix called targets (1X4000); column 1 to 2000 contains double value 0 and column 2001 to 4000 contains double value 1
a)
i want to create a matrix called targets_1 where i want to check if the value is 0 then make the entry 1 so at the end of the day i must have a matrix with :column 1 to 2000 with value 1 and column 2001:4000 with value zero
b)
Same situation as above but this time i want to check if the value is 1 then make the entry 1 and if it is zero then make the entry zero; at the end; my new matrix targets_2 contains values: column 1 to 2000 with value zero and column 2001:4000 with value 1
i know how to use the strcmp function to make such checking with strings, but problem is that my original matrix is double and i dont know if there is such function like
setosaCmp = strcmp('setosa',species);
which could work with double (numbers); any help would be appreciated
Your question isn't very clear. It sounds like the following would satisfy your description:
targets_1 = 1 - targets;
targets_2 = targets;
targets1 = double(targets == 0);
targets2 = targets;
I'm basing this answer purely on the fact that you've mentioned setosaCmp = strcmp('setosa', species);. From this I'm guessing that
You have Statistics Toolbox, as setosa is a species of iris from the Fisher Iris dataset widely used in Statistics Toolbox demos, and
You have a variable containing class labels, and you'd like to construct some class indicator variables (i.e. a new variable for each class label, each of which is 1 when the item is in that class, and 0 when it's not).
Is that right? If not, please ignore me.
If I'm right, then I think the command you're looking for is dummyvar from Statistics Toolbox. Try this:
>> classLabels = [1, 2, 1, 2, 3, 1, 3];
>> dummyvar(classLabels)
ans =
1 0 0
0 1 0
1 0 0
0 1 0
0 0 1
1 0 0
0 0 1
Related
I have the following three vectors:
trans_now=[1 2 4]; data2send=[1 0 0 1]; datasent=[0 0 0 0];
I want to set datasent to 1 for those nodes that are members of tran_now and whose data2send status is 1. e.g 4 is a member of trans_now and data2send(4) is 1 therefore datasent(4) should be set to 1.
I can do it using for loop and if statement as shown in the code below.
for i=1:length(trans_now)
if data2send(trans_now(i))==1
datasent(trans_now(i))=1;
end
end
However I want one liner code for this. The one liner code that I tried is
req_sent(req2send(trans_now)==1)=1;
But it doesn't work.
The output should set datasent vector to [1 0 0 1].
you could solve this in 2 ways:
1.
data_sent(trans_now) = data2send(trans_now)
the output is:
data_sent =
1 0 0 1
In this solution I assumed that all the initial values of data_sent are starting as 0 and that you need to assign it once.
2.
datasent(intersect(find(data2send == 1), trans_now)) = 1
output is:
data_sent =
1 0 0 1
In this solution no assumption is used and you assign only indices where data2send == 1 and also appear in trans_now
I have searched the forum and have not found enough info to help me solve this problem.
Consider the set (cell of vectors)
A = {[1],[1 2],[2],[1 2 3],[1 2 3 4],[1 3]}
I want to construct a matrix B that looks like
B = [1 1 0 1 1 1
0 1 0 1 1 0
0 1 1 1 1 0
0 0 0 1 1 0
0 0 0 0 1 0
0 0 0 1 1 1]
The matrix B specifies membership of vectors with respect to each other. That is, the first row looks at the first element in A, [1], and checks if it is a member of the other vectors, placing a 1 if it is a member and a 0 otherwise.
I can do this using two for loops: one over the elements of A, and another nested, for each element of A, that checks membership with respect to every other member of A.
I want to avoid using for loops. Is there a vectorized solution for obtaining B from A?
With cell arrays it's hard to avoid loops, or their cousin cellfun. This is how I would do it:
[ii, jj] = ndgrid(1:numel(A)); % indices of all possible pairs
result = cellfun(#(x,y) all(ismember(x,y)), A(ii), A(jj)); % see if all elements in the
% first are present in the second
Well you asked for it, so here's an almost* vectorized solution using bsxfun and permute -
lens = cellfun('length',A)
vals = [A{:}]
mask = bsxfun(#ge,lens,[1:max(vals)]')
a = nan(size(mask))
a(mask) = vals
matches = bsxfun(#eq,a,permute(a,[3,4,1,2]));
out = bsxfun(#eq,squeeze(sum(any(matches,3),1)),lens(:))
*: Almost because of the use of cellfun at the start with cellfun('length',A), but since its just getting the length of the cells there, so computationally would be negligible .
Also, please note that this approach would use a lot of memory resources, so might not be beneficial, but just respecting the requirements of a vectorized solution as much as possible!
I would like to compare rows across two unequal matrices in Matlab and extract these rows to be stored in a different matrix (say D). For example,
tmp = [2245; 2345; 2290; 4576]
and
id=[1 2245 564 8890 123;
2 2445 5673 7846 342;
3 2290 3428 3321 908].
Id is a much larger matrix. I want to locate each value of tmp which is in ‘id’. Although using the intersect command in the line below I have been able to locate the rows of id which contain the values from tmp, I would like to do this for each value of tmp one by one as each value of tmp is repeated multiple times in id. I tried using foreach. However, I get an error message stating that foreach cannot be used for char type array. Could anyone please suggest an alternative how to go about this?
for j=1:length(tmp);
[D,itmp,id2] = intersect(tmp(j,1),id(:,2), 'rows');
Despite using the loop, the code doesn’t seem to take one value of j at a time. This was the reason behind trying ‘foreach j’. Also after finding the rows common to the two matrices and storing them in D, I would like to append matrix id to include the value of j next to the relevant row within id. For example, if the first value within tmp was repeated in id in rows 1,3,5,10; I would like a column in id which would take the value 1 next to rows 1,3,5,10. Any help on this would be much appreciated! Thanks.
Not sure exactly, what you trying to do, but to search a value in a matrix you can use find:
for i = 1:numel(tmp)
[row, col] = find(id == tmp(i));
end
You can easily achieve this using a combination of bsxfun and permute. What you would do is transform the tmp vector so that it is a single 3D vector, then use the eq (equals) function and see which values in your matrix are equal to each value of tmp. Therefore, do something like:
%// Your data
id=[1 2245 564 8890 123;
2 2445 5673 7846 342;
3 2290 3428 3321 908]
tmp = [2245; 2345; 2290; 4576];
tmp2 = permute(tmp, [3 2 1]); %// Make a 3D vector
tmp3 = bsxfun(#eq, id, tmp2); %// Find which locations of id are equal to each value of tmp
This is what I get for my final output, stored in tmp3:
tmp3(:,:,1) =
0 1 0 0 0
0 0 0 0 0
0 0 0 0 0
tmp3(:,:,2) =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
tmp3(:,:,3) =
0 0 0 0 0
0 0 0 0 0
0 1 0 0 0
tmp3(:,:,4) =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
As you can see here, each 3D slice tells you which elements in id match the corresponding value in tmp. Therefore, the first slice tells you whether any element in id is equal to tmp(1), which is 2245. In this case, this would be the first row and second column. For the second slice, no values matched tmp(2) = 2345. For the third slice, one value in id matched tmp(3) = 2290, which is row 3, column 3.
Now, what you're really after is determining the rows and columns of where each value of tmp matched each location in id. You want this to be delineated per id number. That can easily be done using ind2sub and find on this matrix:
[rows, cols, ID] = ind2sub(size(tmp3), find(tmp3))
rows =
1
3
cols =
2
2
ID =
1
3
Therefore, ID tells you which id we have matched to, and rows, cols tells you which rows and columns in id we were able to match with. Therefore, for id = 1, we found a match with tmp(1)= 2245, and this is located at row=1,col=2. Similarly, for id = 3, we found a match with tmp(3)=2290 and this is at row=3,col=2.
To make this into all one big 2D matrix that contains all the information you want, you can simply concatenate all of these columns into one matrix. Therefore:
final = [ID rows cols]
final =
1 1 2
3 3 2
You can read this like so:
id=1 with tmp(1) = 2245, we found this value in row=1,col=2.
id=3, with tmp(3) = 2290, we found this value in row=3,col=2
Hope this helps!
I'd like to accumulate indexed elements in a matrix, like table and tapply function in R.
I found sparse(i,j,s,m,n) fit my need perfectly,
As the document says:"Any elements of s that have duplicate values of i and j are added together."
But I have to convert the obtained sparse matrix to a full one using full():
a = a + full(sparse(i,j,s,m,n));
Is this a efficient way to do so?
By the way, is there anything like below, no matter whether adding duplicated i,j pairs?
a = setelements(a, i,j,s);
and
vector = getelement(a,i,j);
where i&j take meanings in sparse() function.
And what if a is a multidimensional array? sparse() only deal with matrix.
Do I have to set the entries page by page with outer loops?
Take a look at accumaray. For example,
ii = [1 2 2 3 3];
jj = [3 2 2 2 2];
s = [10 20 30 40 50];
a = accumarray([ii(:) jj(:)],s(:));
gives
a =
0 0 10
0 50 0
0 90 0
Note that each row of the first argument ([ii(:) jj(:)]) defines an N-dimensional index into the output array (N is 2 in this example).
accumarray is very flexible. It works for N-dimensional arrays, lets you specify size of the result (it may be larger than inferred from the supplied indices), and can even apply an arbitrary function (different from sum) to each set of values defined by the same index.
As a more general example, with the above data,
a = accumarray([ii(:) jj(:)],s(:),[4 4],#max)
gives
a =
0 0 10 0
0 30 0 0
0 50 0 0
0 0 0 0
I have an array that starts of with zeros and continues into other numbers
I would like to delete the columns in the array that start off with zero but keep the other numbers
example of an column array below:
x= [0 0 0 0 0 2 4 6 8 0 1 2];
Answer of column array would look like
x= 2 4 6 8 0 1 2
I'm using octave 3.4.2/matlab
Thanks
Here is the code:
x = x(find(x~=0, 1):end);
or
x(1:find(x~=0,1)-1) = [];
The find command should work for this.
Assuming your vector is x:
find(x ~= 0)
Will return all indices where x is non-zero. Just grab the first index and go from there to delete all values from 1 to index.
Logical indexing will work just fine in this case: i.e.,
y = x(:,x(1,:)~=0)
will do the job for you. The inner logical comparison, x(1,:)~=0 returns true for every column whose first element is not zero. The indexing operation, x(:,...) selects only those columns for which the logical comparison returned true.