0
namespace EigenValues {
// вектор
class Vector {
    double[] values; // значения
    public readonly int n; // размерность

    public Vector(int n, double value = 0) {
        this.n = n; // запоминаем размерность
        values = new double[n]; // выделяем памятьпод значения

        for (int i = 0; i < n; i++)
            values[i] = value;
    }

    // нормирование вектора
    public void Norm() {
        double norm = 0;

        // считаем длину вектора
        for (int i = 0; i < n; i++)
            norm += values[i] * values[i];

        norm = Math.Sqrt(norm);

        // если вектор нулевой
        if (norm < 1e-15)
            return; // выходим

        // делим значения вектора на длину
        for (int i = 0; i < n; i++)
            values[i] /= norm;
    }

    // получение элемента по индексу
    public double this[int index] {
        get { return values[index]; }
        set { values[index] = value; }
    }

    // скалярное произведение двух векторов
    public static double operator*(Vector v1, Vector v2) {
        double p = 0;

        for (int i = 0; i < v1.n; i++)
            p += v1.values[i] * v2.values[i];

        return p;
    }

    // вывод вектора
    public void Print() {
        for (int i = 0; i < n; i++)
            Console.Write("{0} ", values[i]);
    }
}

// матрица
class Matrix {
    public readonly int n; // размерность
    double[][] values; // значения

    public Matrix(int n) {
        this.n = n; // сохраняем размерность

        // выделяем память под элементы
        values = new double[n][];

        for (int i = 0; i < n; i++)
            values[i] = new double[n];
    }
    public void FillRandom() {
        Random rand = new Random();

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                values[i][j] = rand.Next(-10000, 10001) / 100.0;
            }
        }
    }

    // вывод матрицы
    public void Print() {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++)
                Console.Write("{0,7} ", values[i][j]);

            Console.WriteLine();
        }
    }

    // умножение матрицы на вектор
    public static Vector operator *(Matrix m, Vector v) {
        Vector result = new Vector(m.n);

        for (int i = 0; i < m.n; i++) {
            result[i] = 0;

            for (int j = 0; j < m.n; j++)
                result[i] += m.values[i][j] * v[j];
        }

        return result; // возвращаем веткор
    }
}

class Program {
    // получение нормы ||a*v1 - v2||
    static double Norm(Vector v1, Vector v2, double a) {
        double norm = 0;

        for (int i = 0; i < v1.n; i++)
            norm += (v1[i] * a - v2[i]) * (v1[i] * a - v2[i]);

        return Math.Sqrt(norm);
    }

    // степенной метод (находит максимальное собственное значение)
    static void PowerMethod(Matrix A, int n, double eps) {
        Vector Xo = new Vector(n, 1 / Math.Sqrt(n)); // случайное начальное приближение
        double lambda = 0;
        int k = 1; // счётчик итераций
        int maxIterations = 10000;

        // выводим начальное приближение вектора
        Console.Write("Xo:");
        Xo.Print();

        // пока не превышен лимит по итерациям
        while (k <= maxIterations) {
            Vector Yo = A * Xo; // находим новое приближение
            lambda = Xo * Yo; // вычисляем лямбду

            Console.Write("\nY{0} = A*X{1} = ", k, k - 1);
            Yo.Print();
            Console.Write(", lambda = (Y{0}, X{1}) = {2}", k, k - 1, lambda);

            Yo.Norm(); // нормируем новое приближение

            // если выполняется критерий останова
            if (Norm(Yo, Xo, Math.Sign(lambda)) < eps)
                break; // выходим

            Xo = Yo; // обновляем вектора
            k++; // увеличиваем номер итерации
        }

        // если алгоритм не сошёлся
        if (k > maxIterations) {
            Console.WriteLine("\n\nUnable to find eigen value"); // сообщаем об этом
        }
        else { // иначе выводим результаты
            Console.WriteLine("\nMax eigen value: {0}", lambda);
            Console.Write("Max eigen vector: ");
            Xo.Print();
            Console.WriteLine();
            Console.WriteLine("Iterations: {0}", k);
        }
    }

    static void Main(string[] args) {
        Console.Write("Enter n: ");
        int n = int.Parse(Console.ReadLine()); // считываем размерность матрицы

        Matrix A = new Matrix(n); // создаём матрицу

        //Console.WriteLine("Enter values of matrix:");
        //A.Read(); // считываем значения матрицы
        A.FillRandom();

        Console.WriteLine("\nA:");
        A.Print(); // выводим значения матрицы

        Console.Write("Enter eps: ");
        double eps = double.Parse(Console.ReadLine()); // считываем точность

        PowerMethod(A, n, eps); // находим собственный вектор и собственное число
        Console.ReadKey();
    }
}

}

МОИ ПОПЫТКИ

namespace GG { public partial class Window1 : Window { ObservableCollection> matrix = new ObservableCollection>();

    Random rnd = new Random();
    static byte numberrow;
    double[] values;
    public Window1()
    {
        InitializeComponent();
        dgMatrix.ItemsSource=matrix;

    }

    void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
    {
        e.Row.Header=e.Row.GetIndex()+1;
    }

    private void CreateDataGrid(DataGrid dgMatrix, int numbercolumn)
    {
        dgMatrix.Columns.Clear();
        if(numbercolumn>0)
        {
            for(int i=0;i<numbercolumn;i++)
            {
                DataGridTextColumn column = new DataGridTextColumn
                {
                    Header = (i+1).ToString(),
                    Binding = new Binding(string.Format("[{0}]",i))
                };
                dgMatrix.Columns.Add(column);
            }
        }
    }

