Finding correct index value for matrix in Matlab using meshgrid - matlab

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

Related

Steepest Descent using Armijo rule

I want to determine the Steepest descent of the Rosenbruck function using Armijo steplength where x = [-1.2, 1]' (the initial column vector).
The problem is, that the code has been running for a long time. I think there will be an infinite loop created here. But I could not understand where the problem was.
Could anyone help me?
n=input('enter the number of variables n ');
% Armijo stepsize rule parameters
x = [-1.2 1]';
s = 10;
m = 0;
sigma = .1;
beta = .5;
obj=func(x);
g=grad(x);
k_max = 10^5;
k=0; % k = # iterations
nf=1; % nf = # function eval.
x_new = zeros([],1) ; % empty vector which can be filled if length is not known ;
[X,Y]=meshgrid(-2:0.5:2);
fx = 100*(X.^2 - Y).^2 + (X-1).^2;
contour(X, Y, fx, 20)
while (norm(g)>10^(-3)) && (k<k_max)
d = -g./abs(g); % steepest descent direction
s = 1;
newobj = func(x + beta.^m*s*d);
m = m+1;
if obj > newobj - (sigma*beta.^m*s*g'*d)
t = beta^m *s;
x = x + t*d;
m_new = m;
newobj = func(x + t*d);
nf = nf+1;
else
m = m+1;
end
obj=newobj;
g=grad(x);
k = k + 1;
x_new = [x_new, x];
end
% Output x and k
x_new, k, nf
fprintf('Optimal Solution x = [%f, %f]\n', x(1), x(2))
plot(x_new)
function y = func(x)
y = 100*(x(1)^2 - x(2))^2 + (x(1)-1)^2;
end
function y = grad(x)
y(1) = 100*(2*(x(1)^2-x(2))*2*x(1)) + 2*(x(1)-1);
end

Matlab Error: Index in Position 1 exceeds array bounds

I am attempting to create a gamma distribution in MATLAB; however, I keep receiving the error:
Index in Position 1 exceeds array bounds (must not exceed 100).
Assuming I am reading this correctly, it is referring to variable M that is simply = 2500 (the number of pseudo-random variables I am using for this project).
I was hoping someone can explain what is wrong with my logic and possibly a solution.
alpha = 0.5;
w = gamma_rdn(M,alpha);
x1 = (0.0001:0.001:1); % For plot
figure(5)
subplot(2,1,1);hist(w);title('Histogram of Gamma RDN');
subplot(2,1,2);plot(x1,pdf('gam',x1,alpha,1));title('Theoretical Gamma Density with \alpha = 0.5');
axis([0 1 0 100]);
% The gamma_rdn function is implemented as follows:
function[w] = gamma_rdn(M,alpha)
% Generate random numbers from the gamma distribution with parameter
% alpha <= 1, beta = 1
pe = exp(1);
w = zeros(M,1);
u = rand(100,1);
b = (alpha + pe)/pe;
i = 0;
j = 0;
while j < M
i = i+1;
y = b*u(i,1);
if y <= 1
z = y^(1/alpha);
i = i+1;
if u(i,1) <= exp(-z)
j = j+1;
w(j,1) = z;
else
i = i+1;
end
else
z = -log((b-y)/alpha);
i = i+1;
if u(i,1) <= z^(alpha - 1)
j = j+1;
w(j,1) = z;
else
i = i+1;
end
end
end
if i > 95
u = rand(100,1);
i = 0;
end
end
Is there a particular reason you chose u = rand(100,1)?
The problem is coming because in while loop, as soon as variable i exceeds 100 (say i=101), y = b*u(i,1) becomes invalid. That is, you are trying to access u(101,1) while the size of u is (100,1).
If there's not particular reason, try a large enough size, like, u = rand(10000,1).

Matlab Code for Linear System by Central Difference Method

I have a linear system Ay = b, which is created by matrix looks like this:
Here attempt to find the curves based on the matrix in the image description:
n = 10;
x0 = 0;
xn = 1;
h = 1/n;
y0 = 0;
y1 = 0;
x = zeros(1:n-1);
for i = 1:n-1;
x(i) = i*h
end
A =zeros(n-1);
for j = 1:n-2;
A(j,j+1) = (1+h/2);
A(j,j) = (h*exp(x(j))-2);
A(j+1,j) = (1-h/2);
end
A(n-1,n-1) = (h*exp(x(n-1))-2);
b = zeros(1,n-1); %Right-hand side vector
for i = 1:n-1
b(i)=h^2*((exp(x(i))-pi^2)*sin(pi*x(i))+pi*cos(pi*x(i)));
end
b=b';
y = zeros(1,n-1);
y = inv(A)*b % Solving for y
figure
plot(x,y,x,sin(x))
This is code that I create but the curves disappear, anyone can help me to check my code?

Poisson PDE solver on a disked shaped domain with finite difference method using matlab

For my studies I had to write a PDE solver for the Poisson equation on a disc shaped domain using the finite difference method.
I already passed the Lab exercise. There is one issue in my code I couldn't fix. Function fun1 with the boundary value problem gun2 is somehow oscillating at the boundary. When I use fun2 everything seems fine...
Both functions use at the boundary gun2. What is the problem?
function z = fun1(x,y)
r = sqrt(x.^2+y.^2);
z = zeros(size(x));
if( r < 0.25)
z = -10^8*exp(1./(r.^2-1/16));
end
end
function z = fun2(x,y)
z = 100*sin(2*pi*x).*sin(2*pi*y);
end
function z = gun2(x,y)
z = x.^2+y.^2;
end
function [u,A] = poisson2(funame,guname,M)
if nargin < 3
M = 50;
end
%Mesh Grid Generation
h = 2/(M + 1);
x = -1:h:1;
y = -1:h:1;
[X,Y] = meshgrid(x,y);
CI = ((X.^2 +Y.^2) < 1);
%Boundary Elements
Sum= zeros(size(CI));
%Sum over the neighbours
for i = -1:1
Sum = Sum + circshift(CI,[i,0]) + circshift(CI,[0,i]) ;
end
%if sum of neighbours larger 3 -> inner note!
CI = (Sum > 3);
%else boundary
CB = (Sum < 3 & Sum ~= 0);
Sum= zeros(size(CI));
%Sum over the boundary neighbour nodes....
for i = -1:1
Sum = Sum + circshift(CB,[i,0]) + circshift(CB,[0,i]);
end
%If the sum is equal 2 -> Diagonal boundary
CB = CB + (Sum == 2 & CB == 0 & CI == 0);
%Converting X Y to polar coordinates
Phi = atan(Y./X);
%Converting Phi R back to cartesian coordinates, only at the boundarys
for j = 1:M+2
for i = 1:M+2
if (CB(i,j)~=0)
if j > (M+2)/2
sig = 1;
else
sig = -1;
end
X(i,j) = sig*1*cos(Phi(i,j));
Y(i,j) = sig*1*sin(Phi(i,j));
end
end
end
%Numberize the internal notes u1,u2,......,un
CI = CI.*reshape(cumsum(CI(:)),size(CI));
%Number of internal notes
Ni = nnz(CI);
f = zeros(Ni,1);
k = 1;
A = spalloc(Ni,Ni,5*Ni);
%Create matix A!
for j=2:M+1
for i =2:M+1
if(CI(i,j) ~= 0)
hN = h;hS = h; hW = h; hE = h;
f(k) = fun(X(i,j),Y(i,j));
if(CB(i+1,j) ~= 0)
hN = abs(1-sqrt(X(i,j)^2+Y(i,j)^2));
f(k) = f(k) + gun(X(i,j),Y(i+1,j))*2/(hN^2+hN*h);
A(k,CI(i-1,j)) = -2/(h^2+h*hN);
else
if(CB(i-1,j) ~= 0) %in negative y is a boundry
hS = abs(1-sqrt(X(i,j)^2+Y(i,j)^2));
f(k) = f(k) + gun(X(i,j),Y(i-1,j))*2/(hS^2+h*hS);
A(k,CI(i+1,j)) = -2/(h^2+h*hS);
else
A(k,CI(i-1,j)) = -1/h^2;
A(k,CI(i+1,j)) = -1/h^2;
end
end
if(CB(i,j+1) ~= 0)
hE = abs(1-sqrt(X(i,j)^2+Y(i,j)^2));
f(k) = f(k) + gun(X(i,j+1),Y(i,j))*2/(hE^2+hE*h);
A(k,CI(i,j-1)) = -2/(h^2+h*hE);
else
if(CB(i,j-1) ~= 0)
hW = abs(1-sqrt(X(i,j)^2+Y(i,j)^2));
f(k) = f(k) + gun(X(i,j-1),Y(i,j))*2/(hW^2+h*hW);
A(k,CI(i,j+1)) = -2/(h^2+h*hW);
else
A(k,CI(i,j-1)) = -1/h^2;
A(k,CI(i,j+1)) = -1/h^2;
end
end
A(k,k) = (2/(hE*hW)+2/(hN*hS));
k = k + 1;
end
end
end
%Solve linear system
u = A\f;
U = zeros(M+2,M+2);
p = 1;
%re-arange u
for j = 1:M+2
for i = 1:M+2
if ( CI(i,j) ~= 0)
U(i,j) = u(p);
p = p+1;
else
if ( CB(i,j) ~= 0)
U(i,j) = gun(X(i,j),Y(i,j));
else
U(i,j) = NaN;
end
end
end
end
surf(X,Y,U);
end
I'm keeping this answer short for now, but may extend when the question contains more info.
My first guess is that what you are seeing is just numerical errors. Looking at the scales of the two graphs, the peaks in the first graph are relatively small compared to the signal in the second graph. Maybe there is a similar issue in the second that is just not visible because the signal is much bigger. You could try to increase the number of nodes and observe what happens with the result.
You should always expect to see numerical errors in such simulations. It's only a matter of trying to get their magnitude as small as possible (or as small as needed).

Undefined variable in 'if' statement

I'm writing a script for an aerodynamics class and I'm getting the following error:
Undefined function or variable 'dCt_dx'.
Error in Project2_Iteration (line 81)
Ct = trapz(x,dCt_dx)
I'm not sure what the cause is. It's something to do with my if statement. My script is below:
clear all
clc
global dr a n Vinf Vr w rho k x c cl dr B R beta t
%Environmental Parameters
n = 2400; %rpm
Vinf = 154; %KTAS
rho = 0.07647 * (.7429/.9450); %from mattingly for 8kft
a = 1084; %speed of sound, ft/s, 8000 ft
n = n/60; %convert to rps
w = 2*pi*n;
Vinf = (Vinf*6076.12)/3600; %convert from KTAS to ft/s
k = length(c);
dr = R/k; %length of each blade element
for i = 1:k
r(i) = i*dr - (.5*dr); %radius at center of blade element
dA = 2*pi*r*dr; %Planform area of blade element
x(i) = r(i)/R;
if x(i) > .15 && x(i-1) < .15
i_15 = i;
end
if x(i) > .75 && x(i-1) < .75
i_75h = i;
i_75l = i-1;
end
Vr(i) = w*r(i) + Vinf;
%Aerodynamic Parameters
M = Vr(i)/a;
if M > 0.9
M = 0.9;
end
m0 = 0.9*(2*pi/(1-M^2)^0.5); %lift-curve slope (2pi/rad)
%1: Calculate phi
phi = atan(Vinf/(2*pi*n*r(i)));
%2: Choose Vo
Vo = .00175*Vinf;
%3: Calculate Theta
theta = atan((Vinf + Vo)/(2*pi*n*r(i)))-phi;
%4:
if option == 1
%calculate cl(i) from c(i)
sigma = (B*c(i))/(pi*R);
if sigma > 0
cl(i) = (8*x(i)*theta*cos(phi)*tan(phi+theta))/sigma;
else
cl(i) = 0;
end
else %option == 2
%calculate c(i) from cl(i)
if cl(i) ~= 0
sigma = (8*x(i)*theta*cos(phi)*tan(phi+theta))/cl(i);
else
sigma = 0;
end
c(i) = (sigma*pi*R)/B;
if c(i) < 0
c(i) = 0;
end
end
%5: Calculate cd
cd(i) = 0.0090 + 0.0055*(cl(i)-0.1)^2;
%6: calculate alpha
alpha = cl(i)/m0;
%7: calculate beta
beta(i) = phi + alpha + theta;
%8: calculate dCt/dx and dCq/dx
phi0 = phi+theta;
lambda_t = (1/(cos(phi)^2))*(cl(i)*cos(phi0) - cd(i)*sin(phi0));
lambda_q = (1/(cos(phi)^2))*(cl(i)*sin(phi0) + cd(i)*cos(phi0));
if x(i) >= 0.15
dCt_dx(i) = ((pi^3)*(x(i)^2)*sigma*lambda_t)/8; %Roskam eq. 7.47, pg. 280
dCq_dx(i) = ((pi^3)*(x(i)^3)*sigma*lambda_q)/16; %Roskam eq. 7.48, pg 280
else
dCt_dx(i) = 0;
dCq_dx(i) = 0;
end
%calculate Mdd
t(i) = (0.04/(x(i)^1.2))*c(i);
Mdd(i) = 0.94 - (t(i)/c(i)) - cl(i)/10;
end
%9: calculate Ct, Cq, Cd
Ct = trapz(x,dCt_dx)
Cq = trapz(x,dCq_dx)
D = 2*R;
Q=(rho*(n^2)*(D^5)*Cq)
T=(rho*(n^2)*(D^4)*Ct)
When I step through your script, I see that the the entire for i = 1:k loop is skipped because k=0. You set k = length(c), but c was never initialized to a value, so it has length zero.
Because of this, dCt_dx is never given a value--and more importantly the majority of your script is never run.
If you're going to be using MATLAB in the future, I really suggest learning how to do this. It makes it a lot easier to find bugs. Try looking at this video.