You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
397 lines
6.9 KiB
C
397 lines
6.9 KiB
C
|
|
/* ----------------------------------------------------------------------
|
|
* Project: CMSIS DSP Library
|
|
* Title: arm_boolean_distance.c
|
|
* Description: Templates for boolean distances
|
|
*
|
|
*
|
|
* Target Processor: Cortex-M cores
|
|
* -------------------------------------------------------------------- */
|
|
/*
|
|
* Copyright (C) 2010-2019 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.
|
|
*/
|
|
|
|
|
|
|
|
|
|
/**
|
|
* @defgroup DISTANCEF Distance Functions
|
|
*
|
|
* Computes Distances between vectors.
|
|
*
|
|
* Distance functions are useful in a lot of algorithms.
|
|
*
|
|
*/
|
|
|
|
|
|
/**
|
|
* @addtogroup DISTANCEF
|
|
* @{
|
|
*/
|
|
|
|
|
|
/**
|
|
* @brief Elements of boolean distances
|
|
*
|
|
* Different values which are used to compute boolean distances
|
|
*
|
|
* @param[in] pA First vector of packed booleans
|
|
* @param[in] pB Second vector of packed booleans
|
|
* @param[in] numberOfBools Number of booleans
|
|
* @param[out] cTT cTT value
|
|
* @param[out] cTF cTF value
|
|
* @param[out] cFT cFT value
|
|
* @return None
|
|
*
|
|
*/
|
|
|
|
#define _FUNC(A,B) A##B
|
|
|
|
#define FUNC(EXT) _FUNC(arm_boolean_distance, EXT)
|
|
|
|
#if defined(ARM_MATH_NEON)
|
|
|
|
|
|
void FUNC(EXT)(const uint32_t *pA
|
|
, const uint32_t *pB
|
|
, uint32_t numberOfBools
|
|
#ifdef TT
|
|
, uint32_t *cTT
|
|
#endif
|
|
#ifdef FF
|
|
, uint32_t *cFF
|
|
#endif
|
|
#ifdef TF
|
|
, uint32_t *cTF
|
|
#endif
|
|
#ifdef FT
|
|
, uint32_t *cFT
|
|
#endif
|
|
)
|
|
{
|
|
#ifdef TT
|
|
uint32_t _ctt=0;
|
|
#endif
|
|
#ifdef FF
|
|
uint32_t _cff=0;
|
|
#endif
|
|
#ifdef TF
|
|
uint32_t _ctf=0;
|
|
#endif
|
|
#ifdef FT
|
|
uint32_t _cft=0;
|
|
#endif
|
|
uint32_t nbBoolBlock;
|
|
uint32_t a,b,ba,bb;
|
|
int shift;
|
|
uint32x4_t aV, bV;
|
|
#ifdef TT
|
|
uint32x4_t cttV;
|
|
#endif
|
|
#ifdef FF
|
|
uint32x4_t cffV;
|
|
#endif
|
|
#ifdef TF
|
|
uint32x4_t ctfV;
|
|
#endif
|
|
#ifdef FT
|
|
uint32x4_t cftV;
|
|
#endif
|
|
uint8x16_t tmp;
|
|
uint16x8_t tmp2;
|
|
uint32x4_t tmp3;
|
|
uint64x2_t tmp4;
|
|
#ifdef TT
|
|
uint64x2_t tmp4tt;
|
|
#endif
|
|
#ifdef FF
|
|
uint64x2_t tmp4ff;
|
|
#endif
|
|
#ifdef TF
|
|
uint64x2_t tmp4tf;
|
|
#endif
|
|
#ifdef FT
|
|
uint64x2_t tmp4ft;
|
|
#endif
|
|
|
|
#ifdef TT
|
|
tmp4tt = vdupq_n_u64(0);
|
|
#endif
|
|
#ifdef FF
|
|
tmp4ff = vdupq_n_u64(0);
|
|
#endif
|
|
#ifdef TF
|
|
tmp4tf = vdupq_n_u64(0);
|
|
#endif
|
|
#ifdef FT
|
|
tmp4ft = vdupq_n_u64(0);
|
|
#endif
|
|
|
|
nbBoolBlock = numberOfBools >> 7;
|
|
while(nbBoolBlock > 0)
|
|
{
|
|
aV = vld1q_u32(pA);
|
|
bV = vld1q_u32(pB);
|
|
pA += 4;
|
|
pB += 4;
|
|
|
|
#ifdef TT
|
|
cttV = vandq_u32(aV,bV);
|
|
#endif
|
|
#ifdef FF
|
|
cffV = vandq_u32(vmvnq_u32(aV),vmvnq_u32(bV));
|
|
#endif
|
|
#ifdef TF
|
|
ctfV = vandq_u32(aV,vmvnq_u32(bV));
|
|
#endif
|
|
#ifdef FT
|
|
cftV = vandq_u32(vmvnq_u32(aV),bV);
|
|
#endif
|
|
|
|
#ifdef TT
|
|
tmp = vcntq_u8(vreinterpretq_u8_u32(cttV));
|
|
tmp2 = vpaddlq_u8(tmp);
|
|
tmp3 = vpaddlq_u16(tmp2);
|
|
tmp4 = vpaddlq_u32(tmp3);
|
|
tmp4tt = vaddq_u64(tmp4tt, tmp4);
|
|
#endif
|
|
|
|
#ifdef FF
|
|
tmp = vcntq_u8(vreinterpretq_u8_u32(cffV));
|
|
tmp2 = vpaddlq_u8(tmp);
|
|
tmp3 = vpaddlq_u16(tmp2);
|
|
tmp4 = vpaddlq_u32(tmp3);
|
|
tmp4ff = vaddq_u64(tmp4ff, tmp4);
|
|
#endif
|
|
|
|
#ifdef TF
|
|
tmp = vcntq_u8(vreinterpretq_u8_u32(ctfV));
|
|
tmp2 = vpaddlq_u8(tmp);
|
|
tmp3 = vpaddlq_u16(tmp2);
|
|
tmp4 = vpaddlq_u32(tmp3);
|
|
tmp4tf = vaddq_u64(tmp4tf, tmp4);
|
|
#endif
|
|
|
|
#ifdef FT
|
|
tmp = vcntq_u8(vreinterpretq_u8_u32(cftV));
|
|
tmp2 = vpaddlq_u8(tmp);
|
|
tmp3 = vpaddlq_u16(tmp2);
|
|
tmp4 = vpaddlq_u32(tmp3);
|
|
tmp4ft = vaddq_u64(tmp4ft, tmp4);
|
|
#endif
|
|
|
|
|
|
nbBoolBlock --;
|
|
}
|
|
|
|
#ifdef TT
|
|
_ctt += tmp4tt[0] + tmp4tt[1];
|
|
#endif
|
|
#ifdef FF
|
|
_cff += tmp4ff[0] + tmp4ff[1];
|
|
#endif
|
|
#ifdef TF
|
|
_ctf += tmp4tf[0] + tmp4tf[1];
|
|
#endif
|
|
#ifdef FT
|
|
_cft += tmp4ft[0] + tmp4ft[1];
|
|
#endif
|
|
|
|
nbBoolBlock = numberOfBools & 0x7F;
|
|
while(nbBoolBlock >= 32)
|
|
{
|
|
a = *pA++;
|
|
b = *pB++;
|
|
shift = 0;
|
|
while(shift < 32)
|
|
{
|
|
ba = a & 1;
|
|
bb = b & 1;
|
|
a = a >> 1;
|
|
b = b >> 1;
|
|
|
|
#ifdef TT
|
|
_ctt += (ba && bb);
|
|
#endif
|
|
#ifdef FF
|
|
_cff += ((1 ^ ba) && (1 ^ bb));
|
|
#endif
|
|
#ifdef TF
|
|
_ctf += (ba && (1 ^ bb));
|
|
#endif
|
|
#ifdef FT
|
|
_cft += ((1 ^ ba) && bb);
|
|
#endif
|
|
shift ++;
|
|
}
|
|
|
|
nbBoolBlock -= 32;
|
|
}
|
|
|
|
a = *pA++;
|
|
b = *pB++;
|
|
|
|
a = a >> (32 - nbBoolBlock);
|
|
b = b >> (32 - nbBoolBlock);
|
|
|
|
while(nbBoolBlock > 0)
|
|
{
|
|
ba = a & 1;
|
|
bb = b & 1;
|
|
a = a >> 1;
|
|
|
|
b = b >> 1;
|
|
#ifdef TT
|
|
_ctt += (ba && bb);
|
|
#endif
|
|
#ifdef FF
|
|
_cff += ((1 ^ ba) && (1 ^ bb));
|
|
#endif
|
|
#ifdef TF
|
|
_ctf += (ba && (1 ^ bb));
|
|
#endif
|
|
#ifdef FT
|
|
_cft += ((1 ^ ba) && bb);
|
|
#endif
|
|
nbBoolBlock --;
|
|
}
|
|
|
|
#ifdef TT
|
|
*cTT = _ctt;
|
|
#endif
|
|
#ifdef FF
|
|
*cFF = _cff;
|
|
#endif
|
|
#ifdef TF
|
|
*cTF = _ctf;
|
|
#endif
|
|
#ifdef FT
|
|
*cFT = _cft;
|
|
#endif
|
|
}
|
|
|
|
#else
|
|
|
|
void FUNC(EXT)(const uint32_t *pA
|
|
, const uint32_t *pB
|
|
, uint32_t numberOfBools
|
|
#ifdef TT
|
|
, uint32_t *cTT
|
|
#endif
|
|
#ifdef FF
|
|
, uint32_t *cFF
|
|
#endif
|
|
#ifdef TF
|
|
, uint32_t *cTF
|
|
#endif
|
|
#ifdef FT
|
|
, uint32_t *cFT
|
|
#endif
|
|
)
|
|
{
|
|
#ifdef TT
|
|
uint32_t _ctt=0;
|
|
#endif
|
|
#ifdef FF
|
|
uint32_t _cff=0;
|
|
#endif
|
|
#ifdef TF
|
|
uint32_t _ctf=0;
|
|
#endif
|
|
#ifdef FT
|
|
uint32_t _cft=0;
|
|
#endif
|
|
uint32_t a,b,ba,bb;
|
|
int shift;
|
|
|
|
while(numberOfBools >= 32)
|
|
{
|
|
a = *pA++;
|
|
b = *pB++;
|
|
shift = 0;
|
|
while(shift < 32)
|
|
{
|
|
ba = a & 1;
|
|
bb = b & 1;
|
|
a = a >> 1;
|
|
b = b >> 1;
|
|
#ifdef TT
|
|
_ctt += (ba && bb);
|
|
#endif
|
|
#ifdef FF
|
|
_cff += ((1 ^ ba) && (1 ^ bb));
|
|
#endif
|
|
#ifdef TF
|
|
_ctf += (ba && (1 ^ bb));
|
|
#endif
|
|
#ifdef FT
|
|
_cft += ((1 ^ ba) && bb);
|
|
#endif
|
|
shift ++;
|
|
}
|
|
|
|
numberOfBools -= 32;
|
|
}
|
|
|
|
a = *pA++;
|
|
b = *pB++;
|
|
|
|
a = a >> (32 - numberOfBools);
|
|
b = b >> (32 - numberOfBools);
|
|
|
|
while(numberOfBools > 0)
|
|
{
|
|
ba = a & 1;
|
|
bb = b & 1;
|
|
a = a >> 1;
|
|
b = b >> 1;
|
|
|
|
#ifdef TT
|
|
_ctt += (ba && bb);
|
|
#endif
|
|
#ifdef FF
|
|
_cff += ((1 ^ ba) && (1 ^ bb));
|
|
#endif
|
|
#ifdef TF
|
|
_ctf += (ba && (1 ^ bb));
|
|
#endif
|
|
#ifdef FT
|
|
_cft += ((1 ^ ba) && bb);
|
|
#endif
|
|
numberOfBools --;
|
|
}
|
|
|
|
#ifdef TT
|
|
*cTT = _ctt;
|
|
#endif
|
|
#ifdef FF
|
|
*cFF = _cff;
|
|
#endif
|
|
#ifdef TF
|
|
*cTF = _ctf;
|
|
#endif
|
|
#ifdef FT
|
|
*cFT = _cft;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
|
|
/**
|
|
* @} end of DISTANCEF group
|
|
*/
|