コード例 #1
0
ファイル: ACA.cs プロジェクト: Yapko/ACASparseMatrix
        /// <summary>
        /// Compress Z submatrix with multilevel subdivision
        /// </summary>
        /// <param name="basicFuncBoxes">Information about the location of basis functions in boxes at different levels</param>
        /// <param name="ix_s">x-index of source box at level l</param>
        /// <param name="iy_s">y-index of source box at level l</param>
        /// <param name="iz_s">z-index of source box at level l</param>
        /// <param name="ix_f">x-index of field box at level l</param>
        /// <param name="iy_f">y-index of field box at level l</param>
        /// <param name="iz_f">z-index of field box at level l</param>
        /// <param name="l">Current level</param>
        /// <param name="L">Maximum level to end multilevel subdivion</param>
        /// <param name="ACA_thres">Relative error threshold to stop adding rows and columns in ACA iteration</param>
        /// <param name="Z_comp">compressed matrix</param>                          
        public static void MultilevelCompres(BasicFuncBoxes basicFuncBoxes, double ix_s, double iy_s, double iz_s, double ix_f, double iy_f, double iz_f, int l, double L, double ACA_thres,ref NewSparseMatrix Z_comp)
        {
            bool sym_source_field = true;
            //NewSparseMatrix Z_comp = new NewSparseMatrix();

            for (double xchs = 0; xchs <= 1; xchs++)
            {
                for (double ychs = 0; ychs <= 1; ychs++)
                {
                    for (double zchs = 0; zchs <= 1; zchs++)
                    {
                        // x-index of source child box at level l+1
                        double ix_chs = ix_s * 2 + xchs;
                        // y-index of source child box at level l+1
                        double iy_chs = iy_s * 2 + ychs;
                        // z-index of source child box at level l+1
                        double iz_chs = iz_s * 2 + zchs;

                        //Find indices of basis functions in source child box
                        List<int> m = new List<int>();
                        for (int i = 0; i < basicFuncBoxes.X.RowCount; i++)
                        {
                            if (basicFuncBoxes.X[i, l] == ix_chs && basicFuncBoxes.Y[i, l] == iy_chs && basicFuncBoxes.Z[i, l] == iz_chs)
                            {
                                m.Add(i);
                            }
                        }
                        if (m.Count == 0)
                        {
                            continue;
                        }

                        //Subdivide field box and process children
                        for (double xchf = 0; xchf <= 1; xchf++)
                        {
                            for (double ychf = 0; ychf <= 1; ychf++)
                            {
                                for (double zchf = 0; zchf <= 1; zchf++)
                                {
                                    //x-index of field child box at level l+1
                                    double ix_chf = ix_f * 2 + xchf;
                                    // y-index of field child box at level l+1
                                    double iy_chf = iy_f * 2 + ychf;
                                    // z-index of field child box at level l+1
                                    double iz_chf = iz_f * 2 + zchf;

                                    //Find indices of testing functions in field child box
                                    List<int> n = new List<int>();
                                    for (int i = 0; i < basicFuncBoxes.X.RowCount; i++)
                                    {
                                        if (basicFuncBoxes.X[i, l] == ix_chf && basicFuncBoxes.Y[i, l] == iy_chf && basicFuncBoxes.Z[i, l] == iz_chf)
                                        {
                                            n.Add(i);
                                        }
                                    }
                                    if (n.Count == 0)
                                    {
                                        continue;
                                    }

                                    // Here we have a pair of non-empty source and field boxes
                                    if (Math.Abs(ix_chs - ix_chf) > 1 || Math.Abs(iy_chs - iy_chf) > 1 || Math.Abs(iz_chs - iz_chf) > 1)
                                    {// Far-field boxes
                                        if (sym_source_field == true)
                                        {
                                            // Symmetric source-field field-source
                                            // interactions are only computed once.
                                            if (ix_chs - ix_chf > 0 || ix_chs - ix_chf == 0 && iy_chs - iy_chf > 0 || ix_chs - ix_chf == 0 && iy_chs - iy_chf == 0 && iz_chs - iz_chf > 0)
                                            {
                                                //[U,V] = ACA(ACA_thres, m,n, OG_data,EM_data);
                                                DenseMatrix U = new DenseMatrix(1, 1);
                                                DenseMatrix V = new DenseMatrix(1, 1);
                                                Tuple<Matrix,Matrix> r = Aca(ACA_thres, m, n, U, V);
                                                //Z_comp{length(Z_comp)+1} = struct('m',m,'n',n,'comp',1,'self',0,'Z',[] ,'U',U,'V',V);
                                                Z_comp.Add(new ACAStruct(m,n,new DenseMatrix(1,1),r.Item1,r.Item2,1,0));
                                            }
                                        }
                                        else
                                        {
                                            // We need to compute all because there is
                                            // not symmetric interactions
                                            DenseMatrix U = new DenseMatrix(1, 1);
                                            DenseMatrix V = new DenseMatrix(1, 1);
                                            //[U,V] = ACA(ACA_thres, m,n, OG_data,EM_data);
                                            Tuple<Matrix, Matrix> r = Aca(ACA_thres, m, n, U, V);
                                            //Z_comp{length(Z_comp)+1} = struct('m',m,'n',n,'comp',1,'self',0,'Z',[] ,'U',U,'V',V);
                                            Z_comp.Add(new ACAStruct(m, n, new DenseMatrix(1, 1), r.Item1, r.Item2, 1, 0));
                                        }
                                    }
                                    else // Near-field boxes
                                    {
                                         double self = 0;
                                         if (l + 1 == L)
                                         {
                                             if (sym_source_field == true)
                                             {
                                                 // Symmetric source-field field-source
                                                 // interactions are only computed once.
                                                 if (ix_chs - ix_chf == 0 && iy_chs - iy_chf == 0 && iz_chs - iz_chf == 0)
                                                 {
                                                     // Self-interactions
                                                     self = 1;
                                                     // Z_comp{length(Z_comp)+1} = struct('m',m,'n',n,'comp',0,'self',self,'Z', user_impedance(m,n,OG_data,EM_data),'U',[],'V',[]);
                                                     Z_comp.Add(new ACAStruct(m, n, UserImpedance(m, n), new DenseMatrix(1, 1), new DenseMatrix(1, 1), 0, self));
                                                 }
                                                 if (ix_chs - ix_chf > 0 || ix_chs - ix_chf == 0 && iy_chs - iy_chf > 0 || ix_chs - ix_chf == 0 && iy_chs - iy_chf == 0 && iz_chs - iz_chf > 0)
                                                 {
                                                     //Z_comp{length(Z_comp)+1} = struct('m',m,'n',n,'comp',0,'self',self,'Z', user_impedance(m,n,OG_data,EM_data),'U',[],'V',[]);
                                                     Z_comp.Add(new ACAStruct(m, n, UserImpedance(m, n), new DenseMatrix(1, 1), new DenseMatrix(1, 1), 0, self));
                                                 }

                                             }
                                             else
                                             {
                                                 // We need to compute all because there are
                                                 // not symmetric interactions
                                                 if (ix_chs - ix_chf == 0 && iy_chs - iy_chf == 0 && iz_chs - iz_chf == 0)
                                                 {
                                                     // Self-interactions
                                                     self = 1;
                                                 }
                                                 //Z_comp{length(Z_comp)+1} = struct('m',m,'n',n,'comp',0,'self',self,'Z', user_impedance(m,n,OG_data,EM_data),'U',[],'V',[]);
                                                 Z_comp.Add(new ACAStruct(m, n, UserImpedance(m, n), new DenseMatrix(1, 1), new DenseMatrix(1, 1), 0, (int)self));
                                             }

                                         }
                                         else
                                         {
                                             //Z_comp = [Z_comp multilevel_compress(basis_func_boxes,ix_chs,iy_chs,iz_chs,ix_chf,iy_chf,iz_chf,l+1,L,ACA_thres,OG_data,EM_data)];
                                                              //multilevel_compress(basis_func_boxes,ix_s,iy_s,iz_s,ix_f,iy_f,iz_f,l,L,ACA_thres,OG_data,EM_data)
                                             MultilevelCompres(basicFuncBoxes,ix_chs,iy_chs,iz_chs,ix_chf,iy_chf,iz_chf,l+1,L,ACA_thres,ref Z_comp);

                                         }
                                    }

                                }
                            }
                        }
                    }
                }
            }

            //return Z_comp;
        }
コード例 #2
0
ファイル: Program.cs プロジェクト: Yapko/ACASparseMatrix
        static void Main(string[] args)
        {
            BasicFuncBoxes b = new BasicFuncBoxes(10, 10);

            double finest_level_size = 0.25; // Size of finest level (lambdas) of multilevel subdivision
            double ACA_thres = 1e-3;       // Relative error threshold to stop adding rows and columns in ACA iteration
            double precon_radius = 0.15;   // Precondioner size (meters): elements of Z with R < precon_radius
            double tol = 1e-2;             // Convergence tolerance in iterative solver
            double maxN_Z = 5000;

            StreamReader xRead = new StreamReader("X.txt");
            StreamReader yRead = new StreamReader("Y.txt");
            StreamReader zRead = new StreamReader("Z.txt");

            StreamReader jRead = new StreamReader("J.txt");

            Vector rcx;
            Vector rcy;
            Vector rcz;

            String str = xRead.ReadToEnd();

            List<double> lst = new List<double>();

            foreach (string s in str.Split('\t'))
            {
                lst.Add(double.Parse(s));
            }

            rcx = new DenseVector(lst.ToArray());

            str = yRead.ReadToEnd();
            lst.Clear();

            foreach (string s in str.Split('\t'))
            {
                lst.Add(double.Parse(s));
            }

            rcy = new DenseVector(lst.ToArray());

            str = zRead.ReadToEnd();
            lst.Clear();

            foreach (string s in str.Split('\t'))
            {
                lst.Add(double.Parse(s));
            }

            rcz = new DenseVector(lst.ToArray());

            int N = 3072;
            //Fill Z matrix
            if( N <= maxN_Z)
            {
               //Z = user_impedance(1:N, 1:N, OG_data,EM_data);
               List<int> n = new List<int>(N);
               for (int i = 0; i < N; i++)
               {
                   n.Add(i);
               }
               Matrix Z = ACA.UserImpedance(n,n);
               // Copy of uncompressed Z for iterative solver
               //Z_uncomp = cell(1,1);
               NewSparseMatrix Z_uncomp = new NewSparseMatrix();
               Z_uncomp.Add(new ACAStruct(n, n, Z, new DenseMatrix(1, 1), new DenseMatrix(1, 1), 0, 1));
            }
            //CHECKED - OK everything before works well
            BasicFuncBoxes bfb = ACA.PrepareMultilevel(rcx, rcy, rcz, N, finest_level_size);
            NewSparseMatrix Z_comp = new NewSparseMatrix();
            ACA.MultilevelCompres(bfb, 0, 0, 0, 0, 0, 0, 0, bfb.L, ACA_thres, ref Z_comp);

            //testing Multiply(matvec in mathlab)
            Vector J = new DenseVector(3072);
            int k = 0;
            while (jRead.EndOfStream == false)
            {
                string s = jRead.ReadLine();
                string[] a = s.Split(' ');
                int p = 3;
                if (a.Length == 5) p = 2;
                J[k] = double.Parse(a[p].Replace('.',','));
                k++;
            }

            Vector r = Z_comp.Multiply(J, true);
        }