矩阵运算的C#代码实现

编写神经网络的程序自然离不开矩阵运算。我写了一个Matrix类,封装了常用运算,包括加、减、乘(数乘和矩阵乘)、转置、取行列向量等操作。
代码如下。

1 /// <summary>
2  /// 矩阵类
3 /// </summary>
4 /// <remarks>
5 /// 孙继磊,2010-10-18
6 /// sun.j.l.studio@gmail.com
7 /// </remarks>
8 public sealed class Matrix
9 {
10 int row, column; //矩阵的行列数
11 double [,] data; //矩阵的数据
12
13 #region 构造函数
14 public Matrix(int rowNum,int columnNum)
15 {
16 row = rowNum;
17 column = columnNum;
18 data = new double[row, column];
19 }
20 public Matrix(double[,] members)
21 {
22 row = members.GetUpperBound(0) + 1;
23 column = members.GetUpperBound(1) + 1;
24 data = new double[row, column];
25 Array.Copy(members, data, row * column);
26 }
27 public Matrix(double[] vector)
28 {
29 row = 1;
30 column = vector.GetUpperBound(0)+1;
31 data = new double[1, column];
32 for (int i = 0; i < vector.Length; i++)
33 {
34 data[0, i] = vector[i];
35 }
36 }
37 #endregion
38
39
40 #region 属性和索引器
41 public int rowNum { get { return row; } }
42 public int columnNum { get { return column; } }
43
44 public double this [int r,int c]
45 {
46 get{ return data[r,c];}
47 set{data[r,c]=value;}
48 }
49 #endregion
50
51
52
53 #region 转置
54 /// <summary>
55 /// 将矩阵转置,得到一个新矩阵(此操作不影响原矩阵)
56 /// </summary>
57 /// <param name="input">要转置的矩阵</param>
58 /// <returns>原矩阵经过转置得到的新矩阵</returns>
59 public static Matrix transpose(Matrix input)
60 {
61 double[,] inverseMatrix = new double[input.column, input.row];
62 for (int r = 0; r < input.row; r++)
63 for (int c = 0; c < input.column; c++)
64 inverseMatrix[c, r] = input[r, c];
65 return new Matrix(inverseMatrix);
66 }
67 #endregion
68
69 #region 得到行向量或者列向量
70 public Matrix getRow(int r)
71 {
72 if (r > row || r<=0) throw new MatrixException("没有这一行。");
73 double[] a = new double[column];
74 Array.Copy(data, column * (row - 1), a, 0, column);
75 Matrix m = new Matrix(a);
76 return m;
77 }
78 public Matrix getColumn(int c)
79 {
80 if (c > column || c < 0) throw new MatrixException("没有这一列。");
81 double[,] a = new double[row,1];
82 for (int i = 0; i < row; i++)
83 a[i,0] = data[i, c];
84 return new Matrix(a);
85 }
86 #endregion
87
88 #region 操作符重载 + - * / == !=
89 public static Matrix operator +(Matrix a, Matrix b)
90 {
91 if (a.row != b.row || a.column != b.column)
92 throw new MatrixException("矩阵维数不匹配。");
93 Matrix result = new Matrix(a.row, a.column);
94 for (int i = 0; i < a.row; i++)
95 for (int j = 0; j < a.column; j++)
96 result[i, j] = a[i, j] + b[i, j];
97 return result;
98 }
99
100 public static Matrix operator -(Matrix a, Matrix b)
101 {
102 return a + b * (-1);
103 }
104
105 public static Matrix operator *(Matrix matrix, double factor)
106 {
107 Matrix result = new Matrix(matrix.row, matrix.column);
108 for (int i = 0; i < matrix.row; i++)
109 for (int j = 0; j < matrix.column; j++)
110 matrix[i, j] = matrix[i, j] * factor;
111 return matrix;
112 }
113 public static Matrix operator *(double factor,Matrix matrix)
114 {
115 return matrix * factor;
116 }
117 public static Matrix operator *(Matrix a, Matrix b)
118 {
119 if(a.column!=b.row)
120 throw new MatrixException("矩阵维数不匹配。");
121 Matrix result = new Matrix(a.row, b.column);
122 for (int i = 0; i < a.row; i++)
123 for (int j = 0; j < b.column; j++)
124 for (int k = 0; k < a.column; k++)
125 result[i, j] += a[i, k] * b[k, j];
126
127 return result;
128 }
129 public static bool operator ==(Matrix a, Matrix b)
130 {
131 if (object.Equals(a, b)) return true;
132 if(object.Equals(null,b))
133 return a.Equals(b);
134 return b.Equals(a);
135 }
136 public static bool operator !=(Matrix a, Matrix b)
137 {
138 return !(a == b);
139 }
140 public override bool Equals(object obj)
141 {
142 if (obj == null) return false;
143 if (!(obj is Matrix)) return false;
144 Matrix t = obj as Matrix;
145 if (row != t.row || column != t.column) return false;
146 return this.Equals(t, 10);
147 }
148 /// <summary>
149 /// 按照给定的精度比较两个矩阵是否相等
150 /// </summary>
151 /// <param name="matrix">要比较的另外一个矩阵</param>
152 /// <param name="precision">比较精度(小数位)</param>
153 /// <returns>是否相等</returns>
154 public bool Equals(Matrix matrix, int precision)
155 {
156 if (precision < 0) throw new MatrixException("小数位不能是负数");
157 double test = Math.Pow(10.0, -precision);
158 if (test<double.Epsilon)
159 throw new MatrixException("所要求的精度太高,不被支持。");
160 for (int r = 0; r < this.row; r++)
161 for (int c = 0; c < this.column; c++)
162 if (Math.Abs(this[r, c] - matrix[r, c] )>=test)
163 return false;
164
165 return true;
166 }
167 #endregion
168 }

 

 

版权所有:基础软件。作者邮箱:sun.j.l.studio@gmail.com。本文首发于 http://www.cnblogs.com/FoundationSoft。文章转载请保持此版权信息并注明出处。

posted @ 2010-10-17 12:11  基础软件  阅读(14469)  评论(1编辑  收藏