评估MATLAB中的恒定表达
我目前正在编写一个脚本,该脚本从用户那里获取一个函数和间隔,然后使用梯形法计算积分。该脚本还会计算误差。为此,我需要使用输入函数的二阶导数。如果二阶导数为常数或 0,则会出现“输入参数过多”错误。以下是一小段代码,用于说明错误发生的位置:
%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.
matlab 是否有办法计算向量 0:0.01:5,并返回一个大小相同的向量,每个传递的值均为“2”?函数导数是否为常数尚不清楚,取决于用户输入的内容。
听起来,一个逻辑结构应该足以解决这个问题。然而,开发它的挑战来自于必须在三 (3) 种数据类型(
double
、
sym
和
char
)之间进行权衡。我找不到更简洁的方法,但这应该可以解决这个问题(请参阅下面的解释以了解详情):
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
注意:
从现在开始,
x = sym('x')
假设用户定义表达式
f = 3*x^3
,然后对其调用
diff
,因为
der = diff(f,x)
应该输出
der=9*x^2
。由于这是一个非零导数,因此您将继续使用梯形规则算法。但是,假设
f = 2
,调用此新
f
的 diff 函数的结果将是
der = 0
。
注意
:当
diff
对结果为常量的表达式进行微分时,输出将被视为
sym
对象。在此示例中,
0
是
sym
对象,而不是
double
。要将其转换为
double
,可以考虑将其强制转换为
c = double(der)
。问题是,
double()
没有处理
der
仍然是代数表达式的情况的功能(即,如果
der = 3*x
,则
double(der)
返回错误)。但是,函数
char()
可以处理这种情况。实际上,它应该能够将任何
sym
表达式转换为
char
数组。这样就可以使用
str2num()
函数,该函数有一个可选参数,用于确定是否可以进行字符串到双精度(或 char 到双精度)的转换。语法为:
[num,status] = str2num(char(der))
。如果
der =3*x
,则
char(der) = '3*x'
、
num = []
和
status = 0
。然而,对于常数导数的情况,比如
der = 3
,那么
char(der) = '3'
,然后
num = 3
,并且
status = 1
;
@J.A. Ferrand:我无法在您的答案下发表评论(声誉太低),但您提供的解决方案有一个明显的错误。我们应该使用
str2num
,而不是代码第 7 行中的
num2str
。
下面我根据 J.A. Ferrand 的解决方案提供我自己的解决问题的方法。
将常量代数表达式转换为函数句柄是有问题的,因为在这种情况下
matlabFunction
无法“猜测”函数变量的数量以及它们的名称。但是,如果您处理的是具有一定数量输入变量的函数(例如:一个),下面是
matlabFunction
的“改进”版本。
function fh = matlabFunctionImproved(symExp)
% This is an improved version of matlabFunction function,
% that circumvents an "inconvenient" behaviour of the original function
% in case of constant argument.
% Remark: This function works properly only for single-valued functions.
charExp = char(symExp) % Convert algebraic expression to character array.
[num,status] = str2num(charExp) ; % Check to see if symExp is algebraically equivalent to a constant.
if status == 1 %If so
fh = @(x) num * ones(size(x)) ; %Extract its value and copy it along a vector of the same length as the input
else % Run your code essentially.
fh = matlabFunction(symExp);
end
end
如果要使用两个或更多变量的函数,则可以修改所提供的代码...