当前位置:文档之家› C++实现矩阵类

C++实现矩阵类

C++实现矩阵类
C++实现矩阵类

#include "Matrix.h"

#include "general.h"

#include

#include

#include

#include

#include

#include

using namespace std;

//------------------------------ Implementation -----------------------------

Matrix::Matrix() //default constructor

{

rows=columns=0;

buf=NULL;

cout<<"call constructor"<

}

Matrix::Matrix( int m, int n)//declare an mxn matrix

{

// if(!this->buf)//个人认为该行程序根本没用

// delete[] this->buf;

this->rows=m;

this->columns=n;

this->buf=new double[m*n];

cout<<"call constructor"<

}

Matrix::Matrix(const Matrix& A) //copy constructor

{

// Matrix C(C); ??????????? could not pass compile, don't worry

// if(!this->buf)delete[] this->buf;

this->rows=A.rows;

this->columns=A.columns;

this->buf=new double[(A.rows)*(A.columns)];

int i;

for(i=0;i<((A.rows)*(A.columns));i++)

{

this->buf[i]=A.buf[i];

}

cout<<"call copy constructor"<

}

Matrix::~Matrix()//destructor

{

delete[] this->buf;

this->rows=0;

this->columns=0;

cout<<"call destructor"<

}

//Assignment

Matrix& Matrix::operator = (const Matrix& A) //overloading = {

if(this==&A) return *this;

if(!buf) delete[] buf;

columns=A.columns;

rows=A.rows;

buf=new double[columns*rows];

int i;

for(i=0;i<(columns*rows);i++)

{

buf[i]=A.buf[i];

}

return *this;

}

//operators

bool Matrix::operator == (const Matrix& A)//overloading == {

int i;

if(!this->buf||!A.buf)

{

cout<<"Two Empty Matrix"<

return true;

}

if(this->columns!=A.columns||this->rows!=A.rows)

return false;

else

{

for(i=0;i

{

if(abs(this->buf[i]-A.buf[i])>1e-10) return false;

}

}

return true;

}

bool Matrix::operator != (const Matrix& A)//overloading !=

{

return !(*this==A); //use ==

}

Matrix& Matrix::operator += (const Matrix& A) //overloading +=

