C#,数值计算——蒙特卡洛(蒙地卡罗)积分法的计算方法与源程序

1 文本格式

using System;

namespace Legalsoft.Truffer
{
    /// <summary>
    /// 蒙特卡洛(蒙地卡罗)积分法
    /// Monte Carlo integration
    /// Object for Monte Carlo integration of one or 
    /// more functions in an ndim-dimensional region
    /// </summary>
    public abstract class MCintegrate
    {
        private int n { get; set; }
        private int ndim { get; set; }
        private int nfun { get; set; }
        private double[] ff { get; set; }
        private double[] fferr { get; set; }
        private double[] xlo { get; set; }
        private double[] xhi { get; set; }
        private double[] x { get; set; }
        private double[] xx { get; set; }
        private double[] fn { get; set; }
        private double[] sf { get; set; }
        private double[] sferr { get; set; }
        private double vol { get; set; }

        private Ran ran { get; set; }

        bool xmappValid = false;
        public abstract double[] funcs(double[] x);
        public abstract bool inregion(double[] x);
        public abstract double[] xmap(double[] x);

        public MCintegrate(double[] xlow, double[] xhigh, int ranseed, bool xmappValid)
        {
            this.ndim = xlow.Length;
            this.n = 0;
            this.xlo = Globals.CopyFrom(xlow);
            this.xhi = Globals.CopyFrom(xhigh);
            this.x = new double[ndim];
            this.xx = new double[ndim];
            //this.funcsp = funcs;
            //this.xmapp = xmap;
            //this.inregionp = inregion;
            this.vol = 1.0;
            this.ran = new Ran((ulong)ranseed);
            this.xmappValid = xmappValid;
            if (xmappValid)
            {
                nfun = funcs(xmap(xlo)).Length;
            }
            else
            {
                nfun = funcs(xlo).Length;
            }
            /*
            if (xmapp != null)
            {
                nfun = funcs(xmapp(xlo)).Length;
            }
            else
            {
                nfun = funcs(xlo).Length;
            }
            */
            ff = new double[nfun];
            fferr = new double[nfun];
            fn = new double[nfun];
            sf = new double[nfun];
            sferr = new double[nfun];
            for (int j = 0; j < ndim; j++)
            {
                vol *= Math.Abs(xhi[j] - xlo[j]);
            }
        }

        public void step(int nstep)
        {
            for (int i = 0; i < nstep; i++)
            {
                for (int j = 0; j < ndim; j++)
                {
                    x[j] = xlo[j] + (xhi[j] - xlo[j]) * ran.doub();
                }
                if (xmappValid)
                {
                    xx = xmap(x);
                }
                //else
                //{
                //    xx.CopyFrom(x);
                //}
                if (inregion(xx))
                {
                    fn = funcs(xx);
                    for (int j = 0; j < nfun; j++)
                    {
                        sf[j] += fn[j];
                        sferr[j] += Globals.SQR(fn[j]);
                    }
                }
            }
            n += nstep;
        }

        public void calcanswers()
        {
            for (int j = 0; j < nfun; j++)
            {
                ff[j] = vol * sf[j] / n;
                fferr[j] = vol * Math.Sqrt((sferr[j] / n - Globals.SQR(sf[j] / n)) / n);
            }
        }

        public static double[] torusfuncs(double[] x)
        {
            double den = 1.0;
            double[] f = new double[4];
            f[0] = den;
            for (int i = 1; i < 4; i++)
            {
                f[i] = x[i - 1] * den;
            }
            return f;
        }

        public static bool torusregion(double[] x)
        {
            return Globals.SQR(x[2]) + Globals.SQR(Math.Sqrt(Globals.SQR(x[0]) + Globals.SQR(x[1])) - 3.0) <= 1.0;
        }

        public static double[] torusmap(double[] s)
        {
            double[] xx = Globals.CopyFrom(s);
            xx[2] = 0.2 * Math.Log(5.0 * s[2]);
            return xx;
        }

    }
}
 

