Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions .ralph/state.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Ralph Loop State

## Issue
**Title**: Review `@stdlib/ndarray/nans-like`
**Source**: stdlib-js/todo#2771
**Task**: Implement the `@stdlib/ndarray/nans-like` package in the stdlib-js/stdlib repository.

## Verbatim Issue Text
"Review `@stdlib/ndarray/nans-like`."

## Acceptance Criteria
- [ ] Package `@stdlib/ndarray/nans-like` exists at `lib/node_modules/@stdlib/ndarray/nans-like/`
- [ ] `lib/main.js` implements `nansLike(x[, options])` function
- [ ] Function uses `dtypes('floating_point_and_generic')` (not integer types, since NaN is undefined for integers)
- [ ] Function fills ndarray with `NaN`
- [ ] Options: dtype, shape, order, mode, submode, readonly (same as ones-like)
- [ ] `lib/index.js` module wrapper exists
- [ ] `package.json` correct
- [ ] `test/test.js` comprehensive (all dtypes, options, edge cases)
- [ ] `examples/index.js` working example
- [ ] `benchmark/benchmark.js` and per-dtype size benchmarks
- [ ] `docs/repl.txt` correct REPL documentation
- [ ] `docs/types/index.d.ts` TypeScript declarations (float types + generic only)
- [ ] `docs/types/test.ts` TypeScript test file
- [ ] `README.md` documentation
- [ ] `nansLike` added to `@stdlib/ndarray` namespace (`lib/index.js`)
- [ ] Tests pass
- [ ] Lint passes

## PR Template Sections
- Description
- Related Issues
- Questions
- Other
- Checklist (contributing guidelines, AI assistance disclosure)

## Make Commands
- Test: `make test TESTS_FILTER="*/ndarray/nans-like/*"`
- Lint JS: `make lint-javascript FILES="lib/node_modules/@stdlib/ndarray/nans-like/**/*.js"`
- Examples: `node lib/node_modules/@stdlib/ndarray/nans-like/examples/index.js`

## Branch
`claude/vibrant-brahmagupta-9A236`

## Key Design Decisions
1. NaN only valid for floating-point and generic types → use `dtypes('floating_point_and_generic')`
2. Complex types: `fill(out, NaN)` fills real=NaN, imag=0 (consistent with numpy behavior)
3. TypeScript overloads: float64, float32, complex128, complex64, generic (no integer overloads)
4. Fill mechanism: same as ones-like but with `NaN` instead of `1.0`

## Hypothesis
The package needs to be created from scratch following the pattern of `@stdlib/ndarray/ones-like`, with the key difference being the fill value (NaN) and the restricted set of supported dtypes (floating-point and generic only).

## Iteration 1 - Implement

### Primary Goal: Implement

### Plan
1. Create all package files for `@stdlib/ndarray/nans-like`
2. Add `nansLike` to `@stdlib/ndarray` namespace
3. Run tests and lint
4. Dispatch review agents

## Files Touched
- `lib/node_modules/@stdlib/ndarray/nans-like/` (new)
- `lib/node_modules/@stdlib/ndarray/lib/index.js` (modified - add nansLike)

## Decisions Log
- Using `floating_point_and_generic` dtype group (not `numeric_and_generic`) because NaN throws for integer dtypes in `ndarray/base/fill`
- NaN for complex128/complex64: real=NaN, imag=0 (verified via test)
- Pattern: follows `ones-like` exactly, substituting NaN fill and reduced dtype set

## Iteration 1 - Review Findings (5 parallel agents)

### Agent A: Correctness
- ✅ Complex dtype imaginary parts test — fixed (assert real=NaN, imag=0.0)
- ✅ `FloatingPointAndGenericDataType` import used in `docs/types/index.d.ts`
- Minor: `float16`/`complex32` in dtype list but `buffer()` not implemented — pre-existing issue

### Agent B: Test Quality
- ✅ `bool`/`binary` added to dtype rejection tests
- ✅ Column-major inferred test added
- ✅ Buffer non-sharing test added
- ✅ Isolated option override tests added (dtype, order, shape separately)
- All 316 tests pass

### Agent C: Convention
- ✅ Removed `"numpy.full_like"` keyword from `package.json`
- Naming, JSDoc, file structure all follow stdlib conventions

### Agent D: Security/Robustness
- No security concerns; proper validation mirrors ones-like pattern

### Agent E: Issue-Scope
- Implementation is complete; scope matches "Review `@stdlib/ndarray/nans-like`"

## Final Test Count: 316 tests, 316 pass
41 changes: 41 additions & 0 deletions lib/node_modules/@stdlib/ndarray/docs/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ import maybeBroadcastArray = require( '@stdlib/ndarray/maybe-broadcast-array' );
import maybeBroadcastArrays = require( '@stdlib/ndarray/maybe-broadcast-arrays' );
import minDataType = require( '@stdlib/ndarray/min-dtype' );
import mostlySafeCasts = require( '@stdlib/ndarray/mostly-safe-casts' );
import nansLike = require( '@stdlib/ndarray/nans-like' );
import ndarraylike2ndarray = require( '@stdlib/ndarray/ndarraylike2ndarray' );
import ndims = require( '@stdlib/ndarray/ndims' );
import nextDataType = require( '@stdlib/ndarray/next-dtype' );
Expand Down Expand Up @@ -2211,6 +2212,46 @@ interface Namespace {
*/
mostlySafeCasts: typeof mostlySafeCasts;

/**
* Creates an ndarray filled with NaNs and having the same shape and data type as a provided input ndarray.
*
* @param x - input array
* @param options - options
* @param options.dtype - output array data type
* @param options.order - specifies whether the output array is 'row-major' (C-style) or 'column-major' (Fortran-style)
* @param options.shape - output array shape
* @param options.mode - specifies how to handle a linear index which exceeds array dimensions
* @param options.submode - specifies how to handle subscripts which exceed array dimensions on a per dimension basis
* @param options.readonly - boolean indicating whether an array should be read-only
* @returns NaN-filled array
*
* @example
* var getShape = require( '@stdlib/ndarray/shape' );
* var getDType = require( '@stdlib/ndarray/dtype' );
* var zeros = require( '@stdlib/ndarray/zeros' );
*
* var x = zeros( [ 2, 2 ], {
* 'dtype': 'float64'
* });
* // returns <ndarray>[ [ 0.0, 0.0 ], [ 0.0, 0.0 ] ]
*
* var sh = getShape( x );
* // returns [ 2, 2 ]
*
* var dt = String( getDType( x ) );
* // returns 'float64'
*
* var y = ns.nansLike( x );
* // returns <ndarray>[ [ NaN, NaN ], [ NaN, NaN ] ]
*
* sh = getShape( y );
* // returns [ 2, 2 ]
*
* dt = String( getDType( y ) );
* // returns 'float64'
*/
nansLike: typeof nansLike;

/**
* Converts an ndarray-like object to an ndarray.
*
Expand Down
9 changes: 9 additions & 0 deletions lib/node_modules/@stdlib/ndarray/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,15 @@ setReadOnly( ns, 'minDataType', require( '@stdlib/ndarray/min-dtype' ) );
*/
setReadOnly( ns, 'mostlySafeCasts', require( '@stdlib/ndarray/mostly-safe-casts' ) );

/**
* @name nansLike
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/ndarray/nans-like}
*/
setReadOnly( ns, 'nansLike', require( '@stdlib/ndarray/nans-like' ) );

/**
* @name ndarraylike2ndarray
* @memberof ns
Expand Down
174 changes: 174 additions & 0 deletions lib/node_modules/@stdlib/ndarray/nans-like/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
<!--

@license Apache-2.0

Copyright (c) 2026 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.

-->

# nansLike

> Create an [ndarray][@stdlib/ndarray/ctor] filled with NaNs and having the same shape and [data type][@stdlib/ndarray/dtypes] as a provided ndarray.

<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->

<section class="intro">

</section>

<!-- /.intro -->

<!-- Package usage documentation. -->

<section class="usage">

## Usage

```javascript
var nansLike = require( '@stdlib/ndarray/nans-like' );
```

#### nansLike( x\[, options] )

Creates an [ndarray][@stdlib/ndarray/ctor] filled with NaNs and having the same shape and [data type][@stdlib/ndarray/dtypes] as a provided ndarray.

```javascript
var getShape = require( '@stdlib/ndarray/shape' );
var getDType = require( '@stdlib/ndarray/dtype' );
var zeros = require( '@stdlib/ndarray/zeros' );

var x = zeros( [ 2, 2 ] );
// returns <ndarray>[ [ 0.0, 0.0 ], [ 0.0, 0.0 ] ]

var y = nansLike( x );
// returns <ndarray>[ [ NaN, NaN ], [ NaN, NaN ] ]

var sh = getShape( y );
// returns [ 2, 2 ]

var dt = String( getDType( y ) );
// returns 'float64'
```

The function supports the following options:

- **dtype**: output [ndarray][@stdlib/ndarray/ctor] [data type][@stdlib/ndarray/dtypes]. Must be a floating-point or "generic" [data type][@stdlib/ndarray/dtypes]. Overrides the input ndarray's inferred [data type][@stdlib/ndarray/dtypes].
- **shape**: output [ndarray][@stdlib/ndarray/ctor] shape. Overrides the input ndarray's inferred shape.
- **order**: specifies whether the output [ndarray][@stdlib/ndarray/ctor] should be `'row-major'` (C-style) or `'column-major'` (Fortran-style). Overrides the input ndarray's inferred order.
- **mode**: specifies how to handle indices which exceed array dimensions (see [ndarray][@stdlib/ndarray/ctor]). Default: `'throw'`.
- **submode**: a mode array which specifies for each dimension how to handle subscripts which exceed array dimensions (see [ndarray][@stdlib/ndarray/ctor]). If provided fewer modes than dimensions, the constructor recycles modes using modulo arithmetic. Default: `[ options.mode ]`.
- **readonly**: boolean indicating whether an array should be **read-only**. Default: `false`.

To override either the `dtype`, `shape`, or `order`, specify the corresponding option. For example, to override the inferred [data type][@stdlib/ndarray/dtypes],

```javascript
var getShape = require( '@stdlib/ndarray/shape' );
var getDType = require( '@stdlib/ndarray/dtype' );
var zeros = require( '@stdlib/ndarray/zeros' );

var x = zeros( [ 2, 2 ] );
// returns <ndarray>[ [ 0.0, 0.0 ], [ 0.0, 0.0 ] ]

var dt = String( getDType( x ) );
// returns 'float64'

var y = nansLike( x, {
'dtype': 'float32'
});
// returns <ndarray>[ [ NaN, NaN ], [ NaN, NaN ] ]

var sh = getShape( y );
// returns [ 2, 2 ]

dt = String( getDType( y ) );
// returns 'float32'
```

</section>

<!-- /.usage -->

<!-- Package usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->

<section class="notes">

## Notes

- The function only supports floating-point and "generic" [data types][@stdlib/ndarray/dtypes], as NaN is not defined for integer data types.

</section>

<!-- /.notes -->

<!-- Package usage examples. -->

<section class="examples">

## Examples

<!-- eslint no-undef: "error" -->

```javascript
var zeros = require( '@stdlib/ndarray/zeros' );
var ndarray2array = require( '@stdlib/ndarray/to-array' );
var nansLike = require( '@stdlib/ndarray/nans-like' );

// Define a list of supported floating-point data types:
var dt = [ 'float32', 'float64', 'complex64', 'complex128', 'generic' ];

// Generate NaN-filled arrays...
var x;
var y;
var i;
for ( i = 0; i < dt.length; i++ ) {
x = zeros( [ 2, 2 ], {
'dtype': dt[ i ]
});
y = nansLike( x );
console.log( ndarray2array( y ) );
}
```

</section>

<!-- /.examples -->

<!-- Section to include cited references. If references are included, add a horizontal rule *before* the section. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->

<section class="references">

</section>

<!-- /.references -->

<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->

<section class="related">

</section>

<!-- /.related -->

<!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->

<section class="links">

[@stdlib/ndarray/ctor]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/ndarray/ctor

[@stdlib/ndarray/dtypes]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/ndarray/dtypes

</section>

<!-- /.links -->
Loading
Loading