bool schur(const cmat &A, cmat &U, cmat &T) { it_assert_debug(A.rows() == A.cols(), "schur(): Matrix is not square"); char jobvs = 'V'; char sort = 'N'; int info; int n = A.rows(); int lda = n; int ldvs = n; int lwork = 2 * n; // This may be choosen better! int sdim = 0; vec rwork(n); cvec w(n); cvec work(lwork); T.set_size(lda, n, false); U.set_size(ldvs, n, false); T = A; // The routine overwrites input matrix with eigenvectors zgees_(&jobvs, &sort, 0, &n, T._data(), &lda, &sdim, w._data(), U._data(), &ldvs, work._data(), &lwork, rwork._data(), 0, &info); return (info == 0); }
cmat operator-(const double &s, const cmat &m) { it_assert_debug(m.rows() > 0 && m.cols() > 0, "operator-(): Matrix of zero length"); cmat temp(m.rows(), m.cols()); for (int i = 0;i < m._datasize();i++) { temp._data()[i] = std::complex<double>((double)s - m(i).real(), -m(i).imag()); } return temp; }
static void assert_cmat(const cmat &ref, const cmat &act) { ASSERT_EQ(ref.rows(), act.rows()); ASSERT_EQ(ref.cols(), act.cols()); for (int n = 0; n < ref.rows(); ++n) { for (int k = 0; k < ref.cols(); ++k) { ASSERT_NEAR(ref(n,k).real(), act(n,k).real(), tol); ASSERT_NEAR(ref(n,k).imag(), act(n,k).imag(), tol); } } }
bool qr(const cmat &A, cmat &R) { int info; int m = A.rows(); int n = A.cols(); int lwork = n; int k = std::min(m, n); cvec tau(k); cvec work(lwork); R = A; // perform workspace query for optimum lwork value int lwork_tmp = -1; zgeqrf_(&m, &n, R._data(), &m, tau._data(), work._data(), &lwork_tmp, &info); if (info == 0) { lwork = static_cast<int>(real(work(0))); work.set_size(lwork, false); } zgeqrf_(&m, &n, R._data(), &m, tau._data(), work._data(), &lwork, &info); // construct R for (int i = 0; i < m; i++) for (int j = 0; j < std::min(i, n); j++) R(i, j) = 0; return (info == 0); }
cmat operator/(const cmat &m, const double &s) { it_assert_debug(m.rows() > 0 && m.cols() > 0, "operator/(): Matrix of zero length"); cmat temp = m; for (int i = 0;i < m._datasize();i++) { temp._data()[i] /= (double)s; } return temp; }
// Perform LTE ratematching for convolutionally encoded bits d to fit // an e vector of length n_e. cvec lte_conv_ratematch( const cmat & d, const uint32 & n_e ) { const uint8 n_c=32; const uint32 n_r=ceil((double)d.cols()/n_c); ASSERT(d.rows()==3); // Subblock interleaving const static int perm_pattern_c[]={1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31,0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30}; const ivec perm_pattern(perm_pattern_c,32); cmat v(3,n_r*n_c); #ifndef NDEBUG v=NAN; #endif for (uint8 t=0;t<3;t++) { cvec temp_row=d.get_row(t); cvec temp_nan(n_r*n_c-d.cols()); temp_nan=NAN; temp_row=concat(temp_nan,temp_row); cmat y=transpose(reshape(temp_row,n_c,n_r)); // Permute the columns cmat y_perm(n_r,n_c); #ifndef NDEBUG y_perm=NAN; #endif for (uint8 k=0;k<32;k++) { y_perm.set_col(k,y.get_col(perm_pattern(k))); } // Assign v.set_row(t,cvectorize(y_perm)); } // Bit collection cvec w=cvectorize(transpose(v)); // Selection cvec e(n_e); #ifndef NDEBUG e=NAN; #endif uint32 k=0; uint32 j=0; while (k<n_e) { if (isfinite(w(j).real())) { e(k)=w(j); k++; } j=mod(j+1,3*n_r*n_c); } return e; }
cmat operator+(const mat &a, const cmat &b) { it_assert_debug(a.cols() == b.cols() && a.rows() == b.rows(), "operator+(): sizes does not match"); cmat temp(b); for (int i = 0;i < a.rows();i++) { for (int j = 0;j < a.cols();j++) { temp(i, j) += std::complex<double>(static_cast<double>(a(i, j)), 0.0); } } return temp; }
cmat operator+(const smat &a, const cmat &b) { it_assert_debug(a.cols() == b.cols() && a.rows() == b.rows(), "operator+(): sizes does not match"); cmat temp(b); for (int i = 0;i < a.rows();i++) { for (int j = 0;j < a.cols();j++) { temp(i, j) += (double)a(i, j); } } return temp; }
bool qr(const cmat &A, cmat &Q, cmat &R, bmat &P) { int info; int m = A.rows(); int n = A.cols(); int lwork = n; int k = std::min(m, n); cvec tau(k); cvec work(lwork); vec rwork(std::max(1, 2*n)); ivec jpvt(n); jpvt.zeros(); R = A; // perform workspace query for optimum lwork value int lwork_tmp = -1; zgeqp3_(&m, &n, R._data(), &m, jpvt._data(), tau._data(), work._data(), &lwork_tmp, rwork._data(), &info); if (info == 0) { lwork = static_cast<int>(real(work(0))); work.set_size(lwork, false); } zgeqp3_(&m, &n, R._data(), &m, jpvt._data(), tau._data(), work._data(), &lwork, rwork._data(), &info); Q = R; Q.set_size(m, m, true); // construct permutation matrix P = zeros_b(n, n); for (int j = 0; j < n; j++) P(jpvt(j) - 1, j) = 1; // construct R for (int i = 0; i < m; i++) for (int j = 0; j < std::min(i, n); j++) R(i, j) = 0; // perform workspace query for optimum lwork value lwork_tmp = -1; zungqr_(&m, &m, &k, Q._data(), &m, tau._data(), work._data(), &lwork_tmp, &info); if (info == 0) { lwork = static_cast<int>(real(work(0))); work.set_size(lwork, false); } zungqr_(&m, &m, &k, Q._data(), &m, tau._data(), work._data(), &lwork, &info); return (info == 0); }
bool inv(const cmat &X, cmat &Y) { // it_assert1(X.rows() == X.cols(), "inv: matrix is not square"); int m = X.rows(), info, lwork; lwork = m; // may be choosen better ivec p(m); Y = X; cvec work(lwork); zgetrf_(&m, &m, Y._data(), &m, p._data(), &info); // LU-factorization if (info!=0) return false; zgetri_(&m, Y._data(), &m, p._data(), work._data(), &lwork, &info); return (info==0); }
void Matlab_Engine::put(const cmat &m, const char *name){ const int rows = m.rows(); const int cols = m.cols(); mxArray *T; if((T = mxCreateDoubleMatrix(rows, cols, mxCOMPLEX)) == NULL) cout << "Unable to allocate Matlab matrix. Out of memory?\n"; mxSetName(T, name); double *pt_r = (double*) mxGetPr(T); double *pt_i = (double*) mxGetPi(T); for(int row=0; row<rows; row++){ for(int col=0; col<cols; col++){ *pt_r++ = real(m(row, col)); *pt_i++ = imag(m(row, col)); } } if(engPutArray(e, T)) cout << "Unable to put it++ matrix to Matlab workspace!\n"; }
bool svd(const cmat &A, vec &S) { char jobu='N', jobvt='N'; int m, n, lda, ldu, ldvt, lwork, info; m = lda = ldu = A.rows(); n = ldvt = A.cols(); lwork = 2*min(m,n)+max(m,n); cvec U, V; //U.set_size(m,m, false); //V.set_size(n,n, false); S.set_size(min(m,n), false); cvec work(lwork); vec rwork(max(1, 5*min(m, n))); cmat B(A); zgesvd_(&jobu, &jobvt, &m, &n, B._data(), &lda, S._data(), U._data(), &ldu, V._data(), &ldvt, work._data(), &lwork, rwork._data(), &info); return (info==0); }
bool svd(const cmat &A, cmat &U, vec &S, cmat &V) { char jobu='A', jobvt='A'; int m, n, lda, ldu, ldvt, lwork, info; m = lda = ldu = A.rows(); n = ldvt = A.cols(); lwork = 2*min(m,n)+max(m,n); U.set_size(m,m, false); V.set_size(n,n, false); S.set_size(min(m,n), false); cvec work(lwork); vec rwork(max(1, 5*min(m, n))); cmat B(A); zgesvd_(&jobu, &jobvt, &m, &n, B._data(), &lda, S._data(), U._data(), &ldu, V._data(), &ldvt, work._data(), &lwork, rwork._data(), &info); V = transpose(conj(V)); // This is slow!!! return (info==0); }
/* Determinant of complex square matrix. Calculate determinant of inmatrix (Uses LU-factorisation) (See Theorem 3.2.1 p. 97 in Golub & van Loan, "Matrix Computations"). det(X) = det(P')*det(L)*det(U) = det(P')*1*prod(diag(U)) Needs LU-factorization of complex matrices (LAPACK) */ double_complex det(const cmat &X) { // it_assert1(X.rows()==X.cols(),"det : Only square matrices"); int i; cmat L, U; ivec p; double s=1.0; lu(X,L,U,p); // calculate LU-factorisation double_complex temp=U(0,0); for (i=1;i<X.rows();i++) { temp*=U(i,i); } // Calculate det(P´). Equal to (-1)^(no row changes) for (i=0; i<p.size(); i++) if (i != p(i)) s *=-1.0; return temp*s; }
void DiagonalResponse::solve(cmat& res, const cmat& M) const { // TODO make sure this is optimal assert( diag.size() == M.rows() ); assert( &res != &M ); res = (M.transpose() * diag.asDiagonal() ).transpose(); }