{

if(!A.buf) return *this;

if ( (this->rows != A.rows) || (this->columns != A.columns))

{

//cerr << "Size mismatch in matrix addition" << endl;

throw logic_error ("Size mismatch in matrix addition");

}

for(int i=0;i

this->buf[i]+=A.buf[i];

return *this;

}

Matrix& Matrix::operator -=(const Matrix& A) //overloading -= {

if(!A.buf) return *this;

if ( (this->rows != A.rows) || (this->columns != A.columns))

{

//cerr << "Size mismatch in matrix addition" << endl;

throw logic_error ("Size mismatch in matrix addition");

}

for(int i=0;i

this->buf[i]-=A.buf[i];

return *this;

}

Matrix& Matrix::operator *=(const Matrix& A) //overloading *=

{

if(!A.buf) throw logic_error (" You are Multipling Empty Matrix");

if(this->columns!=A.rows) throw logic_error ("Size Mismatch!");

if(A.columns==0||A.rows==0||this->columns==0||this->rows==0) throw logic_error ("go check your weried matrix first");

// Matrix tmp(*this);

//delete[] this->buf;

//this->buf= new double[this->rows*A.columns];

Matrix tmp(this->rows, A.columns);

for (int i=1; i<=tmp.rows; i++)

{

for (int j=1; j<=tmp.columns; j++)

{

tmp(i,j) = 0;

for (int k=1; k<=A.rows; k++)

tmp(i,j) += (*this)(i,k) * A(k,j);

}

}

*this = tmp;

return *this;

}

Matrix& Matrix::operator *=(double a) //overloading *=

{

if(!this->buf) throw logic_error ("please Check your empty Matrix first");

for(int i=0;i

{

this->buf[i]*=a;

}

return *this;

}

Matrix Matrix::operator + () //unary +

{

return *this; //good enough.

}

Matrix Matrix::operator - () //unary -

{

if ((this->rows == 0) || (this->columns == 0) )

{

throw invalid_argument ("Missing matrix data");

}

Matrix tmp(this->rows, this->columns);

for (int i=0; i

{

tmp.buf[i]=-(this->buf[i]);

}

return tmp;

}

double& Matrix::operator ()( int i, int j)// access (i,j)

{

if(i>this->rows||j>this->columns) throw logic_error ("Matrix is not this big");

if(i<=0||j<=0) throw logic_error ("can not access, your index is wrong");

return buf[(i-1)*columns+(j-1)]; // is this correct? Unsafe

}

double& Matrix::operator()( int i, int j) const //read only

{

//return buf[i*columns+j]; // is this correct? Unsafe

return buf[(i-1)*columns+(j-1)]; // is this correct? Unsafe

}

std::ostream& operator << (std::ostream& output, const Matrix& A)

{

output<<"------------------------"<

for ( int i = 1; i <= A.rows; i++)

{

for ( int j = 1; j <= A.columns; j++)

output << A(i,j) << "\t";

output << endl;

}

output<<"------------------------";

// for ( int i = 1; i <= A.GetRows(); i++)//???????????????????????????????????????????????

// {

// for ( int j = 1; j <= A.GetColumns(); j++)//??????????????????????????????????????????

// output << A(i,j) << "\t ";

// output << endl;

// }

return output;

}

std::istream& operator >> (std::istream& input, Matrix& A)

{

if (input.fail())

{

throw runtime_error ("Error reading input");

}

BypassComment(input);

input >> A.rows;

BypassComment(input);

input >> A.columns;

cout<

if (A.rows<=0 || A.columns<=0)

{

throw invalid_argument ("Invalid matrix data");

}

if (A.buf) delete[] A.buf;//check if A.buf=NULL, if not,delete A

A.buf=new double[A.rows*A.columns];

for (int i=1; i<=A.rows; i++)

{

for (int j=1; j<=A.columns; j++)

{

BypassComment(input);

input >> A(i,j);

//cout<

}

}

//use BypassComment to skip comments.

return input;

}

//------------Member Functions------------------------------

Matrix Matrix::Adjugate() //Adjoint/Adjugate伴随矩阵是代数余子式的转置

{

Matrix tmp;

tmp=this->Cofactor();//余因子

tmp=tmp.Transpose();//转置

return tmp;

}

double Matrix::Cofactor(int i, int j) //cofactor Cij余因子(代数余子式)

{

double tmp;

tmp=this->Minor(i,j);//子式

tmp=pow(-1,(i+j))*tmp;//代数余子式

// double tmp;

return tmp;

}

Matrix Matrix::Cofactor()//matrix of cofactors

{

if(!this->buf) throw logic_error (" Empty Matrix ");

Matrix tmp(this->rows, this->columns);

for (int i=1;i<=this->rows;i++)

{

for (int j=1;j<=this->columns;j++)

{

tmp(i,j)=this->Cofactor(i,j);

}

}

return tmp;

}

double Matrix::Minor(int i, int j)//Minor Mij

{

double tmp;

Matrix A;

A.rows=(this->rows)-1;

A.columns=(this->columns)-1;

A.buf=new double[A.rows*A.columns];

int a=0;

for(int m=1;m<=this->rows;m++)

{

for(int n=1;n<=this->columns;n++)

{

if(m==i) continue;

if(n==j) continue;

A.buf[a]=(*this)(m,n);

a++;

}

}

tmp=A.det();//计算矩阵行列式的值

return tmp;

}

bool Matrix::IsSingular()

{

//return (this->det()==0); //may not work, because of double

precision. you fix it.

return (fabs(this->det()-0)<0.00000001);

}

bool Matrix::IsSymmetric()

{

return ((*this)==(this->Transpose()));

}

const int Matrix::GetRows() const

{

return rows;

};

const int Matrix::GetColumns() const

{

return columns; //

};

Matrix Matrix::Transpose() //transpose

{

//check size

if ((this->GetRows() == 0) || (this->GetColumns() == 0) )

{

//cerr << "Missing matrix data" << endl;

throw invalid_argument ("Missing matrix data");

}

Matrix tmp(this->GetColumns(), this->GetRows());

for (int i=1; i<=tmp.GetRows(); ++i)

{

for (int j=1; j<=tmp.GetColumns(); ++j)

tmp(i,j) = (*this)(j,i);

}

return tmp;

}

Matrix Matrix::Inverse()//Inverse Matrix

Matrix tmp;

if((*this).GetRows()!=(*this).GetColumns())

{throw logic_error ("Solving for Inverse fail: Not a square matrix!");

//return (*this);

}

if(fabs(this->det()-0)<0.000000001)

{

throw logic_error ("determinant equal to zero, can not do inverse");

}

Matrix A;

A=this->Adjugate();

tmp=(1/this->det())*A;

return tmp;

}

Matrix Matrix::Null(int n) //make a "zero" Matrix, with a new dimension, change "this"

{

/*

if ( n==0 || this->GetRows==0 || this->GetColumns==0) {

//cerr << "Size mismatch in matrix addition" << endl;

throw logic_error ("can not do Null");

}

*/

// if(n==0||this->GetRows==0||this->GetRows==0) return false;

this->rows=n;

this->columns=n;

this->buf=new double[n*n];

for(int a=0;a

for(int b=0;b

this->buf[a*this->columns+b]=0;

}

return *this;

}

Matrix Matrix::Null()//make a "zero" Matrix, does not change the dimension, change "this"

{

//if(this->GetRows()=0||this->GetColumns()=0) return false;

for(int a=0;a< this->GetRows();a++)

{

for(int b=0;b< this->GetColumns();b++)

this->buf[a*this->GetColumns()+b]=0;

}

return *this;

}

Matrix Matrix::Identity( int n)//make a nxn identity matrix,change "this"

{

// if(n==0) return false;

if(n<=0)

throw invalid_argument ("argument has to be larger than 0");

this->rows=n;

this->columns=n;

this->buf=new double[n*n];

int a;

int b;

for(a=0;a< this->GetRows();a++)

{

for(b=0;b< this->GetRows();b++)

{

if(a==b)

this->buf[a*n+b]=1;

else

this->buf[a*n+b]=0;

}

}

return *this;

}

Matrix Matrix::Identity()//make a identity matrix, does not change the dimentsion, change "this"

{

if(this->GetRows()!=this->GetColumns() || this->GetRows()==0)

throw logic_error ("Check your matrix . Matrix has to be squre ");

int a;

int b;

for(a=0;aGetRows();a++)

{

for(b=0; b< this->GetColumns();b++)

{

if(a==b)

this->buf[a*this->columns+b]=1;

else

this->buf[a*this->columns+b]=0;

}

}

return *this;

}

bool Matrix::LU(Matrix& L, Matrix& U)//LU decomposition. return true if successful

{

/*

//check size

if ((this->GetRows() == 0) || (this->GetColumns() == 0) || (this->GetRows() != this->GetColumns()))

return false; //cannot do it.

Matrix B = *this;

B.Null();//zero out

L=B;

U=B;

//check for pivot point (normalized to 1), record row change permutation and row scaling factor

int* rowIndex; double* rowScale;

try

{

rowIndex = new int [B.rows];

rowScale = new double [B.rows];

}

catch (...) //mostly bad_alloc&

{

cout << "Error allocating memory" << "\n";

if (rowIndex) delete[] rowIndex; rowIndex = NULL;

if (rowScale) delete[] rowScale; rowScale = NULL;

return false;

}

int detSign = 1;

double tol = numeric_limits::min();

cout<

double tmp, eMax; int rowMax;

for (int i=0; i

{

for (int j=0; j

{

tmp = fabs(B.buf[i*B.columns+j]);

if (tmp>eMax) eMax = tmp;

}

if (eMax

{

cout << "Matrix is singular" << "\n";

detSign = 0;

return false;

}

rowScale[i] = 1/eMax;

}

for (int j=0; j

{

eMax = 0;

for (int i=j; i

{

tmp = fabs(B.buf[i*B.columns+j]) * rowScale[i];

if (tmp>eMax)

{

eMax = tmp;

rowMax = i;

}

}

if (eMax

{

cout << "Matrix is singular" << "\n";

detSign = 0;

return false;

}

//if row interchange is performed, record new detSign and row scaling factor

if (rowMax != j)

{

for (int k=0; k

{

tmp = B.buf[j*B.columns+k];

B.buf[j*B.columns+k] = B.buf[rowMax*B.columns+k];

B.buf[rowMax*B.columns+k] =tmp;

}

detSign = -detSign;

tmp = rowScale[j];

rowScale[j] = rowScale[rowMax];

rowScale[rowMax] = tmp;

}

rowIndex[j] = rowMax; //used for root solving (need to modify variables declaration of LU function)

}

//same procedure as Crout's algorithm without pivoting

for (int j=0; j

{

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

{

U.buf[i*U.columns+j] = B.buf[i*B.columns+j];

for (int k=0; k

{

U.buf[i*U.columns+j] -= L.buf[i*L.columns+k] * U.buf[k*U.columns+j];

}

if (i==j) L.buf[i*L.columns+j] = 1;

else L.buf[i*L.columns+j] = 0;

}

for (int i=j+1; i

{

if (fabs(U.buf[j*U.columns+j]) < tol)

{

cout << "Matrix is singular" << "\n";

detSign = 0;

return false;

}

L.buf[i*L.columns+j] = B.buf[i*B.columns+j] / U.buf[j*U.columns+j];

for (int k=0; k

{

L.buf[i*L.columns+j] -= L.buf[i*L.columns+k] * U.buf[k*U.columns+j] / U.buf[j*U.columns+j];

}

U.buf[i*U.columns+j] = 0;

}

}

return true;

*/

/*

if(this->GetRows()==0 || this->GetRows()!=this->GetColumns()) return false;

Matrix B=*this;

B.Null();

L=B;

U=B;

int i,j,n,k,m=1;

for(i=0;iGetColumns();i++)

U.buf[i]=this->buf[i];

for(i=0;iGetColumns();i++)

L.buf[i*columns+1]=this->buf[i*columns+1];

while(mGetColumns())

{

for(j=m;jGetRows();j++)

{

double sum=0;

for(k=0;k

sum+=L.buf[m*columns+k]*U.buf[k*columns+j];

U.buf[m*columns+j]=this->buf[m*columns+j]-sum;

if(U.buf[m*columns+j]==0) return false;

}

for(j=m;jGetRows();j++)

{

double sum2=0;

for(k=0;k

sum2+=L.buf[j*columns+k]*U.buf[k*columns+m];

L.buf[j*columns+m]=this->buf[j*columns+m]-sum2;

}

m++;

}

return true;

*/

/*

double m=0;

//check this Matrix

if(!this->buf)

cout<<"Matrix A has no data"<

if(this->columns!=this->rows)

cout<<"Matrix has to be square matrix for LU decomposition"<

if(L.buf)

{

L.rows=L.columns=0;

delete[] L.buf;

L.buf=NULL;

}

L.columns=this->columns;

L.rows=this->rows;

L.buf=new double[L.rows*L.columns];

if(U.buf)

{

U.rows=U.columns=0;

delete[] U.buf;

U.buf=NULL;

}

U.columns=this->columns;

U.rows=this->rows;

U.buf=new double[U.rows*U.columns];

// initialize Matrix U

for(long i=0;i< this->rows*this->columns;i++)

{

// *(U.buf+i)=*(A.buf+i);

U.buf[i]=this->buf[i];

}

// initialize Matrix L

for(long i=0;i< this->rows;i++)

{

for (long k=0;k< this->columns;k++)

{

if(i==k) // ==,==,==,==,==

// *(L.buf+i*A.columns+k)=1;

L.buf[i*this->columns+k]=1;

else

// *(L.buf+i*A.columns+k)=0;

L.buf[i*this->columns+k]=1;

}

}

//LU decomposition start from here

for(long i=0; i< this->columns;i++)

{

for(long j=i+1;j< this->columns;j++)

{

//if(*(U.buf+i*U.columns+i)==0)

if(U.buf[i*this->columns+i]==0)

{ cout<<"Matrix can not be divided by LU decomposition"<

return false;

}

else

{

//

m=*(U.buf+j*U.columns+i)/(*(U.buf+i*U.columns+i));

m=U.buf[j*this->columns+i]/U.buf[i*this->columns+i];

//

*(L.buf+j*L.columns+i)=*(U.buf+j*U.columns+i)/(*(U.buf+i*U.colu mns+i));// get Matrix L

L.buf[j*this->columns+i]=U.buf[j*this->columns+i]/U.buf[i*this->col

c++课程设计-矩阵的转置与乘法计算

c++课程设计-矩阵的转置与乘法计算

C++课程设计实验报告 姓名学号班级 任课教师时间 9月 教师指定题目4-4 矩阵的转置与乘法计算评定难易级别 A 实验报告成绩 1.实验内容: 1.1 程序功能介绍 该程序定义了一个向量类,里面的元素是模板形式,定义了有关向量了类的各种属性、方法及运算符重载函数。 1.2 程序设计要求 (1)利用已知的向量类对象定义一个矩阵类,矩阵类的数据是向量子对象,同样定义矩阵类的各种属性、方法及运算符重载函数。 (2)完善成员函数,使矩阵可以由文件输入,具体的输入格式自己规定。 (3)完成矩阵的赋值、转置、乘法等运算,要求用整形矩阵和浮点型矩阵分别演算。 (4)更改main函数结构,可由用户选择输入矩阵数据的方法,程序可以连续运行,直到选择退出为止。

2. 源程序结构流程框图与说明(含新增子函数的结构框图)

作者:喻皓学号:0511590125

3. 基本数据结构 定义的类模板,将函数用链表将一些功能函数连接起来。其中定义了构造函数,析构函数,重载赋值、乘法、数乘、输入、输出,矩阵转置等函数,实现矩阵的矩阵的赋值、转置、乘法等运算。 template class CMatrix { struct node { Vector **f;//**************************************组成矩阵的向量指针 int refcnt;//*************************************************被引用次数 int length;//*************************************************矩阵的行数 T **tmppointer;//*******************************************头指针类型} *p; public: // Vector ** begin() const {return p->f;}; CMatrix();//****************************************************默认的构造 CMatrix(int xsize,int ysize,T init=0);//***************************构造函数 CMatrix(int xlength,const Vector *vec);//************************构造函

三元组顺序表实现矩阵的转置

三元组顺序表实现矩阵的转置: /*-------------------------------------------------------------- ----------------用三元组顺序表实现对稀疏矩阵的转置----------------- ------------------------编译环境:VS 2013------------------------ --------------------------------------------------------------*/ #define_CRT_SECURE_NO_WARNINGS//用于取消VS 2013对printf、scanf等函数的警告#include #include #define MAXSIZE 100 typedef int ElemType; typedef struct { int i; int j; ElemType e; }tupletype; typedef struct { int rownum; int colnum; int nznum; tupletype data[MAXSIZE]; }table; void creatable(table *M); //用户输入,创建一个三元组表 void trans(table *M, table *T); //转置 void show(table *M); //以矩阵形式输出三元组表 int main() { table M, T; creatable(&M); system("cls"); puts("矩阵M:"); show(&M); trans(&M, &T); puts("矩阵M的转置矩阵T:"); show(&T); return 0; }

矩阵转置及相加实验报告

一、实验内容和要求 1、稀疏矩阵A,B均采用三元组表示,验证实现矩阵A快速转置算法,设计并验证A,B相 加得到矩阵C的算法。 (1)从键盘输入矩阵的行数和列数,随机生成稀疏矩阵。 (2)设计算法将随机生成的稀疏矩阵转换成三元组顺序表示形式存储。 (3)设计算法将快速转置得到的与相加得到的三元组顺序表分别转换成矩阵形式。 (4)输出随机生成的稀疏矩阵A,B及其三元组顺序表、快速转置得到的与相加得到的三元组顺序表及其矩阵形式。 二、实验过程及结果 一、需求分析 1、将随机生成的数定义为int型(为方便起见设定范围为-20至20(不含0),可 修改),三元组存储的元素分别为非零元的行下标、列下标及该位置的元素值,零元不进行存储。实际上在生成稀疏矩阵时是随机选取一些位置生成非零元然后存入三元组中。 2、从键盘输入矩阵的行数和列数后应能输出三元组顺序表及相应矩阵(按行和列 排列形式输出)。 3、程序能实现的功能包括: ①随机产生稀疏矩阵;②输出阵列形式的矩阵;③输出三元组顺序 表;④将矩阵快速转置;⑤将两个稀疏矩阵相加生成新的矩阵。 二、概要设计 1、稀疏矩阵的抽象数据类型定义: ADT TSMatrix{ 数据对象:D={ aij|i=1,2,…,m,j=1,2,…,n; Ai,j∈ElemSet,m和n分别称为矩阵的行数和列数}数据关系:R={Row,Col} Row={|1≤i≤m, 1≤j≤n-1} Col ={|1≤i≤m-1, 1≤j≤n} 基本操作: CreateTSMatrix(&M) 操作结果:创建矩阵M PrintTSMatrix(M) 初始条件:矩阵M已存在 操作结果:输出矩阵M中三元组形式的非零元素 PrintTSMatrix1(M) 初始条件:矩阵M已存在 操作结果:以阵列形式输出矩阵 UnZore(M, row, col) 初始条件:矩阵M已存在 操作结果:若位置(row,col)处存在非零元素,则返回该元素存储在矩阵中的序号

c课程设计矩阵的转置与乘法计算

c课程设计矩阵的转置与乘法计算

C++课程设计实验报告 姓名学号班级 任课教师时间 9月 教师指定题目4-4 矩阵的转置与乘法计算评定难易级别 A 实验报告成绩 1.实验内容: 1.1 程序功能介绍 该程序定义了一个向量类,里面的元素是模板形式,定义了有关向量了类的各种属性、方法及运算符重载函数。 1.2 程序设计要求 (1)利用已知的向量类对象定义一个矩阵类,矩阵类的数据是向量子对象,同样定义矩阵类的各种属性、方法及运算符重载函数。 (2)完善成员函数,使矩阵能够由文件输入,具体的输入格式自己规定。(3)完成矩阵的赋值、转置、乘法等运算,要求用整形矩阵和浮点型矩阵分别演算。 (4)更改main函数结构,可由用户选择输入矩阵数据的方法,程序能够连续运行,直到选择退出为止。 2. 源程序结构流程框图与说明(含新增子函数的结构框图)

作者:喻皓学号:

3. 基本数据结构 定义的类模板,将函数用链表将一些功能函数连接起来。其中定义了构造函数,析构函数,重载赋值、乘法、数乘、输入、输出,矩阵转置等函数,实现矩阵的矩阵的赋值、转置、乘法等运算。 template class CMatrix { struct node { Vector **f;//**************************************组成矩阵的向量指针 int refcnt;//*************************************************被引用次数 int length;//*************************************************矩阵的行数T **tmppointer;//*******************************************头指针类型} *p;

求矩阵与其转置矩阵的乘积的和

#include using namespace std; //#include void zc(int a[][5],int b[][3],int c[][3]); void cj(int a[][5],int b[][3],int c[][3]); int sum(int a[3][3]); int main() { int a[3][5],b[5][3],c[3][3]={0}; for(int i=0;i<15;i++) a[0][i]=i+1; /*for( i=0;i<3;i++) { for(int j=0;j<5;j++) cout<<" "<

for(int j=0;j<3;j++) //b的列,c的列 { for(int k=0;k<5;k++) //b的行,a的列 { //cout<

矩阵的加、乘、转置运算实现

定义:由m × n 个数aij排成的m行n列的数表称为m行n列的矩阵,简称m × n矩阵;在编程语言中可以当做二维数组来处理; 加减法:同型矩阵之间 乘法:两个矩阵的乘法仅当第一个矩阵A的列数和另一个矩阵B的行数相等时才能定义。如A是m×n矩阵和B是n×p矩阵,它们的乘积C是一个m×p矩阵; 转置:把矩阵A的行换成同序数的列所得到的新矩阵称为A的转置矩阵; 详细的运算及原理可以百度一下; 如下是完整的Java代码实现: package algorithm; public class Matrix { public final int TYPE_ADD = 1; public final int TYPE_MUL = 2; /** * 矩阵类,实现n阶矩阵的加、乘、转置运算 * * @paramargs */ public static void main(String[] args) { // TODO Auto-generated method stub int[][] a = { { 1, 2 }, { 2, 3 } }; int[][] b = { { 4, 5 }, { 6, 7 } }; int[][] aa = new int[][]{{1,0,2},{-1,3,1}}; int[][] bb = new int[][]{{3,1}, {2,1},{1,0}}; Matrix m = new Matrix();

System.out.println("两矩阵相加:"); int[][] r = m.matrix_add(a, b); for (inti = 0; i

实验报告 矩阵快速转置

实验报告 实验项目名称:实现矩阵的快速 转置的操作 所属课题名称:数据结构 实验类型:验证实验 实验日期:2010/12/20 学院:数学与信息科学学院 专业: 信息与计算科学 班级: 082班 姓名:李晓璐 学号:0801214037

实验稀疏矩阵的快速转置操作 一、实验目的 1、了解稀疏矩阵的三元组存储形式。 2、熟悉掌握三元表存储矩阵的转置算法。 二、实验环境 硬件:PC 微型计算机、256M以上内存,40G以上硬盘。 软件:Windows XP,Turbo C/C++ 三、实验内容 转置运算是一种最简单的矩阵运算。对于一个m*n的矩阵M,它的转置矩阵T是一个n*m的矩阵。假设a和b是TSMatrix型的变量,分别表示矩阵M和T。按照a.data中三元组的次序进行转置,并将转置后的三元组置入b中恰当的位置。实现由a得到b的方式如下。 在转置前,应先求得M的每一列中非零元的个数,进而求得每一列的第一个非零元在b.data中应有的位置。在此,设num和cpot两个向量,num[col]表示矩阵M中第col列中非零元的个数,cpot[col]指示M中第col列的第一个非零元在b.data中应有的位置。显然有: cpot[1]=1; cpot[col]=cpot[col-1]+num[col-1] 四、实验步骤 1、本实验的程序清单如下。 “TSMatrix.h” #define MAXSIZE 12500 #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define OVERFLOW 0 typedef int Status; typedef int ElemType; struct Triple { int i,j;

稀疏矩阵快速转置 数据结构实验报告

南昌航空大学实验报告 课程名称:数据结构实验名称:实验五稀疏矩阵的存储和快速转置班级:学生姓名:学号: 指导教师评定:签名: 题目:假设稀疏矩阵A采用三元组表表示,编写程序实现该矩阵的快速转置 要求:输入一个稀疏矩阵A,由程序将其转换成三元组表存储;转置后的三元组表,由程序将其转换成矩阵形式后输出。 一、需求分析 1.用户可以根据自己的需求输入任意一个稀疏矩阵,通过程序将其转换成三元组存储方 式; 2.并且能够完成矩阵的转置功能,要求需要使用的方法是快速转置的方法。 3.最后要够显示原矩阵和转置后的矩阵让用户能进行比较。 4.程序执行的命令包括: (1)构造稀疏矩阵M (2)求转转矩阵T (3)显示(打印)矩阵 二、概要设计 ⒈为实现上述算法,需要线性表的抽象数据类型: ADT SparseMatrix { 数据对象:D={a ij:|a ij∈TermSet,i=1…m,m≥0,j=1…n,n≥0 m和n分别成为矩阵的行数和列数 } 数据关系:R={Row,Col} Row ={|1≤i≤m,1≤j≤n-1 } Col ={|1≤i≤m-1,1≤j≤n } 基本操作: CreateSMtrix(& M) 操作结果:创建稀疏矩阵M。 DestroySMaix(&M) 初始条件:稀疏矩阵M已存在。 操作结果:销毁稀疏矩阵M。 PrintSMatrix(L) 初始条件:稀疏矩阵M已经存在。 操作结果:输出稀疏矩阵M。 CopySMatrix(M,&T) 初始条件:稀疏矩阵M已经存在。 操作结果:由稀疏矩阵M复制得到T。 TransposeSMatrix(M,&T) 初始条件:稀疏矩阵M已经存在。

java实现矩阵的加,减,乘,转置运算

import java.util.*; public class JuZhen { // 创建矩阵 public static int[][] createJuZhen(int x, int y) { Scanner input = new Scanner(System.in); System.out.println("请输入" + x + "行" + y + "列的矩阵数据(行优先):"); int[][] array = new int[x][y]; for (int i = 0; i < array.length; i++) for (int j = 0; j < array[i].length; j++) { array[i][j] = input.nextInt(); } return array; } // 矩阵输出 public static void outputJuZhen(int[][] list) { for (int i = 0; i < list.length; i++) { for (int j = 0; j < list[i].length; j++) { System.out.print(list[i][j] + " "); } System.out.println(); } } // 矩阵求和 public static int[][] addJuZhen(int[][] list1, int[][] list2) { int[][] list3 = new int[list1.length][list1[0].length]; if (list1.length != list2.length || list1[0].length != list2[0].length) { System.out.println("行数或列数不同的矩阵不能相加!并将返回0:!!"); } else { for (int i = 0; i < list1.length; i++) for (int j = 0; j < list1[0].length; j++) list3[i][j] = list1[i][j] + list2[i][j]; } return list3; } // 矩阵相乘 public static int[][] mulJuZhen(int[][] list1, int[][] list2) { int[][] list3 = new int[list1.length][list2[0].length]; if (list1.length != list2[0].length || list1[0].length != list2.length) System.out.println("两矩阵不能符合条件相乘!并将返回0:!!"); else

求三角矩阵在压缩存储下的转置矩阵

#include #include #define max 20 #define zero 0 typedef struct{ int i,j,v; }node; typedef struct{ node data[max]; int m; }TSmatrix; TSmatrix *Setmatrix(){ //建三对角矩阵TSmatrix *T; T=(TSmatrix *)malloc(sizeof(TSmatrix)); printf("请输入矩阵行数或列数:\n"); scanf("%d",&T->m); printf("建立三对角矩阵:\n"); for(int n=0;n<3*T->m-2;n++) scanf("%d%d%d",&T->data[n].i,&T->dat a[n].j,&T->data[n].v); return T; } TSmatrix *Trabsmatrix(TSmatrix *T){ //三对角矩阵转置 int n,k,temp; TSmatrix *F; F=(TSmatrix *)malloc(sizeof(TSmatrix)); F->m=T->m; for(n=0;n<3*T->m-2;n++){ //将结点信息存入新三元组表中 temp=2*T->data[n].j+T->data[n].i; //计算待存入三元数组下标 F->data[temp].i=T->data[n].j; F->data[temp].j=T->data[n].i; F->data[temp].v=T->data[n].v; } return F; } void TSmatrixout(TSmatrix *T){ //三对角矩阵输出 int a,b,n; n=0; for(a=0;am;a++){ for(b=0;bm;b++){ if(T->data[n].i==a&&T->data[n].j==b){ printf("%-5d",T->data[n].v); n++; } else printf("%-5d",zero); } printf("\n"); } } void main(){ TSmatrix *T; T=Setmatrix(); printf("三对角矩阵:\n"); TSmatrixout(T); T=Trabsmatrix(T); printf("转置后三对角矩阵:\n"); TSmatrixout(T); }

矩阵转置及相加实验报告材料

一、实验容和要求 1、稀疏矩阵A,B均采用三元组表示,验证实现矩阵A快速转置算法,设计并验证A,B相 加得到矩阵C的算法。 (1)从键盘输入矩阵的行数和列数,随机生成稀疏矩阵。 (2)设计算法将随机生成的稀疏矩阵转换成三元组顺序表示形式存储。 (3)设计算法将快速转置得到的与相加得到的三元组顺序表分别转换成矩阵形式。 (4)输出随机生成的稀疏矩阵A,B及其三元组顺序表、快速转置得到的与相加得到的三元组顺序表及其矩阵形式。 二、实验过程及结果 一、需求分析 1、将随机生成的数定义为int型(为方便起见设定围为-20至20(不含0),可修 改),三元组存储的元素分别为非零元的行下标、列下标及该位置的元素值,零元不进行存储。实际上在生成稀疏矩阵时是随机选取一些位置生成非零元然后存入三元组中。 2、从键盘输入矩阵的行数和列数后应能输出三元组顺序表及相应矩阵(按行和列 排列形式输出)。 3、程序能实现的功能包括: ①随机产生稀疏矩阵;②输出阵列形式的矩阵;③输出三元组顺序 表;④将矩阵快速转置;⑤将两个稀疏矩阵相加生成新的矩阵。 二、概要设计 1、稀疏矩阵的抽象数据类型定义: ADT TSMatrix{ 数据对象:D={ aij|i=1,2,…,m,j=1,2,…,n; Ai,j∈ElemSet,m和n分别称为矩阵的行数和列数} 数据关系:R={Row,Col} Row={|1≤i≤m, 1≤j≤n-1} Col ={|1≤i≤m-1, 1≤j≤n} 基本操作: CreateTSMatrix(&M) 操作结果:创建矩阵M PrintTSMatrix(M) 初始条件:矩阵M已存在 操作结果:输出矩阵M中三元组形式的非零元素 PrintTSMatrix1(M) 初始条件:矩阵M已存在 操作结果:以阵列形式输出矩阵 UnZore(M, row, col) 初始条件:矩阵M已存在 操作结果:若位置(row,col)处存在非零元素,则返回该元素存储在矩阵中的序号 TSMatrix_Add(M, N,&Q)

矩阵转置与乘法

C++课程设计实验报告 姓名喻皓学号0511590125 班级 05115901 任课教师肖亮时间 9月 教师指定题目4-4 矩阵的转置与乘法计算评定难易级别 A 实验报告成绩 1.实验内容: 1.1 程序功能介绍 该程序定义了一个向量类,里面的元素是模板形式,定义了有关向量了类的各种属性、方法及运算符重载函数。 1.2 程序设计要求 (1)利用已知的向量类对象定义一个矩阵类,矩阵类的数据是向量子对象,同样定义矩阵类的各种属性、方法及运算符重载函数。 (2)完善成员函数,使矩阵可以由文件输入,具体的输入格式自己规定。 (3)完成矩阵的赋值、转置、乘法等运算,要求用整形矩阵和浮点型矩阵分别演算。 (4)更改main函数结构,可由用户选择输入矩阵数据的方法,程序可以连续运行,直到选择退出为止。 2. 源程序结构流程框图与说明(含新增子函数的结构框图)

作者:喻皓学号:0511590125

3. 基本数据结构 定义的类模板,将函数用链表将一些功能函数连接起来。其中定义了构造函数,析构函数,重载赋值、乘法、数乘、输入、输出,矩阵转置等函数,实现矩阵的矩阵的赋值、转置、乘法等运算。 template class CMatrix { struct node { Vector **f;//**************************************组成矩阵的向量指针 int refcnt;//*************************************************被引用次数 int length;//*************************************************矩阵的行数 T **tmppointer;//*******************************************头指针类型} *p; public: // Vector ** begin() const {return p->f;}; CMatrix();//****************************************************默认的构造 CMatrix(int xsize,int ysize,T init=0);//***************************构造函数CMatrix(int xlength,const Vector *vec);//************************构造函数CMatrix(CMatrix &x); //**************************************拷贝构造函数~CMatrix(); //****************************************************析构函数 CMatrix & operator=(const CMatrix &mat);//**************重载赋值运算符int row() const;//**************************************************返回行数int col() const;//**************************************************返回列数Vector & operator []( int i);//********************************重载[] void Inver(CMatrix &mat);//****************************************矩阵转置operator T **();//****************************************************重载** void ReadFromFile();//*************************************从文件中读入矩阵friend CMatrix cpy(CMatrix &v);//***********************************拷贝函数friend std::ostream & operator<<(std::ostream &s,const CMatrix &mat);//重载输出函数 friend std::istream & operator>>(std::istream &s,const CMatrix &mat);//重载输入函数 friend CMatrix operator*(CMatrix &v1,CMatrix &v2);//******矩阵乘法friend CMatrix operator*(const CMatrix &v,T val); //************数乘}; 4. 程序运行结果界面

矩阵转置实验报告doc

矩阵转置实验报告 篇一:实验报告矩阵快速转置 实验报告 实验项目名称:实现矩阵的快速转置的操作所属课题名称:数据结构 实验类型:验证实验 实验日期:XX/12/20 学院:数学与信息科学学院 专业: 信息与计算科学 班级: 082班 姓名:李晓璐 学号:0801214037 实验稀疏矩阵的快速转置操作 一、实验目的 1、了解稀疏矩阵的三元组存储形式。 2、熟悉掌握三元表存储矩阵的转置算法。 二、实验环境 硬件:PC 微型计算机、256M以上内存,40G以上硬盘。 软件:Windows XP,Turbo C/C++ 三、实验内容 转置运算是一种最简单的矩阵运算。对于一个m*n的矩阵M,它的转置矩阵T是一个n*m的矩阵。假设a和b是

TSMatrix型的变量,分别表示矩阵M和T。按照a.data中三元组的次序进行转置,并将转置后的三元组置入b中恰当的位置。实现由a得到b的方式如下。 在转置前,应先求得M的每一列中非零元的个数,进而求得每一列的第一个非零元在b.data中应有的位置。在此,设num和cpot两个向量,num[col]表示矩阵M中第col列中非零元的个数,cpot[col]指示M中第col列的第一个非零元在b.data中应有的位置。显然有: cpot[1]=1; cpot[col]=cpot[col-1]+num[col-1] 四、实验步骤 1、本实验的程序清单如下。 “TSMatrix.h” #define MAXSIZE 12500 #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define OVERFLOW 0 typedef int Status; typedef int ElemType; struct Triple

矩阵的转置,乘法

C++课程设计试验报告 姓名:张健学号:0806230209 班级:08062302任课老师:陆建峰时间:2009年9月23日 题目:矩阵运算 1.实验内容:用模板定义一个矩阵类,可能的数据类型为整数,浮点和复数。 需要完成的功能,主菜单 1 计算矩阵的转置 2 计算矩阵的乘法 3 计算矩阵的数乘 要求用指针来存储矩阵的内容,数据输入提供两种接口,从文件和键盘。 如果是从文件输入,则在主函数main中运用命令行参数将文件导入。 2.源程序结构流程框图与说明(含新增子函数的结构框图)

3.基本数据结构 template class jux { T **p; //矩阵的头指针 int nRow; //矩阵行数 int nCol; // 矩阵的列数public: void cinget(char *m); // 从文件输入矩阵friend istream& operator>>(istream &is,jux &a); // 重载输入运算符jux(int row ,int col); // 构造函数 void operator=(jux &b); // 重载赋值运算符void turn(jux &a); // 矩阵的转置 jux operator*(jux &a); // 矩阵的乘法void math(int x); // 矩阵的数乘void show(); // 矩阵的输出 4. 程序运行结果界面 图一,初始界面,选择运算方式 图二,选择运算数据类型

行数列数后,选择输入方式。 图四,选择文件输入后得到相乘的结果 再次循环。 5. 课程设计遇到的技术问题与解决思路 (1)构造函数开始时是包含输入矩阵的,很难对其进行初始化,每太繁琐,定义一个矩 阵就必须要对其进行输入!也不能进行从文件中直接读取数据。之后我将它分离出来,然后 再单独定义输入的重载。 (2)开始时不是很明白命令行参数的使用方法,在看过一些具体的例子后才明白如何使 用命令行参数。 (3)在运行程序时常常忘记命令行参数的使用。

c++课程设计 矩阵的转置与乘法计算

C++课程设计实验报告 姓名学号班级 任课教师时间 9月 教师指定题目4-4 矩阵的转置与乘法计算评定难易级别 A 实验报告成绩 1.实验内容: 1.1 程序功能介绍 该程序定义了一个向量类,里面的元素是模板形式,定义了有关向量了类的各种属性、方法及运算符重载函数。 1.2 程序设计要求 (1)利用已知的向量类对象定义一个矩阵类,矩阵类的数据是向量子对象,同样定义矩阵类的各种属性、方法及运算符重载函数。 (2)完善成员函数,使矩阵可以由文件输入,具体的输入格式自己规定。 (3)完成矩阵的赋值、转置、乘法等运算,要求用整形矩阵和浮点型矩阵分别演算。 (4)更改main函数结构,可由用户选择输入矩阵数据的方法,程序可以连续运行,直到选择退出为止。 2. 源程序结构流程框图与说明(含新增子函数的结构框图)

作者:喻皓学号:0511590125

3. 基本数据结构 定义的类模板,将函数用链表将一些功能函数连接起来。其中定义了构造函数,析构函数,重载赋值、乘法、数乘、输入、输出,矩阵转置等函数,实现矩阵的矩阵的赋值、转置、乘法等运算。 template class CMatrix { struct node { Vector **f;//**************************************组成矩阵的向量指针 int refcnt;//*************************************************被引用次数 int length;//*************************************************矩阵的行数 T **tmppointer;//*******************************************头指针类型} *p; public: // Vector ** begin() const {return p->f;}; CMatrix();//****************************************************默认的构造 CMatrix(int xsize,int ysize,T init=0);//***************************构造函数CMatrix(int xlength,const Vector *vec);//************************构造函数CMatrix(CMatrix &x); //**************************************拷贝构造函数~CMatrix(); //****************************************************析构函数 CMatrix & operator=(const CMatrix &mat);//**************重载赋值运算符int row() const;//**************************************************返回行数int col() const;//**************************************************返回列数Vector & operator []( int i);//********************************重载[] void Inver(CMatrix &mat);//****************************************矩阵转置operator T **();//****************************************************重载** void ReadFromFile();//*************************************从文件中读入矩阵friend CMatrix cpy(CMatrix &v);//***********************************拷贝函数friend std::ostream & operator<<(std::ostream &s,const CMatrix &mat);//重载输出函数 friend std::istream & operator>>(std::istream &s,const CMatrix &mat);//重载输入函数 friend CMatrix operator*(CMatrix &v1,CMatrix &v2);//******矩阵乘法friend CMatrix operator*(const CMatrix &v,T val); //************数乘}; 4. 程序运行结果界面

矩阵转置及相加实验报告

、实验内容和要求 1、稀疏矩阵A,B均采用三元组表示,验证实现矩阵A快速转置算法,设计并验证 A,B相 加得到矩阵C的算法。 (1)从键盘输入矩阵的行数和列数,随机生成稀疏矩阵。 (2)设计算法将随机生成的稀疏矩阵转换成三元组顺序表示形式存储。 (3)设计算法将快速转置得到的与相加得到的三元组顺序表分别转换成矩阵形式。 (4)输出随机生成的稀疏矩阵 A,B及其三元组顺序表、快速转置得到的与相加得 到的三元组顺序表及其矩阵形式。 、实验过程及结果 一、需求分析 1、将随机生成的数定义为 int 型(为方便起见设定范围为 -20 至20(不含 0),可修改),三元组存储的元素分别为非零元的行下标、列下标及该位置的元素值,零元不进行存储。实际上在生成稀疏矩阵时是随机选取一些位置生成非零元然后存入三元组 中。 2、从键盘输入矩阵的行数和列数后应能输出三元组顺序表及相应矩阵(按行和列排列形式输出)。 3、程序能实现的功能包括: ①随机产生稀疏矩阵;②输出阵列形式的矩阵;③输出三元组顺序表; ④将矩阵快速转置;⑤将两个稀疏矩阵相加生成新的矩阵。 二、概要设计 1、稀疏矩阵的抽象数据类型定义: ADT TSMatrix{ 数据对象:D={ aij|i =1,2,…,m,j=1,2,…,n; Ai,j € ElemSet,m和n分别称为矩阵的行数和列数} 数据关系:R={Row ,Col} Row={|1 < i < m, 1 < j < n-1 } Col ={|1 < i< m-1, 1 < j< n} 基本操作 : CreateTSMatrix(&M) 操作结果:创建矩阵 M PrintTSMatrix(M) 初始条件:矩阵M已存在 操作结果:输出矩阵 M中三元组形式的非零元素 PrintTSMatrix1(M) 初始条件:矩阵M已存在操作结果:以阵列形式输出矩阵 UnZore(M, row, col)初始 条件:矩阵M已存在操作结果:若位置(row,col)处存在非零元素,则返回该元素存 储在矩阵中的序 号 TSMatrix_Add(M, N,&Q) 初始条件:矩阵M, N已存在 操作结果:将矩阵 M,N相加得到Q并返回矩阵Q

三元组结构实现稀疏矩阵转置算法的分析

三元组结构实现稀疏矩阵转置算法的分析 文章简要叙述了稀疏矩阵压缩存储的三元组表示法及其基于此种结构的矩阵的转置运算。探讨了基于三元组结构的矩阵转置算法的具体实现方法及其时空复杂度的问题。 【关键词】稀疏矩阵压缩存储三元组转置算法 在一些特殊矩阵中,如对称矩阵和上下三角矩阵,非零元素一般都有明显的规律,从而都可以压缩到一维数组里面,然而,实际应用中经常会遇到这样一些矩阵,它们非零元素少,且分布不均匀,且没有明显的规律,称之为稀疏矩阵。按照压缩存储的思想,只需存储矩阵中的非零元素。为了便于存取和检索,一般在存储的时候必须带有合适的辅助信息,即同时记录下它所在的行列的位置等等。在实际应用中,一般我们采取的是用三元组和十字链表两种表示方法来实现稀疏矩阵的存储及其运算。稀疏矩阵在数值计算、电力系统的潮流计算、天气预报、工程分析计算等方面都有着大量的应用,不少实际问题都可以转化为对稀疏矩阵的计算问题。了解稀疏矩阵的各种操作变得尤为重要。 1 基本概念 设矩阵中有t个非零元素,若t远远小于矩阵元素的总数,则称该矩阵为稀疏矩阵。通常,在m×n 的矩阵中,存在t个非零元素。设δ= t/(m*n),则称δ为矩阵的稀疏

因子,一般认为当δ≤0.05时为稀疏矩阵。在存储稀疏矩阵时,为了节约存储单元,很自然的压缩方法就是只存储非零元素,但由于非零元素的分布一般是没有规律的,因此在存储非零元素的同时,还必须存储相应的辅助信息,才能准确迅速确定一个非零元素是矩阵中的哪一个元素。最简单的办法就是将非零元素的值和它所在的行列号作为一个结点存放到一起,于是矩阵中的每一个非零元素就由一个三元组(i,j,aij)唯一确定。显然,稀疏矩阵的压缩存储方法会让其失去随机存取功能。 2 三元组表示稀疏矩阵转置算法的实现 用三元组来表示非零元素时稀疏矩阵的压缩存储方法的具体数据类型说明如下: 三元组表示的稀疏矩阵,如何实现转置算法呢?矩阵的转置是基本的矩阵运算,对于一个m×n 的矩阵M,它的转置N是一个n×m 的矩阵,且有N(i,j)=M(j,i)。设M和N互为转置矩阵,显然一个稀疏矩阵的转置亦是稀疏矩阵,假定a和b是此Stp类型的变量,分别表示矩阵M和N,接下来的问题就是如何实现由a到b。由于我们所用的存储方式一般都是按行存储,三元组表示的稀疏矩阵实现转置时具体做法是将每个三元组中的行列号互换,并按照新的行号排列三元组。实现转置操作主要有两步:第一步,在三元组表中,对i和j的值进行交换。第二步,重新排列三元组之

相关主题
文本预览
相关文档 最新文档