fresnels.js (3575B)
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, 1987, 1989, 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 sincos = require( './../../../../base/special/sincos' ); 38 var abs = require( './../../../../base/special/abs' ); 39 var HALF_PI = require( '@stdlib/constants/float64/half-pi' ); 40 var PI = require( '@stdlib/constants/float64/pi' ); 41 var polyS = require( './rational_psqs.js' ); 42 var polyF = require( './rational_pfqf.js' ); 43 var polyG = require( './rational_pgqg.js' ); 44 45 46 // VARIABLES // 47 48 // Array for storing sincos evaluation: 49 var sc = [ 0.0, 0.0 ]; // WARNING: not thread safe 50 51 52 // MAIN // 53 54 /** 55 * Computes the Fresnel integral S(x). 56 * 57 * ## Method 58 * 59 * Evaluates the Fresnel integral 60 * 61 * ```tex 62 * \operatorname{S}(x) = \int_0^x \sin\left(\frac{\pi}{2} t^2\right)\,\mathrm{d}t 63 * ``` 64 * 65 * The integral is evaluated by a power series for \\( x < 1 \\). For \\( x >= 1 \\) auxiliary functions \\( f(x) \\) and \\( g(x) \\) are employed such that 66 * 67 * ```tex 68 * \operatorname{S}(x) = \frac{1}{2} - f(x) \cos\left( \frac{\pi}{2} x^2 \right) - g(x) \sin\left( \frac{\pi}{2} x^2 \right). 69 * ``` 70 * 71 * ## Notes 72 * 73 * - Relative error on test interval \\( \[0,10\] \\): 74 * 75 * | arithmetic | function | # trials | peak | rms | 76 * |:----------:|:--------:|:--------:|:--------:|:-------:| 77 * | IEEE | S(x) | 10000 | 2.0e-15 | 3.2e-16 | 78 * 79 * 80 * @param {number} x - input value 81 * @returns {number} S(x) 82 * 83 * @example 84 * var v = fresnels( 0.0 ); 85 * // returns 0.0 86 * 87 * @example 88 * var v = fresnels( 1.0 ); 89 * // returns ~0.438 90 * 91 * @example 92 * var v = fresnels( Infinity ); 93 * // returns ~0.5 94 * 95 * @example 96 * var v = fresnels( -Infinity ); 97 * // returns ~-0.5 98 * 99 * @example 100 * var v = fresnels( NaN ); 101 * // returns NaN 102 */ 103 function fresnels( x ) { 104 var x2; 105 var xa; 106 var S; 107 var f; 108 var g; 109 var t; 110 var u; 111 112 xa = abs( x ); 113 x2 = xa * xa; 114 if ( x2 < 2.5625 ) { 115 t = x2 * x2; 116 S = xa * x2 * polyS( t ); 117 } else if ( xa > 36974.0 ) { 118 S = 0.5; 119 } else { 120 // Asymptotic power series auxiliary functions for large arguments... 121 x2 = xa * xa; 122 t = PI * x2; 123 u = 1.0 / (t * t); 124 t = 1.0 / t; 125 f = 1.0 - ( u * polyF( u ) ); 126 g = t * polyG( u ); 127 t = HALF_PI * x2; 128 sincos( sc, t ); 129 t = PI * xa; 130 S = 0.5 - ( ( (f*sc[1]) + (g*sc[0]) ) / t ); 131 } 132 if ( x < 0.0 ) { 133 S = -S; 134 } 135 return S; 136 } 137 138 139 // EXPORTS // 140 141 module.exports = fresnels;