PLaSK library
Loading...
Searching...
No Matches
tnt_cmat.h
Go to the documentation of this file.
1
/*
2
*
3
* Template Numerical Toolkit (TNT)
4
*
5
* Mathematical and Computational Sciences Division
6
* National Institute of Technology,
7
* Gaithersburg, MD USA
8
*
9
*
10
* This software was developed at the National Institute of Standards and
11
* Technology (NIST) by employees of the Federal Government in the course
12
* of their official duties. Pursuant to title 17 Section 105 of the
13
* United States Code, this software is not subject to copyright protection
14
* and is in the public domain. NIST assumes no responsibility whatsoever for
15
* its use by other parties, and makes no guarantees, expressed or implied,
16
* about its quality, reliability, or any other characteristic.
17
*
18
*/
19
20
21
// C compatible matrix: row-oriented, 0-based [i][j] and 1-based (i,j) indexing
22
//
23
24
#ifndef TNT_CMAT_H
25
#define TNT_CMAT_H
26
27
#include "
tnt_subscript.h
"
28
#include "
tnt_vec.h
"
29
#include <cstdlib>
30
#include <cassert>
31
#include <iostream>
32
#include <sstream>
33
34
namespace
TNT
35
{
36
37
38
template
<
class
T>
39
class
Matrix
40
{
41
42
43
public
:
44
45
typedef
Subscript
size_type
;
46
typedef
T
value_type
;
47
typedef
T
element_type
;
48
typedef
T*
pointer
;
49
typedef
T*
iterator
;
50
typedef
T&
reference
;
51
typedef
const
T*
const_iterator
;
52
typedef
const
T&
const_reference
;
53
54
Subscript
lbound
()
const
{
return
1;}
55
56
protected
:
57
Subscript
m_
;
58
Subscript
n_
;
59
Subscript
mn_
;
// total size
60
T*
v_
;
61
T**
row_
;
62
T*
vm1_
;
// these point to the same data, but are 1-based
63
T**
rowm1_
;
64
65
// internal helper function to create the array
66
// of row pointers
67
68
void
initialize
(
Subscript
M,
Subscript
N
)
69
{
70
mn_
= M*
N
;
71
m_
= M;
72
n_
=
N
;
73
74
v_
=
new
T[
mn_
];
75
row_
=
new
T*[M];
76
rowm1_
=
new
T*[M];
77
78
assert(
v_
!=
NULL
);
79
assert(
row_
!=
NULL
);
80
assert(
rowm1_
!=
NULL
);
81
82
T* p =
v_
;
83
vm1_
=
v_
- 1;
84
for
(
Subscript
i=0; i<M; i++)
85
{
86
row_
[i] = p;
87
rowm1_
[i] = p-1;
88
p +=
N
;
89
90
}
91
92
rowm1_
-- ;
// compensate for 1-based offset
93
}
94
95
void
copy
(
const
T* v)
96
{
97
Subscript
N
=
m_
*
n_
;
98
Subscript
i;
99
100
#ifdef TNT_UNROLL_LOOPS
101
Subscript
Nmod4 =
N
& 3;
102
Subscript
N4 =
N
- Nmod4;
103
104
for
(i=0; i<N4; i+=4)
105
{
106
v_
[i] = v[i];
107
v_
[i+1] = v[i+1];
108
v_
[i+2] = v[i+2];
109
v_
[i+3] = v[i+3];
110
}
111
112
for
(i=N4; i<
N
; i++)
113
v_
[i] = v[i];
114
#else
115
116
for
(i=0; i<
N
; i++)
117
v_
[i] = v[i];
118
#endif
119
}
120
121
void
set
(
const
T& val)
122
{
123
Subscript
N
=
m_
*
n_
;
124
Subscript
i;
125
126
#ifdef TNT_UNROLL_LOOPS
127
Subscript
Nmod4 =
N
& 3;
128
Subscript
N4 =
N
- Nmod4;
129
130
for
(i=0; i<N4; i+=4)
131
{
132
v_
[i] = val;
133
v_
[i+1] = val;
134
v_
[i+2] = val;
135
v_
[i+3] = val;
136
}
137
138
for
(i=N4; i<
N
; i++)
139
v_
[i] = val;
140
#else
141
142
for
(i=0; i<
N
; i++)
143
v_
[i] = val;
144
145
#endif
146
}
147
148
149
150
void
destroy
()
151
{
152
/* do nothing, if no memory has been previously allocated */
153
if
(
v_
==
NULL
) return ;
154
155
/* if we are here, then matrix was previously allocated */
156
if
(
v_
!=
NULL
)
delete
[] (
v_
);
157
if
(
row_
!=
NULL
)
delete
[] (
row_
);
158
159
/* return rowm1_ back to original value */
160
rowm1_
++;
161
if
(
rowm1_
!=
NULL
)
delete
[] (
rowm1_
);
162
}
163
164
165
public
:
166
167
operator
T**(){
return
row_
; }
168
operator
T**()
const
{
return
row_
; }
169
170
171
Subscript
size
()
const
{
return
mn_
; }
172
173
// constructors
174
175
Matrix
() :
m_
(0),
n_
(0),
mn_
(0),
v_
(0),
row_
(0),
vm1_
(0),
rowm1_
(0) {};
176
177
Matrix
(
const
Matrix<T>
&A)
178
{
179
initialize
(A.m_, A.n_);
180
copy
(A.v_);
181
}
182
183
Matrix
(
Subscript
M,
Subscript
N
,
const
T& value = T())
184
{
185
initialize
(M,
N
);
186
set
(value);
187
}
188
189
Matrix
(
Subscript
M,
Subscript
N
,
const
T* v)
190
{
191
initialize
(M,
N
);
192
copy
(v);
193
}
194
195
Matrix
(
Subscript
M,
Subscript
N
,
const
char
*s)
196
{
197
initialize
(M,
N
);
198
//std::istrstream ins(s);
199
std::istringstream ins(s);
200
201
Subscript
i, j;
202
203
for
(i=0; i<M; i++)
204
for
(j=0; j<
N
; j++)
205
ins >>
row_
[i][j];
206
}
207
208
// destructor
209
//
210
~Matrix
()
211
{
212
destroy
();
213
}
214
215
216
// reallocating
217
//
218
Matrix<T>
&
newsize
(
Subscript
M,
Subscript
N
)
219
{
220
if
(
num_rows
() == M &&
num_cols
() ==
N
)
221
return
*
this
;
222
223
destroy
();
224
initialize
(M,
N
);
225
226
return
*
this
;
227
}
228
229
230
231
232
// assignments
233
//
234
Matrix<T>
&
operator=
(
const
Matrix<T>
&A)
235
{
236
if
(
v_
== A.v_)
237
return
*
this
;
238
239
if
(
m_
== A.m_ &&
n_
== A.n_)
// no need to re-alloc
240
copy
(A.v_);
241
242
else
243
{
244
destroy
();
245
initialize
(A.m_, A.n_);
246
copy
(A.v_);
247
}
248
249
return
*
this
;
250
}
251
252
Matrix<T>
&
operator=
(
const
T& scalar)
253
{
254
set
(scalar);
255
return
*
this
;
256
}
257
258
259
Subscript
dim
(
Subscript
d)
const
260
{
261
#ifdef TNT_BOUNDS_CHECK
262
assert( d >= 1);
263
assert( d <= 2);
264
#endif
265
return
(d==1) ?
m_
: ((d==2) ?
n_
: 0);
266
}
267
268
Subscript
num_rows
()
const
{
return
m_
; }
269
Subscript
num_cols
()
const
{
return
n_
; }
270
271
272
273
274
inline
T*
operator[]
(
Subscript
i)
275
{
276
#ifdef TNT_BOUNDS_CHECK
277
assert(0<=i);
278
assert(i <
m_
) ;
279
#endif
280
return
row_
[i];
281
}
282
283
inline
const
T*
operator[]
(
Subscript
i)
const
284
{
285
#ifdef TNT_BOUNDS_CHECK
286
assert(0<=i);
287
assert(i <
m_
) ;
288
#endif
289
return
row_
[i];
290
}
291
292
inline
reference
operator()
(
Subscript
i)
293
{
294
#ifdef TNT_BOUNDS_CHECK
295
assert(1<=i);
296
assert(i <=
mn_
) ;
297
#endif
298
return
vm1_
[i];
299
}
300
301
inline
const_reference
operator()
(
Subscript
i)
const
302
{
303
#ifdef TNT_BOUNDS_CHECK
304
assert(1<=i);
305
assert(i <=
mn_
) ;
306
#endif
307
return
vm1_
[i];
308
}
309
310
311
312
inline
reference
operator()
(
Subscript
i,
Subscript
j)
313
{
314
#ifdef TNT_BOUNDS_CHECK
315
assert(1<=i);
316
assert(i <=
m_
) ;
317
assert(1<=j);
318
assert(j <=
n_
);
319
#endif
320
return
rowm1_
[i][j];
321
}
322
323
324
325
inline
const_reference
operator()
(
Subscript
i,
Subscript
j)
const
326
{
327
#ifdef TNT_BOUNDS_CHECK
328
assert(1<=i);
329
assert(i <=
m_
) ;
330
assert(1<=j);
331
assert(j <=
n_
);
332
#endif
333
return
rowm1_
[i][j];
334
}
335
336
337
338
339
};
340
341
342
/* *************************** I/O ********************************/
343
344
template
<
class
T>
345
std::ostream&
operator<<
(std::ostream &s,
const
Matrix<T>
&A)
346
{
347
Subscript
M=A.num_rows();
348
Subscript
N
=A.num_cols();
349
350
s << M <<
" "
<<
N
<<
"\n"
;
351
352
for
(
Subscript
i=0; i<M; i++)
353
{
354
for
(
Subscript
j=0; j<
N
; j++)
355
{
356
s << A[i][j] <<
" "
;
357
}
358
s <<
"\n"
;
359
}
360
361
362
return
s;
363
}
364
365
template
<
class
T>
366
std::istream&
operator>>
(std::istream &s,
Matrix<T>
&A)
367
{
368
369
Subscript
M,
N
;
370
371
s >> M >>
N
;
372
373
if
( !(M == A.num_rows() &&
N
== A.num_cols() ))
374
{
375
A.newsize(M,
N
);
376
}
377
378
379
for
(
Subscript
i=0; i<M; i++)
380
for
(
Subscript
j=0; j<
N
; j++)
381
{
382
s >> A[i][j];
383
}
384
385
386
return
s;
387
}
388
389
// *******************[ basic matrix algorithms ]***************************
390
391
392
template
<
class
T>
393
Matrix<T>
operator+
(
const
Matrix<T>
&A,
394
const
Matrix<T>
&B)
395
{
396
Subscript
M = A.num_rows();
397
Subscript
N
= A.num_cols();
398
399
assert(M==B.num_rows());
400
assert(
N
==B.num_cols());
401
402
Matrix<T>
tmp(M,
N
);
403
Subscript
i,j;
404
405
for
(i=0; i<M; i++)
406
for
(j=0; j<
N
; j++)
407
tmp[i][j] = A[i][j] + B[i][j];
408
409
return
tmp;
410
}
411
412
template
<
class
T>
413
Matrix<T>
operator-
(
const
Matrix<T>
&A,
414
const
Matrix<T>
&B)
415
{
416
Subscript
M = A.num_rows();
417
Subscript
N
= A.num_cols();
418
419
assert(M==B.num_rows());
420
assert(
N
==B.num_cols());
421
422
Matrix<T>
tmp(M,
N
);
423
Subscript
i,j;
424
425
for
(i=0; i<M; i++)
426
for
(j=0; j<
N
; j++)
427
tmp[i][j] = A[i][j] - B[i][j];
428
429
return
tmp;
430
}
431
432
template
<
class
T>
433
Matrix<T>
mult_element
(
const
Matrix<T>
&A,
434
const
Matrix<T>
&B)
435
{
436
Subscript
M = A.num_rows();
437
Subscript
N
= A.num_cols();
438
439
assert(M==B.num_rows());
440
assert(
N
==B.num_cols());
441
442
Matrix<T>
tmp(M,
N
);
443
Subscript
i,j;
444
445
for
(i=0; i<M; i++)
446
for
(j=0; j<
N
; j++)
447
tmp[i][j] = A[i][j] * B[i][j];
448
449
return
tmp;
450
}
451
452
453
template
<
class
T>
454
Matrix<T>
transpose
(
const
Matrix<T>
&A)
455
{
456
Subscript
M = A.num_rows();
457
Subscript
N
= A.num_cols();
458
459
Matrix<T>
S(
N
,M);
460
Subscript
i, j;
461
462
for
(i=0; i<M; i++)
463
for
(j=0; j<
N
; j++)
464
S[j][i] = A[i][j];
465
466
return
S;
467
}
468
469
470
471
template
<
class
T>
472
inline
Matrix<T>
matmult
(
const
Matrix<T>
&A,
473
const
Matrix<T>
&B)
474
{
475
476
#ifdef TNT_BOUNDS_CHECK
477
assert(A.num_cols() == B.num_rows());
478
#endif
479
480
Subscript
M = A.num_rows();
481
Subscript
N
= A.num_cols();
482
Subscript
K
= B.num_cols();
483
484
Matrix<T>
tmp(M,
K
);
485
T sum;
486
487
for
(
Subscript
i=0; i<M; i++)
488
for
(
Subscript
k=0; k<
K
; k++)
489
{
490
sum = 0;
491
for
(
Subscript
j=0; j<
N
; j++)
492
sum = sum + A[i][j] * B[j][k];
493
494
tmp[i][k] = sum;
495
}
496
497
return
tmp;
498
}
499
500
template
<
class
T>
501
inline
Matrix<T>
operator*
(
const
Matrix<T>
&A,
502
const
Matrix<T>
&B)
503
{
504
return
matmult
(A,B);
505
}
506
507
template
<
class
T>
508
inline
int
matmult
(
Matrix<T>
& C,
const
Matrix<T>
&A,
509
const
Matrix<T>
&B)
510
{
511
512
assert(A.num_cols() == B.num_rows());
513
514
Subscript
M = A.num_rows();
515
Subscript
N
= A.num_cols();
516
Subscript
K
= B.num_cols();
517
518
C.newsize(M,
K
);
519
520
T sum;
521
522
const
T* row_i;
523
const
T* col_k;
524
525
for
(
Subscript
i=0; i<M; i++)
526
for
(
Subscript
k=0; k<
K
; k++)
527
{
528
row_i = &(A[i][0]);
529
col_k = &(B[0][k]);
530
sum = 0;
531
for
(
Subscript
j=0; j<
N
; j++)
532
{
533
sum += *row_i * *col_k;
534
row_i++;
535
col_k +=
K
;
536
}
537
C[i][k] = sum;
538
}
539
540
return
0;
541
}
542
543
544
template
<
class
T>
545
Vector<T>
matmult
(
const
Matrix<T>
&A,
const
Vector<T>
&x)
546
{
547
548
#ifdef TNT_BOUNDS_CHECK
549
assert(A.num_cols() == x.dim());
550
#endif
551
552
Subscript
M = A.num_rows();
553
Subscript
N
= A.num_cols();
554
555
Vector<T>
tmp(M);
556
T sum;
557
558
for
(
Subscript
i=0; i<M; i++)
559
{
560
sum = 0;
561
const
T* rowi = A[i];
562
for
(
Subscript
j=0; j<
N
; j++)
563
sum = sum + rowi[j] * x[j];
564
565
tmp[i] = sum;
566
}
567
568
return
tmp;
569
}
570
571
template
<
class
T>
572
inline
Vector<T>
operator*
(
const
Matrix<T>
&A,
const
Vector<T>
&x)
573
{
574
return
matmult
(A,x);
575
}
576
577
}
// namespace TNT
578
579
#endif
580
// CMAT_H
solvers
gain
wasiak
wzmocnienie
tnt
tnt_cmat.h
Generated by
1.9.8