数学公式快速计算方法
#pragma once
#define fmaxf(a,b) (((a) > (b)) ? (a) : (b))
typedef unsigned int uint32_t;
//==========================================================================
// 对数部分
//==========================================================================
///对数(底为2)函数
static inline float fastlog2 (float x)
{
union { float f; uint32_t i; } vx = { x };
union { uint32_t i; float f; } mx = { (vx.i & 0x007FFFFF) | 0x3f000000 };
float y = (float)vx.i;
y *= 1.1920928955078125e-7f;
return y - 124.22551499f
- 1.498030302f * mx.f
- 1.72587999f / (0.3520887068f + mx.f);
}
///对数(底为2)函数
static inline float fasterlog2 (float x)
{
union { float f; uint32_t i; } vx = { x };
float y = (float)vx.i;
y *= 1.1920928955078125e-7f;
return y - 126.94269504f;
}
///对数函数
static inline float fastlog (float x)
{
return 0.69314718f * fastlog2 (x);
}
///对数函数
static inline float fasterlog (float x)
{
union { float f; uint32_t i; }
vx = { x };
float y = (float)vx.i;
y *= 8.2629582881927490e-8f;
return y - 87.989971088f;
}
//==========================================================================
// 指数部分
//==========================================================================
static inline float fastpow2 (float p)
{
float offset = (p < 0) ? 1.0f : 0.0f;
float clipp = (p < -126) ? -126.0f : p;
int w = (int)clipp;
float z = clipp - w + offset;
union
{
uint32_t i;
float f;
}
v = { (unsigned int) ( (1 << 23) * (clipp + 121.2740575f + 27.7280233f
/ (4.84252568f - z) - 1.49012907f * z) ) };
return v.f;
}
static inline float fasterpow2 (float p)
{
float clipp = (p < -126) ? -126.0f : p;
union
{
uint32_t i;
float f;
}
v = { (unsigned int) ( (1 << 23) * (clipp + 126.94269504f) ) };
return v.f;
}
///exp指数
static inline float fastexp (float p)
{
return fastpow2 (1.442695040f * p);
}
///exp指数
static inline float fasterexp (float p)
{
return fasterpow2 (1.442695040f * p);
}
static inline float fastpow (float x, float p)
{
return fastpow2 (p * fastlog2 (x));
}
static inline float fasterpow (float x, float p)
{
return fasterpow2 (p * fasterlog2 (x));
}
//==========================================================================
// 三角函数部分(-pi, pi)
//==========================================================================
///超越正弦函数
static inline float fastsinh (float p)
{
return 0.5f * (fastexp (p) - fastexp (-p));
}
///超越正弦函数
static inline float fastersinh (float p)
{
return 0.5f * (fasterexp (p) - fasterexp (-p));
}
///超越余弦函数
static inline float fastcosh (float p)
{
return 0.5f * (fastexp (p) + fastexp (-p));
}
///超越余弦函数
static inline float fastercosh (float p)
{
return 0.5f * (fasterexp (p) + fasterexp (-p));
}
///超越正切函数
static inline float fasttanh (float p)
{
return -1.0f + 2.0f / (1.0f + fastexp (-2.0f * p));
}
///超越正切函数
static inline float fastertanh (float p)
{
return -1.0f + 2.0f / (1.0f + fasterexp (-2.0f * p));
}
///正弦函数
static inline float fastsin (float x)
{
static const float fouroverpi = 1.2732395447351627f;
static const float fouroverpisq = 0.40528473456935109f;
static const float q = 0.78444488374548933f;
union { float f; uint32_t i; } p = { 0.20363937680730309f };
union { float f; uint32_t i; } r = { 0.015124940802184233f };
union { float f; uint32_t i; } s = { -0.0032225901625579573f };
union { float f; uint32_t i; } vx = { x };
uint32_t sign = vx.i & 0x80000000;
vx.i = vx.i & 0x7FFFFFFF;
float qpprox = fouroverpi * x - fouroverpisq * x * vx.f;
float qpproxsq = qpprox * qpprox;
p.i |= sign;
r.i |= sign;
s.i ^= sign;
return q * qpprox + qpproxsq * (p.f + qpproxsq * (r.f + qpproxsq * s.f));
}
///正弦函数
static inline float fastersin (float x)
{
static const float fouroverpi = 1.2732395447351627f;
static const float fouroverpisq = 0.40528473456935109f;
static const float q = 0.77633023248007499f;
union { float f; uint32_t i; } p = { 0.22308510060189463f };
union { float f; uint32_t i; } vx = { x };
uint32_t sign = vx.i & 0x80000000;
vx.i &= 0x7FFFFFFF;
float qpprox = fouroverpi * x - fouroverpisq * x * vx.f;
p.i |= sign;
return qpprox * (q + p.f * qpprox);
}
///正弦函数
static inline float fastsinfull (float x)
{
static const float twopi = 6.2831853071795865f;
static const float invtwopi = 0.15915494309189534f;
int k = (int)(x * invtwopi);
float half = (x < 0) ? -0.5f : 0.5f;
return fastsin ((half + k) * twopi - x);
}
///正弦函数
static inline float fastersinfull (float x)
{
static const float twopi = 6.2831853071795865f;
static const float invtwopi = 0.15915494309189534f;
int k = (int)(x * invtwopi);
float half = (x < 0) ? -0.5f : 0.5f;
return fastersin ((half + k) * twopi - x);
}
///余弦函数
static inline float fastcos (float x)
{
static const float halfpi = 1.5707963267948966f;
static const float halfpiminustwopi = -4.7123889803846899f;
float offset = (x > halfpi) ? halfpiminustwopi : halfpi;
return fastsin (x + offset);
}
///余弦函数
static inline float fastercos (float x)
{
static const float twooverpi = 0.63661977236758134f;
static const float p = 0.54641335845679634f;
union { float f; uint32_t i; } vx = { x };
vx.i &= 0x7FFFFFFF;
float qpprox = 1.0f - twooverpi * vx.f;
return qpprox + p * qpprox * (1.0f - qpprox * qpprox);
}
///余弦函数
static inline float fastcosfull (float x)
{
static const float halfpi = 1.5707963267948966f;
return fastsinfull (x + halfpi);
}
///余弦函数
static inline float fastercosfull (float x)
{
static const float halfpi = 1.5707963267948966f;
return fastersinfull (x + halfpi);
}
///正切函数
static inline float fasttan (float x)
{
static const float halfpi = 1.5707963267948966f;
return fastsin (x) / fastsin (x + halfpi);
}
///正切函数
static inline float fastertan (float x)
{
return fastersin (x) / fastercos (x);
}
///正切函数
static inline float fasttanfull (float x)
{
static const float twopi = 6.2831853071795865f;
static const float invtwopi = 0.15915494309189534f;
int k = (int)(x * invtwopi);
float half = (x < 0) ? -0.5f : 0.5f;
float xnew = x - (half + k) * twopi;
return fastsin (xnew) / fastcos (xnew);
}
///正切函数
static inline float fastertanfull (float x)
{
static const float twopi = 6.2831853071795865f;
static const float invtwopi = 0.15915494309189534f;
int k = (int)(x * invtwopi);
float half = (x < 0) ? -0.5f : 0.5f;
float xnew = x - (half + k) * twopi;
return fastersin (xnew) / fastercos (xnew);
}
//==========================================================================
// sigmoid函数部分(1/(1 + exp(x))
//==========================================================================
static inline float fastsigmoid (float x)
{
return 1.0f / (1.0f + fastexp (-x));
}
static inline float fastersigmoid (float x)
{
return 1.0f / (1.0f + fasterexp (-x));
}
//==========================================================================
// 朗伯W函数部分
//==========================================================================
static inline float fastlambertw (float x)
{
static const float threshold = 2.26445f;
float c = (x < threshold) ? 1.546865557f : 1.0f;
float d = (x < threshold) ? 2.250366841f : 0.0f;
float a = (x < threshold) ? -0.737769969f : 0.0f;
float logterm = fastlog (c * x + d);
float loglogterm = fastlog (logterm);
float minusw = -a - logterm + loglogterm - loglogterm / logterm;
float expminusw = fastexp (minusw);
float xexpminusw = x * expminusw;
float pexpminusw = xexpminusw - minusw;
return (2.0f * xexpminusw - minusw * (4.0f * xexpminusw - minusw * pexpminusw)) /
(2.0f + pexpminusw * (2.0f - minusw));
}
static inline float fasterlambertw (float x)
{
static const float threshold = 2.26445f;
float c = (x < threshold) ? 1.546865557f : 1.0f;
float d = (x < threshold) ? 2.250366841f : 0.0f;
float a = (x < threshold) ? -0.737769969f : 0.0f;
float logterm = fasterlog (c * x + d);
float loglogterm = fasterlog (logterm);
float w = a + logterm - loglogterm + loglogterm / logterm;
float expw = fasterexp (-w);
return (w * w + expw * x) / (1.0f + w);
}
///朗伯W函数z=W(z).exp(W(z))
static inline float fastlambertwexpx (float x)
{
static const float k = 1.1765631309f;
static const float a = 0.94537622168f;
float logarg = fmaxf (x, k);
float powarg = (x < k) ? a * (x - k) : 0;
float logterm = fastlog (logarg);
float powterm = fasterpow2 (powarg); // don't need accuracy here
float w = powterm * (logarg - logterm + logterm / logarg);
float logw = fastlog (w);
float p = x - logw;
return w * (2.0f + p + w * (3.0f + 2.0f * p)) / (2.0f - p + w * (5.0f + 2.0f * w));
}
///朗伯W函数z=W(z).exp(W(z))
static inline float fasterlambertwexpx (float x)
{
static const float k = 1.1765631309f;
static const float a = 0.94537622168f;
float logarg = fmaxf (x, k);
float powarg = (x < k) ? a * (x - k) : 0;
float logterm = fasterlog (logarg);
float powterm = fasterpow2 (powarg);
float w = powterm * (logarg - logterm + logterm / logarg);
float logw = fasterlog (w);
return w * (1.0f + x - logw) / (1.0f + w);
}
//==========================================================================
// 对数Γ函数(伽玛函数)部分
//==========================================================================
///Log Gamma函数
static inline float fastlgamma (float x)
{
float logterm = fastlog (x * (1.0f + x) * (2.0f + x));
float xp3 = 3.0f + x;
return - 2.081061466f - x + 0.0833333f / xp3 - logterm + (2.5f + x) * fastlog (xp3);
}
///Log Gamma函数
static inline float fasterlgamma (float x)
{
return - 0.0810614667f
- x
- fasterlog (x)
+ (0.5f + x) * fasterlog (1.0f + x);
}
///双伽马函数
static inline float fastdigamma (float x)
{
float twopx = 2.0f + x;
float logterm = fastlog (twopx);
return (-48.0f + x * (-157.0f + x * (-127.0f - 30.0f * x))) /
(12.0f * x * (1.0f + x) * twopx * twopx) + logterm;
}
///双伽马函数
static inline float fasterdigamma (float x)
{
float onepx = 1.0f + x;
return -1.0f / x - 1.0f / (2 * onepx) + fasterlog (onepx);
}
数学公式快速计算方法相关推荐
- 大数量级组合数的快速计算方法
转自:大数量级组合数的快速计算方法,保存在此以学习. 计算组合数最大的困难在于数据的溢出,对于大于150的整数n求阶乘很容易超出double类型的范围,那么当C(n,m)中的n=200时,直接用组合公 ...
- 阶乘数的快速计算方法
阶乘数的快速计算方法 如何快速计算阶乘数n!?一种简单的办法是采用下面的循环: fac=1; for (k=2;k<=n;k++) fac*= k; 最后的fac值即为n!的值.当然,当n较大, ...
- 【JY】钢筋混凝土正截面极限承载力设计的基本原理和快速计算方法
本文转自 筑信达-李楚舒教授高工 的文章,关于快速计算PMM相关面的新方法,对于混凝土分析有较深刻的理解,文章内容充实丰富,与各位读者分享! [摘要] 本文从钢筋混凝土正截面极限承载力设计的基本原理出 ...
- 计算机基础—任意整数补码的快速计算方法
这几天读<深入理解计算机系统>(英文名: Computer Systems : A Programmer's Perspective)一书时,再次复习到了整数的各种类型及其表示方法.本科学 ...
- 计算机函数乘法word,乘法快速计算方法Word版
<乘法快速计算方法Word版>由会员分享,可在线阅读,更多相关<乘法快速计算方法Word版(10页珍藏版)>请在人人文库网上搜索. 1.传播优秀Word版文档 ,希望对您有帮助 ...
- 计算机机房ups电池常用配置表,机房UPS电池容量、后备电池配置、使用时间快速计算方法!...
原标题:机房UPS电池容量.后备电池配置.使用时间快速计算方法! UPS-Uninterruptible Power System是不间断电源系统的简称,作用是提供不间断的稳定电中断(停电)时UPS之 ...
- 离散傅里叶变换 - 快速计算方法及C实现 - 第一篇
DFT – Fast algorithms and C implementations - Part1 引言 算法中经常用到傅里叶变换,很长一段时间我都是使用FFTW("the fastes ...
- 子网掩码和网络ID的快速计算方法
CIDR的子网掩码都是连续的1跟连接的0表示,则子网掩码有以下几种表示方法: 0000 0000 0 1000 0000 128 1100 0000 128+64=192 1110 000 ...
- 计算机快速算法研究,可视化继电保护整定计算中快速计算方法的研究
摘要: 随着我国国民经济的稳定而快速的发展,电网规模不断升级,造成电网分析时数据量激增.还有电力系统的接线方式变得非常复杂,造成电网的运行方式复杂多变.特别是近年来风能,太阳能等分布式电源的并网运行更 ...
最新文章
- java主窗体设计代码_java窗体设计+GUI经典代码全放送
- 皮一皮:别人家的老公...
- f2py支持在fortran语言中调用其他Fortran函数或C代码或Python代码
- Android Service 形式分类
- kafka 集群的部署安装
- [密码学基础][每个信息安全博士生应该知道的52件事][Bristol52]41所有的侧信道分析都是能量分析吗
- 对数函数定义域和值域为r_对数函数
- 深度学习- 激活函数总结(Sigmoid, Tanh, Relu, leaky Relu, PReLU, Maxout, ELU, Softmax,交叉熵函数)
- 编码的奥秘txt_各学科最佳入门丛书推荐
- LintCode,hihoCoder,LeetCode有什么区别?
- HDU 4432 Sum of divisors 2012 Asia Tianjin Regional Contest
- exchange 2010 部署
- 业余草教你简单 4 步搞定 SpringBoot 整合 Shiro!
- 121、华为交换机配置手册
- 陕西2020行政区划调整_陕西2020行政区划调整
- html背景半透明 字不变,css实现背景半透明文字不透明的效果示例
- 为什么我不建议你裸辞做自媒体?
- android模拟器 菜单键,夜神安卓模拟器系统设置有哪些?
- CAD打印怎么布满图纸?
- 网络通信技术(TCP/IP)