Newton's method roots on Matlab - matlab

I am not so much experiences with Matlab. I just need it for the sake of solving some lengthy non-linear equations. Instead of using fzero, I wanna use Newton-Raphson's to solve the equation.
newton.m file contains the following code.
function [ x, ex ] = newton( f, df, x0, tol, nmax )
if nargin == 3
tol = 1e-4;
nmax = 1e1;
elseif nargin == 4
nmax = 1e1;
elseif nargin ~= 5
error('newton: invalid input parameters');
end
x(1) = x0 - (f(x0)/df(x0));
ex(1) = abs(x(1)-x0);
k = 2;
while (ex(k-1) >= tol) && (k <= nmax)
x(k) = x(k-1) - (f(x(k-1))/df(x(k-1)));
ex(k) = abs(x(k)-x(k-1));
k = k+1;
end
end
And in the main file, I have called this function as follows:
ext_H = newton( exp(x) + x^3, diff(exp(x) + x^3), 9, 0.5*10^-5, 10);
When I run this function, it gives me the following error.
Error using sym/subsref (line 9)
Error using maplemex
Error, (in MTM:-subsref) Array index out of range
Error in newton (line 37)
x(1) = x0 - (f(x0)/df(x0));
Error in main (line 104)
ext_H = newton( exp(x) + x^3, diff(exp(x) + x^3), 9, 0.5*10^-5, 10);
Could anyone please help me to get through this?

You can probably use Matlab's fsolve (http://uk.mathworks.com/help/optim/ug/fsolve.html) with a couple of options
x0 = 9;
options = optimoptions('fsolve','Algorithm','levenberg-marquardt','TolFun',5*10^-6,'MaxIter',100);
x = fsolve(#(x)(exp(x) + x^3), x0,options);
or just fzero (http://uk.mathworks.com/help/optim/ug/fzero.html) which implements BD algorithm
x = fzero(#(x)(exp(x) + x^3), x0);

Related

Implementing an Optimization problem using matlab

I am trying to implement an Optimization problem using matlab
Where N=100 , M=(N-1/k) and L=50.
N=100;
L = 50;
for K= 101:1:1000
M = (N-1)/K;
R=#(x) -((1./x(2)).*(N- (x(1).*M)-((min ( N./(L.*x(2)), K)-x(1))*(max(0,N-(L.*x(2).*x(1)))))/(x(1)+(min ( N./(L.*x(2)), K)-x(2)))) - (max(0,N-(L.*K*x(2)))));
LB = [1 1];
b=1:min((ceil(N/L)), K) ;
UB = [min((ceil(N./L)), K) ((N./(L*b))) ];
options = optimoptions('fmincon','Algorithm','interior-point'); % run interior-point algorithm
[xopt, vopt] = fmincon(R,1,[],[],[],[],LB,UB,[],options);
v(K) = -vopt;
end
plot(101:1000,v,'v-','LineWidth',2);
xlabel('Number of Users (K)');
ylabel('Delivery Rate (R)');
The following error appears:
Warning: Length of lower bounds is > length(x); ignoring extra bounds.
> In checkbounds (line 27)
In fmincon (line 318)
In R1 (line 19)
Warning: Length of upper bounds is > length(x); ignoring extra bounds.
> In checkbounds (line 41)
In fmincon (line 318)
In R1 (line 19)
Index exceeds array bounds.
Error in
R1>#(x)-((1./x(2)).*(N-(x(1).*M)-((min(N./(L.*x(2)),K)-x(1))*(max(0,N-(L.*x(2).*x(1)))))/(x(1)+(min(N./(L.*x(2)),K)-x(2))))-(max(0,N-(L.*K*x(2)))))
Error in fmincon (line 546)
initVals.f = feval(funfcn{3},X,varargin{:});
Error in R1 (line 19)
[xopt, vopt] = fmincon(R,1,[],[],[],[],LB,UB,[],options);
Caused by:
Failure in initial objective function evaluation. FMINCON cannot continue.
The output graph should be the one shown here:
(the lower bound curve)
Couples of mistakes
First, the initial guess should be an 1D array of length 2, kindly
replace 1 by [1, 1]
Better initialize the variable v first , it will speed up your
computation
The most important is the upper bound of l, as you can see it
depends on s and it's in the denominator, consider it as non linear
constraint then set UB = [] You will need to include nonlcon into
fmincon
The code is as follow
N=100;
L = 50;
t = 101:1:1000;
le = length(t);
v = zeros(1, le);
for K= 100:1:1000
M = (N-1)/K;
R = #(x) -(1./(x(1))).*(N-x(1).*((N-1)./K)-((min(ceil(N./(L.*x(2))), K)).*...
max(N -L.*x(1).*x(2), 0))./((x(1) +(min(ceil(N./(L.*x(2))), K))))...
-(max(N - K.*L.*x(2), 0)));
LB = [1 1];
options = optimoptions('fmincon','Algorithm','interior-point');
[xopt, vopt] = fmincon(R,[1, 1],[],[],[],[],LB,[],...
#(x)nonlincon(x(1), x(2),N, L, K ),options);
v(K-101+1) = -vopt;
end
plot(101:1000,v,'v-','LineWidth',2);
xlabel('Number of Users (K)');
ylabel('Delivery Rate (R)');
function [c, ceq] = nonlincon(s, l,N, L, K )
c(1) = l -N./(L.*s);
c(2) = s - min((ceil(N./L)), K) ;
ceq = [];
end

MATLAB ERROR Feval requires a function handle as the first argument

I have this code (*) and when I do:
»syms x
»newton_raphson({((5400.*(1 + x)*0^360) - (1450000.*x.*(1 + x).^360))}, diff(((5400.*(1 + x)*0^360) - (1450000.*x.*(1 + x).^360)),1), 0.001, eps, 5, 0.1)
this error appears:
Error using feval
Argument must contain a string or function_handle.
Error in newton_raphson (line 10)
fz = feval(f,z(1));
How can I fix this error?
(*)
function [raiz, zn, fz, i] = newton_raphson(f, flinha, x0, eps, iter_max, debug)
if nargin < 4
eps = 1e-6;
end
if nargin < 5
iter_max = 1e3;
end
z(1) = x0;
fz = feval(f,z(1));
fzlinha = feval(flinha,z(1));
if (nargin > 5 && debug > 0)
fprintf(2,'i=%d z=%23.18G fz=%G fzlinha=%G\n',0,x0,fz,fzlinha);
end
for i = 1:iter_max
if abs(fzlinha) == 0 % f'(x0) equal zero
disp('O valor da derivada em Xi não pode ser zero');
z(i+1) = x0;
return
end
z(i+1) = x0 - fz / fzlinha;
fz = feval(f,z(i+1));
fzlinha = feval(flinha,z(i+1));
dif = abs(z(i+1) - x0);
if (nargin > 5 && debug > 0)
fprintf(2,'i=%d z=%23.18G fz=%G fzlinha=%G dif=%E\n',i,z(i+1),fz,fzlinha,dif);
end
if dif < eps
break;
elseif i == iter_max
disp('Foi excedido o número máximo de iterações (iter_max)');
break
end
x0=z(i+1);
end
zn = z';
raiz = z(i+1);
end`
You are passing a symbolic expression to a function designed to evaluate an anonymous function, function handle, or a function on the Matlab path with it's name indicated by a string via feval. If you desire Matlab to do the differentiation for you, you can first use symbolic expressions and then convert them to anonymous functions via matlabFunction like this
syms x f Df
%
% Symbolic expressions
f = (5400.*(1 + x)*0^360) - (1450000.*x.*(1 + x).^360);
Df = diff(f,x);
%
% Convert to anonymous functions
f = matlabFunction(f ,'Vars',x);
Df = matlabFunction(Df,'Vars',x);

Calculate the derivative of the sum of a mathematical function-MATLAB

In Matlab I want to create the partial derivative of a cost function called J(theta_0, theta_1) (in order to do the calculations necessary to do gradient descent).
The function J(theta_0, theta_1) is defined as:
Lets say h_theta(x) = theta_1 + theta_2*x. Also: alpha is fixed, the starting values of theta_1 and theta_2 are given. Let's say in this example: alpha = 0.1 theta_1 = 0, theta_2 = 1. Also I have all the values for x and y in two different vectors.
VectorOfX =
5
5
6
VectorOfX =
6
6
10
Steps I took to try to solve this in Matlab: I have no clue how to solve this problem in matlab. So I started off with trying to define a function in Matlab and tried this:
theta_1 = 0
theta_2 = 1
syms x;
h_theta(x) = theta_1 + t2*x;
This worked, but is not what I really wanted. I wanted to get x^(i), which is in a vector. The next thing I tried was:
theta_1 = 0
theta_2 = 1
syms x;
h_theta(x) = theta_1 + t2*vectorOfX(1);
This gives the following error:
Error using sym/subsindex (line 672)
Invalid indexing or function definition. When defining a
function, ensure that the body of the function is a SYM
object. When indexing, the input must be numeric, logical or
':'.
Error in prog1>gradientDescent (line 46)
h_theta(x) = theta_1 + theta_2*vectorOfX(x);
I looked up this error and don't know how to solve it for this particular example. I have the feeling that I make matlab work against me instead of using it in my favor.
When I have to perform symbolic computations I prefer to use Mathematica. In that environment this is the code to get the partial derivatives you are looking for.
J[th1_, th2_, m_] := Sum[(th1 + th2*Subscript[x, i] - Subscript[y, i])^2, {i, 1, m}]/(2*m)
D[J[th1, th2, m], th1]
D[J[th1, th2, m], th2]
and gives
Coming back to MATLAB we can solve this problem with the following code
%// Constants.
alpha = 0.1;
theta_1 = 0;
theta_2 = 1;
X = [5 ; 5 ; 6];
Y = [6 ; 6 ; 10];
%// Number of points.
m = length(X);
%// Partial derivatives.
Dtheta1 = #(theta_1, theta_2) sum(2*(theta_1+theta_2*X-Y))/2/m;
Dtheta2 = #(theta_1, theta_2) sum(2*X.*(theta_1+theta_2*X-Y))/2/m;
%// Loop initialization.
toll = 1e-5;
maxIter = 100;
it = 0;
err = 1;
theta_1_Last = theta_1;
theta_2_Last = theta_2;
%// Iterations.
while err>toll && it<maxIter
theta_1 = theta_1 - alpha*Dtheta1(theta_1, theta_2);
theta_2 = theta_2 - alpha*Dtheta2(theta_1, theta_2);
it = it + 1;
err = norm([theta_1-theta_1_Last ; theta_2-theta_2_Last]);
theta_1_Last = theta_1;
theta_2_Last = theta_2;
end
Unfortunately for this case the iterations does not converge.
MATLAB is not very flexible for symbolic computations, however a way to get those partial derivatives is the following
m = 10;
syms th1 th2
x = sym('x', [m 1]);
y = sym('y', [m 1]);
J = #(th1, th2) sum((th1+th2.*x-y).^2)/2/m;
diff(J, th1)
diff(J, th2)

MATLAB: How do I use a loop variable in the initial conditions in dsolve?

In MATLAB, I am trying to build a loop which calls dsolve with different initial conditions in each iteration. To accomplish this, I built this loop:
y0 = -2:0.5:2;
y1 = -2:2:2;
syms y(t)
for i = y1
for k = y0
y(t) = dsolve(diff(y,2) + diff(y) - 2*y == t^2 - 4*t + 3,...
['y(0) == ',num2str(k)],['Dy(0) == ',num2str(i)])
end
end
It works through the first iteration, but it fails for the second one with this error:
Error using mupadengine/feval (line 157)
MuPAD error: Error: Invalid equation or initial condition. [ode::splitSys]
Error in dsolve>mupadDsolve (line 325)
T = feval(symengine,'symobj::dsolve',sys,x,options);
Error in dsolve (line 186)
sol = mupadDsolve(args, options);
Error in MWE (line 9)
y(t) = dsolve(diff(y,2) + diff(y) - 2*y == t^2 - 4*t + 3,...
The command works outside the loop for all the initial conditions I have tried. Inside the loop, the first iteration works, the next one always fails. It does not seem to matter which ones I choose.
What's going on?
You can use different name for the solution
y0 = -2:0.5:2;
y1 = -2:2:2;
syms y(t);
for q = y1
for k = y0
ysol(t) = dsolve(diff(y,2) + diff(y) - 2*y == t^2 - 4*t + 3,...
['y(0) == ',num2str(k)],['Dy(0) == ',num2str(q)])
end
end
I would also change i to q
http://www.mathworks.com/help/matlab/ref/i.html

variable in solving the equation

I want to solve equations in matlab, eg.
100+a/2=173*cos(b)
sqrt(3)*a/2=173*sin(b)
and the code would be:
[a,b]=solve('100+a/2=173*cos(b)','sqrt(3)*a/2=173*sin(b)','a','b')
However, if I want to take 100 as a variable, like
for k=1:100
[a,b]=solve('k+a/2=173*cos(b)','sqrt(3)*a/2=173*sin(b)','a','b')
end
There would be an error, how to make it?
degree=140/1000000;
p=42164000;
a=6378136.5;
b=6356751.8;
x_1=0;
y_1=p;
z_1=0;
for i=451:550
for j=451:550
alpha=(1145-i)*degree;
beta=(1145-j)*degree;
x_2=p/cos(alpha)*tan(beta);
y_2=0;
z_2=p*tan(alpha);
syms x y z x_1 x_2 y_1 y_2 z_1 z_2 a b
eq = [(x-x_1)*(y2-y_1)-(x_2-x_1)*(y-y_1),(x-x_1)*(z_2-z_1)-(x_2-x_1)*(z-z_1), b^2*(x^2+y^2)+a^2*(y^2)-a^2*b^2 ];
sol = solve(eq(1),x,eq(2),y, eq(3),z);
sol.x
sol.y
sol.z
end
end
I got the expression value, how do I get the numeric value of x,y,z?
[['x(1)=';'x(2)='],num2str(double(sol.x))]
not work ,shows
??? Error using ==> mupadmex
Error in MuPAD command: DOUBLE cannot convert the input expression into a double array.
If the input expression contains a symbolic variable, use the VPA function instead.
Error in ==> sym.sym>sym.double at 927
Xstr = mupadmex('mllib::double', S.s, 0);
Error in ==> f2 at 38
[['x(1)=';'x(2)='],num2str(double(sol.x))]
If you have access to the Symbolic Toolkit then you do the following:
syms a b k
eq = [k+a/2-173*cos(b), sqrt(3)*a/2-173*sin(b)];
sol = solve(eq(1),a,eq(2),b);
sol.a = simplify(sol.a);
sol.b = simplify(sol.b);
% There are two solutions for 'a' and 'b'
% check residuals for example k=20
subs(subs(eq,{a,b},{sol.a(1),sol.b(1)}),k,20)
% ans = 0.2e-13
subs(subs(eq,{a,b},{sol.a(2),sol.b(2)}),k,20)
% ans = 0.2e-13
Edit 1
Based on new code by OP the matlab script to solve this is:
clear all
clc
syms alpha beta
degree=140/1000000;
p=42164000;
a=6378136.5;
b=6356751.8;
x_1=0;
y_1=p;
z_1=0;
x_2 = p/cos(alpha)*tan(beta);
y_2 = 0;
z_2 = p*tan(alpha);
syms x y z
eq = [(x-x_1)*(y_2-y_1)-(x_2-x_1)*(y-y_1);...
(x-x_1)*(z_2-z_1)-(x_2-x_1)*(z-z_1); ...
b^2*(x^2+y^2)+a^2*(y^2)-a^2*b^2 ];
sol = solve(eq(1),x,eq(2),y,eq(3),z);
sol.x = simplify(sol.x);
sol.y = simplify(sol.y);
sol.z = simplify(sol.z);
pt_1 = [sol.x(1);sol.y(1);sol.z(1)] % First Solution Point
pt_2 = [sol.x(2);sol.y(2);sol.z(2)] % Second Solution Point
x = zeros(100,100);
y = zeros(100,100);
z = zeros(100,100);
for i=451:550
disp(['i=',num2str(i)])
for j=451:550
res = double(subs(pt_1,{alpha,beta},{(1145-i)*degree,(1145-j)*degree}));
x(i-450, j-450) = res(1);
y(i-450, j-450) = res(2);
z(i-450, j-450) = res(3);
end
end
disp('x=');
disp(x);
disp('y=');
disp(x);
disp('z=');
disp(x);
I would try
for i=1:100
k=num2str(i)
[a,b]=solve('100+a/2=173*cos(b)','sqrt(3)*a/2=173*sin(b)','a','b')
end
and then solve the equation