声明:本文非原创,原创为相对定向-绝对定向(C++实现)--摄影测量学,本文只是参照该文章代码学习了相对定向到绝对定向的实现的过程,在此对csuhan表示感谢!此外关于摄影测量解析相对定向及绝对定向原理及公式部分参见乖摸摸头_1951
原始数据为:
焦距:150mm
左片像点坐标:
0.016012 0.079963
0.08856 0.081134
0.013362 -0.07937
0.08224 -0.080027
0.051758 0.080555
0.014618 -0.000231
0.04988 -0.000782
0.08614 -0.001346
0.048035 -0.079962
右片像点坐标:
-0.07393 0.078706
-0.005252 0.078184
-0.079122 -0.078879
-0.009887 -0.080089
-0.039953 0.078463
-0.076006 0.000036
-0.042201 -0.001022
-0.007706 -0.002112
-0.044438 -0.079736
地面点坐标:
5083.205 5852.099 527.925
5780.02 5906.365 571.549
5210.879 4258.446 461.81
5909.264 4314.283 455.484
计算结果为
#include "pch.h"
#include <iostream>
#include"Matrix.h"
#include"Rotation.h"
#include<fstream>
using namespace std;
int main()
{
int m1=9, m2=4;
double f=0.15;
double Left[9][2] =
{
0.016012,0.079963,
0.08856,0.081134,
0.013362 ,-0.07937,
0.08224 ,-0.080027,
0.051758,0.080555,
0.014618 ,- 0.000231,
0.04988 ,-0.000782,
0.08614,-0.001346,
0.048035,-0.079962
};
double Right[9][2] =
{
-0.07393 ,0.078706,
-0.005252 ,0.078184,
-0.079122 ,-0.078879,
-0.009887, -0.080089,
-0.039953 ,0.078463,
-0.076006 ,0.000036,
-0.042201 ,-0.001022,
-0.007706 ,-0.002112,
-0.044438 ,-0.079736,
};
double Ground[4][3]=
{
5083.205 ,5852.099,527.925,
5780.02 ,5906.365,571.549,
5210.879 ,4258.446,461.81,
5909.264 ,4314.283,455.484,
};
Model resolve(m1,Left, Right, m2, Ground, f);
resolve.relative();//相对定位
resolve.model();//求算模型点坐标
resolve.absolute();//绝对定位
resolve.transabs();
return 0;
}
定向过程
#pragma once
#include "pch.h"
#include"Matrix.h"
class Model
{
public:
Model(int m1, double Left[][2], double Right[][2], int m2, double Ground[][3],double f);
~Model();
Matrix romatrix(double o, double p, double k);/*计算旋转矩阵*/
void relative();//相对定位
void model();//求算模型点坐标
void absolute();//绝对定位
void transabs();//模型点转换为地面坐标值
private:
/*左右相片量测数据\地面已知数据模型点数据*/
int m;
int n;
double **L=NULL;
double **R=NULL;
double **G=NULL;
double **MO=NULL;
double **AB=NULL;
/*相机内方位元素*/
double x0;
double y0;
double f0;
/************************相对定向参数**********************************/
//相对定向线元素
double bx;
double by;
double bz;
//相对定向角元素
double o;
double p;
double k;
double u;
double v;
/************************绝对定向参数********************************/
//绝对定向线元素
double X;
double Y;
double Z;
//绝对定向角元素
double O;
double P;
double K;
//比例因子
double M;
double MA;
//投影系数
double N1;
double N2;
//精度因子
double c1;
double c2;
//迭代次数
int count1;
int count2;
};
#include "pch.h"
#include"Rotation.h"
#include <math.h>
using namespace std;
/*构造函数赋初值*/
Model::Model(int m1, double Left[9][2], double Right[9][2], int m2, double Ground[9][3], double f)
{
//焦距赋值
this->f0 = f;
//相对定向赋初值
bx = Left[0][0] - Right[0][0];
o = 0, p = 0, k = 0, u = 0, v = 0, count1 = 0;
//绝对定向初始值
X = 0, Y = 0, Z = 0, O = 0, P = 0, K = 0, MA = 1;
//左右相片测量数据赋值
m = m1;
n = m2;
L = new double*[m];
R = new double*[m];
G = new double*[n];
MO = new double*[m];
AB = new double*[m];
for (int i = 0;i < m;i++)
{
L[i] = new double[2];
R[i] = new double[2];
MO[i] = new double[3];
AB[i] = new double[3];
}
for (int i = 0; i < n; i++)
{
G[i] = new double[3];
}
for (int i = 0; i < m; i++)
{
L[i][0] = Left[i][0];
L[i][1] = Left[i][1];
R[i][0] = Right[i][0];
R[i][1] = Right[i][1];
}
//地面已知值
for (int j = 0; j < n; j++)
{
G[j][0] = Ground[j][0];
G[j][1] = Ground[j][1];
G[j][2] = Ground[j][2];
}
//定义模型初始值
for (int i = 0; i < m; i++)
{
MO[i][0] = 0;
MO[i][1] = 0;
MO[i][2] = 0;
AB[i][0] = 0;
AB[i][1] = 0;
AB[i][2] = 0;
}
}
/*析构函数*/
Model::~Model()
{
for (int i = 0; i < m; i++)
{
delete[]L[i];
delete[]R[i];
delete[]MO[i];
delete[]AB[i];
}
delete[]L;
delete[]R;
delete[]MO;
delete[]AB;
for (int i = 0; i < n; i++)
{
delete[]G[i];
}
delete[]G;
}
/*进行相对定向*/
void Model::relative()
{
//定义法方程中的矩阵
Matrix A(6, 5),Lc(6, 1),V(6, 1),Xa(5, 1), xfu(3, 1);;
while (true)
{
by = bx * u, bz = bx * v;
for (int i = 0; i < 6; i++)
{
xfu(0, 0) = R[i][0];
xfu(1, 0) = R[i][1];
xfu(2, 0) = -f0;
xfu = romatrix(o, p, k)*xfu;
//左片
double X1 = L[i][0];
double Y1 = L[i][1];
double Z1 = -f0;
//右片
double X2 = xfu(0, 0);
double Y2 = xfu(1, 0);
double Z2 = xfu(2, 0);
//计算投影系数
N1 = (bx* Z2 - bz * X2) / (X1 * Z2 - X2*Z1);
N2 = (bx* Z1 - bz *X1) / (X1 * Z2 - X2 * Z1);
//计算法方程系数
A(i, 0) = -X2 * Y2*N2 / Z2;
A(i, 1) = -(Z2+Y2*Y2/Z2)*N2;
A(i, 2) =X2*N2;
A(i, 3) = bx;
A(i, 4) = -(Y2 *bx) /Z2;
//计算常数项
Lc(i, 0) = N1 *Y1 - N2 * Y2 - by;
}
Xa = (~A*A).Inv()*(~A)*Lc;
o += Xa(0, 0), p += Xa(1, 0), k += Xa(2, 0), u += Xa(3, 0), v += Xa(4, 0);
count1++;
if (fabs(Xa(0, 0))<0.00003&&fabs(Xa(1, 0))<0.00003 && fabs(Xa(2, 0))< 0.00003&&fabs(Xa(3, 0)) < 0.00003&&fabs(Xa(4, 0))< 0.00003)
{
cout << "Xa:\n" << Xa(0, 0) << "\t" << Xa(1, 0) << "\t" << Xa(2, 0) << "\t" << Xa(3, 0) << "\t" << Xa(4, 0) << endl;
V = A * Xa - Lc;
c1=sqrt((~V*V)(0,0)/6);
cout << "相对定向的结果为:\n" << "o=" << o << "\t" << "p=" << p << "\t" << "k=" << k << "\t" << "u:" << u<< "\t" << "v:" <<v<< "\n";
cout << "迭代的精度以及次数为:\n" << "精度为:" << c1 << "迭代次数为:" << count1 << "\n";
break;
}
}
}
/*确定模型点的坐标*/
void Model::model()
{
//确定模型比例尺M
M = sqrt(((G[0][0] - G[1][0])* (G[0][0] - G[1][0]) + (G[0][1] - G[1][1])* (G[0][1] - G[1][1])) / ((L[0][0] - L[1][0])* (L[0][0] - L[1][0]) + (L[0][1] - L[1][1])* (L[0][1] - L[1][1])));
//计算模型的坐标
cout << "模型点坐标为:\n";
Matrix temp(3, 1);
for (int i = 0; i < m; i++)
{
temp(0, 0) = R[i][0];
temp(1, 0) = R[i][1];
temp(2, 0) = -f0;
temp = romatrix(o, p, k)*temp;
//左片
double X1 = L[i][0];
double Y1 = L[i][1];
double Z1 = -f0;
//右片
double X2 = temp(0, 0);
double Y2 = temp(1, 0);
double Z2 = temp(2, 0);
//计算投影系数
N1 = (bx* Z2 - bz * X2) / (X1 * Z2 - X2 * Z1);
N2 = (bx* Z1 - bz * X1) / (X1 * Z2 - X2 * Z1);
MO[i][0] = M * N1*X1;
MO[i][1] = 0.5*M*(N1*Y1 + N2*Y2+by);
MO[i][2] = M * (f0 + N1 * (-f0));
cout << MO[i][0] << "\t" << MO[i][1] << "\t" << MO[i][2] << endl;
}
}
//绝对定向
void Model::absolute()
{
Matrix A(3*n,7), Xa(7,1), V(3*n,1), La(3*n,1);
while(true)
{
int i = 0;
for (int j=0; j < n; j++)
{
Matrix temp(3,1);
temp(0, 0) = MO[j][0], temp(1, 0) = MO[j][1], temp(2, 0) = MO[j][2];
A(i, 0) = 1,A(i, 3) =MO[j][0], A(i, 4) = -MO[j][2], A(i, 6) = -MO[j][1];
A(i + 1, 1) = 1, A(i + 1, 3) = MO[j][1], A(i+1, 5) = -MO[j][2], A(i+1, 6) = MO[j][0];
A(i + 2, 2) = 1, A(i + 2, 3) = MO[j][2], A(i+2, 4) = MO[j][0], A(i + 2, 5) = MO[j][1];
temp=romatrix(O, P, K)*temp;
La(i, 0) = G[j][0] - MA * temp(0, 0) - X;
La(i + 1, 0) = G[j][1] - MA * temp(1, 0) - Y;
La(i + 2, 0) = G[j][2] - MA * temp(2, 0) - Z;
i += 3;
}
Xa= (~A*A).Inv()*(~A)*La;
X += Xa(0, 0), Y += Xa(1, 0), Z += Xa(2, 0), O += Xa(4, 0), P += Xa(5, 0), K += Xa(6, 0), MA += Xa(3, 0);
count2++;
if (fabs(Xa(0, 0)) < 0.001&&fabs(Xa(1, 0)) < 0.001 && fabs(Xa(2, 0)) < 0.001&&fabs(Xa(3,0)) < 0.001&&fabs(Xa(4,0)) < 0.001&&fabs(Xa(5, 0)) < 0.001&&fabs(Xa(6, 0)) < 0.001)
{
V = A * Xa - La;
c2 = sqrt((~V*V)(0, 0) / (3*n-7));
cout << "绝对定向的结果:\n" << "X:" << X << "\t" << "Y:" << Y << "\t" << "Z:" << Z << "\t" << "MA:" << MA << "\t" << "O:" << O << "\t" << "P:" << P << "\t" << "K:" << K << "\n";
cout << "绝对定向精度与迭代的次数为:\n" << "精度:" << c2 << "\t" << "迭代次数:" << count2 << "\n";
break;
}
}
}
//计算模型点在地面的坐标
void Model::transabs()
{
cout << "转换为的地面点的坐标为:\n";
for(int i = 0; i < m; i++)
{
Matrix temp(3, 1);
temp(0, 0) = MO[i][0];
temp(1, 0) = MO[i][1];
temp(2, 0) = MO[i][2];
temp=romatrix(O, P, K)*temp;
AB[i][0] = MA * temp(0, 0) + X;
AB[i][1] = MA * temp(1, 0) + Y;
AB[i][2] = MA * temp(2, 0) + Z;
cout << AB[i][0] << "\t" << AB[i][1] << "\t" << AB[i][2] << "\n";
}
}
//计算旋转矩阵
Matrix Model::romatrix(double o, double p, double k)
{
Matrix rota(3, 3);
rota(0, 0) = cos(o)*cos(k) - sin(o)*sin(p)*sin(k);
rota(0, 1) = -cos(o)*sin(k) - sin(o)*sin(p)*cos(k);
rota(0, 2) = -sin(o)*cos(p);
rota(1, 0) = cos(p)*sin(k);
rota(1, 1) = cos(p)*cos(k);
rota(1, 2) = -sin(p);
rota(2, 0) = sin(o)*cos(k) + cos(o)*sin(p)*sin(k);
rota(2, 1) = -sin(o)*sin(k) + cos(o)*sin(p)*cos(k);
rota(2, 2) = cos(o)*cos(p);
return rota;
}
矩阵类
#include "pch.h"
#include"Rotation.h"
#include <math.h>
using namespace std;
/*构造函数赋初值*/
Model::Model(int m1, double Left[9][2], double Right[9][2], int m2, double Ground[9][3], double f)
{
//焦距赋值
this->f0 = f;
//相对定向赋初值
bx = Left[0][0] - Right[0][0];
o = 0, p = 0, k = 0, u = 0, v = 0, count1 = 0;
//绝对定向初始值
X = 0, Y = 0, Z = 0, O = 0, P = 0, K = 0, MA = 1;
//左右相片测量数据赋值
m = m1;
n = m2;
L = new double*[m];
R = new double*[m];
G = new double*[n];
MO = new double*[m];
AB = new double*[m];
for (int i = 0;i < m;i++)
{
L[i] = new double[2];
R[i] = new double[2];
MO[i] = new double[3];
AB[i] = new double[3];
}
for (int i = 0; i < n; i++)
{
G[i] = new double[3];
}
for (int i = 0; i < m; i++)
{
L[i][0] = Left[i][0];
L[i][1] = Left[i][1];
R[i][0] = Right[i][0];
R[i][1] = Right[i][1];
}
//地面已知值
for (int j = 0; j < n; j++)
{
G[j][0] = Ground[j][0];
G[j][1] = Ground[j][1];
G[j][2] = Ground[j][2];
}
//定义模型初始值
for (int i = 0; i < m; i++)
{
MO[i][0] = 0;
MO[i][1] = 0;
MO[i][2] = 0;
AB[i][0] = 0;
AB[i][1] = 0;
AB[i][2] = 0;
}
}
/*析构函数*/
Model::~Model()
{
for (int i = 0; i < m; i++)
{
delete[]L[i];
delete[]R[i];
delete[]MO[i];
delete[]AB[i];
}
delete[]L;
delete[]R;
delete[]MO;
delete[]AB;
for (int i = 0; i < n; i++)
{
delete[]G[i];
}
delete[]G;
}
/*进行相对定向*/
void Model::relative()
{
//定义法方程中的矩阵
Matrix A(6, 5),Lc(6, 1),V(6, 1),Xa(5, 1), xfu(3, 1);;
while (true)
{
by = bx * u, bz = bx * v;
for (int i = 0; i < 6; i++)
{
xfu(0, 0) = R[i][0];
xfu(1, 0) = R[i][1];
xfu(2, 0) = -f0;
xfu = romatrix(o, p, k)*xfu;
//左片
double X1 = L[i][0];
double Y1 = L[i][1];
double Z1 = -f0;
//右片
double X2 = xfu(0, 0);
double Y2 = xfu(1, 0);
double Z2 = xfu(2, 0);
//计算投影系数
N1 = (bx* Z2 - bz * X2) / (X1 * Z2 - X2*Z1);
N2 = (bx* Z1 - bz *X1) / (X1 * Z2 - X2 * Z1);
//计算法方程系数
A(i, 0) = -X2 * Y2*N2 / Z2;
A(i, 1) = -(Z2+Y2*Y2/Z2)*N2;
A(i, 2) =X2*N2;
A(i, 3) = bx;
A(i, 4) = -(Y2 *bx) /Z2;
//计算常数项
Lc(i, 0) = N1 *Y1 - N2 * Y2 - by;
}
Xa = (~A*A).Inv()*(~A)*Lc;
o += Xa(0, 0), p += Xa(1, 0), k += Xa(2, 0), u += Xa(3, 0), v += Xa(4, 0);
count1++;
if (fabs(Xa(0, 0))<0.00003&&fabs(Xa(1, 0))<0.00003 && fabs(Xa(2, 0))< 0.00003&&fabs(Xa(3, 0)) < 0.00003&&fabs(Xa(4, 0))< 0.00003)
{
cout << "Xa:\n" << Xa(0, 0) << "\t" << Xa(1, 0) << "\t" << Xa(2, 0) << "\t" << Xa(3, 0) << "\t" << Xa(4, 0) << endl;
V = A * Xa - Lc;
c1=sqrt((~V*V)(0,0)/6);
cout << "相对定向的结果为:\n" << "o=" << o << "\t" << "p=" << p << "\t" << "k=" << k << "\t" << "u:" << u<< "\t" << "v:" <<v<< "\n";
cout << "迭代的精度以及次数为:\n" << "精度为:" << c1 << "迭代次数为:" << count1 << "\n";
break;
}
}
}
/*确定模型点的坐标*/
void Model::model()
{
//确定模型比例尺M
M = sqrt(((G[0][0] - G[1][0])* (G[0][0] - G[1][0]) + (G[0][1] - G[1][1])* (G[0][1] - G[1][1])) / ((L[0][0] - L[1][0])* (L[0][0] - L[1][0]) + (L[0][1] - L[1][1])* (L[0][1] - L[1][1])));
//计算模型的坐标
cout << "模型点坐标为:\n";
Matrix temp(3, 1);
for (int i = 0; i < m; i++)
{
temp(0, 0) = R[i][0];
temp(1, 0) = R[i][1];
temp(2, 0) = -f0;
temp = romatrix(o, p, k)*temp;
//左片
double X1 = L[i][0];
double Y1 = L[i][1];
double Z1 = -f0;
//右片
double X2 = temp(0, 0);
double Y2 = temp(1, 0);
double Z2 = temp(2, 0);
//计算投影系数
N1 = (bx* Z2 - bz * X2) / (X1 * Z2 - X2 * Z1);
N2 = (bx* Z1 - bz * X1) / (X1 * Z2 - X2 * Z1);
MO[i][0] = M * N1*X1;
MO[i][1] = 0.5*M*(N1*Y1 + N2*Y2+by);
MO[i][2] = M * (f0 + N1 * (-f0));
cout << MO[i][0] << "\t" << MO[i][1] << "\t" << MO[i][2] << endl;
}
}
//绝对定向
void Model::absolute()
{
Matrix A(3*n,7), Xa(7,1), V(3*n,1), La(3*n,1);
while(true)
{
int i = 0;
for (int j=0; j < n; j++)
{
Matrix temp(3,1);
temp(0, 0) = MO[j][0], temp(1, 0) = MO[j][1], temp(2, 0) = MO[j][2];
A(i, 0) = 1,A(i, 3) =MO[j][0], A(i, 4) = -MO[j][2], A(i, 6) = -MO[j][1];
A(i + 1, 1) = 1, A(i + 1, 3) = MO[j][1], A(i+1, 5) = -MO[j][2], A(i+1, 6) = MO[j][0];
A(i + 2, 2) = 1, A(i + 2, 3) = MO[j][2], A(i+2, 4) = MO[j][0], A(i + 2, 5) = MO[j][1];
temp=romatrix(O, P, K)*temp;
La(i, 0) = G[j][0] - MA * temp(0, 0) - X;
La(i + 1, 0) = G[j][1] - MA * temp(1, 0) - Y;
La(i + 2, 0) = G[j][2] - MA * temp(2, 0) - Z;
i += 3;
}
Xa= (~A*A).Inv()*(~A)*La;
X += Xa(0, 0), Y += Xa(1, 0), Z += Xa(2, 0), O += Xa(4, 0), P += Xa(5, 0), K += Xa(6, 0), MA += Xa(3, 0);
count2++;
if (fabs(Xa(0, 0)) < 0.001&&fabs(Xa(1, 0)) < 0.001 && fabs(Xa(2, 0)) < 0.001&&fabs(Xa(3,0)) < 0.001&&fabs(Xa(4,0)) < 0.001&&fabs(Xa(5, 0)) < 0.001&&fabs(Xa(6, 0)) < 0.001)
{
V = A * Xa - La;
c2 = sqrt((~V*V)(0, 0) / (3*n-7));
cout << "绝对定向的结果:\n" << "X:" << X << "\t" << "Y:" << Y << "\t" << "Z:" << Z << "\t" << "MA:" << MA << "\t" << "O:" << O << "\t" << "P:" << P << "\t" << "K:" << K << "\n";
cout << "绝对定向精度与迭代的次数为:\n" << "精度:" << c2 << "\t" << "迭代次数:" << count2 << "\n";
break;
}
}
}
//计算模型点在地面的坐标
void Model::transabs()
{
cout << "转换为的地面点的坐标为:\n";
for(int i = 0; i < m; i++)
{
Matrix temp(3, 1);
temp(0, 0) = MO[i][0];
temp(1, 0) = MO[i][1];
temp(2, 0) = MO[i][2];
temp=romatrix(O, P, K)*temp;
AB[i][0] = MA * temp(0, 0) + X;
AB[i][1] = MA * temp(1, 0) + Y;
AB[i][2] = MA * temp(2, 0) + Z;
cout << AB[i][0] << "\t" << AB[i][1] << "\t" << AB[i][2] << "\n";
}
}
//计算旋转矩阵
Matrix Model::romatrix(double o, double p, double k)
{
Matrix rota(3, 3);
rota(0, 0) = cos(o)*cos(k) - sin(o)*sin(p)*sin(k);
rota(0, 1) = -cos(o)*sin(k) - sin(o)*sin(p)*cos(k);
rota(0, 2) = -sin(o)*cos(p);
rota(1, 0) = cos(p)*sin(k);
rota(1, 1) = cos(p)*cos(k);
rota(1, 2) = -sin(p);
rota(2, 0) = sin(o)*cos(k) + cos(o)*sin(p)*sin(k);
rota(2, 1) = -sin(o)*sin(k) + cos(o)*sin(p)*cos(k);
rota(2, 2) = cos(o)*cos(p);
return rota;
}
#include "pch.h"
#include<iostream>
#include"Matrix.h"
using namespace std;
//默认构造函数
Matrix::Matrix(int r, int c)
{
Row = r;
Col = c;
Data = new double*[Row];
for (int i = 0; i < Row; i++)
{
Data[i] = new double[Col];
for (int j = 0; j < Col; j++)
{
Data[i][j] = 0;
}
}
}
/*复制构造函数*/
Matrix::Matrix(const Matrix&ma)
{
Row = ma.R();
Col = ma.C();
Data = new double *[Row];
for (int i = 0; i < Row; i++)
{
Data[i] = new double[Col];
memcpy(Data[i], ma.Data[i], sizeof(double)*Col);
}
}
/*析构函数*/
Matrix::~Matrix()
{
for (int i = 0; i < Row; i++)
{
delete[]Data[i];
}
delete[]Data;
}
/*重载运算符()*/
double &Matrix::operator()(int a, int b)
{
if (a >= Row || b >= Col)
throw("Matrix::operator:Index out of range!");
return Data[a][b];
}
/*常量对象重载运算符()*/
double &Matrix::operator()(int a, int b)const
{
if (a >= Row || b >= Col)
throw("Matrix::operator:Index out of range!");
return Data[a][b];
}
/*重载=运算符*/
Matrix Matrix ::operator =(const Matrix &ma1)
{
if (Row != ma1.R() || Col != ma1.C())
{
throw"the matrix are different!";
}
for (int i = 0; i < Row; i++)
{
for (int j = 0; j < Col; j++)
{
Data[i][j] = ma1(i, j);
}
}
return *this;
}
/*重载+运算符*/
Matrix operator+(const Matrix &ma1, const Matrix &ma2)
{
if (ma1.R() != ma2.R() || ma1.C() != ma2.C())
throw("the size of two matrix is different");
Matrix ma(ma1.R(), ma1.C());
for (int i = 0; i < ma1.R(); i++)
{
for (int j = 0; j < ma1.C(); j++)
{
ma(i, j) = ma1(i, j) + ma2(i, j);
}
}
return ma;
}
/*重载-运算符*/
Matrix operator-(const Matrix &ma1, const Matrix &ma2)
{
if (ma1.R() != ma2.R() || ma1.C() != ma2.C())
throw("the size of two matrix is different");
Matrix ma(ma1.R(), ma1.C());
for (int i = 0; i < ma1.R(); i++)
{
for (int j = 0; j < ma1.C(); j++)
{
ma(i, j) = ma1(i, j) - ma2(i, j);
}
}
return ma;
}
/*重载*运算符--矩阵相乘*/
Matrix operator * (const Matrix &ma1, const Matrix &ma2)
{
if (ma1.C() != ma2.R())
throw("There two matrix can not *");
Matrix ma(ma1.R(), ma2.C());
for (int i = 0; i < ma1.R(); i++)
{
for (int j = 0; j < ma2.C(); j++)
{
for (int k = 0; k < ma1.C(); k++)
{
ma(i, j) += ma1(i, k)*ma2(k, j);
}
}
}
return ma;
}
/*重载*运算符--数乘矩阵左乘*/
Matrix operator *(int a, const Matrix &ma1)
{
Matrix ma(ma1.R(), ma1.C());
for (int i = 0; i < ma1.R(); i++)
{
for (int j = 0; j < ma1.C(); j++)
{
ma(i, j) = a * ma1(i, j);
}
}
return ma;
}
/*重载*运算符--数乘矩阵右乘*/
Matrix operator *(const Matrix &ma1, int a)
{
Matrix ma(ma1.R(), ma1.C());
for (int i = 0; i < ma1.R(); i++)
{
for (int j = 0; j < ma1.C(); j++)
{
ma(i, j) = a * ma1(i, j);
}
}
return ma;
}
/*重载~运算符--矩阵转置*/
Matrix operator ~(const Matrix &ma1)
{
Matrix ma(ma1.C(), ma1.R());
for (int i = 0; i < ma1.R(); i++)
{
for (int j = 0; j < ma1.C(); j++)
{
ma(j, i) = ma1(i, j);
}
}
return ma;
}
/*矩阵求逆----全选主元法*/
Matrix Matrix::Inv()
{
if (Row != Col)
{
throw("The matrix can not be inversion!");
}
Matrix cmat(Row, Row);
cmat = *this;//复制对象
int i, j, k, v;
int *mainrow = new int[Row];//存放主元的行号
int *maincol = new int[Row];//存放主元的列号
double mid; //临时变量
double maincount; //主元值
/*选取主元*/
for (k = 0; k < Row; k++)
{
maincount = 0;
for (i = k; i < Row; i++)
{
for (j = k; j < Col; j++)
{
if (fabs(cmat(i, j)) >= maincount)
{
maincount = fabs(cmat(i, j));
mainrow[k] = i;
maincol[k] = j;
}
}
}
if (fabs(maincount) < 0.0000000000001)
{
throw("The matrix can not be inversion!");
}
/*行交换*/
if (mainrow[k] != k)
{
for (i = 0; i < Row; i++)
{
v = mainrow[k];
mid = cmat(k, i);
cmat(k, i) = cmat(v, i);
cmat(v, i) = mid;
}
}
/*列交换*/
if (maincol[k] != k)
{
for (i = 0; i < Row; i++)
{
v = maincol[k];
mid = cmat(i, k);
cmat(i, k) = cmat(i, v);
cmat(i, v) = mid;
}
}
/*----计算cmat(k, k)*/
cmat(k, k) = 1 / cmat(k, k);
/*----计算cmat(k,j)j!=k*/
for (j = 0; j < Row; j++)
{
if (j != k)
{
cmat(k, j) *= cmat(k, k);
}
}
/*----计算cmat(i,j)i,j!=k*/
for (i = 0; i < Row; i++)
{
if (i != k)
{
for (j = 0; j < Row; j++)
{
if (j != k)
cmat(i, j) -= cmat(i, k)*cmat(k, j);
}
}
}
/*计算cmat(i,k)i!=k*/
for (i = 0; i < Row; i++)
{
if (i != k)
cmat(i, k) = -cmat(i, k)*cmat(k, k);
}
}
/*交换行列*/
for (k = Row - 1; k >= 0; k--)
{
for (i = 0; i < Row; i++)
{
v = maincol[k];
mid = cmat(k, i);
cmat(k, i) = cmat(v, i);
cmat(v, i) = mid;
}
for (i = 0; i < Row; i++)
{
v = mainrow[k];
mid = cmat(i, k);
cmat(i, k) = cmat(i, v);
cmat(i, v) = mid;
}
}
delete[]mainrow;
delete[]maincol;
return cmat;
}