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