array-kit 0.2.11 → 0.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/NDArray.js +207 -65
- package/package.json +1 -1
package/lib/NDArray.js
CHANGED
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
params: an object of optional parameters, where:
|
|
43
43
|
order: array of coord order stored in the storage, by default [ 0 , 1 , 2 , ..., N ], for 2D it's row-first,
|
|
44
44
|
if you want column-first, use [ 1 , 0 ], or params.reverse = true
|
|
45
|
-
reverse: syntactic sugar, like params.order = [ N , ... , 2 , 1 , 0 ]
|
|
45
|
+
reverse: syntactic sugar, like params.order = [ N , ... , 2 , 1 , 0 ], means that the slowest moving dimension comes first
|
|
46
46
|
dataStart: the index in the data storage where the ND-array starts (e.g. the start of the view in the Buffer)
|
|
47
|
-
stride: (default: 1) the stride of the fastest moving dimension, usually 1 except if there is
|
|
48
|
-
|
|
47
|
+
stride: (default: 1) the stride of the fastest moving dimension, usually 1 except if there is faster dimensions
|
|
48
|
+
that are removed from the view
|
|
49
49
|
|
|
50
50
|
Not added yet:
|
|
51
51
|
offset: the offset of the first logical element of the ND-array
|
|
@@ -86,14 +86,21 @@ function NDArray( dataOrConstructor , sizes , params ) {
|
|
|
86
86
|
// Define the layout of the array in memory, strides are products of all faster dimensions
|
|
87
87
|
this.strides = new Array( dimensions ) ;
|
|
88
88
|
|
|
89
|
+
// Use to speed up the whole array iteration
|
|
90
|
+
this.backStrides = new Array( dimensions ) ;
|
|
91
|
+
|
|
89
92
|
// This is the index of the first logical element in the physical data storage
|
|
90
93
|
this.offset = 0 ;
|
|
91
94
|
|
|
95
|
+
// True if the physical backend is contiguous, that can speed up some operation like .fill()
|
|
96
|
+
this.isContiguous = true ;
|
|
97
|
+
|
|
92
98
|
// This is physical start and end of the ND-array in the data storage
|
|
93
99
|
this.dataStart = 0 ;
|
|
94
100
|
this.dataEnd = 0 ;
|
|
95
101
|
|
|
96
|
-
// The underlying data store
|
|
102
|
+
// The underlying physical data store backend.
|
|
103
|
+
// Can be: Array, TypedArray, Buffer... anything that is indexed.
|
|
97
104
|
this.data = null ;
|
|
98
105
|
|
|
99
106
|
if ( ! noInit ) {
|
|
@@ -128,7 +135,7 @@ NDArray.prototype._init = function( dataOrConstructor , sizes , params = {} ) {
|
|
|
128
135
|
}
|
|
129
136
|
|
|
130
137
|
// Compute the stride
|
|
131
|
-
this.
|
|
138
|
+
this._initStridesFromSizes( params.stride ) ;
|
|
132
139
|
|
|
133
140
|
// The index where the ND-array region starts
|
|
134
141
|
this.dataStart = params.dataStart || 0 ;
|
|
@@ -140,7 +147,7 @@ NDArray.prototype._init = function( dataOrConstructor , sizes , params = {} ) {
|
|
|
140
147
|
// Set or create a new data store
|
|
141
148
|
if ( typeof dataOrConstructor === 'function' ) {
|
|
142
149
|
if ( typeof dataOrConstructor.allocUnsafe === 'function' ) {
|
|
143
|
-
// Detect Node.js's Buffer referencing it (avoid browser compatibility layer)
|
|
150
|
+
// Detect Node.js's Buffer without referencing it (avoid browser compatibility layer)
|
|
144
151
|
this.data = dataOrConstructor.allocUnsafe( this.dataEnd ) ;
|
|
145
152
|
}
|
|
146
153
|
else {
|
|
@@ -161,6 +168,8 @@ NDArray.prototype._init = function( dataOrConstructor , sizes , params = {} ) {
|
|
|
161
168
|
// Fragmented init, because it can be re-use by various cloning things
|
|
162
169
|
|
|
163
170
|
NDArray.prototype._initMinsMaxsSizesFromRegion = function( region ) {
|
|
171
|
+
this.size = 1 ;
|
|
172
|
+
|
|
164
173
|
for ( let d = 0 ; d < this.dimensions ; d ++ ) {
|
|
165
174
|
this.mins[ d ] = region[ d ][ 0 ] ;
|
|
166
175
|
this.maxs[ d ] = region[ d ][ 1 ] ;
|
|
@@ -200,13 +209,23 @@ NDArray.prototype._initMinsMaxsFromSizes = function( sizes ) {
|
|
|
200
209
|
} ;
|
|
201
210
|
|
|
202
211
|
// Sizes is not passed as argument, it should already be computed on the instance
|
|
203
|
-
NDArray.prototype.
|
|
212
|
+
NDArray.prototype._initStridesFromSizes = function( nextStride = 1 ) {
|
|
213
|
+
// It's always contiguous when strides start at 1
|
|
214
|
+
this.isContiguous = nextStride === 1 ;
|
|
215
|
+
|
|
204
216
|
for ( const d of this.order ) {
|
|
205
|
-
this.strides[ d ] =
|
|
206
|
-
|
|
217
|
+
this.strides[ d ] = nextStride ;
|
|
218
|
+
this.backStrides[ d ] = ( 1 - this.sizes[ d ] ) * nextStride ;
|
|
219
|
+
nextStride *= this.sizes[ d ] ;
|
|
207
220
|
}
|
|
208
221
|
} ;
|
|
209
222
|
|
|
223
|
+
// Strides is not passed as argument, it should already be computed on the instance
|
|
224
|
+
NDArray.prototype._initOrderFromStrides = function() {
|
|
225
|
+
this.order = Array.from( { length: this.strides.length } , ( v , i ) => i ) ;
|
|
226
|
+
this.order.sort( ( a , b ) => this.strides[ a ] - this.strides[ b ] ) ;
|
|
227
|
+
} ;
|
|
228
|
+
|
|
210
229
|
// Offset, sizes and strides are not passed as argument, they should already be computed on the instance
|
|
211
230
|
NDArray.prototype._initOffsetEndFromStartSizesStrides = function() {
|
|
212
231
|
this.dataEnd = this.dataStart + 1 ;
|
|
@@ -225,7 +244,6 @@ NDArray.prototype._initOffsetEndFromStartSizesStrides = function() {
|
|
|
225
244
|
}
|
|
226
245
|
} ;
|
|
227
246
|
|
|
228
|
-
/* Not sure if it's useful to compute based on offset
|
|
229
247
|
// Offset, sizes and strides are not passed as argument, they should already be computed on the instance
|
|
230
248
|
NDArray.prototype._initStartEndFromOffsetSizesStrides = function() {
|
|
231
249
|
this.dataStart = this.offset ;
|
|
@@ -240,7 +258,62 @@ NDArray.prototype._initStartEndFromOffsetSizesStrides = function() {
|
|
|
240
258
|
}
|
|
241
259
|
}
|
|
242
260
|
} ;
|
|
243
|
-
|
|
261
|
+
|
|
262
|
+
// Init .isContiguous based on strides and sizes.
|
|
263
|
+
// Usually only called for views, because if ._initStridesFromSizes() is called it already set it to the right value.
|
|
264
|
+
NDArray.prototype._initIsContiguousFromStridesSizes = function() {
|
|
265
|
+
let nextStride = 1 ;
|
|
266
|
+
|
|
267
|
+
for ( const d of this.order ) {
|
|
268
|
+
const absStride = Math.abs( this.strides[ d ] ) ;
|
|
269
|
+
|
|
270
|
+
if ( absStride !== nextStride ) {
|
|
271
|
+
this.isContiguous = false ;
|
|
272
|
+
return ;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
nextStride *= absStride ;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
this.isContiguous = true ;
|
|
279
|
+
} ;
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
// Create a new data back-end from another one
|
|
284
|
+
// sliceStart and sliceEnd are optional
|
|
285
|
+
NDArray.prototype._createDataFrom = function( data , sliceStart = 0 , sliceEnd = data.length ) {
|
|
286
|
+
if ( Array.isArray( data ) ) {
|
|
287
|
+
this.data = data.slice( sliceStart , sliceEnd ) ;
|
|
288
|
+
}
|
|
289
|
+
else if ( typeof data.constructor.allocUnsafe === 'function' ) {
|
|
290
|
+
// Detect Node.js's Buffer without referencing it (avoid browser compatibility layer)
|
|
291
|
+
this.data = data.constructor.allocUnsafe( sliceEnd - sliceStart ) ;
|
|
292
|
+
data.copy( this.data , 0 , sliceStart , sliceEnd ) ;
|
|
293
|
+
}
|
|
294
|
+
else if ( typeof data.slice === 'function' ) {
|
|
295
|
+
this.data = data.slice( sliceStart , sliceEnd ) ;
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
this.data = new data.constructor( data.length ) ;
|
|
299
|
+
|
|
300
|
+
for ( let src = sliceStart , dst = 0 ; src < sliceEnd ; src ++ , dst ++ ) {
|
|
301
|
+
this.data[ dst ] = data[ src ] ;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
} ;
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
// Create a new data store of the same type
|
|
309
|
+
NDArray.prototype._newStorageOfTheSameKind = function( size = this.dataEnd - this.dataStart ) {
|
|
310
|
+
if ( typeof this.data?.constructor?.allocUnsafe === 'function' ) {
|
|
311
|
+
// Detect Node.js's Buffer referencing it (avoid browser compatibility layer)
|
|
312
|
+
return this.data.constructor.allocUnsafe( size ) ;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return new this.data.constructor( size ) ;
|
|
316
|
+
} ;
|
|
244
317
|
|
|
245
318
|
|
|
246
319
|
|
|
@@ -283,6 +356,7 @@ NDArray.prototype.flip = function( dimension ) {
|
|
|
283
356
|
}
|
|
284
357
|
|
|
285
358
|
this.strides[ dimension ] *= - 1 ;
|
|
359
|
+
this.backStrides[ dimension ] *= - 1 ;
|
|
286
360
|
this._initOffsetEndFromStartSizesStrides() ;
|
|
287
361
|
|
|
288
362
|
return this ;
|
|
@@ -290,16 +364,78 @@ NDArray.prototype.flip = function( dimension ) {
|
|
|
290
364
|
|
|
291
365
|
// Flip coordinates along all dimensions at once, but preserving min and max
|
|
292
366
|
NDArray.prototype.flipAll = function() {
|
|
293
|
-
for ( let d = 0 ; d < this.dimensions ; d ++ ) {
|
|
367
|
+
for ( let d = 0 ; d < this.dimensions ; d ++ ) {
|
|
368
|
+
this.strides[ d ] *= - 1 ;
|
|
369
|
+
this.backStrides[ d ] *= - 1 ;
|
|
370
|
+
}
|
|
371
|
+
|
|
294
372
|
this._initOffsetEndFromStartSizesStrides() ;
|
|
295
373
|
return this ;
|
|
296
374
|
} ;
|
|
297
375
|
|
|
298
376
|
|
|
299
377
|
|
|
378
|
+
/*
|
|
379
|
+
Fix some axis and reduce the number of dimensions.
|
|
380
|
+
Like .pick() in the "ndarray" package.
|
|
381
|
+
|
|
382
|
+
Examples:
|
|
383
|
+
.select( null , 3 , null ) fix the second coordinate to 3, the ND-array will now have 2 dimensions instead of 3
|
|
384
|
+
.select( 1 , 3 , null ) fix the first and second coordinates respectively to 1 and 3, the ND-array will now have 1 dimensions instead of 3
|
|
385
|
+
*/
|
|
386
|
+
NDArray.prototype.select = function( ... coords ) {
|
|
387
|
+
this.size = 1 ;
|
|
388
|
+
|
|
389
|
+
// dimensions should be cached because it's modified along the way
|
|
390
|
+
for ( let d = 0 , newD = 0 , dimensions = this.dimensions ; d < dimensions ; d ++ ) {
|
|
391
|
+
const coord = coords[ d ] ;
|
|
392
|
+
|
|
393
|
+
if ( coord === null || coord === undefined ) {
|
|
394
|
+
this.size *= this.sizes[ newD ] ;
|
|
395
|
+
newD ++ ;
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
this.offset += ( coord - this.mins[ newD ] ) * this.strides[ newD ] ;
|
|
399
|
+
this.sizes.splice( newD , 1 ) ;
|
|
400
|
+
this.mins.splice( newD , 1 ) ;
|
|
401
|
+
this.maxs.splice( newD , 1 ) ;
|
|
402
|
+
this.strides.splice( newD , 1 ) ;
|
|
403
|
+
this.backStrides.splice( newD , 1 ) ;
|
|
404
|
+
this.dimensions -- ;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
this._initOrderFromStrides() ;
|
|
409
|
+
this._initStartEndFromOffsetSizesStrides() ;
|
|
410
|
+
this._initIsContiguousFromStridesSizes() ;
|
|
411
|
+
|
|
412
|
+
return this ;
|
|
413
|
+
} ;
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
// Clone only the view, the data storage is the same
|
|
418
|
+
NDArray.prototype.cloneView =
|
|
419
|
+
NDArray.prototype.view = function() {
|
|
420
|
+
const newNDArray = this._cloneGeometry( true ) ;
|
|
421
|
+
newNDArray.data = this.data ;
|
|
422
|
+
return newNDArray ;
|
|
423
|
+
} ;
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
// Full clone
|
|
428
|
+
NDArray.prototype.clone = function() {
|
|
429
|
+
const newNDArray = this._cloneGeometry() ;
|
|
430
|
+
newNDArray._createDataFrom( this.data , this.dataStart , this.dataEnd ) ;
|
|
431
|
+
return newNDArray ;
|
|
432
|
+
} ;
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
|
|
300
436
|
// Create a new clone of the current NDArray with the same geometry but an empty (but ready) data
|
|
301
|
-
// The new data is limited to the used size (dataStart = 0).
|
|
302
|
-
NDArray.prototype._cloneGeometry = function() {
|
|
437
|
+
// The new data is limited to the used size (dataStart = 0) except if keepDataStart is set to true.
|
|
438
|
+
NDArray.prototype._cloneGeometry = function( keepDataStart = false ) {
|
|
303
439
|
const newNDArray = new NDArray( this.dimensions ) ;
|
|
304
440
|
|
|
305
441
|
// Copy geometry
|
|
@@ -309,10 +445,18 @@ NDArray.prototype._cloneGeometry = function() {
|
|
|
309
445
|
Object.assign( newNDArray.mins , this.mins ) ;
|
|
310
446
|
Object.assign( newNDArray.maxs , this.maxs ) ;
|
|
311
447
|
Object.assign( newNDArray.strides , this.strides ) ;
|
|
448
|
+
Object.assign( newNDArray.backStrides , this.backStrides ) ;
|
|
312
449
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
450
|
+
if ( keepDataStart ) {
|
|
451
|
+
newNDArray.dataStart = this.dataStart ;
|
|
452
|
+
newNDArray.dataEnd = this.dataEnd ;
|
|
453
|
+
newNDArray.offset = this.offset ;
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
// Start at index=0 in the physical storage
|
|
457
|
+
newNDArray.offset = this.offset - this.dataStart ;
|
|
458
|
+
newNDArray.dataEnd = this.dataEnd - this.dataStart ;
|
|
459
|
+
}
|
|
316
460
|
|
|
317
461
|
return newNDArray ;
|
|
318
462
|
} ;
|
|
@@ -325,7 +469,7 @@ NDArray.prototype._resizeGeometry = function( mins , maxs ) {
|
|
|
325
469
|
|
|
326
470
|
Object.assign( newNDArray.order , this.order ) ;
|
|
327
471
|
newNDArray._initSizesFromMinsMaxs( mins , maxs ) ;
|
|
328
|
-
newNDArray.
|
|
472
|
+
newNDArray._initStridesFromSizes() ;
|
|
329
473
|
newNDArray._initOffsetEndFromStartSizesStrides() ;
|
|
330
474
|
|
|
331
475
|
return newNDArray ;
|
|
@@ -333,24 +477,11 @@ NDArray.prototype._resizeGeometry = function( mins , maxs ) {
|
|
|
333
477
|
|
|
334
478
|
|
|
335
479
|
|
|
336
|
-
// Create a new data store of the same type
|
|
337
|
-
NDArray.prototype._newStorageOfTheSameKind = function( size = this.dataEnd - this.dataStart ) {
|
|
338
|
-
if ( typeof this.data?.constructor?.allocUnsafe === 'function' ) {
|
|
339
|
-
// Detect Node.js's Buffer referencing it (avoid browser compatibility layer)
|
|
340
|
-
return this.data.constructor.allocUnsafe( size ) ;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
return new this.data.constructor( size ) ;
|
|
344
|
-
} ;
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
480
|
// Internal version without any unnessessary test
|
|
349
481
|
// Classic strided array access is:
|
|
350
482
|
// index = coords[ 0 ] * strides[ 0 ] + coords[ 1 ] * strides[ 1 ] + ... + coords[ n ] * strides[ n ]
|
|
351
483
|
NDArray.prototype._getIndex = function( coords ) {
|
|
352
484
|
let index = this.offset ;
|
|
353
|
-
//for ( const d of this.order ) { index += ( coords[ d ] - this.mins[ d ] ) * this.strides[ d ] ; }
|
|
354
485
|
for ( let d = 0 ; d < this.dimensions ; d ++ ) { index += ( coords[ d ] - this.mins[ d ] ) * this.strides[ d ] ; }
|
|
355
486
|
return index ;
|
|
356
487
|
} ;
|
|
@@ -358,7 +489,6 @@ NDArray.prototype._getIndex = function( coords ) {
|
|
|
358
489
|
NDArray.prototype._getIndexCheck = function( coords ) {
|
|
359
490
|
let index = this.offset ;
|
|
360
491
|
|
|
361
|
-
//for ( const d of this.order ) {
|
|
362
492
|
for ( let d = 0 ; d < this.dimensions ; d ++ ) {
|
|
363
493
|
const c = coords[ d ] ;
|
|
364
494
|
|
|
@@ -537,31 +667,7 @@ NDArray.prototype._getStrideStartAndVectorDimension = function( coords ) {
|
|
|
537
667
|
*/
|
|
538
668
|
NDArray.prototype.forEach =
|
|
539
669
|
NDArray.prototype._forEach = function( callback ) {
|
|
540
|
-
|
|
541
|
-
const stride0 = this.strides[ this.order[ 0 ] ] ;
|
|
542
|
-
const coords = Array.from( this.mins ) ;
|
|
543
|
-
let index = this.dataStart ;
|
|
544
|
-
|
|
545
|
-
for ( ;; ) {
|
|
546
|
-
callback( this.data[ index ] , coords , index , this ) ;
|
|
547
|
-
|
|
548
|
-
index += stride0 ;
|
|
549
|
-
if ( index >= this.dataEnd ) { return ; }
|
|
550
|
-
|
|
551
|
-
for ( let i = 0 ; i < this.dimensions ; i ++ ) {
|
|
552
|
-
const d = this.order[ i ] ;
|
|
553
|
-
coords[ d ] ++ ;
|
|
554
|
-
if (
|
|
555
|
-
i < this.dimensions - 1
|
|
556
|
-
&& coords[ d ] - this.mins[ d ] >= this.strides[ this.order[ i + 1 ] ]
|
|
557
|
-
) {
|
|
558
|
-
coords[ d ] = this.mins[ d ] ;
|
|
559
|
-
}
|
|
560
|
-
else {
|
|
561
|
-
break ;
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
}
|
|
670
|
+
return this._forEachInRegion( this.mins , this.maxs , callback , true ) ;
|
|
565
671
|
} ;
|
|
566
672
|
|
|
567
673
|
|
|
@@ -597,10 +703,19 @@ NDArray.prototype._forEachInRegionCheck = function( mins , maxs , callback ) {
|
|
|
597
703
|
this._forEachInRegion( mins , maxs , callback ) ;
|
|
598
704
|
} ;
|
|
599
705
|
|
|
600
|
-
|
|
601
|
-
|
|
706
|
+
// wholeArray=true when coming from ._forEach()
|
|
707
|
+
NDArray.prototype._forEachInRegion = function( mins , maxs , callback , wholeArray = false ) {
|
|
708
|
+
let backStrides , index ;
|
|
602
709
|
const coords = Array.from( mins ) ;
|
|
603
|
-
|
|
710
|
+
|
|
711
|
+
if ( wholeArray ) {
|
|
712
|
+
backStrides = this.backStrides ;
|
|
713
|
+
index = this.offset ;
|
|
714
|
+
}
|
|
715
|
+
else {
|
|
716
|
+
backStrides = mins.map( ( min , d ) => ( min - maxs[ d ] ) * this.strides[ d ] ) ;
|
|
717
|
+
index = this._getIndex( coords ) ;
|
|
718
|
+
}
|
|
604
719
|
|
|
605
720
|
for ( ;; ) {
|
|
606
721
|
callback( this.data[ index ] , coords , index , this ) ;
|
|
@@ -677,6 +792,13 @@ NDArray.prototype._forEachVectorInRegion = function( strideStartCoords , maxs ,
|
|
|
677
792
|
|
|
678
793
|
|
|
679
794
|
|
|
795
|
+
// Return a Generator
|
|
796
|
+
// .each()
|
|
797
|
+
NDArray.prototype.each =
|
|
798
|
+
NDArray.prototype._each = function() {
|
|
799
|
+
return this._eachInRegion( this.mins , this.maxs , true ) ;
|
|
800
|
+
} ;
|
|
801
|
+
|
|
680
802
|
// Return a Generator
|
|
681
803
|
// .eachInRegion( region )
|
|
682
804
|
// .eachInRegion( mins , maxs )
|
|
@@ -696,10 +818,20 @@ NDArray.prototype._eachInRegionCheck = function( mins , maxs ) {
|
|
|
696
818
|
|
|
697
819
|
// Generator
|
|
698
820
|
// The yielded entry { coords , index , value } should be cloned, as well as entry.coords, if userland want to modify it
|
|
699
|
-
|
|
700
|
-
|
|
821
|
+
// wholeArray=true when coming from ._each()
|
|
822
|
+
NDArray.prototype._eachInRegion = function*( mins , maxs , wholeArray = false ) {
|
|
823
|
+
let backStrides , index ;
|
|
701
824
|
const coords = Array.from( mins ) ;
|
|
702
|
-
|
|
825
|
+
|
|
826
|
+
if ( wholeArray ) {
|
|
827
|
+
backStrides = this.backStrides ;
|
|
828
|
+
index = this.offset ;
|
|
829
|
+
}
|
|
830
|
+
else {
|
|
831
|
+
backStrides = mins.map( ( min , d ) => ( min - maxs[ d ] ) * this.strides[ d ] ) ;
|
|
832
|
+
index = this._getIndex( coords ) ;
|
|
833
|
+
}
|
|
834
|
+
|
|
703
835
|
const entry = { coords , index , value: undefined } ;
|
|
704
836
|
|
|
705
837
|
for ( ;; ) {
|
|
@@ -931,8 +1063,18 @@ NDArray.prototype._eachVectorIndexInRegionBackward = function*( strideStartCoord
|
|
|
931
1063
|
|
|
932
1064
|
|
|
933
1065
|
NDArray.prototype.fill = function( value ) {
|
|
934
|
-
|
|
935
|
-
|
|
1066
|
+
if ( this.isContiguous ) {
|
|
1067
|
+
// Fast path: iterate directly on the physical data
|
|
1068
|
+
for ( let i = this.dataStart ; i < this.dataEnd ; i ++ ) {
|
|
1069
|
+
this.data[ i ] = value ;
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
else {
|
|
1073
|
+
for ( const { index } of this._each() ) {
|
|
1074
|
+
this.data[ index ] = value ;
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
|
|
936
1078
|
return this ;
|
|
937
1079
|
} ;
|
|
938
1080
|
|