Creating Multi Dimesnional Array from 1D array in Matlab? - matlab

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)

Related

Calculation between 2 vectors where one is 4d and other is 1d

I am using Matlab 2018b. One problem has emerged when I am working with 2 vectors. One is of 4d form and other is of 1d form. I would like to subtract the value of a vector from the values of the other vector.
Idea:
I need to run a loop upon the vector A and vector B. Inside the loop I'll obtain the value of the vector A and subtract a value of the corresponding index from B
But, I would like to solve the problem in a more MATLAB way rather than procedural way. Can you please guide me for this?
Example:
A=[val(:,:,1,1)
= 0.67
val(:,:,2,1)
=0.55
val(:,:,3,1)
=0.12
val(:,:,1,2)
= 0.12
val(:,:,2,2)
=0.50
val(:,:,3,2)
=0.11
]
B=[1
0]
The operation would be like this one
Result=[
val(:,:,1,1) =0.67-1
val(:,:,2,1) =0.55-1
val(:,:,3,1) =0.12-1
val(:,:,1,2) =0.12-0
val(:,:,2,2) =0.5-0
val(:,:,3,2) =0.11-0
]
thanks,
In order to avoid using permute you can use two tricks:
Implicit expansion
Singleton dimension
If you want to substract a 1D matrix to a 4D matrix the problem is that matlab doesn't know on which dimension the substraction should be applied.
But matlab allows you to create a matrix with singleton dimension for example a matrix 1x1x1x2 can be created.
Here is an example:
% Creation of the 4D matrix
A = rand(3,4,5,2);
% Creation of another 4D matrix but with 3 singleton dimension
B = [1,0];
B = reshape(B,1,1,1,2);
% ↑
% 4th dimension
%Now matlab know that the substraction should be applied on the 4th dimension.
X = A-B;
Another example:
% Creation of the 4D matrix
A = rand(3,4,2,5);
% Creation of another 4D matrix but with 2 singleton dimension
B = [1,0];
B = reshape(B,1,1,2); %could also be written reshape(B,1,1,2,1)
% ↑
% 3th dimension
%Now matlab know that the substraction should be applied on the 3th dimension.
X = A-B;

Remove columns from matrix by logical array: Matlab

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.

Matrices with different size element-by-element comparison

I have two matrices, but with different size.
Right now I'm doing the comparison like this:
ABV = zeros(5,5);
ABB = zeros(4,1);
for ii = 1:4
test = ABV > ABB(ii)
end
I'm trying to find a vectorized method that would do the same thing, as my matrices are not that small. I tried to use BSXFUN, however it asks for same dimension matrices.
You need to use permute there to "send" the elements of ABB to the third dimension creating singleton dimensions in dim-1 and dim-2. Thus, the final result after applying bsxfun (for singleton expansion) would be an expanded 3D array covering the comparisons for each element of the 2D array ABV against each element of 1D array ABB. So, do something like this -
test = bsxfun(#gt,ABV,permute(ABB(:),[3 2 1]))
Thus, each 3D slice of test would be the comparison of all elements of ABV against one of the elements in ABB.
Since ABB is a 1D array, you can replace permute with reshape -
test = bsxfun(#gt,ABV,reshape(ABB,1,1,[]))
You can avoid using bsxfun at the third dimension by converting the input 2D array to a 1D array and this might lead to a more efficient approach as listed here -
test = reshape(bsxfun(#gt,ABV(:),ABB(:).'),[size(ABV) numel(ABB)])

Matrix of Arrays [duplicate]

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)

Put elements of a 1D vector into a 3D matrix using another matrix of positions

I have a vector of data points which were saved from a 3D array by some other program in one big list. The vector is nk elements long. nk = nx*ny*nz where nx, ny and nz are the dimensions of the original 3D array.
The position of a data point in the original array is stored in a (nk x 3) array, arranged with each row (position(k,:)) giving the (i,j,k) position of the corresponding data point.
I can't use reshape on my data array as the position vector is not simple (it depends on some stuff to do with how the data was generated - it isn't completely random - but I won't necessarily know what it looks like beforehand).
If the nk vector is called 'data', the nk x 3 position array is called 'position' and the output array is called 'data_reshaped' then currently I am doing the following:
for k = 1:nk
data_reshaped(position(k,1),position(k,2),position(k,3)) = data(k);
end
This is really slow - is there some faster method without knowing much about what 'position' looks like?
You could use sub2ind function:
data_reshaped = zeros(nx, ny, nz);
data_reshaped( sub2ind([nx ny nz], position(:,1), ...
position(:,2), ...
position(:,3)) ) = data;