⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spscale.c

📁 经济学专业代码
💻 C
📖 第 1 页 / 共 3 页
字号:
  xd = fwork + SQR(n);
/* ------------------------------------------------------------
   Let dxcols={j: X(:,j)!= all-0}, m = |dxcols|,
   fwork = D*X(:,dxcols).
   ------------------------------------------------------------ */
  m = realdmulx(fwork, dxcols, d, xpr, xir, pxjc0, xjc1, first, n);
/* ------------------------------------------------------------
   Let xd = fwork' = X(:,dxcols)'*D.
   ------------------------------------------------------------ */
  realtransp(xd, fwork, n,m);
/* ------------------------------------------------------------
   Let fwork = D(dxcols,:).     Both xd and fwork are m x n.
   ------------------------------------------------------------ */
  for(j = 0, inz = 0; j < n; j++, d += n)
    for(i = 0; i < m; i++)
      fwork[inz++] = d[dxcols[i]];        /* fwork(i,j) = d(dxcols(i),j) */
/* ------------------------------------------------------------
   For all target subscripts (i,j), let
   zij = (D*sym(X)*D)_ij = [ DXD_ij + DXD_ji ] /2.
   Note that DXD_ij = xd(:,i)' * fwork(:,j).   (m mults)
   ------------------------------------------------------------ */
  jlast = 0;      /* index right after last activated column */
  for(inz = 0; inz < znnz; inz++){
    if((i = zir[inz]) >= jlast){      /* move to new z-column */
      j = (i-first) / n;              /* col j = floor( (i-first)/n ) */
      if(j >= n)
        break;                        /* finished all columns of Z */
      jfirst = first + n * j;
      jlast = jfirst + n;
      icol = m * j;
      dj = fwork + icol;
      xdj = xd + icol;
      if(i - jfirst == j)             /* zjj = xdj' * dj */
        z[i] = realdot(xdj,dj, m);
      else{              /* zij = (xdj'*di + xdi'*dj) / 2 */
        icol = (i - jfirst) * m;
        z[i] = (realdot(xdj,fwork + icol, m) + realdot(xd + icol, dj, m)) / 2;
      }
    }
    else{               /* zij = (xdj'*di + xdi'*dj) / 2 */
      icol = (i - jfirst) * m;
      z[i] = (realdot(xdj,fwork + icol, m) + realdot(xd + icol, dj, m)) / 2;
    }
  }
}

/* ************************************************************
   PROCEDURE spcpxdxd - Computes Z = D*herm(X)*D with D = D' and
        herm(X) = (X+X')/2. X sparse, and Z has pre-chosen sparsity
        structure zir (typically subset of tril-entries).
      Z,D, and X are complex matrices, stored as [vec(RE); vec(IM)].
   INPUT
     zir, zjc0, zjc1 - Target sparsity structure. We compute z(i) only for
       i in zir(zjc0:zjc1-1) with i < first + 2*n^2.
       zjc0 such that zir(zjc0) >= first.
     d      - full 2*(n x n) matrix D.
     xpr, xir, xjc1 - sparse vector, xjc1 nonzeros.
     first  - Subscript of X(1,1) and Z(1,1), i.e.
       x(first:first+n^2-1) = vec(real(X)), x(first+n^2:end)=vec(imag(X)).
     n      - order of D, X.
   UPDATED
     *pxjc0 - On input, points to first nonzero with index in range
       first:first+2*n^2-1. On output, points just BEYOND.
   OUTPUT
     Z - lenfull vector. Only z(first:first+2*n^2-1) is affected, and from this
       only the indices listed in zir. (Other entries unaffected.)
   WORK
     dxcols - length n integer array.
     fwork  - 4 * n^2 vector.
   RETURNS zjc0_NEW
   ************************************************************ */
void spcpxdxd(double *z, const int *zir, const int znnz,
              const double *d,
              const double *xpr, const int *xir, int *pxjc0, const int xjc1,
              const int first, const int n, double *fwork, int *dxcols)
{
  int inz, i, icol, j, jfirst, jlast, m, nsqr, imgfirst;
  double *dx, *dxpi, *fworkpi;
  double zi;
  const double *dj, *djpi, *djx, *djxpi;
  nsqr = SQR(n);
/* ------------------------------------------------------------
   Partition 4*n^2 WORKING array fwork into [fwork(2*n^2), dxRows(2*n^2)].
   ------------------------------------------------------------ */
  fworkpi = fwork + nsqr;
  dx = fworkpi + nsqr;
  dxpi = dx + nsqr;
/* ------------------------------------------------------------
   Let dxcols={j: X(:,j)!= all-0}, m = |dxcols|,
   fwork = RE(D*X(:,dxcols)), fwork+n^2 = IM D*X(:,dxcols).
   ------------------------------------------------------------ */
  m = cpxdmulx(fwork, dxcols, d, xpr, xir, pxjc0, xjc1, first, n);
/* ------------------------------------------------------------
   Let dxRows = D*X(:,dxcols) in row-stacking (instead of usual col-stack).
   ------------------------------------------------------------ */
  realtransp(dx, fwork, n,m);
  realtransp(dxpi, fworkpi, n,m);
/* ------------------------------------------------------------
   Let fwork = D(dxcols,:) in (usual) column stacking; m x n.
   ------------------------------------------------------------ */
  for(j = 0, inz = 0; j < n; j++, d += n)
    for(i = 0; i < m; i++)
      fwork[inz++] = d[dxcols[i]];        /* fwork(i,j) = RE d(dxcols(i),j) */
  for(j = 0, inz = 0; j < n; j++, d += n)
    for(i = 0; i < m; i++)
      fworkpi[inz++] = d[dxcols[i]];     /* fworkpi(i,j) = IM d(dxcols(i),j) */
/* ------------------------------------------------------------
   For all target subscripts (i,j) in RE Z, let
   zij = RE (D*herm(X)*D)_ij = RE [ DXD_ij + DXD_ji ] /2.
   Note that DXD_ij = dx(i,:) * fwork(:,j).   (m mults)
   Since dx is in row-stacking, we can simply browse thru memory.
   ------------------------------------------------------------ */
  jlast = 0;      /* index right after last activated column */
  for(inz = 0; inz < znnz; inz++){
    if((i = zir[inz]) >= jlast){      /* move to new z-column */
      j = (i-first) / n;              /* col j = floor( (i-first)/n ) */
      if(j >= n)
        break;                        /* finished all columns of RE(Z) */
      jfirst = first + n * j;
      jlast = jfirst + n;
      icol = m * j;
      dj = fwork + icol;
      djpi = dj + nsqr;
      djx = dx + icol;
      djxpi = djx + nsqr;
      if(i - jfirst == j)             /* zjj = djx * dj - IMdjx*IMdj * */
        z[i] = realdot(djx,dj, m) - realdot(djxpi,djpi, m);
      else{              /* zij = RE (dix*dj + conj(djx*di)) / 2 */
        icol = (i - jfirst) * m;
        zi = realdot(djx,fwork + icol, m) - realdot(djxpi,fworkpi+icol,m);
        zi += realdot(dx + icol, dj, m) - realdot(dxpi+icol, djpi, m);
        z[i] = zi / 2;
      }
    }
    else{               /* zij = RE (dix*dj + conj(djx*di)) / 2 */
      icol = (i - jfirst) * m;
      zi = realdot(djx,fwork + icol, m) - realdot(djxpi,fworkpi+icol,m);
      zi += realdot(dx + icol, dj, m) - realdot(dxpi+icol, djpi, m);
      z[i] = zi / 2;
    }
  }
/* ------------------------------------------------------------
   Remains: target subscripts (i,j) in IM Z.
   zij = IM (D*herm(X)*D)_ij = IM [ DXD_ij + DXD_ji ] /2.
   Note that DXD_ij = dx(i,:) * fwork(:,j).   (m mults)
   Since dx is in row-stacking, we can simply browse thru memory.
   ------------------------------------------------------------ */
  imgfirst = first + nsqr;
  for(; inz < znnz; inz++){
    if((i = zir[inz]) >= jlast){      /* move to new z-column */
      j = (i-imgfirst) / n;              /* col j = floor( (i-first)/n ) */
      if(j >= n)
        break;                        /* finished all columns of IM(Z) */
      jfirst = imgfirst + n * j;
      jlast = jfirst + n;
      icol = m * j;
      dj = fwork + icol;
      djpi = dj + nsqr;
      djx = dx + icol;
      djxpi = djx + nsqr;
      mxAssert(i - jfirst != j,"");          /* Herm => diag(imag(Z))=0 */
      icol = (i - jfirst) * m;     /* zij = IM (dix*dj + conj(djx*di)) / 2 */
      zi = realdot(dx + icol, djpi, m) + realdot(dxpi+icol, dj, m);
      zi -= realdot(djx,fworkpi + icol, m) + realdot(djxpi,fwork+icol,m);
      z[i] = zi / 2;
    }
    else{               /* zij = IM (dix*dj + conj(djx*di)) / 2 */
      icol = (i - jfirst) * m;
      zi = realdot(dx + icol, djpi, m) + realdot(dxpi+icol, dj, m);
      zi -= realdot(djx,fworkpi + icol, m) + realdot(djxpi,fwork+icol,m);
      z[i] = zi / 2;
    }
  }
}

/* ************************************************************
   PROCEDURE spsqrscale - Computes z = D(d^2)x for PSD-part.
   INPUT
     zir, zjc1 - Target sparsity structure. We compute z(i) only for
       i in zir(0:zjc1-1).
     d      - lenud vector containing full n x n matrices Dk (=Ud'*Ud).
     xpr, xir, xjc1 - sparse vector, xjc1 nonzeros.
     xjc0 - Points to first nonzero with index in range
       blkstart[0]:blkstart[psdN].
     blkstart  - length psdN+1 array such that 
       x(blkstart[k]:blkstart[k+1]) = vec(Xk) for all PSD blocks k.
     xblk - length psdDim array, with k = xblk(i-blkstart[0]) iff
       blkstart[k] <= i < blkstart[k+1], k=0:nblk-1.
       psdDim:=blkstart[end]-blkstart[0].
     psdNL     - length psdN array, is K.s.
     rpsdN     - number of real symmetric PSD blocks.
   OUTPUT
     z - lenfull vector. Only indices listed in zir are affected.
       Other entries are unaffected (not even set to 0).
     blks - length blksnnz <= length(K.s), lists PSD-blocks where
       z has nonzeros.
   WORK
     fwork - 2 * (rMaxn^2 + 2*hMaxn^2) vector.  (<= 4*max(K.s)^2)
     iwork - length n=MAX(rMaxn,hMaxn) integer array. (n=max(K.s))
   RETURNS blksnnz, number of entries written into blks.
   ************************************************************ */
int spsqrscale(double *z, int *blks, const int *zjc, const int *zir,
               const int *znnz, const double *d,
               const int *xir, const double *xpr, int xjc0, const int xjc1,
               const int *blkstart, const int *xblk, const int *psdNL,
               const int rpsdN, double *fwork, int *iwork)
{
  int blksnnz, k;

  blksnnz = 0;
  d -= blkstart[0];        /* Now, d + blkstart[k] gives Dk */
  while(xjc0 < xjc1){
/* ------------------------------------------------------------
   For each nonzero block xblk[.] in x, Let zk = vec(tril(Dk * Xk * Dk)).
   ------------------------------------------------------------ */
    if((k = xblk[xir[xjc0]]) >= rpsdN)
      break;                                /* 1st nz Hermitian PSD block */
    sprealdxd(z, zir+zjc[k], znnz[k], d + blkstart[k], xpr, xir, &xjc0, xjc1,
              blkstart[k], psdNL[k], fwork, iwork);
    blks[blksnnz++] = k;
  }
/* ------------------------------------------------------------
   Hermitian PSD blocks
   ------------------------------------------------------------ */
  while(xjc0 < xjc1){
    k = xblk[xir[xjc0]];
    spcpxdxd(z, zir+zjc[k], znnz[k], d + blkstart[k], xpr, xir, &xjc0, xjc1,
             blkstart[k], psdNL[k], fwork, iwork);
    blks[blksnnz++] = k;
  }
  return blksnnz;
}

#ifdef OLDSEDUMI
/* =========================  P S D :  ========================= 
   D(d)x = vec(U' * X * U), only at zir positions.
   Typically, zir is subset of tril (or of triu).
   ============================================================ */

/* ************************************************************
   PROCEDURE sprealutxu - Computes Z(perm,perm) = U' * X * U.
        Z has pre-chosen sparsity structure zir
	(typically subset of tril-entries [or of triu-entries]).
   INPUT
     zir, zjc0, zjc1 - Target sparsity structure. We compute z(i) only for
       i in zir(zjc0:zjc1-1) with i < first + n^2.
       zjc0 such that zir(zjc0) >= first.
     u      - full n x n matrix, triu(u) = U.
     invperm - length n array, invperm(perm)=0:n-1. Used to translate Z-index
       to u- and x-index.
     x - n x n full symmetric matrix containing triu(X).
     first  - Subscript of X(1,1) and Z(1,1), i.e.
       x(first:first+n^2-1) = vec(X).
     n      - order of U, X.
   OUTPUT
     Z - lenfull vector. Only z(first:first+n^2-1) is affected, and from this
       only the indices listed in zir. (Other entries unaffected.)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -