Matlab Newton Raphson - matlab

I asked for help about Matlab task few weeks ago but removed it since it took me some time to solve. Unfortunately, I still have a problem.
Task is: Find a real root of the function f(x)=tanh(x^2 - 9) using at least 3 iterations, using Newton-Raphson method. x= 3.2 show each iteration graphically.
In code "pog" means min. mistake, "br" is counter.
If I don't put a counter, it immediately gives me "NaN", with counter it does write first few calculations.
My code:
clc
clear all
x=3.2;
fx=tanh(x^2-9);
iter=5;
pog=0.01;
br=1;
while br<10;
xk= x-((tanh(x^2-9))/(-2*x*(tanh(x^2 - 9)^2 - 1)));
fprintf ('x=%g\txk=%g\t%g\n', x,xk, abs(xk-x))
if pog>abs(xk-x);
break
end
x=xk;
br=br+1;
end
Thank you in advance!

As far as showing the iterations graphically, this is the best I can do:
clc
clear all
close
G=zeros(20,10);
X=linspace(2.5,3.5,20)
G(:,1)=X;
for i=1:length(X)
x=X(i)
fx=tanh(x^2-9);
pog=0.0001;
br=1;
while br<10;
xk= x-((tanh(x^2-9))/(2*x*sech(9-x^2)^2));
G(i,br+1)=xk;
x=xk;
br=br+1;
end
end
I=tanh(G(:,end).^2-9)<1e-5;
X(I)
plot(G,1:10)
hold off
axis([2.5 3.5 0 5])
X(I) is a list of starting values the converge to the root, and the plot shows iteration number on the y-axis, and the guess at that iteration on the x-axis. You can follow each starting value through and see what happens.
Here's another way of visualising Newton's method. It shows the tangent line that is constructed, and where it passes through 0 which gives you the new x values, from which a vertical line gives you the new function value, which defines a new tangent line for the next iteration. It might help.
clc
clear all
close
G=zeros(20,10);
X=linspace(2.75,3.25,20)
G(:,1)=X;
x2=2:.01:4;f2=#(x) tanh(x.^2-9); %// to help with plotting
for i=1:length(X)
x=X(i)
fx=tanh(x^2-9);
pog=0.0001;
br=1;
xk=x;
while br<10;
%// Newton method step
dx=((tanh(x^2-9))/(2*x*sech(9-x^2)^2));
xk=x-dx;
%// plotting everything
G(i,br+1)=xk;
plot(x2,f2(x2))
hold all
plot(G(i,br:br+1),f2(G(i,br:br+1)),'.','MarkerSize',16)
plot(x2,f2(x)+(x2-x)./(xk-x).*(-f2(x)))
plot(xk,0,'.','MarkerSize',16)
plot(x2,(x2-xk)*(2*xk*sech(9-xk^2)^2)+f2(xk))
plot([xk xk],[-1 1])
plot([2 4],[0 0],'k')
axis([2 4 -1 1])
drawnow
pause
hold off
%// finishing Newton step
x=xk;
br=br+1;
end
hold off
end

Related

Struggling to get convergence to Euler's number

Hi there I’ve been working on trying to plot the convergence of 'e' through using the equation 1/N! with limits from 0 to 9.
clc,clear
terms=[1];
x=10;
for i=2:x
terms(i,1)=terms(i-1,1) + 1/factorial(i);
end
disp(terms)
xplotrange = 0:9;
plot(xplotrange,terms,'b-')
With the code I intened to plot the number of terms in the 'x' axis and the result of the series in the 'y' axis. But I am confused as to why the array of numbers outputted in the for loop converges at 1.718 instead of 2.718?
As #Daniel stated, Euler's number via Taylor expansion should start from x=0 . Thus you can adjust your code to something like below
terms=[1];
x=10;
for i=2:x
terms(i,1)=terms(i-1,1) + 1/factorial(i-1);
end
disp(terms)
xplotrange = 0:9;
plot(xplotrange,terms,'b-')
or a method using cumsum, e.g.,
terms=[1];
x=10;
terms = cumsum(1./factorial(0:x));
disp(terms)
xplotrange = 0:x;
plot(xplotrange,terms,'b-');
Initializing terms with 1 and starting your for loop at 2, you effectively start at i=1, but the sum has to start at i=0. 1/0! is the 1 you are missing.

Incorrect value range shown after numeric integration

I'm trying to plot the probability of error for the following equation using MATLAB, I want to use the command trapz for the numerical integration, the problem is that I get a fine shape for the plot, but the values in the y-axis are wrong, the whole curve should be between 0 and 1.2 but it is between 0.492 and 0.5!! Can anyone just tell me what is wrong in my code, or just give me a hint? I really need help. Here is my formula that I need to plot (written using Maketex):
This is my code:
close all; clear;clc;
Nr=2;Ns=2;
lmda1=.3; lmda2=.3;
lmdas=.1; lmdar=.1;
z= 0.0001:1:40;
k1=2;k2=2;
kr=2.*Nr;ks=2.*Ns;
ax=0;
avg=0.0001:1:40;
em=1;
ch=2;
for alp=1-k1.*.5:ch
for beta=1-k2.*.5:ch
for eta=0:ch
for N=0:ch
for M=0:ch
for Q=0:ch
for id=0:eta
for jd=0:N
for A=0:N-jd
%
up=.25.*exp(-lmda1./2).*(lmda1./2).^(alp).*(lmda2.^2./(4)).^(beta./2).*exp(-lmda2./2).*(lmda1./(4.*em.*avg)).^eta.*(lmda2./(4.*em.*avg)).^N.*exp(-lmdas.*Ns.*.5).*.25.^(ks.*.25-.5).*exp(-lmdar.*Nr.*.5).*.25.^(kr.*.25-.5).*(Ns.*lmdas.*.25).^M.*(Nr.*lmdar.*.25).^Q;
cy=up.*(1./(factorial(eta).*factorial(N).*factorial(M).*factorial(Q).*gamma(eta+alp+1).*gamma(N+beta+1).*gamma(M+ks.*.5).*gamma(Q+kr.*.5)));
cj=cy.*(factorial(eta)./(factorial(id).*factorial(eta-id))).*(factorial(N)./(factorial(jd).*factorial(N-jd))).*gamma(M+id+jd+ks.*.5);
f1=(cj.*(factorial(N-jd)./(factorial(A).*factorial(N-jd-A))).*em.^A.*(((em+1).^(N-jd-A))).*gamma(kr.*.5+Q+A));
f2=f1.*(2.^(kr.*.5+Q+A)).*avg.^(eta+N);
ax=ax+f2;
end
end
end
end
end
end
end
end
end
q2=2;n2=2;N2=1;eta2=1;
fun2 = exp(-z.*avg.*(1+1.5./avg)).*z.^(eta2+N2-1./2).*(1./((1+z).^(q2).*(1./2+z).^(n2)));
out= trapz(z,fun2);
b=.5.*(1-ax.*(1./sqrt(pi)).*out.*avg.^(1./2));
plot(avg,b);grid;
There was a few wrong expressions in your code. Also I suspect you should evaluate the integral within the loop. What is more your integral meshgrid z seems too coarse. The following code gives me a 0~1.2 range for the second term in P(e)
% close all; clear;clc;
Nr=2;Ns=2;
lmda1=.3; lmda2=.3;
lmdas=.1; lmdar=.1;
z= .01:.01:40;
k1=2;k2=2;
kr=2.*Nr;ks=2.*Ns;
ax=0;
avg=z;
em=1;
ch=2;
for alp=1-k1*.5:ch
for beta=1-k2*.5:ch
for eta=0:ch
for N=0:ch
for M=0:ch
for Q=0:ch
for id=0:eta
for jd=0:N
for A=0:N-jd
%
up=.25.*exp(-lmda1./2).*(lmda1.^2./4).^(alp/2).*(lmda2.^2./(4)).^(beta./2).*exp(-lmda2./2).*(lmda1./(4.*em.*avg)).^eta.*(lmda2./(4.*em.*avg)).^N.*exp(-lmdas.*Ns.*.5).*.25.^(ks.*.25-.5).*exp(-lmdar.*Nr.*.5).*.25.^(kr.*.25-.5).*(Ns.*lmdas.*.25).^M.*(Nr.*lmdar.*.25).^Q;
cy=up./((factorial(eta).*factorial(N).*factorial(M).*factorial(Q).*gamma(eta+alp+1).*gamma(N+beta+1).*gamma(M+ks.*.5).*gamma(Q+kr.*.5)));
cj=cy.*(factorial(eta)./(factorial(id).*factorial(eta-id))).*(factorial(N)./(factorial(jd).*factorial(N-jd))).*gamma(M+id+jd+ks.*.5);
f1=(cj.*(factorial(N-jd)./(factorial(A).*factorial(N-jd-A))).*em.^A.*(((em+1).^(N-jd-A))).*gamma(kr.*.5+Q+A));
C=f1.*(2.^(kr.*.5+Q+A)).*avg.^(eta+N);
q2=Q;
n2=M+id+jd+ks/2;
N2=N;
eta2=eta;
fun2 = exp(-z.*avg.*(1+1.5./avg)).*z.^(eta2+N2-1./2).*(1./((1+z).^(q2).*(1./2+z).^(n2)));
itgrl= trapz(fun2)*.01*.01;
v = avg.^(eta2+N2+1./2);
ax=ax+v.*C.*itgrl;
end
end
end
end
end
end
end
end
end
b=.5-.5/pi^.5 *ax;
plot(avg,b);grid;
I don't know why I need to multiply dz twice but this gives me the correct value range. But I think it has something to do with the v vector values.
>> [min(.5/pi^.5 *ax),max(.5/pi^.5 *ax)]
ans =
0.0002 1.2241

