00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #if !defined(_WIN32)
00020 #define zhesvx zhesvx_
00021 #define dsysvx dsysvx_
00022 #endif
00023
00024 #include "mex.h"
00025 #include "fort.h"
00026
00027 extern void zhesvx(
00028 char *fact,
00029 char *uplo,
00030 int *n,
00031 int *nrhs,
00032 double *a,
00033 int *lda,
00034 double *af,
00035 int *ldaf,
00036 int *ipiv,
00037 double *b,
00038 int *ldb,
00039 double *x,
00040 int *ldx,
00041 double *rcond,
00042 double *ferr,
00043 double *berr,
00044 double *work,
00045 int *lwork,
00046 double *rwork,
00047 int *info
00048 );
00049
00050 extern void dsysvx(
00051 char *fact,
00052 char *uplo,
00053 int *n,
00054 int *nrhs,
00055 double *a,
00056 int *lda,
00057 double *af,
00058 int *ldaf,
00059 int *ipiv,
00060 double *b,
00061 int *ldb,
00062 double *x,
00063 int *ldx,
00064 double *rcond,
00065 double *ferr,
00066 double *berr,
00067 double *work,
00068 int *lwork,
00069 int *iwork,
00070 int *info
00071 );
00072
00073 void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
00074 {
00075
00076
00077
00078 char fact[2] = {'N','\0'}, uplo[2] = {'U','\0'};
00079 char msg[101];
00080 int cplx, info, n, nrhsb, lda, ldaf, ldb, ldx, lwork;
00081 int *ipiv, *iwork=NULL;
00082 double *A, *AF, *b, *x, rcond, *ferr, *berr, *work1, *work, *rwork=NULL;
00083
00084 if ((nlhs > 1) || (nrhs != 2)) {
00085 mexErrMsgTxt("Expect 2 input arguments and return 1 output argument");
00086 }
00087
00088
00089
00090
00091 mxAssert(mxGetM(prhs[0])<INT_MAX, "Matrix is too large for 32-bit LAPACK");
00092 mxAssert(mxGetN(prhs[0])<INT_MAX, "Matrix is too large for 32-bit LAPACK");
00093 mxAssert(mxGetM(prhs[1])<INT_MAX, "Matrix is too large for 32-bit LAPACK");
00094 mxAssert(mxGetN(prhs[1])<INT_MAX, "Matrix is too large for 32-bit LAPACK");
00095
00096 n = (int)mxGetN(prhs[0]);
00097 nrhsb = (int)mxGetN(prhs[1]);
00098 lda = (int)mxGetM(prhs[0]);
00099 if (lda != n) {
00100 mexErrMsgTxt("Matrix must be square and symmetric");
00101 }
00102 cplx = (mxGetPi(prhs[0]) || mxGetPi(prhs[1]));
00103 if (cplx) {
00104 A = mat2fort(prhs[0],lda,n);
00105 AF = (double *)mxCalloc(2*lda*n,sizeof(double));
00106 } else {
00107 A = mxGetPr(prhs[0]);
00108 AF = (double *)mxCalloc(lda*n,sizeof(double));
00109 }
00110 ldaf = lda;
00111 ipiv = (int *)mxCalloc(n,sizeof(int));
00112 ldb = (int)mxGetM(prhs[1]);
00113 if (lda != ldb) {
00114 mexErrMsgTxt("A and b must have the same number of rows");
00115 }
00116 ldx = ldb;
00117 ferr = (double *)mxCalloc(nrhsb,sizeof(double));
00118 berr = (double *)mxCalloc(nrhsb,sizeof(double));
00119 lwork = -1;
00120 info = 0;
00121 if (cplx) {
00122 b = mat2fort(prhs[1],ldb,nrhsb);
00123 x = (double *)mxCalloc(2*ldb*nrhsb,sizeof(double));
00124 work1 = (double *)mxCalloc(2,sizeof(double));
00125 rwork = (double *)mxCalloc(n,sizeof(double));
00126
00127 zhesvx ( fact, uplo, &n, &nrhsb, A, &lda, AF, &ldaf, ipiv, b, &ldb,
00128 x, &ldx, &rcond, ferr, berr, work1, &lwork, rwork, &info );
00129 if (info < 0) {
00130 sprintf(msg, "Input %d to zhesvx had an illegal value",-info);
00131 mexErrMsgTxt(msg);
00132 }
00133 lwork = (int)(work1[0]);
00134 work = (double *)mxCalloc(2*lwork,sizeof(double));
00135 zhesvx ( fact, uplo, &n, &nrhsb, A, &lda, AF, &ldaf, ipiv, b, &ldb,
00136 x, &ldx, &rcond, ferr, berr, work, &lwork, rwork, &info );
00137 if (info < 0) {
00138 sprintf(msg, "Input %d to zhesvx had an illegal value",-info);
00139 mexErrMsgTxt(msg);
00140 }
00141 } else {
00142 b = mxGetPr(prhs[1]);
00143 x = (double *)mxCalloc(ldb*nrhsb,sizeof(double));
00144 work1 = (double *)mxCalloc(1,sizeof(double));
00145 iwork = (int *)mxCalloc(n,sizeof(int));
00146
00147 dsysvx ( fact, uplo, &n, &nrhsb, A, &lda, AF, &ldaf, ipiv, b, &ldb,
00148 x, &ldx, &rcond, ferr, berr, work1, &lwork, iwork, &info );
00149 if (info < 0) {
00150 sprintf(msg, "Input %d to dsysvx had an illegal value",-info);
00151 mexErrMsgTxt(msg);
00152 }
00153 lwork = (int)(work1[0]);
00154 work = (double *)mxCalloc(lwork,sizeof(double));
00155 dsysvx ( fact, uplo, &n, &nrhsb, A, &lda, AF, &ldaf, ipiv, b, &ldb,
00156 x, &ldx, &rcond, ferr, berr, work, &lwork, iwork, &info );
00157 if (info < 0) {
00158 sprintf(msg, "Input %d to dsysvx had an illegal value",-info);
00159 mexErrMsgTxt(msg);
00160 }
00161 }
00162
00163 if (rcond == 0) {
00164 sprintf(msg,"Matrix is singular to working precision.");
00165 mexErrMsgTxt(msg);
00166 } else if (rcond < mxGetEps()) {
00167 sprintf(msg,"Matrix is close to singular or badly scaled.\n"
00168 " Results may be inaccurate. RCOND = %g",rcond);
00169 mexWarnMsgTxt(msg);
00170 }
00171
00172 if (cplx) {
00173 plhs[0] = fort2mat(x,ldx,ldx,nrhsb);
00174 mxFree(A);
00175 mxFree(b);
00176 mxFree(rwork);
00177 } else {
00178 plhs[0] = mxCreateDoubleMatrix(ldx,nrhsb,0);
00179 mxSetPr(plhs[0],x);
00180 mxFree(iwork);
00181 }
00182
00183 mxFree(AF);
00184 mxFree(ipiv);
00185 mxFree(ferr);
00186 mxFree(berr);
00187 mxFree(work1);
00188 mxFree(work);
00189 }