arm_quick_sort_f32.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /* ----------------------------------------------------------------------
  2. * Project: CMSIS DSP Library
  3. * Title: arm_quick_sort_f32.c
  4. * Description: Floating point quick sort
  5. *
  6. * $Date: 23 April 2021
  7. * $Revision: V1.9.0
  8. *
  9. * Target Processor: Cortex-M and Cortex-A cores
  10. * -------------------------------------------------------------------- */
  11. /*
  12. * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
  13. *
  14. * SPDX-License-Identifier: Apache-2.0
  15. *
  16. * Licensed under the Apache License, Version 2.0 (the License); you may
  17. * not use this file except in compliance with the License.
  18. * You may obtain a copy of the License at
  19. *
  20. * www.apache.org/licenses/LICENSE-2.0
  21. *
  22. * Unless required by applicable law or agreed to in writing, software
  23. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  24. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  25. * See the License for the specific language governing permissions and
  26. * limitations under the License.
  27. */
  28. #include "arm_sorting.h"
  29. static uint32_t arm_quick_sort_partition_f32(float32_t *pSrc, int32_t first, int32_t last, uint8_t dir)
  30. {
  31. /* This function will be called */
  32. int32_t i, j, pivot_index;
  33. float32_t pivot;
  34. float32_t temp;
  35. /* The first element is the pivot */
  36. pivot_index = first;
  37. pivot = pSrc[pivot_index];
  38. /* Initialize indices for do-while loops */
  39. i = first - 1;
  40. j = last + 1;
  41. while(i < j)
  42. {
  43. /* The loop will stop as soon as the indices i and j cross each other.
  44. *
  45. * This event will happen surely since the values of the indices are incremented and
  46. * decrement in the do-while loops that are executed at least once.
  47. * It is impossible to loop forever inside the do-while loops since the pivot is
  48. * always an element of the array and the conditions cannot be always true (at least
  49. * the i-th or the j-th element will be equal to the pivot-th element).
  50. * For example, in the extreme case of an ordered array the do-while loop related to i will stop
  51. * at the first iteration (because pSrc[i]=pSrc[pivot] already), and the loop related to j
  52. * will stop after (last-first) iterations (when j=pivot=i=first). j is returned and
  53. * j+1 is going to be used as pivot by other calls of the function, until j=pivot=last. */
  54. /* Move indices to the right and to the left */
  55. if(dir)
  56. {
  57. /* Compare left elements with pivot */
  58. do
  59. {
  60. i++;
  61. } while (pSrc[i] < pivot && i<last);
  62. /* Compare right elements with pivot */
  63. do
  64. {
  65. j--;
  66. } while (pSrc[j] > pivot);
  67. }
  68. else
  69. {
  70. /* Compare left elements with pivot */
  71. do
  72. {
  73. i++;
  74. } while (pSrc[i] > pivot && i<last);
  75. /* Compare right elements with pivot */
  76. do
  77. {
  78. j--;
  79. } while (pSrc[j] < pivot);
  80. }
  81. /* If the indices didn't cross each other */
  82. if (i < j)
  83. {
  84. /* i and j are in the wrong position -> Swap */
  85. temp=pSrc[i];
  86. pSrc[i]=pSrc[j];
  87. pSrc[j]=temp;
  88. }
  89. }
  90. return j;
  91. }
  92. static void arm_quick_sort_core_f32(float32_t *pSrc, int32_t first, int32_t last, uint8_t dir)
  93. {
  94. /* If the array [first ... last] has more than one element */
  95. if(first<last)
  96. {
  97. int32_t pivot;
  98. /* Compute pivot */
  99. pivot = arm_quick_sort_partition_f32(pSrc, first, last, dir);
  100. /* Iterate algorithm with two sub-arrays [first ... pivot] and [pivot+1 ... last] */
  101. arm_quick_sort_core_f32(pSrc, first, pivot, dir);
  102. arm_quick_sort_core_f32(pSrc, pivot+1, last, dir);
  103. }
  104. }
  105. /**
  106. @ingroup groupSupport
  107. */
  108. /**
  109. @addtogroup Sorting
  110. @{
  111. */
  112. /**
  113. * @private
  114. * @param[in] S points to an instance of the sorting structure.
  115. * @param[in,out] pSrc points to the block of input data.
  116. * @param[out] pDst points to the block of output data.
  117. * @param[in] blockSize number of samples to process.
  118. *
  119. * @par Algorithm
  120. * The quick sort algorithm is a comparison algorithm that
  121. * divides the input array into two smaller sub-arrays and
  122. * recursively sort them. An element of the array (the pivot)
  123. * is chosen, all the elements with values smaller than the
  124. * pivot are moved before the pivot, while all elements with
  125. * values greater than the pivot are moved after it (partition).
  126. *
  127. * @par
  128. * In this implementation the Hoare partition scheme has been
  129. * used [Hoare, C. A. R. (1 January 1962). "Quicksort". The Computer
  130. * Journal. 5 (1): 10...16.] The first element has always been chosen
  131. * as the pivot. The partition algorithm guarantees that the returned
  132. * pivot is never placed outside the vector, since it is returned only
  133. * when the pointers crossed each other. In this way it isn't
  134. * possible to obtain empty partitions and infinite recursion is avoided.
  135. *
  136. * @par
  137. * It's an in-place algorithm. In order to obtain an out-of-place
  138. * function, a memcpy of the source vector is performed.
  139. */
  140. void arm_quick_sort_f32(
  141. const arm_sort_instance_f32 * S,
  142. float32_t * pSrc,
  143. float32_t * pDst,
  144. uint32_t blockSize)
  145. {
  146. float32_t * pA;
  147. /* Out-of-place */
  148. if(pSrc != pDst)
  149. {
  150. memcpy(pDst, pSrc, blockSize*sizeof(float32_t) );
  151. pA = pDst;
  152. }
  153. else
  154. pA = pSrc;
  155. arm_quick_sort_core_f32(pA, 0, blockSize-1, S->dir);
  156. /* The previous function could be called recursively a maximum
  157. * of (blockSize-1) times, generating a stack consumption of 4*(blockSize-1) bytes. */
  158. }
  159. /**
  160. @} end of Sorting group
  161. */