Esempio n. 1
0
        //-------------------------------

        //-------------------------------
        //下面的函数用来计算m和n之间的连线所在的Element
        //the following function is used to identify the cell where the node m, n and their connection stay.
        public List <int> union(NodesInversion n)
        {
            List <int> output = new List <int>();
            //限定:连线只能处于一个Element中
            //constraint: the connection between nodes can only be in one cell
            List <int> Draund = new List <int>();

            Draund.Add(_daround[0, 0]); Draund.Add(_daround[0, 1]); Draund.Add(_daround[1, 0]); Draund.Add(_daround[1, 1]);
            List <int> nDraund = new List <int>();

            nDraund.Add(n.Daround[0, 0]); nDraund.Add(n.Daround[0, 1]); nDraund.Add(n.Daround[1, 0]); nDraund.Add(n.Daround[1, 1]);
            foreach (int i in Draund)
            {
                foreach (int j in nDraund)
                {
                    if (i == j && i != -1)
                    {
                        output.Add(i);
                        nDraund.Remove(j);
                        break;
                    }
                }
            }
            return(output);//output=null表示没有union的element// output=null means there isn't any joint cell
        }
        //下面是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());
        }
        //================================================================
        //下面的程序是用来将Grid后的数据类型转换成Dijkstra算法需要的数据类型;
        //the following function is utilized to transfer Grid data into the data format, which is suitable for Dijkstra
        //8 nodes in each cell
        public List <NodesInversion> NodesGenerator8()
        {
            //nx is the number of cells in x direction
            //nz is the number of cells in z direction

            _sbNodes.Clear();

            List <NodesInversion> List = new List <NodesInversion>();

            //MessageBox.Show(domain[0].ToString()+"  "+domain[1].ToString()+"  "+domain[2].ToString()+"  "+domain[3].ToString()+"  ");
            if (_domain.GetLength(0) != 4 || _nx < 1 || _nz < 1)
            {
                MessageBox.Show("Parameter error in NodesGenerator8");
            }


            //add common nodes
            int nodescount = 2 * _nx * (_nz + 1) + 2 * _nz * (_nx + 1);

            for (int i = 0; i < nodescount; i++)
            {
                NodesInversion ninv = new NodesInversion();
                ninv.Name = i.ToString();
                List.Add(ninv);
            }
            //设置横向的nodes//set the nodes in x direction
            #region
            for (int i = 0; i < _fRs.Count; i++)
            {
                //下面是设置左上角的node,它下方相邻的矩形是L中的第i个矩形
                List[i * 2].Type          = NodesInversion.NodesType.NormalNode;
                List[i * 2].Coor[0]       = _fRs[i].Xleft * (2f / 3f) + _fRs[i].Xright * (1f / 3f);
                List[i * 2].Coor[1]       = _fRs[i].Zup;
                List[i * 2].Daround[1, 0] = i;
                List[i * 2].Daround[1, 1] = i;
                //下面是设置右上角的node,它下方相邻的矩形是L中的第i个矩形
                List[i * 2 + 1].Type          = NodesInversion.NodesType.NormalNode;
                List[i * 2 + 1].Coor[0]       = _fRs[i].Xleft * (1f / 3f) + _fRs[i].Xright * (2f / 3f);
                List[i * 2 + 1].Coor[1]       = _fRs[i].Zup;
                List[i * 2 + 1].Daround[1, 0] = i;
                List[i * 2 + 1].Daround[1, 1] = i;
                //下面是设置左下角的node,它上方相邻的矩形是L中的第i个矩形
                List[i * 2 + 2 * _nx].Type          = NodesInversion.NodesType.NormalNode;
                List[i * 2 + 2 * _nx].Coor[0]       = _fRs[i].Xleft * (2f / 3f) + _fRs[i].Xright * (1f / 3f);
                List[i * 2 + 2 * _nx].Coor[1]       = _fRs[i].Zdown;
                List[i * 2 + 2 * _nx].Daround[0, 0] = i;
                List[i * 2 + 2 * _nx].Daround[0, 1] = i;
                //下面是设置右下角的node,它上方相邻的矩形是L中的第i个矩形
                List[i * 2 + 2 * _nx + 1].Type          = NodesInversion.NodesType.NormalNode;
                List[i * 2 + 2 * _nx + 1].Coor[0]       = _fRs[i].Xleft * (1f / 3f) + _fRs[i].Xright * (2f / 3f);
                List[i * 2 + 2 * _nx + 1].Coor[1]       = _fRs[i].Zdown;
                List[i * 2 + 2 * _nx + 1].Daround[0, 0] = i;
                List[i * 2 + 2 * _nx + 1].Daround[0, 1] = i;
            }
            #endregion
            //设置竖向的nodes//set the nodes in z direction
            #region

            int m     = 2 * _nx * (_nz + 1);   //已用nodes数量,在上面一个region中已经标记的nodes的数量
            int count = 0;                     //用来计数,表明在下面双重循环的次数
            for (int i = 0; i < _nx; i++)      //大循环,下标第二位
            {
                for (int j = 0; j < _nz; j++)  //小循环,下标第一位
                {
                    int D     = j * _nx + i;   //设置D的序号
                    int node0 = m + 2 * count; //左上角第一个node
                    //MessageBox.Show("i="+i.ToString()+" j="+j.ToString()+"  D="+D.ToString()+"  node0="+node0.ToString());
                    //下面是左上角node的设置
                    List[node0].Type          = NodesInversion.NodesType.NormalNode;
                    List[node0].Coor[0]       = _fRs[D].Xleft;
                    List[node0].Coor[1]       = _fRs[D].Zup * (2f / 3f) + _fRs[D].Zdown * (1f / 3f);
                    List[node0].Daround[0, 1] = D; //右边相邻的矩形是L中第D个矩形
                    List[node0].Daround[1, 1] = D; //右边相邻的矩形是L中第D个矩形
                    //下面是右上角node的设置
                    List[node0 + 1].Type          = NodesInversion.NodesType.NormalNode;
                    List[node0 + 1].Coor[0]       = _fRs[D].Xleft;
                    List[node0 + 1].Coor[1]       = _fRs[D].Zup * (1f / 3f) + _fRs[D].Zdown * (2f / 3f);
                    List[node0 + 1].Daround[0, 1] = D; //左边相邻的矩形是L中第D个矩形
                    List[node0 + 1].Daround[1, 1] = D; //左边相邻的矩形是L中第D个矩形
                    //下面是左下角node的设置
                    List[node0 + 2 * _nz].Type          = NodesInversion.NodesType.NormalNode;
                    List[node0 + 2 * _nz].Coor[0]       = _fRs[D].Xright;
                    List[node0 + 2 * _nz].Coor[1]       = _fRs[D].Zup * (2f / 3f) + _fRs[D].Zdown * (1f / 3f);
                    List[node0 + 2 * _nz].Daround[0, 0] = D; //右边相邻的矩形是L中第D个矩形
                    List[node0 + 2 * _nz].Daround[1, 0] = D; //右边相邻的矩形是L中第D个矩形
                    //下面是右下角node的设置
                    List[node0 + 2 * _nz + 1].Type          = NodesInversion.NodesType.NormalNode;
                    List[node0 + 2 * _nz + 1].Coor[0]       = _fRs[D].Xright;
                    List[node0 + 2 * _nz + 1].Coor[1]       = _fRs[D].Zup * (1f / 3f) + _fRs[D].Zdown * (2f / 3f);
                    List[node0 + 2 * _nz + 1].Daround[0, 0] = D; //左边相邻的矩形是L中第D个矩形
                    List[node0 + 2 * _nz + 1].Daround[1, 0] = D; //左边相邻的矩形是L中第D个矩形

                    count = count + 1;
                }
            }

            #endregion
            // set S
            #region
            List <NodesInversion> List_temp = new List <NodesInversion>();
            //MessageBox.Show(table.Sset.Count.ToString());
            foreach (Inv_SR3D sender in _table.Sset)
            {
                bool criterium = false;
                foreach (NodesInversion sender2 in List)
                {
                    if (sender.Coor[0] == sender2.Coor[0] && sender.Coor[2] == sender2.Coor[1])
                    {
                        sender2.Name = sender2.Name + "(" + sender.Name + ")"; break;
                    }
                    else
                    {
                        criterium = true;
                    }
                }
                if (criterium)
                {
                    NodesInversion newnode = new NodesInversion();
                    newnode.Name    = sender.Name;
                    newnode.Type    = NodesInversion.NodesType.Sender;
                    newnode.Coor[0] = sender.Coor[0];
                    newnode.Coor[1] = sender.Coor[2];
                    for (int i = 0; i < _fRs.Count; i++)
                    {
                        int k = _fRs[i].Location(newnode.Coor[0], newnode.Coor[1]);

                        switch (k)
                        {
                        case -1: MessageBox.Show("error by using rechtsangle.loction"); break;

                        case 0: newnode.Daround[1, 1] = i; break;

                        case 1: newnode.Daround[1, 0] = i; newnode.Daround[1, 1] = i; break;

                        case 2: newnode.Daround[1, 0] = i; break;

                        case 3: newnode.Daround[0, 1] = i; newnode.Daround[1, 1] = i; break;

                        case 4: newnode.Daround[0, 0] = i; newnode.Daround[0, 1] = i; newnode.Daround[1, 0] = i; newnode.Daround[1, 1] = i; break;

                        case 5: newnode.Daround[0, 0] = i; newnode.Daround[1, 0] = i; break;

                        case 6: newnode.Daround[0, 1] = i; break;

                        case 7: newnode.Daround[0, 0] = i; newnode.Daround[0, 1] = i; break;

                        case 8: newnode.Daround[0, 0] = i; break;

                        case 9: break;
                        }
                    }
                    List_temp.Add(newnode);
                }
            }

            #endregion
            //set R
            #region
            foreach (Inv_SR3D rec in _table.Rset)
            {
                bool criterium = false;
                foreach (NodesInversion rec2 in List)
                {
                    if (rec.Coor[0] == rec2.Coor[0] && rec.Coor[2] == rec2.Coor[1])
                    {
                        rec2.Name = rec2.Name + "(" + rec.Name + ")"; break;
                    }
                    else
                    {
                        criterium = true;
                    }
                }
                if (criterium)
                {
                    NodesInversion newnode = new NodesInversion();
                    newnode.Name    = rec.Name;
                    newnode.Type    = NodesInversion.NodesType.Receiver;
                    newnode.Coor[0] = rec.Coor[0];
                    newnode.Coor[1] = rec.Coor[2];
                    for (int i = 0; i < _fRs.Count; i++)
                    {
                        //MessageBox.Show(i.ToString());
                        int k = _fRs[i].Location(newnode.Coor[0], newnode.Coor[1]);
                        switch (k)
                        {
                        case -1: MessageBox.Show("error by using rechtsangle.loction"); break;

                        case 0: newnode.Daround[1, 1] = i; break;

                        case 1: newnode.Daround[1, 0] = i; newnode.Daround[1, 1] = i; break;

                        case 2: newnode.Daround[1, 0] = i; break;

                        case 3: newnode.Daround[0, 1] = i; newnode.Daround[1, 1] = i; break;

                        case 4: newnode.Daround[0, 0] = i; newnode.Daround[0, 1] = i; newnode.Daround[1, 0] = i; newnode.Daround[1, 1] = i; break;

                        case 5: newnode.Daround[0, 0] = i; newnode.Daround[1, 0] = i; break;

                        case 6: newnode.Daround[0, 1] = i; break;

                        case 7: newnode.Daround[0, 0] = i; newnode.Daround[0, 1] = i; break;

                        case 8: newnode.Daround[0, 0] = i; break;

                        case 9: break;
                        }
                    }
                    List_temp.Add(newnode);
                }
            }
            #endregion
            //copy S and R into the List
            foreach (NodesInversion n in List_temp)
            {
                List.Add(n);
            }
            //
            foreach (NodesInversion t in List)
            {
                _sbNodes.Append(t.print(1));
            }
            return(List);
        }