Eötvös Quantum Utilities  v4.9.146
Providing the Horsepowers in the Quantum Realm
zgetPartialInv.c
Go to the documentation of this file.
1 /*======================================================================
2  Copyright (C) 2016 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 <unistd.h>
30 #include "mex.h"
31 #ifdef __cplusplus
32 extern "C"
33 #endif
34 
38 typedef struct dcomplex {
40  double real;
42  double imag;
43 } comp;
44 
46 #ifdef MIC
47 __declspec( target(mic) ) void getpartialinv_mp_zgetpartialinv_(int *sizeA, int *nonzerosA, comp *a, int *ia, int *ja, int *sizeInv, double *real_invA, double *imag_invA, int *error);
48 #else
49 void getpartialinv_mp_zgetpartialinv_(int *sizeA, int *nonzerosA, comp *a, int *ia, int *ja, int *sizeInv, double *real_invA, double *imag_invA, int *error);
50 #endif
51 
52 
59 void mexFunction(int nlhs, mxArray *plhs[],
60  int nrhs, const mxArray *prhs[])
61 {
62 /* Array information: */
63  mwSize nonzerosA; /*number of nonzeros elements in A*/
64  mwSize sizeAm;
65  mwSize sizeAn; /*size of the matrix A (rows, and cols) */
66  mwSize sizeInv; /*Size of the Schur complement to be calculated*/
67  int sizeAn_fort, nonzerosA_fort, sizeInv_fort; /*fortran compatible matrix dimensions*/
68 
69  mwSize *ia, *ja;
70  int *ia_fort, *ja_fort; /* fortran compatible indices */
71  int error;
72  comp* a;
73  double *real, *imag;
74 
75 
76 /*-----------------------------------------------------------------------*/
77 /* Check for proper number of arguments. */
78  if(nrhs != 2) {
79  mexErrMsgIdAndTxt ("EQuUs:zgetPartialInv:nInput", "Two inputs required.");
80  }
81  else if (nlhs > 1) {
82  mexErrMsgIdAndTxt ("EQuUs:zgetPartialInv:nOutput", "Too many output arguments.");
83  }
84 
85 /* Validate inputs */
86 
87 /* Check that the input is a double.*/
88  if ((mxIsDouble(prhs[0]) == 0)) {
89  mexErrMsgIdAndTxt ("EQuUs:zgetPartialInv:NonDouble", "Input must be a double.");
90  }
91 
92 /* Check if inputs are complex.*/
93  if ((mxIsComplex(prhs[0]) == 0) ) {
94  mexErrMsgIdAndTxt ("EQuUs:zgetPartialInv:NonComplex", "Inputs must be complex.");
95  }
96 
97 /* Get the size of the input array. (MATLAB) */
98  nonzerosA = mxGetNzmax(prhs[0]);
99  sizeAm = mxGetM(prhs[0]);
100  sizeAn = mxGetN(prhs[0]);
101 
102  ia = mxGetJc(prhs[0]);
103  ja = mxGetIr(prhs[0]);
104  real = mxGetPr(prhs[0]);
105  imag = mxGetPi(prhs[0]);
106 
107  ia_fort = (int*)mxMalloc( (sizeAm+1)*sizeof(int) );
108  ja_fort = (int*)mxMalloc( nonzerosA*sizeof(int) );
109 #ifdef matlab
110  a = (comp*)mxMalloc( nonzerosA*sizeof(comp) );
111 #else
112  a = (comp*)real;
113 #endif
114 
115  mwSize idx;
116  for( idx=1; idx<=sizeAm+1; idx++ ) {
117  ia_fort[idx-1] = (int)ia[idx-1] + 1;
118  }
119 
120  for( idx=1; idx<=nonzerosA; idx++ ) {
121  ja_fort[idx-1] = (int)ja[idx-1] + 1;
122 #ifdef matlab
123  a[idx-1].real = real[idx-1];
124  a[idx-1].imag = imag[idx-1];
125 #endif
126  }
127 
128 /* getting the size of the partial inverse */
129  sizeInv = *mxGetPr(prhs[1]);
130 
131 
132  plhs[0] = mxCreateDoubleMatrix(sizeInv, sizeInv, mxCOMPLEX); /* create output matrix */
133  /* populate the real and imaginary part of the created array */
134  real = mxGetPr(plhs[0]);
135  imag = mxGetPi(plhs[0]);
136 
137  sizeAn_fort = (int)sizeAn;
138  nonzerosA_fort = (int)nonzerosA;
139  sizeInv_fort = (int)sizeInv;
140 
141 #ifdef MIC
142 #pragma offload target(mic) \
143  in(sizeAn_fort, nonzerosA_fort, sizeInv_fort) \
144  in(a:length(nonzerosA)) \
145  in(ia_fort:length(sizeAn+1)) \
146  in(ja_fort:length(nonzerosA)) \
147  out(real:length(sizeInv_fort*sizeInv_fort)) \
148  out(imag:length(sizeInv_fort*sizeInv_fort)) \
149  out(error)
150  {
151 #endif
152 
153 #ifdef __INTEL_COMPILER
154  getpartialinv_mp_zgetpartialinv_(&sizeAn_fort, &nonzerosA_fort, a, ia_fort, ja_fort, &sizeInv_fort, real, imag, &error);
155 #else
156  __getpartialinv_MOD_zgetpartialinv(&sizeAn_fort, &nonzerosA_fort, a, ia_fort, ja_fort, &sizeInv_fort, real, imag, &error);
157 #endif
158 
159 #ifdef MIC
160  }
161 #endif
162 
163  mxFree(ia_fort);
164  mxFree(ja_fort);
165  mxFree(a);
166 
167 /* Check the error flag .*/
168  if ((error != 0) ) {
169  char output[100];
170  sprintf(output, "PARDISO solver ended with error flag: %i\n", error);
171  mexErrMsgIdAndTxt ("EQuUs:zgetPartialInv:PardisoError", output);
172  }
173 
174 #ifdef DEBUG
175  mexPrintf("Pardiso calculations finished for complex matrix\n");
176 #endif
177 
178 }
179 
180 
double real
The real part of the complex number.
Definition: zgetDiagInv.c:42
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Gateway routine to call the zgetpartialinv subroutine from the mkl_EQuUs package.
Fortran compatible complex type.
Definition: zgetDiagInv.c:40
void getpartialinv_mp_zgetpartialinv_(int *sizeA, int *nonzerosA, comp *a, int *ia, int *ja, int *sizeInv, double *real_invA, double *imag_invA, int *error)
For specification see getpartialinv::zgetpartialinv.
double imag
The imaginary part of the complex number.
Definition: zgetDiagInv.c:44