For example, I can create a zeros(100). But I want the entry of row 58 and column 59 to be 1. But I need temporary variable and multiple lines to do this.
a. Let this matrix be M. How can I do this in one line? M = ....?
P.S.
b. Better still, sometimes I want two or more entries of the zero matrix be 1.
Again, how can I do this?
If I can do a. in one-line, of course I can add them up. But is there any special function to do fill zero matrix entries with 1?
First, remember that a one line expression isn't always the most effective. It could also be harder to read/understand.
One way to do this is by using a sparse matrix
The following example creates a 10x10 zero-matrix with ones at [5,2] (row 5, col 2) and [7 5]
full(sparse([5 7],[2 5],1,10,10))
Use full to convert it from a sparse matrix to a "full" one
Another (faster but maybe not as intuitive) alternative is to use accumarray
accumarray([5 2;7 5],1,[10,10])
Remember that the index values above is used directly in the expression to get on one line, the better option would be to create them separately
points = [5 2; 7 5]
or perhaps,
rowIdx = [5 7];
colIdx = [2 5];
Related
I am trying to add two vectors; however, they do not have the same dimensions. For example only (since the one I am doing have 1000+ values), the vectors are:
a = [1 2 3 4 5];
b = [1 2];
Since they do not have the same dimensions, I want to simply add zeroes to vector b to match the dimension of vector a.
Using the code b(numel(a)) = 0; I was able to do it. However, I am quite confused on how it worked as I only saw this code on the internet. I know that numel(a) is equal to 5, but I don't know how that code was able to add zeroes after 1 2 in variable b to match the dimension of variable a.
Can anyone explain?
When you set b(5) = 0, matlab can not simply leave the intervening elements b(3:4) unfilled, so they get zeros. If you did b(numel(a)) = 1, the intervening elements would still be filled with zero.
Keep in mind that this is a short cut that only works if you know for that fact that b is shorter than a. If not, you will be setting an element of b to 0, which is likely not what you want.
I would like to have a better comprehension of Matlab mutidimensionnal arrays and the : operator with a quick question
So I ran this example
A = zeros(2,3,4,5);
size(A)
% ans = 2 3 4 5
%% 1.
size(A(:,:,1,1))
% ans = 2 3
%% 2.
size(A(1,1,:,:))
% ans = 1 1 4 5
%% 3.
size(reshape(A(1,1,:,:), 4, 5))
% ans = 4 5
1. is the behavior I actually expected for all operations.
I don't understand why do I kept unwanted dimension in 2.
Do I need to reshape like in 3. everytime I need a subarray ?
Matlab removes singleton trailing dimensions only, so what you see is normal.
In 1, you removed a 2D subset from a 4D array, but the first two dimensions were "row" and "column".
In 2, the "row" and "column" are both singleton, and the rest of the array is in the third and fourth dimensions, so Matlab keeps it that way.
Instead of reshapeing, you can squeeze(A(1,1,:,:)) to remove dimensions that have length one (except for dimensions 1 and 2, which are sort of hard-coded into Matlab).
You can use reshape or simply squeeze in this case.
MATLAB always removes trailing singleton dimensions (past the first two):
>> size(zeros(4,4,4,1,1))
ans =
4 4 4
But it also adds them when needed (or as Ander points out in the comment, they are always implicitly there):
>> a = zeros(4,4);
>> a(2,2,1,1); % is OK
>> size(a,100)
ans =
1
On the other hand, other singleton dimensions are kept. squeeze removes them.
For your particular application it makes sense to remove singleton dimensions, but other applications would have problems if this were the default behavior. Imagine code that extracts a certain sub-volume, and changing the direction of the data depending on how many rows or columns are selected. For example:
>> a(1:x,1:y,1:z)
would return an array of size (x,y,z) as long as x and y are larger than one. Make x=1, and now it's an array of size (y,z)? Bad idea!
I have already looked here and here, but I'm not sure I found what I need.
I have an irregular file (that represents neighbors of particles 1 to 5) that looks like that
2 3 5
1 3
1 2
1
I am want to figure out a way to load it (as 'something' called A) and do the following things:
Count the number of elements on one line (for instance size(A(1,:)) shall give me 3)
Given an array B (of size 5) select the elements of B corresponding to the indices given by a line (something like B(A(1,:)) shall give me [B(2) B(3) B(5)])
Since you want arrays with size depending on their first index, you're probably left with cells. Your cell A could be such that A{1} equals to [2 3 5] and A{2} to [1 3] in your example etc. To do this you can read your file infile by
fid=fopen(infile,'rt');
A=[];
while 1
nextline=fgets(fid);
if nextline==-1 %EOF reached
break;
end
A{end+1}=sscanf(nextline,'%d');
end
fclose(fid);
%demonstrate use for indexing
B=randi(10,5,1);
B(A{3}) %2-element vector
B(A{4}) %empty vector
Then A{i} is a vector corresponding to the ith line in your file. If the line is empty, then it's the empty vector. You can use it to index B as you want to, see the example above. Note that you should not add a newline at the very end of your infile, otherwise you'll have a spurious empty element for A. If you know in advance how many lines you need to read, this is not an issue.
And the number of entries in line i are given by length(A{i}), with i=1:length(A).
Starting wish a 7x4 binary matrix I need to change a random bit in each column to simulate error. Have been trying to no avail.
A very straightforward way to do this is to use a for loop. It might not be the most efficient approach in MATLAB, but it's probably good enough considering your data set is so small.
Iterate through each of the four columns. On each iteration, randomly chose a number from 1 to 7 to represent the row in that column that you have selected to change. Finally, flip the bit at that row/column. The following code does just this. Assume that "A" is a binary matrix with 7 rows and 4 columns
for col=1:4; %// Iterate through each column
row = ceil(7*rand()); %// Randomly chose a number from 1 to 7 to represent row
A(row,col) = ~A(row,col); %// Flip the bit at the specified row/col
end
Another possibility is to create 4 random numbers in one call, and assign in a vectorized fashion:
rowNumbers = randi(4,[1 4])
A(rowNumbers,:) = ~A(rowNumbers,:);
This is very closely related to this other question, but that question wanted to avoid sub2ind because of performance concerns. I am more concerned about the "unelegance" of using sub2ind.
Let's suppose I want to create another MxN matrix which is all zeros except for one entry in each column that I want to assign from the corresponding entry in a vector, and choice of row in each column is based on another vector. For example:
z = zeros(10,4);
rchoice = [3 1 8 7];
newvals = [123 456 789 10];
% ??? I would like to set z(3,1)=123, z(1,2)=456, z(8,3)=789, z(7,4)=10
I can use sub2ind to accomplish this (which I used in an answer to a closely related question):
z(sub2ind(size(z),rchoice,1:4)) = newvals
but is there another alternative? Seems like logical addressing could be used in some way but I'm stumped, because in order to set the elements of a logical matrix to 1, you're dealing with the same element positions as in the matrix you actually want to address.
There's a much simpler way of doing it.
nCols=size(z,2);
z(rchoice,1:nCols)=diag(newvals);
You can just add the number of rows in previous columns to rchoice to get the linear index directly.
nRows = size(z,1); %# in case you don't know this already
nCols2write = length(newvals);
z(rchoice+[0:nRows:(nRows*(nCols2write-1)]) = newvals;