Search code examples
matlabsymbolic-math

Element wise evaluation of symbolic functions in Matlab


I have a vector of symbolic expressions and a vector of points. I then want to obtain a vector, where 1st element is the first symbolic function evaluated at the first point, second - value of the second function at the second point etc. I can do this with the 'for' loop like this

>> syms x
>> f=formula([x, x^2, x^3]);
>> a=[1, 2, 3];
>> ans=zeros(1,3);
>> for i=1:3
z(x)=f(i);
ans(i)=z(a(i));
end
>> ans
ans =
     1     4    27

But is there a way to avoid loops? Some kind of element-wise evaluation?

Thanks in advance!


Solution

  • This is an additional answer to your question, supposing that we had to use the symbolic math toolbox instead. First, create your formula as normal:

    syms x
    f = formula([x, x^2, x^3);
    

    You can then use subs to substitute values of x with values that you want. subs has syntax like so:

    out = subs(f, val);
    

    val can be a single value, vector or matrix of values that you wish to substitute the variables in your formula with. If you want to use a vector, it's important that you specify this as a column vector. You'll see why later.

    The crux behind this is that for each value of x you want to use for substituting, it will replace the entire formula with x. In other words, if you did out = subs(f, [1;2;3]);, this will output a matrix where the first row consists of x=1, the next row consists of x=2 and the last row consists of x=3. If you did out = subs(f,[1 2 3]);, this will give you a 9 x 1 vector, where each trio of three is the output for that particular x value.

    This isn't exactly what you want, but you can simply choose all of the elements along the diagonal when you specify the input as a column vector as your output, as this would exactly correspond the i'th entry of the element in your vector with the i'th formula.

    In other words:

    A = (1:3).';
    out = subs(f, A)
    
    out =
    
    [ 1, 1,  1]
    [ 2, 4,  8]
    [ 3, 9, 27]
    
    finalOut = diag(out)
    
    finalOut =
    
      1
      4
     27
    

    This is really the only way I can see this without using a for loop. Bear in mind that this is only for a single vector. If you want the actual double values instead of it being represented as sym, you'll need to cast the output using double().