Custom functions basics
To fully benefit from ILNumerics, it is essential to learn about the dos and don'ts. ILNumerics distinguishes itself by a high execution speed due to a particular memory management. Only by following a few rules you can make use of the ILNumerics memory management.
So let's take a look at one of the basic components of a program: functions. A function consists of a head and a body. The head may include a return value, input and output parameters. The body comprises calculations that are based on the input parameters and may result in a return value and output parameters.
As shown in the image above ILNumerics provides different array types that vary in terms of lifetime and field of use:
- ILArray<T> is a local array declared and used inside the function body
- ILRetArray<T> is a return parameter used to return a value of a function
- ILInArray<T> is a readonly input parameter of a function
- ILOutArray<T> is an optional output parameter of a function
The following example displays a very simple function that rounds down every single entry of the input parameter inArray.
Here, two different types of ILNumerics arrays are applied. While the function body contains a local array ILArray<float>, the head includes an input array ILInArray<float>. So what happens if we try to use the input array again as shown below?
An error message will appear, since the input array is no longer available. To prevent this from happening, we must implement an artifical scope. In this scope both, input arrays and local arrays, are retained. Once the scope is left, the arrays are released.
Since we can't access the results in this way, it makes sense to add a return value as displayed in the following:
Here, the ILNumerics array type ILRetArray<float> is introduced, thus, an arbitrary local array of the type float can be returned. Note, you can only use return arrays once. Afterwards they will be disposed. Thus, the return array must be assigned to a local array within the function body. Local arrays may be of the type ILArray<T>, ILLogical, or ILCell.
If you want to return more than one array, use the output array type ILOutArray<T>.
The output array above is optional with a default value of null. Inside the function body, it is checked, whether the output array is null or not. If it is not, a local array will be assigned to it.
The arrays mentioned before are not just available for dense arrays, but also for cell and logical arrays. Here, you can get more details.
The following list sums up the recommendations that were mentioned above:
- only use ILArray<T> to declare local variables
- only use the parameters ILRetArray<T>, ILInArray<T>, ILOutArray<T> inside the head of a function
- use artificial scopes inside the function body to make sure that arrays are available within the scope and released once the scope is left
Next to applying the right type of array depending on the situation, it is also important to know which features of the C# language are not supported by ILNumerics:
- ILNumerics arrays always must be defined explicitely. As a result the C# var keyword can not be used, since it is not compatible with ILNumerics memory management.
- Compound arrays such as +=, -=, *= and /= can not be used when referencing a subarray
To learn more about best practices in ILNumerics, check out the following pages: