asin.js (3311B)
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 1984, 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 isnan = require( './../../../../base/assert/is-nan' ); 38 var sqrt = require( './../../../../base/special/sqrt' ); 39 var PIO4 = require( '@stdlib/constants/float64/fourth-pi' ); 40 var ratevalPQ = require( './rational_pq.js' ); 41 var ratevalRS = require( './rational_rs.js' ); 42 43 44 // VARIABLES // 45 46 var MOREBITS = 6.123233995736765886130e-17; // pi/2 = PIO2 + MOREBITS 47 48 49 // MAIN // 50 51 /** 52 * Computes the arcsine of a number. 53 * 54 * ## Method 55 * 56 * - A rational function of the form 57 * 58 * ```tex 59 * x + x^3 \frac{P(x^2)}{Q(x^2)} 60 * ``` 61 * 62 * is used for \\(\|x\|\\) in the interval \\(\[0, 0.5\]\\). If \\(\|x\| > 0.5\\), it is transformed by the identity 63 * 64 * ```tex 65 * \operatorname{asin}(x) = \frac{\pi}{2} - 2 \operatorname{asin}( \sqrt{ (1-x)/2 } ) 66 * ``` 67 * 68 * ## Notes 69 * 70 * - Relative error: 71 * 72 * | arithmetic | domain | # trials | peak | rms | 73 * |:-----------|:-------|:---------|:--------|:--------| 74 * | DEC | -1, 1 | 40000 | 2.6e-17 | 7.1e-18 | 75 * | IEEE | -1, 1 | 10^6 | 1.9e-16 | 5.4e-17 | 76 * 77 * @param {number} x - input value 78 * @returns {number} arcsine (in radians) 79 * 80 * @example 81 * var v = asin( 0.0 ); 82 * // returns ~0.0 83 * 84 * @example 85 * var v = asin( 3.141592653589793/4.0 ); 86 * // returns ~0.903 87 * 88 * @example 89 * var v = asin( -3.141592653589793/6.0 ); 90 * // returns ~-0.551 91 * 92 * @example 93 * var v = asin( NaN ); 94 * // returns NaN 95 */ 96 function asin( x ) { 97 var sgn; 98 var zz; 99 var a; 100 var p; 101 var z; 102 103 if ( isnan( x ) ) { 104 return NaN; 105 } 106 if ( x > 0.0 ) { 107 a = x; 108 } else { 109 sgn = true; 110 a = -x; 111 } 112 if ( a > 1.0 ) { 113 return NaN; 114 } 115 if ( a > 0.625 ) { 116 // arcsin(1-x) = pi/2 - sqrt(2x)(1+R(x)) 117 zz = 1.0 - a; 118 p = zz * ratevalRS( zz ); 119 zz = sqrt( zz + zz ); 120 z = PIO4 - zz; 121 zz = ( zz*p ) - MOREBITS; 122 z -= zz; 123 z += PIO4; 124 } else { 125 if ( a < 1.0e-8 ) { 126 return x; 127 } 128 zz = a * a; 129 z = zz * ratevalPQ( zz ); 130 z = ( a*z ) + a; 131 } 132 return ( sgn ) ? -z : z; 133 } 134 135 136 // EXPORTS // 137 138 module.exports = asin;