Compatibility lists: version 5
This page gives a comprehensive list of differences between ILNumerics version 5 and * ILNumerics version 4, * numpy ndarray 1.13 and * the Matlab framework.
ILNumerics version 5 requires .NET Framework version 4.5.2 or higher. It installs into Visual Studio 2013...2017 and can also be used without Visual Studio. Since some functionality is provided by means of native modules, currently Windows 7 or higher is required for the full feature set to work.
Major Changes in ILNumerics version 5
- Classes have nicer names: The 'IL' prefixes have been removed from most class names. Only two exceptions: ILNumerics – the root namespace, and the static class ILMath contained therein (the latter is to prevent from conflicts with System.Math).
- The speed of subarrays has been drastically improved. We have tried very hard to design the feature optimal regarding both: the convenience and flexibility of the supported subarray feature set and the speed of execution for a wide range of array / index sizes and dimensionalities. While in version 5 subarrays are fully compatible to version 4 they now take compiler support and make use of overload resolution to automatically pick the best subarray overload suitable for the indexing parameter set provided. This allows us to achieve outstanding performance - for large and small arrays, and even for scalar access! Additionally, all numpy indexing features are now supported.
- The core of ILNumerics has been reworked. Arrays are now compatible to Matlab® and numpy.
- The speeds of general array functions have been greatly improved. Within the core of ILNumerics we introduced a "no new()" policy: most algorithms will not trigger the GC even when running for hours. A new, more efficient low-level parallelization scheme auto-adopts to the current state of the system and to the problem size. Your algorithms 'learn' how to run faster over time!
- Arrays no longer utilize the managed heap as element storage. Elements can be accessed via pointers instead of System.Array. The old way via Array<T>.GetArrayForRead() is now deprecated. Pinning internal storage is not necessary for pointer element access . Size limitations as for CLR arrays are gone.
- Memory pools play an important role in version 5, too. In fact, each computational thread manages its own memory now. Also, the pools in version 5 build the foundation of multi-device memory management (coming soon). But ILNumerics users commonly don't have to deal with memory, though. This remains true for version 5! In the vast majority of cases one can leave the memory management to the same, simple function rules, known from earlier versions. For the rest you may use the low-level memory allocation functions: ILNumerics.ILMath.New<T>() and ILNumerics.ILMath.Free<T>(handle).
- Elements are now stored using arbitrary storage orders, including, but not limited to: column major and row major order. Strides for the storage are accessed via Size A.S.GetStride(i). (In version 4 and in Matlab, Octave, Julia,.. all arrays are stored in column major storage only.)
- ILNumerics’ specific exceptions have been removed and replaced with common .NET exceptions. The function documentation provides details about when which exception is thrown. Most places will generate ArgumentException or IndexOutOfRangeException.
- Index value types: sizes, dimension lengths and element counts are now refered to by long (Int64) values. Where formerly an ILSize was expected now an Array<long> is provided instead. Element indices in general are now <long> / Int64. All places returning dimension lengths (long d = A.S[i]), number of elements (long n = A.S.NumberOfElements) and indices addressing elements (find(),max(),sort(),...) have changed their API regarding indices to long.
- ILNumerics arrays can be used as enumerators over their elements in foreach loops a.t.l. A number of extension methods allows to optionally specify the iteration order. The extension methods are imported from the ILNumerics root namespace.
In earlier versions ILNumerics arrays had more in common with Matlab than with numpy . Now, up from version 5 you can use the new array style setting in order to make arrays act like numpy ndarrays. The following minor differences must be kept in mind, though:
- Positive strides only: when indexing with ranges / slices and custom step sizes, ILNumerics allows positive steps only. Advanced indexing with downward counting indices can be used in order to flip dimensions.
- Scalars: No difference here: 'scalars' in numpy were introduced to compensate for the lack of numeric primitive types in python. On .NET we have excellent support for native primitives. With version 5 support for numpys 'scalar arrays' is added: They are realized by regular ILNumerics arrays, having 0 or more dimensions and exactly 1 element. Such arrays can be used in the very same way as any other ILNumerics array.
- There is no distinction between views and copies in ILNumerics (as there is in numpy). All subarrays semantically act as copies in ILNumerics and such a copy does not alter the underlying storage of the original array when modified ('lazy copy on write').
- ILNumerics arrays know the concept of 'virtual dimensions': next to the dimensions actually stored in the array any number of additional 'virtual', singleton dimensions can be addressed. One advantage: a scalar S can conveniently be indexed by S.
- The maximum number of dimensions stored into an ILNumerics array is currently limited to 7.
- ILNumerics already implements future numpy (indexing) features, planned for upcoming versions of numpy. F.e.: boolean scalars are considered valid indices already.
- Reducing empty arrays: np.zeros([0,2]).sum() -> gives 0.0 in numpy. ILNumerics retains an empty working dimension: the output has the same number and length of dimensions, except that the working dimension in the output is 1 for non-empty input lengths and 0 for empty input lengths.
- any(), all() on empty A: reduced dimension ‘dim’ is set to length 1, even if A.S[dim] == 0. If elements are ‘created’ by the new singleton dimension, their value is always false. In numpy they are false for all(), but true for any().
- A.flat on an array A returns a readonly iterator in row major order. Changing iteration values is not supported. This is due to the strong types of arrays and the distinction between mutable and immutable arrays. ILNumerics maintains the functionality separately: indices for iteration (Size.Iterator) and a pointer for reading/writing (GetHostPointerForRead() /--- GetHostPointerForWrite()). Expressions like: A.flat[indices_array] = 0 are currently not supported. (If you require it probably a helper function flatIndices() would be the best option. It converts incoming flat indices into sequential indices for the array.)
There are no known incompatibilities. However, ILNumerics arrays utilize arbitrary storage schemes. Keep this in mind when working directly with the memory used for storing arrays elements.