001    // --- BEGIN LICENSE BLOCK ---
002    /* 
003     * Copyright (c) 2009, Mikio L. Braun
004     * All rights reserved.
005     * 
006     * Redistribution and use in source and binary forms, with or without
007     * modification, are permitted provided that the following conditions are
008     * met:
009     * 
010     *     * Redistributions of source code must retain the above copyright
011     *       notice, this list of conditions and the following disclaimer.
012     * 
013     *     * Redistributions in binary form must reproduce the above
014     *       copyright notice, this list of conditions and the following
015     *       disclaimer in the documentation and/or other materials provided
016     *       with the distribution.
017     * 
018     *     * Neither the name of the Technische Universit?t Berlin nor the
019     *       names of its contributors may be used to endorse or promote
020     *       products derived from this software without specific prior
021     *       written permission.
022     * 
023     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
024     * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
025     * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
026     * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
027     * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
028     * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
029     * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
030     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
031     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
032     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
033     * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
034     */
035    // --- END LICENSE BLOCK ---
036    package org.jblas;
037    
038    import org.jblas.util.Logger;
039    
040    /**
041     * Native BLAS and LAPACK functions.
042     *
043     * <p>The NativeBlas class contains the native BLAS and LAPACK functions. Each
044     * Fortran function is mapped to a static method of this class. For each array argument,
045     * an additional parameter is introduced which gives the offset from the beginning of
046     * the passed array. In C, you would be able to pass a different pointer, but
047     * in Java, you can only pass the whole array.</p>
048     *
049     * <p>Note that due to the way the JNI is usually implemented, the arrays are first
050     * copied outside of the JVM before the function is called. This means that
051     * functions whose runtime is linear in the amount of memory do usually not
052     * run faster just because you are using a native implementation. This holds true
053     * for most Level 1 BLAS routines (like vector addition), and unfortunately also
054     * for most Level 2 BLAS routines (like matrix-vector multiplication). For these,
055     * there exists a class JavaBlas which contains Java implementations.</p>
056     *
057     * <p>In LAPACK, there exist routines which require workspace to be allocated together
058     * with a standard procedure for computing the size of these workspaces. jblas
059     * automatically also generates wrappers for these routines with automatic
060     * workspace allocation. These routines have the same name, but the workspace
061     * arguments are removed.</p>
062     *
063     * <p>Finally, an example: The fortran routine<pre>
064     * SUBROUTINE DAXPY(N,DA,DX,INCX,DY,INCY)
065     *     DOUBLE PRECISION DA
066     *     INTEGER INCX,INCY,N
067     *     DOUBLE PRECISION DX(*),DY(*)
068     * </pre>
069     * becomes <pre>
070     * public static native void daxpy(int n, double da, double[] dx, int dxIdx,
071     *    int incx, double[] dy, int dyIdx, int incy);
072     * </pre>
073     */
074    public class NativeBlas {
075    
076      static {
077              try {
078                      System.loadLibrary("jblas");
079            } catch (UnsatisfiedLinkError e) {
080                Logger.getLogger().config(
081                        "BLAS native library not found in path. Copying native library "
082                        + "from the archive. Consider installing the library somewhere "
083                        + "in the path (for Windows: PATH, for Linux: LD_LIBRARY_PATH).");
084                new org.jblas.util.LibraryLoader().loadLibrary("jblas", true);
085            }
086        }
087        private static int[] intDummy = new int[1];
088        private static double[] doubleDummy = new double[1];
089        private static float[] floatDummy = new float[1];
090    
091         
092      public static native void ccopy(int n, float[] cx, int cxIdx, int incx, float[] cy, int cyIdx, int incy);
093      public static native void dcopy(int n, double[] dx, int dxIdx, int incx, double[] dy, int dyIdx, int incy);
094      public static native void scopy(int n, float[] sx, int sxIdx, int incx, float[] sy, int syIdx, int incy);
095      public static native void zcopy(int n, double[] zx, int zxIdx, int incx, double[] zy, int zyIdx, int incy);
096      public static native void cswap(int n, float[] cx, int cxIdx, int incx, float[] cy, int cyIdx, int incy);
097      public static native void dswap(int n, double[] dx, int dxIdx, int incx, double[] dy, int dyIdx, int incy);
098      public static native void sswap(int n, float[] sx, int sxIdx, int incx, float[] sy, int syIdx, int incy);
099      public static native void zswap(int n, double[] zx, int zxIdx, int incx, double[] zy, int zyIdx, int incy);
100      public static native void caxpy(int n, ComplexFloat ca, float[] cx, int cxIdx, int incx, float[] cy, int cyIdx, int incy);
101      public static native void daxpy(int n, double da, double[] dx, int dxIdx, int incx, double[] dy, int dyIdx, int incy);
102      public static native void saxpy(int n, float sa, float[] sx, int sxIdx, int incx, float[] sy, int syIdx, int incy);
103      public static native void zaxpy(int n, ComplexDouble za, double[] zx, int zxIdx, int incx, double[] zy, int zyIdx, int incy);
104      public static native void cscal(int n, ComplexFloat ca, float[] cx, int cxIdx, int incx);
105      public static native void dscal(int n, double da, double[] dx, int dxIdx, int incx);
106      public static native void sscal(int n, float sa, float[] sx, int sxIdx, int incx);
107      public static native void zscal(int n, ComplexDouble za, double[] zx, int zxIdx, int incx);
108      public static native void csscal(int n, float sa, float[] cx, int cxIdx, int incx);
109      public static native void zdscal(int n, double da, double[] zx, int zxIdx, int incx);
110      public static native ComplexFloat cdotc(int n, float[] cx, int cxIdx, int incx, float[] cy, int cyIdx, int incy);
111      public static native ComplexFloat cdotu(int n, float[] cx, int cxIdx, int incx, float[] cy, int cyIdx, int incy);
112      public static native double ddot(int n, double[] dx, int dxIdx, int incx, double[] dy, int dyIdx, int incy);
113      public static native float sdot(int n, float[] sx, int sxIdx, int incx, float[] sy, int syIdx, int incy);
114      public static native ComplexDouble zdotc(int n, double[] zx, int zxIdx, int incx, double[] zy, int zyIdx, int incy);
115      public static native ComplexDouble zdotu(int n, double[] zx, int zxIdx, int incx, double[] zy, int zyIdx, int incy);
116      public static native double dnrm2(int n, double[] x, int xIdx, int incx);
117      public static native double dznrm2(int n, double[] x, int xIdx, int incx);
118      public static native float scnrm2(int n, float[] x, int xIdx, int incx);
119      public static native float snrm2(int n, float[] x, int xIdx, int incx);
120      public static native double dasum(int n, double[] dx, int dxIdx, int incx);
121      public static native double dzasum(int n, double[] zx, int zxIdx, int incx);
122      public static native float sasum(int n, float[] sx, int sxIdx, int incx);
123      public static native float scasum(int n, float[] cx, int cxIdx, int incx);
124      public static native int icamax(int n, float[] cx, int cxIdx, int incx);
125      public static native int idamax(int n, double[] dx, int dxIdx, int incx);
126      public static native int isamax(int n, float[] sx, int sxIdx, int incx);
127      public static native int izamax(int n, double[] zx, int zxIdx, int incx);
128      public static native void cgemv(char trans, int m, int n, ComplexFloat alpha, float[] a, int aIdx, int lda, float[] x, int xIdx, int incx, ComplexFloat beta, float[] y, int yIdx, int incy);
129      public static native void dgemv(char trans, int m, int n, double alpha, double[] a, int aIdx, int lda, double[] x, int xIdx, int incx, double beta, double[] y, int yIdx, int incy);
130      public static native void sgemv(char trans, int m, int n, float alpha, float[] a, int aIdx, int lda, float[] x, int xIdx, int incx, float beta, float[] y, int yIdx, int incy);
131      public static native void zgemv(char trans, int m, int n, ComplexDouble alpha, double[] a, int aIdx, int lda, double[] x, int xIdx, int incx, ComplexDouble beta, double[] y, int yIdx, int incy);
132      public static native void cgerc(int m, int n, ComplexFloat alpha, float[] x, int xIdx, int incx, float[] y, int yIdx, int incy, float[] a, int aIdx, int lda);
133      public static native void cgeru(int m, int n, ComplexFloat alpha, float[] x, int xIdx, int incx, float[] y, int yIdx, int incy, float[] a, int aIdx, int lda);
134      public static native void dger(int m, int n, double alpha, double[] x, int xIdx, int incx, double[] y, int yIdx, int incy, double[] a, int aIdx, int lda);
135      public static native void sger(int m, int n, float alpha, float[] x, int xIdx, int incx, float[] y, int yIdx, int incy, float[] a, int aIdx, int lda);
136      public static native void zgerc(int m, int n, ComplexDouble alpha, double[] x, int xIdx, int incx, double[] y, int yIdx, int incy, double[] a, int aIdx, int lda);
137      public static native void zgeru(int m, int n, ComplexDouble alpha, double[] x, int xIdx, int incx, double[] y, int yIdx, int incy, double[] a, int aIdx, int lda);
138      public static native void cgemm(char transa, char transb, int m, int n, int k, ComplexFloat alpha, float[] a, int aIdx, int lda, float[] b, int bIdx, int ldb, ComplexFloat beta, float[] c, int cIdx, int ldc);
139      public static native void dgemm(char transa, char transb, int m, int n, int k, double alpha, double[] a, int aIdx, int lda, double[] b, int bIdx, int ldb, double beta, double[] c, int cIdx, int ldc);
140      public static native void sgemm(char transa, char transb, int m, int n, int k, float alpha, float[] a, int aIdx, int lda, float[] b, int bIdx, int ldb, float beta, float[] c, int cIdx, int ldc);
141      public static native void zgemm(char transa, char transb, int m, int n, int k, ComplexDouble alpha, double[] a, int aIdx, int lda, double[] b, int bIdx, int ldb, ComplexDouble beta, double[] c, int cIdx, int ldc);
142      public static native int dgesv(int n, int nrhs, double[] a, int aIdx, int lda, int[] ipiv, int ipivIdx, double[] b, int bIdx, int ldb);
143      public static native int sgesv(int n, int nrhs, float[] a, int aIdx, int lda, int[] ipiv, int ipivIdx, float[] b, int bIdx, int ldb);
144      public static native int dsysv(char uplo, int n, int nrhs, double[] a, int aIdx, int lda, int[] ipiv, int ipivIdx, double[] b, int bIdx, int ldb, double[] work, int workIdx, int lwork);
145      public static int dsysv(char uplo, int n, int nrhs, double[] a, int aIdx, int lda, int[] ipiv, int ipivIdx, double[] b, int bIdx, int ldb) {
146        int info;
147        double[] work = new double[1];
148        int lwork;
149        info = dsysv(uplo, n, nrhs, doubleDummy, 0, lda, intDummy, 0, doubleDummy, 0, ldb, work, 0, -1);
150        if (info != 0)
151          return info;
152        lwork = (int) work[0]; work = new double[lwork];
153        info = dsysv(uplo, n, nrhs, a, aIdx, lda, ipiv, ipivIdx, b, bIdx, ldb, work, 0, lwork);
154        return info;
155      }
156    
157      public static native int ssysv(char uplo, int n, int nrhs, float[] a, int aIdx, int lda, int[] ipiv, int ipivIdx, float[] b, int bIdx, int ldb, float[] work, int workIdx, int lwork);
158      public static int ssysv(char uplo, int n, int nrhs, float[] a, int aIdx, int lda, int[] ipiv, int ipivIdx, float[] b, int bIdx, int ldb) {
159        int info;
160        float[] work = new float[1];
161        int lwork;
162        info = ssysv(uplo, n, nrhs, floatDummy, 0, lda, intDummy, 0, floatDummy, 0, ldb, work, 0, -1);
163        if (info != 0)
164          return info;
165        lwork = (int) work[0]; work = new float[lwork];
166        info = ssysv(uplo, n, nrhs, a, aIdx, lda, ipiv, ipivIdx, b, bIdx, ldb, work, 0, lwork);
167        return info;
168      }
169    
170      public static native int dsyev(char jobz, char uplo, int n, double[] a, int aIdx, int lda, double[] w, int wIdx, double[] work, int workIdx, int lwork);
171      public static int dsyev(char jobz, char uplo, int n, double[] a, int aIdx, int lda, double[] w, int wIdx) {
172        int info;
173        double[] work = new double[1];
174        int lwork;
175        info = dsyev(jobz, uplo, n, doubleDummy, 0, lda, doubleDummy, 0, work, 0, -1);
176        if (info != 0)
177          return info;
178        lwork = (int) work[0]; work = new double[lwork];
179        info = dsyev(jobz, uplo, n, a, aIdx, lda, w, wIdx, work, 0, lwork);
180        return info;
181      }
182    
183      public static native int ssyev(char jobz, char uplo, int n, float[] a, int aIdx, int lda, float[] w, int wIdx, float[] work, int workIdx, int lwork);
184      public static int ssyev(char jobz, char uplo, int n, float[] a, int aIdx, int lda, float[] w, int wIdx) {
185        int info;
186        float[] work = new float[1];
187        int lwork;
188        info = ssyev(jobz, uplo, n, floatDummy, 0, lda, floatDummy, 0, work, 0, -1);
189        if (info != 0)
190          return info;
191        lwork = (int) work[0]; work = new float[lwork];
192        info = ssyev(jobz, uplo, n, a, aIdx, lda, w, wIdx, work, 0, lwork);
193        return info;
194      }
195    
196      public static native int dsyevd(char jobz, char uplo, int n, double[] a, int aIdx, int lda, double[] w, int wIdx, double[] work, int workIdx, int lwork, int[] iwork, int iworkIdx, int liwork);
197      public static int dsyevd(char jobz, char uplo, int n, double[] a, int aIdx, int lda, double[] w, int wIdx) {
198        int info;
199        double[] work = new double[1];
200        int lwork;
201        int[] iwork = new int[1];
202        int liwork;
203        info = dsyevd(jobz, uplo, n, doubleDummy, 0, lda, doubleDummy, 0, work, 0, -1, iwork, 0, -1);
204        if (info != 0)
205          return info;
206        lwork = (int) work[0]; work = new double[lwork];
207        liwork = (int) iwork[0]; iwork = new int[liwork];
208        info = dsyevd(jobz, uplo, n, a, aIdx, lda, w, wIdx, work, 0, lwork, iwork, 0, liwork);
209        return info;
210      }
211    
212      public static native int dsyevr(char jobz, char range, char uplo, int n, double[] a, int aIdx, int lda, double vl, double vu, int il, int iu, double abstol, int[] m, int mIdx, double[] w, int wIdx, double[] z, int zIdx, int ldz, int[] isuppz, int isuppzIdx, double[] work, int workIdx, int lwork, int[] iwork, int iworkIdx, int liwork);
213      public static int dsyevr(char jobz, char range, char uplo, int n, double[] a, int aIdx, int lda, double vl, double vu, int il, int iu, double abstol, int[] m, int mIdx, double[] w, int wIdx, double[] z, int zIdx, int ldz, int[] isuppz, int isuppzIdx) {
214        int info;
215        double[] work = new double[1];
216        int lwork;
217        int[] iwork = new int[1];
218        int liwork;
219        info = dsyevr(jobz, range, uplo, n, doubleDummy, 0, lda, vl, vu, il, iu, abstol, intDummy, 0, doubleDummy, 0, doubleDummy, 0, ldz, intDummy, 0, work, 0, -1, iwork, 0, -1);
220        if (info != 0)
221          return info;
222        lwork = (int) work[0]; work = new double[lwork];
223        liwork = (int) iwork[0]; iwork = new int[liwork];
224        info = dsyevr(jobz, range, uplo, n, a, aIdx, lda, vl, vu, il, iu, abstol, m, mIdx, w, wIdx, z, zIdx, ldz, isuppz, isuppzIdx, work, 0, lwork, iwork, 0, liwork);
225        return info;
226      }
227    
228      public static native int dsyevx(char jobz, char range, char uplo, int n, double[] a, int aIdx, int lda, double vl, double vu, int il, int iu, double abstol, int[] m, int mIdx, double[] w, int wIdx, double[] z, int zIdx, int ldz, double[] work, int workIdx, int lwork, int[] iwork, int iworkIdx, int[] ifail, int ifailIdx);
229      public static int dsyevx(char jobz, char range, char uplo, int n, double[] a, int aIdx, int lda, double vl, double vu, int il, int iu, double abstol, int[] m, int mIdx, double[] w, int wIdx, double[] z, int zIdx, int ldz, int[] iwork, int iworkIdx, int[] ifail, int ifailIdx) {
230        int info;
231        double[] work = new double[1];
232        int lwork;
233        info = dsyevx(jobz, range, uplo, n, doubleDummy, 0, lda, vl, vu, il, iu, abstol, intDummy, 0, doubleDummy, 0, doubleDummy, 0, ldz, work, 0, -1, intDummy, 0, intDummy, 0);
234        if (info != 0)
235          return info;
236        lwork = (int) work[0]; work = new double[lwork];
237        info = dsyevx(jobz, range, uplo, n, a, aIdx, lda, vl, vu, il, iu, abstol, m, mIdx, w, wIdx, z, zIdx, ldz, work, 0, lwork, iwork, iworkIdx, ifail, ifailIdx);
238        return info;
239      }
240    
241      public static native int ssyevd(char jobz, char uplo, int n, float[] a, int aIdx, int lda, float[] w, int wIdx, float[] work, int workIdx, int lwork, int[] iwork, int iworkIdx, int liwork);
242      public static int ssyevd(char jobz, char uplo, int n, float[] a, int aIdx, int lda, float[] w, int wIdx) {
243        int info;
244        float[] work = new float[1];
245        int lwork;
246        int[] iwork = new int[1];
247        int liwork;
248        info = ssyevd(jobz, uplo, n, floatDummy, 0, lda, floatDummy, 0, work, 0, -1, iwork, 0, -1);
249        if (info != 0)
250          return info;
251        lwork = (int) work[0]; work = new float[lwork];
252        liwork = (int) iwork[0]; iwork = new int[liwork];
253        info = ssyevd(jobz, uplo, n, a, aIdx, lda, w, wIdx, work, 0, lwork, iwork, 0, liwork);
254        return info;
255      }
256    
257      public static native int ssyevr(char jobz, char range, char uplo, int n, float[] a, int aIdx, int lda, float vl, float vu, int il, int iu, float abstol, int[] m, int mIdx, float[] w, int wIdx, float[] z, int zIdx, int ldz, int[] isuppz, int isuppzIdx, float[] work, int workIdx, int lwork, int[] iwork, int iworkIdx, int liwork);
258      public static int ssyevr(char jobz, char range, char uplo, int n, float[] a, int aIdx, int lda, float vl, float vu, int il, int iu, float abstol, int[] m, int mIdx, float[] w, int wIdx, float[] z, int zIdx, int ldz, int[] isuppz, int isuppzIdx) {
259        int info;
260        float[] work = new float[1];
261        int lwork;
262        int[] iwork = new int[1];
263        int liwork;
264        info = ssyevr(jobz, range, uplo, n, floatDummy, 0, lda, vl, vu, il, iu, abstol, intDummy, 0, floatDummy, 0, floatDummy, 0, ldz, intDummy, 0, work, 0, -1, iwork, 0, -1);
265        if (info != 0)
266          return info;
267        lwork = (int) work[0]; work = new float[lwork];
268        liwork = (int) iwork[0]; iwork = new int[liwork];
269        info = ssyevr(jobz, range, uplo, n, a, aIdx, lda, vl, vu, il, iu, abstol, m, mIdx, w, wIdx, z, zIdx, ldz, isuppz, isuppzIdx, work, 0, lwork, iwork, 0, liwork);
270        return info;
271      }
272    
273      public static native int ssyevx(char jobz, char range, char uplo, int n, float[] a, int aIdx, int lda, float vl, float vu, int il, int iu, float abstol, int[] m, int mIdx, float[] w, int wIdx, float[] z, int zIdx, int ldz, float[] work, int workIdx, int lwork, int[] iwork, int iworkIdx, int[] ifail, int ifailIdx);
274      public static int ssyevx(char jobz, char range, char uplo, int n, float[] a, int aIdx, int lda, float vl, float vu, int il, int iu, float abstol, int[] m, int mIdx, float[] w, int wIdx, float[] z, int zIdx, int ldz, int[] iwork, int iworkIdx, int[] ifail, int ifailIdx) {
275        int info;
276        float[] work = new float[1];
277        int lwork;
278        info = ssyevx(jobz, range, uplo, n, floatDummy, 0, lda, vl, vu, il, iu, abstol, intDummy, 0, floatDummy, 0, floatDummy, 0, ldz, work, 0, -1, intDummy, 0, intDummy, 0);
279        if (info != 0)
280          return info;
281        lwork = (int) work[0]; work = new float[lwork];
282        info = ssyevx(jobz, range, uplo, n, a, aIdx, lda, vl, vu, il, iu, abstol, m, mIdx, w, wIdx, z, zIdx, ldz, work, 0, lwork, iwork, iworkIdx, ifail, ifailIdx);
283        return info;
284      }
285    
286      public static native int dposv(char uplo, int n, int nrhs, double[] a, int aIdx, int lda, double[] b, int bIdx, int ldb);
287      public static native int sposv(char uplo, int n, int nrhs, float[] a, int aIdx, int lda, float[] b, int bIdx, int ldb);
288      public static native int cgeev(char jobvl, char jobvr, int n, float[] a, int aIdx, int lda, float[] w, int wIdx, float[] vl, int vlIdx, int ldvl, float[] vr, int vrIdx, int ldvr, float[] work, int workIdx, int lwork, float[] rwork, int rworkIdx);
289      public static int cgeev(char jobvl, char jobvr, int n, float[] a, int aIdx, int lda, float[] w, int wIdx, float[] vl, int vlIdx, int ldvl, float[] vr, int vrIdx, int ldvr, float[] rwork, int rworkIdx) {
290        int info;
291        float[] work = new float[1*2];
292        int lwork;
293        info = cgeev(jobvl, jobvr, n, floatDummy, 0, lda, floatDummy, 0, floatDummy, 0, ldvl, floatDummy, 0, ldvr, work, 0, -1, floatDummy, 0);
294        if (info != 0)
295          return info;
296        lwork = (int) work[0]; work = new float[lwork*2];
297        info = cgeev(jobvl, jobvr, n, a, aIdx, lda, w, wIdx, vl, vlIdx, ldvl, vr, vrIdx, ldvr, work, 0, lwork, rwork, rworkIdx);
298        return info;
299      }
300    
301      public static native int dgeev(char jobvl, char jobvr, int n, double[] a, int aIdx, int lda, double[] wr, int wrIdx, double[] wi, int wiIdx, double[] vl, int vlIdx, int ldvl, double[] vr, int vrIdx, int ldvr, double[] work, int workIdx, int lwork);
302      public static int dgeev(char jobvl, char jobvr, int n, double[] a, int aIdx, int lda, double[] wr, int wrIdx, double[] wi, int wiIdx, double[] vl, int vlIdx, int ldvl, double[] vr, int vrIdx, int ldvr) {
303        int info;
304        double[] work = new double[1];
305        int lwork;
306        info = dgeev(jobvl, jobvr, n, doubleDummy, 0, lda, doubleDummy, 0, doubleDummy, 0, doubleDummy, 0, ldvl, doubleDummy, 0, ldvr, work, 0, -1);
307        if (info != 0)
308          return info;
309        lwork = (int) work[0]; work = new double[lwork];
310        info = dgeev(jobvl, jobvr, n, a, aIdx, lda, wr, wrIdx, wi, wiIdx, vl, vlIdx, ldvl, vr, vrIdx, ldvr, work, 0, lwork);
311        return info;
312      }
313    
314      public static native int sgeev(char jobvl, char jobvr, int n, float[] a, int aIdx, int lda, float[] wr, int wrIdx, float[] wi, int wiIdx, float[] vl, int vlIdx, int ldvl, float[] vr, int vrIdx, int ldvr, float[] work, int workIdx, int lwork);
315      public static int sgeev(char jobvl, char jobvr, int n, float[] a, int aIdx, int lda, float[] wr, int wrIdx, float[] wi, int wiIdx, float[] vl, int vlIdx, int ldvl, float[] vr, int vrIdx, int ldvr) {
316        int info;
317        float[] work = new float[1];
318        int lwork;
319        info = sgeev(jobvl, jobvr, n, floatDummy, 0, lda, floatDummy, 0, floatDummy, 0, floatDummy, 0, ldvl, floatDummy, 0, ldvr, work, 0, -1);
320        if (info != 0)
321          return info;
322        lwork = (int) work[0]; work = new float[lwork];
323        info = sgeev(jobvl, jobvr, n, a, aIdx, lda, wr, wrIdx, wi, wiIdx, vl, vlIdx, ldvl, vr, vrIdx, ldvr, work, 0, lwork);
324        return info;
325      }
326    
327      public static native int zgeev(char jobvl, char jobvr, int n, double[] a, int aIdx, int lda, double[] w, int wIdx, double[] vl, int vlIdx, int ldvl, double[] vr, int vrIdx, int ldvr, double[] work, int workIdx, int lwork, double[] rwork, int rworkIdx);
328      public static int zgeev(char jobvl, char jobvr, int n, double[] a, int aIdx, int lda, double[] w, int wIdx, double[] vl, int vlIdx, int ldvl, double[] vr, int vrIdx, int ldvr, double[] rwork, int rworkIdx) {
329        int info;
330        double[] work = new double[1*2];
331        int lwork;
332        info = zgeev(jobvl, jobvr, n, doubleDummy, 0, lda, doubleDummy, 0, doubleDummy, 0, ldvl, doubleDummy, 0, ldvr, work, 0, -1, doubleDummy, 0);
333        if (info != 0)
334          return info;
335        lwork = (int) work[0]; work = new double[lwork*2];
336        info = zgeev(jobvl, jobvr, n, a, aIdx, lda, w, wIdx, vl, vlIdx, ldvl, vr, vrIdx, ldvr, work, 0, lwork, rwork, rworkIdx);
337        return info;
338      }
339    
340      public static native int dgetrf(int m, int n, double[] a, int aIdx, int lda, int[] ipiv, int ipivIdx);
341      public static native int sgetrf(int m, int n, float[] a, int aIdx, int lda, int[] ipiv, int ipivIdx);
342      public static native int dpotrf(char uplo, int n, double[] a, int aIdx, int lda);
343      public static native int spotrf(char uplo, int n, float[] a, int aIdx, int lda);
344      public static native int cgesvd(char jobu, char jobvt, int m, int n, float[] a, int aIdx, int lda, float[] s, int sIdx, float[] u, int uIdx, int ldu, float[] vt, int vtIdx, int ldvt, float[] work, int workIdx, int lwork, float[] rwork, int rworkIdx);
345      public static int cgesvd(char jobu, char jobvt, int m, int n, float[] a, int aIdx, int lda, float[] s, int sIdx, float[] u, int uIdx, int ldu, float[] vt, int vtIdx, int ldvt, float[] rwork, int rworkIdx) {
346        int info;
347        float[] work = new float[1*2];
348        int lwork;
349        info = cgesvd(jobu, jobvt, m, n, floatDummy, 0, lda, floatDummy, 0, floatDummy, 0, ldu, floatDummy, 0, ldvt, work, 0, -1, floatDummy, 0);
350        if (info != 0)
351          return info;
352        lwork = (int) work[0]; work = new float[lwork*2];
353        info = cgesvd(jobu, jobvt, m, n, a, aIdx, lda, s, sIdx, u, uIdx, ldu, vt, vtIdx, ldvt, work, 0, lwork, rwork, rworkIdx);
354        return info;
355      }
356    
357      public static native int dgesvd(char jobu, char jobvt, int m, int n, double[] a, int aIdx, int lda, double[] s, int sIdx, double[] u, int uIdx, int ldu, double[] vt, int vtIdx, int ldvt, double[] work, int workIdx, int lwork);
358      public static int dgesvd(char jobu, char jobvt, int m, int n, double[] a, int aIdx, int lda, double[] s, int sIdx, double[] u, int uIdx, int ldu, double[] vt, int vtIdx, int ldvt) {
359        int info;
360        double[] work = new double[1];
361        int lwork;
362        info = dgesvd(jobu, jobvt, m, n, doubleDummy, 0, lda, doubleDummy, 0, doubleDummy, 0, ldu, doubleDummy, 0, ldvt, work, 0, -1);
363        if (info != 0)
364          return info;
365        lwork = (int) work[0]; work = new double[lwork];
366        info = dgesvd(jobu, jobvt, m, n, a, aIdx, lda, s, sIdx, u, uIdx, ldu, vt, vtIdx, ldvt, work, 0, lwork);
367        return info;
368      }
369    
370      public static native int sgesvd(char jobu, char jobvt, int m, int n, float[] a, int aIdx, int lda, float[] s, int sIdx, float[] u, int uIdx, int ldu, float[] vt, int vtIdx, int ldvt, float[] work, int workIdx, int lwork);
371      public static int sgesvd(char jobu, char jobvt, int m, int n, float[] a, int aIdx, int lda, float[] s, int sIdx, float[] u, int uIdx, int ldu, float[] vt, int vtIdx, int ldvt) {
372        int info;
373        float[] work = new float[1];
374        int lwork;
375        info = sgesvd(jobu, jobvt, m, n, floatDummy, 0, lda, floatDummy, 0, floatDummy, 0, ldu, floatDummy, 0, ldvt, work, 0, -1);
376        if (info != 0)
377          return info;
378        lwork = (int) work[0]; work = new float[lwork];
379        info = sgesvd(jobu, jobvt, m, n, a, aIdx, lda, s, sIdx, u, uIdx, ldu, vt, vtIdx, ldvt, work, 0, lwork);
380        return info;
381      }
382    
383      public static native int zgesvd(char jobu, char jobvt, int m, int n, double[] a, int aIdx, int lda, double[] s, int sIdx, double[] u, int uIdx, int ldu, double[] vt, int vtIdx, int ldvt, double[] work, int workIdx, int lwork, double[] rwork, int rworkIdx);
384      public static int zgesvd(char jobu, char jobvt, int m, int n, double[] a, int aIdx, int lda, double[] s, int sIdx, double[] u, int uIdx, int ldu, double[] vt, int vtIdx, int ldvt, double[] rwork, int rworkIdx) {
385        int info;
386        double[] work = new double[1*2];
387        int lwork;
388        info = zgesvd(jobu, jobvt, m, n, doubleDummy, 0, lda, doubleDummy, 0, doubleDummy, 0, ldu, doubleDummy, 0, ldvt, work, 0, -1, doubleDummy, 0);
389        if (info != 0)
390          return info;
391        lwork = (int) work[0]; work = new double[lwork*2];
392        info = zgesvd(jobu, jobvt, m, n, a, aIdx, lda, s, sIdx, u, uIdx, ldu, vt, vtIdx, ldvt, work, 0, lwork, rwork, rworkIdx);
393        return info;
394      }
395    
396      public static native int dsygvd(int itype, char jobz, char uplo, int n, double[] a, int aIdx, int lda, double[] b, int bIdx, int ldb, double[] w, int wIdx, double[] work, int workIdx, int lwork, int[] iwork, int iworkIdx, int liwork);
397      public static int dsygvd(int itype, char jobz, char uplo, int n, double[] a, int aIdx, int lda, double[] b, int bIdx, int ldb, double[] w, int wIdx) {
398        int info;
399        double[] work = new double[1];
400        int lwork;
401        int[] iwork = new int[1];
402        int liwork;
403        info = dsygvd(itype, jobz, uplo, n, doubleDummy, 0, lda, doubleDummy, 0, ldb, doubleDummy, 0, work, 0, -1, iwork, 0, -1);
404        if (info != 0)
405          return info;
406        lwork = (int) work[0]; work = new double[lwork];
407        liwork = (int) iwork[0]; iwork = new int[liwork];
408        info = dsygvd(itype, jobz, uplo, n, a, aIdx, lda, b, bIdx, ldb, w, wIdx, work, 0, lwork, iwork, 0, liwork);
409        return info;
410      }
411    
412      public static native int ssygvd(int itype, char jobz, char uplo, int n, float[] a, int aIdx, int lda, float[] b, int bIdx, int ldb, float[] w, int wIdx, float[] work, int workIdx, int lwork, int[] iwork, int iworkIdx, int liwork);
413      public static int ssygvd(int itype, char jobz, char uplo, int n, float[] a, int aIdx, int lda, float[] b, int bIdx, int ldb, float[] w, int wIdx) {
414        int info;
415        float[] work = new float[1];
416        int lwork;
417        int[] iwork = new int[1];
418        int liwork;
419        info = ssygvd(itype, jobz, uplo, n, floatDummy, 0, lda, floatDummy, 0, ldb, floatDummy, 0, work, 0, -1, iwork, 0, -1);
420        if (info != 0)
421          return info;
422        lwork = (int) work[0]; work = new float[lwork];
423        liwork = (int) iwork[0]; iwork = new int[liwork];
424        info = ssygvd(itype, jobz, uplo, n, a, aIdx, lda, b, bIdx, ldb, w, wIdx, work, 0, lwork, iwork, 0, liwork);
425        return info;
426      }
427    
428    
429    }