在C++故障中集成Goempertz功能
Integrating Goempertz Function in C++ glitch
我试图找到Goempertz函数的梯形规则估计,并使用它来测量50岁吸烟者和50岁非吸烟者的预期寿命之间的差异,但我的代码一直给了我废话答案。
50岁人的Goempertz函数可以编码为:
exp((-b/log(c))*pow(c,50)*(pow(c,t)-1))
其中b
和c
是常数,我们需要将其从 0 积分到无穷大(一个非常大的数字)以获得预期寿命。
对于非吸烟者,预期寿命可以通过以下方式计算: 常量 b = 0.0005,c = 1.07。 对于吸烟者,预期寿命可以用 常量 b = 0.0010,c = 1.07。
const double A = 0; // lower limit of integration
const double B = 1000000000000; // Upper limit to represent infinity
const int N = 10000; //# number of steps of the approximation
double g(double b, double c, double t) //
{//b and c are constants, t is the variable of integration.
return exp((-b/log(c))*pow(c,50)*(pow(c,t)-1));
}
double trapezoidal(double Bconst, double Cconst)
{
double deltaX = (B-A)/N; //The "horizontal height" of each tiny trapezoid
double innerTrap = 0; //innerTrap is summation of terms inside Trapezoidal rule
for (int i = 0; i <= N; i++)
{
double xvalue;
if (i == 0) // at the beginning, evaluate function of innerTrap at x0=A
{
xvalue = A;
}
else if (i == N) //at the end, evaluate function at xN=B
{
xvalue = B;
}
else //in the middle terms, evaluate function at xi=x0+i(dX)
{
xvalue = A + i * deltaX;
}
if ((i == 0) || (i == N)) //coefficient is 1 at beginning and end
{
innerTrap = innerTrap + 1*g(Bconst, Cconst, xvalue);
}
else // for all other terms in the middle, has coefficient 2
{
innerTrap = innerTrap + 2*g(Bconst, Cconst, xvalue);
}
}
return (deltaX/2)*innerTrap;
}
int main()
{
cout << "years 50 year old nonsmoker lives: " << trapezoidal(0.0005,1.07) << endl;
cout << "years 50 year old smoker lives: " << trapezoidal(0.0010,1.07) << endl;
cout << "difference between life expectancies: " << trapezoidal(0.0005,1.07)-trapezoidal(0.0010,1.07) << endl;
return 0;
}
问题在于你选择的末端x坐标以及你对面积求和的切片数量:
const double A = 0;
const double B = 1000000000000;
const int N = 10000;
double deltaX = (B-A) / N; //100 million!
当你做这样的离散集成时,你希望你的deltaX
与函数的变化相比很小。我猜Goempertz函数在0到1亿之间变化很大。
要修复它,只需进行两项更改:
const double B = 100;
const int N = 10000000;
这使得deltaX == 0.00001
并且似乎给出了良好的结果(21.2和14.8)。放大B
不会改变最终答案(如果有的话),因为此范围内的函数值基本上为 0。
如果您希望能够弄清楚如何选择B
的良好值并N
该过程大致如下:
- 对于
B
查找函数结果足够小(或函数更改足够小)以忽略的x
的值。这对于周期性或复杂函数来说可能很棘手。 - 从一个小
N
值开始,然后计算结果。将N
增加 2 倍(或更多),直到结果收敛到所需的精度。 - 您可以通过增加
B
来检查您选择的是否有效,并查看结果的变化是否小于您想要的准确性。
例如,我对B
和N
的选择非常保守。这些可以减少到低至B = 50
和N = 10
,并且仍然为 3 个有效数字提供相同的结果。
据我了解,您在常量B
和N
上犯了一个错误。B
- 一个人可以以一定的概率和N
生活多少年是积分步。因此B
应该相对较小(<100,因为一个人活50+100岁或更长时间的概率非常小),N
应该尽可能大。您可以使用以下代码来解决您的任务
const double A = 0; // lower limit of integration
const double B = 100; // Upper limit to represent infinity
const int N = 1000000; //# number of steps of the approximation
double g(double b, double c, double t) //
{//b and c are constants, t is the variable of integration.
return exp((-b/log(c))*pow(c,50)*(pow(c,t)-1));
}
double trapezoidal(double Bconst, double Cconst)
{
double deltaX = (B-A)/double(N); //The "horizontal height" of each tiny trapezoid
double innerTrap = 0; //innerTrap is summation of terms inside Trapezoidal rule
double xvalue = A + deltaX/2;
for (int i = 0; i < N; i++)
{
xvalue += deltaX;
innerTrap += g(Bconst, Cconst, xvalue);
}
return deltaX*innerTrap;
}
int main()
{
double smk = trapezoidal(0.0010,1.07);
double nonsmk = trapezoidal(0.0005,1.07);
cout << "years 50 year old nonsmoker lives: " << nonsmk << endl;
cout << "years 50 year old smoker lives: " << smk << endl;
cout << "difference between life expectancies: " << nonsmk-smk << endl;
return 0;
}
相关文章:
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 多态性和功能结合
- 带内存和隔离功能的SQLite
- 在CMakeLists.txt的安装功能中使用.cmake文件有什么用
- 类模板的成员功能的定义在单独的TU中完全专业化
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何在C++中获得"静态纯虚拟"功能?
- 两个文件使用彼此的功能-如何解决
- 我应该实现右值推送功能吗?我应该使用std::move吗
- QML按钮点击功能执行顺序
- 无法理解此 return 语句的功能,没有它就会发生运行时错误
- 有没有可能有一个只有ADL才能找到的非好友功能
- 功能样式转换从 'int' 到 'ItemType' 的匹配转换
- 文件系统:复制功能的速度秘诀是什么
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 如何在Directwrite中获得给定字体的可用OpenType功能
- 对可变参数使用声明.如何选择正确的功能
- 询问在设计我的手臂模拟器功能表示格式1
- 功能原型的目的
- 在C++故障中集成Goempertz功能