liba 0.1.15

An algorithm library based on C/C++
Documentation
/*!
 @file lpf.h
 @brief Low Pass Filter
 @details
 low frequencies are passed, high frequencies are attenuated.
 \f[
  RC\frac{\text{d}V_{\mathrm o}}{\text{dt}}+V_{\mathrm o}=V_{\mathrm i}
 \f]
 \f[
  RC\frac{V_{\mathrm o}(n)-V_{\mathrm o}(n-1)}{T_s}+V_{\mathrm o}(n)=V_{\mathrm i}(n)
 \f]
 \f[
  V_{\mathrm o}(n)=\frac{RC}{RC+T_s}V_{\mathrm o}(n-1)+\frac{T_s}{RC+T_s}V_{\mathrm i}(n)
 \f]
 \f[
  V_{\mathrm o}(n)=(1-\alpha)V_{\mathrm o}(n-1)+\alpha V_{\mathrm i}(n)
 \f]
 \f[
  \alpha=\frac{T_s}{RC+T_s}=\frac{T_s}{{\frac{1}{2\pi f_c}}+T_s}
 \f]
 https://en.wikipedia.org/wiki/Low-pass_filter
*/

#ifndef LIBA_LPF_H
#define LIBA_LPF_H

#include "math.h"

/*!
 @ingroup liba
 @addtogroup a_lpf Low Pass Filter
 @{
*/

/*!
 @brief instance structure for Low Pass Filter
*/
typedef struct a_lpf
{
    a_float alpha; //!< filter coefficient [0,1]
    a_float output; //!< filter output
#if defined(__cplusplus)
    A_INLINE void gen(a_float fc, a_float ts)
    {
        alpha = ts / (A_FLOAT_1_TAU / fc + ts);
    }
    A_INLINE a_float operator()(a_float x)
    {
        output *= 1 - alpha;
        output += x * alpha;
        return output;
    }
    A_INLINE void zero() { output = 0; }
#endif /* __cplusplus */
} a_lpf;
#if defined(__cplusplus)
namespace a
{
typedef struct a_lpf lpf;
} /* namespace a */
#endif /* __cplusplus */
// clang-format off
#if defined(__cplusplus)
#define A_LPF_INIT(alpha) {a_float_c(alpha), 0}
#define A_LPF_INIT2(fc, ts) {A_LPF_GEN(fc, ts), 0}
#else /* !__cplusplus */
#define A_LPF_INIT(alpha) (a_lpf){a_float_c(alpha), 0}
#define A_LPF_INIT2(fc, ts) (a_lpf){A_LPF_GEN(fc, ts), 0}
#endif /* __cplusplus */
// clang-format on
#define A_LPF_GEN(fc, ts) (a_float_c(ts) / (A_FLOAT_1_TAU / a_float_c(fc) + a_float_c(ts)))

/*!
 @brief generate for Low Pass Filter
 \f{cases}{
  \alpha=\frac{T_s}{RC+T_s},&\alpha\in[0,1]\\
  RC=\frac{1}{2\pi f_c}.
 \f}
 \f[
  \alpha=\frac{T_s}{\frac{1}{2\pi f_c}+T_s}
 \f]
 @param[in] fc cut-off frequency unit(hz)
 @param[in] ts sampling time unit(s)
 @return filter coefficient [0,1]
*/
A_INTERN a_float a_lpf_gen(a_float fc, a_float ts)
{
    return ts / (A_FLOAT_1_TAU / fc + ts);
}

/*!
 @brief initialize for Low Pass Filter
 @param[in,out] ctx points to an instance of Low Pass Filter
 @param[in] alpha filter coefficient [0,1]
*/
A_INTERN void a_lpf_init(a_lpf *ctx, a_float alpha)
{
    ctx->alpha = alpha;
    ctx->output = 0;
}

/*!
 @brief calculate for Low Pass Filter
 \f[
  V_{\mathrm o}(n)=(1-\alpha)V_{\mathrm o}(n-1)+\alpha V_{\mathrm i}(n)
 \f]
 @param[in,out] ctx points to an instance of Low Pass Filter
 @param[in] x input value
 @return output value
*/
A_INTERN a_float a_lpf_iter(a_lpf *ctx, a_float x)
{
    ctx->output *= 1 - ctx->alpha;
    ctx->output += x * ctx->alpha;
    return ctx->output;
}

/*!
 @brief zeroing for Low Pass Filter
 @param[in,out] ctx points to an instance of Low Pass Filter
*/
A_INTERN void a_lpf_zero(a_lpf *ctx) { ctx->output = 0; }

/*! @} a_lpf */

#endif /* a/lpf.h */