Skip to content

[NEP27 NEP51] Scalar and Zero-Rank Array Handling #550

@Nucs

Description

@Nucs

Overview

NumPy's handling of zero-rank arrays (scalar arrays) and scalar representation.


NEP 27: Zero Rank Arrays

Status: Final (Informational) | Full Text

Definition

Arrays with shape=() representing scalar quantities:

x = np.array(5)
x.shape  # ()
x.ndim   # 0
x.size   # 1

Three Scalar Representations

Feature Zero-Rank Array Array Scalar Python Scalar
Type ndarray e.g., np.int64 int, float
Mutable Yes No N/A
Has .shape Yes () Yes () No
Output buffer Yes No No
Shares memory Can Cannot N/A

Indexing Zero-Rank Arrays

x = np.array(1)
x[...]     # Returns scalar (not array)
x[()]      # Same
x[np.newaxis]  # array([1]) - adds dimension

Critical Use Cases

  1. Output arguments: Zero-rank arrays work as output buffers
  2. Shared memory views: Can be views into larger arrays
  3. Generic code: Uniform behavior across all ranks

NEP 51: Changing Scalar Representation

Status: Accepted | Full Text

Before (NumPy 1.x)

>>> np.float32(3.0)
3.0
>>> np.int64(34)
34
>>> np.True_
True

After (NumPy 2.x)

>>> np.float32(3.0)
np.float32(3.0)
>>> np.int64(34)
np.int64(34)
>>> np.True_
np.True_

Rationale

  • Makes type distinctions explicit
  • NumPy scalars behave differently (overflow, precision)
  • Aids debugging

Suggested Implementation for NumSharp

Zero-Rank Support Verification

// Ensure Shape handles zero-rank
var shape = new Shape();  // shape.NDim == 0, shape.Size == 1
var scalar = np.array(5); // Zero-rank array

// Verify properties
Assert.True(shape.IsScalar);
Assert.False(shape.IsEmpty);
Assert.Equal(0, shape.NDim);
Assert.Equal(1, shape.Size);

Indexing Behavior

// arr[...] and arr[()] should return scalar value, not array
var arr = np.array(5);
var value = arr["..."];  // Should be scalar 5

Scalar ToString (Optional)

// Consider matching NumPy 2.x representation
public override string ToString() {
    if (IsScalar) {
        return $"np.{TypeName}({Value})";
    }
    // ...
}

Broadcasting

// Zero-rank arrays broadcast to any shape
var scalar = np.array(5);
var arr = np.ones(new Shape(3, 4));
var result = scalar + arr;  // Shape (3, 4)

Documentation

See docs/neps/NEP27.md, docs/neps/NEP51.md

Metadata

Metadata

Assignees

Labels

NumPy 2.x ComplianceAligns behavior with NumPy 2.x (NEPs, breaking changes)coreInternal engine: Shape, Storage, TensorEngine, iteratorsdocumentation-neededFeature requires documentation after implementation or depiction of lack of documentationenhancementNew feature or request

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions