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.
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
;