Search code examples
functionmatlab

Evaluate a constant expression in matlab


I am currently writing a script that takes a function and interval from the user and then evaluates the integral using the trapezoid method. The script also evaluates the error. To do so, I need to use the second derivative of the function entered. In the case where the second derivative is a constant or 0, I get the Too many input arguments error. Here is a small section of the code to illustrate where the error happens:

%integrate x^2 from 0 to 5
syms x
func = x^2;
deriv = diff(func,x,2);
func = matlabFunction(func);
deriv = matlabFunction(deriv);
deriv(0:0.01:5); %<- error since deriv = 2, needed to compute the error on the trapezoid method.

Is there a way for matlab to evaluate the vector 0:0.01:5 and return a vector of the same size with the value "2" for each value passed? Whether the function deriv is a constant or not is unknown and depends on what the user enters.


Solution

  • From the sounds of it, a logical structure should suffice to address the problem. The challenge in developing it, however, stems from having to juggle between three(3) data types (double, sym, and char). I couldn't find a crisper way, but this should handle the issue (see explanation below it for insight):

    syms x
    func = x^2;
    deriv = diff(func,x,2);
    IN = *input vector*; %User-defined input vector.
    N = length(IN); %Get length of input vector.
    algebra = char(deriv); %Convert algebraic expression "deriv" to character array.
    [num,status] = num2str(algebra); %Check to see if "deriv" is algebraically equivalent to a constant.
    if status == 1 %If so
        deriv = num*ones(N,1) %Extract its value and copy it along a vector of the same length as the input
    else %Run your code essentially.
        func = matlabFunction(func);
        deriv = matlabFunction(deriv);
        deriv(0:0.01:5);
    end
    

    NOTE: From here on out, x = sym('x')

    Say the user defines the expression f = 3*x^3, then, calling diff on it as der = diff(f,x) should output der=9*x^2. Since this is a non-zero derivative, then you would proceed with the trapezoidal rule algorithm. However, say f = 2, the result of calling the diff function of this new f would be der = 0. BEWARE: when diff differentiates an expression that results in a constant, the output is considered at sym object. In this example 0 is a sym object, not a double. To convert it to a double, one could think to cast it so as c = double(der). The problem is, that double() does not have the functionality to handle the cases when der is still an algebraic expression (i.e. if der = 3*x, then double(der) returns an error). The function char(), however, can handle that. In fact, it should be able to convert any sym expression to a char array. This then permits the use of the str2num() function, which has an optional parameter to determine if string-to-double (or char-to-double) conversion is possible or not. The syntax is: [num,status] = str2num(char(der)). If der =3*x, then char(der) = '3*x', num = [], and status = 0. However, for the constant derivative case, say der = 3, then char(der) = '3', then num = 3, and status = 1;