Esempio n. 1
0
        /// <summary>
        /// sort data in A along dimension 'dim'
        /// </summary>
        /// <param name="A">input array: empty, scalar, vector or matrix</param>
        /// <param name="descending">Specifies the direction of sorting</param>
        /// <param name="dim">dimension to sort along</param>
        /// <param name="Indices">output parameter: returns permutation matrix also</param>
        /// <returns>sorted array of the same size as A</returns>
        /// <remarks><para>The data in A will be sorted using the quick sort algorithm. Data
        /// along the dimension <paramref name="dim"/> will therefore get sorted independently from data
        /// in the next row/column.</para>
        /// <para>This overload also returns an array 'Indices' which will hold the indices into the original
        /// elements <b>after sorting</b>. Elements of 'Indices' are of type double.</para>
        ///</remarks>
        public static ILArray <string> sort(ILArray <string> A, out ILArray <double> Indices, int dim, bool descending)
        {
            if (object.Equals(A, null))
            {
                throw new Exception("sort: parameter A must not be null");
            }
            if (A.Dimensions.NumberOfDimensions > 2)
            {
                throw new ILArgumentException("sort: for element type string only matrices are supported!");
            }
            if (dim < 0 || dim >= A.Dimensions.NumberOfDimensions)
            {
                throw new ILArgumentException("sort: invalid dimension argument");
            }
            // early exit: scalar/ empty
            if (A.IsEmpty || A.IsScalar)
            {
                Indices = 0.0;
                return(A.C);
            }
            ILArray <string> ret = new ILArray <string>(new string[A.Dimensions.NumberOfElements], A.Dimensions);
            int dim1             = dim % A.Dimensions.NumberOfDimensions;
            int dim2             = (dim1 + 1) % A.Dimensions.NumberOfDimensions;
            int maxRuns          = A.Dimensions[dim2];
            ILQueueList <string, double> ql;

            ILArray <int>[]  ind  = new ILArray <int> [2];
            int []           indI = new int[2];
            ILASCIIKeyMapper km   = new ILASCIIKeyMapper();

            Indices = ILMath.counter(0.0, 1.0, A.Dimensions.ToIntArray());
            for (int c = 0; c < maxRuns; c++)
            {
                ind[dim2]  = c;
                ind[dim1]  = null;
                ql         = ILBucketSort.BucketSort <string, char, double>(A[ind].Values, Indices[ind].Values, km, ILBucketSort.SortMethod.ConstantLength);
                indI[dim2] = c;
                if (descending)
                {
                    for (int i = ql.Count; i-- > 0;)
                    {
                        indI[dim1] = i;
                        ILListItem <string, double> item = ql.Dequeue();
                        ret.SetValue(item.Data, indI);
                        Indices.SetValue(item.m_index, indI);
                    }
                }
                else
                {
                    for (int i = 0; ql.Count > 0; i++)
                    {
                        indI[dim1] = i;
                        ILListItem <string, double> item = ql.Dequeue();
                        ret.SetValue(item.Data, indI);
                        Indices.SetValue(item.m_index, indI);
                    }
                }
            }
            return(ret);
        }
Esempio n. 2
0
        bucketSort_constantLength <ElementType, SubelementType, IndexType>(
            IEnumerable <ElementType> input,
            IEnumerable <IndexType> indices,
            ILKeyMapper <ElementType, SubelementType> mapper)
        {
            int m   = mapper.NumberOfKeys;
            int tmp = 0;

            ILQueueList <ElementType, IndexType>[] buckets = new ILQueueList <ElementType, IndexType> [m];
            ILQueueList <ElementType, IndexType>   Q       = new ILQueueList <ElementType, IndexType>();
            // find longest element
            int maxLen = 0;

            foreach (ElementType elem in input)
            {
                tmp = mapper.SubelementsCount(elem);
                if (tmp > maxLen)
                {
                    maxLen = tmp;
                }
            }
            // sort into buckets
            IEnumerator <IndexType> indIt = indices.GetEnumerator();

            indIt.MoveNext();
            for (int k = maxLen; k-- > 0;)
            {
                // walk along the input
                if (k == maxLen - 1)
                {
                    foreach (ElementType elem in input)
                    {
                        // put current into bucket
                        int bpos = mapper.Map(elem, k, 0);
                        if (buckets[bpos] == null)
                        {
                            // must create list first
                            buckets[bpos] = new ILQueueList <ElementType, IndexType>();
                        }
                        // append to list
                        buckets[bpos].Enqueue(elem, indIt.Current);
                        indIt.MoveNext();
                    }
                }
                else
                {
                    while (Q.Count > 0)
                    {
                        // put current into bucket
                        ILListItem <ElementType, IndexType> elem = Q.Dequeue();
                        int bpos = mapper.Map(elem.Data, k, 0);
                        if (buckets[bpos] == null)
                        {
                            // must create list first
                            buckets[bpos] = new ILQueueList <ElementType, IndexType>();
                        }
                        // append to list
                        buckets[bpos].Enqueue(elem);
                    }
                }
                // concatenate all buckets
                for (int i = 0; i < buckets.Length; i++)
                {
                    if (buckets[i] != null && buckets[i].Count > 0)
                    {
                        Q.Enqueue(buckets[i]);
                        buckets[i].Clear();
                    }
                }
                // goto previous position in strings
            }
            return(Q);
        }
Esempio n. 3
0
        /// <summary>
        /// generic sort algorithm in A along dimension 'dim'
        /// </summary>
        /// <param name="A">input array: empty, scalar, vector or matrix</param>
        /// <param name="descending">Specifies the direction of sorting</param>
        /// <param name="dim">dimension to sort along</param>
        /// <param name="Indices">input/output parameter: the values in Indices will be returned in the same sorted order as the elements in A. This can be used to derive a permutation matrix of the sorting process.</param>
        /// <param name="keymapper">Instancce of an object of type ILKeyMapper. This object must
        /// be derived ILKeyMapper&lt;T,SubelementType&gt; and match the generic argument <typeparamref name="T"/>. It will be
        /// used to split single elements into its subelements and map their content into bucket numbers. For all
        /// reference types except those of type string you will have to write your own ILKeyMapper class for that purpose.</param>
        /// <returns>sorted array of the same size as A</returns>
        /// <remarks><para>The data in A will be sorted using the quick sort algorithm. Data
        /// along the dimension <paramref name="dim"/> will therefore get sorted independently from data
        /// in the next row/column.</para>
        /// <para>This overload also returns an array 'Indices' which will hold the indices into the original
        /// elements <b>after sorting</b>. Elements of 'Indices' are always of type int.</para>
        /// <para>This generic version is able to sort arbitrary element types. Even user defined reference types can be sorted
        /// by specifying a user defined ILKeyMapper class instance. Also the type of Indices may be arbitrarily choosen. In difference
        /// to the regular sort function overload, Indices must manually given to the function on the beginning. The given array's
        /// elements will than be sorted in the same order as the input array A and returned.</para>
        /// <para>By using this overload you may use the same permutation matrix several times to reflect the
        /// manipulations done to A due multiple sort processes. The Indices given will directly get used for the current sorting
        /// without looking at their initial order.</para>
        /// </remarks>
        public static ILArray <T> sort <T, S, I> (ILArray <T> A, ref ILArray <I> Indices, int dim, bool descending, ILKeyMapper <T, S> keymapper)
        {
            if (object.Equals(A, null))
            {
                throw new Exception("sort: parameter A must not be null");
            }
            if (A.Dimensions.NumberOfDimensions > 2)
            {
                throw new ILArgumentException("sort: for generic element type - only matrices are supported!");
            }
            if (dim < 0 || dim >= A.Dimensions.NumberOfDimensions)
            {
                throw new ILArgumentException("sort: invalid dimension argument");
            }
            if (keymapper == null)
            {
                throw new ILArgumentException("sort: the keymapper argument must not be null");
            }
            if (object.Equals(Indices, null) || !Indices.Dimensions.IsSameSize(A.Dimensions))
            {
                throw new ILArgumentException("sort: Indices argument must have same size/shape as input A");
            }
            // early exit: scalar/ empty
            if (A.IsEmpty || A.IsScalar)
            {
                Indices = default(I);
                return(A.C);
            }
            ILArray <T>        ret     = new ILArray <T>(new T[A.Dimensions.NumberOfElements], A.Dimensions);
            int                dim1    = dim % A.Dimensions.NumberOfDimensions;
            int                dim2    = (dim1 + 1) % A.Dimensions.NumberOfDimensions;
            int                maxRuns = A.Dimensions[dim2];
            ILQueueList <T, I> ql;

            ILArray <int>[] ind  = new ILArray <int> [2];
            int []          indI = new int[2];
            for (int c = 0; c < maxRuns; c++)
            {
                ind[dim2]  = c;
                ind[dim1]  = null;
                ql         = ILBucketSort.BucketSort <T, S, I>(A[ind].Values, Indices[ind].Values, keymapper, ILBucketSort.SortMethod.ConstantLength);
                indI[dim2] = c;
                if (descending)
                {
                    for (int i = ql.Count; i-- > 0;)
                    {
                        indI[dim1] = i;
                        ILListItem <T, I> item = ql.Dequeue();
                        ret.SetValue(item.Data, indI);
                        Indices.SetValue(item.m_index, indI);
                    }
                }
                else
                {
                    for (int i = 0; ql.Count > 0; i++)
                    {
                        indI[dim1] = i;
                        ILListItem <T, I> item = ql.Dequeue();
                        ret.SetValue(item.Data, indI);
                        Indices.SetValue(item.m_index, indI);
                    }
                }
            }
            return(ret);
        }