Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 

159 строки
3.9 KiB

  1. /* ----------------------------------------------------------------------
  2. * Project: CMSIS DSP Library
  3. * Title: arm_braycurtis_distance_f16.c
  4. * Description: Bray-Curtis distance between two vectors
  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 "dsp/distance_functions_f16.h"
  29. #if defined(ARM_FLOAT16_SUPPORTED)
  30. #include <limits.h>
  31. #include <math.h>
  32. /**
  33. * @ingroup groupDistance
  34. */
  35. /**
  36. * @defgroup FloatDist Float Distances
  37. *
  38. * Distances between two vectors of float values.
  39. */
  40. /**
  41. @ingroup FloatDist
  42. */
  43. /**
  44. @defgroup braycurtis Bray-Curtis distance
  45. Bray-Curtis distance between two vectors
  46. */
  47. /**
  48. @addtogroup braycurtis
  49. @{
  50. */
  51. /**
  52. * @brief Bray-Curtis distance between two vectors
  53. * @param[in] pA First vector
  54. * @param[in] pB Second vector
  55. * @param[in] blockSize vector length
  56. * @return distance
  57. *
  58. */
  59. #if defined(ARM_MATH_MVE_FLOAT16) && !defined(ARM_MATH_AUTOVECTORIZE)
  60. #include "arm_helium_utils.h"
  61. float16_t arm_braycurtis_distance_f16(const float16_t *pA,const float16_t *pB, uint32_t blockSize)
  62. {
  63. _Float16 accumDiff = 0.0f, accumSum = 0.0f;
  64. uint32_t blkCnt;
  65. f16x8_t a, b, c, accumDiffV, accumSumV;
  66. accumDiffV = vdupq_n_f16(0.0f);
  67. accumSumV = vdupq_n_f16(0.0f);
  68. blkCnt = blockSize >> 3;
  69. while (blkCnt > 0) {
  70. a = vld1q(pA);
  71. b = vld1q(pB);
  72. c = vabdq(a, b);
  73. accumDiffV = vaddq(accumDiffV, c);
  74. c = vaddq_f16(a, b);
  75. c = vabsq_f16(c);
  76. accumSumV = vaddq(accumSumV, c);
  77. pA += 8;
  78. pB += 8;
  79. blkCnt--;
  80. }
  81. blkCnt = blockSize & 7;
  82. if (blkCnt > 0U) {
  83. mve_pred16_t p0 = vctp16q(blkCnt);
  84. a = vldrhq_z_f16(pA, p0);
  85. b = vldrhq_z_f16(pB, p0);
  86. c = vabdq(a, b);
  87. accumDiffV = vaddq_m(accumDiffV, accumDiffV, c, p0);
  88. c = vaddq_f16(a, b);
  89. c = vabsq_f16(c);
  90. accumSumV = vaddq_m(accumSumV, accumSumV, c, p0);
  91. }
  92. accumDiff = vecAddAcrossF16Mve(accumDiffV);
  93. accumSum = vecAddAcrossF16Mve(accumSumV);
  94. /*
  95. It is assumed that accumSum is not zero. Since it is the sum of several absolute
  96. values it would imply that all of them are zero. It is very unlikely for long vectors.
  97. */
  98. return (accumDiff / accumSum);
  99. }
  100. #else
  101. float16_t arm_braycurtis_distance_f16(const float16_t *pA,const float16_t *pB, uint32_t blockSize)
  102. {
  103. _Float16 accumDiff=0.0f16, accumSum=0.0f16, tmpA, tmpB;
  104. while(blockSize > 0)
  105. {
  106. tmpA = *pA++;
  107. tmpB = *pB++;
  108. accumDiff += (_Float16)fabsf((float32_t)((_Float16)tmpA - (_Float16)tmpB));
  109. accumSum += (_Float16)fabsf((float32_t)((_Float16)tmpA + (_Float16)tmpB));
  110. blockSize --;
  111. }
  112. /*
  113. It is assumed that accumSum is not zero. Since it is the sum of several absolute
  114. values it would imply that all of them are zero. It is very unlikely for long vectors.
  115. */
  116. return(accumDiff / accumSum);
  117. }
  118. #endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
  119. /**
  120. * @} end of braycurtis group
  121. */
  122. #endif /* #if defined(ARM_FLOAT16_SUPPORTED) */