Пример #1
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
   y = mJdetd(detd,K)
   ************************************************************ */
void mexFunction(const int nlhs, mxArray *plhs[],
  const int nrhs, const mxArray *prhs[])
{
 mwIndex i,nexti,k;
 double detdk;
 double *y;
 const double *detd;
 coneK cK;

/* ------------------------------------------------------------
   Check for proper number of arguments 
   ------------------------------------------------------------ */
 if(nrhs < NPARIN)
   mexErrMsgTxt("mJdetd requires more input arguments.");
 if (nlhs > NPAROUT)
   mexErrMsgTxt("mJdetd generates 1 output argument.");
/* ------------------------------------------------------------
   Disassemble cone K structure
   ------------------------------------------------------------ */
 conepars(K_IN, &cK);
/* ------------------------------------------------------------
   Get input detd
   ------------------------------------------------------------ */
 if(mxGetM(DETD_IN) * mxGetN(DETD_IN) != cK.lorN)
   mexErrMsgTxt("detd size mismatch");
 detd = mxGetPr(DETD_IN);
/* ------------------------------------------------------------
   Allocate output y(qDim)
   ------------------------------------------------------------ */
 Y_OUT =  mxCreateDoubleMatrix(cK.qDim, 1, mxREAL);
 y = mxGetPr(Y_OUT);
/* ------------------------------------------------------------
   LORENTZ: yk = [-detd(k); detd(k)* ones(nk-1,1)]
   ------------------------------------------------------------ */
 i = 0;
 nexti = 0;
 for(k = 0; k < cK.lorN; k++){
   nexti += cK.lorNL[k];
   detdk = detd[k];
   y[i] = -detdk;
   for(++i; i < nexti; i++)
     y[i] = detdk;
 }
}
Пример #2
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
   ************************************************************ */
void mexFunction(const int nlhs, mxArray *plhs[],
  const int nrhs, const mxArray *prhs[])
{
  int i,k, nk;
  double *y;
  const double *d,*rdetd,*x;
  coneK cK;
/* ------------------------------------------------------------
   Check for proper number of arguments 
   ------------------------------------------------------------ */
  mxAssert(nrhs >= NPARIN, "qscaleK requires more input arguments.");
  mxAssert(nlhs <= NPAROUT, "qscaleK generates 1 output argument.");
/* ------------------------------------------------------------
   Disassemble cone K structure
   ------------------------------------------------------------ */
  conepars(K_IN, &cK);
/* ------------------------------------------------------------
   Get scale data: (d,rdetd) and input x.
   ------------------------------------------------------------ */
  mxAssert(mxGetM(D_IN) * mxGetN(D_IN) >= cK.lpN + cK.qDim, "d size mismatch");
  d = mxGetPr(D_IN) + cK.lpN;              /* skip LP part */
  mxAssert(mxGetM(RDETD_IN) * mxGetN(RDETD_IN) == cK.lorN, "rdetx size mismatch");
  rdetd = mxGetPr(RDETD_IN);
  mxAssert(mxGetM(X_IN) * mxGetN(X_IN) == cK.qDim, "x size mismatch");
  x = mxGetPr(X_IN);
/* ------------------------------------------------------------
   Allocate output Y
   ------------------------------------------------------------ */
  Y_OUT =  mxCreateDoubleMatrix(cK.qDim, 1, mxREAL);
  y = mxGetPr(Y_OUT);
/* ------------------------------------------------------------
   The actual job is done here: y=D(d)x, Lorentz part.
   ------------------------------------------------------------ */
  for(k = 0; k < cK.lorN; k++){               /* LORENTZ */
    nk = cK.lorNL[k];
    qlmul(y, d,x,rdetd[k],nk);
    y += nk; x += nk; d += nk;
  }
}
Пример #3
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
     y = vecsym(x,K)

     Computes "symmetrization of x: Yk = (Xk+Xk')/2
   ************************************************************ */
void mexFunction(const int nlhs, mxArray *plhs[],
  const int nrhs, const mxArray *prhs[])
{
 mxArray *output_array[1], *Xk;

 coneK cK;
 int k, nk, nksqr, lqDim,lenfull;
 const double *x;
 double *y;

 /* ------------------------------------------------------------
    Check for proper number of arguments
    ------------------------------------------------------------ */
 mxAssert(nrhs >= 2, "vecsym requires 2 input arguments.");
 mxAssert(nlhs <= 1, "vecsym generates 1 output argument.");
 /* ------------------------------------------------------------
    Disassemble cone K structure
    ------------------------------------------------------------ */
 conepars(K_IN, &cK);
 /* ------------------------------------------------------------
    Compute some statistics based on cone K structure
    ------------------------------------------------------------ */
 lqDim = cK.lpN + cK.qDim;
 lenfull = lqDim + cK.rDim + cK.hDim;
 /* ------------------------------------------------------------
    Get input vector x
    ------------------------------------------------------------ */
 mxAssert(!mxIsSparse(X_IN), "x must be full.");
 mxAssert(mxGetM(X_IN) * mxGetN(X_IN) == lenfull, "Parameter `x' size mismatch.");
 x = mxGetPr(X_IN);
/* ------------------------------------------------------------
   Allocate output vector y, and make it vecsym(x)
   ------------------------------------------------------------ */
 Y_OUT = mxCreateDoubleMatrix(lenfull, 1, mxREAL);
 y = mxGetPr(Y_OUT);
 memcpy(y,x,lqDim * sizeof(double));
 x += lqDim; y += lqDim;
 vecsymPSD(y, x,cK.rsdpN,cK.sdpN,cK.sdpNL);
}
Пример #4
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
   ************************************************************ */
void mexFunction(const int nlhs, mxArray *plhs[],
  const int nrhs, const mxArray *prhs[])
{
  int i,k, nk;
  double *y;
  const double *x,*qdetx;
  coneK cK;
/* ------------------------------------------------------------
   Check for proper number of arguments 
   ------------------------------------------------------------ */
  mxAssert(nrhs >= NPARIN, "qinvsqrt requires more input arguments.");
  mxAssert(nlhs <= NPAROUT, "qinvsqrt generates less output arguments.");
/* ------------------------------------------------------------
   Disassemble cone K structure
   ------------------------------------------------------------ */
  conepars(K_IN, &cK);
/* ------------------------------------------------------------
   Get inputs x, qdetx
   ------------------------------------------------------------ */
  mxAssert(mxGetM(X_IN) * mxGetN(X_IN) >= cK.lpN + cK.qDim, "x size mismatch");
  x = mxGetPr(X_IN) + cK.lpN;              /* skip LP part */
  mxAssert(mxGetM(QDETX_IN) * mxGetN(QDETX_IN) == cK.lorN, "qdetx size mismatch");
  qdetx = mxGetPr(QDETX_IN);
/* ------------------------------------------------------------
   Allocate output y
   ------------------------------------------------------------ */
  Y_OUT =  mxCreateDoubleMatrix(cK.qDim, 1, mxREAL);
  y = mxGetPr(Y_OUT);
/* ------------------------------------------------------------
   The actual job is done here: y = w^{-1/2}, Lorentz part.
   ------------------------------------------------------------ */
  for(k = 0; k < cK.lorN; k++){               /* LORENTZ */
    nk = cK.lorNL[k];
    powminhalf(y, x,qdetx[k],nk);
    y += nk; x += nk;
  }
}
Пример #5
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
   ************************************************************ */
void mexFunction(const int nlhs, mxArray *plhs[],
  const int nrhs, const mxArray *prhs[])
{
  const mxArray *UD_FIELD;
  mwIndex lenfull, lenud, sdplen, fwsiz, i,k;
  double *fwork, *y,*permPr;
  const double *x,*ud;
  mwIndex *perm, *iwork;
  coneK cK;
  bool use_pivot, transp;

/* ------------------------------------------------------------
   Check for proper number of arguments 
   ------------------------------------------------------------ */
  if(nrhs < NPARIN){
    transp = 0;
    mxAssert(nrhs >= NPARINMIN, "psdscale requires more input arguments.");
  }
  else
    transp = (bool)mxGetScalar(TRANSP_IN);
  mxAssert(nlhs <= NPAROUT, "psdscale generates less output arguments.");
/* ------------------------------------------------------------
   Disassemble cone K structure
   ------------------------------------------------------------ */
  conepars(K_IN, &cK);
/* ------------------------------------------------------------
   Get statistics of cone K structure
   ------------------------------------------------------------ */
  lenud = cK.rDim + cK.hDim;
  lenfull = cK.lpN +  cK.qDim + lenud;
  sdplen = cK.rLen + cK.hLen;
/* ------------------------------------------------------------
   Get scale data: ud.{u,perm}.
   ------------------------------------------------------------ */
  if(!mxIsStruct(UD_IN)){
    mxAssert(mxGetM(UD_IN) * mxGetN(UD_IN) == lenud, "ud size mismatch."); /* ud is vector */
    ud = mxGetPr(UD_IN);
    use_pivot = 0;
  }
  else{                         /* ud is structure */
    UD_FIELD = mxGetField(UD_IN,(mwIndex)0,"u");
      mxAssert( UD_FIELD!= NULL,  "Field ud.u missing.");    /* ud.u */
    mxAssert(mxGetM(UD_FIELD) * mxGetN(UD_FIELD) == lenud, "ud.u size mismatch.");
    ud = mxGetPr(UD_FIELD);
    UD_FIELD = mxGetField(UD_IN,(mwIndex)0,"perm");                       /* ud.perm */
    if((use_pivot = (UD_FIELD != NULL))){
      if(mxGetM(UD_FIELD) * mxGetN(UD_FIELD) == sdplen)
        permPr = mxGetPr(UD_FIELD);
      else {
        mxAssert(mxGetM(UD_FIELD) * mxGetN(UD_FIELD) == 0, "ud.perm size mismatch");
        use_pivot = 0;
      }
    }
  }
/* ------------------------------------------------------------
   Get input x
   ------------------------------------------------------------ */
  mxAssert(!mxIsSparse(X_IN), "Sparse x not supported by this version of psdscale.");
  x = mxGetPr(X_IN);
/* ------------------------------------------------------------
   Validate x-input, and let x point to PSD part.
   ------------------------------------------------------------ */
  if(mxGetM(X_IN) * mxGetN(X_IN) == lenfull)
    x += cK.lpN + cK.qDim;
  else mxAssert(mxGetM(X_IN) * mxGetN(X_IN) == lenud, "size x mismatch.");
/* ------------------------------------------------------------
   Allocate output Y(lenud)
   ------------------------------------------------------------ */
  Y_OUT =  mxCreateDoubleMatrix(lenud, (mwSize)1, mxREAL);
  y = mxGetPr(Y_OUT);
/* ------------------------------------------------------------
   Allocate fwork 2 * [ max(cK.rMaxn^2, 2*cK.hMaxn^2) ]
   iwork = mwIndex(sdplen)
   ------------------------------------------------------------ */
  fwsiz = MAX(SQR(cK.rMaxn),2*SQR(cK.hMaxn));
  fwork = (double *) mxCalloc( MAX(1,2 * fwsiz), sizeof(double));
  iwork = (mwIndex *) mxCalloc( MAX(1, sdplen), sizeof(mwIndex) );
/* ------------------------------------------------------------
   Convert Fortran to C-style in perm:
   ------------------------------------------------------------ */
  if(use_pivot){
    perm = iwork;
    for(k = 0; k < sdplen; k++){
      i = permPr[k];
      perm[k] = --i;
    }
  }
  else
    perm = (mwIndex *) NULL;
/* ------------------------------------------------------------
   The actual job is done here:.
   ------------------------------------------------------------ */
  psdscaleK(y, ud, perm, x, cK, transp, fwork);
/* ------------------------------------------------------------
   Release working arrays.
   ------------------------------------------------------------ */
  mxFree(fwork);
  mxFree(iwork);
}
Пример #6
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
   x = whichcpx(K)
   ************************************************************ */
