- matrix a=matrix::unit(4); //4阶单位阵。
- matrix c(a);
- a(1,2)=2; //此时矩阵a的副本c任然不变。
- cout<<a<<c<<endl;
- c=a; //此时c是a的一个副本。
- a(2,1,false)=10; //此时矩阵所有的副本(比如c)都会改变,如果确定矩阵没有副本使用此方法可以提升速度。
- cout<<a<<c<<endl;
- cout<<a.inv()<<endl; //逆矩阵。
- matrix b(a(1)*a(_ALL,2)); //矩阵a的第一行乘以矩阵的第二列,结果赋给b。相当于MATLAB语句:b=a(1,:)*a(:,2)。
- cout<<b<<endl;
- _index id1,id2; //_index类型继承自vector<size_t>,用来表示子矩阵取自原矩阵的那些行(列)。
- id1.push_back(1);
- id1.push_back(2);
- id2.push_back(3);
- id2.push_back(4);
- a(id1)+=a(id2); //将三、四行构成的子矩阵加到一、二行。相当于MATLAB语句:a(1:2,:)=a(1:2,:)+a(3:4,:)。
- cout<<a<<endl;
- b=(b|b|b|b)&a; //将四个b纵向合并构成的矩阵横向合并a,赋给b。相当于MATLAB语句:b=[[b;b;b;b],a]。
- cout<<b<<endl;
- b.swap_col(2,3); //交换b的二、三列。
- cout<<b<<endl;
以上是一个简单的代码demo。
转载自:http://topic.csdn.net/u/20080904/22/e27eb499-122b-476c-ace7-9cb28482556c.html?seed=1956122429
1.头文件
TrMatrix_Kernel.h,TrMatrix_Shell.h,TrMatrix_Main.h
使用本库只需要包含TrMatrix_Main.h即可。
2.矩阵对象
矩阵类定义为template <class S, class T = CTrMatrix_Kernel <S> >class CTrMatrix_Shell。
第一个模板参数表示矩阵元素的类型(如double型矩阵)。
第二个模板参数是系统在处理矩阵转置、分块、合并时自动使用的,自定义矩阵是都请使用默认模板参数。
如果第二个模板参数(矩阵内核)为默认参数,我们称之为简单矩阵否则称之为复杂矩阵。
原则上用户定义的矩阵实例不应是复杂矩阵,也就是说复杂矩阵对象应当总是临时对象。
3.简单矩阵的初始化
构造函数有如下3种。
CTrMatrix_Shell(size_t row, size_t col):按照指定的行、列数量定义矩阵,元素未初始化。
CTrMatrix_Shell(size_t row, size_t col, S* p):按照指定的行、列数量定义矩阵,元素由数组p中的值指定。
CTrMatrix_Shell():生成空矩阵。
此外简单矩阵还有拷贝构造函数和赋值运算符,源矩阵可以是简单或复杂矩阵。
请注意:
由复杂矩阵对象生成简单对象,将会对其元素进行复制操作。
而如果由简单矩阵对象生成简单对象,为了节约资源,不执行复制操作,只拷贝内核对象(其中包含矩阵元素)的指针。
4.通用方法(简单与复杂矩阵功能一样之处)
运算:+、-、*、/、%、+=、-=、*=、/=、%=与其字面含义相同;inv()表示求逆。
变换:swap_row(size_t row1,size_t row2)与swap_col(size_t col1,size_t col2)分别表示交换矩阵的两行或两列。
转置:Tran(),该方法生成复杂矩阵对象。
合并:为了使合并更具可读性,我们重载了运算符|与&,分别表示纵向和横向合并。该方法生成复杂矩阵对象。
例如,a和b是1*2的矩阵,c是2*2的矩阵,则(a|b)&c是2*3的矩阵。
取子矩阵:取子矩阵由重载的()运算符实现。两个参数分别说明子矩阵的行、列各是原矩阵的哪些行、列。该方法生成复杂矩阵对象。
因此这两个参数都是向量,我们从vector <size_t>中继承了类型_index,用以表示这种向量。
size_t类型可以隐式转换为_index类型,表示只取原矩阵的一行(或一列)。
如果要取原矩阵的所有行(或列),可以使用一个预定义的参数_ALL。()运算符第二个参数缺省值为_ALL。
例如:a(_ALL,2)表示a的第2列,a(1)表示a的第一行。
IO流:
输出流可以方便的输出结果矩阵,也可保存矩阵到文件,输出内容包括矩阵大小和元素。
输入流需要与输出流相同的格式,主要用于输入保存在文件的结果。
5.简单与复杂矩阵的区别
读取元素:()运算符,可以返回值和返回引用。
返回值的情况两种矩阵无区别。定义为:S operator () (size_t row, size_t col) const。
返回引用的情况,定义为:S& operator () (size_t row, size_t col, bool needclone = true)。
根据第3条的注意中所述,多个简单矩阵可能共用一个内核;为了防止影响其他矩阵,简单矩阵在返回引用之前要检查内核对象的引用计数器并在需要时复制内核。
如果确定某简单矩阵没有跟其他矩阵共用内核,可以将第三个参数needclone设为false,以避免引用计数器检查从而提高效率。
复杂矩阵的内核是由简单矩阵的内核构造而成的。而为了实现MATLAB式效果,复杂矩阵返回的引用位于其所持有的简单矩阵内核上。因而第三个参数不起作用。
比如:如果执行语句a.Trans()(1,2)=1;则a(2,1)的值将变为1。这一设计的作用将在后文中提到。
6.应用举例
有一种重要的初等变换,是将矩阵的某行(或某列)乘以一个常数加到另一行(或列)上。使用我们的库可以非常简单的实现:
假设a是TrMatrix_Shell <double>型的矩阵,要将a的第二行乘以2加到第一行上,只需如下代码:
a(2)+=a(1)*2.0; //注意:如将"2.0"改为"2",则编译时报错,这是因为C++的特性:模板参数不支持隐式转换。
其原理如下:a(2)是一个复杂矩阵,它返回的元素引用位于简单矩阵a上,因为对a(2)的变换操作同时就改变了a。
在转置操作中:代码a=b.Trans()与a.Trans()=b是等价的。
假设a、b是2*2矩阵,c是2*4矩阵,如要将c的前两列赋给a,后两列赋给b,最简单的代码是:a&b=c。