/****************************************************************** * mexProd2.c : C-MEX file to compute the product of two matrices. * * P = mexProd2(blk,A,B,type) * * input: blk = 1x2 cell array describing the block structure of A and B * A = mxn matrix. * B = nxp matrix. * type = 0 general matrix product * 1 if P is symmetric * 21 if B is upper triangular * 211 if B is upper triangular, P is symmetric * 22 if B is lower triangular * 221 if B is lower triangular, P is symmetric * 31 if A is upper triangular * 311 if A is upper triangular, P is symmetric * 32 if A is lower triangular * 321 if A is lower triangular, P is symmetric * 41 if A is upper triangular, B is upper triangular * 42 if A is upper triangular, B is lower triangualr * 421 if A is upper triangular, B is lower triangualr, * P is symmetric * * SDPT3: version 3.0 * Copyright (c) 1997 by * K.C. Toh, M.J. Todd, R.H. Tutuncu * Last Modified: 2 Feb 01 ******************************************************************/ #include #include static int min1, min2; #define IMIN(a,b) (min1=(a),min2=(b),(min1)<(min2)?(min1):(min2)) /********************************************************** * saxpy: z = z + alpha*y **********************************************************/ static void saxpy(const double x, const double *y, const int idx1, double *z, const int idx2, const istart, const iend) { int i; for(i=istart; i< iend-3; i++){ /* LEVEL 4 */ z[i+idx2] += x * y[i+idx1]; i++; z[i+idx2] += x * y[i+idx1]; i++; z[i+idx2] += x * y[i+idx1]; i++; z[i+idx2] += x * y[i+idx1]; } if(i < iend-1){ /* LEVEL 2 */ z[i+idx2] += x * y[i+idx1]; i++; z[i+idx2] += x * y[i+idx1]; i++; } if(i < iend){ /* LEVEL 1 */ z[i+idx2] += x * y[i+idx1]; } return; } /********************************************************** * form P using the upper triangular part **********************************************************/ void symmetrize(double *P, int n) { int j, k, jn; for (j=0; j j & sym) { break; } P[ri+jm] += tmp*A[i]; } } } } if (type==1 || type==211 || type==221 || type==311 || type==321 || type==421) { symmetrize(P,m); } return; } /********************************************************** * A sparse, B sparse **********************************************************/ static void product4(double *A, int *irA, int *jcA, double *B, int *irB, int *jcB, double *P, int *irP, int *jcP, double *Ptmp, int numblk, int *cumblk) { int i, j, k, l, r, t, istart, iend, kstart, kend, jstart, jend; int idx; double tmp; idx = 0; jcP[0]=0; for (l=0; l2){ mexErrMsgTxt("mexProd2: requires 1 output argument."); } if (mxIsCell(prhs[1]) || mxIsCell(prhs[2])) { mexErrMsgTxt("mexProd2: 2ND and 3RD input must both be matrices"); } if (mxGetM(prhs[0]) > 1) { mexErrMsgTxt("mexProd2: blk can only have 1 row"); } /*** get pointers ***/ if (nrhs > 3) { type = (int)*mxGetPr(prhs[3]); } else { type = 0; } subs[0] = 0; subs[1] = 1; index = mxCalcSingleSubscript(prhs[0],nsubs,subs); blk_cell_pr = mxGetCell(prhs[0],index); blksize = mxGetPr(blk_cell_pr); numblk = mxGetN(blk_cell_pr); cumblk = mxCalloc(numblk+1,sizeof(int)); NZmax = 0; for (l=0; l 1) & !(isspA & isspB) & !(n1==1 & n2==1)) { mexErrMsgTxt("mexProd2: 2ND and 3RD must be both sparse"); } /***** create return argument *****/ if (isspA & isspB & !(n1==1 & n2==1)){ plhs[0] = mxCreateSparse(m1,n2,NZmax,mxREAL); P = mxGetPr(plhs[0]); irP = mxGetIr(plhs[0]); jcP = mxGetJc(plhs[0]); } else { plhs[0] = mxCreateDoubleMatrix(m1,n2,mxREAL); P = mxGetPr(plhs[0]); } if (isspA & isspB & !(n1==1 & n2==1)) { Ptmp = mxCalloc(cumblk[numblk],sizeof(double)); } /********************************************** * Do the actual computations in a subroutine **********************************************/ if (m1 == m2 & n1 == 1 & n2 == 1) { product5(A, irA, jcA, B, irB, jcB, P, m1, isspA, isspB); } else { if (!isspA & !isspB){ product(A, B, P, m1, n1, n2, type); } else if (!isspA & isspB){ product2(A, B, irB, jcB, P, m1, n1, n2, type); } else if (isspA & !isspB){ product3(A, irA, jcA, B, P, m1, n1, n2, type); } else if (isspA & isspB){ product4(A, irA, jcA, B, irB, jcB,P,irP,jcP,Ptmp,numblk,cumblk); } } mxFree(cumblk); if (isspA & isspB & !(n1==1 & n2==1)) { mxFree(Ptmp); } return; } /**********************************************************/