/// <summary> /// Initializes a new instance of the <see cref="TestableDoubleMatrixDoubleMatrixAddition{TExpected}"/> class. /// </summary> /// <param name="expected">The expected result or exception.</param> /// <param name="left">The left operand.</param> /// <param name="right">The right operand.</param> public TestableDoubleMatrixDoubleMatrixAddition( TExpected expected, TestableDoubleMatrix left, TestableDoubleMatrix right) : base( expected, left, right, leftWritableRightWritableOps: new Func <DoubleMatrix, DoubleMatrix, DoubleMatrix>[2] { (l, r) => l + r, (l, r) => DoubleMatrix.Add(l, r) }, leftReadOnlyRightWritableOps: new Func <ReadOnlyDoubleMatrix, DoubleMatrix, DoubleMatrix>[2] { (l, r) => l + r, (l, r) => ReadOnlyDoubleMatrix.Add(l, r) }, leftWritableRightReadOnlyOps: new Func <DoubleMatrix, ReadOnlyDoubleMatrix, DoubleMatrix>[2] { (l, r) => l + r, (l, r) => ReadOnlyDoubleMatrix.Add(l, r) }, leftReadOnlyRightReadOnlyOps: new Func <ReadOnlyDoubleMatrix, ReadOnlyDoubleMatrix, DoubleMatrix>[2] { (l, r) => l + r, (l, r) => ReadOnlyDoubleMatrix.Add(l, r) } ) { }
public void Main() { // Create the left operand. var data = new double[6] { 0, 2, 4, 1, 3, 5, }; var left = DoubleMatrix.Dense(2, 3, data, StorageOrder.RowMajor); Console.WriteLine("left ="); Console.WriteLine(left); // Create the right operand. data = new double[6] { 0, 20, 40, 10, 30, 50, }; var right = DoubleMatrix.Dense(2, 3, data, StorageOrder.RowMajor); Console.WriteLine("right ="); Console.WriteLine(right); // Compute the sum of left and right. var result = left + right; Console.WriteLine(); Console.WriteLine("left + right ="); Console.WriteLine(result); // In .NET languages that do not support overloaded operators, // you can use the alternative methods named Add. result = DoubleMatrix.Add(left, right); Console.WriteLine(); Console.WriteLine("DoubleMatrix.Add(left, right) returns"); Console.WriteLine(); Console.WriteLine(result); // Both operators and alternative methods are overloaded to // support read-only matrix arguments. // Compute the sum using a read-only wrapper of left. ReadOnlyDoubleMatrix readOnlyLeft = left.AsReadOnly(); result = readOnlyLeft + right; Console.WriteLine(); Console.WriteLine("readOnlyLeft + right ="); Console.WriteLine(result); }
public TestableDoubleScalarDoubleMatrixAddition( TExpected expected, double left, TestableDoubleMatrix right) : base( expected, left, right, leftScalarRightWritableOps: new Func <double, DoubleMatrix, DoubleMatrix>[2] { (l, r) => l + r, (l, r) => DoubleMatrix.Add(l, r) }, leftScalarRightReadOnlyOps: new Func <double, ReadOnlyDoubleMatrix, DoubleMatrix>[2] { (l, r) => l + r, (l, r) => ReadOnlyDoubleMatrix.Add(l, r) } ) { }
public TestableDoubleMatrixComplexScalarAddition( TExpected expected, TestableDoubleMatrix left, Complex right) : base( expected, left, right, leftWritableRightScalarOps: new Func <DoubleMatrix, Complex, ComplexMatrix>[2] { (l, r) => l + r, (l, r) => DoubleMatrix.Add(l, r) }, leftReadOnlyRightScalarOps: new Func <ReadOnlyDoubleMatrix, Complex, ComplexMatrix>[2] { (l, r) => l + r, (l, r) => ReadOnlyDoubleMatrix.Add(l, r) } ) { }
public void MemberAddIncompatible() { DoubleMatrix a = new DoubleMatrix(2); DoubleMatrix b = new DoubleMatrix(3); a.Add(b); }
public void MemberAddNull() { DoubleMatrix a = new DoubleMatrix(2); DoubleMatrix b = null; a.Add(b); }
public void MemberAdd() { DoubleMatrix a = new DoubleMatrix(2); DoubleMatrix b = new DoubleMatrix(2); a[0,0] = b[0,0] = 1; a[0,1] = b[0,1] = 2; a[1,0] = b[1,0] = 3; a[1,1] = b[1,1] = 4; a.Add(b); Assert.AreEqual(a[0,0],2); Assert.AreEqual(a[0,1],4); Assert.AreEqual(a[1,0],6); Assert.AreEqual(a[1,1],8); }
public void Add() { M.Add(2, 1, 100); Assert.AreEqual(121, M[2, 1], 0.001); }
private static void Main(string[] args) { // Параметры программы string inputFileName = "input.csv"; string outputFileName = "output.csv"; double unit = 1.0; double epsilon = 0.0000000001; var nodeList = new StackListQueue <string>(); var matrix = new DoubleMatrix(); // Определение параметров программы for (int i = 0; i < args.Length; i++) { if (string.CompareOrdinal(args[i], "-s") == 0 || string.CompareOrdinal(args[i], "-i") == 0) { inputFileName = args[++i]; } else if (string.CompareOrdinal(args[i], "-d") == 0 || string.CompareOrdinal(args[i], "-o") == 0) { outputFileName = args[++i]; } else if (string.CompareOrdinal(args[i], "-b1") == 0) { unit = 1.0; } else if (string.CompareOrdinal(args[i], "-b100") == 0) { unit = 100.0; } else if (string.CompareOrdinal(args[i], "-e") == 0) { epsilon = Math.Pow(0.1, Int32.ParseAsString(args[++i])); } } // Загрузка матрицы из файла int lines = 0; using (StreamReader reader = File.OpenText(inputFileName)) { // регулярное выражение для разбора полей исходного файла var regex = new Regex(@"\s*(?<from>[^;]+)\s*;\s*(?<to>[^;]+)\s*;\s*(?<value>\d+([,.]\d*)?)\s*"); for (string line = reader.ReadLine();; line = reader.ReadLine()) { lines++; Match match = regex.Match(line); int i = nodeList.IndexOf(match.Groups["from"].Value); if (i == -1) { i = nodeList.Count; if (!nodeList.Any()) { matrix.Add(new DoubleVector { 0.0 }); } else { matrix.AddColumn(); matrix.AddRow(); } nodeList.Add(match.Groups["from"].Value); Debug.WriteLine("Зарегистрирован участник {0} под номером {1}", nodeList.Last(), i); Debug.WriteLine("Текущий размер матрицы {0}x{1}", matrix.Rows, matrix.Columns); } int j = nodeList.IndexOf(match.Groups["to"].Value); if (j == -1) { j = nodeList.Count; matrix.AddColumn(); matrix.AddRow(); nodeList.Add(match.Groups["to"].Value); Debug.WriteLine("Зарегистрирован участник {0} под номером {1}", nodeList.Last(), j); Debug.WriteLine("Текущий размер матрицы {0}x{1}", matrix.Rows, matrix.Columns); } double value = Double.ParseAsString(match.Groups["value"].Value); matrix[i][j] = value / unit; if (reader.EndOfStream) { break; } } reader.Close(); } Console.WriteLine("Прочитано строк = {0}", lines); // Проверка исходных данных Debug.Assert(matrix.Rows == matrix.Columns); Debug.Assert(matrix.All(row => row.All(x => x >= 0.0 - epsilon && x <= 1.0 + epsilon))); int total = Math.Max(matrix.Rows, matrix.Columns); #if DEBUG // Проверка исходных данных for (int i = 0; i < total; i++) { double s = 0.0; for (int j = 0; j < total; j++) { s += matrix[j][i]; } Debug.Assert(s <= 1.0 + epsilon); } #endif // Определение компонент связанности var groupList = new StackListQueue <StackListQueue <int> >(); // Инициализация определения компонент связанности for (int i = 0; i < total; i++) { groupList.Add(new StackListQueue <int> { i }); } for (int i = groupList.Count - 1; i > 0; i--) { for (int j = i - 1; j >= 0; j--) { // Проверяем существование путей из одной группы в другую группу if (DoubleMatrix.IsZero(matrix.SubMatrix(groupList[i], groupList[j])) && DoubleMatrix.IsZero(matrix.SubMatrix(groupList[j], groupList[i]))) { continue; } // Если существует путь между двумя группами // то объединяем группы в одну groupList[j].AddRange(groupList[i]); groupList.RemoveAt(i); Debug.WriteLine("Группа {0} присоеденена к группе {1}", i, j); break; } } Console.WriteLine("Обнаружено {0} групп", groupList.Count); #if DEBUG for (int i = 0; i < groupList.Count; i++) { Debug.WriteLine("Группа #{0}", i); foreach (int j in groupList[i]) { Debug.WriteLine(nodeList[j]); } } #endif using (StreamWriter writer = File.CreateText(outputFileName)) { // Для каждой компоненты связанности foreach (var group in groupList) { int n = group.Count; // Отсекаются группы из одного участника if (n == 1) { continue; } Console.WriteLine("Анализируется группа из {0} участников", n); var e = new DoubleMatrix(n, n); for (int i = 0; i < n; i++) { e[i][i] = 1.0; } // Получение выборки из исходной матрицы E-A DoubleMatrix a = matrix.SubMatrix(group, group); DoubleMatrix b = e - a; #if DEBUG // Сохраняем матрицу для дальнейшей самопроверки var z = new DoubleMatrix(b.Select(row => new DoubleVector(row))); Debug.Assert(z.Rows == n); Debug.Assert(z.Columns == n); #endif // Дописывание к выборке единичной матрицы справа b.AppendColumns(e); Debug.Assert(b.Rows == n); Debug.Assert(b.Columns == 2 * n); // Приведение выборки к каноническому виду преобразованиями по строкам b.GaussJordan( DoubleMatrix.Search.SearchByRows, DoubleMatrix.Transform.TransformByRows, 0, n); Debug.Assert(b.All(row => !DoubleVector.IsZero(new DoubleVector(row.GetRange(0, n))))); // Сортировка строк для приведения канонической матрицы к единичной матрице var dic = new Dictionary <int, DoubleVector>(); for (int i = 0; i < n; i++) { int j = 0; DoubleVector vector = b[i]; while (DoubleVector.IsZero(vector[j])) { j++; } dic.Add(j, vector); } // Получение обратной матрицы для E-A var c = new DoubleMatrix(); for (int i = 0; i < n; i++) { c.Add(new DoubleVector(dic[i].GetRange(n, n))); } #if DEBUG // Проверяем, что полученная матрица действительно является обратной DoubleMatrix y = c * z; Debug.Assert(y.Rows == n); Debug.Assert(y.Columns == n); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (i == j) { Debug.Assert(Math.Abs(y[i][j] - 1.0) < epsilon); } else { Debug.Assert(Math.Abs(y[i][j] - 0.0) < epsilon); } } } Console.WriteLine("Сверка вычислений произведена"); #endif Debug.Assert(c.Rows == c.Columns); // Проверка выходных данных #if DEBUG //for (int i = 0; i < n; i++) //{ // for (int j = 0; j < n; j++) // { // if (i == j) continue; // Debug.Assert(c[i][j] >= 0.0 - epsilon && c[i][j] <= 1.0 + epsilon); // } //} #endif // Выгрузка ненулевых элементов обратной матрицы в файл for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (i == j) { continue; } if (DoubleMatrix.IsZero(c[i][j])) { continue; } // Сохранение полей в том же формате, что и исходные данные writer.Write(nodeList[group[i]]); writer.Write(";"); writer.Write(nodeList[group[j]]); writer.Write(";"); writer.Write(c[i][j].ToString().Replace(",", ".")); writer.WriteLine(); } } } } }