Eötvös Quantum Utilities  v4.9.146
Providing the Horsepowers in the Quantum Realm
zgetDiagInv.c
Go to the documentation of this file.
1 /*======================================================================
2  Copyright (C) 2018 Peter Rakyta, Ph.D.
3 
4  This program is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program. If not, see http://www.gnu.org/licenses/.
16 
17 ======================================================================*/
18 
29 #include "mex.h"
30 #include <stdio.h>
31 #include <omp.h>
32 
33 #ifdef __cplusplus
34 extern "C"
35 #endif
36 
40 typedef struct dcomplex {
42  double real;
44  double imag;
45 } comp;
46 
48 #ifdef MIC
49 __declspec( target(mic) ) void getdiaginv_mp_zgetdiaginv_(int *sizeA, int *nonzerosA, comp *a, int *ia, int *ja, double *real_invA, double *imag_invA, int *error);
50 #else
51 void getdiaginv_mp_zgetdiaginv_(int *sizeA, int *nonzerosA, comp *a, int *ia, int *ja, double *real_invA, double *imag_invA, int *error);
52 #endif
53 
54 
55 
62 void mexFunction(int nlhs, mxArray *plhs[],
63  int nrhs, const mxArray *prhs[])
64 {
65 /* Array information: */
66  mwSize nonzerosA; /*number of nonzeros elements in A*/
67  mwSize sizeAm;
68  mwSize sizeAn; /*size of the matrix A (rows, and cols) */
69  int sizeAn_fort, nonzerosA_fort; /*fortran compatible matrix dimensions*/
70 
71  mwSize *ia, *ja;
72  int *ia_fort, *ja_fort; /* fortran compatible indices */
73  int error;
74  comp* a;
75  double *real, *imag;
76 
77 
78 /*-----------------------------------------------------------------------*/
79 /* Check for proper number of arguments. */
80  if(nrhs != 1) {
81  mexErrMsgIdAndTxt ("EQuUs:zgetdiaginv:nInput", "One input required.");
82  }
83  else if (nlhs > 1) {
84  mexErrMsgIdAndTxt ("EQuUs:zgetdiaginv:nOutput", "Too many output arguments.");
85  }
86 
87 /* Validate inputs */
88 
89 /* Check that the input is a double.*/
90  if ((mxIsDouble(prhs[0]) == 0)) {
91  mexErrMsgIdAndTxt ("EQuUs:zgetdiaginv:NonDouble", "Input must be a double.");
92  }
93 
94 /* Check if inputs are complex.*/
95  if ((mxIsComplex(prhs[0]) == 0) ) {
96  mexErrMsgIdAndTxt ("EQuUs:zgetdiaginv:NonComplex", "Inputs must be complex.");
97  }
98 
99 /* Get the size of the input array. (MATLAB) */
100  nonzerosA = mxGetNzmax(prhs[0]);
101  sizeAm = mxGetM(prhs[0]);
102  sizeAn = mxGetN(prhs[0]);
103 
104  ia = mxGetJc(prhs[0]);
105  ja = mxGetIr(prhs[0]);
106  real = mxGetPr(prhs[0]);
107  imag = mxGetPi(prhs[0]);
108 
109  ia_fort = (int*)mxMalloc( (sizeAm+1)*sizeof(int) );
110  ja_fort = (int*)mxMalloc( nonzerosA*sizeof(int) );
111 #ifdef matlab
112  a = (comp*)mxMalloc( nonzerosA*sizeof(comp) );
113 #else
114  a = (comp*)real;
115 #endif
116 
117  mwSize idx;
118  for( idx=1; idx<=sizeAm+1; idx++ ) {
119  ia_fort[idx-1] = (int)ia[idx-1] + 1;
120  }
121 
122  for( idx=1; idx<=nonzerosA; idx++ ) {
123  ja_fort[idx-1] = (int)ja[idx-1] + 1;
124 #ifdef matlab
125  a[idx-1].real = real[idx-1];
126  a[idx-1].imag = imag[idx-1];
127 #endif
128  }
129 
130 
131  plhs[0] = mxCreateDoubleMatrix(sizeAn, 1, mxCOMPLEX); /* create output matrix */
132  /* populate the real and imaginary part of the created array */
133  real = mxGetPr(plhs[0]);
134  imag = mxGetPi(plhs[0]);
135 
136  sizeAn_fort = (int)sizeAn;
137  nonzerosA_fort = (int)nonzerosA;
138 
139 #ifdef MIC
140 #pragma offload target(mic) \
141  in(sizeAn_fort, nonzerosA_fort) \
142  in(a:length(nonzerosA)) \
143  in(ia_fort:length(sizeAn+1)) \
144  in(ja_fort:length(nonzerosA)) \
145  out(real:length(sizeAn_fort)) \
146  out(imag:length(sizeAn_fort)) \
147  out(error)
148  {
149 #endif
150 
151 #ifdef __INTEL_COMPILER
152  getdiaginv_mp_zgetdiaginv_(&sizeAn_fort, &nonzerosA_fort, a, ia_fort, ja_fort, real, imag, &error);
153 #else
154  __getdiaginv_MOD_zgetdiaginv(&sizeAn_fort, &nonzerosA_fort, a, ia_fort, ja_fort, real, imag, &error);
155 #endif
156 
157 #ifdef MIC
158  }
159 #endif
160 
161  mxFree(ia_fort);
162  mxFree(ja_fort);
163 
164 /* Check the error flag .*/
165  if ((error != 0) ) {
166  char output[100];
167  sprintf(output, "PARDISO solver ended with error flag: %i\n", error);
168  mexErrMsgIdAndTxt ("EQuUs:zgetdiaginv:PardisoError", output);
169  }
170 
171 #ifdef DEBUG
172  mexPrintf("Pardiso calculations finished for real matrix\n");
173 #endif
174 
175 }
176 
177 
double real
The real part of the complex number.
Definition: zgetDiagInv.c:42
Fortran compatible complex type.
Definition: zgetDiagInv.c:40
void getdiaginv_mp_zgetdiaginv_(int *sizeA, int *nonzerosA, comp *a, int *ia, int *ja, double *real_invA, double *imag_invA, int *error)
For specification see getdiaginv::zgetdiaginv.
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Gateway routine to call the zgetdiaginv subroutine from the mkl_EQuUs package.
Definition: zgetDiagInv.c:62
double imag
The imaginary part of the complex number.
Definition: zgetDiagInv.c:44