Beispiel #1
0
/* ************************************************************
   PROCEDURE getfirstpiv - Find first affecting pivot on column
     j = 1:n. These column numbers are in NON-PIVOTED ORDER, i.e.
     the order in which they appear in Xjc.
   INPUT
     invperm - length n array, yields position in list of nonzeros "dzir".
     xsuper - length n (though it may have n+1) array, partitioning
       of permuted subscripts, is "dzjc".
     Xjc - length n+1 array
     Xir - length Xjc[n] array
     n - number of columns in X.
   OUTPUT
     firstpiv - length n array
   ************************************************************ */
void getfirstpiv(mwIndex *firstpiv, const mwIndex *invperm, const mwIndex *xsuper,
                 const mwIndex *Xjc, const mwIndex *Xir, const mwIndex n)
{
  mwIndex i,j,inz,firstj;
  inz = Xjc[0];                 /* typically inz = 0*/
  for(j = 0; j < n; j++){
/* ------------------------------------------------------------
   Let firstj = min(invperm(find(X(:,j))))
   ------------------------------------------------------------ */
    if(inz < Xjc[j+1]){
      firstj = invperm[Xir[inz]];
      for(++inz; inz < Xjc[j+1]; inz++)
        if((i = invperm[Xir[inz]]) < firstj)
          firstj = i;
/* ------------------------------------------------------------
   First node covering firstj, i.e. xsuper[y] < firstj+1 <= xsuper[y+1],
   with y denoting firstpiv[j].
   ------------------------------------------------------------ */
      firstpiv[j] = 0;             /* search from start */
      intbsearch(firstpiv+j,xsuper+1,n-1,firstj+1);
    }
    else
      firstpiv[j] = n;             /* if all-0 then no affecting pivot */
  }
}
Beispiel #2
0
/* ************************************************************
   PROCEDURE makereal
   INPUT
     xir,xpr,xpi - sparse vector with xnnz nonzeros.
     xnnz - length of xir,xpr,xpi.
     cpxf - length nf integer array, listing free imaginary vars.
     nf - length of cpxf
     cpxx - length nx integer array, listing Lorentz constrained
       imaginary vars.
     nx - length of cpxx.
     cpxsi - length 2*ns increasing integer array. The old subscripts
       of the kth Hermitian block in x are cpxsi[2*k]:cpxsi[2*k+1]-1.
     ns - number of Hermitian PSD blocks.
     lenfull - length of full(x)-vector, 1 beyond last possible subscript.
     iwsize Length of iwork, should be 2 + MAXN + floor(log_2(1+MAXN)).
     lenfull - dimension of x.
     dimflqr - dimension of f/l/q/r part in x, i.e. 1st valid PSD subscript.
   OUTPUT
     yir, ypr - sparse real output vector, ynnz nonzeros.
   WORK ARRAYS
     cfound - length MAXN := MAX(nf,nx,2*ns) character working array.
     iwork - lengt iwsize working array. Needs
      iwsize >= 2 + MAXN + floor(log_2(1+MAXN)).
   RETURNS ynnz (<=2*xnnz), number of nonzeros in y.
   ************************************************************ */
mwIndex makereal(mwIndex *yir, double *ypr,
             const mwIndex *xir, const double *xpr, const double *xpi,
             const mwIndex xnnz, const mwIndex *cpxf, const mwIndex nf,
             const mwIndex *cpxx, const mwIndex nx, const mwIndex *cpxsi,
             const mwIndex ns, const mwIndex lenfull, const mwIndex dimflqr,
             bool *cfound, mwIndex *iwork, mwIndex iwsize)
{
  mwIndex jcs, jnz;
/* ------------------------------------------------------------
   Find position of 1st PSD nonzero
   ------------------------------------------------------------ */
  jcs = 0;
  intbsearch(&jcs, xir, xnnz, dimflqr);
/* ------------------------------------------------------------
   Write free imaginary nonzeros into y
   ------------------------------------------------------------ */
  jnz = fmakereal(yir,ypr, xir,xpi,jcs, cpxf,nf, cfound,iwork,iwsize);
/* ------------------------------------------------------------
   Write LP/Lorentz nonzeros into y, make Lorentz bounded imag nonzeros
   explicit reals.
   ------------------------------------------------------------ */
  jnz += xmakereal(yir+jnz,ypr+jnz, xir,xpr,xpi,jcs, nf, cpxx,nx,
                   cfound,iwork,iwsize);
/* ------------------------------------------------------------
   Write PSD nonzeros into y. First the real blocks, then Hermitian.
   ------------------------------------------------------------ */
  if(xpi != (double *) NULL)
    xpi += jcs;                   /* point to 1st imag PSD nonzero */
  jnz += smakereal(yir+jnz, ypr+jnz, xir+jcs,xpr+jcs,xpi,xnnz-jcs,
                   nf+nx, cpxsi,2*ns, lenfull, cfound,iwork,iwsize);
/* ------------------------------------------------------------
   Return number of nonzeros in y
   ------------------------------------------------------------ */
  return jnz;
}
Beispiel #3
0
/* ************************************************************
   PROCEDURE vectril - Applies sptotril(xk) for each PSD block k.
       On output, each PSD block is lower triangular, i.e.
       Zk = tril(Xk+Xk')/2.
   INPUT
     xir,xpr,xnnz
     psdNL - K.s
     blkstart - length psdN+1 array. PSD block k has subscripts
       blkstart[k]:blkstart[k+1]-1.
     isblk - length psdDim array, with k = xblk(i-blkstart[0]) iff
       blkstart[k] <= i < blkstart[k+1], k=0:psdN-1.
     rpsdN - number of real PSD blocks
     psdN - number of PSD blocks
     iwsize - maxn*(2*maxn+1)+log_2(1+maxn*(maxn-1)/2), where maxn := max(K.s).
   OUTPUT
     zir - length znnz <= xnnz int array: subscripts of z = vectril(x).
     zpr - length znnz <= xnnz vector: nonzeros of z = vectril(x).
   WORKING ARRAYS
     cwork - length maxn*(maxn-1)/2 char array, where maxn := max(K.s).
     iwork - length iwsize integer working array
     fwork - length max(K.s.^2) vector. (Note: not double for Hermitian
       blocks, since we treat real and imag parts seperately.)
   RETURNS znnz
   ************************************************************ */
int vectril(int *zir, double *zpr, const int *xir, const double *xpr,
            const int xnnz, const int *psdNL,
            const int *blkstart, const int *isblk,
            const int rpsdN, const int psdN, const int iwsize,
            char *cwork, int *iwork, double *fwork)
{
  int inz, jnz, k, nk;
/* ------------------------------------------------------------
   Copy f,l,q,r parts without change. Let inz point to first
   PSD-nonzero in x, jnz in z.
   ------------------------------------------------------------ */
  inz = 0;                                   /* pointer into x */
  intbsearch(&inz, xir, xnnz, blkstart[0]);  /* inz points to start PSD */
  isblk -= blkstart[0];
  memcpy(zir, xir, inz * sizeof(int));
  memcpy(zpr, xpr, inz * sizeof(double));
  jnz = inz;                        /* jnz points to start PSD in z */
/* ------------------------------------------------------------
   Process all PSD blocks
   ------------------------------------------------------------ */
  while(inz < xnnz){
    k = isblk[xir[inz]];
    nk = psdNL[k];
    jnz += sptotril(zir + jnz, zpr + jnz, xir, xpr, &inz, xnnz, blkstart[k],
                    nk,0, iwsize, cwork, iwork, fwork);
/* ------------------------------------------------------------
   For the imaginary part, we do a skew transpose: tril(IM Xk)-triu(IM Xk)'.
   This will make the diagonal of the imaginary block zero.
   ------------------------------------------------------------ */
    if(k >= rpsdN){
      jnz += sptotril(zir + jnz, zpr + jnz, xir, xpr, &inz, xnnz,
                      blkstart[k]+SQR(nk), nk,1, iwsize, cwork, iwork, fwork);
    }
  }
  return jnz;
}