-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathndarray.js
More file actions
197 lines (176 loc) · 5.21 KB
/
ndarray.js
File metadata and controls
197 lines (176 loc) · 5.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/**
* @license Apache-2.0
*
* Copyright (c) 2021 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
// MODULES //
var vind2bind = require( '@stdlib/ndarray-base-vind2bind' );
// VARIABLES //
var MODE = 'throw';
// MAIN //
/**
* Applies a function to each element in an ndarray and assigns the result to an element in an output ndarray.
*
* @private
* @param {Object} x - object containing input ndarray meta data
* @param {string} x.ref - reference to original input ndarray-like object
* @param {string} x.dtype - data type
* @param {Collection} x.data - data buffer
* @param {NonNegativeInteger} x.length - number of elements
* @param {NonNegativeIntegerArray} x.shape - dimensions
* @param {IntegerArray} x.strides - stride lengths
* @param {NonNegativeInteger} x.offset - index offset
* @param {string} x.order - specifies whether `x` is row-major (C-style) or column-major (Fortran-style)
* @param {Array<Function>} x.accessors - accessors for accessing data buffer elements
* @param {Object} y - object containing output ndarray meta data
* @param {string} y.dtype - data type
* @param {Collection} y.data - data buffer
* @param {NonNegativeInteger} y.length - number of elements
* @param {NonNegativeIntegerArray} y.shape - dimensions
* @param {IntegerArray} y.strides - stride lengths
* @param {NonNegativeInteger} y.offset - index offset
* @param {string} y.order - specifies whether `y` is row-major (C-style) or column-major (Fortran-style)
* @param {Array<Function>} y.accessors - accessors for accessing data buffer elements
* @param {Function} fcn - function to apply
* @param {*} thisArg - function execution context
* @returns {void}
*
* @example
* var Complex64Array = require( '@stdlib/array-complex64' );
* var Complex64 = require( '@stdlib/complex-float32-ctor' );
* var realf = require( '@stdlib/complex-float32-real' );
* var imagf = require( '@stdlib/complex-float32-imag' );
* var naryFunction = require( '@stdlib/utils-nary-function' );
*
* function scale( z ) {
* return new Complex64( realf(z)*10.0, imagf(z)*10.0 );
* }
*
* // Create data buffers:
* var xbuf = new Complex64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ] );
* var ybuf = new Complex64Array( 4 );
*
* // Define the shape of the input and output arrays:
* var shape = [ 2, 2 ];
*
* // Define the array strides:
* var sx = [ 2, 1 ];
* var sy = [ 2, 1 ];
*
* // Define the index offsets:
* var ox = 0;
* var oy = 0;
*
* // Define getters and setters:
* function getter( buf, idx ) {
* return buf.get( idx );
* }
*
* function setter( buf, idx, value ) {
* buf.set( value, idx );
* }
*
* // Create the input and output ndarray-like objects:
* var x = {
* 'ref': null,
* 'dtype': 'complex64',
* 'data': xbuf,
* 'length': 4,
* 'shape': shape,
* 'strides': sx,
* 'offset': ox,
* 'order': 'row-major',
* 'accessors': [ getter, setter ]
* };
* x.ref = x;
*
* var y = {
* 'ref': null,
* 'dtype': 'complex64',
* 'data': ybuf,
* 'length': 4,
* 'shape': shape,
* 'strides': sy,
* 'offset': oy,
* 'order': 'row-major',
* 'accessors': [ getter, setter ]
* };
*
* // Apply the unary function:
* map( x, y, naryFunction( scale, 1 ) );
*
* var v = y.data.get( 0 );
*
* var re = realf( v );
* // returns 10.0
*
* var im = imagf( v );
* // returns 20.0
*/
function map( x, y, fcn, thisArg ) {
var xbuf;
var ybuf;
var ordx;
var ordy;
var len;
var get;
var set;
var ref;
var shx;
var shy;
var sx;
var sy;
var ox;
var oy;
var ix;
var iy;
var i;
// Cache the total number of elements over which to iterate:
len = x.length;
// Cache the input array shape:
shx = x.shape;
shy = y.shape;
// Cache references to the input and output ndarray data buffers:
xbuf = x.data;
ybuf = y.data;
// Cache references to the respective stride arrays:
sx = x.strides;
sy = y.strides;
// Cache the indices of the first indexed elements in the respective ndarrays:
ox = x.offset;
oy = y.offset;
// Cache the respective array orders:
ordx = x.order;
ordy = y.order;
// Cache accessors:
get = x.accessors[ 0 ];
set = y.accessors[ 1 ];
// Cache the reference to the original input array:
ref = x.ref;
// Check for a zero-dimensional array...
if ( shx.length === 0 ) {
set( ybuf, oy, fcn.call( thisArg, get( xbuf, ox ), 0, ref ) );
return;
}
// Iterate over each element based on the linear **view** index, regardless as to how the data is stored in memory (note: this has negative performance implications for non-contiguous ndarrays due to a lack of data locality)...
for ( i = 0; i < len; i++ ) {
ix = vind2bind( shx, sx, ox, ordx, i, MODE );
iy = vind2bind( shy, sy, oy, ordy, i, MODE );
set( ybuf, iy, fcn.call( thisArg, get( xbuf, ix ), i, ref ) );
}
}
// EXPORTS //
module.exports = map;