| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 | <!doctype html><meta charset="utf-8"><script src="https://distill.pub/template.v1.js"></script><link rel="stylesheet" href="style.css"><script defer src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.9.0/katex.min.js" integrity="sha384-jmxIlussZWB7qCuB+PgKG1uLjjxbVVIayPJwi6cG6Zb4YKq0JIw+OMnkkEC7kYCq" crossorigin="anonymous"></script><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.9.0/katex.min.css" integrity="sha384-TEMocfGvRuD1rIAacqrknm5BQZ7W7uWitoih+jMNFXQIbNl16bO8OZmylH/Vi/Ei" crossorigin="anonymous"><script defer src="bundle.js"></script><script type="text/front-matter">  title: "WebAssembly Cephes - mathematical special functions in JavaScript"  description: >    Using Emscripten to compile a WebAssembly version of Cephes, we finally    have a fast and correct implementations of most mathematical special    functions.  authors:  - Andreas Madsen: https://github.com/AndreasMadsen  affiliations:  - nearForm: https://nearform.com</script><dt-article>  <h1>WebAssembly Cephes - mathematical special functions in JavaScript</h1>  <dt-byline></dt-byline></dt-article><dt-article>  <h2>Introduction</h2>  <p>    A lot of the mathematical implementations we do at NearForm depends on    so-called <a href="https://en.wikipedia.org/wiki/Special_functions">      mathematical special functions</a>. There is no clearly defined    criteria for what a special function is, but suffice to say they are    functions that often turn up in mathematics and most of them are    notoriously hard to compute. Often they are defined as the solution to    a well-posed problem. However the solution itself is not easy to compute.  </p>  <p>    JavaScript is severely lacking in implementations of these special functions,    especially trusted implementations. If you are lucky, you can find    a basic implementation in npm. However, the implementations often have    numerous undocumented issues and only work somewhat well for a    small and undocumented input range.  </p>  <p>    In R these functions are often built-in, and in Python,    <a href="https://www.scipy.org/">SciPy</a> implements these functions.    Deep within the <a href="https://github.com/scipy/scipy/tree/master/scipy/special/cephes">      SciPy source code</a>, we    find the <a href="http://www.netlib.org/cephes/">Cephes library</a>    which is what implements many of these functions.  </p>  <p>    Cephes is a pure C library, that doesn't depend on anything, including    the <a href="https://en.wikipedia.org/wiki/C_standard_library">      C standard library</a>. This makes it ideal to be compiled to WebAssembly    using <a href="http://emscripten.org">emscripten</a>, as it means there won't be calls between JavaScript    and WebAssembly which could otherwise cause performance issues.  </p>  <p>    We have released the WebAssembly version of Cephes on npm, see    <a href="https://www.npmjs.com/package/cephes">https://www.npmjs.com/package/cephes</a>.    So all you need is to install it with <code>npm install cephes</code>.  </p>  <p>    Using our Cephes module is very simple, as we have wrapped each WebAssembly    function in a custom JavaScript function that takes care of all the    memory management.  </p>  <dt-code block language="js">const cephes = require('cephes');const value = cephes.gamma(2);  </dt-code></dt-article><dt-article>  <h2>Examples</h2>  <p>    Below are just a few examples of the 125 available functions. You can see all of them    in our <a href="https://github.com/nearform/node-cephes">README file</a>.  </p>  <p>    All of the values that make up the graph are calculated dynamically in your    browser. This gives you an idea of just how fast Cephes in WebAssembly is.  </p>  <figure>    <div id="ar-walkthrough">      <div class="ar-walkthrough-step">        <div class="ar-walkthrough-number">1</div>        <p class="ar-walkthrough-text">          The <a href="https://en.wikipedia.org/wiki/Bessel_function">Bessel function</a> is the solution to the equation          <math-latex display-mode latex="x^{2}{\frac {d^{2}y}{dx^{2}}}+x{\frac {dy}{dx}}+\left(x^{2}-\alpha ^{2}\right)y=0"></math-latex>          The Bessel function is typically used in partial differential equations,          where <math-latex latex="\alpha"></math-latex> will often be a fixed integer.        </p>      </div>      <div class="ar-walkthrough-step">        <div class="ar-walkthrough-number">2</div>        <p class="ar-walkthrough-text">          The <a href="https://en.wikipedia.org/wiki/Gamma">Gamma function</a> <math-latex latex="\Gamma(x)"></math-latex>          is used in many probability distributions.          <math-latex display-mode latex="\Gamma (x)=\int _{0}^{\infty }y^{x-1}e^{-y}\,dy"></math-latex>          As its value increases          very quickly, it is often the <math-latex latex="\ln(\Gamma(x))"></math-latex>          function that is used in practice. Cephes has dedicated          implementations for both. The DiGamma function          <math-latex latex="\psi(x)"></math-latex>, is its derivative and          also appear frequently in probability theory.          <math-latex display-mode latex="\psi (x)={\frac {d}{dx}}\ln {\big (}\Gamma (x){\big )}={\frac {\Gamma '(x)}{\Gamma (x)}}"></math-latex>        </p>      </div>      <div class="ar-walkthrough-step">        <div class="ar-walkthrough-number">3</div>        <p class="ar-walkthrough-text">          The <a href="https://en.wikipedia.org/wiki/Beta_distribution">beta distribution</a> is central in a lot of Bayesian statistics.          <math-latex display-mode latex="f_{\mathrm{B}}(x; \alpha, \beta) = \frac{x^{\alpha-1}(1-x)^{\beta-1}}{\mathrm{B}(\alpha,\beta)}"></math-latex>          The cumulative distribution function is notoriously hard to compute,          but this function is also implemented by Cephes.          <math-latex display-mode latex="I_x(\alpha, \beta) = \frac{1}{\mathrm{B}(\alpha,\beta)} \int _{0}^{x}t^{a-1}\,(1-t)^{b-1}\,dt"></math-latex>        </p>      </div>      <div class="ar-walkthrough-step">        <div class="ar-walkthrough-number">4</div>        <p class="ar-walkthrough-text">          The <a href="https://en.wikipedia.org/wiki/Airy_function">Airy function</a> <math-latex latex="Ai(x)"></math-latex> is the solution to the differential equation          <math-latex display-mode latex="\frac{d^2y}{dx^2} - xy = 0"></math-latex>          It is often used in physics such as quantum mechanics. Cephes also          defines it compimentary function <math-latex latex="Bi(x)"></math-latex>          and their derivatives <math-latex latex="Ai'(x)"></math-latex> and          <math-latex latex="Bi'(x)"></math-latex>.        </p>      </div>      <div class="ar-walkthrough-pages">        <span class="ar-walkthrough-page">1</span>        <span class="ar-walkthrough-page">2</span>        <span class="ar-walkthrough-page">3</span>        <span class="ar-walkthrough-page">4</span>      </div>    </div>    <div id="ar-line-graph"></div>    <figcaption>      <strong>Mathematical special functions:</strong> shows various mathematical      special functions. Try clicking the page numbers 1, 2, 3, or 4 to change      the function.    </figcaption>  </figure></dt-article><dt-article>  <h2>Cephes as an Open Source project</h2>  <p>    Whilst Cephes lacks a general license, its author, Stephen L. Moshier, has kindly    <a href="https://github.com/nearform/node-cephes/blob/master/LICENSE">      granted us permission to license it </a> as    <a href="https://tldrlegal.com/license/bsd-3-clause-license-(revised)">      BSD-3-Clause</a>. Whilst the library continues to be maintained, it doesn't    use some of the more modern approximation methods for many of the special functions.  </p>  <p>    The good news is that R and SciPy    <a href="https://qz.com/1270139/r-and-python-are-joining-forces-in-the-most-ambitious-crossover-event-of-the-year-for-programmers/">      are working together on making a better Open Source library of these    special functions</a>. But it will take a while before that library is    ready and until then Cephes is by far the best choice.  </p></dt-article><dt-article>  <h2>Contact</h2>  <p>    The mathematical special functions have so many use cases. If you think    your business could benefit from math, such as statistics, logistics, or    something else. Then please feel free to contact us at    <a href="https://www.nearform.com/contact/">https://www.nearform.com/contact/</a>.  </p></dt-article><dt-appendix></dt-appendix><script type="text/bibliography"></script>
 |