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;
}
}
}
}
}
}
}
программа не работаетне говорит ни о чем, пишите конкретную проблему. У вас матрица не выводится? У вас обработчики кнопок не срабатывают? Что не работает? – tym32167 Jul 07 '19 at 18:21button2_Clickвообще вызывается? Чему во время вызова равно полеnumberrow? Отладчиком смотрели, выполнение вообще доходит доotvet.Text="nUnable to find eigen value";илиotvet.Text+= lambda;? – tym32167 Jul 07 '19 at 18:30