- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在编写一个科学程序,它在其主要算法中使用正弦的公共(public)值,即 sin(M_PI/N)
对于 N = 1, 2, 3, 4, 5, 6
.
因为我希望我的程序尽可能快,所以我想:让我们将这些值存储在一个 vector 中,而不是一遍又一遍地计算它们。它看起来像这样:
sin_pi_over_n_.clear();
sin_pi_over_n_.push_back(0.0);
sin_pi_over_n_.push_back(1.0);
sin_pi_over_n_.push_back(sqrt(3.0)/2.0);
sin_pi_over_n_.push_back(sqrt(2.0)/2.0);
sin_pi_over_n_.push_back(sqrt(2.0)*0.25*sqrt(5.0-sqrt(5.0)));
sin_pi_over_n_.push_back(0.5);
所以现在在我的主要算法中我写了s = sin_pi_over_n_[n-1];
而不是 s = sin(M_PI/n);
.
但令我大吃一惊的是,该程序竟然慢了几乎两倍!我想,真的,读取 vector 中的值需要那么长时间吗?但后来我意识到这不是问题:如果我改写
sin_pi_over_n_.push_back(sin(M_PI/1.0));
sin_pi_over_n_.push_back(sin(M_PI/2.0));
sin_pi_over_n_.push_back(sin(M_PI/3.0));
sin_pi_over_n_.push_back(sin(M_PI/4.0));
sin_pi_over_n_.push_back(sin(M_PI/5.0));
sin_pi_over_n_.push_back(sin(M_PI/6.0));
然后程序又快了!然后我想:我的正弦值有问题。但疯狂的是,即使我只替换最后一行 sin_pi_over_n_.push_back(sin(M_PI/6.0));
通过 sin_pi_over_n_.push_back(0.5);
然后程序又慢了!是关于 double 的吗?我有点怀疑:如果我问 std::cout << abs(sin(M_PI/6.0) - 0.5) << std::endl;
, 我得到 0
在我的终端。
糟糕:我才意识到;如果我问std::cout << sin(M_PI/6.0) - 0.5 << std::endl;
(没有 abs
),然后我得到 -5.55112e-17
.我仍将继续并发布该问题,因为这种行为对我来说似乎不可思议。如果这种不可预知的现象对性能有如此大的影响,我怎么可能优化我的程序的速度?
感谢您的见解!
编辑:也许我还不够清楚。在我的程序中,我有一个类 Algo
.当我执行我的程序时,一些功能,比如 my_function
, 被称为无数次。在这个函数中,一行是:s = sin(M_PI/n);
.我想我会用 s = sin_pi_over_n_[n-1];
替换这一行, 其中sin_pi_over_n_[n-1]
是一个 vector ,存储为类 Algo
的成员变量并且我一劳永逸地填入 Algo
的构造函数中.希望这能让事情变得更清楚。
编辑 2:好的,看来你们中的一些人希望我发布更多代码。来了:
类 Algo
:
class Algo : public QThread
{
Q_OBJECT
public:
Algo() {}
void reset_algo(...)
public slots:
void run();
private:
void create_sines();
double super_total_neighbors_angle(const unsigned int &index, double &error);
double super_radius_update(const unsigned int &index, double &error);
// etc
std::vector<double> radii_;
std::vector<double> sin_pi_over_n_;
std::vector<unsigned int> neighbors_lists_sizes_;
// etc
};
成员函数create_sines
:
void Algo::create_sines()
{
sin_pi_over_n_.clear();
/*sin_pi_over_n_.push_back(0.0);
sin_pi_over_n_.push_back(1.0);
sin_pi_over_n_.push_back(0.5*sqrt(3.0));
sin_pi_over_n_.push_back(0.5*sqrt(2.0));
sin_pi_over_n_.push_back(0.25*sqrt(2.0)*sqrt(5.0-sqrt(5.0)));
sin_pi_over_n_.push_back(0.5);*/
sin_pi_over_n_.push_back(sin(M_PI/1.0));
sin_pi_over_n_.push_back(sin(M_PI/2.0));
sin_pi_over_n_.push_back(sin(M_PI/3.0));
sin_pi_over_n_.push_back(sin(M_PI/4.0));
sin_pi_over_n_.push_back(sin(M_PI/5.0));
sin_pi_over_n_.push_back(sin(M_PI/6.0));
return;
}
成员函数super_radius_update
(我在上面重命名为 my_function
):
inline double Algo::super_radius_update(const unsigned int &index, double &error)
{
int n = neighbors_lists_sizes_[index];
double s = sin(super_total_neighbors_angle(index, error)*0.5/n);
double rv = radii_[index]*s/(1-s);
//s = sin(M_PI/n);
s = sin_pi_over_n_[n-1];
return (1-s)*rv/s;
}
恐怕我很难发送一个您可以运行的最小完整示例,因为整个类(class)有点长和复杂。我可以尝试,但我仍然必须发布大量代码,而且我需要相当长的时间来提取...
我在 Linux Ubuntu 12.04 64 位笔记本电脑上使用 Qt Creator 4.8 64 位。
编辑 3 或 4:对于所有的编辑,我深表歉意。有一个重要的信息我没有告诉你:程序将运行(基本上调用函数 super_radius_update
)直到一些错误在一定的容忍范围内。因此,使程序变慢或变快的不是 super_radius_update
的执行时间。但我相信该函数的调用次数。对 sin(M_PI/N)
使用这样或那样的值将对错误达到容差的速度产生影响。
最佳答案
double rv = radii_[index]*s/(1-s);
return (1-s)*rv/s;
此代码在 s = 0
和 s = 1
处有奇点,这两者都会发生,并且由于奇点而在数值上不稳定。您可能通过 sin_pi_over_n_[0]
和 sin_pi_over_n_[1]
的不同计算触发了不稳定性。
虽然这不能解释不同 sin_pi_over_n_[5]
计算的不同行为,但可能存在类似的不稳定性。
关于C++ : sin(M_PI/6) = 0. 5?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11331932/
*> sin sin 0.5 :10:1: Non type-variable argument in the constraint: Floating (a -> a) (Use Flexible
我一直在尝试实现一个快速但更重要的是准确的自定义 sin 函数(我不能在我的项目中使用 math.h sin)。我不是这类数学方面的专家,所以请和我一起工作 XD。在网上稍作搜索后,我发现了以下代码,
我编写了一个 Prolog 程序来求解简单的三角方程。我写它是为了获取三角函数的值。例如,我可以获得 sin(45) 的值,但我无法将 sin(45) 的值赋给术语 sin(45 )。我尝试了 =,=
这是我的代码: # point of intersection between opposite and hypotenuse x,y = pygame.mouse.get_pos() # u
我有一个简单的 C++ 代码,它在一个值 vector 上运行一个默认的 sin 函数。 static void BM_sin() { int data_size = 10000000
有什么区别,如何让 WebGL 的 sin 产生与 Math.sin 相同的结果? 编辑:我的顶点着色器中有一些代码(这不是全部代码),它计算球体周围的斐波那契点,并且应该将顶点放置在这个新点上: a
我有一个客户试图在一个过时的编译器上编译,该编译器似乎没有来自 c++11 的 std::sin 和 std::cos。 (而且他们不能升级)我正在寻找某种快速修复方法来插入标题的顶部以使 std::
#include #include const int TERMS = 7; const float PI = 3.14159265358979; int fact(int n) { r
不幸的是,标准 C++ 库没有对 sincos 的单一调用,这为这个问题提供了空间。 第一个问题: 如果我想计算 sin 和 cos,计算 sin 和 cos 更便宜,还是先计算 sin 再计算 sq
我正在实时渲染 500x500 点。我必须使用 atan() 和 sin() 函数计算点的位置。通过使用 atan() 和 sin(),我得到了 24 fps(每秒帧数)。 float thetaC
我知道 Math.sin() 可以工作,但我需要自己使用 factorial(int) 实现它 我已经在下面有一个阶乘方法是我的 sin 方法,但我无法获得与 Math.sin() 相同的结果: pu
我想知道,当我在 Reddit thread 中发现问题时,为什么 Math.sin(double) 委托(delegate)给 StrictMath.sin(double) .提到的代码片段如下所示
为什么 Pytorch 和 Numpy 的三角函数在以 Pi 的整数倍计算时会导致数量级上如此巨大的差异? >>> torch.sin(torch.ones(1)*2*np.pi) tensor([1
这是一个很简单的问题,让我很困惑。 我收到一个源文件的以下错误,但另一个没有: 4 src/Source2.cpp:1466: error: no matching function for cal
我在 JavaScript 中发现了一个有趣的异常现象。其中重点是我尝试通过预先计算 sin(x) 和 cos(x) 并简单地引用预先计算的值来加速三 Angular 变换计算。 直觉上,预计算比每次
我正在尝试用 Python 对方程 x=a*sin(x) 进行数值求解,其中 a 是某个常数。我已经尝试先用符号求解方程,但似乎这种特殊的表达形式并没有在 sympy 中实现。我也尝试过使用 symp
我在使用 matlab 计算时遇到问题。我知道“pi”是一个 float ,并不精确。因此,在 matlab 中 sin(pi) 不完全为零。我的问题是,如果“pi”不准确,那么为什么 sin(pi/
如何只使用 sin 或 cos 而不是 Math.sin 或 Math.cos?我尝试导入 Math.* 但我想我可能需要对命名空间做一些事情? 最佳答案 import static java.lan
测试代码: #include #include const int N = 4096; const float PI = 3.1415926535897932384626; float cosin
我在其他问题中读到,例如由于浮点表示,sin(2π) 不为零,但非常接近。这个非常小的错误在我的代码中不是问题,因为例如我可以四舍五入 5 位小数。 但是当2π乘以一个非常大的数时,误差就会放大很多。
我是一名优秀的程序员,十分优秀!