在下面的图中,我的目标是在1 / 2 / 3区域内求积分,这样我就知道直线下方有多少区域(1 / 3区域),直线上方有多少区域(2区域)。
我不是在寻找精确的积分,只是一个近似值来测量。一个近似值,它将以同样的方式工作,为其他版本的曲线,我已经表示。
y1:蓝线为线性函数y= -0.148x + 1301.35
y2:黄线是任意曲线
两条曲线共享相同的x轴。
image of curves linear & arbitrary curve
我试过几种方法,在这里找到了关于stackoverflow的方法,主要是这两种方法引起了我的注意:
https://stackoverflow.com/a/57827807
&
https://stackoverflow.com/a/25447819
他们给予我完全相同的输出为整个地区,我的问题是分开它上面/下面。
我的最佳尝试示例:(https://stackoverflow.com/a/25447819/20441461的修改版本)
y1 / y2 / x -是用于上图中曲线的数据
y1 = [1298.54771845, 1298.40019417, 1298.2526699, 1298.10514563,
1297.95762136,1297.81009709, 1297.66257282, 1297.51504854]
y2 = [1298.59, 1297.31, 1296.04, 1297.31, 1296.95, 1299.18, 1297.05, 1297.45]
x = np.arange(len(y1))
z = y1-y2
dx = x[1:] - x[:-1]
cross_test = np.sign(z[:-1] * z[1:])
x_intersect = x[:-1] - dx / (z[1:] - z[:-1]) * z[:-1]
dx_intersect = - dx / (z[1:] - z[:-1]) * z[:-1]
areas_pos = abs(z[:-1] + z[1:]) * 0.5 * dx # signs of both z are same
areas_neg = 0.5 * dx_intersect * abs(z[:-1]) + 0.5 * (dx - dx_intersect) * abs(z[1:])
negatives = np.where(cross_test < 0)
negative_sum = np.sum(x_intersect[negatives])
positives = np.where(cross_test >= 0)
positive_sum = np.sum(x_intersect[positives])`
就是给予我这个结果
负积分= 10.15
正积分= 9.97
仅仅从图片上看,我就可以看出这不可能是正确的值。(直线下面的面积比上面的大得多。)
我已经花了大量时间在这上面了,而且很困--任何建议或建议都是受欢迎的。
2条答案
按热度按时间efzxgjgh1#
下面是一段代码,它 * 精确 * 计算所有区域,并以 * 矢量化 * 的方式(快速)完成计算:
示例:
您的原始示例:
说明
为了理解它是如何工作的,让我们考虑四点的四边形:
[a, b, c, d]
,其中a
和b
位于相同的x
位置,c
和d
也位于相同的x
位置。如果没有边相交,则可以是"直的",否则可以是"扭曲的"。在这两种情况下,我们都考虑扭曲版本相交的交点的x位置,以及在该位置的四边形的实际垂直截面(如果是扭曲的,则为0,或者如果是直的,则为垂直边的加权平均)。假设我们把垂直距离称为
b0
和b1
,它们是有方向的(如果y1 > y2
,则为正),交点在x坐标x + r * dx
处,其中r = |b0| / (|b0| + |b1|)
和是0和1之间的一个因子。对于绞合四边形,左侧(三角形)区域为
b0*r*dx/2
,右侧区域为b1*(1-r)*dx/2
。对于一个直四边形,左边区域(梯形)是
(b0 + br)/2 * r * dx
,右边是(b1 + br) / 2 * (1 - r) * dx
,其中br
是r
水平比例的高度,br = b0 * (1 - r) + b1 * r
。一般来说,我们在计算中总是使用
br
。对于扭曲四边形,它是0,我们可以使用与直四边形相同的表达式。这是消除任何测试并产生纯矢量化函数的关键。剩下的是一点
numpy
表达式来高效地计算所有这些值。示例详细信息
以前面的例子为例:
还有:
中的一个
vddsk6oq2#
也许您可以对两个数组的绝对差进行积分: