Plotting level curves in MATLAB for a complex function - matlab

I am trying to plot the contour plots for the given function
syms r x y k z
[ph,r] = meshgrid((0:5:360)*pi/180,0:.5:10);
[X,Y] = pol2cart(ph,r);
Z = X+i*Y;
J = besselj(k,l.*r);
J2 = besselj(k,m.*r);
Y = bessely(k,l.*r);
Y2 = bessely(k,m.*r);
H = besselh(k,r);
F1 = symsum((J).*exp(1i*k*ph),k,-5,5);
F2 = symsum((J2+Y2).*exp(1i.*k.*ph),k,-5,5);
F3 = symsum(H.*exp(1i.*k.*ph),k,-5,5);
pwu = nan(size(F1), 'like', F1);
mask = 0 <= r & r < 0.5;
pwu(mask) = F1(mask);
mask = 0.5 <= r & r < 1;
pwu(mask) = F2(mask);
mask = r >= 1;
pwu(mask) = F3(mask);
U = subs(pwu, {l, m}, {1.5, 3});hold on
contour(X,Y,imag(double(U)),30)
axis equal
xlabel('r','FontSize',14);
ylabel('phi','FontSize',14);
but I keep getting errors for the form of the 4th last line. Apparently U cannot be converted to a double. Is there any other way to do this?
Thanks

This code works:
syms r x y k z
[ph,r] = meshgrid((0:5:360)*pi/180,0:.5:10);
[x,y] = pol2cart(ph,r);
Z = x+1i*y;
J = besselj(k,l.*r);
J2 = besselj(k,m.*r);
Y = bessely(k,l.*r);
Y2 = bessely(k,m.*r);
H = besselh(k,r);
F1 = symsum((J).*exp(1i*k*ph),k,-5,5);
F2 = symsum((J2+Y2).*exp(1i.*k.*ph),k,-5,5);
F3 = symsum(H.*exp(1i.*k.*ph),k,-5,5);
pwu = nan(size(F1), 'like', F1);
mask = 0 <= r & r < 0.5;
pwu(mask) = F1(mask);
mask = 0.5 <= r & r < 1;
pwu(mask) = F2(mask);
mask = r >= 1;
pwu(mask) = F3(mask);
U = subs(pwu, {l, m}, {1.5, 3});hold on
J0 = besselj(k,r);
u0 = symsum(1i.^(-k).*J0.*exp(1i*k*ph),k,-5,5);
W = U+u0;
contour(x, y, angle(double(W)), 30);
axis equal
xlabel('r','FontSize',14);
ylabel('phi','FontSize',14);
Thanks for your comments!

Related

matlab mesh2d issue which cant be found

im trying to use mesh2d function according to a guide I read.
for some reason im getting all the time this issue:
Undefined function 'mesh2d' for input arguments of type 'double'.
Error in Try1 (line 88)
[p,t] = mesh2d(allnodes, alledges);
I install mesh2d , according to the guide here:
https://github.com/dengwirda/mesh2d
but for some reason im still getting this issue...
this is my code:(im adding the code so it whould be easier in case im missing something, instead il mark the bad part)
clf
file = 'pattern3';
P = imread('Pattern3.png');
P = P(400:3400, 400:3400);
P = 255 - P*6;
P = 1-im2bw(P);
Nmin = min(size(P));
P = P(1:Nmin, 1:Nmin);
[xg, yg] = meshgrid(1:Nmin, 1:Nmin);
P((xg - Nmin/2).^2 + (yg - Nmin/2).^2 > 0.99*0.25*Nmin^2) = 0;
P = padarray(P, [1 1], 0);
CC = bwconncomp(P);
dtheta = pi/24;
theta = (-pi:dtheta:(pi-dtheta))';
nodeouter = [1.1*cos(theta) 1.1*sin(theta)];
Nnodes = length(nodeouter);
nodelist = (1:Nnodes)';
allnodes = nodeouter;
alledges = [nodelist , mod(nodelist, Nnodes)+1];
for n = 1:CC.NumObjects
%for n = 2:2
newP = zeros(size(P));
newP(CC.PixelIdxList{1,n}(:)) = 1;
newP = filter2(fspecial('average',5),newP);
C = contourc(newP,[0.2 0.2]);
C = C(:,2:end)';
C2 = dpsimplify(C,1);
m = 1;
while m <= length(C2(:,1))
if(C2(m,1) == 1 || C2(m,2) == 1)
C2(m,:) = [];
else
m = m + 1;
end
end
C2 = (C2 - Nmin/2)/(Nmin/2);
C = (C - Nmin/2)/(Nmin/2);
figure(1)
hold all
plot(C2(:,1), C2(:,2))
axis image xy
drawnow
nodeinner = C2;
Nnodeshole = length(nodeinner);
nodelist = (1:Nnodeshole)';
edgelist = [nodelist , mod(nodelist, Nnodeshole)+1];
edgelist = edgelist + Nnodes;
allnodes = [allnodes; nodeinner];
alledges = [alledges; edgelist];
Nnodes = Nnodes + Nnodeshole;
n
end
%%
hdata.fun = #(x,y) 0.05*(1 + ((x.^2 + y.^2)/a^2)).^2;
[p,t] = mesh2d(allnodes, alledges); %%here is the issue!!!!!!!!!!!!!!!!!!!!!!!1
%%
as = 0.5;
for n = 1:length(as)
a = as(n);
h = 0;
x = p(:,1);
y = p(:,2);
z = zeros(size(x));
r = sqrt(x.^2 + y.^2);
phi = atan2(y,x);
theta = atan(r/(a+h));
alpha = 2*theta;
xnew = a*sin(alpha).*cos(phi);
ynew = a*sin(alpha).*sin(phi);
znew = -a*cos(alpha);
p2 = [xnew, ynew, znew];
stlwrite('Test.stl', t, p2)
fv.faces = t;
fv.vertices = p2;
clf
figure(3)
patch(fv, 'FaceColor', [1 1 1], 'EdgeColor', 'black', 'LineWidth', 0.1)
axis equal
axis off
xlim([-a a])
ylim([-a a])
zlim([-a a])
camlight head
view(58,28)
zoom(1.5)
drawnow
end
the photo im trying to use:
I recently completely rewrote MESH2D -- bringing it up-to-date with more recent meshing techniques and MATLAB functionality. It looks like you are trying to use subroutines from old versions of the library.
Based on the updates, the routines you want are refine2 and smooth2 (they build and then optimise a two-dimensional constrained Delaunay triangulation).
I recommend that you have a look at the example code contained in tridemo to see how the updated MESH2D toolbox works.

Why do the plot and patch commands both not execute in Matlab?

So I was tasked with plotting the Golden Rectangles along with the Golden Spiral over top of the rectangles. We were given the code for the rectangles, for the "spiral" I used multiple arcs from this forum post, and I can only use if and for statements. The code for the rectangles works and the code for the spiral almost works, but what I really need is to get the patch to display behind the plot. This is the code that I have now:
clear variables; close all; clc
phi = (1+sqrt(5))/2;
x0 = 0;
y0 = 0;
for i = 1:8
edgeLength = 1/(phi^(i-1));
moveLength = 1/(phi^i);
modStep = mod(i,4);
if (modStep == 1) %move W, orient NW
x0 = x0 - moveLength;
sx = [x0 x0 x0-edgeLength x0-edgeLength];
sy = [y0 y0+edgeLength y0+edgeLength y0];
%spiral
P1 = [(x0-edgeLength);y0];
P2 = [x0;(y0+edgeLength)];
P0 = [x0;y0];
n = 1000;
v1 = P1-P0;
v2 = P2-P0;
c = det([v1,v2]);
a = linspace(0,atan2(abs(c),dot(v1,v2)),n);
v3 = [0,-c;c,0]*v1;
v = v1*cos(a)+((norm(v1)/norm(v3))*v3)*sin(a);
if i == 1
vx1 = v(1,:);
vy1 = v(2,:);
elseif i == 5
vx6 = (v(1,:)+(1/(phi^5)));
vy6 = (v(2,:)+(1/(phi^5)));
end
end
if (modStep == 2) %move N, orient NE
y0 = y0 + moveLength;
sx = [x0 x0+edgeLength x0+edgeLength x0];
sy = [y0 y0 y0+edgeLength y0+edgeLength];
%spiral
P1 = [x0;(y0+edgeLength)];
P2 = [(x0+edgeLength);y0];
P0 = [x0;y0];
n = 1000;
v1 = P1-P0;
v2 = P2-P0;
c = det([v1,v2]);
a = linspace(0,atan2(abs(c),dot(v1,v2)),n);
v3 = [0,-c;c,0]*v1;
v = v1*cos(a)+((norm(v1)/norm(v3))*v3)*sin(a);
if i == 2
vx2 = v(1,:);
vy2 = (v(2,:)+(1/(phi^2)));
elseif i == 6
vx5 = (v(1,:)+(1/(phi^5)));
vy5 = (v(2,:)+(1/(phi^6)));
end
end
if (modStep == 3) %move E, orient SE
x0 = x0 + moveLength;
sx = [x0 x0 x0+edgeLength x0+edgeLength];
sy = [y0 y0-edgeLength y0-edgeLength y0];
%spiral
P1 = [(x0+edgeLength);y0];
P2 = [x0;(y0-edgeLength)];
P0 = [x0;y0];
n = 1000;
v1 = P1-P0;
v2 = P2-P0;
c = det([v1,v2]);
a = linspace(0,atan2(abs(c),dot(v1,v2)),n);
v3 = [0,-c;c,0]*v1;
v = v1*cos(a)+((norm(v1)/norm(v3))*v3)*sin(a);
if i == 3
vx3 = (v(1,:)+(1/(phi^3)));
vy3 = (v(2,:)+(1/(phi^2)));
elseif i == 7
vx7 = (v(1,:)+(1/(phi^7)));
vy7 = (v(2,:)+(1/(phi^6)));
end
end
if (modStep == 0) %move S, orient SW
y0 = y0 - moveLength;
sx = [x0 x0-edgeLength x0-edgeLength x0];
sy = [y0 y0 y0-edgeLength y0-edgeLength];
%spiral
P1 = [(x0-edgeLength);y0];
P2 = [x0;(y0-edgeLength)];
P0 = [x0;y0];
n = 1000;
v1 = P1-P0;
v2 = P2-P0;
c = det([v1,v2]);
a = linspace(0,atan2(abs(c),dot(v1,v2)),n);
v3 = [0,-c;c,0]*v1;
v = v1*cos(a)+((norm(v1)/norm(v3))*v3)*sin(a);
if i == 4
vx4 = (v(1,:)+(1/(phi^3)));
vy4 = (v(2,:)+(1/(phi^3)));
elseif i == 8
vx8 = (v(1,:)+(1/(phi^7)));
vy8 = (v(2,:)+(1/(phi^7)));
end
end
end
patch(sx,sy,0.8+0.2*rand(1,3));
vx = [vx1 vx2 vx3 vx4 vx5 vx6 vx7 vx8];
vy = [vy1 vy2 vy3 vy4 vy5 vy6 vy7 vy8];
plot(vx,vy);
axis equal
In the code, the comments about North, West, etc. are in reference to the rectangles that are displayed and their orientation. The parts of the code that make up the spiral are likewise labeled.
So I really have two questions, however, the one that is most pressing is why will only the plot(vx,vy) command only work and not the patch? I tried looking at other examples of things but they seem to just type each command in in the order they want them to print and it does it.
The other issue I have it that when I do run this code the arcs work perfectly for i = 1:4 but after that, you can see, the lines are all messed up. I don't really know why that is either.
If I left out any other information I'm sorry!
Thank you

Matlab: how to calculate the Pseudo Zernike moments?

The code below is defined as algorithm 1 that computes the Pseudo Zernike Radial polynomials:
function R = pseudo_zernike_radial_polynomials(n,r)
if any( r>1 | r<0 | n<0)
error(':zernike_radial_polynomials either r is less than or greater thatn 1, r must be between 0 and 1 or n is less than 0.')
end
if n==0;
R =ones(n +1, length(r));
return;
end
R =ones(n +1, length(r));
rSQRT= sqrt(r);
r0 = ~logical(rSQRT.^(2*n+1)) ; % if any low r exist, and high n, then treat as 0
if any(r0)
m = n:-1:mod(n,2); ss=1:sum(r0);
R0(m +1, ss)=0;
R0(0 +1, ss)=1;
R(:,r0)=R0;
end
if any(~r0)
rSQRT= rSQRT(~r0);
R1 = zernike_radial_polynomials(2*n+1, rSQRT );
m = 2:2: 2*n+1 +1;
R1=R1(m,:);
for m=1:size(R1,1)
R1(m,:) = R1(m,:)./rSQRT';
end
R(:,~r0)=R1;
end
Then, this is algorithm 2 that calculates the moments:
and I translate into the code as follow:
clear all
%input : 2D image f, Nmax = order.
f = rgb2gray(imread('Oval_45.png'));
prompt = ('Input PZM order Nmax:');
Nmax = input(prompt);
Pzm =0;
l = size(f,1);
for x = 1:l;
for y =x;
for n = 0:Nmax;
[X,Y] = meshgrid(x,y);
R = sqrt((2.*X-l-1).^2+(2.*Y-l-1).^2)/l;
theta = atan2((l-1-2.*Y+2),(2.*X-l+1-2));
R = (R<=1).*R;
rad = pseudo_zernike_radial_polynomials(n, R);
for m = 0:n;
%find psi
if mod(m,2)==0
%m is even
newd1 = f(x,y)+f(x,y);
newd2 = f(y,x)+f(y,x);
newd3 = f(x,y)+f(x,y);
newd4 = f(y,x)+f(y,x);
x1 = newd1;
y1 = (-1)^m/2*newd2;
x2 = newd3;
y2 = (-1)^m/2*newd4;
psi = cos(m*theta)*(x1+y1+x2+y2)-(1i)*sin(m*theta)*(x1+y1-x2-y2);
else
newd1 = f(x,y)-f(x,y);
newd2 = f(y,x)-f(y,x);
newd3 = f(x,y)-f(x,y);
newd4 = f(y,x)-f(y,x);
x1 = newd1;
y1 = (-1)^m/2*newd2;
x2 = newd3;
y2 = (-1)^m/2*newd4;
psi = cos(m*theta)*(x1+x2)+sin(m*theta)*(y1-y2)+(1i)*(cos(m*theta)*(y1+y2)-sin(m*theta)*(x1-x2));
end
Pzm = Pzm+rad*psi;
end
end
end
end
However its give me error :
Error using *
Integers can only be combined with integers of the same class, or scalar doubles.
Error in main_pzm (line 44)
Pzm = Pzm+rad*psi;
The detail of the calculation can be seen here

Finding correct index value for matrix in Matlab using meshgrid

