📄 eigk.c
字号:
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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -