C#,数值计算——数据建模Fitsvd(general linear fit using SVD)的计算方法与源程序

1 文本格式

using System;

namespace Legalsoft.Truffer
{
    ///


    /// general linear fit using SVD
    ///

    public class Fitsvd
    {
        private int ndat { get; set; }
        private int ma { get; set; }
        private double tol { get; set; }
        private double[] x { get; set; }
        private double[] y { get; set; }
        private double[] sig { get; set; }
        private double[] a;
        private double[,] covar { get; set; }
        private double chisq { get; set; }

        private double[,] xmd { get; set; }

        public UniVarRealMultiValueFun funcs;
        public RealMultiValueFun funcsmd;

        public Fitsvd(double[] xx, double[] yy, double[] ssig, UniVarRealMultiValueFun funks, double TOL = 1.0e-12)
        {
            this.ndat = yy.Length;
            this.x = xx;
            this.xmd = null;
            this.y = yy;
            this.sig = ssig;
            this.funcs = funks;
            this.tol = TOL;
        }

        public void fit()
        {
            if (x != null)
            {
                ma = funcs.funk(x[0]).Length;
            }
            else
            {
                ma = funcsmd.funk(row(xmd, 0)).Length;
            }
            //a.resize(ma);
            a = new double[ma];
            //covar.resize(ma, ma);
            covar = new double[ma, ma];
            double[,] aa = new double[ndat, ma];
            double[] b = new double[ndat];
            double[] afunc = new double[ma];
            for (int i = 0; i < ndat; i++)
            {
                if (x != null)
                {
                    afunc = funcs.funk(x[i]);
                }
                else
                {
                    afunc = funcsmd.funk(row(xmd, i));
                }
                double tmp = 1.0 / sig[i];
                for (int j = 0; j < ma; j++)
                {
                    aa[i, j] = afunc[j] * tmp;
                }
                b[i] = y[i] * tmp;
            }
            SVD svd = new SVD(aa);
            double thresh = (tol > 0.0 ? tol * svd.w[0] : -1.0);
            svd.solve(b,  a, thresh);
            chisq = 0.0;
            for (int i = 0; i < ndat; i++)
            {
                double sum = 0.0;
                for (int j = 0; j < ma; j++)
                {
                    sum += aa[i, j] * a[j];
                }
                chisq += Globals.SQR(sum - b[i]);
            }
            for (int i = 0; i < ma; i++)
            {
                for (int j = 0; j < i + 1; j++)
                {
                    double sum = 0.0;
                    for (int k = 0; k < ma; k++)
                    {
                        if (svd.w[k] > svd.tsh)
                        {
                            sum += svd.v[i, k] * svd.v[j, k] / Globals.SQR(svd.w[k]);
                        }
                    }
                    covar[j, i] = covar[i, j] = sum;
                }
            }
        }

        public double[] row(double[,] a, int i)
        {
            int n = a.GetLength(1);
            double[] ans = new double[n];
            for (int j = 0; j < n; j++)
            {
                ans[j] = a[i, j];
            }
            return ans;
        }
    }
}
 

2 代码格式

using System;

namespace Legalsoft.Truffer
{
    /// 
    /// general linear fit using SVD
    /// 
    public class Fitsvd
    {
        private int ndat { get; set; }
        private int ma { get; set; }
        private double tol { get; set; }
        private double[] x { get; set; }
        private double[] y { get; set; }
        private double[] sig { get; set; }
        private double[] a;
        private double[,] covar { get; set; }
        private double chisq { get; set; }

        private double[,] xmd { get; set; }

        public UniVarRealMultiValueFun funcs;
        public RealMultiValueFun funcsmd;

        public Fitsvd(double[] xx, double[] yy, double[] ssig, UniVarRealMultiValueFun funks, double TOL = 1.0e-12)
        {
            this.ndat = yy.Length;
            this.x = xx;
            this.xmd = null;
            this.y = yy;
            this.sig = ssig;
            this.funcs = funks;
            this.tol = TOL;
        }

        public void fit()
        {
            if (x != null)
            {
                ma = funcs.funk(x[0]).Length;
            }
            else
            {
                ma = funcsmd.funk(row(xmd, 0)).Length;
            }
            //a.resize(ma);
            a = new double[ma];
            //covar.resize(ma, ma);
            covar = new double[ma, ma];
            double[,] aa = new double[ndat, ma];
            double[] b = new double[ndat];
            double[] afunc = new double[ma];
            for (int i = 0; i < ndat; i++)
            {
                if (x != null)
                {
                    afunc = funcs.funk(x[i]);
                }
                else
                {
                    afunc = funcsmd.funk(row(xmd, i));
                }
                double tmp = 1.0 / sig[i];
                for (int j = 0; j < ma; j++)
                {
                    aa[i, j] = afunc[j] * tmp;
                }
                b[i] = y[i] * tmp;
            }
            SVD svd = new SVD(aa);
            double thresh = (tol > 0.0 ? tol * svd.w[0] : -1.0);
            svd.solve(b,  a, thresh);
            chisq = 0.0;
            for (int i = 0; i < ndat; i++)
            {
                double sum = 0.0;
                for (int j = 0; j < ma; j++)
                {
                    sum += aa[i, j] * a[j];
                }
                chisq += Globals.SQR(sum - b[i]);
            }
            for (int i = 0; i < ma; i++)
            {
                for (int j = 0; j < i + 1; j++)
                {
                    double sum = 0.0;
                    for (int k = 0; k < ma; k++)
                    {
                        if (svd.w[k] > svd.tsh)
                        {
                            sum += svd.v[i, k] * svd.v[j, k] / Globals.SQR(svd.w[k]);
                        }
                    }
                    covar[j, i] = covar[i, j] = sum;
                }
            }
        }

        public double[] row(double[,] a, int i)
        {
            int n = a.GetLength(1);
            double[] ans = new double[n];
            for (int j = 0; j < n; j++)
            {
                ans[j] = a[i, j];
            }
            return ans;
        }
    }
}

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