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

Ваш аккаунт

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

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

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

проблемы с обратной матрицей

15K
15 ноября 2006 года
umbrella
15 / / 29.10.2006
курсовая по C++
задание:вычисление обратной матрицы(квадратной) MxN и оформление проги в виде ф-ии;
основная проблема-нахождение квдратного определителя MxN и нахождение алгебраических дополнений матрицы MxN....
думал воспользоватся разложением по i-ой строке или j-ому столбцу (частный случай теоремы Лапласа) но понял,что это невозможно....или возможно????????:confused:
а срок---до 15-го Декабря....:eek: и мне труба....
Очень прошу---может быть у кого нибуть на бабушкиных дискетах и перфокартах завалялась подобная прога на C++ ....если можно -помогите кодом или на крайний случай алгоритмом....:o

C уважением umbrella
273
15 ноября 2006 года
3A3-968M
1.2K / / 22.12.2005
В исходниках есть библиотека для работы с матрицами. Там есть и функция нахождения обратной:
http://sources.codenet.ru/download/814/MatrixAPI.html
15K
03 декабря 2006 года
umbrella
15 / / 29.10.2006
конечно спасибо за библиотеку,но она написана не на C++....
По-моему-это или Delphi либо Pascal....
А что нибуть подобное на C++ есть?

c уважением
UMBRELLA
63
03 декабря 2006 года
Zorkus
2.6K / / 04.11.2006
Для матрицы 3 * 3 вроде я набросал так, это решение системы линейных уравнений по методу Гаусса, тут как подзадача идет вычисление обратной матрицы, могут быть ошибки, но вдруг че найдешь полезное.
Код:
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <cmath>
using namespace std;

    long double matrix[3][7];
   
    // end of init
    void dbg()
    {
    for(int i = 0; i < 3; i++)
    {
        for(int j  = 3; j < 6; j++)
        {  
            cout.width(9);
            cout <<fixed << setprecision(4) << right <<  matrix[j] << "  ";
        }
        cout << endl << endl;
    }
   
    }
   
int main()
{
    //1 string
    matrix[0][0] = 3.75;
    matrix[0][1] = -0.28;
    matrix[0][2] = 0.17;
    matrix[0][3] = 1;
    matrix[0][4] = 0;
    matrix[0][5] = 0;
    matrix[0][6] = 0.75;
    //2 string
    matrix[1][0] = 2.11;
    matrix[1][1] = -0.11;
    matrix[1][2] = -0.12;
    matrix[1][3] = 0;
    matrix[1][4] = 1;
    matrix[1][5] = 0;
    matrix[1][6] = 1.11;
    //3 string
    matrix[2][0] = 0.22;
    matrix[2][1] = -3.17;
    matrix[2][2] = 1.81;
    matrix[2][3] = 0;
    matrix[2][4] = 0;
    matrix[2][5] = 1;
    matrix[2][6] = 0.05;
   
    for(int i = 1; i < 3; i++)
    {
        for(int j = 1; j < 7; j++)
        {
            matrix[j] -= matrix[0][j] / (matrix[0][0] / matrix[0]);
        }
    }
    matrix[1][0] = 0;
    matrix[2][0] = 0;
    for(int j = 2; j < 7; j++)
    {
        matrix[2][j] -= matrix[1][j] / (matrix[1][1] / matrix[2][1]);
    }
    matrix[2][1] = 0;
   
    long double det = matrix[0][0] * matrix[1][1] *matrix[2][2];
    cout << "Det = " <<  det << endl;
    for(int j = 3; j  <7; j++)
    {
        matrix[2][j] /= matrix[2][2];
    }
    matrix[2][2] = 1;
    for(int i =0; i < 2;i++)
    {
        for(int j = 6; j > 1 ; j--)
        {
            matrix[j] -= matrix[2][j] / (matrix[2][2] / matrix[2]);
        }
    }
   
    for(int j = 2; j  <7; j++)
    {
        matrix[1][j] /= matrix[1][1];
    }
    matrix[1][1] = 1;
    for(int j = 6; j >0 ; j-- )
    {
        matrix[0][j] -= matrix[1][j] / (matrix[1][1] / matrix[0][1]);
    }
    for(int j = 1; j  <7; j++)
    {
        matrix[0][j] /= matrix[0][0];
    }
    matrix[0][0] = 1;
    cout << "Obr matriza" << endl << endl;
    dbg();
    cout << "Otvet [" << matrix[0][6] <<" , " << matrix[1][6] << " , " << matrix[2][6] << "]" ;
    return EXIT_SUCCESS;
}
15K
04 декабря 2006 года
umbrella
15 / / 29.10.2006
спасибо люди что помогаете!
но что мне интересно,реально вычислить обратную матрицу размером MxN (M=N-квадратная)разложением по элементам i-ой строки или j-го столбца?


