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; } } }
/// <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++; } } }