在没有 SMT 的情况下在 MATLAB R2016A 中生成分段函数
Generating piecewise functions in MATLAB R2016A without SMT
在符号数学工具箱中使用没有分段的 r2016a。希望分段使用以下内容,但使用各种方法都失败了。预先感谢您的建议。
函数:
(3*x^2)/100 + 30 if x<22.3607
x^2/100 + 40 if 22.3607<=x<=109.5445
(3*x^2)/400 + 70 if x>109.5445
选项 1) SMT 可能允许:
y(x) = piecewise([x<22.3607, (3*x^2)/100 + 30], [22.3607<=x<=109.5445, x^2/100 + 40], [x>109.5445, (3*x^2)/400 + 70)]);
结果:
Undefined function or variable 'piecewise'.
选项 2) 创建函数:
%%%%%%%%%%%%%%%%%%%%%
function y = y(x)
if x<=22.3607;
y = (3*x^2)/100 + 30;
else if 22.3607<x<=109.5445;
y = x^2/100 + 40;
else if 109.5445<x;
y = (3*x^2)/400 + 70;
end
end
end
%%%%%%%%%%%%%%%%%%%%%
结果:
q_piecewise
Not enough input arguments.
q_piecewise 错误(第 3 行)
如果 x<=22.3607;
选项 3) 使用重边:
y = ['(heaviside(x)-heaviside(x-22.3607))*((3*x^2)/100 + 30) + ' ...
'(heaviside(x-22.3607)-heaviside(x-109.5445))*(x^2/100 + 40) + ' ...
'(heaviside(x-109.5445)-heaviside(x-800))*((3*x^2)/400 + 70)'];
yinv = finverse(y,x)
结果(尝试计算逆):
yinv =
10.0*(x - 40.0)^(1/2)
我希望能够将 x 的值输入到此分段方程中并接收 y 的值。理想情况下,我也想对上述分段函数的反函数执行此操作。此外,我想计算 diff() 和 int(),所以我相信符号函数最适合这个。想法?谢谢!!
- 布莱恩
来自沃尔特·罗伯森:
在R2016b之前没有MATLAB的分段接口。可以使用 evalin(symengine) 在 mupad 级别构造分段对象,但不能创建它的函数。
f = evalin(symengine,'piecewise([x<5,x^2],[x>=5,-x])')
你可以将 subs() 转换为 f 或者你可以 int(f, x)
通过 MATLAB 级别的程序构建分段需要一些 non-obvious 步骤。我需要进行一些搜索才能找到发布所需辅助函数的位置...
找到了。
您需要构建列表的辅助函数,并且您需要 feval(symengine, 'piecewise',LIST,LIST,...)
white LIST 是由辅助函数构建的。
或者,来自 Star Strider:
y = @(x) ((3*x.^2)/100 + 30) .* (x<22.3607) + (x.^2/100 + 40) .* ((22.3607<=x) & (x<=109.5445)) + ((3*x.^2)/400 + 70) .* (x>109.5445);
t = linspace(0, 150, 500);
figure(1)
plot(t, y(t))
grid
xlabel('t')
ylabel('y(t)')
title('Original Fincton')
yi = linspace(min(y(t)), max(y(t)), 20); % Interpolate Inverse
ti = interp1(y(t),t, yi, 'linear');
figure(2)
plot(y(t), t) % Plot Inverse
hold on
plot(yi, ti, 'pg', 'MarkerFaceColor','g') % Inverse Interpolated Values
hold off
grid
xlabel('y(t)')
ylabel('t')
title('Inverse Function')
它利用了逻辑索引,然后只需添加向量片段即可创建一条连续线。
反函数与 interp1 函数一起使用。
在符号数学工具箱中使用没有分段的 r2016a。希望分段使用以下内容,但使用各种方法都失败了。预先感谢您的建议。
函数:
(3*x^2)/100 + 30 if x<22.3607
x^2/100 + 40 if 22.3607<=x<=109.5445
(3*x^2)/400 + 70 if x>109.5445
选项 1) SMT 可能允许:
y(x) = piecewise([x<22.3607, (3*x^2)/100 + 30], [22.3607<=x<=109.5445, x^2/100 + 40], [x>109.5445, (3*x^2)/400 + 70)]);
结果:
Undefined function or variable 'piecewise'.
选项 2) 创建函数:
%%%%%%%%%%%%%%%%%%%%%
function y = y(x)
if x<=22.3607;
y = (3*x^2)/100 + 30;
else if 22.3607<x<=109.5445;
y = x^2/100 + 40;
else if 109.5445<x;
y = (3*x^2)/400 + 70;
end
end
end
%%%%%%%%%%%%%%%%%%%%%
结果:
q_piecewise Not enough input arguments.
q_piecewise 错误(第 3 行) 如果 x<=22.3607;
选项 3) 使用重边:
y = ['(heaviside(x)-heaviside(x-22.3607))*((3*x^2)/100 + 30) + ' ...
'(heaviside(x-22.3607)-heaviside(x-109.5445))*(x^2/100 + 40) + ' ...
'(heaviside(x-109.5445)-heaviside(x-800))*((3*x^2)/400 + 70)'];
yinv = finverse(y,x)
结果(尝试计算逆):
yinv = 10.0*(x - 40.0)^(1/2)
我希望能够将 x 的值输入到此分段方程中并接收 y 的值。理想情况下,我也想对上述分段函数的反函数执行此操作。此外,我想计算 diff() 和 int(),所以我相信符号函数最适合这个。想法?谢谢!!
- 布莱恩
来自沃尔特·罗伯森:
在R2016b之前没有MATLAB的分段接口。可以使用 evalin(symengine) 在 mupad 级别构造分段对象,但不能创建它的函数。
f = evalin(symengine,'piecewise([x<5,x^2],[x>=5,-x])')
你可以将 subs() 转换为 f 或者你可以 int(f, x)
通过 MATLAB 级别的程序构建分段需要一些 non-obvious 步骤。我需要进行一些搜索才能找到发布所需辅助函数的位置...
找到了。
您需要构建列表的辅助函数,并且您需要 feval(symengine, 'piecewise',LIST,LIST,...)
white LIST 是由辅助函数构建的。
或者,来自 Star Strider:
y = @(x) ((3*x.^2)/100 + 30) .* (x<22.3607) + (x.^2/100 + 40) .* ((22.3607<=x) & (x<=109.5445)) + ((3*x.^2)/400 + 70) .* (x>109.5445);
t = linspace(0, 150, 500);
figure(1)
plot(t, y(t))
grid
xlabel('t')
ylabel('y(t)')
title('Original Fincton')
yi = linspace(min(y(t)), max(y(t)), 20); % Interpolate Inverse
ti = interp1(y(t),t, yi, 'linear');
figure(2)
plot(y(t), t) % Plot Inverse
hold on
plot(yi, ti, 'pg', 'MarkerFaceColor','g') % Inverse Interpolated Values
hold off
grid
xlabel('y(t)')
ylabel('t')
title('Inverse Function')
它利用了逻辑索引,然后只需添加向量片段即可创建一条连续线。
反函数与 interp1 函数一起使用。