Exemplo n.º 1
0
        public static void FitNonlin(double[] x, double[] y, double[] sig, double[] a,
                                     out double chisq, Funcs2 func)
        {
            MrqminFunc f = delegate(double x1, double[] a1, out double y1, double[] dyda, int na) {
                y1 = func(x1, a1);
                for (int i = 0; i < na; i++)
                {
                    dyda[i] = Dyda(x1, a1, func, i, 1e-6);
                }
            };

            FitNonlin(x, y, sig, a, out chisq, f);
        }
Exemplo n.º 2
0
        public static void FitNonlin(double[] x, double[] y, double[] sig, double[] a,
                                     out double chisq, MrqminFunc func)
        {
            int ndata = x.Length;

            if (sig == null)
            {
                sig = new double[ndata];
                for (int i = 0; i < sig.Length; i++)
                {
                    sig[i] = 1;
                }
            }
            int ma = a.Length;

            double[,] covar = new double[ma, ma];
            double[,] alpha = new double[ma, ma];
            int[] ia = new int[ma];
            for (int i = 0; i < ma; i++)
            {
                ia[i] = 1;
            }
            double alamda = -1;
            double ochisq = 0;

            double[,] oneda = null;
            int mfit = 0;

            double[] atry = null;
            double[] beta = null;
            double[] da   = null;
            NumericalRecipes.Mrqmin(x, y, sig, ndata, a, ia, ma, covar, alpha, out chisq, func, ref alamda, ref ochisq,
                                    ref oneda, ref mfit, ref atry, ref beta, ref da);
            int count1 = 0;

            while (alamda > 1e-20 && alamda < 1e20 && count1 < 100)
            {
                NumericalRecipes.Mrqmin(x, y, sig, ndata, a, ia, ma, covar, alpha, out chisq, func, ref alamda, ref ochisq,
                                        ref oneda, ref mfit, ref atry, ref beta, ref da);
                count1++;
            }
            alamda = 0;
            NumericalRecipes.Mrqmin(x, y, sig, ndata, a, ia, ma, covar, alpha, out chisq, func, ref alamda, ref ochisq,
                                    ref oneda, ref mfit, ref atry, ref beta, ref da);
        }
        public static void Mrqcof(double[] x, double[] y, double[] sig, int ndata,
                                  double[] a, double[,] alpha, double[] beta,
                                  out double chisq, MrqminFunc func)
        {
            int ma = a.Length;

            double[] dyda = new double[ma];
            for (int j = 0; j < ma; j++)
            {
                for (int k = 0; k <= j; k++)
                {
                    alpha[j, k] = 0.0;
                }
                beta[j] = 0.0;
            }
            chisq = 0.0;
            for (int i = 0; i < ndata; i++)
            {
                double ymod;
                func(x[i], a, out ymod, dyda, ma);
                double sig2i = 1.0 / (sig[i] * sig[i]);
                double dy    = y[i] - ymod;
                for (int j = 0, l = 0; l < ma; l++)
                {
                    double wt = dyda[l] * sig2i;
                    for (int k = 0, m = 0; m <= l; m++)
                    {
                        alpha[j, k++] += wt * dyda[m];
                    }
                    beta[j] += dy * wt;
                    j++;
                }
                chisq += dy * dy * sig2i;
            }
            for (int j = 1; j < ma; j++)
            {
                for (int k = 0; k < j; k++)
                {
                    alpha[k, j] = alpha[j, k];
                }
            }
        }
        public static void Mrqmin(double[] x, double[] y, double[] sig, int ndata, double[] a,
                                  int[] ia, int ma, double[,] covar, double[,] alpha, out double chisq, MrqminFunc func,
                                  ref double alamda, ref double ochisq, ref double[,] oneda, ref int mfit, ref double[] atry,
                                  ref double[] beta, ref double[] da)
        {
            int j, k, l, m;

            if (alamda < 0.0)
            {
                atry   = new double[ma];
                beta   = new double[ma];
                da     = new double[ma];
                mfit   = ma;
                oneda  = new double[mfit, 1];
                alamda = 0.001;
                Mrqcof(x, y, sig, ndata, a, alpha, beta, out chisq, func);
                ochisq = (chisq);
                for (j = 0; j < ma; j++)
                {
                    atry[j] = a[j];
                }
            }
            for (j = 0, l = 0; l < ma; l++)
            {
                for (k = 0, m = 0; m < ma; m++)
                {
                    covar[j, k] = alpha[j, k];
                    k++;
                }
                covar[j, j] = alpha[j, j] * (1.0 + (alamda));
                oneda[j, 0] = beta[j];
                j++;
            }
            Gaussj(covar, mfit, oneda, 1);
            for (j = 0; j < mfit; j++)
            {
                da[j] = oneda[j, 0];
            }
            if (alamda == 0.0)
            {
                Covsrt(covar);
                chisq = ochisq;
                return;
            }
            for (j = 0, l = 0; l < ma; l++)
            {
                atry[l] = a[l] + da[j++];
            }
            Mrqcof(x, y, sig, ndata, atry, covar, da, out chisq, func);
            if (chisq < ochisq)
            {
                alamda *= 0.1;
                ochisq  = (chisq);
                for (j = 0, l = 0; l < ma; l++)
                {
                    for (k = 0, m = 0; m < ma; m++)
                    {
                        alpha[j, k] = covar[j, k];
                        k++;
                    }
                    beta[j] = da[j];
                    a[l]    = atry[l];
                    j++;
                }
            }
            else
            {
                alamda *= 10.0;
                chisq   = ochisq;
            }
        }
