Beispiel #1
0
        public Complex[] Decompose(NearField nf, NearFieldType sourceType)
        {
            NearField[] basisFields;
            Complex[]   coefs;

            switch (sourceType)
            {
            case NearFieldType.Incident:
                basisFields = x_basisNF;
                break;

            case NearFieldType.Scattered:
                basisFields = y_basisNF;
                break;

            default:
                basisFields = null;
                throw new Exception("Invalid field type.");
            }

            coefs = new Complex[used_fields];

            for (int i = 0; i < used_fields; ++i)
            {
                coefs[i] = basisFields[i].DotProduct(nf);
            }

            return(coefs);
        }
Beispiel #2
0
        public NearField Compose(Complex[] coef, NearFieldType sourceType)
        {
            if (coef.Length != used_fields)
            {
                throw new Exception(string.Format("The coefficients number ({0}) is not equal to the used basis fields number ({1} of {2})",
                                                  coef.Length, used_fields, basis_size));
            }

            NearField[] inputFields = null;
            NearField   result      = null;

            switch (sourceType)
            {
            case NearFieldType.Incident:
                inputFields = x_basisNF;
                break;

            case NearFieldType.Scattered:
                inputFields = y_basisNF;
                break;
            }

            NearField.op_Assign(ref result, new NearField(inputFields[0].NodesX, inputFields[0].NodesY,
                                                          inputFields[0].StepX, inputFields[0].StepY, inputFields[0].MinX, inputFields[0].MinY,
                                                          inputFields[0].Wavelength));

            for (int i = 0; i < used_fields; ++i)
            {
                NearField.op_Assign(ref result, result + inputFields[i] * coef[i]);
            }

            return(result);
        }
Beispiel #3
0
        private void ReadFields(Stream stream, string dir, ref byte[] buffer)
        {
            string[] in_filenames, out_filenames;
            int[]    in_filenames_byteCount, out_filenames_byteCount;

            string in_dir  = Path.Combine(dir, "IN_FIELDS");
            string out_dir = Path.Combine(dir, "OUT_FIELDS");

            //if (buffer.Length < sizeof(int))
            //    buffer = new byte[sizeof(int)];

            //stream.Read(buffer, 0, sizeof(int));
            //basis_size = BitConverter.ToInt32(buffer, 0);

            in_filenames            = new string[basis_size];
            out_filenames           = new string[basis_size];
            in_filenames_byteCount  = new int[in_filenames.Length];
            out_filenames_byteCount = new int[out_filenames.Length];

            in_filenames_byteCount.AsByteArray(bytes => stream.Read(bytes, 0, bytes.Length));
            out_filenames_byteCount.AsByteArray(bytes => stream.Read(bytes, 0, bytes.Length));

            int max_size = Math.Max(in_filenames_byteCount.Max <int>(), out_filenames_byteCount.Max <int>());

            if (buffer.Length < max_size)
            {
                buffer = new byte[max_size];
            }

            for (int i = 0; i < basis_size; i++)
            {
                stream.Read(buffer, 0, in_filenames_byteCount[i]);
                in_filenames[i] = Encoding.Unicode.GetString(buffer, 0, in_filenames_byteCount[i]);
            }

            for (int i = 0; i < basis_size; i++)
            {
                stream.Read(buffer, 0, out_filenames_byteCount[i]);
                out_filenames[i] = Encoding.Unicode.GetString(buffer, 0, out_filenames_byteCount[i]);
            }

            x_basisNF = new NearField[basis_size];
            y_basisNF = new NearField[basis_size];
            for (int i = 0; i < basis_size; i++)
            {
                NearField.op_Assign(ref x_basisNF[i], new NearField(Path.Combine(in_dir, in_filenames[i])));
                NearField.op_Assign(ref y_basisNF[i], new NearField(Path.Combine(out_dir, out_filenames[i])));
            }
        }
