0

I'm having a problem with a user defined function I am constructing here. What I'm trying to do is to substitute a value into a symbolic function and then use that numerical answer for various purposes. Specifically here:

x = xo;
subst = subs(f,x);
while((n>i) && (subst > eps))

Running my program, I get the following error:

>> sym_newtonRaphson(f,fdiff,1,1e-8,10)
Conversion to logical from sym is not possible.

Error in sym_newtonRaphson (line 8)

I've tried using double(subs(f,x)) to no avail. I seem to be getting a totally different error relating to MuPAD (DOUBLE cannot convert the input expression into a double array.)

The following is the whole program:

function [output] = sym_newtonRaphson(f,fdiff,xo,eps,n)

i = 0;
%initial iteration
x = xo;
subst = subs(f,x);

  while((n>i) && (subst > eps))
     x = x - (subs(f,x))/fdiff;
     i = i+1;
     subst = subs(f,x);
     %fprintf('%f\t%f\t%f\t%f\t%f\t%f',i,alpha,f(
  end
  output = x;
end

I'd appreciate some pointers as to what I'm doing wrong; all the best.

  • 1
    FYI. It looks like you're passing [`eps`](http://www.mathworks.com/help/matlab/ref/eps.html) in as an argument to your function. `eps`, [machine epsilon](http://en.wikipedia.org/wiki/Machine_epsilon), is a builtin constant (and function) available anywhere in Matlab. You don't need to pass it in and it's usually a good idea to avoid variable names that match common builtin function names (I don't care what people say [about `i` and `j`](http://stackoverflow.com/questions/14790740) though). If you like, create an argument called `tol` for your function and set it equal to `eps` or `1e-8`. – horchler Jun 02 '13 at 23:28
  • I use epsilon here as a tolerance value that I must input, but thank you for the tip. –  Jun 02 '13 at 23:33
  • 1
    try using `eval` instead of `subs` – Rasman Jun 03 '13 at 00:09
  • If we knew what `f` and `xo` looked like, we could have a better idea of what was going on. – horchler Jun 03 '13 at 00:40
  • That would be: `f=8-4.5*(x-sin(x))` and `xo` is simply 1 as I showed here. –  Jun 03 '13 at 00:47
  • Tried using `eval` and it works wonderfully. Thank you. –  Jun 03 '13 at 00:57

1 Answers1

1

What you're trying to do with the while expression is equivalent to logical(f), where f is a symbolic function (rather than a symbolic value). logical(sym('exp(1)') > 0) is fine, but logical(sym('exp(f)') > 0) is generally not going to be (see assume). Matlab has no way of casting a symbolic variable to a logical (true and false) one. It tries to do this because the short circuit AND operator, &&, isn't supported for symbolic variables. For example

a = 1.5;
syms x;

% All of these will not generate errors
y1 = x > 1;
y2 = x > 1 & x < 2;
y3 = x > 1 & x < 2;
y4 = x > 1 & a < 2;
y5 = x > 1 & a > 2;

% These will result in errors
y2 = x > 1 && x < 2;
y3 = x > 1 && x < 2;
y4 = x > 1 && a < 2;
y5 = x > 1 && a > 2;

You should print out subst and make sure that it is a symbolic value or a function that does not include any variables (if argnames(subst) returns an empty symbolic matrix then you should be okay). The fact that you get the second error when you call double seems to imply that subst is actually an expression that still includes unknown variables. If this is the case, then you'll either need to substitute in other variables or use assumptions (see here) in order to do logical comparisons as you're doing.

horchler
  • 17,884
  • 4
  • 31
  • 65