I would like to combine several 2-D data into 3 dimensional data. I have 124 2-D data (151 x 151) now I want to combine all these data into 3 dimensional, so that it will be like this 124 x 151 x 151. The 2-D data contains NaN elements.
To concatenate multiple 2D arrays into a 3D array, use the generalized concatenation function cat, specifying dimension 3.
For example, given 2D arrays A1,A2,... of equal size:
M = cat(3,A1,A2,...)
Say you have k 2D arrays organized in a cell array, C, where each cell is a 2D matrix, all of size M-by-N:
M = cat(3,C{:});
Then M will be of size M-by-N-by-k. Now if you want to go from M-by-N-by-k, to k-by-M-by-N, use permute or shiftdim:
Mn = permute(M,[3 1 2]); % my preference
Mn = shiftdim(M,2);
NOTE: An alternative to cat is cell2mat:
M = cell2mat(reshape(C,1,1,[]))
Related
Given a matrix A in matlab with:
3 1
4 5
7 8
and another matrix B which could be referred to as some reference points (each row is reference point that is to be compared to each row of A),
1 1
1 2
I need to compute a matrix C, such that
4 5
25 18
85 72
Where each row of C is the difference (squared L2 norm) between each row of A and the rows of B. One possible way to do this in MATLAB is to first create a zero matrix C, C = zeros(5,2), and then use double for-loops to fill in the appropriate value. Is there any other efficient/simpler way in MATLAB?
Find the code snippet below
C = zeros(5,2)
for i = 1:rows
for j = 1:rows2
C(i,j) = (norm(A(i,:)-B(j,:)))^2
end
end
A solution similar to ThomasIsCoding's, but generalized to any number of dimensions (=columns). Thomas' answer requires A and B to have exactly 2 columns to use the complex representation. Here, we use a 3rd array dimension instead of complex values:
n = 3; % number of spatial dimensions for computing the L2 norm
A = 10*rand(20,n);
B = 10*rand(4,n);
C = sum((reshape(A,[],1,n) - reshape(B,1,[],n)).^2,3)
First we reshape A, such that its rows remain rows, but its columns are arranged along the 3rd array dimension. We reshape B similarly, but its rows become columns, and its columns are moved to the 3rd dimension. This arrangement of the first two dimensions match that of the output C.
Next we take the difference (using implicit singleton expansion, for older versions of MATLAB you'd need to use bsxfun), square, and sum along the 3rd dimension.
Maybe you can try bsxfun like below
A = [3,1; 4,5;7,8];
B = [1,1;1,2];
% you can first rewrite A and B in complex coordinates to simplify the computation, and then compute difference of two complex values
C = abs(bsxfun(#minus,A*[1;1j],transpose(B*[1;1j]))).^2;
and you will get
C =
4.0000 5.0000
25.0000 18.0000
85.0000 72.0000
R comes with three types to store lists of homogenous objects: vector, matrix and array.
As far as I can tell:
vector is special cases for 1 dimension arrays
matrix is a special case for 2 dimensions arrays
array can also have any dimension level (including 1 and 2).
What is the difference between using 1D arrays over vectors and 2D arrays over matrices? Do we need to cast between those, or will it happen automagically?
There is no difference between a matrix and a 2D array:
> x <- matrix(1:10, 2)
> y <- array(1:10, c(2, 5))
> identical(x, y)
[1] TRUE
...
matrix is just a more convenient constructor, and there are many functions and methods that only accept 2D arrays (a.k.a. matrices).
Internally, arrays are just vectors with a dimension attribute:
...
> attributes(x)
$dim
[1] 2 5
> dim(x) <- NULL
> x
[1] 1 2 3 4 5 6 7 8 9 10
> z <- 1:10
> dim(z) <- c(2, 5)
> is.matrix(z)
[1] TRUE
To cite the language definition:
Matrices and arrays are simply vectors with the attribute dim and
optionally dimnames attached to the vector.
[...]
The dim attribute is used to implement arrays. The content of the
array is stored in a vector in column-major order and the dim
attribute is a vector of integers specifying the respective extents of
the array. R ensures that the length of the vector is the product of
the lengths of the dimensions. The length of one or more dimensions
may be zero.
A vector is not the same as a one-dimensional array since the latter
has a dim attribute of length one, whereas the former has no dim
attribute.
I assume that I have a 2D matrix that range from 0 to 255 (size 2x3) and a 1D matrix (size 256x1). In which, 1D matrix stores the information of 256 pixel values of 2D array. For example,
2D matrix is
[0 1 2
255 2 2]
and 1D matrix
[0 0 0.1 ....0.5]
I want to make a new 2D matrix that store the information of 1D matrix at each pixel value. We can see 2 in the 2D matrix has value is 0.1 and 255 has information values is 0.5. So I want to make a matrix such as
[0 0 0.1
0.5 0.1 0.1]
How to make that matrix by MATLAB code?
You need to index into the 1D array with the elements of the 2D array as indices. Now, MATLAB's indexing starts from 1 and you have values in the interval [0,255] in your 2D indexing array, so you need to add 1 to them before indexing. Thus, assuming array1Dand array2D as the variable names for the 1D and 2D arrays respectively, use this -
array1D(array2D+1)
Example
Let us assume some values for these two arrays as demo, shall we? Let array2D has 6 pixel values from 0 to 5 (to simulate 0 to 255 in your case) and array1D has 6 elements for each of the 6 pixels. The inputs and the code run -
array2D = [
0 1 2 ;
5 2 2]
array1D = [105 103 107 102 108 101]
out = array1D(array2D+1)
out =
105 103 107
101 107 107
Let's do the verification.
Now, array1D(1,1) was 0 and therefore out(1,1) must be the first element from array1D i.e. 105, is it? hell yeah it is!
Similarly, array1D(1,2) was 1 and thus, out(1,2) must be the second element from array1D i.e. 103, is it? YES!
...
array1D(2,1) was 5 and thus, out(2,1) must be the final element from array1D i.e. 101, is it? YES!
... check the rest of the output elements for yourself?
I have a 3X3 cell array and each element store a (x,y) point.
The point are generate by random number from [0,1].
What I want to do is sort the cell array so that it looks like following
ex: 9 points
each circle is one 2D point
index:(1,1) in the left top corner and (3,3) to the right bottom corner as the usual array index
that is to ensure the topological order.
How do I do it?
Thank in advance.
for the example
pairs = [4 9 2 6 5 1 7 8 3; 9 6 2 1 3 8 7 4 5] (row 1 = x-values, row 2 = y-values))
what I want to do is put them in the cell array so that they can be connected by read lines like the image's topology.
The number of permutations is factorial(9), which is not terribly large. So a brute-froce approach is feasible: test all permutations for your desired conditions, and pick the first that is valid.
In the following I'm using a 2x3x3 array, instead of a 3x3 cell array containing length-2 vectors, because it's much easier that way.
N = 3;
data = rand(2,N,N);
permutations = perms(1:N^2); %// generate all permutations
for k = 1:numel(permutations)
dx = reshape(data(1,permutations(k,:)),N,N); %// permuted x data
dy = reshape(data(2,permutations(k,:)),N,N); %// permuted y data
if all(all(diff(dy,[],1)<0)) && all(all(diff(dx,[],2)>0)) %// solution found
disp(dx) %// display solution: x values
disp(dy) %// y values
break %// we only want one solution
end
end
Note that for some choices of data there may not be a solution.
How to increase the size of a matrix. I have a matrix of size 36 rows and 3000 columns. I want to convert it to an array of size 200 rows and 3600 columns without affecting the information contained in the original matrix.
In any programming language you will need to create the new array and do copy of the previous elements in the new array.
If you are using java i would prefer to use Arraylist.
You can always create 2D array using arrayList in java.Something like this
ArrayList<ArrayList<Type>>
But in C/C++ you will need to do entire copy operation.
There is a way to do this using zero padding.
Assuming matrix A has p rows and q columns and you want to convert it to a matrix B having m rows and n columns (m>p and n>q). You can use
B = padarray(A,[m-p n-q],0,'post');
B will contain the matrix A and the rest of the matrix will be all zeros.
Example:
a=randi(10,[2 2]);
a =
10 10
2 9
b = padarray(a,[4-2 3-2],0,'post');
b =
10 10 0
2 9 0
0 0 0
0 0 0