/ Drivers / CMSIS / DSP / Source / FastMathFunctions / arm_cos_f32.c
arm_cos_f32.c
  1  /* ----------------------------------------------------------------------
  2   * Project:      CMSIS DSP Library
  3   * Title:        arm_cos_f32.c
  4   * Description:  Fast cosine calculation for floating-point values
  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/fast_math_functions.h"
 30  #include "arm_common_tables.h"
 31  
 32  /**
 33    @ingroup groupFastMath
 34   */
 35  
 36  /**
 37    @defgroup cos Cosine
 38  
 39    Computes the trigonometric cosine function using a combination of table lookup
 40    and linear interpolation.  There are separate functions for
 41    Q15, Q31, and floating-point data types.
 42    The input to the floating-point version is in radians while the
 43    fixed-point Q15 and Q31 have a scaled input with the range
 44    [0 +0.9999] mapping to [0 2*pi).  The fixed-point range is chosen so that a
 45    value of 2*pi wraps around to 0.
 46  
 47    The implementation is based on table lookup using 512 values together with linear interpolation.
 48    The steps used are:
 49     -# Calculation of the nearest integer table index
 50     -# Compute the fractional portion (fract) of the table index.
 51     -# The final result equals <code>(1.0f-fract)*a + fract*b;</code>
 52  
 53    where
 54    <pre>
 55       a = Table[index];
 56       b = Table[index+1];
 57    </pre>
 58   */
 59  
 60  /**
 61    @addtogroup cos
 62    @{
 63   */
 64  
 65  /**
 66    @brief         Fast approximation to the trigonometric cosine function for floating-point data.
 67    @param[in]     x  input value in radians
 68    @return        cos(x)
 69   */
 70  float32_t arm_cos_f32(
 71    float32_t x)
 72  {
 73    float32_t cosVal, fract, in;                   /* Temporary input, output variables */
 74    uint16_t index;                                /* Index variable */
 75    float32_t a, b;                                /* Two nearest output values */
 76    int32_t n;
 77    float32_t findex;
 78  
 79    /* input x is in radians */
 80    /* Scale input to [0 1] range from [0 2*PI] , divide input by 2*pi, add 0.25 (pi/2) to read sine table */
 81    in = x * 0.159154943092f + 0.25f;
 82  
 83    /* Calculation of floor value of input */
 84    n = (int32_t) in;
 85  
 86    /* Make negative values towards -infinity */
 87    if (in < 0.0f)
 88    {
 89      n--;
 90    }
 91  
 92    /* Map input value to [0 1] */
 93    in = in - (float32_t) n;
 94  
 95    /* Calculation of index of the table */
 96    findex = (float32_t)FAST_MATH_TABLE_SIZE * in;
 97    index = (uint16_t)findex;
 98  
 99    /* when "in" is exactly 1, we need to rotate the index down to 0 */
100    if (index >= FAST_MATH_TABLE_SIZE) {
101      index = 0;
102      findex -= (float32_t)FAST_MATH_TABLE_SIZE;
103    }
104  
105    /* fractional value calculation */
106    fract = findex - (float32_t) index;
107  
108    /* Read two nearest values of input value from the cos table */
109    a = sinTable_f32[index];
110    b = sinTable_f32[index+1];
111  
112    /* Linear interpolation process */
113    cosVal = (1.0f - fract) * a + fract * b;
114  
115    /* Return output value */
116    return (cosVal);
117  }
118  
119  /**
120    @} end of cos group
121   */