Subversion Repositories DashDisplay

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /* ----------------------------------------------------------------------    
  2. * Copyright (C) 2010-2014 ARM Limited. All rights reserved.    
  3. *    
  4. * $Date:        19. March 2015
  5. * $Revision:    V.1.4.5
  6. *    
  7. * Project:          CMSIS DSP Library    
  8. * Title:                arm_cmplx_dot_prod_q31.c    
  9. *    
  10. * Description:  Q31 complex dot product    
  11. *    
  12. * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
  13. *  
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions
  16. * are met:
  17. *   - Redistributions of source code must retain the above copyright
  18. *     notice, this list of conditions and the following disclaimer.
  19. *   - Redistributions in binary form must reproduce the above copyright
  20. *     notice, this list of conditions and the following disclaimer in
  21. *     the documentation and/or other materials provided with the
  22. *     distribution.
  23. *   - Neither the name of ARM LIMITED nor the names of its contributors
  24. *     may be used to endorse or promote products derived from this
  25. *     software without specific prior written permission.
  26. *
  27. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  28. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  29. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  30. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  31. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  32. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  33. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  34. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  35. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  37. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  38. * POSSIBILITY OF SUCH DAMAGE.  
  39. * -------------------------------------------------------------------- */
  40.  
  41. #include "arm_math.h"
  42.  
  43. /**    
  44.  * @ingroup groupCmplxMath    
  45.  */
  46.  
  47. /**    
  48.  * @addtogroup cmplx_dot_prod    
  49.  * @{    
  50.  */
  51.  
  52. /**    
  53.  * @brief  Q31 complex dot product    
  54.  * @param  *pSrcA points to the first input vector    
  55.  * @param  *pSrcB points to the second input vector    
  56.  * @param  numSamples number of complex samples in each vector    
  57.  * @param  *realResult real part of the result returned here    
  58.  * @param  *imagResult imaginary part of the result returned here    
  59.  * @return none.    
  60.  *    
  61.  * <b>Scaling and Overflow Behavior:</b>    
  62.  * \par    
  63.  * The function is implemented using an internal 64-bit accumulator.    
  64.  * The intermediate 1.31 by 1.31 multiplications are performed with 64-bit precision and then shifted to 16.48 format.    
  65.  * The internal real and imaginary accumulators are in 16.48 format and provide 15 guard bits.    
  66.  * Additions are nonsaturating and no overflow will occur as long as <code>numSamples</code> is less than 32768.    
  67.  * The return results <code>realResult</code> and <code>imagResult</code> are in 16.48 format.    
  68.  * Input down scaling is not required.    
  69.  */
  70.  
  71. void arm_cmplx_dot_prod_q31(
  72.   q31_t * pSrcA,
  73.   q31_t * pSrcB,
  74.   uint32_t numSamples,
  75.   q63_t * realResult,
  76.   q63_t * imagResult)
  77. {
  78.   q63_t real_sum = 0, imag_sum = 0;              /* Temporary result storage */
  79.   q31_t a0,b0,c0,d0;
  80.  
  81. #ifndef ARM_MATH_CM0_FAMILY
  82.  
  83.   /* Run the below code for Cortex-M4 and Cortex-M3 */
  84.   uint32_t blkCnt;                               /* loop counter */
  85.  
  86.  
  87.   /*loop Unrolling */
  88.   blkCnt = numSamples >> 2u;
  89.  
  90.   /* First part of the processing with loop unrolling.  Compute 4 outputs at a time.    
  91.    ** a second loop below computes the remaining 1 to 3 samples. */
  92.   while(blkCnt > 0u)
  93.   {
  94.       a0 = *pSrcA++;
  95.       b0 = *pSrcA++;
  96.       c0 = *pSrcB++;
  97.       d0 = *pSrcB++;  
  98.  
  99.       real_sum += ((q63_t)a0 * c0) >> 14;
  100.       imag_sum += ((q63_t)a0 * d0) >> 14;
  101.       real_sum -= ((q63_t)b0 * d0) >> 14;
  102.       imag_sum += ((q63_t)b0 * c0) >> 14;
  103.      
  104.       a0 = *pSrcA++;
  105.       b0 = *pSrcA++;
  106.       c0 = *pSrcB++;
  107.       d0 = *pSrcB++;  
  108.  
  109.       real_sum += ((q63_t)a0 * c0) >> 14;
  110.       imag_sum += ((q63_t)a0 * d0) >> 14;
  111.       real_sum -= ((q63_t)b0 * d0) >> 14;
  112.       imag_sum += ((q63_t)b0 * c0) >> 14;
  113.      
  114.       a0 = *pSrcA++;
  115.       b0 = *pSrcA++;
  116.       c0 = *pSrcB++;
  117.       d0 = *pSrcB++;  
  118.  
  119.       real_sum += ((q63_t)a0 * c0) >> 14;
  120.       imag_sum += ((q63_t)a0 * d0) >> 14;
  121.       real_sum -= ((q63_t)b0 * d0) >> 14;
  122.       imag_sum += ((q63_t)b0 * c0) >> 14;
  123.      
  124.       a0 = *pSrcA++;
  125.       b0 = *pSrcA++;
  126.       c0 = *pSrcB++;
  127.       d0 = *pSrcB++;  
  128.  
  129.       real_sum += ((q63_t)a0 * c0) >> 14;
  130.       imag_sum += ((q63_t)a0 * d0) >> 14;
  131.       real_sum -= ((q63_t)b0 * d0) >> 14;
  132.       imag_sum += ((q63_t)b0 * c0) >> 14;
  133.  
  134.       /* Decrement the loop counter */
  135.       blkCnt--;
  136.   }
  137.  
  138.   /* If the numSamples  is not a multiple of 4, compute any remaining output samples here.    
  139.    ** No loop unrolling is used. */
  140.   blkCnt = numSamples % 0x4u;
  141.  
  142.   while(blkCnt > 0u)
  143.   {
  144.       a0 = *pSrcA++;
  145.       b0 = *pSrcA++;
  146.       c0 = *pSrcB++;
  147.       d0 = *pSrcB++;  
  148.  
  149.       real_sum += ((q63_t)a0 * c0) >> 14;
  150.       imag_sum += ((q63_t)a0 * d0) >> 14;
  151.       real_sum -= ((q63_t)b0 * d0) >> 14;
  152.       imag_sum += ((q63_t)b0 * c0) >> 14;
  153.  
  154.       /* Decrement the loop counter */
  155.       blkCnt--;
  156.   }
  157.  
  158. #else
  159.  
  160.   /* Run the below code for Cortex-M0 */
  161.  
  162.   while(numSamples > 0u)
  163.   {
  164.       a0 = *pSrcA++;
  165.       b0 = *pSrcA++;
  166.       c0 = *pSrcB++;
  167.       d0 = *pSrcB++;  
  168.  
  169.       real_sum += ((q63_t)a0 * c0) >> 14;
  170.       imag_sum += ((q63_t)a0 * d0) >> 14;
  171.       real_sum -= ((q63_t)b0 * d0) >> 14;
  172.       imag_sum += ((q63_t)b0 * c0) >> 14;
  173.  
  174.       /* Decrement the loop counter */
  175.       numSamples--;
  176.   }
  177.  
  178. #endif /* #ifndef ARM_MATH_CM0_FAMILY */
  179.  
  180.   /* Store the real and imaginary results in 16.48 format  */
  181.   *realResult = real_sum;
  182.   *imagResult = imag_sum;
  183. }
  184.  
  185. /**    
  186.  * @} end of cmplx_dot_prod group    
  187.  */
  188.