Eötvös Quantum Utilities  v4.9.146
Providing the Horsepowers in the Quantum Realm
dgetSchur.F
Go to the documentation of this file.
1 #include "fintrf.h"
2 C======================================================================
3 C Gateway routine to call the zggev.f function from LAPACK package.
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 getschur
29  1 (asize, a, ia, ja, ssize, s, is, js, mtype)
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 ssize !size of the Schur complement to be calculated
34  INTEGER, ALLOCATABLE :: iS(:), jS(:) ! row and culomn indices of the Schur complement
35  real*8, ALLOCATABLE :: s(:) !nonzeros elements in the Schur complement
36  INTEGER mtype
37  end subroutine
38  end interface
39 
40 C mexFunction arguments:
41  mwpointer plhs(*), prhs(*)
42  integer nlhs, nrhs
43 
44 
45 C Function declarations:
46  mwsize mxgetnzmax
47  mwpointer mxgetjc
48  mwpointer mxgetir
49 
50 C Arguments for mxCreateNumericArray
51  integer*4 complexflag
52  mwsize ndim
53 
54  mwpointer mxgetpr
55  mwpointer mxcreatedoublematrix
56  mwpointer mxgetm, mxgetn
57  integer*4 mxIsDouble
58  integer*4 mxIsComplex
59  integer*4 mexPrintf
60 
61 
62 
63 C Array information:
64  mwsize nonzerosa !number of nonzeros elements in A
65  mwsize sizeam, sizean !size of the matrix A (rows, and cols)
66  integer*4 nonzerosS !number of nonzeros elements in S
67  integer*4 sizeS !Size of the Schur complement to be calculated
68 
69 C Arguments for computational routine:
70 C fortran representation of the input matrix (CSR format)
71  integer*8, allocatable :: ia_int8(:), ja_int8(:)
72  integer*4, allocatable :: ia(:), ja(:)
73  real*8, allocatable :: a(:)
74 C fortran representation of the Schur complement matrix (CSR format)
75  integer, allocatable :: iS(:), jS(:)
76  real*8, allocatable :: s(:)
77  real*8, allocatable :: s_full(:,:)
78  mwpointer mxs_full
79 
80 C Parameters for pardiso
81  INTEGER mtype
82  integer i,j
83 
84 #ifdef DEBUG
85 C Debug parameters
86  integer*4 tmp
87  character*800 line
88 #endif
89 
90 
91 C-----------------------------------------------------------------------
92 C Check for proper number of arguments.
93  if(nrhs .ne. 2) then
94  call mexerrmsgidandtxt ('MATLAB:timestwo:nInput',
95  + 'Two inputs required.')
96  elseif(nlhs .gt. 1) then
97  call mexerrmsgidandtxt ('MATLAB:timestwo:nOutput',
98  + 'Too many output arguments.')
99  endif
100 
101 C Validate inputs
102 
103 C Check that the input is a double.
104  if ((mxisdouble(prhs(1)) .eq. 0)) then
105  call mexerrmsgidandtxt ('MATLAB:timestwo:NonDouble',
106  + 'Input must be a double.')
107  endif
108 
109 C Check if inputs are complex.
110  if ((mxiscomplex(prhs(1)) .ne. 0) ) then
111  call mexerrmsgidandtxt ('MATLAB:convec:NonComplex',
112  + 'Inputs must be real.')
113  endif
114 
115 C Get the size of the input array. (MATLAB)
116  nonzerosa = mxgetnzmax(prhs(1))
117  sizeam = mxgetm(prhs(1))
118  sizean = mxgetn(prhs(1))
119 
120 
121 C Allocating fortran arrays
122  allocate(ia_int8(sizean+1))
123  allocate(ja_int8(nonzerosa))
124  allocate(ia(sizean+1))
125  allocate(ja(nonzerosa))
126  allocate(a(nonzerosa))
127 C
128 C Check the allocated arrays
129  if (.not. ( allocated(ia_int8) .and.
130  + allocated(ja_int8) .and.
131  + allocated(ia) .and.
132  + allocated(ja) .and.
133  + allocated(a) )) then
134  call mexerrmsgidandtxt ('MATLAB:dgetSchur:BadAllocation',
135  + 'The allocation of variables was unsuccesfull.')
136  endif
137 C Copy data into the fortran arrays
138 C MATLAB does CSC format and PARDISO CSR format for the sparse matrices! Need to transpose.
139  call mxcopyptrtointeger8(
140  + mxgetjc(prhs(1)), ia_int8, sizean+1 )
141  call mxcopyptrtointeger8(
142  + mxgetir(prhs(1)), ja_int8, nonzerosa )
143  call mxcopyptrtoreal8( mxgetpr(prhs(1)), a, nonzerosa )
144 C Fortran starts the indexes from 1
145  ia = int(ia_int8, 4) + 1
146  ja = int(ja_int8, 4) + 1
147  deallocate(ia_int8)
148  deallocate(ja_int8)
149 
150 C choose the matrix type for pardiso factorization
151  mtype = 1 ! structurally symmetric real matrix
152 C getting the size of the Schur complement
153  ndim = 1
154  call mxcopyptrtointeger4( mxgetpr(prhs(2)), sizes, ndim )
155 
156 
157 C Do the pardiso calulations to get the Schur complement
158 C Passing deallocated arrays might cause troubles
159  ALLOCATE(is(0))
160  ALLOCATE(js(0))
161  ALLOCATE(s(0))
162  CALL getschur(int(sizeam, 4), a, ia, ja,
163  + sizes, s, is, js, mtype)
164 
165 C deallocate the fortran matrix A
166  deallocate(ia)
167  deallocate(ja)
168  deallocate(a)
169 
170 
171 #ifdef DEBUG
172  write(line,*) new_line('A')
173  tmp = mexprintf(line)
174  write(line,*) 'The Calculated Schur complement:', new_line('A')
175  tmp = mexprintf(line)
176  i = 0
177  do j = 1, size(s)
178  if (j >= is(i+1)) then
179  i=i+1
180  end if
181 
182  if (j < is(i+1)) then
183  write(line,*) 'row', i, 'col', js(j),
184  + 'element of S = ', s(j), new_line('A')
185  tmp = mexprintf(line)
186  end if
187  end do
188 
189 #endif
190 
191 C creating full S matrix
192  ALLOCATE(s_full(sizes, sizes))
193  s_full = 0.d0
194  i = 0
195  do j = 1, size(s)
196  if (j >= is(i+1)) then
197  i=i+1
198  end if
199 
200  if (j < is(i+1)) then
201 C MATLAB does CSC format and PARDISO CSR format for the sparse matrices! Need to transpose back.
202  s_full(js(j), i) = s(j)
203  end if
204  end do
205  ndim = int(sizes, 8)
206  complexflag = 0;
207  plhs(1) = mxcreatedoublematrix(ndim, ndim,
208  + complexflag) ! for S_full
209  mxs_full = mxgetpr(plhs(1))
210  call mxcopyreal8toptr(s_full, mxs_full,ndim*ndim)
211 
212 
213 
214 
215 
216 C.. Deallocating memory for the Schur complement
217  if ( allocated(is) ) then
218  DEALLOCATE(is)
219  endif
220 
221  if ( allocated(js) ) then
222  DEALLOCATE(js)
223  endif
224 
225  if ( allocated(s) ) then
226  DEALLOCATE(s)
227  endif
228 
229  if ( allocated(s_full) ) then
230  DEALLOCATE(s_full)
231  endif
232 
233 
234  return
235  end
236 
237 
subroutine mexfunction(nlhs, plhs, nrhs, prhs)