Commit 68642e5d21b0cb88b82aa6c7a681e3b448197363
1 parent
204ded3d3d
Exists in
geevx_2020
Using [SDCZ]GEEVX instead of [SDCZ]GEEV to avoid use of
[SDCZ]GEBAL which cause NaN in some circumstances
Showing 1 changed file with 49 additions and 9 deletions Side-by-side Diff
fvn_linear/fvn_linear.f90
... | ... | @@ -1095,6 +1095,7 @@ |
1095 | 1095 | ! integer(kind=ip_kind) (out) : status =0 if something went wrong |
1096 | 1096 | ! |
1097 | 1097 | ! interfacing Lapack routine SGEEV |
1098 | + ! 2020 11 03 : SGEEVX with BALANC='N' | |
1098 | 1099 | implicit none |
1099 | 1100 | integer(kind=ip_kind), intent(in) :: d |
1100 | 1101 | real(kind=sp_kind), intent(in) :: a(d,d) |
... | ... | @@ -1114,6 +1115,10 @@ |
1114 | 1115 | integer(kind=ip_kind) i |
1115 | 1116 | integer(kind=ip_kind) j |
1116 | 1117 | |
1118 | + integer(kind=ip_kind) :: ilo,ihi, iwork | |
1119 | + real(kind=sp_kind), allocatable, dimension(:) :: scal, rconde, rcondv | |
1120 | + real(kind=sp_kind) :: abnrm | |
1121 | + | |
1117 | 1122 | if (present(status)) status=1 |
1118 | 1123 | |
1119 | 1124 | ! making a working copy of a |
1120 | 1125 | |
1121 | 1126 | |
1122 | 1127 | |
... | ... | @@ -1124,12 +1129,16 @@ |
1124 | 1129 | allocate(wr(d)) |
1125 | 1130 | allocate(wi(d)) |
1126 | 1131 | allocate(vr(d,d)) |
1132 | + allocate(scal(d),rconde(d),rcondv(d)) | |
1127 | 1133 | ! query optimal work size |
1128 | - call sgeev('N','V',d,wc_a,d,wr,wi,vl,1,vr,d,twork,-1,info) | |
1134 | + ! call sgeev('N','V',d,wc_a,d,wr,wi,vl,1,vr,d,twork,-1,info) | |
1135 | + call sgeevx('N','N','V','N',d,wc_a,d,wr,wi,vl,1,vr,d,ILO,IHI,SCAL,ABNRM,RCONDE,RCONDV,twork,-1,IWORK,info) | |
1129 | 1136 | lwork=int(twork(1)) |
1130 | 1137 | allocate(work(lwork)) |
1131 | - call sgeev('N','V',d,wc_a,d,wr,wi,vl,1,vr,d,work,lwork,info) | |
1138 | + ! call sgeev('N','V',d,wc_a,d,wr,wi,vl,1,vr,d,work,lwork,info) | |
1139 | + call sgeevx('N','N','V','N',d,wc_a,d,wr,wi,vl,1,vr,d,ILO,IHI,SCAL,ABNRM,RCONDE,RCONDV,work,lwork,IWORK,info) | |
1132 | 1140 | |
1141 | + | |
1133 | 1142 | if (info /= 0) then |
1134 | 1143 | if (present(status)) status=0 |
1135 | 1144 | deallocate(work) |
... | ... | @@ -1137,6 +1146,7 @@ |
1137 | 1146 | deallocate(wi) |
1138 | 1147 | deallocate(wr) |
1139 | 1148 | deallocate(wc_a) |
1149 | + deallocate(scal,rconde,rcondv) | |
1140 | 1150 | return |
1141 | 1151 | end if |
1142 | 1152 | |
... | ... | @@ -1159,6 +1169,7 @@ |
1159 | 1169 | deallocate(wi) |
1160 | 1170 | deallocate(wr) |
1161 | 1171 | deallocate(wc_a) |
1172 | + deallocate(scal,rconde,rcondv) | |
1162 | 1173 | |
1163 | 1174 | ! sorting |
1164 | 1175 | if (present(sortval) .and. sortval) then |
... | ... | @@ -1176,6 +1187,7 @@ |
1176 | 1187 | ! integer(kind=ip_kind) (out) : status =0 if something went wrong |
1177 | 1188 | ! |
1178 | 1189 | ! interfacing Lapack routine DGEEV |
1190 | + ! 2020 11 03 : DGEEVX with BALANC='N' | |
1179 | 1191 | implicit none |
1180 | 1192 | integer(kind=ip_kind), intent(in) :: d |
1181 | 1193 | real(kind=dp_kind), intent(in) :: a(d,d) |
... | ... | @@ -1195,6 +1207,10 @@ |
1195 | 1207 | integer(kind=ip_kind) i |
1196 | 1208 | integer(kind=ip_kind) j |
1197 | 1209 | |
1210 | + integer(kind=ip_kind) :: ilo,ihi, iwork | |
1211 | + real(kind=dp_kind), allocatable, dimension(:) :: scal, rconde, rcondv | |
1212 | + real(kind=dp_kind) :: abnrm | |
1213 | + | |
1198 | 1214 | if (present(status)) status=1 |
1199 | 1215 | |
1200 | 1216 | ! making a working copy of a |
1201 | 1217 | |
1202 | 1218 | |
... | ... | @@ -1205,11 +1221,14 @@ |
1205 | 1221 | allocate(wr(d)) |
1206 | 1222 | allocate(wi(d)) |
1207 | 1223 | allocate(vr(d,d)) |
1224 | + allocate(scal(d),rconde(d),rcondv(d)) | |
1208 | 1225 | ! query optimal work size |
1209 | - call dgeev('N','V',d,wc_a,d,wr,wi,vl,1,vr,d,twork,-1,info) | |
1226 | + ! call dgeev('N','V',d,wc_a,d,wr,wi,vl,1,vr,d,twork,-1,info) | |
1227 | + call dgeevx('N','N','V','N',d,wc_a,d,wr,wi,vl,1,vr,d,ILO,IHI,SCAL,ABNRM,RCONDE,RCONDV,twork,-1,IWORK,info) | |
1210 | 1228 | lwork=int(twork(1)) |
1211 | 1229 | allocate(work(lwork)) |
1212 | - call dgeev('N','V',d,wc_a,d,wr,wi,vl,1,vr,d,work,lwork,info) | |
1230 | + ! call dgeev('N','V',d,wc_a,d,wr,wi,vl,1,vr,d,work,lwork,info) | |
1231 | + call dgeevx('N','N','V','N',d,wc_a,d,wr,wi,vl,1,vr,d,ILO,IHI,SCAL,ABNRM,RCONDE,RCONDV,work,lwork,IWORK,info) | |
1213 | 1232 | |
1214 | 1233 | if (info /= 0) then |
1215 | 1234 | if (present(status)) status=0 |
... | ... | @@ -1218,6 +1237,7 @@ |
1218 | 1237 | deallocate(wi) |
1219 | 1238 | deallocate(wr) |
1220 | 1239 | deallocate(wc_a) |
1240 | + deallocate(scal,rconde,rcondv) | |
1221 | 1241 | return |
1222 | 1242 | end if |
1223 | 1243 | |
... | ... | @@ -1241,6 +1261,7 @@ |
1241 | 1261 | deallocate(wi) |
1242 | 1262 | deallocate(wr) |
1243 | 1263 | deallocate(wc_a) |
1264 | + deallocate(scal,rconde,rcondv) | |
1244 | 1265 | |
1245 | 1266 | ! sorting |
1246 | 1267 | if (present(sortval) .and. sortval) then |
... | ... | @@ -1258,6 +1279,7 @@ |
1258 | 1279 | ! integer(kind=ip_kind) (out) : status =0 if something went wrong |
1259 | 1280 | ! |
1260 | 1281 | ! interfacing Lapack routine CGEEV |
1282 | + ! 2020 11 03 : CGEEVX with BALANC='N' | |
1261 | 1283 | implicit none |
1262 | 1284 | integer(kind=ip_kind), intent(in) :: d |
1263 | 1285 | complex(kind=sp_kind), intent(in) :: a(d,d) |
... | ... | @@ -1274,6 +1296,10 @@ |
1274 | 1296 | real(kind=sp_kind), allocatable :: rwork(:) |
1275 | 1297 | complex(kind=sp_kind) :: vl ! unused but necessary for the call |
1276 | 1298 | |
1299 | + integer(kind=ip_kind) :: ilo,ihi | |
1300 | + real(kind=sp_kind), allocatable, dimension(:) :: scal, rconde, rcondv | |
1301 | + real(kind=sp_kind) :: abnrm | |
1302 | + | |
1277 | 1303 | if (present(status)) status=1 |
1278 | 1304 | |
1279 | 1305 | ! making a working copy of a |
1280 | 1306 | |
1281 | 1307 | |
... | ... | @@ -1283,11 +1309,14 @@ |
1283 | 1309 | |
1284 | 1310 | ! rwork must be allocated before query |
1285 | 1311 | allocate(rwork(2*d)) |
1312 | + allocate(scal(d),rconde(d),rcondv(d)) | |
1286 | 1313 | ! query optimal work size |
1287 | - call cgeev('N','V',d,wc_a,d,evala,vl,1,eveca,d,twork,-1,rwork,info) | |
1314 | + ! call cgeev('N','V',d,wc_a,d,evala,vl,1,eveca,d,twork,-1,rwork,info) | |
1315 | + call cgeevx('N','N','V','N',d,wc_a,d,evala,vl,1,eveca,d,ILO,IHI,SCAL,ABNRM,RCONDE,RCONDV,twork,-1,rwork,info) | |
1288 | 1316 | lwork=int(twork(1)) |
1289 | 1317 | allocate(work(lwork)) |
1290 | - call cgeev('N','V',d,wc_a,d,evala,vl,1,eveca,d,work,lwork,rwork,info) | |
1318 | + ! call cgeev('N','V',d,wc_a,d,evala,vl,1,eveca,d,work,lwork,rwork,info) | |
1319 | + call cgeevx('N','N','V','N',d,wc_a,d,evala,vl,1,eveca,d,ILO,IHI,SCAL,ABNRM,RCONDE,RCONDV,work,lwork,rwork,info) | |
1291 | 1320 | |
1292 | 1321 | if (info /= 0) then |
1293 | 1322 | if (present(status)) status=0 |
... | ... | @@ -1295,6 +1324,7 @@ |
1295 | 1324 | deallocate(rwork) |
1296 | 1325 | deallocate(work) |
1297 | 1326 | deallocate(wc_a) |
1327 | + deallocate(scal,rconde,rcondv) | |
1298 | 1328 | |
1299 | 1329 | ! sorting |
1300 | 1330 | if (present(sortval) .and. sortval) then |
... | ... | @@ -1312,6 +1342,7 @@ |
1312 | 1342 | ! integer(kind=ip_kind) (out) : status =0 if something went wrong |
1313 | 1343 | ! |
1314 | 1344 | ! interfacing Lapack routine ZGEEV |
1345 | + ! 2020 11 03 : ZGEEVX with BALANC='N' | |
1315 | 1346 | implicit none |
1316 | 1347 | integer(kind=ip_kind), intent(in) :: d |
1317 | 1348 | complex(kind=dp_kind), intent(in) :: a(d,d) |
... | ... | @@ -1328,6 +1359,11 @@ |
1328 | 1359 | real(kind=dp_kind), allocatable :: rwork(:) |
1329 | 1360 | complex(kind=dp_kind) :: vl ! unused but necessary for the call |
1330 | 1361 | |
1362 | + integer(kind=ip_kind) :: ilo,ihi | |
1363 | + real(kind=dp_kind), allocatable, dimension(:) :: scal, rconde, rcondv | |
1364 | + real(kind=dp_kind) :: abnrm | |
1365 | + | |
1366 | + | |
1331 | 1367 | if (present(status)) status=1 |
1332 | 1368 | |
1333 | 1369 | ! making a working copy of a |
1334 | 1370 | |
1335 | 1371 | |
... | ... | @@ -1337,11 +1373,14 @@ |
1337 | 1373 | |
1338 | 1374 | ! rwork must be allocated before query |
1339 | 1375 | allocate(rwork(2*d)) |
1376 | + allocate(scal(d),rconde(d),rcondv(d)) | |
1340 | 1377 | ! query optimal work size |
1341 | - call zgeev('N','V',d,wc_a,d,evala,vl,1,eveca,d,twork,-1,rwork,info) | |
1378 | + ! call zgeev('N','V',d,wc_a,d,evala,vl,1,eveca,d,twork,-1,rwork,info) | |
1379 | + call zgeevx('N','N','V','N',d,wc_a,d,evala,vl,1,eveca,d,ILO,IHI,SCAL,ABNRM,RCONDE,RCONDV,twork,-1,rwork,info) | |
1342 | 1380 | lwork=int(twork(1)) |
1343 | 1381 | allocate(work(lwork)) |
1344 | - call zgeev('N','V',d,wc_a,d,evala,vl,1,eveca,d,work,lwork,rwork,info) | |
1382 | + ! call zgeev('N','V',d,wc_a,d,evala,vl,1,eveca,d,work,lwork,rwork,info) | |
1383 | + call zgeevx('N','N','V','N',d,wc_a,d,evala,vl,1,eveca,d,ILO,IHI,SCAL,ABNRM,RCONDE,RCONDV,work,lwork,rwork,info) | |
1345 | 1384 | |
1346 | 1385 | if (info /= 0) then |
1347 | 1386 | if (present(status)) status=0 |
... | ... | @@ -1349,6 +1388,7 @@ |
1349 | 1388 | deallocate(rwork) |
1350 | 1389 | deallocate(work) |
1351 | 1390 | deallocate(wc_a) |
1391 | + deallocate(scal,rconde,rcondv) | |
1352 | 1392 | |
1353 | 1393 | ! sorting |
1354 | 1394 | if (present(sortval) .and. sortval) then |