/ Drivers / CMSIS / DSP / Source / ComplexMathFunctions / arm_cmplx_conj_f16.c
arm_cmplx_conj_f16.c
  1  /* ----------------------------------------------------------------------
  2   * Project:      CMSIS DSP Library
  3   * Title:        arm_cmplx_conj_f16.c
  4   * Description:  Floating-point complex conjugate
  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  
 29  #include "dsp/complex_math_functions_f16.h"
 30  
 31  #if defined(ARM_FLOAT16_SUPPORTED)
 32  /**
 33    @ingroup groupCmplxMath
 34   */
 35  
 36  /**
 37    @defgroup cmplx_conj Complex Conjugate
 38  
 39    Conjugates the elements of a complex data vector.
 40  
 41    The <code>pSrc</code> points to the source data and
 42    <code>pDst</code> points to the destination data where the result should be written.
 43    <code>numSamples</code> specifies the number of complex samples
 44    and the data in each array is stored in an interleaved fashion
 45    (real, imag, real, imag, ...).
 46    Each array has a total of <code>2*numSamples</code> values.
 47  
 48    The underlying algorithm is used:
 49    <pre>
 50    for (n = 0; n < numSamples; n++) {
 51        pDst[(2*n)  ] =  pSrc[(2*n)  ];    // real part
 52        pDst[(2*n)+1] = -pSrc[(2*n)+1];    // imag part
 53    }
 54    </pre>
 55  
 56    There are separate functions for floating-point, Q15, and Q31 data types.
 57   */
 58  
 59  /**
 60    @addtogroup cmplx_conj
 61    @{
 62   */
 63  
 64  /**
 65    @brief         Floating-point complex conjugate.
 66    @param[in]     pSrc        points to the input vector
 67    @param[out]    pDst        points to the output vector
 68    @param[in]     numSamples  number of samples in each vector
 69    @return        none
 70   */
 71  
 72  #if defined(ARM_MATH_MVE_FLOAT16) && !defined(ARM_MATH_AUTOVECTORIZE)
 73  
 74  void arm_cmplx_conj_f16(
 75      const float16_t * pSrc,
 76      float16_t * pDst,
 77      uint32_t numSamples)
 78  {
 79      static const float16_t cmplx_conj_sign[8] = { 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f };
 80      uint32_t blockSize = numSamples * CMPLX_DIM;   /* loop counters */
 81      uint32_t blkCnt;
 82      f16x8_t vecSrc;
 83      f16x8_t vecSign;
 84  
 85      /*
 86       * load sign vector
 87       */
 88      vecSign = *(f16x8_t *) cmplx_conj_sign;
 89  
 90      /* Compute 4 real samples at a time */
 91      blkCnt = blockSize >> 3U;
 92  
 93      while (blkCnt > 0U)
 94      {
 95          vecSrc = vld1q(pSrc);
 96          vst1q(pDst,vmulq(vecSrc, vecSign));
 97          /*
 98           * Decrement the blkCnt loop counter
 99           * Advance vector source and destination pointers
100           */
101          pSrc += 8;
102          pDst += 8;
103          blkCnt--;
104      }
105  
106       /* Tail */
107      blkCnt = (blockSize & 0x7) >> 1;
108  
109      while (blkCnt > 0U)
110      {
111        /* C[0] + jC[1] = A[0]+ j(-1)A[1] */
112    
113        /* Calculate Complex Conjugate and store result in destination buffer. */
114        *pDst++ =  *pSrc++;
115        *pDst++ = -*pSrc++;
116    
117        /* Decrement loop counter */
118        blkCnt--;
119      }
120  
121  }
122  
123  #else
124  void arm_cmplx_conj_f16(
125    const float16_t * pSrc,
126          float16_t * pDst,
127          uint32_t numSamples)
128  {
129          uint32_t blkCnt;                               /* Loop counter */
130  
131  #if defined (ARM_MATH_LOOPUNROLL) && !defined(ARM_MATH_AUTOVECTORIZE)
132  
133    /* Loop unrolling: Compute 4 outputs at a time */
134    blkCnt = numSamples >> 2U;
135  
136    while (blkCnt > 0U)
137    {
138      /* C[0] + jC[1] = A[0]+ j(-1)A[1] */
139  
140      /* Calculate Complex Conjugate and store result in destination buffer. */
141      *pDst++ =  *pSrc++;
142      *pDst++ = -*pSrc++;
143  
144      *pDst++ =  *pSrc++;
145      *pDst++ = -*pSrc++;
146  
147      *pDst++ =  *pSrc++;
148      *pDst++ = -*pSrc++;
149  
150      *pDst++ =  *pSrc++;
151      *pDst++ = -*pSrc++;
152  
153      /* Decrement loop counter */
154      blkCnt--;
155    }
156  
157    /* Loop unrolling: Compute remaining outputs */
158    blkCnt = numSamples % 0x4U;
159  
160  #else
161  
162    /* Initialize blkCnt with number of samples */
163    blkCnt = numSamples;
164  
165  #endif /* #if defined (ARM_MATH_LOOPUNROLL) */
166  
167    while (blkCnt > 0U)
168    {
169      /* C[0] + jC[1] = A[0]+ j(-1)A[1] */
170  
171      /* Calculate Complex Conjugate and store result in destination buffer. */
172      *pDst++ =  *pSrc++;
173      *pDst++ = -*pSrc++;
174  
175      /* Decrement loop counter */
176      blkCnt--;
177    }
178  
179  }
180  #endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
181  
182  /**
183    @} end of cmplx_conj group
184   */
185  #endif /* #if defined(ARM_FLOAT16_SUPPORTED) */