private static bool InterpolateFrequency(this double[,] frequencyMatrix, int filterSize, double sigma, int w)
        {
            bool needMoreInterpolationFlag = false;

            int height = frequencyMatrix.GetLength(0);
            int width  = frequencyMatrix.GetLength(1);

            for (int i = 0; i < height; i ++)
            {
                for (int j = 0; j < width; j ++)
                {
                    if (frequencyMatrix[i, j] == -1.0)
                    {
                        var gaussian = new Filter(filterSize, sigma);
                        int center = filterSize/2; //filter is always a square.
                        int upperCenter = (filterSize & 1) == 0 ? center - 1 : center;
                        double numerator   = 0;
                        double denominator = 0;
                        for (int u = -upperCenter; u <= center; u++)
                        {
                            for (int v = -upperCenter; v <= center; v++)
                            {
                                int indexX = i + u * w;
                                int indexY = j + v * w;
                                if (indexX < 0) indexX = 0;
                                if (indexX >= height) indexX = height - 1;
                                if (indexY < 0) indexY = 0;
                                if (indexY >= width) indexY = width - 1;
                                numerator += gaussian.Matrix[center - u, center - v]*Mu(frequencyMatrix[indexX, indexY]);
                                denominator += gaussian.Matrix[center - u, center - v]*Delta(frequencyMatrix[indexX, indexY] + 1);
                            }
                        }
                        frequencyMatrix[i, j] = numerator/denominator;
                        if ((frequencyMatrix[i, j] != frequencyMatrix[i, j]) || (frequencyMatrix[i, j] > 1.0/3.0) ||
                            (frequencyMatrix[i, j] < 0.04))
                        {
                            frequencyMatrix[i, j] = -1;
                            needMoreInterpolationFlag = true;
                        }
                    }
                }
            }
            return needMoreInterpolationFlag;
        }
        private static double[,] FilterFrequencies(double[,] frequencyMatrix, int filterSize, double sigma, int w)
        {
            var result = new double[frequencyMatrix.GetLength(0), frequencyMatrix.GetLength(1)];
            var lowPassFilter = new Filter(filterSize, sigma);
            lowPassFilter.Normalize();

            result = ConvolutionHelper.Convolve(frequencyMatrix, lowPassFilter.Matrix, w);
            return result;
        }