2

I'm trying to iterate over a function in order to extract the discrete values of a symbolic function:

syms x;
y =  sinc(x);
x = -100:1:100;
for i = 1:length(x)
    t(i) = y(x(i));
end

but it gives me error:

Subscript indices must either be real positive integers or logicals.

if I use:

t(i) = y{i}(x);

it says that:

SYM objects do not allow nested indexing. Assign intermediate values to variables instead.

So how this can be done in matlab, it looks like the linear sampling from symbolic function is somewhat more complicated than expected, or is there a function for this that I'm missing here?

lkn2993
  • 566
  • 7
  • 26
  • Related Q&A that may be helpful: http://stackoverflow.com/questions/20054047/subscript-indices-must-either-be-real-positive-integers-or-logicals-generic-sol/20054048#20054048 – mikkola Dec 16 '15 at 19:49
  • Thanks but this is the thing that I want to do, you know that its not possible to index sym object in general right? – lkn2993 Dec 16 '15 at 19:52
  • How about `y = @(x) sinc(x)` (but then neither `y` or `x` are symbolic, but maybe getting there) – Steve Dec 16 '15 at 19:55
  • or `t(i) = subs(y,'x',x(i));`. (but it doesn't like it for `x=0`) – Steve Dec 16 '15 at 19:57
  • I can give it 0 like if (x(i) ~= 0) subs(y,'x',x(i)); else t(i) = NaN; right? so that would be the answer then(post as answer) – lkn2993 Dec 16 '15 at 20:09

2 Answers2

2

Your y variable is not a symbolic function, but a symbolic expression. If you want to leave it a symbolic expression, you can do something like this:

syms x;
y = sinc(x);
x2 = -100:1:100;               % Don't overwrite your symbolic variable x
t = zeros(length(x2),1,'sym'); % Pre-allocate
for i = 1:length(x2)
    t(i) = subs(y,x,x2(i));
end

Or, more simply:

syms x;
y = sinc(x);
x2 = -100:1:100;
t = subs(y,x,x2);

You can also convert y to a symbolic function:

syms x;
y(x) = sinc(x);
x2 = -100:1:100;
t = y(x2);

Note that in all cases you'll get divide-by-zero error because your x2 vector includes 0. This is because sinc is a numeric function that hasn't been overloaded for symbolic math.

Is there any reason you're not evaluating this numerically?:

y = @(x)sinc(x);
x = -100:1:100;
t = y(x);

If you really need a symbolic sinc function you can create your own vectorized version using MuPAD's piecewise:

sinc_sym = @(x)subs(evalin(symengine,'piecewise([x~=0, sin(x)/x],[Otherwise, 1])'),'x',x);

Or:

sinc_sym = @(x)subs(evalin(symengine,'piecewise([x~=0, sin(pi*x)/(pi*x)],[Otherwise, 1])'),'x',x);
horchler
  • 18,384
  • 4
  • 37
  • 73
1

You've assigned y to a symbolic object, but it is not a function. You can evaluate it at each x(i) with subs:

t(i) = subs(y,'x',x(i));

This has the additional issue that you get an error for x=0, but, as you suggested, could set t(i) with an if statement, something like

 if (x(i) ~= 0)
   subs(y,'x',x(i));
 else 
   t(i) = NaN; % or = 1 (limit of sinc(x) as x -> 0)
 end
Steve
  • 1,579
  • 10
  • 23