Esempio n. 1
0
        private void LineSearch(ref double[][] rcont, 
            ref double[][] rline,
            ref double[] bline,
            ref double[] bcont,
            ref double[] obsSpec1,
            ref double[] x,
            ref double[] f,
            double sqrtLambda,
            int pldim,
            int vpn,
            ref double[] h
            )
        {
            GNHelperForDI gnhdi = new GNHelperForDI();

            double[] x0 = new double[x.Length];
            for (int i = 0; i < x0.Length; i++) x0[i] = x[i];
            double fnorm = 0;
            double fnorm1 = 0;
            for (int i = 0; i < 1000 + 1; i++)
            {
                for (int j = 0; j < x.Length; j++) x[j] = x0[j] + ((double)i / 1000) * h[j];
                for (int j = 0; j < x.Length; j++) if (x[j] > 1) x[j] = 1;
                for (int j = 0; j < x.Length; j++) if (x[j] < 0) x[j] = 0;
                gnhdi.GetVectorFunctionPL(ref rline, ref rcont, ref bline, ref bcont,
                    ref obsSpec1, ref x, ref f, sqrtLambda, pldim, vpn, 0, 1);

                fnorm1 = Norm2(f);

                if (i == 0) { fnorm = fnorm1; }
                else
                {
                    if (fnorm < fnorm1) break;
                    fnorm = fnorm1;
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="vSinI"></param>
        /// <param name="lambda"></param>
        /// <returns></returns>
        public void DoppImGo(double vSinI, double lambda, bool autoCont)
        {
            int vpn = this.srf.GetNumberOfPatchesOfVisibleBelts();

            SpectrumInterpPL siplPhLine = new SpectrumInterpPL(this.phIntLineGrid, masMu, masLambda);

            SpectrumInterpPL siplPhCont = new SpectrumInterpPL(this.phIntContGrid, masMu, masLambda);
            
            SpectrumInterpPL siplSpLine = new SpectrumInterpPL(this.spIntLineGrid, masMu, masLambda);
            
            SpectrumInterpPL siplSpCont = new SpectrumInterpPL(this.spIntContGrid, masMu, masLambda);

            int pldim = 0;
            for (int p = 0; p < this.masObsPhase.Length; p++)
                for (int l = 0; l < this.masObsLambda[p].Length; l++)
                    pldim++;

            double[] bline = new double[pldim];
            double[] bcont = new double[pldim];
            double[][] rline = new double[pldim][];
            double[][] rcont = new double[pldim][];

            for (int i = 0; i < pldim; i++)
            {
                rline[i] = new double[vpn];
                rcont[i] = new double[vpn];
            }

            double vr;
            double deltaX = 0;
            double prArea;
            double sumLine, sumCont;
            int m = 0;
            for (int p = 0; p < this.masObsPhase.Length; p++)
            {
                for (int l = 0; l < this.masObsLambda[p].Length; l++)
                {
                    sumLine = 0;
                    sumCont = 0;
                    for (int i = 0; i < this.srf.GetNumberOfVisibleBelts(); i++)
                    {
                        for (int j = 0; j < this.srf.patch[i].Length; j++)
                        {
                            if (this.srf.patch[i][j].Visible(this.masObsPhase[p], this.srf.GetInc())!=0)
                            {
                                vr = vSinI * Math.Sin(this.srf.patch[i][j].ThetaCenterOnStart()) *
                                    Math.Sin(this.srf.patch[i][j].FiCenterOnStart() + 2 * Math.PI * this.masObsPhase[p] - 0.5 * Math.PI);
                                if (xscale == "Lambda") deltaX = this.masObsLambda[p][l] * vr / 300000;
                                if (xscale == "Vel") deltaX = vr;
                                prArea = this.srf.patch[i][j].ProjectedArea(this.masObsPhase[p], this.srf.GetInc());
                                sumLine = sumLine + prArea * siplPhLine.Interp(
                                    this.srf.patch[i][j].Mu(this.masObsPhase[p],
                                    this.srf.GetInc()),
                                    this.masObsLambda[p][l] - deltaX);
                                sumCont = sumCont + prArea * siplPhCont.Interp(
                                    this.srf.patch[i][j].Mu(this.masObsPhase[p],
                                    this.srf.GetInc()),
                                    this.masObsLambda[p][l]);   
                            }
                        }
                    }
                    bline[m] = sumLine;
                    bcont[m] = sumCont;
                    m++;
                }
            }

            int k;
            m = 0;
            for (int p = 0; p < this.masObsPhase.Length; p++)
            {
                for (int l = 0; l < this.masObsLambda[p].Length; l++)
                {
                    k = 0;
                    for (int i = 0; i < this.srf.GetNumberOfVisibleBelts(); i++)
                    {
                        for (int j = 0; j < this.srf.patch[i].Length; j++)
                        {
                            if (this.srf.patch[i][j].Visible(this.masObsPhase[p], this.srf.GetInc()) != 0)
                            {
                                vr = vSinI * Math.Sin(this.srf.patch[i][j].ThetaCenterOnStart()) *
                                    Math.Sin(this.srf.patch[i][j].FiCenterOnStart() + 2 * Math.PI * this.masObsPhase[p] - 0.5 * Math.PI);
                                if (xscale == "Lambda") deltaX = this.masObsLambda[p][l] * vr / 300000;
                                if (xscale == "Vel") deltaX = vr;
                                prArea = this.srf.patch[i][j].ProjectedArea(this.masObsPhase[p], this.srf.GetInc());
                                rline[m][k] = prArea * (siplSpLine.Interp(
                                    this.srf.patch[i][j].Mu(this.masObsPhase[p], this.srf.GetInc()),
                                    this.masObsLambda[p][l] - deltaX)-
                                    siplPhLine.Interp(
                                    this.srf.patch[i][j].Mu(this.masObsPhase[p], this.srf.GetInc()),
                                    this.masObsLambda[p][l] - deltaX));
                                rcont[m][k] = prArea * ( 
                                    siplSpCont.Interp(
                                    this.srf.patch[i][j].Mu(this.masObsPhase[p], this.srf.GetInc()),
                                    this.masObsLambda[p][l])-
                                    siplPhCont.Interp(
                                    this.srf.patch[i][j].Mu(this.masObsPhase[p], this.srf.GetInc()),
                                    this.masObsLambda[p][l]));
                            }
                            k++;
                        }
                    }
                    m++;
                }
            }

            double[] obsSpec1 = new double[pldim];
            
            k = 0;
            for (int i = 0; i < obsSpec.Length; i++)
            {
                for (int j = 0; j < obsSpec[i].Length; j++)
                {
                    obsSpec1[k] = obsSpec[i][j];
                    k++;
                }
            }

            GNHelperForDI gnhdi = new GNHelperForDI();

            double[] x0 = new double[vpn];
            
            double[] x = new double[vpn];

            double[][] jacobyTr = new double[vpn][];
            
            for (int i = 0; i < vpn; i++) jacobyTr[i] = new double[pldim+vpn];

            double[][] hessian = new double[vpn][];
            
            for (int i = 0; i < vpn; i++) hessian[i] = new double[vpn];

            double[] b = new double[vpn];

            double[] f = new double[pldim + vpn];
            
            double[] h = new double[vpn];

            for (int i = 0; i < vpn; i++) x0[i] = 0.5; //0.0 ----
            
            for (int i = 0; i < vpn; i++) x[i] = x0[i];

            double sqrtLambda = Math.Sqrt(lambda);

            double[] ff = new double[vpn];

            
            /******************************************************************/
            /********************* Gauss-Newton cycle; ************************/
            /******************************************************************/

            int iter = 0;
            int iterMax = 50;
            int threadNum = 4;
            double crit;
            
            do
            {
                Console.Write(" == ITER {0:00} ", iter);

                for (int i = 0; i < vpn; i++) x0[i] = x[i];
                for (int i = 0; i < vpn; i++) ff[i] = x0[i]; //1.0 / (1.0 + Math.Exp(-x0[i]));

                // Initialization of the transponse Jacoby matrix;
                Parallel.For(0, threadNum, t =>
                {
                    gnhdi.GetJacobyTrPL(ref rline,
                        ref rcont,
                        ref bline,
                        ref bcont,
                        ref jacobyTr,
                        ref x0,
                        sqrtLambda,
                        pldim,
                        vpn,
                        t,
                        threadNum
                        );
                });

                Parallel.For(0, threadNum, t =>
                {
                    gnhdi.GetVectorFunctionPL(ref rline,
                        ref rcont,
                        ref bline,
                        ref bcont,
                        ref obsSpec1,
                        ref x0,
                        ref f,
                        sqrtLambda,
                        pldim,
                        vpn,
                        t,
                        threadNum
                        );
                });

                double fnorm = Norm2(f);
                Console.Write("CHI = {0:0.000E000} ", fnorm);
                Console.Write("FMAX = {0:0.000} FMIN = {1:0.000}  \r\n", ff.Max(), ff.Min());

                // Initialization of the Hessian matrix;
                Parallel.For(0, vpn, i =>
                {
                    double sum;
                    for (int j = i; j < vpn; j++)
                    {
                        sum = 0;
                        for (int l = 0; l < pldim /*+ vpn*/; l++)
                        {
                            sum = sum + jacobyTr[i][l] * jacobyTr[j][l];
                        }
                        if (i == j) sum = sum + Math.Pow(jacobyTr[i][i + pldim], 2);
                        hessian[i][j] = sum;
                        hessian[j][i] = sum;
                    }
                });

                MathLib.Basic.AMultB(ref jacobyTr, ref f, ref b);

                MathLib.Basic.VAMultSC(ref b, -1.0);

                ConvGradMethodPL(ref hessian, ref b, ref h, 1e-20);

                //MathLib.Basic.VAMultSC(ref h, 0.1);

                //MathLib.Basic.VAplusVB(ref x0, ref h, ref x);

                LineSearch(ref rcont, ref rline, ref bline, ref bcont, ref obsSpec1, ref x,
                            ref f, sqrtLambda,pldim, vpn, ref h);

                for (int i = 0; i < vpn; i++)
                {
                    if (x[i] < 0) x[i] = 0;
                    if (x[i] > 1) x[i] = 1;
                }

                //if (autoCont) 
                //    AutoScale(ref rline, ref rcont, ref bline, ref bcont, ref x);

                iter++;
                if (iter == iterMax) { Console.WriteLine("Max itearations exceed...\r\n"); break; }

                double[] diff = new double[vpn];
                for (int i = 0; i < vpn; i++) diff[i] = x[i] - x0[i];
                crit = Norm2(diff)/Math.Sqrt(vpn);
                
            } while (crit > 0.0005);

            /************************************************************************/
            /********************* End of Gauss-Newton cycle;************************/
            /************************************************************************/

            
            k = 0;
            for (int i = 0; i < srf.GetNumberOfVisibleBelts(); i++)
                for (int j = 0; j < srf.patch[i].Length; j++)
                {
                    this.calcSrf.teff[i][j] = x[k]; // 1.0 / (1.0 + Math.Exp(-x[k])); ----
                    k++;
                }
            

            this.calcSpec = CalcModelProfs(ref rline, ref rcont, ref bline, ref bcont, ref x);

            k = 0;
            for (int i = 0; i < this.calcSpec.Length; i++)
            {
                for (int j = 0; j < this.calcSpec[i].Length; j++)
                {
                    this.immac_profs[i][j] = bline[k] / bcont[k];
                    k++;
                }
            }
        }