How to generate a multi-dimensional array from a vector ?

1 view (last 30 days)
If I have a vector and a parameter m, I need to generate a m-dimensional array , where X is defined as follows:
where , , .
How do I write this code?

Accepted Answer

Steven Lord
Steven Lord on 21 Jun 2022
Let's make the 5-by-5-by-5 multiplication table.
x = (1:5).';
maxdim = 3;
% Initialize the result to the vector itself
result = x;
n = numel(x);
for dim = 2:maxdim
newsize = ones(1, dim);
newsize(dim) = n;
% Reshape x to be a 1-by-1-by-...-by n array and use implicit expansion
result = result .* reshape(x, newsize);
end
result
result =
result(:,:,1) = 1 2 3 4 5 2 4 6 8 10 3 6 9 12 15 4 8 12 16 20 5 10 15 20 25 result(:,:,2) = 2 4 6 8 10 4 8 12 16 20 6 12 18 24 30 8 16 24 32 40 10 20 30 40 50 result(:,:,3) = 3 6 9 12 15 6 12 18 24 30 9 18 27 36 45 12 24 36 48 60 15 30 45 60 75 result(:,:,4) = 4 8 12 16 20 8 16 24 32 40 12 24 36 48 60 16 32 48 64 80 20 40 60 80 100 result(:,:,5) = 5 10 15 20 25 10 20 30 40 50 15 30 45 60 75 20 40 60 80 100 25 50 75 100 125

More Answers (2)

Karim
Karim on 20 Jun 2022
Edited: Karim on 20 Jun 2022
see below for an example. i used several for loops for sake of readability
% pick the numer of dimensions e.g. 4
M = 4;
% generate 'small x' with 'M' random numbers
x = rand(M,1);
% allocate 'big X', repeat 'M' as many times as you have dimensions
X = zeros(M,M,M,M);
% loop over each dimension
for i1 = 1:M
for i2 = 1:M
for i3 = 1:M
for im = 1:M
% compute the value
X(i1, i2, i3, im) = x(i1) * x(i2) * x(i3) * x(im) ;
end
end
end
end
% have a look at the dimensions of X
size(X)
ans = 1×4
4 4 4 4
  1 Comment
shuang Yang
shuang Yang on 21 Jun 2022
Thank you for your answer, but using loops is not an appropriate approach. Because the number of loop is variable if m has changed.
I have solved the problem, but still thank you for your answer.

Sign in to comment.


DGM
DGM on 20 Jun 2022
Edited: DGM on 20 Jun 2022
I'm sure there are more elegant ways, but here's this. I'm pretty sure it works.
% inputs
m = 3;
x = [1 2 3 4 5 6 7 8 9];
idxmax = floor(sqrt(numel(x))); % assuming the arrays are square
X = 1; % initialize
% build base index array for dim 1:2
idx0 = repmat((1:idxmax).',[1 repmat(idxmax,[1 m-1])]);
idxn = idx0; % work on a copy of the index array
for km = 1:m
X = X.*x(idxn); % partial product
% permute the index array
if km<m
thisdv = 1:m;
thisdv([1 km+1]) = thisdv([km+1 1]);
idxn = permute(idx0,thisdv);
end
end
X
X =
X(:,:,1) = 1 2 3 2 4 6 3 6 9 X(:,:,2) = 2 4 6 4 8 12 6 12 18 X(:,:,3) = 3 6 9 6 12 18 9 18 27
Note that the index array is 2D. Instead of trying to create N-D index arrays, the output X grows by implicit expansion during multiplication.
  1 Comment
shuang Yang
shuang Yang on 21 Jun 2022
Maybe the answer is different from what I expected because the description of the problem is not clear enough, I have rewritten the question, but your answer inspires me that I can use permutation to solve this problem.
In fact,
where is a permutation of .
rng('default')
x = randi(10,[3 1])
x = 3×1
9 10 2
X = expand(x,2)
X = 3×3
81 90 18 90 100 20 18 20 4
X = expand(x,3)
X =
X(:,:,1) = 729 810 162 810 900 180 162 180 36 X(:,:,2) = 810 900 180 900 1000 200 180 200 40 X(:,:,3) = 162 180 36 180 200 40 36 40 8
function X = expand(x,m)
dimension_len = length(x);
expand_idx = dimension_len*ones(1,m);
expand_idx([1 2]) = size(x');
base_array = repmat(x,expand_idx);
X = base_array;
permute_vector = 1:m;
for i = 2:m
permute_idx = circshift(permute_vector,i-1);
permute_array = permute(base_array, permute_idx);
X = X.*permute_array;
end
end

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!