Reputation: 3
I am trying to write a modified Newton formula in MATLAB, but MATLAB shows results in symbolic (x) form, not numeric. Here is the code:
clc
format long g
syms x;
fun = input ('Enter the function f(x)= : ','s');
f=inline(fun);
z=diff(f(x));
f1=inline(z);
z1=diff(f1(x));
f2=inline(z1);
u1=f(x)/f1(x);
u2=1-[(f(x)*f2(x))/(f1(x)^2)];
x0=input('enter the first guess x0=: ');
for i=0:6
xn=x
x=xn-[u1/u2];
if x==xn
break
end
end
And here are the results:
Enter the function f(x)= : x^2-2
enter the first guess x0=: 1
xn =
x
xn =
x + (x^2 - 2)/(2*x*((2*x^2 - 4)/(4*x^2) - 1))
xn =
x + (x^2 - 2)/(x*((2*x^2 - 4)/(4*x^2) - 1))
xn =
x + (3*(x^2 - 2))/(2*x*((2*x^2 - 4)/(4*x^2) - 1))
xn =
x + (2*(x^2 - 2))/(x*((2*x^2 - 4)/(4*x^2) - 1))
xn =
x + (5*(x^2 - 2))/(2*x*((2*x^2 - 4)/(4*x^2) - 1))
xn =
x + (3*(x^2 - 2))/(x*((2*x^2 - 4)/(4*x^2) - 1))
how can i fix it? Thanks.
Upvotes: 0
Views: 79
Reputation: 4558
It is the inlines that causes trouble. If you are going to use something similar you should use anonymous functions, since inline functions are deprecated and about to be removed. However, when going symbolic this is completely redundant. It will only cause more trouble for you, so I strongly suggest that you get rid of the inlines. Normally eval
is not recommended, but for this application it ought to be ok. I guess that there is other ways to do this, but I feel that eval feels intuitive when evaluation expressions.
Further you should consider an approach when you use a function call instead of input. function xout = newton(symbolicExpression, initialGuess)
. This is more dynamic.
The following code should do what you ask:
clc
format long g
syms x;
fun = input ('Enter the function f(x)= : ','s');
f = eval(fun);
f1 = diff(f);
f2 = diff(f1);
u1 = f/f1;
u2 = 1-( (f*f2)/(f1^2) );
x=input('enter the first guess x0=: ');
for i=0:6
xn=x
x=xn-eval(u1/u2);
if (x-xn)<0.01
break
end
end
Upvotes: 1
Reputation: 13876
The answer is symbolic because x
(and by extension xn
) is defined as a symbolic variable. To have numerical results instead use subs
:
for i=0:6
xn=x;
subs(xn) % display numerical value in the command window
x=xn-[u1/u2];
if abs(subs(x)-subs(xn))<=1e-6 % replace equality test by comparing difference to a small threshold value
break
end
end
Note: you shouldn't do equality test on floating-point numbers, instead you should compare the difference to a small threshold value (see my modified code).
Upvotes: 1