Exemplo n.º 5
0
        public static void Mrqcof(double[] x, double[] y, double[] sig, int ndata, double[] a, double[,] alpha, double[] beta,
			out double chisq, MrqminFunc func)
        {
            int ma = a.Length;
            double[] dyda = new double[ma];
            for (int j = 0; j < ma; j++){
                for (int k = 0; k <= j; k++){
                    alpha[j, k] = 0.0;
                }
                beta[j] = 0.0;
            }
            chisq = 0.0;
            for (int i = 0; i < ndata; i++){
                double ymod;
                func(x[i], a, out ymod, dyda, ma);
                double sig2I = sig != null ? 1.0/(sig[i]*sig[i]) : 1.0;
                double dy = y[i] - ymod;
                for (int j = 0, l = 0; l < ma; l++){
                    double wt = dyda[l]*sig2I;
                    for (int k = 0, m = 0; m <= l; m++){
                        alpha[j, k++] += wt*dyda[m];
                    }
                    beta[j] += dy*wt;
                    j++;
                }
                chisq += dy*dy*sig2I;
            }
            for (int j = 1; j < ma; j++){
                for (int k = 0; k < j; k++){
                    alpha[k, j] = alpha[j, k];
                }
            }
        }
Exemplo n.º 6
0
        public static void Mrqmin(double[] x, double[] y, double[] sig, int ndata, double[] a, double[] amin, double[] amax,
			double[,] covar, double[,] alpha, out double chisq, MrqminFunc func, ref double alamda, ref double ochisq,
			ref double[,] oneda, ref int mfit, ref double[] atry, ref double[] beta, ref double[] da, int nthreads)
        {
            if (amin == null){
                amin = new double[a.Length];
                for (int i = 0; i < amin.Length; i++){
                    amin[i] = double.MinValue;
                }
            }
            if (amax == null){
                amax = new double[a.Length];
                for (int i = 0; i < amax.Length; i++){
                    amax[i] = double.MaxValue;
                }
            }
            int ma = a.Length;
            if (alamda < 0.0){
                atry = new double[ma];
                beta = new double[ma];
                da = new double[ma];
                mfit = ma;
                oneda = new double[mfit,1];
                alamda = 0.001;
                if (nthreads > 1){
                    MrqcofMulti(x, y, sig, ndata, a, alpha, beta, out chisq, func, nthreads);
                } else{
                    Mrqcof(x, y, sig, ndata, a, alpha, beta, out chisq, func);
                }
                ochisq = (chisq);
                for (int j = 0; j < ma; j++){
                    atry[j] = a[j];
                }
            }
            for (int j = 0; j < ma; j++){
                for (int k = 0; k < ma; k++){
                    covar[j, k] = alpha[j, k];
                }
                covar[j, j] = alpha[j, j]*(1.0 + (alamda));
                oneda[j, 0] = beta[j];
            }
            NumUtils.Gaussj(covar, mfit, oneda, 1);
            for (int j = 0; j < mfit; j++){
                da[j] = oneda[j, 0];
            }
            if (alamda == 0.0){
                NumUtils.Covsrt(covar);
                chisq = ochisq;
                return;
            }
            for (int j = 0; j < ma; j++){
                double ax = a[j] + da[j];
                if (ax >= amin[j] && ax <= amax[j]){
                    atry[j] = ax;
                }
            }
            if (nthreads > 1){
                MrqcofMulti(x, y, sig, ndata, atry, covar, da, out chisq, func, nthreads);
            } else{
                Mrqcof(x, y, sig, ndata, atry, covar, da, out chisq, func);
            }
            if (chisq < ochisq){
                alamda *= 0.1;
                ochisq = (chisq);
                for (int j = 0; j < ma; j++){
                    for (int k = 0; k < ma; k++){
                        alpha[j, k] = covar[j, k];
                    }
                    beta[j] = da[j];
                    a[j] = atry[j];
                }
            } else{
                alamda *= 10.0;
                chisq = ochisq;
            }
        }