Matlab stepwise fit wont run through loop

I am a relatively new Matlab user and possibly biting off more than I can chew with this code. Basically it loops through a stepwise regression time in all of the 1505 columns that have data (it is important that the columns without data are kept)
At the start of the code, the length of some columns is changed due to a lag (predetermined in another code). I think this is causing the problem as I get a dimension mismatch further down in the code (indicated below by a comment). I am quite stuck and not sure how to fix the problem. I would really appreciate anything that is obvious being pointed out to me.
Thanks in advance for any help!
for j = 1:1505
m = lag (1,j) %this is a number between 1 and 6 indicating the best lag
Nc=NDVI(m+1:end,j);
A1c=Approx1 (1:end-m,j);
A2c=Approx2 (1:end-m,j);
A3c=Approx3 (1:end-m,j);
A4c=Approx4 (1:end-m,j);
D1c=Det1 (1:end-m,j);
D2c=Det2 (1:end-m,j);
D3c=Det3 (1:end-m,j);
D4c=Det4 (1:end-m,j);
xx=[A1c, A2c, A3c, A4c, D1c, D2c, D3c, D4c];
yy = Nc;
%Begin Stepwise Regression
if isnan(Nc)
continue
else
[B,SE,PVAL,INMODEL,STATS,NEXTSTEP,HISTORY]= ...
stepwisefit(xx,yy,'penter',.05);
inApprox1(j)=INMODEL(1);
inApprox2(j)=INMODEL(2);
inApprox3(j)=INMODEL(3);
inApprox4(j)=INMODEL(4);
inDpprox7(j)=INMODEL(5);
inDpprox8(j)=INMODEL(6);
inDpprox9(j)=INMODEL(7);
inDpprox10(j)=INMODEL(8);
sstotApprox1(j)=STATS.SStotal; %calculate R^2
ssresidApprox1(j)=STATS.SSresid;
rsq = 1- ssresidApprox1./sstotApprox1
rsq(rsq==Inf) = NaN %Set Inf to NaN
rmse(j)=STATS.rmse; %Extract rmse
rmse(rmse==Inf) = NaN; %Set Inf to NaN
% repeat regresson only on the sigificant variables
if sum(INMODEL,2)>0
xip=0;
for k=1:8 %8 refers to previous 8 variables including intecept
if INMODEL(1,k)==1
xip=xip+1;
xxn(:,xip)=xx(:,k); %ERROR HERE, xip AND k DIMENSION MISMATCH. UNSURE HOW TO SOLVE
end
end
[Bn,SEn,PVALn,INMODELn,STATSn,NEXTSTEPn,HISTORYn]= ...
stepwisefit(xxn,yy,'penter',.05);
rmsen(j)=STATSn.rmse; %Extract rmse
rmsen(rmse==Inf) = NaN; %Set Inf to NaN
end
end
end
Your code bombs because you are not clearing your xxn variable for each new lag. Instead, because your xxn is persisting, I believe that it will end up having the wrong size (the wrong number of rows) the next time you go through the big outermost loop.
In my opinion, you should initialize your xxn variable to zeros of the right size. You could do it in this section of your code...
% repeat regresson only on the sigificant variables
if sum(INMODEL,2)>0
xxn = zeros(size(xx,1),8); %ADD THIS LINE! Initializes to zero.
xip=0;
for k=1:8 %8 refers to previous 8 variables including intecept
if INMODEL(1,k)==1
xip=xip+1;
xxn(:,xip)=xx(:,k); %these should now be the correct dimension
end
end

