875{
876
877
878
879
880
881
882
883
886
887
888
889
890
891
892
893 static const G4int max_array = 25;
895 if(!xvec)
896 xvec = new std::vector<G4double>(max_array);
898 if(!pivv)
899 pivv = new std::vector<G4int>(max_array);
900 typedef std::vector<G4int>::iterator pivIter;
901 if(xvec->size() < static_cast<unsigned int>(nrow))
902 xvec->resize(nrow);
903 if(pivv->size() < static_cast<unsigned int>(nrow))
904 pivv->resize(nrow);
905
906
907
908
910
911 pivIter piv = pivv->begin();
912
913
919
920
921
922
923
924 for(i = 0; i < nrow; i++)
925 {
926 piv[i] = i + 1;
927 }
928
929 ifail = 0;
930
931
932
933
934
935 for(j = 1; j < nrow; j += ss)
936 {
937 mjj = m.begin() + j * (j - 1) / 2 + j - 1;
939 pivrow = j + 1;
940 ip = m.begin() + (j + 1) * j / 2 + j - 1;
941 for(i = j + 1; i <= nrow; ip += i++)
942 {
943 if(std::fabs(*ip) >
lambda)
944 {
946 pivrow = i;
947 }
948 }
949 if(lambda == 0)
950 {
951 if(*mjj == 0)
952 {
953 ifail = 1;
954 return;
955 }
956 ss = 1;
957 *mjj = 1. / *mjj;
958 }
959 else
960 {
961 if(std::fabs(*mjj) >= lambda * alpha)
962 {
963 ss = 1;
964 pivrow = j;
965 }
966 else
967 {
968 sigma = 0;
969 ip = m.begin() + pivrow * (pivrow - 1) / 2 + j - 1;
970 for(k = j; k < pivrow; k++)
971 {
972 if(std::fabs(*ip) > sigma)
973 sigma = std::fabs(*ip);
974 ip++;
975 }
977 {
978 ss = 1;
979 pivrow = j;
980 }
981 else if(std::fabs(*(m.begin() + pivrow * (pivrow - 1) / 2 + pivrow -
982 1)) >=
alpha * sigma)
983 {
984 ss = 1;
985 }
986 else
987 {
988 ss = 2;
989 }
990 }
991 if(pivrow == j)
992 {
993 piv[j - 1] = pivrow;
994 if(*mjj == 0)
995 {
996 ifail = 1;
997 return;
998 }
999 temp2 = *mjj = 1. / *mjj;
1000
1001
1002 for(i = j + 1; i <= nrow; i++)
1003 {
1004 temp1 = *(m.begin() + i * (i - 1) / 2 + j - 1) * temp2;
1005 ip = m.begin() + i * (i - 1) / 2 + j;
1006 for(k = j + 1; k <= i; k++)
1007 {
1008 *ip -= temp1 * *(m.begin() + k * (k - 1) / 2 + j - 1);
1010 {
1011 *ip = 0;
1012 }
1013 ip++;
1014 }
1015 }
1016
1017 ip = m.begin() + (j + 1) * j / 2 + j - 1;
1018 for(i = j + 1; i <= nrow; ip += i++)
1019 {
1020 *ip *= temp2;
1021 }
1022 }
1023 else if(ss == 1)
1024 {
1025 piv[j - 1] = pivrow;
1026
1027
1028
1029 ip = m.begin() + pivrow * (pivrow - 1) / 2 + j;
1030 for(i = j + 1; i < pivrow; i++, ip++)
1031 {
1032 temp1 = *(m.begin() + i * (i - 1) / 2 + j - 1);
1033 *(m.begin() + i * (i - 1) / 2 + j - 1) = *ip;
1034 *ip = temp1;
1035 }
1036 temp1 = *mjj;
1037 *mjj = *(m.begin() + pivrow * (pivrow - 1) / 2 + pivrow - 1);
1038 *(m.begin() + pivrow * (pivrow - 1) / 2 + pivrow - 1) = temp1;
1039 ip = m.begin() + (pivrow + 1) * pivrow / 2 + j - 1;
1040 iq = ip + pivrow - j;
1041 for(i = pivrow + 1; i <= nrow; ip += i, iq += i++)
1042 {
1043 temp1 = *iq;
1044 *iq = *ip;
1045 *ip = temp1;
1046 }
1047
1048 if(*mjj == 0)
1049 {
1050 ifail = 1;
1051 return;
1052 }
1053 temp2 = *mjj = 1. / *mjj;
1054
1055
1056 for(i = j + 1; i <= nrow; i++)
1057 {
1058 temp1 = *(m.begin() + i * (i - 1) / 2 + j - 1) * temp2;
1059 ip = m.begin() + i * (i - 1) / 2 + j;
1060 for(k = j + 1; k <= i; k++)
1061 {
1062 *ip -= temp1 * *(m.begin() + k * (k - 1) / 2 + j - 1);
1064 {
1065 *ip = 0;
1066 }
1067 ip++;
1068 }
1069 }
1070
1071 ip = m.begin() + (j + 1) * j / 2 + j - 1;
1072 for(i = j + 1; i <= nrow; ip += i++)
1073 {
1074 *ip *= temp2;
1075 }
1076 }
1077 else
1078 {
1079 piv[j - 1] = -pivrow;
1080 piv[j] = 0;
1081
1082 if(j + 1 != pivrow)
1083 {
1084
1085
1086 ip = m.begin() + pivrow * (pivrow - 1) / 2 + j + 1;
1087 for(i = j + 2; i < pivrow; i++, ip++)
1088 {
1089 temp1 = *(m.begin() + i * (i - 1) / 2 + j);
1090 *(m.begin() + i * (i - 1) / 2 + j) = *ip;
1091 *ip = temp1;
1092 }
1093 temp1 = *(mjj + j + 1);
1094 *(mjj + j + 1) =
1095 *(m.begin() + pivrow * (pivrow - 1) / 2 + pivrow - 1);
1096 *(m.begin() + pivrow * (pivrow - 1) / 2 + pivrow - 1) = temp1;
1097 temp1 = *(mjj + j);
1098 *(mjj + j) = *(m.begin() + pivrow * (pivrow - 1) / 2 + j - 1);
1099 *(m.begin() + pivrow * (pivrow - 1) / 2 + j - 1) = temp1;
1100 ip = m.begin() + (pivrow + 1) * pivrow / 2 + j;
1101 iq = ip + pivrow - (j + 1);
1102 for(i = pivrow + 1; i <= nrow; ip += i, iq += i++)
1103 {
1104 temp1 = *iq;
1105 *iq = *ip;
1106 *ip = temp1;
1107 }
1108 }
1109
1110 temp2 = *mjj * *(mjj + j + 1) - *(mjj + j) * *(mjj + j);
1111 if(temp2 == 0)
1112 {
1115 "Error in pivot choice!");
1116 }
1117 temp2 = 1. / temp2;
1118
1119
1120
1121
1122 temp1 = *mjj;
1123 *mjj = *(mjj + j + 1) * temp2;
1124 *(mjj + j + 1) = temp1 * temp2;
1125 *(mjj + j) = -*(mjj + j) * temp2;
1126
1127 if(j < nrow - 1)
1128 {
1129
1130 for(i = j + 2; i <= nrow; i++)
1131 {
1132 ip = m.begin() + i * (i - 1) / 2 + j - 1;
1133 temp1 = *ip * *mjj + *(ip + 1) * *(mjj + j);
1134 if(std::fabs(temp1) <=
epsilon)
1135 {
1136 temp1 = 0;
1137 }
1138 temp2 = *ip * *(mjj + j) + *(ip + 1) * *(mjj + j + 1);
1139 if(std::fabs(temp2) <=
epsilon)
1140 {
1141 temp2 = 0;
1142 }
1143 for(k = j + 2; k <= i; k++)
1144 {
1145 ip = m.begin() + i * (i - 1) / 2 + k - 1;
1146 iq = m.begin() + k * (k - 1) / 2 + j - 1;
1147 *ip -= temp1 * *iq + temp2 * *(iq + 1);
1149 {
1150 *ip = 0;
1151 }
1152 }
1153 }
1154
1155 for(i = j + 2; i <= nrow; i++)
1156 {
1157 ip = m.begin() + i * (i - 1) / 2 + j - 1;
1158 temp1 = *ip * *mjj + *(ip + 1) * *(mjj + j);
1159 if(std::fabs(temp1) <=
epsilon)
1160 {
1161 temp1 = 0;
1162 }
1163 *(ip + 1) = *ip * *(mjj + j) + *(ip + 1) * *(mjj + j + 1);
1164 if(std::fabs(*(ip + 1)) <=
epsilon)
1165 {
1166 *(ip + 1) = 0;
1167 }
1168 *ip = temp1;
1169 }
1170 }
1171 }
1172 }
1173 }
1174
1175 if(j == nrow)
1176 {
1177 mjj = m.begin() + j * (j - 1) / 2 + j - 1;
1178 if(*mjj == 0)
1179 {
1180 ifail = 1;
1181 return;
1182 }
1183 else
1184 {
1185 *mjj = 1. / *mjj;
1186 }
1187 }
1188
1189
1190
1191 for(j = nrow; j >= 1; j -= ss)
1192 {
1193 mjj = m.begin() + j * (j - 1) / 2 + j - 1;
1194 if(piv[j - 1] > 0)
1195 {
1196 ss = 1;
1197 if(j < nrow)
1198 {
1199 ip = m.begin() + (j + 1) * j / 2 + j - 1;
1200 for(i = 0; i < nrow - j; ip += 1 + j + i++)
1201 {
1202 x[i] = *ip;
1203 }
1204 for(i = j + 1; i <= nrow; i++)
1205 {
1206 temp2 = 0;
1207 ip = m.begin() + i * (i - 1) / 2 + j;
1208 for(k = 0; k <= i - j - 1; k++)
1209 {
1210 temp2 += *ip++ * x[k];
1211 }
1212 for(ip += i - 1; k < nrow - j; ip += 1 + j + k++)
1213 {
1214 temp2 += *ip * x[k];
1215 }
1216 *(m.begin() + i * (i - 1) / 2 + j - 1) = -temp2;
1217 }
1218 temp2 = 0;
1219 ip = m.begin() + (j + 1) * j / 2 + j - 1;
1220 for(k = 0; k < nrow - j; ip += 1 + j + k++)
1221 {
1222 temp2 += x[k] * *ip;
1223 }
1224 *mjj -= temp2;
1225 }
1226 }
1227 else
1228 {
1229 if(piv[j - 1] != 0)
1230 {
1231 std::ostringstream message;
1232 message << "Error in pivot: " << piv[j - 1];
1233 G4Exception(
"G4ErrorSymMatrix::invertBunchKaufman()",
1235 }
1236 ss = 2;
1237 if(j < nrow)
1238 {
1239 ip = m.begin() + (j + 1) * j / 2 + j - 1;
1240 for(i = 0; i < nrow - j; ip += 1 + j + i++)
1241 {
1242 x[i] = *ip;
1243 }
1244 for(i = j + 1; i <= nrow; i++)
1245 {
1246 temp2 = 0;
1247 ip = m.begin() + i * (i - 1) / 2 + j;
1248 for(k = 0; k <= i - j - 1; k++)
1249 {
1250 temp2 += *ip++ * x[k];
1251 }
1252 for(ip += i - 1; k < nrow - j; ip += 1 + j + k++)
1253 {
1254 temp2 += *ip * x[k];
1255 }
1256 *(m.begin() + i * (i - 1) / 2 + j - 1) = -temp2;
1257 }
1258 temp2 = 0;
1259 ip = m.begin() + (j + 1) * j / 2 + j - 1;
1260 for(k = 0; k < nrow - j; ip += 1 + j + k++)
1261 {
1262 temp2 += x[k] * *ip;
1263 }
1264 *mjj -= temp2;
1265 temp2 = 0;
1266 ip = m.begin() + (j + 1) * j / 2 + j - 2;
1267 for(i = j + 1; i <= nrow; ip += i++)
1268 {
1269 temp2 += *ip * *(ip + 1);
1270 }
1271 *(mjj - 1) -= temp2;
1272 ip = m.begin() + (j + 1) * j / 2 + j - 2;
1273 for(i = 0; i < nrow - j; ip += 1 + j + i++)
1274 {
1275 x[i] = *ip;
1276 }
1277 for(i = j + 1; i <= nrow; i++)
1278 {
1279 temp2 = 0;
1280 ip = m.begin() + i * (i - 1) / 2 + j;
1281 for(k = 0; k <= i - j - 1; k++)
1282 {
1283 temp2 += *ip++ * x[k];
1284 }
1285 for(ip += i - 1; k < nrow - j; ip += 1 + j + k++)
1286 {
1287 temp2 += *ip * x[k];
1288 }
1289 *(m.begin() + i * (i - 1) / 2 + j - 2) = -temp2;
1290 }
1291 temp2 = 0;
1292 ip = m.begin() + (j + 1) * j / 2 + j - 2;
1293 for(k = 0; k < nrow - j; ip += 1 + j + k++)
1294 {
1295 temp2 += x[k] * *ip;
1296 }
1297 *(mjj - j) -= temp2;
1298 }
1299 }
1300
1301
1302
1303
1304 pivrow = (piv[j - 1] == 0) ? -piv[j - 2] : piv[j - 1];
1305 ip = m.begin() + pivrow * (pivrow - 1) / 2 + j;
1306 for(i = j + 1; i < pivrow; i++, ip++)
1307 {
1308 temp1 = *(m.begin() + i * (i - 1) / 2 + j - 1);
1309 *(m.begin() + i * (i - 1) / 2 + j - 1) = *ip;
1310 *ip = temp1;
1311 }
1312 temp1 = *mjj;
1313 *mjj = *(m.begin() + pivrow * (pivrow - 1) / 2 + pivrow - 1);
1314 *(m.begin() + pivrow * (pivrow - 1) / 2 + pivrow - 1) = temp1;
1315 if(ss == 2)
1316 {
1317 temp1 = *(mjj - 1);
1318 *(mjj - 1) = *(m.begin() + pivrow * (pivrow - 1) / 2 + j - 2);
1319 *(m.begin() + pivrow * (pivrow - 1) / 2 + j - 2) = temp1;
1320 }
1321
1322 ip = m.begin() + (pivrow + 1) * pivrow / 2 + j - 1;
1323 iq = ip + pivrow - j;
1324 for(i = pivrow + 1; i <= nrow; ip += i, iq += i++)
1325 {
1326 temp1 = *iq;
1327 *iq = *ip;
1328 *ip = temp1;
1329 }
1330 }
1331
1332 return;
1333}
G4double epsilon(G4double density, G4double temperature)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)