люди,проблема старая как экскрименты мамонта!Ну неужели ни у кого не найдётся такой пороги на С++?
63
04 декабря 2006 года
Zorkus
2.6K / / 04.11.2006
Зачем тебе что то раскладывать? Для нахождения обратной матрицы используется след. метод. Есть данная квадратная матрица, справа приписываешь единичную такой же размерности. Потом преобразованиями Гаусса (метод решения систем лин. уравнений, курс линейной алгебры) получаешь слева верхнюю диагонализированную формы твоей матрицы, справа - получится волшебным образом обратная:).

P.S. Я дал пример преобразований для фиксированного размера. Для динамического потребуется еще один внешний цикл.
15K
10 декабря 2006 года
umbrella
15 / / 29.10.2006
приведу код проги(не моя)
Я её нашёл где-то на этом сайте .
Заранее извеняюсь если опубликовал её без спроса...
Код:
#include<iostream.h>
#include<conio.h>
#include<assert.h>
#include<stdlib.h>
#include<math.h>
#include<vcl.h>
class matrix{
public:
float **p;
struct st_size{
int gor;
int vert;}size;

static int matrix_count;


friend ostream &operator<<(ostream &,const matrix &);
friend istream &operator>>(istream &,matrix &);
int operator==(const matrix &);

matrix(int n=3,int m=3);
matrix(const matrix&);
~matrix();

st_size getsize() const;
static int getmatrix_count();


matrix minor(int); //opredelenie glavn. minorov
matrix obratnaia(const matrix&); //naxogdenie obratnoi matrix
};


int matrix::matrix_count=0;

matrix::matrix(int n,int m){
++matrix_count;
size.gor=n;
size.vert=m;
p=new float*[size.gor];
assert(p!=0);
for(int i=0;i<size.gor;i++)
p=new float[size.vert];
for(int i=0;i<size.gor;i++)
for(int j=0;j<size.vert;j++)
p[j]=0;}


matrix::matrix(const matrix &mass){
++matrix_count;
size=mass.size;
p=new float*[size.gor];
assert(p!=0);
for(int i=0;i<size.gor;i++)
p=new float[size.vert];
for(int i=0;i<size.gor;i++)
for(int j=0;j<size.vert;j++)
p[j]=mass.p[j];}

matrix::~matrix(){--matrix_count;
delete [size]*p;}

matrix::st_size getsize(const size);

int matrix::getmatrix_count(){
return matrix_count;}

istream &operator>>(istream &inp,matrix &mass)
{for(int i=0;i<mass.size.gor;i++)
for(int j=0;j<mass.size.vert;j++)
inp>>mass.p[j];
return inp;}

ostream &operator<<(ostream &out,const matrix &mass)
{for(int i=0;i<mass.size.gor;i++){out<<"\n";
for(int j=0;j<mass.size.vert;j++)
out<<mass.p[j]<<" ";}
return out;}

int matrix:perator==(const matrix &m)
{if((size.gor!=m.size.gor)||(size.vert!=m.size.ver t))return 0;
for(int i=0;i<size.gor;i++)
for(int j=0;j<size.vert;j++)
if(p[j]!=m.p[j])return 0;
return 1;}








matrix matrix::minor(int i) //opredelenie glavn. minorov
{
matrix B(i,i);

for(int j=0;j<i;j++)
for(int k=0;k<i;k++)
B.p[j][k]=p[j][k];
return B;}

