I created a fas.m script, but I'm getting wrong result.
FUNCTION
function [fnc2] = fas(x)
if x>=0 && x<1
fnc2 = x^3;
elseif x>=1 && x<2
fnc2 = 2-((x^2)/5);
elseif x>2
fnc2 = x^2+x;
elseif x<0
fprintf('x is smaller than 0, function is not defined');
end
TRAPEZOIDAL RULE SUM
clear
clc
h=0.05;
x=0.05;
x0=0;
xn=3;
while x<=2.95
fas(x);
I=0.025*(fas(x0)+2*fas(x)+fas(x0));
x=x+h;
end
Trapezoidal rule is,
so,
h = 0.05;
x = 0;
I = 0;
while x < 3
I = I + h * (fas(x) + fas(x + h)) / 2;
x = x + h;
end
disp(I);
you will get I = 11.3664 while the actual value of I is 10.3667.
Related
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
I'm trying to write a matlab program to calculate an integral by means of trapezoidal and simpsons rule. The program for trapezoidal is as follows:
function [int, flag, stats] = trapComp(f, a, b, tol, hMin)
% Initialise variables
h = b - a;
n = 1;
int = h / 2 * (f(a) + f(b));
flag = 1;
if nargout == 3
stats = struct('totalErEst', [], 'totalNrIntervals', [], 'nodesList', []);
end
while h > hMin
h = h / 2;
n = 2 * n;
if h < eps % Check if h is not "zero"
break;
end
% Update the integral with the new nodes
intNew = int / 2;
for j = 1 : 2 : n
intNew = intNew + h * f(a + j * h);
end
% Estimate the error
errorEst = 1 / 3 * (int - intNew);
int = intNew;
if nargout == 3 % Update stats
stats.totalErEst = [stats.totalErEst; abs(errorEst)];
stats.totalNrIntervals = [stats.totalNrIntervals; n / 2];
end
if abs(errorEst) < tol
flag = 0;
break
end
end
end
Now simpsons rule I cant really quite get around. I know its very similar but I cant seem to figure it out.
This is my simpson code:
function [int, flag, stats] = simpComp(f, a, b, tol, hMin)
% Initialise variables
h = b - a;
n = 1;
int = h / 3 * (f(a) + 4 * f((a+b)/2) + f(b));
flag = 1;
if nargout == 3
stats = struct('totalErEst', [], 'totalNrIntervals', [], 'nodesList', []);
end
while h > hMin
h = h / 2;
n = 2 * n;
if h < eps % Check if h is not "zero"
break;
end
% Update the integral with the new nodes
intNew = int / 2;
for j = 1 : 2 : n
intNew = intNew + h * f(a + j * h);
end
% Estimate the error
errorEst = 1 / 3 * (int - intNew);
int = intNew;
if nargout == 3 % Update stats
stats.totalErEst = [stats.totalErEst; abs(errorEst)];
stats.totalNrIntervals = [stats.totalNrIntervals; n / 2];
end
if abs(errorEst) < tol
flag = 0;
break
end
end
end
Using this, however, gives an answer for an integral with a larger error than trapezoidal which i feel it shouldnt.
Any help would be appreciated
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).
EDIT: The code that I have pasted is too long. Basicaly I dont know how to work with the second code, If I know how calculate alpha from the second code I think my problem will be solved. I have tried a lot of input arguments for the second code but it does not work!
I have written following code to solve a convex optimization problem using Gradient descend method:
function [optimumX,optimumF,counter,gNorm,dx] = grad_descent()
x0 = [3 3]';%'//
terminationThreshold = 1e-6;
maxIterations = 100;
dxMin = 1e-6;
gNorm = inf; x = x0; counter = 0; dx = inf;
% ************************************
f = #(x1,x2) 4.*x1.^2 + 2.*x1.*x2 +8.*x2.^2 + 10.*x1 + x2;
%alpha = 0.01;
% ************************************
figure(1); clf; ezcontour(f,[-5 5 -5 5]); axis equal; hold on
f2 = #(x) f(x(1),x(2));
% gradient descent algorithm:
while and(gNorm >= terminationThreshold, and(counter <= maxIterations, dx >= dxMin))
g = grad(x);
gNorm = norm(g);
alpha = linesearch_strongwolfe(f,-g, x0, 1);
xNew = x - alpha * g;
% check step
if ~isfinite(xNew)
display(['Number of iterations: ' num2str(counter)])
error('x is inf or NaN')
end
% **************************************
plot([x(1) xNew(1)],[x(2) xNew(2)],'ko-')
refresh
% **************************************
counter = counter + 1;
dx = norm(xNew-x);
x = xNew;
end
optimumX = x;
optimumF = f2(optimumX);
counter = counter - 1;
% define the gradient of the objective
function g = grad(x)
g = [(8*x(1) + 2*x(2) +10)
(2*x(1) + 16*x(2) + 1)];
end
end
As you can see, I have commented out the alpha = 0.01; part. I want to calculate alpha via an other code. Here is the code (This code is not mine)
function alphas = linesearch_strongwolfe(f,d,x0,alpham)
alpha0 = 0;
alphap = alpha0;
c1 = 1e-4;
c2 = 0.5;
alphax = alpham*rand(1);
[fx0,gx0] = feval(f,x0,d);
fxp = fx0;
gxp = gx0;
i=1;
while (1 ~= 2)
xx = x0 + alphax*d;
[fxx,gxx] = feval(f,xx,d);
if (fxx > fx0 + c1*alphax*gx0) | ((i > 1) & (fxx >= fxp)),
alphas = zoom(f,x0,d,alphap,alphax);
return;
end
if abs(gxx) <= -c2*gx0,
alphas = alphax;
return;
end
if gxx >= 0,
alphas = zoom(f,x0,d,alphax,alphap);
return;
end
alphap = alphax;
fxp = fxx;
gxp = gxx;
alphax = alphax + (alpham-alphax)*rand(1);
i = i+1;
end
function alphas = zoom(f,x0,d,alphal,alphah)
c1 = 1e-4;
c2 = 0.5;
[fx0,gx0] = feval(f,x0,d);
while (1~=2),
alphax = 1/2*(alphal+alphah);
xx = x0 + alphax*d;
[fxx,gxx] = feval(f,xx,d);
xl = x0 + alphal*d;
fxl = feval(f,xl,d);
if ((fxx > fx0 + c1*alphax*gx0) | (fxx >= fxl)),
alphah = alphax;
else
if abs(gxx) <= -c2*gx0,
alphas = alphax;
return;
end
if gxx*(alphah-alphal) >= 0,
alphah = alphal;
end
alphal = alphax;
end
end
But I get this error:
Error in linesearch_strongwolfe (line 11) [fx0,gx0] = feval(f,x0,d);
As you can see I have written the f function and its gradient manually.
linesearch_strongwolfe(f,d,x0,alpham) takes a function f, Gradient of f, a vector x0 and a constant alpham. is there anything wrong with my declaration of f? This code works just fine if I put back alpha = 0.01;
As I see it:
x0 = [3; 3]; %2-element column vector
g = grad(x0); %2-element column vector
f = #(x1,x2) 4.*x1.^2 + 2.*x1.*x2 +8.*x2.^2 + 10.*x1 + x2;
linesearch_strongwolfe(f,-g, x0, 1); %passing variables
inside the function:
[fx0,gx0] = feval(f,x0,-g); %variable names substituted with input vars
This will in effect call
[fx0,gx0] = f(x0,-g);
but f(x0,-g) is a single 2-element column vector with these inputs. Assingning the output to two variables will not work.
You either have to define f as a proper named function (just like grad) to output 2 variables (one for each component), or edit the code of linesearch_strongwolfe to return a single variable, then slice that into 2 separate variables yourself afterwards.
If you experience a very rare kind of laziness and don't want to define a named function, you can still use an anonymous function at the cost of duplicating code for the two components (at least I couldn't come up with a cleaner solution):
f = #(x1,x2) deal(4.*x1(1)^2 + 2.*x1(1)*x2(1) +8.*x2(1)^2 + 10.*x1(1) + x2(1),...
4.*x1(2)^2 + 2.*x1(2)*x2(2) +8.*x2(2)^2 + 10.*x1(2) + x2(2));
[fx0,gx0] = f(x0,-g); %now works fine
as long as you always have 2 output variables. Note that this is more like a proof of concept, since this is ugly, inefficient, and very susceptible to typos.
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.