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());
        }