コード例 #1
0
 /// <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)
 }
         )
 {
 }
コード例 #2
0
ファイル: AdditionExample0.cs プロジェクト: Novacta/analytics
        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);
        }
コード例 #3
0
 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)
 }
         )
 {
 }
コード例 #4
0
 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)
 }
         )
 {
 }
コード例 #5
0
 public void MemberAddIncompatible()
 {
   DoubleMatrix a = new DoubleMatrix(2);
   DoubleMatrix b = new DoubleMatrix(3);
   a.Add(b);
 }
コード例 #6
0
 public void MemberAddNull()
 {
   DoubleMatrix a = new DoubleMatrix(2);
   DoubleMatrix b = null;
   a.Add(b);
 }
コード例 #7
0
 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);
 }
コード例 #8
0
 public void Add()
 {
     M.Add(2, 1, 100);
     Assert.AreEqual(121, M[2, 1], 0.001);
 }
コード例 #9
0
        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();
                        }
                    }
                }
            }
        }