Namespace NumSharp
Primary NumSharp namespace containing the NDArray type, NumPy-style API facade, dtype metadata, slicing and shape helpers, random state, and NumPy-compatible exception types.
Use this namespace when writing NumSharp code:
- np is the NumPy-style static API, equivalent to Python's
import numpy as np. - NDArray is the main n-dimensional array container.
- Shape, Slice, and NPTypeCode define shape, view, indexing, and dtype behavior.
- NumPyRandom exposes NumPy-compatible MT19937 random generation.
NumSharp targets NumPy 2.x API and behavioral compatibility. Arrays use unmanaged storage,
slicing returns views that share storage, broadcasting follows NumPy shape rules, and the public
NDArray dtype set covers Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Char,
Half, Single, Double, Decimal, and Complex. NPTypeCode.Empty, NPTypeCode.String, and the
NPTypeCode.Float alias are enum/compatibility values, not additional public array dtypes;
Float resolves to Single.
using NumSharp;
var a = np.arange(6).reshape(2, 3);
var b = np.array(new[] { 10, 20, 30 });
NDArray c = a + b; // NumPy-style broadcasting
NDArray col = c[":, 1"]; // Slicing returns a view
Classes
- ArrayMethod
NEP 43's
ArrayMethod— ONE object per (input DTypes → output DTypes) implementation of an operation: it resolves the loop descriptors for the given operand descriptors (ResolveDescriptors(DType[], DType[], out long)) and hands out the strided inner loop that runs them (GetStridedLoop(ArrayMethodContext, bool, long[], out NDArrayMethodFlags)). Casts are the first family (CastingImpl); ufunc loops for a new dtype register the same way (Stage C) instead of adding acase NPTypeCode.X:to the IL generators.
- ArrayMethodContext
NEP 43's
PyArrayMethod_Context: the method being run plus the resolved descriptors — what a strided loop receives so it can read parameters (a datetime unit) without re-resolving.
- AttributeError
Exception that corresponds to Python/NumPy's AttributeError. Raised when an attribute reference or assignment fails.
- AxisError
NumPy-compatible AxisError exception. Raised when an axis argument is out of bounds for the array's dimensions.
- BitGenerator
Base class for the pseudo-random bit generators that drive Generator.
- BuiltinCastingImpl
The cast between two storage-backed builtin classes (NumPy's
add_numeric_cast,convert_datatype.c). Its Casting is computed the way NumPy computesspec.casting: the same class →equiv(a copy or byte swap);safewhen the frozen promotion table sayspromote(from, to) == to(NumPy's_npy_can_cast_safely_table); otherwisesame_kindwhen the source kind orders at or below the destination kind (b < u < i < f < c), elseunsafe. These are exactly the rulesnp.can_cast(NPTypeCode, NPTypeCode)always applied, so the builtin answers are unchanged; the class pair now owns them.
- CastingImpl
An ArrayMethod with one input and one output: the cast from From to To (NumPy's
castingimpl). Looked up per class pair by GetCastingImpl(DTypeMeta) and consulted by DTypeCasting (can_cast, cast-safety, descriptor adaptation) and by CastDescrToDType(DType, DTypeMeta) (which is how a parametric class learns the instance an operand of another class should become).
- DType
NumSharp's data-type descriptor — the INSTANCE of a DTypeMeta class, standing in for NumPy's
numpy.dtypeobject (np.dtype('f8'),np.dtype('M8[ns]')), and the single dtype spelling every dtype-taking API in NumSharp accepts.
- DTypeCasting
The NEP 43 casting engine over descriptors — the ports of NumPy's
convert_datatype.centry points: GetCastingImpl(DTypeMeta, DTypeMeta) (PyArray_GetCastingImpl), GetCastInfo(DType, DType, DTypeMeta, out long) (PyArray_GetCastInfo), CheckCastSafety(NPY_CASTING, DType, DType, DTypeMeta) (PyArray_CheckCastSafety), CanCastTypeTo(DType, DType, NPY_CASTING) (PyArray_CanCastTypeTo— the engine behindnp.can_cast), EquivTypes(DType, DType) (PyArray_EquivTypes), MinCastSafety(NPY_CASTING, NPY_CASTING) and the casting-string parser. Every question is answered by the CastingImpl registered for the CLASS pair, so a new dtype joinsnp.can_castby registering its casts — no table edit.
- DTypeMeta
The DType CLASS — NumPy's
PyArray_DTypeMeta(type(np.dtype('f8')), i.e.np.dtypes.Float64DType). One live object per dtype class; a DType is an INSTANCE of it (the descriptor). This is NEP 41/42's two-level model: behaviour lives on the class as virtual "slots" (CommonDType(DTypeMeta), CommonInstance(DType, DType), DefaultDescr(), EnsureCanonical(DType), DiscoverDescrFromObject(object), IsKnownScalarType(Type), the casting implementations), parameters live on the instance (a datetime unit, a byte order).
- DTypePromotion
The NEP 42 / NEP 50 promotion engine over DType classes and descriptors — the ports of NumPy's
common_dtype.candconvert_datatype.c: CommonDType(DTypeMeta, DTypeMeta) (PyArray_CommonDType), PromoteDTypeSequence(IReadOnlyList<DTypeMeta>) (PyArray_PromoteDTypeSequencewith itsreduce_dtypes_to_most_knowledgeablepass), PromoteTypes(DType, DType) (PyArray_PromoteTypes), CastDescrToDType(DType, DTypeMeta) (PyArray_CastDescrToDType), CastToDTypeAndPromoteDescriptors(IReadOnlyList<DType>, DTypeMeta) and ResultType(params object[]) (PyArray_ResultType, the NEP 50 entry point where C# literals are weak and arrays — 0-d included — are strong).
- DTypePromotionError
numpy.exceptions.DTypePromotionError— raised when two (or more) DTypes have no common DType, i.e.np.promote_types/np.result_typecannot find a dtype that can hold every input (NEP 42'scommon_dtypeprotocol returnedNotImplementedin both directions).
- DTypeRegistry
The table of live DTypeMeta classes and their casting implementations — NumPy's
_builtin_descrs/typenum_to_dtypemeta/_PyArray_MapPyTypeToDTyperolled into one static registry. Lookups by NPTypeCode, C# scalar Type, NumPy type number and class name (aliases included); Register(DTypeMeta) admits a new class (a Stage C/D dtype, a user dtype) without touching the kernel switches — the class registers its code and its casts, and the promotion/casting engines pick it up.
- DatetimeDTypeMeta
The DType classes of
datetime64(np.dtypes.DateTime64DType, type number 21, kind/char'M') andtimedelta64(np.dtypes.TimeDelta64DType, 22,'m') — NumSharp's first PARAMETRIC classes: the unit metadata (DatetimeMetaData) lives on the descriptor INSTANCE, soM8[ns]andM8[s]are two descriptors of one class, and promotion runs CommonInstance(DType, DType) (the unit GCD) instead of returning a class default.
- DatetimeTimedeltaCastingImpl
The cast between
datetime64andtimedelta64(either direction) — NumPy'sdatetime_to_timedelta_resolve_descriptors: the destination inherits the SOURCE's unit when none is given (which is howpromote_typesturnsm8[Y]intoM8[Y]before taking the GCD), and the cast is alwaysunsafe.
- EnvVars
Central, typed accessor for every environment variable NumSharp reads. Each property RETURNS THE VALUE (not the name), read through the shared Get(string) / GetBool(string, bool) helpers, so null/blank handling, trimming and boolean parsing live in ONE place. Read-sites use e.g.
if (EnvVars.DebugGuardPages)orvar lib = EnvVars.OpenBlasLibrary;instead of repeatingEnvironment.GetEnvironmentVariable(...)and its parsing.
- FourierModule
The
numpy.fftmodule surface, reachable as fft. Holds the 18 public transforms/helpers (standardfft/ifft/fft2/ifft2/fftn/ifftn, realrfft/irfft/rfft2/irfft2/rfftn/irfftn, hermitianhfft/ihfft, and helpersfftfreq/rfftfreq/fftshift/ifftshift).The helpers (
fftfreq/rfftfreq/fftshift/ifftshift) are pure compositions of existingnp.*functions. The transforms validate and resolve everything NumPy's Python layer does — n/axis/norm/shape/dtype and the N-D→1-D decomposition — then compute throughPocketFFTDriver.Execute, the managed port of pocketfft's 1-D engine (bit-identical to NumPy 2.4.2 on the double/complex128 path). The N-D wrappers are pure compositions of the 1-D transforms.
- Generator
The modern NumPy random number container returned by
np.random.default_rng.
- IndexError
Exception that corresponds to Python/NumPy's IndexError. Raised when a sequence subscript is out of range, or when an index type is invalid (e.g. float/complex index on an ndarray).
- KeyError
Exception that corresponds to Python/NumPy's KeyError. Raised when a mapping (dict) key is not found.
- LegacyBuiltinDTypeMeta
The DType class of a storage-backed NumSharp dtype — the 15 element types (plus the vestigial String), wrapped the way NumPy's
dtypemeta_wrap_legacy_descriptorwraps its builtin descriptors intonumpy.dtypes.*DTypeclasses. Data-driven: the registry constructs one per NPTypeCode with its NumPy type number, kind, char, size, alignment and aliases; the behaviour slots are the builtin ones — the singleton is the default descriptor, and CommonDType(DTypeMeta) is NumPy'sdefault_builtin_common_dtypeover NumSharp's frozen promotion table (NumSharp.np._nptypemap_arr_arr), so every existingpromote_typesanswer is reproduced bit-for-bit.
- LegacyWrappingCastingImpl
A cast whose safety is fixed per class pair with the plain descriptor resolution — NumPy's
PyArray_AddLegacyWrapping_CastingImpl, used for the numeric ↔ datetime/timedelta casts: every cast to or fromdatetime64isunsafe; an integer or bool castssafely totimedelta64(a 64-bit unsigned one onlysame_kind), a float or complex onlyunsafely.
- LinAlgError
NumPy-compatible
numpy.linalg.LinAlgError. Raised by np.linalg when a matrix is unsuitable for the requested factorisation — the wrong rank, not square, singular, or not positive definite.
- MT19937
Mersenne Twister MT19937 pseudo-random number generator. This implementation matches NumPy's MT19937 exactly, producing identical sequences for the same seed.
- MethodImplOptionsConstants
Method implementation option constants for use with MethodImplAttribute.
- MissingBackendException
Raised when an operation needs a pluggable compute backend — an IBlasBackend assigned to NumSharp.Backends.TensorEngine.Blas — and none is installed, or the installed one declined these operands.
- ModuleNameAttribute
Marks a public type as the C# host of a NumPy module surface — the type whose public members ARE that module's functions.
npitself carries"np", NDArray carries"ndarray", and each function-namespace facade carries its dotted Python path ("np.random"on NumPyRandom,"np.fft"on FourierModule,"np.linalg"on the nestednp.linalgclass).
- NDArray
Container protocol implementation for NDArray. Provides Python-compatible container protocol methods: contains, hash, len, iter, getitem, setitem
- NDArrayFlags
The memory-layout flags of an NDArray — a byte-for-byte port of NumPy 2.4.2's
arrayflagsobject (numpy/_core/src/multiarray/flagsobject.c): the lowercase dotted attributes (c_contiguous,f_contiguous,owndata,writeable,aligned,writebackifcopy, and the derivedfnc/forc/behaved/carray/farray/num), the bracket-key accessor (flags["C"],flags["F_CONTIGUOUS"], …), the six-line ToString() repr, and equality by the integer num. Values are read live from the array's Shape and storage, verified equal to NumPy across every layout (C/F/strided/transposed/broadcast/0-d/empty).ALIGNED is true for every fresh array (managed allocations are always aligned) and can only be cleared through setflags(bool?, bool?, bool?) /
flags["A"] = false— NumPy parity, the flag then reads back False andnum/behaved/carray/farrayfollow. WRITEBACKIFCOPY is always false (NumSharp has no copy-on-write handoff), matching what a NumSharp array can be.
- NDArrayNetInterop
Fluent bridges from NumSharp iteration to built-in .NET types — the "other types (foreach or non-foreach)" companions to the by-
ref T/Span<T>walks and to NDArray._Unsafe.These are the SAFE side of the integration: AsEnumerable<T>(NDArray) gives LINQ/collection interop with UNBOXED elements (only the enumerator is heap-allocated, once, not each element), and the iterator
ToArray/CopyToextensions MATERIALIZE or COPY into caller-owned .NET storage — so, unlike the aliasingnd.Unsafe.*views, the result does not depend on the NDArray staying alive. For a zero-copy aliasingSpan<T>/Memory<T>over the buffer, usend.Unsafe(see Unsafe).
- NDBorrowedAttribute
Marks a field, property, class or struct as borrowing the NDArray(s) it references — they are owned and disposed by someone else — so the compile-time ownership analyzer (
NumSharp.Build.Analyzer) must not demand that the containing type dispose them.
- NDScope
Ambient reclamation scope for transient NDArray intermediates — the library's standard way to make a composition method eagerly return its temporaries' pooled buffers instead of waiting on the finalizer (see
DISPOSAL-GUIDELINES.md). Every NDArray constructed on the current thread while a scope is open is tracked by it; disposing the scope disposes every tracked array that was not yielded via Returns<T>(T). Tracked disposal is ordinary ARC release (the buffer frees only at refcount 0), so releasing a base whose view was yielded never corrupts — the same safety as a hand-writtenDispose, with the bookkeeping automated.
- NDScopedAsyncAttribute
The ASYNC counterpart of NDScopedAttribute: marks an async method, an async iterator, or a non-async method returning
Task/ValueTask[<T>] as an NDScope boundary. At build time the NumSharp IL weaver (tools/NumSharp.Build, shipped to consumer projects as theNumSharp.BuildNuGet package) weaves the method's compiler STATE MACHINE — or, for a non-async Task-returning body, its DEFERRAL egress — so the NDArray temporaries it drops are reclaimed at the invocation's completion instead of waiting on the finalizer, with the source keeping its 100% original body exactly as NDScopedAttribute does for synchronous ones.
- NDScopedAttribute
Marks a method (or a property accessor) as an NDScope boundary: at build time the NumSharp IL weaver (
tools/NumSharp.Build, shipped to consumer projects as theNumSharp.BuildNuGet package) injects the exact code the hand-written pattern spells —using var scope = NDScope.Open(); ...original body, byte-for-byte... return scope.Returns(result); // NDArray-like returns— so the source keeps its 100% original body and the reclamation is invisible.
- NDScopedCoveredAttribute
Marks a method (or property accessor) as covered by an ambient NDScope opened by its caller — a
[NDScoped]OR[NDScopedAsync]boundary (or a hand-written scope) — so its NDArray temporaries are reclaimed by that caller's scope, and theNDW012leak analyzer must treat the method as covered instead of flagging its transients.
- NDScopedExitAttribute
Marks a by-value parameter as one the callee RETAINS — a reference it keeps past the call (stores in a field/property, adds to a long-lived collection, captures in a closure/task that outlives the call). At build time the NumSharp IL weaver detaches the argument from whatever NDScope tracks it, so the CALLER's scope will NOT reclaim an NDArray the callee is still holding.
- NameError
Exception that corresponds to Python/NumPy's
NameError. Raised when a name referenced by value is not defined.
- NumPyRandom
A class that serves as numpy.random.RandomState in python. Uses MT19937 (Mersenne Twister) for NumPy-compatible random number generation.
- OpenBlasMissingBackendException
A MissingBackendException whose message says how to make the operation work: reference the
NumSharp.Interop.OpenBLASNuGet package.
- PCG64
PCG64 (XSL-RR 128/64) bit generator — the default BitGenerator behind
np.random.default_rng.
- PyScalarDTypeMeta
NumPy's abstract DType classes for Python scalars —
numpy.dtypes._PyLongDType,_PyFloatDType,_PyComplexDType(abstractdtypes.c). They are how NEP 50 "weak" promotion works: a literal contributes only its abstract CLASS toresult_type(no descriptor, so no value or width), and the class's CommonDType(DTypeMeta) lets the other operand's dtype win within its kind (int8 + 300 → int8,float32 + 1e300 → float32) while still lifting across kinds (int8 + 1.5 → float64). A literal that survives alone falls back to the class default (int64/float64/complex128).
- RuntimeError
Exception that corresponds to Python/NumPy's RuntimeError. Raised when an error is detected that does not fall into any of the other categories.
- SeedSequence
Mixes an arbitrary seed into a high-quality initial state for a bit generator.
- Slice
NDArray can be indexed using slicing
A slice is constructed by start:stop:step notation
Examples:
a[start:stop] # items start through stop-1
a[start:] # items start through the rest of the array
a[:stop] # items from the beginning through stop-1
The key point to remember is that the :stop value represents the first value that is not
in the selected slice. So, the difference between stop and start is the number of elements
selected (if step is 1, the default).
There is also the step value, which can be used with any of the above:
a[:] # a copy of the whole array
a[start:stop:step] # start through not past stop, by step
The other feature is that start or stop may be a negative number, which means it counts
from the end of the array instead of the beginning. So:
a[-1] # last item in the array
a[-2:] # last two items in the array
a[:-2] # everything except the last two items
Similarly, step may be a negative number:
a[::- 1] # all items in the array, reversed
a[1::- 1] # the first two items, reversed
a[:-3:-1] # the last two items, reversed
a[-3::- 1] # everything except the last two items, reversed
NumSharp is kind to the programmer if there are fewer items than
you ask for. For example, if you ask for a[:-2] and a only contains one element, you get an
empty list instead of an error.Sometimes you would prefer the error, so you have to be aware
that this may happen.
Adapted from Greg Hewgill's answer on Stackoverflow: https://stackoverflow.com/questions/509211/understanding-slice-notation
Note: special IsIndex == true
It will pick only a single value at Start in this dimension effectively reducing the Shape of the sliced matrix by 1 dimension.
It can be used to reduce an N-dimensional array/matrix to a (N-1)-dimensional array/matrix
Example:
a=[[1, 2], [3, 4]]
a[:, 1] returns the second column of that 2x2 matrix as a 1-D vector
- TensorEngine
The linear-algebra entry points beyond
dot/matmul: the matrix products (managed fallback, backend optional), the LU-based factorisationsdet/slogdet/solve/inv(managed fallback via NumSharp.Backends.ManagedLu, backend optional), and the remaining factorisations (backend required, no fallback).
- TensorEngine.Threading
Process-wide threading configuration — one named, environment-variable-backed knob per threading domain (NumSharp's own kernels, and the native BLAS / OpenMP runtimes NumPy and the rest of the ecosystem thread through: OpenBLAS, MKL, BLIS, NumExpr, vecLib). It is the single surface for reading and setting them, and it is extensible per module: a module registers (or upgrades) its own knob via Register(string, string, Func<int?>, Action<int?>) — that is how
NumSharp.Interop.OpenBLASattaches a native applier to the OpenBlas knob so a change reaches the loaded library, and how any future backend adds its own.
- TensorEngine.Threading.Variable
One threading knob: a logical name, an optional backing environment variable, and the module hooks that read and apply its value. Read-only from outside; mutated only through TensorEngine.Threading.
- TimeToTimeCastingImpl
The within-class cast of
datetime64/timedelta64— a unit conversion. Port of NumPy'stime_to_time_resolve_descriptors(datetime.c): identical metadata (or an exact 10³ᵏ metric-prefix fold such as[1000ms] → [s]) is a no-op view /equivbyte swap; a generic source issafe; a generic destination or, for timedelta, a jump across the years-months barrier isunsafe; towards a finer unit that divides exactly issafe, anything elsesame_kind.
- TypeError
Exception that corresponds to Python/NumPy's TypeError. Raised when an operation or function receives an argument of inappropriate type.
- ValueError
NumPy-compatible ValueError exception. Raised when an operation receives an argument with the right type but inappropriate value.
- finfo
Machine limits for floating point types.
- iinfo
Machine limits for integer types.
- np
API bridge between NumSharp and Python NumPy
- np.AxisConcatenator
Translates slice expressions to concatenation along an axis — the machinery shared by r_ and c_.
- np.Broadcast
NumPy's
numpy.broadcast— the broadcast result of N operands, usable as an iterator. Like NumPy, the object is its OWN iterator (iter(b) is b): it keeps a single live cursor exposed as index, iterating it yields one tuple of per-operand values per step (advancing the cursor), and reset() rewinds it.
- np.CClass
Translates slice expressions to concatenation along the SECOND axis.
- np.FlatIterator
A flat, C-order iterator over an NDArray — the NumSharp analog of NumPy's
flatiter(the type ofndarray.flat), obtained from flatiter or flat(NDArray).Unlike NumSharp's flat (a raveled NDArray that materializes a COPY for a non-contiguous array, so writes through it are lost), this iterator always reads AND writes THROUGH to the base array in logical C-order, whatever the memory layout — matching NumPy's
a.flat[i] = vsemantics for transposed, sliced, strided, negative-stride and broadcast layouts alike. Every element access maps a flat C-order index to the base's coordinate and goes through the base's stride-aware element accessors, so no per-dtype branching and no buffer materialization occur.Surface (probed against NumPy 2.4.2): this[long] single-element get (a 0-d write-through view, NumSharp's scalar analog) / set; fancy (
int[]/long[]/ NDArray) and slice-string ("1:4","::2") get/set; the index / coords cursor, Base, size, copy() (a fresh 1-D C-order array), and C-order iteration that shares the cursor (so a second pass RESUMES, as NumPy'siter(f) is f).Scalar assignment matches NumPy's weak-scalar bounds check: an OUT-OF-RANGE C# primitive (NumSharp's NEP50 analog of a Python int/float) written to an integer element RAISES (
OverflowException, "Python integer 300 out of bounds for int8") rather than wrapping, the truncate-then-check rule for floats included (127.9stores 127,128.0raises, NaN/inf raise). A STRONG scalar — an NDArray, reached through the fancy/slice setters ora.astype— still wraps, exactly as in NumPy (which range-checks a Python int but wraps annp.int64scalar).One documented divergence remains (
[Misaligned]): coords read at the EXHAUSTED position (index == size, after a full pass) on a truly non-contiguous array is implementation-defined — NumSharp returns the arithmetic continuation, NumPy an internal odometer artifact; every IN-RANGE coord (the values read during iteration) is bit-exact.
- np.IndexExpression
A nicer way to build up index tuples for arrays — the type behind s_ and index_exp. Use those two instances rather than constructing this directly.
- np.MGridClass
An instance which returns a dense ("fleshed out") multi-dimensional "meshgrid" when indexed, so that every returned axis-grid has the SAME shape. The number of stacked grids and their dimensionality equal the number of indexing slices. If the step length is not a complex number, the stop is NOT inclusive; a complex step (e.g.
"…:5j") instead specifies the number of points, with the stop INCLUSIVE (i.e. linspace(double, double, long, bool, DType, string)).
- np.MemoryView
The NumSharp analog of Python's
memoryview— the buffer object returned by data. It is a lightweight, zero-copy HANDLE onto an array's raw memory plus the layout metadata needed to interpret it (NumPy'sndarray.datais literallymemoryview(self)).It owns no memory of its own: every member reads LIVE through the source array's Storage and Shape, so it stays valid while the source array (held as obj, keeping it alive exactly as NumPy's
memoryview.objdoes) is alive and not structurally mutated. The Pointer addresses the LOGICAL first element (base + offset·itemsize), matching NumPy'sa.data/PyArray_DATA/a.ctypes.data/a.__array_interface__['data'][0]— for a sliced or reversed view this is the offset element, not the buffer base.Surface (probed against NumPy 2.4.2's
memoryview): obj, nbytes, itemsize, ndim, readonly (true for broadcast / non-writeable views), shape, strides (in BYTES like NumPy's — NumSharp's own strides are in elements), format (the struct-module type code), c_contiguous / f_contiguous / contiguous, Length (NumPy'slen(mv)), tobytes(string) / hex(), the raw Pointer / Address, and write-through scalar element access via this[long[]].Deliberately NOT modelled (documented boundaries, not gaps to close): partial-index sub-views (
mv[1]on an N-D memoryview yields a sub-memoryviewin Python — use the NDArray indexer for sub-arrays),cast,tolist,release/ the context-manager protocol, and element iteration. NumSharp has no Python buffer protocol, so these Python-object conveniences have no counterpart; the buffer ESSENCE (pointer + metadata + write-through +tobytes) is whatndarray.datais for.
- np.NDEnumerate
NumPy's
numpy.ndenumerate— walks an array in C-order, yielding(index, value)for every element.// numpy: list(np.ndenumerate(np.array([[1, 2], [3, 4]]))) // -> [((0,0), 1), ((0,1), 2), ((1,0), 3), ((1,1), 4)] foreach (var (index, value) in np.ndenumerate(a)) { … }Like NumPy the object is its OWN iterator (
iter(e) is e): it keeps a single live cursor, so a second enumeration resumes where the first stopped.
- np.NDEnumerate<T>
Typed np.NDEnumerate — identical traversal, but reads elements as
Twithout boxing. See ndenumerate<T>(NDArray).
- np.NDIndex
NumPy's
numpy.ndindex— a C-order odometer over the index space of a shape, yielding one index array per step with the LAST dimension varying fastest.// numpy: list(np.ndindex(3, 2)) -> [(0,0), (0,1), (1,0), (1,1), (2,0), (2,1)] foreach (var idx in np.ndindex(3, 2)) { /* idx = {0,0}, {0,1}, {1,0}, ... */ }Like NumPy the object is its OWN iterator (
iter(i) is i): it keeps a single live cursor, so a second enumeration resumes where the first stopped rather than restarting — the same contract np.Broadcast follows.
- np.NDIterator
NumPy's
numpy.nditer— the public, managed face of NumSharp's NDIterRef.// numpy: for x in np.nditer(a): total += x foreach (var vals in np.nditer(a)) total += (int)vals[0]; // numpy: it = np.nditer(a, flags=['multi_index']) // while not it.finished: print(it.multi_index, it[0]); it.iternext() var it = np.nditer(a, flags: new[] {"multi_index"}); while (!it.finished) { Use(it.multi_index, it[0]); it.iternext(); }
- np.OGridClass
An instance which returns an open multi-dimensional "meshgrid" when indexed, so that only one dimension of each returned array is greater than 1. The number and dimensionality of the outputs equal the number of indexing slices. If the step length is not a complex number, the stop is NOT inclusive; a complex step (e.g.
"…:5j") instead specifies the number of points, with the stop INCLUSIVE (i.e. linspace(double, double, long, bool, DType, string)).
- np.RClass
Translates slice expressions to concatenation along the FIRST axis. Two use cases: comma-separated arrays are stacked along axis 0, and slice notation or scalars build a 1-D array.
- np.dtypes
numpy.dtypes(NEP 56 / NumPy 1.25+): the DType CLASSES —np.dtypes.Float64DTypeistype(np.dtype('f8')). Each member is the live DTypeMeta singleton; its Instantiate() is NumPy's class call (Int8DType()→dtype('int8');DateTime64DType()raises the "Preliminary-API … can only be instantiated usingnp.dtype(...)" TypeError), and Meta istype(dtype).
- np.linalg
NumPy's
numpy.linalgmodule.
- poly1d
A one-dimensional polynomial class — the NumSharp port of
numpy.poly1d. Encapsulates a coefficient vector (highest power first) and the natural polynomial operations.C# has no call syntax, so NumPy's
p(x)evaluation is spellednp.polyval(p, x); the indexerp[k]retrieves the coefficient ofx**kexactly like NumPy. NumPy'sp ** n(polynomial power) has no**operator in C# — spell it with repeated multiplication (p * p * p), which NumPy defines it to equal. ToString() renders NumPy'sreprform (poly1d([...])); NumPy's separate prettystr()form is not reproduced (C# has a singleToString).
Structs
- Char8
Represents a single byte as a character. Equivalent to NumPy's
dtype('S1')/numpy.bytes_of length 1, and to a Pythonbytesobject of length 1. Interoperable with byte, char (via Latin-1), and string (via ASCII/Latin-1 encoding).
- DateTime64
A 64-bit signed tick count representing a date/time value with full
longrange and a NaT sentinel, matching NumPy'snp.datetime64semantics. Used as a conversion-helper type in Converts.
- DatetimeMetaData
The per-INSTANCE parameter of a
datetime64/timedelta64descriptor — NumPy'sPyArray_DatetimeMetaData({ NPY_DATETIMEUNIT base; int num; }): the unit and an integer multiplier, sodatetime64[5m]counts five-minute ticks. This is what makes the datetime pair PARAMETRIC:M8[ns]andM8[s]share one DTypeMeta and one 8-byte storage but are different dtypes, and promotion / casting between units is arithmetic on these two fields.
- EinsumPath
The contraction path returned by einsum_path(string, NDArray[]) — NumPy's
['einsum_path', (1, 2), (0, 1)]list expressed as a value.
- NativeRandomState
Represents the stored state of MT19937 random number generator. This format is compatible with NumPy's random state.
- PCG64.Pcg64StateData
Snapshot of the PCG64 internal state (the typed stand-in for NumPy's
bit_generator.statedict; field names match its keys).
- PolyfitResult
The polymorphic return of polyfit(NDArray, NDArray, int, double?, bool, NDArray, object). Converts implicitly to the coefficient array (the bare-return case); deconstructs to NumPy's
fullfive-tuple(coeffs, residuals, rank, singular_values, rcond)or thecovtwo-tuple(coeffs, covariance).
- Shape
Broadcasting operations for Shape.
- np.FlatRefIter<T>
The
foreach-able returned by flat<T>(NDArray, bool) and AsTyped<T>(bool) — the typed, unboxed, by-reference flat iterator. Yieldsref Tin logical C-order (matching flatiter), write-through for every memory layout.It is exactly a C-order np.NDRefIter<T>. This type reuses np.NDRefIter<T>.Enumerator verbatim — the same NDIterRef cursor that
np.nditer<T>drives — pinned toNPY_CORDER. It exists as its own type only so the flat contract (always C-order, never memory order) is stated in the type rather than left to a parameter default; there is no separate iteration logic. Everything documented on np.NDRefIter<T> — why the enumerator is aref struct, that this value holds no unmanaged state while the enumerator does, thatforeachdisposes it and re-enumeration restarts — applies identically.
- np.MGridResult
The result of an mgrid index expression: a dense mesh — one array. NumPy's
mgridis a singlendarray(a 1-D array for one slice; a stacked(N, *sizes)array for several), and the idiomX, Y = np.mgrid[…]works by iterating that array's first axis. This value carries the array and reproduces both spellings: it converts implicitly to the bare NDArray, and itDeconstructs (var (x, y) = np.mgrid["0:5", "0:3"];) or indexes ([k]) into the per-axis grids along that first axis.
- np.MeshgridResult
The result of meshgrid(NDArray[], string, bool, bool): a tuple of N coordinate grids (NumPy returns a Python tuple). C# cannot return a variadic tuple, so this value stands in for it — it converts implicitly to NDArray
[],Deconstructs (var (xx, yy) = np.meshgrid(x, y);) and indexes ([k]).
- np.NDChunkIter<T>
The
foreach-able returned by nditer_chunks<T>(NDArray, bool, char). See np.NDRefIter<T> for theref struct, disposal, re-enumeration and iteration-order rationale, which apply identically.The yielded Span<T> points straight at the operand, so writes go through and the span is invalidated by the next step.
- np.NDChunkIter<T>.Enumerator
The cursor — one Span<T> per inner loop.
- np.NDEnumerateRef<T>
The
foreach-able returned by AsRef(bool) — the typed, allocation-free, by-ref Tndenumerate. Yields, per element, a np.NDEnumerateRef<T>.Entry carrying the coordinate (a ReadOnlySpan<T> over a reused buffer) and the value BY REFERENCE, in logical C-order (matching ndenumerate(NDArray)), write-through for every memory layout.It composes two things that are already correct: the value
refcomes from np.NDRefIter<T>.Enumerator pinned to C-order (the same engine flat<T>(NDArray, bool) drives), and the coordinate comes from a C-order odometer advanced in lockstep — since a C-order walk visits logical positions0, 1, …, size-1, the k-th value and the k-th unravelled coordinate always line up. Everything documented on np.NDRefIter<T> about theref structenumerator, disposal underforeach, and restart-on-re-enumeration applies.
- np.NDEnumerateRef<T>.Entry
One enumerated element: its coordinate and its value by reference.
- np.NDEnumerateRef<T>.Enumerator
The cursor — pairs the C-order value
refwith a lockstep coordinate odometer.
- np.NDIndexSpans
The
foreach-able returned by AsSpans() — the allocation-free odometer. Yields the current multi-index as a ReadOnlySpan<T> over a buffer REUSED each step (C-order, last axis fastest — identical order to np.NDIndex), so an entire index-space walk allocates nothing per step.Re-enumeration RESTARTS (each
foreachbuilds a fresh enumerator with its own buffer) — deliberately unlike np.NDIndex, which is its own iterator (NumPy'siter(i) is i) and resumes. Copy the span (.ToArray()) to keep an index past the current iteration; storing the span itself, or the whole enumeration, is a use-after-overwrite.
- np.NDIndexSpans.Enumerator
The cursor — one ReadOnlySpan<T> (over a reused buffer) per step.
- np.NDRefIter<T>
The
foreach-able returned by nditer<T>(NDArray, bool, char).Why a
ref structenumerator. C#'sforeachis pattern-based — it needs onlyGetEnumerator/MoveNext/Current, no interface — so an enumerator exposingref T Currentgivesforeach (ref T x in …)with no allocation, no boxing and no interface dispatch. Being aref structalso makes the compiler enforce what this API needs anyway: neither the enumerator nor therefit hands out can escape to a field, a lambda or anasyncframe.This type holds no unmanaged state; the ENUMERATOR does. Each GetEnumerator() builds a fresh NDIterRef, which
foreachthen disposes through the same pattern (noIDisposablerequired). That is why this value is safe to keep and re-enumerate, and why every pass starts from the beginning — deliberately UNLIKE the class-based np.NDIterator, which is its own iterator (NumPy'siter(x) is x) and therefore resumes. ReturningthisfromGetEnumerator— the np.Broadcast pattern — would be a use-after-free here: the firstforeachfrees the state that the second would then walk.Order is
'K', i.e. MEMORY order — not logical C-order. This matchesnp.nditerexactly (probed against NumPy 2.4.2: a reversed viewa[:, ::-1]ofarange(6).reshape(2,3)yields0 1 2 3 4 5under the default order in BOTH libraries, and2 1 0 5 4 3underorder='C'). It is also what lets reversed / F-contiguous / transposed views coalesce to a single chunk. For logical order — the order ndenumerate(NDArray) uses — passorder: 'C'.
- np.NDRefIter<T>.Enumerator
The cursor. Walks the inner loop with plain pointer arithmetic and only touches the iterator at a chunk boundary, so a contiguous array costs one iterator call for the whole walk.
- np.OGridResult
The result of an ogrid index expression: an open mesh — a set of N arrays, each 1 in every axis but its own. NumPy's
ogridis polymorphic (a single slice yields a barendarray, several slices yield atuple), which C# cannot express from one indexer, so this value stands in for both:
- np.UniqueAllResult
The result of unique_all(NDArray): NumPy's
UniqueAllResultnamedtuple (values,indices,inverse_indices,counts). Converts implicitly to NDArray[],Deconstructs (var (values, indices, inv, counts) = np.unique_all(x);) and indexes ([k]).
- np.UniqueCountsResult
The result of unique_counts(NDArray): NumPy's
UniqueCountsResultnamedtuple (values,counts). Converts implicitly to NDArray[],Deconstructs (var (values, counts) = np.unique_counts(x);) and indexes.
- np.UniqueInverseResult
The result of unique_inverse(NDArray): NumPy's
UniqueInverseResultnamedtuple (values,inverse_indices). Converts implicitly to NDArray[],Deconstructs (var (values, inv) = np.unique_inverse(x);) and indexes.
- np.UniqueResult
The result of <xref href="NumSharp.np.unique(NumSharp.NDArray%2cSystem.Boolean%2cSystem.Boolean%2cSystem.Boolean%2cSystem.Nullable%7bSystem.Int32%7d%2cSystem.Boolean%2cSystem.Boolean)" data-throw-if-not-resolved="false"></xref> — NumPy's bare-array-OR-tuple return expressed as one type. It carries the sorted unique <xref href="NumSharp.np.UniqueResult.values" data-throw-if-not-resolved="false"></xref> plus whichever of <xref href="NumSharp.np.UniqueResult.indices" data-throw-if-not-resolved="false"></xref>/<xref href="NumSharp.np.UniqueResult.inverse_indices" data-throw-if-not-resolved="false"></xref>/ <xref href="NumSharp.np.UniqueResult.counts" data-throw-if-not-resolved="false"></xref> were requested (the others are <code>null</code>), so <code>np.unique(ar, return_counts=True)</code> ports from Python verbatim.It stands in for both NumPy return shapes: it converts implicitly to NDArray (the bare form — yields values, so
NDArray u = np.unique(ar);works) and implicitly to NDArray[](the tuple form — the present outputs in NumPy field order). It also indexes ([k]= the k-th present output, matching the oldNDArray[]return) andDeconstructs (var (values, counts) = np.unique(ar, return_counts: true);).
Interfaces
- IIndex
Represents a class that can be served as an index, e.g. ndarray[new Slice(...)]
- INDArrayCarrier
Opt-in seam a tuple-standin result struct (np.UniqueResult, np.MeshgridResult, PolyfitResult, …) implements so the NDScopedAttribute weaver can weave a boundary method that RETURNS it: YieldTo(NDScope) hands every NDArray the struct carries back to the ambient scope (via Returns<T>(T)), so the method's temporaries are reclaimed while its results survive.
Enums
- ArrayFlags
NumPy-aligned array flags. Cached at shape creation for O(1) access. Matches numpy/core/include/numpy/ndarraytypes.h flag definitions.
- DTypeFlags
Flags describing a DTypeMeta — the DType CLASS — mirroring NumPy's
NPY_DT_*bits (dtypemeta.h/dtype_api.h):NPY_DT_LEGACY = 1,NPY_DT_ABSTRACT = 2,NPY_DT_PARAMETRIC = 4,NPY_DT_NUMERIC = 8.
- NPTypeCode
Represents all available types in numpy.
- NPTypeKind
Abstract type categories in NumPy's type hierarchy. These mirror NumPy's abstract scalar types (np.generic, np.number, etc.)
- NPY_DATETIMEUNIT
NumPy's
NPY_DATETIMEUNIT(ndarraytypes.h): the time unit adatetime64/timedelta64value counts in. The enum values are NumPy's — including the gap at 3 where the 1.6 business-day unit sat — because unit ORDER is semantic (a larger value is a finer unit) and NumPy's casting rules compare them.
- PyScalarKind
The three NEP 50 "weak" literal categories: a Python
int,float,complex.