在R

时间:2018-02-22 04:45:39

标签: r for-loop taylor-series

我试图编写一个代码来近似R中Theis水文地质方程中的以下无限泰勒级数。

Well equation (part of the Theis equation

我对功能编程很陌生,所以这是一个挑战!这是我的尝试:

Wu <- function(u, repeats = 100) {
result <- numeric(repeats) 
for (i in seq_along(result)){
result[i] <- -((-u)^i)/(i * factorial(i))
}
return(sum(result) - log(u)-0.5772)
}

我已将结果与此处提供的数据表中的值进行比较:https://pubs.usgs.gov/wsp/wsp1536-E/pdf/wsp_1536-E_b.pdf - 请参阅下文(借用详细代码 - 应该制作一个csv,事后看来):

Wu_QC <- data.frame(u = c(1.0*10^-15, 4.1*10^-14,9.9*10^-13, 7.0*10^-12, 3.7*10^-11, 
2.3*10^-10, 6.8*10^-9, 5.7*10^-8, 8.4*10^-7, 6.3*10^-6,
3.1*10^-5, 7.4*10^-4, 5.1*10^-3, 2.9*10^-2,8.7*10^-1,
4.6,9.90),
Wu_table = c(33.9616, 30.2480, 27.0639, 25.1079, 23.4429, 
21.6157, 18.2291, 16.1030, 13.4126, 11.3978,
9.8043,6.6324, 4.7064,2.9920,0.2742,
0.001841,0.000004637))

Wu_QC$rep_100 <-  Wu(Wu_QC$u,100)

好消息是公式给出重复= 50,100,150和170的相同结果(所以我刚刚给你上面的100版本)。坏消息是,虽然该功能对于u&lt; ~10 ^ -3,它离开导轨并为数字的数量级左右的数字提供负输出。当我只是在单个数字上调用该函数时,这不会发生。即:

> Wu(4.6)
[1] 0.001856671

2sf的正确答案是什么。

有人能发现我做错了什么和/或建议更好的方法来编码这个等式吗?我认为这个问题与我的for循环有关,和/或随着你变大而生成无限数的阶乘的问题,但我完全不确定。

谢谢!

3 个答案:

答案 0 :(得分:3)

正如你在参考文献第93页所说,W也被称为指数积分。另请参阅here

然后,例如,package expint提供计算W(u)的函数:

library(expint)
expint(10^(-8))
# [1] 17.84347
expint(4.6)
# [1] 0.001841006

其结果与您推荐的表格完全相同。

答案 1 :(得分:0)

您可以编写一个函数,该函数将值与重复次数一起输出并输出所需的值:

cbind.fill

随着数字变大,估计不太好,所以我们不得不超过170!但R不能那样做。也许你可以尝试其他平台。即Python

答案 2 :(得分:0)

我想我可能已经解决了这个问题(尽管从Onyambo的答案中大量借用!)这是我的代码:

well_func2 <- function (u, l = 100) {
    result <- numeric(length(u))
a <- 2:l
for(i in seq_along(u)){
result[i] <- -0.5772-log(u[i])+u[i]+sum(u[i]^(a)*rep(c(-1,1),length=l-1)/(a)/factorial(a))
}
return(result)
}

据我所知,到目前为止,这与u&lt; 5(和Onyambo的代码一样)的表格结果很好地匹配,并且它也为矢量与单值输入提供了相同的结果。

仍然需要更多的测试,并且可能有一种更整洁的方法来使用map()或类似代码而不是for循环来编码它,但我现在很开心。以为我会分享以防其他人有同样的问题。