root/win32/itpp-4.0.1/itpp/base/matfunc.h @ 35

Revision 35, 29.9 kB (checked in by mido, 17 years ago)

zasadni zmeny ve /win32

Line 
1/*!
2 * \file
3 * \brief Various functions on vectors and matrices - header file
4 * \author Tony Ottosson, Adam Piatyszek, Conrad Sanderson, Mark Dobossy
5 *         and Martin Senst
6 *
7 * -------------------------------------------------------------------------
8 *
9 * IT++ - C++ library of mathematical, signal processing, speech processing,
10 *        and communications classes and functions
11 *
12 * Copyright (C) 1995-2007  (see AUTHORS file for a list of contributors)
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 *
28 * -------------------------------------------------------------------------
29 */
30
31#ifndef MATFUNC_H
32#define MATFUNC_H
33
34#include <itpp/base/mat.h>
35#include <itpp/base/math/log_exp.h>
36#include <itpp/base/math/elem_math.h>
37
38
39namespace itpp {
40
41  /*!
42    \addtogroup matrix_functions
43    \brief Functions on vectors and matrices
44  */
45  //!@{
46
47  //! Length of vector
48  template<class T>
49  int length(const Vec<T> &v) { return v.length(); }
50
51  //! Length of vector
52  template<class T>
53  int size(const Vec<T> &v) { return v.length(); }
54
55  //! Sum of all elements in the vector
56  template<class T>
57  T sum(const Vec<T> &v)
58  {
59    T M = 0;
60
61    for (int i=0;i<v.length();i++)
62      M += v[i];
63
64    return M;
65  }
66
67  /*!
68   * \brief Sum of elements in the matrix \c m, either along columns or rows
69   *
70   * <tt>sum(m) = sum(m, 1)</tt> returns a vector where the elements are sum
71   * over each column, whereas <tt>sum(m, 2)</tt> returns a vector where the
72   * elements are sum over each row.
73   */
74  template<class T>
75  Vec<T> sum(const Mat<T> &m, int dim=1)
76  {
77    it_assert((dim == 1) || (dim == 2), "sum: dimension need to be 1 or 2");
78    Vec<T> out;
79
80    if (dim == 1) {
81      out.set_size(m.cols(), false);
82
83      for (int i=0; i<m.cols(); i++)
84              out(i) = sum(m.get_col(i));
85    }
86    else {
87      out.set_size(m.rows(), false);
88
89      for (int i=0; i<m.rows(); i++)
90              out(i) = sum(m.get_row(i));
91    }
92
93    return out;
94  }
95
96
97  //! Sum of all elements in the given matrix. Fast version of sum(sum(X))
98  template<class T>
99  T sumsum(const Mat<T> &X)
100  {
101    const T * X_data = X._data();
102    const int X_datasize = X._datasize();
103    T acc = 0;
104
105    for(int i=0;i<X_datasize;i++)
106      acc += X_data[i];
107
108    return acc;
109  }
110
111
112  //! Sum of square of the elements in a vector
113  template<class T>
114  T sum_sqr(const Vec<T> &v)
115  {
116    T M=0;
117
118    for (int i=0; i<v.length(); i++)
119      M += v[i] * v[i];
120
121    return M;
122  }
123
124  /*!
125   * \brief Sum of the square of elements in the matrix \c m
126   *
127   * <tt>sum(m) = sum(m, 1)</tt> returns a vector where the elements are sum
128   * squared over each column, whereas <tt>sum(m, 2)</tt> returns a vector
129   * where the elements are sum squared over each row
130   */
131  template<class T>
132  Vec<T> sum_sqr(const Mat<T> &m, int dim=1)
133  {
134    it_assert((dim == 1) || (dim == 2), "sum_sqr: dimension need to be 1 or 2");
135    Vec<T> out;
136
137    if (dim == 1) {
138      out.set_size(m.cols(), false);
139
140      for (int i=0; i<m.cols(); i++)
141        out(i) = sum_sqr(m.get_col(i));
142    }
143    else {
144      out.set_size(m.rows(), false);
145
146      for (int i=0; i<m.rows(); i++)
147        out(i) = sum_sqr(m.get_row(i));
148    }
149
150    return out;
151  }
152
153  //! Cumulative sum of all elements in the vector
154  template<class T>
155  Vec<T> cumsum(const Vec<T> &v)
156  {
157    Vec<T> out(v.size());
158
159    out(0)=v(0);
160    for (int i=1; i<v.size(); i++)
161      out(i) = out(i-1) + v(i);
162
163    return out;
164  }
165
166  /*!
167   * \brief Cumulative sum of elements in the matrix \c m
168   *
169   * <tt>cumsum(m) = cumsum(m, 1)</tt> returns a matrix where the elements
170   * are sums over each column, whereas <tt>cumsum(m, 2)</tt> returns a
171   * matrix where the elements are sums over each row
172   */
173  template<class T>
174  Mat<T> cumsum(const Mat<T> &m, int dim=1)
175  {
176    it_assert((dim == 1) || (dim == 2), "cumsum: dimension need to be 1 or 2");
177    Mat<T> out(m.rows(), m.cols());
178
179    if (dim == 1) {
180      for (int i=0; i<m.cols(); i++)
181        out.set_col(i, cumsum(m.get_col(i)));
182    } else {
183      for (int i=0; i<m.rows(); i++)
184        out.set_row(i, cumsum(m.get_row(i)));
185    }
186
187    return out;
188  }
189
190  //! The product of all elements in the vector
191  template<class T>
192  T prod(const Vec<T> &v)
193  {
194    it_assert(v.size() >= 1, "prod: size of vector should be at least 1");
195    T out = v(0);
196
197    for (int i=1; i<v.size(); i++)
198      out *= v(i);
199
200    return out;
201  }
202
203  /*!
204   * \brief Product of elements in the matrix \c m
205   *
206   * <tt>prod(m) = prod(m, 1)</tt> returns a vector where the elements are
207   * products over each column, whereas <tt>prod(m, 2)</tt> returns a vector
208   * where the elements are products over each row
209   */
210  template<class T>
211  Vec<T> prod(const Mat<T> &m, int dim=1)
212  {
213    it_assert((dim == 1) || (dim == 2), "prod: dimension need to be 1 or 2");
214    Vec<T> out(m.cols());
215
216    if (dim == 1) {
217      it_assert((m.cols() >= 1) && (m.rows() >= 1),
218                "prod: number of columns should be at least 1");
219      out.set_size(m.cols(), false);
220
221      for (int i=0; i<m.cols(); i++)
222        out(i) = prod(m.get_col(i));
223    }
224    else {
225      it_assert((m.cols() >= 1) && (m.rows() >= 1),
226                "prod: number of rows should be at least 1");
227      out.set_size(m.rows(), false);
228
229      for (int i=0; i<m.rows(); i++)
230        out(i) = prod(m.get_row(i));
231    }
232    return out;
233  }
234
235  //! Vector cross product. Vectors need to be of size 3
236  template<class T>
237  Vec<T> cross(const Vec<T> &v1, const Vec<T> &v2)
238  {
239    it_assert((v1.size() == 3) && (v2.size() == 3),
240              "cross: vectors should be of size 3");
241
242    Vec<T> r(3);
243
244    r(0) = v1(1) * v2(2) - v1(2) * v2(1);
245    r(1) = v1(2) * v2(0) - v1(0) * v2(2);
246    r(2) = v1(0) * v2(1) - v1(1) * v2(0);
247
248    return r;
249  }
250
251
252  //! Zero-pad a vector to size n
253  template<class T>
254  Vec<T> zero_pad(const Vec<T> &v, int n)
255  {
256    it_assert(n >= v.size(), "zero_pad() cannot shrink the vector!");
257    Vec<T> v2(n);
258    v2.set_subvector(0, v.size()-1, v);
259    if (n > v.size())
260      v2.set_subvector(v.size(), n-1, T(0));
261
262    return v2;
263  }
264
265  //! Zero-pad a vector to the nearest greater power of two
266  template<class T>
267  Vec<T> zero_pad(const Vec<T> &v)
268  {
269    int n = pow2i(levels2bits(v.size()));
270
271    return (n == v.size()) ? v : zero_pad(v, n);
272  }
273
274  //! Zero-pad a matrix to size rows x cols
275  template<class T>
276  Mat<T> zero_pad(const Mat<T> &m, int rows, int cols)
277  {
278    it_assert((rows >= m.rows()) && (cols >= m.cols()),
279              "zero_pad() cannot shrink the matrix!");
280    Mat<T> m2(rows, cols);
281    m2.set_submatrix(0,m.rows()-1,0,m.cols()-1, m);
282    if (cols > m.cols()) // Zero
283      m2.set_submatrix(0,m.rows()-1, m.cols(),cols-1, T(0));
284    if (rows > m.rows()) // Zero
285      m2.set_submatrix(m.rows(), rows-1, 0, cols-1, T(0));
286
287    return m2;
288  }
289
290
291  //! Return zero if indexing outside the vector \c v otherwise return the
292  //! element \c index
293  template<class T>
294  T index_zero_pad(const Vec<T> &v, const int index)
295  {
296    if (index >= 0 && index < v.size())
297      return v(index);
298    else
299      return T(0);
300  }
301
302
303  //! Transposition of the matrix \c m returning the transposed matrix in \c out
304  template<class T>
305  void transpose(const Mat<T> &m, Mat<T> &out) { out = m.T(); }
306
307  //! Transposition of the matrix \c m
308  template<class T>
309  Mat<T> transpose(const Mat<T> &m) { return m.T(); }
310
311
312  //! Hermitian transpose (complex conjugate transpose) of the matrix \c m
313  //! returning the transposed matrix in \c out
314  template<class T>
315  void hermitian_transpose(const Mat<T> &m, Mat<T> &out) { out = m.H(); }
316
317  //! Hermitian transpose (complex conjugate transpose) of the matrix \c m
318  template<class T>
319  Mat<T> hermitian_transpose(const Mat<T> &m) { return m.H(); }
320
321
322
323  /*!
324   * \brief Returns true if matrix \c X is hermitian, false otherwise
325   * \author M. Szalay
326   *
327   * A square matrix \f$\mathbf{X}\f$ is hermitian if
328   * \f[
329   * \mathbf{X} = \mathbf{X}^H
330   * \f]
331   */
332  template<class Num_T>
333  bool is_hermitian(const Mat<Num_T>& X) {
334
335    if (X == X.H() )
336      return true;
337    else
338      return false;
339  }
340
341  /*!
342   * \brief Returns true if matrix \c X is unitary, false otherwise
343   * \author M. Szalay
344   *
345   * A square matrix \f$\mathbf{X}\f$ is unitary if
346   * \f[
347   * \mathbf{X}^H = \mathbf{X}^{-1}
348   * \f]
349   */
350  template<class Num_T>
351  bool is_unitary(const Mat<Num_T>& X) {
352
353    if ( inv(X) == X.H() )
354      return true;
355    else
356      return false;
357  }
358
359
360  /*!
361   * \relates Vec
362   * \brief Creates a vector with \c n copies of the vector \c v
363   * \author Martin Senst
364   *
365   * \param v Vector to be repeated
366   * \param n Number of times to repeat \c v
367   */
368  template<class T>
369  Vec<T> repmat(const Vec<T> &v, int n)
370  {
371    it_assert(n > 0, "repmat(): Wrong repetition parameter");
372    int data_length = v.length();
373    it_assert(data_length > 0, "repmat(): Input vector can not be empty");
374    Vec<T> assembly(data_length * n);
375    for (int j = 0; j < n; ++j) {
376      assembly.set_subvector(j * data_length, v);
377    }
378    return assembly;
379  }
380
381
382  /*!
383   * \relates Mat
384   * \brief Creates a matrix with \c m by \c n copies of the matrix \c data
385   * \author Mark Dobossy
386   *
387   * \param data Matrix to be repeated
388   * \param m Number of times to repeat data vertically
389   * \param n Number of times to repeat data horizontally
390   */
391  template<class T>
392  Mat<T> repmat(const Mat<T> &data, int m, int n)
393  {
394    it_assert((m > 0) && (n > 0), "repmat(): Wrong repetition parameters");
395    int data_rows = data.rows();
396    int data_cols = data.cols();
397    it_assert((data_rows > 0) && (data_cols > 0), "repmat(): Input matrix can "
398              "not be empty");
399    Mat<T> assembly(data_rows*m, data_cols*n);
400    for (int i = 0; i < m; ++i) {
401      for (int j = 0; j < n; ++j) {
402        assembly.set_submatrix(i*data_rows, j*data_cols, data);
403      }
404    }
405    return assembly;
406  }
407
408  /*!
409   * \relates Mat
410   * \brief Returns a matrix with \c m by \c n copies of the vector \c data
411   * \author Adam Piatyszek
412   *
413   * \param v Vector to be repeated
414   * \param m Number of times to repeat data vertically
415   * \param n Number of times to repeat data horizontally
416   * \param transpose Specifies the input vector orientation (column vector
417   * by default)
418   */
419  template<class T> inline
420  Mat<T> repmat(const Vec<T> &v, int m, int n, bool transpose = false)
421  {
422    return repmat((transpose ? v.T() : Mat<T>(v)), m, n);
423  }
424
425
426  /*!
427   * \brief Computes the Kronecker product of two matrices
428   *
429   * <tt>K = kron(X, Y)</tt> returns the Kronecker tensor product of \c X
430   * and \c Y. The result is a large array formed by taking all possible
431   * products between the elements of \c X and those of \c Y. If \c X is
432   * <tt>(m x n)</tt> and \c Y is <tt>(p x q)</tt>, then <tt>kron(X, Y)</tt>
433   * is <tt>(m*p x n*q)</tt>.
434   *
435   * \author Adam Piatyszek
436   */
437  template<class Num_T>
438  Mat<Num_T> kron(const Mat<Num_T>& X, const Mat<Num_T>& Y)
439  {
440    Mat<Num_T> result(X.rows() * Y.rows(), X.cols() * Y.cols());
441
442    for (int i = 0; i < X.rows(); i++)
443      for (int j = 0; j < X.cols(); j++)
444        result.set_submatrix(i * Y.rows(), j * Y.cols(), X(i, j) * Y);
445
446    return result;
447  }
448
449
450  /*!
451   * \brief Square root of the complex square matrix \c A
452   *
453   * This function computes the matrix square root of the complex square
454   * matrix \c A. The implementation is based on the Matlab/Octave \c
455   * sqrtm() function.
456   *
457   * Ref: N. J. Higham, "Numerical Analysis Report No. 336", Manchester
458   * Centre for Computational Mathematics, Manchester, England, January 1999
459   *
460   * \author Adam Piatyszek
461   */
462  cmat sqrtm(const cmat& A);
463
464  /*!
465   * \brief Square root of the real square matrix \c A
466   *
467   * This function computes the matrix square root of the real square matrix
468   * \c A. Please note that the returned matrix is complex. The
469   * implementation is based on the Matlab/Octave \c sqrtm() function.
470   *
471   * Ref: N. J. Higham, "Numerical Analysis Report No. 336", Manchester
472   * Centre for Computational Mathematics, Manchester, England, January 1999
473   *
474   * \author Adam Piatyszek
475   */
476  cmat sqrtm(const mat& A);
477
478  //!@}
479
480
481
482  // -------------------- Diagonal matrix functions -------------------------
483
484  //! \addtogroup diag
485  //!@{
486
487  /*!
488   * \brief Create a diagonal matrix using vector \c v as its diagonal
489   *
490   * All other matrix elements except the ones on its diagonal are set to
491   * zero. An optional parameter \c K can be used to shift the diagonal in
492   * the resulting matrix. By default \c K is equal to zero.
493   *
494   * The size of the diagonal matrix will be \f$n+|K| \times n+|K|\f$, where
495   * \f$n\f$ is the length of the input vector \c v.
496   */
497  template<class T>
498  Mat<T> diag(const Vec<T> &v, const int K = 0)
499  {
500    Mat<T> m(v.size() + std::abs(K), v.size() + std::abs(K));
501    m = T(0);
502    if (K>0)
503      for (int i=v.size()-1; i>=0; i--)
504        m(i,i+K) = v(i);
505    else
506      for (int i=v.size()-1; i>=0; i--)
507        m(i-K,i) = v(i);
508
509    return m;
510  }
511
512  /*!
513   * \brief Create a diagonal matrix using vector \c v as its diagonal
514   *
515   * All other matrix elements except the ones on its diagonal are set to
516   * zero.
517   *
518   * The size of the diagonal matrix will be \f$n \times n\f$, where \f$n\f$
519   * is the length of the input vector \c v.
520   */
521  template<class T>
522  void diag(const Vec<T> &v, Mat<T> &m)
523  {
524    m.set_size(v.size(), v.size(), false);
525    m = T(0);
526    for (int i=v.size()-1; i>=0; i--)
527      m(i,i) = v(i);
528  }
529
530  /*!
531   * \brief Get the diagonal elements of the input matrix \c m
532   *
533   * The size of the output vector with diagonal elements will be
534   * \f$n = min(r, c)\f$, where \f$r \times c\f$ are the dimensions of
535   * matrix \c m.
536  */
537  template<class T>
538  Vec<T> diag(const Mat<T> &m)
539  {
540    Vec<T> t(std::min(m.rows(), m.cols()));
541
542    for (int i=0; i<t.size(); i++)
543      t(i) = m(i,i);
544
545    return t;
546  }
547
548  /*!
549    \brief Returns a matrix with the elements of the input vector \c main on
550    the diagonal and the elements of the input vector \c sup on the diagonal
551    row above.
552
553    If the number of elements in the vector \c main is \f$n\f$, then the
554    number of elements in the input vector \c sup must be \f$n-1\f$. The
555    size of the return matrix will be \f$n \times n\f$.
556  */
557  template<class T>
558  Mat<T> bidiag(const Vec<T> &main, const Vec<T> &sup)
559  {
560    it_assert(main.size() == sup.size()+1, "bidiag()");
561
562    int n=main.size();
563    Mat<T> m(n, n);
564    m = T(0);
565    for (int i=0; i<n-1; i++) {
566      m(i,i) = main(i);
567      m(i,i+1) = sup(i);
568    }
569    m(n-1,n-1) = main(n-1);
570
571    return m;
572  }
573
574  /*!
575    \brief Returns in the output variable \c m a matrix with the elements of
576    the input vector \c main on the diagonal and the elements of the input
577    vector \c sup on the diagonal row above.
578
579    If the number of elements in the vector \c main is \f$n\f$, then the
580    number of elements in the input vector \c sup must be \f$n-1\f$. The
581    size of the output matrix \c m will be \f$n \times n\f$.
582  */
583  template<class T>
584  void bidiag(const Vec<T> &main, const Vec<T> &sup, Mat<T> &m)
585  {
586    it_assert(main.size() == sup.size()+1, "bidiag()");
587
588    int n=main.size();
589    m.set_size(n, n);
590    m = T(0);
591    for (int i=0; i<n-1; i++) {
592      m(i,i) = main(i);
593      m(i,i+1) = sup(i);
594    }
595    m(n-1,n-1) = main(n-1);
596  }
597
598  /*!
599    \brief Returns the main diagonal and the diagonal row above in the two
600    output vectors \c main and \c sup.
601
602    The input matrix \c in must be a square \f$n \times n\f$ matrix. The
603    length of the output vector \c main will be \f$n\f$ and the length of
604    the output vector \c sup will be \f$n-1\f$.
605  */
606  template<class T>
607  void bidiag(const Mat<T> &m, Vec<T> &main, Vec<T> &sup)
608  {
609    it_assert(m.rows() == m.cols(), "bidiag(): Matrix must be square!");
610
611    int n=m.cols();
612    main.set_size(n);
613    sup.set_size(n-1);
614    for (int i=0; i<n-1; i++) {
615      main(i) = m(i,i);
616      sup(i) = m(i,i+1);
617    }
618    main(n-1) = m(n-1,n-1);
619  }
620
621  /*!
622    \brief Returns a matrix with the elements of \c main on the diagonal,
623    the elements of \c sup on the diagonal row above, and the elements of \c
624    sub on the diagonal row below.
625
626    If the length of the input vector \c main is \f$n\f$ then the lengths of
627    the vectors \c sup and \c sub must equal \f$n-1\f$. The size of the
628    return matrix will be \f$n \times n\f$.
629  */
630  template<class T>
631  Mat<T> tridiag(const Vec<T> &main, const Vec<T> &sup, const Vec<T> &sub)
632  {
633    it_assert(main.size()==sup.size()+1 && main.size()==sub.size()+1, "bidiag()");
634
635    int n=main.size();
636    Mat<T> m(n, n);
637    m = T(0);
638    for (int i=0; i<n-1; i++) {
639      m(i,i) = main(i);
640      m(i,i+1) = sup(i);
641      m(i+1,i) = sub(i);
642    }
643    m(n-1,n-1) = main(n-1);
644
645    return m;
646  }
647
648  /*!
649    \brief Returns in the output matrix \c m a matrix with the elements of
650    \c main on the diagonal, the elements of \c sup on the diagonal row
651    above, and the elements of \c sub on the diagonal row below.
652
653    If the length of the input vector \c main is \f$n\f$ then the lengths of
654    the vectors \c sup and \c sub must equal \f$n-1\f$. The size of the
655    output matrix \c m will be \f$n \times n\f$.
656  */
657  template<class T>
658  void tridiag(const Vec<T> &main, const Vec<T> &sup, const Vec<T> &sub, Mat<T> &m)
659  {
660    it_assert(main.size()==sup.size()+1 && main.size()==sub.size()+1, "bidiag()");
661
662    int n=main.size();
663    m.set_size(n, n);
664    m = T(0);
665    for (int i=0; i<n-1; i++) {
666      m(i,i) = main(i);
667      m(i,i+1) = sup(i);
668      m(i+1,i) = sub(i);
669    }
670    m(n-1,n-1) = main(n-1);
671  }
672
673  /*!
674    \brief Returns the main diagonal, the diagonal row above, and the
675    diagonal row below int the output vectors \c main, \c sup, and \c sub.
676
677    The input matrix \c m must be a square \f$n \times n\f$ matrix. The
678    length of the output vector \c main will be \f$n\f$ and the length of
679    the output vectors \c sup and \c sup will be \f$n-1\f$.
680  */
681  template<class T>
682  void tridiag(const Mat<T> &m, Vec<T> &main, Vec<T> &sup, Vec<T> &sub)
683  {
684    it_assert(m.rows() == m.cols(), "tridiag(): Matrix must be square!");
685
686    int n=m.cols();
687    main.set_size(n);
688    sup.set_size(n-1);
689    sub.set_size(n-1);
690    for (int i=0; i<n-1; i++) {
691      main(i) = m(i,i);
692      sup(i) = m(i,i+1);
693      sub(i) = m(i+1,i);
694    }
695    main(n-1) = m(n-1,n-1);
696  }
697
698
699  /*!
700    \brief The trace of the matrix \c m, i.e. the sum of the diagonal elements.
701  */
702  template<class T>
703  T trace(const Mat<T> &m)
704  {
705    return sum(diag(m));
706  }
707
708  //!@}
709
710
711  // ----------------- reshaping vectors and matrices ------------------------
712
713  //! \addtogroup reshaping
714  //!@{
715
716  //! Reverse the input vector
717  template<class T>
718  Vec<T> reverse(const Vec<T> &in)
719  {
720    int i, s=in.length();
721
722    Vec<T> out(s);
723    for (i=0;i<s;i++)
724      out[i]=in[s-1-i];
725    return out;
726  }
727
728  //! Row vectorize the matrix [(0,0) (0,1) ... (N-1,N-2) (N-1,N-1)]
729  template<class T>
730  Vec<T> rvectorize(const Mat<T> &m)
731  {
732    int i, j, n=0, r=m.rows(), c=m.cols();
733    Vec<T> v(r * c);
734
735    for (i=0; i<r; i++)
736      for (j=0; j<c; j++)
737        v(n++) = m(i,j);
738
739    return v;
740  }
741
742  //! Column vectorize the matrix [(0,0) (1,0) ... (N-2,N-1) (N-1,N-1)]
743  template<class T>
744  Vec<T> cvectorize(const Mat<T> &m)
745  {
746    int i, j, n=0, r=m.rows(), c=m.cols();
747    Vec<T> v(r * c);
748
749    for (j=0; j<c; j++)
750      for (i=0; i<r; i++)
751        v(n++) = m(i,j);
752
753    return v;
754  }
755
756  /*!
757    \brief Reshape the matrix into an rows*cols matrix
758
759    The data is taken columnwise from the original matrix and written
760    columnwise into the new matrix.
761  */
762  template<class T>
763  Mat<T> reshape(const Mat<T> &m, int rows, int cols)
764  {
765    it_assert_debug(m.rows()*m.cols() == rows*cols, "Mat<T>::reshape: Sizes must match");
766    Mat<T> temp(rows, cols);
767    int i, j, ii=0, jj=0;
768    for (j=0; j<m.cols(); j++) {
769      for (i=0; i<m.rows(); i++) {
770        temp(ii++,jj) = m(i,j);
771        if (ii == rows) {
772          jj++; ii=0;
773        }
774      }
775    }
776    return temp;
777  }
778
779  /*!
780    \brief Reshape the vector into an rows*cols matrix
781
782    The data is element by element from the vector and written columnwise
783    into the new matrix.
784  */
785  template<class T>
786  Mat<T> reshape(const Vec<T> &v, int rows, int cols)
787  {
788    it_assert_debug(v.size() == rows*cols, "Mat<T>::reshape: Sizes must match");
789    Mat<T> temp(rows, cols);
790    int i, j, ii=0;
791    for (j=0; j<cols; j++) {
792      for (i=0; i<rows; i++) {
793        temp(i,j) = v(ii++);
794      }
795    }
796    return temp;
797  }
798
799  //!@}
800
801
802  //! Returns \a true if all elements are ones and \a false otherwise
803  bool all(const bvec &testvec);
804  //! Returns \a true if any element is one and \a false otherwise
805  bool any(const bvec &testvec);
806
807  //! \cond
808
809  // ----------------------------------------------------------------------
810  // Instantiations
811  // ----------------------------------------------------------------------
812
813#ifdef HAVE_EXTERN_TEMPLATE
814
815  extern template int length(const vec &v);
816  extern template int length(const cvec &v);
817  extern template int length(const svec &v);
818  extern template int length(const ivec &v);
819  extern template int length(const bvec &v);
820
821  extern template double sum(const vec &v);
822  extern template std::complex<double> sum(const cvec &v);
823  extern template short sum(const svec &v);
824  extern template int sum(const ivec &v);
825  extern template bin sum(const bvec &v);
826
827  extern template double sum_sqr(const vec &v);
828  extern template std::complex<double> sum_sqr(const cvec &v);
829  extern template short sum_sqr(const svec &v);
830  extern template int sum_sqr(const ivec &v);
831  extern template bin sum_sqr(const bvec &v);
832
833  extern template vec cumsum(const vec &v);
834  extern template cvec cumsum(const cvec &v);
835  extern template svec cumsum(const svec &v);
836  extern template ivec cumsum(const ivec &v);
837  extern template bvec cumsum(const bvec &v);
838
839  extern template double prod(const vec &v);
840  extern template std::complex<double> prod(const cvec &v);
841  extern template short prod(const svec &v);
842  extern template int prod(const ivec &v);
843  extern template bin prod(const bvec &v);
844
845  extern template vec cross(const vec &v1, const vec &v2);
846  extern template cvec cross(const cvec &v1, const cvec &v2);
847  extern template ivec cross(const ivec &v1, const ivec &v2);
848  extern template svec cross(const svec &v1, const svec &v2);
849  extern template bvec cross(const bvec &v1, const bvec &v2);
850
851  extern template vec reverse(const vec &in);
852  extern template cvec reverse(const cvec &in);
853  extern template svec reverse(const svec &in);
854  extern template ivec reverse(const ivec &in);
855  extern template bvec reverse(const bvec &in);
856
857  extern template vec zero_pad(const vec &v, int n);
858  extern template cvec zero_pad(const cvec &v, int n);
859  extern template ivec zero_pad(const ivec &v, int n);
860  extern template svec zero_pad(const svec &v, int n);
861  extern template bvec zero_pad(const bvec &v, int n);
862
863  extern template vec zero_pad(const vec &v);
864  extern template cvec zero_pad(const cvec &v);
865  extern template ivec zero_pad(const ivec &v);
866  extern template svec zero_pad(const svec &v);
867  extern template bvec zero_pad(const bvec &v);
868
869  extern template mat zero_pad(const mat &, int, int);
870  extern template cmat zero_pad(const cmat &, int, int);
871  extern template imat zero_pad(const imat &, int, int);
872  extern template smat zero_pad(const smat &, int, int);
873  extern template bmat zero_pad(const bmat &, int, int);
874
875  extern template vec sum(const mat &m, int dim);
876  extern template cvec sum(const cmat &m, int dim);
877  extern template svec sum(const smat &m, int dim);
878  extern template ivec sum(const imat &m, int dim);
879  extern template bvec sum(const bmat &m, int dim);
880
881  extern template double sumsum(const mat &X);
882  extern template std::complex<double> sumsum(const cmat &X);
883  extern template short sumsum(const smat &X);
884  extern template int sumsum(const imat &X);
885  extern template bin sumsum(const bmat &X);
886
887  extern template vec sum_sqr(const mat & m, int dim);
888  extern template cvec sum_sqr(const cmat &m, int dim);
889  extern template svec sum_sqr(const smat &m, int dim);
890  extern template ivec sum_sqr(const imat &m, int dim);
891  extern template bvec sum_sqr(const bmat &m, int dim);
892
893  extern template mat cumsum(const mat &m, int dim);
894  extern template cmat cumsum(const cmat &m, int dim);
895  extern template smat cumsum(const smat &m, int dim);
896  extern template imat cumsum(const imat &m, int dim);
897  extern template bmat cumsum(const bmat &m, int dim);
898
899  extern template vec prod(const mat &m, int dim);
900  extern template cvec prod(const cmat &v, int dim);
901  extern template svec prod(const smat &m, int dim);
902  extern template ivec prod(const imat &m, int dim);
903  extern template bvec prod(const bmat &m, int dim);
904
905  extern template vec diag(const mat &in);
906  extern template cvec diag(const cmat &in);
907  extern template void diag(const vec &in, mat &m);
908  extern template void diag(const cvec &in, cmat &m);
909  extern template mat diag(const vec &v, const int K);
910  extern template cmat diag(const cvec &v, const int K);
911
912  extern template mat bidiag(const vec &, const vec &);
913  extern template cmat bidiag(const cvec &, const cvec &);
914  extern template void bidiag(const vec &, const vec &, mat &);
915  extern template void bidiag(const cvec &, const cvec &, cmat &);
916  extern template void bidiag(const mat &, vec &, vec &);
917  extern template void bidiag(const cmat &, cvec &, cvec &);
918
919  extern template mat tridiag(const vec &main, const vec &, const vec &);
920  extern template cmat tridiag(const cvec &main, const cvec &, const cvec &);
921  extern template void tridiag(const vec &main, const vec &, const vec &, mat &);
922  extern template void tridiag(const cvec &main, const cvec &, const cvec &, cmat &);
923  extern template void tridiag(const mat &m, vec &, vec &, vec &);
924  extern template void tridiag(const cmat &m, cvec &, cvec &, cvec &);
925
926  extern template double trace(const mat &in);
927  extern template std::complex<double> trace(const cmat &in);
928  extern template short trace(const smat &in);
929  extern template int trace(const imat &in);
930  extern template bin trace(const bmat &in);
931
932  extern template void transpose(const mat &m, mat &out);
933  extern template void transpose(const cmat &m, cmat &out);
934  extern template void transpose(const smat &m, smat &out);
935  extern template void transpose(const imat &m, imat &out);
936  extern template void transpose(const bmat &m, bmat &out);
937
938  extern template mat transpose(const mat &m);
939  extern template cmat transpose(const cmat &m);
940  extern template smat transpose(const smat &m);
941  extern template imat transpose(const imat &m);
942  extern template bmat transpose(const bmat &m);
943
944  extern template void hermitian_transpose(const mat &m, mat &out);
945  extern template void hermitian_transpose(const cmat &m, cmat &out);
946  extern template void hermitian_transpose(const smat &m, smat &out);
947  extern template void hermitian_transpose(const imat &m, imat &out);
948  extern template void hermitian_transpose(const bmat &m, bmat &out);
949
950  extern template mat hermitian_transpose(const mat &m);
951  extern template cmat hermitian_transpose(const cmat &m);
952  extern template smat hermitian_transpose(const smat &m);
953  extern template imat hermitian_transpose(const imat &m);
954  extern template bmat hermitian_transpose(const bmat &m);
955
956  extern template bool is_hermitian(const mat &X);
957  extern template bool is_hermitian(const cmat &X);
958
959  extern template bool is_unitary(const mat &X);
960  extern template bool is_unitary(const cmat &X);
961
962  extern template vec rvectorize(const mat &m);
963  extern template cvec rvectorize(const cmat &m);
964  extern template ivec rvectorize(const imat &m);
965  extern template svec rvectorize(const smat &m);
966  extern template bvec rvectorize(const bmat &m);
967
968  extern template vec cvectorize(const mat &m);
969  extern template cvec cvectorize(const cmat &m);
970  extern template ivec cvectorize(const imat &m);
971  extern template svec cvectorize(const smat &m);
972  extern template bvec cvectorize(const bmat &m);
973
974  extern template mat reshape(const mat &m, int rows, int cols);
975  extern template cmat reshape(const cmat &m, int rows, int cols);
976  extern template imat reshape(const imat &m, int rows, int cols);
977  extern template smat reshape(const smat &m, int rows, int cols);
978  extern template bmat reshape(const bmat &m, int rows, int cols);
979
980  extern template mat reshape(const vec &m, int rows, int cols);
981  extern template cmat reshape(const cvec &m, int rows, int cols);
982  extern template imat reshape(const ivec &m, int rows, int cols);
983  extern template smat reshape(const svec &m, int rows, int cols);
984  extern template bmat reshape(const bvec &m, int rows, int cols);
985
986  extern template mat kron(const mat &X, const mat &Y);
987  extern template cmat kron(const cmat &X, const cmat &Y);
988  extern template imat kron(const imat &X, const imat &Y);
989  extern template smat kron(const smat &X, const smat &Y);
990  extern template bmat kron(const bmat &X, const bmat &Y);
991
992  extern template vec repmat(const vec &v, int n);
993  extern template cvec repmat(const cvec &v, int n);
994  extern template ivec repmat(const ivec &v, int n);
995  extern template svec repmat(const svec &v, int n);
996  extern template bvec repmat(const bvec &v, int n);
997
998  extern template mat repmat(const vec &v, int m, int n, bool transpose);
999  extern template cmat repmat(const cvec &v, int m, int n, bool transpose);
1000  extern template imat repmat(const ivec &v, int m, int n, bool transpose);
1001  extern template smat repmat(const svec &v, int m, int n, bool transpose);
1002  extern template bmat repmat(const bvec &v, int m, int n, bool transpose);
1003
1004  extern template mat repmat(const mat &data, int m, int n);
1005  extern template cmat repmat(const cmat &data, int m, int n);
1006  extern template imat repmat(const imat &data, int m, int n);
1007  extern template smat repmat(const smat &data, int m, int n);
1008  extern template bmat repmat(const bmat &data, int m, int n);
1009
1010#endif // HAVE_EXTERN_TEMPLATE
1011
1012  //! \endcond
1013
1014} // namespace itpp
1015
1016#endif // #ifndef MATFUNC_H
Note: See TracBrowser for help on using the browser.