Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

обратная матрица методом гауса

55K
19 марта 2010 года
manuk
14 / / 19.03.2010
Здравствуйте, я пишу обратную матрицу методом Гаусса уже как вторую неделю, помогите пожалуйста!!!

вот то что я сам смог сделать:
Код:
//Пусть матрица А имеет размер NxN.
//Заведем матрицу а размера Nx2N для хранения (А|E).
//Последовательность действий должна быть такая:
    // Спросить у пользователя А.
     //Дописать справа Е.
     //Применить метод Гаусса.
     //Напечатать ответ.
#include<stdio.h>
#include<conio.h>
#include<math.h>
 
#define N 4
double a[N][2*N];
 
void gauss(void);
void sprositMatr(void);
void dopisatE(void);
void otvet(void);
void delimStr(int s,double lam);
void zanulimStlb(int ns);
void vichestStr(int s1,int s2,double lam);
void nomerStrSNenulElem(void);
void meniaemStr(int s1,int s2);
 
void main(void){
  //clrscr();
  sprositMatr();
  dopisatE();
  gauss();
  otvet();
  getch();
  //delimStr();
  //zanulimStlb();
  //vichestStr();
  nomerStrSNenulElem();
  //meniaemStr();
}
void sprositMatr(void){   //Спросить у пользователя А
  int i,j;
  for(i=0;i<N;i++){
      for(j=0;j<N;j++){
         printf("A%d%d=",i,j);
         scanf("%lf",&a[j]);
      }
  }
}
 
void otvet(void){         //Напечатать ответ
  int i,j;
  for(i=0;i<N;i++){
      for(j=N;j<2*N;j++)
         printf("%6.2f",a[j]);
       printf("\n");
  }
}
//Так как мы объявили матрицу а глобально, она автоматически заполнилась нулями.
//Поэтому, чтобы дописать единичную матрицу к нашей, достаточно поставить единицы на диагонали:
void dopisatE(void){
  int i;
  for (i=0;i<N;i++)
    a[N+i]=1;
}
//Реализуем функцию gauss.
//Сделаем слева диагональную матрицу.
//Сначала, пользуясь нулевой строкой матрицы,
//добьемся того, чтобы все элементы нулевого столбика,
//кроме а00, стали равны 0.
//Далее, с помощью первой строки зануляем все элементы первого столбика, кроме а11.
//Продолжая эту процедуру дальше, мы сделаем слева диагональную матрицу.
//После этого остается только разделить нулевую строку на  а00, первую на а11 и т.д. Программируем:
void gauss(void){
  int i;
  for(i=0;i<N;i++)
    zanulimStlb(i);
  for(i=0;i<N;i++)
    delimStr(i,a);
}
 
//Функция delimStr(s,lam) делит строку номер s на число lam.
//Реализуем ее:
void delimStr(int s,double lam){
 
  int j;
 
  for(j=0;j<2*N;j++)
    a[j]/=lam;
}
 
 
//Функция zanulimStlb(ns), пользуясь строкой номер ns, делает нулями все элементы столбца ns, кроме ans,ns . Чтобы этого добиться, нужно проделать следующие действия:
//(0)-(ns)*a0,ns/ ans,ns
//(1)-(ns)*a1,ns/ ans,ns
//…
//(N-1)-(ns)*aN-1,ns/ ans,ns
//Необходимо только при вычитании не забыть, что из самой себя строку ns вычитать не надо. Программируем:
//Если аns,ns=0, то нужно найти ненулевой элемент из чисел аns+1,ns , аns+2,ns, …, аN-1,ns, а затем строку с этим элементом поменять местами со строкой ns.
//Если такого элемента не окажется, то A-1 не существует.
void zanulimStlb(int ns){
  double lam;
  int nst;
  if( a[ns][ns]==0 ){
     //nst=nomerStrSNenulElem(ns);
      if(nst==N){
           printf("Обратной матрицы нет");
           getch();
           exit(1);
       }
        meniaemStr(ns,nst);
  }
  int i;
  for(i=0;i<N;i++){
    if(i!=ns){
      lam=a[ns]/a[ns][ns];
      vichestStr(i,ns,lam);
    }
  }
}
 
//Функция nomerStrSNenulElem(ns) ищет ненулевой элемент из чисел аns+1,ns , аns+2,ns, …, аN-1,ns и возвращает номер строки с этим элементом.
//Если элемента не оказалось, она возвращает N:
void nomerStrSNenulElem(void){
   int ns;
   int i;
   for(i=ns+1;i<N && fabs(a[ns])<1E-12;i++)
   return(i);
}
 
//Функция meniaemStr(s1,s2) меняет местами строки с номерами s1 и s2:
void meniaemStr(int s1,int s2){
 
 
    double temp;
    int j;
    for(j=0;j<2*N;j++){
        temp=a[s1][j];
        a[s1][j]=a[s2][j];
        a[s2][j]=temp;
    }
}
 
//функция vichestStr(s1,s2,lam), которая из строки s1 вычитает строку s2, умноженную на число lam:
void vichestStr(int s1,int s2,double lam){
  int j;
  for(j=0;j<2*N;j++)
    a[s1][j]-=a[s2][j]*lam;
}


[COLOR="Red"]Получаете на первый раз предупреждение за неправильное оформление кода. Вам нужно прочесть правила раздела Студентам и научится оформлять код при помощи тегов [ code ] [ /code ].[/COLOR]
8.4K
19 марта 2010 года
z0rch
275 / / 02.09.2008
сразу бросается в глаза
 
Код:
void nomerStrSNenulElem(void){                    //void return value?
int ns;
int i;
for(i=ns+1;i<N && fabs(a[ns])<1E-12;i++)
return(i);
}


в общем и целом у вас используются неинициализированные переменные nst и ns, отсюда и проблемы, вникать если чесно сейчас просто не хочется, вам же код ближе, вы быстрее разберетесь =)
 
Код:
void zanulimStlb(int ns){
...
if(nst==N){

void nomerStrSNenulElem(void){
...
for(i=ns+1;i<N && fabs(a[ns])<1E-12;i++)

Также можно сделать тыц, свериться, правда там не полное приведение к единичной матрице, а только нижней части, но думаю не проблема продолжить начатое...
55K
20 марта 2010 года
manuk
14 / / 19.03.2010
да вы правы насчёт void nomerStrSNenulElem(void)
вот я его исправил
 
Код:
int nomerStrSNenulElem(int ns){
   int i;
   for(i=ns+1;i<N;i++)
       if(a[ns]!=0)
           return(i);
   return(N);
}
55K
20 марта 2010 года
manuk
14 / / 19.03.2010
а насчёт void zanulimStlb(int ns)

вот
 
Код:
void zanulimStlb(int ns){
  double lam;
  int i;
  for(i=0;i<N;i++){
    if(i!=ns){
      lam=a[ns]/a[ns][ns];
      vichestStr(i,ns,lam);
    }
  }
}
55K
20 марта 2010 года
manuk
14 / / 19.03.2010
теперь надо сделать проверку

надо чтоб при проверке получилась единичная матрица
help
842
20 марта 2010 года
sigmov
301 / / 16.09.2008
Цитата: manuk
теперь надо сделать проверку
надо чтоб при проверке получилась единичная матрица
help



Ну и что тут сложного? - умножаете исходную матрицу на ее обратную и должна получиться единичная матрица. )))

Сам когда-то кстати тоже этим занимался - даже еще и h файл сохранился.
Там как раз инверсия методом Гаусса с ведущим по столбцу и функции умножения матриц имеются.

55K
20 марта 2010 года
manuk
14 / / 19.03.2010
я знаю что исходную надо умножить на её обратную
только как дописать это в моём коде, у меня не получается, в понедельник надо здать помогите пожалуйста.:confused::confused::confused:
7
20 марта 2010 года
@pixo $oft
3.4K / / 20.09.2006
Вам алгоритма умножения матриц хватит или ещё код за вас написать?
55K
20 марта 2010 года
manuk
14 / / 19.03.2010
если не трудно, то код пожалуйста))!!!
55K
20 марта 2010 года
manuk
14 / / 19.03.2010
вот то что я сам сделал, но не получается

Код:
void otvet(void){         //Напечатать ответ
  int i,j,t,y,n;
  int sprositMatr[N][2*N];
  double otvet[N][N];
  double pmatrix[N][2*N];
  for(i=0;i<N;i++){
      for(j=N;j<2*N;j++)
         printf("%6.2f",a[j]);
       printf("\n");
  }
printf("umnogit y/n\n");
scanf("%f",y,n);
if(y){
    for(i=0;i<N;i++)
    for(j=0;j<2*N;j++)
        for(t=0;t<N;t++)
         pmatrix[j]+=sprositMatr[t]*otvet[t][j];
         printf("%6.2f",pmatrix[j]);
else
printf("not found");

}


}
67K
24 декабря 2010 года
Vertolet
1 / / 24.12.2010
вот немного моего быдлокода. писал для поиска корней методом обратной матрицы по методу гаусса-жордано. переделал вывод под твои цели
Код:
include <cstdlib>
#include <iostream>

using namespace std;

int main()
{
    int n;
    cin>>n;    
    int i, j, k;
    double aI[n][n+1],a[n][2*n],c[n];
    //Ввод матрицы
    for (i=0; i<n; i++)
         for (j=0; j<n+1; j++)
             cin>>aI[j];
    //Вывод исходной матрицы
    cout<<"Ishodhaya matrica \n";
    for (i=0; i<n; i++)
        { for (j=0; j<n+1; j++)
               cout<<aI[j]<<"  ";
          cout<<'\n';
        }
    //КОПИРУЕМ НАШУ МАТРИЦУ БЕЗ ОТВЕТОВ В РАБОЧУЮ
    for (i=0;i<n;i++)
        for (j=0;j<n;j++)
            a[j]=aI[j];        
    //ПРИБАВЛЯЕМ К НАШЕЙ МАТРИЦЕ МАТРИЦУ С 1 ПО ГЛАВНОЙ ДИАГОНАЛИ
    for (i=0;i<n;i++)
        for (j=n;j<2*n;j++)
            {
                if (i+n==j)
                    a[j]=1;
                else
                    a[j]=0;
            }  
    //Вычисление матрицы по методу Гаусса-Жордано
    for (k=0; k<n; k++)
       {
        for (i=0; i<n; i++)
           for (j=0; j<2*n; j++)
              if ((i!=k)&&(j!=k))
                  a[j]=a[j]-a[k]*a[k][j]/a[k][k];
        for (j=0; j<n*2; j++)
           if (j!=k)
               a[k][j]=a[k][j]/a[k][k];
        for (i=0; i<n; i++)
           if (i==k)
               a[k]=1;
           else a[k]=0;
        };
    //Вывод результирующей матрицы
    cout<<"Rezult. matrica    \n";
     for (i=0; i<n; i++)
         {
         for (j=n; j<2*n; j++)
             cout<<a[j]<<"  ";
         cout<<'\n';
         }
    system("PAUSE");
    return EXIT_SUCCESS;
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог