矩matrix八卦

下面这个文件是进行矩阵运算的一些操作,你使用最后一个函数EquationResolution就可以进行最小二乘求解了。当然,在计算前,你需要自己构造上述的系数矩阵和常数矩阵,其实就是两个数组。

// Matrix.hpp

#if !defined(_MATRIXCALCULATE_HPP__INCLUDED_)

#define _MATRIXCALCULATE_HPP__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

#include <math.h>

class CMatrixCalculate

{

public:

////求矩阵matrix的行列式值, n为维数

double CalculateLiner(double *matrix,int n)

{

double liner=0;

int i=0,j=0,k=0;

int p=0,q=0;

if(n==1)

return matrix[0];

else

{

double *tr=(double *)calloc((n-1)*(n-1),sizeof(double));

for(k=0;k<n;k++)

{

p=0;

for(i=0;i<n;i++)

{

if(i!=0)

{

q=0;

for(j=0;j<n;j++)

{

if(j!=k)

{

tr[p*(n-1)+q]=matrix[i*n+j];

q++;

}

}

p++;

}

}

liner+=matrix[k]*pow(-1,k)*CalculateLiner(tr,n-1);

}

free(tr);

return liner;

}

}

////求矩阵matrix的第i行,j列的代数余子式, n为维数

double CalculateCofacter(double *matrix,int i,int j,int n)

{

int x=0,y=0;

int p=0,q=0;

if(n==1)

return matrix[0];

else

{

double *tr=(double *)calloc((n-1)*(n-1),sizeof(double));

p=0;

for(x=0;x<n;x++)

{

if(x!=i)

{

q=0;

for(y=0;y<n;y++)

{

if(y!=j)

{

tr[p*(n-1)+q]=matrix[x*n+y];

q++;

}

}

p++;

}

}

double cc=pow(-1,i+j)*CalculateLiner(tr,n-1);

free(tr);

return cc;

}

}

////矩阵转置, matrixAT=(matrixA)T, m,n为matrixA的行,列数

void CalculateAT(double *matrixA,double *matrixAT,int m,int n)

{

for (int i=0;i<m;i++)

{

for (int j=0;j<n;j++)

{

matrixAT[j*m+i]=matrixA[i*n+j];

}

}

}

////矩阵相乘, matrixAB=matrixA*matrixB, i,j为matrixA的行,列数, j,k为为matrixB的行,列数

void CalculateAB(double *matrixA,double *matrixB,double *matrixAB,int i,int j,int k)

{

for (int m=0;m<i;m++)

{

for (int n=0;n<k;n++)

{

matrixAB[m*k+n]=0;

for (int s=0;s<j;s++)

{

matrixAB[m*k+n]+=matrixA[m*j+s]*matrixB[s*k+n];

}

}

}

}

////matrixATA=(matrixA)T*matrixA, m,n分别为matrixA的行,列数

void CalculateATA(double *matrixA,double *matrixATA,int m,int n)

{

double *at=(double *)calloc((m)*(n),sizeof(double));

CalculateAT(matrixA,at,m,n);

CalculateAB(at,matrixA,matrixATA,n,m,n);

free(at);

}

////matrixA_为matrixA的逆, m为阶数

void CalculateA_(double *matrixA,double *matrixA_,int m)

{

double liner=CalculateLiner(matrixA,m);

for(int i=0;i<m;i++)

{

for(int j=0;j<m;j++)

matrixA_[j*m+i]=CalculateCofacter(matrixA,i,j,m)/liner;

}

}

////////////////////////////////////////////////////////////////////

////求正定矩阵a的逆矩,n为阶数

int MatrixInversion(double *a, int n)

{

int i, j, k, m;

double w, g, *b;

b = new double [n];

for(k = 0; k <= n - 1; k++)

{

w = a[0];

w=a[0]+1.0e-15;

/*

if(fabs(w)+1.0 == 1.0)

{

delete b;

printf("fail\n");

return(-2);

}

*/

m = n - k - 1;

for(i = 1; i <= n - 1; i++)

{

g = a[i * n];

b[i] = g / w;

if(i <= m)

b[i] = -b[i];

for(j = 1; j <= i; j++)

a[(i - 1) * n + j - 1] = a[i * n + j] + g * b[j];

}

a[n * n - 1] = 1.0 / w;

for(i = 1; i <= n - 1; i++)

a[(n - 1) * n + i - 1] = b[i];

}

for(i = 0; i <= n - 2; i++)

for(j = i + 1; j <= n - 1; j++)

a[i * n + j] = a[j * n + i];

delete b;

return(2);

}

////求正定矩阵a的逆矩,n为阶数

void MatInversion(double *a,int n)

{

int i,j,k;

for(k=0;k<n;k++)

{

for(i=0;i<n;i++)

{

if(i!=k) *(a+i*n+k) = -*(a+i*n+k)/(*(a+k*n+k));

}

*(a+k*n+k)=1/(*(a+k*n+k));

for(i=0;i<n;i++)

{

if(i!=k)

{

for(j=0;j<n;j++)

{

if(j!=k) *(a+i*n+j) += *(a+k*n+j)* *(a+i*n+k);

}

}

}

for(j=0;j<n;j++)

{

if(j!=k) *(a+k*n+j)*=*(a+k*n+k);

}

}

}

/*矩阵求逆子程序(Good)*/

int Invers_matrix(double *m1,int n)

{

int *is,*js;

int i,j,k,l,u,v;

double temp,max_v;

is=(int *)malloc(n*sizeof(int));

js=(int *)malloc(n*sizeof(int));

if(is==NULL||js==NULL)

{

printf("out of memory!\n");

return(0);

}

for(k=0;k<n;k++)

{

max_v=0.0;

for(i=k;i<n;i++)

{

for(j=k;j<n;j++)

{

temp=fabs(m1[i*n+j]);

if(temp>max_v)

{

max_v=temp; is[k]=i; js[k]=j;

}

}

}

if(max_v==0.0)

{

free(is); free(js);

printf("invers is not availble!\n");

return(0);

}

if(is[k]!=k)

{

for(j=0;j<n;j++)

{

u=k*n+j; v=is[k]*n+j;

temp=m1[u]; m1[u]=m1[v]; m1[v]=temp;

}

}

if(js[k]!=k)

for(i=0;i<n;i++)

{

u=i*n+k; v=i*n+js[k];

temp=m1[u]; m1[u]=m1[v]; m1[v]=temp;

}

l=k*n+k;

m1[l]=1.0/m1[l];

for(j=0;j<n;j++)

{

if(j!=k)

{

u=k*n+j;

m1[u]*=m1[l];

}

}

for(i=0;i<n;i++)

{

if(i!=k)

{

for(j=0;j<n;j++)

{

if(j!=k)

{

u=i*n+j;

m1[u]-=m1[i*n+k]*m1[k*n+j];

}

}

}

}

for(i=0;i<n;i++)

{

if(i!=k)

{

u=i*n+k;

m1[u]*=-m1[l];

}

}

}

for(k=n-1;k>=0;k--)

{

if(js[k]!=k)

for(j=0;j<n;j++)

{

u=k*n+j; v=js[k]*n+j;

temp=m1[u]; m1[u]=m1[v]; m1[v]=temp;

}

if(is[k]!=k)

for(i=0;i<n;i++)

{

u=i*n+k; v=i*n+is[k];

temp=m1[u]; m1[u]=m1[v]; m1[v]=temp;

}

}

free(is); free(js);

return(1);

}

////求矩阵方程matrixA*matrixX=matrixL的最小二乘解, m,n分别为matrixA矩阵的行,列数

void EquationResolution(double *matrixA,double *matrixL,double *matrixX,int m,int n)

{

if (m<n) return;

double *at=(double *)malloc((m)*(n)*sizeof(double));

double *ata=(double *)malloc((n)*(n)*sizeof(double));

double *atl=(double *)malloc((n)*sizeof(double));

CalculateATA(matrixA,ata,m,n);

MatrixInversion(ata,n);

CalculateAT(matrixA,at,m,n);

CalculateAB(at,matrixL,atl,n,m,1);

CalculateAB(ata,atl,matrixX,n,n,1);

free(at);

free(ata);

free(atl);

}

}

#endif // !defined(_MATRIXCALCULATE_HPP__INCLUDED_)