Пример #1
0
		/// <summary>
		/// Uses the signal in vector x to build a model with <c>numberOfCoefficients</c> parameter.
		/// </summary>
		/// <param name="x">Signal for building the model.</param>
		/// <param name="coefficients">Vector to be filled with the coefficients of the model.</param>
		/// <param name="errors">Vector to be filled with the sum of forward and backward prediction error for every stage of the model.</param>
		/// <param name="reflectionCoefficients">Vector to be filled with the reflection coefficients.</param>
		/// <param name="tempStorage">Instance of this class used to hold the temporary arrays.</param>
		/// <returns>The mean square error of backward and forward prediction.</returns>
		private static double Execution(IROVector x, IVector coefficients, IVector errors, IVector reflectionCoefficients, BurgAlgorithm tempStorage)
		{
			int N = x.Length - 1;
			int m = coefficients.Length;

			double[] Ak; // Prediction coefficients, Ak[0] is always 1
			double[] b; // backward prediction errors
			double[] f; // forward prediction errors

			if (null != tempStorage)
			{
				tempStorage.EnsureAllocation(x.Length, coefficients.Length);
				Ak = tempStorage._Ak;
				b = tempStorage._b;
				f = tempStorage._f;
				for (int i = 1; i <= coefficients.Length; i++)
					Ak[i] = 0;
			}
			else
			{
				Ak = new double[coefficients.Length + 1];
				b = new double[x.Length];
				f = new double[x.Length];
			}

			Ak[0] = 1;

			// Initialize forward and backward prediction errors with x
			for (int i = 0; i <= N; i++)
				f[i] = b[i] = x[i];

			double Dk = 0;

			for (int i = 0; i <= N; i++)
				Dk += 2 * f[i] * f[i];

			Dk -= f[0] * f[0] + b[N] * b[N];

			// Burg recursion
			int k;
			double sumE = 0; // error sum
			for (k = 0; (k < m) && (Dk > 0); k++)
			{
				// Compute mu
				double mu = 0;
				for (int n = 0; n < N - k; n++)
					mu += f[n + k + 1] * b[n];

				mu *= -2 / Dk;

				// Update Ak
				for (int n = 0; n <= (k + 1) / 2; n++)
				{
					double t1 = Ak[n] + mu * Ak[k + 1 - n];
					double t2 = Ak[k + 1 - n] + mu * Ak[n];
					Ak[n] = t1;
					Ak[k + 1 - n] = t2;
				}
				if (null != reflectionCoefficients)
					reflectionCoefficients[k] = Ak[k + 1];

				// update forward and backward predition error with simultaneous total error calculation
				sumE = 0;
				for (int n = 0; n < N - k; n++)
				{
					double t1 = f[n + k + 1] + mu * b[n];
					double t2 = b[n] + mu * f[n + k + 1];
					f[n + k + 1] = t1;
					b[n] = t2;
					sumE += t1 * t1 + t2 * t2;
				}
				if (null != errors)
					errors[k] = sumE / (2 * (N - k));
				// Update Dk
				// Note that it is possible to update Dk without total error calculation because sumE = Dk*(1-mu.GetModulusSquared())
				// but this will render the algorithm numerically unstable especially for higher orders and low noise
				Dk = sumE - (f[k + 1] * f[k + 1] + b[N - k - 1] * b[N - k - 1]);
			}

			// Assign coefficients
			for (int i = 0; i < m; i++)
				coefficients[i] = Ak[i + 1];

			// Assign the rest of reflection coefficients and errors with zero
			// if not all stages could be calculated because Dk was zero or because of rounding effects smaller than zero
			for (int i = k + 1; i < m; i++)
			{
				if (null != reflectionCoefficients)
					reflectionCoefficients[i] = 0;
				if (null != errors)
					errors[i] = 0;
			}

			return sumE / (2 * (N - k));
		}