void mexFunction(const int nlhs, mxArray *plhs[],
  const int nrhs, const mxArray *prhs[])
{
  int i,j,iwsiz, nxcomplex, cpxf;
  int *iwork, *lorNL, *rconeNL, *xcomplex;
  double *myPr;
  const double *xcomplexPr;
  mxArray *MY_FIELD;
  const char *CPXFieldnames[] = {"f", "q", "r", "x"};
  coneK cK;
/* ------------------------------------------------------------
   Check for proper number of arguments 
   ------------------------------------------------------------ */
  mxAssert(nrhs >= 1, "whichcpx requires 1 input argument.");
  mxAssert(nlhs <= 1, "whichcpx generates 1 output argument.");
/* ------------------------------------------------------------
   Disassemble cone K structure
   ------------------------------------------------------------ */
  conepars(K_IN, &cK);
  if( (MY_FIELD = mxGetField(K_IN,0,"xcomplex")) == NULL){  /* K.xcomplex */
    nxcomplex = 0;
  }
  else{
    nxcomplex = mxGetM(MY_FIELD) * mxGetN(MY_FIELD);
    xcomplexPr = mxGetPr(MY_FIELD);
  }
  if(nxcomplex > 0){
/* ------------------------------------------------------------
   ALLOCATE working arrays:
   iwork(2*nxcomplex+lorN+rconeN))
   ------------------------------------------------------------ */
    iwsiz = 2* nxcomplex + cK.lorN + cK.rconeN;
    iwork = (int *) mxCalloc(MAX(iwsiz,1), sizeof(int));
    xcomplex = iwork + nxcomplex;
    lorNL = xcomplex + nxcomplex;
    rconeNL = lorNL + cK.lorN;
/* ------------------------------------------------------------
   Convert double to int
   ------------------------------------------------------------ */
    for(i = 0; i < nxcomplex; i++){
      j = xcomplexPr[i];                       /* double to int */
      xcomplex[i] = --j;                       /* Fortran to C */
    }
    for(i = 0; i < cK.lorN; i++)
      lorNL[i] = cK.lorNL[i];                  /* double to int */
    for(i = 0; i < cK.rconeN; i++)
      rconeNL[i] = cK.rconeNL[i];              /* double to int */
/* ------------------------------------------------------------
   The real work:
   ------------------------------------------------------------ */
    cpxf = whichcpx(iwork, xcomplex, lorNL,rconeNL,
		    nxcomplex, cK.frN + cK.lpN, cK.lorN, cK.rconeN);
    nxcomplex -= cpxf;
  }
/* ------------------------------------------------------------
   If xcomplex = []:
   ------------------------------------------------------------ */
  else{
    cpxf = 0;
    iwsiz = 0;
  }
/* ------------------------------------------------------------
   Create output structure CPX
   ------------------------------------------------------------ */
  CPX_OUT = mxCreateStructMatrix(1, 1, NCPX_FIELDS, CPXFieldnames);
  MY_FIELD = mxCreateDoubleMatrix(cpxf,1,mxREAL);      /* cpx.f */
  myPr = mxGetPr(MY_FIELD);
  for(i = 0; i < cpxf; i++)
    myPr[i] = 1.0 + iwork[i];                          /* int to double */
  mxSetField(CPX_OUT, 0,"f", MY_FIELD);
  MY_FIELD = mxCreateDoubleMatrix(cK.lorN,1,mxREAL);      /* cpx.q */
  if(iwsiz > 0){
    myPr = mxGetPr(MY_FIELD);
    for(i = 0; i < cK.lorN; i++)
      myPr[i] = lorNL[i];                              /* int to double */
  }
  mxSetField(CPX_OUT, 0,"q", MY_FIELD);
  MY_FIELD = mxCreateDoubleMatrix(cK.rconeN,1,mxREAL);      /* cpx.r */
  if(iwsiz > 0){
    myPr = mxGetPr(MY_FIELD);
    for(i = 0; i < cK.rconeN; i++)
      myPr[i] = rconeNL[i];                              /* int to double */
  }
  mxSetField(CPX_OUT, 0,"r", MY_FIELD);
  MY_FIELD = mxCreateDoubleMatrix(nxcomplex,1,mxREAL);      /* cpx.x */
  myPr = mxGetPr(MY_FIELD);
  for(i = 0; i < nxcomplex; i++)
    myPr[i] = 1.0 + xcomplex[i];                       /* int to double */
  mxSetField(CPX_OUT, 0,"x", MY_FIELD);
/* ------------------------------------------------------------
   Release working arrays
   ------------------------------------------------------------ */
  if(iwsiz > 0)
    mxFree(iwork);
}
Пример #7
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
   [qdetx,ux,ispos,perm] = factorK(x,K);
   ************************************************************ */
void mexFunction(const int nlhs, mxArray *plhs[],
  const int nrhs, const mxArray *prhs[])
{
  mxArray *myplhs[NPAROUT];
  coneK cK;
  int i,k,nk,nksqr, sdplen,sdpdim,lenfull, fwsiz, ispos;
  const double *x;
  double *ux, *fwork, *permPr, *qdetx, *up, *uppi;
  int *iwork, *perm;
  double uxk;
  char use_pivot;
/* ------------------------------------------------------------
   Check for proper number of arguments
   ------------------------------------------------------------ */
  mxAssert(nrhs >= NPARIN, "factorK requires more input arguments");
  mxAssert(nlhs <= NPAROUT, "factorK produces less output arguments");
  use_pivot = (nlhs == NPAROUT);
/* ------------------------------------------------------------
   Disassemble cone K structure
   ------------------------------------------------------------ */
  conepars(K_IN, &cK);
/* ------------------------------------------------------------
   Compute statistics: sdpdim = rdim+hdim, sdplen = sum(K.s).
   ------------------------------------------------------------ */
  lenfull = cK.lpN +  cK.qDim + cK.rDim + cK.hDim;
  sdpdim = cK.rDim + cK.hDim;
  sdplen = cK.rLen + cK.hLen;
/* ------------------------------------------------------------
   Get input vector x, skip LP part
   ------------------------------------------------------------ */
  mxAssert(mxGetM(X_IN) * mxGetN(X_IN) == lenfull, "x size mismatch.");
  x = mxGetPr(X_IN) + cK.lpN;
/* ------------------------------------------------------------
   Allocate output qdetx(lorN), UX(sdpdim), perm(sdplen), ispos(1).
   ------------------------------------------------------------ */
  QDETX_OUT = mxCreateDoubleMatrix(cK.lorN, 1, mxREAL);
  qdetx = mxGetPr(QDETX_OUT);
  UX_OUT = mxCreateDoubleMatrix(sdpdim, 1, mxREAL);
  ux = mxGetPr(UX_OUT);
  ISPOS_OUT = mxCreateDoubleMatrix(1,1,mxREAL);
  PERM_OUT =  mxCreateDoubleMatrix(sdplen, 1, mxREAL);
  permPr = mxGetPr(PERM_OUT);
/* ------------------------------------------------------------
   Allocate working arrays iwork(sdplen),
   fwork(MAX(rmaxn^2,2*hmaxn^2) + MAX(rmaxn,hmaxn))
   ------------------------------------------------------------ */
  iwork = (int *) mxCalloc(sdplen, sizeof(int));
  perm = iwork;
  fwsiz = MAX(cK.rMaxn,cK.hMaxn);
  fwork = (double *) mxCalloc(fwsiz + MAX(SQR(cK.rMaxn),2*SQR(cK.hMaxn)),
                              sizeof(double));
  up = fwork + fwsiz;
  uppi = up + SQR(cK.hMaxn);
/* ------------------------------------------------------------
   LORENTZ:  qdetx = sqrt(qdet(x))
   ------------------------------------------------------------ */
  ispos = 1;
  for(k = 0; k < cK.lorN; k++){
    nk = cK.lorNL[k];
    if( (uxk = qdet(x,nk)) < 0.0){
      ispos = 0;
      break;
    }
    else
      qdetx[k] = sqrt(uxk);
    x += nk;
  }
/* ------------------------------------------------------------
   PSD: Cholesky factorization. If use_pivot, then do pivoting.
   ------------------------------------------------------------ */
  if(use_pivot){
    if(ispos)
      for(k = 0; k < cK.rsdpN; k++){                /* real symmetric */
        nk = cK.sdpNL[k];
        if(cholpivot(up,perm, x,nk, fwork)){
          ispos = 0;
          break;
        }
        uperm(ux, up, perm, nk);
        triu2sym(ux,nk);
        nksqr = SQR(nk);
        x += nksqr; ux += nksqr;
        perm += nk;
      }
/* ------------------------------------------------------------
   Complex Hermitian PSD pivoted Cholesky factorization
   ------------------------------------------------------------ */
    if(ispos)
      for(; k < cK.sdpN; k++){                    /* complex Hermitian */
        nk = cK.sdpNL[k];
        nksqr = SQR(nk);
        if(prpicholpivot(up,uppi,perm, x,x+nksqr,nk, fwork)){
          ispos = 0;
          break;
        }
        uperm(ux, up, perm, nk);                  /* real part */
        uperm(ux+nksqr, uppi, perm, nk);          /* imaginary part */
        triu2herm(ux,ux+nksqr,nk);
        nksqr += nksqr;                           /* 2*n^2 for real+imag */
        x += nksqr; ux += nksqr;
        perm += nk;
      }
/* ------------------------------------------------------------
   Convert "perm" to Fortran-index in doubles.
   ------------------------------------------------------------ */
    for(i = 0; i < sdplen; i++)
      permPr[i] = 1.0 + iwork[i];
  }
/* ------------------------------------------------------------
   PSD, !use_pivot: Cholesky without pivoting.
   First let ux = x, then ux=chol(ux).
   ------------------------------------------------------------ */
  else{           /* Cholesky real sym PSD without pivoting */
    if(ispos){
      memcpy(ux, x, sdpdim * sizeof(double));       /* copy real + complex */
      for(k = 0; k < cK.rsdpN; k++){                /* real symmetric */
        nk = cK.sdpNL[k];
        if(cholnopiv(ux,nk)){
          ispos = 0;
          break;
        }
        triu2sym(ux,nk);
        ux += SQR(nk);
      }
    }
/* ------------------------------------------------------------
   Complex Hermitian PSD Cholesky factorization, no pivoting.
   ------------------------------------------------------------ */
    if(ispos)
      for(; k < cK.sdpN; k++){                    /* complex Hermitian */
        nk = cK.sdpNL[k];
        nksqr = SQR(nk);
        if(prpicholnopiv(ux,ux+nksqr,nk)){
          ispos = 0;
         break;
        }
        triu2herm(ux,ux+nksqr,nk);
        ux += 2 * nksqr;
      }
  } /* !use_pivot */
/* ------------------------------------------------------------
   Return parameter ispos
   ------------------------------------------------------------ */
  *mxGetPr(ISPOS_OUT) = ispos;
/* ------------------------------------------------------------
   Release working arrays
   ------------------------------------------------------------ */
  mxFree(iwork);
  mxFree(fwork);
/* ------------------------------------------------------------
   Copy requested output parameters (at least 1), release others.
   ------------------------------------------------------------ */
  i = MAX(nlhs, 1);
  memcpy(plhs,myplhs, i * sizeof(mxArray *));
  for(; i < NPAROUT; i++)
    mxDestroyArray(myplhs[i]);
}
Пример #8
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
   ************************************************************ */