    private ObservableCollection<ObservableCollection<int>> CreateMatrix(int numberrow, int numbercolumn)
    {
        matrix.Clear();
        if(numberrow>0 && numbercolumn>0)
        {
            for(int i =0; i <numberrow;i++)
            {
                matrix.Add(new ObservableCollection<int>());
                for(int j=0;j<numbercolumn;j++)

                    matrix[i].Add(rnd.Next(-10,10));

            }
        }
        return matrix;
    }


    void button1_Click(object sender, RoutedEventArgs e)
    {
        otvet.Clear();
        if(!byte.TryParse(TextRow.Text, out numberrow)||!byte.TryParse(TextColumn.Text, out numberrow))
        {
            MessageBox.Show("Была установлена неправильная размерность!","Информация", MessageBoxButton.OK,MessageBoxImage.Error);
        }
        CreateMatrix(numberrow,numberrow);
        CreateDataGrid(dgMatrix, numberrow);
        dgMatrix.Visibility=Visibility.Visible;

    }



    void TextRow_GotFocus(object sender, RoutedEventArgs e)
    {
        TextRow.Clear();
    }

    void TextColumn_GotFocus(object sender, RoutedEventArgs e)
    {
        TextColumn.Clear();
    }
    void DgMatrix_TextInput(object sender, TextCompositionEventArgs e)
    {
        MessageBox.Show("Были введены недопустимые символы! Введите число!","Информация", MessageBoxButton.OK,MessageBoxImage.Error);
    }
    void MenuItem_Click4(object sender, RoutedEventArgs e)
    {
        MessageBoxResult result = MessageBox.Show("Вариант 45.", "Задание", MessageBoxButton.OK, MessageBoxImage.None);

    }
    void MenuItem_Click5(object sender, RoutedEventArgs e)
    {
        MessageBoxResult result = MessageBox.Show("43", "Задание", MessageBoxButton.OK, MessageBoxImage.None);

    }
    void button2_Click(object sender, RoutedEventArgs e)
    {

        tochnost.Clear();
        otvet.Clear();
        //double eps=double.Parse(tochnost.Text);
    //  a2 = double.Parse(textBox2.Text);
        //string e1=tochnost.Text;
        Vector Xo = new Vector(numberrow, 1 / Math.Sqrt(numberrow)); // случайное начальное приближение
        double lambda = 0;
        int k = 1; // счётчик итераций
        int maxIterations = 1000;
        double norm=1;
        // пока не превышен лимит по итерациям
        while (k <= maxIterations) {
            for(int i =0; i <numberrow;i++)
            {
                for(int j=0;j<numberrow;j++)
                {
                    if (norm>0.0000001)
                    {
                        Vector Yo = matrix[i][j] * Xo; // находим новое приближение
                        lambda = Xo * Yo; // вычисляем лямбду

                        // Yo.Norm(); // нормируем новое приближение

                        // считаем длину вектора


                        // если выполняется критерий останова


                        norm = 0;


                        norm += (Yo * Math.Sign(lambda) - Xo) * (Yo * Math.Sign(lambda) - Xo);
                        norm=Math.Sqrt(norm);



                            Xo = Yo; // обновляем вектора
                        k++; // увеличиваем номер итерации
                    }

                    // если алгоритм не сошёлся
                    if (k > maxIterations) {
                        otvet.Text="nUnable to find eigen value"; // сообщаем об этом
                    }
                    else { // иначе выводим результаты
                        otvet.Text+= lambda;
                    }
                }
            }
        }
    }
}

}

Frager
  • 3
  • чем тут помогать, вы ж сами ничего не сделали для перевода на WPF? – tym32167 Jul 07 '19 at 18:00
  • Извиняюсь, забыл прикрепить мои попытки. – Frager Jul 07 '19 at 18:02
  • осталось добавить что вы вообще хотите сделать и что не получается. Ну и можно чуток поправить оформление – tym32167 Jul 07 '19 at 18:10
  • @tym32167 не получается именно сам перенос, программа не работает. Сама программа должна выводить максимальное собственное число матрицы и матрицу. Но у меня не получается перенести в WPF сам алгоритм программы – Frager Jul 07 '19 at 18:15
  • чтобы вывести число, достаточно текстбокса и записи в него. Чтобы вывести матрицу можно просто гридом воспользоваться. Что у вас из этого не выходит? Вы же понимаете, что программа не работает не говорит ни о чем, пишите конкретную проблему. У вас матрица не выводится? У вас обработчики кнопок не срабатывают? Что не работает? – tym32167 Jul 07 '19 at 18:21
  • @tym32167 не выводится число(ответ) – Frager Jul 07 '19 at 18:24
  • вот эта функция button2_Click вообще вызывается? Чему во время вызова равно поле numberrow? Отладчиком смотрели, выполнение вообще доходит до otvet.Text="nUnable to find eigen value"; или otvet.Text+= lambda;? – tym32167 Jul 07 '19 at 18:30
  • @tym32167 ответ это otvet.Text+=lambda; Да функция вызывается, скорее всего ошибка в самом коде, так как переписывал с нуля, но я не могу понять в чем проблема – Frager Jul 07 '19 at 18:56
  • вы какие то вещи читаете с текстбоксов, какие то вещи у вас рандомные, потому я не могу сказать, где у вас конкретно проблема. Я советую вам воспользоваться отладчиком, понаставить точек останова и поглядеть, чему у вас равны значения ваших переменных. Так как вы уже знаете ваш алгоритм, то, зная исходные данные для него, вы легко найдете проблему. – tym32167 Jul 07 '19 at 19:04
  • @tym32167 возможно я не правильно переписал именно этот метод.Norm(); т. к. я несколько методов объединял в один, только как его по другому сделать я не знаю – Frager Jul 07 '19 at 19:40

0 Answers0