CMSIS-DSP: Added f16 versions of the distance functions
parent
b8c9c080d7
commit
f51b3c3317
@ -0,0 +1,36 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: DistanceFunctions.c
|
||||
* Description: Combination of all distance function f16 source files.
|
||||
*
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2020 ARM Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "arm_braycurtis_distance_f16.c"
|
||||
#include "arm_canberra_distance_f16.c"
|
||||
#include "arm_chebyshev_distance_f16.c"
|
||||
#include "arm_cityblock_distance_f16.c"
|
||||
#include "arm_correlation_distance_f16.c"
|
||||
#include "arm_cosine_distance_f16.c"
|
||||
#include "arm_euclidean_distance_f16.c"
|
||||
#include "arm_jensenshannon_distance_f16.c"
|
||||
#include "arm_minkowski_distance_f16.c"
|
||||
|
||||
@ -0,0 +1,141 @@
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_braycurtis_distance_f16.c
|
||||
* Description: Bray-Curtis distance between two vectors
|
||||
*
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2020 ARM Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "dsp/distance_functions_f16.h"
|
||||
|
||||
#if defined(ARM_FLOAT16_SUPPORTED)
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@addtogroup FloatDist
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Bray-Curtis distance between two vectors
|
||||
* @param[in] pA First vector
|
||||
* @param[in] pB Second vector
|
||||
* @param[in] blockSize vector length
|
||||
* @return distance
|
||||
*
|
||||
*/
|
||||
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
|
||||
|
||||
#include "arm_helium_utils.h"
|
||||
|
||||
float16_t arm_braycurtis_distance_f16(const float16_t *pA,const float16_t *pB, uint32_t blockSize)
|
||||
{
|
||||
float16_t accumDiff = 0.0f, accumSum = 0.0f;
|
||||
uint32_t blkCnt;
|
||||
f16x8_t a, b, c, accumDiffV, accumSumV;
|
||||
|
||||
|
||||
accumDiffV = vdupq_n_f16(0.0f);
|
||||
accumSumV = vdupq_n_f16(0.0f);
|
||||
|
||||
blkCnt = blockSize >> 3;
|
||||
while (blkCnt > 0) {
|
||||
a = vld1q(pA);
|
||||
b = vld1q(pB);
|
||||
|
||||
c = vabdq(a, b);
|
||||
accumDiffV = vaddq(accumDiffV, c);
|
||||
|
||||
c = vaddq_f16(a, b);
|
||||
c = vabsq_f16(c);
|
||||
accumSumV = vaddq(accumSumV, c);
|
||||
|
||||
pA += 8;
|
||||
pB += 8;
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
blkCnt = blockSize & 7;
|
||||
if (blkCnt > 0U) {
|
||||
mve_pred16_t p0 = vctp16q(blkCnt);
|
||||
|
||||
a = vldrhq_z_f16(pA, p0);
|
||||
b = vldrhq_z_f16(pB, p0);
|
||||
|
||||
c = vabdq(a, b);
|
||||
accumDiffV = vaddq_m(accumDiffV, accumDiffV, c, p0);
|
||||
|
||||
c = vaddq_f16(a, b);
|
||||
c = vabsq_f16(c);
|
||||
accumSumV = vaddq_m(accumSumV, accumSumV, c, p0);
|
||||
}
|
||||
|
||||
accumDiff = vecAddAcrossF16Mve(accumDiffV);
|
||||
accumSum = vecAddAcrossF16Mve(accumSumV);
|
||||
|
||||
/*
|
||||
It is assumed that accumSum is not zero. Since it is the sum of several absolute
|
||||
values it would imply that all of them are zero. It is very unlikely for long vectors.
|
||||
*/
|
||||
return (accumDiff / accumSum);
|
||||
}
|
||||
#else
|
||||
|
||||
float16_t arm_braycurtis_distance_f16(const float16_t *pA,const float16_t *pB, uint32_t blockSize)
|
||||
{
|
||||
float16_t accumDiff=0.0f, accumSum=0.0f, tmpA, tmpB;
|
||||
|
||||
while(blockSize > 0)
|
||||
{
|
||||
tmpA = *pA++;
|
||||
tmpB = *pB++;
|
||||
accumDiff += fabsf(tmpA - tmpB);
|
||||
accumSum += fabsf(tmpA + tmpB);
|
||||
blockSize --;
|
||||
}
|
||||
/*
|
||||
|
||||
It is assumed that accumSum is not zero. Since it is the sum of several absolute
|
||||
values it would imply that all of them are zero. It is very unlikely for long vectors.
|
||||
|
||||
*/
|
||||
return(accumDiff / accumSum);
|
||||
}
|
||||
#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
|
||||
|
||||
|
||||
/**
|
||||
* @} end of FloatDist group
|
||||
*/
|
||||
|
||||
/**
|
||||
* @} end of groupDistance group
|
||||
*/
|
||||
|
||||
#endif /* #if defined(ARM_FLOAT16_SUPPORTED) */
|
||||
|
||||
@ -0,0 +1,159 @@
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_canberra_distance_f16.c
|
||||
* Description: Canberra distance between two vectors
|
||||
*
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2020 ARM Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "dsp/distance_functions_f16.h"
|
||||
|
||||
#if defined(ARM_FLOAT16_SUPPORTED)
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
/**
|
||||
@addtogroup FloatDist
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Canberra distance between two vectors
|
||||
*
|
||||
* This function may divide by zero when samples pA[i] and pB[i] are both zero.
|
||||
* The result of the computation will be correct. So the division per zero may be
|
||||
* ignored.
|
||||
*
|
||||
* @param[in] pA First vector
|
||||
* @param[in] pB Second vector
|
||||
* @param[in] blockSize vector length
|
||||
* @return distance
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
|
||||
|
||||
#include "arm_helium_utils.h"
|
||||
#include "arm_vec_math_f16.h"
|
||||
|
||||
float16_t arm_canberra_distance_f16(const float16_t *pA,const float16_t *pB, uint32_t blockSize)
|
||||
{
|
||||
float16_t accum = 0.0f;
|
||||
uint32_t blkCnt;
|
||||
f16x8_t a, b, c, accumV;
|
||||
|
||||
accumV = vdupq_n_f16(0.0f);
|
||||
|
||||
blkCnt = blockSize >> 3;
|
||||
while (blkCnt > 0) {
|
||||
a = vld1q(pA);
|
||||
b = vld1q(pB);
|
||||
|
||||
c = vabdq(a, b);
|
||||
|
||||
a = vabsq(a);
|
||||
b = vabsq(b);
|
||||
a = vaddq(a, b);
|
||||
|
||||
/*
|
||||
* May divide by zero when a and b have both the same lane at zero.
|
||||
*/
|
||||
a = vrecip_hiprec_f16(a);
|
||||
|
||||
/*
|
||||
* Force result of a division by 0 to 0. It the behavior of the
|
||||
* sklearn canberra function.
|
||||
*/
|
||||
a = vdupq_m_n_f16(a, 0.0f, vcmpeqq(a, 0.0f));
|
||||
c = vmulq(c, a);
|
||||
accumV = vaddq(accumV, c);
|
||||
|
||||
pA += 8;
|
||||
pB += 8;
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
blkCnt = blockSize & 7;
|
||||
if (blkCnt > 0U) {
|
||||
mve_pred16_t p0 = vctp16q(blkCnt);
|
||||
|
||||
a = vldrhq_z_f16(pA, p0);
|
||||
b = vldrhq_z_f16(pB, p0);
|
||||
|
||||
c = vabdq(a, b);
|
||||
|
||||
a = vabsq(a);
|
||||
b = vabsq(b);
|
||||
a = vaddq(a, b);
|
||||
|
||||
/*
|
||||
* May divide by zero when a and b have both the same lane at zero.
|
||||
*/
|
||||
a = vrecip_hiprec_f16(a);
|
||||
|
||||
/*
|
||||
* Force result of a division by 0 to 0. It the behavior of the
|
||||
* sklearn canberra function.
|
||||
*/
|
||||
a = vdupq_m_n_f16(a, 0.0f, vcmpeqq(a, 0.0f));
|
||||
c = vmulq(c, a);
|
||||
accumV = vaddq_m(accumV, accumV, c, p0);
|
||||
}
|
||||
|
||||
accum = vecAddAcrossF16Mve(accumV);
|
||||
|
||||
return (accum);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
float16_t arm_canberra_distance_f16(const float16_t *pA,const float16_t *pB, uint32_t blockSize)
|
||||
{
|
||||
float16_t accum=0.0f, tmpA, tmpB,diff,sum;
|
||||
|
||||
while(blockSize > 0)
|
||||
{
|
||||
tmpA = *pA++;
|
||||
tmpB = *pB++;
|
||||
|
||||
diff = fabsf(tmpA - tmpB);
|
||||
sum = fabsf(tmpA) + fabsf(tmpB);
|
||||
if ((tmpA != 0.0f) || (tmpB != 0.0f))
|
||||
{
|
||||
accum += (diff / sum);
|
||||
}
|
||||
blockSize --;
|
||||
}
|
||||
return(accum);
|
||||
}
|
||||
#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
|
||||
|
||||
|
||||
/**
|
||||
* @} end of FloatDist group
|
||||
*/
|
||||
|
||||
#endif /* #if defined(ARM_FLOAT16_SUPPORTED) */
|
||||
|
||||
@ -0,0 +1,135 @@
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_chebyshev_distance_f16.c
|
||||
* Description: Chebyshev distance between two vectors
|
||||
*
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2020 ARM Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "dsp/distance_functions_f16.h"
|
||||
|
||||
#if defined(ARM_FLOAT16_SUPPORTED)
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
/**
|
||||
@addtogroup FloatDist
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Chebyshev distance between two vectors
|
||||
* @param[in] pA First vector
|
||||
* @param[in] pB Second vector
|
||||
* @param[in] blockSize vector length
|
||||
* @return distance
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
|
||||
|
||||
#include "arm_helium_utils.h"
|
||||
#include "arm_vec_math.h"
|
||||
|
||||
float16_t arm_chebyshev_distance_f16(const float16_t *pA,const float16_t *pB, uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt; /* loop counters */
|
||||
f16x8_t vecA, vecB;
|
||||
f16x8_t vecDiff = vdupq_n_f16(0.0);
|
||||
float16_t maxValue = 0.0;
|
||||
|
||||
|
||||
blkCnt = blockSize >> 3;
|
||||
while (blkCnt > 0U) {
|
||||
vecA = vld1q(pA);
|
||||
pA += 8;
|
||||
vecB = vld1q(pB);
|
||||
pB += 8;
|
||||
/*
|
||||
* update per-lane max.
|
||||
*/
|
||||
vecDiff = vmaxnmaq(vsubq(vecA, vecB), vecDiff);
|
||||
/*
|
||||
* Decrement the blockSize loop counter
|
||||
*/
|
||||
blkCnt--;
|
||||
}
|
||||
/*
|
||||
* tail
|
||||
* (will be merged thru tail predication)
|
||||
*/
|
||||
blkCnt = blockSize & 7;
|
||||
if (blkCnt > 0U) {
|
||||
mve_pred16_t p0 = vctp16q(blkCnt);
|
||||
|
||||
vecA = vldrhq_z_f16(pA, p0);
|
||||
vecB = vldrhq_z_f16(pB, p0);
|
||||
|
||||
/*
|
||||
* Get current max per lane and current index per lane
|
||||
* when a max is selected
|
||||
*/
|
||||
vecDiff = vmaxnmaq_m(vecDiff, vsubq(vecA, vecB), p0);
|
||||
}
|
||||
/*
|
||||
* Get max value across the vector
|
||||
*/
|
||||
return vmaxnmavq(maxValue, vecDiff);
|
||||
}
|
||||
|
||||
#else
|
||||
float16_t arm_chebyshev_distance_f16(const float16_t *pA,const float16_t *pB, uint32_t blockSize)
|
||||
{
|
||||
float16_t diff=0.0f, maxVal,tmpA, tmpB;
|
||||
|
||||
tmpA = *pA++;
|
||||
tmpB = *pB++;
|
||||
diff = fabsf(tmpA - tmpB);
|
||||
maxVal = diff;
|
||||
blockSize--;
|
||||
|
||||
while(blockSize > 0)
|
||||
{
|
||||
tmpA = *pA++;
|
||||
tmpB = *pB++;
|
||||
diff = fabsf(tmpA - tmpB);
|
||||
if (diff > maxVal)
|
||||
{
|
||||
maxVal = diff;
|
||||
}
|
||||
blockSize --;
|
||||
}
|
||||
|
||||
return(maxVal);
|
||||
}
|
||||
#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
|
||||
|
||||
|
||||
/**
|
||||
* @} end of FloatDist group
|
||||
*/
|
||||
|
||||
#endif /* #if defined(ARM_FLOAT16_SUPPORTED) */
|
||||
|
||||
@ -0,0 +1,116 @@
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cityblock_distance_f16.c
|
||||
* Description: Cityblock (Manhattan) distance between two vectors
|
||||
*
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2020 ARM Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "dsp/distance_functions_f16.h"
|
||||
|
||||
#if defined(ARM_FLOAT16_SUPPORTED)
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
@addtogroup FloatDist
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Cityblock (Manhattan) distance between two vectors
|
||||
* @param[in] pA First vector
|
||||
* @param[in] pB Second vector
|
||||
* @param[in] blockSize vector length
|
||||
* @return distance
|
||||
*
|
||||
*/
|
||||
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
|
||||
|
||||
#include "arm_helium_utils.h"
|
||||
#include "arm_vec_math.h"
|
||||
|
||||
float16_t arm_cityblock_distance_f16(const float16_t *pA,const float16_t *pB, uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt;
|
||||
f16x8_t a, b, accumV, tempV;
|
||||
|
||||
accumV = vdupq_n_f16(0.0f);
|
||||
|
||||
blkCnt = blockSize >> 3;
|
||||
while (blkCnt > 0U) {
|
||||
a = vld1q(pA);
|
||||
b = vld1q(pB);
|
||||
|
||||
tempV = vabdq(a, b);
|
||||
accumV = vaddq(accumV, tempV);
|
||||
|
||||
pA += 8;
|
||||
pB += 8;
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/*
|
||||
* tail
|
||||
* (will be merged thru tail predication)
|
||||
*/
|
||||
blkCnt = blockSize & 7;
|
||||
if (blkCnt > 0U) {
|
||||
mve_pred16_t p0 = vctp16q(blkCnt);
|
||||
|
||||
a = vldrhq_z_f16(pA, p0);
|
||||
b = vldrhq_z_f16(pB, p0);
|
||||
|
||||
tempV = vabdq(a, b);
|
||||
accumV = vaddq_m(accumV, accumV, tempV, p0);
|
||||
}
|
||||
|
||||
return vecAddAcrossF16Mve(accumV);
|
||||
}
|
||||
|
||||
#else
|
||||
float16_t arm_cityblock_distance_f16(const float16_t *pA,const float16_t *pB, uint32_t blockSize)
|
||||
{
|
||||
float16_t accum,tmpA, tmpB;
|
||||
|
||||
accum = 0.0f;
|
||||
while(blockSize > 0)
|
||||
{
|
||||
tmpA = *pA++;
|
||||
tmpB = *pB++;
|
||||
accum += fabsf(tmpA - tmpB);
|
||||
|
||||
blockSize --;
|
||||
}
|
||||
|
||||
return(accum);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @} end of FloatDist group
|
||||
*/
|
||||
|
||||
#endif /* #if defined(ARM_FLOAT16_SUPPORTED) */
|
||||
|
||||
@ -0,0 +1,88 @@
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_correlation_distance_f16.c
|
||||
* Description: Correlation distance between two vectors
|
||||
*
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2020 ARM Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "dsp/distance_functions_f16.h"
|
||||
|
||||
#if defined(ARM_FLOAT16_SUPPORTED)
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@addtogroup FloatDist
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Correlation distance between two vectors
|
||||
*
|
||||
* The input vectors are modified in place !
|
||||
*
|
||||
* @param[in] pA First vector
|
||||
* @param[in] pB Second vector
|
||||
* @param[in] blockSize vector length
|
||||
* @return distance
|
||||
*
|
||||
*/
|
||||
|
||||
float16_t arm_correlation_distance_f16(float16_t *pA,float16_t *pB, uint32_t blockSize)
|
||||
{
|
||||
float16_t ma,mb,pwra,pwrb,dot,tmp;
|
||||
|
||||
arm_mean_f16(pA, blockSize, &ma);
|
||||
arm_mean_f16(pB, blockSize, &mb);
|
||||
|
||||
arm_offset_f16(pA, -ma, pA, blockSize);
|
||||
arm_offset_f16(pB, -mb, pB, blockSize);
|
||||
|
||||
arm_power_f16(pA, blockSize, &pwra);
|
||||
arm_power_f16(pB, blockSize, &pwrb);
|
||||
|
||||
arm_dot_prod_f16(pA,pB,blockSize,&dot);
|
||||
|
||||
dot = dot / blockSize;
|
||||
pwra = pwra / blockSize;
|
||||
pwrb = pwrb / blockSize;
|
||||
|
||||
arm_sqrt_f16(pwra * pwrb,&tmp);
|
||||
|
||||
return(1.0f - dot / tmp);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @} end of FloatDist group
|
||||
*/
|
||||
|
||||
#endif /* #if defined(ARM_FLOAT16_SUPPORTED) */
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_cosine_distance_f16.c
|
||||
* Description: Cosine distance between two vectors
|
||||
*
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2020 ARM Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "dsp/distance_functions_f16.h"
|
||||
|
||||
#if defined(ARM_FLOAT16_SUPPORTED)
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
/**
|
||||
@addtogroup FloatDist
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Cosine distance between two vectors
|
||||
*
|
||||
* @param[in] pA First vector
|
||||
* @param[in] pB Second vector
|
||||
* @param[in] blockSize vector length
|
||||
* @return distance
|
||||
*
|
||||
*/
|
||||
|
||||
float16_t arm_cosine_distance_f16(const float16_t *pA,const float16_t *pB, uint32_t blockSize)
|
||||
{
|
||||
float16_t pwra,pwrb,dot,tmp;
|
||||
|
||||
arm_power_f16(pA, blockSize, &pwra);
|
||||
arm_power_f16(pB, blockSize, &pwrb);
|
||||
|
||||
arm_dot_prod_f16(pA,pB,blockSize,&dot);
|
||||
|
||||
arm_sqrt_f16(pwra * pwrb, &tmp);
|
||||
return(1.0f - dot / tmp);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @} end of FloatDist group
|
||||
*/
|
||||
|
||||
#endif /* #if defined(ARM_FLOAT16_SUPPORTED) */
|
||||
|
||||
@ -0,0 +1,118 @@
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_euclidean_distance_f16.c
|
||||
* Description: Euclidean distance between two vectors
|
||||
*
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2020 ARM Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "dsp/distance_functions_f16.h"
|
||||
|
||||
#if defined(ARM_FLOAT16_SUPPORTED)
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@addtogroup FloatDist
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Euclidean distance between two vectors
|
||||
* @param[in] pA First vector
|
||||
* @param[in] pB Second vector
|
||||
* @param[in] blockSize vector length
|
||||
* @return distance
|
||||
*
|
||||
*/
|
||||
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
|
||||
|
||||
#include "arm_helium_utils.h"
|
||||
#include "arm_vec_math.h"
|
||||
float16_t arm_euclidean_distance_f16(const float16_t *pA,const float16_t *pB, uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt;
|
||||
float16_t tmp;
|
||||
f16x8_t a, b, accumV, tempV;
|
||||
|
||||
accumV = vdupq_n_f16(0.0f);
|
||||
|
||||
blkCnt = blockSize >> 3;
|
||||
while (blkCnt > 0U) {
|
||||
a = vld1q(pA);
|
||||
b = vld1q(pB);
|
||||
|
||||
tempV = vsubq(a, b);
|
||||
accumV = vfmaq(accumV, tempV, tempV);
|
||||
|
||||
pA += 8;
|
||||
pB += 8;
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/*
|
||||
* tail
|
||||
* (will be merged thru tail predication)
|
||||
*/
|
||||
blkCnt = blockSize & 7;
|
||||
if (blkCnt > 0U) {
|
||||
mve_pred16_t p0 = vctp16q(blkCnt);
|
||||
|
||||
a = vldrhq_z_f16(pA, p0);
|
||||
b = vldrhq_z_f16(pB, p0);
|
||||
|
||||
tempV = vsubq(a, b);
|
||||
accumV = vfmaq_m(accumV, tempV, tempV, p0);
|
||||
}
|
||||
|
||||
arm_sqrt_f16(vecAddAcrossF16Mve(accumV), &tmp);
|
||||
return (tmp);
|
||||
}
|
||||
|
||||
#else
|
||||
float16_t arm_euclidean_distance_f16(const float16_t *pA,const float16_t *pB, uint32_t blockSize)
|
||||
{
|
||||
float16_t accum=0.0f,tmp;
|
||||
|
||||
while(blockSize > 0)
|
||||
{
|
||||
tmp = *pA++ - *pB++;
|
||||
accum += SQ(tmp);
|
||||
blockSize --;
|
||||
}
|
||||
arm_sqrt_f16(accum,&tmp);
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
|
||||
|
||||
|
||||
/**
|
||||
* @} end of FloatDist group
|
||||
*/
|
||||
|
||||
#endif /* #if defined(ARM_FLOAT16_SUPPORTED) */
|
||||
|
||||
@ -0,0 +1,164 @@
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_jensenshannon_distance_f16.c
|
||||
* Description: Jensen-Shannon distance between two vectors
|
||||
*
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2020 ARM Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "dsp/distance_functions_f16.h"
|
||||
|
||||
#if defined(ARM_FLOAT16_SUPPORTED)
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
/**
|
||||
@addtogroup FloatDist
|
||||
@{
|
||||
*/
|
||||
|
||||
#if !defined(ARM_MATH_MVEF) || defined(ARM_MATH_AUTOVECTORIZE)
|
||||
/// @private
|
||||
__STATIC_INLINE float16_t rel_entr(float16_t x, float16_t y)
|
||||
{
|
||||
return (x * logf(x / y));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
|
||||
|
||||
#include "arm_helium_utils.h"
|
||||
#include "arm_vec_math_f16.h"
|
||||
|
||||
float16_t arm_jensenshannon_distance_f16(const float16_t *pA,const float16_t *pB, uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt;
|
||||
float16_t tmp;
|
||||
f16x8_t a, b, t, tmpV, accumV;
|
||||
|
||||
accumV = vdupq_n_f16(0.0f);
|
||||
|
||||
blkCnt = blockSize >> 3;
|
||||
while (blkCnt > 0U) {
|
||||
a = vld1q(pA);
|
||||
b = vld1q(pB);
|
||||
|
||||
t = vaddq(a, b);
|
||||
t = vmulq(t, 0.5f);
|
||||
|
||||
tmpV = vmulq(a, vrecip_medprec_f16(t));
|
||||
tmpV = vlogq_f16(tmpV);
|
||||
accumV = vfmaq(accumV, a, tmpV);
|
||||
|
||||
tmpV = vmulq_f16(b, vrecip_medprec_f16(t));
|
||||
tmpV = vlogq_f16(tmpV);
|
||||
accumV = vfmaq(accumV, b, tmpV);
|
||||
|
||||
pA += 8;
|
||||
pB += 8;
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/*
|
||||
* tail
|
||||
* (will be merged thru tail predication)
|
||||
*/
|
||||
blkCnt = blockSize & 7;
|
||||
if (blkCnt > 0U) {
|
||||
mve_pred16_t p0 = vctp16q(blkCnt);
|
||||
|
||||
a = vldrhq_z_f16(pA, p0);
|
||||
b = vldrhq_z_f16(pB, p0);
|
||||
|
||||
t = vaddq(a, b);
|
||||
t = vmulq(t, 0.5f);
|
||||
|
||||
tmpV = vmulq_f16(a, vrecip_medprec_f16(t));
|
||||
tmpV = vlogq_f16(tmpV);
|
||||
accumV = vfmaq_m_f16(accumV, a, tmpV, p0);
|
||||
|
||||
tmpV = vmulq_f16(b, vrecip_medprec_f16(t));
|
||||
tmpV = vlogq_f16(tmpV);
|
||||
accumV = vfmaq_m_f16(accumV, b, tmpV, p0);
|
||||
|
||||
}
|
||||
|
||||
arm_sqrt_f16(vecAddAcrossF16Mve(accumV) / 2.0f, &tmp);
|
||||
return (tmp);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
/**
|
||||
* @brief Jensen-Shannon distance between two vectors
|
||||
*
|
||||
* This function is assuming that elements of second vector are > 0
|
||||
* and 0 only when the corresponding element of first vector is 0.
|
||||
* Otherwise the result of the computation does not make sense
|
||||
* and for speed reasons, the cases returning NaN or Infinity are not
|
||||
* managed.
|
||||
*
|
||||
* When the function is computing x log (x / y) with x == 0 and y == 0,
|
||||
* it will compute the right result (0) but a division by zero will occur
|
||||
* and should be ignored in client code.
|
||||
*
|
||||
* @param[in] pA First vector
|
||||
* @param[in] pB Second vector
|
||||
* @param[in] blockSize vector length
|
||||
* @return distance
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
float16_t arm_jensenshannon_distance_f16(const float16_t *pA,const float16_t *pB, uint32_t blockSize)
|
||||
{
|
||||
float16_t left, right,sum, result, tmp;
|
||||
uint32_t i;
|
||||
|
||||
left = 0.0f;
|
||||
right = 0.0f;
|
||||
for(i=0; i < blockSize; i++)
|
||||
{
|
||||
tmp = (pA[i] + pB[i]) / 2.0f;
|
||||
left += rel_entr(pA[i], tmp);
|
||||
right += rel_entr(pB[i], tmp);
|
||||
}
|
||||
|
||||
|
||||
sum = left + right;
|
||||
arm_sqrt_f16(sum/2.0f, &result);
|
||||
return(result);
|
||||
|
||||
}
|
||||
|
||||
#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
|
||||
|
||||
/**
|
||||
* @} end of FloatDist group
|
||||
*/
|
||||
|
||||
#endif /* #if defined(ARM_FLOAT16_SUPPORTED) */
|
||||
|
||||
@ -0,0 +1,127 @@
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_minkowski_distance_f16.c
|
||||
* Description: Minkowski distance between two vectors
|
||||
*
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2020 ARM Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "dsp/distance_functions_f16.h"
|
||||
|
||||
#if defined(ARM_FLOAT16_SUPPORTED)
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
/**
|
||||
@addtogroup FloatDist
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Minkowski distance between two vectors
|
||||
*
|
||||
* @param[in] pA First vector
|
||||
* @param[in] pB Second vector
|
||||
* @param[in] order Distance order
|
||||
* @param[in] blockSize Number of samples
|
||||
* @return distance
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
|
||||
|
||||
#include "arm_helium_utils.h"
|
||||
#include "arm_vec_math_f16.h"
|
||||
|
||||
float16_t arm_minkowski_distance_f16(const float16_t *pA,const float16_t *pB, int32_t order, uint32_t blockSize)
|
||||
{
|
||||
uint32_t blkCnt;
|
||||
f16x8_t a, b, tmpV, accumV, sumV;
|
||||
|
||||
sumV = vdupq_n_f16(0.0f);
|
||||
accumV = vdupq_n_f16(0.0f);
|
||||
|
||||
blkCnt = blockSize >> 3;
|
||||
while (blkCnt > 0U) {
|
||||
a = vld1q(pA);
|
||||
b = vld1q(pB);
|
||||
|
||||
tmpV = vabdq(a, b);
|
||||
tmpV = vpowq_f16(tmpV, vdupq_n_f16(order));
|
||||
sumV = vaddq(sumV, tmpV);
|
||||
|
||||
pA += 8;
|
||||
pB += 8;
|
||||
blkCnt--;
|
||||
}
|
||||
|
||||
/*
|
||||
* tail
|
||||
* (will be merged thru tail predication)
|
||||
*/
|
||||
blkCnt = blockSize & 7;
|
||||
if (blkCnt > 0U) {
|
||||
mve_pred16_t p0 = vctp16q(blkCnt);
|
||||
|
||||
a = vldrhq_z_f16(pA, p0);
|
||||
b = vldrhq_z_f16(pB, p0);
|
||||
|
||||
tmpV = vabdq(a, b);
|
||||
tmpV = vpowq_f16(tmpV, vdupq_n_f16(order));
|
||||
sumV = vaddq_m(sumV, sumV, tmpV, p0);
|
||||
}
|
||||
|
||||
return (powf(vecAddAcrossF16Mve(sumV), (1.0f / (float16_t) order)));
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
|
||||
float16_t arm_minkowski_distance_f16(const float16_t *pA,const float16_t *pB, int32_t order, uint32_t blockSize)
|
||||
{
|
||||
float16_t sum;
|
||||
uint32_t i;
|
||||
|
||||
sum = 0.0f;
|
||||
for(i=0; i < blockSize; i++)
|
||||
{
|
||||
sum += powf(fabsf(pA[i] - pB[i]),order);
|
||||
}
|
||||
|
||||
|
||||
return(powf(sum,(1.0f/order)));
|
||||
|
||||
}
|
||||
|
||||
#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
|
||||
|
||||
|
||||
/**
|
||||
* @} end of FloatDist group
|
||||
*/
|
||||
|
||||
#endif /* #if defined(ARM_FLOAT16_SUPPORTED) */
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
#include "Test.h"
|
||||
#include "Pattern.h"
|
||||
|
||||
#include "dsp/distance_functions_f16.h"
|
||||
|
||||
class DistanceTestsF16:public Client::Suite
|
||||
{
|
||||
public:
|
||||
DistanceTestsF16(Testing::testID_t id);
|
||||
virtual void setUp(Testing::testID_t,std::vector<Testing::param_t>& paramsArgs,Client::PatternMgr *mgr);
|
||||
virtual void tearDown(Testing::testID_t,Client::PatternMgr *mgr);
|
||||
private:
|
||||
#include "DistanceTestsF16_decl.h"
|
||||
|
||||
Client::Pattern<float16_t> inputA;
|
||||
Client::Pattern<float16_t> inputB;
|
||||
Client::Pattern<int16_t> dims;
|
||||
|
||||
Client::LocalPattern<float16_t> output;
|
||||
Client::LocalPattern<float16_t> tmpA;
|
||||
Client::LocalPattern<float16_t> tmpB;
|
||||
|
||||
// Reference patterns are not loaded when we are in dump mode
|
||||
Client::RefPattern<float16_t> ref;
|
||||
|
||||
int vecDim;
|
||||
int nbPatterns;
|
||||
|
||||
|
||||
};
|
||||
@ -0,0 +1,303 @@
|
||||
#include "DistanceTestsF16.h"
|
||||
#include <stdio.h>
|
||||
#include "Error.h"
|
||||
#include "Test.h"
|
||||
|
||||
#define REL_ERROR (2e-3)
|
||||
|
||||
#define REL_JS_ERROR (3e-2)
|
||||
|
||||
#define REL_MK_ERROR (1e-2)
|
||||
|
||||
|
||||
void DistanceTestsF16::test_braycurtis_distance_f16()
|
||||
{
|
||||
const float16_t *inpA = inputA.ptr();
|
||||
const float16_t *inpB = inputB.ptr();
|
||||
|
||||
float16_t *outp = output.ptr();
|
||||
|
||||
for(int i=0; i < this->nbPatterns ; i ++)
|
||||
{
|
||||
*outp = arm_braycurtis_distance_f16(inpA, inpB, this->vecDim);
|
||||
|
||||
inpA += this->vecDim;
|
||||
inpB += this->vecDim;
|
||||
outp ++;
|
||||
}
|
||||
|
||||
ASSERT_REL_ERROR(output,ref,REL_ERROR);
|
||||
}
|
||||
|
||||
void DistanceTestsF16::test_canberra_distance_f16()
|
||||
{
|
||||
const float16_t *inpA = inputA.ptr();
|
||||
const float16_t *inpB = inputB.ptr();
|
||||
|
||||
float16_t *outp = output.ptr();
|
||||
|
||||
for(int i=0; i < this->nbPatterns ; i ++)
|
||||
{
|
||||
*outp = arm_canberra_distance_f16(inpA, inpB, this->vecDim);
|
||||
|
||||
inpA += this->vecDim;
|
||||
inpB += this->vecDim;
|
||||
outp ++;
|
||||
}
|
||||
|
||||
ASSERT_REL_ERROR(output,ref,REL_ERROR);
|
||||
}
|
||||
|
||||
void DistanceTestsF16::test_chebyshev_distance_f16()
|
||||
{
|
||||
const float16_t *inpA = inputA.ptr();
|
||||
const float16_t *inpB = inputB.ptr();
|
||||
|
||||
float16_t *outp = output.ptr();
|
||||
|
||||
for(int i=0; i < this->nbPatterns ; i ++)
|
||||
{
|
||||
*outp = arm_chebyshev_distance_f16(inpA, inpB, this->vecDim);
|
||||
|
||||
inpA += this->vecDim;
|
||||
inpB += this->vecDim;
|
||||
outp ++;
|
||||
}
|
||||
|
||||
ASSERT_REL_ERROR(output,ref,REL_ERROR);
|
||||
}
|
||||
|
||||
void DistanceTestsF16::test_cityblock_distance_f16()
|
||||
{
|
||||
const float16_t *inpA = inputA.ptr();
|
||||
const float16_t *inpB = inputB.ptr();
|
||||
|
||||
float16_t *outp = output.ptr();
|
||||
|
||||
for(int i=0; i < this->nbPatterns ; i ++)
|
||||
{
|
||||
*outp = arm_cityblock_distance_f16(inpA, inpB, this->vecDim);
|
||||
|
||||
inpA += this->vecDim;
|
||||
inpB += this->vecDim;
|
||||
outp ++;
|
||||
}
|
||||
|
||||
ASSERT_REL_ERROR(output,ref,REL_ERROR);
|
||||
}
|
||||
|
||||
void DistanceTestsF16::test_correlation_distance_f16()
|
||||
{
|
||||
const float16_t *inpA = inputA.ptr();
|
||||
const float16_t *inpB = inputB.ptr();
|
||||
|
||||
float16_t *tmpap = tmpA.ptr();
|
||||
float16_t *tmpbp = tmpB.ptr();
|
||||
|
||||
float16_t *outp = output.ptr();
|
||||
|
||||
for(int i=0; i < this->nbPatterns ; i ++)
|
||||
{
|
||||
memcpy(tmpap, inpA, sizeof(float16_t) * this->vecDim);
|
||||
memcpy(tmpbp, inpB, sizeof(float16_t) * this->vecDim);
|
||||
|
||||
*outp = arm_correlation_distance_f16(tmpap, tmpbp, this->vecDim);
|
||||
|
||||
inpA += this->vecDim;
|
||||
inpB += this->vecDim;
|
||||
outp ++;
|
||||
}
|
||||
|
||||
ASSERT_REL_ERROR(output,ref,REL_ERROR);
|
||||
}
|
||||
|
||||
void DistanceTestsF16::test_cosine_distance_f16()
|
||||
{
|
||||
const float16_t *inpA = inputA.ptr();
|
||||
const float16_t *inpB = inputB.ptr();
|
||||
|
||||
float16_t *outp = output.ptr();
|
||||
|
||||
for(int i=0; i < this->nbPatterns ; i ++)
|
||||
{
|
||||
*outp = arm_cosine_distance_f16(inpA, inpB, this->vecDim);
|
||||
|
||||
inpA += this->vecDim;
|
||||
inpB += this->vecDim;
|
||||
outp ++;
|
||||
}
|
||||
|
||||
ASSERT_REL_ERROR(output,ref,REL_ERROR);
|
||||
}
|
||||
|
||||
void DistanceTestsF16::test_euclidean_distance_f16()
|
||||
{
|
||||
const float16_t *inpA = inputA.ptr();
|
||||
const float16_t *inpB = inputB.ptr();
|
||||
|
||||
float16_t *outp = output.ptr();
|
||||
|
||||
for(int i=0; i < this->nbPatterns ; i ++)
|
||||
{
|
||||
*outp = arm_euclidean_distance_f16(inpA, inpB, this->vecDim);
|
||||
|
||||
inpA += this->vecDim;
|
||||
inpB += this->vecDim;
|
||||
outp ++;
|
||||
}
|
||||
|
||||
ASSERT_REL_ERROR(output,ref,REL_ERROR);
|
||||
}
|
||||
|
||||
void DistanceTestsF16::test_jensenshannon_distance_f16()
|
||||
{
|
||||
const float16_t *inpA = inputA.ptr();
|
||||
const float16_t *inpB = inputB.ptr();
|
||||
|
||||
float16_t *outp = output.ptr();
|
||||
|
||||
|
||||
|
||||
for(int i=0; i < this->nbPatterns ; i ++)
|
||||
{
|
||||
*outp = arm_jensenshannon_distance_f16(inpA, inpB, this->vecDim);
|
||||
|
||||
inpA += this->vecDim;
|
||||
inpB += this->vecDim;
|
||||
outp ++;
|
||||
}
|
||||
|
||||
ASSERT_REL_ERROR(output,ref,REL_JS_ERROR);
|
||||
}
|
||||
|
||||
void DistanceTestsF16::test_minkowski_distance_f16()
|
||||
{
|
||||
const float16_t *inpA = inputA.ptr();
|
||||
const float16_t *inpB = inputB.ptr();
|
||||
const int16_t *dimsp= dims.ptr();
|
||||
dimsp += 2;
|
||||
|
||||
float16_t *outp = output.ptr();
|
||||
|
||||
for(int i=0; i < this->nbPatterns ; i ++)
|
||||
{
|
||||
*outp = arm_minkowski_distance_f16(inpA, inpB, *dimsp,this->vecDim);
|
||||
|
||||
inpA += this->vecDim;
|
||||
inpB += this->vecDim;
|
||||
outp ++;
|
||||
dimsp ++;
|
||||
}
|
||||
|
||||
ASSERT_REL_ERROR(output,ref,REL_MK_ERROR);
|
||||
}
|
||||
|
||||
|
||||
void DistanceTestsF16::setUp(Testing::testID_t id,std::vector<Testing::param_t>& paramsArgs,Client::PatternMgr *mgr)
|
||||
{
|
||||
|
||||
(void)paramsArgs;
|
||||
if ((id != DistanceTestsF16::TEST_MINKOWSKI_DISTANCE_F16_9) && (id != DistanceTestsF16::TEST_JENSENSHANNON_DISTANCE_F16_8))
|
||||
{
|
||||
inputA.reload(DistanceTestsF16::INPUTA_F16_ID,mgr);
|
||||
inputB.reload(DistanceTestsF16::INPUTB_F16_ID,mgr);
|
||||
dims.reload(DistanceTestsF16::DIMS_S16_ID,mgr);
|
||||
|
||||
const int16_t *dimsp = dims.ptr();
|
||||
|
||||
this->nbPatterns=dimsp[0];
|
||||
this->vecDim=dimsp[1];
|
||||
output.create(this->nbPatterns,DistanceTestsF16::OUT_F16_ID,mgr);
|
||||
}
|
||||
|
||||
switch(id)
|
||||
{
|
||||
case DistanceTestsF16::TEST_BRAYCURTIS_DISTANCE_F16_1:
|
||||
{
|
||||
ref.reload(DistanceTestsF16::REF1_F16_ID,mgr);
|
||||
}
|
||||
break;
|
||||
|
||||
case DistanceTestsF16::TEST_CANBERRA_DISTANCE_F16_2:
|
||||
{
|
||||
ref.reload(DistanceTestsF16::REF2_F16_ID,mgr);
|
||||
}
|
||||
break;
|
||||
|
||||
case DistanceTestsF16::TEST_CHEBYSHEV_DISTANCE_F16_3:
|
||||
{
|
||||
ref.reload(DistanceTestsF16::REF3_F16_ID,mgr);
|
||||
}
|
||||
break;
|
||||
|
||||
case DistanceTestsF16::TEST_CITYBLOCK_DISTANCE_F16_4:
|
||||
{
|
||||
ref.reload(DistanceTestsF16::REF4_F16_ID,mgr);
|
||||
}
|
||||
break;
|
||||
|
||||
case DistanceTestsF16::TEST_CORRELATION_DISTANCE_F16_5:
|
||||
{
|
||||
ref.reload(DistanceTestsF16::REF5_F16_ID,mgr);
|
||||
tmpA.create(this->vecDim,DistanceTestsF16::TMPA_F16_ID,mgr);
|
||||
tmpB.create(this->vecDim,DistanceTestsF16::TMPB_F16_ID,mgr);
|
||||
}
|
||||
break;
|
||||
|
||||
case DistanceTestsF16::TEST_COSINE_DISTANCE_F16_6:
|
||||
{
|
||||
ref.reload(DistanceTestsF16::REF6_F16_ID,mgr);
|
||||
}
|
||||
break;
|
||||
|
||||
case DistanceTestsF16::TEST_EUCLIDEAN_DISTANCE_F16_7:
|
||||
{
|
||||
ref.reload(DistanceTestsF16::REF7_F16_ID,mgr);
|
||||
}
|
||||
break;
|
||||
|
||||
case DistanceTestsF16::TEST_JENSENSHANNON_DISTANCE_F16_8:
|
||||
{
|
||||
inputA.reload(DistanceTestsF16::INPUTA_JEN_F16_ID,mgr);
|
||||
inputB.reload(DistanceTestsF16::INPUTB_JEN_F16_ID,mgr);
|
||||
dims.reload(DistanceTestsF16::DIMS_S16_ID,mgr);
|
||||
|
||||
const int16_t *dimsp = dims.ptr();
|
||||
|
||||
this->nbPatterns=dimsp[0];
|
||||
this->vecDim=dimsp[1];
|
||||
output.create(this->nbPatterns,DistanceTestsF16::OUT_F16_ID,mgr);
|
||||
|
||||
ref.reload(DistanceTestsF16::REF8_F16_ID,mgr);
|
||||
}
|
||||
break;
|
||||
|
||||
case DistanceTestsF16::TEST_MINKOWSKI_DISTANCE_F16_9:
|
||||
{
|
||||
inputA.reload(DistanceTestsF16::INPUTA_F16_ID,mgr);
|
||||
inputB.reload(DistanceTestsF16::INPUTB_F16_ID,mgr);
|
||||
dims.reload(DistanceTestsF16::DIMS_MINKOWSKI_S16_ID,mgr);
|
||||
|
||||
const int16_t *dimsp = dims.ptr();
|
||||
|
||||
this->nbPatterns=dimsp[0];
|
||||
this->vecDim=dimsp[1];
|
||||
output.create(this->nbPatterns,DistanceTestsF16::OUT_F16_ID,mgr);
|
||||
|
||||
ref.reload(DistanceTestsF16::REF9_F16_ID,mgr);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void DistanceTestsF16::tearDown(Testing::testID_t id,Client::PatternMgr *mgr)
|
||||
{
|
||||
(void)id;
|
||||
output.dump(mgr);
|
||||
}
|
||||
Loading…
Reference in New Issue