README.md (4851B)
1 <!-- 2 3 @license Apache-2.0 4 5 Copyright (c) 2018 The Stdlib Authors. 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18 19 --> 20 21 # incrmprod 22 23 > Compute a moving product incrementally. 24 25 <section class="intro"> 26 27 For a window of size `W`, the moving product is defined as 28 29 <!-- <equation class="equation" label="eq:moving_product" align="center" raw="\prod_{i=0}^{W-1} x_i" alt="Equation for the moving product."> --> 30 31 <div class="equation" align="center" data-raw-text="\prod_{i=0}^{W-1} x_i" data-equation="eq:moving_product"> 32 <img src="https://cdn.jsdelivr.net/gh/stdlib-js/stdlib@49d8cabda84033d55d7b8069f19ee3dd8b8d1496/lib/node_modules/@stdlib/stats/incr/mprod/docs/img/equation_moving_product.svg" alt="Equation for the moving product."> 33 <br> 34 </div> 35 36 <!-- </equation> --> 37 38 </section> 39 40 <!-- /.intro --> 41 42 <section class="usage"> 43 44 ## Usage 45 46 ```javascript 47 var incrmprod = require( '@stdlib/stats/incr/mprod' ); 48 ``` 49 50 #### incrmprod( window ) 51 52 Returns an accumulator `function` which incrementally computes a moving product. The `window` parameter defines the number of values over which to compute the moving product. 53 54 ```javascript 55 var accumulator = incrmprod( 3 ); 56 ``` 57 58 #### accumulator( \[x] ) 59 60 If provided an input value `x`, the accumulator function returns an updated product. If not provided an input value `x`, the accumulator function returns the current product. 61 62 ```javascript 63 var accumulator = incrmprod( 3 ); 64 65 var p = accumulator(); 66 // returns null 67 68 // Fill the window... 69 p = accumulator( 2.0 ); // [2.0] 70 // returns 2.0 71 72 p = accumulator( 1.0 ); // [2.0, 1.0] 73 // returns 2.0 74 75 p = accumulator( 3.0 ); // [2.0, 1.0, 3.0] 76 // returns 6.0 77 78 // Window begins sliding... 79 p = accumulator( -7.0 ); // [1.0, 3.0, -7.0] 80 // returns -21.0 81 82 p = accumulator( -5.0 ); // [3.0, -7.0, -5.0] 83 // returns 105.0 84 85 p = accumulator(); 86 // returns 105.0 87 ``` 88 89 Under certain conditions, overflow may be transient. 90 91 ```javascript 92 // Large values: 93 var x = 5.0e+300; 94 var y = 1.0e+300; 95 96 // Tiny value: 97 var z = 2.0e-302; 98 99 // Initialize an accumulator: 100 var accumulator = incrmprod( 3 ); 101 102 var p = accumulator( x ); 103 // returns 5.0e+300 104 105 // Transient overflow: 106 p = accumulator( y ); 107 // returns Infinity 108 109 // Recover a finite result: 110 p = accumulator( z ); 111 // returns 1.0e+299 112 ``` 113 114 Similarly, under certain conditions, underflow may be transient. 115 116 ```javascript 117 // Tiny values: 118 var x = 4.0e-302; 119 var y = 9.0e-303; 120 121 // Large value: 122 var z = 2.0e+300; 123 124 // Initialize an accumulator: 125 var accumulator = incrmprod( 3 ); 126 127 var p = accumulator( x ); 128 // returns 4.0e-302 129 130 // Transient underflow: 131 p = accumulator( y ); 132 // returns 0.0 133 134 // Recover a non-zero result: 135 p = accumulator( z ); 136 // returns 7.2e-304 137 ``` 138 139 </section> 140 141 <!-- /.usage --> 142 143 <section class="notes"> 144 145 ## Notes 146 147 - Input values are **not** type checked. If provided `NaN` or a value which, when used in computations, results in `NaN`, the accumulated value is `NaN` for **at least** `W-1` future invocations. If non-numeric inputs are possible, you are advised to type check and handle accordingly **before** passing the value to the accumulator function. 148 - As `W` values are needed to fill the window buffer, the first `W-1` returned values are calculated from smaller sample sizes. Until the window is full, each returned value is calculated from all provided values. 149 - For large accumulation windows or accumulations of either large or small numbers, care should be taken to prevent overflow and underflow. Note, however, that overflow/underflow may be transient, as the accumulator does not use a double-precision floating-point number to store an accumulated product. Instead, the accumulator splits an accumulated product into a normalized **fraction** and **exponent** and updates each component separately. Doing so guards against a loss in precision. 150 151 </section> 152 153 <!-- /.notes --> 154 155 <section class="examples"> 156 157 ## Examples 158 159 <!-- eslint no-undef: "error" --> 160 161 ```javascript 162 var randu = require( '@stdlib/random/base/randu' ); 163 var incrmprod = require( '@stdlib/stats/incr/mprod' ); 164 165 var accumulator; 166 var v; 167 var i; 168 169 // Initialize an accumulator: 170 accumulator = incrmprod( 5 ); 171 172 // For each simulated datum, update the moving product... 173 for ( i = 0; i < 100; i++ ) { 174 v = ( randu()*10.0 ) - 5.0; 175 accumulator( v ); 176 } 177 console.log( accumulator() ); 178 ``` 179 180 </section> 181 182 <!-- /.examples --> 183 184 <section class="links"> 185 186 </section> 187 188 <!-- /.links -->