C#,数值计算——插值和外推,Laplace_interp的计算方法与源程序

1 文本格式

using System;

namespace Legalsoft.Truffer
{
    ///


    /// Object for interpolating missing data in a matrix by solving Laplace's
    /// equation.Call constructor once, then solve one or more times
    ///

    public class Laplace_interp : Linbcg
    {
        private double[,] mat { get; set; }
        private int ii { get; set; }
        private int jj { get; set; }
        private int nn { get; set; }
        private int iter;
        private double[] b;
        private double[] y;
        private double[] mask { get; set; }

        ///


        /// Values greater than 1.e99 in the input matrix mat are deemed to be missing
        /// data.The matrix is not altered until solve is called.
        ///

        ///
        public Laplace_interp(double[,] matrix)
        {
            this.mat = matrix;
            this.ii = mat.GetLength(0);
            this.jj = mat.GetLength(1);
            this.nn = ii * jj;
            this.iter = 0;
            this.b = new double[nn];
            this.y = new double[nn];
            this.mask = new double[nn];

            double vl = 0.0;
            for (int k = 0; k < nn; k++)
            {
                int i = k / jj;
                int j = k - i * jj;
                if (mat[i, j] < 1.0e99)
                {
                    b[k] = y[k] = vl = mat[i, j];
                    mask[k] = 1;
                }
                else
                {
                    b[k] = 0.0;
                    y[k] = vl;
                    mask[k] = 0;
                }
            }
        }

        ///


        /// Diagonal preconditioner. (Diagonal elements all unity.)
        ///

        ///
        ///
        ///
        public override void asolve(double[] b, double[] x, int itrnsp)
        {
            int n = b.Length;
            for (int i = 0; i < n; i++)
            {
                x[i] = b[i];
            }
        }

        ///


        /// Sparse matrix, and matrix transpose, multiply.
        ///

        ///
        ///
        ///
        public override void atimes(double[] x, double[] r, int itrnsp)
        {
            int n = r.Length;
            double del;
            for (int k = 0; k < n; k++)
            {
                r[k] = 0.0;
            }
            for (int k = 0; k < n; k++)
            {
                int i = k / jj;
                int j = k - i * jj;
                if (mask[k] > 0.0)
                {
                    r[k] += x[k];
                }
                else if (i > 0 && i < ii - 1 && j > 0 && j < jj - 1)
                {
                    if (itrnsp != 0)
                    {
                        r[k] += x[k];
                        del = -0.25 * x[k];
                        r[k - 1] += del;
                        r[k + 1] += del;
                        r[k - jj] += del;
                        r[k + jj] += del;
                    }
                    else
                    {
                        r[k] = x[k] - 0.25 * (x[k - 1] + x[k + 1] + x[k + jj] + x[k - jj]);
                    }
                }
                else if (i > 0 && i < ii - 1)
                {
                    if (itrnsp != 0)
                    {
                        r[k] += x[k];
                        del = -0.5 * x[k];
                        r[k - jj] += del;
                        r[k + jj] += del;
                    }
                    else
                    {
                        r[k] = x[k] - 0.5 * (x[k + jj] + x[k - jj]);
                    }
                }
                else if (j > 0 && j < jj - 1)
                {
                    if (itrnsp != 0)
                    {
                        r[k] += x[k];
                        del = -0.5 * x[k];
                        r[k - 1] += del;
                        r[k + 1] += del;
                    }
                    else
                    {
                        r[k] = x[k] - 0.5 * (x[k + 1] + x[k - 1]);
                    }
                }
                else
                {
                    int jjt = i == 0 ? jj : -jj;
                    int it = j == 0 ? 1 : -1;
                    if (itrnsp != 0)
                    {
                        r[k] += x[k];
                        del = -0.5 * x[k];
                        r[k + jjt] += del;
                        r[k + it] += del;
                    }
                    else
                    {
                        r[k] = x[k] - 0.5 * (x[k + jjt] + x[k + it]);
                    }
                }
            }
        }

        ///


        /// Invoke Linbcg::solve with appropriate arguments.The default argument
        /// values will usually work, in which case this routine need be called only
        /// once. The original matrix mat is refilled with the interpolated solution.
        ///

        ///
        ///
        ///
        public double solve(double tol = 1.0e-6, int itmax = -1)
        {
            double err = 0.0;
            if (itmax <= 0)
            {
                itmax = 2 * Math.Max(ii, jj);
            }
            solve( b,  y, 1, tol, itmax, ref iter, ref err);
            for (int k = 0, i = 0; i < ii; i++)
            {
                for (int j = 0; j < jj; j++)
                {
                    mat[i, j] = y[k++];
                }
            }
            return err;
        }
    }
}
 

2 代码格式

using System;

