void expm(gsl_matrix_complex * L, gsl_complex t, gsl_matrix * m) { int i,j,s; gsl_vector_complex *eval = gsl_vector_complex_alloc(4); gsl_matrix_complex *evec = gsl_matrix_complex_alloc(4, 4); gsl_eigen_nonsymmv_workspace * w = gsl_eigen_nonsymmv_alloc(4); gsl_matrix_complex *evalmat = gsl_matrix_complex_alloc(4, 4); gsl_matrix_complex *vd = gsl_matrix_complex_alloc(4, 4); gsl_complex one = gsl_complex_rect(1, 0); gsl_complex zero = gsl_complex_rect(0, 0); gsl_matrix_complex *K = gsl_matrix_complex_alloc(4, 4); gsl_permutation *p = gsl_permutation_alloc(4); gsl_vector_complex *x = gsl_vector_complex_alloc(4); gsl_vector_complex_view bp; gsl_complex z; gsl_eigen_nonsymmv(m, eval, evec, w); gsl_eigen_nonsymmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC); gsl_eigen_nonsymmv_free(w); // clear workspace for (i = 0; i < 4; i++) { gsl_complex eval_i = gsl_vector_complex_get(eval, i); gsl_complex expeval = gsl_complex_mul(eval_i,t); expeval = gsl_complex_exp(expeval); gsl_matrix_complex_set(evalmat, i, i, expeval); } gsl_vector_complex_free(eval); // clear vector for eigenvalues // v'L'=De'v' gsl_blas_zgemm(CblasTrans, CblasTrans, one, evalmat, evec, zero, vd); gsl_matrix_complex_transpose(evec);//transpose v gsl_matrix_complex_memcpy(K,evec); for (i = 0; i < 4; i++) { bp = gsl_matrix_complex_column(vd, i); gsl_linalg_complex_LU_decomp(evec, p, &s); gsl_linalg_complex_LU_solve(evec, p, &bp.vector, x); for (j = 0; j < 4; j++) { z = gsl_vector_complex_get(x, j); gsl_matrix_complex_set(L,i,j,z); //'through the looking glass' transpose } gsl_matrix_complex_memcpy(evec,K); } gsl_permutation_free(p); gsl_vector_complex_free(x); gsl_matrix_complex_free(vd); gsl_matrix_complex_free(evec); gsl_matrix_complex_free(evalmat); gsl_matrix_complex_free(K); }
static void genhermv_normalize_eigenvectors(gsl_matrix_complex *evec) { const size_t N = evec->size1; size_t i; /* looping */ for (i = 0; i < N; ++i) { gsl_vector_complex_view vi = gsl_matrix_complex_column(evec, i); double scale = 1.0 / gsl_blas_dznrm2(&vi.vector); gsl_blas_zdscal(scale, &vi.vector); } } /* genhermv_normalize_eigenvectors() */
int main (void) { double data[] = { -1.0, 1.0, -1.0, 1.0, -8.0, 4.0, -2.0, 1.0, 27.0, 9.0, 3.0, 1.0, 64.0, 16.0, 4.0, 1.0 }; gsl_matrix_view m = gsl_matrix_view_array (data, 4, 4); gsl_vector_complex *eval = gsl_vector_complex_alloc (4); gsl_matrix_complex *evec = gsl_matrix_complex_alloc (4, 4); gsl_eigen_nonsymmv_workspace * w = gsl_eigen_nonsymmv_alloc (4); gsl_eigen_nonsymmv (&m.matrix, eval, evec, w); gsl_eigen_nonsymmv_free (w); gsl_eigen_nonsymmv_sort (eval, evec, GSL_EIGEN_SORT_ABS_DESC); { int i, j; for (i = 0; i < 4; i++) { gsl_complex eval_i = gsl_vector_complex_get (eval, i); gsl_vector_complex_view evec_i = gsl_matrix_complex_column (evec, i); printf ("eigenvalue = %g + %gi\n", GSL_REAL(eval_i), GSL_IMAG(eval_i)); printf ("eigenvector = \n"); for (j = 0; j < 4; ++j) { gsl_complex z = gsl_vector_complex_get(&evec_i.vector, j); printf("%g + %gi\n", GSL_REAL(z), GSL_IMAG(z)); } } } gsl_vector_complex_free(eval); gsl_matrix_complex_free(evec); return 0; }
static void nonsymmv_normalize_eigenvectors(gsl_vector_complex *eval, gsl_matrix_complex *evec) { const size_t N = evec->size1; size_t i; /* looping */ gsl_complex ei; gsl_vector_complex_view vi; gsl_vector_view re, im; double scale; /* scaling factor */ for (i = 0; i < N; ++i) { ei = gsl_vector_complex_get(eval, i); vi = gsl_matrix_complex_column(evec, i); re = gsl_vector_complex_real(&vi.vector); if (GSL_IMAG(ei) == 0.0) { scale = 1.0 / gsl_blas_dnrm2(&re.vector); gsl_blas_dscal(scale, &re.vector); } else if (GSL_IMAG(ei) > 0.0) { im = gsl_vector_complex_imag(&vi.vector); scale = 1.0 / gsl_hypot(gsl_blas_dnrm2(&re.vector), gsl_blas_dnrm2(&im.vector)); gsl_blas_zdscal(scale, &vi.vector); vi = gsl_matrix_complex_column(evec, i + 1); gsl_blas_zdscal(scale, &vi.vector); } } } /* nonsymmv_normalize_eigenvectors() */
gsl_vector_complex * CRebuildGraph::calculateEgeinval (gsl_matrix *target) { int order = (int)target->size1; gsl_vector_complex *eval = gsl_vector_complex_alloc (order); gsl_matrix_complex *evec = gsl_matrix_complex_alloc (order, order); gsl_eigen_nonsymmv_workspace * w = gsl_eigen_nonsymmv_alloc (order); gsl_eigen_nonsymmv (target, eval, evec, w); gsl_eigen_nonsymmv_free (w); gsl_eigen_nonsymmv_sort (eval, evec, GSL_EIGEN_SORT_ABS_DESC); { int i, j; for (i = 0; i < order; i++) { gsl_complex eval_i = gsl_vector_complex_get (eval, i); gsl_vector_complex_view evec_i = gsl_matrix_complex_column (evec, i); printf ("eigenvalue = %g + %gi\n", GSL_REAL(eval_i), GSL_IMAG(eval_i)); printf ("eigenvector = \n"); for (j = 0; j < order; ++j) { /* gsl_complex z = */ gsl_vector_complex_get(&evec_i.vector, j); // printf("%g + %gi\n", GSL_REAL(z), GSL_IMAG(z)); } } } // gsl_vector_complex_free(eval); gsl_matrix_complex_free(evec); return eval; }
int gsl_linalg_complex_LU_invert (const gsl_matrix_complex * LU, const gsl_permutation * p, gsl_matrix_complex * inverse) { size_t i, n = LU->size1; int status = GSL_SUCCESS; gsl_matrix_complex_set_identity (inverse); for (i = 0; i < n; i++) { gsl_vector_complex_view c = gsl_matrix_complex_column (inverse, i); int status_i = gsl_linalg_complex_LU_svx (LU, p, &(c.vector)); if (status_i) status = status_i; } return status; }
int lls_complex_correlation(gsl_matrix_complex *B, const lls_complex_workspace *w) { size_t n = w->AHA->size1; if (B->size1 != n || B->size2 != n) { fprintf(stderr, "lls_complex_correlation: B has wrong dimensions\n"); return GSL_EBADLEN; } else { int s; size_t i; gsl_vector_complex_view d = gsl_matrix_complex_diagonal(B); /* compute covariance matrix */ s = lls_complex_invert(B, w); if (s) { fprintf(stderr, "lls_complex_correlation: error computing covariance matrix: %d\n", s); return s; } /* compute diag(C)^{-1/2} C diag(C)^{-1/2} */ for (i = 0; i < n; ++i) { gsl_complex di = gsl_vector_complex_get(&d.vector, i); gsl_vector_complex_view ri = gsl_matrix_complex_row(B, i); gsl_vector_complex_view ci = gsl_matrix_complex_column(B, i); gsl_complex z; GSL_SET_COMPLEX(&z, 1.0 / sqrt(GSL_REAL(di)), 0.0); gsl_vector_complex_scale(&ri.vector, z); gsl_vector_complex_scale(&ci.vector, z); } return s; } } /* lls_complex_correlation() */
void MarkovChain::setupCDFS(const gsl_matrix * Q) { double cdf, norm; gsl_vector_complex *eval; gsl_matrix_complex *evec; gsl_eigen_nonsymmv_workspace * w; gsl_vector_complex_view S; gsl_matrix_memcpy (m_cdfQ, Q); eval = gsl_vector_complex_alloc (Q->size1); evec = gsl_matrix_complex_alloc (Q->size1, Q->size2); w = gsl_eigen_nonsymmv_alloc(Q->size1); gsl_eigen_nonsymmv (m_cdfQ, eval, evec, w); gsl_eigen_nonsymmv_sort (eval, evec, GSL_EIGEN_SORT_ABS_DESC); /*vector of stationary probabilities corresponding to the eigenvalue 1 */ S = gsl_matrix_complex_column(evec, 0); /*sum of vector elements*/ norm = 0.0; for(size_t i = 0; i < Q->size1; ++i) { norm += GSL_REAL(gsl_vector_complex_get(&S.vector, i)); } /*cdfs*/ cdf = 0.0; for(size_t i = 0; i < Q->size1; ++i) { cdf += GSL_REAL(gsl_vector_complex_get(&S.vector, i)) / norm; gsl_vector_set(m_cdfS, i, cdf); } gsl_eigen_nonsymmv_free (w); gsl_vector_complex_free(eval); gsl_matrix_complex_free(evec); }
/* computes the svd of a complex matrix. Missing in gsl. */ int svd(gsl_matrix_complex *A, gsl_matrix_complex *V, gsl_vector *S) { int n = A->size1; gsl_eigen_hermv_workspace *gsl_work = gsl_eigen_hermv_alloc(n); gsl_matrix_complex *Asq = gsl_matrix_complex_alloc(n, n); gsl_complex zero = gsl_complex_rect(0., 0.); gsl_complex one = gsl_complex_rect(1., 0.); gsl_vector *e = gsl_vector_alloc(n); gsl_matrix_complex *U = gsl_matrix_complex_alloc(n, n); gsl_blas_zgemm(CblasNoTrans, CblasConjTrans, one, A, A, zero, Asq); gsl_eigen_hermv(Asq, e, U, gsl_work); gsl_eigen_hermv_sort(e, U, GSL_EIGEN_SORT_VAL_DESC); gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, one, A, A, zero, Asq); gsl_eigen_hermv(Asq, e, V, gsl_work); gsl_eigen_hermv_sort(e, V, GSL_EIGEN_SORT_VAL_DESC); gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, A, V, zero, Asq); gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, one, U, Asq, zero, A); for(int i=0; i<n; i++){ gsl_complex x = gsl_matrix_complex_get(A, i, i); double phase = gsl_complex_arg(gsl_complex_mul_real(x, 1./sqrt(e->data[i]))); gsl_vector_complex_view U_col = gsl_matrix_complex_column(U, i); gsl_vector_complex_scale(&U_col.vector, gsl_complex_polar(1., phase)); gsl_vector_set(S, i, sqrt(gsl_vector_get(e, i))); } gsl_matrix_complex_memcpy(A, U); gsl_vector_free(e); gsl_matrix_complex_free(U); gsl_matrix_complex_free(Asq); gsl_eigen_hermv_free(gsl_work); return 0; }
void MCPMPChan::Run() { /// fetch data objects gsl_matrix_complex inmat = min1.GetDataObj(); gsl_matrix_complex cmat = min2.GetDataObj(); // inmat : input signal matrix x(n) (NxM) // i // complex sample at time n from Tx number i // cmat : channel coeffs matrix h(n) (M**2xN) // ij // cmat matrix structure // // +- -+ // | h(0) . . . . h(n) | | // | 11 11 | | // | | | Rx1 // | h(0) . . . . h(n) | | // | 12 12 | | // | | // | h(0) . . . . h(n) | | // | 21 21 | | // | | | Rx2 // | h(0) . . . . h(n) | | // | 22 22 | | // +- -+ // // where h(n) represents the channel impulse response // ij // // at time n, from tx i to rx j // the matrix has MxM rows and N comumns. // The (i,j) channel is locater at row i*M+j // with i,j in the range [0,M-1] and rows counting from 0 // // gsl_matrix_complex_set_zero(outmat); for (int rx=0;rx<M();rx++) { //loop through Rx // // csubmat creates a view on cmat extracting the MxN submatrix for Rx number u // gsl_matrix_complex_const_view csubmat = gsl_matrix_complex_const_submatrix(&cmat,rx*M(),0,M(),N()); // // cut a slice of outmat // gsl_vector_complex_view outvec = gsl_matrix_complex_column(outmat,rx); for (int tx=0;tx<M();tx++) { // loop through Tx // // input signal from tx // gsl_vector_complex_view x = gsl_matrix_complex_column(&inmat,tx); gsl_vector_complex *tmp = gsl_vector_complex_alloc(N()); // // // extract the current tx-rx channel matrix // // for (int i=0; i<N(); i++) { gsl_complex h = gsl_matrix_complex_get(&csubmat.matrix,tx,(N()-i)%N()); for (int j=0; j<N(); j++) { gsl_matrix_complex_set(user_chan,j,(j+i) % N(),h); } } // cout << "Channel (" << tx << "-" << rx << "):" << endl; // gsl_matrix_complex_show(user_chan); // // compute the signal rx = H tx // gsl_blas_zgemv(CblasNoTrans, gsl_complex_rect(1.0,0), user_chan, &x.vector, gsl_complex_rect(0,0), tmp); // // sum for each tx // gsl_vector_complex_add(&outvec.vector,tmp); gsl_vector_complex_free(tmp); } // tx loop for (int i=0; i< N(); i++) { gsl_complex noisesample = gsl_complex_rect( gsl_ran_gaussian(ran,noisestd), gsl_ran_gaussian(ran,noisestd)); gsl_complex ctmp = gsl_complex_add(gsl_vector_complex_get(&outvec.vector,i),noisesample); gsl_vector_complex_set(&outvec.vector,i,ctmp); } } // rx loop // cout << "received signals matrix (" << N() << "x" << M() << ")" << endl; // gsl_matrix_complex_show(outmat); //////// production of data mout1.DeliverDataObj( *outmat ); }
static void nonsymmv_get_right_eigenvectors(gsl_matrix *T, gsl_matrix *Z, gsl_vector_complex *eval, gsl_matrix_complex *evec, gsl_eigen_nonsymmv_workspace *w) { const size_t N = T->size1; const double smlnum = GSL_DBL_MIN * N / GSL_DBL_EPSILON; const double bignum = (1.0 - GSL_DBL_EPSILON) / smlnum; int i; /* looping */ size_t iu, /* looping */ ju, ii; gsl_complex lambda; /* current eigenvalue */ double lambda_re, /* Re(lambda) */ lambda_im; /* Im(lambda) */ gsl_matrix_view Tv, /* temporary views */ Zv; gsl_vector_view y, /* temporary views */ y2, ev, ev2; double dat[4], /* scratch arrays */ dat_X[4]; double scale; /* scale factor */ double xnorm; /* |X| */ gsl_vector_complex_view ecol, /* column of evec */ ecol2; int complex_pair; /* complex eigenvalue pair? */ double smin; /* * Compute 1-norm of each column of upper triangular part of T * to control overflow in triangular solver */ gsl_vector_set(w->work3, 0, 0.0); for (ju = 1; ju < N; ++ju) { gsl_vector_set(w->work3, ju, 0.0); for (iu = 0; iu < ju; ++iu) { gsl_vector_set(w->work3, ju, gsl_vector_get(w->work3, ju) + fabs(gsl_matrix_get(T, iu, ju))); } } for (i = (int) N - 1; i >= 0; --i) { iu = (size_t) i; /* get current eigenvalue and store it in lambda */ lambda_re = gsl_matrix_get(T, iu, iu); if (iu != 0 && gsl_matrix_get(T, iu, iu - 1) != 0.0) { lambda_im = sqrt(fabs(gsl_matrix_get(T, iu, iu - 1))) * sqrt(fabs(gsl_matrix_get(T, iu - 1, iu))); } else { lambda_im = 0.0; } GSL_SET_COMPLEX(&lambda, lambda_re, lambda_im); smin = GSL_MAX(GSL_DBL_EPSILON * (fabs(lambda_re) + fabs(lambda_im)), smlnum); smin = GSL_MAX(smin, GSL_NONSYMMV_SMLNUM); if (lambda_im == 0.0) { int k, l; gsl_vector_view bv, xv; /* real eigenvector */ /* * The ordering of eigenvalues in 'eval' is arbitrary and * does not necessarily follow the Schur form T, so store * lambda in the right slot in eval to ensure it corresponds * to the eigenvector we are about to compute */ gsl_vector_complex_set(eval, iu, lambda); /* * We need to solve the system: * * (T(1:iu-1, 1:iu-1) - lambda*I)*X = -T(1:iu-1,iu) */ /* construct right hand side */ for (k = 0; k < i; ++k) { gsl_vector_set(w->work, (size_t) k, -gsl_matrix_get(T, (size_t) k, iu)); } gsl_vector_set(w->work, iu, 1.0); for (l = i - 1; l >= 0; --l) { size_t lu = (size_t) l; if (lu == 0) complex_pair = 0; else complex_pair = gsl_matrix_get(T, lu, lu - 1) != 0.0; if (!complex_pair) { double x; /* * 1-by-1 diagonal block - solve the system: * * (T_{ll} - lambda)*x = -T_{l(iu)} */ Tv = gsl_matrix_submatrix(T, lu, lu, 1, 1); bv = gsl_vector_view_array(dat, 1); gsl_vector_set(&bv.vector, 0, gsl_vector_get(w->work, lu)); xv = gsl_vector_view_array(dat_X, 1); gsl_schur_solve_equation(1.0, &Tv.matrix, lambda_re, 1.0, 1.0, &bv.vector, &xv.vector, &scale, &xnorm, smin); /* scale x to avoid overflow */ x = gsl_vector_get(&xv.vector, 0); if (xnorm > 1.0) { if (gsl_vector_get(w->work3, lu) > bignum / xnorm) { x /= xnorm; scale /= xnorm; } } if (scale != 1.0) { gsl_vector_view wv; wv = gsl_vector_subvector(w->work, 0, iu + 1); gsl_blas_dscal(scale, &wv.vector); } gsl_vector_set(w->work, lu, x); if (lu > 0) { gsl_vector_view v1, v2; /* update right hand side */ v1 = gsl_matrix_subcolumn(T, lu, 0, lu); v2 = gsl_vector_subvector(w->work, 0, lu); gsl_blas_daxpy(-x, &v1.vector, &v2.vector); } /* if (l > 0) */ } /* if (!complex_pair) */ else { double x11, x21; /* * 2-by-2 diagonal block */ Tv = gsl_matrix_submatrix(T, lu - 1, lu - 1, 2, 2); bv = gsl_vector_view_array(dat, 2); gsl_vector_set(&bv.vector, 0, gsl_vector_get(w->work, lu - 1)); gsl_vector_set(&bv.vector, 1, gsl_vector_get(w->work, lu)); xv = gsl_vector_view_array(dat_X, 2); gsl_schur_solve_equation(1.0, &Tv.matrix, lambda_re, 1.0, 1.0, &bv.vector, &xv.vector, &scale, &xnorm, smin); /* scale X(1,1) and X(2,1) to avoid overflow */ x11 = gsl_vector_get(&xv.vector, 0); x21 = gsl_vector_get(&xv.vector, 1); if (xnorm > 1.0) { double beta; beta = GSL_MAX(gsl_vector_get(w->work3, lu - 1), gsl_vector_get(w->work3, lu)); if (beta > bignum / xnorm) { x11 /= xnorm; x21 /= xnorm; scale /= xnorm; } } /* scale if necessary */ if (scale != 1.0) { gsl_vector_view wv; wv = gsl_vector_subvector(w->work, 0, iu + 1); gsl_blas_dscal(scale, &wv.vector); } gsl_vector_set(w->work, lu - 1, x11); gsl_vector_set(w->work, lu, x21); /* update right hand side */ if (lu > 1) { gsl_vector_view v1, v2; v1 = gsl_matrix_subcolumn(T, lu - 1, 0, lu - 1); v2 = gsl_vector_subvector(w->work, 0, lu - 1); gsl_blas_daxpy(-x11, &v1.vector, &v2.vector); v1 = gsl_matrix_subcolumn(T, lu, 0, lu - 1); gsl_blas_daxpy(-x21, &v1.vector, &v2.vector); } --l; } /* if (complex_pair) */ } /* for (l = i - 1; l >= 0; --l) */ /* * At this point, w->work is an eigenvector of the * Schur form T. To get an eigenvector of the original * matrix, we multiply on the left by Z, the matrix of * Schur vectors */ ecol = gsl_matrix_complex_column(evec, iu); y = gsl_matrix_column(Z, iu); if (iu > 0) { gsl_vector_view x; Zv = gsl_matrix_submatrix(Z, 0, 0, N, iu); x = gsl_vector_subvector(w->work, 0, iu); /* compute Z * w->work and store it in Z(:,iu) */ gsl_blas_dgemv(CblasNoTrans, 1.0, &Zv.matrix, &x.vector, gsl_vector_get(w->work, iu), &y.vector); } /* if (iu > 0) */ /* store eigenvector into evec */ ev = gsl_vector_complex_real(&ecol.vector); ev2 = gsl_vector_complex_imag(&ecol.vector); scale = 0.0; for (ii = 0; ii < N; ++ii) { double a = gsl_vector_get(&y.vector, ii); /* store real part of eigenvector */ gsl_vector_set(&ev.vector, ii, a); /* set imaginary part to 0 */ gsl_vector_set(&ev2.vector, ii, 0.0); if (fabs(a) > scale) scale = fabs(a); } if (scale != 0.0) scale = 1.0 / scale; /* scale by magnitude of largest element */ gsl_blas_dscal(scale, &ev.vector); } /* if (GSL_IMAG(lambda) == 0.0) */ else { gsl_vector_complex_view bv, xv; size_t k; int l; gsl_complex lambda2; /* complex eigenvector */ /* * Store the complex conjugate eigenvalues in the right * slots in eval */ GSL_SET_REAL(&lambda2, GSL_REAL(lambda)); GSL_SET_IMAG(&lambda2, -GSL_IMAG(lambda)); gsl_vector_complex_set(eval, iu - 1, lambda); gsl_vector_complex_set(eval, iu, lambda2); /* * First solve: * * [ T(i:i+1,i:i+1) - lambda*I ] * X = 0 */ if (fabs(gsl_matrix_get(T, iu - 1, iu)) >= fabs(gsl_matrix_get(T, iu, iu - 1))) { gsl_vector_set(w->work, iu - 1, 1.0); gsl_vector_set(w->work2, iu, lambda_im / gsl_matrix_get(T, iu - 1, iu)); } else { gsl_vector_set(w->work, iu - 1, -lambda_im / gsl_matrix_get(T, iu, iu - 1)); gsl_vector_set(w->work2, iu, 1.0); } gsl_vector_set(w->work, iu, 0.0); gsl_vector_set(w->work2, iu - 1, 0.0); /* construct right hand side */ for (k = 0; k < iu - 1; ++k) { gsl_vector_set(w->work, k, -gsl_vector_get(w->work, iu - 1) * gsl_matrix_get(T, k, iu - 1)); gsl_vector_set(w->work2, k, -gsl_vector_get(w->work2, iu) * gsl_matrix_get(T, k, iu)); } /* * We must solve the upper quasi-triangular system: * * [ T(1:i-2,1:i-2) - lambda*I ] * X = s*(work + i*work2) */ for (l = i - 2; l >= 0; --l) { size_t lu = (size_t) l; if (lu == 0) complex_pair = 0; else complex_pair = gsl_matrix_get(T, lu, lu - 1) != 0.0; if (!complex_pair) { gsl_complex bval; gsl_complex x; /* * 1-by-1 diagonal block - solve the system: * * (T_{ll} - lambda)*x = work + i*work2 */ Tv = gsl_matrix_submatrix(T, lu, lu, 1, 1); bv = gsl_vector_complex_view_array(dat, 1); xv = gsl_vector_complex_view_array(dat_X, 1); GSL_SET_COMPLEX(&bval, gsl_vector_get(w->work, lu), gsl_vector_get(w->work2, lu)); gsl_vector_complex_set(&bv.vector, 0, bval); gsl_schur_solve_equation_z(1.0, &Tv.matrix, &lambda, 1.0, 1.0, &bv.vector, &xv.vector, &scale, &xnorm, smin); if (xnorm > 1.0) { if (gsl_vector_get(w->work3, lu) > bignum / xnorm) { gsl_blas_zdscal(1.0/xnorm, &xv.vector); scale /= xnorm; } } /* scale if necessary */ if (scale != 1.0) { gsl_vector_view wv; wv = gsl_vector_subvector(w->work, 0, iu + 1); gsl_blas_dscal(scale, &wv.vector); wv = gsl_vector_subvector(w->work2, 0, iu + 1); gsl_blas_dscal(scale, &wv.vector); } x = gsl_vector_complex_get(&xv.vector, 0); gsl_vector_set(w->work, lu, GSL_REAL(x)); gsl_vector_set(w->work2, lu, GSL_IMAG(x)); /* update the right hand side */ if (lu > 0) { gsl_vector_view v1, v2; v1 = gsl_matrix_subcolumn(T, lu, 0, lu); v2 = gsl_vector_subvector(w->work, 0, lu); gsl_blas_daxpy(-GSL_REAL(x), &v1.vector, &v2.vector); v2 = gsl_vector_subvector(w->work2, 0, lu); gsl_blas_daxpy(-GSL_IMAG(x), &v1.vector, &v2.vector); } /* if (lu > 0) */ } /* if (!complex_pair) */ else { gsl_complex b1, b2, x1, x2; /* * 2-by-2 diagonal block - solve the system */ Tv = gsl_matrix_submatrix(T, lu - 1, lu - 1, 2, 2); bv = gsl_vector_complex_view_array(dat, 2); xv = gsl_vector_complex_view_array(dat_X, 2); GSL_SET_COMPLEX(&b1, gsl_vector_get(w->work, lu - 1), gsl_vector_get(w->work2, lu - 1)); GSL_SET_COMPLEX(&b2, gsl_vector_get(w->work, lu), gsl_vector_get(w->work2, lu)); gsl_vector_complex_set(&bv.vector, 0, b1); gsl_vector_complex_set(&bv.vector, 1, b2); gsl_schur_solve_equation_z(1.0, &Tv.matrix, &lambda, 1.0, 1.0, &bv.vector, &xv.vector, &scale, &xnorm, smin); x1 = gsl_vector_complex_get(&xv.vector, 0); x2 = gsl_vector_complex_get(&xv.vector, 1); if (xnorm > 1.0) { double beta; beta = GSL_MAX(gsl_vector_get(w->work3, lu - 1), gsl_vector_get(w->work3, lu)); if (beta > bignum / xnorm) { gsl_blas_zdscal(1.0/xnorm, &xv.vector); scale /= xnorm; } } /* scale if necessary */ if (scale != 1.0) { gsl_vector_view wv; wv = gsl_vector_subvector(w->work, 0, iu + 1); gsl_blas_dscal(scale, &wv.vector); wv = gsl_vector_subvector(w->work2, 0, iu + 1); gsl_blas_dscal(scale, &wv.vector); } gsl_vector_set(w->work, lu - 1, GSL_REAL(x1)); gsl_vector_set(w->work, lu, GSL_REAL(x2)); gsl_vector_set(w->work2, lu - 1, GSL_IMAG(x1)); gsl_vector_set(w->work2, lu, GSL_IMAG(x2)); /* update right hand side */ if (lu > 1) { gsl_vector_view v1, v2, v3, v4; v1 = gsl_matrix_subcolumn(T, lu - 1, 0, lu - 1); v4 = gsl_matrix_subcolumn(T, lu, 0, lu - 1); v2 = gsl_vector_subvector(w->work, 0, lu - 1); v3 = gsl_vector_subvector(w->work2, 0, lu - 1); gsl_blas_daxpy(-GSL_REAL(x1), &v1.vector, &v2.vector); gsl_blas_daxpy(-GSL_REAL(x2), &v4.vector, &v2.vector); gsl_blas_daxpy(-GSL_IMAG(x1), &v1.vector, &v3.vector); gsl_blas_daxpy(-GSL_IMAG(x2), &v4.vector, &v3.vector); } /* if (lu > 1) */ --l; } /* if (complex_pair) */ } /* for (l = i - 2; l >= 0; --l) */ /* * At this point, work + i*work2 is an eigenvector * of T - backtransform to get an eigenvector of the * original matrix */ y = gsl_matrix_column(Z, iu - 1); y2 = gsl_matrix_column(Z, iu); if (iu > 1) { gsl_vector_view x; /* compute real part of eigenvectors */ Zv = gsl_matrix_submatrix(Z, 0, 0, N, iu - 1); x = gsl_vector_subvector(w->work, 0, iu - 1); gsl_blas_dgemv(CblasNoTrans, 1.0, &Zv.matrix, &x.vector, gsl_vector_get(w->work, iu - 1), &y.vector); /* now compute the imaginary part */ x = gsl_vector_subvector(w->work2, 0, iu - 1); gsl_blas_dgemv(CblasNoTrans, 1.0, &Zv.matrix, &x.vector, gsl_vector_get(w->work2, iu), &y2.vector); } else { gsl_blas_dscal(gsl_vector_get(w->work, iu - 1), &y.vector); gsl_blas_dscal(gsl_vector_get(w->work2, iu), &y2.vector); } /* * Now store the eigenvectors into evec - the real parts * are Z(:,iu - 1) and the imaginary parts are * +/- Z(:,iu) */ /* get views of the two eigenvector slots */ ecol = gsl_matrix_complex_column(evec, iu - 1); ecol2 = gsl_matrix_complex_column(evec, iu); /* * save imaginary part first as it may get overwritten * when copying the real part due to our storage scheme * in Z/evec */ ev = gsl_vector_complex_imag(&ecol.vector); ev2 = gsl_vector_complex_imag(&ecol2.vector); scale = 0.0; for (ii = 0; ii < N; ++ii) { double a = gsl_vector_get(&y2.vector, ii); scale = GSL_MAX(scale, fabs(a) + fabs(gsl_vector_get(&y.vector, ii))); gsl_vector_set(&ev.vector, ii, a); gsl_vector_set(&ev2.vector, ii, -a); } /* now save the real part */ ev = gsl_vector_complex_real(&ecol.vector); ev2 = gsl_vector_complex_real(&ecol2.vector); for (ii = 0; ii < N; ++ii) { double a = gsl_vector_get(&y.vector, ii); gsl_vector_set(&ev.vector, ii, a); gsl_vector_set(&ev2.vector, ii, a); } if (scale != 0.0) scale = 1.0 / scale; /* scale by largest element magnitude */ gsl_blas_zdscal(scale, &ecol.vector); gsl_blas_zdscal(scale, &ecol2.vector); /* * decrement i since we took care of two eigenvalues at * the same time */ --i; } /* if (GSL_IMAG(lambda) != 0.0) */ } /* for (i = (int) N - 1; i >= 0; --i) */ } /* nonsymmv_get_right_eigenvectors() */
void MBlockUser::Run() { // // Allocation Matrices // gsl_matrix_uint signature_frequencies=min2.GetDataObj(); gsl_matrix signature_powers=min3.GetDataObj(); // // input bits // gsl_matrix_uint inputbits = min1.GetDataObj(); // // outer loop: the users // for (int u=0;u<M();u++) { gsl_vector_complex_view tmpout = gsl_matrix_complex_column(outmat,u); // // // FETCH K INPUT SYMBOLS // // for (int j=0;j<K();j++) { symbol_id=0; //////// I take Nb bits from input and map it in new_symbol for (int i=0;i<Nb();i++) { symbol_id = (symbol_id << 1); // symbol_id += in1.GetDataObj(); symbol_id += gsl_matrix_uint_get(&inputbits,u,j*Nb()+i); } new_symbol = gsl_complex_polar(1.0, symbol_arg * double(gsl_vector_uint_get(gray_encoding, symbol_id))); gsl_vector_complex_set(tmp,j,new_symbol); } // // // SELECTION MATRIX UPDATE and POWER // // // gsl_matrix_complex_set_identity(selection_mat); gsl_matrix_complex_set_zero(selection_mat); for (int i=0;i<J(); i++) { unsigned int carrier=gsl_matrix_uint_get(&signature_frequencies,u,i); double power=gsl_matrix_get(&signature_powers,u,i); gsl_complex one=gsl_complex_polar(power,0.0); gsl_matrix_complex_set(selection_mat,carrier,i,one); } // // // PRECODING MATRIX UPDATE // // #ifdef GIANNAKIS_PRECODING double roarg=2.0*double(M_PI/N()); for (int i=0;i<J(); i++) { unsigned int carrier=gsl_matrix_uint_get(&signature_frequencies,u,i); for (int j=0; j<K(); j++) { gsl_complex ro=gsl_complex_polar(sqrt(1.0/double(J())),-j*carrier*roarg); gsl_matrix_complex_set(coding_mat,i,j,ro); } } #else double roarg=2.0*double(M_PI/J()); for (int i=0;i<J(); i++) { for (int j=0; j<K(); j++) { gsl_complex ro=gsl_complex_polar(sqrt(1.0/double(J())),-j*i*roarg); gsl_matrix_complex_set(coding_mat,i,j,ro); } } #endif #ifdef SHOW_MATRIX cout << endl << BlockName << " user: "******"coding matrix (theta) = " << endl; gsl_matrix_complex_show(coding_mat); cout << "T^h*T matrix = " << endl; gsl_matrix_complex_show(THT); cout << "T^h*T trace = " << GSL_REAL(trace) << ", " << GSL_IMAG(trace) << endl; gsl_matrix_complex_free(THT); #endif // // // PRECODING // // gsl_blas_zgemv(CblasNoTrans, gsl_complex_rect(1.0,0), coding_mat, tmp, gsl_complex_rect(0,0), tmp1); // // // CARRIER SELECTION // // gsl_blas_zgemv(CblasNoTrans, gsl_complex_rect(1.0,0), selection_mat, tmp1, gsl_complex_rect(0,0), tmp2); // // // IFFT TRANSFORM // // gsl_blas_zgemv(CblasNoTrans, gsl_complex_rect(1.0,0), transform_mat, tmp2, gsl_complex_rect(0,0), &tmpout.vector); // cout << "\n\n symbols (user " << u << ") = " << endl; // gsl_vector_complex_fprintf(stdout,tmp,"%f"); #ifdef SHOW_MATRIX cout << "\n\n symbols (user " << u << ") = " << endl; gsl_vector_complex_fprintf(stdout,tmp,"%f"); cout << "\n\n precoded = " << endl; gsl_vector_complex_fprintf(stdout,tmp1,"%f"); cout << "\n\n precoded selected = " << endl; gsl_vector_complex_fprintf(stdout,tmp2,"%f"); cout << "\n\n precoded selected transformed = " << endl; gsl_vector_complex_fprintf(stdout,&tmpout.vector,"%f"); #endif } // close user loop mout1.DeliverDataObj(*outmat); }
int lls_complex_stdform(gsl_matrix_complex *A, gsl_vector_complex *b, const gsl_vector *wts, const gsl_vector *L, lls_complex_workspace *w) { const size_t n = A->size1; const size_t p = A->size2; if (p != w->p) { fprintf(stderr, "lls_complex_stdform: A has wrong size2\n"); return GSL_EBADLEN; } else if (n != b->size) { fprintf(stderr, "lls_complex_stdform: b has wrong size\n"); return GSL_EBADLEN; } else if (wts != NULL && n != wts->size) { fprintf(stderr, "lls_complex_stdform: wts has wrong size\n"); return GSL_EBADLEN; } else if (L != NULL && p != L->size) { fprintf(stderr, "lls_complex_stdform: L has wrong size\n"); return GSL_EBADLEN; } else { int s = 0; size_t i; if (wts != NULL) { for (i = 0; i < n; ++i) { gsl_vector_complex_view rv = gsl_matrix_complex_row(A, i); gsl_complex bi = gsl_vector_complex_get(b, i); double wi = gsl_vector_get(wts, i); double sqrtwi = sqrt(wi); gsl_complex val; GSL_SET_COMPLEX(&val, sqrtwi, 0.0); /* A <- sqrt(W) A */ gsl_vector_complex_scale(&rv.vector, val); /* b <- sqrt(W) b */ val = gsl_complex_mul_real(bi, sqrtwi); gsl_vector_complex_set(b, i, val); } } if (L != NULL) { /* A <- sqrt(W) A L^{-1} */ for (i = 0; i < p; ++i) { gsl_vector_complex_view cv = gsl_matrix_complex_column(A, i); double Li = gsl_vector_get(L, i); gsl_complex val; if (Li == 0.0) { GSL_ERROR("L matrix is singular", GSL_ESING); } GSL_SET_COMPLEX(&val, 1.0 / Li, 0.0); gsl_vector_complex_scale(&cv.vector, val); } } return s; } } /* lls_complex_stdform() */
int gsl_linalg_hermtd_decomp (gsl_matrix_complex * A, gsl_vector_complex * tau) { if (A->size1 != A->size2) { GSL_ERROR ("hermitian tridiagonal decomposition requires square matrix", GSL_ENOTSQR); } else if (tau->size + 1 != A->size1) { GSL_ERROR ("size of tau must be (matrix size - 1)", GSL_EBADLEN); } else { const size_t N = A->size1; size_t i; const gsl_complex zero = gsl_complex_rect (0.0, 0.0); const gsl_complex one = gsl_complex_rect (1.0, 0.0); const gsl_complex neg_one = gsl_complex_rect (-1.0, 0.0); for (i = 0 ; i < N - 1; i++) { gsl_vector_complex_view c = gsl_matrix_complex_column (A, i); gsl_vector_complex_view v = gsl_vector_complex_subvector (&c.vector, i + 1, N - (i + 1)); gsl_complex tau_i = gsl_linalg_complex_householder_transform (&v.vector); /* Apply the transformation H^T A H to the remaining columns */ if ((i + 1) < (N - 1) && !(GSL_REAL(tau_i) == 0.0 && GSL_IMAG(tau_i) == 0.0)) { gsl_matrix_complex_view m = gsl_matrix_complex_submatrix (A, i + 1, i + 1, N - (i+1), N - (i+1)); gsl_complex ei = gsl_vector_complex_get(&v.vector, 0); gsl_vector_complex_view x = gsl_vector_complex_subvector (tau, i, N-(i+1)); gsl_vector_complex_set (&v.vector, 0, one); /* x = tau * A * v */ gsl_blas_zhemv (CblasLower, tau_i, &m.matrix, &v.vector, zero, &x.vector); /* w = x - (1/2) tau * (x' * v) * v */ { gsl_complex xv, txv, alpha; gsl_blas_zdotc(&x.vector, &v.vector, &xv); txv = gsl_complex_mul(tau_i, xv); alpha = gsl_complex_mul_real(txv, -0.5); gsl_blas_zaxpy(alpha, &v.vector, &x.vector); } /* apply the transformation A = A - v w' - w v' */ gsl_blas_zher2(CblasLower, neg_one, &v.vector, &x.vector, &m.matrix); gsl_vector_complex_set (&v.vector, 0, ei); } gsl_vector_complex_set (tau, i, tau_i); } return GSL_SUCCESS; } }