|
a/LibDBlasM2.mod |
|
b/LibDBlasM2.mod |
|
... |
|
... |
9 |
(* Letzte Bearbeitung *)
|
9 |
(* Letzte Bearbeitung *)
|
10 |
(* *)
|
10 |
(* *)
|
11 |
(* 23.11.93, MRi: Erstellen der 1. Version *)
|
11 |
(* 23.11.93, MRi: Erstellen der 1. Version *)
|
12 |
(* Aug. 95, MRi: Erweiterung *)
|
12 |
(* Aug. 95, MRi: Erweiterung *)
|
13 |
(* 03.11.95, MRi: Durchsicht *)
|
13 |
(* 03.11.95, MRi: Durchsicht *)
|
14 |
(* 13.10.15, MRi: Ersetzen von LFLOAT(#) durch VAL(LONGREAL,#) *)
|
14 |
(* 13.10.15, MRi: Ersetzen von FLOAT(#) durch VAL(FLOAT,#) *)
|
15 |
(* 30.11.15, MRi: Erstelle der Routinen dscal,daxpy,idmax aus Linpack *)
|
15 |
(* 30.11.15, MRi: Erstelle der Routinen dscal,daxpy,idmax aus Linpack *)
|
16 |
(* Benchmark aus Beispielen von Stony Brook M2 *)
|
16 |
(* Benchmark aus Beispielen von Stony Brook M2 *)
|
17 |
(* 01.12.15, MRi: Umbenennen von BlasLib auf LibDBlas, einfuegen von *)
|
17 |
(* 01.12.15, MRi: Umbenennen von BlasLib auf LibDBlas, einfuegen von *)
|
18 |
(* dnrm2 (aus dnrm2.f) *)
|
18 |
(* dnrm2 (aus dnrm2.f) *)
|
19 |
(* 28.01.16, MRi: Umstellen von dgemv und dgemm auf "Open Array". *)
|
19 |
(* 28.01.16, MRi: Umstellen von dgemv und dgemm auf "Open Array". *)
|
|
... |
|
... |
24 |
(* 31.03.16, MRi: drot und drotg eingefuegt *)
|
24 |
(* 31.03.16, MRi: drot und drotg eingefuegt *)
|
25 |
(* 13.04.16, MRi: dcopy eingefuegt *)
|
25 |
(* 13.04.16, MRi: dcopy eingefuegt *)
|
26 |
(* 21.10.16, MRi: idamin eingefuegt *)
|
26 |
(* 21.10.16, MRi: idamin eingefuegt *)
|
27 |
(* 28.10.17, MRi: zgemm eingefuegt *)
|
27 |
(* 28.10.17, MRi: zgemm eingefuegt *)
|
28 |
(* 29.10.17, MRi: Rolle von M,N in dgemm und dgemv an zgemm angepasst *)
|
28 |
(* 29.10.17, MRi: Rolle von M,N in dgemm und dgemv an zgemm angepasst *)
|
|
|
29 |
(* 11.09.18, MRi: zgemv eingefuegt *)
|
|
|
30 |
(* 12.09.18, MRi: zswap,zcopy,zdotc,dznrm2,zscal,zaxpy,zdrot eingefuegt *)
|
29 |
(*------------------------------------------------------------------------*)
|
31 |
(*------------------------------------------------------------------------*)
|
30 |
(* Testroutinen *)
|
32 |
(* Testroutinen *)
|
31 |
(* *)
|
33 |
(* *)
|
|
|
34 |
(* - dgemv in TstDGEMV *)
|
|
|
35 |
(* - zgemv in TstZGEMV *)
|
32 |
(* - zgemm in TstCmplxMaMul *)
|
36 |
(* - zgemm in TstCmplxMaMul *)
|
33 |
(*------------------------------------------------------------------------*)
|
37 |
(*------------------------------------------------------------------------*)
|
34 |
(* Offene Punkte: *)
|
38 |
(* Offene Punkte: *)
|
35 |
(* *)
|
39 |
(* *)
|
36 |
(* - Weiteres austesten von dgemm und besonders dgemv *)
|
40 |
(* - Weiteres austesten von dgemm und besonders dgemv *)
|
|
... |
|
... |
38 |
(*------------------------------------------------------------------------*)
|
42 |
(*------------------------------------------------------------------------*)
|
39 |
(* Implementation : Michael Riedl *)
|
43 |
(* Implementation : Michael Riedl *)
|
40 |
(* Licence : GNU Lesser General Public License (LGPL) *)
|
44 |
(* Licence : GNU Lesser General Public License (LGPL) *)
|
41 |
(*------------------------------------------------------------------------*)
|
45 |
(*------------------------------------------------------------------------*)
|
42 |
|
46 |
|
43 |
(* $Id: LibDBlasM2.mod,v 1.9 2017/10/29 09:55:11 mriedl Exp mriedl $ *)
|
47 |
(* $Id: LibDBlasM2.mod,v 1.11 2018/09/12 13:20:49 mriedl Exp mriedl $ *)
|
44 |
|
48 |
|
45 |
IMPORT SYSTEM;
|
49 |
IMPORT SYSTEM;
|
46 |
FROM Deklera IMPORT FLOAT; (* REAL type *)
|
50 |
FROM Deklera IMPORT FLOAT,CFLOAT; (* REAL/COMPLEX Type *)
|
47 |
FROM LongMath IMPORT sqrt;
|
51 |
FROM LongMath IMPORT sqrt;
|
48 |
FROM LongComplexMath IMPORT conj;
|
52 |
FROM LongComplexMath IMPORT zero,one,conj,scalarMult;
|
49 |
IMPORT Errors;
|
53 |
IMPORT Errors;
|
|
|
54 |
FROM F77func IMPORT MAX0;
|
50 |
|
55 |
|
51 |
IMPORT TIO;
|
|
|
52 |
|
|
|
53 |
TYPE PVEKTOR = POINTER TO ARRAY [0..MAX(INTEGER)-1] OF FLOAT;
|
|
|
54 |
|
56 |
|
55 |
PROCEDURE IMax(a,b : INTEGER) : INTEGER;
|
57 |
PROCEDURE IMax(a,b : INTEGER) : INTEGER;
|
56 |
|
58 |
|
57 |
BEGIN
|
59 |
BEGIN
|
58 |
IF (a > b) THEN RETURN a; ELSE RETURN b; END;
|
60 |
IF (a > b) THEN RETURN a; ELSE RETURN b; END;
|
|
... |
|
... |
182 |
ELSE
|
184 |
ELSE
|
183 |
scale := 0.0;
|
185 |
scale := 0.0;
|
184 |
ssq := 1.0;
|
186 |
ssq := 1.0;
|
185 |
ix := 0;
|
187 |
ix := 0;
|
186 |
FOR i:=0 TO n-1 DO
|
188 |
FOR i:=0 TO n-1 DO
|
187 |
TIO.WrStr("ix = "); TIO.WrInt(ix,1); TIO.WrLn;
|
|
|
188 |
IF (X[ix] # 0.0) THEN
|
189 |
IF (X[ix] # 0.0) THEN
|
189 |
absxi := ABS(X[ix]);
|
190 |
absxi := ABS(X[ix]);
|
190 |
IF (scale < absxi) THEN
|
191 |
IF (scale < absxi) THEN
|
191 |
zw := scale / absxi;
|
192 |
zw := scale / absxi;
|
192 |
ssq := 1.0 + ssq*zw*zw;
|
193 |
ssq := 1.0 + ssq*zw*zw;
|
|
... |
|
... |
528 |
(* Finds the index of element having min. absolute value. *)
|
529 |
(* Finds the index of element having min. absolute value. *)
|
529 |
(*----------------------------------------------------------------*)
|
530 |
(*----------------------------------------------------------------*)
|
530 |
|
531 |
|
531 |
VAR dmin : FLOAT;
|
532 |
VAR dmin : FLOAT;
|
532 |
i,ix,itemp : INTEGER;
|
533 |
i,ix,itemp : INTEGER;
|
533 |
XX : PVEKTOR;
|
|
|
534 |
BEGIN
|
534 |
BEGIN
|
535 |
IF (n < 1) THEN RETURN -1; END;
|
535 |
IF (n < 1) THEN RETURN -1; END;
|
536 |
IF (n = 1) THEN RETURN 0; END;
|
536 |
IF (n = 1) THEN RETURN 0; END;
|
537 |
|
537 |
|
538 |
XX:=SYSTEM.CAST(PVEKTOR,SYSTEM.ADR(X));
|
|
|
539 |
|
|
|
540 |
itemp:=0;
|
538 |
itemp:=0;
|
541 |
IF (IncX <> 1) THEN (* code for Increment not equal to 1 *)
|
539 |
IF (IncX <> 1) THEN (* code for Increment not equal to 1 *)
|
542 |
dmin := ABS(XX^[0]);
|
540 |
dmin := ABS(X[0]);
|
543 |
ix := 1 + IncX;
|
541 |
ix := 1 + IncX;
|
544 |
FOR i:=1 TO n-1 DO
|
542 |
FOR i:=1 TO n-1 DO
|
545 |
IF (ABS(XX^[ix]) < dmin) THEN
|
543 |
IF (ABS(X[ix]) < dmin) THEN
|
546 |
itemp := i;
|
544 |
itemp := i;
|
547 |
dmin := ABS(XX^[ix]);
|
545 |
dmin := ABS(X[ix]);
|
548 |
END;
|
546 |
END;
|
549 |
INC(ix,IncX);
|
547 |
INC(ix,IncX);
|
550 |
END;
|
548 |
END;
|
551 |
ELSE (* code for increment equal to 1 *)
|
549 |
ELSE (* code for increment equal to 1 *)
|
552 |
dmin := ABS(XX^[0]);
|
550 |
dmin := ABS(X[0]);
|
553 |
FOR i:=1 TO n-1 DO
|
551 |
FOR i:=1 TO n-1 DO
|
554 |
IF (ABS(XX^[i]) < dmin) THEN
|
552 |
IF (ABS(X[i]) < dmin) THEN
|
555 |
itemp := i;
|
553 |
itemp := i;
|
556 |
dmin := ABS(XX^[i]);
|
554 |
dmin := ABS(X[i]);
|
557 |
END;
|
555 |
END;
|
558 |
END;
|
556 |
END;
|
559 |
END;
|
557 |
END;
|
560 |
RETURN itemp + 1;
|
558 |
RETURN itemp + 1;
|
561 |
END idamin;
|
559 |
END idamin;
|
|
... |
|
... |
616 |
VAR Temp : FLOAT;
|
614 |
VAR Temp : FLOAT;
|
617 |
i,j,iy,jx,jy,kx,ky,Info,LenX,LenY : INTEGER;
|
615 |
i,j,iy,jx,jy,kx,ky,Info,LenX,LenY : INTEGER;
|
618 |
BEGIN (* Testen *)
|
616 |
BEGIN (* Testen *)
|
619 |
(* Test the input parameters. *)
|
617 |
(* Test the input parameters. *)
|
620 |
|
618 |
|
621 |
IF (CAP(Trans) = 'C') THEN
|
619 |
IF (NOT (CAP(Trans) = 'N')) AND (NOT (CAP(Trans) = 'T')) THEN
|
622 |
Info := 1;
|
620 |
Info := 1;
|
623 |
ELSIF (M < 0) THEN
|
621 |
ELSIF (M < 0) THEN
|
624 |
Info := 2;
|
622 |
Info := 2;
|
625 |
ELSIF (N < 0) THEN
|
623 |
ELSIF (N < 0) THEN
|
626 |
Info := 3;
|
624 |
Info := 3;
|
|
... |
|
... |
669 |
ky := 1 - (LenY - 1)*IncY;
|
667 |
ky := 1 - (LenY - 1)*IncY;
|
670 |
END;
|
668 |
END;
|
671 |
|
669 |
|
672 |
(* Start the operations. In this version the elements of A are *)
|
670 |
(* Start the operations. In this version the elements of A are *)
|
673 |
(* accessed sequentially with one pass through A. *)
|
671 |
(* accessed sequentially with one pass through A. *)
|
674 |
|
|
|
675 |
|
672 |
|
676 |
IF (Beta # 1.0) THEN (* First form y := beta*y. *)
|
673 |
IF (Beta # 1.0) THEN (* First form y := beta*y. *)
|
677 |
IF (IncY = 1) THEN
|
674 |
IF (IncY = 1) THEN
|
678 |
IF (Beta = 0.0) THEN
|
675 |
IF (Beta = 0.0) THEN
|
679 |
FOR i:=0 TO LenY-1 DO Y[i]:=0.0; END;
|
676 |
FOR i:=0 TO LenY-1 DO Y[i]:=0.0; END;
|
|
... |
|
... |
943 |
INC(ix,IncX);
|
940 |
INC(ix,IncX);
|
944 |
END;
|
941 |
END;
|
945 |
END;
|
942 |
END;
|
946 |
END dger;
|
943 |
END dger;
|
947 |
|
944 |
|
|
|
945 |
(*=========================== Complex valued routines =====================*)
|
|
|
946 |
|
|
|
947 |
PROCEDURE zswap( N : CARDINAL;
|
|
|
948 |
VAR X : ARRAY OF CFLOAT;
|
|
|
949 |
IncX : INTEGER;
|
|
|
950 |
VAR Y : ARRAY OF CFLOAT;
|
|
|
951 |
IncY : INTEGER);
|
|
|
952 |
|
|
|
953 |
CONST veclen = 4;
|
|
|
954 |
|
|
|
955 |
VAR Xi : CFLOAT;
|
|
|
956 |
Xtmp : ARRAY [0..veclen-1] OF CFLOAT;
|
|
|
957 |
ix,iy : INTEGER;
|
|
|
958 |
i,m : CARDINAL;
|
|
|
959 |
BEGIN
|
|
|
960 |
IF (N = 0) THEN RETURN; END;
|
|
|
961 |
|
|
|
962 |
IF (IncX = 1) AND (IncY = 1) THEN
|
|
|
963 |
m := N MOD veclen;
|
|
|
964 |
IF (m # 0) THEN
|
|
|
965 |
FOR i:=0 TO m-1 DO (* Clean up loop *)
|
|
|
966 |
Xi := X[i]; X[i] := Y[i]; Y[i] := Xi;
|
|
|
967 |
END;
|
|
|
968 |
END;
|
|
|
969 |
IF (N < veclen) THEN RETURN; END;
|
|
|
970 |
FOR i:=m TO N-1 BY veclen DO
|
|
|
971 |
Xtmp[0] := X[i+0]; Xtmp[1] := X[i+1];
|
|
|
972 |
Xtmp[2] := X[i+2]; Xtmp[3] := X[i+3];
|
|
|
973 |
X[i+0] := Y[i+0]; X[i+1] := Y[i+1];
|
|
|
974 |
X[i+2] := Y[i+2]; X[i+3] := Y[i+3];
|
|
|
975 |
Y[i+1] := Xtmp[1]; Y[i+0] := Xtmp[0];
|
|
|
976 |
Y[i+2] := Xtmp[2]; Y[i+3] := Xtmp[3];
|
|
|
977 |
END;
|
|
|
978 |
ELSE (* code for unequal increments or equal increments # 1 *)
|
|
|
979 |
IF (IncX > 0) THEN ix:=0; ELSE ix:=(1 - VAL(INTEGER,N))*IncX; END;
|
|
|
980 |
IF (IncY > 0) THEN iy:=0; ELSE iy:=(1 - VAL(INTEGER,N))*IncY; END;
|
|
|
981 |
FOR i:=0 TO N-1 DO
|
|
|
982 |
Xi := X[ix]; X[ix] := Y[iy]; Y[iy] := Xi;
|
|
|
983 |
INC(ix,IncX); INC(iy,IncY);
|
|
|
984 |
END;
|
|
|
985 |
END;
|
|
|
986 |
END zswap;
|
|
|
987 |
|
|
|
988 |
PROCEDURE zcopy( N : INTEGER;
|
|
|
989 |
VAR X : ARRAY OF CFLOAT;
|
|
|
990 |
IncX : INTEGER;
|
|
|
991 |
VAR Y : ARRAY OF CFLOAT;
|
|
|
992 |
IncY : INTEGER);
|
|
|
993 |
|
|
|
994 |
(*----------------------------------------------------------------*)
|
|
|
995 |
(* Adopted to Modula-2, MRi, 04.04.2016, complex version 09.08.18 *)
|
|
|
996 |
(*----------------------------------------------------------------*)
|
|
|
997 |
|
|
|
998 |
VAR i,ix,iy,m : INTEGER;
|
|
|
999 |
BEGIN
|
|
|
1000 |
IF (N <= 0) THEN RETURN; END;
|
|
|
1001 |
|
|
|
1002 |
IF (IncX = 1) AND (IncY = 1) THEN
|
|
|
1003 |
(* code for both increments equal to 1 *)
|
|
|
1004 |
m := (N MOD 8);
|
|
|
1005 |
IF (m # 0) THEN (* Clean-up loop *)
|
|
|
1006 |
FOR i:=0 TO m-1 DO Y[i] := X[i]; END;
|
|
|
1007 |
IF (N < 8) THEN RETURN; END
|
|
|
1008 |
END;
|
|
|
1009 |
FOR i:=m TO N-1 BY 8 DO
|
|
|
1010 |
Y[i+0] := X[i+0]; Y[i+1] := X[i+1];
|
|
|
1011 |
Y[i+2] := X[i+2]; Y[i+3] := X[i+3];
|
|
|
1012 |
Y[i+4] := X[i+4]; Y[i+5] := X[i+5];
|
|
|
1013 |
Y[i+6] := X[i+6]; Y[i+7] := X[i+7];
|
|
|
1014 |
END;
|
|
|
1015 |
ELSE
|
|
|
1016 |
(* code for unequal increments or equal increments not equal to 1 *)
|
|
|
1017 |
IF (IncX > 0) THEN ix:=0; ELSE ix:=(1 - VAL(INTEGER,N))*IncX; END;
|
|
|
1018 |
IF (IncY > 0) THEN iy:=0; ELSE iy:=(1 - VAL(INTEGER,N))*IncY; END;
|
|
|
1019 |
FOR i:=0 TO N-1 DO
|
|
|
1020 |
Y[iy] := X[ix];
|
|
|
1021 |
INC(ix,IncX); INC(iy,IncY);
|
|
|
1022 |
END;
|
|
|
1023 |
END;
|
|
|
1024 |
END zcopy;
|
|
|
1025 |
|
|
|
1026 |
PROCEDURE zdotc( N : INTEGER;
|
|
|
1027 |
VAR X : ARRAY OF CFLOAT;
|
|
|
1028 |
IncX : INTEGER;
|
|
|
1029 |
VAR Y : ARRAY OF CFLOAT;
|
|
|
1030 |
IncY : INTEGER) : CFLOAT;
|
|
|
1031 |
|
|
|
1032 |
CONST veclen = 4;
|
|
|
1033 |
|
|
|
1034 |
VAR dtemp : CFLOAT;
|
|
|
1035 |
i,ix,iy,m : INTEGER;
|
|
|
1036 |
BEGIN
|
|
|
1037 |
IF (N <= 0) THEN RETURN zero; END;
|
|
|
1038 |
|
|
|
1039 |
dtemp := zero;
|
|
|
1040 |
IF (IncX = 1) AND (IncY = 1) THEN
|
|
|
1041 |
(* code for both increments equal to 1 *)
|
|
|
1042 |
m := N MOD veclen;
|
|
|
1043 |
IF (m # 0) THEN
|
|
|
1044 |
FOR i:=0 TO m-1 DO (* clean-up loop *)
|
|
|
1045 |
dtemp:=dtemp + conj(X[i])*Y[i];
|
|
|
1046 |
END;
|
|
|
1047 |
IF (N < veclen) THEN RETURN dtemp; END;
|
|
|
1048 |
END;
|
|
|
1049 |
(* i := m - veclen; *)
|
|
|
1050 |
FOR i:=m TO N-1 BY veclen DO
|
|
|
1051 |
dtemp:=dtemp + conj(X[i+0])*Y[i+0] + conj(X[i+1])*Y[i+1] +
|
|
|
1052 |
conj(X[i+2])*Y[i+2] + conj(X[i+3])*Y[i+3];
|
|
|
1053 |
END;
|
|
|
1054 |
ELSE
|
|
|
1055 |
(* code for unequal increments or equal increments not equal to 1 *)
|
|
|
1056 |
ix := 0; IF (IncX < 0) THEN ix := (1-N)*IncX; END;
|
|
|
1057 |
iy := 0; IF (IncY < 0) THEN iy := (1-N)*IncY; END;
|
|
|
1058 |
FOR i:=1 TO N DO
|
|
|
1059 |
dtemp:=dtemp + conj(X[ix])*Y[iy];
|
|
|
1060 |
INC(ix,IncX); INC(iy,IncY);
|
|
|
1061 |
END;
|
|
|
1062 |
END;
|
|
|
1063 |
RETURN dtemp;
|
|
|
1064 |
END zdotc;
|
|
|
1065 |
|
|
|
1066 |
PROCEDURE dznrm2( N : INTEGER;
|
|
|
1067 |
VAR X : ARRAY OF CFLOAT;
|
|
|
1068 |
IncX : INTEGER) : FLOAT;
|
|
|
1069 |
|
|
|
1070 |
VAR norm,scale,ssq,tmp : FLOAT;
|
|
|
1071 |
i,ix : INTEGER;
|
|
|
1072 |
zw : FLOAT;
|
|
|
1073 |
BEGIN
|
|
|
1074 |
IF (N < 1) OR (IncX < 1) THEN
|
|
|
1075 |
norm := 0.0;
|
|
|
1076 |
ELSE
|
|
|
1077 |
scale := 0.0;
|
|
|
1078 |
ssq := 1.0;
|
|
|
1079 |
ix := 0;
|
|
|
1080 |
FOR i:=0 TO N-1 DO (* DO ix=1,1+(N-1)*IncX,IncX *)
|
|
|
1081 |
IF (RE(X[ix]) # 0.0) THEN
|
|
|
1082 |
tmp := ABS(RE(X[ix]));
|
|
|
1083 |
IF (scale < tmp) THEN
|
|
|
1084 |
zw := scale / tmp;
|
|
|
1085 |
ssq := 1.0 + ssq*(zw*zw);
|
|
|
1086 |
scale := tmp;
|
|
|
1087 |
ELSE
|
|
|
1088 |
zw := tmp / scale;
|
|
|
1089 |
ssq:=ssq + (zw*zw);
|
|
|
1090 |
END;
|
|
|
1091 |
END;
|
|
|
1092 |
IF (IM(X[ix]) # 0.0) THEN
|
|
|
1093 |
tmp := ABS(IM(X[ix]));
|
|
|
1094 |
IF (scale < tmp) THEN
|
|
|
1095 |
zw := scale / tmp;
|
|
|
1096 |
ssq := 1.0 + ssq*(zw*zw);
|
|
|
1097 |
scale := tmp;
|
|
|
1098 |
ELSE
|
|
|
1099 |
zw := tmp / scale;
|
|
|
1100 |
ssq:=ssq + (zw*zw);
|
|
|
1101 |
END;
|
|
|
1102 |
END;
|
|
|
1103 |
INC(ix,IncX);
|
|
|
1104 |
END; (* FOR *)
|
|
|
1105 |
norm := scale*sqrt(ssq);
|
|
|
1106 |
END; (* IF *)
|
|
|
1107 |
RETURN norm;
|
|
|
1108 |
END dznrm2;
|
|
|
1109 |
|
|
|
1110 |
PROCEDURE zscal( n : INTEGER;
|
|
|
1111 |
da : CFLOAT;
|
|
|
1112 |
VAR X : ARRAY OF CFLOAT;
|
|
|
1113 |
IncX : INTEGER);
|
|
|
1114 |
|
|
|
1115 |
CONST veclen = 4;
|
|
|
1116 |
|
|
|
1117 |
VAR i,m : INTEGER;
|
|
|
1118 |
BEGIN
|
|
|
1119 |
IF (n <= 0) THEN RETURN; END;
|
|
|
1120 |
|
|
|
1121 |
IF (IncX <> 1) THEN (* code for increment not equal to 1 *)
|
|
|
1122 |
FOR i:=0 TO n-1 DO
|
|
|
1123 |
X[i*IncX] := da*X[i*IncX];
|
|
|
1124 |
END;
|
|
|
1125 |
ELSE (* code for increment equal to 1 *)
|
|
|
1126 |
m := n REM veclen;
|
|
|
1127 |
IF (m <> 0) THEN
|
|
|
1128 |
FOR i:=0 TO m-1 DO X[i] := da*X[i]; END;
|
|
|
1129 |
IF (n < veclen) THEN
|
|
|
1130 |
RETURN;
|
|
|
1131 |
END;
|
|
|
1132 |
END;
|
|
|
1133 |
FOR i:=m TO n-1 BY veclen DO
|
|
|
1134 |
X[i+0] := da*X[i+0];
|
|
|
1135 |
X[i+1] := da*X[i+1];
|
|
|
1136 |
X[i+2] := da*X[i+2];
|
|
|
1137 |
X[i+3] := da*X[i+3];
|
|
|
1138 |
END;
|
|
|
1139 |
END;
|
|
|
1140 |
END zscal;
|
|
|
1141 |
|
|
|
1142 |
PROCEDURE zaxpy( n : INTEGER;
|
|
|
1143 |
da : CFLOAT;
|
|
|
1144 |
VAR X : ARRAY OF CFLOAT;
|
|
|
1145 |
IncX : INTEGER;
|
|
|
1146 |
VAR Y : ARRAY OF CFLOAT;
|
|
|
1147 |
IncY : INTEGER);
|
|
|
1148 |
|
|
|
1149 |
CONST veclen = 4;
|
|
|
1150 |
|
|
|
1151 |
VAR i,ix,iy,m : INTEGER;
|
|
|
1152 |
BEGIN
|
|
|
1153 |
IF (n <= 0 ) THEN RETURN; END;
|
|
|
1154 |
IF (da = 0.0) THEN RETURN; END;
|
|
|
1155 |
|
|
|
1156 |
IF ((IncX <> 1) OR (IncY <> 1)) THEN
|
|
|
1157 |
(* code for unequal increments or equal increments <> 1 *)
|
|
|
1158 |
ix := 1;
|
|
|
1159 |
iy := 1;
|
|
|
1160 |
IF (IncX < 0) THEN ix := (-n+1)*IncX + 1; END;
|
|
|
1161 |
IF (IncY < 0) THEN iy := (-n+1)*IncY + 1; END;
|
|
|
1162 |
FOR i:=0 TO n-1 DO
|
|
|
1163 |
Y[iy] := Y[iy] + da*X[ix];
|
|
|
1164 |
INC(ix, IncX);
|
|
|
1165 |
INC(iy, IncY);
|
|
|
1166 |
END;
|
|
|
1167 |
ELSE (* code for both increments equal to 1 *)
|
|
|
1168 |
m := n REM veclen;
|
|
|
1169 |
IF (m <> 0) THEN
|
|
|
1170 |
FOR i:=0 TO m-1 DO
|
|
|
1171 |
Y[i] := Y[i] + da*X[i];
|
|
|
1172 |
END;
|
|
|
1173 |
IF (n < veclen) THEN RETURN; END;
|
|
|
1174 |
END;
|
|
|
1175 |
FOR i:=m TO n-1 BY veclen DO
|
|
|
1176 |
Y[i] := Y[i] + da*X[i];
|
|
|
1177 |
Y[i+1] := Y[i+1] + da*X[i+1];
|
|
|
1178 |
Y[i+2] := Y[i+2] + da*X[i+2];
|
|
|
1179 |
Y[i+3] := Y[i+3] + da*X[i+3];
|
|
|
1180 |
END;
|
|
|
1181 |
END;
|
|
|
1182 |
END zaxpy;
|
|
|
1183 |
|
|
|
1184 |
PROCEDURE zdrot( N : INTEGER;
|
|
|
1185 |
VAR X : ARRAY OF CFLOAT;
|
|
|
1186 |
IncX : INTEGER;
|
|
|
1187 |
VAR Y : ARRAY OF CFLOAT;
|
|
|
1188 |
IncY : INTEGER;
|
|
|
1189 |
c,s : FLOAT);
|
|
|
1190 |
|
|
|
1191 |
VAR i,ix,iy : INTEGER;
|
|
|
1192 |
tmp : CFLOAT;
|
|
|
1193 |
BEGIN
|
|
|
1194 |
IF (IncX = 1) AND (IncY = 1) THEN
|
|
|
1195 |
FOR i:=0 TO N-1 DO
|
|
|
1196 |
tmp := scalarMult( c,X[i]) + scalarMult(s,Y[i]);
|
|
|
1197 |
Y[i] := scalarMult(-s,X[i]) + scalarMult(c,Y[i]);
|
|
|
1198 |
X[i] := tmp;
|
|
|
1199 |
END;
|
|
|
1200 |
ELSE
|
|
|
1201 |
IF (IncX > 0) THEN ix:=0; ELSE ix:=(1 - VAL(INTEGER,N))*IncX; END;
|
|
|
1202 |
IF (IncY > 0) THEN iy:=0; ELSE iy:=(1 - VAL(INTEGER,N))*IncY; END;
|
|
|
1203 |
FOR i:=0 TO N-1 DO
|
|
|
1204 |
tmp := scalarMult( c,X[ix]) + scalarMult(s,Y[iy]);
|
|
|
1205 |
Y[iy] := scalarMult(-s,X[ix]) + scalarMult(c,Y[iy]);
|
|
|
1206 |
X[iy] := tmp;
|
|
|
1207 |
ix := ix + IncX;
|
|
|
1208 |
iy := iy + IncY;
|
|
|
1209 |
END;
|
|
|
1210 |
END;
|
|
|
1211 |
END zdrot;
|
|
|
1212 |
|
|
|
1213 |
PROCEDURE zgemv( Trans : CHAR;
|
|
|
1214 |
M,N : INTEGER;
|
|
|
1215 |
Alpha : CFLOAT;
|
|
|
1216 |
VAR A : ARRAY OF ARRAY OF CFLOAT;
|
|
|
1217 |
lda : INTEGER;
|
|
|
1218 |
VAR X : ARRAY OF CFLOAT;
|
|
|
1219 |
IncX : INTEGER;
|
|
|
1220 |
Beta : CFLOAT;
|
|
|
1221 |
VAR Y : ARRAY OF CFLOAT;
|
|
|
1222 |
IncY : INTEGER);
|
|
|
1223 |
|
|
|
1224 |
VAR i,j,iy,jx,kx,ky : INTEGER;
|
|
|
1225 |
lenx,leny,info : INTEGER;
|
|
|
1226 |
s : CFLOAT;
|
|
|
1227 |
noconj : BOOLEAN;
|
|
|
1228 |
BEGIN
|
|
|
1229 |
(* test the input parameters *)
|
|
|
1230 |
|
|
|
1231 |
info := 0;
|
|
|
1232 |
IF (NOT (CAP(Trans) = 'N')) AND (NOT (CAP(Trans) = 'T')) AND
|
|
|
1233 |
(NOT (CAP(Trans) = 'C'))
|
|
|
1234 |
THEN
|
|
|
1235 |
info := 1;
|
|
|
1236 |
ELSIF (M < 0) THEN
|
|
|
1237 |
info := 2;
|
|
|
1238 |
ELSIF (N < 0) THEN
|
|
|
1239 |
info := 3;
|
|
|
1240 |
ELSIF (lda < MAX0(1,M)) THEN
|
|
|
1241 |
info := 6;
|
|
|
1242 |
ELSIF (IncX = 0) THEN
|
|
|
1243 |
info := 8;
|
|
|
1244 |
ELSIF (IncY = 0) THEN
|
|
|
1245 |
info := 11;
|
|
|
1246 |
END;
|
|
|
1247 |
IF (info # 0) THEN (* Fehlerbehandlung ! *)
|
|
|
1248 |
Errors.WriteLn; Errors.WriteLn;
|
|
|
1249 |
Errors.WriteString("Fehler in LibDBlas.zgemv, info = ");
|
|
|
1250 |
Errors.WriteInt(info);
|
|
|
1251 |
Errors.WriteLn; Errors.WriteLn;
|
|
|
1252 |
RETURN;
|
|
|
1253 |
END;
|
|
|
1254 |
|
|
|
1255 |
(* quick return if possible *)
|
|
|
1256 |
|
|
|
1257 |
IF ((M = 0) OR (N = 0) OR ((Alpha = zero) AND (Beta = one))) THEN
|
|
|
1258 |
RETURN
|
|
|
1259 |
END;
|
|
|
1260 |
|
|
|
1261 |
noconj := (CAP(Trans) = 'T');
|
|
|
1262 |
|
|
|
1263 |
(* set lenx and leny, the lengths of the vectors X and Y, *)
|
|
|
1264 |
(* and set up the start points in X and Y. *)
|
|
|
1265 |
|
|
|
1266 |
IF (CAP(Trans) = 'N') THEN
|
|
|
1267 |
lenx := N;
|
|
|
1268 |
leny := M;
|
|
|
1269 |
ELSE
|
|
|
1270 |
lenx := M;
|
|
|
1271 |
leny := N;
|
|
|
1272 |
END;
|
|
|
1273 |
|
|
|
1274 |
IF (IncX > 0) THEN
|
|
|
1275 |
kx := 1;
|
|
|
1276 |
ELSE
|
|
|
1277 |
kx := 1 - (lenx-1)*IncX;
|
|
|
1278 |
END;
|
|
|
1279 |
IF (IncY > 0) THEN
|
|
|
1280 |
ky := 1;
|
|
|
1281 |
ELSE
|
|
|
1282 |
ky := 1 - (leny-1)*IncY;
|
|
|
1283 |
END;
|
|
|
1284 |
|
|
|
1285 |
(* start the operations. In this version the elements of A are *)
|
|
|
1286 |
(* accessed sequentially with one pass through A *)
|
|
|
1287 |
|
|
|
1288 |
(* first form Y = Beta*Y *)
|
|
|
1289 |
|
|
|
1290 |
IF (Beta # one) THEN
|
|
|
1291 |
IF (IncY # 1) THEN
|
|
|
1292 |
iy := ky - 1;
|
|
|
1293 |
IF (Beta = zero) THEN
|
|
|
1294 |
FOR i:=0 TO leny-1 DO
|
|
|
1295 |
Y[iy] := zero;
|
|
|
1296 |
INC(iy,IncY);
|
|
|
1297 |
END; (* FOR *)
|
|
|
1298 |
ELSE
|
|
|
1299 |
FOR i:=0 TO leny-1 DO
|
|
|
1300 |
Y[iy] := Beta*Y[iy];
|
|
|
1301 |
INC(iy,IncY);
|
|
|
1302 |
END; (* FOR *)
|
|
|
1303 |
END; (* IF *)
|
|
|
1304 |
ELSE
|
|
|
1305 |
IF (Beta = zero) THEN
|
|
|
1306 |
FOR i:=0 TO leny-1 DO
|
|
|
1307 |
Y[i] := zero;
|
|
|
1308 |
END;
|
|
|
1309 |
ELSE
|
|
|
1310 |
FOR i:=0 TO leny-1 DO
|
|
|
1311 |
Y[i] := Beta*Y[i];
|
|
|
1312 |
END;
|
|
|
1313 |
END; (* IF *)
|
|
|
1314 |
END; (* IF *)
|
|
|
1315 |
END; (* IF *)
|
|
|
1316 |
|
|
|
1317 |
IF (Alpha = zero) THEN RETURN END;
|
|
|
1318 |
|
|
|
1319 |
IF (CAP(Trans) = 'N') THEN (* Form y := alpha*A*x + y. *)
|
|
|
1320 |
|
|
|
1321 |
|
|
|
1322 |
IF (IncX = 1) AND (IncY = 1) THEN
|
|
|
1323 |
FOR i:=0 TO M-1 DO
|
|
|
1324 |
s:=zero;
|
|
|
1325 |
FOR j:=0 TO N-1 DO
|
|
|
1326 |
s:=s + Alpha*A[i,j]*X[j];
|
|
|
1327 |
END;
|
|
|
1328 |
Y[i]:=Y[i] + s;
|
|
|
1329 |
END;
|
|
|
1330 |
ELSE
|
|
|
1331 |
iy:=ky-1;
|
|
|
1332 |
FOR i:=0 TO M-1 DO
|
|
|
1333 |
s:=zero;
|
|
|
1334 |
jx:=kx-1;
|
|
|
1335 |
FOR j:=0 TO N-1 DO
|
|
|
1336 |
s:=s + Alpha*A[i,j]*X[jx]; INC(jx,IncX);
|
|
|
1337 |
END;
|
|
|
1338 |
Y[iy]:=Y[iy] + s; INC(iy,IncY);
|
|
|
1339 |
END;
|
|
|
1340 |
END;
|
|
|
1341 |
|
|
|
1342 |
ELSE
|
|
|
1343 |
|
|
|
1344 |
(* Form Y = Alpha*A'*X + Y or Y = Alpha*conj(A')*x + y. *)
|
|
|
1345 |
|
|
|
1346 |
IF (IncX = 1) AND (IncY = 1) THEN
|
|
|
1347 |
FOR j:=0 TO M-1 DO
|
|
|
1348 |
IF noconj THEN
|
|
|
1349 |
FOR i:=0 TO N-1 DO
|
|
|
1350 |
Y[i]:=Y[i] + Alpha*A[j,i]*X[j];
|
|
|
1351 |
END;
|
|
|
1352 |
ELSE (* (CAP(Trans) = "C") *)
|
|
|
1353 |
FOR i:=0 TO N-1 DO
|
|
|
1354 |
Y[i]:=Y[i] + Alpha*conj(A[j,i])*X[j];
|
|
|
1355 |
END;
|
|
|
1356 |
END;
|
|
|
1357 |
END;
|
|
|
1358 |
ELSE
|
|
|
1359 |
jx:=kx-1;
|
|
|
1360 |
FOR j:=0 TO M-1 DO
|
|
|
1361 |
IF noconj THEN
|
|
|
1362 |
iy:=ky-1;
|
|
|
1363 |
FOR i:=0 TO N-1 DO
|
|
|
1364 |
Y[iy]:=Y[iy] + Alpha*A[j,i]*X[jx]; INC(iy,IncY);
|
|
|
1365 |
END;
|
|
|
1366 |
ELSE (* (CAP(Trans) = "C") *)
|
|
|
1367 |
iy:=ky-1;
|
|
|
1368 |
FOR i:=0 TO N-1 DO
|
|
|
1369 |
Y[iy]:=Y[iy] + Alpha*conj(A[j,i])*X[jx]; INC(iy,IncY);
|
|
|
1370 |
END;
|
|
|
1371 |
END;
|
|
|
1372 |
INC(jx,IncX);
|
|
|
1373 |
END; (* FOR j *)
|
|
|
1374 |
END;
|
|
|
1375 |
END; (* IF Trans *)
|
|
|
1376 |
END zgemv;
|
|
|
1377 |
|
948 |
PROCEDURE zgemm( TransA,TransB : CHAR;
|
1378 |
PROCEDURE zgemm( TransA,TransB : CHAR;
|
949 |
M,N,K : INTEGER;
|
1379 |
M,N,K : INTEGER;
|
950 |
Alpha : LONGCOMPLEX;
|
1380 |
Alpha : CFLOAT;
|
951 |
VAR A : ARRAY OF ARRAY OF LONGCOMPLEX;
|
1381 |
VAR A : ARRAY OF ARRAY OF CFLOAT;
|
952 |
LDA : INTEGER;
|
1382 |
LDA : INTEGER;
|
953 |
VAR B : ARRAY OF ARRAY OF LONGCOMPLEX;
|
1383 |
VAR B : ARRAY OF ARRAY OF CFLOAT;
|
954 |
LDB : INTEGER;
|
1384 |
LDB : INTEGER;
|
955 |
Beta : LONGCOMPLEX;
|
1385 |
Beta : CFLOAT;
|
956 |
VAR C : ARRAY OF ARRAY OF LONGCOMPLEX;
|
1386 |
VAR C : ARRAY OF ARRAY OF CFLOAT;
|
957 |
LDC : INTEGER);
|
1387 |
LDC : INTEGER);
|
958 |
|
1388 |
|
959 |
CONST zero = CMPLX(0.0,0.0);
|
1389 |
CONST zero = CMPLX(0.0,0.0);
|
960 |
one = CMPLX(1.0,0.0);
|
1390 |
one = CMPLX(1.0,0.0);
|
961 |
|
1391 |
|
962 |
VAR NotA,NotB,ConjA,ConjB : BOOLEAN;
|
1392 |
VAR NotA,NotB,ConjA,ConjB : BOOLEAN;
|
963 |
i,j,k,Info,NRowA,NRowB : INTEGER;
|
1393 |
i,j,k,Info,NRowA,NRowB : INTEGER;
|
964 |
Temp,Aki,Aik : LONGCOMPLEX;
|
1394 |
Temp,Aki,Aik : CFLOAT;
|
965 |
Nm1,Mm1,Km1 : INTEGER;
|
1395 |
Nm1,Mm1,Km1 : INTEGER;
|
966 |
BEGIN
|
1396 |
BEGIN
|
967 |
(* Set NotA and NotB as true if A and B respectively are not *)
|
1397 |
(* Set NotA and NotB as true if A and B respectively are not *)
|
968 |
(* transposed and set NRowA, NColA and NRowB as the number of rows *)
|
1398 |
(* transposed and set NRowA, NColA and NRowB as the number of rows *)
|
969 |
(* and columns of A and the number of rows of B respectively. *)
|
1399 |
(* and columns of A and the number of rows of B respectively. *)
|