matrix matrix:bratnaia(const matrix &F) //naxogdenie obratnoi matrix
{
// LU-razlogenie
matrix B(size.gor,size.gor),C(size.gor,size.gor),Z(1,1);//Z-nulevaia matrix, vozvrachaemaia pri ochibke
float res1=0,res2=0;

for(int i=0;i<size.gor;i++)
for(int j=0;j<size.gor;j++){
if(i==j)C.p[j]=1;
if(i>=j){
for(int k=0;k<=j-1;k++)res1=res1+B.p[k]*C.p[k][j];
B.p[j]=p[j]-res1;res1=0;}
else {
for(int k=0;k<=i-1;k++)res2=res2+B.p[k]*C.p[k][j];
if(B.p==0){cout<<"Error:minor =0\n";return Z;}
else {C.p[j]=(1/B.p)*(p[j]-res2);res2=0;}}}

// reshenie By=f
matrix Y(size.gor,1);
float res3=0;

for(int i=0;i<size.gor;i++){
for(int j=0;j<=i-1;j++)res3=res3+B.p[j]*Y.p[j][0];
if(B.p==0){cout<<"Error:minor =0\n";return Z;}
else Y.p[0]=(F.p[0]-res3)/B.p;res3=0; }

// reshenie Cx=y
matrix X(size.gor,1);
float res4=0;

for(int i=size.gor-1;i>=0;i--){
for(int j=i+1;j<size.gor;j++)res4=res4+C.p[j]*X.p[j][0];
X.p[0]=(1/C.p)*(Y.p[0]-res4);res4=0;}

return X;}

void DisplayMenu()
{
std::cout<<"---Programma dlya vichislenia obratnoj matrix---"<<endl;
std::cout<<"1. Vvesti matrix"<<endl;
std::cout<<"2. Exit"<<endl;
}

int GetSelection()
{
int sel;
std::cout<<"Set variant:\n";
std::cin >> sel;
return sel;
}

void NextMenu()
{
textcolor(YELLOW);
cprintf("Matrix calculation complete: \n\r");
cprintf("1. Vivesti rezultati na ekran\n\r");
cprintf("2. Sohranit' rezultat v fail (v lokal'noj dirrektorii)\n\r");
cprintf("3. Vivesti rezul'tati na pechat'\n\r");
}

int main(){

DisplayMenu();
int sel;
sel=GetSelection();
switch (sel)
{
case 1:break;
case 2:return 0;
default: std::cout<<"\aNekorrektnij vibor!";getch();return 0;
}
int a=0;
cout<<"vvedite razmernost matrix A\n";
cin>>a;
matrix A(a,a);
cout<<"vvedite matrix A\n";
cin>>A;

NextMenu();
int sel2;
sel2=GetSelection();
switch (sel2)
{
case 1:break;
case 2:/*WriteOfFile();break;*/
case 3:
default: cprintf("\aNekorrektnij vibor!");getch();return 0;
}

matrix Q(1,1);
bool z=false;

for(int k=1;k<=a;k++){

z=false;
cout<<"Glavnij minor:\n";
cout<<A.minor(k)<<'\n';

matrix E(k,k); //edinichnaia matrix
for(int i=0;i<k;i++)
for(int j=0;j<k;j++)
if(i==j)E.p[j]=1;

matrix F(k,1); //stolbec edinichnoi matrix
matrix O(k,k); //obratnaia matrix


for(int j=0;j<k;j++){

for(int i=0;i<k;i++)
F.p[0]=E.p[j]; //formirovanie F

for(int i=0;i<k;i++){
if(((A.minor(k)).obratnaia(F))==Q)z=true;
if (z==true)break;
O.p[j]=((A.minor(k)).obratnaia(F)).p[0];

} if (z==true)break;
}if (z==true)break;
cout<<"Obratnaya matrix:\n";
cout<<O<<'\n';}
while(!getch());
return 0;
}


задаю матрицу размером 3х3
3 -1 0
-2 1 1
2 -1 4

выводит матрицу вида:
1 0.8 -0.2
2 2.4 -0.6
3.97364e-09 0.2 0.2

число 3.97364e-09 -бесконечно малая величина ...
а должно быть=0.
я UL-разложение не знаю.....
кто может исправить-ПОМОГИТЕ!!!!!!!!

И заранее благодарю неизвестного разработчика....
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог