所以我正在尝试编写一个函数来生成Hermite多项式,并且它正在做一些非常疯狂的事情......当我开始使用不同的h
时,为什么会为n
生成不同的元素?所以输入Hpoly(2,1)
会给出
h = [ 1, 2*y, 4*y^2 - 2]
而Hpoly(3,1)
,
h = [ 1, 2*y, 4*y^2 - 4, 2*y*(4*y^2 - 4) - 8*y]
((4y ^ 2 - 2 )vs(4y ^ 2 - 4 )作为第三个元素)
另外,我无法弄清楚如何实际评估表达式。我试过out = subs(h(np1),y,x)
,但没有做任何事。
代码:
function out = Hpoly(n, x)
clc;
syms y
np1 = n + 1;
h = [1, 2*y];
f(np1)
function f(np1)
if numel(h) < np1
f(np1 - 1)
h(np1) = 2*y*h(np1-1) - 2*(n-1)*h(np1-2);
end
end
h
y = x;
out = h(np1);
end
-------------------------- EDIT -------------------- --------
所以我通过使用while
循环来解决这个问题。我想知道为什么另一种方式不起作用...(并且仍然无法弄清楚如何评估表达式而不仅仅是从一开始就插入x ...我想这并不重要,但仍然会很高兴知道...)
可悲的是,我的代码没有hermiteH
那么快:(我想知道为什么。
function out = Hpoly(n, x)
h = [1, 2*x];
np1 = n + 1;
while np1 > length(h)
h(end+1) = 2*x*h(end) - 2*(length(h)-1)*h(end-1);
end
out = h(end)
end
答案 0 :(得分:3)
为什么你的代码更慢?递归不一定是Matlab的强项,所以你可以使用recurrence relation来改进它。但是,hermiteH
是用C语言编写的,你的循环不会像现在这样快,因为你使用的是while
而不是for
并且不必要地重新分配内存而不是预先分配内存。 hermiteH
甚至可以对第一个系数使用查找表,或者可以使用explicit expression从矢量化中受益。我可能会像这样重写你的函数:
function h = Hpoly(n,x)
% n - Increasing sequence of integers starting at zero
% x - Point at which to evaluate polynomial, numeric or symbolic value
mx = max(n);
h = cast(zeros(1,mx),class(x)); % Use zeros(1,mx,'like',x) in newer versions of Matlab
h(1) = 1;
if mx > 0
h(2) = 2*x;
end
for i = 2:length(n)-1
h(i+1) = 2*x*h(i)-2*(i-1)*h(i-1);
end
然后您可以使用
调用它syms x;
deg = 3;
h = Hpoly(0:deg,x)
返回[ 1, 2*x, 4*x^2 - 2, 2*x*(4*x^2 - 2) - 8*x]
(如果需要,请在输出中使用expand
)。不幸的是,如果x
具有象征性,这将不会快得多。
如果您只对在特定值处评估的多项式的数值结果感兴趣,那么最好完全避免使用符号数学。对于双精度x
,上述函数的值比符号x
快三到四个数量级。例如:
x = pi;
deg = 3;
h = Hpoly(0:deg,x)
产量
h =
1.0e+02 *
0.010000000000000 0.062831853071796 0.374784176043574 2.103511015993210
注意:强>
hermiteH
函数是R2015a +,但假设您仍然可以访问符号数学工具箱而Matlab version
是R2012b +,您也可以尝试调用MuPAD的orthpoly::hermite
。 hermiteH
在引擎盖下使用了这个功能。有关如何从Matlab调用MuPAD函数的详细信息,请参阅here。此函数稍微简单一点,因为它只返回一个单词。使用for
循环:
syms x;
deg = 2;
h = sym(zeros(1,deg+1));
for i = 1:deg+1
h(i) = feval(symengine,'orthpoly::hermite',i-1,x);
end
或者,您可以使用map
对上述内容进行矢量化:
deg = 2;
h = feval(symengine,'map',0:deg,'n->orthpoly::hermite(n,x)');
两者都返回[ 1, 2*x, 4*x^2 - 2]
。