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