如何将梯形积分方法调整到自定义零点?
How to adjust trapezoidal integration method to a custom zero point?
我想计算序列向量的积分。由于没有可用的功能,我使用 trapezoidal method1.
iglTzm <- function(x, y) sum(diff(x) * (head(y, -1) + tail(y, -1))) / 2
序列的第一个元素应该是零点,所以原则是:如果序列的值主要低于第一个值,则积分应为负,否则为正,即为0。
考虑矩阵 m1
:
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 6 7 8 8 6 8 10
[2,] 9 9 8 9 9 8 9
[3,] 9 10 10 9 9 9 9
[4,] 9 8 8 8 6 8 9
[5,] 10 10 10 9 10 8 0
[6,] 9 8 9 10 9 9 9
与这些原始值的集成很可能会导致值不一致:
> setNames(apply(m1, 1, iglTzm, 0:6), 1:6)
1 2 3 4 5 6
15 2 -2 7 -52 0
所以我调整序列(行)的第一个值(第 1 列),以便设置正确的符号,并得到矩阵 m2
:
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 0 1 2 2 0 2 4
[2,] 0 0 -1 0 0 -1 0
[3,] 0 1 1 0 0 0 0
[4,] 0 -1 -1 -1 -3 -1 0
[5,] 0 0 0 -1 0 -2 -10
[6,] 0 -1 0 1 0 0 0
从逻辑上讲,这不会改变 iglTzm()
抛出的任何值,因为 diff()
是相同的:
> setNames(apply(m2, 1, iglTzm, 0:6), 1:6)
1 2 3 4 5 6
15 2 -2 7 -52 0
无论如何,因为我不能简单地缩放或反转它,所以我还没有一个绝妙的主意如何调整函数以获得正确的符号,假设是:
# 1 2 3 4 5 6
# 15 -2 2 -7 -52 0
有谁知道如何调整 iglTzm()
以获得符号正确的积分?
m2
的情节应该更能说明原理:
数据
m1 <- matrix(c(6, 7, 8, 8, 6, 8, 10,
9, 9, 8, 9, 9, 8, 9,
9, 10, 10, 9, 9, 9, 9,
9, 8, 8, 8, 6, 8, 9,
10, 10, 10, 9, 10, 8, 0,
9, 8, 9, 10, 9, 9, 9), 6, byrow=TRUE)
m2 <- t(apply(m1, 1, function(x) scale(x, center=x[1], scale=FALSE)))
# plot
par(mfrow=c(2, 3))
lapply(1:nrow(m2), function(x) {
plot(m2[x, ], type="l", main=x)
abline(h=m2[x, 1], col="red", lty=2)
})
首先,还有一个更小但更重要的问题,尽管在修复它之后你的问题仍然有效。我的意思是,由于您在 apply
.
中使用函数的方式,x
和 y
作为函数参数的顺序应该颠倒
但这还不够,现在我们回到您的问题。为此,让我们回忆一下通常的积分:ʃf(x)dx(从 a 到 b 的限制)将积分 f 下面的区域,这是您的函数已经成功完成的。现在你想要的是调整它的水平。但是,如果我们从 a 到 b 进行积分,则与 ʃ(f(x)-f(a))dx = ʃf(x)dx - (b-a)f(a) 相同,这导致
iglTzm <- function(y, x) sum(diff(x) * (head(y, -1) + tail(y, -1))) / 2 - y[1] * (max(x) - min(x))
setNames(apply(m1, 1, iglTzm, 0:6), 1:6)
# 1 2 3 4 5 6
# 9 -2 2 -7 -8 0
刚好只有两个绝对值与x
和y
颠倒的版本不同。让我们看一下第一个函数:它应该是 9 还是 15?我们有 2*2/2 + 1*2 + 1*2/2 + 2*4/2 = 9,所以我们确实想要反转 x
和 y
.
另一种编写函数的方法是
iglTzm <- function(y, x) sum(diff(x) * (head(y - y[1], -1) + tail(y - y[1], -1))) / 2
setNames(apply(m1, 1, iglTzm, 0:6), 1:6)
# 1 2 3 4 5 6
# 9 -2 2 -7 -8 0
编辑:我所说的颠倒只是指函数定义中的顺序或你如何在apply
中使用它;就 y(函数值)和 x(网格值)而言,函数本身很好。
我想计算序列向量的积分。由于没有可用的功能,我使用 trapezoidal method1.
iglTzm <- function(x, y) sum(diff(x) * (head(y, -1) + tail(y, -1))) / 2
序列的第一个元素应该是零点,所以原则是:如果序列的值主要低于第一个值,则积分应为负,否则为正,即为0。
考虑矩阵 m1
:
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 6 7 8 8 6 8 10
[2,] 9 9 8 9 9 8 9
[3,] 9 10 10 9 9 9 9
[4,] 9 8 8 8 6 8 9
[5,] 10 10 10 9 10 8 0
[6,] 9 8 9 10 9 9 9
与这些原始值的集成很可能会导致值不一致:
> setNames(apply(m1, 1, iglTzm, 0:6), 1:6)
1 2 3 4 5 6
15 2 -2 7 -52 0
所以我调整序列(行)的第一个值(第 1 列),以便设置正确的符号,并得到矩阵 m2
:
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 0 1 2 2 0 2 4
[2,] 0 0 -1 0 0 -1 0
[3,] 0 1 1 0 0 0 0
[4,] 0 -1 -1 -1 -3 -1 0
[5,] 0 0 0 -1 0 -2 -10
[6,] 0 -1 0 1 0 0 0
从逻辑上讲,这不会改变 iglTzm()
抛出的任何值,因为 diff()
是相同的:
> setNames(apply(m2, 1, iglTzm, 0:6), 1:6)
1 2 3 4 5 6
15 2 -2 7 -52 0
无论如何,因为我不能简单地缩放或反转它,所以我还没有一个绝妙的主意如何调整函数以获得正确的符号,假设是:
# 1 2 3 4 5 6
# 15 -2 2 -7 -52 0
有谁知道如何调整 iglTzm()
以获得符号正确的积分?
m2
的情节应该更能说明原理:
数据
m1 <- matrix(c(6, 7, 8, 8, 6, 8, 10,
9, 9, 8, 9, 9, 8, 9,
9, 10, 10, 9, 9, 9, 9,
9, 8, 8, 8, 6, 8, 9,
10, 10, 10, 9, 10, 8, 0,
9, 8, 9, 10, 9, 9, 9), 6, byrow=TRUE)
m2 <- t(apply(m1, 1, function(x) scale(x, center=x[1], scale=FALSE)))
# plot
par(mfrow=c(2, 3))
lapply(1:nrow(m2), function(x) {
plot(m2[x, ], type="l", main=x)
abline(h=m2[x, 1], col="red", lty=2)
})
首先,还有一个更小但更重要的问题,尽管在修复它之后你的问题仍然有效。我的意思是,由于您在 apply
.
x
和 y
作为函数参数的顺序应该颠倒
但这还不够,现在我们回到您的问题。为此,让我们回忆一下通常的积分:ʃf(x)dx(从 a 到 b 的限制)将积分 f 下面的区域,这是您的函数已经成功完成的。现在你想要的是调整它的水平。但是,如果我们从 a 到 b 进行积分,则与 ʃ(f(x)-f(a))dx = ʃf(x)dx - (b-a)f(a) 相同,这导致
iglTzm <- function(y, x) sum(diff(x) * (head(y, -1) + tail(y, -1))) / 2 - y[1] * (max(x) - min(x))
setNames(apply(m1, 1, iglTzm, 0:6), 1:6)
# 1 2 3 4 5 6
# 9 -2 2 -7 -8 0
刚好只有两个绝对值与x
和y
颠倒的版本不同。让我们看一下第一个函数:它应该是 9 还是 15?我们有 2*2/2 + 1*2 + 1*2/2 + 2*4/2 = 9,所以我们确实想要反转 x
和 y
.
另一种编写函数的方法是
iglTzm <- function(y, x) sum(diff(x) * (head(y - y[1], -1) + tail(y - y[1], -1))) / 2
setNames(apply(m1, 1, iglTzm, 0:6), 1:6)
# 1 2 3 4 5 6
# 9 -2 2 -7 -8 0
编辑:我所说的颠倒只是指函数定义中的顺序或你如何在apply
中使用它;就 y(函数值)和 x(网格值)而言,函数本身很好。