Beispiel #1
0
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);
}
Beispiel #2
0
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;
}
Beispiel #4
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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);
}
Beispiel #9
0
/*
  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;
}
Beispiel #10
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 );
  
}
Beispiel #11
0
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() */
Beispiel #12
0
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);

}
Beispiel #13
0
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() */
Beispiel #14
0
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;
    }
}