I wrote the below code to calculate the multilayer reflection, each time the new matrix should be multiplied from the left side to give the final matrix. When I plot it, it only gives the final value and doesn't calculate former data, so the graph is uniform.
Thanks in advance
%This program is for calculating the total reflection from multilayer of
%epidermis-dermis-blood by considering air as the initial medium
clc;
l=(0.3:0.03:3).*1.0E-3;%milimeter
e_inf=[1.0,3.0,5.5,2.1,1.0]; %Air-Epidermis-Dermis-Whole Blood_air(for reflection)
e_1=[1.0,58,58,130,1.0];
e_2=[1.0,3.6,5.6,3.8,1.0];
t_1=[0.1,9.4,9.4,14.4,0.1]*(1.0E-12);
t_2=[0.1,0.18,0.18,0.1,0.1]*(1.0E-12);
d=[2,0.2,0.002,0.05]*1.0E-3; %Thickness of air-epidermis-dermis-blood
Q=zeros(length(l),5);
for x=1:1:length(l)
M_TOT=ones(2,2);%for matrix calculation
l_0=l(x); %wavelength
w=((2*pi)*(3.0E8))./l_0; %angular frequency
for z=1:1:4 %Four matrices should be calculated
Z=z+1; %each time two refractive indices should be calculated
%%%% refractive index%%%
epsilon_r_z=e_inf(1,z)+((e_1(1,z)-e_2(1,z))./(1+(w.*t_1(1,z)).^2))...
+((e_2(1,z)-e_inf(1,z))./(1+(w.*t_2(1,z)).^2));
epsilon_im_z=((e_1(1,z)-e_2(1,z)).*(w.*t_1(1,z)))./(1+(w.*t_1(1,z)).^2)...
+((e_2(1,z)-e_inf(1,z)).*((w.*t_2(1,z)))./(1+(w.*t_2(1,z)).^2));
n_1_z=sqrt((sqrt((epsilon_r_z).^2+(epsilon_im_z).^2)+epsilon_r_z)./2);
n_2_z=sqrt((sqrt((epsilon_r_z).^2+(epsilon_im_z).^2)-epsilon_r_z)./2);
n_z=n_1_z-1j*n_2_z; %Refractive Index of first layer
epsilond_r_Z=e_inf(1,Z)+((e_1(1,Z)-e_2(1,Z))./(1+(w.*t_1(1,Z)).^2))...
+((e_2(1,Z)-e_inf(1,Z))./(1+(w.*t_2(1,Z)).^2));
epsilond_im_Z=((e_1(1,Z)-e_2(1,Z)).*(w.*t_1(1,Z)))./(1+(w.*t_1(1,Z)).^2)...
+((e_2(1,Z)-e_inf(1,Z)).*((w.*t_2(1,Z)))./(1+(w.*t_2(1,Z)).^2));
n_1_Z=sqrt((sqrt((epsilond_r_Z).^2+(epsilond_im_Z).^2)+epsilond_r_Z)./2);
n_2_Z=sqrt((sqrt((epsilond_r_Z).^2+(epsilond_im_Z).^2)-epsilond_r_Z)./2);
n_Z=n_1_Z-1j*n_2_Z; %Refractive Index of second layer
phi_z=(n_z).*(2*pi/l_0).*d(1,z);%Phase
r_TE_21_z=(n_Z-n_z)./(n_Z+n_z); %For simplicicty
M_TE_z=[exp(-2j*phi_z) r_TE_21_z; r_TE_21_z.*exp(-2j*phi_z) 1]; %Matrix
M_TOT=M_TE_z*M_TOT; %Total Matrix
end
Final= y_1*M_TOT; %Final Result
der_1=-Final(2,1); %2*1
der_2=Final(2,2); %2*2
r_12=(der_1)./(der_2);%r_12
Ref=abs(r_12).^2; %R
Q(x,1)=l_0*1.0E3;
Q(x,2)=Ref;
end
plot(Q(:,1),Q(:,2))
title('Multilayer Reflection','Fontsize',14)
set(gcf,'color','w');
ylabel('Reflection','Fontsize',14)
xlabel('\lambda(mm)','Fontsize',14)
Related
I am trying to solve the 2D time dependent heat equation using finite difference method in Matlab. The code is below:
%Spatial variable on x direction
Lx=1;
delta=0.1;
xmin=-Lx/2;
xmax=Lx/2;
Nx=(xmax-xmin)/delta;
x=linspace(xmin,xmax,Nx);
%Spatial variable on y direction
Ly=1;
delta=0.1;
ymin=-Ly/2;
ymax=Ly/2;
Ny=(ymax-ymin)/delta;
y=linspace(ymin,ymax,Ny);
%Total matrix size
N = (Nx * Ny);
%Time variable
dt=0.002;
tmin=0;
tmax=1;
nt=(tmax-tmin)/dt;
tspan=linspace(tmin,tmax,nt);
%Create a meshgrid
[X,Y] = meshgrid(x,y);
% Defining initial state:
T0=exp(-(X.^2+Y.^2));
%reshape the initial condition to a vector
T_reshape = reshape(T0,N,1);
% Constructing the 1D spatial matrix
A=zeros(N,N);
I = eye(N);
%the diagonal elements
for m=1:N %the number of rows
for n=1:N %the number of columns
if (m==n)
A(m,n)=-2/delta^2;
end
%Boundary conditions: A(1,N)==A(N,1)
if(n==N)&&(m==1)
A(m,n)=1;
end
if(n==1)&&(m==N)
A(m,n)=1;
end
end
end
%the off-diagonal elements
for n=1:N-1
A(n+1,n)=1/delta^2; %the value of each lower off-diagonal elements
end
for n=2:N
A(n-1,n)=1/delta^2; %the value of each upper off-diagonal element
end
%create the 2D matrix
B = kron(A,I)+kron(I,A);
% Solve the equation
[Time,Tem]=ode45('dTDistribution',tspan,T_reshape,[],B,delta);
The function that is being called here is as following:
%Define the function
function dT=dTDistribution(tspan,T_reshape,dummy,B,delta)
dT = B.*T_reshape;
end
My problem is that the dimension of my matrix B is different than the dimensions of the initial condition T_reshape, therefore, the multiplication of B.*T_reshape won't be possible. I'm wondering how can I change the dimension of T_reshape to make the multiplication valid. Hope anyone could help.
Thank you.
Thank you for looking at my problem, but I have figured out the mistake in the code. Since A is the 1D matrix, then its size should be either (Nx,Nx) or (Ny,Ny) and then when taking the tensor product to get B the 2D matrix its size will be (N,N). However in the code, A has the size of (N,N) and as a result B is blowing up making the multiplication afterwards not possible.
Thanks.
What are the difference between the following two functions?
prepTransform.m
function [mu trmx] = prepTransform(tvec, comp_count)
% Computes transformation matrix to PCA space
% tvec - training set (one row represents one sample)
% comp_count - count of principal components in the final space
% mu - mean value of the training set
% trmx - transformation matrix to comp_count-dimensional PCA space
% this is memory-hungry version
% commented out is the version proper for Win32 environment
tic;
mu = mean(tvec);
cmx = cov(tvec);
%cmx = zeros(size(tvec,2));
%f1 = zeros(size(tvec,1), 1);
%f2 = zeros(size(tvec,1), 1);
%for i=1:size(tvec,2)
% f1(:,1) = tvec(:,i) - repmat(mu(i), size(tvec,1), 1);
% cmx(i, i) = f1' * f1;
% for j=i+1:size(tvec,2)
% f2(:,1) = tvec(:,j) - repmat(mu(j), size(tvec,1), 1);
% cmx(i, j) = f1' * f2;
% cmx(j, i) = cmx(i, j);
% end
%end
%cmx = cmx / (size(tvec,1)-1);
toc
[evec eval] = eig(cmx);
eval = sum(eval);
[eval evid] = sort(eval, 'descend');
evec = evec(:, evid(1:size(eval,2)));
% save 'nist_mu.mat' mu
% save 'nist_cov.mat' evec
trmx = evec(:, 1:comp_count);
pcaTransform.m
function [pcaSet] = pcaTransform(tvec, mu, trmx)
% tvec - matrix containing vectors to be transformed
% mu - mean value of the training set
% trmx - pca transformation matrix
% pcaSet - output set transforrmed to PCA space
pcaSet = tvec - repmat(mu, size(tvec,1), 1);
%pcaSet = zeros(size(tvec));
%for i=1:size(tvec,1)
% pcaSet(i,:) = tvec(i,:) - mu;
%end
pcaSet = pcaSet * trmx;
Which one is actually doing PCA?
If one is doing PCA, what is the other one doing?
The first function prepTransform is actually doing the PCA on your training data where you are determining the new axes to represent your data onto a lower dimensional space. What it does is that it finds the eigenvectors of the covariance matrix of your data and then orders the eigenvectors such that the eigenvector with the largest eigenvalue appears in the first column of the eigenvector matrix evec and the eigenvector with the smallest eigenvalue appears in the last column. What's important with this function is that you can define how many dimensions you want to reduce the data down to by keeping the first N columns of evec which will allow you to reduce your data down to N dimensions. The discarding of the other columns and keeping only the first N is what is set as trmx in the code. The variable N is defined by the prep_count variable in prepTransform function.
The second function pcaTransform finally transforms data that is defined within the same domain as your training data but not necessarily the training data itself (it could be if you wish) onto the lower dimensional space that is defined by the eigenvectors of the covariance matrix. To finally perform the reduction of dimensions, or dimensionality reduction as it is popularly known, you simply take your training data where each feature is subtracted from its mean and you multiply your training data by the matrix trmx. Note that prepTransform outputting the mean of each feature in the vector mu is important in order to mean subtract your data when you finally call pcaTransform.
How to use these functions
To use these functions effectively, first determine the trmx matrix, which contain the principal components of your data by first defining how many dimensions you want to reduce your data down to as well as the mean of each feature stored in mu:
N = 2; % Reduce down to two dimensions for example
[mu, trmx] = prepTransform(tvec, N);
Next you can finally perform dimensionality reduction on your data that is defined within the same domain as tvec (or even tvec if you wish, but it doesn't have to be) by:
pcaSet = pcaTransform(tvec, mu, trmx);
In terms of vocabulary, pcaSet contain what are known as the principal scores of your data, which is the term used for the transformation of your data to the lower dimensional space.
If I can recommend something...
Finding PCA through the eigenvector approach is known to be unstable. I highly recommend you use the Singular Value Decomposition via svd on the covariance matrix where the V matrix of the result already gives you the eigenvectors sorted which correspond to your principal components:
mu = mean(tvec, 1);
[~,~,V] = svd(cov(tvec));
Then perform the transformation by taking the mean subtracted data per feature and multiplying by the V matrix, once you subset and grab the first N columns of V:
N = 2;
X = bsxfun(#minus, tvec, mu);
pcaSet = X*V(:, 1:N);
X is the mean subtracted data which performs the same thing as doing pcaSet = tvec - repmat(mu, size(tvec,1), 1);, but you are not explicitly replicating the mean vector over each training example but letting bsxfun do that for you internally. However, taking advantage of MATLAB R2016b, this repeating can be done without the explicit call to bsxfun:
X = tvec - mu;
Further Reading
If you fully want to understand the code that was written and the theory behind what it's doing, I recommend the following two Stack Overflow posts that I have written that talk about the topic:
What does selecting the largest eigenvalues and eigenvectors in the covariance matrix mean in data analysis?
How to use eigenvectors obtained through PCA to reproject my data?
The first post brings the code you presented into light which performs PCA using the eigenvector approach. The second post touches base on how you'd do it using the SVD towards the end of the answer. This answer I've written here is a mix between the two posts above.
I am trying to implement the 2D Discrete Cosine Transform to an image by using
1D DCT operations. My output is incorrect if I compare it to the dct2 MATLAB function. I don't understand what went wrong in my code and where it's happening.
If someone can point out the mistake or any other advice, that would be really helpful.
Here is my code written in MATLAB
% main function
signal=rand(100);
signal_dct=myDCT(signal);
figure; imshow((signal_dct));
% function to calculate 2D DCT of an image
function res=myDCT(signal)
signal=double(signal);
l=size(signal,1);
res=zeros(l); %initialize the final result matrix
for k=1:l %calculate 1D DCT of each row of image
res(k,:)=mdct(signal(k,:));
end
for k=1:l %calculate 1D DCT of each column of image
res(:,k)=mdct(res(:,k));
end
end
%% function to calculate 1D DFT of a 1D signal
function res=mdct(signal)
l=size(signal,1);
for i=1:l
if i==1 %for signal index of 1, alpha is 1/sqrt(l)
alpha=sqrt(1/l);
else %for signal index of greater than 1
alpha=sqrt(2/l);
end
j=[1:l];
% summation calculates single entry of res by applying the
% formula of DCT on the signal
summation=sum(sum(signal(j)*cos((pi*(2*(j-1)+1)*(i-1))/(2*l))));
res(i)=alpha*summation;
end
end
You are correct in that the 2D DCT is separable. You would just apply the 1D DCT to every row first, then take the intermediate result and apply it to the columns. However, you have two fundamental mistakes. Let's go through them.
Mistake #1 - Size of DCT isn't correct
Specifically, look at this statement in your mdct function:
l=size(signal,1);
Because you are applying the DCT for each row, then each column, the above would only work if you are applying the DCT to the columns. size(signal,1) would certainly give you the length of the input vector if the input was a column. However, if your input was a row, then the output of size(signal,1) would be 1. Therefore, you should replace size(signal,1) with numel so that you are for sure going to get the total number of elements - regardless if the input is a row or column.
Also, if you want to make the code compatible to do the summation in the DCT loop, you should make sure that the input is a row vector regardless. As such, do this instead:
l = numel(signal);
signal = signal(:).';
The first line determines how many elements we have for our input signal, and the second line ensures that we have a row vector. This is done by (:) to unroll the elements into a column vector, then doing .' after to ensure we transpose the result to get a row vector.
Mistake #2 - Summation statement isn't correct
Next, you're going to have to do element-wise multiplications in your summation to get what you're looking for. You also don't need the extra sum call there. It's superfluous. Therefore, modify your summation statement to this:
summation=sum(signal.*cos((pi*(2*(j-1)+1).*(i-1))/(2*l)));
There's no need to do signal(j) because j spans the entire length of the vector, and you can just do that with signal.
Once I made these changes, and I did this on a smaller size matrix to ensure that we get the same results:
rng(123123);
signal=rand(7);
signal_dct=myDCT(signal);
signal_dct2 = dct2(signal);
The last line of code calls dct2 so that we can compare the results from your custom function and what dct2 gives us.
We get:
>> signal_dct
signal_dct =
3.7455 -0.1854 -0.1552 0.3949 0.2182 -0.3707 0.2621
-0.2747 0.1566 -0.0955 0.1415 0.3156 -0.0503 0.8581
-0.2095 0.0233 -0.2769 -0.4341 -0.1639 0.3700 -0.2282
-0.0282 0.0791 0.0517 0.4749 -0.0169 -0.4327 0.0427
-0.4047 -0.4383 0.3415 -0.1120 -0.0229 0.0310 0.3767
-0.6058 -0.0389 -0.3460 0.2732 -0.2395 -0.2961 0.1789
-0.0648 -0.3173 -0.0584 -0.3461 -0.1866 0.0301 0.2710
>> signal_dct2
signal_dct2 =
3.7455 -0.1854 -0.1552 0.3949 0.2182 -0.3707 0.2621
-0.2747 0.1566 -0.0955 0.1415 0.3156 -0.0503 0.8581
-0.2095 0.0233 -0.2769 -0.4341 -0.1639 0.3700 -0.2282
-0.0282 0.0791 0.0517 0.4749 -0.0169 -0.4327 0.0427
-0.4047 -0.4383 0.3415 -0.1120 -0.0229 0.0310 0.3767
-0.6058 -0.0389 -0.3460 0.2732 -0.2395 -0.2961 0.1789
-0.0648 -0.3173 -0.0584 -0.3461 -0.1866 0.0301 0.2710
As you can see, both results match up. Looks good to me!
Just to be sure we are consistent, this is the full code listing for both your functions, with the modifications I made:
% function to calculate 2D DCT of an image
function res=myDCT(signal)
signal=double(signal);
l=size(signal,1);
res = zeros(l);
for k=1:l %calculate 1D DCT of each row of image
res(k,:)=mdct(signal(k,:));
end
for k=1:l %calculate 1D DCT of each column of image
res(:,k)=mdct(res(:,k));
end
end
%% function to calculate 1D DFT of a 1D signal
function res=mdct(signal)
%// Change
l = numel(signal);
signal = signal(:).';
for i=1:l
if i==1 %for signal index of 1, alpha is 1/sqrt(l)
alpha=sqrt(1/l);
else %for signal index of greater than 1
alpha=sqrt(2/l);
end
j=[1:l];
% summation calculates single entry of res by applying the
% formula of DCT on the signal
%// Change
summation=sum(signal.*cos((pi*(2*(j-1)+1).*(i-1))/(2*l)));
res(i)=alpha*summation;
end
end
I have a weird problem with the discrete fft. I know that the Fourier Transform of a Gauss function exp(-x^2/2) is again the same Gauss function exp(-k^2/2). I tried to test that with some simple code in MatLab and FFTW but I get strange results.
First, the imaginary part of the result is not zero (in MatLab) as it should be.
Second, the absolute value of the real part is a Gauss curve but without the absolute value half of the modes have a negative coefficient. More precisely, every second mode has a coefficient that is the negative of that what it should be.
Third, the peak of the resulting Gauss curve (after taking the absolute value of the real part) is not at one but much higher. Its height is proportional to the number of points on the x-axis. However, the proportionality factor is not 1 but nearly 1/20.
Could anyone explain me what I am doing wrong?
Here is the MatLab code that I used:
function [nooutput,M] = fourier_test
Nx = 512; % number of points in x direction
Lx = 50; % width of the window containing the Gauss curve
x = linspace(-Lx/2,Lx/2,Nx); % creating an equidistant grid on the x-axis
input_1d = exp(-x.^2/2); % Gauss function as an input
input_1d_hat = fft(input_1d); % computing the discrete FFT
input_1d_hat = fftshift(input_1d_hat); % ordering the modes such that the peak is centred
plot(real(input_1d_hat), '-')
hold on
plot(imag(input_1d_hat), 'r-')
The answer is basically what Paul R suggests in his second comment, you introduce a phase shift (linearly dependent on the frequency) because the center of the Gaussian described by input_1d_hat is effectively at k>0, where k+1 is the index into input_1d_hat. Instead if you center your data (such that input_1d_hat(1) corresponds to the center) as follows you get a phase-corrected Gaussian in the frequency domain:
Nx = 512; % number of points in x direction
Lx = 50; % width of the window containing the Gauss curve
x = linspace(-Lx/2,Lx/2,Nx); % creating an equidistant grid on the x-axis
%%%%%%%%%%%%%%%%
x=fftshift(x); % <-- center
%%%%%%%%%%%%%%%%
input_1d = exp(-x.^2/2); % Gauss function as an input
input_1d_hat = fft(input_1d); % computing the discrete FFT
input_1d_hat = fftshift(input_1d_hat); % ordering the modes such that the peak is centered
plot(real(input_1d_hat), '-')
hold on
plot(imag(input_1d_hat), 'r-')
From the definition of the DFT, if the Gaussian is not centered such that maximum occurs at k=0, you will see a phase twist. The effect off fftshift is to perform a circular shift or swapping of left and right sides of the dataset, which is equivalent to shifting the center of the peak to k=0.
As for the amplitude scaling, that is an issue with the definition of the DFT implemented in Matlab. From the documentation for the FFT:
For length N input vector x, the DFT is a length N vector X,
with elements
N
X(k) = sum x(n)*exp(-j*2*pi*(k-1)*(n-1)/N), 1 <= k <= N.
n=1
The inverse DFT (computed by IFFT) is given by
N
x(n) = (1/N) sum X(k)*exp( j*2*pi*(k-1)*(n-1)/N), 1 <= n <= N.
k=1
Note that in the forward step the summation is not normalized by N. Therefore if you increase the number of points Nx in the summation while keeping the width Lx of the Gaussian function constant you will increase X(k) proportionately.
As for signal leaking into the imaginary frequency dimension, that is due to the discrete form of the DFT, which results in truncation and other effects, as noted again by Paul R. If you reduce Lx while keeping Nx constant, you should see a reduction in the amount of signal in the imaginary dimension relative to the real dimension (compare the spectra while keeping peak intensities in the real dimension equal).
You'll find additional answers to similar questions here and here.
I have an assignment to implement MoG with EM in matlab. The assignment:
My code atm;
clear
clc
load('data2')
%% INITIALIZE
K = 20
pi = 0.01:((1-0.01)/K):1;
for k=1:20
sigma{k} = eye(2);
mu(k,:) = [rand(1),rand(1)];
end
%% Posterior over the laten variables
addition = 0;
for k =1:20
addition = addition + (pi(k)*mvnpdf(x,mu(k,:), sigma{k}));
end
test = 0;
for k =1:20
gamma{k} = (pi(k)*mvnpdf(x,mu(k), sigma{k})) ./ addition;
end
data has 1000 rows and 2 columns (so 1000 datapoints). My question is now how do I calculate the responsibilities. When I try to calculate the covariance matrix I get a 1x1000 matrix. While I believe the covariance matrix should be 2x2.
Unfortunately, I don't speak Matlab, so I can't really see where your code is incorrect, but I can answer generally (and maybe someone who knows Matlab can see if your code can be salvaged). Each datapoint has a gamma associated with it, which is the expectation of an indicator variable for each component in the mixture. Calculating them is pretty simple: for the i-th datapoint and the k-th component, gamma_ik is just the density of the k-th component at the i-th point, multiplied by the k-th mixture coefficient (the prior probability that the point came from the k-th component, which is pi in your assignment), normalised by this quantity computed over all k. Thus for each datapoint, you have a vector of responsibilities (of length k) with a sum of one.