从对数范围计算每十年的点数



我有一个以10为基数的对数间隔点的范围,我需要计算这些点每十年的#点。

基于维基百科的这一部分,我们有#tenders=log10(开始/停止(。由此,我们应该能够将每十年的#点计算为#点/#十年。然而,这并不能给出正确的答案。以下是我用来测试这种方法的一个短程序:

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <float.h>
class GenLog {
public:
GenLog(double start, double step) : curVal(start), step(step) {
m = 1.0 / step;
b = std::log10(start);
stepi = 0;
};
double operator()() {
++stepi;
double arg = m*stepi+b;
if (arg < DBL_MAX_10_EXP) {
curVal += pow(10.0, arg) - curVal;
} else {
curVal = DBL_MAX;
}
return curVal;
}
private:
double step, stepi, curVal, m, b;
};
int main(int argc, char *argv[])
{
if (argc < 5) {
std::cout << "Wrong number of args: format is [start] [stop] [points-per-decade] [size]n";
return -1;
}

double start = atof(argv[1]);
double stop = atof(argv[2]);
double ppd = atof(argv[3]);
int size = atoi(argv[4]);
std::vector<double> vals;
vals.push_back(start);
// generate total number of points - 2 (excluding endpoints, GenLog takes in
// starting freq, and #point/dec
std::generate_n(std::back_inserter(vals), size - 2, GenLog(start, ppd));
vals.push_back(stop);
for (auto i : vals) {
std::cout << i << " ";
}
std::cout << "n---TEST BACKWARDS PPD---n";
std::cout << "ppd: " << ppd << "t          " << (vals.size()) / std::log10(*std::prev(vals.end()) / vals.front()) << "n";
return 0;
}

输出示例:这会生成一个从1到10.1681的对数间隔的点序列,每十年13个点,总共15个点——尽管原则上你只需要起点和每十年的点就可以生成序列中的下一个对数点。

正如你所看到的,得到的数字(13和14.8922(在应该是的时候是不一样的。

./so 1.0 10.1681 13 15
1 1.19378 1.4251 1.70125 2.03092 2.42446 2.89427 3.45511 4.12463 4.92388 5.87802 7.01704 8.37678 10 10.1681 
---TEST BACKWARDS PPD---
ppd: 13           14.8922

根据我到目前为止的测试,我不认为这是一个错误。也许每十年#点的计算在概念上是错误的?如果是,正确的计算方法是什么?

我计算每十年#点的方法是错误的

因此,基于维基百科文章计算部分的最后一个等式,我们有:

步长=10^(每十年1/#点(

由于我们知道步长,我们可以重新安排

1/#点每十年*ln(10(=ln(步长(

并最终求解每十年的#点

#每十年点数=ln(10(/ln(步长(

最新更新