|
a/SVDLib1.mod.m2pp |
|
b/SVDLib1.mod.m2pp |
|
... |
|
... |
70 |
(* 24.08.18, MRi: Die rechte Seite der Gleichungssysteme auf einheit- *)
|
70 |
(* 24.08.18, MRi: Die rechte Seite der Gleichungssysteme auf einheit- *)
|
71 |
(* liches Speicherformat [1..nB,1..M] gebracht *)
|
71 |
(* liches Speicherformat [1..nB,1..M] gebracht *)
|
72 |
(* 25.08.18, MRi: In BerLsg die Schleifenstrukturen optimiert *)
|
72 |
(* 25.08.18, MRi: In BerLsg die Schleifenstrukturen optimiert *)
|
73 |
(* 26.08.18, MRi: In BerLsg und MinFit komplett auf offene Felder umge- *)
|
73 |
(* 26.08.18, MRi: In BerLsg und MinFit komplett auf offene Felder umge- *)
|
74 |
(* stellt *)
|
74 |
(* stellt *)
|
|
|
75 |
(* 28.08.18, MRi: In MinFit die Indexberechnung bereinigt *)
|
75 |
(*------------------------------------------------------------------------*)
|
76 |
(*------------------------------------------------------------------------*)
|
76 |
(* Offene Punkte *)
|
77 |
(* Offene Punkte *)
|
77 |
(* *)
|
78 |
(* *)
|
78 |
(* - Durchsehen der Fehlermeldungen *)
|
79 |
(* - Durchsehen der Fehlermeldungen *)
|
79 |
(* - Durchsehen der Kommentare und Erklaerungen *)
|
80 |
(* - Durchsehen der Kommentare und Erklaerungen *)
|
|
... |
|
... |
99 |
(*------------------------------------------------------------------------*)
|
100 |
(*------------------------------------------------------------------------*)
|
100 |
(* Implementation : Michael Riedl *)
|
101 |
(* Implementation : Michael Riedl *)
|
101 |
(* Licence : GNU Lesser General Public License (LGPL) *)
|
102 |
(* Licence : GNU Lesser General Public License (LGPL) *)
|
102 |
(*------------------------------------------------------------------------*)
|
103 |
(*------------------------------------------------------------------------*)
|
103 |
|
104 |
|
104 |
(* $Id: SVDLib1.mod.m2pp,v 1.6 2018/08/26 14:25:59 mriedl Exp $ *)
|
105 |
(* $Id: SVDLib1.mod.m2pp,v 1.5 2018/08/28 12:30:50 mriedl Exp mriedl $ *)
|
105 |
|
106 |
|
106 |
FROM SYSTEM IMPORT TSIZE;
|
107 |
FROM SYSTEM IMPORT TSIZE;
|
107 |
FROM Storage IMPORT ALLOCATE,DEALLOCATE;
|
108 |
FROM Storage IMPORT ALLOCATE,DEALLOCATE;
|
108 |
IMPORT Errors;
|
109 |
IMPORT Errors;
|
109 |
FROM Errors IMPORT Fehlerflag;
|
110 |
FROM Errors IMPORT Fehlerflag;
|
|
... |
|
... |
1181 |
PROCEDURE sqr(x : LONGREAL) : LONGREAL; BEGIN RETURN x*x; END sqr;
|
1182 |
PROCEDURE sqr(x : LONGREAL) : LONGREAL; BEGIN RETURN x*x; END sqr;
|
1182 |
|
1183 |
|
1183 |
CONST maxit = 30;
|
1184 |
CONST maxit = 30;
|
1184 |
|
1185 |
|
1185 |
VAR i,j,k,kk,l,ll,mn,it,kache : INTEGER;
|
1186 |
VAR i,j,k,kk,l,ll,mn,it,kache : INTEGER;
|
|
|
1187 |
kp1,ip1 :INTEGER;
|
1186 |
c,s,x,y,z,f,g,h,bnorm,s16,r16 : LONGREAL;
|
1188 |
c,s,x,y,z,f,g,h,bnorm,s16,r16 : LONGREAL;
|
1187 |
cancellation,exit : BOOLEAN;
|
1189 |
cancellation,exit : BOOLEAN;
|
1188 |
E : POINTER TO ARRAY
|
1190 |
E : POINTER TO ARRAY
|
1189 |
[0..MAX(INTEGER)-1] OF LONGREAL;
|
1191 |
[0..MAX(INTEGER)-1] OF LONGREAL;
|
1190 |
BEGIN
|
1192 |
BEGIN
|
|
... |
|
... |
1196 |
kache := CacheLen(HIGH(A));
|
1198 |
kache := CacheLen(HIGH(A));
|
1197 |
kk := N - kache;
|
1199 |
kk := N - kache;
|
1198 |
|
1200 |
|
1199 |
(* reduction to upper-bidiagonal form by householder transformations *)
|
1201 |
(* reduction to upper-bidiagonal form by householder transformations *)
|
1200 |
|
1202 |
|
1201 |
k:=1;
|
1203 |
kp1:=1;
|
1202 |
LOOP (* FOR k:=1 TO mn DO *)
|
1204 |
LOOP (* FOR k:=1 TO mn DO *)
|
|
|
1205 |
k:=kp1-1;
|
1203 |
(* IF (k > mn) THEN EXIT; END; *)
|
1206 |
(* IF (k > mn) THEN EXIT; END; *)
|
1204 |
(* L1 norm of the subdiagonal part of column k *)
|
1207 |
(* L1 norm of the subdiagonal part of column k *)
|
1205 |
x:=0.0;
|
1208 |
x:=0.0;
|
1206 |
FOR i:=k+1 TO M DO
|
1209 |
FOR i:=kp1 TO M-1 DO
|
1207 |
x:=x + ABS(A[k-1,i-1]);
|
1210 |
x:=x + ABS(A[k,i]);
|
1208 |
END;
|
1211 |
END;
|
1209 |
IF (x # 0.0) THEN
|
1212 |
IF (x # 0.0) THEN
|
1210 |
x:=x + ABS(A[k-1,k-1]);
|
1213 |
x:=x + ABS(A[k,k]);
|
1211 |
(* scaled householder vector *)
|
1214 |
(* scaled householder vector *)
|
1212 |
DSC16(x,s16,r16);
|
1215 |
DSC16(x,s16,r16);
|
1213 |
s:=0.0;
|
1216 |
s:=0.0;
|
1214 |
FOR i:=k TO M DO
|
1217 |
FOR i:=k TO M-1 DO
|
1215 |
A[k-1,i-1] := r16*A[k-1,i-1];
|
1218 |
A[k,i] := r16*A[k,i];
|
1216 |
s:=s + sqr(A[k-1,i-1]);
|
1219 |
s:=s + sqr(A[k,i]);
|
1217 |
END;
|
1220 |
END;
|
1218 |
s := -DSIGN(sqrt(s),A[k-1,k-1]);
|
1221 |
s := -DSIGN(sqrt(s),A[k,k]);
|
1219 |
x := 1.0 / s;
|
1222 |
x := 1.0 / s;
|
1220 |
<* IF (__BLAS__) THEN *>
|
1223 |
<* IF (__BLAS__) THEN *>
|
1221 |
dscal(M-k+1,x,A[k-1,k-1],1);
|
1224 |
dscal(M-kp1+1,x,A[k,k],1);
|
1222 |
<* ELSE *>
|
1225 |
<* ELSE *>
|
1223 |
FOR i:=k TO M DO A[k-1,i-1] := x*A[k-1,i-1]; END;
|
1226 |
FOR i:=k TO M-1 DO
|
|
|
1227 |
A[k,i] := x*A[k,i];
|
|
|
1228 |
END;
|
1224 |
<* END *>
|
1229 |
<* END *>
|
1225 |
A[k-1,k-1] := A[k-1,k-1] - 1.0;
|
1230 |
A[k,k] := A[k,k] - 1.0;
|
1226 |
(* diagonal element *)
|
1231 |
(* diagonal element *)
|
1227 |
D[k-1] := s16*s;
|
1232 |
D[k] := s16*s;
|
1228 |
(* left transformation *)
|
1233 |
(* left transformation *)
|
1229 |
x := 1.0 / A[k-1,k-1];
|
1234 |
x := 1.0 / A[k,k];
|
1230 |
IF (k < kk) THEN
|
1235 |
IF (kp1 < kk) THEN
|
1231 |
(* path for small arrays *)
|
1236 |
(* path for small arrays *)
|
1232 |
FOR j:=k+1 TO N DO
|
1237 |
FOR j:=k+1 TO N-1 DO
|
1233 |
s:=0.0;
|
1238 |
s:=0.0;
|
1234 |
FOR i:=k TO M DO
|
1239 |
FOR i:=k TO M-1 DO
|
1235 |
s:=s + A[j-1,i-1]*A[k-1,i-1];
|
1240 |
s:=s + A[j,i]*A[k,i];
|
1236 |
END;
|
1241 |
END;
|
1237 |
s := s*x;
|
1242 |
s := s*x;
|
1238 |
FOR i:=k TO M DO
|
1243 |
FOR i:=k TO M-1 DO
|
1239 |
A[j-1,i-1]:=A[j-1,i-1] + s*A[k-1,i-1];
|
1244 |
A[j,i]:=A[j,i] + s*A[k,i];
|
1240 |
END;
|
1245 |
END;
|
1241 |
E^[j-1] := A[j-1,k-1];
|
1246 |
E^[j] := A[j,k];
|
1242 |
END; (* FOR *)
|
1247 |
END; (* FOR *)
|
1243 |
ELSE
|
1248 |
ELSE
|
1244 |
(* path for large arrays *)
|
1249 |
(* path for large arrays *)
|
1245 |
FOR j:=k+1 TO N DO
|
1250 |
FOR j:=k+1 TO N-1 DO
|
1246 |
<* IF (__BLAS__) THEN *>
|
1251 |
<* IF (__BLAS__) THEN *>
|
1247 |
s := x*ddot(M-k+1,A[j-1,k-1],1,A[k-1,k-1],1);
|
1252 |
s := x*ddot(M-kp1+1,A[j,k],1,A[k,k],1);
|
1248 |
daxpy(M-k+1,s,A[k-1,k-1],1,A[j-1,k-1],1);
|
1253 |
daxpy(M-kp1+1,s,A[k,k],1,A[j,k],1);
|
1249 |
<* ELSE *>
|
1254 |
<* ELSE *>
|
1250 |
s:=0.0;
|
1255 |
s:=0.0;
|
1251 |
FOR i:=k TO M DO s:=s + A[j-1,i-1]*A[k-1,i-1]; END;
|
1256 |
FOR i:=k TO M-1 DO
|
|
|
1257 |
s:=s + A[j,i]*A[k,i];
|
|
|
1258 |
END;
|
1252 |
s := s*x;
|
1259 |
s := s*x;
|
1253 |
FOR i:=k TO M DO
|
1260 |
FOR i:=k TO M-1 DO
|
1254 |
A[j-1,i-1] := A[j-1,i-1] + s*A[k-1,i-1];
|
1261 |
A[j,i] := A[j,i] + s*A[k,i];
|
1255 |
END;
|
1262 |
END;
|
1256 |
<* END *>
|
1263 |
<* END *>
|
1257 |
E^[j-1] := A[j-1,k-1];
|
1264 |
E^[j] := A[j,k];
|
1258 |
END; (* FOR j *)
|
1265 |
END; (* FOR j *)
|
1259 |
|
1266 |
|
1260 |
END; (* IF k < kk *)
|
1267 |
END; (* IF k < kk *)
|
1261 |
(* transformation of the right-hand side *)
|
1268 |
(* transformation of the right-hand side *)
|
1262 |
FOR j:=1 TO Nb DO
|
1269 |
FOR j:=0 TO Nb-1 DO
|
1263 |
s:=0.0;
|
1270 |
s:=0.0;
|
1264 |
FOR i:=k TO M DO
|
1271 |
FOR i:=k TO M-1 DO
|
1265 |
s:=s + A[k-1,i-1]*B[i-1,j-1]; (* !!! *)
|
1272 |
s:=s + A[k,i]*B[i,j]; (* !!! *)
|
1266 |
END;
|
1273 |
END;
|
1267 |
s := s*x;
|
1274 |
s := s*x;
|
1268 |
FOR i:=k TO M DO
|
1275 |
FOR i:=k TO M-1 DO
|
1269 |
B[i-1,j-1]:=B[i-1,j-1] + s*A[k-1,i-1]; (* !!! *)
|
1276 |
B[i,j]:=B[i,j] + s*A[k,i]; (* !!! *)
|
1270 |
END;
|
1277 |
END;
|
1271 |
END; (* FOR j *)
|
1278 |
END; (* FOR j *)
|
1272 |
ELSE
|
1279 |
ELSE
|
1273 |
(* the transformation is bypassed if the norm is zero *)
|
1280 |
(* the transformation is bypassed if the norm is zero *)
|
1274 |
D[k-1] := A[k-1,k-1];
|
1281 |
D[k] := A[k,k];
|
1275 |
FOR j:=k+1 TO N DO
|
1282 |
FOR j:=k+1 TO N-1 DO
|
1276 |
E^[j-1] := A[j-1,k-1];
|
1283 |
E^[j] := A[j,k];
|
1277 |
END;
|
1284 |
END;
|
1278 |
END; (* IF x # 0 *)
|
1285 |
END; (* IF x # 0 *)
|
1279 |
IF (k = N) THEN
|
1286 |
IF (kp1 = N) THEN
|
1280 |
EXIT; (* LOOP k *)
|
1287 |
EXIT; (* LOOP k *)
|
1281 |
END;
|
1288 |
END;
|
1282 |
(* L1 norm of the supercodiagonal part of row k *)
|
1289 |
(* L1 norm of the supercodiagonal part of row k *)
|
1283 |
x:=0.0;
|
1290 |
x:=0.0;
|
1284 |
FOR j:=k+2 TO N DO
|
1291 |
FOR j:=k+2 TO N-1 DO
|
1285 |
x:=x + ABS(E^[j-1]);
|
1292 |
x:=x + ABS(E^[j]);
|
1286 |
END;
|
1293 |
END;
|
1287 |
IF (x # 0.0) THEN
|
1294 |
IF (x # 0.0) THEN
|
1288 |
(* scaled householder vector *)
|
1295 |
(* scaled householder vector *)
|
1289 |
x:=x + ABS(E^[k]);
|
1296 |
x:=x + ABS(E^[kp1]);
|
1290 |
DSC16(x,s16,r16);
|
1297 |
DSC16(x,s16,r16);
|
1291 |
s:=0.0;
|
1298 |
s:=0.0;
|
1292 |
FOR j:=k+1 TO N DO
|
1299 |
FOR j:=k+1 TO N-1 DO
|
1293 |
E^[j-1] := r16*E^[j-1];
|
1300 |
E^[j] := r16*E^[j];
|
1294 |
s:=s + sqr(E^[j-1]);
|
1301 |
s:=s + sqr(E^[j]);
|
1295 |
END;
|
1302 |
END;
|
1296 |
y := -DSIGN(sqrt(s),E^[k]);
|
1303 |
y := -DSIGN(sqrt(s),E^[kp1]);
|
1297 |
E^[k] := E^[k] - y;
|
1304 |
E^[kp1] := E^[kp1] - y;
|
1298 |
x := 1.0 / y;
|
1305 |
x := 1.0 / y;
|
1299 |
FOR j:=k+1 TO N DO
|
1306 |
FOR j:=k+1 TO N-1 DO
|
1300 |
E^[j-1] := x*E^[j-1];
|
1307 |
E^[j] := x*E^[j];
|
1301 |
A[k-1,j-1] := E^[j-1];
|
1308 |
A[k,j] := E^[j];
|
1302 |
END;
|
1309 |
END;
|
1303 |
x := 1.0 / E^[k];
|
1310 |
x := 1.0 / E^[kp1];
|
1304 |
(* right transformation *)
|
1311 |
(* right transformation *)
|
1305 |
FOR i:=k+1 TO M DO
|
1312 |
FOR i:=kp1 TO M-1 DO
|
1306 |
s:=0.0;
|
1313 |
s:=0.0;
|
1307 |
FOR j:=k+1 TO N DO
|
1314 |
FOR j:=k+1 TO N-1 DO
|
1308 |
s:=s + A[j-1,i-1]*E^[j-1];
|
1315 |
s:=s + A[j,i]*E^[j];
|
1309 |
END;
|
1316 |
END;
|
1310 |
s := s*x;
|
1317 |
s := s*x;
|
1311 |
FOR j:=k+1 TO N DO
|
1318 |
FOR j:=k+1 TO N-1 DO
|
1312 |
A[j-1,i-1]:=A[j-1,i-1] + E^[j-1]*s;
|
1319 |
A[j,i]:=A[j,i] + E^[j]*s;
|
1313 |
END;
|
1320 |
END;
|
1314 |
END; (* FOR *)
|
1321 |
END; (* FOR *)
|
1315 |
(* codiagonal element *)
|
1322 |
(* codiagonal element *)
|
1316 |
E^[k] := s16*y;
|
1323 |
E^[kp1] := s16*y;
|
1317 |
ELSE (* x = 0 *)
|
1324 |
ELSE (* x = 0 *)
|
1318 |
(* the transformation is bypassed if the norm is zero *)
|
1325 |
(* the transformation is bypassed if the norm is zero *)
|
1319 |
FOR i:=k+1 TO N DO
|
1326 |
FOR i:=kp1 TO N-1 DO
|
1320 |
A[k-1,i-1]:=0.0;
|
1327 |
A[k,i]:=0.0;
|
1321 |
END;
|
1328 |
END;
|
1322 |
END; (* IF x *)
|
1329 |
END; (* IF x *)
|
1323 |
INC(k);
|
1330 |
INC(kp1);
|
1324 |
END; (* LOOP k *)
|
1331 |
END; (* LOOP k *)
|
1325 |
|
1332 |
|
1326 |
l := mn;
|
1333 |
l := mn;
|
1327 |
IF (M < N) THEN
|
1334 |
IF (M < N) THEN
|
1328 |
INC(l);
|
1335 |
INC(l);
|
1329 |
END; (* IF *)
|
1336 |
END; (* IF *)
|
1330 |
|
1337 |
|
1331 |
(* right matrix of the bidiagonal decomposition *)
|
1338 |
(* right matrix of the bidiagonal decomposition *)
|
1332 |
FOR j:=l+1 TO N DO
|
1339 |
FOR j:=l TO N-1 DO
|
1333 |
FOR i:=1 TO N DO
|
1340 |
FOR i:=0 TO N-1 DO
|
1334 |
A[j-1,i-1]:=0.0;
|
1341 |
A[j,i]:=0.0;
|
1335 |
END;
|
1342 |
END;
|
1336 |
A[j-1,j-1]:=1.0;
|
1343 |
A[j,j]:=1.0;
|
1337 |
END; (* FOR j *)
|
1344 |
END; (* FOR j *)
|
1338 |
|
1345 |
|
1339 |
kk := N - kache;
|
1346 |
kk := N - kache;
|
1340 |
FOR k:=l TO 2 BY -1 DO
|
1347 |
FOR kp1:=l TO 2 BY -1 DO
|
|
|
1348 |
k:=kp1-1;
|
1341 |
FOR i:=1 TO k-1 DO
|
1349 |
FOR i:=0 TO k-1 DO
|
1342 |
A[k-1,i-1] := 0.0;
|
1350 |
A[k,i] := 0.0;
|
1343 |
END;
|
1351 |
END;
|
1344 |
FOR i:=k TO N DO
|
1352 |
FOR i:=k TO N-1 DO
|
1345 |
A[k-1,i-1] := A[k-1-1,i-1];
|
1353 |
A[k,i] := A[k-1,i];
|
1346 |
END;
|
1354 |
END;
|
1347 |
IF (A[k-1,k-1] # 0.0) THEN
|
1355 |
IF (A[k,k] # 0.0) THEN
|
1348 |
x := 1.0 / A[k-1,k-1];
|
1356 |
x := 1.0 / A[k,k];
|
1349 |
IF (k < kk) THEN
|
1357 |
IF (kp1 < kk) THEN
|
1350 |
(* path for small arrays *)
|
1358 |
(* path for small arrays *)
|
1351 |
FOR j:=k+1 TO N DO
|
1359 |
FOR j:=k+1 TO N-1 DO
|
1352 |
s:=0.0;
|
1360 |
s:=0.0;
|
1353 |
FOR i:=k TO N DO
|
1361 |
FOR i:=k TO N-1 DO
|
1354 |
s:=s + A[k-1,i-1]*A[j-1,i-1];
|
1362 |
s:=s + A[k,i]*A[j,i];
|
1355 |
END;
|
1363 |
END;
|
1356 |
s := s*x;
|
1364 |
s := s*x;
|
1357 |
FOR i:=k TO N DO
|
1365 |
FOR i:=k TO N-1 DO
|
1358 |
A[j-1,i-1]:=A[j-1,i-1] + s*A[k-1,i-1];
|
1366 |
A[j,i]:=A[j,i] + s*A[k,i];
|
1359 |
END;
|
1367 |
END;
|
1360 |
END; (* FOR *)
|
1368 |
END; (* FOR *)
|
1361 |
ELSE
|
1369 |
ELSE
|
1362 |
(* path for large arrays *)
|
1370 |
(* path for large arrays *)
|
1363 |
FOR j:=k+1 TO N DO
|
1371 |
FOR j:=k+1 TO N-1 DO
|
1364 |
<* IF (__BLAS__) THEN *>
|
1372 |
<* IF (__BLAS__) THEN *>
|
1365 |
s := x*ddot(N-k+1,A[k-1,k-1],1,A[j-1,k-1],1);
|
1373 |
s := x*ddot(N-kp1+1,A[k,k],1,A[j,k],1);
|
1366 |
daxpy(N-k+1,s,A[k-1,k-1],1,A[j-1,k-1],1);
|
1374 |
daxpy(N-kp1+1,s,A[k,k],1,A[j,k],1);
|
1367 |
<* ELSE *>
|
1375 |
<* ELSE *>
|
1368 |
s := 0.0;
|
1376 |
s := 0.0;
|
1369 |
FOR i:=k TO N DO
|
1377 |
FOR i:=k TO N-1 DO
|
1370 |
s:=s + A[k-1,i-1]*A[j-1,i-1];
|
1378 |
s:=s + A[k,i]*A[j,i];
|
1371 |
END;
|
1379 |
END;
|
1372 |
s := s*x;
|
1380 |
s := s*x;
|
1373 |
FOR i:=k TO N DO
|
1381 |
FOR i:=k TO N-1 DO
|
1374 |
A[j-1,i-1]:=A[j-1,i-1] + s*A[k-1,i-1];
|
1382 |
A[j,i]:=A[j,i] + s*A[k,i];
|
1375 |
END;
|
1383 |
END;
|
1376 |
<* END *>
|
1384 |
<* END *>
|
1377 |
END; (* FOR j *)
|
1385 |
END; (* FOR j *)
|
1378 |
|
1386 |
|
1379 |
END; (* IF k < kk *)
|
1387 |
END; (* IF k < kk *)
|
1380 |
END; (* IF A[k-1,k-1] # 0 *)
|
1388 |
END; (* IF A[k-1,k-1] # 0 *)
|
1381 |
A[k-1,k-1]:=A[k-1,k-1] + 1.0;
|
1389 |
A[k,k]:=A[k,k] + 1.0;
|
1382 |
END; (* FOR k *)
|
1390 |
END; (* FOR k *)
|
1383 |
|
1391 |
|
1384 |
A[1-1,1-1]:=1.0;
|
1392 |
A[0,0]:=1.0;
|
1385 |
FOR i:=2 TO N DO
|
1393 |
FOR i:=1 TO N-1 DO
|
1386 |
A[1-1,i-1]:=0.0;
|
1394 |
A[0,i]:=0.0;
|
1387 |
END;
|
1395 |
END;
|
1388 |
|
1396 |
|
1389 |
(* annihilation of the last superdiagonal element when m < n *)
|
1397 |
(* annihilation of the last superdiagonal element when m < n *)
|
1390 |
IF (M < N) THEN
|
1398 |
IF (M < N) THEN
|
1391 |
c := 1.0;
|
1399 |
c := 1.0;
|
1392 |
s := -1.0;
|
1400 |
s := -1.0;
|
1393 |
k:=mn; exit:=FALSE;
|
1401 |
kp1:=mn; exit:=FALSE;
|
1394 |
WHILE (k > 1) AND NOT exit DO (* FOR k:=mn TO 1 BY -1 DO *)
|
1402 |
WHILE (kp1 > 1) AND NOT exit DO (* FOR k:=mn TO 1 BY -1 DO *)
|
1395 |
x := -s*E^[k];
|
1403 |
x := -s*E^[kp1];
|
1396 |
E^[k] := c*E^[k];
|
1404 |
E^[kp1] := c*E^[kp1];
|
1397 |
IF (x = 0.0) THEN
|
1405 |
IF (x = 0.0) THEN
|
1398 |
exit:=TRUE;
|
1406 |
exit:=TRUE;
|
1399 |
ELSE
|
1407 |
ELSE
|
1400 |
IF (ABS(D[k-1]) < ABS(x)) THEN
|
1408 |
IF (ABS(D[k]) < ABS(x)) THEN
|
1401 |
c := D[k-1] / x;
|
1409 |
c := D[k] / x;
|
1402 |
y := sqrt(1.0 + c*c);
|
1410 |
y := sqrt(1.0 + c*c);
|
1403 |
s := 1.0 / y;
|
1411 |
s := 1.0 / y;
|
1404 |
c := c*s;
|
1412 |
c := c*s;
|
1405 |
D[k-1] := y*x;
|
1413 |
D[k] := y*x;
|
1406 |
ELSE
|
1414 |
ELSE
|
1407 |
s := x / D[k-1];
|
1415 |
s := x / D[k];
|
1408 |
y := sqrt(1.0 + s*s);
|
1416 |
y := sqrt(1.0 + s*s);
|
1409 |
c := 1.0 / y;
|
1417 |
c := 1.0 / y;
|
1410 |
s := s*c;
|
1418 |
s := s*c;
|
1411 |
D[k-1] := y*D[k-1];
|
1419 |
D[k] := y*D[k];
|
1412 |
END; (* IF *)
|
1420 |
END; (* IF *)
|
1413 |
FOR i:=1 TO N DO
|
1421 |
FOR i:=0 TO N-1 DO
|
1414 |
x := A[k-1,i-1];
|
1422 |
x := A[k,i];
|
1415 |
y := A[l-1,i-1];
|
1423 |
y := A[l-1,i];
|
1416 |
A[k-1,i-1] := c*x + s*y;
|
1424 |
A[k,i] := c*x + s*y;
|
1417 |
A[l-1,i-1] := c*y - s*x;
|
1425 |
A[l-1,i] := c*y - s*x;
|
1418 |
END; (* FOR *)
|
1426 |
END; (* FOR *)
|
1419 |
END; (* IF *)
|
1427 |
END; (* IF *)
|
1420 |
DEC(k);
|
1428 |
DEC(kp1);
|
1421 |
END; (* WHILE k *)
|
1429 |
END; (* WHILE k *)
|
1422 |
END; (* IF M < N *)
|
1430 |
END; (* IF M < N *)
|
1423 |
|
1431 |
|
1424 |
FOR i:=mn+1 TO N DO
|
1432 |
FOR i:=mn TO N-1 DO
|
1425 |
FOR j:=1 TO Nb DO
|
1433 |
FOR j:=0 TO Nb-1 DO
|
1426 |
B[i-1,j-1]:=0.0;
|
1434 |
B[i,j]:=0.0;
|
1427 |
END;
|
1435 |
END;
|
1428 |
D[i-1]:=0.0;
|
1436 |
D[i]:=0.0;
|
1429 |
END;
|
1437 |
END;
|
1430 |
|
1438 |
|
1431 |
(* singular-value decomposition of the upper- *)
|
1439 |
(* singular-value decomposition of the upper- *)
|
1432 |
(* bidiagonal matrix of order min(m,n) *)
|
1440 |
(* bidiagonal matrix of order min(m,n) *)
|
1433 |
(* L1 norm of the bidiagonal matrix *)
|
1441 |
(* L1 norm of the bidiagonal matrix *)
|
1434 |
bnorm := 0.0;
|
1442 |
bnorm := 0.0;
|
1435 |
FOR i:=1 TO mn DO
|
1443 |
FOR i:=0 TO mn-1 DO
|
1436 |
bnorm := DMAX(ABS(D[i-1])+ABS(E^[i-1]),bnorm);
|
1444 |
bnorm := DMAX(ABS(D[i])+ABS(E^[i]),bnorm);
|
1437 |
END;
|
1445 |
END;
|
1438 |
|
1446 |
|
1439 |
FOR k:=mn TO 1 BY -1 DO (* diagonalization *)
|
1447 |
FOR k:=mn TO 1 BY -1 DO (* diagonalization *)
|
1440 |
|
1448 |
kp1:=k+1;
|
1441 |
it:=0;
|
1449 |
it:=0;
|
1442 |
REPEAT (* L100 *)
|
1450 |
REPEAT (* L100 *)
|
1443 |
|
|
|
1444 |
(* tests for splitting *)
|
1451 |
(* tests for splitting *)
|
1445 |
cancellation:=TRUE;
|
1452 |
cancellation:=TRUE;
|
1446 |
ll:=k; (* k=mn,1,-1 *)
|
1453 |
ll:=kp1; (* k=mn,1,-1 *)
|
1447 |
LOOP (* FOR l:=k TO 1 BY -1 DO *)
|
1454 |
LOOP (* FOR l:=k TO 1 BY -1 DO *)
|
1448 |
x := bnorm + ABS(E^[ll-1]);
|
1455 |
x := bnorm + ABS(E^[ll-1]);
|
1449 |
IF (x = bnorm) THEN
|
1456 |
IF (x = bnorm) THEN
|
1450 |
cancellation:=FALSE;
|
1457 |
cancellation:=FALSE;
|
1451 |
EXIT;
|
1458 |
EXIT;
|
|
... |
|
... |
1461 |
|
1468 |
|
1462 |
IF cancellation THEN
|
1469 |
IF cancellation THEN
|
1463 |
(* cancellation of E[l] *)
|
1470 |
(* cancellation of E[l] *)
|
1464 |
c := 0.0;
|
1471 |
c := 0.0;
|
1465 |
s := 1.0;
|
1472 |
s := 1.0;
|
1466 |
i := l; exit := FALSE;
|
1473 |
ip1 := l; exit := FALSE;
|
1467 |
WHILE (l <= k) AND NOT exit DO (* FOR i:=l TO k DO *)
|
1474 |
WHILE (l <= kp1) AND NOT exit DO (* FOR i:=l TO k DO *)
|
|
|
1475 |
i:=ip1-1;
|
1468 |
f := s*E^[i-1];
|
1476 |
f := s*E^[i];
|
1469 |
E^[i-1] := c*E^[i-1];
|
1477 |
E^[i] := c*E^[i];
|
1470 |
x := bnorm + ABS(f);
|
1478 |
x := bnorm + ABS(f);
|
1471 |
IF (x = bnorm) THEN
|
1479 |
IF (x = bnorm) THEN
|
1472 |
exit := TRUE;
|
1480 |
exit := TRUE;
|
1473 |
ELSE
|
1481 |
ELSE
|
1474 |
g := D[i-1];
|
1482 |
g := D[i];
|
1475 |
IF (ABS(g) < ABS(f)) THEN
|
1483 |
IF (ABS(g) < ABS(f)) THEN
|
1476 |
c := g / f;
|
1484 |
c := g / f;
|
1477 |
h := sqrt(1.0 + c*c);
|
1485 |
h := sqrt(1.0 + c*c);
|
1478 |
s := -1.0 / h;
|
1486 |
s := -1.0 / h;
|
1479 |
c := -c*s;
|
1487 |
c := -c*s;
|
1480 |
D[i-1] := f*h;
|
1488 |
D[i] := f*h;
|
1481 |
ELSE
|
1489 |
ELSE
|
1482 |
s := f / g;
|
1490 |
s := f / g;
|
1483 |
h := sqrt(1.0 + s*s);
|
1491 |
h := sqrt(1.0 + s*s);
|
1484 |
c := 1.0 / h;
|
1492 |
c := 1.0 / h;
|
1485 |
s := -s*c;
|
1493 |
s := -s*c;
|
1486 |
D[i-1] := g*h;
|
1494 |
D[i] := g*h;
|
1487 |
END; (* IF *)
|
1495 |
END; (* IF *)
|
1488 |
(* update of the right-hand side *)
|
1496 |
(* update of the right-hand side *)
|
1489 |
FOR j:=1 TO Nb DO
|
1497 |
FOR j:=0 TO Nb-1 DO
|
1490 |
y := B[l-2,j-1];
|
1498 |
y := B[l-2,j];
|
1491 |
z := B[i-1,j-1];
|
1499 |
z := B[i,j];
|
1492 |
B[l-2,j-1] := y*c + z*s;
|
1500 |
B[l-2,j] := y*c + z*s;
|
1493 |
B[i-1,j-1] := -y*s + z*c;
|
1501 |
B[i,j] := -y*s + z*c;
|
1494 |
END;
|
1502 |
END;
|
1495 |
INC(i);
|
1503 |
INC(ip1);
|
1496 |
END; (* IF *)
|
1504 |
END; (* IF *)
|
1497 |
END; (* FOR i *)
|
1505 |
END; (* WHILE i *)
|
1498 |
END; (* IF cancellation *)
|
1506 |
END; (* IF cancellation *)
|
1499 |
|
1507 |
|
1500 |
(* test for convergence *)
|
1508 |
(* test for convergence *)
|
1501 |
z := D[k-1];
|
1509 |
z := D[k];
|
1502 |
IF (l # k) THEN
|
1510 |
IF (l # kp1) THEN
|
1503 |
(* shift from bottom principal matrix of order 2 *)
|
1511 |
(* shift from bottom principal matrix of order 2 *)
|
1504 |
INC(it);
|
1512 |
INC(it);
|
1505 |
IF (it >= maxit) THEN
|
1513 |
IF (it >= maxit) THEN
|
1506 |
(* no convergence to a singular value after maxit iterations *)
|
1514 |
(* no convergence to a singular value after maxit iterations *)
|
1507 |
iErr := k;
|
1515 |
iErr := kp1;
|
1508 |
DEALLOCATE(E,MAX0(M,N)*TSIZE(LONGREAL));
|
1516 |
DEALLOCATE(E,MAX0(M,N)*TSIZE(LONGREAL));
|
1509 |
Errors.Pause(999);
|
1517 |
Errors.Pause(999);
|
1510 |
RETURN;
|
1518 |
RETURN;
|
1511 |
END; (* IF *)
|
1519 |
END; (* IF *)
|
1512 |
x := D[l-1];
|
1520 |
x := D[l-1];
|
1513 |
y := D[k-2];
|
1521 |
y := D[kp1-2];
|
1514 |
g := E^[k-2];
|
1522 |
g := E^[kp1-2];
|
1515 |
h := E^[k-1];
|
1523 |
h := E^[k];
|
1516 |
f := 0.5*(((g + z) / h)*((g - z) / y) + y/h - h/y);
|
1524 |
f := 0.5*(((g + z) / h)*((g - z) / y) + y/h - h/y);
|
1517 |
IF (ABS(f) >= 1.0) THEN
|
1525 |
IF (ABS(f) >= 1.0) THEN
|
1518 |
f := x - (z/x)*z +
|
1526 |
f := x - (z/x)*z +
|
1519 |
(h/x)*(y / (f*(1.0 + sqrt(1.0 + sqr(1.0/f)))) - h);
|
1527 |
(h/x)*(y / (f*(1.0 + sqrt(1.0 + sqr(1.0/f)))) - h);
|
1520 |
ELSE
|
1528 |
ELSE
|
|
... |
|
... |
1522 |
(h/x)*(y / (f + DSIGN(sqrt(1.0 + f*f),f)) - h);
|
1530 |
(h/x)*(y / (f + DSIGN(sqrt(1.0 + f*f),f)) - h);
|
1523 |
END; (* IF *)
|
1531 |
END; (* IF *)
|
1524 |
(* QR sweep *)
|
1532 |
(* QR sweep *)
|
1525 |
c := 1.0;
|
1533 |
c := 1.0;
|
1526 |
s := 1.0;
|
1534 |
s := 1.0;
|
1527 |
FOR i:=l TO k-1 DO
|
1535 |
FOR i:=l-1 TO k-1 DO
|
|
|
1536 |
ip1:=i+1;
|
1528 |
g := E^[i];
|
1537 |
g := E^[ip1];
|
1529 |
y := D[i];
|
1538 |
y := D[ip1];
|
1530 |
h := s*g;
|
1539 |
h := s*g;
|
1531 |
g := c*g;
|
1540 |
g := c*g;
|
1532 |
IF (ABS(f) < ABS(h)) THEN
|
1541 |
IF (ABS(f) < ABS(h)) THEN
|
1533 |
c := f / h;
|
1542 |
c := f / h;
|
1534 |
z := sqrt(1.0 + c*c);
|
1543 |
z := sqrt(1.0 + c*c);
|
1535 |
s := 1.0 / z;
|
1544 |
s := 1.0 / z;
|
1536 |
c := c*s;
|
1545 |
c := c*s;
|
1537 |
E^[i-1] := h*z;
|
1546 |
E^[i] := h*z;
|
1538 |
ELSE
|
1547 |
ELSE
|
1539 |
s := h / f;
|
1548 |
s := h / f;
|
1540 |
z := sqrt(1.0 + s*s);
|
1549 |
z := sqrt(1.0 + s*s);
|
1541 |
c := 1.0 / z;
|
1550 |
c := 1.0 / z;
|
1542 |
s := s*c;
|
1551 |
s := s*c;
|
1543 |
E^[i-1] := f*z;
|
1552 |
E^[i] := f*z;
|
1544 |
END; (* IF |f| < |h| *)
|
1553 |
END; (* IF |f| < |h| *)
|
1545 |
f := x*c + g*s;
|
1554 |
f := x*c + g*s;
|
1546 |
g := -x*s + g*c;
|
1555 |
g := -x*s + g*c;
|
1547 |
h := y*s;
|
1556 |
h := y*s;
|
1548 |
y := y*c;
|
1557 |
y := y*c;
|
1549 |
(* update of matrix V *)
|
1558 |
(* update of matrix V *)
|
1550 |
FOR j:=1 TO N DO
|
1559 |
FOR j:=0 TO N-1 DO
|
1551 |
x := A[i-1,j-1];
|
1560 |
x := A[i,j];
|
1552 |
z := A[i+1-1,j-1];
|
1561 |
z := A[ip1,j];
|
1553 |
A[i-1,j-1] := x*c + z*s;
|
1562 |
A[i,j] := x*c + z*s;
|
1554 |
A[i+1-1,j-1] := -x*s + z*c;
|
1563 |
A[ip1,j] := -x*s + z*c;
|
1555 |
END; (* FOR j *)
|
1564 |
END; (* FOR j *)
|
1556 |
z := DMAX(ABS(f),ABS(h));
|
1565 |
z := DMAX(ABS(f),ABS(h));
|
1557 |
z := z*sqrt(sqr(f/z) + sqr(h/z));
|
1566 |
z := z*sqrt(sqr(f/z) + sqr(h/z));
|
1558 |
D[i-1] := z;
|
1567 |
D[i] := z;
|
1559 |
IF (z#0.0) THEN
|
1568 |
IF (z#0.0) THEN
|
1560 |
c := f / z;
|
1569 |
c := f / z;
|
1561 |
s := h / z;
|
1570 |
s := h / z;
|
1562 |
END; (* IF *)
|
1571 |
END; (* IF *)
|
1563 |
f := c*g + s*y;
|
1572 |
f := c*g + s*y;
|
1564 |
x := -s*g + c*y;
|
1573 |
x := -s*g + c*y;
|
1565 |
(* update of the right-hand side *)
|
1574 |
(* update of the right-hand side *)
|
1566 |
FOR j:=1 TO Nb DO
|
1575 |
FOR j:=0 TO Nb-1 DO
|
1567 |
y := B[i-1,j-1];
|
1576 |
y := B[i,j];
|
1568 |
z := B[i+1-1,j-1];
|
1577 |
z := B[ip1,j];
|
1569 |
B[i-1,j-1] := y*c + z*s;
|
1578 |
B[i,j] := y*c + z*s;
|
1570 |
B[i+1-1,j-1] := -y*s + z*c;
|
1579 |
B[ip1,j] := -y*s + z*c;
|
1571 |
END; (* FOR *)
|
1580 |
END; (* FOR *)
|
1572 |
END; (* FOR *)
|
1581 |
END; (* FOR i *)
|
1573 |
E^[l-1] := 0.0;
|
1582 |
E^[l-1] := 0.0;
|
1574 |
E^[k-1] := f;
|
1583 |
E^[k] := f;
|
1575 |
D[k-1] := x;
|
1584 |
D[k] := x;
|
1576 |
END; (* IF l # k *)
|
1585 |
END; (* IF l # k *)
|
1577 |
UNTIL (l = k); (* LOOP L100 *)
|
1586 |
UNTIL (l = kp1); (* LOOP L100 *)
|
1578 |
|
1587 |
|
1579 |
IF (z < 0.0) THEN
|
1588 |
IF (z < 0.0) THEN
|
1580 |
(* k-th singular value *)
|
1589 |
(* k-th singular value *)
|
1581 |
D[k-1] := -z;
|
1590 |
D[k] := -z;
|
1582 |
FOR j:=1 TO N DO
|
1591 |
FOR j:=0 TO N-1 DO
|
1583 |
A[k-1,j-1] := -A[k-1,j-1];
|
1592 |
A[k,j] := -A[k,j];
|
1584 |
END;
|
1593 |
END;
|
1585 |
END;
|
1594 |
END;
|
1586 |
|
1595 |
|
1587 |
END; (* FOR k *)
|
1596 |
END; (* FOR k *)
|
1588 |
DEALLOCATE(E,MAX0(M,N)*TSIZE(LONGREAL));
|
1597 |
DEALLOCATE(E,MAX0(M,N)*TSIZE(LONGREAL));
|