C#矩阵向量类与线性代数
关于C#的语法书,请参考相关C#编程书籍或微软官方文档。
这里直接给出矩阵与线性代数类定义。
class MAT
{
/*--------------------------------------class comment
Version : V1.0
Coded by : syz
Date : 2011-06-16 16:53:40 *星期四*
----------------------------------------------------
Desciption :
* 矩阵类
* 该类中的部分算符重载需要用到VEC类
parameters :
*
Methods :
* MAT------构造函数
* + --------两矩阵相加(对应元素分别相加)
* - --------矩阵相减(对应元素分别相减)
* * --------矩阵元素分别相乘(相当于MATLAB中的 .*算符)
* / --------矩阵元素分别相除(相当与MATLAB中的 ./算符)
*
* + --------矩阵加实数(所有元素分别加该实数)
* - --------矩阵减实数(所有元素分别减该实数)
* * --------矩阵乘实数(所有元素分别乘该实数)
* / --------矩阵除实数(所有元素分别除该实数)
*
* 以下再次重载四则算符,
* 如此可以在矩阵左右均可进行与实数的双目运算
* + --------实数加矩阵(所有元素分别加该实数)
* - --------实数减矩阵(所有元素分别减该实数)
* * --------实数乘矩阵(所有元素分别乘该实数)
* / --------<无>---不重载--(即不能用实数除以矩阵)
*
* | --------数学意义下的矩阵相乘
* | --------矩阵与向量相乘(线性变换)
* ~ --------矩阵转置(向量中~该算符用于求2范数平方)
--------------------------------------------------*/
public int dim1, dim2; //数组维数
public double[,] ele;
public MAT(int m, int n)
{
//构造函数
dim1 = m;
dim2 = n;
//矩阵维数
ele = new double[m, n];
//用二维数组构造数学意义下的矩阵
//矩阵元素保存于对象ele中
}
//-------两个矩阵加法算符重载
//------矩阵元素分别相加
public static MAT operator +(MAT a1, MAT a2)
{
int m, n;
m = a1.dim1;
n = a1.dim2;
MAT a3 = new MAT(m, n);
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
a3.ele[i, j] = a1.ele[i, j] + a2.ele[i, j];
return a3;
}
//-------两个矩阵减法算符重载
//------矩阵元素分别相减
public static MAT operator -(MAT a1, MAT a2)
{
int m, n;
m = a1.dim1;
n = a1.dim2;
MAT a3 = new MAT(m, n);
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
a3.ele[i, j] = a1.ele[i, j] - a2.ele[i, j];
return a3;
}
//-------两个矩阵乘法算符重载
//------矩阵元素分别相乘,相当于MATLAB中的 .*
// 要求两个矩阵维数相同,矩阵类不进行个数判断
public static MAT operator *(MAT a1, MAT a2)
{
int m, n;
m = a1.dim1;
n = a1.dim2;
MAT a3 = new MAT(m, n);
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
a3.ele[i, j] = a1.ele[i, j] * a2.ele[i, j];
return a3;
}
//-------两个矩阵除法算符重载
//------矩阵元素分别相除,相当于MATLAB中的 ./
// 要求两个矩阵维数相同,矩阵类不进行个数判断
public static MAT operator /(MAT a1, MAT a2)
{
int m, n;
m = a1.dim1;
n = a1.dim2;
MAT a3 = new MAT(m, n);
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
a3.ele[i, j] = a1.ele[i, j] / a2.ele[i, j];
return a3;
}
//矩阵加实数算符重载
//各分量分别加实数
public static MAT operator +(MAT a1, double x)
{
int m, n;
m = a1.dim1;
n = a1.dim2;
MAT a2 = new MAT(m, n);
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
a2.ele[i, j] = a1.ele[i, j] + x;
return a2;
}
//矩阵减实数算符重载
//各分量分别减实数
public static MAT operator -(MAT a1, double x)
{
int m, n;
m = a1.dim1;
n = a1.dim2;
MAT a2 = new MAT(m, n);
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
a2.ele[i, j] = a1.ele[i, j] - x;
return a2;
}
//矩阵乘以实数算符重载
//各分量分别乘以实数
public static MAT operator *(MAT a1, double x)
{
int m, n;
m = a1.dim1;
n = a1.dim2;
MAT a2 = new MAT(m, n);
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
a2.ele[i, j] = a1.ele[i, j] * x;
return a2;
}
//矩阵除以实数算符重载
//各分量分别除以实数
public static MAT operator /(MAT a1, double x)
{
int m, n;
m = a1.dim1;
n = a1.dim2;
MAT a2 = new MAT(m, n);
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
a2.ele[i, j] = a1.ele[i, j] / x;
return a2;
}
//实数加矩阵算符重载
//各分量分别加实数
public static MAT operator +(double x, MAT a1)
{
int m, n;
m = a1.dim1;
n = a1.dim2;
MAT a2 = new MAT(m, n);
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
a2.ele[i, j] = a1.ele[i, j] + x;
return a2;
}
//实数减矩阵算符重载
//各分量分别减实数
public static MAT operator -(double x, MAT a1)
{
int m, n;
m = a1.dim1;
n = a1.dim2;
MAT a2 = new MAT(m, n);
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
a2.ele[i, j] = a1.ele[i, j] - x;
return a2;
}
//实数乘矩阵算符重载
//各分量分别乘以实数
public static MAT operator *(double x, MAT a1)
{
int m, n;
m = a1.dim1;
n = a1.dim2;
MAT a2 = new MAT(m, n);
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
a2.ele[i, j] = a1.ele[i, j] * x;
return a2;
}
//数学上的矩阵相乘
public static MAT operator |(MAT a1, MAT a2)
{
int m, n, p, q;
m = a1.dim1;
n = a1.dim2;
p = a2.dim1;
q = a2.dim2;
if (n != p) System.Console.WriteLine("Inner matrix dimensions must agree!");
//如果矩阵维数不匹配给出告警信息
//新矩阵,用于存放结果
MAT a3 = new MAT(m, q);
int i, j;
for (i = 0; i < m; i++)
for (j = 0; j < q; j++)
{
a3.ele[i, j] = 0.0;
for (int k = 0; k < n; k++)
a3.ele[i, j] = a3.ele[i, j] + a1.ele[i, k] * a2.ele[k, j];
}
return a3;
}
//矩阵乘以向量(线性变换)
//即 b=Ax
public static VEC operator |(MAT A, VEC x)
{
int m, n, p;
m = A.dim1;
n = A.dim2;
p = x.dim;
if (n != p) System.Console.WriteLine("Inner matrix dimensions must agree!");
//如果矩阵维数不匹配,给出告警信息
VEC b = new VEC(m);
for (int i = 0; i < m; i++)
{
b.ele[i] = 0.0;
for (int k = 0; k < n; k++)
b.ele[i] = b.ele[i] + A.ele[i, k] * x.ele[k];
}
return b;
}
//矩阵转置
public static MAT operator ~(MAT A)
{
int m, n;
m = A.dim1;
n = A.dim2;
MAT TA = new MAT(n, m);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
TA.ele[i, j] = A.ele[j, i];
return TA;
}
public double this[int index1, int index2]
// 矩阵索引器
{
get
{
return ele[index1, index2];
}
set
{
ele[index1, index2] = value;
}
}
}
class VEC
/*--------------------------------------class comment
Version : V1.0
Coded by : syz
Date : 2011-06-15 12:50:11 *星期三*
----------------------------------------------------
Desciption :
向量类
parameters :
* dim------向量维数
* ele------向量元素
*
Methods :
* = -----------向量相等
* 注意该方法不需要自行编写重载函数,
* c#已经实现了对类的等号算符重载,并禁止
* 用户编写等号算符(=)重载函数
* + -----------两向量对应元素相加
* - -----------两向量对应元素相减
* * -----------两向量对应元素相乘(相当于MATLAB中的 .*算符)
* / -----------两向量对应元素相除(相当于MATLAB中的 ./算符)
*
* + -----------重载向量加一实数(所有元素)
* - -----------重载向量减一实数(所有元素)
* * -----------重载向量乘一实数(所有元素)
* / -----------重载向量除一实数(所有元素)
*
* + -----------重载实数加向量(所有元素)
* - -----------重载实数减向量(所有元素)
* * -----------重载实数乘以向量(所有元素)
* / -----------<无>--不重载--<即不能用实数除以向量>
*
* | (VEC1|ve2)----向量内积
* ~ (~VEC1)-------向量2范数的平方
* - (-VEC1)-------向量取负
* ^ (VEC1^VEC2)---向量外积
*
--------------------------------------------------*/
{
public int dim; //数组维数
public double[] ele;
public VEC(int m)
{
//构造函数
dim = m;
ele = new double[dim];
//用一维数组构造向量
}
//-------两个向量加法算符重载
//------分量分别相加
public static VEC operator +(VEC v1, VEC v2)
{
int N0;
//获取变量维数
N0 = v1.dim;
VEC v3 = new VEC(N0);
int j;
for (j = 0; j < N0; j++)
{
v3.ele[j] = v1.ele[j] + v2.ele[j];
}
return v3;
}
//-----------------向量减法算符重载
//-----------------分量分别想减
public static VEC operator -(VEC v1, VEC v2)
{
int N0;
//获取变量维数
N0 = v1.dim;
VEC v3 = new VEC(N0);
int j;
for (j = 0; j < N0; j++)
{
v3.ele[j] = v1.ele[j] - v2.ele[j];
}
return v3;
}
//----------------向量乘法算符重载
//-------分量分别相乘,相当于MATLAB中的 .*算符
public static VEC operator *(VEC v1, VEC v2)
{
int N0;
//获取变量维数
N0 = v1.dim;
VEC v3 = new VEC(N0);
int j;
for (j = 0; j < N0; j++)
{
v3.ele[j] = v1.ele[j] * v2.ele[j];
}
return v3;
}
//---------------向量除法算符重载
//--------------分量分别相除,相当于MATLAB中的 ./算符
public static VEC operator /(VEC v1, VEC v2)
{
int N0;
//获取变量维数
N0 = v1.dim;
VEC v3 = new VEC(N0);
int j;
for (j = 0; j < N0; j++)
{
v3.ele[j] = v1.ele[j] / v2.ele[j];
}
return v3;
}
//向量减加实数
//各分量分别加实数
public static VEC operator +(VEC v1, double a)
{
//向量数加算符重载
int N0;
//获取变量维数
N0 = v1.dim;
VEC v2 = new VEC(N0);
int j;
for (j = 0; j < N0; j++)
{
v2.ele[j] = v1.ele[j] + a;
}
return v2;
}
//向量减实数
//各分量分别减实数
public static VEC operator -(VEC v1, double a)
{
//向量数加算符重载
int N0;
//获取变量维数
N0 = v1.dim;
VEC v2 = new VEC(N0);
int j;
for (j = 0; j < N0; j++)
{
v2.ele[j] = v1.ele[j] - a;
}
return v2;
}
//向量 数乘
//各分量分别乘以实数
public static VEC operator *(VEC v1, double a)
{
int N0;
//获取变量维数
N0 = v1.dim;
VEC v2 = new VEC(N0);
int j;
for (j = 0; j < N0; j++)
{
v2.ele[j] = v1.ele[j] * a;
}
return v2;
}
//向量 数除
//各分量分别除以实数
public static VEC operator /(VEC v1, double a)
{
int N0;
//获取变量维数
N0 = v1.dim;
VEC v2 = new VEC(N0);
int j;
for (j = 0; j < N0; j++)
{
v2.ele[j] = v1.ele[j] / a;
}
return v2;
}
//实数加向量
public static VEC operator +(double a, VEC v1)
{
//向量数加算符重载
int N0;
//获取变量维数
N0 = v1.dim;
VEC v2 = new VEC(N0);
int j;
for (j = 0; j < N0; j++)
{
v2.ele[j] = v1.ele[j] + a;
}
return v2;
}
//实数减向量
public static VEC operator -(double a, VEC v1)
{
//向量数加算符重载
int N0;
//获取变量维数
N0 = v1.dim;
VEC v2 = new VEC(N0);
int j;
for (j = 0; j < N0; j++)
{
v2.ele[j] = v1.ele[j] - a;
}
return v2;
}
//向量 数乘
public static VEC operator *(double a, VEC v1)
{
int N0;
//获取变量维数
N0 = v1.dim;
VEC v2 = new VEC(N0);
int j;
for (j = 0; j < N0; j++)
{
v2.ele[j] = v1.ele[j] * a;
}
return v2;
}
//---------------向量内积
public static double operator |(VEC v1, VEC v2)
{
int N0, M0;
//获取变量维数
N0 = v1.dim;
M0 = v2.dim;
if (N0 != M0)
System.Console.WriteLine("Inner vector dimensions must agree!");
//如果向量维数不匹配,给出告警信息
double sum;
sum = 0.0;
int j;
for (j = 0; j < N0; j++)
{
sum = sum + v1.ele[j] * v2.ele[j];
}
return sum;
}
//-----------向量外积(相当于列向量,乘以横向量)
public static MAT operator ^(VEC v1, VEC v2)
{
int N0, M0;
//获取变量维数
N0 = v1.dim;
M0 = v2.dim;
if (N0 != M0)
System.Console.WriteLine("Inner vector dimensions must agree!");
//如果向量维数不匹配,给出告警信息
MAT vvmat = new MAT(N0, N0);
for (int i = 0; i < N0; i++)
for (int j = 0; j < N0; j++)
vvmat[i, j] = v1[i] * v2[j];
//返回外积矩阵
return vvmat;
}
//---------------向量模的平方
public static double operator ~(VEC v1)
{
int N0;
//获取变量维数
N0 = v1.dim;
double sum;
sum = 0.0;
int j;
for (j = 0; j < N0; j++)
{
sum = sum + v1.ele[j] * v1.ele[j];
}
return sum;
}
// 负向量
public static VEC operator -(VEC v1)
{
int N0 = v1.dim;
VEC v2=new VEC(N0);
for (int i = 0; i < N0; i++)
v2.ele[i] = -v1.ele[i];
return v2;
}
public double this[int index]
/*------------------------------------------ comment
Author : syz
Date : 2011-07-03 19:53:28
---------------------------------------------------
Desciption : 创建索引器
*
Post Script :
*
paramtegers :
*
-------------------------------------------------*/
{
get
{
//get accessor
return ele[index];
}
set
{
//set accessor
ele[index] = value;
}
}
}