Пример #1
0
/* ************************************************************
   PROCEDURE spsub - Let z = x - y
   INPUT
     xir, xpr, xnnz - sparse vector
     yir, ypr, ynnz - sparse vector
     iwsize - ynnz+2 + floor(log_2(ynnz+1))
   OUTPUT
     zir, zpr - length znnz arrays containing sparse output z = x - y.
   WORK
     iwork - length iwsize working array
   RETURNS znnz
   ************************************************************ */
int spsub(int *zir, double *zpr, const int *xir, const double *xpr,
          const int xnnz, const int *yir, const double *ypr, const int ynnz,
          int iwsize, char *cfound, int *iwork)
{
  int inz,jnz,knz, i;
  int *yinx;
/* ------------------------------------------------------------
   Partition working array [yinx(ynnz+2), iwork(log_2(ynnz+1))].
   ------------------------------------------------------------ */
  yinx = iwork;
  iwork += ynnz + 2;
  iwsize -= ynnz + 2;
  intmbsearch(yinx, cfound, xir, xnnz, yir, ynnz, iwork, iwsize);
  jnz = yinx[1];
  memcpy(zir, xir, jnz * sizeof(int));
  memcpy(zpr, xpr, jnz * sizeof(double));
  for(i = 0; i < ynnz; i++){
    inz = yinx[i+1];
    if(cfound[i])
      zpr[jnz] = xpr[inz++] - ypr[i];
    else
      zpr[jnz] = -ypr[i];
    zir[jnz++] = yir[i];
    knz = yinx[i+2]-inz;
    memcpy(zir + jnz, xir + inz, knz * sizeof(int));
    memcpy(zpr + jnz, xpr + inz, knz * sizeof(double));
    jnz += knz;
  }
  return jnz;
}
Пример #2
0
/* ************************************************************
   PROCEDURE spadd - Let z = x + y
   INPUT
     xir, xpr, xnnz - sparse vector
     yir, ypr, ynnz - sparse vector
     iwsize - ynnz+2 + floor(log_2(ynnz+1))
   OUTPUT
     zir, zpr - length znnz arrays containing sparse output z = x + y.
   WORK
     iwork - length iwsize working array
   RETURNS znnz
   ************************************************************ */
mwIndex spadd2(mwIndex *zir, double *zpr, const mwIndex *xir, const double *xpr,
           const mwIndex xnnz, const mwIndex *yir, const double *ypr, const mwIndex ynnz,
           mwIndex iwsize, bool *cfound, mwIndex *iwork)
{
  mwIndex inz,jnz,knz, i;
  mwIndex * yinx;
/* ------------------------------------------------------------
   Partition working array [yinx(ynnz+2), iwork(log_2(ynnz+1))].
   ------------------------------------------------------------ */
  yinx = iwork;
  iwork += ynnz + 2;
  iwsize -= ynnz + 2;
  intmbsearch(yinx, cfound, xir, xnnz, yir, ynnz, iwork, iwsize);
  jnz = yinx[1];
  memcpy(zir, xir, jnz * sizeof(mwIndex));
  memcpy(zpr, xpr, jnz * sizeof(double));
  for(i = 0; i < ynnz; i++){
    inz = yinx[i+1];
    if(cfound[i])
      zpr[jnz] = xpr[inz++] + ypr[i];
    else
      zpr[jnz] = ypr[i];
    zir[jnz++] = yir[i];
    knz = yinx[i+2]-inz;
    memcpy(zir + jnz, xir + inz, knz * sizeof(mwIndex));
    memcpy(zpr + jnz, xpr + inz, knz * sizeof(double));
    jnz += knz;
  }
  return jnz;
}
Пример #3
0
/* ************************************************************
   PROCEDURE smakereal
   INPUT
     xir,xpr,xpi - sparse vector with xnnz nonzeros, in PSD ONLY!.
     xnnz - length of xir,xpr,xpi (PSD only).
     idelta - subscript adjustment of 1st PSD entry
     cpxsi - length twons increasing integer array. The old subscripts
       of the kth Hermitian block in x are cpxsi[2*k]:cpxsi[2*k+1]-1.
     twons - twons/2 is number of Hermitian PSD blocks.
     lenfull - length of full(x)-vector, 1 beyond last possible subscript.
     iwsize Length of iwork, should be 2*(1+ns) + floor(log_2(1+2*ns)).
   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+2*ns + floor(log_2(1+2*ns)).
   RETURNS ynnz (<=2*xnnz), number of nonzeros in y.
   ************************************************************ */
mwIndex smakereal(mwIndex *yir, double *ypr,
	      const mwIndex *xir, const double *xpr, const double *xpi,
	      const mwIndex xnnz, const mwIndex idelta,
	      const mwIndex *cpxsi, const mwIndex twons, const mwIndex lenfull,
	      bool *cfound, mwIndex *iwork, mwIndex iwsize)
{
  mwIndex i,j,k,inz,jnz;
  mwIndex *ipos;
/* ------------------------------------------------------------
   Partition WORKING ARRAY:
   ------------------------------------------------------------ */
  ipos = iwork;         /* length 2*(1+ns) array */
  iwork += 2 + twons;
  iwsize -= 2 + twons;
/* ------------------------------------------------------------
   Locate cpxsi in x(jcs:end); these mark the start+ends of Hermitian blocks,
   and hence the complement are real blocks.
   ------------------------------------------------------------ */
  if(intmbsearch(ipos, cfound, xir, xnnz, cpxsi, twons, iwork, iwsize) != 0)
    mexErrMsgTxt("Out of working space");
/* ------------------------------------------------------------
   Write real PSD blocks into y, i.e. skip Hermitian blocks
   ------------------------------------------------------------ */
  memcpy(ypr, xpr, ipos[1] * sizeof(double));
  if(idelta != 0)
    intscalaradd(yir, idelta, xir, ipos[1]);
  else
    memcpy(yir, xir, ipos[1] * sizeof(mwIndex));
  jnz = ipos[1];
  j = idelta;             /* subscript adjustment */
  for(i = 0; i < twons; ){
    j -= cpxsi[i+1] - cpxsi[i];               /* skip complex block */
    i += 2;
    inz = ipos[i];
    k = ipos[i + 1] - inz;
    memcpy(ypr + jnz, xpr + inz, k * sizeof(double));
    intscalaradd(yir+jnz, j, xir+inz, k);
    jnz += k;
  }
/* ------------------------------------------------------------
   Write Hermitian PSD blocks into y
   ------------------------------------------------------------ */
  j += lenfull;    /* j points to 1st available index for Hermitian blocks */
  for(i = 0; i < twons; i += 2){
    k = cpxsi[i];              /* Old 1st index of Herm PSD block */
/* ---------- write real part ---------- */
    writenz(yir, ypr, &jnz, xir, xpr, ipos[i+1],ipos[i+2],j-k);
    j += cpxsi[i+1] - k;                 /* point to 1st available index */
/* ---------- write imag part ---------- */
    if(xpi != (double *) NULL)
      writenz(yir, ypr, &jnz, xir, xpi, ipos[i+1],ipos[i+2],j-k);
    j += cpxsi[i+1] - k;                 /* point to 1st available index */
  }
/* ------------------------------------------------------------
   RETURN number of nonzeros written into y
   ------------------------------------------------------------ */
  return jnz;
}
Пример #4
0
/* ************************************************************
   PROCEDURE findblks
   INPUT
     Ajc1, Ajc2, Air, m  - sparse N x m matrix, we only consider nonzeros
       in Air[Ajc1[k]:Ajc2[k]-1], k=0:m-1.
     blkstart, nblk - length nblk integer array of subscripts.
     blkstartm1 - length nblk array, blkstartm1[k]=blkstart[k]-1
     iwsize - length of iwork, iwsize = nblk+2+floor(log(1+nblk)/log(2)).
   OUTPUT
     Ablkjc, Ablkir - sparse nblk x m matrix, less than sum(Ajc2-Ajc1)
       nonzeros.
   WORK
     cfound - length nblk char work array
     iwork  - length iwsize = nblk+2+floor(log(1+nblk)/log(2)) work array.
   ************************************************************ */
void findblks(mwIndex *Ablkir, mwIndex *Ablkjc, const mwIndex *Ajc1,const mwIndex *Ajc2,
              const mwIndex *Air, const mwIndex *blkstart, const mwIndex *blkstartm1,
              const mwIndex m,const mwIndex nblk,
              mwIndex iwsize, bool *cfound, mwIndex *iwork)
{
  mwIndex i,j,inz,ajnnz;
  mwIndex *ipos;
/* ------------------------------------------------------------
   Partition working array into ipos(nblk+2), iwork.
   ------------------------------------------------------------ */
  ipos = iwork;
  iwork += nblk+2;
  iwsize -= nblk+2;
  inz = 0;
  for(j = 0; j < m; j++){
    Ablkjc[j] = inz;
/* ------------------------------------------------------------
   If A(:,j) has more nonzeros than blkstart, we search blkstart
   ------------------------------------------------------------ */
    if((ajnnz = Ajc2[j]-Ajc1[j]) > nblk){
      intmbsearch(ipos, cfound, Air+Ajc1[j], ajnnz,
                  blkstart, nblk, iwork, iwsize);
      for(i = 0; i < nblk; i++)
        if(ipos[i+2] > ipos[i+1])
          Ablkir[inz++] = i;
    }
    else{
/* ------------------------------------------------------------
   If A(:,j) has less nonzeros than blkstart, we search those nonzeros
   within blkstartm1. The position of the nonzero is then the block number+1.
   ------------------------------------------------------------ */
      intmbsearch(ipos, cfound, blkstartm1,nblk, Air+Ajc1[j],ajnnz,
                  iwork, iwsize);
      for(i = 0; i < ajnnz; i++)
        if(ipos[i+1] > ipos[i])         /* New block number ? */
          Ablkir[inz++] = ipos[i+1] - 1;   /* ipos is block number + 1 */
    }
  }
/* ------------------------------------------------------------
   Close last column of Ablk
   ------------------------------------------------------------ */
  Ablkjc[m] = inz;
}
Пример #5
0
/* ************************************************************
   PROCEDURE partitA
   INPUT
     Ajc, Air, m  - sparse N x m matrix
     blkstart, nblk - length nblk integer array of subscripts.
     iwsize - length of iwork, iwsize = floor(log(1+nblk)/log(2)).
   OUTPUT
     Ablkjc - length (nblk+2)*m array. Rows 1+(1:nblk) list 1st nonzero
       with subscript at or beyond blkstart.
   WORK
     cfound - length nblk char work array
     iwork  - length iwsize = floor(log(1+nblk)/log(2)) work array.
   ************************************************************ */
void partitA(int *Ablkjc, const int *Ajc,const int *Air,
             const int *blkstart, const int m,const int nblk,
             const int iwsize, char *cfound, int *iwork)
{
  int j, L;
  L = nblk+2;
  for(j = 0; j < m; j++)
    intmbsearch(Ablkjc + j*L, cfound, Air+Ajc[j], Ajc[j+1]-Ajc[j],
		blkstart, nblk, iwork, iwsize);
  for(j = 0; j < m; j++)
    intadd(Ablkjc + j*L, Ajc[j],L);
}
Пример #6
0
/* ************************************************************
   PROCEDURE partitA
   INPUT
     Ajc, Air, m  - sparse N x m matrix
     blkstart, nblk - length nblk integer array of subscripts.
     iwsize - length of iwork, iwsize = floor(log(1+nblk)/log(2)).
   OUTPUT
     Ablkjc - length (nblk+1)*m array. Rows 1+(1:nblk) list 1st nonzero
       with subscript at or beyond blkstart.
   WORK
     cfound - length nblk char work array
     iwork  - length iwsize = floor(log(1+nblk)/log(2)) work array.
   ************************************************************ */
void partitA(mwIndex *Ablkjc, const mwIndex *Ajc,const mwIndex *Air,
             const mwIndex *blkstart, const mwIndex m,const mwIndex nblk,
             const mwIndex iwsize, bool *cfound, mwIndex *iwork)
{
  mwIndex j, L;
  L = nblk+2;
  for(j = 0; j < m; j++)
    intmbsearch(Ablkjc + j*L, cfound, Air+Ajc[j], Ajc[j+1]-Ajc[j],
		blkstart, nblk, iwork, iwsize);
  for(j = 0; j < m; j++)
    intadd(Ablkjc + j*L, Ajc[j],L);
}
Пример #7
0
/* ************************************************************
   PROCEDURE fmakereal
   INPUT
     xir,xpi - sparse imaginary vector with xnnz "nonzeros" in LP/Lorentz.
        If xpi == NULL, then all imaginary data is zero.
     xnnz - length of xir,xpi, before PSD part.
     cpxf - length nf integer array, listing free imaginary vars.
     nf - length of cpxf
     iwsize Length of iwork, should be 2+nf + floor(log_2(1+nf)).
   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+nf + floor(log_2(1+nf)).
   RETURNS ynnz (<=2*xnnz), number of free imag nonzeros in y.
   ************************************************************ */
mwIndex fmakereal(mwIndex *yir, double *ypr, const mwIndex *xir, const double *xpi,
	     const mwIndex xnnz, const mwIndex *cpxf, const mwIndex nf,
	     bool *cfound, mwIndex *iwork, mwIndex iwsize)
{
  mwIndex i,jnz;
  mwIndex *ipos;
  double yj;

  if(xpi == (double *) NULL)
    return 0;                  /* No imaginary nonzeros */
/* ------------------------------------------------------------
   Partition WORKING ARRAY:
   ------------------------------------------------------------ */
  ipos = iwork;
  iwork += 2 + nf;
  iwsize -= 2 + nf;
/* ------------------------------------------------------------
   Locate cpx.f in xir(1:xnnz)
   ------------------------------------------------------------ */
  if(intmbsearch(ipos, cfound, xir, xnnz, cpxf, nf, iwork, iwsize) != 0)
    mexErrMsgTxt("Out of working space");
/* ------------------------------------------------------------
   Write y = sparse(imag(x(cpx.f))), the free imaginary components
   ------------------------------------------------------------ */
  jnz = 0;
  for(i = 0; i < nf; i++)
    if(cfound[i] != 0){
      if( (yj = xpi[ipos[i+1]]) != 0.0){
	ypr[jnz] = yj;
	yir[jnz] = i;
	jnz++;
      }
    }
/* ------------------------------------------------------------
   RETURN number of (free imag) nonzeros in y
   ------------------------------------------------------------ */
  return jnz;
}
Пример #8
0
/* ************************************************************
   PROCEDURE xmakereal
   INPUT
     xir,xpr,xpi - sparse vector with xnnz nonzeros in LP/Lor.
     xnnz - length of xir,xpr,xpi; counting only LP/Lor nonzeros.
     idelta - Subscript adjustment for x(1), i.e. nf.
     cpxx - length nx integer array, listing Lorentz constrained
       imaginary vars.
     nx - length of cpxx.
     iwsize Length of iwork, should be 2+nx + floor(log_2(1+nx)).
   OUTPUT
     yir, ypr - sparse real output vector, ynnz nonzeros.
   WORK ARRAYS
     cfound - length nx character working array.
     iwork - lengt iwsize working array. Needs
      iwsize >= 2+nx + floor(log_2(1+nx)).
   RETURNS ynnz (<=2*xnnz), number of nonzeros in y.
   ************************************************************ */
mwIndex xmakereal(mwIndex *yir, double *ypr,
	      const mwIndex *xir, const double *xpr, const double *xpi,
	      const mwIndex xnnz, const mwIndex idelta, const mwIndex *cpxx, const mwIndex nx,
	      bool *cfound, mwIndex *iwork, mwIndex iwsize)
{
  mwIndex i,j,k,inz,jnz;
  mwIndex *ipos;
  double yj;
/* ------------------------------------------------------------
   Partition WORKING ARRAY:
   ------------------------------------------------------------ */
  ipos = iwork;
  iwork += 2 + nx;
  iwsize -= 2 + nx;
/* ------------------------------------------------------------
   Locate cpx.x in xir(1:xnnz)
   ------------------------------------------------------------ */
  if(intmbsearch(ipos, cfound, xir, xnnz, cpxx, nx, iwork, iwsize) != 0)
    mexErrMsgTxt("Out of working space");
/* ------------------------------------------------------------
   Write y(nf:nf+dimflqr+nx) = merge( real(x), imag(x(cpx.xcomplex)) )
   ------------------------------------------------------------ */
  memcpy(ypr, xpr, ipos[1] * sizeof(double));
  if(idelta != 0)
    intscalaradd(yir, idelta, xir, ipos[1]);
  else
    memcpy(yir, xir, ipos[1] * sizeof(mwIndex));
  jnz = ipos[1];
  for(i = 0; i < nx; ){
    if(cfound[i++]){
      inz = ipos[i];
      j = xir[inz] + idelta + i;         /* new index of imag part */
      if((yj = xpr[inz]) != 0.0){
	ypr[jnz] = yj;
	yir[jnz] = j-1;              /* index of real part */
	jnz++;
      }
      if(xpi != (double *) NULL)
        if((yj = xpi[inz]) != 0.0){
          ypr[jnz] = yj;
          yir[jnz] = j;                /* imag part */
          jnz++;
        }
      inz++;   /* point to first nonzero in x beyond cpx.x(i) */
    }
    else
      inz = ipos[i];    /*  point to first nonzero in x beyond cpx.x(i) */
/* ------------------------------------------------------------
   Let y(nf+i+(cpx.x(i)+1:cpx.x(i+1)-1)) = real(x(cpx.x(i)+1:cpx.x(i+1)-1))
   If i==nx, then this is simply the remainder.
   ------------------------------------------------------------ */
    k = ipos[i+1] - inz;                  /* number of nonzeros to copy */
    memcpy(ypr + jnz, xpr + inz, k * sizeof(double));
    intscalaradd(yir+jnz, idelta + i, xir+inz, k);     /* adjust subscript */
    jnz += k;
  }
/* ------------------------------------------------------------
   RETURN number of nonzeros written into y
   ------------------------------------------------------------ */
  return jnz;
}