Newton Raphson in MATLAB

I would like to implement the following: ive written a script that executes the Newton Raphson algorithm for my specific function. Now I would like to write a script that repeats itself using the previous found zero as my next intial starting point:
x=zeros(1,31);
for i=1:31
x(i)=(i-1)/10;
end
y0=0;
for i=1:length(x)
y0=newton(x(i),y0)
end
So, I want this script to execute newton(x,y0). So it will start with newton(0,0), it will find a new value y0 and then I want the script to execute newton(0.1,y0) etc. I want these values to be displayed in a table together with the number of iterates that was needed to find the value y0.
I hope my question is clear. Thanks in regards.
Again: I have a vector x with elements 0, 0.1, 0.2, ...,3
When I implement x(i) with initial value y0 newton(x,y) will give me a value. Then I want the script to execute newton(x,y) again with value x(2) for x and the previous found y0.So I need some kind of loop, but I can't get it done .. :(
EDIT
This is my newton-function:
function nulpunt=newton(x,y0)
tolerantie=1e-8;
iteraties=0;
while (abs(functie1(y0,x))>tolerantie)
y0=y0-functie1(y0,x)/afgeleide_functie1(y0);
iteraties=iteraties+1;
end
if iteraties==100;
fprintf('Maximaal aantal iteraties bereikt')
else
fprintf('De benadering van het nulpunt y*(%.2f) is %.4f gevonden in %d iteraties.\n',x,y0,iteraties)
end
end
Your loop should already use the previous y0 every consecutive time it operates.
If you want to display the y0 and the number of iterations in the Matlab command window, you first need to change the newton-function to return not just y0 but also the number of iterations, iteraties:
function [nulpunt, iteraties]=newton(x,y0)
Also, your function should actually return the final y0as nulpunt:
if iteraties==100;
fprintf('Maximaal aantal iteraties bereikt')
nulpunt = 0; % in this case, no solution was found, return the baseline value;
else
fprintf('De benadering van het nulpunt y*(%.2f) is %.4f gevonden in %d iteraties.\n',x,y0,iteraties)
nulpunt = y0;
end
to display the number of iterations and y0 after each execution of newton, add these two lines after you call the function:
[y0, iteraties] = newton(x(i),y0);
disp(['This point was found: ',num2str(y0)])
disp(['It took ',num2str(iteraties),' iterations.'])
This may actually be redundant, as your function already outputs which y0 it found and how long that took.

