第一次搬进自己的blog,打算放点东东到里面。在工程软件开发过程中,会碰到很多有关矩阵的运算。这是一年前的源代码
1
using System;
2
using System.IO;
3
using System.Diagnostics;
4
5
6
namespace Adjust
7
{
8
/// <summary>
9
/// Matrix 的摘要说明。
10
/// 实现矩阵的基本运算
11
/// </summary>
12
public class Matrix
13
{
14
15
//构造方阵
16
public Matrix(int row)
17
{
18
m_data = new double[row,row];
19
20
}
21
public Matrix(int row,int col)
22
{
23
m_data = new double[row,col];
24
}
25
//复制构造函数
26
public Matrix(Matrix m)
27
{
28
int row = m.Row;
29
int col = m.Col;
30
m_data = new double[row,col];
31
32
for(int i=0;i<row;i++)
33
for(int j=0;j<col;j++)
34
m_data[i,j] = m[i,j];
35
36
}
37
38
/*
39
//分配方阵的大小
40
//对于已含有内存的矩阵,将清空数据
41
public void SetSize(int row)
42
{
43
m_data = new double[row,row];
44
}
45
46
47
//分配矩阵的大小
48
//对于已含有内存的矩阵,将清空数据
49
public void SetSize(int row,int col)
50
{
51
m_data = new double[row,col];
52
}
53
*/
54
55
//unit matrix:设为单位阵
56
public void SetUnit()
57
{
58
for(int i=0;i<m_data.GetLength(0);i++)
59
for(int j=0;j<m_data.GetLength(1);j++)
60
m_data[i,j] = ((i==j)?1:0);
61
}
62
63
//设置元素值
64
public void SetValue(double d)
65
{
66
for(int i=0;i<m_data.GetLength(0);i++)
67
for(int j=0;j<m_data.GetLength(1);j++)
68
m_data[i,j] = d;
69
}
70
71
// Value extraction:返中行数
72
public int Row
73
{
74
get
75
{
76
77
return m_data.GetLength(0);
78
}
79
}
80
81
//返回列数
82
public int Col
83
{
84
get
85
{
86
return m_data.GetLength(1);
87
}
88
}
89
90
//重载索引
91
//存取数据成员
92
public double this[int row,int col]
93
{
94
get
95
{
96
return m_data[row,col];
97
}
98
set
99
{
100
m_data[row,col] = value;
101
}
102
}
103
104
//primary change
105
// 初等变换 对调两行:ri<-->rj
106
public Matrix Exchange(int i,int j)
107
{
108
double temp;
109
110
for(int k=0;k<Col;k++)
111
{
112
temp = m_data[i,k];
113
m_data[i,k] = m_data[j,k];
114
m_data[j,k] = temp;
115
}
116
return this;
117
}
118
119
120
//初等变换 第index 行乘以mul
121
Matrix Multiple(int index,double mul)
122
{
123
for(int j=0;j<Col;j++)
124
{
125
m_data[index,j] *= mul;
126
}
127
return this;
128
}
129
130
131
//初等变换 第src行乘以mul加到第index行
132
Matrix MultipleAdd(int index,int src,double mul)
133
{
134
for(int j=0;j<Col;j++)
135
{
136
m_data[index,j] += m_data[src,j]*mul;
137
}
138
139
return this;
140
}
141
142
//transpose 转置
143
public Matrix Transpose()
144
{
145
Matrix ret = new Matrix(Col,Row);
146
147
for(int i=0;i<Row;i++)
148
for(int j=0;j<Col;j++)
149
{
150
ret[j,i] = m_data[i,j];
151
}
152
return ret;
153
}
154
155
//binary addition 矩阵加
156
public static Matrix operator+ (Matrix lhs,Matrix rhs)
157
{
158
if(lhs.Row != rhs.Row) //异常
159
{
160
System.Exception e = new Exception("相加的两个矩阵的行数不等");
161
throw e;
162
}
163
if(lhs.Col != rhs.Col) //异常
164
{
165
System.Exception e = new Exception("相加的两个矩阵的列数不等");
166
throw e;
167
}
168
169
int row = lhs.Row;
170
int col = lhs.Col;
171
Matrix ret=new Matrix(row,col);
172
173
for(int i=0;i<row;i++)
174
for(int j=0;j<col;j++)
175
{
176
double d = lhs[i,j] + rhs[i,j];
177
ret[i,j] = d;
178
}
179
return ret;
180
181
}
182
183
//binary subtraction 矩阵减
184
public static Matrix operator- (Matrix lhs,Matrix rhs)
185
{
186
if(lhs.Row != rhs.Row) //异常
187
{
188
System.Exception e = new Exception("相减的两个矩阵的行数不等");
189
throw e;
190
}
191
if(lhs.Col != rhs.Col) //异常
192
{
193
System.Exception e = new Exception("相减的两个矩阵的列数不等");
194
throw e;
195
}
196
197
int row = lhs.Row;
198
int col = lhs.Col;
199
Matrix ret=new Matrix(row,col);
200
201
for(int i=0;i<row;i++)
202
for(int j=0;j<col;j++)
203
{
204
double d = lhs[i,j] - rhs[i,j];
205
ret[i,j] = d;
206
}
207
return ret;
208
}
209
210
211
//binary multiple 矩阵乘
212
public static Matrix operator* (Matrix lhs,Matrix rhs)
213
{
214
if(lhs.Col != rhs.Row) //异常
215
{
216
System.Exception e = new Exception("相乘的两个矩阵的行列数不匹配");
217
throw e;
218
}
219
220
Matrix ret = new Matrix (lhs.Row,rhs.Col);
221
double temp;
222
for(int i=0;i<lhs.Row;i++)
223
{
224
for(int j=0;j<rhs.Col;j++)
225
{
226
temp = 0;
227
for(int k=0;k<lhs.Col;k++)
228
{
229
temp += lhs[i,k] * rhs[k,j];
230
}
231
ret[i,j] = temp;
232
}
233
}
234
235
return ret;
236
}
237
238
239
//binary division 矩阵除
240
public static Matrix operator/ (Matrix lhs,Matrix rhs)
241
{
242
return lhs * rhs.Inverse();
243
}
244
245
//unary addition单目加
246
public static Matrix operator+ (Matrix m)
247
{
248
Matrix ret = new Matrix(m);
249
return ret;
250
}
251
252
//unary subtraction 单目减
253
public static Matrix operator- (Matrix m)
254
{
255
Matrix ret = new Matrix(m);
256
for(int i=0;i<ret.Row;i++)
257
for(int j= 0;j<ret.Col;j++)
258
{
259
ret[i,j] = -ret[i,j];
260
}
261
262
return ret;
263
}
264
265
//number multiple 数乘
266
public static Matrix operator* (double d,Matrix m)
267
{
268
Matrix ret = new Matrix(m);
269
for(int i=0;i<ret.Row;i++)
270
for(int j=0;j<ret.Col;j++)
271
ret[i,j] *= d;
272
273
return ret;
274
}
275
276
//number division 数除
277
public static Matrix operator/ (double d,Matrix m)
278
{
279
return d*m.Inverse();
280
}
281
282
//功能:返回列主元素的行号
283
//参数:row为开始查找的行号
284
//说明:在行号[row,Col)范围内查找第row列中绝对值最大的元素,返回所在行号
285
int Pivot(int row)
286
{
287
int index=row;
288
289
for(int i=row+1;i<Row;i++)
290
{
291
if(m_data[i,row] > m_data[index,row])
292
index=i;
293
}
294
295
return index;
296
}
297
298
//inversion 逆阵:使用矩阵的初等变换,列主元素消去法
299
public Matrix Inverse()
300
{
301
if(Row != Col) //异常,非方阵
302
{
303
System.Exception e = new Exception("求逆的矩阵不是方阵");
304
throw e;
305
}
306
StreamWriter sw = new StreamWriter("..\\annex\\close_matrix.txt");
307
Matrix tmp = new Matrix(this);
308
Matrix ret =new Matrix(Row); //单位阵
309
ret.SetUnit();
310
311
int maxIndex;
312
double dMul;
313
314
for(int i=0;i<Row;i++)
315
{
316
maxIndex = tmp.Pivot(i);
317
318
if(tmp.m_data[maxIndex,i]==0)
319
{
320
System.Exception e = new Exception("求逆的矩阵的行列式的值等于0,");
321
throw e;
322
}
323
324
if(maxIndex != i) //下三角阵中此列的最大值不在当前行,交换
325
{
326
tmp.Exchange(i,maxIndex);
327
ret.Exchange(i,maxIndex);
328
329
}
330
331
ret.Multiple(i,1/tmp[i,i]);
332
333
tmp.Multiple(i,1/tmp[i,i]);
334
335
for(int j=i+1;j<Row;j++)
336
{
337
dMul = -tmp[j,i]/tmp[i,i];
338
tmp.MultipleAdd(j,i,dMul);
339
ret.MultipleAdd(j,i,dMul);
340
341
}
342
sw.WriteLine("tmp=\r\n"+tmp);
343
sw.WriteLine("ret=\r\n"+ret);
344
}//end for
345
346
347
sw.WriteLine("**=\r\n"+ this*ret);
348
349
for(int i=Row-1;i>0;i--)
350
{
351
for(int j=i-1;j>=0;j--)
352
{
353
dMul = -tmp[j,i]/tmp[i,i];
354
tmp.MultipleAdd(j,i,dMul);
355
ret.MultipleAdd(j,i,dMul);
356
}
357
}//end for
358
359
360
sw.WriteLine("tmp=\r\n"+tmp);
361
sw.WriteLine("ret=\r\n"+ret);
362
sw.WriteLine("***=\r\n"+ this*ret);
363
sw.Close();
364
365
return ret;
366
367
}//end Inverse
368
369
#region
370
/*
371
//inversion 逆阵:使用矩阵的初等变换,列主元素消去法
372
public Matrix Inverse()
373
{
374
if(Row != Col) //异常,非方阵
375
{
376
System.Exception e = new Exception("求逆的矩阵不是方阵");
377
throw e;
378
}
379
///////////////
380
StreamWriter sw = new StreamWriter("..\\annex\\matrix_mul.txt");
381
////////////////////
382
///
383
Matrix tmp = new Matrix(this);
384
Matrix ret =new Matrix(Row); //单位阵
385
ret.SetUnit();
386
387
int maxIndex;
388
double dMul;
389
390
for(int i=0;i<Row;i++)
391
{
392
393
maxIndex = tmp.Pivot(i);
394
395
if(tmp.m_data[maxIndex,i]==0)
396
{
397
System.Exception e = new Exception("求逆的矩阵的行列式的值等于0,");
398
throw e;
399
}
400
401
if(maxIndex != i) //下三角阵中此列的最大值不在当前行,交换
402
{
403
tmp.Exchange(i,maxIndex);
404
ret.Exchange(i,maxIndex);
405
406
}
407
408
ret.Multiple(i,1/tmp[i,i]);
409
410
/////////////////////////
411
//sw.WriteLine("nul \t"+tmp[i,i]+"\t"+ret[i,i]);
412
////////////////
413
tmp.Multiple(i,1/tmp[i,i]);
414
//sw.WriteLine("mmm \t"+tmp[i,i]+"\t"+ret[i,i]);
415
sw.WriteLine("111111111 tmp=\r\n"+tmp);
416
for(int j=i+1;j<Row;j++)
417
{
418
dMul = -tmp[j,i];
419
tmp.MultipleAdd(j,i,dMul);
420
ret.MultipleAdd(j,i,dMul);
421
422
}
423
sw.WriteLine("222222222222=\r\n"+tmp);
424
425
}//end for
426
427
428
429
for(int i=Row-1;i>0;i--)
430
{
431
for(int j=i-1;j>=0;j--)
432
{
433
dMul = -tmp[j,i];
434
tmp.MultipleAdd(j,i,dMul);
435
ret.MultipleAdd(j,i,dMul);
436
}
437
}//end for
438
439
//////////////////////////
440
441
442
sw.WriteLine("tmp = \r\n" + tmp.ToString());
443
444
sw.Close();
445
///////////////////////////////////////
446
///
447
return ret;
448
449
}//end Inverse
450
451
*/
452
453
#endregion
454
455
//determine if the matrix is square:方阵
456
public bool IsSquare()
457
{
458
return Row==Col;
459
}
460
461
//determine if the matrix is symmetric对称阵
462
public bool IsSymmetric()
463
{
464
465
if(Row != Col)
466
return false;
467
468
for(int i=0;i<Row;i++)
469
for(int j=i+1;j<Col;j++)
470
if( m_data[i,j] != m_data[j,i])
471
return false;
472
473
return true;
474
}
475
476
//一阶矩阵->实数
477
public double ToDouble()
478
{
479
Trace.Assert(Row==1 && Col==1);
480
481
return m_data[0,0];
482
}
483
484
//conert to string
485
public override string ToString()
486
{
487
488
string s="";
489
for(int i=0;i<Row;i++)
490
{
491
for(int j=0;j<Col;j++)
492
s += string.Format("{0} ",m_data[i,j]);
493
494
s += "\r\n";
495
}
496
return s;
497
498
}
499
500
501
//私有数据成员
502
private double[,] m_data;
503
504
}//end class Matrix
505
}

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

460

461

462

463

464

465

466

467

468

469

470

471

472

473

474

475

476

477

478

479

480

481

482

483

484

485

486

487

488

489

490

491

492

493

494

495

496

497

498

499

500

501

502

503

504

505

例子:















