Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C++]собственные значения, симметрической матрицы методом Якоби 
V
    Опции темы
MxAxKxC
Дата 4.12.2007, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 8.5.2007

Репутация: 1
Всего: 1



Помогите с данной задачей пожайлуста.
PM MAIL   Вверх
MxAxKxC
Дата 7.12.2007, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 8.5.2007

Репутация: 1
Всего: 1



суть метода в том, что в результате преобразований данной нам матрицы, мы получаем матрицу, с диагональными элементами, которые являются собственными числами нашей исходной матрицы.
Вот примерный алгоритм:
1.В исходной симметрической матрице A(k)=A(0) выберается максимальный по модулю наддиагональный элемент.
2. Нужно найти ортогональную данной матрицу(U), чтобы элемент, выбранный нами в пункте 1 был равен 0.
В качестве ортогональной матрицы выбирается матрица вращения, в которой элемент А[i,j]=-sin(a), 
угол а= 0.5*arctg((i*j)/(A[i,i]+A[j,j])), если А[ii]=A[jj], a=pi/4. элемент A[j,i]=sin(a);элемент A[i,i]=cos(a);элемент A[j,j]=cos(a), остальные элементы на главной диагонали равны 1, а все остальные элементы равны 0.
3.Находим матрицу A(k+1) по формуле:
A(k+1)=U(транспонированную)(К)*A(k)*U(k).
4. Итерационный процесс останавливается когда достигается необходимая точность Е.
То есть когда корень из суммы квадратов наддиагональных элементов матрицы А(К+1)будет меньше Е.
Написал несколько функций:



Это сообщение отредактировал(а) MxAxKxC - 8.12.2007, 17:35
PM MAIL   Вверх
MxAxKxC
Дата 8.12.2007, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 8.5.2007

Репутация: 1
Всего: 1



так, осталось еще немного, нужно сделать условие остановки итерационного процесса.
вот что получилось пока:
Код

 void matrix_enter(double **matrix, int n)
 {
  cout<<"enter elements of matrix :\n";
  for(int i=0;i<n;i++)
  {
  cout<<"\n";
  for(int j=0;j<n;j++)
  {
  cout << "A" << i+1 << j+1 << "=";
  cin >> matrix[i][j];
 }
 }       
      
 }
 int n_enter()
 {
  int n;
  cout << "Enter size of matrix: \n";
  cin >> n;
  
  return n;   
 }
 
 void matrix_show(double **matrix, int n)
 {
  cout << "\n";
  for (int i=0; i<n; i++)
  {
    cout << "\n";    
    for (int j=0; j<n; j++)
    {
      printf("  %.4f ",matrix[i][j]);
    }
  }    
 }
 void new_matrix (double** &matrix,int n)
{
  matrix= new double* [n];
  for (int i=0; i<n; i++)
    matrix[i]= new double [n];
}

 void pr_matrix (double **A, double **B, double **C, int n)
{
for (int i=0; i<n; i++) 
  for (int j=0; j<n; j++) 
    for (int k=0; k<n; k++) 
      C[i][j]+=A[i][k]*B[k][j];
}     


 void calc_U(double **A,double **B, int n)
 {
  double max_elem=A[1][0];
  int h,k;
  h=2;
  k=1;
  for(int i=1;i<n;i++){
  for(int j=i+1;j<n;j++)
  if(A[i][j]>max_elem){
  k++;
  h++;
  max_elem=A[i][j];
}
}
 double fi=0.5*atan(( 2*max_elem )/( A[k-1][k-1]-A[h-1][h-1] ));
  //cout<<A[k-1][h-1];
   for(int i=0;i<n;i++)
  for(int j=0;j<n;j++){
  B[k-1][h-1]=-sin(fi);  
  B[h-1][k-1]=sin(fi);
  B[h-1][h-1]=cos(fi);
  B[k-1][k-1]=cos(fi);
  if (i==j) B[i][j]=1;
    else      B[i][j]=0; 
  } 
       
 }
 
 double elem_sum(double **A, int n)
 {
  double sum=0;
  
  for(int i=0;i<n;i++)
  for(int j=i+1;j<n;j++)
  
  sum+=A[i][j];
  
  return sum;      
 }
 void trans_matrix (double **A, double **B,int n)
{
  for (int i=0; i<n; i++)
    for (int j=0; j<n; j++)
      B[i][j]=A[j][i];
}     


Это сообщение отредактировал(а) MxAxKxC - 9.12.2007, 12:07
PM MAIL   Вверх
MxAxKxC
Дата 9.12.2007, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 8.5.2007

Репутация: 1
Всего: 1



как я понимаю должен быть цикл, но как его запрограммировать незнаю... 

вот собственно это надо как то в цикл запихнуть:
Код

 calc_U(A,U,n);
    trans_matrix(U,UT,n); 
    pr_matrix(UT,A,E,n);
    pr_matrix(E,U,C,n);


я думаю примерно условие выхода должно быть таким:
Код


double eps;
    cout<<"enter eps ";
    cin>>eps;
double s;
s=elem_sum(C,n);
while(sqrt(s)>eps)

но у меня воид функции, незнаю как с ними цикл составить. smile 

Это сообщение отредактировал(а) MxAxKxC - 9.12.2007, 14:58
PM MAIL   Вверх
MxAxKxC
Дата 13.12.2007, 21:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 8.5.2007

Репутация: 1
Всего: 1



Задача решена, спасибо всем, что поддержали морально smile !)))))

Добавлено @ 21:47
вот код, если вдруг комунить понадобится


Это сообщение отредактировал(а) MxAxKxC - 13.12.2007, 21:48

Присоединённый файл ( Кол-во скачиваний: 56 )
Присоединённый файл  main.cpp 3,45 Kb
PM MAIL   Вверх
MxAxKxC
Дата 27.12.2007, 19:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 8.5.2007

Репутация: 1
Всего: 1



вот 100% рабочая версия программы


Присоединённый файл ( Кол-во скачиваний: 272 )
Присоединённый файл  main.cpp 3,52 Kb
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0699 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.