Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.12.2014, 23:42   #1
1anton
 
Регистрация: 06.12.2014
Сообщений: 6
По умолчанию QR разложение

Здравствуйте, мне нужно написать код для QR разложение и вывести на экран исходную матрицу и матрицу Q и R. Я совсем не разбираюсь в среде программирования си шарп и, поэтому искал нужный код в интернете. Нашел вот такой код(комментарий для наглядности оставил):

Код:
using System;
using System.Globalization;
using MathNet.Numerics.LinearAlgebra.Double;

namespace Examples.LinearAlgebra.FactorizationExamples
{

    public class QR : IExample
    {
        /// <summary>
        /// Gets the name of this example
        /// </summary>
        public string Name
        {
            get
            {
                return "QR factorization";
            }
        }

        /// <summary>
        /// Gets the description of this example
        /// </summary>
        public string Description
        {
            get
            {
                return "Perform the QR factorization by means of the Gram?Schmidt process and Householder transformations";
            }
        }

        /// <summary>
        /// Run example
        /// </summary>
        /// <seealso cref="http://en.wikipedia.org/wiki/QR_decomposition">QR decomposition</seealso>
        public void Run()
        {
            // Format matrix output to console
            var formatProvider = (CultureInfo)CultureInfo.InvariantCulture.Clone();
            formatProvider.TextInfo.ListSeparator = " ";

            // Create 3 x 2 matrix
            var matrix = new DenseMatrix(new[,] { { 1.0, 2.0 }, { 3.0, 4.0 }, { 5.0, 6.0 } });
            Console.WriteLine(@"Initial 3x2 matrix");
            Console.WriteLine(matrix.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Perform QR decomposition (Householder transformations)
            var qr = matrix.QR();
            Console.WriteLine(@"QR decomposition (Householder transformations)");

            // 1. Orthogonal Q matrix
            Console.WriteLine(@"1. Orthogonal Q matrix");
            Console.WriteLine(qr.Q.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 2. Multiply Q matrix by its transpose gives identity matrix
            Console.WriteLine(@"2. Multiply Q matrix by its transpose gives identity matrix");
            Console.WriteLine(qr.Q.TransposeAndMultiply(qr.Q).ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 3. Upper triangular factor R
            Console.WriteLine(@"3. Upper triangular factor R");
            Console.WriteLine(qr.R.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 4. Reconstruct initial matrix: A = Q * R
            var reconstruct = qr.Q * qr.R;
            Console.WriteLine(@"4. Reconstruct initial matrix: A = Q*R");
            Console.WriteLine(reconstruct.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // Perform QR decomposition (Gram?Schmidt process)
            var gramSchmidt = matrix.GramSchmidt();
            Console.WriteLine(@"QR decomposition (Gram?Schmidt process)");

            // 5. Orthogonal Q matrix
            Console.WriteLine(@"5. Orthogonal Q matrix");
            Console.WriteLine(gramSchmidt.Q.ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 6. Multiply Q matrix by its transpose gives identity matrix
            Console.WriteLine(@"6. Multiply Q matrix by its transpose gives identity matrix");
            Console.WriteLine((gramSchmidt.Q.Transpose() * gramSchmidt.Q).ToString("#0.00\t", formatProvider));
            Console.WriteLine();

            // 7. Upper triangular factor R
            Console.WriteLine(@"7. Upper triangular factor R");
            Console.WriteLine(gramSchmidt.R.ToString("#0.00\t", formatProvider));
            Console.WriteLine();
            
            // 8. Reconstruct initial matrix: A = Q * R
            reconstruct = gramSchmidt.Q * gramSchmidt.R;
            Console.WriteLine(@"8. Reconstruct initial matrix: A = Q*R");
            Console.WriteLine(reconstruct.ToString("#0.00\t", formatProvider));
            Console.WriteLine();
        }
    }
}
Этот код у меня не работает: ругается на DenseMatrix. Раньше прога ругалась на строчку MathNet.Numerics.LinearAlgebra.Doub le; в слове MathNet. Я так понял, что нужно подключить библиотеку MathNet. Но даже после подключения у меня прога не перестала ругаться. Попробуйте запустить у себя, может я как то неправильно воспользовался библиотекой или код неработоспособный.
1anton вне форума Ответить с цитированием
Старый 07.12.2014, 00:26   #2
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Наверно код для старой версии библиотеки и ее API успело измениться.

Как-то так работает (последняя версия из NuGet):
Код:
var matrix = DenseMatrix.OfColumns(2, 3, new[] { new[] { 1.0, 2.0 }, new [] { 3.0, 4.0 }, new[] { 5.0, 6.0 } });
Вот весь работающий проект, VS2012. https://dl.dropboxusercontent.com/u/...plication1.zip
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 07.12.2014, 17:27   #3
1anton
 
Регистрация: 06.12.2014
Сообщений: 6
По умолчанию

Спасибо, все прекрасно работает. Но у меня есть еще одна маленькая проблема: необходимо, что бы матрица бралась не из кода, а из файла txt. Я нашел код, но он не работает в проге qr-разложения:
Код:
 class ReadFromFile
    {
        static void Main()
        {
            string text = System.IO.File.ReadAllText(@"C:\a.txt");
            System.Console.WriteLine("Contents of WriteText.txt = {0}", text);
            Console.ReadLine();
            
        }
    }
Я как понял либо код я неправильно адаптировал к своей программе, либо он мне вовсе не подходит.
1anton вне форума Ответить с цитированием
Старый 07.12.2014, 17:46   #4
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Ну тут просто содержимое файла читается в строку.

Надо доставать из него числа в соответствии с форматом данных файла и заносить в матрицу.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 10.12.2014, 23:36   #5
1anton
 
Регистрация: 06.12.2014
Сообщений: 6
По умолчанию

Нашел прогу, только там есть проблемы:
Код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;

class Program
{
    static void Main(string[] args)
    {
        string file = File.ReadAllText(@"C:\a.txt");
        var nums = file
            .Split(new char[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries)
            .Select(n => int.Parse(n));
        foreach (int i in nums)
            Console.WriteLine(i);
    }
}
Вроде все по плану:
загружаю файл, создал метод перебора всего текста и разделил строку с помощью .Split(" ") и сохранил в char. Дальше при каждом обращении к методу из массива char преобразовал в массив цифр (int.Parse)
Добавил массив цифр в конец нового двумерного массива (foreach)
Осталось сделать цикл, чтобы добавить все элементы и я не знаю, что делать с Select(n => int.Parse(n));
1anton вне форума Ответить с цитированием
Старый 12.12.2014, 01:36   #6
1anton
 
Регистрация: 06.12.2014
Сообщений: 6
По умолчанию

Я сделал более простую прогу, которая вручную берет каждый элемент из текста и этот элемент вкладываю в массив:
Код:
            // Create 3 x 3 matrix
            string str = System.IO.File.OpenText(@"C:\a.txt").ReadToEnd().Trim();
            string[] spli = str.Replace("\r\n", ";").Split(' ', ';');
            int[,] mass = new int[3, spli.Length / 2];
            mass[0, 0] = Convert.ToInt32(spli[0]);
            mass[1, 0] = Convert.ToInt32(spli[1]);
            mass[2, 0] = Convert.ToInt32(spli[2]);
            mass[0, 1] = Convert.ToInt32(spli[3]);
            mass[1, 1] = Convert.ToInt32(spli[4]);
            mass[2, 1] = Convert.ToInt32(spli[5]);
            mass[0, 2] = Convert.ToInt32(spli[6]);
            mass[1, 2] = Convert.ToInt32(spli[7]);
            mass[2, 2] = Convert.ToInt32(spli[8]);



            var matrix = DenseMatrix.OfColumns(3, 3, new[] { new[] { mass[0, 0], mass[0, 1], 1.0 }, new[] { mass[1, 0], mass[1, 1], 2.0 }, new[] { mass[2, 0], mass[2, 1], 3.0 } })
Только последний элемент у меня не хочет читать прога, поэтому я оставил цифры в коде. Как это исправить? И как можно сделать так, чтобы элементы брались из файла не только целые, но и дробные?
1anton вне форума Ответить с цитированием
Старый 12.12.2014, 09:24   #7
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Не проще было за неделю язык поизучать, а не "проги искать"?)

Числа в файле в каком виде хранятся, чем разделены?
Размер матрицы в файле указан или 3х3 всегда?

Цитата:
загружаю файл, создал метод перебора всего текста и разделил строку с помощью .Split(" ") и сохранил в char. Дальше при каждом обращении к методу из массива char преобразовал в массив цифр (int.Parse)
Добавил массив цифр в конец нового двумерного массива (foreach)
Странное описание, нету там никакого char (кроме списка разделителей), а в foreach просто выводится содержимое одномерного массива nums в консоль.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 12.12.2014, 18:01   #8
1anton
 
Регистрация: 06.12.2014
Сообщений: 6
По умолчанию

Матрица 3*3 и значения разделены пробелом и могут быть дробными и целыми. Предыдущею прогу, где по ней Вы делали замечания, можете забыть. Я решил свою проблему вот таким способом:
Код:
string str = System.IO.File.OpenText(@"C:\a.txt").ReadToEnd().Trim();
            string[] spli = str.Replace("\r\n", ";").Split(' ', ';');
            double[,] mass = new double[3, spli.Length ];

            mass[0, 0] = Convert.ToDouble(spli[0]);
            mass[1, 0] = Convert.ToDouble(spli[1]);
            mass[2, 0] = Convert.ToDouble(spli[2]);
            mass[0, 1] = Convert.ToDouble(spli[3]);
            mass[1, 1] = Convert.ToDouble(spli[4]);
            mass[2, 1] = Convert.ToDouble(spli[5]);
            mass[0, 2] = Convert.ToDouble(spli[6]);
            mass[1, 2] = Convert.ToDouble(spli[7]);
            mass[2, 2] = Convert.ToDouble(spli[8]);

            var matrix = DenseMatrix.OfColumns(3, 3, new[] { new[] { mass[0, 0], mass[0, 1], mass[0, 2] }, new[] { mass[1, 0], mass[1, 1], mass[1, 2] }, new[] { mass[2, 0], mass[2, 1], mass[2, 2] } });
Тут только прога может брать матрицу 3*3 и потому это не совсем правильно. Можно все это запихнуть в цикл:
Код:
for (int i = 0; i < spli.Length ; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    mass[i,j]=Convert.ToDouble(spli[i]);
                }
            }
Но как эти значения представить в массив и потом, чтобы все это работало в моей проге, я не знаю. И я сомневаюсь в реализации этого способа. Вопрос именно в этом.
1anton вне форума Ответить с цитированием
Старый 12.12.2014, 18:49   #9
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
Можно все это запихнуть в цикл
Только запихнуть-то правильно надо.
Код:
            double[,] mass = new double[3, 3];
            int k = 0;
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    mass[i,j]=Convert.ToDouble(spli[k++]);
                }
            }
А вообще тут не нужен этот mass, если DenseMatrix нужен.

Код:
using System;
using System.Globalization;
using System.IO;
using MathNet.Numerics.LinearAlgebra.Double;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string filePath = "1.txt";

            File.WriteAllText(filePath,
@"1 2 3
3.5 4 8.5
9 1.0 3.1");

            var lines = File.ReadAllLines(filePath);

            int n = 3;

            var matrix = new DenseMatrix(n, n);

            for (int i = 0; i < n; i++)
            {
                var numStrs = lines[i].Split(' ');

                for (int j = 0; j < n; j++)
                {
                    // InvariantCulture - используется точка (3.5)
                    double num = Convert.ToDouble(numStrs[j].Replace(',', '.'), CultureInfo.InvariantCulture);

                    matrix[i, j] = num;
                }
            }

            for (int i = 0; i < matrix.RowCount; i++)
            {
                for (int j = 0; j < matrix.ColumnCount; j++)
                {
                    Console.Write(matrix[i, j] + " ");
                }
                Console.WriteLine();
            }
        }
    }
}
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 13.12.2014, 14:25   #10
1anton
 
Регистрация: 06.12.2014
Сообщений: 6
По умолчанию

Цитата:
А вообще тут не нужен этот mass, если DenseMatrix нужен.
Да, но можно было из этого цикла сделать прогу, просто заменив mass на matrix:
Код:
   string str = System.IO.File.OpenText(@"C:\a.txt").ReadToEnd().Trim();
            string[] spli = str.Replace("\r\n", ";").Split(' ', ';');


            int n = 3;

            var matrix = new DenseMatrix(n, n);

          
            int k = 0;
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    matrix[i, j] = Convert.ToDouble(spli[k++]);
                }
            }
И также будет работать как и Ваша прога. Спасибо за помощь.
1anton вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Си,Си ++, QR разложение Осип Помощь студентам 1 28.10.2012 16:41
Разложение Avicenna Помощь студентам 2 24.10.2011 08:31
разложение матрицы Monomah Помощь студентам 2 28.02.2011 19:47
Разложение функции stepanov_ivan Помощь студентам 0 25.10.2010 09:08