【问题标题】:How to write/code several functions as one如何将多个功能编写/编码为一个
【发布时间】:2015-08-27 18:10:28
【问题描述】:

我正在尝试在 中写一条由两段组成的线作为一个方程:

y = m1*x + c1 , for x<=x1
y = m2*x + c2 , for x>=x1

我的问题是:

  1. 如何将这条组合线的函数写成一个方程?
  2. 如何将多个函数(在线性参数空间的不同区域中有效)编写为一个方程?

请解释如何以数学方式表达这一点,以及如何在一般情况下特别是在 Matlab 中对此进行编程。

【问题讨论】:

  • 是的,它是分段线性的。我想知道,是否可以用一个方程来表示 [A 到 B] ?如果是,那是什么?
  • 作为记录,您可以通过检查断点的x 坐标来破解它,并使用 Heaviside 函数从两个公式中选择x 更小并且比断点更大......但仍然没有编程。我的意思是y(x)=H(x1-x)*(m1*x+c1) + H(x-x1)*(m2*x+c2),其中x1 是断点的x 坐标...
  • @barceloco,对题外话问题给出彻底的回答,然后重写问题以包括编程。非常顺利:D
  • @AndrasDeak touché :-) 我们需要保持这些问题的高质量和主题,对吧? ;-)
  • @barceloco 当然,但我现在必须删除我的反对票:P

标签: matlab


【解决方案1】:

您可以使用 Heaviside 阶跃函数 https://en.wikipedia.org/wiki/Heaviside_step_function 将此方程写成一行。

将两个功能合二为一:

其实你想做的是

f(x) = a(x)   (for x < x1)
f(x) = q      (for x = x1), where q = a(x1) = b(x1)
f(x) = b(x)   (for x > x1)

(半最大值)Heaviside 函数定义为

H(x) = 0      (for x < 0)
H(x) = 0.5    (for x = 0)
H(x) = 1      (for x > 0)

因此,您的功能将是

f(x) = H(x1-x) * a(c) + H(x-x1) * b(x)

因此,

f(x) = H(x1-x) * (m1*x+c1) + H(x-x1) * (m2x+c2)

如果你想实现这个,请注意许多编程语言都允许你编写类似

f(x) = (x<x1)?a(x):b(x)

这意味着如果x&lt;x1,则返回值a(x),否则返回b(x),或者在你的情况下:

f(x) = (x<x1)?(m1*x+c1):(m2x+c2)

Matlab 实现:

在Matlab中,可以编写简单的函数如

a = @(x) m1.*x+c1,
b = @(x) m2.*x+c2,

假设您之前定义了m1m2c1c2

有几种方法可以使用/实现 Heaviside 函数

  1. 如果你有Matlab的Symbolic Math Toolbox,可以直接使用heaviside()作为函数。
  2. @AndrasDeak(见下面的cmets)指出,你可以在Matlab中通过输入自己编写半最大Heaviside函数H

    iif = @(varargin) varargin{2 * find([varargin{1:2:end}], 1, 'first')}();
    H = @(x) iif(x<0,0,x>0,1,true,0.5);
    
  3. 如果你想要一个逼近Heaviside函数的连续函数,可以使用逻辑函数H定义为

    H = @(x) 1./(1+exp(-100.*x));
    

独立于您对 Heaviside 函数 H 的实现,您可以通过以下方式创建单线(为简单起见,我使用 x1=0):

a = @(x) 2.*x + 3;
b = @(x) -1.5.*x + 3;

这允许您将原始函数编写为单行:

f = @(x) H(-x).*a(x) + H(x).*b(x);

然后你可以绘制这个函数,例如从 -10 到 10,通过写 plot(-10:10, f(-10:10)) 你会得到下面的图。

概括:

假设你有

f(x) = a(x)   (for x < x1)
f(x) = q      (for x = x1), where q = a(x1) = b(x1)
f(x) = b(x)   (for x1 < x < x2)
f(x) = r      (for x = x2), where r = b(x2) = c(x2)
f(x) = c(x)   (for x2 < x < x3)
f(x) = s      (for x = x2), where s = c(x3) = d(x3)
f(x) = d(x)   (for x3 < x)

通过将 Heaviside 函数相乘,您现在可以确定将计算特定函数的区域。

f(x) = H(x1-x)*a(c) + H(x-x1)*H(x2-x)*b(x) + H(x-x2)*H(x3-x)*c(x) + H(x-x3)*d(x)

PS:刚刚意识到上面的一个 cmets 也谈到了 Heaviside 函数。感谢@AndrasDeak。

【讨论】:

  • 请注意,matlab 有一个名为 heaviside 的函数,约定为 heaviside(0)==0.5
  • @AndrasDeak :正确,感谢您指出这一点。事实上,人们可以购买Symbolic Math Toolbox,其中包含heaviside()功能。上面描述的逻辑函数是一个很好的近似值,但如果你有Symbolic Math Toolbox,请直接使用heaviside :-)
  • 你完全正确,对不起,出于某种原因,我认为这是一个内置的。好吧,那我建议iif = @(varargin) varargin{2 * find([varargin{1:2:end}], 1, 'first')}(); H=@(x)iif(x&lt;0,0,x&gt;0,1,true,0.5):)
  • @AndrasDeak:漂亮!!我刚刚学到了一些东西。感谢您展示如何在单行中实现正确的 Heaviside 功能。我会把它添加到答案中。干杯
  • 好吧,老实说,两条线;)我今天自己才学到这一点,请参阅this comment。积分转到 @beaker 以进行查找。
猜你喜欢
  • 1970-01-01
  • 2020-09-16
  • 1970-01-01
  • 2023-03-17
  • 2017-05-05
  • 2021-12-19
  • 1970-01-01
  • 2014-04-09
  • 1970-01-01
相关资源
最近更新 更多