namespace Legalsoft.Truffer
{
    /// 
    /// Object for interpolating missing data in a matrix by solving Laplace's
    /// equation.Call constructor once, then solve one or more times
    /// 
    public class Laplace_interp : Linbcg
    {
        private double[,] mat { get; set; }
        private int ii { get; set; }
        private int jj { get; set; }
        private int nn { get; set; }
        private int iter;
        private double[] b;
        private double[] y;
        private double[] mask { get; set; }

        /// 
        /// Values greater than 1.e99 in the input matrix mat are deemed to be missing
        /// data.The matrix is not altered until solve is called.
        /// 
        /// 
        public Laplace_interp(double[,] matrix)
        {
            this.mat = matrix;
            this.ii = mat.GetLength(0);
            this.jj = mat.GetLength(1);
            this.nn = ii * jj;
            this.iter = 0;
            this.b = new double[nn];
            this.y = new double[nn];
            this.mask = new double[nn];

            double vl = 0.0;
            for (int k = 0; k < nn; k++)
            {
                int i = k / jj;
                int j = k - i * jj;
                if (mat[i, j] < 1.0e99)
                {
                    b[k] = y[k] = vl = mat[i, j];
                    mask[k] = 1;
                }
                else
                {
                    b[k] = 0.0;
                    y[k] = vl;
                    mask[k] = 0;
                }
            }
        }

        /// 
        /// Diagonal preconditioner. (Diagonal elements all unity.)
        /// 
        /// 
        /// 
        /// 
        public override void asolve(double[] b, double[] x, int itrnsp)
        {
            int n = b.Length;
            for (int i = 0; i < n; i++)
            {
                x[i] = b[i];
            }
        }

        /// 
        /// Sparse matrix, and matrix transpose, multiply.
        /// 
        /// 
        /// 
        /// 
        public override void atimes(double[] x, double[] r, int itrnsp)
        {
            int n = r.Length;
            double del;
            for (int k = 0; k < n; k++)
            {
                r[k] = 0.0;
            }
            for (int k = 0; k < n; k++)
            {
                int i = k / jj;
                int j = k - i * jj;
                if (mask[k] > 0.0)
                {
                    r[k] += x[k];
                }
                else if (i > 0 && i < ii - 1 && j > 0 && j < jj - 1)
                {
                    if (itrnsp != 0)
                    {
                        r[k] += x[k];
                        del = -0.25 * x[k];
                        r[k - 1] += del;
                        r[k + 1] += del;
                        r[k - jj] += del;
                        r[k + jj] += del;
                    }
                    else
                    {
                        r[k] = x[k] - 0.25 * (x[k - 1] + x[k + 1] + x[k + jj] + x[k - jj]);
                    }
                }
                else if (i > 0 && i < ii - 1)
                {
                    if (itrnsp != 0)
                    {
                        r[k] += x[k];
                        del = -0.5 * x[k];
                        r[k - jj] += del;
                        r[k + jj] += del;
                    }
                    else
                    {
                        r[k] = x[k] - 0.5 * (x[k + jj] + x[k - jj]);
                    }
                }
                else if (j > 0 && j < jj - 1)
                {
                    if (itrnsp != 0)
                    {
                        r[k] += x[k];
                        del = -0.5 * x[k];
                        r[k - 1] += del;
                        r[k + 1] += del;
                    }
                    else
                    {
                        r[k] = x[k] - 0.5 * (x[k + 1] + x[k - 1]);
                    }
                }
                else
                {
                    int jjt = i == 0 ? jj : -jj;
                    int it = j == 0 ? 1 : -1;
                    if (itrnsp != 0)
                    {
                        r[k] += x[k];
                        del = -0.5 * x[k];
                        r[k + jjt] += del;
                        r[k + it] += del;
                    }
                    else
                    {
                        r[k] = x[k] - 0.5 * (x[k + jjt] + x[k + it]);
                    }
                }
            }
        }

        /// 
        /// Invoke Linbcg::solve with appropriate arguments.The default argument
        /// values will usually work, in which case this routine need be called only
        /// once. The original matrix mat is refilled with the interpolated solution.
        /// 
        /// 
        /// 
        /// 
        public double solve(double tol = 1.0e-6, int itmax = -1)
        {
            double err = 0.0;
            if (itmax <= 0)
            {
                itmax = 2 * Math.Max(ii, jj);
            }
            solve( b,  y, 1, tol, itmax, ref iter, ref err);
            for (int k = 0, i = 0; i < ii; i++)
            {
                for (int j = 0; j < jj; j++)
                {
                    mat[i, j] = y[k++];
                }
            }
            return err;
        }
    }
}

你可能感兴趣的:(C#数值计算,Numerical,Recipes,c#,开发语言,数值计算,算法)