Scilab:如何使用“numderivative”函数
Scilab: How to use ´numderivative´ function
- 我是
Scilab
的新用户,我不是数学家。
- 作为我的 最终目标 ,我想计算(并绘制)分段定义函数的导数,请参阅 here。
- 我试着从小做起,只使用一个简单的(连续的)函数:
f(x) = 3*x
。
- 我的 Google-Fu 引导我进入 numderivative 函数。
- 问题: 看来我不明白参数
x
是如何工作的,因为结果不是一维数组,而是一个矩阵。
- 更新 1:也许我使用了错误的函数,
diff
是正确的方法。但是 numderivative
的目的是什么?
PS:这里是询问 Scilab 相关问题的正确地点吗?似乎有几个 Whosebug 社区提出了与 Scilab 相关的问题。
// Define limits
x0 = 0;
x1 = 2;
// Define array x for which the derivative will be calculated.
n = 100;
x = linspace (x0, x1, n);
// Define function f(x)
deff('y=f(x)','y=3*x');
// Calculate derivative of f(x) at the positions x
myDiff = numderivative(f,x)
(我希望结果是 3 3
而不是矩阵。)
numderivative(f,x) 将为您提供单个向量 x 处 f 的近似值 derivative/Jacobian。对于您的示例,它产生 3 倍的单位矩阵,这是自 f(x)=3*x 以来的预期结果。如果您更愿意将 f 的导数视为 x=1 和 x=2 处的单个 标量 变量的函数,则 numderivative 不方便,因为您必须进行显式循环.自己编写公式(这里是一阶公式):
// Define limits
x0 = 0;
x1 = 2;
// Define array x for which the derivative will be calculated.
n = 100;
x = linspace (x0, x1, n);
// Define function f(x)
deff('y=f(x)','y=3*x');x = [1 2];
h = sqrt(%eps);
d = (f(x+h)-f(x))/h;
公式可以改进(二阶或复阶公式)。
我不小心(但幸运的是)找到了一个优雅的解决方案,可以解决您的 最终目标 (以及我的)通过 SciLab 文档本身通过 splin
(https://help.scilab.org/docs/6.1.1/en_US/splin.html) and interp
(https://help.scilab.org/docs/6.1.1/en_US/interp.html) 函数。这不仅适用于 piece-wise 定义的函数,而且适用于由数据定义的数字函数。
前者会给你相应的数组值的一阶导数,而后者会给你三阶导数。两者实际上是要结合使用的,因为 interp
函数需要您的 y
值的相应导数,您可以 轻松地 通过 splin
函数。使用此方法比使用 diff
函数更好,因为输出数组与原始数组大小相同。
通过您的代码示例说明这一点:
// Define limits
x0 = 0;
x1 = 2;
// Define array x for which the derivatives will be calculated.
n = 100;
x = linspace (x0, x1, n);
// Define function f(x)
deff('y=f(x)','y=3*x');
// Calculate derivative of f(x) at the positions x
myDiff = splin(x, f(x));
// Calculate up to the third derivative of f(x) at the positions x
// The first derivatives obtained earlier are required by this function
[yp, yp1, yp2, yp3]=interp(x, x, f(x), myDiff);
// Plot and label all the values in one figure with gridlines
plot(x', [yp', yp1', yp2', yp3'], 'linewidth', 2)
xgrid();
// Put the legend on the upper-left by specifying 2 after the list of legend names
legend(['yp', 'yp1', 'yp2', 'yp3'], 2);
- 我是
Scilab
的新用户,我不是数学家。 - 作为我的 最终目标 ,我想计算(并绘制)分段定义函数的导数,请参阅 here。
- 我试着从小做起,只使用一个简单的(连续的)函数:
f(x) = 3*x
。 - 我的 Google-Fu 引导我进入 numderivative 函数。
- 问题: 看来我不明白参数
x
是如何工作的,因为结果不是一维数组,而是一个矩阵。 - 更新 1:也许我使用了错误的函数,
diff
是正确的方法。但是numderivative
的目的是什么?
PS:这里是询问 Scilab 相关问题的正确地点吗?似乎有几个 Whosebug 社区提出了与 Scilab 相关的问题。
// Define limits
x0 = 0;
x1 = 2;
// Define array x for which the derivative will be calculated.
n = 100;
x = linspace (x0, x1, n);
// Define function f(x)
deff('y=f(x)','y=3*x');
// Calculate derivative of f(x) at the positions x
myDiff = numderivative(f,x)
(我希望结果是 3 3
而不是矩阵。)
numderivative(f,x) 将为您提供单个向量 x 处 f 的近似值 derivative/Jacobian。对于您的示例,它产生 3 倍的单位矩阵,这是自 f(x)=3*x 以来的预期结果。如果您更愿意将 f 的导数视为 x=1 和 x=2 处的单个 标量 变量的函数,则 numderivative 不方便,因为您必须进行显式循环.自己编写公式(这里是一阶公式):
// Define limits
x0 = 0;
x1 = 2;
// Define array x for which the derivative will be calculated.
n = 100;
x = linspace (x0, x1, n);
// Define function f(x)
deff('y=f(x)','y=3*x');x = [1 2];
h = sqrt(%eps);
d = (f(x+h)-f(x))/h;
公式可以改进(二阶或复阶公式)。
我不小心(但幸运的是)找到了一个优雅的解决方案,可以解决您的 最终目标 (以及我的)通过 SciLab 文档本身通过 splin
(https://help.scilab.org/docs/6.1.1/en_US/splin.html) and interp
(https://help.scilab.org/docs/6.1.1/en_US/interp.html) 函数。这不仅适用于 piece-wise 定义的函数,而且适用于由数据定义的数字函数。
前者会给你相应的数组值的一阶导数,而后者会给你三阶导数。两者实际上是要结合使用的,因为 interp
函数需要您的 y
值的相应导数,您可以 轻松地 通过 splin
函数。使用此方法比使用 diff
函数更好,因为输出数组与原始数组大小相同。
通过您的代码示例说明这一点:
// Define limits
x0 = 0;
x1 = 2;
// Define array x for which the derivatives will be calculated.
n = 100;
x = linspace (x0, x1, n);
// Define function f(x)
deff('y=f(x)','y=3*x');
// Calculate derivative of f(x) at the positions x
myDiff = splin(x, f(x));
// Calculate up to the third derivative of f(x) at the positions x
// The first derivatives obtained earlier are required by this function
[yp, yp1, yp2, yp3]=interp(x, x, f(x), myDiff);
// Plot and label all the values in one figure with gridlines
plot(x', [yp', yp1', yp2', yp3'], 'linewidth', 2)
xgrid();
// Put the legend on the upper-left by specifying 2 after the list of legend names
legend(['yp', 'yp1', 'yp2', 'yp3'], 2);