コード例 #1
0
/* ************************************************************
   PROCEDURE prpiqxqt - computes tril(Qb * X * Qb')
    Here, Qb = Q_1*Q_2*..*Q_{m-1}*diag(q(:,m)), where each Q_i is a
    Householder reflection, and q(:,m) is a complex sign-vector.
    (Qb is from a Qb * R decomposition.)
   INPUT
     beta - length m vector (real)
     c,cpi - m x m matrix, lower triangular gives Householder reflections
     m    - order
   UPDATED
     x,xpi -  m x m. On output, Xnew = Qb * X * Qb'
       This means: start with order 2 reflection, up to order m reflection.
   WORK
     fwork - length 2*m working vector.
   ************************************************************ */
void prpiqxqt(double *x, double *xpi, const double *beta, const double *c,
              const double *cpi, const mwIndex m, double *fwork)
{
    mwIndex i,k, inz;
    const double *qsgn, *qsgnpi;
    double qk, qkim, qij,qijim, xij;

    /* ------------------------------------------------------------
       START BY COMPLEX SIGNING.
       Let qsgn = c(:,m) be the sign vector. Then let
       X_new = diag(qsgn) * X * diag(qsgn)' = qsign(i) * conj(qsign(j)) * x_ij
       for i > j. The diagonal is not affected, since |qsign(i)| = 1.
       ------------------------------------------------------------ */
    qsgn = c + m * (m-1);
    qsgnpi = cpi + m * (m-1);
    inz = 0;
    for(k = 0; k < m-1; k++) {
        inz += k+1;                       /* point below diagonal */
        qk = qsgn[k];
        qkim = qsgnpi[k];
        for(i = k+1; i < m; i++) {
            /* qij = conj(qsign(i)) * qsign(k) */
            qij = qsgn[i]*qk + qsgnpi[i] * qkim;
            qijim = qsgn[i]*qkim - qsgnpi[i] * qk;
            /* xij *= conj(qij) */
            xij = x[inz] * qij + xpi[inz] * qijim;
            xpi[inz] = xpi[inz] * qij - x[inz] * qijim;      /* conj qij */
            x[inz] = xij;                             /* WRITE signed x-values */
            inz++;
        }
    }
    /* ------------------------------------------------------------
       FINISH by Householder transformations:
       For each k, c[inz] = c(k,k), the top of the lower-right block,
       x[k] is start of k-th row in k.
       ------------------------------------------------------------ */
    inz = SQR(m) - (m+2);
    for(k = m-1; k > 0; k--, inz -= m+1)
        prpielqxq(x + k-1,xpi + k-1, -beta[k-1], c + inz,cpi+inz, k-1, m, fwork);
}
コード例 #2
0
ファイル: reflect.c プロジェクト: HongliangZhou/protein
/* ************************************************************
   PROCEDURE prpiqtxq - computes tril(Qb' * X * Qb)
    Here, Qb = Q_1*Q_2*..*Q_{m-1}*diag(q(:,m)), where each Q_i is a
    Householder reflection, and q(:,m) is a complex sign-vector.
    (Qb is from a Qb * R decomposition.)
   INPUT
     beta - length m vector (real)
     c,cpi - m x m matrix, lower triangular gives Householder reflections
     m    - order
   UPDATED
     x,xpi -  m x m. On output, Xnew = Qb' * X * Qb
       This means: start with order m reflection, up to order 2 reflection.
   WORK
     fwork - length 2*m working vector.
   ************************************************************ */
void prpiqtxq(double *x, double *xpi, const double *beta, const double *c,
              const double *cpi, const int m, double *fwork)
{
  int i,k, inz;
  const double *qsgn, *qsgnpi;
  double qk, qkim, qij,qijim, xij;

/* ------------------------------------------------------------
   START by Householder transformations:
   For each k, c[inz] = c(k,k), the top of the lower-right block,
   x[k] is start of k-th row in k.
   ------------------------------------------------------------ */
  inz = 0;
  for(k = 0; k < m-1; k++, inz += m+1)
    prpielqxq(x + k,xpi + k, -beta[k], c + inz,cpi + inz, k, m, fwork);
/* ------------------------------------------------------------
   FINISH BY COMPLEX SIGNING.
   Let qsgn = c(:,m) be the sign vector. Then let
   X_new = diag(qsgn)' * X * diag(qsgn) = conj(qsign(i)) * qsign(j) * x_ij
   for i > j. The diagonal is not affected, since |qsign(i)| = 1.
   ------------------------------------------------------------ */
  qsgn = c + m * (m-1);
  qsgnpi = cpi + m * (m-1);
  inz = 0;
  for(k = 0; k < m-1; k++){
    qk = qsgn[k]; qkim = qsgnpi[k];
    inz += k+1;                       /* point below diagonal */
    for(i = k+1; i < m; i++){
/* qij = conj(qsign(i)) * qsign(k) */
      qij = qsgn[i]*qk + qsgnpi[i] * qkim;
      qijim = qsgn[i]*qkim - qsgnpi[i] * qk;
/* xij *= qij */
      xij = x[inz] * qij - xpi[inz] * qijim;
      xpi[inz] = x[inz] * qijim + xpi[inz] * qij;
      x[inz] = xij;
      inz++;
    }
  }
}