Exemplo n.º 7
0
        public static void MrqcofMulti(double[] x, double[] y, double[] sig, int ndata, double[] a, double[,] alpha,
			double[] beta, out double chisq, MrqminFunc func, int nthreads)
        {
            int ma = a.Length;
            for (int j = 0; j < ma; j++){
                for (int k = 0; k <= j; k++){
                    alpha[j, k] = 0.0;
                }
                beta[j] = 0.0;
            }
            chisq = 0.0;
            double[][] dyda = new double[ndata][];
            double[] ymod = new double[ndata];
            for (int i = 0; i < ndata; i++){
                dyda[i] = new double[ma];
            }
            if (nthreads == 1){
                for (int i = 0; i < ndata; i++){
                    func(x[i], a, out ymod[i], dyda[i], ma);
                }
            } else{
                nthreads = Math.Min(nthreads, ndata);
                int[] inds = new int[nthreads + 1];
                for (int i = 0; i < nthreads + 1; i++){
                    inds[i] = (int) Math.Round(i/(double) (nthreads)*(ndata));
                }
                Thread[] t = new Thread[nthreads];
                for (int i = 0; i < nthreads; i++){
                    int index0 = i;
                    t[i] = new Thread(new ThreadStart(delegate{
                        for (int i1 = inds[index0]; i1 < inds[index0 + 1]; i1++){
                            func(x[i1], a, out ymod[i1], dyda[i1], ma);
                        }
                    }));
                    t[i].Start();
                }
                for (int i = 0; i < nthreads; i++){
                    t[i].Join();
                }
            }
            for (int i = 0; i < ndata; i++){
                double sig2I = sig != null ? 1.0/(sig[i]*sig[i]) : 1.0;
                double dy = y[i] - ymod[i];
                for (int j = 0, l = 0; l < ma; l++){
                    double wt = dyda[i][l]*sig2I;
                    for (int k = 0, m = 0; m <= l; m++){
                        alpha[j, k++] += wt*dyda[i][m];
                    }
                    beta[j] += dy*wt;
                    j++;
                }
                chisq += dy*dy*sig2I;
            }
            for (int j = 1; j < ma; j++){
                for (int k = 0; k < j; k++){
                    alpha[k, j] = alpha[j, k];
                }
            }
        }
Exemplo n.º 8
0
        public static void FitNonlin(double[] x, double[] y, double[] sig, double[] a, double[] amin, double[] amax,
			out double chisq, MrqminFunc func, int nthreads)
        {
            int ndata = x.Length;
            if (sig == null){
                sig = new double[ndata];
                for (int i = 0; i < sig.Length; i++){
                    sig[i] = 1;
                }
            }
            int ma = a.Length;
            double[,] covar = new double[ma,ma];
            double[,] alpha = new double[ma,ma];
            double alamda = -1;
            double ochisq = 0;
            double[,] oneda = null;
            int mfit = 0;
            double[] atry = null;
            double[] beta = null;
            double[] da = null;
            NumRecipes.Mrqmin(x, y, sig, ndata, a, amin, amax, covar, alpha, out chisq, func, ref alamda, ref ochisq, ref oneda,
                ref mfit, ref atry, ref beta, ref da, nthreads);
            int count1 = 0;
            while (alamda > 1e-60 && alamda < 1e60 && count1 < 500){
                NumRecipes.Mrqmin(x, y, sig, ndata, a, amin, amax, covar, alpha, out chisq, func, ref alamda, ref ochisq, ref oneda,
                    ref mfit, ref atry, ref beta, ref da, nthreads);
                count1++;
            }
            alamda = 0;
            NumRecipes.Mrqmin(x, y, sig, ndata, a, amin, amax, covar, alpha, out chisq, func, ref alamda, ref ochisq, ref oneda,
                ref mfit, ref atry, ref beta, ref da, nthreads);
        }
