Skip to content

Commit bfe7a10

Browse files
committed
Add strided interface to apply a unary function to a float64 strided array according to a mask strided array
1 parent 4089709 commit bfe7a10

File tree

21 files changed

+3156
-0
lines changed

21 files changed

+3156
-0
lines changed
Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
<!--
2+
3+
@license Apache-2.0
4+
5+
Copyright (c) 2020 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+
<!-- lint disable maximum-heading-length -->
22+
23+
# dmskmap
24+
25+
> Apply a unary function accepting and returning double-precision floating-point numbers to each element in a double-precision floating-point strided input array according to a corresponding element in a strided mask array and assign each result to an element in a double-precision floating-point strided output array.
26+
27+
<section class="intro">
28+
29+
</section>
30+
31+
<!-- /.intro -->
32+
33+
<section class="usage">
34+
35+
## Usage
36+
37+
```javascript
38+
var dmskmap = require( '@stdlib/strided/base/dmskmap' );
39+
```
40+
41+
#### dmskmap( N, x, strideX, mask, strideMask, y, strideY, fcn )
42+
43+
Applies a unary function accepting and returning double-precision floating-point numbers to each element in a double-precision floating-point strided input array according to a corresponding element in a strided mask array and assigns each result to an element in a double-precision floating-point strided output array.
44+
45+
```javascript
46+
var Float64Array = require( '@stdlib/array/float64' );
47+
var Uint8Array = require( '@stdlib/array/uint8' );
48+
var abs = require( '@stdlib/math/base/special/abs' );
49+
50+
var x = new Float64Array( [ -2.0, 1.0, -3.0, -5.0, 4.0, 0.0, -1.0, -3.0 ] );
51+
var m = new Uint8Array( [ 0, 0, 1, 0, 0, 1, 1, 0 ] );
52+
53+
// Compute the absolute values in-place:
54+
dmskmap( x.length, x, 1, m, 1, x, 1, abs );
55+
// x => <Float64Array>[ 2.0, 1.0, -3.0, 5.0, 4.0, 0.0, -1.0, 3.0 ]
56+
```
57+
58+
The function accepts the following arguments:
59+
60+
- **N**: number of indexed elements.
61+
- **x**: input [`Float64Array`][@stdlib/array/float64].
62+
- **strideX**: index increment for `x`.
63+
- **mask**: mask [`Uint8Array`][@stdlib/array/uint8].
64+
- **strideMask**: index increment for `mask`.
65+
- **y**: output [`Float64Array`][@stdlib/array/float64].
66+
- **strideY**: index increment for `y`.
67+
- **fcn**: function to apply.
68+
69+
The `N` and `stride` parameters determine which elements in the strided arrays are accessed at runtime. For example, to index every other value in `x` and to index the first `N` elements of `y` in reverse order,
70+
71+
```javascript
72+
var Float64Array = require( '@stdlib/array/float64' );
73+
var Uint8Array = require( '@stdlib/array/uint8' );
74+
var floor = require( '@stdlib/math/base/special/floor' );
75+
var abs = require( '@stdlib/math/base/special/abs' );
76+
77+
var x = new Float64Array( [ -1.0, -2.0, -3.0, -4.0, -5.0, -6.0 ] );
78+
var m = new Uint8Array( [ 0, 0, 1, 0, 0, 1 ] );
79+
var y = new Float64Array( [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ] );
80+
81+
var N = floor( x.length / 2 );
82+
83+
dmskmap( N, x, 2, m, 2, y, -1, abs );
84+
// y => <Float64Array>[ 5.0, 0.0, 1.0, 0.0, 0.0, 0.0 ]
85+
```
86+
87+
Note that indexing is relative to the first index. To introduce an offset, use [`typed array`][@stdlib/array/float64] views.
88+
89+
```javascript
90+
var Float64Array = require( '@stdlib/array/float64' );
91+
var Uint8Array = require( '@stdlib/array/uint8' );
92+
var floor = require( '@stdlib/math/base/special/floor' );
93+
var abs = require( '@stdlib/math/base/special/abs' );
94+
95+
// Initial arrays...
96+
var x0 = new Float64Array( [ -1.0, -2.0, -3.0, -4.0, -5.0, -6.0 ] );
97+
var m0 = new Uint8Array( [ 0, 0, 1, 0, 0, 1 ] );
98+
var y0 = new Float64Array( [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ] );
99+
100+
// Create offset views...
101+
var x1 = new Float64Array( x0.buffer, x0.BYTES_PER_ELEMENT*1 ); // start at 2nd element
102+
var m1 = new Uint8Array( m0.buffer, m0.BYTES_PER_ELEMENT*3 ); // start at 4th element
103+
var y1 = new Float64Array( y0.buffer, y0.BYTES_PER_ELEMENT*3 ); // start at 4th element
104+
105+
var N = floor( x0.length / 2 );
106+
107+
dmskmap( N, x1, -2, m1, 1, y1, 1, abs );
108+
// y0 => <Float64Array>[ 0.0, 0.0, 0.0, 6.0, 4.0, 0.0 ]
109+
```
110+
111+
#### dmskmap.ndarray( N, x, strideX, offsetX, mask, strideMask, offsetMask, y, strideY, offsetY )
112+
113+
Applies a unary function accepting and returning double-precision floating-point numbers to each element in a double-precision floating-point strided input array according to a corresponding element in a strided mask array and assigns each result to an element in a double-precision floating-point strided output array using alternative indexing semantics.
114+
115+
```javascript
116+
var Float64Array = require( '@stdlib/array/float64' );
117+
var Uint8Array = require( '@stdlib/array/uint8' );
118+
var abs = require( '@stdlib/math/base/special/abs' );
119+
120+
var x = new Float64Array( [ -1.0, -2.0, -3.0, -4.0, -5.0 ] );
121+
var m = new Uint8Array( [ 0, 0, 1, 0, 0 ] );
122+
var y = new Float64Array( [ 0.0, 0.0, 0.0, 0.0, 0.0 ] );
123+
124+
dmskmap.ndarray( x.length, x, 1, 0, m, 1, 0, y, 1, 0, abs );
125+
// y => <Float64Array>[ 1.0, 2.0, 0.0, 4.0, 5.0 ]
126+
```
127+
128+
The function accepts the following additional arguments:
129+
130+
- **offsetX**: starting index for `x`.
131+
- **offsetMask**: starting index for `mask`.
132+
- **offsetY**: starting index for `y`.
133+
134+
While [`typed array`][@stdlib/array/float64] views mandate a view offset based on the underlying `buffer`, the `offsetX` and `offsetY` parameters support indexing semantics based on starting indices. For example, to index every other value in `x` starting from the second value and to index the last `N` elements in `y`,
135+
136+
```javascript
137+
var Float64Array = require( '@stdlib/array/float64' );
138+
var Uint8Array = require( '@stdlib/array/uint8' );
139+
var floor = require( '@stdlib/math/base/special/floor' );
140+
var abs = require( '@stdlib/math/base/special/abs' );
141+
142+
var x = new Float64Array( [ -1.0, -2.0, -3.0, -4.0, -5.0, -6.0 ] );
143+
var m = new Uint8Array( [ 0, 0, 1, 0, 0, 1 ] );
144+
var y = new Float64Array( [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ] );
145+
146+
var N = floor( x.length / 2 );
147+
148+
dmskmap.ndarray( N, x, 2, 1, m, 2, 1, y, -1, y.length-1, abs );
149+
// y => <Float64Array>[ 0.0, 0.0, 0.0, 0.0, 4.0, 2.0 ]
150+
```
151+
152+
</section>
153+
154+
<!-- /.usage -->
155+
156+
<section class="notes">
157+
158+
</section>
159+
160+
<!-- /.notes -->
161+
162+
<section class="examples">
163+
164+
## Examples
165+
166+
<!-- eslint no-undef: "error" -->
167+
168+
```javascript
169+
var round = require( '@stdlib/math/base/special/round' );
170+
var randu = require( '@stdlib/random/base/randu' );
171+
var bernoulli = require( '@stdlib/random/base/bernoulli' );
172+
var Float64Array = require( '@stdlib/array/float64' );
173+
var Uint8Array = require( '@stdlib/array/uint8' );
174+
var dmskmap = require( '@stdlib/strided/base/dmskmap' );
175+
176+
function scale( x ) {
177+
return x * 10.0;
178+
}
179+
180+
var x = new Float64Array( 10 );
181+
var m = new Uint8Array( x.length );
182+
var y = new Float64Array( x.length );
183+
184+
var i;
185+
for ( i = 0; i < x.length; i++ ) {
186+
x[ i ] = round( (randu()*200.0) - 100.0 );
187+
m[ i ] = bernoulli( 0.2 );
188+
}
189+
console.log( x );
190+
console.log( m );
191+
console.log( y );
192+
193+
dmskmap.ndarray( x.length, x, 1, 0, m, 1, 0, y, -1, y.length-1, scale );
194+
console.log( y );
195+
```
196+
197+
</section>
198+
199+
<!-- /.examples -->
200+
201+
<!-- C interface documentation. -->
202+
203+
* * *
204+
205+
<section class="c">
206+
207+
## C APIs
208+
209+
<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
210+
211+
<section class="intro">
212+
213+
</section>
214+
215+
<!-- /.intro -->
216+
217+
<!-- C usage documentation. -->
218+
219+
<section class="usage">
220+
221+
### Usage
222+
223+
```c
224+
#include "stdlib/strided/base/dmskmap.h"
225+
```
226+
227+
#### stdlib_strided_dmskmap( N, \*X, strideX, \*Mask, strideMask, \*Y, strideY, fcn )
228+
229+
Applies a unary function accepting and returning double-precision floating-point numbers to each element in a double-precision floating-point strided input array according to a corresponding element in a strided mask array and assigns each result to an element in a double-precision floating-point strided output array.
230+
231+
```c
232+
#include <stdint.h>
233+
234+
static double scale( const double x ) {
235+
return x * 10.0;
236+
}
237+
238+
double X[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 };
239+
uint8_t M[] = { 0, 0, 1, 0, 0, 1 };
240+
double Y[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
241+
242+
int64_t N = 6;
243+
244+
stdlib_strided_dmskmap( N, X, 1, M, 1, Y, 1, scale );
245+
```
246+
247+
The function accepts the following arguments:
248+
249+
- **N**: `[in] int64_t` number of indexed elements.
250+
- **X**: `[in] double*` input array.
251+
- **strideX** `[in] int64_t` index increment for `X`.
252+
- **Mask**: `[in] uint8_t*` mask array.
253+
- **strideMask**: `[in] int64_t` index increment for `Mask`.
254+
- **Y**: `[out] double*` output array.
255+
- **strideY**: `[in] int64_t` index increment for `Y`.
256+
- **fcn**: `[in] double (*fcn)( double )` unary function to apply.
257+
258+
```c
259+
void stdlib_strided_dmskmap( const int64_t N, const double *X, const int64_t strideX, const uint8_t *Mask, const int64_t strideMask, double *Y, const int64_t strideY, double (*fcn)( double ) );
260+
```
261+
262+
</section>
263+
264+
<!-- /.usage -->
265+
266+
<!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
267+
268+
<section class="notes">
269+
270+
</section>
271+
272+
<!-- /.notes -->
273+
274+
<!-- C API usage examples. -->
275+
276+
<section class="examples">
277+
278+
### Examples
279+
280+
```c
281+
#include "stdlib/strided/base/dmskmap.h"
282+
#include <stdint.h>
283+
#include <stdio.h>
284+
285+
// Define a callback:
286+
static double scale( const double x ) {
287+
return x * 10.0;
288+
}
289+
290+
int main() {
291+
// Create an input strided array:
292+
double X[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 };
293+
294+
// Create a mask strided array:
295+
uint8_t M[] = { 0, 0, 1, 0, 0, 1 };
296+
297+
// Create an output strided array:
298+
double Y[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
299+
300+
// Specify the number of elements:
301+
int64_t N = 6;
302+
303+
// Define the strides:
304+
int64_t strideX = 1;
305+
int64_t strideM = 1;
306+
int64_t strideY = -1;
307+
308+
// Apply the callback:
309+
stdlib_strided_dmskmap( N, X, strideX, M, strideM, Y, strideY, scale );
310+
311+
// Print the results:
312+
for ( int64_t i = 0; i < N; i++ ) {
313+
printf( "Y[ %lli ] = %lf\n", i, Y[ i ] );
314+
}
315+
}
316+
```
317+
318+
</section>
319+
320+
<!-- /.examples -->
321+
322+
</section>
323+
324+
<!-- /.c -->
325+
326+
<section class="links">
327+
328+
[@stdlib/array/float64]: https://github.com/stdlib-js/stdlib
329+
330+
[@stdlib/array/uint8]: https://github.com/stdlib-js/stdlib
331+
332+
</section>
333+
334+
<!-- /.links -->

0 commit comments

Comments
 (0)