void mexFunction(const int nlhs, mxArray *plhs[],
  const int nrhs, const mxArray *prhs[])
{
  int inz, i, k, nk, nksqr, lenud, sdplen, gnnz;
  int *gjc, *iwork;
  const double *gjcPr;
  const double *g, *gk;
  double *y;
  coneK cK;
/* ------------------------------------------------------------
   Check for proper number of arguments 
   ------------------------------------------------------------ */
  mxAssert(nrhs >= NPARIN, "givensrot requires more input arguments.");
  mxAssert(nlhs <= NPAROUT, "givensrot generates less output arguments.");
/* ------------------------------------------------------------
   Disassemble cone K structure
   ------------------------------------------------------------ */
  conepars(K_IN, &cK);
/* ------------------------------------------------------------
   Get statistics of cone K structure
   ------------------------------------------------------------ */
  lenud = cK.rDim + cK.hDim;
  sdplen = cK.rLen + cK.hLen;
/* ------------------------------------------------------------
   Get inputs gjc,g,x
   ------------------------------------------------------------ */
  mxAssert(mxGetM(GJC_IN) * mxGetN(GJC_IN) == sdplen, "gjc size mismatch");
  gjcPr = mxGetPr(GJC_IN);
  g = (double *) mxGetPr(G_IN);
  gnnz = mxGetM(G_IN) * mxGetN(G_IN);
  mxAssert(mxGetM(X_IN) == lenud && mxGetN(X_IN) == 1, "x size mismatch");
/* ------------------------------------------------------------
   Allocate output y(lenud), and let y = x.
   ------------------------------------------------------------ */
  Y_OUT = mxCreateDoubleMatrix(lenud, 1, mxREAL);
  y = mxGetPr(Y_OUT);
  memcpy(y, mxGetPr(X_IN), lenud * sizeof(double));
/* ------------------------------------------------------------
   Allocate working array iwork(sum(K.s))
   ------------------------------------------------------------ */
  iwork = (int *) mxCalloc(MAX(1,sdplen), sizeof(int));
/* ------------------------------------------------------------
   Convert gjcPr from float to int, and store in gjc:=iwork.
   ------------------------------------------------------------ */
  gjc = iwork;
  for(i = 0; i < sdplen; i++)
    gjc[i] = gjcPr[i];                 /* don't subtract 1: already C-style */
/* ------------------------------------------------------------
   The actual job is done here: U_NEW = Q(g) * U_OLD
   ------------------------------------------------------------ */
  inz = 0;
  for(k = 0; k < cK.rsdpN; k++){                /* real symmetric */
    nk = cK.sdpNL[k];
    nksqr = SQR(nk);
    mxAssert(inz + 2 * gjc[nk-1] <= gnnz, "g size mismatch");
    gk = g+inz;
    matgivens(y, (twodouble *) gk, gjc, nk);
    y += nksqr;
    inz += 2 * gjc[nk-1];        /* each rotation consists of 2 doubles */
    gjc += nk;
  }
  for(; k < cK.sdpN; k++){                       /* complex Hermitian */
    nk = cK.sdpNL[k];
    nksqr = SQR(nk);
    mxAssert(inz + 3 * gjc[nk-1] <= gnnz, "g size mismatch");
    gk = g+inz;
    prpimatgivens(y,y+nksqr, (tridouble *) gk, gjc, nk);
    nksqr += nksqr;
    y += nksqr;
    inz += 3 * gjc[nk-1];            /* each rotation consists of 3 doubles */
    gjc += nk;
  }
/* ------------------------------------------------------------
   Release working arrays
   ------------------------------------------------------------ */
  mxFree(iwork);
}
Пример #9
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
     [lab,q] = eigK(x,K)
     Computes spectral coefficients of x w.r.t. K
   REMARK If this function is used internally by SeDuMi, then
     complex numbers are stored in a single real vector. To make
     it invokable from the Matlab command-line by the user, we
     also allow Matlab complex vector x.
   ************************************************************ */
void mexFunction(const int nlhs, mxArray *plhs[],
  const int nrhs, const mxArray *prhs[])
{
 mxArray *output_array[3], *Xk, *hXk;
 coneK cK;
 int k, nk, nksqr, lendiag,i,ii,nkp1, lenfull;
 double *lab,*q,*qpi,*labk,*xwork,*xpiwork;
 const double *x,*xpi;

/* ------------------------------------------------------------
   Check for proper number of arguments
   ------------------------------------------------------------ */
  mxAssert(nrhs >= NPARIN, "eigK requires more input arguments");
  mxAssert(nlhs <= NPAROUT, "eigK produces less output arguments");
/* ------------------------------------------------------------
   Disassemble cone K structure
   ------------------------------------------------------------ */
  conepars(K_IN, &cK);
/* ------------------------------------------------------------
   Compute statistics based on cone K structure
   ------------------------------------------------------------ */
  lendiag = cK.lpN + 2 * (cK.lorN + cK.rconeN) + cK.rLen + cK.hLen;
  lenfull = cK.lpN + cK.qDim + cK.rDim + cK.hDim;
  if(cK.rconeN > 0)
    for(i = 0; i < cK.rconeN; i++)
      lenfull += cK.rconeNL[i];
/* ------------------------------------------------------------
   Get input vector x
   ------------------------------------------------------------ */
  mxAssert(mxGetM(X_IN) * mxGetN(X_IN) == lenfull, "Size mismatch x");
  mxAssert(!mxIsSparse(X_IN), "x must be full (not sparse).");
  x = mxGetPr(X_IN);
  if(mxIsComplex(X_IN))
    xpi = mxGetPi(X_IN) + cK.lpN;
/* ------------------------------------------------------------
   Allocate output LAB(diag), eigvec Q(full for psd)
   ------------------------------------------------------------ */
  LAB_OUT = mxCreateDoubleMatrix(lendiag, 1, mxREAL);
  lab = mxGetPr(LAB_OUT);
  if(nlhs > 1){
    if(mxIsComplex(X_IN)){
      Q_OUT = mxCreateDoubleMatrix(cK.rDim, 1, mxCOMPLEX);
      qpi = mxGetPi(Q_OUT);
    }
    else
      Q_OUT = mxCreateDoubleMatrix(cK.rDim + cK.hDim, 1, mxREAL);
    q = mxGetPr(Q_OUT);
  }
/* ------------------------------------------------------------
   Allocate working arrays:
   ------------------------------------------------------------ */
  Xk = mxCreateDoubleMatrix(0,0,mxREAL);
  hXk = mxCreateDoubleMatrix(0,0,mxCOMPLEX);
  if(mxIsComplex(X_IN)){
    xwork = (double *) mxCalloc(MAX(1,2 * SQR(cK.rMaxn)), sizeof(double));
    xpiwork = xwork + SQR(cK.rMaxn);
  }
  else
    xwork =(double *) mxCalloc(MAX(1,SQR(cK.rMaxn)+2*SQR(cK.hMaxn)),
                               sizeof(double));
/* ------------------------------------------------------------
   The actual job is done here:.
   ------------------------------------------------------------ */
  if(cK.lpN){
/* ------------------------------------------------------------
   LP: lab = x
   ------------------------------------------------------------ */
    memcpy(lab, x, cK.lpN * sizeof(double));
    lab += cK.lpN; x += cK.lpN;
  }
/* ------------------------------------------------------------
   CONSIDER FIRST MATLAB-REAL-TYPE:
   ------------------------------------------------------------ */
  if(!mxIsComplex(X_IN)){                  /* Not Matlab-type complex */
/* ------------------------------------------------------------
   LORENTZ:  (I) lab = qeig(x)
   ------------------------------------------------------------ */
    for(k = 0; k < cK.lorN; k++){
      nk = cK.lorNL[k];
      qeig(lab,x,nk);
      lab += 2; x += nk;
    }
/* ------------------------------------------------------------
   RCONE: LAB = eig(X)     (Lorentz-Rcone's are not used internally)
   ------------------------------------------------------------ */
    for(k = 0; k < cK.rconeN; k++){
      nk = cK.rconeNL[k];
      rconeeig(lab,x[0],x[1],realssqr(x+2,nk-2));
      lab += 2; x += nk;
    }
/* ------------------------------------------------------------
   PSD: (I) LAB = eig(X)
   ------------------------------------------------------------ */
    if(nlhs < 2){
      for(k=0; k < cK.rsdpN; k++){                /* real symmetric */
        nk = cK.sdpNL[k];
        symproj(xwork,x,nk);              /* make it symmetric */
        mxSetM(Xk, nk);
        mxSetN(Xk, nk);
        mxSetPr(Xk, xwork);
        mexCallMATLAB(1, output_array, 1, &Xk, "eig");
        memcpy(lab, mxGetPr(output_array[0]), nk * sizeof(double));
/* ------------------------------------------------------------
   With mexCallMATLAB, we invoked the mexFunction "eig", which
   allocates a matrix struct *output_array[0], AND a block for the
   float data of that matrix.
   ==> mxDestroyArray() does not only free the float data, it
   also releases the matrix struct (and this is what we want).
   ------------------------------------------------------------ */
        mxDestroyArray(output_array[0]);
        lab += nk;  x += SQR(nk);
      }
/* ------------------------------------------------------------
   WARNING: Matlab's eig doesn't recognize Hermitian, hence VERY slow
   ------------------------------------------------------------ */
      for(; k < cK.sdpN; k++){                    /* complex Hermitian */
        nk = cK.sdpNL[k]; nksqr = SQR(nk);
        symproj(xwork,x,nk);              /* make it Hermitian */
        skewproj(xwork + nksqr,x+nksqr,nk);
        mxSetM(hXk, nk);
        mxSetN(hXk, nk);
        mxSetPr(hXk, xwork);
        mxSetPi(hXk, xwork + nksqr);     
        mexCallMATLAB(1, output_array, 1, &hXk, "eig");
        memcpy(lab, mxGetPr(output_array[0]), nk * sizeof(double));
        mxDestroyArray(output_array[0]);
        lab += nk;  x += 2 * nksqr;
      }
    }
    else{
/* ------------------------------------------------------------
   SDP: (II) (Q,LAB) = eig(X)
   ------------------------------------------------------------ */
      for(k=0; k < cK.rsdpN; k++){                /* real symmetric */
        nk = cK.sdpNL[k];
        symproj(xwork,x,nk);                      /* make it symmetric */
        mxSetM(Xk, nk);
        mxSetN(Xk, nk);
        mxSetPr(Xk, xwork);
        mexCallMATLAB(2, output_array, 1, &Xk, "eig");
        nksqr = SQR(nk);                                  /* copy Q-matrix */
        memcpy(q, mxGetPr(output_array[0]), nksqr * sizeof(double));
        nkp1 = nk + 1;                                   /* copy diag(Lab) */
        labk = mxGetPr(output_array[1]);
        for(i = 0, ii = 0; i < nk; i++, ii += nkp1)
          lab[i] = labk[ii];
        mxDestroyArray(output_array[0]);
        mxDestroyArray(output_array[1]);
        lab += nk;  x += nksqr; q += nksqr;
      }
      for(; k < cK.sdpN; k++){                    /* complex Hermitian */
        nk = cK.sdpNL[k]; nksqr = SQR(nk);
        symproj(xwork,x,nk);                      /* make it Hermitian */
        skewproj(xwork + nksqr,x+nksqr,nk);
        mxSetM(hXk, nk);
        mxSetN(hXk, nk);
        mxSetPr(hXk, xwork);
        mxSetPi(hXk, xwork+nksqr);
        mexCallMATLAB(2, output_array, 1, &hXk, "eig");
        memcpy(q, mxGetPr(output_array[0]), nksqr * sizeof(double));
        q += nksqr;
        if(mxIsComplex(output_array[0]))     /* if any imaginary part */
          memcpy(q, mxGetPi(output_array[0]), nksqr * sizeof(double));
        nkp1 = nk + 1;                              /* copy diag(Lab) */
        labk = mxGetPr(output_array[1]);
        for(i = 0, ii = 0; i < nk; i++, ii += nkp1)
          lab[i] = labk[ii];
        mxDestroyArray(output_array[0]);
        mxDestroyArray(output_array[1]);
        lab += nk;  x += 2 * nksqr; q += nksqr;
      }
    } /* [lab,q] = eigK */
  } /* !iscomplex */
  else{              /* is MATLAB type complex */
/* ------------------------------------------------------------
   LORENTZ:  (I) lab = qeig(x)
   ------------------------------------------------------------ */
    for(k = 0; k < cK.lorN; k++){
      nk = cK.lorNL[k];
      cxqeig(lab,x,xpi,nk);
      lab += 2; x += nk; xpi += nk;
    }
/* ------------------------------------------------------------
   RCONE: LAB = eig(X)     (Lorentz-Rcone's are not used internally)
   ------------------------------------------------------------ */
    for(k = 0; k < cK.rconeN; k++){
      nk = cK.rconeNL[k];
      rconeeig(lab,x[0],x[1],
               realssqr(x+2,nk-2) + realssqr(xpi+2,nk-2));
      lab += 2; x += nk; xpi += nk;
    }
/* ------------------------------------------------------------
   PSD: (I) LAB = eig(X)
   ------------------------------------------------------------ */
    for(k = 0; k < cK.sdpN; k++){
      nk = cK.sdpNL[k]; nksqr = SQR(nk);
      symproj(xwork,x,nk);              /* make it Hermitian */
      skewproj(xpiwork,xpi,nk);
      mxSetM(hXk, nk);
      mxSetN(hXk, nk);
      mxSetPr(hXk, xwork);
      mxSetPi(hXk, xpiwork);     
      if(nlhs < 2){
        mexCallMATLAB(1, output_array, 1, &hXk, "eig");
        memcpy(lab, mxGetPr(output_array[0]), nk * sizeof(double));
      }
      else{
        mexCallMATLAB(2, output_array, 1, &hXk, "eig");
        memcpy(q, mxGetPr(output_array[0]), nksqr * sizeof(double));
        if(mxIsComplex(output_array[0]))     /* if any imaginary part */
          memcpy(qpi, mxGetPi(output_array[0]), nksqr * sizeof(double));
        nkp1 = nk + 1;                              /* copy diag(Lab) */
        labk = mxGetPr(output_array[1]);
        for(i = 0, ii = 0; i < nk; i++, ii += nkp1)
          lab[i] = labk[ii];
        mxDestroyArray(output_array[1]);
        q += nksqr; qpi += nksqr;
      }
      mxDestroyArray(output_array[0]);
      lab += nk;  x += nksqr; xpi += nksqr;
    }
  } /* iscomplex */
/* ------------------------------------------------------------
   Release PSD-working arrays.
   ------------------------------------------------------------ */
  mxSetM(Xk,0); mxSetN(Xk,0); 
  mxSetPr(Xk, (double *) NULL);
  mxDestroyArray(Xk);
  mxSetM(hXk,0); mxSetN(hXk,0); 
  mxSetPr(hXk, (double *) NULL);   mxSetPi(hXk, (double *) NULL);
  mxDestroyArray(hXk);
  mxFree(xwork);
}
Пример #10
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
   [ux,ispos] = psdfactor(x,K);
   ************************************************************ */
