Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [C++]собственные значения


Автор: MxAxKxC 4.12.2007, 16:23
Помогите с данной задачей пожайлуста.

Автор: MxAxKxC 7.12.2007, 22:08
суть метода в том, что в результате преобразований данной нам матрицы, мы получаем матрицу, с диагональными элементами, которые являются собственными числами нашей исходной матрицы.
Вот примерный алгоритм:
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
так, осталось еще немного, нужно сделать условие остановки итерационного процесса.
вот что получилось пока:
Код

 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:08
как я понимаю должен быть цикл, но как его запрограммировать незнаю... 

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

 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 13.12.2007, 21:45
Задача решена, спасибо всем, что поддержали морально smile !)))))

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

Автор: MxAxKxC 27.12.2007, 19:50
вот 100% рабочая версия программы

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)