public void StartMapping(double regPar, double lambdaPole, string pathNNLSDir) { this.sizePar = lambdaPole; double aveFlux = curves[0].value.Average(); int allPhases = 0; for (int p = 0; p < this.curves.Length; p++) { allPhases += this.curves[p].phases.Length; } int observablePatchesNumber = this.magSrf.GetNumberOfObservablePatches(); int observableLatBeltsNumber = this.magSrf.GetNumberOfObservableLatBelts(); double[][] a = new double[allPhases][]; for (int i = 0; i < a.Length; i++) { a[i] = new double[observablePatchesNumber]; } { int s = 0; for (int q = 0; q < this.curves.Length; q++) { for (int p = 0; p < this.curves[q].phases.Length; p++) { int k = 0; double muPole = this.magSrf.MuOfThePole(this.curves[q].phases[p]); double sinGammaCenter = Math.Sqrt(1 - muPole * muPole); if (sinGammaCenter > 1.0) { sinGammaCenter = 1.0; } if (sinGammaCenter < -1.0) { sinGammaCenter = -1.0; } double cosKhi = this.magSrf.GetCosOmega(this.curves[q].phases[p], muPole); double sinKhi = 0; double eps = this.magSrf.PhiOfThePole(this.curves[q].phases[p]) - 2 * Math.PI * Math.Floor(this.magSrf.PhiOfThePole(this.curves[q].phases[p]) / (2 * Math.PI)); if (eps < Math.PI / 2.0 || eps > 1.5 * Math.PI) { sinKhi = -Math.Sqrt(1 - cosKhi * cosKhi); } else { sinKhi = Math.Sqrt(1 - cosKhi * cosKhi); } for (int i = 0; i < observableLatBeltsNumber; i++) { for (int j = 0; j < this.magSrf.Patches[i].Length; j++) { double mu = magSrf.MuOfThePatchCenter(i, j, muPole, sinGammaCenter, cosKhi, sinKhi); if (mu > 0) { double area = (this.magSrf.Patches[i][j].Phi20 - this.magSrf.Patches[i][j].Phi10) * (Math.Cos(this.magSrf.Patches[i][j].Theta1) - Math.Cos(this.magSrf.Patches[i][j].Theta2)); double cosAlpha = this.magSrf.GetCosAlpha2(i, j, this.curves[q].phases[p]); double alpha = Math.Acos(cosAlpha); double prArea = area * mu; double koeff_i, koeff_q, koeff_v, koeff_u; if (this.curves[q].type == "I") { if (alpha > 0.5 * Math.PI) { koeff_i = this.stokes_func("I", this.curves[q].filter, this.magSrf.MagneticStrength(i, j) * 1e-6, Math.PI - alpha, this.magSrf.Lambda(i, j, lambdaPole)); } else { koeff_i = this.stokes_func("I", this.curves[q].filter, this.magSrf.MagneticStrength(i, j) * 1e-6, alpha, this.magSrf.Lambda(i, j, lambdaPole)); } a[s][k] = prArea * koeff_i; } if (this.curves[q].type == "V") { if (alpha <= Math.PI * 0.5) { a[s][k] = prArea * this.stokes_func("V", this.curves[q].filter, this.magSrf.MagneticStrength(i, j) * 1e-6, alpha, this.magSrf.Lambda(i, j, lambdaPole)); } else { a[s][k] = -prArea *this.stokes_func("V", this.curves[q].filter, this.magSrf.MagneticStrength(i, j) * 1e-6, Math.PI - alpha, this.magSrf.Lambda(i, j, lambdaPole)); } } if (this.curves[q].type == "Q") { double ro = this.magSrf.GetRo(i, j, this.curves[q].phases[p]); double alpha1 = alpha; if (alpha > 0.5 * Math.PI) { alpha1 = Math.PI - alpha; } a[s][k] = area * Math.Cos(2 * ro) * this.stokes_func("Q", this.curves[q].filter, this.magSrf.MagneticStrength(i, j), alpha1, this.magSrf.Lambda(i, j, lambdaPole)); } if (this.curves[q].type == "U") { double ro = this.magSrf.GetRo(i, j, this.curves[q].phases[p]); double alpha1 = alpha; if (alpha > 0.5 * Math.PI) { alpha1 = Math.PI - alpha; } a[s][k] = -area *Math.Sin(2 *ro) * this.stokes_func("Q", this.curves[q].filter, this.magSrf.MagneticStrength(i, j), alpha1, this.magSrf.Lambda(i, j, lambdaPole)); } } k++; } } s++; } } } // scaling scale_koeff = aveFlux / (Math.PI * this.stokes_func("I", "V", this.magSrf.MagneticStrength(0, 0) * 1e-6, 0.0, lambdaPole)); for (int i = 0; i < a.Length; i++) { for (int j = 0; j < a[i].Length; j++) { a[i][j] *= scale_koeff; } } double[] f = new double[allPhases]; { int k = 0; for (int q = 0; q < this.curves.Length; q++) { for (int p = 0; p < this.curves[q].phases.Length; p++) { f[k] = this.curves[q].value[p]; k++; } } } double[][] aTa = new double[observablePatchesNumber][]; for (int i = 0; i < aTa.Length; i++) { aTa[i] = new double[observablePatchesNumber]; } double[] aTf = new double[observablePatchesNumber]; double[] x = new double[observablePatchesNumber]; double[][] aT = new double[observablePatchesNumber][]; for (int i = 0; i < aT.Length; i++) { aT[i] = new double[allPhases]; } for (int i = 0; i < aT.Length; i++) { for (int j = 0; j < aT[i].Length; j++) { aT[i][j] = a[j][i]; } } MathLib.Basic.ATrA(ref a, ref aTa); for (int i = 0; i < aTa.Length; i++) { aTa[i][i] += regPar; } MathLib.Basic.AMultB(ref aT, ref f, ref aTf); // Preparing input files for NNLS; StreamWriter sw = new StreamWriter(pathNNLSDir + "\\nnls_a.dat"); sw.WriteLine("{0} {1}", a.Length + observablePatchesNumber, observablePatchesNumber); for (int i = 0; i < a.Length; i++) { for (int j = 0; j < a[i].Length; j++) { sw.Write(string.Format("{0:0.000000000000000E000} ", a[i][j]).Replace(",", ".")); } sw.Write("\r\n"); } for (int i = 0; i < observablePatchesNumber; i++) { for (int j = 0; j < observablePatchesNumber; j++) { if (i == j) { sw.Write(string.Format("{0:0.000E000} ", Math.Sqrt(regPar)).Replace(",", ".")); } else { sw.Write(string.Format("{0:0.000E000} ", 0.0).Replace(",", ".")); } } sw.Write("\r\n"); } sw.Close(); sw = new StreamWriter(pathNNLSDir + "\\nnls_b.dat"); sw.WriteLine("{0} {1}", f.Length + observablePatchesNumber, 1); for (int i = 0; i < a.Length; i++) { sw.Write(string.Format("{0:0.000000000000000E000}\r\n", f[i]).Replace(",", ".")); } for (int i = 0; i < observablePatchesNumber; i++) { sw.Write(string.Format("{0:0.00000E000}\r\n", 0).Replace(",", ".")); } sw.Close(); // Run NNLS; Process pro = new Process(); pro.StartInfo.FileName = pathNNLSDir + "\\NNLS.exe"; pro.StartInfo.WorkingDirectory = pathNNLSDir; pro.StartInfo.Arguments = "d nnls_a.dat nnls_b.dat 5000"; pro.Start(); pro.WaitForExit(); // StreamReader sr = new StreamReader(pathNNLSDir + "\\nnls_solution.dat"); for (int i = 0; i < x.Length; i++) { x[i] = double.Parse(sr.ReadLine().Replace(".", ",")); } sr.Close(); //x = MathLib.LES_Solver.SolveWithGaussMethod(aTa, aTf); //MathLib.LES_Solver.ConvGradMethodPL(ref aTa, ref aTf, ref x, 1e-20); { int k = 0; for (int i = 0; i < observableLatBeltsNumber; i++) { for (int j = 0; j < this.magSrfRes.Patches[i].Length; j++) { this.magSrfRes.SetDensity(i, j, x[k]); k++; } } } }
public void StartStokesCurvesModelling(double[] phases, double scale, double poleOptDepth) { this.stokesI = new double[phases.Length]; this.stokesQ = new double[phases.Length]; this.stokesV = new double[phases.Length]; this.stokesU = new double[phases.Length]; this.phasesI = phases; this.phasesQ = phases; this.phasesV = phases; this.phasesU = phases; //Parallel.For(0, phases.Length, p => for (int p = 0; p < phases.Length; p++) { double muPole; double sinGammaCenter; double sinKhi, cosKhi; double sumI = 0; double sumV = 0; double sumQ = 0; double sumU = 0; muPole = this.magSrf.MuOfThePole(phases[p]); sinGammaCenter = Math.Sqrt(1 - muPole * muPole); if (sinGammaCenter > 1.0) sinGammaCenter = 1.0; if (sinGammaCenter < -1.0) sinGammaCenter = -1.0; cosKhi = this.magSrf.GetCosOmega(phases[p], muPole); double eps = this.magSrf.PhiOfThePole(phases[p]) - 2 * Math.PI * Math.Floor(this.magSrf.PhiOfThePole(phases[p]) / (2 * Math.PI)); if (eps < 0.5*Math.PI || eps > 1.5 * Math.PI) { sinKhi = -Math.Sqrt(1 - cosKhi * cosKhi); } else { sinKhi = Math.Sqrt(1 - cosKhi * cosKhi); } for (int i = 0; i < this.magSrf.Patches.Length; i++) { // areas of patches in the same belt are equil double area = (this.magSrf.Patches[i][0].Phi20 - this.magSrf.Patches[i][0].Phi10) * (Math.Cos(this.magSrf.Patches[i][0].Theta1) - Math.Cos(this.magSrf.Patches[i][0].Theta2)); for (int j = 0; j < this.magSrf.Patches[i].Length; j++) { if (this.magSrf.BrightnessDensity[i][j] != 0) { double mu = magSrf.MuOfThePatchCenter(i, j, muPole, sinGammaCenter, cosKhi, sinKhi); if (mu >= 0) { //double cosAlpha = magSrf.GetCosAlpha(i, j, muPole, sinGammaCenter, cosKhi, sinKhi); double cosAlpha = magSrf.GetCosAlpha2(i, j, phases[p]); double alpha = Math.Acos(cosAlpha); double scale1 = this.magSrf.BrightnessDensity[i][j] * area; //mu = 1; // !!!!!!!!!!!!!!! double ro; ro = this.magSrf.GetRo(i, j, phases[p]); double koeff_i = 0, koeff_v = 0, koeff_q = 0, koeff_u = 0; // Stokes I integration; if (alpha > 0.5 * Math.PI) { koeff_i = this.stokesI_b_theta_lambda( this.magSrf.MagneticStrength(i, j) * 1e-6, Math.PI - alpha, this.magSrf.Lambda(i, j, poleOptDepth)); } else { koeff_i = this.stokesI_b_theta_lambda( this.magSrf.MagneticStrength(i, j) * 1e-6, alpha, this.magSrf.Lambda(i, j, poleOptDepth)); } if (koeff_i < 0) { koeff_i = 0; } sumI += koeff_i * scale1 * mu; // Stokes V integration; if (alpha > 0.5 * Math.PI) { koeff_v = -this.stokesV_b_theta_lambda( this.magSrf.MagneticStrength(i, j) * 1e-6, Math.PI - alpha, this.magSrf.Lambda(i, j, poleOptDepth)); } else { koeff_v = this.stokesV_b_theta_lambda( this.magSrf.MagneticStrength(i, j) * 1e-6, alpha, this.magSrf.Lambda(i, j, poleOptDepth)); } sumV += koeff_v * scale1 * mu; // Stokes Q integration; if (alpha > 0.5 * Math.PI) { koeff_q = this.stokesQ_b_theta_lambda( this.magSrf.MagneticStrength(i, j) * 1e-6, Math.PI - alpha, this.magSrf.Lambda(i, j, poleOptDepth)); } else { koeff_q = this.stokesQ_b_theta_lambda( this.magSrf.MagneticStrength(i, j) * 1e-6, alpha, this.magSrf.Lambda(i, j, poleOptDepth)); } //if (koeff_q < 0) koeff_q = 0; sumQ += Math.Cos(2 * ro) * koeff_q * scale1 * mu; // Stokes U integration; if (alpha > 0.5 * Math.PI) { koeff_u = this.stokesQ_b_theta_lambda( this.magSrf.MagneticStrength(i, j) * 1e-6, Math.PI - alpha, this.magSrf.Lambda(i, j, poleOptDepth)); } else { koeff_u = this.stokesQ_b_theta_lambda( this.magSrf.MagneticStrength(i, j) * 1e-6, alpha, this.magSrf.Lambda(i, j, poleOptDepth)); } //if (koeff_i < 0) koeff_i = 0; sumU += -Math.Sin(2 * ro) * koeff_u * scale1 * mu; } } } } //this.prAreaArray[p] = 1; this.stokesI[p] = sumI; this.stokesV[p] = sumV; this.stokesQ[p] = sumQ; this.stokesU[p] = sumU; this.stokesI[p] = stokesI[p] * scale; this.stokesV[p] = stokesV[p] * scale; this.stokesQ[p] = stokesQ[p] * scale; this.stokesU[p] = stokesU[p] * scale; }//); }
public void StartMapping(double regPar) { int allPhases = 0; for (int p = 0; p < this.curves.Length; p++) { allPhases += this.curves[p].phases.Length; } int observablePatchesNumber = this.magSrf.GetNumberOfObservablePatches(); int observableLatBeltsNumber = this.magSrf.GetNumberOfObservableLatBelts(); double[][] a = new double[allPhases][]; for (int i = 0; i < a.Length; i++) { a[i] = new double[observablePatchesNumber]; } { int s = 0; for (int q = 0; q < this.curves.Length; q++) { for (int p = 0; p < this.curves[q].phases.Length; p++) { int k = 0; double muPole = this.magSrf.MuOfThePole(this.curves[q].phases[p]); double sinGammaCenter = Math.Sqrt(1 - muPole * muPole); if (sinGammaCenter > 1.0) { sinGammaCenter = 1.0; } if (sinGammaCenter < -1.0) { sinGammaCenter = -1.0; } double cosKhi = this.magSrf.GetCosOmega(this.curves[q].phases[p], muPole); double sinKhi = 0; double eps = this.magSrf.PhiOfThePole(this.curves[q].phases[p]) - 2 * Math.PI * Math.Floor(this.magSrf.PhiOfThePole(this.curves[q].phases[p]) / (2 * Math.PI)); if (eps < Math.PI / 2.0 || eps > 1.5 * Math.PI) { sinKhi = -Math.Sqrt(1 - cosKhi * cosKhi); } else { sinKhi = Math.Sqrt(1 - cosKhi * cosKhi); } for (int i = 0; i < observableLatBeltsNumber; i++) { for (int j = 0; j < this.magSrf.Patches[i].Length; j++) { double mu = magSrf.MuOfThePatchCenter(i, j, muPole, sinGammaCenter, cosKhi, sinKhi); if (mu > 0) { double area = (this.magSrf.Patches[i][j].Phi20 - this.magSrf.Patches[i][j].Phi10) * (Math.Cos(this.magSrf.Patches[i][j].Theta1) - Math.Cos(this.magSrf.Patches[i][j].Theta2)); double cosAlpha = this.magSrf.GetCosAlpha2(i, j, this.curves[q].phases[p]); double alpha = Math.Acos(cosAlpha); double prArea = area * mu; double koeff_i, koeff_q, koeff_v, koeff_u; if (this.curves[q].type == "I") { if (alpha > 0.5 * Math.PI) { koeff_i = this.stokes_func("I", this.curves[q].filter, this.magSrf.MagneticStrength(i, j) * 1e-6, Math.PI - alpha, this.magSrf.Lambda(i, j, 1e7)); } else { koeff_i = this.stokes_func("I", this.curves[q].filter, this.magSrf.MagneticStrength(i, j) * 1e-6, alpha, this.magSrf.Lambda(i, j, 1e7)); } a[s][k] = prArea * koeff_i; } if (this.curves[q].type == "V") { if (alpha <= Math.PI * 0.5) { a[s][k] = prArea * this.stokes_func("V", this.curves[q].filter, this.magSrf.MagneticStrength(i, j) * 1e-6, alpha, this.magSrf.Lambda(i, j, 1e7)); } else { a[s][k] = -prArea *this.stokes_func("V", this.curves[q].filter, this.magSrf.MagneticStrength(i, j) * 1e-6, Math.PI - alpha, this.magSrf.Lambda(i, j, 1e7)); } } if (this.curves[q].type == "Q") { double ro = this.magSrf.GetRo(i, j, this.curves[q].phases[p]); double alpha1 = alpha; if (alpha > 0.5 * Math.PI) { alpha1 = Math.PI - alpha; } a[s][k] = area * Math.Cos(2 * ro) * this.stokes_func("Q", this.curves[q].filter, this.magSrf.MagneticStrength(i, j), alpha1, this.magSrf.Lambda(i, j, 1e7)); } if (this.curves[q].type == "U") { double ro = this.magSrf.GetRo(i, j, this.curves[q].phases[p]); double alpha1 = alpha; if (alpha > 0.5 * Math.PI) { alpha1 = Math.PI - alpha; } a[s][k] = -area *Math.Sin(2 *ro) * this.stokes_func("Q", this.curves[q].filter, this.magSrf.MagneticStrength(i, j), alpha1, this.magSrf.Lambda(i, j, 1e7)); } } k++; } } s++; } } } double[] f = new double[allPhases]; { int k = 0; for (int q = 0; q < this.curves.Length; q++) { for (int p = 0; p < this.curves[q].phases.Length; p++) { f[k] = this.curves[q].value[p]; k++; } } } double[][] aTa = new double[observablePatchesNumber][]; for (int i = 0; i < aTa.Length; i++) { aTa[i] = new double[observablePatchesNumber]; } double[] aTf = new double[observablePatchesNumber]; double[] x = new double[observablePatchesNumber]; double[][] aT = new double[observablePatchesNumber][]; for (int i = 0; i < aT.Length; i++) { aT[i] = new double[allPhases]; } for (int i = 0; i < aT.Length; i++) { for (int j = 0; j < aT[i].Length; j++) { aT[i][j] = a[j][i]; } } MathLib.Basic.ATrA(ref a, ref aTa); for (int i = 0; i < aTa.Length; i++) { aTa[i][i] += regPar; } MathLib.Basic.AMultB(ref aT, ref f, ref aTf); x = MathLib.LES_Solver.SolveWithGaussMethod(aTa, aTf); //MathLib.LES_Solver.ConvGradMethodPL(ref aTa, ref aTf, ref x, 1e+10); { int k = 0; for (int i = 0; i < observableLatBeltsNumber; i++) { for (int j = 0; j < this.magSrfRes.Patches[i].Length; j++) { this.magSrfRes.SetDensity(i, j, x[k]); k++; } } } }