void mexFunction(const int nlhs, mxArray *plhs[],
  const int nrhs, const mxArray *prhs[])
{
  mxArray *myplhs[NPAROUT];
  coneK cK;
  mwIndex k,nk,nksqr, sdplen,sdpdim,lenfull, ispos;
  const double *x;
  double *ux;
/* ------------------------------------------------------------
   Check for proper number of arguments
   ------------------------------------------------------------ */
  mxAssert(nrhs >= NPARIN, "psdfactor requires more input arguments");
  mxAssert(nlhs <= NPAROUT, "psdfactor produces less output arguments");
/* ------------------------------------------------------------
   Disassemble cone K structure
   ------------------------------------------------------------ */
  conepars(K_IN, &cK);
/* ------------------------------------------------------------
   Compute statistics: sdpdim = rdim+hdim, sdplen = sum(K.s).
   ------------------------------------------------------------ */
  lenfull = cK.lpN +  cK.qDim + cK.rDim + cK.hDim;
  sdpdim = cK.rDim + cK.hDim;
  sdplen = cK.rLen + cK.hLen;
/* ------------------------------------------------------------
   Get input vector x, skip LP + Lorentz part
   ------------------------------------------------------------ */
  x = mxGetPr(X_IN);
  if(mxGetM(X_IN) * mxGetN(X_IN) == lenfull)
    x += cK.lpN + cK.qDim;
  else mxAssert(mxGetM(X_IN) * mxGetN(X_IN) == sdpdim, "x size mismatch.");
/* ------------------------------------------------------------
   Allocate output UX(sdpdim), ispos(1).
   ------------------------------------------------------------ */
  UX_OUT = mxCreateDoubleMatrix(sdpdim, (mwSize)1, mxREAL);
  ux = mxGetPr(UX_OUT);
  ISPOS_OUT = mxCreateDoubleMatrix((mwSize)1,(mwSize)1,mxREAL);
/* ------------------------------------------------------------
   PSD: Cholesky factorization.
   Initialize  ispos = 1 and ux = x.
   ------------------------------------------------------------ */
  ispos = 1;
  memcpy(ux, x, sdpdim * sizeof(double));       /* copy real + complex */
  for(k = 0; k < cK.rsdpN; k++){                /* real symmetric */
    nk = cK.sdpNL[k];
/* ------------------------------------------------------------
   Attempt Cholesky on block k. Returns 1 if fail (i.e. not psd).
   ------------------------------------------------------------ */
    if(cholnopiv(ux,nk)){
      ispos = 0;
      break;
    }
    triu2sym(ux,nk);
    ux += SQR(nk);
  }
/* ------------------------------------------------------------
   Complex Hermitian PSD Cholesky factorization, no pivoting.
   ------------------------------------------------------------ */
  if(ispos)
    for(; k < cK.sdpN; k++){                    /* complex Hermitian */
      nk = cK.sdpNL[k];
      nksqr = SQR(nk);
      if(prpicholnopiv(ux,ux+nksqr,nk)){
        ispos = 0;
        break;
      }
      triu2herm(ux,ux+nksqr,nk);
      ux += 2 * nksqr;
    }
/* ------------------------------------------------------------
   Return parameter ispos
   ------------------------------------------------------------ */
  *mxGetPr(ISPOS_OUT) = ispos;
/* ------------------------------------------------------------
   Copy requested output parameters (at least 1), release others.
   ------------------------------------------------------------ */
  k = MAX(nlhs, 1);
  memcpy(plhs,myplhs, k * sizeof(mxArray *));
  for(; k < NPAROUT; k++)
    mxDestroyArray(myplhs[k]);
}
Пример #11
0
void mexFunction(
    const int nlhs, mxArray *plhs[],
    const int nrhs, const mxArray *prhs[] )
{
    mxArray *output_array[3], *Xk;
    coneK cK;
    mwSize nk, nkp1, nksqr, lendiag, lenud, lenfull, nmax;
    mwIndex k, i, ii;
    double *lab, *q, *labk;
    const double *x;
    
    /* Argument check */
    mxAssert(nrhs >= NPARIN, "psdeig requires more input arguments");
    mxAssert(nlhs <= NPAROUT, "psdeig produces less output arguments");
    
    /* Disassemble cone structure and determine output sizes */
    conepars(K_IN, &cK);
    lendiag = cK.rLen + cK.hLen;
    lenud = cK.rDim + cK.hDim;
    lenfull = cK.lpN + cK.qDim + lenud;
    
    /* Get input vector x and skip to the PSD terms */
    mxAssert( !mxIsSparse(X_IN), "x must be full (not sparse)." );
    x = mxGetPr(X_IN);
    if ( mxGetM(X_IN) * mxGetN(X_IN) != lenud ) {
        mxAssert( mxGetM(X_IN) * mxGetN(X_IN) == lenfull, "Size mismatch x" );
        x += cK.lpN + cK.qDim;       
    }
    
    /* Allocate the output arrays */
    LAB_OUT = mxCreateDoubleMatrix( lendiag, (mwSize)1, mxREAL );
    lab = mxGetPr( LAB_OUT );
    if ( nlhs > 1 ) {
        Q_OUT = mxCreateDoubleMatrix( lenud, (mwSize)1, mxREAL );
        q = mxGetPr( Q_OUT );
    }
  
    /* 
     * Real symmetric matrices   
     */
    if ( cK.rsdpN != 0 ) {
        nmax = 1;
        for ( k = 0 ; k != cK.rsdpN ; ++k ) {
            nk = (mwSize)cK.sdpNL[k];
            if ( nmax < nk ) nmax = nk;
        }
        Xk = mxCreateDoubleMatrix( nmax, nmax, mxREAL );
        for ( k = 0 ; k != cK.rsdpN ; ++k ) {
            nk = (mwSize)cK.sdpNL[k]; 
            nksqr = SQR(nk);
            mxSetM( Xk, nk ); mxSetN( Xk, nk );
            /* Symmetric projection onto the work array */
            symproj( mxGetPr(Xk), x, nk );
            if ( nlhs <= 1 ) {
                /* One argument only: lab */
                mexCallMATLAB( 1, output_array, 1, &Xk, "eig" );
                memcpy( lab, mxGetPr(output_array[0]), nk * sizeof(double) );
                mxDestroyArray( output_array[0] );
            } else {
                /* First argument: Q */
                mexCallMATLAB( 2, output_array, 1, &Xk, "eig" );
                memcpy( q, mxGetPr(output_array[0]), nksqr * sizeof(double) );
                q += nksqr;
                /* Second argument: extract diag(Lab) */
                nkp1 = nk + 1;
                labk = mxGetPr( output_array[1] );
                for(i = 0, ii = 0; i < nk; i++, ii += nkp1)
                    lab[i] = labk[ii];
                mxDestroyArray( output_array[0] );
                mxDestroyArray( output_array[1] );
            }
            lab += nk;
            x += nksqr;
        }
        mxDestroyArray( Xk );
    }
    
    /* Complex Hermitian matrices 
     * Note that if a complex argument is offered, even the "real" matrices
     * must be passed through here, just to be safe.
     */
    if ( cK.sdpN != cK.rsdpN ) {
        nmax = 1;
        for ( k = cK.rsdpN ; k != cK.sdpN ; ++k ) {
            nk = (mwSize)cK.sdpNL[k];
            if ( nmax < nk ) nmax = nk;
        }
        Xk = mxCreateDoubleMatrix( nmax, nmax, mxCOMPLEX );
        for ( k = cK.rsdpN ; k != cK.sdpN ; ++k ) {
            nk = (mwSize)cK.sdpNL[k]; 
            nksqr = SQR(nk);
            mxSetM(Xk, nk); mxSetN(Xk, nk);
            /* Skew-symmetric projection onto the work matrix */
            symproj( mxGetPr(Xk), x, nk );
            skewproj( mxGetPi(Xk), x + nksqr, nk );
            if ( nlhs <= 1 ) {
                /* One argument only: lab */
                mexCallMATLAB( 1, output_array, 1, &Xk, "eig" );
                memcpy(lab, mxGetPr(output_array[0]), nk * sizeof(double));
                mxDestroyArray(output_array[0]);
            } else {
                #ifdef USE_SVD
                mexCallMATLAB(3, output_array, 1, &Xk, "svd");
                #else
                mexCallMATLAB(2, output_array, 1, &Xk, "eig");
                #endif
                /* First argument: Q */
                memcpy( q, mxGetPr(output_array[0]), nksqr * sizeof(double) );
                q += nksqr;
                if( mxIsComplex(output_array[0]) )     /* if any imaginary part */
                    memcpy( q, mxGetPi(output_array[0]), nksqr * sizeof(double) );
                q += nksqr;
                /* Second argument: extract diag(Lab) */
                nkp1 = nk + 1;
                labk = mxGetPr(output_array[1]);
                for(i = 0, ii = 0; i < nk; i++, ii += nkp1)
                    lab[i] = labk[ii];
                mxDestroyArray(output_array[0]);
                mxDestroyArray(output_array[1]);
                #ifdef USE_SVD
                mxDestroyArray(output_array[2]);
                #endif
            }
            lab += nk;
            x += 2 * nksqr;
        }
        mxDestroyArray( Xk );
    }
    
}
Пример #12
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
   ************************************************************ */
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
  coneK cK;
  const mxArray *MY_FIELD;
  mwIndex m, i, j;
  const double *permPr;
  double *fwork;
  mwIndex *iwork, *perm, *invperm;
  jcir ada, ddota;
/* ------------------------------------------------------------
   Check for proper number of arguments
   ------------------------------------------------------------ */
  mxAssert(nrhs >= NPARIN, "getADA requires more input arguments.");
  mxAssert(nlhs <= NPAROUT, "getADA produces less output arguments.");
/* ------------------------------------------------------------
   Disassemble cone K structure
   ------------------------------------------------------------ */
  conepars(K_IN, &cK);
  m = mxGetM(ADA_IN);
/* ------------------------------------------------------------
   Allocate output matrix ADA with sparsity structure of ADA_IN,
   and initialize as a copy of ADA_IN.
   ------------------------------------------------------------ */
  mxAssert(mxGetN(ADA_IN) == m, "Size mismatch ADA.");
  mxAssert(mxIsSparse(ADA_IN), "ADA should be sparse.");
  ADA_OUT = mxDuplicateArray(ADA_IN);              /* ADA = ADA_IN */
  if(cK.lorN <= 0)                          /* READY if no LORENTZ blocks !*/
    return;
  ada.jc = mxGetJc(ADA_OUT);
  ada.ir = mxGetIr(ADA_OUT);
  ada.pr = mxGetPr(ADA_OUT);
/* ------------------------------------------------------------
   DISASSEMBLE DAt structure: DAt.q
   ------------------------------------------------------------ */
  mxAssert(mxIsStruct(DAT_IN), "DAt should be a structure.");
  MY_FIELD = mxGetField(DAT_IN,(mwIndex)0,"q");       /* DAt.q */
  mxAssert( MY_FIELD != NULL, "Missing field DAt.q.");
  mxAssert(mxGetM(MY_FIELD) == cK.lorN && mxGetN(MY_FIELD) == m, "Size mismatch DAt.q");
  mxAssert(mxIsSparse(MY_FIELD), "DAt.q should be sparse.");
  ddota.jc = mxGetJc(MY_FIELD);
  ddota.ir = mxGetIr(MY_FIELD);
  ddota.pr = mxGetPr(MY_FIELD);
/* ------------------------------------------------------------
   DISASSEMBLE Aord structure: Aord.qperm
   ------------------------------------------------------------ */
  mxAssert(mxIsStruct(AORD_IN), "Aord should be a structure.");
  MY_FIELD = mxGetField(AORD_IN,(mwIndex)0,"qperm");        /* Aord.qperm */
  mxAssert( MY_FIELD != NULL, "Missing field Aord.qperm.");
  mxAssert(mxGetM(MY_FIELD) * mxGetN(MY_FIELD) == m, "Size mismatch Aord.qperm.");
  permPr = mxGetPr(MY_FIELD);
/* ------------------------------------------------------------
   Only work to do if ~isempty(ddota):
   ------------------------------------------------------------ */
  if(ddota.jc[m] > 0){
/* ------------------------------------------------------------
   ALLOCATE working arrays:
   iwork(2*m) = [perm(m), invperm(m)].
   fwork[lorN]
   ------------------------------------------------------------ */
    iwork = (mwIndex *) mxCalloc(MAX(2 * m,1), sizeof(mwIndex));
    perm = iwork;
    invperm = perm + m;
    fwork  = (double *) mxCalloc(MAX(cK.lorN,1), sizeof(double));
/* ------------------------------------------------------------
   perm to integer C-style
   ------------------------------------------------------------ */
    for(i = 0; i < m; i++){
      j = (mwIndex) permPr[i];
      mxAssert(j>0,"");
      perm[i] = --j;
    }
/* ------------------------------------------------------------
   Let invperm(perm) = 0:m-1.
   ------------------------------------------------------------ */
    for(i = 0; i < m; i++)
      invperm[perm[i]] = i;
/* ------------------------------------------------------------
   ACTUAL COMPUTATION: ADA += DAt.q'*DAt.q.
   ------------------------------------------------------------ */
    getada2(ada, ddota, perm, invperm, m, cK.lorN, fwork);
/* ------------------------------------------------------------
   RELEASE WORKING ARRAYS.
   ------------------------------------------------------------ */
    mxFree(fwork);
    mxFree(iwork);
  } /* !isempty(ddota) */
}
Пример #13
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
   x = eyeK(K)
   ************************************************************ */
void mexFunction(const int nlhs, mxArray *plhs[],
  const int nrhs, const mxArray *prhs[])
{
 int i,j,k, nk, lenfull;
 double *x;
 coneK cK;

/* ------------------------------------------------------------
   Check for proper number of arguments 
   ------------------------------------------------------------ */
 mxAssert(nrhs == 1, "eyeK requires 1 input argument.");
 mxAssert(nlhs == 1, "eyeK generates 1 output argument.");
 /* ------------------------------------------------------------
    Disassemble cone K structure
    ------------------------------------------------------------ */
 conepars(K_IN, &cK);
 /* ------------------------------------------------------------
    Get statistics of cone K structure
    ------------------------------------------------------------ */
 lenfull = cK.lpN +  cK.qDim + cK.rDim + cK.hDim;
 for(k = 0; k < cK.rconeN; k++)
   lenfull += cK.rconeNL[k];
 /* ------------------------------------------------------------
    Allocate output x
    ------------------------------------------------------------ */
 X_OUT =  mxCreateDoubleMatrix(lenfull, 1, mxREAL);
 x = mxGetPr(X_OUT);
 /* ------------------------------------------------------------
    The actual job is done here:.
    ------------------------------------------------------------ */
 /* ------------------------------------------------------------
    LP: x = ones(K.l,1)
    ------------------------------------------------------------ */
 for(k = 0; k < cK.lpN; k++)
   x[k] = 1.0;
 x += cK.lpN;
 /* ------------------------------------------------------------
    LORENTZ: x(1) = sqrt(2)
    ------------------------------------------------------------ */
 for(k = 0; k < cK.lorN; k++){
   nk = cK.lorNL[k];
   x[0] = M_SQRT2;
   x += nk;
 }
 /* ------------------------------------------------------------
    RCONE: x(1) = x(2) = 1
    ------------------------------------------------------------ */
 for(k = 0; k < cK.rconeN; k++){
   nk = cK.rconeNL[k];
   x[0] = 1.0;
   x[1] = 1.0;
   x += nk;
 }
 /* ------------------------------------------------------------
    PSD:  x = eye(nk)
    ------------------------------------------------------------ */
 for(k = 0; k < cK.sdpN; k++){
   nk = cK.sdpNL[k];
   for(i = 0, j = 0; i < nk; i++, j += nk+1)
     x[j] = 1.0;
   x += (1 + (k >= cK.rsdpN)) * SQR(nk);
 }
}
Пример #14
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
   [beta,U,d,perm] = qrpfacK(x,K)
   ************************************************************ */
void mexFunction( int nlhs, mxArray *plhs[],
  int nrhs, const mxArray *prhs[])
{
  mxArray *myplhs[NPAROUT];
  coneK cK;
  mwIndex i,k,nk,nksqr, sdpdim, qsize;
  double *q, *r, *betak;
/* ------------------------------------------------------------
   Check for proper number of arguments
   ------------------------------------------------------------ */
  mxAssert(nrhs >= NPARIN, "qrK requires more input arguments");
  mxAssert(nlhs <= NPAROUT, "qrK produces less output arguments");
/* ------------------------------------------------------------
   Disassemble cone K structure
   ------------------------------------------------------------ */
  conepars(K_IN, &cK);
/* ------------------------------------------------------------
   Compute statistics: sdpdim = rdim+hdim, qsize = sdpdim + hLen.
   ------------------------------------------------------------ */
  sdpdim = cK.rDim + cK.hDim;
  qsize = sdpdim + cK.hLen;
/* ------------------------------------------------------------
   Check input vector x.
   ------------------------------------------------------------ */
  mxAssert(mxGetM(X_IN) * mxGetN(X_IN) == sdpdim, "size mismatch x");
/* ------------------------------------------------------------
   Allocate output Q(qsize), R(sdpdim)
   and let r = x.
   ------------------------------------------------------------ */
  Q_OUT = mxCreateDoubleMatrix(qsize, (mwSize)1, mxREAL);
  q = mxGetPr(Q_OUT);
  R_OUT = mxCreateDoubleMatrix(sdpdim, (mwSize)1, mxREAL);
  r = mxGetPr(R_OUT);
  memcpy(r, mxGetPr(X_IN), sdpdim * sizeof(double));
/* ------------------------------------------------------------
   The actual job is done here:
   ------------------------------------------------------------ */
  for(k = 0; k < cK.rsdpN; k++){                /* real symmetric */
    nk = (mwIndex) cK.sdpNL[k];
    nksqr = SQR(nk);
    qrfac(q+nksqr-nk,q,r, nk);
    r += nksqr; 
    q += nksqr;
  }
  for(; k < cK.sdpN; k++){                      /* complex Hermitian */
    nk = (mwIndex) cK.sdpNL[k];
    nksqr = SQR(nk);
    betak = q + 2*nksqr;
    prpiqrfac(betak,q,q+nksqr, r,r+nksqr, nk);
    nksqr += nksqr;
    r += nksqr; 
    q += nksqr + nk;               /* nk for betak */
  }
/* ------------------------------------------------------------
   Copy requested output parameters (at least 1), release others.
   ------------------------------------------------------------ */
  i = MAX(nlhs, 1);
  memcpy(plhs,myplhs, i * sizeof(mxArray *));
  for(; i < NPAROUT; i++)
    mxDestroyArray(myplhs[i]);
}
Пример #15
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
     y = vectril(x,K)

   For the PSD submatrices, we let Yk = tril(Xk+Xk').
   Complex numbers are stored as vec([real(Xk) imag(Xk)]).
   NB: x and y are sparse.
   ************************************************************ */
void mexFunction(const int nlhs, mxArray *plhs[],
  const int nrhs, const mxArray *prhs[])
{
  int i, j, k, jnz, m,lenfull, firstPSD, maxn, iwsize;
  jcir x,y;
  int *iwork, *psdNL, *blkstart, *xblk;
  char *cwork;
  double *fwork;
  coneK cK;
/* ------------------------------------------------------------
   Check for proper number of arguments
   ------------------------------------------------------------ */
  mxAssert(nrhs >= NPARIN, "vectril requires more input arguments");
  mxAssert(nlhs <= NPAROUT, "vectril produces less output arguments");
/* ------------------------------------------------------------
   Disassemble cone K structure
   ------------------------------------------------------------ */
  conepars(K_IN, &cK);
/* ------------------------------------------------------------
   Compute statistics based on cone K structure
   ------------------------------------------------------------ */
  firstPSD = cK.frN + cK.lpN + cK.qDim;
  for(i = 0; i < cK.rconeN; i++)        /* add dim of rotated cone */
    firstPSD += cK.rconeNL[i];
  lenfull =  firstPSD + cK.rDim + cK.hDim;
/* ------------------------------------------------------------
   Get inputs x, blkstart
   ------------------------------------------------------------ */
  mxAssert(mxGetM(X_IN) == lenfull, "X size mismatch.");
  m = mxGetN(X_IN);                       /* number of columns to handle */
  mxAssert( mxIsSparse(X_IN), "X should be sparse.");
  x.pr = mxGetPr(X_IN);
  x.jc = mxGetJc(X_IN);
  x.ir = mxGetIr(X_IN);
/* ------------------------------------------------------------
   Allocate output Y = sparse([],[],[],length(x),m,nnz(x))
   ------------------------------------------------------------ */
  Y_OUT = mxCreateSparse(lenfull, m, x.jc[m], mxREAL);
  y.pr = mxGetPr(Y_OUT);
  y.jc = mxGetJc(Y_OUT);
  y.ir = mxGetIr(Y_OUT);
  y.jc[0] = 0;
/* ------------------------------------------------------------
   If x = [], then we are ready with y=[]. Otherwise, proceed:
   ------------------------------------------------------------ */
  if(x.jc[m] > 0){
/* ------------------------------------------------------------
   Allocate iwork[iwsize],
   iwsize := maxn*(2*maxn+1)+log_2(1+maxn*(maxn-1)/2), where maxn := max(K.s);
   cwork[maxn*(maxn-1)/2], fwork(maxn^2), int psdNL(length(K.s)).
   int blkstart(sdpN+1), xblk(sdpDim)
   ------------------------------------------------------------ */
    maxn = MAX(cK.rMaxn,cK.hMaxn);
    iwsize = log(1 + maxn*(maxn-1)/2) / log(2);
    iwsize += maxn * (2*maxn+1);
    iwork = (int *) mxCalloc(MAX(1,iwsize), sizeof(int));
    cwork = (char *) mxCalloc(MAX(1,maxn*(maxn-1)/2), sizeof(char));
    fwork = (double *) mxCalloc(MAX(1,SQR(maxn)), sizeof(double));
    psdNL = (int *) mxCalloc(MAX(1,cK.sdpN), sizeof(int));
    blkstart = (int *) mxCalloc(1 + cK.sdpN, sizeof(int));
    xblk = (int *) mxCalloc(MAX(1,cK.rDim + cK.hDim), sizeof(int));
/* ------------------------------------------------------------
   double -> int for K.s
   ------------------------------------------------------------ */
    for(i = 0; i < cK.sdpN; i++)
      psdNL[i] = cK.sdpNL[i];
/* ------------------------------------------------------------
   Let k = xblk(j-blkstart[0]) iff
   blkstart[k] <= j < blkstart[k+1], k=0:psdN-1.
   ------------------------------------------------------------ */
    j = firstPSD;
    for(i = 0; i < cK.rsdpN; i++){     /* real sym */
      blkstart[i] = j;
      j += SQR(psdNL[i]);
    }
    for(; i < cK.sdpN; i++){            /* complex herm. */
      blkstart[i] = j;
      j += 2*SQR(psdNL[i]);
    }
    blkstart[cK.sdpN] = j;
    mxAssert(j - firstPSD == cK.rDim + cK.hDim, "Size mismatch blkstart, K.");
    j = 0;
    for(k = 0; k < cK.sdpN; k++){
      i = blkstart[k+1] - blkstart[0];
      while(j < i)
        xblk[j++] = k;
    }
/* ------------------------------------------------------------
   Let y(:,i)= vectril(x(:,i)), for i=1:m.
   ------------------------------------------------------------ */
    jnz = 0;            /* points into y */
    for(i = 0; i < m; i++){
      y.jc[i] = jnz;
      jnz += vectril(y.ir+jnz,y.pr+jnz, x.ir+x.jc[i],x.pr+x.jc[i],
                     x.jc[i+1]-x.jc[i],
                     psdNL, blkstart, xblk, cK.rsdpN,cK.sdpN, iwsize,
                     cwork, iwork, fwork);
    }
    y.jc[m] = jnz;    /* nnz written into y */
    mxAssert(jnz <= x.jc[m],"");
/* ------------------------------------------------------------
   REALLOC: Shrink Y to its current size
   ------------------------------------------------------------ */
    jnz = MAX(jnz,1);
    if( (y.pr = (double *) mxRealloc(y.pr, jnz*sizeof(double))) == NULL)
      mexErrMsgTxt("Memory reallocation error");
    mxSetPr(Y_OUT,y.pr);
    if( (y.ir = (int *) mxRealloc(y.ir, jnz*sizeof(int))) == NULL)
      mexErrMsgTxt("Memory reallocation error");
    mxSetIr(Y_OUT,y.ir);
    mxSetNzmax(Y_OUT,jnz);
/* ------------------------------------------------------------
   Release working arrays
   ------------------------------------------------------------ */
    mxFree(xblk);
    mxFree(blkstart);
    mxFree(psdNL);
    mxFree(fwork);
    mxFree(iwork);
    mxFree(cwork);
  }
}
Пример #16
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
   ************************************************************ */
void mexFunction(const int nlhs, mxArray *plhs[],
  const int nrhs, const mxArray *prhs[])
{
  mwIndex lenfull, lenud, fwsiz, i, ifirst;
  double *fwork, *y;
  const double *x,*ud;
  mwIndex *psdNL;
  coneK cK;
  bool transp;
/* ------------------------------------------------------------
   Check for proper number of arguments 
   ------------------------------------------------------------ */
  if(nrhs < NPARIN){
    transp = 0;
    mxAssert(nrhs >= NPARINMIN, "psdinvscale requires more input arguments.");
  }
  else
    transp = (bool) mxGetScalar(TRANSP_IN);
  mxAssert(nlhs <= NPAROUT, "psdinvscale generates 1 output argument.");
/* ------------------------------------------------------------
   Disassemble cone K structure
   ------------------------------------------------------------ */
  conepars(K_IN, &cK);
/* ------------------------------------------------------------
   Get statistics of cone K structure
   ------------------------------------------------------------ */
  ifirst = cK.lpN +  cK.qDim;
  lenud = cK.rDim + cK.hDim;
  lenfull = ifirst + lenud;
/* ------------------------------------------------------------
   Get inputs ud, x.
   ------------------------------------------------------------ */
  mxAssert(mxGetM(UD_IN) * mxGetN(UD_IN) == lenud, "ud size mismatch.");
  ud = mxGetPr(UD_IN);
  mxAssert(!mxIsSparse(X_IN), "Sparse x not supported by this version of psdinvscale.");
  mxAssert(mxGetM(X_IN) * mxGetN(X_IN) == lenfull, "size x mismatch.");
  x = mxGetPr(X_IN) + ifirst;           /* Jump to PSD part */
/* ------------------------------------------------------------
   Allocate output Y
   ------------------------------------------------------------ */
  Y_OUT =  mxCreateDoubleMatrix(lenud, (mwSize)1, mxREAL);
  y = mxGetPr(Y_OUT);
/* ------------------------------------------------------------
   Allocate fwork [ max(cK.rMaxn^2, 2*cK.hMaxn^2) ]
   psdNL = mwIndex(cK.sdpN)
   ------------------------------------------------------------ */
  fwsiz = MAX(SQR(cK.rMaxn),2*SQR(cK.hMaxn));
  fwork = (double *) mxCalloc( MAX(1,fwsiz), sizeof(double));
  psdNL = (mwIndex *) mxCalloc( MAX(1, cK.sdpN), sizeof(mwIndex) );
/* ------------------------------------------------------------
   Convert double to mwIndex
   ------------------------------------------------------------ */
  for(i = 0; i < cK.sdpN; i++)
    psdNL[i] = cK.sdpNL[i];               /* double to mwIndex */
/* ------------------------------------------------------------
   The real job:
   ------------------------------------------------------------ */
  psdinvscale(y, ud,x,psdNL,cK.rsdpN,cK.sdpN,transp, fwork);
/* ------------------------------------------------------------
   Release working arrays.
   ------------------------------------------------------------ */
  mxFree(fwork);
  mxFree(psdNL);
}
Пример #17
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
   ************************************************************ */
void mexFunction(const int nlhs, mxArray *plhs[],
                 const int nrhs, const mxArray *prhs[])
{
    mxArray *myplhs[NPAROUT];
    int i,j,k, nk, nksqr, lenud, sdplen, gnnz, inz, maxKs,maxKssqr, rgnnz, hgnnz;
    const double *uOld, *permOld;
    double *u, *d, *gjcPr, *permPr, *fwork, *fworkpi;
    int *perm, *gjc;
    double *g, *gk;
    double maxusqr;
    coneK cK;
    char use_pivot;
    /* ------------------------------------------------------------
       Check for proper number of arguments
       ------------------------------------------------------------ */
    mxAssert(nrhs >= NPARINMIN, "urotorder requires more input arguments.");
    mxAssert(nlhs <= NPAROUT, "urotorder generates less output arguments.");
    /* ------------------------------------------------------------
       Disassemble cone K structure
       ------------------------------------------------------------ */
    conepars(K_IN, &cK);
    /* ------------------------------------------------------------
       Get statistics of cone K structure
       ------------------------------------------------------------ */
    lenud = cK.rDim + cK.hDim;
    sdplen = cK.rLen + cK.hLen;
    /* ------------------------------------------------------------
       Get scalar input MAXU and input vectors U_IN, PERM_IN
       ------------------------------------------------------------ */
    maxusqr = mxGetScalar(MAXU_IN);
    maxusqr *= maxusqr;
    mxAssert(mxGetM(U_IN) * mxGetN(U_IN) == lenud, "u size mismatch");
    uOld = mxGetPr(U_IN);
    use_pivot = 0;
    if(nrhs >= NPARIN)                              /* Optional permIN */
        if(mxGetM(PERM_IN) * mxGetN(PERM_IN) > 0) {
            mxAssert(mxGetM(PERM_IN) * mxGetN(PERM_IN) == sdplen, "perm size mismatch");
            use_pivot = 1;
            permOld = mxGetPr(PERM_IN);
        }
    /* ------------------------------------------------------------
       Allocate output U_OUT, and initialize u_out = u_in.
       ------------------------------------------------------------ */
    U_OUT = mxCreateDoubleMatrix(lenud, 1, mxREAL);
    u = mxGetPr(U_OUT);
    memcpy(u, mxGetPr(U_IN), lenud * sizeof(double));
    /* ------------------------------------------------------------
       Allocate outputs PERM(sum(K.s)), GJC(sum(K.s))
       ------------------------------------------------------------ */
    PERM_OUT = mxCreateDoubleMatrix(sdplen, 1, mxREAL);
    permPr = mxGetPr(PERM_OUT);
    GJC_OUT  = mxCreateDoubleMatrix(sdplen, 1, mxREAL);
    gjcPr = mxGetPr(GJC_OUT);
    /* ------------------------------------------------------------
       Allocate g initially as length (lenud - cK.rLen) / 2. The final
       length can be shorter (viz. gjc[sum(K.s)])
       ------------------------------------------------------------ */
    rgnnz = (cK.rDim - cK.rLen) / 2;               /* n(n-1)/2 real sym */
    hgnnz = (cK.hDim - 2*cK.hLen) / 4;             /* n(n-1)/2 complex herm */
    gnnz = rgnnz * 2 + hgnnz * 3;
    g = (double *) mxCalloc(MAX(1, gnnz),sizeof(double));
    /* ------------------------------------------------------------
       Allocate working arrays:
       Let maxKssqr = max(rMaxn^2, 2*hMaxn^2), then
       integer perm(max(K.s)), gjc(max(K.s))
       double d(max(K.s)), fwork(maxKs)
       ------------------------------------------------------------ */
    maxKs = MAX(cK.rMaxn,cK.hMaxn);                     /* max(K.s) */
    maxKssqr = MAX(SQR(cK.rMaxn),2 * SQR(cK.hMaxn));    /* max(K.s.^2) */
    perm = (int *) mxCalloc(MAX(1,maxKs), sizeof(int));
    gjc  = (int *) mxCalloc(MAX(1,maxKs), sizeof(int));
    d     = (double *) mxCalloc(MAX(1,maxKs), sizeof(double));
    fwork = (double *) mxCalloc(MAX(1,maxKssqr), sizeof(double));
    fworkpi = fwork + SQR(cK.hMaxn);
    /* ------------------------------------------------------------
       The actual job is done here: U_NEW = Q(g) * U_OLD
       ------------------------------------------------------------ */
    inz = 0;
    for(k = 0; k < cK.rsdpN; k++) {               /* real symmetric */
        nk = cK.sdpNL[k];
        nksqr = SQR(nk);
        memcpy(fwork, uOld, nksqr *sizeof(double));   /* k-th U-matrix */
        gk = g+inz;
        rotorder(perm, fwork, gjc, (twodouble *) gk, d, maxusqr, nk);
        /* ------------------------------------------------------------
           Physically reorder the columns from fwork into u. Then Let
           tril(U) = triu(U)'
           ------------------------------------------------------------ */
        uperm(u, fwork, perm, nk);
        triu2sym(u,nk);
        /* ------------------------------------------------------------
           Let perm_out = perm_in(perm)
           ------------------------------------------------------------ */
        if(use_pivot) {
            for(i = 0; i < nk; i++)
                permPr[i] = permOld[perm[i]];
            permOld += nk;
        }
        else
            for(i = 0; i < nk; i++)
                permPr[i] = 1.0 + perm[i];
        for(i = 0; i < nk; i++)
            gjcPr[i] = gjc[i];               /* don't add 1 */
        inz += 2 * gjc[nk-1];     /* next PSD block. Rotation g is 2 doubles */
        gjcPr += nk;
        permPr += nk;
        uOld += nksqr;
        u += nksqr;
    }
    /* ------------------------------------------------------------
       Complex Hermitian
       ------------------------------------------------------------ */
    for(; k < cK.sdpN; k++) {                   /* complex Hermitian */
        nk = cK.sdpNL[k];
        nksqr = SQR(nk);
        memcpy(fwork, uOld, nksqr *sizeof(double));   /* k-th complex U-matrix */
        memcpy(fworkpi, uOld+nksqr, nksqr *sizeof(double));
        gk = g+inz;
        prpirotorder(perm, fwork,fworkpi, gjc, (tridouble *) gk, d, maxusqr, nk);
        /* ------------------------------------------------------------
           Physically reorder the columns from fwork into u. Then Let
           tril(U) = triu(U)'
           ------------------------------------------------------------ */
        uperm(u, fwork, perm, nk);                  /* real part */
        uperm(u+nksqr, fworkpi, perm, nk);      /* imaginary part */
        triu2herm(u,u+nksqr, nk);
        /* ------------------------------------------------------------
           Let perm_out = perm_in(perm)
           ------------------------------------------------------------ */
        if(use_pivot) {
            for(i = 0; i < nk; i++)
                permPr[i] = permOld[perm[i]];
            permOld += nk;
        }
        else
            for(i = 0; i < nk; i++)
                permPr[i] = 1.0 + perm[i];
        for(i = 0; i < nk; i++)
            gjcPr[i] = gjc[i];               /* don't add 1 */
        inz += 3 * gjc[nk-1];     /* next PSD block. Rotation g is 3 doubles */
        gjcPr += nk;
        permPr += nk;
        nksqr += nksqr;
        uOld += nksqr;
        u += nksqr;
    }
    /* ------------------------------------------------------------
       In total, we used inz doubles in Givens rotations.
       Reallocate (shrink) g accordingly.
       ------------------------------------------------------------ */
    mxAssert(inz <= gnnz,"");
    if(inz > 0) {
        if((g = (double *) mxRealloc(g, inz * sizeof(double))) == NULL)
            mexErrMsgTxt("Memory allocation error.");
    }
    else {
        mxFree(g);
        g = (double *) NULL;
    }
    /* ------------------------------------------------------------
       Assign g to a length inz output vector
       ------------------------------------------------------------ */
    G_OUT = mxCreateDoubleMatrix(1, 1, mxREAL);
    mxFree(mxGetPr(G_OUT));
    mxSetPr(G_OUT, (double *) g);
    mxSetM(G_OUT, inz);
    /* ------------------------------------------------------------
       Release working arrays
       ------------------------------------------------------------ */
    mxFree(fwork);
    mxFree(d);
    mxFree(gjc);
    mxFree(perm);
    /* ------------------------------------------------------------
       Copy requested output parameters (at least 1), release others.
       ------------------------------------------------------------ */
    i = MAX(nlhs, 1);
    memcpy(plhs,myplhs, i * sizeof(mxArray *));
    for(; i < NPAROUT; i++)
        mxDestroyArray(myplhs[i]);
}
Пример #18
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
   ************************************************************ */
void mexFunction(const int nlhs, mxArray *plhs[],
  const int nrhs, const mxArray *prhs[])
{
 mxArray *output_array[3], *Xk, *hXk;
 coneK cK;
 int k, nk, nkp1, nksqr, lendiag,lenud, lenfull, i,ii;
 double *lab,*q,*labk,*xwork;
 const double *x;

/* ------------------------------------------------------------
   Check for proper number of arguments
   ------------------------------------------------------------ */
  mxAssert(nrhs >= NPARIN, "psdeig requires more input arguments");
  mxAssert(nlhs <= NPAROUT, "psdeig produces less output arguments");
/* ------------------------------------------------------------
   Disassemble cone K structure
   ------------------------------------------------------------ */
  conepars(K_IN, &cK);
/* ------------------------------------------------------------
   Compute statistics based on cone K structure
   ------------------------------------------------------------ */
  lendiag = cK.rLen + cK.hLen;
  lenud = cK.rDim + cK.hDim;
  lenfull = cK.lpN + cK.qDim + lenud;
/* ------------------------------------------------------------
   Get input vector x
   ------------------------------------------------------------ */
  mxAssert(!mxIsSparse(X_IN), "x must be full (not sparse).");
  x = mxGetPr(X_IN);
  if(mxGetM(X_IN) * mxGetN(X_IN) != lenud){
    mxAssert(mxGetM(X_IN) * mxGetN(X_IN) == lenfull, "Size mismatch x");
    x += cK.lpN + cK.qDim;       /* point to PSD part */
  }

/* ------------------------------------------------------------
   Allocate output LAB(diag), eigvec Q(full for psd)
   ------------------------------------------------------------ */
  LAB_OUT = mxCreateDoubleMatrix(lendiag, 1, mxREAL);
  lab = mxGetPr(LAB_OUT);
  if(nlhs > 1){
    Q_OUT = mxCreateDoubleMatrix(lenud, 1, mxREAL);
    q = mxGetPr(Q_OUT);
  }
/* ------------------------------------------------------------
   Allocate working arrays:
   ------------------------------------------------------------ */
  Xk = mxCreateDoubleMatrix(0,0,mxREAL);
  hXk = mxCreateDoubleMatrix(0,0,mxCOMPLEX);
  xwork =(double *) mxCalloc(MAX(1,SQR(cK.rMaxn)+2*SQR(cK.hMaxn)),
                             sizeof(double));
/* ------------------------------------------------------------
   PSD: (I) LAB = eig(X)
   ------------------------------------------------------------ */
  if(nlhs < 2){
    for(k=0; k < cK.rsdpN; k++){                /* real symmetric */
      nk = cK.sdpNL[k];
      symproj(xwork,x,nk);              /* make it symmetric */
      mxSetM(Xk, nk);
      mxSetN(Xk, nk);
      mxSetPr(Xk, xwork);
      mexCallMATLAB(1, output_array, 1, &Xk, "eig");
      memcpy(lab, mxGetPr(output_array[0]), nk * sizeof(double));
/* ------------------------------------------------------------
   With mexCallMATLAB, we invoked the mexFunction "eig", which
   allocates a matrix struct *output_array[0], AND a block for the
   float data of that matrix.
   ==> mxDestroyArray() does not only free the float data, it
   also releases the matrix struct (and this is what we want).
   ------------------------------------------------------------ */
      mxDestroyArray(output_array[0]);
      lab += nk;  x += SQR(nk);
    }
/* ------------------------------------------------------------
   WARNING: Matlab's eig doesn't recognize Hermitian, hence VERY slow
   ------------------------------------------------------------ */
    for(; k < cK.sdpN; k++){                    /* complex Hermitian */
      nk = cK.sdpNL[k]; nksqr = SQR(nk);
      symproj(xwork,x,nk);              /* make it Hermitian */
      skewproj(xwork + nksqr,x+nksqr,nk);
      mxSetM(hXk, nk);
      mxSetN(hXk, nk);
      mxSetPr(hXk, xwork);
      mxSetPi(hXk, xwork + nksqr);     
      mexCallMATLAB(1, output_array, 1, &hXk, "eig");
      memcpy(lab, mxGetPr(output_array[0]), nk * sizeof(double));
      mxDestroyArray(output_array[0]);
      lab += nk;  x += 2 * nksqr;
    }
  } /* nlhs < 2 */
  else{
/* ------------------------------------------------------------
   SDP: (II) (Q,LAB) = eig(X)
   ------------------------------------------------------------ */
    for(k=0; k < cK.rsdpN; k++){                /* real symmetric */
      nk = cK.sdpNL[k];
      symproj(xwork,x,nk);                      /* make it symmetric */
      mxSetM(Xk, nk);
      mxSetN(Xk, nk);
      mxSetPr(Xk, xwork);
      mexCallMATLAB(2, output_array, 1, &Xk, "eig");
      nksqr = SQR(nk);                                  /* copy Q-matrix */
      memcpy(q, mxGetPr(output_array[0]), nksqr * sizeof(double));
      nkp1 = nk + 1;                                   /* copy diag(Lab) */
      labk = mxGetPr(output_array[1]);
      for(i = 0, ii = 0; i < nk; i++, ii += nkp1)
        lab[i] = labk[ii];
      mxDestroyArray(output_array[0]);
      mxDestroyArray(output_array[1]);
      lab += nk;  x += nksqr; q += nksqr;
    }
    for(; k < cK.sdpN; k++){                    /* complex Hermitian */
      nk = cK.sdpNL[k]; nksqr = SQR(nk);
      symproj(xwork,x,nk);                      /* make it Hermitian */
      skewproj(xwork + nksqr,x+nksqr,nk);
      mxSetM(hXk, nk);
      mxSetN(hXk, nk);
      mxSetPr(hXk, xwork);
      mxSetPi(hXk, xwork+nksqr);
#ifdef USE_SVD
      mexCallMATLAB(3, output_array, 1, &hXk, "svd");
#else
      mexCallMATLAB(2, output_array, 1, &hXk, "eig");
#endif
      memcpy(q, mxGetPr(output_array[0]), nksqr * sizeof(double));
      q += nksqr;
      if(mxIsComplex(output_array[0]))     /* if any imaginary part */
        memcpy(q, mxGetPi(output_array[0]), nksqr * sizeof(double));
      nkp1 = nk + 1;                              /* copy diag(Lab) */
      labk = mxGetPr(output_array[1]);
      for(i = 0, ii = 0; i < nk; i++, ii += nkp1)
        lab[i] = labk[ii];
      mxDestroyArray(output_array[0]);
      mxDestroyArray(output_array[1]);
#ifdef USE_SVD
      mxDestroyArray(output_array[2]);
#endif
      lab += nk;  x += 2 * nksqr; q += nksqr;
    }
  } /* [lab,q] = eigK */
/* ------------------------------------------------------------
   Release PSD-working arrays.
   ------------------------------------------------------------ */
  mxSetM(Xk,0); mxSetN(Xk,0); 
  mxSetPr(Xk, (double *) NULL);
  mxDestroyArray(Xk);
  mxSetM(hXk,0); mxSetN(hXk,0); 
  mxSetPr(hXk, (double *) NULL);   mxSetPi(hXk, (double *) NULL);
  mxDestroyArray(hXk);
  mxFree(xwork);
}
Пример #19
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
   ************************************************************ */
void mexFunction(const int nlhs, mxArray *plhs[],
  const int nrhs, const mxArray *prhs[])
{
 mwIndex i, lenfull, lendiag, lenud, qsize;
 double *z, *fwork;
 const double *x,*y, *frms;
 mwIndex *sdpNL;
 coneK cK;
/* ------------------------------------------------------------
   Check for proper number of arguments 
   ------------------------------------------------------------ */
 mxAssert(nrhs >= NPARIN, "psdinvjmul requires more input arguments.");
 mxAssert(nlhs <= NPAROUT, "psdinvjmul generates 1 output argument.");
/* ------------------------------------------------------------
   Disassemble cone K structure
   ------------------------------------------------------------ */
 conepars(K_IN, &cK);
/* ------------------------------------------------------------
   Get statistics of cone K structure
   ------------------------------------------------------------ */
 lenud = cK.rDim + cK.hDim;
 qsize = lenud + cK.hLen;
 lenfull = cK.lpN +  cK.qDim + lenud;
 lendiag = cK.lpN + 2 * cK.lorN + cK.rLen + cK.hLen;
/* ------------------------------------------------------------
   Get inputs x, frm, y.
   ------------------------------------------------------------ */
 mxAssert(!mxIsSparse(X_IN) && !mxIsSparse(Y_IN), "Sparse inputs not supported by this version of psdinvjmul.");
 x = mxGetPr(X_IN);                                /* get x and y */
 y = mxGetPr(Y_IN);
 if(mxGetM(Y_IN) * mxGetN(Y_IN) != lenud){
   mxAssert(mxGetM(Y_IN) * mxGetN(Y_IN) == lenfull, "size y mismatch.");
   y += cK.lpN + cK.qDim;          /* point to PSD */
 }
 if(mxGetM(X_IN) * mxGetN(X_IN) != cK.rLen + cK.hLen){
   mxAssert(mxGetM(X_IN) * mxGetN(X_IN) == lendiag, "size xlab mismatch.");
   x += cK.lpN + 2 * cK.lorN;       /* point to PSD */
 }
 mxAssert(mxGetM(FRM_IN) * mxGetN(FRM_IN) == qsize, "size xfrm mismatch.");
 frms = mxGetPr(FRM_IN);
/* ------------------------------------------------------------
   Allocate output Z
   ------------------------------------------------------------ */
 Z_OUT =  mxCreateDoubleMatrix(lenud, (mwIndex)1, mxREAL);
 z = mxGetPr(Z_OUT);
/* ------------------------------------------------------------
   Allocate working array fwork(max(rmaxn,2*hmaxn))
   integer working array sdpNL(sdpN).
   ------------------------------------------------------------ */
  fwork = (double *) mxCalloc(MAX(1,MAX(cK.rMaxn,2*cK.hMaxn)),sizeof(double));
  sdpNL = (mwIndex *) mxCalloc(MAX(1,cK.sdpN), sizeof(mwIndex));
/* ------------------------------------------------------------
   double to integer
   ------------------------------------------------------------ */
  for(i = 0; i < cK.sdpN; i++)
    sdpNL[i] = (mwIndex) cK.sdpNL[i];
  psdinvjmul(z,frms,x,y,sdpNL,cK.rsdpN,cK.sdpN, fwork);
/* ------------------------------------------------------------
   Release working array
   ------------------------------------------------------------ */
  mxFree(sdpNL);
  mxFree(fwork);
}
Пример #20
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
   ************************************************************ */
void mexFunction(const int nlhs, mxArray *plhs[],
  const int nrhs, const mxArray *prhs[])
{
  mwIndex i,lendiag, lenfull, lenud,qsize;
  double *x, *fwork;
  const double *lab,*frms;
  mwIndex *sdpNL;
  coneK cK;
/* ------------------------------------------------------------
   Check for proper number of arguments 
   ------------------------------------------------------------ */
  mxAssert(nrhs >= NPARIN, "psdframeit requires more input arguments.");
  mxAssert(nlhs <= NPAROUT, "psdframeit generates less output arguments.");
/* ------------------------------------------------------------
   Disassemble cone K structure
   ------------------------------------------------------------ */
  conepars(K_IN, &cK);
/* ------------------------------------------------------------
   Get statistics of cone K structure
   ------------------------------------------------------------ */
  lenud = cK.rDim + cK.hDim;
  qsize = lenud + cK.hLen;
  lenfull = cK.lpN +  cK.qDim + lenud;
  lendiag = cK.lpN + 2 * cK.lorN + cK.rLen + cK.hLen;
/* ------------------------------------------------------------
   Get inputs lab,frms
   ------------------------------------------------------------ */
  lab = mxGetPr(LAB_IN);
  if(mxGetM(LAB_IN) * mxGetN(LAB_IN) != cK.rLen + cK.hLen){
    mxAssert(mxGetM(LAB_IN) * mxGetN(LAB_IN) == lendiag, "lab size mismatch");
    lab += cK.lpN + 2 * cK.lorN;
  }
  mxAssert(mxGetM(FRMS_IN) * mxGetN(FRMS_IN) == qsize, "frms size mismatch");
  frms = mxGetPr(FRMS_IN);
/* ------------------------------------------------------------
   Allocate output x
   ------------------------------------------------------------ */
  X_OUT =  mxCreateDoubleMatrix(lenud, (mwSize)1, mxREAL);
  x = mxGetPr(X_OUT);
/* ------------------------------------------------------------
   Allocate working array fwork(max(rmaxn,2*hmaxn))
   integer working array sdpNL(sdpN).
   ------------------------------------------------------------ */
  fwork = (double *) mxCalloc(MAX(1,MAX(cK.rMaxn,2*cK.hMaxn)),sizeof(double));
  sdpNL = (mwIndex *) mxCalloc(MAX(1,cK.sdpN), sizeof(mwIndex));
/* ------------------------------------------------------------
   double to integer
   ------------------------------------------------------------ */
  for(i = 0; i < cK.sdpN; i++)
    sdpNL[i] = cK.sdpNL[i];
/* ------------------------------------------------------------
   PSD: X = Qb' * diag(lab) * Qb,          Qb = Q_1*Q_2*..*Q_{n-1}
   where Q_k = I-ck*ck'/betak is an elementary Householder reflection.
   Format: frms = [c1, .., c_{n-1}, beta].
   VERY INEFFICIENT !!!!
   ------------------------------------------------------------ */
  psdframeit(x, frms,lab,sdpNL,cK.rsdpN,cK.sdpN,fwork);
/* ------------------------------------------------------------
   Release working array
   ------------------------------------------------------------ */
  mxFree(sdpNL);
  mxFree(fwork);
}
Пример #21
0
/* ************************************************************
   PROCEDURE mexFunction - Entry for Matlab
   ************************************************************ */
void mexFunction(const int nlhs, mxArray *plhs[],
  const int nrhs, const mxArray *prhs[])
{
  mwIndex i,j,jnz,MAXN, m,dimflqr,lenfull,reallength, nf,nx,ns, iwsize;
  mwIndex *iwork, *sdpNL, *cpxf, *cpxx, *cpxs, *cpxsi;
  bool *cwork;
  const double *cpxfPr, *cpxxPr, *cpxsPr, *xpi;
  mxArray *MY_FIELD;
  coneK cK;
  jcir x,y;
/* ------------------------------------------------------------
   Check for proper number of arguments
   ------------------------------------------------------------ */
  mxAssert(nrhs >= NPARIN, "makereal requires more input arguments");
  mxAssert(nlhs <= NPAROUT, "makereal produces less output arguments");
/* ------------------------------------------------------------
   Disassemble cone K structure
   ------------------------------------------------------------ */
  conepars(K_IN, &cK);
  dimflqr = cK.frN + cK.lpN + cK.qDim;
  for(i = 0; i < cK.rconeN; i++)        /* add dim of rotated cone */
    dimflqr += cK.rconeNL[i];
  lenfull =  dimflqr + cK.rDim + cK.hDim;
/* ------------------------------------------------------------
   Disassemble cpx structure
   ------------------------------------------------------------ */
  mxAssert(mxIsStruct(CPX_IN), "Parameter `cpx' should be a structure.");
  if( (MY_FIELD = mxGetField(CPX_IN,(mwIndex)0,"f")) == NULL)  /* cpx.f */
    nf = 0;
  else{
    nf = mxGetM(MY_FIELD) * mxGetN(MY_FIELD);
    cpxfPr = mxGetPr(MY_FIELD);
  }
  if( (MY_FIELD = mxGetField(CPX_IN,(mwIndex)0,"s")) == NULL)  /* cpx.s */
    ns = 0;
  else{
    ns = mxGetM(MY_FIELD) * mxGetN(MY_FIELD);
    cpxsPr = mxGetPr(MY_FIELD);
  }
  if( (MY_FIELD = mxGetField(CPX_IN,(mwIndex)0,"x")) == NULL)  /* cpx.x */
    nx = 0;
  else{
    nx = mxGetM(MY_FIELD) * mxGetN(MY_FIELD);
    cpxxPr = mxGetPr(MY_FIELD);
  }
/* ------------------------------------------------------------
   Get input matrix x
   ------------------------------------------------------------ */
  mxAssert(mxGetM(X_IN) == lenfull, "Size x mismatch.");
  m = mxGetN(X_IN);                       /* number of columns to handle */
  mxAssert( mxIsSparse(X_IN), "X should be sparse.");
  x.pr = mxGetPr(X_IN);
  if(mxIsComplex(X_IN))
    xpi = mxGetPi(X_IN);
  else
    xpi = (double *) NULL;
  x.jc = mxGetJc(X_IN);
  x.ir = mxGetIr(X_IN);
/* ------------------------------------------------------------
   Allocate iwork[iwsiz], cwork[MAXN], {K.s, cpx.{f[nf],x[nx],s[ns],si[2*ns]}}
   ------------------------------------------------------------ */
  MAXN = MAX(MAX(nf,nx),2*ns);
  iwsize = floor(log(1.0 + MAXN) / log(2.0));       /* for binary tree search */
  iwsize += 2 * ns + 2 + MAXN;
  iwork = (mwIndex *) mxCalloc(iwsize, sizeof(mwIndex));
  cwork = (bool *) mxCalloc(MAX(1,MAXN), sizeof(bool));
  sdpNL = (mwIndex *) mxCalloc(MAX(1, cK.sdpN + nf + nx + 3*ns), sizeof(mwIndex));
  cpxf = sdpNL + cK.sdpN;
  cpxx = cpxf + nf;
  cpxs = cpxx + nx;
  cpxsi = cpxs + ns;        /* length 2*ns */
/* ------------------------------------------------------------
   Convert double to mwIndex
   ------------------------------------------------------------ */
  for(i = 0; i < cK.sdpN; i++){        /* K.s */
    j = cK.sdpNL[i];
    sdpNL[i] = j;                    /* These are lengths, not subscripts!*/
  }
  for(i = 0; i < nf; i++){             /* cpx.f */
    j = cpxfPr[i];
    cpxf[i] = --j;
  }
  for(i = 0; i < nx; i++){             /* cpx.x */
    j = cpxxPr[i];
    cpxx[i] = --j;
  }
  for(i = 0; i < ns; i++){             /* cpx.s */
    j = cpxsPr[i];
    cpxs[i] = --j;
  }
/* ------------------------------------------------------------
   Create cpxsi(1:2*ns). This lists the 1st subscript and the
   1-beyond-last subscript of each Hermitian PSD matrix in x.
   ------------------------------------------------------------ */
  jnz = dimflqr;
  j = 0;
  for(i = 0; i < ns; i++){
    for(; j < cpxs[i]; j++)
      jnz += SQR(sdpNL[j]);
    cpxsi[2 * i] = jnz;            /* start of Hermitian block */
    jnz += SQR(sdpNL[j]);
    j++;
    cpxsi[2 * i + 1] = jnz;        /* end of Hermitian block */
  }
/* ------------------------------------------------------------
   Allocate output Y = sparse([],[],[],reallength(x),m,2 * nnz(x))
   ------------------------------------------------------------ */
  reallength = lenfull + nf + nx;
  for(i = 0; i < ns; i++){
    reallength += cpxsi[2*i+1] - cpxsi[2*i];
  }
  jnz = x.jc[m];
  if(xpi != (double *) NULL)
    jnz *= 2;                       /* reserve room for imaginary parts */
  Y_OUT = mxCreateSparse(reallength, m, jnz, mxREAL);
  y.pr = mxGetPr(Y_OUT);
  y.jc = mxGetJc(Y_OUT);
  y.ir = mxGetIr(Y_OUT);
/* ------------------------------------------------------------
   The real job, MAKEREAL:
   ------------------------------------------------------------ */
  y.jc[0] = 0;
  jnz = 0;
  for(i = 0; i < m; i++){
    y.jc[i] = jnz;
    j = x.jc[i+1] - x.jc[i];
    jnz += makereal(y.ir+jnz, y.pr+jnz, x.ir+x.jc[i],x.pr+x.jc[i],xpi,j,
                    cpxf,nf, cpxx,nx, cpxsi,ns, lenfull, dimflqr,
                    cwork, iwork, iwsize);
    if(xpi != (double *) NULL)
      xpi += j;                 /* To next imaginary column */
  }
  y.jc[i] = jnz;
  mxAssert(jnz <= mxGetNzmax(Y_OUT),"");
/* ------------------------------------------------------------
   REALLOC: Shrink Y to its current size
   ------------------------------------------------------------ */
  jnz = MAX(jnz,1);
  if( (y.pr = (double *) mxRealloc(y.pr, jnz*sizeof(double))) == NULL)
    mexErrMsgTxt("Memory reallocation error");
  mxSetPr(Y_OUT,y.pr);
  if( (y.ir = (mwIndex *) mxRealloc(y.ir, jnz*sizeof(mwIndex))) == NULL)
    mexErrMsgTxt("Memory reallocation error");
  mxSetIr(Y_OUT,y.ir);
  mxSetNzmax(Y_OUT,jnz);
/* ------------------------------------------------------------
   Release working arrays
   ------------------------------------------------------------ */
  mxFree(sdpNL);
  mxFree(cwork);
  mxFree(iwork);
}