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); }
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); }
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]))); } }
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(); } }
public static Matrix <Complex> CalculateDotProductMatrix(this NearField[] fields) { return(NearField.CalculateDotProductMatrix(fields)); }
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(); } }