Inverse of Non-Linear Equations - MatLab - matlab

I have been trying without success to figure out how to invert the two equations shown below. As you can see, the equations are fairly complex nonlinear equation expressing R and T (reflection and transmission coefficients in acoustics) as a function of the variables n, k, d, and xi. What I need is to invert these equations and get expressions for xi and n in terms of the other variables. i is the imaginary unit.
Starting Equations
I know the answer I need to get (second image) and I am trying to replicate this answer using some MatLab code. m is branch number of the cos inverse (arccos) function.
Solution to aim for

1.- Since surf, like plot and other commands, requires X and Y to be same length, graphically inverting the function, what in AutoCAD is called rotating the UCS rather that starting with a symbolic inversion attempt, makes sense.
UCS : Universal Coordinates System . The tripod on the CAD drawing sheet indicating axes and origin.
% MATLAB
close all;clear all;clc
c0=299792458; % [m/s] light velocity
% guessing frequency band centre
f0=2e9; % [Hz]
lambda0=c0/f0; % wavelength
k0=2*pi/lambda0 % wave number
d=.03 % 3 [cm]? chip size? connector? antenna? waveguide length? the kettle?
% range_n=[0:lambda0/10:lambda0/4];
range_n=[0:.01:4.25];
range_e=[0:.05:10];
[N,E]=meshgrid(range_n,range_e);
%% Reflection Coefficient
R=1j*tan(N*k0*d).*(1./E-E)./(2-1j*tan(N*k0*d).*(1./E+E));
figure(1);
ax1=gca;
hs1=surf(ax1,N,E,abs(R))
hs1.EdgeColor='none';
grid on;xlabel('n');ylabel('e');zlabel('abs(R)');title('|R(n,e)|')
xcr1_1=ax1.XTickLabel; % x axis x measure ruler
xcr1_2=ax1.YTickLabel; % x axis y measure ruler
figure(2);
ax2=gca;
hs2=surf(ax2,N,E,angle(R))
hs2.EdgeColor='none';
grid on;xlabel('n');ylabel('e');zlabel('angle(R)');title('phase(R(n,e)) [rad]')
%% Transmission Coefficient
T=2./(cos(N*k0*d).*(2-1j*tan(N*k0*d).*(1./E+E)));
figure(3);
ax3=gca;
hs3=surf(ax3,N,E,abs(T))
hs3.EdgeColor='none';
grid on;xlabel('n');ylabel('e');zlabel('abs(T)');title('|T(n,e)|')
It makes sense that where there's high reflection then there's low transmission and where there's low reflection, then T gets close or equal to 1.
It's a passive device / material.
figure(4);
ax4=gca;
hs4=surf(ax4,N,E,angle(T))
hs4.EdgeColor='none';
grid on;xlabel('n');ylabel('e');zlabel('angle(T)');title('phase(T(n,e))')
2.- Now E from the other side, the sought inversion :
E2up=abs((((1+R).^2-T.^2)./((1-R)-T.^2)).^.5);
E2down=-abs((((1+R).^2-T.^2)./((1-R)-T.^2)).^.5);
[sz_s11,sz_s12]=size(E2up);
range_s11=[1:1:sz_s11];
range_s12=[1:1:sz_s12];
[sz_s1,sz_s2]=size(E2up);
range_s11=[1:1:sz_s11];
range_s12=[1:1:sz_s12];
[S11,S12]=meshgrid(range_s11,range_s12);
% |E(S,T)|>0
figure(5);
ax5=gca;
hs5=surf(ax5,S11,S12,abs(E2up'));
hs5.EdgeColor='none';
grid on;xlabel('s1_R');ylabel('s1_T');zlabel('abs(E_u_p)');title('|E_u_p(s1_R,s1_T)|')
s1_R s1_T variables in this particular context ARE NOT scattering parameters.
s1_r s1_T are numerals, indexs related to R and T.
n and m already in use.
3.- Changing inverted surface X Y numerals to R T
ax5.XTickLabel=xcr1_1; % x axis x change ruler
ax5.YTickLabel=xcr1_2; % x axis y change ruler
xlabel(ax5,'R');ylabel(ax5,'T');zlabel(ax5,'|(E_u_p)| positive values only');
% |E(S,T)|<0
ax6=gca;
hs6=surf(ax6,S11,S12,abs(E2down'));
hs6.EdgeColor='none';
grid on;xlabel('s1_R');ylabel('s1_T');zlabel('abs(E2_d_o_w_n)');title('|E_d_o_w_n(s1_R,s2_T)|')
ax6.XTickLabel=xcr1_1; % x axis x change ruler
ax6.YTickLabel=xcr1_2; % x axis y change ruler
xlabel(ax6,'R');ylabel(ax6,'T');zlabel(ax6,'|(E_d_o_w_n)| negative values only');
4.- Comments :
4.1.- Repeat for angle(Edown(R,T)) and then for n_up(R,T) n_down(R,T).
4.2.- Including the 2*pi*m/(k0*d) shouldn't be difficult either.
4.3.- Assumed waveguide filled with air.
Dielectrics modify lambda0 to lambda k0 to k and may add more cut-offs.
4.4.- Is the material homogeneous and isotropic?

Related

Matlab atan2 for angle between two 3D vectors

I need to calculate the angle between two plane. One plane is the hand plane and the second is the forearm plane. I calculated the normals of that planes and used the formula atan2(norm(cross(var.n1,var.n2)),dot(var.n1,var.n2)); in MATLAB. I want to see the flexion/extension angle of the wrist that is characterised by positive and negative peaks but with this formula I obtain only positive peaks.
%% Script to compute the angles of wrist flexion/extension and adduction/abduction based on Vicon data
% REF: Cheryl et al., March 2008
% Order of the markers: 1.WRR 2.WRU 3.FAU 4.FAR 5.CMC2 6.CMC5 7.MCP5 8.MCP2
clc
close all
clear all
%% Initialization
% dir_kinematic = input('Path of the folder containing the kinematic files: ','s');
dir_kinematic = 'C:\Users\Utente\Desktop\TESI\Vicon\test.mat';
cd(dir_kinematic);
fileList = getAllFiles(dir_kinematic,0); % Get names of all kinematic files
f=1;
%% Conversion to angles
for f = 1:length(fileList)
if ~isempty(strfind(fileList{f},'mat')) % Take only mat files
% 0. Loading
load(fileList{f});
% 1. Filtering
frameRate = kinematic.framerate;
n = 9;
Wn = 2/(frameRate/2);
ftype = 'low';
[b,a] = butter(n,Wn,ftype);
kinematic.x = filtfilt(b,a,kinematic.x);
kinematic.y = filtfilt(b,a,kinematic.y);
kinematic.z = filtfilt(b,a,kinematic.z);
% 2. Create vectors
var.n=length(kinematic.x);
% Forearm plane
var.FAU_WRU=[kinematic.x(:,2)-kinematic.x(:,3),kinematic.y(:,2)-kinematic.y(:,3),kinematic.z(:,2)-kinematic.z(:,3)];
var.WRR_WRU=[kinematic.x(:,2)-kinematic.x(:,1),kinematic.y(:,2)-kinematic.y(:,1),kinematic.z(:,2)-kinematic.z(:,1)];
% Hand plane
var.CMC5_MCP5=[kinematic.x(:,7)-kinematic.x(:,6),kinematic.y(:,7)-kinematic.y(:,6),kinematic.z(:,7)-kinematic.z(:,6)];
var.MCP2_MCP5=[kinematic.x(:,7)-kinematic.x(:,8),kinematic.y(:,7)-kinematic.y(:,8),kinematic.z(:,7)-kinematic.z(:,8)];
% Transpose
var.FAU_WRU = var.FAU_WRU';
var.WRR_WRU = var.WRR_WRU';
var.CMC5_MCP5 = var.CMC5_MCP5';
var.MCP2_MCP5 = var.MCP2_MCP5';
% 3. Calculate angle of wrist flexion/extension
% Cross vector function for all time => create normal vector plane
var.forearm_n=[];
var.hand_n=[];
var.theta_rad=[];
for i = 1:var.n % Loop through experiment
% vector x and y of the forearm plane
var.v1=var.FAU_WRU(:,i); % take x,y,z of the vector for every time
var.v2=var.WRR_WRU(:,i);
% vector x and y of the hand plane
var.v3=var.CMC5_MCP5(:,i);
var.v4=var.MCP2_MCP5(:,i);
var.forearm_n= [var.forearm_n, cross(var.v1,var.v2)];
var.hand_n=[var.hand_n, cross(var.v3,var.v4)];
end
% Calculate angle
for i = 1:var.n
var.n1=(var.forearm_n(:,i));
var.n2=var.hand_n(:,i);
var.scalar_product(i) = dot(var.n1,var.n2);
%Equation (2) of the paper
var.theta_rad=[var.theta_rad, atan2(norm(cross(var.n1,var.n2)),dot(var.n1,var.n2))]; % result in radian
angle.flex_deflex_wrist{f}=(var.theta_rad*180)/pi;
end
% 4. Calculate angle of wrist adduction/abduction
% Projection vector onto plane
var.MCP2_MCP5_forearmproj=[];
var.WRR_WRU_forearmproj=[];
var.rad_ul_angle_rad=[];
for i=1:var.n
%take x,y,z of the vector for each time
var.v1=var.MCP2_MCP5(:,i);
var.v2=var.WRR_WRU(:,i);
% vector x and y of the forearm plane
var.vfx=var.FAU_WRU(:,i); % take x,y,z of the vector for every time
var.vfy=var.WRR_WRU(:,i);
%projection of vector MCP2_MCP5 and WRR_WRU onto forearm plane
var.squNorm1=(norm(var.vfx)*norm(var.vfx));
var.squNorm2=(norm(var.vfy)*norm(var.vfy));
var.MCP2_MCP5_forearmproj=[var.MCP2_MCP5_forearmproj,((((var.v1')*var.vfx)*var.vfx/var.squNorm1)+(((var.v1')*var.vfy)*var.vfy/var.squNorm2))];
var.WRR_WRU_forearmproj=[var.WRR_WRU_forearmproj,((var.vfx*((var.v2')*var.vfx/var.squNorm1))+(var.vfy*((var.v2')*var.vfy/var.squNorm2)))];
end
% Calculate angle
for i=1:var.n
var.n1=var.MCP2_MCP5_forearmproj(:,i)';
var.n2=var.WRR_WRU_forearmproj(:,i);
var.product=var.n1*var.n2;
var.rad_ul_angle_rad=[var.rad_ul_angle_rad, atan2(norm(cross(var.n1,var.n2)),dot(var.n1,var.n2))];% en rad
angle.rad_ul_wrist{f}=(var.rad_ul_angle_rad*180)/pi;
end
end
end
I want to know why my angles are always positive? I need to see positive and negative peaks...
Thanks for the help!
Since the angle between two planes is the same as that between it's normals, I will constrain the discussion to angle between two vectors.
We know that the cross product between two vectors (a and b) is another vector, perpendicular to both of them.
We are dealing with the problem of distinguishing angles -T and +T, where T is some angle.
Using the formula you used, these two angles would give the same result, due to the fundamental formula itself that is used:
atan2 (|a x b|, a.b)
This is because while a.b is the same in both cases, a x b differs, exactly in the sign of the normal to the two vectors, and nothing else (verify yourself using hand rules). When we compute the norm of this vector, information about its sign is lost, due to which the function always returns positive values.
What you can do about it
You need to keep track of the sign of a x b, to determine if the angle is positive or negative.
Note: As I'm replying from my phone I am unable to add better formatting or code, will update the answer soon.

How to display two plot in a specific position with Matlab

Hi to all,
When I run a Matlab code which generate two plot, these are overplotted (the second over the first).
I would like obtain a result as this figure, where the two plots are like in a subplot(211) and subplot(212), the first and the second in two colons, but without using subplot.
It is possible?
UPDATE
I generate this two plot with two subfuncion:
function create_figure(X1, YMatrix1, p)
%CREATE_FIGURE(X1, YMATRIX1)
% X1: vector of x data
% YMATRIX1: matrix of y data
% P: parameters used in legend
% Create figure
figure1 = figure('Name','Acceleration Power vs. Velocity LPF 1st order');
...
and
function create_figure_gamma(X1, YMatrix1, p)
%CREATE_FIGURE_GAMMA(X1, YMATRIX1, P)
% X1: vector of x data
% YMATRIX1: matrix of y data
% P: parameters used in legend
% Create figure
figure1 = figure('Name','gamma trend vs. Velocity');
...
Of course, I can give in output the parameter figure1, writing:
function figure1 = create_figure(X1, YMatrix1, p)
I think that which this parameter is possible set the position of the two plots, but I do not know the procedure respect the generic window size.
You could also set the Units to 'normalized' and enter relative positions for the figures:
set(h1,'Units','normalized');
set(h2,'Units','normalized');
set(h1,'Position',[0.1021 0.1708 0.2917 0.3500]);
set(h2,'Position',[0.4021 0.1700 0.2917 0.3508]);
This way you are independent of the current screen resolution.
This would produce two figures with plots side by side:
x = 0:0.1:2*pi;
y1 = sin(x);
y2 = cos(x);
h1=figure
plot(x,y1);
h2=figure
plot(x,y2);
% x, y, width, height
set(h1,'Position',[20 616,560,420])
set(h2,'Position',[20+560 616,560,420])

Computing and plotting pdf of U as a function of two uniformly distributed random variables

I am working on a joint pdf problem in which the random variable
U = sqrt(X^2+Y^2)
X and Y are uniformly distributed over (-2,2). I want to plot joint pdf of X and Y. Then compute pdf of U and plot it as well. I am using matlab R2011a, and so far, I have come up with the following code. On running the code I got an error message
Undefined function or method 'makedist' for input arguement type 'char'.
I found out that makedist is not on 2011 version. So I tried using
a=-2;
b=2;
X=a+(b-a)*rand(-10,10);
Y= a+(b-a)*rand(-10,10).
However, I am not sure how to compute pdfs of X and Y, and then joint pdf of XY from this. Any help, partial or holistic, is appreciated.
Here is the matlab code for the problem
%% Create distribution objects for X~U(-2,2) and Y~U(-2,2)
pdx=makedist('Uniform','lower',-2,'upper',2);
pdy=makedist('Uniform','lower',-2,'upper',2);
%Compute the pfs
x_ref=-10:1:10;
y_ref=-10:1:10;
pdf_x=pdf(pdx,x_ref);
pdf_y=pdf(pdy,y_ref);
% Plot the pdfs
figure 1;
stairs(x_ref,pdf_x,'g','Linewidth',2);
hold on;
stairs(y_ref,pdf_y,'r','Linewidth',2);
ylim([0 1.5]);
hold off;
% Joint pdf of x and Y
pdfXY=pdf_x*pdf_y;
figure 2;
plot(pdfXY);
%CDF and PDF of U
U=sqrt(X^2+Y^2);
Umin=0;
Umax=sqrt(b^2+b^2);
a=lower;
b=upper;
x=sqrt(U^2-Y^2);
xmin=0;
xmax=x;
ymin=0;
ymax=U;
Ucdf=integral2(pdfXY,xmin,xmax,ymin,ymax);
% plot CDF of U
figure 3;
plot(Ucdf)
I am just looking to plot the regions than for any specific sample set. X and Y are continuous independent uniform random variables.
As your x and y are independent at random, the theoretical joint distribution is just a product of the two
P(x,y) = P(x)*P(y)
In terms of MATLAB code, you may think of x and y running along two different dimensions:
N = 10; %// think of a probability mass function over N points
x = linspace(-2,2, N);
y = linspace(-2,2, N)';
Px = ones(N,1)./N;
Py = ones(1,10)./N;
%// Then the joint will be:
Jxy = bsxfun(#times, Px , Py);
figure
pcolor(x,y,Jxy)
You can now plug whatever distribution you like, if they are independent for Px and Py, and it will work

FFTW and fft with MatLab

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.

Plot a grid of Gaussians with Matlab

With the following code I'm able to draw the plot of a single 2D-Gaussian function:
x=linspace(-3,3,1000);
y=x';
[X,Y]=meshgrid(x,y);
z=exp(-(X.^2+Y.^2)/2);
surf(x,y,z);shading interp
This is the produced plot:
However, I'd like to plot a grid having a specified number x of these 2D-Gaussians.
Think of the following picture as an above view of the plot I'd like to produce (where in particular the grid is made of 5x5 2D-Gaussians). Each Gaussian should be weighed by a coefficient such that if it's negative the Gaussian is pointing towards negative values of the z axis (black points in the grid below) and if it's positive it's as in the above image (white points in the grid below).
Let me provide some mathematical details. The grid corresponds to a mixture of 2D-Gaussians summed as in the following equation:
In which each Gaussian has its own mean and deviation.
Note that each Gaussian of the mixture should be put in a determined (X,Y) coordinate, in such a way that they are equally distant from each other. e.g think of the central Gaussian in (0,0) then the other ones should be in (-1,1) (0,1) (1,1) (-1,0) (1,0) (-1,-1) (0,-1) (1,-1) in the case of a grid with dimension 3x3.
Can you provide me (and explain to me) how can I do such a plot?
Thanks in advance for the help.
Indeed you said yourself, put (as an example just for the means)
[X,Y]=meshgrid(x,y); % //mesh
g_centers = -3:3;
[x_g,y_g] = meshgrid(g_centers,g_centers); % //grid of centers (coarser)
mu = [x_g(:) , y_g(:)]; % // mesh of centers in column
z = zeros(size(X));
for i = 1:size(mu,1)
z= z + exp(-((X-mu(i,1)).^2+(Y-mu(i,2)).^2)/( 2* .001) );
end
surf(X,Y,z);shading interp