/// <summary>
        ///   Computes the maximum absolute change between two members of a matrix.
        /// </summary>
        ///
        private static double getMaximumAbsoluteChange(double[][] W, double[][] W0)
        {
            // Used in the parallel method
            double[] diag = W.DotWithTransposed(W0).Diagonal();

            return(diag.Abs(result: diag)
                   .Subtract(1, result: diag)
                   .Abs(result: diag)
                   .Max());
        }
Пример #2
0
        private double[] Compute()
        {
            for (int iR = 0; iR < nRow - 1; iR++)
            {
                for (int iS = iR + 1; iS < nRow; iS++)
                {
                    //z[s,] - z[s,r]/z[r,r]*z[r,]
                    double   tmp = -z[iS, iR] / z[iR, iR];
                    double[] row = GetRowAt(iS).Add(GetRowAt(iR).Multiply(tmp));
                    SetRowAt(iS, row);
                    //                       z[s,] < -z[s,] - z[s, r] / z[r, r] * z[r,]
                }
            }

            for (int iR = 0; iR < nRow - 1; iR++)
            {
                for (int iS = iR + 1; iS < nRow; iS++)
                {
                    double   tmp = -z[iR, iS] / z[iS, iS];
                    double[] row = GetRowAt(iR).Add(GetRowAt(iS).Multiply(tmp));
                    SetRowAt(iR, row);
                    //z[r,] <- z[r,] - z[r,s]/z[s,s]*z[s,]
                }
            }

            double[] y           = this.GetColumnAt(nCol - 1);
            double[] diagonal    = this.Diagonal();
            double[] logAbsTheta = y.Abs().Log().Substract(diagonal.Abs().Log());
            double[] theta       = logAbsTheta.Exp();
            for (int i = 0; i < nRow; i++)
            {
                theta[i] = theta[i] * (Math.Sign(y[i]) * Math.Sign(diagonal[i]));
            }
            return(theta);
            //9.0909091 -3.0909091 -1.3333333 -0.6666667
        }
        public void processingRoutine()
        {
            points_to_process = arduinoHandler.bufferAquisition.Count; //número de elementos no buffer
            if (points_to_process > 30)                                //Processando a 1 decimo da frequencia de aquisição = 100Hz
            {
                //Obtem vetor de tempo
                #region Time
                //Desloca os Pontos atuais para a esquerda
                for (int i = 0; i < (qnt_pontos - points_to_process); i++)
                {
                    time_values[i] = time_values[i + points_to_process];
                }
                for (int i = (qnt_pontos - points_to_process); i < qnt_pontos; i++)
                {
                    time_values[i] = time_values[i - 1] + aquire_interval;
                }
                #endregion

                //Descarrega dados do EMG bruto
                #region EMG_bruto
                //Desloca os Pontos atuais para a esquerda
                for (int i = 0; i < (qnt_pontos - points_to_process); i++)
                {
                    emg_bruto_values[i] = emg_bruto_values[i + points_to_process];
                }

                //Adiciona os novos pontos no novo espaço a direita
                for (int i = (qnt_pontos - points_to_process); i < qnt_pontos; i++)
                {
                    emg_bruto_values[i] = arduinoHandler.bufferAquisition.
                                          SecureDequeue() * 5 / 1024.0 - 2.5;
                }
                #endregion

                //Aplica a transformada de Hilbert
                #region EMG filtrado por Hilbert
                hilbert_values = emg_bruto_values.Copy();
                Accord.Math.HilbertTransform.FHT(hilbert_values, Accord.Math.FourierTransform.Direction.Forward); //aplicar a transformada de Hilbert
                hilbert_retificado_values = hilbert_values.Abs();
                #endregion

                //Passa um filtro passa baixa de resposta butterworth em 7Hz
                #region Envoltoria através de um filtro passa baixa
                double[] primeira_metade           = hilbert_retificado_values.Get(0, qnt_pontos / 2);
                double[] primeira_metade_invertida = primeira_metade.Reversed();
                double[] segunda_metade            = hilbert_retificado_values.Get(qnt_pontos / 2, qnt_pontos);
                double[] segunda_metade_invertida  = segunda_metade.Reversed();

                double[] janela_passa_baixa = primeira_metade_invertida.Concatenate(hilbert_retificado_values);
                janela_passa_baixa = janela_passa_baixa.Concatenate(segunda_metade_invertida);

                double[] grande_envoltoria = Butter.Butterworth(janela_passa_baixa, aquire_interval, 7);
                envoltoria_values = grande_envoltoria.Get(qnt_pontos / 2, 3 * qnt_pontos / 2);
                #endregion

                //Verifica se o a envoltoria esta acima ou abaixo do limiar
                #region Detecção do Limiar
                double time_inicio = time_values[qnt_pontos - 1];
                double time_end    = time_values[0];

                for (int i = 1; i < qnt_pontos; i++)
                {
                    //Borda de Subida
                    if (envoltoria_values[i] > limiar & envoltoria_values[i - 1] < limiar)
                    {
                        time_inicio = time_values[i];              //Armazena tempo de inicio da contração
                        time_end    = time_values[qnt_pontos - 1]; //E reseta tempo de termino
                    }
                    //Borda de Descida
                    if (envoltoria_values[i] < limiar & envoltoria_values[i - 1] > limiar)
                    {
                        time_end = time_values[i];//Armazena tempo de termino da contração
                    }

                    if (time_values[i] > time_inicio)
                    {
                        contraction_sites[i] = true; //Se existe um tempo de inicio antes de mim eu estou em contração
                    }

                    if (time_values[i] > time_end)
                    {
                        contraction_sites[i] = false; //Se existe um tempo de termino antes de mim eu não estou em contração
                    }
                }
                #endregion

                //Envia novos dados para o chart:
                emgChart.SetNewPointArrays(time_values,
                                           emg_bruto_values,
                                           hilbert_values,
                                           hilbert_retificado_values,
                                           envoltoria_values,
                                           contraction_sites);
            }
        }
 public void AbsTests()
 {
     VerifyAbsoluteValue(3, A, A.Abs(), "Abs(A)");
     VerifyAbsoluteValue(3, B, B.Abs(), "Abs(B)");
     VerifyAbsoluteValue(4, C, C.Abs(), "Abs(C)");
 }