Eötvös Quantum Utilities  v4.9.146
Providing the Horsepowers in the Quantum Realm
dgetPartialInv.F
Go to the documentation of this file.
1 #include "fintrf.h"
2 C======================================================================
3 C Gateway routine to call the gatPartialInv.F subroutine.
4 C (See: http://www.netlib.org/lapack/explore-html/d9/d52/dggev_8f.html for details)
5 C Copyright (C) 2009-2015 Peter Rakyta, Ph.D.
6 C
7 C This program is free software: you can redistribute it and/or modify
8 C it under the terms of the GNU General Public License as published by
9 C the Free Software Foundation, either version 3 of the License, or
10 C (at your option) any later version.
11 C
12 C This program is distributed in the hope that it will be useful,
13 C but WITHOUT ANY WARRANTY; without even the implied warranty of
14 C MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 C GNU General Public License for more details.
16 C
17 C You should have received a copy of the GNU General Public License
18 C along with this program. If not, see http://www.gnu.org/licenses/.
19 C
20 C======================================================================
21 C Gateway routine
22  subroutine mexfunction(nlhs, plhs, nrhs, prhs)
23 
24 C Declarations
25  implicit none
26 
27  interface
28  subroutine getpartialinv
29  1 (asize, a, ia, ja, sizeinv, inva)
30  INTEGER*4 asize !matrix A is of size asize x asize
31  INTEGER*4, ALLOCATABLE :: ia(:), ja(:)
32  real*8, ALLOCATABLE :: a(:)
33  INTEGER*4 sizeInv !size of the Schur complement to be calculated
34  real*8, ALLOCATABLE :: inva(:,:)
35  end subroutine
36  end interface
37 
38 C mexFunction arguments:
39  mwpointer plhs(*), prhs(*)
40  integer nlhs, nrhs
41 
42 
43 C Function declarations:
44  mwsize mxgetnzmax
45  mwpointer mxgetjc
46  mwpointer mxgetir
47 
48 C Arguments for mxCreateNumericArray
49  integer*4 complexflag
50  mwsize ndim
51 
52  mwpointer mxgetpr
53  mwpointer mxcreatedoublematrix
54  mwpointer mxgetm, mxgetn
55  integer*4 mxIsDouble
56  integer*4 mxIsComplex
57  integer*4 mexPrintf
58 
59 
60 
61 C Array information:
62  mwsize nonzerosa !number of nonzeros elements in A
63  mwsize sizeam, sizean !size of the matrix A (rows, and cols)
64  integer*4 sizeInv !Size of the Schur complement to be calculated
65 
66 C Arguments for computational routine:
67 C fortran representation of the input matrix (CSR format)
68  integer*8, allocatable :: ia_int8(:), ja_int8(:)
69  integer*4, allocatable :: ia(:), ja(:)
70  real*8, allocatable :: a(:)
71  real*8, allocatable :: inva(:,:)
72  mwpointer mxinva
73 
74  integer i,j
75 
76 #ifdef DEBUG
77 C Debug parameters
78  integer*4 tmp
79  character*800 line
80 #endif
81 
82 
83 C-----------------------------------------------------------------------
84 C Check for proper number of arguments.
85  if(nrhs .ne. 2) then
86  call mexerrmsgidandtxt ('MATLAB:timestwo:nInput',
87  + 'Two inputs required.')
88  elseif(nlhs .gt. 1) then
89  call mexerrmsgidandtxt ('MATLAB:timestwo:nOutput',
90  + 'Too many output arguments.')
91  endif
92 
93 C Validate inputs
94 
95 C Check that the input is a double.
96  if ((mxisdouble(prhs(1)) .eq. 0)) then
97  call mexerrmsgidandtxt ('MATLAB:timestwo:NonDouble',
98  + 'Input must be a double.')
99  endif
100 
101 C Check if inputs are complex.
102  if ((mxiscomplex(prhs(1)) .ne. 0) ) then
103  call mexerrmsgidandtxt ('MATLAB:convec:NonComplex',
104  + 'Inputs must be real.')
105  endif
106 
107 C Get the size of the input array. (MATLAB)
108  nonzerosa = mxgetnzmax(prhs(1))
109  sizeam = mxgetm(prhs(1))
110  sizean = mxgetn(prhs(1))
111 
112 
113 C Allocating fortran arrays
114  allocate(ia_int8(sizean+1))
115  allocate(ja_int8(nonzerosa))
116  allocate(ia(sizean+1))
117  allocate(ja(nonzerosa))
118  allocate(a(nonzerosa))
119 C
120 C Check the allocated arrays
121  if (.not. ( allocated(ia_int8) .and.
122  + allocated(ja_int8) .and.
123  + allocated(ia) .and.
124  + allocated(ja) .and.
125  + allocated(a) )) then
126  call mexerrmsgidandtxt ('MATLAB:dgetSchur:BadAllocation',
127  + 'The allocation of variables was unsuccesfull.')
128  endif
129 C Copy data into the fortran arrays
130 C MATLAB does CSC format and PARDISO CSR format for the sparse matrices! Need to transpose.
131  call mxcopyptrtointeger8(
132  + mxgetjc(prhs(1)), ia_int8, sizean+1 )
133  call mxcopyptrtointeger8(
134  + mxgetir(prhs(1)), ja_int8, nonzerosa )
135  call mxcopyptrtoreal8( mxgetpr(prhs(1)), a, nonzerosa )
136 C Fortran starts the indexes from 1
137  ia = int(ia_int8, 4) + 1
138  ja = int(ja_int8, 4) + 1
139  deallocate(ia_int8)
140  deallocate(ja_int8)
141 
142 C choose the matrix type for pardiso factorization
143 C getting the size of the partial inverse
144  ndim = 1
145  call mxcopyptrtointeger4( mxgetpr(prhs(2)), sizeinv, ndim )
146 
147 
148 C Do the pardiso calulations to get the partial inverse
149  ALLOCATE(inva(sizeinv, sizeinv))
150  CALL getpartialinv(int(sizean, 4), a, ia, ja, sizeinv, inva)
151 
152 C deallocate the fortran matrix A
153  deallocate(ia)
154  deallocate(ja)
155  deallocate(a)
156 
157 
158 C Allocating memory for the Schur complement
159 #ifdef DEBUG
160  write(*,*) 'diagonal Elements of the partial solution'
161  do i = 1, sizeinv
162  write(line,*) inva(i,i), new_line('A')
163  tmp = mexprintf( line )
164  end do
165 #endif
166 
167 C Converting the partial inverse to matlab format
168  ndim = int(sizeinv, 8)
169  complexflag = 0;
170  plhs(1) = mxcreatedoublematrix(ndim, ndim,
171  + complexflag) ! for invA
172  mxinva = mxgetpr(plhs(1))
173  call mxcopyreal8toptr(inva, mxinva,ndim*ndim)
174 
175 
176 
177 C.. Deallocating memory for the partial inverse
178 
179  if ( allocated(inva) ) then
180  DEALLOCATE(inva)
181  endif
182 
183 
184  return
185  end
186 
187 
Module to calculate the partial inverse of a real/complex sparse matrix via the PARDISO libraries.
subroutine mexfunction(nlhs, plhs, nrhs, prhs)