protected virtual void _ArgMerge(ArgSortData[] input, npy_intp left, npy_intp middle, npy_intp right)
        {
            var leftArray  = new ArgSortData[middle - left + 1];
            var rightArray = new ArgSortData[right - middle];

            Array.Copy(input, left, leftArray, 0, middle - left + 1);
            Array.Copy(input, middle + 1, rightArray, 0, right - middle);

            int i = 0;
            int j = 0;

            for (npy_intp k = left; k < right + 1; k++)
            {
                if (i == leftArray.Length)
                {
                    input[k] = rightArray[j];
                    j++;
                }
                else if (j == rightArray.Length)
                {
                    input[k] = leftArray[i];
                    i++;
                }
                else if (CompareTo(leftArray[i].dvalue, rightArray[j].dvalue) <= 0)
                {
                    input[k] = leftArray[i];
                    i++;
                }
                else
                {
                    input[k] = rightArray[j];
                    j++;
                }
            }
        }
        private void argMergeSortIndexes(VoidPtr ip, npy_intp m, VoidPtr sortData, npy_intp startingIndex, int DivSize, int IntpDivSize)
        {
            T[] data = sortData.datap as T[];

            var argSortData = new ArgSortData[m];

            var adjustedIndex = startingIndex + (sortData.data_offset >> DivSize);

            for (npy_intp i = 0; i < m; i++)
            {
                argSortData[i].index  = i;
                argSortData[i].dvalue = data[adjustedIndex++];
            }

            ArgMergeSort(argSortData, 0, m - 1);

            npy_intp[] _ip = (npy_intp[])ip.datap;

            npy_intp data_offset = ip.data_offset >> IntpDivSize;

            for (int i = 0; i < m; i++)
            {
                _ip[data_offset++] = argSortData[i].index - startingIndex;
            }
        }