applying algebraic eqns across multiple dimesions of matrix using indexing

I am "time-stepping" an electromagnetic field at time instances per frequency
The EM field value at time-zero is a 3D matrix of dimensions [nvalues x 1 x nfrequencies] (see attached)
I want to create a 4D matrix where time is the 4th dimension and apply an algebraic equation across each dimension based on the value of the variables stored in arrays [frequency] and [time]
ie
size(EM_freq_time) = [nvalues x 1 x frequencies x time]
to attempt this i create a matrix of zeros
EM_freq_time = zeros(length(Ex), length(frequencies), length(t));
the equation i must apply is
EM_value(frequency,time,phase) = value*sin(2*pi.*frequencies.*t+Phase)
where frequency is a column vector size [nfreqs, 1]
time is a column vector size [nsteps, 1]
phase is a column vector size [nvalues]
how can i apply this equation using indexing?

2 Comments

'how can i apply this equation using indexing?'
What exactly do you mean by this? Are you looking to run loops to examine different sets of values and want to index each set, or are you looking to get multiple sets at once using some kind of vector method? I would just appreciate some expansion on what exactly you're looking for.
As a side note, why do you have a 4D matrix when one of your dimensions is size one? There's nothing technically wrong with this, it just seems like making things '4D' unnecessarily complicates the problem.
Hi Thanks for your reply - i thought it would require further explanation. but i wanted to see if there were any answerers to my question first.
You are right about the dimension this can be simplied although i working with it this way in case i need to add another column of data to the base matrix.
the eqn i need to apply is this
EM_value(frequency,time,phase) = value*sin(2*pi.*frequencies.*t+Phase)
what you see with Ex.mat is the values which are calculated with an external program
Ex has values for each position and frequency.
ie size(Ex) = [npositions x 1 (column of values) x frequencies)
ie Ex(:,:,5) would be all the value for each position for frequency 5 up to frequency n.
i then need to time step this so i want to create a 4th dimension for time.
ie Ex_freq_time (:,:,1,1) would be for frequency 1 and time step 1
the values of the variables frequency and time are stored in arrays
so for example for
Ex_freq_time(:,:,2,2) would be applying the value of the 2nd element of the frequency and time array for the eqn for each row in the column which stores the time and frequency varying values
Ex(frequency,time,phase) = Ex*sin(2*pi.*frequencies.*t+Phase)
where Phase is the same length as Ex
so for each matrix in the first 2 dimesions Ex and Phase are the same length and correspond with the number of positions at which these are calculated and we apply a fixed value of freq and time based on the index which corresponds to the element of the frequency and time arrays.
so again Ex_freq_time(:,:,10,2) would use the value of the tenth element of the frequency array and the 2nd element of the time array for each row of values in the "base matrix"
so to answer your question i want to get mutltiple sets at once using some kind of vector method that corresponds to the index of the 3rd (freq) and 4th (time) dimension and uses the value for the variables of frequency and time arrays based on the indexes.
thank you!
I had something like this but i dont know how this will work based on order MATLAB works/
Ex_freq_time(:,:,5,5) = Ex(*sin(2*pi.*frequencies(5).*time(5)+Phase)
this is not correct but it is where my thoughts are currently.

Sign in to comment.

 Accepted Answer

Ok, you aren't too far off with your thoughts, but I'll include an example.
You should be able to cover the first and second dimension all at once, but because you want to look at specific values in the third and fourth dimensions you will need to loop them, as far as I know.
for i = 1:size(Ex,3) % Loop through each frequency
for j = 1:length(time) % Loop through each time value, not really sure where you're getting this from, but I'm also just setting this up as a template
Ex_freq_time(:,:,i,j) = Ex(:,:,i)*sin(2*pi*frequencies(i).*time(j)+Phase);
end
end
You may also need to index Phase (probably with i, because it matches the number of frequencies), but I wasn't entirely sure where you were getting it from. Sorry, I'm a very visual person, and this forum doesn't do pictures too well.
Let me know if you have any problems, or need clarification.

6 Comments

firstly i must say it that the speed, genuine interest and expertise with which you answered my question is commendable!
so based on your initial template this is what used
for i = 1:length(frequencies) % Loop through each frequency
for j = 1:length(time) % Loop through each time value
Ex_freq_time(:,i,j) = Ex(:,:,i).*sin(2*pi*frequencies(i).*time(j)+PhaseExDeg(:,:,i));
end
end
I added in the (.)*sin...and yes i also indexed the Phase matrix - (size(phase) = size(Ex))
i changed the first line to
i = 1:length(frequencies)
frequencies and time are pre-defined ie time = [0:1:360] - length(time) = 361
and i have a list of unique 20 frequencies.
so size(Ex_freq_time) = (length(Ex) x 20 x 361)
It appears this is working I will do some plots to confirm.
ie the values for the Em feild are for positions in an XY plane.
so for each "base" matrix at each time and frequency ie will make a contour plot.
and then combine each plot (for each time-step) into a movie.
any tips on how to do that?
this is how i do the contour plots
X_VAR = RXlist; %co-ords for X and Y
Y_VAR = RYlist;
Z_VAR = Ex_freq_time(:,1,50); % ie for frequency 1, time step 50
%Transpose column vectors
XX = X_VAR.';
YY = Y_VAR.';
ZZ = Z_VAR.';
%combine X, Y, Z rows into row matrix
XYZ_rows = [XX;YY;ZZ];
%transpose row matrix into *.XYZ FORMAT
XYZ = XYZ_rows.';
%Reshaping .XYZ data for contouring in MATLAB
%MATLAB contours requires matrices of dimension X*Y for X,Y,Z
D = XYZ;
[Du,D1] = unique(D(:,1));
Dd = diff(D1);
Dr = reshape(D, Dd(1), [], size(D,2));
X = Dr(:,:,1);
Y = Dr(:,:,2);
Z = Dr(:,:,3);
figure
contourf(X, Y, log10(Z))
hold on
title('Total Electric Field');
xlabel('Distance East-West (m)');
ylabel('Distance North-South (m)');
h = colorbar;
ylabel(h, 'log10(Total Electric Field (V/Am^2)')
how could i batch generate plots for each index of time?
and then take successive plots (for successive time-steps) and combine them into a movie in MATLAB. I dont want to do some ad-hoc image export and use an external program. I want to learn the proper way to do this in MATLAB
again thank you for such incredibly detailed help and speed in your answers!!!
I am blown away by being able to access such high-level help
First, be careful using length(Ex) with a multidimensional array, as the length command picks the largest dimension, not necessarily the first. It is prudent to use size(Ex,1) to specify the first dimension in these cases.
Next, just looking at a minor thing I noticed, it shouldn't affect the fuction of the code, just a preference for writing it.
X_VAR = RXlist; %co-ords for X and Y
Y_VAR = RYlist;
Z_VAR = Ex_freq_time(:,1,50); % ie for frequency 1, time step 50
%Transpose column vectors
XX = X_VAR.';
YY = Y_VAR.';
ZZ = Z_VAR.';
%combine X, Y, Z rows into row matrix
XYZ_rows = [XX;YY;ZZ];
%transpose row matrix into *.XYZ FORMAT
XYZ = XYZ_rows.';
%Reshaping .XYZ data for contouring in MATLAB
%MATLAB contours requires matrices of dimension X*Y for X,Y,Z
D = XYZ;
This can all be shortened into one line. Only reason I can see to keep it log like the above is for the sake of clarity of steps.
D = ([RXlist,RYlist,Ex_freq_time(:,1,50)]);
For the plots themselves, I know that it is possible to generate multiple plots at once with plot():
plot(A(:,1),A(:,2:end)); % Plot columns against first column
But because you are looking to use each 'sheet' of your array to plot each figure you may be stuck with running a for loop.
for i = 1:size(Ex_freq_time,3)
figure(i)
contourf(X, Y, log10(Z))
end
I think the rest of your stuff, defining D and such, will also need to be in the loop, but I don't feel it is necessary to show that here.
For making a slideshow out of the figures I am not personally an expert with how to do this, but I suggest looking up getframe, writevideo, and videowriter. These commands will also likely be added to your for loop.
1 i use length(frequencies) for the loop as this will always only ever be a column vector
2. for some reason i thought everything had to be in rows.
combining the column vectors it much simpler than i thought. - thanks for that!
3. this is what i did to loop generate the images across the time slice with the simplified data structuring. everything works perfeclty!
for i = 1:size(ETotal,3)
X_VAR = RXlist; %co-ords for X and Y
Y_VAR = RYlist;
Z_VAR = ETotal(:,1,i); %
XYZ = ([X_VAR,Y_VAR,Z_VAR]);
D = XYZ;
[Du,D1] = unique(D(:,1));
Dd = diff(D1);
Dr = reshape(D, Dd(1), [], size(D,2));
X = Dr(:,:,1);
Y = Dr(:,:,2);
Z = Dr(:,:,3);
figure(i)
contourf(X, Y, log10(Z),10)
hold on
title('Total Electric Field');
xlabel('Distance East-West (m)');
ylabel('Distance North-South (m)');
h = colorbar;
ylabel(h, 'log10(Total Electric Field (V/Am^2)');
end
so it should be easy now to generate a movie after i read the docs on those functions.
thanks!!!!
so for storing each figure capture to a F and then playing a movie of this i did this and it works correctly.
for i = 1:size(ETotal,3)
X_VAR = RXlist; %co-ords for X and Y
Y_VAR = RYlist;
Z_VAR = ETotal(:,1,i); %
XYZ = ([X_VAR,Y_VAR,Z_VAR]);
D = XYZ;
[Du,D1] = unique(D(:,1));
Dd = diff(D1);
Dr = reshape(D, Dd(1), [], size(D,2));
A = Dr(:,:,1);
B = Dr(:,:,2);
C = Dr(:,:,3);
figure(i);
contourf(A, B, log10(C),10);
% hold on
% title('Total Electric Field');
% xlabel('Distance East-West (m)');
% ylabel('Distance North-South (m)');
% h = colorbar;
% ylabel(h, 'log10(Total Electric Field (V/Am^2)');
F(i) = struct('cdata',[],'colormap',[]);
F(i) = getframe;
end
close all
movie(F,5)
now i will figure out how to write this as a video file.
I believe the videowriter command allows you to save the video variable to an appropriate file.
thanks. ill get it working and show you the result which i achieved due to your help :)

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!