public ButterworthFilterService(double frequency, EExamType type)
        {
            int    order  = 4;
            double cutoff = SensorService.GetCuttoffFrequency(type);
            double Wd     = cutoff / frequency * 2;

            Coeff = ButterworthLowPassFilter(order, Wd);
        }
        /// <summary>
        /// Transformação bilinear
        /// </summary>
        /// <param name="order">Ordem de filtro</param>
        /// <param name="Wa">Frequência de corte normalizada do filtro ou frequência central (normalizada na frequência de Nyquist)</param>
        /// <param name="aAnalog">Coeficiente do numerador do filtro analógico</param>
        /// <param name="bAnalog">Coeficiente de denominador do filtro analógico</param>
        /// <returns>FilterCoefficient - Coeficientes do filtro digital transformado bilinearmente</returns>
        private static FilterCoefficient BilinearTransform(int order, double Wa, double[,] aAnalog, double[,] bAnalog)
        {
            // Matriz para armazenamento de transformações bilineares
            var a = new double[aAnalog.GetLength(0), aAnalog.GetLength(1)];
            var b = new double[bAnalog.GetLength(0), bAnalog.GetLength(1)];

            // Julgamento uniforme e estranho de ordem de filtro
            bool odd = order % 2 != 0;

            // Número de seções
            int sections = aAnalog.GetLength(0);

            // Transformar o coeficiente de transformação bilinear
            double h = 1 / (Wa * Math.PI / 2);

            for (var k = 0; k < sections; k++)
            {
                double BB;

                if (k == 0 && odd)
                {
                    // Low-pass high-pass somente para primeira ordem, primeira ordem
                    // Inverso do coeficiente b0 do denominador
                    BB      = 1 / (h + bAnalog[0, 0]);
                    a[k, 0] = BB * (aAnalog[0, 1] * h + aAnalog[0, 0]);
                    a[k, 1] = BB * (-aAnalog[0, 1] * h + aAnalog[0, 0]);
                    a[k, 2] = 0;

                    b[k, 0] = BB * (h + bAnalog[0, 0]);
                    b[k, 1] = BB * (-h + bAnalog[0, 0]);
                    b[k, 2] = 0;
                }
                else
                {
                    // Inverso do coeficiente b0 do denominador
                    BB = 1 / (h * h + bAnalog[k, 1] * h + bAnalog[k, 2]);

                    a[k, 0] = BB * (aAnalog[k, 2] * h * h + aAnalog[k, 1] * h + aAnalog[k, 0]);
                    a[k, 1] = BB * 2 * (-aAnalog[k, 2] * h * h + aAnalog[k, 0]);
                    a[k, 2] = BB * (aAnalog[k, 2] * h * h - aAnalog[k, 1] * h + aAnalog[k, 0]);

                    b[k, 0] = BB * (h * h + bAnalog[k, 1] * h + bAnalog[k, 2]);
                    b[k, 1] = BB * (-2 * h * h + 2 * bAnalog[k, 2]);
                    b[k, 2] = BB * (h * h - bAnalog[k, 1] * h + bAnalog[k, 2]);
                }
            }

            // Reúna os ganhos na primeira seção
            double gain = 1;

            for (var k = 0; k < sections; k++)
            {
                gain    *= a[k, 0];
                a[k, 2] /= a[k, 0];
                a[k, 1] /= a[k, 0];
                a[k, 0] /= a[k, 0];
            }
            a[0, 0] *= gain;
            a[0, 1] *= gain;
            a[0, 2] *= gain;

            var filterValue = new FilterCoefficient();

            filterValue.Numerator   = a;
            filterValue.Denominator = b;
            filterValue.Sections    = sections;
            filterValue.Order       = order;

            return(filterValue);
        }