Two for loops (nested), computing matrices Matlab - matlab

my current code is below.
What I have is two sets of data phi and theta both 18x30 and I have a for loop running from 1 to 30 which are the 30 columns of my data. Each of these individual columns will produce a matrix 'B' for me. The matrix 'B' is produced after going through the 18 rows of each column.
The problem I have is that I need to multiply all the resulting 'B' matrices for each of the 18 rows with each other in order to get a final matrix for each of the 30 columns, that is why I have set A(:,:,i) = eye(2) so that my first matrix will multiply by A. But I don't want to store A or B for each loop, instead what I want is that on the first loop of i my matrix B will multiply the identity matrix A. Then that matrix A will multiply the next matrix B...with the result of each multiplication being carried forward to the next matrix B that will be calculated, so the multiplications will get done as the program loops. That's why I have the line:
A(:,:,i) = A.*B;
but it doesn't seem to work. I get an error message saying the dimensions must match.
At the end of the program I want to be able to access each of the 30 matrices using a command like:
A(:,:,3), for example, to get my 2x2 matrix for the 3rd column.
Hope that was clear enough!
theta = dlmread('theta.dat');
phi = dlmread('phi.dat');
ne = 1.7;
no = 1.5;
d = 0.000001;
w = 0.000000555;
for i = 1:30
A(:,:,i) = eye(2);
for j = 1:18
nx =((cos(theta(j,i)).^2)/(no^2) + ((sin(theta(j,i)).^2)/(ne^2))).^(-1/2);
D = (2*pi*(nx-no)*d)/w;
x = ((cos(phi(j,i))).^2).*exp((-1i.*D)/2) + ((sin(phi(j,i))).^2).*exp((1i.*D)/2);
y = 1i*(sin(D/2)).*sin(2*phi(j,i));
z = ((cos(phi(j,i))).^2).*exp((1i.*D/2) + ((sin(phi(j,i))).^2).*exp((-1i.*D)/2));
B = [x y;y z];
A(:,:,i) = A.*B;
end
end