I'm trying to build make a code where an equation is not calculated for some certain values. I have a meshgrid with several values for x and y and I want to include a for loop that will calculate some values for most of the points in the meshgrid but I'm trying to include in that loop a condition that if the points have a specified index, the value will not be calculated. In my second group of for/if loops, I want to say that for all values of i and k (row and column), the value for z and phi are calculated with the exception of the specified i and k values (in the if loop). What I'm doing at the moment is not working...
The error I'm getting is:
The expression to the left of the equals sign is not a valid target for an assignment.
Here is my code at the moment. I'd really appreciate any advice on this! Thanks in advance
U_i = 20;
a = 4;
c = -a*5;
b = a*10;
d = -20;
e = 20;
n = a*10;
[x,y] = meshgrid([c:(b-c)/n:b],[d:(e-d)/n:e]');
for i = 1:length(x)
for k = 1:length(x)
% Zeroing values where cylinder is
if sqrt(x(i,k).^2 + y(i,k).^2) < a
x(i,k) = 0;
y(i,k) = 0;
end
end
end
r = sqrt(x.^2 + y.^2);
theta = atan2(y,x);
z = zeros(length(x));
phi = zeros(length(x));
for i = 1:length(x)
for k = 1:length(x)
if (i > 16 && i < 24 && k > 16 && k <= length(x))
z = 0;
phi = 0;
else
z = U_i.*r.*(1-a^2./r.^2).*sin(theta); % Stream function
phi = U_i*r.*(1+a^2./r.^2).*cos(theta); % Velocity potential
end
end
end
The original code in the question can be rewritten as seen below. Pay attention in the line with ind(17:24,:) since your edit now excludes 24 and you original question included 24.
U_i = 20;
a = 4;
c = -a*5;
b = a*10;
d = -20;
e = 20;
n = a*10;
[x,y] = meshgrid([c:(b-c)/n:b],[d:(e-d)/n:e]');
ind = find(sqrt(x.^2 + y.^2) < a);
x(ind) = 0;
y(ind) = 0;
r = sqrt(x.^2 + y.^2);
theta = atan2(y,x);
ind = true(size(x));
ind(17:24,17:length(x)) = false;
z = zeros(size(x));
phi = zeros(size(x));
z(ind) = U_i.*r(ind).*(1-a^2./r(ind).^2).*sin(theta(ind)); % Stream function
phi(ind) = U_i.*r(ind).*(1+a^2./r(ind).^2).*cos(theta(ind)); % Velocity potential

Vectorizing 4 nested for loops

I'm trying to vectorize the 2 inner nested for loops, but I can't come up with a way to do this. The FS1 and FS2 functions have been written to accept argument for N_theta and N_e, which is what the loops are iterating over
%% generate regions
for raw_r=1:visual_field_width
for raw_c=1:visual_field_width
r = raw_r - center_r;
c = raw_c - center_c;
% convert (r,c) to polar: (eccentricity, angle)
e = sqrt(r^2+c^2)*deg_per_pixel;
a = mod(atan2(r,c),2*pi);
for nt=1:N_theta
for ne=1:N_e
regions(raw_r, raw_c, nt, ne) = ...
FS_1(nt-1,a,N_theta) * ...
FS_2(ne-1,e,N_e,e0_in_deg, e_max);
end
end
end
end
Ideally, I could replace the two inner nested for loops by:
regions(raw_r,raw_c,:,:) = FS_1(:,a,N_theta) * FS_2(:,N_e,e0_in_deg,e_max);
But this isn't possible. Maybe I'm missing an easy fix or vectorization technique? e0_in_deg and e_max are parameters.
The FS_1 function is
function h = FS_1(n,theta,N,t)
if nargin==2
N = 9;
t=1/2;
elseif nargin==3
t=1/2;
end
w = (2*pi)/N;
theta = theta + w/4;
if n==0 && theta>(3/2)*pi
theta = theta - 2*pi;
end
h = FS_f((theta - (w*n + 0.5*w*(1-t)))/w);
the FS_2 function is
function g = FS_gne(n,e,N,e0, e_max)
if nargin==2
N = 10;
e0 = .5;
elseif nargin==3
e0 = .5;
end
w = (log(e_max) - log(e0))/N;
g = FS_f((log(e)-log(e0)-w*(n+1))/w);
and the FS_f function is
function f = FS_f(x, t)
if nargin<2
t = 0.5;
end
f = zeros(size(x));
% case 1
idx = x>-(1+t)/2 & x<=(t-1)/2;
f(idx) = (cos(0.5*pi*((x(idx)-(t-1)/2)/t))).^2;
% case 2
idx = x>(t-1)/2 & x<=(1-t)/2;
f(idx) = 1;
% case 3
idx = x>(1-t)/2 & x<=(1+t)/2;
f(idx) = -(cos(0.5*pi*((x(idx)-(1+t)/2)/t))).^2+1;
I had to assume values for the constants, and then used ndgrid to find the possible configurations and sub2ind to get the indices. Doing this I removed all loops. Let me know if this produced the correct values.
function RunningFunction
%% generate regions
visual_field_width = 10;
center_r = 2;
center_c = 3;
deg_per_pixel = 17;
N_theta = 2;
N_e = 5;
e0_in_deg = 35;
e_max = 17;
[raw_r, raw_c, nt, ne] = ndgrid(1:visual_field_width, 1:visual_field_width, 1:N_theta, 1:N_e);
ind = sub2ind(size(raw_r), raw_r, raw_c, nt, ne);
r = raw_r - center_r;
c = raw_c - center_c;
% convert (r,c) to polar: (eccentricity, angle)
e = sqrt(r.^2+c.^2)*deg_per_pixel;
a = mod(atan2(r,c),2*pi);
regions(ind) = ...
FS_1(nt-1,a,N_theta) .* ...
FS_2(ne-1,e,N_e,e0_in_deg, e_max);
regions = reshape(regions, size(raw_r));
end
function h = FS_1(n,theta,N,t)
if nargin==2
N = 9;
t=1/2;
elseif nargin==3
t=1/2;
end
w = (2*pi)./N;
theta = theta + w/4;
theta(n==0 & theta>(3/2)*pi) = theta(n==0 & theta>(3/2)*pi) - 2*pi;
h = FS_f((theta - (w*n + 0.5*w*(1-t)))/w);
end
function g = FS_2(n,e,N,e0, e_max)
if nargin==2
N = 10;
e0 = .5;
elseif nargin==3
e0 = .5;
end
w = (log(e_max) - log(e0))/N;
g = FS_f((log(e)-log(e0)-w*(n+1))/w);
end
function f = FS_f(x, t)
if nargin<2
t = 0.5;
end
f = zeros(size(x));
% case 1
idx = x>-(1+t)/2 & x<=(t-1)/2;
f(idx) = (cos(0.5*pi*((x(idx)-(t-1)/2)/t))).^2;
% case 2
idx = x>(t-1)/2 & x<=(1-t)/2;
f(idx) = 1;
% case 3
idx = x>(1-t)/2 & x<=(1+t)/2;
f(idx) = -(cos(0.5*pi*((x(idx)-(1+t)/2)/t))).^2+1;
end