827{
828
829
830
831
832
833
834
835
838
839
840
841
842
843
844
845 static const G4int max_array = 25;
847 if (!xvec) xvec = new std::vector<G4double> (max_array) ;
849 if (!pivv) pivv = new std::vector<G4int> (max_array) ;
850 typedef std::vector<G4int>::iterator pivIter;
851 if (xvec->size() < static_cast<unsigned int>(nrow)) xvec->resize(nrow);
852 if (pivv->size() < static_cast<unsigned int>(nrow)) pivv->resize(nrow);
853
854
855
856
858
859 pivIter piv = pivv->begin();
860
861
867
868
869
870
871
872 for (i = 0; i < nrow; i++)
873 {
874 piv[i] = i+1;
875 }
876
877 ifail = 0;
878
879
880
881
882
883 for (j=1; j < nrow; j+=ss)
884 {
885 mjj = m.begin() + j*(j-1)/2 + j-1;
887 pivrow = j+1;
888 ip = m.begin() + (j+1)*j/2 + j-1;
889 for (i=j+1; i <= nrow ; ip += i++)
890 {
891 if (std::fabs(*ip) >
lambda)
892 {
894 pivrow = i;
895 }
896 }
897 if (lambda == 0 )
898 {
899 if (*mjj == 0)
900 {
901 ifail = 1;
902 return;
903 }
904 ss=1;
905 *mjj = 1./ *mjj;
906 }
907 else
908 {
909 if (std::fabs(*mjj) >= lambda*alpha)
910 {
911 ss=1;
912 pivrow=j;
913 }
914 else
915 {
916 sigma = 0;
917 ip = m.begin() + pivrow*(pivrow-1)/2+j-1;
918 for (k=j; k < pivrow; k++)
919 {
920 if (std::fabs(*ip) > sigma)
921 sigma = std::fabs(*ip);
922 ip++;
923 }
925 {
926 ss=1;
927 pivrow = j;
928 }
929 else if (std::fabs(*(m.begin()+pivrow*(pivrow-1)/2+pivrow-1))
931 { ss=1; }
932 else
933 { ss=2; }
934 }
935 if (pivrow == j)
936 {
937 piv[j-1] = pivrow;
938 if (*mjj == 0)
939 {
940 ifail=1;
941 return;
942 }
943 temp2 = *mjj = 1./ *mjj;
944
945
946 for (i=j+1; i <= nrow; i++)
947 {
948 temp1 = *(m.begin() + i*(i-1)/2 + j-1) * temp2;
949 ip = m.begin()+i*(i-1)/2+j;
950 for (k=j+1; k<=i; k++)
951 {
952 *ip -= temp1 * *(m.begin() + k*(k-1)/2 + j-1);
954 { *ip=0; }
955 ip++;
956 }
957 }
958
959 ip = m.begin() + (j+1)*j/2 + j-1;
960 for (i=j+1; i <= nrow; ip += i++)
961 {
962 *ip *= temp2;
963 }
964 }
965 else if (ss==1)
966 {
967 piv[j-1] = pivrow;
968
969
970
971 ip = m.begin() + pivrow*(pivrow-1)/2 + j;
972 for (i=j+1; i < pivrow; i++, ip++)
973 {
974 temp1 = *(m.begin() + i*(i-1)/2 + j-1);
975 *(m.begin() + i*(i-1)/2 + j-1)= *ip;
976 *ip = temp1;
977 }
978 temp1 = *mjj;
979 *mjj = *(m.begin()+pivrow*(pivrow-1)/2+pivrow-1);
980 *(m.begin()+pivrow*(pivrow-1)/2+pivrow-1) = temp1;
981 ip = m.begin() + (pivrow+1)*pivrow/2 + j-1;
982 iq = ip + pivrow-j;
983 for (i = pivrow+1; i <= nrow; ip += i, iq += i++)
984 {
985 temp1 = *iq;
986 *iq = *ip;
987 *ip = temp1;
988 }
989
990 if (*mjj == 0)
991 {
992 ifail = 1;
993 return;
994 }
995 temp2 = *mjj = 1./ *mjj;
996
997
998 for (i = j+1; i <= nrow; i++)
999 {
1000 temp1 = *(m.begin() + i*(i-1)/2 + j-1) * temp2;
1001 ip = m.begin()+i*(i-1)/2+j;
1002 for (k=j+1; k<=i; k++)
1003 {
1004 *ip -= temp1 * *(m.begin() + k*(k-1)/2 + j-1);
1005 if (std::fabs(*ip) <=
epsilon)
1006 { *ip=0; }
1007 ip++;
1008 }
1009 }
1010
1011 ip = m.begin() + (j+1)*j/2 + j-1;
1012 for (i=j+1; i<=nrow; ip += i++)
1013 {
1014 *ip *= temp2;
1015 }
1016 }
1017 else
1018 {
1019 piv[j-1] = -pivrow;
1020 piv[j] = 0;
1021
1022 if (j+1 != pivrow)
1023 {
1024
1025
1026 ip = m.begin() + pivrow*(pivrow-1)/2 + j+1;
1027 for (i=j+2; i < pivrow; i++, ip++)
1028 {
1029 temp1 = *(m.begin() + i*(i-1)/2 + j);
1030 *(m.begin() + i*(i-1)/2 + j) = *ip;
1031 *ip = temp1;
1032 }
1033 temp1 = *(mjj + j + 1);
1034 *(mjj + j + 1) =
1035 *(m.begin() + pivrow*(pivrow-1)/2 + pivrow-1);
1036 *(m.begin() + pivrow*(pivrow-1)/2 + pivrow-1) = temp1;
1037 temp1 = *(mjj + j);
1038 *(mjj + j) = *(m.begin() + pivrow*(pivrow-1)/2 + j-1);
1039 *(m.begin() + pivrow*(pivrow-1)/2 + j-1) = temp1;
1040 ip = m.begin() + (pivrow+1)*pivrow/2 + j;
1041 iq = ip + pivrow-(j+1);
1042 for (i = pivrow+1; i <= nrow; ip += i, iq += i++)
1043 {
1044 temp1 = *iq;
1045 *iq = *ip;
1046 *ip = temp1;
1047 }
1048 }
1049
1050 temp2 = *mjj * *(mjj + j + 1) - *(mjj + j) * *(mjj + j);
1051 if (temp2 == 0)
1052 {
1055 "Error in pivot choice!");
1056 }
1057 temp2 = 1. / temp2;
1058
1059
1060
1061
1062 temp1 = *mjj;
1063 *mjj = *(mjj + j + 1) * temp2;
1064 *(mjj + j + 1) = temp1 * temp2;
1065 *(mjj + j) = - *(mjj + j) * temp2;
1066
1067 if (j < nrow-1)
1068 {
1069
1070 for (i=j+2; i <= nrow ; i++)
1071 {
1072 ip = m.begin() + i*(i-1)/2 + j-1;
1073 temp1 = *ip * *mjj + *(ip + 1) * *(mjj + j);
1074 if (std::fabs(temp1 ) <=
epsilon)
1075 { temp1 = 0; }
1076 temp2 = *ip * *(mjj + j) + *(ip + 1) * *(mjj + j + 1);
1077 if (std::fabs(temp2 ) <=
epsilon)
1078 { temp2 = 0; }
1079 for (k = j+2; k <= i ; k++)
1080 {
1081 ip = m.begin() + i*(i-1)/2 + k-1;
1082 iq = m.begin() + k*(k-1)/2 + j-1;
1083 *ip -= temp1 * *iq + temp2 * *(iq+1);
1084 if (std::fabs(*ip) <=
epsilon)
1085 { *ip = 0; }
1086 }
1087 }
1088
1089 for (i=j+2; i <= nrow ; i++)
1090 {
1091 ip = m.begin() + i*(i-1)/2 + j-1;
1092 temp1 = *ip * *mjj + *(ip+1) * *(mjj + j);
1093 if (std::fabs(temp1) <=
epsilon)
1094 { temp1 = 0; }
1095 *(ip+1) = *ip * *(mjj + j) + *(ip+1) * *(mjj + j + 1);
1096 if (std::fabs(*(ip+1)) <=
epsilon)
1097 { *(ip+1) = 0; }
1098 *ip = temp1;
1099 }
1100 }
1101 }
1102 }
1103 }
1104
1105 if (j == nrow)
1106 {
1107 mjj = m.begin() + j*(j-1)/2 + j-1;
1108 if (*mjj == 0)
1109 {
1110 ifail = 1;
1111 return;
1112 }
1113 else
1114 {
1115 *mjj = 1. / *mjj;
1116 }
1117 }
1118
1119
1120
1121 for (j = nrow ; j >= 1 ; j -= ss)
1122 {
1123 mjj = m.begin() + j*(j-1)/2 + j-1;
1124 if (piv[j-1] > 0)
1125 {
1126 ss = 1;
1127 if (j < nrow)
1128 {
1129 ip = m.begin() + (j+1)*j/2 + j-1;
1130 for (i=0; i < nrow-j; ip += 1+j+i++)
1131 {
1132 x[i] = *ip;
1133 }
1134 for (i=j+1; i<=nrow ; i++)
1135 {
1136 temp2=0;
1137 ip = m.begin() + i*(i-1)/2 + j;
1138 for (k=0; k <= i-j-1; k++)
1139 { temp2 += *ip++ * x[k]; }
1140 for (ip += i-1; k < nrow-j; ip += 1+j+k++)
1141 { temp2 += *ip * x[k]; }
1142 *(m.begin()+ i*(i-1)/2 + j-1) = -temp2;
1143 }
1144 temp2 = 0;
1145 ip = m.begin() + (j+1)*j/2 + j-1;
1146 for (k=0; k < nrow-j; ip += 1+j+k++)
1147 { temp2 += x[k] * *ip; }
1148 *mjj -= temp2;
1149 }
1150 }
1151 else
1152 {
1153 if (piv[j-1] != 0)
1154 {
1155 std::ostringstream message;
1156 message << "Error in pivot: " << piv[j-1];
1157 G4Exception(
"G4ErrorSymMatrix::invertBunchKaufman()",
1159 }
1160 ss=2;
1161 if (j < nrow)
1162 {
1163 ip = m.begin() + (j+1)*j/2 + j-1;
1164 for (i=0; i < nrow-j; ip += 1+j+i++)
1165 {
1166 x[i] = *ip;
1167 }
1168 for (i=j+1; i<=nrow ; i++)
1169 {
1170 temp2 = 0;
1171 ip = m.begin() + i*(i-1)/2 + j;
1172 for (k=0; k <= i-j-1; k++)
1173 { temp2 += *ip++ * x[k]; }
1174 for (ip += i-1; k < nrow-j; ip += 1+j+k++)
1175 { temp2 += *ip * x[k]; }
1176 *(m.begin()+ i*(i-1)/2 + j-1) = -temp2;
1177 }
1178 temp2 = 0;
1179 ip = m.begin() + (j+1)*j/2 + j-1;
1180 for (k=0; k < nrow-j; ip += 1+j+k++)
1181 { temp2 += x[k] * *ip; }
1182 *mjj -= temp2;
1183 temp2 = 0;
1184 ip = m.begin() + (j+1)*j/2 + j-2;
1185 for (i=j+1; i <= nrow; ip += i++)
1186 { temp2 += *ip * *(ip+1); }
1187 *(mjj-1) -= temp2;
1188 ip = m.begin() + (j+1)*j/2 + j-2;
1189 for (i=0; i < nrow-j; ip += 1+j+i++)
1190 {
1191 x[i] = *ip;
1192 }
1193 for (i=j+1; i <= nrow ; i++)
1194 {
1195 temp2 = 0;
1196 ip = m.begin() + i*(i-1)/2 + j;
1197 for (k=0; k <= i-j-1; k++)
1198 { temp2 += *ip++ * x[k]; }
1199 for (ip += i-1; k < nrow-j; ip += 1+j+k++)
1200 { temp2 += *ip * x[k]; }
1201 *(m.begin()+ i*(i-1)/2 + j-2)= -temp2;
1202 }
1203 temp2 = 0;
1204 ip = m.begin() + (j+1)*j/2 + j-2;
1205 for (k=0; k < nrow-j; ip += 1+j+k++)
1206 { temp2 += x[k] * *ip; }
1207 *(mjj-j) -= temp2;
1208 }
1209 }
1210
1211
1212
1213
1214 pivrow = (piv[j-1]==0)? -piv[j-2] : piv[j-1];
1215 ip = m.begin() + pivrow*(pivrow-1)/2 + j;
1216 for (i=j+1;i < pivrow; i++, ip++)
1217 {
1218 temp1 = *(m.begin() + i*(i-1)/2 + j-1);
1219 *(m.begin() + i*(i-1)/2 + j-1) = *ip;
1220 *ip = temp1;
1221 }
1222 temp1 = *mjj;
1223 *mjj = *(m.begin() + pivrow*(pivrow-1)/2 + pivrow-1);
1224 *(m.begin() + pivrow*(pivrow-1)/2 + pivrow-1) = temp1;
1225 if (ss==2)
1226 {
1227 temp1 = *(mjj-1);
1228 *(mjj-1) = *( m.begin() + pivrow*(pivrow-1)/2 + j-2);
1229 *( m.begin() + pivrow*(pivrow-1)/2 + j-2) = temp1;
1230 }
1231
1232 ip = m.begin() + (pivrow+1)*pivrow/2 + j-1;
1233 iq = ip + pivrow-j;
1234 for (i = pivrow+1; i <= nrow; ip += i, iq += i++)
1235 {
1236 temp1 = *iq;
1237 *iq = *ip;
1238 *ip = temp1;
1239 }
1240 }
1241
1242 return;
1243}
double epsilon(double density, double temperature)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)