Skip to content

[Core] Implement and align np typing functions #599

@Nucs

Description

@Nucs

Overview

Implement NumPy's type introspection and promotion functions (np.iinfo, np.finfo, np.can_cast, etc.) and consolidate NumSharp's scattered type information into a centralized, NumPy-aligned system.

Problem

NumSharp's type information is scattered across 5+ files with duplicates and inconsistencies:

File What it has
NPTypeCode.cs GetDefaultValue(), SizeOf(), AsType(), IsUnsigned(), IsSigned(), GetAccumulatingType()
NumberInfo.cs MinValue(), MaxValue()
TypeRules.cs GetTypeSize(), GetClrType(), IsUnsigned(), IsSigned(), IsFloatingPoint(), GetAccumulatingType()
InfoOf<T> Size, Zero, MaxValue, MinValue (generic cached)
ReductionTypeExtensions GetOneValue(), GetMinValue(), GetMaxValue() (uses infinity for floats)

Duplicates found:

  • SizeOf() vs GetTypeSize() vs InfoOf<T>.Size (3 implementations)
  • AsType() vs GetClrType() (2 implementations)
  • IsUnsigned(), IsSigned() (2 implementations each)
  • GetAccumulatingType() (2 implementations)
  • MinValue()/MaxValue() vs GetMinValue()/GetMaxValue() (different semantics!)

NumPy has clean, unified APIs (np.iinfo, np.finfo) that NumSharp lacks entirely.

Proposal

Phase 1: Implement np.iinfo and np.finfo

  • Create np.iinfo(int_type) class returning:

    • bits - number of bits (8, 16, 32, 64)
    • min - smallest value
    • max - largest value
    • dtype - the NPTypeCode
    • kind - 'i' (signed) or 'u' (unsigned)
  • Create np.finfo(float_type) class returning:

    • bits - number of bits
    • min, max - value range
    • eps - machine epsilon
    • epsneg - negative epsilon
    • tiny / smallest_normal - smallest positive normal
    • smallest_subnormal - smallest positive subnormal
    • precision - decimal digits
    • resolution - 10^-precision
    • maxexp, minexp - exponent limits
    • dtype - the NPTypeCode

Phase 2: Implement Type Checking Functions

  • np.issubdtype(arg1, arg2) - check dtype inheritance
  • np.isdtype(dtype, kind) - check dtype against kind string
  • np.issctype(rep) - check if scalar type
  • np.issubsctype(arg1, arg2) - check scalar type inheritance
  • np.sctype2char(sctype) - scalar type to character code
  • np.maximum_sctype(t) - highest precision of same kind

Phase 3: Implement Type Promotion Functions

  • np.can_cast(from, to, casting="safe") - check if cast is valid
  • np.result_type(*arrays_and_dtypes) - common result type (make public)
  • np.promote_types(type1, type2) - smallest type to hold both
  • np.min_scalar_type(a) - minimum type to hold scalar
  • np.common_type(*arrays) - common type for arrays

Phase 4: Consolidate Internal Type Info

  • Create centralized NPTypeInfo static class with all type metadata
  • Remove duplicate GetTypeSize() from TypeRules.cs (use NPTypeCode.SizeOf())
  • Remove duplicate GetClrType() from TypeRules.cs (use NPTypeCode.AsType())
  • Remove duplicate IsUnsigned(), IsSigned() from TypeRules.cs
  • Remove duplicate GetAccumulatingType() from TypeRules.cs
  • Move ReductionTypeExtensions.GetOneValue() to NPTypeCode extensions
  • Keep ReductionTypeExtensions.GetMinValue()/GetMaxValue() separate (uses infinity - different semantics)
  • Update all callers to use consolidated APIs

Phase 5: Additional Type Functions

  • np.isreal(x) - check if array has no imaginary part
  • np.iscomplex(x) - check if array has imaginary part
  • np.iscomplexobj(x) - check if object is complex type
  • np.isrealobj(x) - check if object is real type

NumPy vs NumSharp Current State

NumPy Function NumSharp Status
np.iinfo(dtype) ❌ Missing
np.finfo(dtype) ❌ Missing
np.isscalar(x) ✅ Implemented
np.issctype(rep) ❌ Missing
np.issubdtype(arg1, arg2) ❌ Missing
np.isdtype(dtype, kind) ❌ Missing
np.result_type(*arrays) ⚠️ Internal only (_FindCommonType)
np.find_common_type(array_types, scalar_types) ✅ Implemented
np.promote_types(t1, t2) ❌ Missing (internal only)
np.can_cast(from, to) ❌ Missing
np.min_scalar_type(a) ❌ Missing
np.common_type(*arrays) ❌ Missing
np.isnan(x) ✅ Implemented
np.isinf(x) ✅ Implemented
np.isfinite(x) ✅ Implemented
np.isclose(a, b) ✅ Implemented
np.isreal(x) ❌ Missing
np.iscomplex(x) ❌ Missing
np.sctype2char(sctype) ❌ Missing
np.maximum_sctype(t) ❌ Missing

Evidence

NumPy source reference: src/numpy/numpy/_core/getlimits.py (iinfo, finfo)
NumPy source reference: src/numpy/numpy/_core/numerictypes.py (type functions)
NumPy source reference: src/numpy/numpy/_core/multiarray.py (can_cast, result_type, min_scalar_type)

Scope / Non-goals

In scope:

  • Type introspection classes (iinfo, finfo)
  • Type checking functions (issubdtype, isdtype, etc.)
  • Type promotion functions (can_cast, promote_types, etc.)
  • Consolidating scattered internal type info
  • Removing duplicates

Out of scope:

Metadata

Metadata

Assignees

Labels

NumPy 2.x ComplianceAligns behavior with NumPy 2.x (NEPs, breaking changes)apiPublic API surface (np.*, NDArray methods, operators)coreInternal engine: Shape, Storage, TensorEngine, iteratorsenhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions