예제 #1
0
        void covsrt(ref double[,] covar)
        {
            int i, j, k;

            for (i = mfit; i < ma; i++)
            {
                for (j = 0; j < i + 1; j++)
                {
                    covar[i, j] = covar[j, i] = 0.0;
                }
            }
            k = mfit - 1;
            for (j = ma - 1; j >= 0; j--)
            {
                if (ia[j])
                {
                    for (i = 0; i < ma; i++)
                    {
                        GaussJordan.swap(ref covar[i, k], ref covar[i, j]);
                    }
                    for (i = 0; i < ma; i++)
                    {
                        GaussJordan.swap(ref covar[k, i], ref covar[j, i]);
                    }
                    k--;
                }
            }
        }
예제 #2
0
        public double fit(object target)
        {
            int    j, k, l, iter, done = 0;
            double alamda = 0.001, ochisq;

            mfit = 0;
            for (j = 0; j < ma; j++)
            {
                if (ia[j])
                {
                    mfit++;
                }
            }
            double[,] oneda = new double[mfit, 1];
            double[,] temp  = new double[mfit, mfit];
            mrqcof(target, a, alpha, beta);
            for (j = 0; j < ma; j++)
            {
                atry[j] = a[j];
            }
            ochisq = chisq;
            for (iter = 0; iter < ITMAX; iter++)
            {
                if (done == NDONE)
                {
                    alamda = 0;
                }
                for (j = 0; j < mfit; j++)
                {
                    for (k = 0; k < mfit; k++)
                    {
                        covar[j, k] = alpha[j, k];
                    }
                    covar[j, j] = alpha[j, j] * (1.0 + alamda);
                    for (k = 0; k < mfit; k++)
                    {
                        temp[j, k] = covar[j, k];
                    }
                    oneda[j, 0] = beta[j];
                }
                GaussJordan.gaussj(temp, oneda);
                for (j = 0; j < mfit; j++)
                {
                    for (k = 0; k < mfit; k++)
                    {
                        covar[j, k] = temp[j, k];
                    }
                    da[j] = oneda[j, 0];
                }
                if (done == NDONE)
                {
                    covsrt(ref covar);
                    covsrt(ref alpha);
                    int ndat = 0;
                    for (j = 0; j < datpos.Length; j++)
                    {
                        ndat += datpos[j][1] - datpos[j][0];
                    }
                    chisq /= ndat - mfit;
                    return(chisq);
                }
                for (j = 0, l = 0; l < ma; l++)
                {
                    if (ia[l])
                    {
                        atry[l] = a[l] + da[j++];
                    }
                }
                mrqcof(target, atry, covar, da);
                if (Math.Abs(chisq - ochisq) < Math.Max(tol, tol * chisq))
                {
                    done++;
                }
                if (chisq < ochisq)
                {
                    alamda *= 0.1;
                    ochisq  = chisq;
                    for (j = 0; j < mfit; j++)
                    {
                        for (k = 0; k < mfit; k++)
                        {
                            alpha[j, k] = covar[j, k];
                        }
                        beta[j] = da[j];
                    }
                    for (l = 0; l < ma; l++)
                    {
                        a[l] = atry[l];
                    }
                }
                else
                {
                    alamda *= 10.0;
                    chisq   = ochisq;
                }
            }
            throw new InvalidOperationException("Fitmrq too many iterations");
        }