/*********************************************************************** * mexsvec.c : C mex file * * x = mexsvec(blk,A,isspx,type); * * Input: A = nxn matrix * isspx = 0, store x as a dense vector * 1, store x as a sparse vector. * type = 0, stack upper triangular part of A column-wise * 1, stack lower triangular part of A row-wise * * SDPT3: version 3.0 * Copyright (c) 1997 by * K.C. Toh, M.J. Todd, R.H. Tutuncu * Last Modified: 2 Feb 01 ***********************************************************************/ #include #include /********************************************************** * single block: stack upper triangular part of A column-wise * into a column vector **********************************************************/ void svec1(int n, double r2, double *A, mwIndex *irA, mwIndex *jcA, int isspA, double *B, mwIndex *irB, mwIndex *jcB, int isspB) { int idx, i, j, jn, k, kstart, kend, idxj; if (!isspB & !isspA) { idx = 0; for (j=0; j= j) { break; } B[idx+i] = A[k]*r2; } if (i == j) { B[idx+i] = A[k]; } } } } else if (isspB & isspA) { idx = 0; idxj = 0; for (j=0; j= j) { break; } irB[idx] = i+idxj; B[idx] = A[k]*r2; idx++; } if ( i == j) { irB[idx] = j+idxj; B[idx] = A[k]; idx++; } } } jcB[1] = idx; } return; } /********************************************************** * multiple sub-blocks: stack upper triangular part of A * column-wise into a column vector **********************************************************/ void svec2(int n, int numblk, int *cumblksize, int *blknnz, double r2, double *A, mwIndex *irA, mwIndex *jcA, int isspA, double *B, mwIndex *irB, mwIndex *jcB, int isspB) { int idx, i, j, jn, l, jstart, jend, istart; int rowidx, idxj, k, kstart, kend; if (!isspB & !isspA) { idx = 0; jstart = 0; jend = 0; for (l=0; l= j) { break; } B[idx+i-istart] = A[k]*r2; } if (i == j) { B[idx+i-istart] = A[k]; } } } jstart = jend; } } else if (isspB & isspA) { idx = 0; jstart = 0; jend = 0; for (l=0; l= j) { break; } irB[idx] = rowidx+i; B[idx] = A[k]*r2; idx++; } if (i == j) { irB[idx] = rowidx+j; B[idx] = A[k]; idx++; } } } jstart = jend; } jcB[1] = idx; } return; } /********************************************************** * single block: stack upper lower part of A row-wise * into a column vector **********************************************************/ void svec3(int n, double r2, double *A, mwIndex *irA, mwIndex *jcA, int isspA, double *B, mwIndex *irB, mwIndex *jcB, int isspB) { int idx, rowidx, i, j, jn, k, kstart, kend; if (!isspB & !isspA) { idx = 0; for (i=0; i= j) { break; } B[idx+i] = A[k]*r2; BI[idx+i] = AI[k]*r2; } if (i == j) { B[idx+i] = A[k]; BI[idx+i] = AI[k];} } } } else if (isspB & isspA) { idx = 0; idxj = 0; for (j=0; j= j) { break; } irB[idx] = i+idxj; B[idx] = A[k]*r2; BI[idx] = AI[k]*r2; idx++; } if (i == j) { irB[idx] = j+idxj; B[idx] = A[k]; BI[idx] = AI[k]; idx++; } } } jcB[1] = idx; } return; } /********************************************************** * Complex case: * multiple sub-blocks: stack upper triangular part of A * column-wise into a column vector **********************************************************/ void svec2cmp(int n, int numblk, int *cumblksize, int *blknnz, double r2, double *A, mwIndex *irA, mwIndex *jcA, int isspA, double *B, mwIndex *irB, mwIndex *jcB, int isspB, double *AI, double *BI) { int idx, i, j, jn, l, jstart, jend, istart; int rowidx, idxj, k, kstart, kend; if (!isspB & !isspA) { idx = 0; jstart = 0; jend = 0; for (l=0; l= j) { break; } B[idx+i-istart] = A[k]*r2; BI[idx+i-istart] = AI[k]*r2; } if (i == j) { B[idx+i-istart] = A[k]; BI[idx+i-istart] = AI[k]; } } } jstart = jend; } } else if (isspB & isspA) { idx = 0; jstart = 0; jend = 0; for (l=0; l= j) { break; } irB[idx] = rowidx+i; B[idx] = A[k]*r2; BI[idx] = AI[k]*r2; idx++; } if (i == j) { irB[idx] = rowidx+j; B[idx] = A[k]; BI[idx] = AI[k]; idx++; } } } jstart = jend; } jcB[1] = idx; } return; } /********************************************************** * Complex case: * single block: stack upper lowere part of A row-wise * into a column vector **********************************************************/ void svec3cmp(int n, double r2, double *A, mwIndex *irA, mwIndex *jcA, int isspA, double *B, mwIndex *irB, mwIndex *jcB, int isspB, double *AI, double *BI) { int idx, rowidx, i, j, jn, k, kstart, kend; if (!isspB & !isspA) { idx = 0; for (i=0; i 1){ mexErrMsgTxt("mexsvec: requires 1 output argument."); } /* CHECK THE DIMENSIONS */ mblk = mxGetM(prhs[0]); if (mblk > 1) { mexErrMsgTxt("mexsvec: blk can have only 1 row."); } m = mxGetM(prhs[1]); n = mxGetN(prhs[1]); if (m != n) { mexErrMsgTxt("mexsvec: matrix must be square."); } subs[0] = 0; subs[1] = 1; index = mxCalcSingleSubscript(prhs[0],nsubs,subs); blk_cell_pr = mxGetCell(prhs[0],index); numblk = mxGetN(blk_cell_pr); blksize = mxGetPr(blk_cell_pr); if (numblk == 1) { n2 = n*(n+1)/2; } else { cumblksize = (int*)mxCalloc(numblk+1,sizeof(int)); blknnz = (int*)mxCalloc(numblk+1,sizeof(int)); cumblksize[0] = 0; blknnz[0] = 0; n = 0; n2 = 0; for (k=0; k 1) & (!isspA)) { mexErrMsgTxt("mexsvec: matrix must be sparse for numblk > 1"); } if (nrhs > 2) { if (mxGetM(prhs[2])>1) { isspB = (int)*mxGetPr(prhs[2]); } else if (NZmax < n2/2) { isspB = 1; } else { isspB = 0; } } else { if (NZmax < n2/2) { isspB = 1; } else { isspB = 0; } } if (nrhs > 3) { type = (int)*mxGetPr(prhs[3]); } else { type = 0; } /***** create return argument *****/ if (isspB) { if (iscmpA) { plhs[0] = mxCreateSparse(n2,1,NZmax,mxCOMPLEX); } else { plhs[0] = mxCreateSparse(n2,1,NZmax,mxREAL); } B = mxGetPr(plhs[0]); irB = mxGetIr(plhs[0]); jcB = mxGetJc(plhs[0]); jcB[0] = 0; } else { if (iscmpA) { plhs[0] = mxCreateDoubleMatrix(n2,1,mxCOMPLEX); } else { plhs[0] = mxCreateDoubleMatrix(n2,1,mxREAL); } B = mxGetPr(plhs[0]); } if (iscmpA) { BI = mxGetPi(plhs[0]); } /***** Do the computations in a subroutine *****/ r2 = sqrt(2); if (type == 0) { if (iscmpA) { if (numblk == 1) { svec1cmp(n,r2,A,irA,jcA,isspA,B,irB,jcB,isspB,AI,BI); } else { svec2cmp(n,numblk,cumblksize,blknnz,r2,A,irA,jcA,isspA,B,irB,jcB,isspB,AI,BI); } } else { if (numblk == 1) { svec1(n,r2,A,irA,jcA,isspA,B,irB,jcB,isspB); } else { svec2(n,numblk,cumblksize,blknnz,r2,A,irA,jcA,isspA,B,irB,jcB,isspB); } } } else { if (iscmpA) { if (numblk == 1) { svec3cmp(n,r2,A,irA,jcA,isspA,B,irB,jcB,isspB,AI,BI); } else { svec4cmp(n,numblk,cumblksize,blknnz,r2,A,irA,jcA,isspA,B,irB,jcB,isspB,AI,BI); } } else { if (numblk == 1) { svec3(n,r2,A,irA,jcA,isspA,B,irB,jcB,isspB); } else { svec4(n,numblk,cumblksize,blknnz,r2,A,irA,jcA,isspA,B,irB,jcB,isspB); } } } return; } /**********************************************************/