Mercurial > octave-nkf
comparison liboctave/CMatrix.cc @ 1948:d7dec93d4b87
[project @ 1996-02-14 03:45:49 by jwe]
author | jwe |
---|---|
date | Wed, 14 Feb 1996 03:47:59 +0000 |
parents | 1281a23a34dd |
children | ab6abe89aaa1 |
comparison
equal
deleted
inserted
replaced
1947:5ab3c25a3cf9 | 1948:d7dec93d4b87 |
---|---|
799 } | 799 } |
800 | 800 |
801 ComplexMatrix | 801 ComplexMatrix |
802 ComplexMatrix::inverse (int& info, double& rcond, int force) const | 802 ComplexMatrix::inverse (int& info, double& rcond, int force) const |
803 { | 803 { |
804 int nr = rows (); | 804 ComplexMatrix retval; |
805 int nc = cols (); | 805 |
806 int len = length (); | 806 int nr = rows (); |
807 int nc = cols (); | |
808 | |
807 if (nr != nc) | 809 if (nr != nc) |
808 { | 810 (*current_liboctave_error_handler) ("inverse requires square matrix"); |
809 (*current_liboctave_error_handler) ("inverse requires square matrix"); | |
810 return ComplexMatrix (); | |
811 } | |
812 | |
813 info = 0; | |
814 | |
815 int *ipvt = new int [nr]; | |
816 Complex *z = new Complex [nr]; | |
817 Complex *tmp_data = dup (data (), len); | |
818 | |
819 F77_FCN (zgeco, ZGECO) (tmp_data, nr, nc, ipvt, rcond, z); | |
820 | |
821 volatile double rcond_plus_one = rcond + 1.0; | |
822 | |
823 if (rcond_plus_one == 1.0) | |
824 info = -1; | |
825 | |
826 if (info == -1 && ! force) | |
827 { | |
828 copy (tmp_data, data (), len); // Restore contents. | |
829 } | |
830 else | 811 else |
831 { | 812 { |
832 Complex *dummy = 0; | 813 info = 0; |
833 | 814 |
834 F77_FCN (zgedi, ZGEDI) (tmp_data, nr, nc, ipvt, dummy, z, 1); | 815 Array<int> ipvt (nr); |
835 } | 816 int *pipvt = ipvt.fortran_vec (); |
836 | 817 |
837 delete [] ipvt; | 818 Array<Complex> z (nr); |
838 delete [] z; | 819 Complex *pz = z.fortran_vec (); |
839 | 820 |
840 return ComplexMatrix (tmp_data, nr, nc); | 821 retval = *this; |
822 Complex *tmp_data = retval.fortran_vec (); | |
823 | |
824 F77_XFCN (zgeco, ZGECO, (tmp_data, nr, nc, pipvt, rcond, pz)); | |
825 | |
826 if (f77_exception_encountered) | |
827 (*current_liboctave_error_handler) ("unrecoverable error in zgeco"); | |
828 else | |
829 { | |
830 volatile double rcond_plus_one = rcond + 1.0; | |
831 | |
832 if (rcond_plus_one == 1.0) | |
833 info = -1; | |
834 | |
835 if (info == -1 && ! force) | |
836 retval = *this; // Restore contents. | |
837 else | |
838 { | |
839 Complex *dummy = 0; | |
840 | |
841 F77_XFCN (zgedi, ZGEDI, (tmp_data, nr, nc, pipvt, dummy, | |
842 pz, 1)); | |
843 | |
844 if (f77_exception_encountered) | |
845 (*current_liboctave_error_handler) | |
846 ("unrecoverable error in zgedi"); | |
847 } | |
848 } | |
849 } | |
850 | |
851 return retval; | |
841 } | 852 } |
842 | 853 |
843 ComplexMatrix | 854 ComplexMatrix |
844 ComplexMatrix::pseudo_inverse (double tol) | 855 ComplexMatrix::pseudo_inverse (double tol) |
845 { | 856 { |
882 } | 893 } |
883 | 894 |
884 ComplexMatrix | 895 ComplexMatrix |
885 ComplexMatrix::fourier (void) const | 896 ComplexMatrix::fourier (void) const |
886 { | 897 { |
887 int nr = rows (); | 898 ComplexMatrix retval; |
888 int nc = cols (); | 899 |
900 int nr = rows (); | |
901 int nc = cols (); | |
902 | |
889 int npts, nsamples; | 903 int npts, nsamples; |
904 | |
890 if (nr == 1 || nc == 1) | 905 if (nr == 1 || nc == 1) |
891 { | 906 { |
892 npts = nr > nc ? nr : nc; | 907 npts = nr > nc ? nr : nc; |
893 nsamples = 1; | 908 nsamples = 1; |
894 } | 909 } |
897 npts = nr; | 912 npts = nr; |
898 nsamples = nc; | 913 nsamples = nc; |
899 } | 914 } |
900 | 915 |
901 int nn = 4*npts+15; | 916 int nn = 4*npts+15; |
902 Complex *wsave = new Complex [nn]; | 917 |
903 Complex *tmp_data = dup (data (), length ()); | 918 Array<Complex> wsave (nn); |
904 | 919 Complex *pwsave = wsave.fortran_vec (); |
905 F77_FCN (cffti, CFFTI) (npts, wsave); | 920 |
921 retval = *this; | |
922 Complex *tmp_data = retval.fortran_vec (); | |
923 | |
924 F77_FCN (cffti, CFFTI) (npts, pwsave); | |
906 | 925 |
907 for (int j = 0; j < nsamples; j++) | 926 for (int j = 0; j < nsamples; j++) |
908 F77_FCN (cfftf, CFFTF) (npts, &tmp_data[npts*j], wsave); | 927 F77_FCN (cfftf, CFFTF) (npts, &tmp_data[npts*j], pwsave); |
909 | 928 |
910 delete [] wsave; | 929 return retval; |
911 | |
912 return ComplexMatrix (tmp_data, nr, nc); | |
913 } | 930 } |
914 | 931 |
915 ComplexMatrix | 932 ComplexMatrix |
916 ComplexMatrix::ifourier (void) const | 933 ComplexMatrix::ifourier (void) const |
917 { | 934 { |
918 int nr = rows (); | 935 ComplexMatrix retval; |
919 int nc = cols (); | 936 |
937 int nr = rows (); | |
938 int nc = cols (); | |
939 | |
920 int npts, nsamples; | 940 int npts, nsamples; |
941 | |
921 if (nr == 1 || nc == 1) | 942 if (nr == 1 || nc == 1) |
922 { | 943 { |
923 npts = nr > nc ? nr : nc; | 944 npts = nr > nc ? nr : nc; |
924 nsamples = 1; | 945 nsamples = 1; |
925 } | 946 } |
928 npts = nr; | 949 npts = nr; |
929 nsamples = nc; | 950 nsamples = nc; |
930 } | 951 } |
931 | 952 |
932 int nn = 4*npts+15; | 953 int nn = 4*npts+15; |
933 Complex *wsave = new Complex [nn]; | 954 |
934 Complex *tmp_data = dup (data (), length ()); | 955 Array<Complex> wsave (nn); |
935 | 956 Complex *pwsave = wsave.fortran_vec (); |
936 F77_FCN (cffti, CFFTI) (npts, wsave); | 957 |
958 retval = *this; | |
959 Complex *tmp_data = retval.fortran_vec (); | |
960 | |
961 F77_FCN (cffti, CFFTI) (npts, pwsave); | |
937 | 962 |
938 for (int j = 0; j < nsamples; j++) | 963 for (int j = 0; j < nsamples; j++) |
939 F77_FCN (cfftb, CFFTB) (npts, &tmp_data[npts*j], wsave); | 964 F77_FCN (cfftb, CFFTB) (npts, &tmp_data[npts*j], pwsave); |
940 | 965 |
941 for (int j = 0; j < npts*nsamples; j++) | 966 for (int j = 0; j < npts*nsamples; j++) |
942 tmp_data[j] = tmp_data[j] / (double) npts; | 967 tmp_data[j] = tmp_data[j] / (double) npts; |
943 | 968 |
944 delete [] wsave; | 969 return retval; |
945 | |
946 return ComplexMatrix (tmp_data, nr, nc); | |
947 } | 970 } |
948 | 971 |
949 ComplexMatrix | 972 ComplexMatrix |
950 ComplexMatrix::fourier2d (void) const | 973 ComplexMatrix::fourier2d (void) const |
951 { | 974 { |
952 int nr = rows (); | 975 ComplexMatrix retval; |
953 int nc = cols (); | 976 |
977 int nr = rows (); | |
978 int nc = cols (); | |
979 | |
954 int npts, nsamples; | 980 int npts, nsamples; |
981 | |
955 if (nr == 1 || nc == 1) | 982 if (nr == 1 || nc == 1) |
956 { | 983 { |
957 npts = nr > nc ? nr : nc; | 984 npts = nr > nc ? nr : nc; |
958 nsamples = 1; | 985 nsamples = 1; |
959 } | 986 } |
962 npts = nr; | 989 npts = nr; |
963 nsamples = nc; | 990 nsamples = nc; |
964 } | 991 } |
965 | 992 |
966 int nn = 4*npts+15; | 993 int nn = 4*npts+15; |
967 Complex *wsave = new Complex [nn]; | 994 |
968 Complex *tmp_data = dup (data (), length ()); | 995 Array<Complex> wsave (nn); |
969 | 996 Complex *pwsave = wsave.fortran_vec (); |
970 F77_FCN (cffti, CFFTI) (npts, wsave); | 997 |
998 retval = *this; | |
999 Complex *tmp_data = retval.fortran_vec (); | |
1000 | |
1001 F77_FCN (cffti, CFFTI) (npts, pwsave); | |
971 | 1002 |
972 for (int j = 0; j < nsamples; j++) | 1003 for (int j = 0; j < nsamples; j++) |
973 F77_FCN (cfftf, CFFTF) (npts, &tmp_data[npts*j], wsave); | 1004 F77_FCN (cfftf, CFFTF) (npts, &tmp_data[npts*j], pwsave); |
974 | |
975 delete [] wsave; | |
976 | 1005 |
977 npts = nc; | 1006 npts = nc; |
978 nsamples = nr; | 1007 nsamples = nr; |
979 nn = 4*npts+15; | 1008 nn = 4*npts+15; |
980 wsave = new Complex [nn]; | 1009 |
981 Complex *row = new Complex[npts]; | 1010 wsave.resize (nn); |
982 | 1011 pwsave = wsave.fortran_vec (); |
983 F77_FCN (cffti, CFFTI) (npts, wsave); | 1012 |
1013 Array<Complex> row (npts); | |
1014 Complex *prow = row.fortran_vec (); | |
1015 | |
1016 F77_FCN (cffti, CFFTI) (npts, pwsave); | |
984 | 1017 |
985 for (int j = 0; j < nsamples; j++) | 1018 for (int j = 0; j < nsamples; j++) |
986 { | 1019 { |
987 for (int i = 0; i < npts; i++) | 1020 for (int i = 0; i < npts; i++) |
988 row[i] = tmp_data[i*nr + j]; | 1021 prow[i] = tmp_data[i*nr + j]; |
989 | 1022 |
990 F77_FCN (cfftf, CFFTF) (npts, row, wsave); | 1023 F77_FCN (cfftf, CFFTF) (npts, prow, pwsave); |
991 | 1024 |
992 for (int i = 0; i < npts; i++) | 1025 for (int i = 0; i < npts; i++) |
993 tmp_data[i*nr + j] = row[i]; | 1026 tmp_data[i*nr + j] = prow[i]; |
994 } | 1027 } |
995 | 1028 |
996 delete [] wsave; | 1029 return retval; |
997 delete [] row; | |
998 | |
999 return ComplexMatrix (tmp_data, nr, nc); | |
1000 } | 1030 } |
1001 | 1031 |
1002 ComplexMatrix | 1032 ComplexMatrix |
1003 ComplexMatrix::ifourier2d (void) const | 1033 ComplexMatrix::ifourier2d (void) const |
1004 { | 1034 { |
1005 int nr = rows (); | 1035 ComplexMatrix retval; |
1006 int nc = cols (); | 1036 |
1037 int nr = rows (); | |
1038 int nc = cols (); | |
1039 | |
1007 int npts, nsamples; | 1040 int npts, nsamples; |
1041 | |
1008 if (nr == 1 || nc == 1) | 1042 if (nr == 1 || nc == 1) |
1009 { | 1043 { |
1010 npts = nr > nc ? nr : nc; | 1044 npts = nr > nc ? nr : nc; |
1011 nsamples = 1; | 1045 nsamples = 1; |
1012 } | 1046 } |
1015 npts = nr; | 1049 npts = nr; |
1016 nsamples = nc; | 1050 nsamples = nc; |
1017 } | 1051 } |
1018 | 1052 |
1019 int nn = 4*npts+15; | 1053 int nn = 4*npts+15; |
1020 Complex *wsave = new Complex [nn]; | 1054 |
1021 Complex *tmp_data = dup (data (), length ()); | 1055 Array<Complex> wsave (nn); |
1022 | 1056 Complex *pwsave = wsave.fortran_vec (); |
1023 F77_FCN (cffti, CFFTI) (npts, wsave); | 1057 |
1058 retval = *this; | |
1059 Complex *tmp_data = retval.fortran_vec (); | |
1060 | |
1061 F77_FCN (cffti, CFFTI) (npts, pwsave); | |
1024 | 1062 |
1025 for (int j = 0; j < nsamples; j++) | 1063 for (int j = 0; j < nsamples; j++) |
1026 F77_FCN (cfftb, CFFTB) (npts, &tmp_data[npts*j], wsave); | 1064 F77_FCN (cfftb, CFFTB) (npts, &tmp_data[npts*j], pwsave); |
1027 | |
1028 delete [] wsave; | |
1029 | 1065 |
1030 for (int j = 0; j < npts*nsamples; j++) | 1066 for (int j = 0; j < npts*nsamples; j++) |
1031 tmp_data[j] = tmp_data[j] / (double) npts; | 1067 tmp_data[j] = tmp_data[j] / (double) npts; |
1032 | 1068 |
1033 npts = nc; | 1069 npts = nc; |
1034 nsamples = nr; | 1070 nsamples = nr; |
1035 nn = 4*npts+15; | 1071 nn = 4*npts+15; |
1036 wsave = new Complex [nn]; | 1072 |
1037 Complex *row = new Complex[npts]; | 1073 wsave.resize (nn); |
1038 | 1074 pwsave = wsave.fortran_vec (); |
1039 F77_FCN (cffti, CFFTI) (npts, wsave); | 1075 |
1076 Array<Complex> row (npts); | |
1077 Complex *prow = row.fortran_vec (); | |
1078 | |
1079 F77_FCN (cffti, CFFTI) (npts, pwsave); | |
1040 | 1080 |
1041 for (int j = 0; j < nsamples; j++) | 1081 for (int j = 0; j < nsamples; j++) |
1042 { | 1082 { |
1043 for (int i = 0; i < npts; i++) | 1083 for (int i = 0; i < npts; i++) |
1044 row[i] = tmp_data[i*nr + j]; | 1084 prow[i] = tmp_data[i*nr + j]; |
1045 | 1085 |
1046 F77_FCN (cfftb, CFFTB) (npts, row, wsave); | 1086 F77_FCN (cfftb, CFFTB) (npts, prow, pwsave); |
1047 | 1087 |
1048 for (int i = 0; i < npts; i++) | 1088 for (int i = 0; i < npts; i++) |
1049 tmp_data[i*nr + j] = row[i] / (double) npts; | 1089 tmp_data[i*nr + j] = prow[i] / (double) npts; |
1050 } | 1090 } |
1051 | 1091 |
1052 delete [] wsave; | 1092 return retval; |
1053 delete [] row; | |
1054 | |
1055 return ComplexMatrix (tmp_data, nr, nc); | |
1056 } | 1093 } |
1057 | 1094 |
1058 ComplexDET | 1095 ComplexDET |
1059 ComplexMatrix::determinant (void) const | 1096 ComplexMatrix::determinant (void) const |
1060 { | 1097 { |
1086 retval = ComplexDET (d); | 1123 retval = ComplexDET (d); |
1087 } | 1124 } |
1088 else | 1125 else |
1089 { | 1126 { |
1090 info = 0; | 1127 info = 0; |
1091 int *ipvt = new int [nr]; | 1128 |
1092 | 1129 Array<int> ipvt (nr); |
1093 Complex *z = new Complex [nr]; | 1130 int *pipvt = ipvt.fortran_vec (); |
1094 Complex *tmp_data = dup (data (), length ()); | 1131 |
1095 | 1132 Array<Complex> z (nr); |
1096 F77_FCN (zgeco, ZGECO) (tmp_data, nr, nr, ipvt, rcond, z); | 1133 Complex *pz = z.fortran_vec (); |
1097 | 1134 |
1098 volatile double rcond_plus_one = rcond + 1.0; | 1135 ComplexMatrix atmp = *this; |
1099 if (rcond_plus_one == 1.0) | 1136 Complex *tmp_data = atmp.fortran_vec (); |
1100 { | 1137 |
1101 info = -1; | 1138 F77_XFCN (zgeco, ZGECO, (tmp_data, nr, nr, pipvt, rcond, pz)); |
1102 retval = ComplexDET (); | 1139 |
1103 } | 1140 if (f77_exception_encountered) |
1141 (*current_liboctave_error_handler) ("unrecoverable error in zgeco"); | |
1104 else | 1142 else |
1105 { | 1143 { |
1106 Complex d[2]; | 1144 volatile double rcond_plus_one = rcond + 1.0; |
1107 F77_FCN (zgedi, ZGEDI) (tmp_data, nr, nr, ipvt, d, z, 10); | 1145 |
1108 retval = ComplexDET (d); | 1146 if (rcond_plus_one == 1.0) |
1109 } | 1147 { |
1110 | 1148 info = -1; |
1111 delete [] tmp_data; | 1149 retval = ComplexDET (); |
1112 delete [] ipvt; | 1150 } |
1113 delete [] z; | 1151 else |
1152 { | |
1153 Complex d[2]; | |
1154 | |
1155 F77_XFCN (zgedi, ZGEDI, (tmp_data, nr, nr, pipvt, d, pz, 10)); | |
1156 | |
1157 if (f77_exception_encountered) | |
1158 (*current_liboctave_error_handler) | |
1159 ("unrecoverable error in dgedi"); | |
1160 else | |
1161 retval = ComplexDET (d); | |
1162 } | |
1163 } | |
1114 } | 1164 } |
1115 | 1165 |
1116 return retval; | 1166 return retval; |
1117 } | 1167 } |
1118 | 1168 |
1157 { | 1207 { |
1158 ComplexMatrix retval; | 1208 ComplexMatrix retval; |
1159 | 1209 |
1160 int nr = rows (); | 1210 int nr = rows (); |
1161 int nc = cols (); | 1211 int nc = cols (); |
1162 int b_nr = b.rows (); | 1212 |
1163 int b_nc = b.cols (); | 1213 if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) |
1164 if (nr == 0 || nc == 0 || nr != nc || nr != b_nr) | 1214 (*current_liboctave_error_handler) |
1165 { | 1215 ("matrix dimension mismatch in solution of linear equations"); |
1166 (*current_liboctave_error_handler) | |
1167 ("matrix dimension mismatch in solution of linear equations"); | |
1168 return ComplexMatrix (); | |
1169 } | |
1170 | |
1171 info = 0; | |
1172 int *ipvt = new int [nr]; | |
1173 | |
1174 Complex *z = new Complex [nr]; | |
1175 Complex *tmp_data = dup (data (), length ()); | |
1176 | |
1177 F77_FCN (zgeco, ZGECO) (tmp_data, nr, nr, ipvt, rcond, z); | |
1178 | |
1179 volatile double rcond_plus_one = rcond + 1.0; | |
1180 if (rcond_plus_one == 1.0) | |
1181 { | |
1182 info = -2; | |
1183 } | |
1184 else | 1216 else |
1185 { | 1217 { |
1186 Complex *result = dup (b.data (), b.length ()); | 1218 info = 0; |
1187 | 1219 |
1188 for (int j = 0; j < b_nc; j++) | 1220 Array<int> ipvt (nr); |
1189 F77_FCN (zgesl, ZGESL) (tmp_data, nr, nr, ipvt, &result[nr*j], 0); | 1221 int *pipvt = ipvt.fortran_vec (); |
1190 | 1222 |
1191 retval = ComplexMatrix (result, b_nr, b_nc); | 1223 Array<Complex> z (nr); |
1192 } | 1224 Complex *pz = z.fortran_vec (); |
1193 | 1225 |
1194 delete [] tmp_data; | 1226 ComplexMatrix atmp = *this; |
1195 delete [] ipvt; | 1227 Complex *tmp_data = atmp.fortran_vec (); |
1196 delete [] z; | 1228 |
1229 F77_XFCN (zgeco, ZGECO, (tmp_data, nr, nr, pipvt, rcond, pz)); | |
1230 | |
1231 if (f77_exception_encountered) | |
1232 (*current_liboctave_error_handler) ("unrecoverable error in zgeco"); | |
1233 else | |
1234 { | |
1235 volatile double rcond_plus_one = rcond + 1.0; | |
1236 | |
1237 if (rcond_plus_one == 1.0) | |
1238 { | |
1239 info = -2; | |
1240 } | |
1241 else | |
1242 { | |
1243 retval = b; | |
1244 Complex *result = retval.fortran_vec (); | |
1245 | |
1246 int b_nc = b.cols (); | |
1247 | |
1248 for (volatile int j = 0; j < b_nc; j++) | |
1249 { | |
1250 F77_XFCN (zgesl, ZGESL, (tmp_data, nr, nr, pipvt, | |
1251 &result[nr*j], 0)); | |
1252 | |
1253 if (f77_exception_encountered) | |
1254 { | |
1255 (*current_liboctave_error_handler) | |
1256 ("unrecoverable error in dgesl"); | |
1257 | |
1258 break; | |
1259 } | |
1260 } | |
1261 } | |
1262 } | |
1263 } | |
1197 | 1264 |
1198 return retval; | 1265 return retval; |
1199 } | 1266 } |
1200 | 1267 |
1201 ComplexColumnVector | 1268 ComplexColumnVector |
1219 { | 1286 { |
1220 ComplexColumnVector retval; | 1287 ComplexColumnVector retval; |
1221 | 1288 |
1222 int nr = rows (); | 1289 int nr = rows (); |
1223 int nc = cols (); | 1290 int nc = cols (); |
1224 int b_len = b.length (); | 1291 |
1225 if (nr == 0 || nc == 0 || nr != nc || nr != b_len) | 1292 if (nr == 0 || nc == 0 || nr != nc || nr != b.length ()) |
1226 { | 1293 (*current_liboctave_error_handler) |
1227 (*current_liboctave_error_handler) | 1294 ("matrix dimension mismatch in solution of linear equations"); |
1228 ("matrix dimension mismatch in solution of linear equations"); | |
1229 return ComplexColumnVector (); | |
1230 } | |
1231 | |
1232 info = 0; | |
1233 int *ipvt = new int [nr]; | |
1234 | |
1235 Complex *z = new Complex [nr]; | |
1236 Complex *tmp_data = dup (data (), length ()); | |
1237 | |
1238 F77_FCN (zgeco, ZGECO) (tmp_data, nr, nr, ipvt, rcond, z); | |
1239 | |
1240 volatile double rcond_plus_one = rcond + 1.0; | |
1241 if (rcond_plus_one == 1.0) | |
1242 { | |
1243 info = -2; | |
1244 } | |
1245 else | 1295 else |
1246 { | 1296 { |
1247 Complex *result = dup (b.data (), b_len); | 1297 info = 0; |
1248 | 1298 |
1249 F77_FCN (zgesl, ZGESL) (tmp_data, nr, nr, ipvt, result, 0); | 1299 Array<int> ipvt (nr); |
1250 | 1300 int *pipvt = ipvt.fortran_vec (); |
1251 retval = ComplexColumnVector (result, b_len); | 1301 |
1252 } | 1302 Array<Complex> z (nr); |
1253 | 1303 Complex *pz = z.fortran_vec (); |
1254 delete [] tmp_data; | 1304 |
1255 delete [] ipvt; | 1305 ComplexMatrix atmp = *this; |
1256 delete [] z; | 1306 Complex *tmp_data = atmp.fortran_vec (); |
1307 | |
1308 F77_XFCN (zgeco, ZGECO, (tmp_data, nr, nr, pipvt, rcond, pz)); | |
1309 | |
1310 if (f77_exception_encountered) | |
1311 (*current_liboctave_error_handler) | |
1312 ("unrecoverable error in dgeco"); | |
1313 else | |
1314 { | |
1315 volatile double rcond_plus_one = rcond + 1.0; | |
1316 | |
1317 if (rcond_plus_one == 1.0) | |
1318 { | |
1319 info = -2; | |
1320 } | |
1321 else | |
1322 { | |
1323 retval = b; | |
1324 Complex *result = retval.fortran_vec (); | |
1325 | |
1326 F77_XFCN (zgesl, ZGESL, (tmp_data, nr, nr, pipvt, result, 0)); | |
1327 | |
1328 if (f77_exception_encountered) | |
1329 (*current_liboctave_error_handler) | |
1330 ("unrecoverable error in dgesl"); | |
1331 } | |
1332 } | |
1333 } | |
1257 | 1334 |
1258 return retval; | 1335 return retval; |
1259 } | 1336 } |
1260 | 1337 |
1261 ComplexMatrix | 1338 ComplexMatrix |
1274 } | 1351 } |
1275 | 1352 |
1276 ComplexMatrix | 1353 ComplexMatrix |
1277 ComplexMatrix::lssolve (const ComplexMatrix& b, int& info, int& rank) const | 1354 ComplexMatrix::lssolve (const ComplexMatrix& b, int& info, int& rank) const |
1278 { | 1355 { |
1356 ComplexMatrix retval; | |
1357 | |
1279 int nrhs = b.cols (); | 1358 int nrhs = b.cols (); |
1280 | 1359 |
1281 int m = rows (); | 1360 int m = rows (); |
1282 int n = cols (); | 1361 int n = cols (); |
1283 | 1362 |
1284 if (m == 0 || n == 0 || m != b.rows ()) | 1363 if (m == 0 || n == 0 || m != b.rows ()) |
1285 { | 1364 (*current_liboctave_error_handler) |
1286 (*current_liboctave_error_handler) | 1365 ("matrix dimension mismatch solution of linear equations"); |
1287 ("matrix dimension mismatch solution of linear equations"); | |
1288 return Matrix (); | |
1289 } | |
1290 | |
1291 Complex *tmp_data = dup (data (), length ()); | |
1292 | |
1293 int nrr = m > n ? m : n; | |
1294 ComplexMatrix result (nrr, nrhs); | |
1295 | |
1296 for (int j = 0; j < nrhs; j++) | |
1297 for (int i = 0; i < m; i++) | |
1298 result.elem (i, j) = b.elem (i, j); | |
1299 | |
1300 Complex *presult = result.fortran_vec (); | |
1301 | |
1302 int len_s = m < n ? m : n; | |
1303 double *s = new double [len_s]; | |
1304 double rcond = -1.0; | |
1305 int lwork; | |
1306 if (m < n) | |
1307 lwork = 2*m + (nrhs > n ? nrhs : n); | |
1308 else | 1366 else |
1309 lwork = 2*n + (nrhs > m ? nrhs : m); | 1367 { |
1310 | 1368 ComplexMatrix atmp = *this; |
1311 Complex *work = new Complex [lwork]; | 1369 Complex *tmp_data = atmp.fortran_vec (); |
1312 | 1370 |
1313 int lrwork = (5 * (m < n ? m : n)) - 4; | 1371 int nrr = m > n ? m : n; |
1314 lrwork = lrwork > 1 ? lrwork : 1; | 1372 ComplexMatrix result (nrr, nrhs); |
1315 double *rwork = new double [lrwork]; | 1373 |
1316 | 1374 for (int j = 0; j < nrhs; j++) |
1317 F77_FCN (zgelss, ZGELSS) (m, n, nrhs, tmp_data, m, presult, nrr, s, | 1375 for (int i = 0; i < m; i++) |
1318 rcond, rank, work, lwork, rwork, info); | 1376 result.elem (i, j) = b.elem (i, j); |
1319 | 1377 |
1320 ComplexMatrix retval (n, nrhs); | 1378 Complex *presult = result.fortran_vec (); |
1321 for (int j = 0; j < nrhs; j++) | 1379 |
1322 for (int i = 0; i < n; i++) | 1380 int len_s = m < n ? m : n; |
1323 retval.elem (i, j) = result.elem (i, j); | 1381 Array<double> s (len_s); |
1324 | 1382 double *ps = s.fortran_vec (); |
1325 delete [] tmp_data; | 1383 double rcond = -1.0; |
1326 delete [] s; | 1384 int lwork; |
1327 delete [] work; | 1385 if (m < n) |
1328 delete [] rwork; | 1386 lwork = 2*m + (nrhs > n ? nrhs : n); |
1387 else | |
1388 lwork = 2*n + (nrhs > m ? nrhs : m); | |
1389 | |
1390 Array<Complex> work (lwork); | |
1391 Complex *pwork = work.fortran_vec (); | |
1392 | |
1393 int lrwork = (5 * (m < n ? m : n)) - 4; | |
1394 lrwork = lrwork > 1 ? lrwork : 1; | |
1395 Array<double> rwork (lrwork); | |
1396 double *prwork = rwork.fortran_vec (); | |
1397 | |
1398 F77_XFCN (zgelss, ZGELSS, (m, n, nrhs, tmp_data, m, presult, | |
1399 nrr, ps, rcond, rank, pwork, lwork, | |
1400 prwork, info)); | |
1401 | |
1402 if (f77_exception_encountered) | |
1403 (*current_liboctave_error_handler) ("unrecoverable error in zgelss"); | |
1404 else | |
1405 { | |
1406 ComplexMatrix retval (n, nrhs); | |
1407 for (int j = 0; j < nrhs; j++) | |
1408 for (int i = 0; i < n; i++) | |
1409 retval.elem (i, j) = result.elem (i, j); | |
1410 } | |
1411 } | |
1329 | 1412 |
1330 return retval; | 1413 return retval; |
1331 } | 1414 } |
1332 | 1415 |
1333 ComplexColumnVector | 1416 ComplexColumnVector |
1347 | 1430 |
1348 ComplexColumnVector | 1431 ComplexColumnVector |
1349 ComplexMatrix::lssolve (const ComplexColumnVector& b, int& info, | 1432 ComplexMatrix::lssolve (const ComplexColumnVector& b, int& info, |
1350 int& rank) const | 1433 int& rank) const |
1351 { | 1434 { |
1435 ComplexColumnVector retval; | |
1436 | |
1352 int nrhs = 1; | 1437 int nrhs = 1; |
1353 | 1438 |
1354 int m = rows (); | 1439 int m = rows (); |
1355 int n = cols (); | 1440 int n = cols (); |
1356 | 1441 |
1357 if (m == 0 || n == 0 || m != b.length ()) | 1442 if (m == 0 || n == 0 || m != b.length ()) |
1358 { | 1443 (*current_liboctave_error_handler) |
1359 (*current_liboctave_error_handler) | 1444 ("matrix dimension mismatch solution of least squares problem"); |
1360 ("matrix dimension mismatch solution of least squares problem"); | |
1361 return ComplexColumnVector (); | |
1362 } | |
1363 | |
1364 Complex *tmp_data = dup (data (), length ()); | |
1365 | |
1366 int nrr = m > n ? m : n; | |
1367 ComplexColumnVector result (nrr); | |
1368 | |
1369 for (int i = 0; i < m; i++) | |
1370 result.elem (i) = b.elem (i); | |
1371 | |
1372 Complex *presult = result.fortran_vec (); | |
1373 | |
1374 int len_s = m < n ? m : n; | |
1375 double *s = new double [len_s]; | |
1376 double rcond = -1.0; | |
1377 int lwork; | |
1378 if (m < n) | |
1379 lwork = 2*m + (nrhs > n ? nrhs : n); | |
1380 else | 1445 else |
1381 lwork = 2*n + (nrhs > m ? nrhs : m); | 1446 { |
1382 | 1447 ComplexMatrix atmp = *this; |
1383 Complex *work = new Complex [lwork]; | 1448 Complex *tmp_data = atmp.fortran_vec (); |
1384 | 1449 |
1385 int lrwork = (5 * (m < n ? m : n)) - 4; | 1450 int nrr = m > n ? m : n; |
1386 lrwork = lrwork > 1 ? lrwork : 1; | 1451 ComplexColumnVector result (nrr); |
1387 double *rwork = new double [lrwork]; | 1452 |
1388 | 1453 for (int i = 0; i < m; i++) |
1389 F77_FCN (zgelss, ZGELSS) (m, n, nrhs, tmp_data, m, presult, nrr, s, | 1454 result.elem (i) = b.elem (i); |
1390 rcond, rank, work, lwork, rwork, info); | 1455 |
1391 | 1456 Complex *presult = result.fortran_vec (); |
1392 ComplexColumnVector retval (n); | 1457 |
1393 for (int i = 0; i < n; i++) | 1458 int len_s = m < n ? m : n; |
1394 retval.elem (i) = result.elem (i); | 1459 Array<double> s (len_s); |
1395 | 1460 double *ps = s.fortran_vec (); |
1396 delete [] tmp_data; | 1461 |
1397 delete [] s; | 1462 double rcond = -1.0; |
1398 delete [] work; | 1463 |
1399 delete [] rwork; | 1464 int lwork; |
1465 if (m < n) | |
1466 lwork = 2*m + (nrhs > n ? nrhs : n); | |
1467 else | |
1468 lwork = 2*n + (nrhs > m ? nrhs : m); | |
1469 | |
1470 Array<Complex> work (lwork); | |
1471 Complex *pwork = work.fortran_vec (); | |
1472 | |
1473 int lrwork = (5 * (m < n ? m : n)) - 4; | |
1474 lrwork = lrwork > 1 ? lrwork : 1; | |
1475 Array<double> rwork (lrwork); | |
1476 double *prwork = rwork.fortran_vec (); | |
1477 | |
1478 F77_XFCN (zgelss, ZGELSS, (m, n, nrhs, tmp_data, m, presult, | |
1479 nrr, ps, rcond, rank, pwork, lwork, | |
1480 prwork, info)); | |
1481 | |
1482 if (f77_exception_encountered) | |
1483 (*current_liboctave_error_handler) ("unrecoverable error in zgelss"); | |
1484 else | |
1485 { | |
1486 ComplexColumnVector retval (n); | |
1487 for (int i = 0; i < n; i++) | |
1488 retval.elem (i) = result.elem (i); | |
1489 } | |
1490 } | |
1400 | 1491 |
1401 return retval; | 1492 return retval; |
1402 } | 1493 } |
1403 | 1494 |
1404 // Constants for matrix exponential calculation. | 1495 // Constants for matrix exponential calculation. |
1536 } | 1627 } |
1537 | 1628 |
1538 ComplexMatrix | 1629 ComplexMatrix |
1539 operator * (const ComplexColumnVector& v, const ComplexRowVector& a) | 1630 operator * (const ComplexColumnVector& v, const ComplexRowVector& a) |
1540 { | 1631 { |
1632 ComplexMatrix retval; | |
1633 | |
1541 int len = v.length (); | 1634 int len = v.length (); |
1542 int a_len = a.length (); | 1635 int a_len = a.length (); |
1636 | |
1543 if (len != a_len) | 1637 if (len != a_len) |
1544 { | 1638 (*current_liboctave_error_handler) |
1545 (*current_liboctave_error_handler) | 1639 ("nonconformant vector multiplication attempted"); |
1546 ("nonconformant vector multiplication attempted"); | 1640 else |
1547 return ComplexMatrix (); | 1641 { |
1548 } | 1642 if (len != 0) |
1549 | 1643 { |
1550 if (len == 0) | 1644 retval.resize (len, a_len); |
1551 return ComplexMatrix (len, len, 0.0); | 1645 Complex *c = retval.fortran_vec (); |
1552 | 1646 |
1553 Complex *c = new Complex [len * a_len]; | 1647 F77_XFCN (zgemm, ZGEMM, ("N", "N", len, a_len, 1, 1.0, |
1554 | 1648 v.data (), len, a.data (), 1, 0.0, |
1555 F77_FCN (zgemm, ZGEMM) ("N", "N", len, a_len, 1, 1.0, v.data (), | 1649 c, len, 1L, 1L)); |
1556 len, a.data (), 1, 0.0, c, len, 1L, 1L); | 1650 |
1557 | 1651 if (f77_exception_encountered) |
1558 return ComplexMatrix (c, len, a_len); | 1652 (*current_liboctave_error_handler) |
1653 ("unrecoverable error in zgemm"); | |
1654 } | |
1655 } | |
1656 | |
1657 return retval; | |
1559 } | 1658 } |
1560 | 1659 |
1561 // diagonal matrix by scalar -> matrix operations | 1660 // diagonal matrix by scalar -> matrix operations |
1562 | 1661 |
1563 ComplexMatrix | 1662 ComplexMatrix |
1764 return result; | 1863 return result; |
1765 } | 1864 } |
1766 | 1865 |
1767 ComplexMatrix | 1866 ComplexMatrix |
1768 operator * (const Matrix& m, const ComplexDiagMatrix& a) | 1867 operator * (const Matrix& m, const ComplexDiagMatrix& a) |
1868 { | |
1869 ComplexMatrix retval; | |
1870 | |
1871 int nr = m.rows (); | |
1872 int nc = m.cols (); | |
1873 | |
1874 int a_nr = a.rows (); | |
1875 int a_nc = a.cols (); | |
1876 | |
1877 if (nc != a_nr) | |
1878 (*current_liboctave_error_handler) | |
1879 ("nonconformant matrix multiplication attempted"); | |
1880 else | |
1881 { | |
1882 if (nr == 0 || nc == 0 || a_nc == 0) | |
1883 retval.resize (nr, a_nc, 0.0); | |
1884 else | |
1885 { | |
1886 retval.resize (nr, a_nc); | |
1887 Complex *c = retval.fortran_vec (); | |
1888 | |
1889 Complex *ctmp = 0; | |
1890 | |
1891 for (int j = 0; j < a.length (); j++) | |
1892 { | |
1893 int idx = j * nr; | |
1894 ctmp = c + idx; | |
1895 if (a.elem (j, j) == 1.0) | |
1896 { | |
1897 for (int i = 0; i < nr; i++) | |
1898 ctmp[i] = m.elem (i, j); | |
1899 } | |
1900 else if (a.elem (j, j) == 0.0) | |
1901 { | |
1902 for (int i = 0; i < nr; i++) | |
1903 ctmp[i] = 0.0; | |
1904 } | |
1905 else | |
1906 { | |
1907 for (int i = 0; i < nr; i++) | |
1908 ctmp[i] = a.elem (j, j) * m.elem (i, j); | |
1909 } | |
1910 } | |
1911 | |
1912 if (a_nr < a_nc) | |
1913 { | |
1914 for (int i = nr * nc; i < nr * a_nc; i++) | |
1915 ctmp[i] = 0.0; | |
1916 } | |
1917 } | |
1918 } | |
1919 | |
1920 return retval; | |
1921 } | |
1922 | |
1923 // diagonal matrix by matrix -> matrix operations | |
1924 | |
1925 ComplexMatrix | |
1926 operator + (const DiagMatrix& m, const ComplexMatrix& a) | |
1927 { | |
1928 int nr = m.rows (); | |
1929 int nc = m.cols (); | |
1930 if (nr != a.rows () || nc != a.cols ()) | |
1931 { | |
1932 (*current_liboctave_error_handler) | |
1933 ("nonconformant matrix addition attempted"); | |
1934 return ComplexMatrix (); | |
1935 } | |
1936 | |
1937 if (nr == 0 || nc == 0) | |
1938 return ComplexMatrix (nr, nc); | |
1939 | |
1940 ComplexMatrix result (a); | |
1941 for (int i = 0; i < m.length (); i++) | |
1942 result.elem (i, i) += m.elem (i, i); | |
1943 | |
1944 return result; | |
1945 } | |
1946 | |
1947 ComplexMatrix | |
1948 operator - (const DiagMatrix& m, const ComplexMatrix& a) | |
1949 { | |
1950 int nr = m.rows (); | |
1951 int nc = m.cols (); | |
1952 if (nr != a.rows () || nc != a.cols ()) | |
1953 { | |
1954 (*current_liboctave_error_handler) | |
1955 ("nonconformant matrix subtraction attempted"); | |
1956 return ComplexMatrix (); | |
1957 } | |
1958 | |
1959 if (nr == 0 || nc == 0) | |
1960 return ComplexMatrix (nr, nc); | |
1961 | |
1962 ComplexMatrix result (-a); | |
1963 for (int i = 0; i < m.length (); i++) | |
1964 result.elem (i, i) += m.elem (i, i); | |
1965 | |
1966 return result; | |
1967 } | |
1968 | |
1969 ComplexMatrix | |
1970 operator * (const DiagMatrix& m, const ComplexMatrix& a) | |
1769 { | 1971 { |
1770 int nr = m.rows (); | 1972 int nr = m.rows (); |
1771 int nc = m.cols (); | 1973 int nc = m.cols (); |
1772 int a_nr = a.rows (); | 1974 int a_nr = a.rows (); |
1773 int a_nc = a.cols (); | 1975 int a_nc = a.cols (); |
1777 ("nonconformant matrix multiplication attempted"); | 1979 ("nonconformant matrix multiplication attempted"); |
1778 return ComplexMatrix (); | 1980 return ComplexMatrix (); |
1779 } | 1981 } |
1780 | 1982 |
1781 if (nr == 0 || nc == 0 || a_nc == 0) | 1983 if (nr == 0 || nc == 0 || a_nc == 0) |
1782 return ComplexMatrix (nr, a_nc, 0.0); | 1984 return ComplexMatrix (nr, nc, 0.0); |
1783 | 1985 |
1784 Complex *c = new Complex [nr*a_nc]; | 1986 ComplexMatrix c (nr, a_nc); |
1785 Complex *ctmp = 0; | 1987 |
1786 | 1988 for (int i = 0; i < m.length (); i++) |
1787 for (int j = 0; j < a.length (); j++) | 1989 { |
1788 { | 1990 if (m.elem (i, i) == 1.0) |
1789 int idx = j * nr; | 1991 { |
1790 ctmp = c + idx; | 1992 for (int j = 0; j < a_nc; j++) |
1791 if (a.elem (j, j) == 1.0) | 1993 c.elem (i, j) = a.elem (i, j); |
1792 { | 1994 } |
1793 for (int i = 0; i < nr; i++) | 1995 else if (m.elem (i, i) == 0.0) |
1794 ctmp[i] = m.elem (i, j); | 1996 { |
1795 } | 1997 for (int j = 0; j < a_nc; j++) |
1796 else if (a.elem (j, j) == 0.0) | 1998 c.elem (i, j) = 0.0; |
1797 { | |
1798 for (int i = 0; i < nr; i++) | |
1799 ctmp[i] = 0.0; | |
1800 } | 1999 } |
1801 else | 2000 else |
1802 { | 2001 { |
1803 for (int i = 0; i < nr; i++) | 2002 for (int j = 0; j < a_nc; j++) |
1804 ctmp[i] = a.elem (j, j) * m.elem (i, j); | 2003 c.elem (i, j) = m.elem (i, i) * a.elem (i, j); |
1805 } | 2004 } |
1806 } | 2005 } |
1807 | 2006 |
1808 if (a_nr < a_nc) | 2007 if (nr > nc) |
1809 { | 2008 { |
1810 for (int i = nr * nc; i < nr * a_nc; i++) | 2009 for (int j = 0; j < a_nc; j++) |
1811 ctmp[i] = 0.0; | 2010 for (int i = a_nr; i < nr; i++) |
1812 } | 2011 c.elem (i, j) = 0.0; |
1813 | 2012 } |
1814 return ComplexMatrix (c, nr, a_nc); | 2013 |
1815 } | 2014 return c; |
1816 | 2015 } |
1817 // diagonal matrix by matrix -> matrix operations | 2016 |
1818 | 2017 ComplexMatrix |
1819 ComplexMatrix | 2018 operator + (const ComplexDiagMatrix& m, const Matrix& a) |
1820 operator + (const DiagMatrix& m, const ComplexMatrix& a) | |
1821 { | 2019 { |
1822 int nr = m.rows (); | 2020 int nr = m.rows (); |
1823 int nc = m.cols (); | 2021 int nc = m.cols (); |
1824 if (nr != a.rows () || nc != a.cols ()) | 2022 if (nr != a.rows () || nc != a.cols ()) |
1825 { | 2023 { |
1837 | 2035 |
1838 return result; | 2036 return result; |
1839 } | 2037 } |
1840 | 2038 |
1841 ComplexMatrix | 2039 ComplexMatrix |
1842 operator - (const DiagMatrix& m, const ComplexMatrix& a) | 2040 operator - (const ComplexDiagMatrix& m, const Matrix& a) |
1843 { | 2041 { |
1844 int nr = m.rows (); | 2042 int nr = m.rows (); |
1845 int nc = m.cols (); | 2043 int nc = m.cols (); |
1846 if (nr != a.rows () || nc != a.cols ()) | 2044 if (nr != a.rows () || nc != a.cols ()) |
1847 { | 2045 { |
1859 | 2057 |
1860 return result; | 2058 return result; |
1861 } | 2059 } |
1862 | 2060 |
1863 ComplexMatrix | 2061 ComplexMatrix |
1864 operator * (const DiagMatrix& m, const ComplexMatrix& a) | 2062 operator * (const ComplexDiagMatrix& m, const Matrix& a) |
1865 { | 2063 { |
1866 int nr = m.rows (); | 2064 int nr = m.rows (); |
1867 int nc = m.cols (); | 2065 int nc = m.cols (); |
1868 int a_nr = a.rows (); | 2066 int a_nr = a.rows (); |
1869 int a_nc = a.cols (); | 2067 int a_nc = a.cols (); |
1873 ("nonconformant matrix multiplication attempted"); | 2071 ("nonconformant matrix multiplication attempted"); |
1874 return ComplexMatrix (); | 2072 return ComplexMatrix (); |
1875 } | 2073 } |
1876 | 2074 |
1877 if (nr == 0 || nc == 0 || a_nc == 0) | 2075 if (nr == 0 || nc == 0 || a_nc == 0) |
1878 return ComplexMatrix (nr, nc, 0.0); | 2076 return ComplexMatrix (nr, a_nc, 0.0); |
1879 | 2077 |
1880 ComplexMatrix c (nr, a_nc); | 2078 ComplexMatrix c (nr, a_nc); |
1881 | 2079 |
1882 for (int i = 0; i < m.length (); i++) | 2080 for (int i = 0; i < m.length (); i++) |
1883 { | 2081 { |
1907 | 2105 |
1908 return c; | 2106 return c; |
1909 } | 2107 } |
1910 | 2108 |
1911 ComplexMatrix | 2109 ComplexMatrix |
1912 operator + (const ComplexDiagMatrix& m, const Matrix& a) | 2110 operator + (const ComplexDiagMatrix& m, const ComplexMatrix& a) |
1913 { | 2111 { |
1914 int nr = m.rows (); | 2112 int nr = m.rows (); |
1915 int nc = m.cols (); | 2113 int nc = m.cols (); |
1916 if (nr != a.rows () || nc != a.cols ()) | 2114 if (nr != a.rows () || nc != a.cols ()) |
1917 { | 2115 { |
1929 | 2127 |
1930 return result; | 2128 return result; |
1931 } | 2129 } |
1932 | 2130 |
1933 ComplexMatrix | 2131 ComplexMatrix |
1934 operator - (const ComplexDiagMatrix& m, const Matrix& a) | 2132 operator - (const ComplexDiagMatrix& m, const ComplexMatrix& a) |
1935 { | 2133 { |
1936 int nr = m.rows (); | 2134 int nr = m.rows (); |
1937 int nc = m.cols (); | 2135 int nc = m.cols (); |
1938 if (nr != a.rows () || nc != a.cols ()) | 2136 if (nr != a.rows () || nc != a.cols ()) |
1939 { | 2137 { |
1951 | 2149 |
1952 return result; | 2150 return result; |
1953 } | 2151 } |
1954 | 2152 |
1955 ComplexMatrix | 2153 ComplexMatrix |
1956 operator * (const ComplexDiagMatrix& m, const Matrix& a) | 2154 operator * (const ComplexDiagMatrix& m, const ComplexMatrix& a) |
1957 { | 2155 { |
1958 int nr = m.rows (); | 2156 int nr = m.rows (); |
1959 int nc = m.cols (); | 2157 int nc = m.cols (); |
1960 int a_nr = a.rows (); | 2158 int a_nr = a.rows (); |
1961 int a_nc = a.cols (); | 2159 int a_nc = a.cols (); |
1998 } | 2196 } |
1999 | 2197 |
2000 return c; | 2198 return c; |
2001 } | 2199 } |
2002 | 2200 |
2003 ComplexMatrix | 2201 // matrix by matrix -> matrix operations |
2004 operator + (const ComplexDiagMatrix& m, const ComplexMatrix& a) | 2202 |
2203 ComplexMatrix& | |
2204 ComplexMatrix::operator += (const Matrix& a) | |
2205 { | |
2206 int nr = rows (); | |
2207 int nc = cols (); | |
2208 if (nr != a.rows () || nc != a.cols ()) | |
2209 { | |
2210 (*current_liboctave_error_handler) | |
2211 ("nonconformant matrix += operation attempted"); | |
2212 return *this; | |
2213 } | |
2214 | |
2215 if (nr == 0 || nc == 0) | |
2216 return *this; | |
2217 | |
2218 Complex *d = fortran_vec (); // Ensures only one reference to my privates! | |
2219 | |
2220 add2 (d, a.data (), length ()); | |
2221 return *this; | |
2222 } | |
2223 | |
2224 ComplexMatrix& | |
2225 ComplexMatrix::operator -= (const Matrix& a) | |
2226 { | |
2227 int nr = rows (); | |
2228 int nc = cols (); | |
2229 if (nr != a.rows () || nc != a.cols ()) | |
2230 { | |
2231 (*current_liboctave_error_handler) | |
2232 ("nonconformant matrix -= operation attempted"); | |
2233 return *this; | |
2234 } | |
2235 | |
2236 if (nr == 0 || nc == 0) | |
2237 return *this; | |
2238 | |
2239 Complex *d = fortran_vec (); // Ensures only one reference to my privates! | |
2240 | |
2241 subtract2 (d, a.data (), length ()); | |
2242 return *this; | |
2243 } | |
2244 | |
2245 ComplexMatrix& | |
2246 ComplexMatrix::operator += (const ComplexMatrix& a) | |
2247 { | |
2248 int nr = rows (); | |
2249 int nc = cols (); | |
2250 if (nr != a.rows () || nc != a.cols ()) | |
2251 { | |
2252 (*current_liboctave_error_handler) | |
2253 ("nonconformant matrix += operation attempted"); | |
2254 return *this; | |
2255 } | |
2256 | |
2257 if (nr == 0 || nc == 0) | |
2258 return *this; | |
2259 | |
2260 Complex *d = fortran_vec (); // Ensures only one reference to my privates! | |
2261 | |
2262 add2 (d, a.data (), length ()); | |
2263 return *this; | |
2264 } | |
2265 | |
2266 ComplexMatrix& | |
2267 ComplexMatrix::operator -= (const ComplexMatrix& a) | |
2268 { | |
2269 int nr = rows (); | |
2270 int nc = cols (); | |
2271 if (nr != a.rows () || nc != a.cols ()) | |
2272 { | |
2273 (*current_liboctave_error_handler) | |
2274 ("nonconformant matrix -= operation attempted"); | |
2275 return *this; | |
2276 } | |
2277 | |
2278 if (nr == 0 || nc == 0) | |
2279 return *this; | |
2280 | |
2281 Complex *d = fortran_vec (); // Ensures only one reference to my privates! | |
2282 | |
2283 subtract2 (d, a.data (), length ()); | |
2284 return *this; | |
2285 } | |
2286 | |
2287 // unary operations | |
2288 | |
2289 Matrix | |
2290 ComplexMatrix::operator ! (void) const | |
2291 { | |
2292 return Matrix (not (data (), length ()), rows (), cols ()); | |
2293 } | |
2294 | |
2295 // matrix by scalar -> matrix operations | |
2296 | |
2297 ComplexMatrix | |
2298 operator + (const Matrix& a, const Complex& s) | |
2299 { | |
2300 return ComplexMatrix (add (a.data (), a.length (), s), | |
2301 a.rows (), a.cols ()); | |
2302 } | |
2303 | |
2304 ComplexMatrix | |
2305 operator - (const Matrix& a, const Complex& s) | |
2306 { | |
2307 return ComplexMatrix (subtract (a.data (), a.length (), s), | |
2308 a.rows (), a.cols ()); | |
2309 } | |
2310 | |
2311 ComplexMatrix | |
2312 operator * (const Matrix& a, const Complex& s) | |
2313 { | |
2314 return ComplexMatrix (multiply (a.data (), a.length (), s), | |
2315 a.rows (), a.cols ()); | |
2316 } | |
2317 | |
2318 ComplexMatrix | |
2319 operator / (const Matrix& a, const Complex& s) | |
2320 { | |
2321 return ComplexMatrix (divide (a.data (), a.length (), s), | |
2322 a.rows (), a.cols ()); | |
2323 } | |
2324 | |
2325 ComplexMatrix | |
2326 operator + (const ComplexMatrix& a, double s) | |
2327 { | |
2328 return ComplexMatrix (add (a.data (), a.length (), s), | |
2329 a.rows (), a.cols ()); | |
2330 } | |
2331 | |
2332 ComplexMatrix | |
2333 operator - (const ComplexMatrix& a, double s) | |
2334 { | |
2335 return ComplexMatrix (subtract (a.data (), a.length (), s), | |
2336 a.rows (), a.cols ()); | |
2337 } | |
2338 | |
2339 ComplexMatrix | |
2340 operator * (const ComplexMatrix& a, double s) | |
2341 { | |
2342 return ComplexMatrix (multiply (a.data (), a.length (), s), | |
2343 a.rows (), a.cols ()); | |
2344 } | |
2345 | |
2346 ComplexMatrix | |
2347 operator / (const ComplexMatrix& a, double s) | |
2348 { | |
2349 return ComplexMatrix (divide (a.data (), a.length (), s), | |
2350 a.rows (), a.cols ()); | |
2351 } | |
2352 | |
2353 // scalar by matrix -> matrix operations | |
2354 | |
2355 ComplexMatrix | |
2356 operator + (double s, const ComplexMatrix& a) | |
2357 { | |
2358 return ComplexMatrix (add (a.data (), a.length (), s), a.rows (), | |
2359 a.cols ()); | |
2360 } | |
2361 | |
2362 ComplexMatrix | |
2363 operator - (double s, const ComplexMatrix& a) | |
2364 { | |
2365 return ComplexMatrix (subtract (s, a.data (), a.length ()), | |
2366 a.rows (), a.cols ()); | |
2367 } | |
2368 | |
2369 ComplexMatrix | |
2370 operator * (double s, const ComplexMatrix& a) | |
2371 { | |
2372 return ComplexMatrix (multiply (a.data (), a.length (), s), | |
2373 a.rows (), a.cols ()); | |
2374 } | |
2375 | |
2376 ComplexMatrix | |
2377 operator / (double s, const ComplexMatrix& a) | |
2378 { | |
2379 return ComplexMatrix (divide (s, a.data (), a.length ()), | |
2380 a.rows (), a.cols ()); | |
2381 } | |
2382 | |
2383 ComplexMatrix | |
2384 operator + (const Complex& s, const Matrix& a) | |
2385 { | |
2386 return ComplexMatrix (add (s, a.data (), a.length ()), | |
2387 a.rows (), a.cols ()); | |
2388 } | |
2389 | |
2390 ComplexMatrix | |
2391 operator - (const Complex& s, const Matrix& a) | |
2392 { | |
2393 return ComplexMatrix (subtract (s, a.data (), a.length ()), | |
2394 a.rows (), a.cols ()); | |
2395 } | |
2396 | |
2397 ComplexMatrix | |
2398 operator * (const Complex& s, const Matrix& a) | |
2399 { | |
2400 return ComplexMatrix (multiply (a.data (), a.length (), s), | |
2401 a.rows (), a.cols ()); | |
2402 } | |
2403 | |
2404 ComplexMatrix | |
2405 operator / (const Complex& s, const Matrix& a) | |
2406 { | |
2407 return ComplexMatrix (divide (s, a.data (), a.length ()), | |
2408 a.rows (), a.cols ()); | |
2409 } | |
2410 | |
2411 // matrix by diagonal matrix -> matrix operations | |
2412 | |
2413 ComplexMatrix | |
2414 operator + (const ComplexMatrix& m, const DiagMatrix& a) | |
2005 { | 2415 { |
2006 int nr = m.rows (); | 2416 int nr = m.rows (); |
2007 int nc = m.cols (); | 2417 int nc = m.cols (); |
2008 if (nr != a.rows () || nc != a.cols ()) | 2418 if (nr != a.rows () || nc != a.cols ()) |
2009 { | 2419 { |
2013 } | 2423 } |
2014 | 2424 |
2015 if (nr == 0 || nc == 0) | 2425 if (nr == 0 || nc == 0) |
2016 return ComplexMatrix (nr, nc); | 2426 return ComplexMatrix (nr, nc); |
2017 | 2427 |
2018 ComplexMatrix result (a); | 2428 ComplexMatrix result (m); |
2019 for (int i = 0; i < m.length (); i++) | 2429 for (int i = 0; i < a.length (); i++) |
2020 result.elem (i, i) += m.elem (i, i); | 2430 result.elem (i, i) += a.elem (i, i); |
2021 | 2431 |
2022 return result; | 2432 return result; |
2023 } | 2433 } |
2024 | 2434 |
2025 ComplexMatrix | 2435 ComplexMatrix |
2026 operator - (const ComplexDiagMatrix& m, const ComplexMatrix& a) | 2436 operator - (const ComplexMatrix& m, const DiagMatrix& a) |
2027 { | 2437 { |
2028 int nr = m.rows (); | 2438 int nr = m.rows (); |
2029 int nc = m.cols (); | 2439 int nc = m.cols (); |
2030 if (nr != a.rows () || nc != a.cols ()) | 2440 if (nr != a.rows () || nc != a.cols ()) |
2031 { | 2441 { |
2035 } | 2445 } |
2036 | 2446 |
2037 if (nr == 0 || nc == 0) | 2447 if (nr == 0 || nc == 0) |
2038 return ComplexMatrix (nr, nc); | 2448 return ComplexMatrix (nr, nc); |
2039 | 2449 |
2040 ComplexMatrix result (-a); | 2450 ComplexMatrix result (m); |
2041 for (int i = 0; i < m.length (); i++) | 2451 for (int i = 0; i < a.length (); i++) |
2042 result.elem (i, i) += m.elem (i, i); | 2452 result.elem (i, i) -= a.elem (i, i); |
2043 | 2453 |
2044 return result; | 2454 return result; |
2045 } | 2455 } |
2046 | 2456 |
2047 ComplexMatrix | 2457 ComplexMatrix |
2048 operator * (const ComplexDiagMatrix& m, const ComplexMatrix& a) | 2458 operator * (const ComplexMatrix& m, const DiagMatrix& a) |
2049 { | 2459 { |
2460 ComplexMatrix retval; | |
2461 | |
2050 int nr = m.rows (); | 2462 int nr = m.rows (); |
2051 int nc = m.cols (); | 2463 int nc = m.cols (); |
2052 int a_nr = a.rows (); | 2464 |
2053 int a_nc = a.cols (); | 2465 int a_nc = a.cols (); |
2054 if (nc != a_nr) | 2466 |
2055 { | 2467 if (nc != a.rows ()) |
2056 (*current_liboctave_error_handler) | 2468 (*current_liboctave_error_handler) |
2057 ("nonconformant matrix multiplication attempted"); | 2469 ("nonconformant matrix multiplication attempted"); |
2058 return ComplexMatrix (); | 2470 else |
2059 } | 2471 { |
2060 | 2472 if (nr == 0 || nc == 0 || a_nc == 0) |
2061 if (nr == 0 || nc == 0 || a_nc == 0) | 2473 retval.resize (nr, nc, 0.0); |
2062 return ComplexMatrix (nr, a_nc, 0.0); | |
2063 | |
2064 ComplexMatrix c (nr, a_nc); | |
2065 | |
2066 for (int i = 0; i < m.length (); i++) | |
2067 { | |
2068 if (m.elem (i, i) == 1.0) | |
2069 { | |
2070 for (int j = 0; j < a_nc; j++) | |
2071 c.elem (i, j) = a.elem (i, j); | |
2072 } | |
2073 else if (m.elem (i, i) == 0.0) | |
2074 { | |
2075 for (int j = 0; j < a_nc; j++) | |
2076 c.elem (i, j) = 0.0; | |
2077 } | |
2078 else | 2474 else |
2079 { | 2475 { |
2080 for (int j = 0; j < a_nc; j++) | 2476 retval.resize (nr, a_nc); |
2081 c.elem (i, j) = m.elem (i, i) * a.elem (i, j); | 2477 Complex *c = retval.fortran_vec (); |
2082 } | 2478 Complex *ctmp = 0; |
2083 } | 2479 |
2084 | 2480 for (int j = 0; j < a.length (); j++) |
2085 if (nr > nc) | 2481 { |
2086 { | 2482 int idx = j * nr; |
2087 for (int j = 0; j < a_nc; j++) | 2483 ctmp = c + idx; |
2088 for (int i = a_nr; i < nr; i++) | 2484 if (a.elem (j, j) == 1.0) |
2089 c.elem (i, j) = 0.0; | 2485 { |
2090 } | 2486 for (int i = 0; i < nr; i++) |
2091 | 2487 ctmp[i] = m.elem (i, j); |
2092 return c; | 2488 } |
2093 } | 2489 else if (a.elem (j, j) == 0.0) |
2094 | 2490 { |
2095 // matrix by matrix -> matrix operations | 2491 for (int i = 0; i < nr; i++) |
2096 | 2492 ctmp[i] = 0.0; |
2097 ComplexMatrix& | 2493 } |
2098 ComplexMatrix::operator += (const Matrix& a) | 2494 else |
2099 { | 2495 { |
2100 int nr = rows (); | 2496 for (int i = 0; i < nr; i++) |
2101 int nc = cols (); | 2497 ctmp[i] = a.elem (j, j) * m.elem (i, j); |
2102 if (nr != a.rows () || nc != a.cols ()) | 2498 } |
2103 { | 2499 } |
2104 (*current_liboctave_error_handler) | 2500 |
2105 ("nonconformant matrix += operation attempted"); | 2501 if (a.rows () < a_nc) |
2106 return *this; | 2502 { |
2107 } | 2503 for (int i = nr * nc; i < nr * a_nc; i++) |
2108 | 2504 ctmp[i] = 0.0; |
2109 if (nr == 0 || nc == 0) | 2505 } |
2110 return *this; | 2506 } |
2111 | 2507 } |
2112 Complex *d = fortran_vec (); // Ensures only one reference to my privates! | 2508 |
2113 | 2509 return retval; |
2114 add2 (d, a.data (), length ()); | 2510 } |
2115 return *this; | 2511 |
2116 } | 2512 ComplexMatrix |
2117 | 2513 operator + (const ComplexMatrix& m, const ComplexDiagMatrix& a) |
2118 ComplexMatrix& | |
2119 ComplexMatrix::operator -= (const Matrix& a) | |
2120 { | |
2121 int nr = rows (); | |
2122 int nc = cols (); | |
2123 if (nr != a.rows () || nc != a.cols ()) | |
2124 { | |
2125 (*current_liboctave_error_handler) | |
2126 ("nonconformant matrix -= operation attempted"); | |
2127 return *this; | |
2128 } | |
2129 | |
2130 if (nr == 0 || nc == 0) | |
2131 return *this; | |
2132 | |
2133 Complex *d = fortran_vec (); // Ensures only one reference to my privates! | |
2134 | |
2135 subtract2 (d, a.data (), length ()); | |
2136 return *this; | |
2137 } | |
2138 | |
2139 ComplexMatrix& | |
2140 ComplexMatrix::operator += (const ComplexMatrix& a) | |
2141 { | |
2142 int nr = rows (); | |
2143 int nc = cols (); | |
2144 if (nr != a.rows () || nc != a.cols ()) | |
2145 { | |
2146 (*current_liboctave_error_handler) | |
2147 ("nonconformant matrix += operation attempted"); | |
2148 return *this; | |
2149 } | |
2150 | |
2151 if (nr == 0 || nc == 0) | |
2152 return *this; | |
2153 | |
2154 Complex *d = fortran_vec (); // Ensures only one reference to my privates! | |
2155 | |
2156 add2 (d, a.data (), length ()); | |
2157 return *this; | |
2158 } | |
2159 | |
2160 ComplexMatrix& | |
2161 ComplexMatrix::operator -= (const ComplexMatrix& a) | |
2162 { | |
2163 int nr = rows (); | |
2164 int nc = cols (); | |
2165 if (nr != a.rows () || nc != a.cols ()) | |
2166 { | |
2167 (*current_liboctave_error_handler) | |
2168 ("nonconformant matrix -= operation attempted"); | |
2169 return *this; | |
2170 } | |
2171 | |
2172 if (nr == 0 || nc == 0) | |
2173 return *this; | |
2174 | |
2175 Complex *d = fortran_vec (); // Ensures only one reference to my privates! | |
2176 | |
2177 subtract2 (d, a.data (), length ()); | |
2178 return *this; | |
2179 } | |
2180 | |
2181 // unary operations | |
2182 | |
2183 Matrix | |
2184 ComplexMatrix::operator ! (void) const | |
2185 { | |
2186 return Matrix (not (data (), length ()), rows (), cols ()); | |
2187 } | |
2188 | |
2189 // matrix by scalar -> matrix operations | |
2190 | |
2191 ComplexMatrix | |
2192 operator + (const Matrix& a, const Complex& s) | |
2193 { | |
2194 return ComplexMatrix (add (a.data (), a.length (), s), | |
2195 a.rows (), a.cols ()); | |
2196 } | |
2197 | |
2198 ComplexMatrix | |
2199 operator - (const Matrix& a, const Complex& s) | |
2200 { | |
2201 return ComplexMatrix (subtract (a.data (), a.length (), s), | |
2202 a.rows (), a.cols ()); | |
2203 } | |
2204 | |
2205 ComplexMatrix | |
2206 operator * (const Matrix& a, const Complex& s) | |
2207 { | |
2208 return ComplexMatrix (multiply (a.data (), a.length (), s), | |
2209 a.rows (), a.cols ()); | |
2210 } | |
2211 | |
2212 ComplexMatrix | |
2213 operator / (const Matrix& a, const Complex& s) | |
2214 { | |
2215 return ComplexMatrix (divide (a.data (), a.length (), s), | |
2216 a.rows (), a.cols ()); | |
2217 } | |
2218 | |
2219 ComplexMatrix | |
2220 operator + (const ComplexMatrix& a, double s) | |
2221 { | |
2222 return ComplexMatrix (add (a.data (), a.length (), s), | |
2223 a.rows (), a.cols ()); | |
2224 } | |
2225 | |
2226 ComplexMatrix | |
2227 operator - (const ComplexMatrix& a, double s) | |
2228 { | |
2229 return ComplexMatrix (subtract (a.data (), a.length (), s), | |
2230 a.rows (), a.cols ()); | |
2231 } | |
2232 | |
2233 ComplexMatrix | |
2234 operator * (const ComplexMatrix& a, double s) | |
2235 { | |
2236 return ComplexMatrix (multiply (a.data (), a.length (), s), | |
2237 a.rows (), a.cols ()); | |
2238 } | |
2239 | |
2240 ComplexMatrix | |
2241 operator / (const ComplexMatrix& a, double s) | |
2242 { | |
2243 return ComplexMatrix (divide (a.data (), a.length (), s), | |
2244 a.rows (), a.cols ()); | |
2245 } | |
2246 | |
2247 // scalar by matrix -> matrix operations | |
2248 | |
2249 ComplexMatrix | |
2250 operator + (double s, const ComplexMatrix& a) | |
2251 { | |
2252 return ComplexMatrix (add (a.data (), a.length (), s), a.rows (), | |
2253 a.cols ()); | |
2254 } | |
2255 | |
2256 ComplexMatrix | |
2257 operator - (double s, const ComplexMatrix& a) | |
2258 { | |
2259 return ComplexMatrix (subtract (s, a.data (), a.length ()), | |
2260 a.rows (), a.cols ()); | |
2261 } | |
2262 | |
2263 ComplexMatrix | |
2264 operator * (double s, const ComplexMatrix& a) | |
2265 { | |
2266 return ComplexMatrix (multiply (a.data (), a.length (), s), | |
2267 a.rows (), a.cols ()); | |
2268 } | |
2269 | |
2270 ComplexMatrix | |
2271 operator / (double s, const ComplexMatrix& a) | |
2272 { | |
2273 return ComplexMatrix (divide (s, a.data (), a.length ()), | |
2274 a.rows (), a.cols ()); | |
2275 } | |
2276 | |
2277 ComplexMatrix | |
2278 operator + (const Complex& s, const Matrix& a) | |
2279 { | |
2280 return ComplexMatrix (add (s, a.data (), a.length ()), | |
2281 a.rows (), a.cols ()); | |
2282 } | |
2283 | |
2284 ComplexMatrix | |
2285 operator - (const Complex& s, const Matrix& a) | |
2286 { | |
2287 return ComplexMatrix (subtract (s, a.data (), a.length ()), | |
2288 a.rows (), a.cols ()); | |
2289 } | |
2290 | |
2291 ComplexMatrix | |
2292 operator * (const Complex& s, const Matrix& a) | |
2293 { | |
2294 return ComplexMatrix (multiply (a.data (), a.length (), s), | |
2295 a.rows (), a.cols ()); | |
2296 } | |
2297 | |
2298 ComplexMatrix | |
2299 operator / (const Complex& s, const Matrix& a) | |
2300 { | |
2301 return ComplexMatrix (divide (s, a.data (), a.length ()), | |
2302 a.rows (), a.cols ()); | |
2303 } | |
2304 | |
2305 // matrix by diagonal matrix -> matrix operations | |
2306 | |
2307 ComplexMatrix | |
2308 operator + (const ComplexMatrix& m, const DiagMatrix& a) | |
2309 { | 2514 { |
2310 int nr = m.rows (); | 2515 int nr = m.rows (); |
2311 int nc = m.cols (); | 2516 int nc = m.cols (); |
2312 if (nr != a.rows () || nc != a.cols ()) | 2517 if (nr != a.rows () || nc != a.cols ()) |
2313 { | 2518 { |
2325 | 2530 |
2326 return result; | 2531 return result; |
2327 } | 2532 } |
2328 | 2533 |
2329 ComplexMatrix | 2534 ComplexMatrix |
2330 operator - (const ComplexMatrix& m, const DiagMatrix& a) | 2535 operator - (const ComplexMatrix& m, const ComplexDiagMatrix& a) |
2331 { | 2536 { |
2332 int nr = m.rows (); | 2537 int nr = m.rows (); |
2333 int nc = m.cols (); | 2538 int nc = m.cols (); |
2334 if (nr != a.rows () || nc != a.cols ()) | 2539 if (nr != a.rows () || nc != a.cols ()) |
2335 { | 2540 { |
2347 | 2552 |
2348 return result; | 2553 return result; |
2349 } | 2554 } |
2350 | 2555 |
2351 ComplexMatrix | 2556 ComplexMatrix |
2352 operator * (const ComplexMatrix& m, const DiagMatrix& a) | 2557 operator * (const ComplexMatrix& m, const ComplexDiagMatrix& a) |
2353 { | 2558 { |
2559 ComplexMatrix retval; | |
2560 | |
2354 int nr = m.rows (); | 2561 int nr = m.rows (); |
2355 int nc = m.cols (); | 2562 int nc = m.cols (); |
2563 | |
2356 int a_nc = a.cols (); | 2564 int a_nc = a.cols (); |
2565 | |
2357 if (nc != a.rows ()) | 2566 if (nc != a.rows ()) |
2358 { | 2567 (*current_liboctave_error_handler) |
2359 (*current_liboctave_error_handler) | 2568 ("nonconformant matrix multiplication attempted"); |
2360 ("nonconformant matrix multiplication attempted"); | 2569 else |
2361 return ComplexMatrix (); | 2570 { |
2362 } | 2571 if (nr == 0 || nc == 0 || a_nc == 0) |
2363 | 2572 retval.resize (nr, nc, 0.0); |
2364 if (nr == 0 || nc == 0 || a_nc == 0) | |
2365 return ComplexMatrix (nr, nc, 0.0); | |
2366 | |
2367 Complex *c = new Complex [nr*a_nc]; | |
2368 Complex *ctmp = 0; | |
2369 | |
2370 for (int j = 0; j < a.length (); j++) | |
2371 { | |
2372 int idx = j * nr; | |
2373 ctmp = c + idx; | |
2374 if (a.elem (j, j) == 1.0) | |
2375 { | |
2376 for (int i = 0; i < nr; i++) | |
2377 ctmp[i] = m.elem (i, j); | |
2378 } | |
2379 else if (a.elem (j, j) == 0.0) | |
2380 { | |
2381 for (int i = 0; i < nr; i++) | |
2382 ctmp[i] = 0.0; | |
2383 } | |
2384 else | 2573 else |
2385 { | 2574 { |
2386 for (int i = 0; i < nr; i++) | 2575 retval.resize (nr, nc); |
2387 ctmp[i] = a.elem (j, j) * m.elem (i, j); | 2576 Complex *c = retval.fortran_vec (); |
2388 } | 2577 Complex *ctmp = 0; |
2389 } | 2578 |
2390 | 2579 for (int j = 0; j < a.length (); j++) |
2391 if (a.rows () < a_nc) | 2580 { |
2392 { | 2581 int idx = j * nr; |
2393 for (int i = nr * nc; i < nr * a_nc; i++) | 2582 ctmp = c + idx; |
2394 ctmp[i] = 0.0; | 2583 if (a.elem (j, j) == 1.0) |
2395 } | 2584 { |
2396 | 2585 for (int i = 0; i < nr; i++) |
2397 return ComplexMatrix (c, nr, a_nc); | 2586 ctmp[i] = m.elem (i, j); |
2398 } | 2587 } |
2399 | 2588 else if (a.elem (j, j) == 0.0) |
2400 ComplexMatrix | 2589 { |
2401 operator + (const ComplexMatrix& m, const ComplexDiagMatrix& a) | 2590 for (int i = 0; i < nr; i++) |
2591 ctmp[i] = 0.0; | |
2592 } | |
2593 else | |
2594 { | |
2595 for (int i = 0; i < nr; i++) | |
2596 ctmp[i] = a.elem (j, j) * m.elem (i, j); | |
2597 } | |
2598 } | |
2599 | |
2600 if (a.rows () < a_nc) | |
2601 { | |
2602 for (int i = nr * nc; i < nr * a_nc; i++) | |
2603 ctmp[i] = 0.0; | |
2604 } | |
2605 } | |
2606 } | |
2607 | |
2608 return retval; | |
2609 } | |
2610 | |
2611 // matrix by matrix -> matrix operations | |
2612 | |
2613 ComplexMatrix | |
2614 operator + (const ComplexMatrix& m, const Matrix& a) | |
2402 { | 2615 { |
2403 int nr = m.rows (); | 2616 int nr = m.rows (); |
2404 int nc = m.cols (); | 2617 int nc = m.cols (); |
2405 if (nr != a.rows () || nc != a.cols ()) | 2618 if (nr != a.rows () || nc != a.cols ()) |
2406 { | 2619 { |
2410 } | 2623 } |
2411 | 2624 |
2412 if (nr == 0 || nc == 0) | 2625 if (nr == 0 || nc == 0) |
2413 return ComplexMatrix (nr, nc); | 2626 return ComplexMatrix (nr, nc); |
2414 | 2627 |
2415 ComplexMatrix result (m); | 2628 return ComplexMatrix (add (m.data (), a.data (), m.length ()), nr, nc); |
2416 for (int i = 0; i < a.length (); i++) | 2629 } |
2417 result.elem (i, i) += a.elem (i, i); | 2630 |
2418 | 2631 ComplexMatrix |
2419 return result; | 2632 operator - (const ComplexMatrix& m, const Matrix& a) |
2420 } | |
2421 | |
2422 ComplexMatrix | |
2423 operator - (const ComplexMatrix& m, const ComplexDiagMatrix& a) | |
2424 { | 2633 { |
2425 int nr = m.rows (); | 2634 int nr = m.rows (); |
2426 int nc = m.cols (); | 2635 int nc = m.cols (); |
2427 if (nr != a.rows () || nc != a.cols ()) | 2636 if (nr != a.rows () || nc != a.cols ()) |
2428 { | 2637 { |
2432 } | 2641 } |
2433 | 2642 |
2434 if (nr == 0 || nc == 0) | 2643 if (nr == 0 || nc == 0) |
2435 return ComplexMatrix (nr, nc); | 2644 return ComplexMatrix (nr, nc); |
2436 | 2645 |
2437 ComplexMatrix result (m); | 2646 return ComplexMatrix (subtract (m.data (), a.data (), m.length ()), nr, nc); |
2438 for (int i = 0; i < a.length (); i++) | 2647 } |
2439 result.elem (i, i) -= a.elem (i, i); | 2648 |
2440 | 2649 ComplexMatrix |
2441 return result; | 2650 operator + (const Matrix& m, const ComplexMatrix& a) |
2442 } | |
2443 | |
2444 ComplexMatrix | |
2445 operator * (const ComplexMatrix& m, const ComplexDiagMatrix& a) | |
2446 { | |
2447 int nr = m.rows (); | |
2448 int nc = m.cols (); | |
2449 int a_nc = a.cols (); | |
2450 if (nc != a.rows ()) | |
2451 { | |
2452 (*current_liboctave_error_handler) | |
2453 ("nonconformant matrix multiplication attempted"); | |
2454 return ComplexMatrix (); | |
2455 } | |
2456 | |
2457 if (nr == 0 || nc == 0 || a_nc == 0) | |
2458 return ComplexMatrix (nr, nc, 0.0); | |
2459 | |
2460 Complex *c = new Complex [nr*a_nc]; | |
2461 Complex *ctmp = 0; | |
2462 | |
2463 for (int j = 0; j < a.length (); j++) | |
2464 { | |
2465 int idx = j * nr; | |
2466 ctmp = c + idx; | |
2467 if (a.elem (j, j) == 1.0) | |
2468 { | |
2469 for (int i = 0; i < nr; i++) | |
2470 ctmp[i] = m.elem (i, j); | |
2471 } | |
2472 else if (a.elem (j, j) == 0.0) | |
2473 { | |
2474 for (int i = 0; i < nr; i++) | |
2475 ctmp[i] = 0.0; | |
2476 } | |
2477 else | |
2478 { | |
2479 for (int i = 0; i < nr; i++) | |
2480 ctmp[i] = a.elem (j, j) * m.elem (i, j); | |
2481 } | |
2482 } | |
2483 | |
2484 if (a.rows () < a_nc) | |
2485 { | |
2486 for (int i = nr * nc; i < nr * a_nc; i++) | |
2487 ctmp[i] = 0.0; | |
2488 } | |
2489 | |
2490 return ComplexMatrix (c, nr, a_nc); | |
2491 } | |
2492 | |
2493 // matrix by matrix -> matrix operations | |
2494 | |
2495 ComplexMatrix | |
2496 operator + (const ComplexMatrix& m, const Matrix& a) | |
2497 { | 2651 { |
2498 int nr = m.rows (); | 2652 int nr = m.rows (); |
2499 int nc = m.cols (); | 2653 int nc = m.cols (); |
2500 if (nr != a.rows () || nc != a.cols ()) | 2654 if (nr != a.rows () || nc != a.cols ()) |
2501 { | 2655 { |
2502 (*current_liboctave_error_handler) | 2656 (*current_liboctave_error_handler) |
2503 ("nonconformant matrix addition attempted"); | 2657 ("nonconformant matrix addition attempted"); |
2504 return ComplexMatrix (); | 2658 return ComplexMatrix (); |
2505 } | 2659 } |
2506 | 2660 |
2507 if (nr == 0 || nc == 0) | |
2508 return ComplexMatrix (nr, nc); | |
2509 | |
2510 return ComplexMatrix (add (m.data (), a.data (), m.length ()), nr, nc); | 2661 return ComplexMatrix (add (m.data (), a.data (), m.length ()), nr, nc); |
2511 } | 2662 } |
2512 | 2663 |
2513 ComplexMatrix | 2664 ComplexMatrix |
2514 operator - (const ComplexMatrix& m, const Matrix& a) | 2665 operator - (const Matrix& m, const ComplexMatrix& a) |
2515 { | 2666 { |
2516 int nr = m.rows (); | 2667 int nr = m.rows (); |
2517 int nc = m.cols (); | 2668 int nc = m.cols (); |
2518 if (nr != a.rows () || nc != a.cols ()) | 2669 if (nr != a.rows () || nc != a.cols ()) |
2519 { | 2670 { |
2527 | 2678 |
2528 return ComplexMatrix (subtract (m.data (), a.data (), m.length ()), nr, nc); | 2679 return ComplexMatrix (subtract (m.data (), a.data (), m.length ()), nr, nc); |
2529 } | 2680 } |
2530 | 2681 |
2531 ComplexMatrix | 2682 ComplexMatrix |
2532 operator + (const Matrix& m, const ComplexMatrix& a) | 2683 operator * (const ComplexMatrix& m, const Matrix& a) |
2533 { | 2684 { |
2685 ComplexMatrix tmp (a); | |
2686 return m * tmp; | |
2687 } | |
2688 | |
2689 ComplexMatrix | |
2690 operator * (const Matrix& m, const ComplexMatrix& a) | |
2691 { | |
2692 ComplexMatrix tmp (m); | |
2693 return tmp * a; | |
2694 } | |
2695 | |
2696 ComplexMatrix | |
2697 operator * (const ComplexMatrix& m, const ComplexMatrix& a) | |
2698 { | |
2699 ComplexMatrix retval; | |
2700 | |
2534 int nr = m.rows (); | 2701 int nr = m.rows (); |
2535 int nc = m.cols (); | 2702 int nc = m.cols (); |
2536 if (nr != a.rows () || nc != a.cols ()) | 2703 |
2537 { | |
2538 (*current_liboctave_error_handler) | |
2539 ("nonconformant matrix addition attempted"); | |
2540 return ComplexMatrix (); | |
2541 } | |
2542 | |
2543 return ComplexMatrix (add (m.data (), a.data (), m.length ()), nr, nc); | |
2544 } | |
2545 | |
2546 ComplexMatrix | |
2547 operator - (const Matrix& m, const ComplexMatrix& a) | |
2548 { | |
2549 int nr = m.rows (); | |
2550 int nc = m.cols (); | |
2551 if (nr != a.rows () || nc != a.cols ()) | |
2552 { | |
2553 (*current_liboctave_error_handler) | |
2554 ("nonconformant matrix subtraction attempted"); | |
2555 return ComplexMatrix (); | |
2556 } | |
2557 | |
2558 if (nr == 0 || nc == 0) | |
2559 return ComplexMatrix (nr, nc); | |
2560 | |
2561 return ComplexMatrix (subtract (m.data (), a.data (), m.length ()), nr, nc); | |
2562 } | |
2563 | |
2564 ComplexMatrix | |
2565 operator * (const ComplexMatrix& m, const Matrix& a) | |
2566 { | |
2567 ComplexMatrix tmp (a); | |
2568 return m * tmp; | |
2569 } | |
2570 | |
2571 ComplexMatrix | |
2572 operator * (const Matrix& m, const ComplexMatrix& a) | |
2573 { | |
2574 ComplexMatrix tmp (m); | |
2575 return tmp * a; | |
2576 } | |
2577 | |
2578 ComplexMatrix | |
2579 operator * (const ComplexMatrix& m, const ComplexMatrix& a) | |
2580 { | |
2581 int nr = m.rows (); | |
2582 int nc = m.cols (); | |
2583 int a_nc = a.cols (); | 2704 int a_nc = a.cols (); |
2705 | |
2584 if (nc != a.rows ()) | 2706 if (nc != a.rows ()) |
2585 { | 2707 (*current_liboctave_error_handler) |
2586 (*current_liboctave_error_handler) | 2708 ("nonconformant matrix multiplication attempted"); |
2587 ("nonconformant matrix multiplication attempted"); | 2709 else |
2588 return ComplexMatrix (); | 2710 { |
2589 } | 2711 if (nr == 0 || nc == 0 || a_nc == 0) |
2590 | 2712 retval.resize (nr, nc, 0.0); |
2591 if (nr == 0 || nc == 0 || a_nc == 0) | 2713 else |
2592 return ComplexMatrix (nr, nc, 0.0); | 2714 { |
2593 | 2715 int ld = nr; |
2594 int ld = nr; | 2716 int lda = a.rows (); |
2595 int lda = a.rows (); | 2717 |
2596 | 2718 retval.resize (nr, a_nc); |
2597 Complex *c = new Complex [nr*a_nc]; | 2719 Complex *c = retval.fortran_vec (); |
2598 | 2720 |
2599 F77_FCN (zgemm, ZGEMM) ("N", "N", nr, a_nc, nc, 1.0, m.data (), ld, | 2721 F77_XFCN (zgemm, ZGEMM, ("N", "N", nr, a_nc, nc, 1.0, |
2600 a.data (), lda, 0.0, c, nr, 1L, 1L); | 2722 m.data (), ld, a.data (), lda, 0.0, |
2601 | 2723 c, nr, 1L, 1L)); |
2602 return ComplexMatrix (c, nr, a_nc); | 2724 |
2725 if (f77_exception_encountered) | |
2726 (*current_liboctave_error_handler) | |
2727 ("unrecoverable error in zgemm"); | |
2728 } | |
2729 } | |
2730 | |
2731 return retval; | |
2603 } | 2732 } |
2604 | 2733 |
2605 ComplexMatrix | 2734 ComplexMatrix |
2606 product (const ComplexMatrix& m, const Matrix& a) | 2735 product (const ComplexMatrix& m, const Matrix& a) |
2607 { | 2736 { |