Eötvös Quantum Utilities  v4.9.146
Providing the Horsepowers in the Quantum Realm
zggev.c
Go to the documentation of this file.
1 /*======================================================================
2  (See: http://www.netlib.org/lapack/explore-html/d9/d52/zggev_8f.html for details)
3  Copyright (C) 2016 Peter Rakyta, Ph.D.
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see http://www.gnu.org/licenses/.
17 
18 ====================================================================== */
19 
32 #include "mex.h"
33 #define lapack_int long
34 #include "mkl.h"
35 
36 #ifdef __cplusplus
37 extern "C"
38 #endif
39 
40 
47 void mexFunction(int nlhs, mxArray *plhs[],
48  int nrhs, const mxArray *prhs[])
49 {
50 /* variable declarations here */
51 /* Array information: */
52  mwSize nonzerosA; /*number of nonzeros elements in A*/
53  mwSize sizeAm, sizeAn; /*size of the matrix A (rows, and cols) */
54  mwSize sizeBm, sizeBn; /*size of the matrix B (rows, and cols) */
55  lapack_int sizeAm_mkl, sizeAn_mkl;
56  lapack_int sizeBm_mkl, sizeBn_mkl;
57 
58 
59  lapack_complex_double *a, *b, *alpha, *beta, *l_eigvec, *r_eigvec;
60 /* pointers to the real and imaginary marts of the MATLAB matrices */
61  double *ar, *ai, *br, *bi;
62  double *alphar, *alphai, *betar, *betai;
63  double *l_eigvec_r, *l_eigvec_i, *r_eigvec_r, *r_eigvec_i;
64 
65  double Work1[1];
66  double *Work;
67 
68  lapack_int Lwork, info;
69  lapack_int idx;
70 
71 
72 
73 /* code here */
74 /*-----------------------------------------------------------------------*/
75 /* Check for proper number of arguments. */
76  if(nrhs != 2) {
77  mexErrMsgIdAndTxt ("MATLAB:zggev:nInput", "Two inputs required.");
78  }
79  else if (nlhs > 5) {
80  mexErrMsgIdAndTxt ("MATLAB:zggev:nOutput", "Too many output arguments.");
81  }
82 
83 /* Validate inputs */
84 
85 /* Check that the input is a double.*/
86  if ((mxIsDouble(prhs[0]) == 0) && (mxIsDouble(prhs[1]) == 0)) {
87  mexErrMsgIdAndTxt ("MATLAB:zggev:NonDouble", "Inputs must be both a double.");
88  }
89 
90 /* Check if inputs are complex.*/
91  if ((mxIsComplex(prhs[0]) == 0) && (mxIsComplex(prhs[1]) == 0)) {
92  mexErrMsgIdAndTxt ("MATLAB:convec:NonReal", "Inputs must be both complex");
93  }
94 
95 /* Get the size of the input array. (MATLAB) */
96  sizeAm = mxGetM(prhs[0]);
97  sizeAn = mxGetN(prhs[0]);
98  sizeBm = mxGetM(prhs[1]);
99  sizeBn = mxGetN(prhs[1]);
100 
101  ar = mxGetPr(prhs[0]);
102  br = mxGetPr(prhs[1]);
103  ai = mxGetPi(prhs[0]);
104  bi = mxGetPi(prhs[1]);
105 
106 /* Creating output arrays */
107  plhs[0] = mxCreateDoubleMatrix(sizeAm, 1, mxCOMPLEX); /* alpha*/
108  plhs[1] = mxCreateDoubleMatrix(sizeAm, 1, mxCOMPLEX); /* beta*/
109  plhs[2] = mxCreateDoubleMatrix(sizeAm, sizeAn, mxCOMPLEX); /* l_eigvec*/
110  plhs[3] = mxCreateDoubleMatrix(sizeAm, sizeAn, mxCOMPLEX); /* r_eigvec*/
111 
112 
113  alphar = mxGetPr(plhs[0]);
114  alphai = mxGetPi(plhs[0]);
115  betar = mxGetPr(plhs[1]);
116  betai = mxGetPi(plhs[1]);
117  l_eigvec_r = mxGetPr(plhs[2]);
118  l_eigvec_i = mxGetPi(plhs[2]);
119  r_eigvec_r = mxGetPr(plhs[3]);
120  r_eigvec_i = mxGetPi(plhs[3]);
121 
122 
123 
124  sizeAm_mkl = (lapack_int)sizeAm;
125  sizeAn_mkl = (lapack_int)sizeAn;
126  sizeBm_mkl = (lapack_int)sizeBm;
127  sizeBn_mkl = (lapack_int)sizeBn;
128 
129  if ( sizeAm != sizeAn || sizeAm != sizeBm || sizeAm != sizeBn ) {
130  mexErrMsgIdAndTxt ("MATLAB:dggev:MatrixSize", "Inputs must be square matrices and must have the same dimensions.");
131  }
132 
133 #ifdef DEBUG
134  mexPrintf("Size of the matrix: %d\n", sizeAm_mkl);
135 #endif
136 
137 /* Creating LAPACKE arrays */
138  a = (lapack_complex_double*)malloc(sizeAm_mkl*sizeAm_mkl*sizeof(lapack_complex_double));
139  if ( a == NULL ) {
140  mexErrMsgIdAndTxt ("MATLAB:zggev:malloc", "Failed to allocate space for matrix A.");
141  }
142 
143  b = (lapack_complex_double*)malloc(sizeBm_mkl*sizeBm_mkl*sizeof(lapack_complex_double));
144  if ( b == NULL ) {
145  mexErrMsgIdAndTxt ("MATLAB:zggev:malloc", "Failed to allocate space for matrix B.");
146  }
147 
148  for( idx=1; idx<=sizeBm_mkl*sizeBm_mkl; idx++) {
149  a[idx-1].real = ar[idx-1];
150  a[idx-1].imag = ai[idx-1];
151  b[idx-1].real = br[idx-1];
152  b[idx-1].imag = bi[idx-1];
153  }
154 
155  l_eigvec = (lapack_complex_double*)malloc(sizeBm_mkl*sizeBm_mkl*sizeof(lapack_complex_double));
156  if ( l_eigvec == NULL ) {
157  mexErrMsgIdAndTxt ("MATLAB:zggev:malloc", "Failed to allocate space for matrix l_eigvec.");
158  }
159 
160  r_eigvec = (lapack_complex_double*)malloc(sizeBm_mkl*sizeBm_mkl*sizeof(lapack_complex_double));
161  if ( r_eigvec == NULL ) {
162  mexErrMsgIdAndTxt ("MATLAB:zggev:malloc", "Failed to allocate space for matrix r_eigvec.");
163  }
164 
165 
166  alpha = (lapack_complex_double*)malloc(sizeBm_mkl*sizeof(lapack_complex_double));
167  if ( alpha == NULL ) {
168  mexErrMsgIdAndTxt ("MATLAB:zggev:malloc", "Failed to allocate space for matrix alpha.");
169  }
170 
171  beta = (lapack_complex_double*)malloc(sizeBm_mkl*sizeof(lapack_complex_double));
172  if ( beta == NULL ) {
173  mexErrMsgIdAndTxt ("MATLAB:zggev:malloc", "Failed to allocate space for matrix beta.");
174  }
175 mkl_set_num_threads_local(12);
176  info = LAPACKE_zggev( LAPACK_COL_MAJOR, 'V', 'V',
177  sizeAm_mkl, a, sizeAn_mkl, b,
178  sizeBm_mkl, alpha,
179  beta, l_eigvec, sizeAm_mkl, r_eigvec,
180  sizeAm_mkl );
181 
182 /* TODO_ check info */
183 
184 /* Copy output arrays to MATLAB format */
185 
186  for( idx=1; idx<=sizeAm_mkl; idx++) {
187  alphar[idx-1] = alpha[idx-1].real;
188  alphai[idx-1] = alpha[idx-1].imag;
189  betar[idx-1] = beta[idx-1].real;
190  betai[idx-1] = beta[idx-1].imag;
191  }
192 
193 
194  for( idx=1; idx<=sizeAm_mkl*sizeAm_mkl; idx++) {
195  l_eigvec_r[idx-1] = l_eigvec[idx-1].real;
196  l_eigvec_i[idx-1] = l_eigvec[idx-1].imag;
197  r_eigvec_r[idx-1] = r_eigvec[idx-1].real;
198  r_eigvec_i[idx-1] = r_eigvec[idx-1].imag;
199  }
200 
201  free( l_eigvec );
202  free( r_eigvec );
203  free( alpha );
204  free( beta );
205 
206 }
207 
208 
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Gateway routine to call the zggev function from LAPACKE package.
Definition: zggev.c:47
#define lapack_int
Definition: zggev.c:33