B is a 2x2 matrix. For A.*B to work, A must also be 2x2. But A in your program is three-dimensional.
From your problem description, I think you want
A(:,:,i) = A(:,:,i)*B; % Edited now that I see this happens 18 times on the same i
(Please note, I also replaced element-wise multiply .* with matrix multiply *, because that's what it sounds like you want.)
But I suggest
A = eye(2);
and
A = A*B;
and store it at the end like
results(:,:,i) = A;

Related

Multiplying non-zeros values of two matrices

I have two matrices multiplied with each other H.Z where both matrices H and Z have the same size of (256,256). Matrix Z is permutation matrix has the following pattern: In the first 32 rows, only columns 1,9,17,...(256-8) are non-zeros, other columns are zeros, next 32 rows, only columns 2,10,18,...(256-7) are non-zeros, other columns are zeros and so on till the last 32 rows, where columns 8,16,24,....,256 are non-zeros and other columns are zeros.
Therefore, multiplying matrix H with Z includes only multiplying the first 32 elements of first row in H with the first 32 element of column 1 of matrix Z, then next 32 element of first rows of matrix H with next 32 element (33-64 elements) of column 2 in matrix Z and so on. because all other multiplications will result of zero. So in that way, the number of multiplication will be less.
My question, I couldn't write that in Matlab !! I don't know how create the loop to go through only the non-zeros elements. Could you please help in that?
Thank you in advance.
For loops are generally much slower than inbuilt MATLAB operations. A better options is to multiply only the nonzero elements of Z using the following approach.
result = zeros(256,256);
result(Z ~= 0) = H(Z ~= 0) .* Z(Z ~= 0);
You can see the complete code below, running a test to make sure it gets the right answer, and timing the code to see if it's faster.
% setup variables
H = rand(256,256);
Z = zeros(256,256);
for i = 1:8
Z((i-1)*32+1:i*32, i:8:256) = 1;
end
% run calcuations and check that they are equal
HZ1 = f1(H, Z);
HZ2 = f2(H, Z);
are_equal = all(all(HZ1 == HZ2));
% time both functions
timeit(#() f1(H,Z))
timeit(#() f2(H,Z))
function result = f1(H, Z)
result = H .* Z;
end
function result = f2(H, Z)
result = zeros(256,256);
result(Z ~= 0) = H(Z ~= 0) .* Z(Z ~= 0);
end
Timeit results:
f1 - 6.875835e-05 s
f2 - 0.0008205853 s
Unfortunately, the new approach is about 12 times slower than just multiplying the matrices elementwise. This is because MATLAB is heavily optimised for matrix multiplication, and multiplying the complete matrices H and Z ensures the memory to be operated on is contiguous.

Perform element wise multiplication of vectors efficiently?

I have to perform matrix updating by M = M + c*a*a' large number of times, where c is a constant and a is a column vector. If the size of matrix is larger than 1000, this simple updating will cost most of the time of my function, typically more than 1 min counted by profile.
Main codes are:
for i = 1:N
_do something..._
for k = 1:n
a(1:k) = M(1:k,1:k)*p(1:k);
M(1:k,1:k) = M(1:k,1:k)+c*a(1:k)*a(1:k)';
M(1:k, k+1) = b(1:k);
M(k+1, 1:k) = b(1:k)';
M(k+1, k+1) = x;
......
end
end
I have preallocated all variables, column vectors p and b are known, and x is another constant.
As I have large number of data to process by this function, does there exist more efficient alternative to this matrix updating?
You can concatenate a vectors to create a matrix A then apply multiplication just one time.
A =[a1 a2 a3];
M = c * A * A.';
consider the example
A = rand(5,5);
M = 0;
c=4;
for n = 1:5
M = M + c * A(:,n) * A(:,n).';
end
and this one
M1 = c * A * A.'
both M and M1 are equal
Have you tried using bsxfun?
In any case, bsxfun is much faster than regular multiplication, but the vectors/matrices have to be of equal length (which they are for you, aren't they?), and it's operating elementwise (i.e. a Nx1 vector bsx-multiplied with itself yields a Nx1 vector, multiplied with the transpose however yields a NxN matrix).
see https://mathworks.com/help/matlab/ref/bsxfun.html
use as
bsxfun(#times, a, a')

Filling in a Cell of Matrices in MATLAB

In Matlab I am trying to create a cell of size 16 x1 where each entry of this cell is a matrix. I have the following equation
$$W_g = exp^{\frac{j{2\pi m}{N}(n+\frac{g}{G}))} \,\,\,\,\,\,\, m,n=0,1,.....(N-1)$$
for this work assume $N=4$ and the index $g$ is the index that refers to the cell element i.e g=0:1:15
W=cell(16,1);
for g=1:16
for m=1:3
for n=1:3
W{g,m,n}= exp((2*pi*j*m/4)* n+(g-1)/16));
end
end
end
How can I make this work? I have two problems with this, you see g starts from 0 and MATLAB doesnt accept index of zero and how to actually define the matrices within the cell.
Thanks
So if I understand you have this equation:
And you just want the following code:
W=cell(16,1);
n = 1:3;
m = 1:3;
N = 4;
for g=1:16
W{g}= exp((2*pi*j.*m/4*N).*n+(g-1)/16);
end
%or the 1 line version:
W = cellfun(#(g) exp((2*pi*j.*m/4*N).*n+(g-1)/16),num2cell([1:16]),'UniformOutput',0);
With matlab you can use the Element-wise multiplication symbol .*
For example:
%A matrix multiplication
A = [2,3]
B = [1,3]';
result = A * B %result = 11
%An element wise multiplication
A = [2,3]
B = [1,3];
result = A .* B %result = [2,9]
First of all, i is the complex number in matlab (sqrt(-1)) not j, and you are correct, matlab is indexed in 1, so simply start counting g at 1, until 16.
Next, create a zero matrix, and calculate all indices accordingly. Something like this should work just fine :
clc
clear all
W=cell(16,1);
for g=1:16;
temp = zeros(3,3);
for m=1:3
for n=1:3
temp (m,n) = exp((2*pi*1i*m/4)* n+g/16);
end
end
W{g} = temp;
end
if you are considering doing much larger operations, consider using linspace to create your m and n indices and using matrix operations

Create vector of inner vectors with elementwise subtracted elements for plotting (Matlab)

I am running a program where at each time loop I obtain a N dim. vector v(t).
At the end of the program, I want to obtain a vector (or array?) which contains vectors from each iteration that is created by taking each element of v(t) and subtracting it will all other elements. However I am only interested in the absolute difference of the elements.
Therefore, if I let u denote the vector with subtracted elements at some arbitrary iteration, I want for instance that u(1)(t_0) = v_1(t_0) - v_2(t_0) but I don't also need u(k) = v_2(t_0) - v_1(t_0) for some index k
At each iteration t I also create a time vector Time(end+1) = t.
At the end I obtain a vector of vectors: [u_1, u_2, u_3,...] and a time vector Time = [t_1 , t_2 , ...] and I want to plot [u_1(i), u_2(i) , ...] against Time for all i in the same plot.
Here is a small example:
T = 400
dt = 1e-1
u = [];
Time = [];
v = [0; 0; 0; 0;];
for t = 0:dt:T
v = v + func(t)
Y = subtractFunc(v) % I am looking for help to create this subtractFunc..
Time(end+1) = t;
u(end+1) = Y;
end
% ... And help to create the properplot command, below code not appropriate
plot(u,Time)
To sum it up: How do I create subtractFunc (or a some inline command) that takes creates a new vector Y containing the absolute difference between each pair of elements in v?
And how do I then go about and plot all the differences in u at each time against the time vector Time?
You can use MATLAB diff to take pairwise differences, then take the absolute value:
>> v = [1 3 6 -2 6]; %% random values
>> diff(v)
ans =
2 3 -8 8
>> abs(diff(v))
ans =
2 3 8 8

Matlab d-dimensional multipication table?

I'm new to Matlab and I'm trying to solve a problem that involves creating a d dimensional multiplication table where each edge goes from 1 to n. The problem statement says that inputting d = 0 should return the number 1 and d = 1 should return a column vector with the elements 1 to n.
Ideally, I would just create a matrix of 1 to n along d dimensions and then iterate through for each element setting it equal to the product of the indices, but I don't know how to create the d dimensional matrix.
Can anyone help me with this problem?
You can create the table with repeated use of bsxfun. At each iteration, the vector 1,2,...,n is shifted to a new dimension and multiplied (with singleton expansion) by the previous result.
%// Data
d = 3;
n = 10;
%// Computations
vector = (1:n).'; %// first dimension: column vector
result = 1; %// initialization
for n = 1:d
result = bsxfun(#times, result, vector); %// new dimension
vector = shiftdim(vector,-1); %// shift to the next dimension
end