项目中需要快速求解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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.Remoting.Messaging;
  5. using System.Text;
  6. using Diagnostics;
  7.  
  8. namespace Asin
  9. {
  10. class Program
  11. {
  12. static void Main(string[] args)
  13. {
  14. int count = 100000;
  15. List<double> values = new List<double>(count);
  16.  
  17. Random r = new Random();
  18. for (var i = 0; i <= count; ++i)
  19. {
  20. values .Add(r.NextDouble() * 2 - 1);
  21. }
  22.  
  23. CodeTime.Init();
  24. int? iter = 0;
  25. CodeTime.Timer("Math.ASin", count, () =>
  26. {
  27. var i = iter.Value + 1;
  28. iter = i;
  29.  
  30. Math.Asin(values[i]);
  31.  
  32. });
  33.  
  34. iter = 0;
  35. CodeTime.Timer("Maclaurin.ASin", count, () =>
  36. {
  37. var i = iter.Value + 1;
  38. iter = i;
  39.  
  40. Maclaurin.Asin(values[i],3);
  41.  
  42. });
  43.  
  44. while (true)
  45. {
  46. iter = 0;
  47. CodeTime.Timer("Math.ASin", count, () =>
  48. {
  49. var i = iter.Value + 1;
  50. iter = i;
  51.  
  52. Math.Asin(values[i]);
  53.  
  54. });
  55.  
  56. iter = 0;
  57. CodeTime.Timer("Maclaurin.ASin", count, () =>
  58. {
  59. var i = iter.Value + 1;
  60. iter = i;
  61.  
  62. Maclaurin.Asin(values[i], 3);
  63.  
  64. });
  65. }
  66.  
  67. //var ret = Maclaurin.Asin(0.5, 3);
  68. //var ret2 = Math.Asin(0.5);
  69. //Console.WriteLine(ret);
  70. //Console.WriteLine(ret2);
  71. Console.ReadLine();
  72. }
  73. }
  74.  
  75. class Maclaurin
  76. {
  77. class ASinImpl
  78. {
  79. private List<double> quotieties = new List<double>();
  80. private IEnumerator<double> computeQuotieties = null;
  81.  
  82. public ASinImpl()
  83. {
  84. this.computeQuotieties = ComputeQuotiety();
  85. }
  86.  
  87. public double Calc(double v, int precision = 2)
  88. {
  89. if (quotieties.Count < precision)
  90. {
  91. for (var i = quotieties.Count; i < precision; ++i)
  92. {
  93. computeQuotieties.MoveNext();
  94. quotieties.Add(computeQuotieties.Current);
  95. }
  96. }
  97.  
  98. double ret = 0;
  99. var values = ComputeValues(v);
  100. for (int i = 0; i < precision; ++i)
  101. {
  102. values.MoveNext();
  103. ret += quotieties[i]*values.Current;
  104. }
  105.  
  106. return ret;
  107. }
  108.  
  109. private IEnumerator<double> ComputeValues(double v)
  110. {
  111. double ret = 1;
  112. double q = v*v;
  113. for(int i = 0;;++i)
  114. {
  115.  
  116. if (i == 0)
  117. {
  118. ret = v;
  119. yield return ret;
  120. }
  121. else
  122. {
  123. ret *= q;
  124. yield return ret;
  125. }
  126. }
  127.  
  128. throw new NotImplementedException();
  129. }
  130.  
  131. private IEnumerator<double> ComputeQuotiety()
  132. {
  133. for (int i = 0;; i++)
  134. {
  135.  
  136. double up = Factorial(2*i);
  137.  
  138. double down = Math.Pow(Math.Pow(2, i)*Factorial(i), 2)*(2*i + 1);
  139.  
  140. double quotiety = up/down;
  141.  
  142. yield return quotiety;
  143.  
  144. }
  145.  
  146. throw new NotImplementedException();
  147. }
  148.  
  149. private long Factorial(long v )
  150. {
  151. if( v < 0)
  152. throw new ArgumentOutOfRangeException("v");
  153.  
  154. if (v == 0)
  155. return 1;
  156.  
  157. if (v == 1)
  158. return 1;
  159.  
  160. long ret = 1;
  161. for (int i = 2; i <= v; ++i)
  162. {
  163. ret *= i;
  164. }
  165.  
  166. return ret;
  167. }
  168. }
  169.  
  170. private static ASinImpl asinImpl = new ASinImpl();
  171.  
  172. /// <summary>
  173. ///
  174. /// </summary>
  175. /// <param name="v"></param>
  176. /// <param name="precision"></param>
  177. /// <returns></returns>
  178. public static double Asin(double v, int precision)
  179. {
  180. if (v < -1 || v > 1)
  181. {
  182. throw new ArgumentOutOfRangeException("v");
  183. }
  184.  
  185. return asinImpl.Calc(v, precision);
  186. }
  187. }
  188. }

通过一下优化:基本持平

  1. class ASinImpl
  2. {
  3. private readonly int _precision;
  4. private double[] _quotieties = null;
  5. private long[] _factorials =null;
  6. public ASinImpl(int precision = 3)
  7. {
  8. _precision = precision;
  9. _quotieties = new double[precision + 1];
  10. _factorials = new long[(precision + 2)*2 + 1];
  11. Factorial();
  12. ComputeQuotiety();
  13. }
  14.  
  15. public double Calc(double v)
  16. {
  17. unchecked
  18. {
  19. double retVal = 0;
  20.  
  21. double vVal = 1;
  22. double q = v * v;
  23. unsafe
  24. {
  25. fixed (double* pq = _quotieties)
  26. {
  27. for (int i = 0; i < _precision; ++i)
  28. {
  29.  
  30. if (i == 0)
  31. {
  32. vVal = v;
  33. //yield return ret;
  34. retVal += pq[i] * vVal;
  35. }
  36. else
  37. {
  38. vVal *= q;
  39. //yield return ret;
  40. retVal += pq[i] * vVal;
  41. }
  42. }
  43.  
  44. return retVal;
  45. }
  46.  
  47. }
  48.  
  49. }
  50.  
  51. }
  52.  
  53. private void ComputeQuotiety()
  54. {
  55. unchecked
  56. {
  57. int precision = _quotieties.Length;
  58. for (int i = 0; i < precision; i++)
  59. {
  60.  
  61. double up = _factorials[2*i];
  62.  
  63. double down = Math.Pow(Math.Pow(2, i)*_factorials[i], 2)*(2*i + 1);
  64.  
  65. double quotiety = up/down;
  66.  
  67. _quotieties[i] = quotiety;
  68.  
  69. }
  70. }
  71.  
  72. }
  73.  
  74. private void Factorial()
  75. {
  76. unchecked
  77. {
  78. int precision = _factorials.Length ;
  79. long ret = 1;
  80. for (long v = 0; v < precision; ++v)
  81. {
  82. if (v == 0)
  83. {
  84. this._factorials[v] = 1;
  85. }
  86. else if (v == 1){
  87. this._factorials[v] = 1;
  88. }
  89. else
  90. {
  91. ret *= v;
  92.  
  93. this._factorials[v] = ret;
  94. }
  95.  
  96. }
  97. }
  98. }
  99. }

实现 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. Protocol Buffer搭建及示例

    本文来源:http://www.tanhao.me/code/150911.html/ Protocol Buffer(简称Protobuf或PB)是由Google推出的一种数据交换格式,与传统的XM ...

  2. [leetcode] 小心成环

    156. Binary Tree Upside Down Given a binary tree where all the right nodes are either leaf nodes wit ...

  3. 连接Linux下 XAMPP集成环境中部署的禅道的数据库MariaDB

    用mysql数据库工具连接linuxmysql环境,但是会遇到连接失败的问题,如下所示: 这就需要涉及到另外的问题了,需要我们打开mysql的连接授权,具体的操作步骤如下: 1)在xshell里进入m ...

  4. [spring源码学习]十、IOC源码-conversionService

    一.代码示例 1.我们在之前的Person类里新增一个两个属性,分别是客户的兴趣和生日,兴趣爱好有很多,我们使用list进行保存,生日使用日期进行保存 public class Person { pr ...

  5. jQuery Validate验证框架详解

    转自:http://www.cnblogs.com/linjiqin/p/3431835.html jQuery校验官网地址:http://bassistance.de/jquery-plugins/ ...

  6. 【转】通过Hibernate将数据 存入oracle数据库例子

    一. Hibernate介绍 Hibernate是基于对象/关系映射(ORM,Object/Relational Mapping)的一个解决方案.ORM方案的思想是将对象模型表示的对象映射到关系型数据 ...

  7. linux终端 字符界面 显示乱码

    方法一:配置SSH工具 SecureCRT中文版配置 [全局选项]→[默认会话]→[编辑默认设置]→[终端]→[外观]→[字体]→[新宋体 10pt CHINESE_GB2312]→[字符编码 UTF ...

  8. Cocos2d 利用继承Draw方法制作可显示三维数据(宠物三维等)的三角形显示面板

    很久没有写博客了,这段时间比较忙,又是搬家又是做自己的项目,还有太多琐碎的事情缠身,好不容易抽出时间把最近自己做的一些简单例子记录一下. 在我的项目中,我需要一个显示面板来显示游戏中的一个三维数据,例 ...

  9. CentOS7 编译安装LVS 互为主备 (实测 笔记 Centos 7.0 + ipvsadm 1.27 + keepalived 1.2.15 )

    环境: 系统硬件:vmware vsphere (CPU:2*4核,内存2G,双网卡) LVS服务器(两台): 系统:Centos7.0 64位(LVS+keepalived) LvsMaster:1 ...

  10. mysql 表表连接的问题。

    select * from table a, table b where a.aid = b.bid and aid >100 这样连接,如果a有数据,b没有数据,  a.aid = b.bid ...