Skip to content

Commit 5795b39

Browse files
committed
fix: determine layout based on physical layout
--- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: passed - task: lint_typescript_tests status: na - task: lint_license_headers status: passed ---
1 parent c20c5d6 commit 5795b39

2 files changed

Lines changed: 127 additions & 10 deletions

File tree

  • lib/node_modules/@stdlib/ndarray/base/spread-dimensions

lib/node_modules/@stdlib/ndarray/base/spread-dimensions/lib/main.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@
2020

2121
// MODULES //
2222

23-
var isRowMajor = require( '@stdlib/ndarray/base/assert/is-row-major-string' );
23+
var isRowMajorString = require( '@stdlib/ndarray/base/assert/is-row-major-string' );
2424
var isSortedAscending = require( '@stdlib/array/base/assert/is-sorted-ascending' );
2525
var toNormalizedIndices = require( '@stdlib/ndarray/base/to-unique-normalized-indices' );
26+
var strides2order = require( '@stdlib/ndarray/base/strides2order' );
2627
var getDType = require( '@stdlib/ndarray/base/dtype' );
2728
var getShape = require( '@stdlib/ndarray/base/shape' );
2829
var getStrides = require( '@stdlib/ndarray/base/strides' );
@@ -91,19 +92,29 @@ function spreadDimensions( ndims, x, dims, writable ) {
9192
var ord;
9293
var sh;
9394
var st;
95+
var N;
9496
var d;
9597
var S;
9698
var s;
99+
var o;
97100
var i;
98101
var j;
99102

100103
sh = getShape( x, false );
101104
st = getStrides( x, false );
102105
ord = getOrder( x );
103-
isrm = isRowMajor( ord );
104106

105-
if ( sh.length > ndims ) {
106-
throw new RangeError( format( 'invalid argument. First argument must be greater than or equal to the number of dimensions in the input ndarray. Number of dimensions: %d. Value: `%d`.', sh.length, ndims ) );
107+
o = strides2order( st );
108+
if ( o === 0 || o === 3 ) {
109+
// Fallback to stated layout when unable to infer the underlying physical layout:
110+
isrm = isRowMajorString( ord );
111+
} else {
112+
isrm = ( o === 1 );
113+
}
114+
N = sh.length;
115+
116+
if ( N > ndims ) {
117+
throw new RangeError( format( 'invalid argument. First argument must be greater than or equal to the number of dimensions in the input ndarray. Number of dimensions: %d. Value: `%d`.', N, ndims ) );
107118
}
108119
// Resolve dimension indices...
109120
d = toNormalizedIndices( dims, ndims-1 );
@@ -113,14 +124,14 @@ function spreadDimensions( ndims, x, dims, writable ) {
113124
if ( d.length !== dims.length ) {
114125
throw new Error( format( 'invalid argument. Must provide unique dimension indices. Value: `[%s]`.', join( dims, ', ' ) ) );
115126
}
116-
if ( d.length !== sh.length ) {
117-
throw new RangeError( format( 'invalid argument. Must provide the same number of dimension indices as the number of dimensions in the input ndarray. Number of dimensions: %d. Value: `[%s]`.', sh.length, join( dims, ', ' ) ) );
127+
if ( d.length !== N ) {
128+
throw new RangeError( format( 'invalid argument. Must provide the same number of dimension indices as the number of dimensions in the input ndarray. Number of dimensions: %d. Value: `[%s]`.', N, join( dims, ', ' ) ) );
118129
}
119130
if ( d.length && !isSortedAscending( d ) ) {
120131
throw new Error( format( 'invalid argument. Must provide dimension indices which resolve to nonnegative indices arranged in ascending order. Value: `[%s]`.', join( dims, ', ' ) ) );
121132
}
122133
// When provided a zero-dimensional array, every expanded dimension is a singleton dimension having zero stride...
123-
if ( sh.length === 0 ) {
134+
if ( N === 0 ) {
124135
shape = ones( ndims );
125136
strides = zeros( ndims );
126137
} else {
@@ -134,7 +145,7 @@ function spreadDimensions( ndims, x, dims, writable ) {
134145
S = sh[ j ];
135146
s = st[ j ];
136147
j += 1;
137-
} else if ( j === sh.length ) { // append
148+
} else if ( j === N ) { // append
138149
// We should only get here after exhausting all the dimension indices...
139150
S = 1;
140151
s = st[ j-1 ];

lib/node_modules/@stdlib/ndarray/base/spread-dimensions/test/test.js

Lines changed: 108 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,30 @@ tape( 'the function throws an error if not provided indices sorted in ascending
156156
}
157157
});
158158

159-
tape( 'the function prepends singleton dimensions', function test( t ) {
159+
tape( 'the function prepends singleton dimensions (1d)', function test( t ) {
160+
var x;
161+
var y;
162+
163+
x = array( [ 1, 2, 3, 4 ] );
164+
165+
y = spreadDimensions( 3, x, [ 2 ], false );
166+
167+
t.notEqual( y, x, 'returns expected value' );
168+
t.deepEqual( getShape( y ), [ 1, 1, 4 ], 'returns expected value' );
169+
t.strictEqual( getData( y ), getData( x ), 'returns expected value' );
170+
t.strictEqual( isReadOnly( y ), true, 'returns expected value' );
171+
172+
y = spreadDimensions( 3, x, [ 2 ], true );
173+
174+
t.notEqual( y, x, 'returns expected value' );
175+
t.deepEqual( getShape( y ), [ 1, 1, 4 ], 'returns expected value' );
176+
t.strictEqual( getData( y ), getData( x ), 'returns expected value' );
177+
t.strictEqual( isReadOnly( y ), false, 'returns expected value' );
178+
179+
t.end();
180+
});
181+
182+
tape( 'the function prepends singleton dimensions (2d)', function test( t ) {
160183
var x;
161184
var y;
162185

@@ -202,7 +225,30 @@ tape( 'the function prepends singleton dimensions (negative index)', function te
202225
t.end();
203226
});
204227

205-
tape( 'the function appends singleton dimensions', function test( t ) {
228+
tape( 'the function appends singleton dimensions (1d)', function test( t ) {
229+
var x;
230+
var y;
231+
232+
x = array( [ 1, 2, 3, 4 ] );
233+
234+
y = spreadDimensions( 3, x, [ 0 ], false );
235+
236+
t.notEqual( y, x, 'returns expected value' );
237+
t.deepEqual( getShape( y ), [ 4, 1, 1 ], 'returns expected value' );
238+
t.strictEqual( getData( y ), getData( x ), 'returns expected value' );
239+
t.strictEqual( isReadOnly( y ), true, 'returns expected value' );
240+
241+
y = spreadDimensions( 3, x, [ 0 ], true );
242+
243+
t.notEqual( y, x, 'returns expected value' );
244+
t.deepEqual( getShape( y ), [ 4, 1, 1 ], 'returns expected value' );
245+
t.strictEqual( getData( y ), getData( x ), 'returns expected value' );
246+
t.strictEqual( isReadOnly( y ), false, 'returns expected value' );
247+
248+
t.end();
249+
});
250+
251+
tape( 'the function appends singleton dimensions (2d)', function test( t ) {
206252
var x;
207253
var y;
208254

@@ -307,6 +353,16 @@ tape( 'the function prepends singleton dimensions (base; row-major)', function t
307353
t.deepEqual( getStrides( y ), [ 4, 2, 1 ], 'returns expected value' );
308354
t.strictEqual( getData( y ), getData( x ), 'returns expected value' );
309355

356+
// Transposed:
357+
x = ndarray( 'generic', [ 1, 2, 3, 4 ], [ 2, 2 ], [ 1, 2 ], 0, 'row-major' );
358+
359+
y = spreadDimensions( 3, x, [ 1, 2 ], false );
360+
361+
t.notEqual( y, x, 'returns expected value' );
362+
t.deepEqual( getShape( y ), [ 1, 2, 2 ], 'returns expected value' );
363+
t.deepEqual( getStrides( y ), [ 1, 1, 2 ], 'returns expected value' );
364+
t.strictEqual( getData( y ), getData( x ), 'returns expected value' );
365+
310366
t.end();
311367
});
312368

@@ -339,6 +395,16 @@ tape( 'the function prepends singleton dimensions (base; column-major)', functio
339395
t.deepEqual( getStrides( y ), [ 1, 1, 2 ], 'returns expected value' );
340396
t.strictEqual( getData( y ), getData( x ), 'returns expected value' );
341397

398+
// Transposed:
399+
x = ndarray( 'generic', [ 1, 2, 3, 4 ], [ 2, 2 ], [ 2, 1 ], 0, 'column-major' );
400+
401+
y = spreadDimensions( 3, x, [ 1, 2 ], false );
402+
403+
t.notEqual( y, x, 'returns expected value' );
404+
t.deepEqual( getShape( y ), [ 1, 2, 2 ], 'returns expected value' );
405+
t.deepEqual( getStrides( y ), [ 4, 2, 1 ], 'returns expected value' );
406+
t.strictEqual( getData( y ), getData( x ), 'returns expected value' );
407+
342408
t.end();
343409
});
344410

@@ -371,6 +437,16 @@ tape( 'the function appends singleton dimensions (base; row-major)', function te
371437
t.deepEqual( getStrides( y ), [ 2, 1, 1 ], 'returns expected value' );
372438
t.strictEqual( getData( y ), getData( x ), 'returns expected value' );
373439

440+
// Transposed:
441+
x = ndarray( 'generic', [ 1, 2, 3, 4 ], [ 2, 2 ], [ 1, 2 ], 0, 'row-major' );
442+
443+
y = spreadDimensions( 3, x, [ 0, 1 ], false );
444+
445+
t.notEqual( y, x, 'returns expected value' );
446+
t.deepEqual( getShape( y ), [ 2, 2, 1 ], 'returns expected value' );
447+
t.deepEqual( getStrides( y ), [ 1, 2, 4 ], 'returns expected value' );
448+
t.strictEqual( getData( y ), getData( x ), 'returns expected value' );
449+
374450
t.end();
375451
});
376452

@@ -403,6 +479,16 @@ tape( 'the function appends singleton dimensions (base; column-major)', function
403479
t.deepEqual( getStrides( y ), [ 1, 2, 4 ], 'returns expected value' );
404480
t.strictEqual( getData( y ), getData( x ), 'returns expected value' );
405481

482+
// Transposed:
483+
x = ndarray( 'generic', [ 1, 2, 3, 4 ], [ 2, 2 ], [ 2, 1 ], 0, 'column-major' );
484+
485+
y = spreadDimensions( 3, x, [ 0, 1 ], false );
486+
487+
t.notEqual( y, x, 'returns expected value' );
488+
t.deepEqual( getShape( y ), [ 2, 2, 1 ], 'returns expected value' );
489+
t.deepEqual( getStrides( y ), [ 2, 1, 1 ], 'returns expected value' );
490+
t.strictEqual( getData( y ), getData( x ), 'returns expected value' );
491+
406492
t.end();
407493
});
408494

@@ -434,6 +520,16 @@ tape( 'the function inserts singleton dimensions (base; row-major)', function te
434520
t.deepEqual( getShape( y ), [ 2, 1, 2 ], 'returns expected value' );
435521
t.deepEqual( getStrides( y ), [ 2, 2, 1 ], 'returns expected value' );
436522
t.strictEqual( getData( y ), getData( x ), 'returns expected value' );
523+
524+
// Transposed:
525+
x = ndarray( 'generic', [ 1, 2, 3, 4 ], [ 2, 2 ], [ 1, 2 ], 0, 'row-major' );
526+
527+
y = spreadDimensions( 3, x, [ 0, 2 ], false );
528+
529+
t.notEqual( y, x, 'returns expected value' );
530+
t.deepEqual( getShape( y ), [ 2, 1, 2 ], 'returns expected value' );
531+
t.deepEqual( getStrides( y ), [ 1, 2, 2 ], 'returns expected value' );
532+
t.strictEqual( getData( y ), getData( x ), 'returns expected value' );
437533
t.end();
438534
});
439535

@@ -466,6 +562,16 @@ tape( 'the function inserts singleton dimensions (base; column-major)', function
466562
t.deepEqual( getStrides( y ), [ 1, 2, 2 ], 'returns expected value' );
467563
t.strictEqual( getData( y ), getData( x ), 'returns expected value' );
468564

565+
// Transposed:
566+
x = ndarray( 'generic', [ 1, 2, 3, 4 ], [ 2, 2 ], [ 2, 1 ], 0, 'column-major' );
567+
568+
y = spreadDimensions( 3, x, [ 0, 2 ], false );
569+
570+
t.notEqual( y, x, 'returns expected value' );
571+
t.deepEqual( getShape( y ), [ 2, 1, 2 ], 'returns expected value' );
572+
t.deepEqual( getStrides( y ), [ 2, 2, 1 ], 'returns expected value' );
573+
t.strictEqual( getData( y ), getData( x ), 'returns expected value' );
574+
469575
t.end();
470576
});
471577

0 commit comments

Comments
 (0)