2 代码格式

using System;

namespace Legalsoft.Truffer
{
    /// <summary>
    /// 蒙特卡洛(蒙地卡罗)积分法
    /// Monte Carlo integration
    /// Object for Monte Carlo integration of one or 
    /// more functions in an ndim-dimensional region
    /// </summary>
    public abstract class MCintegrate
    {
        private int n { get; set; }
        private int ndim { get; set; }
        private int nfun { get; set; }
        private double[] ff { get; set; }
        private double[] fferr { get; set; }
        private double[] xlo { get; set; }
        private double[] xhi { get; set; }
        private double[] x { get; set; }
        private double[] xx { get; set; }
        private double[] fn { get; set; }
        private double[] sf { get; set; }
        private double[] sferr { get; set; }
        private double vol { get; set; }

        private Ran ran { get; set; }

        bool xmappValid = false;
        public abstract double[] funcs(double[] x);
        public abstract bool inregion(double[] x);
        public abstract double[] xmap(double[] x);

        public MCintegrate(double[] xlow, double[] xhigh, int ranseed, bool xmappValid)
        {
            this.ndim = xlow.Length;
            this.n = 0;
            this.xlo = Globals.CopyFrom(xlow);
            this.xhi = Globals.CopyFrom(xhigh);
            this.x = new double[ndim];
            this.xx = new double[ndim];
            //this.funcsp = funcs;
            //this.xmapp = xmap;
            //this.inregionp = inregion;
            this.vol = 1.0;
            this.ran = new Ran((ulong)ranseed);
            this.xmappValid = xmappValid;
            if (xmappValid)
            {
                nfun = funcs(xmap(xlo)).Length;
            }
            else
            {
                nfun = funcs(xlo).Length;
            }
            /*
            if (xmapp != null)
            {
                nfun = funcs(xmapp(xlo)).Length;
            }
            else
            {
                nfun = funcs(xlo).Length;
            }
            */
            ff = new double[nfun];
            fferr = new double[nfun];
            fn = new double[nfun];
            sf = new double[nfun];
            sferr = new double[nfun];
            for (int j = 0; j < ndim; j++)
            {
                vol *= Math.Abs(xhi[j] - xlo[j]);
            }
        }

        public void step(int nstep)
        {
            for (int i = 0; i < nstep; i++)
            {
                for (int j = 0; j < ndim; j++)
                {
                    x[j] = xlo[j] + (xhi[j] - xlo[j]) * ran.doub();
                }
                if (xmappValid)
                {
                    xx = xmap(x);
                }
                //else
                //{
                //    xx.CopyFrom(x);
                //}
                if (inregion(xx))
                {
                    fn = funcs(xx);
                    for (int j = 0; j < nfun; j++)
                    {
                        sf[j] += fn[j];
                        sferr[j] += Globals.SQR(fn[j]);
                    }
                }
            }
            n += nstep;
        }

        public void calcanswers()
        {
            for (int j = 0; j < nfun; j++)
            {
                ff[j] = vol * sf[j] / n;
                fferr[j] = vol * Math.Sqrt((sferr[j] / n - Globals.SQR(sf[j] / n)) / n);
            }
        }

        public static double[] torusfuncs(double[] x)
        {
            double den = 1.0;
            double[] f = new double[4];
            f[0] = den;
            for (int i = 1; i < 4; i++)
            {
                f[i] = x[i - 1] * den;
            }
            return f;
        }

        public static bool torusregion(double[] x)
        {
            return Globals.SQR(x[2]) + Globals.SQR(Math.Sqrt(Globals.SQR(x[0]) + Globals.SQR(x[1])) - 3.0) <= 1.0;
        }

        public static double[] torusmap(double[] s)
        {
            double[] xx = Globals.CopyFrom(s);
            xx[2] = 0.2 * Math.Log(5.0 * s[2]);
            return xx;
        }

    }
}

猜你喜欢

转载自blog.csdn.net/beijinghorn/article/details/132982679