How to set an array identifier within code

Hi,
I am trying to write a snippet that takes an input array of any size (I will refer to it as A with N dimensions) and a column or row vector v, that returns an array B having N+1 dimensions, which elements along the (N+1)th dimension are the products A*v(i) (where v(i) are the individual scalar elements in v).
If A is a 2D matrix, it can be done this way:
A=rand(4,5);
v=rand(1,3);
B=zeros([size(A) length(v)]);
for k=1:length(v)
B(:,:,k)=v(k)*A;
end
This works fine but since I need to write as many ' : ' as there are dimensions in A, this is not very versatile.
So I am looking for a way to change this argument as the code executes to adapt to the number of dimensions in A. I have tried the following:
A=rand(4,5);
v=rand(1,3);
bit=sprintf(':,'); %Define the string element to be repeated N times in the argument
arg=bit; %Initiate the argument string
for c=1:(length(size(A))-1)
arg=strcat(arg,bit) %Concatenate as many times as necessary
end
arg=strcat(arg,'k') %Append with the letter k
%In this example, arg is ':,:,k'
B=zeros([size(A) length(v)]);
for k=1:length(v)
B(arg)=v(k)*A;
end
But it doesn't work...

 Risposta accettata

Guillaume
Guillaume il 29 Mar 2019
Modificato: Guillaume il 29 Mar 2019
Trying to build the indices as text is never going to be efficient. What you want can be trivially obtained:
%A: an N-d matrix
%v: a vector
%B: an (N+1)-d vector where B(..., k) = B(...) .* v(k). Dimensions 1:N have same size as A, dimension N+1 is numel(v)
B = A .* reshape(v, [ones(1, ndims(A)), numel(v)]); %move v in the N+1 dimension and multiply

4 Commenti

I think I see where you're coming from but I get a "Matrix dimensions must agree" error with the elementwise multiplication...
B = bsxfun(@times,A,reshape(v, [ones(1, ndims(A)), numel(v)]));
Up there, in the right corner of the webpage there's a field for you to enter the version of matlab that you're using. It's important to fill out if you're on an old version.
My guess is that you're using a version prior to R2016b which does not have implicit expansion. In that case,
B = bsxfun(@times, A, reshape(v, [ones(1, ndims(A)), numel(v)])));
The code in my answer is guaranteed to never generate a Matrix dimensions must agree error in R2016b and later.
Oh alright, sorry about that, the computer I'm using is indeed running on R2016a. Thanks a million to both of you!

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Operators and Elementary Operations in Centro assistenza e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by