项目中需要快速求解Asin(x) 的近似值,原以为用泰勒展开式会快一些,结果比原生的慢一倍。

Math.ASin
        Time Elapsed:   9ms
        Gen 0:          0
        Gen 1:          0
        Gen 2:          0
Maclaurin.ASin
        Time Elapsed:   17ms
        Gen 0:          4
        Gen 1:          0
        Gen 2:          0

各位,谁有能力改进?

附:

http://www.mathportal.org/formulas/pdf/taylor-series-formulas.pdf

http://pages.pacificcoast.net/~cazelais/260/maclaurin.pdf

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
using Diagnostics; namespace Asin
{
class Program
{
static void Main(string[] args)
{
int count = 100000;
List<double> values = new List<double>(count); Random r = new Random();
for (var i = 0; i <= count; ++i)
{
values .Add(r.NextDouble() * 2 - 1);
} CodeTime.Init();
int? iter = 0;
CodeTime.Timer("Math.ASin", count, () =>
{
var i = iter.Value + 1;
iter = i; Math.Asin(values[i]); }); iter = 0;
CodeTime.Timer("Maclaurin.ASin", count, () =>
{
var i = iter.Value + 1;
iter = i; Maclaurin.Asin(values[i],3); }); while (true)
{
iter = 0;
CodeTime.Timer("Math.ASin", count, () =>
{
var i = iter.Value + 1;
iter = i; Math.Asin(values[i]); }); iter = 0;
CodeTime.Timer("Maclaurin.ASin", count, () =>
{
var i = iter.Value + 1;
iter = i; Maclaurin.Asin(values[i], 3); });
} //var ret = Maclaurin.Asin(0.5, 3);
//var ret2 = Math.Asin(0.5);
//Console.WriteLine(ret);
//Console.WriteLine(ret2);
Console.ReadLine();
}
} class Maclaurin
{
class ASinImpl
{
private List<double> quotieties = new List<double>();
private IEnumerator<double> computeQuotieties = null; public ASinImpl()
{
this.computeQuotieties = ComputeQuotiety();
} public double Calc(double v, int precision = 2)
{
if (quotieties.Count < precision)
{
for (var i = quotieties.Count; i < precision; ++i)
{
computeQuotieties.MoveNext();
quotieties.Add(computeQuotieties.Current);
}
} double ret = 0;
var values = ComputeValues(v);
for (int i = 0; i < precision; ++i)
{
values.MoveNext();
ret += quotieties[i]*values.Current;
} return ret;
} private IEnumerator<double> ComputeValues(double v)
{
double ret = 1;
double q = v*v;
for(int i = 0;;++i)
{ if (i == 0)
{
ret = v;
yield return ret;
}
else
{
ret *= q;
yield return ret;
}
} throw new NotImplementedException();
} private IEnumerator<double> ComputeQuotiety()
{
for (int i = 0;; i++)
{ double up = Factorial(2*i); double down = Math.Pow(Math.Pow(2, i)*Factorial(i), 2)*(2*i + 1); double quotiety = up/down; yield return quotiety; } throw new NotImplementedException();
} private long Factorial(long v )
{
if( v < 0)
throw new ArgumentOutOfRangeException("v"); if (v == 0)
return 1; if (v == 1)
return 1; long ret = 1;
for (int i = 2; i <= v; ++i)
{
ret *= i;
} return ret;
}
} private static ASinImpl asinImpl = new ASinImpl(); /// <summary>
///
/// </summary>
/// <param name="v"></param>
/// <param name="precision"></param>
/// <returns></returns>
public static double Asin(double v, int precision)
{
if (v < -1 || v > 1)
{
throw new ArgumentOutOfRangeException("v");
} return asinImpl.Calc(v, precision);
}
}
}

通过一下优化:基本持平

  class ASinImpl
{
private readonly int _precision;
private double[] _quotieties = null;
private long[] _factorials =null;
public ASinImpl(int precision = 3)
{
_precision = precision;
_quotieties = new double[precision + 1];
_factorials = new long[(precision + 2)*2 + 1];
Factorial();
ComputeQuotiety();
} public double Calc(double v)
{
unchecked
{
double retVal = 0; double vVal = 1;
double q = v * v;
unsafe
{
fixed (double* pq = _quotieties)
{
for (int i = 0; i < _precision; ++i)
{ if (i == 0)
{
vVal = v;
//yield return ret;
retVal += pq[i] * vVal;
}
else
{
vVal *= q;
//yield return ret;
retVal += pq[i] * vVal;
}
} return retVal;
} } } } private void ComputeQuotiety()
{
unchecked
{
int precision = _quotieties.Length;
for (int i = 0; i < precision; i++)
{ double up = _factorials[2*i]; double down = Math.Pow(Math.Pow(2, i)*_factorials[i], 2)*(2*i + 1); double quotiety = up/down; _quotieties[i] = quotiety; }
} } private void Factorial()
{
unchecked
{
int precision = _factorials.Length ;
long ret = 1;
for (long v = 0; v < precision; ++v)
{
if (v == 0)
{
this._factorials[v] = 1;
}
else if (v == 1){
this._factorials[v] = 1;
}
else
{
ret *= v; this._factorials[v] = ret;
} }
}
}
}

实现 Math.Asin 迈克劳林(泰勒)展开式,结果比Math.Asin 慢一倍的更多相关文章

  1. YTU 2452: 麦克劳林用于函数求值

    2452: 麦克劳林用于函数求值 时间限制: 1 Sec  内存限制: 128 MB 提交: 18  解决: 12 题目描述 泰勒公式是一个用函数在某点的信息描述其附近取值的公式.如果函数足够光滑的话 ...

  2. python数学第二天【泰勒展开式】

    1. 泰勒展开式 推论1: 泰勒展开式的应用 推论2: 推论3:

  3. luogu P2000 拯救世界 生成函数_麦克劳林展开_python

    模板题. 将所有的多项式按等比数列求和公式将生成函数压缩,相乘后麦克劳林展开即可. Code: n=int(input()) print((n+1)*(n+2)*(n+3)*(n+4)//24)

  4. bzoj 3028: 食物 生成函数_麦克劳林展开

    不管怎么求似乎都不太好求,我们试试生成函数.这个东西好神奇.生成函数的精华是两个生成函数相乘,对应 $x^{i}$ 前的系数表示取 $i$ 个时的方案数. 有时候,我们会将函数按等比数列求和公式进行压 ...

  5. XGBoost 完整推导过程

    参考: 陈天奇-"XGBoost: A Scalable Tree Boosting System" Paper地址: <https://arxiv.org/abs/1603 ...

  6. 【数学基础篇】---详解极限与微分学与Jensen 不等式

    一.前述 数学基础知识对机器学习还有深度学习的知识点理解尤为重要,本节主要讲解极限等相关知识. 二.极限 1.例子 当 x 趋于 0 的时候,sin(x) 与 tan(x) 都趋于 0. 但是哪一个趋 ...

  7. bzoj3028食物

    http://www.lydsy.com/JudgeOnline/problem.php?id=3028 好吧,这是我第一道生成函数的题目. 先搞出各种食物的生成函数: 汉堡:$1+x^2+x^4+. ...

  8. JavaScript中Math对象的方法介绍

    1.比较最值方法 比较最值有两种方法,max() 和 min() 方法. 1.1 max() 方法,比较一组数值中的最大值,返回最大值. var maxnum = Math.max(12,6,43,5 ...

  9. JavaScript Math和Number对象

    目录 1. Math 对象:数学对象,提供对数据的数学计算.如:获取绝对值.向上取整等.无构造函数,无法被初始化,只提供静态属性和方法. 2. Number 对象 :Js中提供数字的对象.包含整数.浮 ...

随机推荐

  1. [转载] 构造linux 系统下免密码ssh登陆  _How to establish password-less login with SSH

    In present (post production) IT infrastructure many different workstations, servers etc. have to be ...

  2. Tween Animation----Alpha渐变透明度动画

    本博文是我自己操作过的并且能运行才给大家分享的 layout ----activity_main.xml 在res/新建一个anim文件夹,用来保存动画属性的xml 在anim文件夹里新建一个alph ...

  3. Bug库

    netsh int tcp set global  ecn=disable C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe ...

  4. XV Open Cup named after E.V. Pankratiev. GP of Tatarstan

    A. Survival Route 留坑. B. Dispersed parentheses $f[i][j][k]$表示长度为$i$,未匹配的左括号数为$j$,最多的未匹配左括号数为$k$的方案数. ...

  5. Java 数列求和

    编写程序,显示1+2+3+4+5+6+7+8+9的结果 public class Homework006 { public static void main(String[] args) { int ...

  6. 洛谷1640 bzoj1854游戏 匈牙利就是又短又快

    bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...

  7. Oracle Database 创建HR模式

    其实Oracle是自带演示模式的,我还一直在跪舔外面的培训机构的sql文件 首先以system 用户登陆SQL 输入: alter user hr account unlock identified ...

  8. centos中docker mongodb 配置

    安装docker,对于Centos7,如下: $ sudo yum update$ sudo yum -y install docker$ sudo systemctl start docker 首先 ...

  9. 联想昭阳E47外接显示器屏幕由扩展改为复制

    公司给我配的电脑室是联想昭阳e47,显卡是集成显卡,很差,做开发看显示屏久了眼睛很累视力会下降的很快. 所以本人自己买了一个三星22寸的显示器,京东上¥779买的,第二天早上就送来了. 之前我自己的电 ...

  10. How Long Does It Take

    好长时间没写博客了,真心惭愧啊! 废话少说,原题链接:https://pta.patest.cn/pta/test/1342/exam/4/question/24939 题目如下: Given the ...