Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If you look inside the <em><a href="http://www.mathworks.com/matlabcentral/fileexchange/16777-lapack/content/lapack.m" rel="nofollow noreferrer">lapack.m</a></em> file from the FEX submission mentioned, you will see a couple of examples on how to use the function:</p> <h3>Example: SVD decomposition using <a href="http://www.netlib.org/lapack/explore-html/dgesvd.f.html" rel="nofollow noreferrer">DGESVD</a>:</h3> <pre><code>X = rand(4,3); [m,n] = size(X); C = lapack('dgesvd', ... 'A', 'A', ... % compute ALL left/right singular vectors m, n, X, m, ... % input MxN matrix zeros(n,1), ... % output S array zeros(m), m, ... % output U matrix zeros(n), n, .... % output VT matrix zeros(5*m,1), 5*m, ... % workspace array 0 ... % return value ); [s,U,VT] = C{[7,8,10]}; % extract outputs V = VT'; </code></pre> <p><em>(Note: the reason we used those dummy variables for output variables is because Fortran functions expect all arguments to be passed by reference, but MEX-functions in MATLAB do not allow modifying their input, thus it's written to return copies of all inputs in a cell array with any modifications)</em></p> <p>We get:</p> <pre><code>U = -0.44459 -0.6264 -0.54243 0.3402 -0.61505 0.035348 0.69537 0.37004 -0.41561 -0.26532 0.10543 -0.86357 -0.50132 0.73211 -0.45948 -0.039753 s = 2.1354 0.88509 0.27922 V = -0.58777 0.20822 -0.78178 -0.6026 -0.75743 0.25133 -0.53981 0.61882 0.57067 </code></pre> <p>Which is equivalent to MATLAB's own <a href="http://www.mathworks.com/help/matlab/ref/svd.html" rel="nofollow noreferrer">SVD</a> function:</p> <pre><code>[U,S,V] = svd(X); s = diag(S); </code></pre> <p>that gives:</p> <pre><code>U = -0.44459 -0.6264 -0.54243 0.3402 -0.61505 0.035348 0.69537 0.37004 -0.41561 -0.26532 0.10543 -0.86357 -0.50132 0.73211 -0.45948 -0.039753 s = 2.1354 0.88509 0.27922 V = -0.58777 0.20822 -0.78178 -0.6026 -0.75743 0.25133 -0.53981 0.61882 0.57067 </code></pre> <hr> <h1>EDIT:</h1> <p>For completeness, I show below an example of a MEX-function directly calling the Fortran interface of the DGESVD routine.</p> <p>The good news is that MATLAB provides <code>libmwlapack</code> and <code>libmwblas</code> libraries and two corresponding header files <code>blas.h</code> and <code>lapack.h</code> we can use. In fact, there is a page in the documentation explaining the process of <a href="http://www.mathworks.com/help/matlab/matlab_external/calling-lapack-and-blas-functions-from-mex-files.html" rel="nofollow noreferrer">calling BLAS/LAPACK functions from MEX-files</a>.</p> <p>In our case, <code>lapack.h</code> defines the following prototype:</p> <pre><code>extern void dgesvd(char *jobu, char *jobvt, ptrdiff_t *m, ptrdiff_t *n, double *a, ptrdiff_t *lda, double *s, double *u, ptrdiff_t *ldu, double *vt, ptrdiff_t *ldvt, double *work, ptrdiff_t *lwork, ptrdiff_t *info); </code></pre> <h3>svd_lapack.c</h3> <pre><code>#include "mex.h" #include "lapack.h" void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mwSignedIndex m, n, lwork, info=0; double *A, *U, *S, *VT, *work; double workopt = 0; mxArray *in; /* verify input/output arguments */ if (nrhs != 1) { mexErrMsgTxt("One input argument required."); } if (nlhs &gt; 3) { mexErrMsgTxt("Too many output arguments."); } if (!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0])) { mexErrMsgTxt("Input matrix must be real double matrix."); } /* duplicate input matrix (since its contents will be overwritten) */ in = mxDuplicateArray(prhs[0]); /* dimensions of input matrix */ m = mxGetM(in); n = mxGetN(in); /* create output matrices */ plhs[0] = mxCreateDoubleMatrix(m, m, mxREAL); plhs[1] = mxCreateDoubleMatrix((m&lt;n)?m:n, 1, mxREAL); plhs[2] = mxCreateDoubleMatrix(n, n, mxREAL); /* get pointers to data */ A = mxGetPr(in); U = mxGetPr(plhs[0]); S = mxGetPr(plhs[1]); VT = mxGetPr(plhs[2]); /* query and allocate the optimal workspace size */ lwork = -1; dgesvd("A", "A", &amp;m, &amp;n, A, &amp;m, S, U, &amp;m, VT, &amp;n, &amp;workopt, &amp;lwork, &amp;info); lwork = (mwSignedIndex) workopt; work = (double *) mxMalloc(lwork * sizeof(double)); /* perform SVD decomposition */ dgesvd("A", "A", &amp;m, &amp;n, A, &amp;m, S, U, &amp;m, VT, &amp;n, work, &amp;lwork, &amp;info); /* cleanup */ mxFree(work); mxDestroyArray(in); /* check if call was successful */ if (info &lt; 0) { mexErrMsgTxt("Illegal values in arguments."); } else if (info &gt; 0) { mexErrMsgTxt("Failed to converge."); } } </code></pre> <p>On my 64-bit Windows, I compile the MEX-file as: <code>mex -largeArrayDims svd_lapack.c "C:\Program Files\MATLAB\R2013a\extern\lib\win64\microsoft\libmwlapack.lib"</code></p> <p>Here is a test:</p> <pre><code>&gt;&gt; X = rand(4,3); &gt;&gt; [U,S,VT] = svd_lapack(X) U = -0.5964 0.4049 0.6870 -0.0916 -0.3635 0.3157 -0.3975 0.7811 -0.3514 0.3645 -0.6022 -0.6173 -0.6234 -0.7769 -0.0861 -0.0199 S = 1.0337 0.5136 0.0811 VT = -0.6065 -0.5151 -0.6057 0.0192 0.7521 -0.6588 -0.7949 0.4112 0.4462 </code></pre> <p>vs.</p> <pre><code>&gt;&gt; [U,S,V] = svd(X); &gt;&gt; U, diag(S), V' U = -0.5964 0.4049 0.6870 0.0916 -0.3635 0.3157 -0.3975 -0.7811 -0.3514 0.3645 -0.6022 0.6173 -0.6234 -0.7769 -0.0861 0.0199 ans = 1.0337 0.5136 0.0811 ans = -0.6065 -0.5151 -0.6057 0.0192 0.7521 -0.6588 -0.7949 0.4112 0.4462 </code></pre> <p><em>(remember that the sign of the eigenvectors in <code>U</code> and <code>V</code> is arbitrary, so you might get flipped signs comparing the two)</em></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload