NCBI C++ ToolKit
matrix.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef UTIL_MATH___MATRIX__HPP
2 #define UTIL_MATH___MATRIX__HPP
3 
4 /* $Id: matrix.hpp 96160 2022-02-17 13:30:14Z gouriano $
5  * ===========================================================================
6  *
7  * PUBLIC DOMAIN NOTICE
8  * National Center for Biotechnology Information
9  *
10  * This software/database is a "United States Government Work" under the
11  * terms of the United States Copyright Act. It was written as part of
12  * the author's official duties as a United States Government employee and
13  * thus cannot be copyrighted. This software/database is freely available
14  * to the public for use. The National Library of Medicine and the U.S.
15  * Government have not placed any restriction on its use or reproduction.
16  *
17  * Although all reasonable efforts have been taken to ensure the accuracy
18  * and reliability of the software and data, the NLM and the U.S.
19  * Government do not and cannot warrant the performance or results that
20  * may be obtained by using this software or data. The NLM and the U.S.
21  * Government disclaim all warranties, express or implied, including
22  * warranties of performance, merchantability or fitness for any particular
23  * purpose.
24  *
25  * Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Authors: Mike DiCuccio
30  *
31  * File Description:
32  *
33  */
34 
35 #include <corelib/ncbistd.hpp>
36 #include <util/math/promote.hpp>
37 #include <vector>
38 
39 
41 
42 template <class T> class CNcbiMatrix;
43 
44 
45 template <class T>
47 {
48 public:
49  typedef vector<T> TData;
50  typedef typename TData::iterator iterator;
51  typedef typename TData::const_iterator const_iterator;
52 
54  CNcbiMatrix(size_t r, size_t c, T val = T());
55 
56  /// make this matrix an identity matrix of a given size
57  void Identity(size_t size);
58 
59  /// make this matrix an identity matrix
60  void Identity();
61 
62  /// make this matrix a diagonal matrix of a given size, with a given value
63  /// on the diagonal
64  void Diagonal(size_t size, T val);
65 
66  /// make this matrix a diagonal matrix, with a given value on the diagonal
67  void Diagonal(T val);
68 
69  /// transpose this matrix
70  void Transpose();
71 
72  /// resize this matrix, filling the empty cells with a known value
73  void Resize(size_t i, size_t j, T val = T());
74 
75  /// swap two rows in the matrix
76  void SwapRows(size_t i, size_t j);
77 
78  /// remove a given row in the matrix
79  void RemoveRow(size_t i);
80 
81  /// remove a given column in the matrix
82  void RemoveCol(size_t i);
83 
84  /// get the number of rows in this matrix
85  size_t GetRows() const;
86 
87  /// get the number of columns in this matrix
88  size_t GetCols() const;
89 
90  /// retrieve the data associated with this matrix
92  const TData& GetData() const;
93 
94  /// iterators
99 
100  /// set all values in the matrix to a known value
101  void Set(T val);
102 
103  /// swap two matrices efficiently
105 
106  /// operator[] for raw data indexing
107  const T& operator[] (size_t i) const;
108  T& operator[] (size_t i);
109 
110  /// operator() for row/column indexing
111  const T& operator() (size_t i, size_t j) const;
112  T& operator() (size_t i, size_t j);
113 
114 protected:
115 
116  /// the data strip we use
118 
119  /// size of this matrix
120  size_t m_Rows;
121  size_t m_Cols;
122 };
123 
124 
125 
126 ///
127 /// global operators
128 ///
129 
130 ///
131 /// stream input.
132 ///
133 /// One line per row, with entries readable by successive calls
134 /// to operator>>. For doubles, this just means they're separated
135 /// by whitespace.
136 template <class T>
137 inline CNcbiIstream&
139 
140 ///
141 /// stream output.
142 ///
143 /// One line per row, with entries separated by a single space
144 template <class T>
145 inline CNcbiOstream&
147 
148 ///
149 /// global addition: matrix + matrix
150 ///
151 template <class T, class U>
152 inline CNcbiMatrix< NCBI_PROMOTE(T,U) >
154 
155 ///
156 /// global subtraction: matrix - matrix
157 ///
158 template <class T, class U>
159 inline CNcbiMatrix< NCBI_PROMOTE(T,U) >
161 
162 
163 ///
164 /// global multiplication: matrix * scalar
165 /// this is a hack, as MSVC doesn't support partial template specialization
166 /// we provide implementations for a number of popular types
167 ///
168 template <class T>
169 inline CNcbiMatrix< NCBI_PROMOTE(T, size_t) >
170 operator* (const CNcbiMatrix<T>&, size_t);
171 
172 template <class U>
173 inline CNcbiMatrix< NCBI_PROMOTE(size_t, U) >
174 operator* (size_t, const CNcbiMatrix<U>&);
175 
176 
177 template <class T>
178 inline CNcbiMatrix< NCBI_PROMOTE(T, float) >
179 operator* (const CNcbiMatrix<T>&, float);
180 
181 template <class U>
182 inline CNcbiMatrix< NCBI_PROMOTE(float, U) >
183 operator* (float, const CNcbiMatrix<U>&);
184 
185 
186 template <class T>
187 inline CNcbiMatrix< NCBI_PROMOTE(T, double) >
188 operator* (const CNcbiMatrix<T>&, double);
189 
190 template <class U>
191 inline CNcbiMatrix< NCBI_PROMOTE(double, U) >
192 operator* (double, const CNcbiMatrix<U>&);
193 
194 
195 ///
196 /// global multiplication: matrix * matrix
197 ///
198 template <class T, class U>
199 inline CNcbiMatrix< NCBI_PROMOTE(T,U) >
201 
202 ///
203 /// global multiplication: matrix * vector
204 ///
205 template <class T, class U>
206 inline vector< NCBI_PROMOTE(T,U) >
207 operator* (const CNcbiMatrix<T>&, const vector<U>&);
208 
209 ///
210 /// global multiplication: vector * matrix
211 ///
212 template <class T, class U>
213 inline vector< NCBI_PROMOTE(T,U) >
214 operator* (const vector<T>&, const CNcbiMatrix<U>&);
215 
216 ///
217 /// global addition: matrix += matrix
218 ///
219 template <class T, class U>
220 inline CNcbiMatrix<T>&
222 
223 ///
224 /// global subtraction: matrix -= matrix
225 ///
226 template <class T, class U>
227 inline CNcbiMatrix<T>&
229 
230 ///
231 /// global multiplication: matrix *= matrix
232 ///
233 template <class T, class U>
234 inline CNcbiMatrix<T>&
236 
237 ///
238 /// global multiplication: matrix *= vector
239 ///
240 template <class T, class U>
241 inline vector<T>&
242 operator*= (CNcbiMatrix<T>&, const vector<U>&);
243 
244 ///
245 /// global multiplication: matrix *= scalar
246 ///
247 template <class T>
248 inline CNcbiMatrix<T>&
250 
251 ///
252 /// global division: matrix /= matrix
253 ///
254 template <class T>
255 inline CNcbiMatrix<T>&
257 
258 ///
259 /// global comparison: matrix == matrix
260 ///
261 template <class T, class U>
262 inline bool
264 
265 ///
266 /// global comparison: matrix != matrix
267 ///
268 template <class T, class U>
269 inline bool
271 
272 
273 /////////////////////////////////////////////////////////////////////////////
274 //
275 // Inline Methods
276 //
277 
278 ///
279 /// default ctor
280 template <class T>
282  : m_Rows(0),
283  m_Cols(0)
284 {
285 }
286 
287 
288 template <class T>
289 inline CNcbiMatrix<T>::CNcbiMatrix(size_t r, size_t c, T val)
290  : m_Rows(r),
291  m_Cols(c)
292 {
293  m_Data.resize(r*c, val);
294 }
295 
296 
297 template <class T>
298 inline size_t CNcbiMatrix<T>::GetRows() const
299 {
300  return m_Rows;
301 }
302 
303 
304 template <class T>
305 inline size_t CNcbiMatrix<T>::GetCols() const
306 {
307  return m_Cols;
308 }
309 
310 
311 template <class T>
313 {
314  return m_Data;
315 }
316 
317 
318 template <class T>
319 inline const typename CNcbiMatrix<T>::TData& CNcbiMatrix<T>::GetData() const
320 {
321  return m_Data;
322 }
323 
324 template <class T>
326 {
327  return m_Data.begin();
328 }
329 
330 
331 template <class T>
333 {
334  return m_Data.end();
335 }
336 
337 
338 template <class T>
340 {
341  return m_Data.begin();
342 }
343 
344 
345 template <class T>
347 {
348  return m_Data.end();
349 }
350 
351 
352 template <class T>
353 inline const T&
355 {
356  _ASSERT(i < m_Data.size());
357  return m_Data[i];
358 }
359 
360 
361 template <class T>
363 {
364  _ASSERT(i < m_Data.size());
365  return m_Data[i];
366 }
367 
368 
369 template <class T>
370 inline const T& CNcbiMatrix<T>::operator() (size_t i, size_t j) const
371 {
372  _ASSERT(i < m_Rows);
373  _ASSERT(j < m_Cols);
374 
375  return m_Data[i * m_Cols + j];
376 }
377 
378 
379 template <class T>
380 inline T& CNcbiMatrix<T>::operator() (size_t i, size_t j)
381 {
382  _ASSERT(i < m_Rows);
383  _ASSERT(j < m_Cols);
384 
385  return m_Data[i * m_Cols + j];
386 }
387 
388 
389 template <class T>
390 inline void CNcbiMatrix<T>::Resize(size_t new_rows, size_t new_cols, T val)
391 {
392 
393  if (new_cols == m_Cols && new_rows >= m_Rows) {
394  /// common special case that can easily be handled efficiently
395  m_Data.resize(new_rows * new_cols, val);
396  } else {
397  /// hack: we just make a new strip and copy things correctly
398  /// there is a faster way to do this
399  TData new_data(new_rows * new_cols, val);
400  size_t i = min(new_rows, m_Rows);
401  size_t j = min(new_cols, m_Cols);
402 
403  for (size_t r = 0; r < i; ++r) {
404  for (size_t c = 0; c < j; ++c) {
405  new_data[r * new_cols + c] = m_Data[r * m_Cols + c];
406  }
407  }
408 
409  new_data.swap(m_Data);
410  }
411  m_Rows = new_rows;
412  m_Cols = new_cols;
413 }
414 
415 
416 template <class T>
417 inline void CNcbiMatrix<T>::Set(T val)
418 {
419  m_Data.clear();
420  m_Data.resize(m_Rows * m_Cols, val);
421 }
422 
423 
424 template <class T>
426 {
427  _ASSERT(m_Rows == m_Cols);
428  Set(T(0));
429 
430  for (size_t i = 0; i < m_Rows; ++i) {
431  m_Data[i * m_Cols + i] = T(1);
432  }
433 }
434 
435 
436 template <class T>
437 inline void CNcbiMatrix<T>::Identity(size_t size)
438 {
439  Resize(size, size);
440  Set(T(0));
441 
442  for (size_t i = 0; i < m_Rows; ++i) {
443  m_Data[i * m_Cols + i] = T(1);
444  }
445 }
446 
447 
448 template <class T>
449 inline void CNcbiMatrix<T>::Diagonal(T val)
450 {
451  _ASSERT(m_Rows == GetCols());
452  Set(T(0));
453 
454  for (size_t i = 0; i < m_Rows; ++i) {
455  m_Data[i * m_Cols + i] = val;
456  }
457 }
458 
459 
460 template <class T>
461 inline void CNcbiMatrix<T>::Diagonal(size_t size, T val)
462 {
463  Resize(size, size);
464  Set(T(0));
465 
466  for (size_t i = 0; i < m_Rows; ++i) {
467  m_Data[i * m_Cols + i] = val;
468  }
469 }
470 
471 
472 template <class T>
474 {
475  TData new_data(m_Cols * m_Rows);
476 
477  for (size_t i = 0; i < m_Rows; ++i) {
478  for (size_t j = 0; j < m_Cols; ++j) {
479  new_data[j * m_Cols + i] = m_Data[i * m_Cols + j];
480  }
481  }
482 
483  m_Data.swap(new_data);
484  swap(m_Rows, m_Cols);
485 }
486 
487 
488 template <class T>
489 inline void CNcbiMatrix<T>::SwapRows(size_t i, size_t j)
490 {
491  size_t i_offs = i * m_Cols;
492  size_t j_offs = j * m_Cols;
493 
494  for (size_t c = 0; c < m_Cols; ++c) {
495  swap(m_Data[i_offs + c], m_Data[j_offs + c] );
496  }
497 }
498 
499 
500 template <class T>
502 {
503  m_Data.swap(M.m_Data);
504  swap(m_Cols, M.m_Cols);
505  swap(m_Rows, M.m_Rows);
506 }
507 
508 
509 template <class T>
510 inline void CNcbiMatrix<T>::RemoveRow(size_t r)
511 {
512  _ASSERT(r < m_Rows);
513  for (++r; r < m_Rows; ++r) {
514  for (size_t c = 0; c < m_Cols; ++c) {
515  m_Data[(r - 1) * m_Cols + c] = m_Data[r * m_Cols + c];
516  }
517  }
518 
519  --m_Rows;
520  m_Data.resize(m_Rows * m_Cols);
521 }
522 
523 
524 template <class T>
525 inline void CNcbiMatrix<T>::RemoveCol(size_t col)
526 {
527  _ASSERT(col < m_Cols);
528  for (size_t r = 0; r < m_Rows; ++r) {
529  for (size_t c = col + 1; c < m_Cols; ++c) {
530  m_Data[r * m_Cols + c - 1] = m_Data[r * m_Cols + c];
531  }
532  }
533 
534  Resize(m_Rows, m_Cols - 1);
535 }
536 
537 ///
538 /// global operators
539 ///
540 
541 
542 ///
543 /// addition
544 ///
545 
546 template <class T, class U>
547 inline CNcbiMatrix< NCBI_PROMOTE(T,U) >
549 {
550  _ASSERT(m0.GetRows() == m1.GetRows());
551  _ASSERT(m0.GetCols() == m1.GetCols());
552 
553  CNcbiMatrix<NCBI_PROMOTE(T,U)> res(m0.GetRows(), m0.GetCols());
554 
555  typename CNcbiMatrix<NCBI_PROMOTE(T,U)>::iterator res_iter = res.begin();
556  typename CNcbiMatrix<NCBI_PROMOTE(T,U)>::iterator res_end = res.end();
557  typename CNcbiMatrix<T>::const_iterator m0_iter = m0.begin();
558  typename CNcbiMatrix<U>::const_iterator m1_iter = m1.begin();
559 
560  for ( ; res_iter != res_end; ++res_iter, ++m0_iter, ++m1_iter) {
561  *res_iter = *m0_iter + *m1_iter;
562  }
563 
564  return res;
565 }
566 
567 
568 template <class T, class U>
569 inline CNcbiMatrix<T>&
571 {
572  _ASSERT(m0.GetRows() == m1.GetRows());
573  _ASSERT(m0.GetCols() == m1.GetCols());
574 
575  typename CNcbiMatrix<T>::iterator m0_iter = m0.begin();
576  typename CNcbiMatrix<T>::iterator m0_end = m0.end();
577  typename CNcbiMatrix<U>::const_iterator m1_iter = m1.begin();
578 
579  size_t mod = (m0.GetRows() * m0.GetCols()) % 4;
580  for ( ; mod; --mod, ++m0_iter, ++m1_iter) {
581  *m0_iter += *m1_iter;
582  }
583 
584  for ( ; m0_iter != m0_end; ) {
585  *m0_iter++ += *m1_iter++;
586  *m0_iter++ += *m1_iter++;
587  *m0_iter++ += *m1_iter++;
588  *m0_iter++ += *m1_iter++;
589  }
590 
591  return m0;
592 }
593 
594 
595 ///
596 /// subtraction
597 ///
598 
599 template <class T, class U>
600 inline CNcbiMatrix< NCBI_PROMOTE(T,U) >
602 {
603  _ASSERT(m0.GetRows() == m1.GetRows());
604  _ASSERT(m0.GetCols() == m1.GetCols());
605 
606  CNcbiMatrix< NCBI_PROMOTE(T,U) > res(m0.GetRows(), m0.GetCols());
607  typename CNcbiMatrix<NCBI_PROMOTE(T,U)>::iterator res_iter = res.begin();
608  typename CNcbiMatrix<NCBI_PROMOTE(T,U)>::iterator res_end = res.end();
609  typename CNcbiMatrix<T>::const_iterator m0_iter = m0.begin();
610  typename CNcbiMatrix<U>::const_iterator m1_iter = m1.begin();
611 
612  for ( ; res_iter != res_end; ++res_iter, ++m0_iter, ++m1_iter) {
613  *res_iter = *m0_iter - *m1_iter;
614  }
615 
616  return res;
617 }
618 
619 
620 template <class T, class U>
621 inline CNcbiMatrix<T>&
623 {
624  _ASSERT(m0.GetRows() == m1.GetRows());
625  _ASSERT(m0.GetCols() == m1.GetCols());
626 
627  typename CNcbiMatrix<T>::iterator m0_iter = m0.begin();
628  typename CNcbiMatrix<T>::iterator m0_end = m0.end();
629  typename CNcbiMatrix<U>::const_iterator m1_iter = m1.begin();
630 
631  for ( ; m0_iter != m0_end; ++m0_iter, ++m1_iter) {
632  *m0_iter -= *m1_iter;
633  }
634 
635  return m0;
636 }
637 
638 
639 ///
640 /// multiplication
641 ///
642 template <class T>
643 inline CNcbiMatrix< NCBI_PROMOTE(T, size_t) >
644 operator* (const CNcbiMatrix<T>& m0, size_t val)
645 {
646  CNcbiMatrix< NCBI_PROMOTE(T, size_t) > res(m0.GetRows(), m0.GetCols());
647 
648  typename CNcbiMatrix<T>::iterator res_iter = res.begin();
649  typename CNcbiMatrix<T>::iterator res_end = res.end();
650  typename CNcbiMatrix<T>::const_iterator m0_iter = m0.begin();
651 
652  for ( ; res_iter != res_end; ++res_iter, ++m0_iter) {
653  *res_iter = *m0_iter * val;
654  }
655 
656  return res;
657 }
658 
659 
660 template <class U>
661 inline CNcbiMatrix< NCBI_PROMOTE(size_t, U) >
662 operator* (size_t val, const CNcbiMatrix<U>& m0)
663 {
664  CNcbiMatrix< NCBI_PROMOTE(U, size_t) > res(m0.GetRows(), m0.GetCols());
665 
666  typename CNcbiMatrix<U>::iterator res_iter = res.begin();
667  typename CNcbiMatrix<U>::iterator res_end = res.end();
668  typename CNcbiMatrix<U>::const_iterator m0_iter = m0.begin();
669 
670  for ( ; res_iter != res_end; ++res_iter, ++m0_iter) {
671  *res_iter = *m0_iter * val;
672  }
673 
674  return res;
675 }
676 
677 
678 template <class T>
679 inline CNcbiMatrix< NCBI_PROMOTE(T, float) >
680 operator* (const CNcbiMatrix<T>& m0, float val)
681 {
682  CNcbiMatrix< NCBI_PROMOTE(T, float) > res(m0.GetRows(), m0.GetCols());
683 
684  typename CNcbiMatrix<T>::iterator res_iter = res.begin();
685  typename CNcbiMatrix<T>::iterator res_end = res.end();
686  typename CNcbiMatrix<T>::const_iterator m0_iter = m0.begin();
687 
688  for ( ; res_iter != res_end; ++res_iter, ++m0_iter) {
689  *res_iter = *m0_iter * val;
690  }
691 
692  return res;
693 }
694 
695 
696 template <class U>
697 inline CNcbiMatrix< NCBI_PROMOTE(float, U) >
698 operator* (float val, const CNcbiMatrix<U>& m0)
699 {
700  CNcbiMatrix< NCBI_PROMOTE(U, float) > res(m0.GetRows(), m0.GetCols());
701 
702  typename CNcbiMatrix<U>::iterator res_iter = res.begin();
703  typename CNcbiMatrix<U>::iterator res_end = res.end();
704  typename CNcbiMatrix<U>::const_iterator m0_iter = m0.begin();
705 
706  for ( ; res_iter != res_end; ++res_iter, ++m0_iter) {
707  *res_iter = *m0_iter * val;
708  }
709 
710  return res;
711 }
712 
713 
714 template <class T>
715 inline CNcbiMatrix< NCBI_PROMOTE(T, double) >
716 operator* (const CNcbiMatrix<T>& m0, double val)
717 {
718  CNcbiMatrix< NCBI_PROMOTE(T, double) > res(m0.GetRows(), m0.GetCols());
719 
720  typename CNcbiMatrix<T>::iterator res_iter = res.begin();
721  typename CNcbiMatrix<T>::iterator res_end = res.end();
722  typename CNcbiMatrix<T>::const_iterator m0_iter = m0.begin();
723 
724  for ( ; res_iter != res_end; ++res_iter, ++m0_iter) {
725  *res_iter = *m0_iter * val;
726  }
727 
728  return res;
729 }
730 
731 
732 template <class U>
733 inline CNcbiMatrix< NCBI_PROMOTE(double, U) >
734 operator* (double val, const CNcbiMatrix<U>& m0)
735 {
736  CNcbiMatrix< NCBI_PROMOTE(U, double) > res(m0.GetRows(), m0.GetCols());
737 
738  typename CNcbiMatrix<U>::iterator res_iter = res.begin();
739  typename CNcbiMatrix<U>::iterator res_end = res.end();
740  typename CNcbiMatrix<U>::const_iterator m0_iter = m0.begin();
741 
742  for ( ; res_iter != res_end; ++res_iter, ++m0_iter) {
743  *res_iter = *m0_iter * val;
744  }
745 
746  return res;
747 }
748 
749 
750 template <class T>
751 inline CNcbiMatrix<T>&
753 {
754  typename CNcbiMatrix<T>::iterator m0_iter = m0.begin();
755  typename CNcbiMatrix<T>::iterator m0_end = m0.end();
756 
757  for ( ; m0_iter != m0_end; ++m0_iter) {
758  *m0_iter *= val;
759  }
760 
761  return m0;
762 }
763 
764 
765 template <class T>
766 inline CNcbiMatrix<T>&
768 {
769  val = T(1/val);
770 
771  typename CNcbiMatrix<T>::iterator m0_iter = m0.begin();
772  typename CNcbiMatrix<T>::iterator m0_end = m0.end();
773 
774  for ( ; m0_iter != m0_end; ++m0_iter) {
775  *m0_iter *= val;
776  }
777 
778  return m0;
779 }
780 
781 
782 template <class T, class U>
783 inline vector< NCBI_PROMOTE(T,U) >
784 operator* (const CNcbiMatrix<T>& m, const vector<U>& v)
785 {
786  _ASSERT(m.GetCols() == v.size());
787 
788  typedef NCBI_PROMOTE(T,U) TPromote;
789  vector< TPromote > res(m.GetRows(), TPromote(0));
790 
791  for (size_t r = 0; r < m.GetRows(); ++r) {
792  for (size_t i = 0; i < m.GetCols(); ++i) {
793  res[r] += m(r,i) * v[i];
794  }
795  }
796 
797  return res;
798 }
799 
800 
801 template <class T, class U>
802 inline vector< NCBI_PROMOTE(T,U) >
803 operator* (const vector<T>& v, const CNcbiMatrix<U>& m)
804 {
805  _ASSERT(m.GetRows() == v.size());
806 
807  typedef NCBI_PROMOTE(T,U) TPromote;
808  vector<TPromote> res(m.GetCols(), TPromote(0));
809 
810  for (size_t c = 0; c < m.GetCols(); ++c) {
811  for (size_t i = 0; i < m.GetRows(); ++i) {
812  res[c] += m(i,c) * v[i];
813  }
814  }
815 
816  return res;
817 }
818 
819 
820 template <class T, class U>
821 inline CNcbiMatrix< NCBI_PROMOTE(T,U) >
823 {
824  _ASSERT(m0.GetCols() == m1.GetRows());
825 
826  typedef NCBI_PROMOTE(T,U) TPromote;
827  CNcbiMatrix< TPromote > res(m0.GetRows(), m1.GetCols(), TPromote(0));
828 
829 #if 1
830  for (size_t r = 0; r < m0.GetRows(); ++r) {
831  for (size_t c = 0; c < m1.GetCols(); ++c) {
832  for (size_t i = 0; i < m0.GetCols(); ++i) {
833  res(r,c) += m0(r,i) * m1(i,c);
834  }
835  }
836  }
837 #endif
838 
839 
840 #if 0
841  const vector<T>& lhs = m0.GetData();
842  const vector<U>& rhs = m1.GetData();
843  size_t col_mod = m0.GetCols() % 4;
844 
845  for (size_t r = 0; r < m0.GetRows(); ++r) {
846  size_t r_offs = r * m0.GetCols();
847 
848  for (size_t c = 0; c < m1.GetCols(); ++c) {
849  size_t i=0;
850  T t0 = 0;
851  T t1 = 0;
852  T t2 = 0;
853  T t3 = 0;
854 
855  switch(col_mod) {
856  default:
857  case 0:
858  break;
859 
860  case 3:
861  t0 += m0.GetData()[r_offs + 2] * m1(2,c);
862  ++i;
863  case 2:
864  t0 += m0.GetData()[r_offs + 1] * m1(1,c);
865  ++i;
866  case 1:
867  t0 += m0.GetData()[r_offs + 0] * m1(0,c);
868  ++i;
869  break;
870  }
871 
872  for (; i < m0.GetCols(); i += 2) {
873  t0 += lhs[r_offs + i + 0] * m1(i + 0, c);
874  t1 += lhs[r_offs + i + 1] * m1(i + 1, c);
875  //t2 += lhs[r_offs + i + 2] * m1(i + 2, c);
876  //t3 += lhs[r_offs + i + 3] * m1(i + 3, c);
877  }
878  res(r,c) = t0 + t1 + t2 + t3;
879  }
880  }
881 #endif
882 
883  return res;
884 }
885 
886 
887 template <class T, class U>
888 inline CNcbiMatrix<T>&
890 {
891  _ASSERT(m0.GetCols() == m1.GetRows());
892 
893  m0 = m0 * m1;
894  return m0;
895 }
896 
897 
898 ///
899 /// comparators
900 ///
901 
902 template <class T, class U>
903 inline bool
905 {
906  if (m0.GetRows() != m1.GetRows()) {
907  return false;
908  }
909  if (m0.GetCols() != m1.GetCols()) {
910  return false;
911  }
912 
913  for (size_t i = 0; i < m0.GetData().size(); ++i) {
914  if (m0[i] != m1[i]) {
915  return false;
916  }
917  }
918 
919  return true;
920 }
921 
922 
923 template <class T, class U>
924 inline bool
926 {
927  return !(m0 == m1);
928 }
929 
930 
931 ///
932 /// stream output
933 template <class T>
935 {
936  for (size_t i = 0; i < M.GetRows(); ++i) {
937  for (size_t j = 0; j < M.GetCols(); ++j) {
938  if (j > 0) {
939  os << " ";
940  }
941  os << M(i, j);
942  }
943  os << NcbiEndl;
944  }
945  return os;
946 }
947 
948 
949 ///
950 /// stream input
951 template <class T>
953 {
955  string line;
956  vector<T> row;
957  T entry;
958  int linenum = 0;
959  while(getline(is, line)) {
960  linenum++;
961  if (line.empty() || line[0] == '#') {
962  continue;
963  }
964  CNcbiIstrstream iss(line);
965  row.clear();
966  while(1) {
967  iss >> entry;
968  if (!iss) {
969  break;
970  }
971  row.push_back(entry);
972  }
973  if (A.GetCols() == 0) {
974  A.Resize(A.GetCols(), row.size());
975  }
976  if (row.size() != A.GetCols()) {
978  "error at line " +
979  NStr::IntToString(linenum) + ": expected " +
980  NStr::IntToString(A.GetCols()) + " columns; got" +
981  NStr::IntToString(row.size()));
982  }
983  A.Resize(A.GetRows() + 1, A.GetCols());
984  for (int i = 0; i < A.GetCols(); ++i) {
985  A(A.GetRows() - 1, i) = row[i];
986  }
987  }
988  M.Swap(A);
989  return is;
990 }
991 
992 
993 
995 
996 #endif /// UTIL_MATH___MATRIX__HPP
void Resize(size_t i, size_t j, T val=T())
resize this matrix, filling the empty cells with a known value
Definition: matrix.hpp:390
TData & GetData()
retrieve the data associated with this matrix
Definition: matrix.hpp:312
iterator end()
Definition: matrix.hpp:332
void Diagonal(size_t size, T val)
make this matrix a diagonal matrix of a given size, with a given value on the diagonal
Definition: matrix.hpp:461
TData::iterator iterator
Definition: matrix.hpp:50
void SwapRows(size_t i, size_t j)
swap two rows in the matrix
Definition: matrix.hpp:489
const T & operator[](size_t i) const
operator[] for raw data indexing
Definition: matrix.hpp:354
void Swap(CNcbiMatrix< T > &M)
swap two matrices efficiently
Definition: matrix.hpp:501
const_iterator begin() const
Definition: matrix.hpp:339
void Identity()
make this matrix an identity matrix
Definition: matrix.hpp:425
void Set(T val)
set all values in the matrix to a known value
Definition: matrix.hpp:417
void RemoveRow(size_t i)
remove a given row in the matrix
Definition: matrix.hpp:510
size_t m_Rows
size of this matrix
Definition: matrix.hpp:120
size_t m_Cols
Definition: matrix.hpp:121
void Identity(size_t size)
make this matrix an identity matrix of a given size
Definition: matrix.hpp:437
size_t GetRows() const
get the number of rows in this matrix
Definition: matrix.hpp:298
TData::const_iterator const_iterator
Definition: matrix.hpp:51
void RemoveCol(size_t i)
remove a given column in the matrix
Definition: matrix.hpp:525
vector< T > TData
Definition: matrix.hpp:49
const T & operator()(size_t i, size_t j) const
operator() for row/column indexing
Definition: matrix.hpp:370
size_t GetCols() const
get the number of columns in this matrix
Definition: matrix.hpp:305
CNcbiMatrix(size_t r, size_t c, T val=T())
Definition: matrix.hpp:289
void Diagonal(T val)
make this matrix a diagonal matrix, with a given value on the diagonal
Definition: matrix.hpp:449
void Transpose()
transpose this matrix
Definition: matrix.hpp:473
CNcbiMatrix()
default ctor
Definition: matrix.hpp:281
const TData & GetData() const
Definition: matrix.hpp:319
const_iterator end() const
Definition: matrix.hpp:346
iterator begin()
iterators
Definition: matrix.hpp:325
TData m_Data
the data strip we use
Definition: matrix.hpp:117
Include a standard set of the NCBI C++ Toolkit most basic headers.
#define T(s)
Definition: common.h:230
#define A(i)
Definition: ecp_curves.c:948
void swap(NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair1, NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair2)
Definition: ncbimisc.hpp:1508
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
NCBI_PROMOTE(T, U) operator*(const CVect2< T > &v1
@ eUnknown
Definition: app_popup.hpp:72
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define NcbiEndl
Definition: ncbistre.hpp:548
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
Definition: ncbistre.hpp:149
IO_PREFIX::istream CNcbiIstream
Portable alias for istream.
Definition: ncbistre.hpp:146
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5084
int i
CNcbiMatrix< NCBI_PROMOTE(T, size_t) > operator*(const CNcbiMatrix< T > &, size_t)
global multiplication: matrix * scalar this is a hack, as MSVC doesn't support partial template speci...
Definition: matrix.hpp:644
CNcbiMatrix< T > & operator+=(CNcbiMatrix< T > &, const CNcbiMatrix< U > &)
global addition: matrix += matrix
Definition: matrix.hpp:570
CNcbiMatrix< T > & operator*=(CNcbiMatrix< T > &, const CNcbiMatrix< U > &)
global multiplication: matrix *= matrix
Definition: matrix.hpp:889
CNcbiIstream & operator>>(CNcbiIstream &is, CNcbiMatrix< T > &M)
global operators
Definition: matrix.hpp:952
CNcbiMatrix< T > & operator-=(CNcbiMatrix< T > &, const CNcbiMatrix< U > &)
global subtraction: matrix -= matrix
Definition: matrix.hpp:622
bool operator==(const CNcbiMatrix< T > &, const CNcbiMatrix< U > &)
global comparison: matrix == matrix
Definition: matrix.hpp:904
CNcbiMatrix< T > & operator/=(CNcbiMatrix< T > &, T)
global division: matrix /= matrix
Definition: matrix.hpp:767
CNcbiOstream & operator<<(CNcbiOstream &os, const CNcbiMatrix< T > &M)
stream output.
Definition: matrix.hpp:934
CNcbiMatrix< NCBI_PROMOTE(T, U) > operator-(const CNcbiMatrix< T > &, const CNcbiMatrix< U > &)
global subtraction: matrix - matrix
Definition: matrix.hpp:601
CNcbiMatrix< NCBI_PROMOTE(T, U) > operator+(const CNcbiMatrix< T > &, const CNcbiMatrix< U > &)
global addition: matrix + matrix
Definition: matrix.hpp:548
bool operator!=(const CNcbiMatrix< T > &, const CNcbiMatrix< U > &)
global comparison: matrix != matrix
Definition: matrix.hpp:925
const struct ncbi::grid::netcache::search::fields::SIZE size
T min(T x_, T y_)
Int mod(Int i, Int j)
Definition: njn_integer.hpp:67
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
#define _ASSERT
Modified on Sat Feb 24 07:46:00 2024 by modify_doxy.py rev. 669887