public void StRayAlgo()//straight ray algorithm { if (_result.Count == 0) { _result.Clear(); } int n_d = _initialDiffusivity.Count; //he number of cells, it equals the number of columns of matrix A int n_t = _tProcessed.Count; //the number of travel times, it equals the number of rows of matrix A // b=Ax, x->x2 // consider b as time, A as distance, x as speed double xMax = 1.0 / (Math.Sqrt(_iP.MinD)); // set the constraint, the max of x, x=1/(root of diffusivity) double xMin = 1.0 / (Math.Sqrt(_iP.MaxD)); // set the constraint, the min of x, x=1/(root of diffusivity) List <double> estimatedD = _initialDiffusivity.ToList(); Vector <double> x = Vector <double> .Build.Dense(n_d, 1); for (int i = 0; i < n_d; i++) { x[i] = 1.0 / (Math.Sqrt(estimatedD[i]));//the speed vector, x=1/(root of diffusivity) } #region int iter = 0; double RMS = _iP.CriRMS + 1; while (iter <_iP.StrRay& RMS> _iP.CriRMS) { //STEP 1 SIRT_Result_StraightRay Record = new SIRT_Result_StraightRay(); Record.Iter = iter; Record.OldProcessedD = x.ToList(); //==================================================== //STEP 2 : Set matrix A Matrix <double> A = Matrix <double> .Build.Dense(n_t, n_d, 0); for (int row = 0; row < n_t; row++) { Inv_SRInfoLine infoLine = (Inv_SRInfoLine)_table.SRInfoLineList[row]; MathNet.Spatial.Euclidean.Point2D PStart = new MathNet.Spatial.Euclidean.Point2D(infoLine.Start.Coor[0], infoLine.Start.Coor[2]); MathNet.Spatial.Euclidean.Point2D PEnd = new MathNet.Spatial.Euclidean.Point2D(infoLine.End.Coor[0], infoLine.End.Coor[2]); MathNet.Spatial.Euclidean.Line2D Traj = new MathNet.Spatial.Euclidean.Line2D(PStart, PEnd); for (int col = 0; col < n_d; col++) { CohenSutherland coh = new CohenSutherland(); List <MathNet.Spatial.Euclidean.Point2D> Ps = coh.CohenSutherlandLineClip(_fRs[col], PStart, PEnd).ToList(); if (Ps.Count > 1) { A[row, col] = Ps[0].DistanceTo(Ps[1]); } } } Record.A = A.Clone(); Record.ProcessedTime = (A * x).ToList(); //==================================================== //STEP 3 : set the start node and the end node from Record foreach (object obj in _table.SRInfoLineList) { Inv_SRInfoLine infoLine = (Inv_SRInfoLine)obj; Record.Start.Add(infoLine.Start); Record.End.Add(infoLine.End); } //==================================================== //STEP 4 : cimmino calculation Vector <double> b = Vector <double> .Build.DenseOfArray(_tProcessed.ToArray()); SIRT_Options so = new SIRT_Options(b, A, x, 1);// b=Ax Vector <double> x2 = so.XUpdaterDROP(x, 1); //==================================================== //STEP 7 : update x and diffusivity for next iteration x = x2.Clone(); for (int i = 0; i < n_d; i++) { if (x[i] < conMinX[i]) { x[i] = conMinX[i]; } if (x[i] > conMaxX[i]) { x[i] = conMaxX[i]; } } Record.NewProcessedD = x.ToList(); //==================================================== _result.Add(Record);//output iter = iter + 1; } #endregion }
//下面是SIRT主程序//the main function of SIRT public void SIRT_2() { _sbSIRT_2.Clear(); //======================================================================== List <Edge> sirt_edges = Dij_0(_nodesInv);//将以距离作为单位的edge包装好,准备调用//prepair the edge //======================================================================== Dictionary <string, NodesInversion> sirt_nodesinv = new Dictionary <string, NodesInversion>(); foreach (NodesInversion n in _nodesInv)//将nodesInv包装好,适合通过name调用//prepair the nodesInv, for usage by name { sirt_nodesinv.Add(n.Name, n); } //======================================================================== int n_d = _diffusivity.Count; //距离矩阵A的列数,D的数量//the number of columns in A, equals the number of D int n_t = _tProcessed.Count; //距离矩阵A的行数,T的数量//the number of rows in A, equals the number of T #region _sbSIRT_2.Append("TomoGo 1.01" + "\r\n"); _sbSIRT_2.Append("f: " + _table.F_alpha_d.ToString() + "\r\n"); _sbSIRT_2.Append("count of D (col of distance-matrix A): " + n_d.ToString() + "\r\n"); _sbSIRT_2.Append("count of T (row of distance-matrix A): " + n_t.ToString() + "\r\n"); _sbSIRT_2.Append("Initial Diffusivity:\r\n"); foreach (double d in _diffusivity) { _sbSIRT_2.Append(d.ToString("N") + " "); } _sbSIRT_2.Append("\r\n" + "------------------------------------" + "\r\n"); _sbSIRT_2.Append("Initial x=1/sqrt(D):\r\n"); foreach (double d in _diffusivity) { _sbSIRT_2.Append((1 / Math.Sqrt(d)).ToString("N") + " "); } _sbSIRT_2.Append("\r\n" + "------------------------------------" + "\r\n"); _sbSIRT_2.Append("Measured Travel Time t:\r\n"); foreach (double t in _tMeasured) { _sbSIRT_2.Append(t.ToString("N") + " "); } _sbSIRT_2.Append("\r\n" + "------------------------------------" + "\r\n"); _sbSIRT_2.Append("Measured b = sqrt(6*f*t or 4*f*t):\r\n"); foreach (double t in _tProcessed) { _sbSIRT_2.Append(t.ToString("N") + " "); } _sbSIRT_2.Append("\r\n" + "------------------------------------" + "\r\n"); #endregion //==================================================================== // initialize b = sqrt(6*f*t or4*f*t) Vector <double> b = Vector <double> .Build.DenseOfArray(_tProcessed.ToArray()); // initialize x, x=1/(root of diffusivity) Vector <double> x = Vector <double> .Build.Dense(_diffusivity.Count, 1); for (int i = 0; i < _diffusivity.Count; i++) { x[i] = 1.0 / (Math.Pow(_diffusivity[i], 0.5)); } List <double> diffusivity = _diffusivity.ToList(); //================================================================ #region int iter = 0; double RMS = _iP.CriRMS + 1; while (iter <_iP.CurRay& RMS> _iP.CriRMS) { SIRT_Result si_R = new SIRT_Result(); si_R.Iter = iter; //将用时写入output中//wirte traveltime into output //================================================================ si_R.GuessDiffusivity = diffusivity.ToList(); //将Guess的D写入output中//write D of Guess into output //================================================================ #region _sbSIRT_2.Append("************************************" + "\r\n"); _sbSIRT_2.Append("********** iteration: " + iter.ToString() + " **********" + "\r\n"); _sbSIRT_2.Append("************************************" + "\r\n"); _sbSIRT_2.Append("Input Diffusivity: " + "\r\n"); foreach (double d in diffusivity) { _sbSIRT_2.Append(d.ToString("N") + " "); } _sbSIRT_2.Append("\r\n" + "------------------------------------" + "\r\n"); //=============================================================== _sbSIRT_2.Append("************************************" + "\r\n"); _sbSIRT_2.Append("********** iteration: " + iter.ToString() + " **********" + "\r\n"); _sbSIRT_2.Append("************************************" + "\r\n"); _sbSIRT_2.Append("d_cori: " + "\r\n"); foreach (double d in diffusivity) { _sbSIRT_2.Append(d.ToString("N") + " "); } _sbSIRT_2.Append("\r\n" + "------------------------------------" + "\r\n"); #endregion //=============================================================== //STEP 0 List <Dijkstra_output> dij_outputs = Dij_1b(_nodesInv, diffusivity, _table); //每次迭代产生的Dijkstra算法的结果//the result of Dijkstra algorithm after every iteration si_R.Dijk_output = dij_outputs.ToList(); //将用时写入output中//write traveltime into output #region foreach (Dijkstra_output n in dij_outputs) { _sbSIRT_2.Append(n.print()); } #endregion //==================================================== //STEP 1 //通过对Dijkstra Algorithm结果的逐行分析,设置距离矩阵。 //analyze the Dijkstra algorithm result, set the distance matrix A Matrix <double> A = Matrix <double> .Build.Dense(n_t, n_d, 0); #region int row = 0; foreach (Dijkstra_output dij_single in dij_outputs)//对Dij算法的结果逐行分析//Dijkstra result analysis { List <Node> path = dij_single.Path; if (path.Count < 2) { MessageBox.Show("error in path.count in SIRT_2"); } for (int i = 0; i < path.Count - 1; i++) { Node n0 = path[i]; Node n1 = path[i + 1]; NodesInversion n0_inv = sirt_nodesinv[n0.Name]; NodesInversion n1_inv = sirt_nodesinv[n1.Name]; List <int> union = n0_inv.union(n1_inv); if (union != null) { foreach (Edge e in sirt_edges) { if (e.Origin.equals(n0) && e.Destination.equals(n1)) { A[row, union[0]] = e.Distance; break; } } } } row = row + 1; } #endregion _sbSIRT_2.Append("***** Ax=b, x->x2*****\r\n"); _sbSIRT_2.Append("A: \r\n" + A.ToString() + "\r\n------------------------------------\r\n"); //==================================================== _sbSIRT_2.Append("x: \r\n" + x.ToString() + "\r\n------------------------------------\r\n"); //==================================================== //STEP 3 : calculate c=Ax //计算用时//calculate the traveltime Vector <double> c = A * x; #region _sbSIRT_2.Append("c=A*x: " + "\r\n"); _sbSIRT_2.Append(c.ToString("N") + " "); _sbSIRT_2.Append("\r\n" + "------------------------------------" + "\r\n"); #endregion //==================================================== //TEST: //从Dijkstra中提取时间, compare the time with Step 4 where the time is from A*x //get traveltime from Dijkstra, compare the time with Step 4 where the time is from A*x double[] t_dijkstra = new double[n_t]; for (int i = 0; i < n_t; i++) { t_dijkstra[i] = dij_outputs[i].TravelTime; } #region _sbSIRT_2.Append("t_dijkstra: " + "\r\n"); foreach (double dou in t_dijkstra) { _sbSIRT_2.Append(dou.ToString("N") + " "); } _sbSIRT_2.Append("\r\n" + "------------------------------------" + "\r\n"); _sbSIRT_2.Append("real time from dijkstra: " + "\r\n"); foreach (double dou in t_dijkstra) { _sbSIRT_2.Append((dou * dou / (_table.F_alpha_d * _table.DimFactor)).ToString("N") + " "); } _sbSIRT_2.Append("\r\n" + "------------------------------------" + "\r\n"); #endregion //==================================================== //STEP 4 //计算时间差//calculate the delta t double[] realTimeList = new double[n_t]; //转换时间为真实的时间 //transfer to real time for (int i = 0; i < n_t; i++) { double realTime = Math.Pow(c[i], 2) / ((double)_table.DimFactor * (double)_table.F_alpha_d); //the realtime realTimeList[i] = realTime; si_R.Time.Add(realTime); //将用时写入output中//wirte traveltime into output } Statistic stc = new Statistic(); RMS = stc.RMS(new List <double>(realTimeList), _tMeasured); #region _sbSIRT_2.Append("Real Time from c=A*x: " + "\r\n"); foreach (double rt in realTimeList) { _sbSIRT_2.Append(rt.ToString("N") + " "); } _sbSIRT_2.Append("\r\n" + "------------------------------------" + "\r\n"); _sbSIRT_2.Append("RMS Residual: " + RMS.ToString("N")); _sbSIRT_2.Append("\r\n" + "------------------------------------" + "\r\n"); #endregion //==================================================== //STEP 6 SIRT_Options so = new SIRT_Options(b, A, x, 1); Vector <double> x2; switch (_iP.SIRTOption) { case 1: x2 = so.XUpdaterDROP(x, 1); //use the DROP method break; case 2: x2 = so.XUpdaterCAV(x, 1); //use the CAV method break; case 3: x2 = so.XUpdaterCimmino(x, 1); //use the Cimmino method break; default: x2 = x.Clone(); // no update break; } #region _sbSIRT_2.Append("x2: " + "\r\n"); _sbSIRT_2.Append(x2.ToString("N") + " "); _sbSIRT_2.Append("\r\n" + "------------------------------------" + "\r\n"); #endregion //==================================================== //STEP 7: update x and diffusivity x = x2.Clone(); for (int i = 0; i < n_d; i++) { if (x[i] < conMinX[i]) { x[i] = conMinX[i]; } if (x[i] > conMaxX[i]) { x[i] = conMaxX[i]; } diffusivity[i] = 1.0 / (x[i] * x[i]); } #region _sbSIRT_2.Append("x after Min&Max filter: " + "\r\n"); _sbSIRT_2.Append(x.ToString("N") + " "); _sbSIRT_2.Append("\r\n" + "------------------------------------" + "\r\n"); _sbSIRT_2.Append("diffusivity after Min&Max filter: " + "\r\n"); foreach (double dou in diffusivity) { _sbSIRT_2.Append(dou.ToString("N") + " "); } _sbSIRT_2.Append("\r\n" + "------------------------------------" + "\r\n"); #endregion //==================================================== iter = iter + 1; //==================================================== _sbSIRT_2.Append("====================================\r\n"); si_R.UpdatedDiffusivity = diffusivity.ToList(); //write the result into output _sirt_Res.Add(si_R); //write the result into output } #endregion //================================================================ // iteration is finished _diffusivity = diffusivity.ToList();//update the diffusivity //to check the result in txt file, see below //System.IO.File.WriteAllText("Inversion-Network-SIRT2.txt", sbPrint.ToString()); //System.IO.File.WriteAllText("Inversion-Network-SIRT2-Dijk.txt", _sbSIRT_2.ToString()); }