计算平均精度
Compute average precision
我在计算有效位数,两个数相同。但是,我编写的函数在数字相等时 return 会是一个很大的值。结果,平均结果不够具有代表性,我将在下面展示。
代码如下:
#include <iostream>
#include <cmath>
double calc_error(double a,double x) {
return std::abs(x-a)/std::abs(a);
}
int significant(double err) {
int s = -1;
do {
++s;
} while(err < pow(5, -s));
return s;
}
int main(void) {
double sans[]={-250207683.634793,-1353198687.861288,2816966067.598196,-144344843844.616425, 323890119928.788757};
double pans[]={-250207683.634692, -1353198687.861386, 2816966067.598891, -144344843844.617096, 323890119928.788757};
double err[5];
double avg_err = 0;
int avg_significant = 0;
std::cout<<"Serial Answer,Distributed Answer, Error, Significant digits"<<std::endl;
for (int it=0; it<5; it++) {
err[it]=calc_error(sans[it], pans[it]);
avg_err += err[it];
avg_significant += significant(err[it]);
std::cout<<sans[it]<<","<<pans[it]<<","<<err[it]<<","<<significant(err[it])<<"\n";
}
std::cout << "avg_error: " << avg_err/5 << ", avg_sign:" << avg_significant/5 << "\n";
}
并检查输出:
Serial Answer,Distributed Answer, Error, Significant digits
-2.50208e+08,-2.50208e+08,4.03665e-13,18
-1.3532e+09,-1.3532e+09,7.24136e-14,19
2.81697e+09,2.81697e+09,2.46631e-13,19
-1.44345e+11,-1.44345e+11,4.65127e-15,21
3.2389e+11,3.2389e+11,0,463
avg_error: 1.45472e-13, avg_sign:108
在我的实际应用中,我有很多数字,因此我应该提供一些具有代表性的。你会怎么做?写这个 post 时出现的一个想法是计算有多少个案例(即一对数字)有 18 个(例如)有效数字相等,有多少个 17 等等,但我担心传播可能多了。
有两种选择,取决于您希望如何处理相同的值,其中一种几乎涉及将 significant(0) 视为特例并返回 0。
那就看你要不要把这些0算进平均值了;如果不这样做,只需除以重要函数不是 0 而不是 5 的数字。
我在计算有效位数,两个数相同。但是,我编写的函数在数字相等时 return 会是一个很大的值。结果,平均结果不够具有代表性,我将在下面展示。
代码如下:
#include <iostream>
#include <cmath>
double calc_error(double a,double x) {
return std::abs(x-a)/std::abs(a);
}
int significant(double err) {
int s = -1;
do {
++s;
} while(err < pow(5, -s));
return s;
}
int main(void) {
double sans[]={-250207683.634793,-1353198687.861288,2816966067.598196,-144344843844.616425, 323890119928.788757};
double pans[]={-250207683.634692, -1353198687.861386, 2816966067.598891, -144344843844.617096, 323890119928.788757};
double err[5];
double avg_err = 0;
int avg_significant = 0;
std::cout<<"Serial Answer,Distributed Answer, Error, Significant digits"<<std::endl;
for (int it=0; it<5; it++) {
err[it]=calc_error(sans[it], pans[it]);
avg_err += err[it];
avg_significant += significant(err[it]);
std::cout<<sans[it]<<","<<pans[it]<<","<<err[it]<<","<<significant(err[it])<<"\n";
}
std::cout << "avg_error: " << avg_err/5 << ", avg_sign:" << avg_significant/5 << "\n";
}
并检查输出:
Serial Answer,Distributed Answer, Error, Significant digits
-2.50208e+08,-2.50208e+08,4.03665e-13,18
-1.3532e+09,-1.3532e+09,7.24136e-14,19
2.81697e+09,2.81697e+09,2.46631e-13,19
-1.44345e+11,-1.44345e+11,4.65127e-15,21
3.2389e+11,3.2389e+11,0,463
avg_error: 1.45472e-13, avg_sign:108
在我的实际应用中,我有很多数字,因此我应该提供一些具有代表性的。你会怎么做?写这个 post 时出现的一个想法是计算有多少个案例(即一对数字)有 18 个(例如)有效数字相等,有多少个 17 等等,但我担心传播可能多了。
有两种选择,取决于您希望如何处理相同的值,其中一种几乎涉及将 significant(0) 视为特例并返回 0。
那就看你要不要把这些0算进平均值了;如果不这样做,只需除以重要函数不是 0 而不是 5 的数字。