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

📄 mextriang.c

📁 斯坦福大学Grant和Boyd教授等开发的凸优化matlab工具箱
💻 C
字号:
/***********************************************************************  y = mextriang(U,b,options)*  Given nxn upper-triangular matrix U, *  options = 1 (default), solves     U *y = b, *          = 2          , solves     U'*y = b. **  Important: U is assumed to be dense. *********************************************************************/#include <mex.h>#include <math.h>#include <matrix.h>#if !defined(MX_API_VER) || ( MX_API_VER < 0x07030000 )typedef int mwIndex;typedef int mwSize;#endif#if !defined(SQR)#define SQR(x) ((x)*(x))#endif#if !defined(MIN)#define  MIN(A, B)   ((A) < (B) ? (A) : (B))#endif/**************************************************************   TIME-CRITICAL PROCEDURE -- r=realdot(x,y,n)   Computes r=sum(x_i * y_i) using LEVEL 8 loop-unrolling.**************************************************************/ double realdot(const double *x, const double *y, const int n) {   int i;   double r;   r=0.0;   for(r=0.0, i=0; i< n-7; i++){          /* LEVEL 8 */      r+= x[i] * y[i]; i++;      r+= x[i] * y[i]; i++;      r+= x[i] * y[i]; i++;      r+= x[i] * y[i]; i++;      r+= x[i] * y[i]; i++;      r+= x[i] * y[i]; i++;      r+= x[i] * y[i]; i++;      r+= x[i] * y[i];   }   if(i < n-3){                           /* LEVEL 4 */     r+= x[i] * y[i]; i++;     r+= x[i] * y[i]; i++;     r+= x[i] * y[i]; i++;     r+= x[i] * y[i]; i++;   }   if(i < n-1){                           /* LEVEL 2 */     r+= x[i] * y[i]; i++;     r+= x[i] * y[i]; i++;   }   if(i < n)                              /* LEVEL 1 */     r+= x[i] * y[i];   return r;}/*************************************************************   TIME-CRITICAL PROCEDURE -- subscalarmul(x,alpha,y,n)   Computes x -= alpha * y using LEVEL 8 loop-unrolling.**************************************************************/void subscalarmul(double *x, const double alpha,                   const double *y, const int n){ int i;  for(i=0; i< n-7; i++){          /* LEVEL 8 */    x[i] -= alpha * y[i]; i++;    x[i] -= alpha * y[i]; i++;    x[i] -= alpha * y[i]; i++;    x[i] -= alpha * y[i]; i++;    x[i] -= alpha * y[i]; i++;    x[i] -= alpha * y[i]; i++;    x[i] -= alpha * y[i]; i++;    x[i] -= alpha * y[i];  }  if(i < n-3){                    /* LEVEL 4 */    x[i] -= alpha * y[i]; i++;    x[i] -= alpha * y[i]; i++;    x[i] -= alpha * y[i]; i++;    x[i] -= alpha * y[i]; i++;  }  if(i < n-1){                    /* LEVEL 2 */    x[i] -= alpha * y[i]; i++;    x[i] -= alpha * y[i]; i++;  }  if(i < n)                       /* LEVEL 1 */    x[i] -= alpha * y[i];}/*************************************************************   PROCEDURE fwsolve -- Solve y from U'*y = x. **************************************************************/void fwsolve(double *y,const double *u,const double *x,const int n){  int k;  /*-----------------------------------------------    u(1:k-1,k)'*y(1:k-1) + u(k,k)*y(k) = x(k).   -----------------------------------------------*/   for (k = 0; k < n; k++, u += n)      y[k] = (x[k] - realdot(y,u,k)) / u[k];}/*************************************************************   PROCEDURE ubsolve -- Solves xnew from U * xnew = x,   UPDATED     x - length n vector     On input, contains the right-hand-side.     On output, xnew = U\x**************************************************************/void bwsolve(double *x,const double *u,const int n){   int j;  /*---------------------------------------------    xnew[j] = x[j] / u[j,j]    Then, we update the right-hand side:    xnew(0:j-1) = x(0:j-1) - xnew[j] * u(0:j-1)   ---------------------------------------------*/   j = n;   u += SQR(n);   while(j > 0){     --j;     u -= n;     x[j] /= u[j];     subscalarmul(x,x[j],u,j);   }}/**************************************************************   PROCEDURE mexFunction - Entry for Matlab**************************************************************/ void mexFunction(int nlhs, mxArray *plhs[],                  int nrhs, const mxArray *prhs[]){  const double  *U;   mwIndex       *irb, *jcb;    int            isspb;   int            n, k, kend, options;      double        *y, *b, *btmp;   if (nrhs < 2) {      mexErrMsgTxt("mextriang requires 2 input arguments."); }   if (nlhs > 1) {      mexErrMsgTxt("mextriang generates 1 output argument."); }    U = mxGetPr(prhs[0]);   if (mxIsSparse(prhs[0])) {      mexErrMsgTxt("mextriang: Sparse U not supported."); }   n = mxGetM(prhs[0]);    if (mxGetN(prhs[0]) != n) {      mexErrMsgTxt("mextriang: U should be square and upper triangular."); }   isspb = mxIsSparse(prhs[1]);    if ( mxGetM(prhs[1])*mxGetN(prhs[1]) != n ) {       mexErrMsgTxt("mextriang: size of U,b mismatch."); }   if (nrhs > 2) {       options = (int)*mxGetPr(prhs[2]); }   else {      options = 1;    }   if (isspb) {      btmp = mxGetPr(prhs[1]);      irb = mxGetIr(prhs[1]); jcb = mxGetJc(prhs[1]);       b = mxCalloc(n,sizeof(double));             kend = jcb[1];       for (k=0; k<kend; k++) { b[irb[k]] = btmp[k]; }    } else {      b = mxGetPr(prhs[1]);    }   /************************************************/   plhs[0] = mxCreateDoubleMatrix(n, 1, mxREAL);   y = mxGetPr(plhs[0]);     /************************************************/   if (options==1) {       for (k=0; k<n; k++) { y[k]=b[k]; }       bwsolve(y,U,n);     } else if (options==2) {       fwsolve(y,U,b,n);    }      return;}/*************************************************************/

⌨️ 快捷键说明

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