Beispiel #4
0
        public NearField Compose(Vector <Complex> coefs, NearFieldType sourceType, NearField[] nonBasisFields)
        {
            if (coefs.Count != used_fields)
            {
                throw new Exception(string.Format("The coefficients number ({0}) is not equal to the used basis fields number ({1} of {2})",
                                                  coefs.Count, used_fields, basis_size));
            }

            NearField        result           = null;
            Matrix <Complex> conversion_coefs = null;

            switch (sourceType)
            {
            case NearFieldType.Incident:
                conversion_coefs = Matrix <Complex> .Build.DenseOfRowArrays(conv_coefs_inc);

                break;

            case NearFieldType.Scattered:
                conversion_coefs = Matrix <Complex> .Build.DenseOfRowArrays(conv_coefs_scat);

                break;
            }

            NearField.op_Assign(ref result, new NearField(nonBasisFields[0].NodesX, nonBasisFields[0].NodesY,
                                                          nonBasisFields[0].StepX, nonBasisFields[0].StepY, nonBasisFields[0].MinX, nonBasisFields[0].MinY,
                                                          nonBasisFields[0].Wavelength));

            if (used_fields < basis_size)
            {
                conversion_coefs = conversion_coefs.SubMatrix(0, conversion_coefs.RowCount, 0, used_fields);
            }


            Vector <Complex> res = conversion_coefs * coefs;

            for (int i = 0; i < used_fields; ++i)
            {
                NearField.op_Assign(ref result, result + nonBasisFields[i] * res[i]);
            }

            return(result);
        }
        public Basis(string[] x_inputFields, string[] y_inputFields, int f_count)
        {
            // Возможно, стоит сделать всё в блоках try-finally
            NearField[] x_fields, y_fields;

            x_fields = new NearField[x_inputFields.Length];
            y_fields = new NearField[y_inputFields.Length];

            for (int i = 0; i < x_inputFields.Length; i++)
            {
                NearField.op_Assign(ref x_fields[i], new NearField(x_inputFields[i]));
                NearField.op_Assign(ref y_fields[i], new NearField(y_inputFields[i]));
            }

            BuildBasis(x_fields, y_fields, f_count);

            for (int i = 0; i < x_fields.Length; i++)
            {
                x_fields[i].Dispose();
                y_fields[i].Dispose();
            }
        }
Beispiel #6
0
 public static Matrix <Complex> CalculateDotProductMatrix(this NearField[] fields)
 {
     return(NearField.CalculateDotProductMatrix(fields));
 }
