This question already has answers here:
Three-dimensional array
(2 answers)
Closed 8 years ago.
I want to create a matrix of arrays. So, I want an a-by-b matrix, where each element M(i,j) is actually a single column array. This would be the equivalent of a three-dimensional array in C.
The only solution I can see in Matlab, is by creating a three-dimensional matrix. However, the third dimension is yet another matrix, rather than a column array.
What's the solution?
Like CST-Link said, and you can add squeeze() :
M = randi(3, [4,5,6]);
v = squeeze(M(1,3,:))
Using cell array handles a 3rd dimension with variable length. But if they all have the same length, I would use a 3-D matrix (less memory overhead, and you can take a vector easily from any dimension).
3D matrix in Matlab may work very well, and you can extract the vectors like this:
M = ones(4,5,6); % 4x5 matrix of 6-element vectors
V = M(2,3,:) % the vector on position (2,3)
A more flexible solution, though with a tiny penalty in data access speed, would be a cell array:
M = repmat({ones(6,1)}, 4, 5); % 4x5 cell array of 6-element vectors
V = M{2,3} % the vector on position (2,3)
Related
Hello I am trying to create a simple array that contains a '10' 3x3 matrices. So I tried to create a 1D matrix that has 1 x 10 values. Then I tried assigning a 3x3 matrix in to each of the 10 slots in the 1D matrix. I am quite sure my syntax is wrong and matlab (I don't think allows this) but I couldn't find too much info to pre assign such array and I just started learning about matlab. Here is my attempt:
big_array = zeros(1,10) # creates 1x10 1d array
for i = 1:10
big_array(i) = zeros(3,3); #supposedly? assign 3x3 matrix in to each of the 10 slots
end
big_array # received an error
If you know that you want an array of 10 3x3 matrices, you would typically want to use a multidimensional array from the start.
big_array = zeros(10,3,3);
You can access the i'th matrix using big_array(i,:,:).
If you really do want a one-dimensional array of 3x3 matrices, you need to use a cell array.
big_array = {};
for i = 1:10
big_array{i} = zeros(3,3);
end
big_array
You can now access the i'th matrix using big_array{i}.
A small clarification - If all your slots must contain submatrices with the same size, then you can use very simple expression:
big_array = zeros(3,3,10) % (first dimension - rows, second dimension - columns, third dimension - bands or arrays)
I have a matrix in Matlab and I want to remove some columns from it. I have also a vector with the indices that I want to remove. How exactly I can do so?
train_data % My input matrix with size 1500x773
toremove % 1x773 logical vector values (0,1), 1 at 40 indices
How can I apply toremove to the train_data to remove the desired indices?
output = train_data(toremove) % I want the output to be a matrix with size 1500x733
If your array is truly logical (true/false) you can use it directly for indexing, it sounds like it's binary though (0/1), so you can use logical(toremove) to convert it to logical, then it's simple:
train_data = train_data(:,~logical(toremove));
% or equivalently
train_data(:, logical(toremove)) = [];
Avoiding a call to the find function will increase speed.
If you wish to delete columns in 2d matrix based off 1d column matrix:
output = train_data(:,find(toremove<1));
If it's rows that need deleting instead, based off 1d row matrix:
output = train_data(find(toremove<1),:);
Might do the job if I understand this correctly.
In matlab, I have a matrix and index vector v (in real problem, v vector is very long)
A = [1,2,3;4,5,6;7,8,9]; % 3-by-3 matrix
v = [1,2,3,2,3,3,1]
How can I generate a matrix like
[A(1,:);A(2,:);A(3,:);A(2,:);A(3,:);A(3,:);A(1,:)]
without using loop or write out everything explicitly?
You can use vectors to index, A([1,1,1]) would give you three times the first element.
A(v,:)
I have a vector created from linspace between specific numbers and have dimensions of 1*150. Now i want to multiply each element of the above created vector with another vector whose dimension is 1*25. The detail of my code is given below
c_p = linspace(1,.3*pi,150);
c = c_p';
C = zeros([150,25]);
for i= 1:1:size(C,1)
wp= c(i);
for n= 1:25
c_wp(n) = cos(n*wp);
end
C(i,25)= c_wp;
end
The vector is actually a multiple of cosine of length 25 and here wp is the elements of first vector of dimension 1*150. SO by the logic, I must have an output of 150*25 but instead giving me "subscripted assignment dimension mismatch". Any help would be appreciated, as i am new to matlab.
To multiply each element of a row vector a with each element of another row vector b, we can use linear algebra. We transpose a to make it a column vector and then use matrix multiplication:
a.' * b
That way you don't even need a for loop.
I have a 512x512 image , which i made 4x4 block for entire image, then i want access the (3rd row , 3rd element) of the all indivial 4x4 matrices and add it to the index values, which i obtained. Please help me on below code.
[row col] = size(a);
m = zeros(row,col);
count = [(row-4)*(col-4)]/4;
outMat = zeros(4,4,count);
l = 0;
for i=2:4:row-4
for j=2:4:col-4
l = l + 1;
outMat(:,:,l) = double(a(i-1:i+2,j-1:j+2));% for each matrix i have to find(3rd row,3rd element of each matrix.
end;
end;
Adding the (3rd row,3rd element):
m(i,j) = sum(sum(a .* w)); %index value of each 4x4 matrix % w = 4x4 matrix.
LUT = m(i,j)+ outMat(3,3);%(3rd row,3rd element each matrix should be added to all m(i,j) values. In which i fail to add all(3rd row,3rd element) of all 4x4 matrices.
I am going to reword your question so that it's easier to understand, as well as allowing it to be easy for me to write an answer.
From your comments in Kostya's post, you have two images img1 and img2 where they are decomposed into 4 x 4 blocks. outMat would be a 3D matrix where each slice contains a 4 x 4 block extracted from img1. From this, you have a matrix m that stores a weighted sum of 4 x 4 blocks stored outMat.
Next, you'll have another matrix, let's call this outMat2, which also is a 3D matrix where each slice is a 4 x 4 block extracted from img2. From this 3D matrix, you wish to extract the third row and third column of each block, add this to the corresponding position of m and store the output into a variable called LUT.
All you have to do is extract a single vector that slices through all of the slices located at the third row and third column. You would then have to reshape this into a matrix that is the same size as m then add this on top of m and store it into a variable called LUT. Bear in mind that if we reshape this into a matrix, the reshaping will be done in column major format, and so you would stack the values by columns. Because your blocks were created row-wise, what we need to do reshape this matrix so that it has size(m,2) rows and size(m,1) columns then transpose it.
Therefore:
vec = outMat2(3,3,:);
vec = vec(:); %// Make sure it's a 1D vector
m2 = reshape(vec, size(m,2), size(m,1)).';
LUT = m + m2;
LUT will contain a 2D matrix where each element contains the weighted sum of the 4 x 4 blocks from img1 with the corresponding third row, third column of each block in img2.
Next time, please update your question so that you have all of the information. We shouldn't have to dig through your comments to figure out what you want.
I think you can do just
LUT = sum( sum( a(3:4:row,3:4,col) * w(3,3) ) );