Metropolis algorithm in MATLAB -->> error with function handles

i have a piece of metropolis algorithm:
mB=5.79*10^(-9); %Bohr magnetone in eV*G^-1
kB=0.86*10^(-4); %Boltzmann in eV*K^-1
%system parameters
L=60; %side square grid
L2=L*L; % total number grid position
Tstep=5; %step in temperature change (K)
Maxstep=10; %max number of steps
nmcs=5; % cycle numberof Metropolis algorithm
magnet=NaN(1,Maxstep);%store magnetization in "monte carlo images" of sample
%Creation initial point arrangement of magnetic spins
%Outer parameters
H=100000; %Gauss
T=20; % Kelvin
%Energy alteration in spin-reverse
de =# (i,j) (2*mB*H).*mlat(i,j);
%Metropolis probability
pmetro=# (i,j) exp(-de(i,j)./(kB*T));
%Creation and display of initial lattice
mlat=2*round(rand(L,L))-1;
mtotal=sum(mlat(:))./L2
% Alteration of system with time
for ii=1:Maxstep
for imc=1:nmcs
for i=1:L
for j=1:L
if pmetro(i,j)>=1
mlat(i,j)=-mlat(i,j);
elseif rand<pmetro(i,j)
mlat(i,j)=-mlat(i,j);
end
end
end
end
magnet(:,ii)=sum(mlat(:))./L2;
%figure(ii);
%pcolor(mlat);
% shading interp;
end
m1=mean(magnet)
error=std(magnet) ./sqrt(numel(magnet))
fprintf('Temperature = %d K',T)
figure(13)
plot(magnet(1,:),'b.')
axis([0 10 0 0.5])
grid on
xlabel('i (Configuration) ')
ylabel('M/(N*mB)')
Now,the problem is in figure(13).The values it gives me are around zero (0.05,0.02..).It supposes to give me values around 0.3..
Generally,the graph its ok,It gives me the right "shape"(it has points) but as i said around zero.
I really don't know how to put this post in order to be understood.Maybe i have some mistake in the "magnet"matrix ,i don't know.
Anyway,i don't demand from anybody to check it thoroughly ,i am just asking if with a quick look anyone can help.
ΕDIT--->> Also,sometimes when i run the program ,it gives me :
Undefined function or method 'mlat'
for input arguments of type 'double'.
Error in ==> #(i,j)(2*mB*H).*mlat(i,j)
Error in ==>
#(i,j)exp(-de(i,j)./(kB*T))
Error in ==> metropolis at 39
if pmetro(i,j)>=1
EDIT--->>> I found the "mistake" .In my code in the loops where i have the function "pmetro" i replaced it with the "exp(-(2*mB*H).*mlat(i,j)./(kB*T))" and the program worked just fine!!!
Why it didn't work with calling the "pmetro"??How can i overcome this?Is there a problem with function handles in loops?
Blockquote
I very strongly suggest that you try writing code without using any function handles until you're really familiar with Matlab.
The line
de =# (i,j) (2*mB*H).*mlat(i,j);
is what causes your problems. In Matlab, when you define a function handle that refers to, say, an array, the function handle will use the array as it was at the time of definition. In other words, even though mlat changes inside your loop, mlat(i,j) inside the function de is always the same. In fact, you cannot even run this code unless you have previously defined mlat in the workspace.
You should therefore rewrite the main loop as follows
for iStep = 1:maxStep
for imc = 1:mcs
pmetro = $some function of mlat - this can be calculated using the
entire array as input
%# for each element in mlat (and thus pmetro), decide whether
%# you have to switch the spin
switchIdx = pmetro > 1 | pmetro < rand(size(mlat));
mlat(switchIdx) = -mlat(switchIdx);
end
$calculate magnetization$
end
Also, note that there is a command mean to take the average. No need to sum and then divide by the number of elements.