Exemplo n.º 9
0
        public static void Mrqmin(double[] x, double[] y, double[] sig, int ndata, double[] a, double[] amin, double[] amax,
                                  double[,] covar, double[,] alpha, out double chisq, MrqminFunc func, ref double alamda, ref double ochisq,
                                  ref double[,] oneda, ref int mfit, ref double[] atry, ref double[] beta, ref double[] da, int nthreads)
        {
            if (amin == null)
            {
                amin = new double[a.Length];
                for (int i = 0; i < amin.Length; i++)
                {
                    amin[i] = double.MinValue;
                }
            }
            if (amax == null)
            {
                amax = new double[a.Length];
                for (int i = 0; i < amax.Length; i++)
                {
                    amax[i] = double.MaxValue;
                }
            }
            int ma = a.Length;

            if (alamda < 0.0)
            {
                atry   = new double[ma];
                beta   = new double[ma];
                da     = new double[ma];
                mfit   = ma;
                oneda  = new double[mfit, 1];
                alamda = 0.001;
                if (nthreads > 1)
                {
                    MrqcofMulti(x, y, sig, ndata, a, alpha, beta, out chisq, func, nthreads);
                }
                else
                {
                    Mrqcof(x, y, sig, ndata, a, alpha, beta, out chisq, func);
                }
                ochisq = (chisq);
                for (int j = 0; j < ma; j++)
                {
                    atry[j] = a[j];
                }
            }
            for (int j = 0; j < ma; j++)
            {
                for (int k = 0; k < ma; k++)
                {
                    covar[j, k] = alpha[j, k];
                }
                covar[j, j] = alpha[j, j] * (1.0 + (alamda));
                oneda[j, 0] = beta[j];
            }
            NumUtils.Gaussj(covar, mfit, oneda, 1);
            for (int j = 0; j < mfit; j++)
            {
                da[j] = oneda[j, 0];
            }
            if (alamda == 0.0)
            {
                NumUtils.Covsrt(covar);
                chisq = ochisq;
                return;
            }
            for (int j = 0; j < ma; j++)
            {
                double ax = a[j] + da[j];
                if (ax >= amin[j] && ax <= amax[j])
                {
                    atry[j] = ax;
                }
            }
            if (nthreads > 1)
            {
                MrqcofMulti(x, y, sig, ndata, atry, covar, da, out chisq, func, nthreads);
            }
            else
            {
                Mrqcof(x, y, sig, ndata, atry, covar, da, out chisq, func);
            }
            if (chisq < ochisq)
            {
                alamda *= 0.1;
                ochisq  = (chisq);
                for (int j = 0; j < ma; j++)
                {
                    for (int k = 0; k < ma; k++)
                    {
                        alpha[j, k] = covar[j, k];
                    }
                    beta[j] = da[j];
                    a[j]    = atry[j];
                }
            }
            else
            {
                alamda *= 10.0;
                chisq   = ochisq;
            }
        }
Exemplo n.º 10
0
        public static void MrqcofMulti(double[] x, double[] y, double[] sig, int ndata, double[] a, double[,] alpha,
                                       double[] beta, out double chisq, MrqminFunc func, int nthreads)
        {
            int ma = a.Length;

            for (int j = 0; j < ma; j++)
            {
                for (int k = 0; k <= j; k++)
                {
                    alpha[j, k] = 0.0;
                }
                beta[j] = 0.0;
            }
            chisq = 0.0;
            double[][] dyda = new double[ndata][];
            double[]   ymod = new double[ndata];
            for (int i = 0; i < ndata; i++)
            {
                dyda[i] = new double[ma];
            }
            if (nthreads == 1)
            {
                for (int i = 0; i < ndata; i++)
                {
                    func(x[i], a, out ymod[i], dyda[i], ma);
                }
            }
            else
            {
                nthreads = Math.Min(nthreads, ndata);
                int[] inds = new int[nthreads + 1];
                for (int i = 0; i < nthreads + 1; i++)
                {
                    inds[i] = (int)Math.Round(i / (double)(nthreads) * (ndata));
                }
                Thread[] t = new Thread[nthreads];
                for (int i = 0; i < nthreads; i++)
                {
                    int index0 = i;
                    t[i] = new Thread(new ThreadStart(delegate {
                        for (int i1 = inds[index0]; i1 < inds[index0 + 1]; i1++)
                        {
                            func(x[i1], a, out ymod[i1], dyda[i1], ma);
                        }
                    }));
                    t[i].Start();
                }
                for (int i = 0; i < nthreads; i++)
                {
                    t[i].Join();
                }
            }
            for (int i = 0; i < ndata; i++)
            {
                double sig2I = sig != null ? 1.0 / (sig[i] * sig[i]) : 1.0;
                double dy    = y[i] - ymod[i];
                for (int j = 0, l = 0; l < ma; l++)
                {
                    double wt = dyda[i][l] * sig2I;
                    for (int k = 0, m = 0; m <= l; m++)
                    {
                        alpha[j, k++] += wt * dyda[i][m];
                    }
                    beta[j] += dy * wt;
                    j++;
                }
                chisq += dy * dy * sig2I;
            }
            for (int j = 1; j < ma; j++)
            {
                for (int k = 0; k < j; k++)
                {
                    alpha[k, j] = alpha[j, k];
                }
            }
        }