Ejemplo n.º 1
0
        /// <summary>
        /// 9 point stencil operation.
        /// Applies a function to a moving <i>3 x 3</i> window.
        /// </summary>
        /// <param name="A">
        /// the matrix to operate on.
        /// </param>
        /// <param name="function">
        /// the function to be applied to each window.
        /// </param>
        /// <param name="maxIterations">
        /// the maximum number of times the stencil shall be applied to the matrixd
        /// Should be a multiple of 2 because two iterations are always done in one atomic step.
        /// </param>
        /// <param name="hasConverged">
        /// Convergence condition; will return before maxIterations are done when <i>hasConverged.apply(A)==true</i>.
        /// Set this parameter to <i>null</i> to indicate that no convergence checks shall be made.
        /// </param>
        /// <param name="convergenceIterations">
        /// the number of iterations to pass between each convergence check.
        /// (Since a convergence may be expensive, you may want to do it only every 2,4 or 8 iterationsd)
        /// </param>
        /// <returns><the number of iterations actually executedd /returns>
        public static int Stencil9(DoubleMatrix2D A, Cern.Colt.Function.Double9Function function, int maxIterations, DoubleMatrix2DProcedure hasConverged, int convergenceIterations)
        {
            DoubleMatrix2D B = A.Copy();

            if (convergenceIterations <= 1)
            {
                convergenceIterations = 2;
            }
            if (convergenceIterations % 2 != 0)
            {
                convergenceIterations++;                                 // odd -> make it even
            }
            int i = 0;

            while (i < maxIterations)
            { // do two steps at a time for efficiency
                A.ZAssign8Neighbors(B, function);
                B.ZAssign8Neighbors(A, function);
                i = i + 2;
                if (i % convergenceIterations == 0 && hasConverged != null)
                {
                    if (hasConverged(A))
                    {
                        return(i);
                    }
                }
            }
            return(i);
        }