相关疑难解决方法(0)

C如何计算sin()和其他数学函数?

我一直在研究.NET反汇编和GCC源代码,但似乎无法找到实际实现sin()和其他数学函数的任何地方......它们似乎总是引用其他东西.

谁能帮我找到它们?我觉得C运行的所有硬件都不太可能支持硬件中的触发功能,因此某处必须有软件算法,对吧?


我知道有几种方法可以计算函数,并编写了我自己的例程来计算函数使用泰勒系列来获得乐趣.我很好奇真正的生产语言是如何做到的,因为我的所有实现总是慢几个数量级,即使我认为我的算法非常聪明(显然它们不是).

c math trigonometry

236
推荐指数
15
解决办法
15万
查看次数

快速实现c ++的三角函数

简短版本:我想知道标准三角函数的实现是否比包含的更快math.h.

龙版本:我有一个程序,对NUMERICS相当重(这是一个物理模拟),并需要调用三角函数,主要是sincos,有很多.目前我只是使用其中包含的实现math.h.分析显示对这些函数的调用花费比我预期的要多(希望).

虽然代码的其他部分肯定有足够的优化空间,但速度更快sin,cos可能会给我一些额外的百分比..那么,你们有什么建议吗?
在另一篇文章中,建议使用自制的查找表.但也许有其他选择?或者在一些图书馆中提供现成且经过良好测试的查找解决方

c++ math optimization

33
推荐指数
2
解决办法
2万
查看次数

在单位半球的表面上快速均匀分布的随机点

我试图在单位球体的表面上生成均匀的随机点,用于蒙特卡罗射线追踪程序.当我说均匀时,我的意思是这些点相对于表面积均匀分布.我目前的方法是计算指向正z轴并基于xy平面的半球上的均匀随机点.

半球上的随机点表示漫射灰色发射器的热辐射发射方向.

当我使用以下计算时,我获得了正确的结果:

注意:dsfmt*将返回0到1之间的随机数.

azimuthal = 2*PI*dsfmt_genrand_close_open(&dsfmtt);
zenith = asin(sqrt(dsfmt_genrand_close_open(&dsfmtt)));

// Calculate the cartesian point
osRay.c._x = sin(zenith)*cos(azimuthal); 
osRay.c._y = sin(zenith)*sin(azimuthal);
osRay.c._z = cos(zenith);
Run Code Online (Sandbox Code Playgroud)

然而,这是非常缓慢的,并且分析表明它占用了大部分的运行时间.因此,我找到了一些替代方法:

Marsaglia 1972年的拒绝方法

do {
   x1 = 2.0*dsfmt_genrand_open_open(&dsfmtt)-1.0;
   x2 = 2.0*dsfmt_genrand_open_open(&dsfmtt)-1.0;
   S = x1*x1 + x2*x2;
} while(S > 1.0f);


osRay.c._x = 2.0*x1*sqrt(1.0-S);
osRay.c._y = 2.0*x2*sqrt(1.0-S);
osRay.c._z = abs(1.0-2.0*S);
Run Code Online (Sandbox Code Playgroud)

分析笛卡尔坐标计算

azimuthal = 2*PI*dsfmt_genrand_close_open(&dsfmtt);
u = 2*dsfmt_genrand_close_open(&dsfmtt) -1;
w = sqrt(1-u*u);

osRay.c._x = w*cos(azimuthal);
osRay.c._y = w*sin(azimuthal);
osRay.c._z = abs(u);
Run Code Online (Sandbox Code Playgroud)

虽然最后两种方法比第一种方法运行的时间更快,但当我使用它们时,我得到的结果表明它们不是在球体表面上产生均匀的随机点,而是给出了有利于赤道的分布.

此外,最后两种方法给出相同的最终结果,但我确定它们是不正确的,因为我正在与分析解决方案进行比较.

我发现的每个参考都表明这些方法确实产生了均匀的分布但是我没有达到正确的结果.

我的实现中是否有错误,或者我在第二和第三种方法中错过了一个基本想法?

c++ random math geometry

21
推荐指数
1
解决办法
7122
查看次数

c ++ libstd同时计算sin和cos

在C库中math.h,有一个sincos非常有效的函数,因为它在更接近单个调用sin()或者cos()调用两者的总时间的时间内计算正弦和余弦.

C++标准库中有这样的功能吗?

c++ math trigonometry libstdc++

12
推荐指数
3
解决办法
6530
查看次数

一次计算正弦和余弦

我有一个使用相同参数的正弦和余弦的科学代码(我基本上需要该参数的复数指数).我想知道是否有可能比分别调用正弦和余弦函数更快.

另外我只需要0.1%的精度.那么有什么方法可以找到默认的触发功能并截断功率系列的速度?

我想到的另一件事是,有没有办法执行余数运算,结果总是积极的?在我自己使用的算法中,x=fmod(x,2*pi);但如果x为负数,我需要加2pi(较小的域意味着我可以使用较短的幂级数)

编辑:LUT原来是最好的方法,但我很高兴我了解了其他近似技术.我还建议使用明确的中点近似.这就是我最终做的事情:

const int N = 10000;//about 3e-4 error for 1000//3e-5 for 10 000//3e-6 for 100 000
double *cs = new double[N];
double *sn = new double[N];
for(int i  =0;i<N;i++){
    double A= (i+0.5)*2*pi/N;
    cs[i]=cos(A);
    sn[i]=sin(A);
}
Run Code Online (Sandbox Code Playgroud)

以下部分近似(中点)sincos(2*pi*(wc2 + t [j]*(cotp*t [j] -wc)))

double A=(wc2+t[j]*(cotp*t[j]-wc));
int B =(int)N*(A-floor(A));
re += cs[B]*f[j];
im += sn[B]*f[j];
Run Code Online (Sandbox Code Playgroud)

另一种方法可能是使用切比雪夫分解.您可以使用orthogonality属性来查找系数.针对指数进行了优化,它看起来像这样:

double fastsin(double x){
    x=x-floor(x/2/pi)*2*pi-pi;//this line can be improved, both inside this 
                              //function and before you input it into the function

    double x2 …
Run Code Online (Sandbox Code Playgroud)

c++ algorithm trigonometry

9
推荐指数
1
解决办法
2116
查看次数

为什么System.Math有Sin,Cos等的外部方法?

[MethodImpl(MethodImplOptions.InternalCall)]
public static extern double Sin(double a);
Run Code Online (Sandbox Code Playgroud)

这是什么原因?

.net c#

2
推荐指数
1
解决办法
1638
查看次数

标签 统计

c++ ×4

math ×4

trigonometry ×3

.net ×1

algorithm ×1

c ×1

c# ×1

geometry ×1

libstdc++ ×1

optimization ×1

random ×1