複數矩陣計算行列式

項目上需要對復矩陣的行列式計算,根據計算一般矩陣行列式的代碼改成了復矩陣行列式計算。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<fstream>
#include <iomanip>
using namespace std;

#define ROW 25
#define COL 25
typedef struct  
{
	float Real;
	float Image;
}Complex;


Complex add(Complex a,Complex b)
{
	Complex c;
	c.Real=a.Real+b.Real;
	c.Image=a.Image+b.Image;
	return c;
}
Complex sub(Complex a,Complex b)
{
	Complex c;
	c.Real=a.Real-b.Real;
	c.Image=a.Image-b.Image;
	return c;
}
Complex Mul(Complex a,Complex b)
{
	Complex c;
	c.Real=a.Real*b.Real-a.Image*b.Image;
	c.Image=a.Real*b.Image+b.Real*a.Image;
	return c;
}
Complex Div(Complex a,Complex b)
{
	Complex c;
	c.Real=(a.Real*b.Real+a.Image*b.Image)/(b.Real*b.Real+b.Image*b.Image);
	c.Image=(a.Image*b.Real-a.Real*b.Image)/(b.Real*b.Real+b.Image*b.Image);
	return c;
}
Complex matrix_det(const Complex *mat, int n)
{
    int i,j,k,is,js,l,v;
	Complex det;
	float flag,pivot,tmp;
    Complex *cpmat;
	Complex tempValue;
    if(mat == NULL)                            /* 檢查輸入的指針是否爲空*/
    {
      printf("matrix pointer is NULL.\n");
    }
    cpmat = (Complex*)malloc(n*n*sizeof(Complex));  /* 將輸入矩陣的內容拷貝一份,以免破壞*/
    for(i=0; i<n*n; i++)
      cpmat[i] = mat[i];
	det.Real = 1.0;                                 /* 設置行列式值初置*/ 
	det.Image=0.0;
	flag= 1.0;                                /* 這個變量原來記錄行列式值的符號*/
    for(k=0; k<n-1; k++){           /* 最多進行n-1次消去*/     
    
		pivot = 0.0;                             /* 選擇主元*/

		for(i=k; i<n; i++){
			for(j=k; j<n; j++){
				tmp = cpmat[i*n+j].Real*cpmat[i*n+j].Real+cpmat[i*n+j].Image*cpmat[i*n+j].Image;
				if(tmp > pivot){
					pivot = tmp;
					is = i;
					js = j;
				}
			}
		}
		if(pivot < 1e-5){                          /* 如果找到的主元小於eps,則認爲是0。*/
			det.Real = 0.0;                             /*此時行列式值也是0。*/
			det.Image=0.0;
			return(det);
		} 
		if(is != k){                              /* 判斷是否需要行交換*/
			flag = -flag;                          /* 行交換一次,行列式值變號*/
			for(j=k; j<n; j++){                     /* 進行行交換*/	
				l = k*n + j;
				v = is*n + j;
				tempValue = cpmat[l];
				cpmat[l] = cpmat[v];
				cpmat[v] = tempValue;
			}
      }
      if(js != k){                              /* 判斷是否需要列交換*/
			flag = -flag;                          /* 列交換一次,行列式值變號*/
			for(i=k; i<n; i++){                     /* 進行列交換*/
				
				l = i*n + k;
				v = i*n + js;
				tempValue = cpmat[v];
				cpmat[v] = cpmat[l];
				cpmat[l] = tempValue;
			}
     }
     for(i=k+1; i<n; i++){                    /* 進行消去*/
		tempValue=Div(cpmat[i*n+k],cpmat[k*n+k]);   /* 記錄下此值,減少除法的次數*/   
		for(j=k+1; j<n; j++) {                 /* 消去*/
			Complex aa;
			aa=Mul(tempValue,cpmat[k*n+j]);
			cpmat[i*n+j]=sub(cpmat[i*n+j],aa);
		}
	 }
      det = Mul(det,cpmat[k*n+k]);           /*更新det的值*/
    }
	det = Mul(det,cpmat[k*n+k]); /* 最終更新det的值*/
	det.Real=flag*det.Real;
	det.Image=flag*det.Image;
    free(cpmat);       
    return(det);
}

int main()
{
	Complex *inputdata;
	Complex result;
	inputdata=(Complex*)malloc(sizeof(Complex)*ROW*COL);
	ofstream myfile("example.txt");
	srand(time(0));
	for(int i=0;i<ROW*COL;i++){
		inputdata[i].Real=(float)rand()/10000;
		inputdata[i].Image=(float)rand()/10000;
	}
	//cout<<"[";
	myfile<<"b=[";
	for(int i=0;i<ROW;i++){
		for(int j=0;j<COL;j++){
			//cout<<inputdata[i*COL+j].Real<<"+"<<inputdata[i*COL+j].Image<<"i";
			myfile<<inputdata[i*COL+j].Real<<"+"<<inputdata[i*COL+j].Image<<"i";
			if(j<COL-1){
			//	cout<<",";
				myfile<<",";
			}
		}
		if(i<COL-1){
			//cout<<";";
			myfile<<";";
		}
		
	}
	//cout<<"]"<<endl;
	myfile<<"]"<<endl;;
	
	result=matrix_det(inputdata,ROW);
	//cout<<"Result:"<<endl;
	//cout<<result.Real<<"+"<<result.Image<<"i"<<endl;
	myfile<<setiosflags(ios::showpoint)<<result.Real<<"+"<<result.Image<<"i"<<endl;
	myfile<<flush;
	myfile.close();
	return 0;
}
計算結果與matlab計算對比,沒有問題
發佈了40 篇原創文章 · 獲贊 7 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章