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

📄 mexsparchol.c

📁 凸优化程序包
💻 C
📖 第 1 页 / 共 2 页
字号:
  *pnadd = nadd;  return ix;}/* ============================================================   MAIN: MEXFUNCTION   ============================================================ *//* ************************************************************   PROCEDURE mexFunction - Entry for Matlab   ************************************************************ */void mexFunction(const int nlhs, mxArray *plhs[],  const int nrhs, const mxArray *prhs[]){  const mxArray *L_FIELD;  mxArray *myplhs[NPAROUT];  int    m, i, j, inz, iwsiz, nsuper, tmpsiz, fwsiz, nskip, nadd, m1;  double *fwork, *d, *skipPr, *orgd;  const double *permPr,*xsuperPr,*Ppr,*absd;  int    *perm, *snode, *xsuper, *iwork, *xlindx, *skip, *skipJc;  const int *LINir, *Pjc, *Pir;  double canceltol, maxu, abstol;  jcir   L;  char useAbsd, useDelay;/* ------------------------------------------------------------   Check for proper number of arguments   blkchol(L,P, pars,absd) with nparinmin=2.   ------------------------------------------------------------ */  if(nrhs < NPARINMIN)    mexErrMsgTxt("blkchol requires more input arguments");  if(nlhs > NPAROUT)    mexErrMsgTxt("blkchol produces less output arguments");/* ------------------------------------------------------------   Get input matrix P to be factored.   ------------------------------------------------------------ */  if( (m = mxGetM(P_IN)) != mxGetN(P_IN))    mexErrMsgTxt("P must be square");  if(!mxIsSparse(P_IN))    mexErrMsgTxt("P must be sparse");  Pjc    = mxGetJc(P_IN);  Pir    = mxGetIr(P_IN);  Ppr    = mxGetPr(P_IN);/* ------------------------------------------------------------   Disassemble block Cholesky structure L   ------------------------------------------------------------ */  if(!mxIsStruct(L_IN))    mexErrMsgTxt("Parameter `L' should be a structure.");  if( (L_FIELD = mxGetField(L_IN,0,"perm")) == NULL)        /* L.perm */    mexErrMsgTxt("Missing field L.perm.");  if(m != mxGetM(L_FIELD) * mxGetN(L_FIELD))    mexErrMsgTxt("perm size mismatch");  permPr = mxGetPr(L_FIELD);  if( (L_FIELD = mxGetField(L_IN,0,"L")) == NULL)           /* L.L */    mexErrMsgTxt("Missing field L.L.");  if( m != mxGetM(L_FIELD) || m != mxGetN(L_FIELD) )    mexErrMsgTxt("Size L.L mismatch.");  if(!mxIsSparse(L_FIELD))    mexErrMsgTxt("L.L should be sparse.");  L.jc = mxGetJc(L_FIELD);  LINir = mxGetIr(L_FIELD);  if( (L_FIELD = mxGetField(L_IN,0,"xsuper")) == NULL)      /* L.xsuper */    mexErrMsgTxt("Missing field L.xsuper.");  nsuper = mxGetM(L_FIELD) * mxGetN(L_FIELD) - 1;  if( nsuper > m )    mexErrMsgTxt("Size L.xsuper mismatch.");  xsuperPr = mxGetPr(L_FIELD);  if( (L_FIELD = mxGetField(L_IN,0,"tmpsiz")) == NULL)      /* L.tmpsiz */    mexErrMsgTxt("Missing field L.tmpsiz.");  tmpsiz   = mxGetScalar(L_FIELD);/* ------------------------------------------------------------   Disassemble pars structure: canceltol, maxu   ------------------------------------------------------------ */  canceltol = 1E-15;           /* supply with defaults */  maxu = 5E5;  abstol = 1E-20;  useAbsd = 0;  useDelay = 0;  if(nrhs >= NPARINMIN + 1){       /* 3rd argument = pars */    if(!mxIsStruct(PARS_IN))      mexErrMsgTxt("Parameter `pars' should be a structure.");    if( (L_FIELD = mxGetField(PARS_IN,0,"canceltol")) != NULL)      canceltol  = mxGetScalar(L_FIELD);  /* pars.canceltol */    if( (L_FIELD = mxGetField(PARS_IN,0,"maxu")) != NULL)      maxu = mxGetScalar(L_FIELD);  /* pars.maxu */    if( (L_FIELD = mxGetField(PARS_IN,0,"abstol")) != NULL){      abstol = mxGetScalar(L_FIELD);  /* pars.abstol */      abstol = MAX(abstol, 0.0);    }    if( (L_FIELD = mxGetField(PARS_IN,0,"delay")) != NULL)      useDelay = mxGetScalar(L_FIELD);  /* pars.delay *//* ------------------------------------------------------------   Get optional vector absd   ------------------------------------------------------------ */    if(nrhs >= NPARIN){      useAbsd = 1;      absd = mxGetPr(ABSD_IN);      if(m != mxGetM(ABSD_IN) * mxGetN(ABSD_IN))        mexErrMsgTxt("absd size mismatch");    }  }/* ------------------------------------------------------------   Create sparse output matrix L(m x m).   ------------------------------------------------------------ */  L_OUT = mxCreateSparse(m,m, L.jc[m],mxREAL);  L.ir  = mxGetIr(L_OUT);  L.pr  = mxGetPr(L_OUT);  memcpy(mxGetJc(L_OUT), L.jc, (m+1) * sizeof(int));  memcpy(L.ir, LINir, L.jc[m] * sizeof(int));/* ------------------------------------------------------------   Create ouput vector d(m).   ------------------------------------------------------------ */  D_OUT = mxCreateDoubleMatrix(m,1,mxREAL);  d     = mxGetPr(D_OUT);/* ------------------------------------------------------------   Compute required sizes of working arrays:   iwsiz = 2*(m + nsuper).   fwsiz = tmpsiz.   ------------------------------------------------------------ */  iwsiz = MAX(2*(m+nsuper), 1);  fwsiz = MAX(tmpsiz, 1);/* ------------------------------------------------------------   Allocate working arrays:   integer: perm(m), snode(m), xsuper(nsuper+1),      iwork(iwsiz), xlindx(m+1), skip(m),   double: orgd(m), fwork(fwsiz).   ------------------------------------------------------------ */  m1 = MAX(m,1);                  /* avoid alloc to 0 */  perm      = (int *) mxCalloc(m1,sizeof(int));   snode     = (int *) mxCalloc(m1,sizeof(int));   xsuper    = (int *) mxCalloc(nsuper+1,sizeof(int));  iwork     = (int *) mxCalloc(iwsiz,sizeof(int));  xlindx    = (int *) mxCalloc(m+1,sizeof(int));  skip      = (int *) mxCalloc(m1, sizeof(int));  orgd    = (double *) mxCalloc(m1,sizeof(double));   fwork   = (double *) mxCalloc(fwsiz,sizeof(double)); /* ------------------------------------------------------------   Convert PERM, XSUPER to integer and C-Style   ------------------------------------------------------------ */  for(i = 0; i < m; i++){    j = permPr[i];    perm[i] = --j;  }  for(i = 0; i <= nsuper; i++){    j =  xsuperPr[i];    xsuper[i] = --j;  }/* ------------------------------------------------------------   Let L = tril(P(PERM,PERM)), uses orgd(m) as temp working storage.   ------------------------------------------------------------ */  permuteP(L.jc,L.ir,L.pr, Pjc,Pir,Ppr, perm, orgd, m);/* ------------------------------------------------------------   If no orgd has been supplied, take orgd = diag(L on input)   Otherwise, let orgd = absd(perm).   ------------------------------------------------------------ */  if(useAbsd)    for(j = 0; j < m; j++)      orgd[j] = absd[perm[j]];  else    for(j = 0; j < m; j++)      orgd[j] = L.pr[L.jc[j]];/* ------------------------------------------------------------   Create "snode" and "xlindx"; change L.ir to the compact subscript   array (with xlindx), and do BLOCK SPARSE CHOLESKY.   ------------------------------------------------------------ */  nskip = spchol(m, nsuper, xsuper, snode, xlindx,                 L.ir, orgd, L.jc, L.pr, d, perm, abstol,                 canceltol, maxu, skip, &nadd, iwsiz, iwork, fwsiz, fwork);  if(nskip < 0)    mexErrMsgTxt("Insufficient workspace in pblkchol");/* ------------------------------------------------------------   Copy original row-indices from LINir to L.ir.   ------------------------------------------------------------ */  memcpy(L.ir, LINir, L.jc[m] * sizeof(int));/* ------------------------------------------------------------   Create output matrices skip = sparse([],[],[],m,1,nskip),   diagadd = sparse([],[],[],m,1,nadd),   ------------------------------------------------------------ */  SKIP_OUT = mxCreateSparse(m,1, MAX(1,nskip),mxREAL);  memcpy(mxGetIr(SKIP_OUT), skip, nskip * sizeof(int));  skipJc = mxGetJc(SKIP_OUT);  skipJc[0] = 0; skipJc[1] = nskip;  skipPr   = mxGetPr(SKIP_OUT);/* ------------------------------------------------------------   useDelay = 1 then L(:,i) is i-th column before ith pivot; useful     for pivot-delaying strategy. (Fwslv(L, L(:,i)) still required.)   ------------------------------------------------------------ */  if(useDelay == 1)    for(j = 0; j < nskip; j++)      skipPr[j] = 1.0;  else    for(j = 0; j < nskip; j++){      i = skip[j];      skipPr[j] = L.pr[L.jc[i]];             /* Set skipped l(:,i)=ei. */      L.pr[L.jc[i]] = 1.0;      fzeros(L.pr+L.jc[i]+1,L.jc[i+1]-L.jc[i]-1);    }  DIAGADD_OUT = mxCreateSparse(m,1, MAX(1,nadd),mxREAL);  memcpy(mxGetIr(DIAGADD_OUT), iwork, nadd * sizeof(int));  skipJc = mxGetJc(DIAGADD_OUT);  skipJc[0] = 0; skipJc[1] = nadd;  skipPr   = mxGetPr(DIAGADD_OUT);  for(j = 0; j < nadd; j++)    skipPr[j] = orgd[iwork[j]];/* ------------------------------------------------------------   Release working arrays.   ------------------------------------------------------------ */  mxFree(fwork);  mxFree(orgd);  mxFree(skip);  mxFree(xlindx);  mxFree(iwork);  mxFree(xsuper);  mxFree(snode);  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]);}

⌨️ 快捷键说明

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