#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;
}
проблемы с обратной матрицей
задание:вычисление обратной матрицы(квадратной) MxN и оформление проги в виде ф-ии;
основная проблема-нахождение квдратного определителя MxN и нахождение алгебраических дополнений матрицы MxN....
думал воспользоватся разложением по i-ой строке или j-ому столбцу (частный случай теоремы Лапласа) но понял,что это невозможно....или возможно????????:confused:
а срок---до 15-го Декабря....:eek: и мне труба....
Очень прошу---может быть у кого нибуть на бабушкиных дискетах и перфокартах завалялась подобная прога на C++ ....если можно -помогите кодом или на крайний случай алгоритмом....:o
C уважением umbrella
В исходниках есть библиотека для работы с матрицами. Там есть и функция нахождения обратной:
По-моему-это или Delphi либо Pascal....
А что нибуть подобное на C++ есть?
c уважением
UMBRELLA
Для матрицы 3 * 3 вроде я набросал так, это решение системы линейных уравнений по методу Гаусса, тут как подзадача идет вычисление обратной матрицы, могут быть ошибки, но вдруг че найдешь полезное.
но что мне интересно,реально вычислить обратную матрицу размером MxN (M=N-квадратная)разложением по элементам i-ой строки или j-го столбца?
люди,проблема старая как экскрименты мамонта!Ну неужели ни у кого не найдётся такой пороги на С++?
P.S. Я дал пример преобразований для фиксированного размера. Для динамического потребуется еще один внешний цикл.
Я её нашёл где-то на этом сайте .
Заранее извеняюсь если опубликовал её без спроса...
Код:
#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;
}
#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-разложение не знаю.....
кто может исправить-ПОМОГИТЕ!!!!!!!!
И заранее благодарю неизвестного разработчика....