time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

kernel_sin.js (3756B)


      1 /**
      2 * @license Apache-2.0
      3 *
      4 * Copyright (c) 2018 The Stdlib Authors.
      5 *
      6 * Licensed under the Apache License, Version 2.0 (the "License");
      7 * you may not use this file except in compliance with the License.
      8 * You may obtain a copy of the License at
      9 *
     10 *    http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing, software
     13 * distributed under the License is distributed on an "AS IS" BASIS,
     14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15 * See the License for the specific language governing permissions and
     16 * limitations under the License.
     17 *
     18 *
     19 * ## Notice
     20 *
     21 * The following copyright, license, and long comment were part of the original implementation available as part of [FreeBSD]{@link https://svnweb.freebsd.org/base/release/9.3.0/lib/msun/src/k_sin.c}. The implementation follows the original, but has been modified for JavaScript.
     22 *
     23 * ```text
     24 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
     25 *
     26 * Developed at SunPro, a Sun Microsystems, Inc. business.
     27 * Permission to use, copy, modify, and distribute this
     28 * software is freely granted, provided that this notice
     29 * is preserved.
     30 * ```
     31 */
     32 
     33 'use strict';
     34 
     35 // VARIABLES //
     36 
     37 var S1 = -1.66666666666666324348e-01; // 0xBFC55555, 0x55555549
     38 var S2 = 8.33333333332248946124e-03;  // 0x3F811111, 0x1110F8A6
     39 var S3 = -1.98412698298579493134e-04; // 0xBF2A01A0, 0x19C161D5
     40 var S4 = 2.75573137070700676789e-06;  // 0x3EC71DE3, 0x57B1FE7D
     41 var S5 = -2.50507602534068634195e-08; // 0xBE5AE5E6, 0x8A2B9CEB
     42 var S6 = 1.58969099521155010221e-10;  // 0x3DE5D93A, 0x5ACFD57C
     43 
     44 
     45 // MAIN //
     46 
     47 /**
     48 * Computes the sine on \\( \approx \[-\pi/4, \pi/4] \\) (except on \\(-0\\)), where \\( \pi/4 \approx 0.7854 \\).
     49 *
     50 * ## Method
     51 *
     52 * -   Since \\( \sin(-x) = -\sin(x) \\), we need only to consider positive \\(x\\).
     53 *
     54 * -   Callers must return \\( \sin(-0) = -0 \\) without calling here since our odd polynomial is not evaluated in a way that preserves \\(-0\\). Callers may do the optimization \\( \sin(x) \approx x \\) for tiny \\(x\\).
     55 *
     56 * -   \\( \sin(x) \\) is approximated by a polynomial of degree \\(13\\) on \\( \left\[0,\tfrac{pi}{4}\right] \\)
     57 *
     58 *     ```tex
     59 *     \sin(x) \approx x + S_1 \cdot x^3 + \ldots + S_6 \cdot x^{13}
     60 *     ```
     61 *
     62 *     where
     63 *
     64 *     ```tex
     65 *     \left| \frac{\sin(x)}{x} \left( 1 + S_1 \cdot x + S_2 \cdot x + S_3 \cdot x + S_4 \cdot x + S_5 \cdot x + S_6 \cdot x \right) \right| \le 2^{-58}
     66 *     ```
     67 *
     68 * -   We have
     69 *
     70 *     ```tex
     71 *     \sin(x+y) = \sin(x) + \sin'(x') \cdot y \approx \sin(x) + (1-x*x/2) \cdot y
     72 *     ```
     73 *
     74 *     For better accuracy, let
     75 *
     76 *     ```tex
     77 *     r = x^3 * \left( S_2 + x^2 \cdot \left( S_3 + x^2 * \left( S_4 + x^2 \cdot ( S_5+x^2 \cdot S_6 ) \right) \right) \right)
     78 *     ```
     79 *
     80 *     then
     81 *
     82 *     ```tex
     83 *     \sin(x) = x + \left( S_1 \cdot x + ( x \cdot (r-y/2) + y ) \right)
     84 *     ```
     85 *
     86 *
     87 * @param {number} x - input value (in radians, assumed to be bounded by `~pi/4` in magnitude)
     88 * @param {number} y - tail of `x`
     89 * @returns {number} sine
     90 *
     91 * @example
     92 * var v = kernelSin( 0.0, 0.0 );
     93 * // returns ~0.0
     94 *
     95 * @example
     96 * var v = kernelSin( 3.141592653589793/6.0, 0.0 );
     97 * // returns ~0.5
     98 *
     99 * @example
    100 * var v = kernelSin( 0.619, 9.279e-18 );
    101 * // returns ~0.58
    102 *
    103 * @example
    104 * var v = kernelSin( NaN, 0.0 );
    105 * // returns NaN
    106 *
    107 * @example
    108 * var v = kernelSin( 3.0, NaN );
    109 * // returns NaN
    110 *
    111 * @example
    112 * var v = kernelSin( NaN, NaN );
    113 * // returns NaN
    114 */
    115 function kernelSin( x, y ) {
    116 	var r;
    117 	var v;
    118 	var w;
    119 	var z;
    120 
    121 	z = x * x;
    122 	w = z * z;
    123 	r = S2 + (z * (S3 + (z*S4))) + (z * w * (S5 + (z*S6)));
    124 	v = z * x;
    125 	if ( y === 0.0 ) {
    126 		return x + (v * (S1 + (z*r)));
    127 	}
    128 	return x - (((z*((0.5*y) - (v*r))) - y) - (v*S1));
    129 }
    130 
    131 
    132 // EXPORTS //
    133 
    134 module.exports = kernelSin;