00001
00030 #ifndef MATFUNC_H
00031 #define MATFUNC_H
00032
00033 #include <itpp/base/mat.h>
00034 #include <itpp/base/math/log_exp.h>
00035 #include <itpp/base/math/elem_math.h>
00036 #include <itpp/base/algebra/inv.h>
00037 #include <itpp/base/algebra/svd.h>
00038
00039
00040 namespace itpp
00041 {
00042
00047
00048
00050 template<class T>
00051 int length(const Vec<T> &v) { return v.length(); }
00052
00054 template<class T>
00055 int size(const Vec<T> &v) { return v.length(); }
00056
00058 template<class T>
00059 T sum(const Vec<T> &v)
00060 {
00061 T M = 0;
00062
00063 for (int i = 0;i < v.length();i++)
00064 M += v[i];
00065
00066 return M;
00067 }
00068
00076 template<class T>
00077 Vec<T> sum(const Mat<T> &m, int dim = 1)
00078 {
00079 it_assert((dim == 1) || (dim == 2), "sum: dimension need to be 1 or 2");
00080 Vec<T> out;
00081
00082 if (dim == 1) {
00083 out.set_size(m.cols(), false);
00084
00085 for (int i = 0; i < m.cols(); i++)
00086 out(i) = sum(m.get_col(i));
00087 }
00088 else {
00089 out.set_size(m.rows(), false);
00090
00091 for (int i = 0; i < m.rows(); i++)
00092 out(i) = sum(m.get_row(i));
00093 }
00094
00095 return out;
00096 }
00097
00098
00100 template<class T>
00101 T sumsum(const Mat<T> &X)
00102 {
00103 const T * X_data = X._data();
00104 const int X_datasize = X._datasize();
00105 T acc = 0;
00106
00107 for (int i = 0;i < X_datasize;i++)
00108 acc += X_data[i];
00109
00110 return acc;
00111 }
00112
00113
00115 template<class T>
00116 T sum_sqr(const Vec<T> &v)
00117 {
00118 T M = 0;
00119
00120 for (int i = 0; i < v.length(); i++)
00121 M += v[i] * v[i];
00122
00123 return M;
00124 }
00125
00133 template<class T>
00134 Vec<T> sum_sqr(const Mat<T> &m, int dim = 1)
00135 {
00136 it_assert((dim == 1) || (dim == 2), "sum_sqr: dimension need to be 1 or 2");
00137 Vec<T> out;
00138
00139 if (dim == 1) {
00140 out.set_size(m.cols(), false);
00141
00142 for (int i = 0; i < m.cols(); i++)
00143 out(i) = sum_sqr(m.get_col(i));
00144 }
00145 else {
00146 out.set_size(m.rows(), false);
00147
00148 for (int i = 0; i < m.rows(); i++)
00149 out(i) = sum_sqr(m.get_row(i));
00150 }
00151
00152 return out;
00153 }
00154
00156 template<class T>
00157 Vec<T> cumsum(const Vec<T> &v)
00158 {
00159 Vec<T> out(v.size());
00160
00161 out(0) = v(0);
00162 for (int i = 1; i < v.size(); i++)
00163 out(i) = out(i - 1) + v(i);
00164
00165 return out;
00166 }
00167
00175 template<class T>
00176 Mat<T> cumsum(const Mat<T> &m, int dim = 1)
00177 {
00178 it_assert((dim == 1) || (dim == 2), "cumsum: dimension need to be 1 or 2");
00179 Mat<T> out(m.rows(), m.cols());
00180
00181 if (dim == 1) {
00182 for (int i = 0; i < m.cols(); i++)
00183 out.set_col(i, cumsum(m.get_col(i)));
00184 }
00185 else {
00186 for (int i = 0; i < m.rows(); i++)
00187 out.set_row(i, cumsum(m.get_row(i)));
00188 }
00189
00190 return out;
00191 }
00192
00194 template<class T>
00195 T prod(const Vec<T> &v)
00196 {
00197 it_assert(v.size() >= 1, "prod: size of vector should be at least 1");
00198 T out = v(0);
00199
00200 for (int i = 1; i < v.size(); i++)
00201 out *= v(i);
00202
00203 return out;
00204 }
00205
00213 template<class T>
00214 Vec<T> prod(const Mat<T> &m, int dim = 1)
00215 {
00216 it_assert((dim == 1) || (dim == 2), "prod: dimension need to be 1 or 2");
00217 Vec<T> out(m.cols());
00218
00219 if (dim == 1) {
00220 it_assert((m.cols() >= 1) && (m.rows() >= 1),
00221 "prod: number of columns should be at least 1");
00222 out.set_size(m.cols(), false);
00223
00224 for (int i = 0; i < m.cols(); i++)
00225 out(i) = prod(m.get_col(i));
00226 }
00227 else {
00228 it_assert((m.cols() >= 1) && (m.rows() >= 1),
00229 "prod: number of rows should be at least 1");
00230 out.set_size(m.rows(), false);
00231
00232 for (int i = 0; i < m.rows(); i++)
00233 out(i) = prod(m.get_row(i));
00234 }
00235 return out;
00236 }
00237
00239 template<class T>
00240 Vec<T> cross(const Vec<T> &v1, const Vec<T> &v2)
00241 {
00242 it_assert((v1.size() == 3) && (v2.size() == 3),
00243 "cross: vectors should be of size 3");
00244
00245 Vec<T> r(3);
00246
00247 r(0) = v1(1) * v2(2) - v1(2) * v2(1);
00248 r(1) = v1(2) * v2(0) - v1(0) * v2(2);
00249 r(2) = v1(0) * v2(1) - v1(1) * v2(0);
00250
00251 return r;
00252 }
00253
00254
00256 template<class T>
00257 Vec<T> zero_pad(const Vec<T> &v, int n)
00258 {
00259 it_assert(n >= v.size(), "zero_pad() cannot shrink the vector!");
00260 Vec<T> v2(n);
00261 v2.set_subvector(0, v);
00262 if (n > v.size())
00263 v2.set_subvector(v.size(), n - 1, T(0));
00264
00265 return v2;
00266 }
00267
00269 template<class T>
00270 Vec<T> zero_pad(const Vec<T> &v)
00271 {
00272 int n = pow2i(levels2bits(v.size()));
00273
00274 return (n == v.size()) ? v : zero_pad(v, n);
00275 }
00276
00278 template<class T>
00279 Mat<T> zero_pad(const Mat<T> &m, int rows, int cols)
00280 {
00281 it_assert((rows >= m.rows()) && (cols >= m.cols()),
00282 "zero_pad() cannot shrink the matrix!");
00283 Mat<T> m2(rows, cols);
00284 m2.set_submatrix(0, 0, m);
00285 if (cols > m.cols())
00286 m2.set_submatrix(0, m.rows() - 1, m.cols(), cols - 1, T(0));
00287 if (rows > m.rows())
00288 m2.set_submatrix(m.rows(), rows - 1, 0, cols - 1, T(0));
00289
00290 return m2;
00291 }
00292
00293
00296 template<class T>
00297 T index_zero_pad(const Vec<T> &v, const int index)
00298 {
00299 if (index >= 0 && index < v.size())
00300 return v(index);
00301 else
00302 return T(0);
00303 }
00304
00305
00307 template<class T>
00308 void transpose(const Mat<T> &m, Mat<T> &out) { out = m.T(); }
00309
00311 template<class T>
00312 Mat<T> transpose(const Mat<T> &m) { return m.T(); }
00313
00314
00317 template<class T>
00318 void hermitian_transpose(const Mat<T> &m, Mat<T> &out) { out = m.H(); }
00319
00321 template<class T>
00322 Mat<T> hermitian_transpose(const Mat<T> &m) { return m.H(); }
00323
00324
00325
00335 template<class Num_T>
00336 bool is_hermitian(const Mat<Num_T>& X)
00337 {
00338
00339 if (X == X.H())
00340 return true;
00341 else
00342 return false;
00343 }
00344
00354 template<class Num_T>
00355 bool is_unitary(const Mat<Num_T>& X)
00356 {
00357
00358 if (inv(X) == X.H())
00359 return true;
00360 else
00361 return false;
00362 }
00363
00364
00373 template<class T>
00374 Vec<T> repmat(const Vec<T> &v, int n)
00375 {
00376 it_assert(n > 0, "repmat(): Wrong repetition parameter");
00377 int data_length = v.length();
00378 it_assert(data_length > 0, "repmat(): Input vector can not be empty");
00379 Vec<T> assembly(data_length * n);
00380 for (int j = 0; j < n; ++j) {
00381 assembly.set_subvector(j * data_length, v);
00382 }
00383 return assembly;
00384 }
00385
00386
00396 template<class T>
00397 Mat<T> repmat(const Mat<T> &data, int m, int n)
00398 {
00399 it_assert((m > 0) && (n > 0), "repmat(): Wrong repetition parameters");
00400 int data_rows = data.rows();
00401 int data_cols = data.cols();
00402 it_assert((data_rows > 0) && (data_cols > 0), "repmat(): Input matrix can "
00403 "not be empty");
00404 Mat<T> assembly(data_rows*m, data_cols*n);
00405 for (int i = 0; i < m; ++i) {
00406 for (int j = 0; j < n; ++j) {
00407 assembly.set_submatrix(i*data_rows, j*data_cols, data);
00408 }
00409 }
00410 return assembly;
00411 }
00412
00424 template<class T> inline
00425 Mat<T> repmat(const Vec<T> &v, int m, int n, bool transpose = false)
00426 {
00427 return repmat((transpose ? v.T() : Mat<T>(v)), m, n);
00428 }
00429
00430
00442 template<class Num_T>
00443 Mat<Num_T> kron(const Mat<Num_T>& X, const Mat<Num_T>& Y)
00444 {
00445 Mat<Num_T> result(X.rows() * Y.rows(), X.cols() * Y.cols());
00446
00447 for (int i = 0; i < X.rows(); i++)
00448 for (int j = 0; j < X.cols(); j++)
00449 result.set_submatrix(i * Y.rows(), j * Y.cols(), X(i, j) * Y);
00450
00451 return result;
00452 }
00453
00454
00467 cmat sqrtm(const cmat& A);
00468
00481 cmat sqrtm(const mat& A);
00482
00483
00492 template<class T>
00493 int rank(const Mat<T> &m, double tol = -1.0)
00494 {
00495 int rows = m.rows();
00496 int cols = m.cols();
00497 if ((rows == 0) || (cols == 0))
00498 return 0;
00499
00500 vec sing_val = svd(m);
00501
00502 if (tol < 0.0) {
00503 tol = eps * sing_val(0) * (rows > cols ? rows : cols);
00504 }
00505
00506
00507 int r = 0;
00508 while ((r < sing_val.length()) && (sing_val(r) > tol)) {
00509 r++;
00510 }
00511
00512 return r;
00513 }
00514
00516 template<> inline
00517 int rank(const imat &m, double tol)
00518 {
00519 return rank(to_mat(m), tol);
00520 }
00521
00523 template<> inline
00524 int rank(const smat &m, double tol)
00525 {
00526 return rank(to_mat(m), tol);
00527 }
00528
00530 template<> inline
00531 int rank(const bmat &, double)
00532 {
00533 it_error("rank(bmat): Function not implemented for GF(2) algebra");
00534 return 0;
00535 }
00536
00538
00539
00540
00541
00542
00545
00556 template<class T>
00557 Mat<T> diag(const Vec<T> &v, const int K = 0)
00558 {
00559 Mat<T> m(v.size() + std::abs(K), v.size() + std::abs(K));
00560 m = T(0);
00561 if (K > 0)
00562 for (int i = v.size() - 1; i >= 0; i--)
00563 m(i, i + K) = v(i);
00564 else
00565 for (int i = v.size() - 1; i >= 0; i--)
00566 m(i - K, i) = v(i);
00567
00568 return m;
00569 }
00570
00580 template<class T>
00581 void diag(const Vec<T> &v, Mat<T> &m)
00582 {
00583 m.set_size(v.size(), v.size(), false);
00584 m = T(0);
00585 for (int i = v.size() - 1; i >= 0; i--)
00586 m(i, i) = v(i);
00587 }
00588
00596 template<class T>
00597 Vec<T> diag(const Mat<T> &m)
00598 {
00599 Vec<T> t(std::min(m.rows(), m.cols()));
00600
00601 for (int i = 0; i < t.size(); i++)
00602 t(i) = m(i, i);
00603
00604 return t;
00605 }
00606
00616 template<class T>
00617 Mat<T> bidiag(const Vec<T> &main, const Vec<T> &sup)
00618 {
00619 it_assert(main.size() == sup.size() + 1, "bidiag()");
00620
00621 int n = main.size();
00622 Mat<T> m(n, n);
00623 m = T(0);
00624 for (int i = 0; i < n - 1; i++) {
00625 m(i, i) = main(i);
00626 m(i, i + 1) = sup(i);
00627 }
00628 m(n - 1, n - 1) = main(n - 1);
00629
00630 return m;
00631 }
00632
00642 template<class T>
00643 void bidiag(const Vec<T> &main, const Vec<T> &sup, Mat<T> &m)
00644 {
00645 it_assert(main.size() == sup.size() + 1, "bidiag()");
00646
00647 int n = main.size();
00648 m.set_size(n, n);
00649 m = T(0);
00650 for (int i = 0; i < n - 1; i++) {
00651 m(i, i) = main(i);
00652 m(i, i + 1) = sup(i);
00653 }
00654 m(n - 1, n - 1) = main(n - 1);
00655 }
00656
00665 template<class T>
00666 void bidiag(const Mat<T> &m, Vec<T> &main, Vec<T> &sup)
00667 {
00668 it_assert(m.rows() == m.cols(), "bidiag(): Matrix must be square!");
00669
00670 int n = m.cols();
00671 main.set_size(n);
00672 sup.set_size(n - 1);
00673 for (int i = 0; i < n - 1; i++) {
00674 main(i) = m(i, i);
00675 sup(i) = m(i, i + 1);
00676 }
00677 main(n - 1) = m(n - 1, n - 1);
00678 }
00679
00689 template<class T>
00690 Mat<T> tridiag(const Vec<T> &main, const Vec<T> &sup, const Vec<T> &sub)
00691 {
00692 it_assert(main.size() == sup.size() + 1 && main.size() == sub.size() + 1, "bidiag()");
00693
00694 int n = main.size();
00695 Mat<T> m(n, n);
00696 m = T(0);
00697 for (int i = 0; i < n - 1; i++) {
00698 m(i, i) = main(i);
00699 m(i, i + 1) = sup(i);
00700 m(i + 1, i) = sub(i);
00701 }
00702 m(n - 1, n - 1) = main(n - 1);
00703
00704 return m;
00705 }
00706
00716 template<class T>
00717 void tridiag(const Vec<T> &main, const Vec<T> &sup, const Vec<T> &sub, Mat<T> &m)
00718 {
00719 it_assert(main.size() == sup.size() + 1 && main.size() == sub.size() + 1, "bidiag()");
00720
00721 int n = main.size();
00722 m.set_size(n, n);
00723 m = T(0);
00724 for (int i = 0; i < n - 1; i++) {
00725 m(i, i) = main(i);
00726 m(i, i + 1) = sup(i);
00727 m(i + 1, i) = sub(i);
00728 }
00729 m(n - 1, n - 1) = main(n - 1);
00730 }
00731
00740 template<class T>
00741 void tridiag(const Mat<T> &m, Vec<T> &main, Vec<T> &sup, Vec<T> &sub)
00742 {
00743 it_assert(m.rows() == m.cols(), "tridiag(): Matrix must be square!");
00744
00745 int n = m.cols();
00746 main.set_size(n);
00747 sup.set_size(n - 1);
00748 sub.set_size(n - 1);
00749 for (int i = 0; i < n - 1; i++) {
00750 main(i) = m(i, i);
00751 sup(i) = m(i, i + 1);
00752 sub(i) = m(i + 1, i);
00753 }
00754 main(n - 1) = m(n - 1, n - 1);
00755 }
00756
00757
00761 template<class T>
00762 T trace(const Mat<T> &m)
00763 {
00764 return sum(diag(m));
00765 }
00766
00768
00769
00770
00771
00774
00776 template<class T>
00777 Vec<T> reverse(const Vec<T> &in)
00778 {
00779 int i, s = in.length();
00780
00781 Vec<T> out(s);
00782 for (i = 0;i < s;i++)
00783 out[i] = in[s-1-i];
00784 return out;
00785 }
00786
00788 template<class T>
00789 Vec<T> rvectorize(const Mat<T> &m)
00790 {
00791 int i, j, n = 0, r = m.rows(), c = m.cols();
00792 Vec<T> v(r * c);
00793
00794 for (i = 0; i < r; i++)
00795 for (j = 0; j < c; j++)
00796 v(n++) = m(i, j);
00797
00798 return v;
00799 }
00800
00802 template<class T>
00803 Vec<T> cvectorize(const Mat<T> &m)
00804 {
00805 int i, j, n = 0, r = m.rows(), c = m.cols();
00806 Vec<T> v(r * c);
00807
00808 for (j = 0; j < c; j++)
00809 for (i = 0; i < r; i++)
00810 v(n++) = m(i, j);
00811
00812 return v;
00813 }
00814
00821 template<class T>
00822 Mat<T> reshape(const Mat<T> &m, int rows, int cols)
00823 {
00824 it_assert_debug(m.rows()*m.cols() == rows*cols, "Mat<T>::reshape: Sizes must match");
00825 Mat<T> temp(rows, cols);
00826 int i, j, ii = 0, jj = 0;
00827 for (j = 0; j < m.cols(); j++) {
00828 for (i = 0; i < m.rows(); i++) {
00829 temp(ii++, jj) = m(i, j);
00830 if (ii == rows) {
00831 jj++;
00832 ii = 0;
00833 }
00834 }
00835 }
00836 return temp;
00837 }
00838
00845 template<class T>
00846 Mat<T> reshape(const Vec<T> &v, int rows, int cols)
00847 {
00848 it_assert_debug(v.size() == rows*cols, "Mat<T>::reshape: Sizes must match");
00849 Mat<T> temp(rows, cols);
00850 int i, j, ii = 0;
00851 for (j = 0; j < cols; j++) {
00852 for (i = 0; i < rows; i++) {
00853 temp(i, j) = v(ii++);
00854 }
00855 }
00856 return temp;
00857 }
00858
00860
00861
00863 bool all(const bvec &testvec);
00865 bool any(const bvec &testvec);
00866
00868
00869
00870
00871
00872
00873 #ifdef HAVE_EXTERN_TEMPLATE
00874
00875 extern template int length(const vec &v);
00876 extern template int length(const cvec &v);
00877 extern template int length(const svec &v);
00878 extern template int length(const ivec &v);
00879 extern template int length(const bvec &v);
00880
00881 extern template double sum(const vec &v);
00882 extern template std::complex<double> sum(const cvec &v);
00883 extern template short sum(const svec &v);
00884 extern template int sum(const ivec &v);
00885 extern template bin sum(const bvec &v);
00886
00887 extern template double sum_sqr(const vec &v);
00888 extern template std::complex<double> sum_sqr(const cvec &v);
00889 extern template short sum_sqr(const svec &v);
00890 extern template int sum_sqr(const ivec &v);
00891 extern template bin sum_sqr(const bvec &v);
00892
00893 extern template vec cumsum(const vec &v);
00894 extern template cvec cumsum(const cvec &v);
00895 extern template svec cumsum(const svec &v);
00896 extern template ivec cumsum(const ivec &v);
00897 extern template bvec cumsum(const bvec &v);
00898
00899 extern template double prod(const vec &v);
00900 extern template std::complex<double> prod(const cvec &v);
00901 extern template short prod(const svec &v);
00902 extern template int prod(const ivec &v);
00903 extern template bin prod(const bvec &v);
00904
00905 extern template vec cross(const vec &v1, const vec &v2);
00906 extern template cvec cross(const cvec &v1, const cvec &v2);
00907 extern template ivec cross(const ivec &v1, const ivec &v2);
00908 extern template svec cross(const svec &v1, const svec &v2);
00909 extern template bvec cross(const bvec &v1, const bvec &v2);
00910
00911 extern template vec reverse(const vec &in);
00912 extern template cvec reverse(const cvec &in);
00913 extern template svec reverse(const svec &in);
00914 extern template ivec reverse(const ivec &in);
00915 extern template bvec reverse(const bvec &in);
00916
00917 extern template vec zero_pad(const vec &v, int n);
00918 extern template cvec zero_pad(const cvec &v, int n);
00919 extern template ivec zero_pad(const ivec &v, int n);
00920 extern template svec zero_pad(const svec &v, int n);
00921 extern template bvec zero_pad(const bvec &v, int n);
00922
00923 extern template vec zero_pad(const vec &v);
00924 extern template cvec zero_pad(const cvec &v);
00925 extern template ivec zero_pad(const ivec &v);
00926 extern template svec zero_pad(const svec &v);
00927 extern template bvec zero_pad(const bvec &v);
00928
00929 extern template mat zero_pad(const mat &, int, int);
00930 extern template cmat zero_pad(const cmat &, int, int);
00931 extern template imat zero_pad(const imat &, int, int);
00932 extern template smat zero_pad(const smat &, int, int);
00933 extern template bmat zero_pad(const bmat &, int, int);
00934
00935 extern template vec sum(const mat &m, int dim);
00936 extern template cvec sum(const cmat &m, int dim);
00937 extern template svec sum(const smat &m, int dim);
00938 extern template ivec sum(const imat &m, int dim);
00939 extern template bvec sum(const bmat &m, int dim);
00940
00941 extern template double sumsum(const mat &X);
00942 extern template std::complex<double> sumsum(const cmat &X);
00943 extern template short sumsum(const smat &X);
00944 extern template int sumsum(const imat &X);
00945 extern template bin sumsum(const bmat &X);
00946
00947 extern template vec sum_sqr(const mat & m, int dim);
00948 extern template cvec sum_sqr(const cmat &m, int dim);
00949 extern template svec sum_sqr(const smat &m, int dim);
00950 extern template ivec sum_sqr(const imat &m, int dim);
00951 extern template bvec sum_sqr(const bmat &m, int dim);
00952
00953 extern template mat cumsum(const mat &m, int dim);
00954 extern template cmat cumsum(const cmat &m, int dim);
00955 extern template smat cumsum(const smat &m, int dim);
00956 extern template imat cumsum(const imat &m, int dim);
00957 extern template bmat cumsum(const bmat &m, int dim);
00958
00959 extern template vec prod(const mat &m, int dim);
00960 extern template cvec prod(const cmat &v, int dim);
00961 extern template svec prod(const smat &m, int dim);
00962 extern template ivec prod(const imat &m, int dim);
00963 extern template bvec prod(const bmat &m, int dim);
00964
00965 extern template vec diag(const mat &in);
00966 extern template cvec diag(const cmat &in);
00967 extern template void diag(const vec &in, mat &m);
00968 extern template void diag(const cvec &in, cmat &m);
00969 extern template mat diag(const vec &v, const int K);
00970 extern template cmat diag(const cvec &v, const int K);
00971
00972 extern template mat bidiag(const vec &, const vec &);
00973 extern template cmat bidiag(const cvec &, const cvec &);
00974 extern template void bidiag(const vec &, const vec &, mat &);
00975 extern template void bidiag(const cvec &, const cvec &, cmat &);
00976 extern template void bidiag(const mat &, vec &, vec &);
00977 extern template void bidiag(const cmat &, cvec &, cvec &);
00978
00979 extern template mat tridiag(const vec &main, const vec &, const vec &);
00980 extern template cmat tridiag(const cvec &main, const cvec &, const cvec &);
00981 extern template void tridiag(const vec &main, const vec &, const vec &, mat &);
00982 extern template void tridiag(const cvec &main, const cvec &, const cvec &, cmat &);
00983 extern template void tridiag(const mat &m, vec &, vec &, vec &);
00984 extern template void tridiag(const cmat &m, cvec &, cvec &, cvec &);
00985
00986 extern template double trace(const mat &in);
00987 extern template std::complex<double> trace(const cmat &in);
00988 extern template short trace(const smat &in);
00989 extern template int trace(const imat &in);
00990 extern template bin trace(const bmat &in);
00991
00992 extern template void transpose(const mat &m, mat &out);
00993 extern template void transpose(const cmat &m, cmat &out);
00994 extern template void transpose(const smat &m, smat &out);
00995 extern template void transpose(const imat &m, imat &out);
00996 extern template void transpose(const bmat &m, bmat &out);
00997
00998 extern template mat transpose(const mat &m);
00999 extern template cmat transpose(const cmat &m);
01000 extern template smat transpose(const smat &m);
01001 extern template imat transpose(const imat &m);
01002 extern template bmat transpose(const bmat &m);
01003
01004 extern template void hermitian_transpose(const mat &m, mat &out);
01005 extern template void hermitian_transpose(const cmat &m, cmat &out);
01006 extern template void hermitian_transpose(const smat &m, smat &out);
01007 extern template void hermitian_transpose(const imat &m, imat &out);
01008 extern template void hermitian_transpose(const bmat &m, bmat &out);
01009
01010 extern template mat hermitian_transpose(const mat &m);
01011 extern template cmat hermitian_transpose(const cmat &m);
01012 extern template smat hermitian_transpose(const smat &m);
01013 extern template imat hermitian_transpose(const imat &m);
01014 extern template bmat hermitian_transpose(const bmat &m);
01015
01016 extern template bool is_hermitian(const mat &X);
01017 extern template bool is_hermitian(const cmat &X);
01018
01019 extern template bool is_unitary(const mat &X);
01020 extern template bool is_unitary(const cmat &X);
01021
01022 extern template vec rvectorize(const mat &m);
01023 extern template cvec rvectorize(const cmat &m);
01024 extern template ivec rvectorize(const imat &m);
01025 extern template svec rvectorize(const smat &m);
01026 extern template bvec rvectorize(const bmat &m);
01027
01028 extern template vec cvectorize(const mat &m);
01029 extern template cvec cvectorize(const cmat &m);
01030 extern template ivec cvectorize(const imat &m);
01031 extern template svec cvectorize(const smat &m);
01032 extern template bvec cvectorize(const bmat &m);
01033
01034 extern template mat reshape(const mat &m, int rows, int cols);
01035 extern template cmat reshape(const cmat &m, int rows, int cols);
01036 extern template imat reshape(const imat &m, int rows, int cols);
01037 extern template smat reshape(const smat &m, int rows, int cols);
01038 extern template bmat reshape(const bmat &m, int rows, int cols);
01039
01040 extern template mat reshape(const vec &m, int rows, int cols);
01041 extern template cmat reshape(const cvec &m, int rows, int cols);
01042 extern template imat reshape(const ivec &m, int rows, int cols);
01043 extern template smat reshape(const svec &m, int rows, int cols);
01044 extern template bmat reshape(const bvec &m, int rows, int cols);
01045
01046 extern template mat kron(const mat &X, const mat &Y);
01047 extern template cmat kron(const cmat &X, const cmat &Y);
01048 extern template imat kron(const imat &X, const imat &Y);
01049 extern template smat kron(const smat &X, const smat &Y);
01050 extern template bmat kron(const bmat &X, const bmat &Y);
01051
01052 extern template vec repmat(const vec &v, int n);
01053 extern template cvec repmat(const cvec &v, int n);
01054 extern template ivec repmat(const ivec &v, int n);
01055 extern template svec repmat(const svec &v, int n);
01056 extern template bvec repmat(const bvec &v, int n);
01057
01058 extern template mat repmat(const vec &v, int m, int n, bool transpose);
01059 extern template cmat repmat(const cvec &v, int m, int n, bool transpose);
01060 extern template imat repmat(const ivec &v, int m, int n, bool transpose);
01061 extern template smat repmat(const svec &v, int m, int n, bool transpose);
01062 extern template bmat repmat(const bvec &v, int m, int n, bool transpose);
01063
01064 extern template mat repmat(const mat &data, int m, int n);
01065 extern template cmat repmat(const cmat &data, int m, int n);
01066 extern template imat repmat(const imat &data, int m, int n);
01067 extern template smat repmat(const smat &data, int m, int n);
01068 extern template bmat repmat(const bmat &data, int m, int n);
01069
01070 #endif // HAVE_EXTERN_TEMPLATE
01071
01073
01074 }
01075
01076 #endif // #ifndef MATFUNC_H