Пример #2
0
        /// <summary>
        /// Uses the signal in vector x to build a model with <c>numberOfCoefficients</c> parameter.
        /// </summary>
        /// <param name="x">Signal for building the model.</param>
        /// <param name="coefficients">Vector to be filled with the coefficients of the model.</param>
        /// <param name="errors">Vector to be filled with the sum of forward and backward prediction error for every stage of the model.</param>
        /// <param name="reflectionCoefficients">Vector to be filled with the reflection coefficients.</param>
        /// <param name="tempStorage">Instance of this class used to hold the temporary arrays.</param>
        /// <returns>The mean square error of backward and forward prediction.</returns>
        private static double Execution(IReadOnlyList <double> x, IVector <double> coefficients, IVector <double> errors, IVector <double> reflectionCoefficients, BurgAlgorithm tempStorage)
        {
            int N = x.Count - 1;
            int m = coefficients.Length;

            double[] Ak; // Prediction coefficients, Ak[0] is always 1
            double[] b;  // backward prediction errors
            double[] f;  // forward prediction errors

            if (null != tempStorage)
            {
                tempStorage.EnsureAllocation(x.Count, coefficients.Length);
                Ak = tempStorage._Ak;
                b  = tempStorage._b;
                f  = tempStorage._f;
                for (int i = 1; i <= coefficients.Length; i++)
                {
                    Ak[i] = 0;
                }
            }
            else
            {
                Ak = new double[coefficients.Length + 1];
                b  = new double[x.Count];
                f  = new double[x.Count];
            }

            Ak[0] = 1;

            // Initialize forward and backward prediction errors with x
            for (int i = 0; i <= N; i++)
            {
                f[i] = b[i] = x[i];
            }

            double Dk = 0;

            for (int i = 0; i <= N; i++)
            {
                Dk += 2 * f[i] * f[i];
            }

            Dk -= f[0] * f[0] + b[N] * b[N];

            // Burg recursion
            int    k;
            double sumE = 0; // error sum

            for (k = 0; (k < m) && (Dk > 0); k++)
            {
                // Compute mu
                double mu = 0;
                for (int n = 0; n < N - k; n++)
                {
                    mu += f[n + k + 1] * b[n];
                }

                mu *= -2 / Dk;

                // Update Ak
                for (int n = 0; n <= (k + 1) / 2; n++)
                {
                    double t1 = Ak[n] + mu * Ak[k + 1 - n];
                    double t2 = Ak[k + 1 - n] + mu * Ak[n];
                    Ak[n]         = t1;
                    Ak[k + 1 - n] = t2;
                }
                if (null != reflectionCoefficients)
                {
                    reflectionCoefficients[k] = Ak[k + 1];
                }

                // update forward and backward predition error with simultaneous total error calculation
                sumE = 0;
                for (int n = 0; n < N - k; n++)
                {
                    double t1 = f[n + k + 1] + mu * b[n];
                    double t2 = b[n] + mu * f[n + k + 1];
                    f[n + k + 1] = t1;
                    b[n]         = t2;
                    sumE        += t1 * t1 + t2 * t2;
                }
                if (null != errors)
                {
                    errors[k] = sumE / (2 * (N - k));
                }
                // Update Dk
                // Note that it is possible to update Dk without total error calculation because sumE = Dk*(1-mu.GetModulusSquared())
                // but this will render the algorithm numerically unstable especially for higher orders and low noise
                Dk = sumE - (f[k + 1] * f[k + 1] + b[N - k - 1] * b[N - k - 1]);
            }

            // Assign coefficients
            for (int i = 0; i < m; i++)
            {
                coefficients[i] = Ak[i + 1];
            }

            // Assign the rest of reflection coefficients and errors with zero
            // if not all stages could be calculated because Dk was zero or because of rounding effects smaller than zero
            for (int i = k + 1; i < m; i++)
            {
                if (null != reflectionCoefficients)
                {
                    reflectionCoefficients[i] = 0;
                }
                if (null != errors)
                {
                    errors[i] = 0;
                }
            }

            return(sumE / (2 * (N - k)));
        }