Beispiel #7
0
 public static Complex[][] CalculateDotProductArray(this NearField[] fields)
 {
     return(NearField.CalculateDotProductArray(fields));
 }
        //private void SaveFields()
        //{

        //}

        private void BuildBasis(NearField[] x_fields, NearField[] y_fields)
        {
            Matrix <Complex> dotProdX, dotProdY;

            Svd <Complex>    f_x, f_r;
            Matrix <Complex> Wnorm_x, Wnorm_r, R;
            Matrix <Complex> Wnorm_x_Left, Wnorm_x_Right;
            Matrix <Complex> psiMat, fMat;

            if (x_fields.Length != y_fields.Length)
            {
                throw new Exception("Input arrays have different sizes.");
            }

            basis_size = x_fields.Length;

            dotProdX = NearField.CalculateDotProductMatrix(x_fields);
            dotProdY = NearField.CalculateDotProductMatrix(y_fields);

            /* Calculate PSI and F factors */
            f_x     = dotProdX.Svd();
            Wnorm_x = f_x.W.Clone();
            // Normalization
            for (int i = 0; i < Wnorm_x.RowCount; i++)
            {
                Wnorm_x[i, i] = Wnorm_x[i, i].SquareRoot();
            }
            // Check pseudo-inverse
            Wnorm_x = Wnorm_x.PseudoInverse();

            Wnorm_x_Left  = Wnorm_x;
            Wnorm_x_Right = Wnorm_x;

            R   = Wnorm_x_Left * f_x.VT * dotProdY * f_x.U * Wnorm_x_Right;
            f_r = R.Svd();

            Wnorm_r = f_r.W.Clone();
            for (int i = 0; i < Wnorm_r.RowCount; i++)
            {
                Wnorm_r[i, i] = Wnorm_r[i, i].SquareRoot();
            }
            Wnorm_r = Wnorm_r.Inverse();

            psiMat = f_x.U * Wnorm_x_Right * f_r.U;
            //fMat = f_x.U * Wnorm_x * f_r.U * Wnorm_r;
            fMat = psiMat * Wnorm_r;

            /* Save conversion coefficients */
            conv_coefs_inc  = psiMat.ToRowArrays();
            conv_coefs_scat = fMat.ToRowArrays();

            //conv_coefs_inc_mat = psiMat;    // Copy of the reference!
            //conv_coefs_sca_mat = fMat;      // Copy of the reference!

            /* Calculate PSI and F fields */
            x_basisFiles = new string[basis_size];
            y_basisFiles = new string[basis_size];
            x_basisNF    = new NearField[basis_size];
            y_basisNF    = new NearField[basis_size];

            int    nodes_x, nodes_y;
            double step_x, step_y, min_x, min_y, max_x, max_y, wavelength;

            nodes_x    = x_fields[0].NodesX;
            nodes_y    = x_fields[0].NodesY;
            step_x     = x_fields[0].StepX;
            step_y     = x_fields[0].StepY;
            min_x      = x_fields[0].MinX;
            max_x      = x_fields[0].MaxX;
            min_y      = x_fields[0].MinY;
            max_y      = x_fields[0].MaxY;
            wavelength = x_fields[0].Wavelength;

            for (int i = 0; i < basis_size; i++)
            {
                x_basisFiles[i] = string.Format("in_basis_{0}.bin", i.ToString("D3"));
                y_basisFiles[i] = string.Format("out_basis_{0}.bin", i.ToString("D3"));

                NearField.op_Assign(ref x_basisNF[i], new NearField(nodes_x, nodes_y, step_x, step_y, min_x,
                                                                    min_y, wavelength));
                NearField.op_Assign(ref y_basisNF[i], new NearField(nodes_x, nodes_y, step_x, step_y, min_x,
                                                                    min_y, wavelength));
            }

            if (Environment.ProcessorCount > 1) // Multithread
            {
                int i      = 0;
                int pCount = Environment.ProcessorCount;

                Task[] tasks = new Task[pCount];

                for (int p = 0; p < pCount && i < basis_size; ++p, ++i)
                {
                    int index = i;
                    tasks[p] = new Task(new Action(() =>
                    {
                        while (index < basis_size)
                        {
                            for (int j = 0; j < psiMat.RowCount; ++j)
                            {
                                NearField.op_Assign(ref x_basisNF[index], x_basisNF[index] + x_fields[j] * psiMat[j, index]);
                                NearField.op_Assign(ref y_basisNF[index], y_basisNF[index] + y_fields[j] * fMat[j, index]);
                            }

                            index = System.Threading.Interlocked.Increment(ref i);
                        }
                    }));
                }

                --i; // Чтоб не пропустить один файл под номером i = Environment.ProcessorCount

                for (int p = 0; p < pCount; p++)
                {
                    tasks[p].Start();
                }

                Task.WaitAll(tasks);
            }
            else   // Single thread
            {
                for (int i = 0; i < basis_size; i++)
                {
                    for (int j = 0; j < psiMat.RowCount; j++)
                    {
                        NearField.op_Assign(ref x_basisNF[i], x_basisNF[i] + x_fields[j] * psiMat[j, i]);
                        NearField.op_Assign(ref y_basisNF[i], y_basisNF[i] + y_fields[j] * fMat[j, i]);
                    }
                }
            }

            wElems = f_r.W.Diagonal().ToArray();
            for (int i = 0; i < wElems.Length; i++)
            {
                wElems[i] = wElems[i].SquareRoot();
            }
        }