index.js (4078B)
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 original C code, long comment, copyright, license, and constants are from [Cephes]{@link http://www.netlib.org/cephes}. The implementation follows the original, but has been modified for JavaScript. 22 * 23 * ```text 24 * Copyright 1985, 1995, 2000 by Stephen L. Moshier 25 * 26 * Some software in this archive may be from the book _Methods and Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster International, 1989) or from the Cephes Mathematical Library, a commercial product. In either event, it is copyrighted by the author. What you see here may be used freely but it comes with no support or guarantee. 27 * 28 * Stephen L. Moshier 29 * moshier@na-net.ornl.gov 30 * ``` 31 */ 32 33 'use strict'; 34 35 // MODULES // 36 37 var evalpoly = require( './../../../../../base/tools/evalpoly' ).factory; // TODO: replace with compiled polyval functions 38 var floor = require( './../../../../../base/special/floor' ); 39 var ldexp = require( './../../../../../base/special/ldexp' ); 40 var isnan = require( './../../../../../base/assert/is-nan' ); 41 var isinfinite = require( './../../../../../base/assert/is-infinite' ); 42 43 44 // VARIABLES // 45 46 var DP1 = 7.85398125648498535156e-1; // 0x3fe921fb40000000, Pi/4 split into three parts 47 var DP2 = 3.77489470793079817668e-8; // 0x3e64442d00000000, 48 var DP3 = 2.69515142907905952645e-15; // 0x3ce8469898cc5170, 49 var PIO4 = 7.85398163397448309616E-1; // 4/pi 50 var SIN_COEF = [ 51 -1.66666666666666307295e-1, // 0xbfc5555555555548 52 8.33333333332211858878e-3, // 0x3f8111111110f7d0 53 -1.98412698295895385996e-4, // 0xbf2a01a019bfdf03 54 2.75573136213857245213e-6, // 0x3ec71de3567d48a1 55 -2.50507477628578072866e-8, // 0xbe5ae5e5a9291f5d 56 1.58962301576546568060e-10 // 0x3de5d8fd1fd19ccd 57 ]; 58 var COS_COEF = [ 59 4.16666666666665929218e-2, // 0x3fa555555555554b 60 -1.38888888888730564116e-3, // 0xbf56c16c16c14f91 61 2.48015872888517045348e-5, // 0x3efa01a019c844f5 62 -2.75573141792967388112e-7, // 0xbe927e4f7eac4bc6 63 2.08757008419747316778e-9, // 0x3e21ee9d7b4e3f05 64 -1.13585365213876817300e-11 // 0xbda8fa49a0861a9b 65 ]; 66 67 68 // FUNCTIONS // 69 70 // Compile functions to evaluate polynomial functions based on the above coefficients... 71 var polyvalSIN = evalpoly( SIN_COEF ); 72 var polyvalCOS = evalpoly( COS_COEF ); 73 74 75 // MAIN // 76 77 /** 78 * Computes the cosine of a number. 79 * 80 * @param {number} x - input value 81 * @returns {number} cosine (in radians) 82 * 83 * @example 84 * var v = cos( 0.0 ); 85 * // returns 1.0 86 * 87 * @example 88 * var v = cos( 3.14/4.0 ); 89 * // returns ~0.707 90 * 91 * @example 92 * var v = cos( -3.14/6.0 ); 93 * // returns ~0.866 94 * 95 * @example 96 * var v = cos( NaN ); 97 * // returns NaN 98 */ 99 function cos( x ) { 100 var sgn; 101 var zz; 102 var i; 103 var j; 104 var y; 105 var z; 106 107 if ( isnan( x ) || isinfinite( x ) ) { 108 return NaN; 109 } 110 111 // Make argument positive... 112 sgn = 1; 113 if ( x < 0 ) { 114 x = -x; 115 } 116 117 y = floor( x/PIO4 ); 118 z = ldexp( y, -4 ); 119 z = floor( z ); // Integer part of y/8 120 z = y - ldexp( z, 4 ); // y - 16 * (y/16) 121 122 // Integer and fractional part modulo one octant... 123 i = y; 124 125 // Map zeros to origin... 126 if ( i & 1 ) { 127 i += 1; 128 y += 1.0; 129 } 130 j = i & 7; 131 if ( j > 3 ) { 132 j -= 4; 133 sgn = -sgn; 134 } 135 if ( j > 1 ) { 136 sgn = -sgn; 137 } 138 139 // Extended precision modular arithmetic... 140 z = ( ( x - ( y*DP1 ) ) - ( y*DP2 ) ) - ( y * DP3 ); 141 zz = z * z; 142 143 if ( j === 1 || j === 2 ) { 144 y = z + ( z * z * z * polyvalSIN( zz ) ); 145 } else { 146 y = 1.0 - ldexp( zz, -1 ) + ( zz * zz * polyvalCOS( zz ) ); 147 } 148 149 if ( sgn < 0 ) { 150 y = -y; 151 } 152 return y; 153 } 154 155 156 // EXPORTS // 157 158 module.exports = cos;