/// <summary>
        /// N(mu, sigma)
        /// </summary>
        /// <param name="l">lower bound</param>
        /// <param name="u">upper bound</param>
        public MultivariateNormalDistribution(PZMath_vector m, PZMath_matrix s)
        {
            dimension = m.Size;
            mu = new PZMath_vector(dimension);
            mu.MemCopyFrom(m);

            sigma = new PZMath_matrix(dimension, dimension);
            sigma.MemCopyFrom(s);

            if (dimension != sigma.RowCount || dimension != sigma.ColumnCount)
                throw new ApplicationException("MultivariateNormalDistribution::MultivariateNormalDistribution(), mu and sigma in different dimension!");

            Init();
        }
Пример #2
0
        // calculate covar
        public void Covar(double epsrel, PZMath_matrix covar)
        {
            double tolr;

            int i, j, k;
            int kmax = 0;

            PZMath_matrix r;
            PZMath_vector tau;
            PZMath_vector norm;
            PZMath_permutation perm;

            int m = J.RowCount;
            int n = J.ColumnCount ;

            if (m < n)
                PZMath_errno.ERROR ("PZMath_multifit_fdfsolver::Covar(), Jacobian be rectangular M x N with M >= N", PZMath_errno.PZMath_EBADLEN);
            if (covar.ColumnCount != covar.RowCount || covar.RowCount != n)
                PZMath_errno.ERROR ("PZMath_multifit_fdfsolver::Covar(), covariance matrix must be square and match second dimension of jacobian", PZMath_errno.PZMath_EBADLEN);
            r = new PZMath_matrix(m, n);
            tau = new PZMath_vector(n);
            perm = new PZMath_permutation(n);
            norm = new PZMath_vector(n);

            {
                int signum = 0;
                r.MemCopyFrom(J);
                PZMath_linalg.QRPTDecomp(r, tau, perm, out signum, norm);
            }

            /* Form the inverse of R in the full upper triangle of R */

            tolr = epsrel * System.Math.Abs(r[0, 0]);

            for (k = 0 ; k < n ; k++)
            {
                double rkk = r[k, k];

                if (System.Math.Abs(rkk) <= tolr)
                {
                    break;
                }

                r[k, k] = 1.0 / rkk;

                for (j = 0; j < k ; j++)
                {
                    double t = r[j, k] / rkk;
                    r[j, k] = 0.0;

                    for (i = 0; i <= j; i++)
                    {
                        double rik = r[i, k];
                        double rij = r[i, j];
                        r[i, k] = rik - t * rij;
                    }
                }
                kmax = k;
            }

            /* Form the full upper triangle of the inverse of R^T R in the full
                upper triangle of R */

            for (k = 0; k <= kmax ; k++)
            {
                for (j = 0; j < k; j++)
                {
                    double rjk = r[j, k];

                    for (i = 0; i <= j ; i++)
                    {
                        double rij = r[i, j];
                        double rik = r[i, k];

                        r[i, j] = rij + rjk * rik;
                    }
                }

                {
                    double t = r[k, k];

                    for (i = 0; i <= k; i++)
                    {
                        double rik = r[i, k];

                        r[i, k] = t * rik;
                    }
                }
            }

            /* Form the full lower triangle of the covariance matrix in the
                strict lower triangle of R and in w */

            for (j = 0 ; j < n ; j++)
            {
                int pj = (int) perm[j];

                for (i = 0; i <= j; i++)
                {
                    int pi = (int) perm[i];

                    double rij;

                    if (j > kmax)
                    {
                        r[i, j] = 0.0;
                        rij = 0.0 ;
                    }
                    else
                    {
                        rij = r[i, j];
                    }

                    if (pi > pj)
                    {
                        r[pi, pj] = rij;
                    }
                    else if (pi < pj)
                    {
                        r[pj, pi] = rij;
                    }

                }

                {
                    double rjj = r[j, j];
                    covar[pj, pj] = rjj;
                }
            }

            /* symmetrize the covariance matrix */

            for (j = 0 ; j < n ; j++)
            {
                for (i = 0; i < j ; i++)
                {
                    double rji = r[j, i];

                    covar[j, i] = rji;
                    covar[i, j] = rji;
                }
            }
        }