Uncommon data conversion with ILArray

ILNumerics Computing Engine supports the most common numeric data types out of the box: double, float, complex, fcomplex, byte, short, int, long, ulong

If you need to convert from, let’s say ushort to float, you will not find any prepared conversion function in ILMath. Luckily, it is very easy to write your own:

Here comes a method which implements the conversion from ushort -> float. A straight forward version first:

        /// <summary>
        /// Convert ushort data to ILArray&lt;float>
        /// </summary>
        /// <param name="A">Input Array</param>
        /// <returns>Array of the same size as A, single precision float elements</returns>
        public static ILRetArray<float> UShort2Single(ILInArray<ushort> A) {
            using (ILScope.Enter(A)) {
                ILArray<float> ret = ILMath.zeros<float>(A.S);
                var retArr = ret.GetArrayForWrite();
                var AArr = A.GetArrayForRead();
                int c = 0;
                foreach (ushort a in A) {
                    retArr[c++] = a;
                }
                return ret;
            }
        }

This method is used like that:

            ushort[,] rawSensorData = new ushort[,] {{0,1,2},{3,4,5}};
            ILArray<float> converted = UShort2Single(rawSensorData);
            /*
             * <Single> [3,2]
             * [0]:          0          3
             * [1]:          1          4
             * [2]:          2          5
             */

            // continue working with 'converted' here...

The following method does the same but utilizes pointer arithmetic, hence it needs the /unsafe flag. Use this, if performance is critical and your data are sufficiently large:

        /// <summary>
        /// Convert ushort data to ILArray&lt;float> (unsafe version)
        /// </summary>
        /// <param name="A">Input Array</param>
        /// <returns>Array of the same size as A, single precision float elements</returns>
        public unsafe static ILRetArray<float> UShort2SingleUnsafe(ILInArray<ushort> A) {
            using (ILScope.Enter(A)) {
                ILArray<float> ret = ILMath.zeros<float>(A.S);
                var retArr = ret.GetArrayForWrite();
                var AArr = A.GetArrayForRead();

                fixed (ushort* pAArr = AArr)
                fixed (float* pRetArr = retArr) {
                    ushort* pInWalk = pAArr;
                    ushort* pInEnd = pAArr + A.S.NumberOfElements;
                    float* pRetWalk = pRetArr;
                    while (pInWalk < pInEnd) {
                        *(pRetWalk++) = /*implicit: (float)*/ (*(pInWalk++));
                    }
                }
                return ret;
            }
        }
  • ILNumerics

    while the statement “no such method in ILMath” is correct, one can utilize a simple assignment from System.Array to any ILArray of the element types listed above. This will trigger very similar things under the hood of the Computing Engine. However, if performance is really important for your large data, consider using the unsafe method above. As always: use a profiler and compare…

  • http://ilnumerics.net haymo

    while the statement “no such method in ILMath” is correct, one can utilize a simple assignment from System.Array to any ILArray of the element types listed above. This will make very similar things under the hood. However, if performance is really important for your large data, consider using the unsafe method above. As always: use a profiler and compare…

  • http://ilnumerics.net haymo

    While the statement ‘there is no method in ILMath’ is correct, another option exists for converting most (all?) numeric datatypes to any datatype supported in ILNumerics: a simple assignment.

    The implicit conversion operator allows to assign System.Array (1 dimensional and multidimensional) to ILArray, where T is any of the types supported and listed above. The conversion will
    basically do similar things as given in this example. However, the Convert class from the .NET framework is used which involved at least another function call for each element. Also, the iteration will be less efficient than the version given here. This may or may not be significant for your application. As always: a profiler is your friend.