11#include "CLHEP/Matrix/defs.h"
12#include "CLHEP/Random/Random.h"
13#include "CLHEP/Matrix/SymMatrix.h"
14#include "CLHEP/Matrix/Matrix.h"
15#include "CLHEP/Matrix/DiagMatrix.h"
16#include "CLHEP/Matrix/Vector.h"
18#ifdef HEP_DEBUG_INLINE
19#include "CLHEP/Matrix/SymMatrix.icc"
26#define SIMPLE_UOP(OPER) \
27 HepMatrix::mIter a=m.begin(); \
28 HepMatrix::mIter e=m.begin()+num_size(); \
29 for(;a<e; a++) (*a) OPER t;
31#define SIMPLE_BOP(OPER) \
32 HepMatrix::mIter a=m.begin(); \
33 HepMatrix::mcIter b=hm2.m.begin(); \
34 HepMatrix::mcIter e=m.begin()+num_size(); \
35 for(;a<e; a++, b++) (*a) OPER (*b);
37#define SIMPLE_TOP(OPER) \
38 HepMatrix::mcIter a=hm1.m.begin(); \
39 HepMatrix::mcIter b=hm2.m.begin(); \
40 HepMatrix::mIter t=mret.m.begin(); \
41 HepMatrix::mcIter e=hm1.m.begin()+hm1.num_size(); \
42 for( ;a<e; a++, b++, t++) (*t) = (*a) OPER (*b);
44#define CHK_DIM_2(r1,r2,c1,c2,fun) \
45 if (r1!=r2 || c1!=c2) { \
46 HepGenMatrix::error("Range error in SymMatrix function " #fun "(1)."); \
49#define CHK_DIM_1(c1,r2,fun) \
51 HepGenMatrix::error("Range error in SymMatrix function " #fun "(2)."); \
57 : m(p*(p+1)/2), nrow(p)
59 size_ = nrow * (nrow+1) / 2;
64 : m(p*(p+1)/2), nrow(p)
66 size_ = nrow * (nrow+1) / 2;
77 for(
int i=0;i<nrow;++i) {
78 a = m.begin() + (i+1)*i/2 + i;
84 error(
"SymMatrix: initialization must be either 0 or 1.");
89 : m(p*(p+1)/2), nrow(p)
91 size_ = nrow * (nrow+1) / 2;
94 for(;a<b;a++) *a = r();
104 :
HepGenMatrix(hm1), m(hm1.size_), nrow(hm1.nrow), size_(hm1.size_)
110 : m(hm1.nrow*(hm1.nrow+1)/2), nrow(hm1.nrow)
112 size_ = nrow * (nrow+1) / 2;
119 for(
int r=1;r<=n;r++) {
121 if(r<n) mrr += (r+1);
132#ifdef HEP_GNU_OPTIMIZED_RETURN
133return mret(max_row-min_row+1);
139 if(max_row > num_row())
140 error(
"HepSymMatrix::sub: Index out of range");
143 int rowsize=mret.num_row();
144 for(
int irow=1; irow<=rowsize; irow++) {
146 for(
int icol=0; icol<irow; ++icol) {
149 if(irow<rowsize) b1 += irow+min_row-1;
158 error(
"HepSymMatrix::sub: Index out of range");
162 for(
int irow=1; irow<=rowsize; irow++) {
164 for(
int icol=0; icol<irow; ++icol) {
167 if(irow<rowsize) b1 += irow+min_row-1;
175 error(
"HepSymMatrix::sub: Index out of range");
179 for(
int irow=1; irow<=rowsize; ++irow) {
181 for(
int icol=0; icol<irow; ++icol) {
184 if(irow<rowsize) b1 += irow+row-1;
194#ifdef HEP_GNU_OPTIMIZED_RETURN
212#ifdef HEP_GNU_OPTIMIZED_RETURN
222 for(;a<e; a++, b++) (*b) = -(*a);
229#ifdef HEP_GNU_OPTIMIZED_RETURN
241#ifdef HEP_GNU_OPTIMIZED_RETURN
254#ifdef HEP_GNU_OPTIMIZED_RETURN
255 return mret(hm1.nrow);
271#ifdef HEP_GNU_OPTIMIZED_RETURN
279 hm1.num_col(),hm2.
num_col(),-);
284#ifdef HEP_GNU_OPTIMIZED_RETURN
298#ifdef HEP_GNU_OPTIMIZED_RETURN
317#ifdef HEP_GNU_OPTIMIZED_RETURN
329#ifdef HEP_GNU_OPTIMIZED_RETURN
341#ifdef HEP_GNU_OPTIMIZED_RETURN
354#ifdef HEP_GNU_OPTIMIZED_RETURN
365 for(mit1=hm1.m.begin();
370 for(
int step=1;step<=hm2.
num_row();++step)
377 temp+=*(sp++)*(*(mit2++));
380 for(
int stept=step+1;stept<=hm2.
num_row();stept++)
382 temp+=*sp*(*(mit2++));
383 if(stept<hm2.
num_row()) sp+=stept;
393#ifdef HEP_GNU_OPTIMIZED_RETURN
405 for(step=1,snp=hm1.m.begin();step<=hm1.
num_row();snp+=step++)
406 for(mit1=hm2.m.begin();mit1<hm2.m.begin()+hm2.
num_col();mit1++)
413 temp+=*mit2*(*(sp++));
420 for(stept=step+1;stept<=hm1.
num_row();stept++)
435#ifdef HEP_GNU_OPTIMIZED_RETURN
443 int step1,stept1,step2,stept2;
448 for(step1=1;step1<=hm1.
num_row();++step1) {
450 for(step2=1;step2<=hm2.
num_row();++step2)
458 while(sp1<snp1+step1) {
459 temp+=(*(sp1++))*(*(sp2++));
462 for(stept1=step1+1;stept1!=step2+1;++stept1) {
463 temp+=(*sp1)*(*(sp2++));
464 if(stept1<hm2.
num_row()) sp1+=stept1;
468 for(stept2=step2+1;stept2<=hm2.
num_row();stept1++,stept2++) {
480 temp+=(*(sp1++))*(*(sp2++));
484 for(stept2=step2+1;stept2!=step1+1;stept2++) {
485 temp+=(*(sp1++))*(*sp2);
486 if(stept2<hm1.
num_row()) sp2+=stept2;
490 for(stept1=step1+1;stept1<=hm1.
num_row();stept1++,stept2++) {
502 if(step1<hm1.
num_row()) snp1+=step1;
508#ifdef HEP_GNU_OPTIMIZED_RETURN
520 for(step=1,snp=hm1.m.begin();step<=hm1.
num_row();++step)
527 temp+=*(sp++)*(*(vpt++));
528 if(step<hm1.
num_row()) sp+=step-1;
529 for(stept=step+1;stept<=hm1.
num_row();stept++)
531 temp+=*sp*(*(vpt++));
532 if(stept<hm1.
num_row()) sp+=stept;
540#ifdef HEP_GNU_OPTIMIZED_RETURN
549 for(vt1=v.m.begin();vt1<v.m.begin()+v.
num_row();vt1++)
550 for(vt2=v.m.begin();vt2<=vt1;vt2++)
551 *(mr++)=(*vt1)*(*vt2);
564 for(
int j=0; j!=nrow; ++j) {
565 for(
int k=0; k<=j; ++k) {
568 if(k!=j) m[k*nrow+j] += *sjk;
587 for(
int j=0; j!=nrow; ++j) {
588 for(
int k=0; k<=j; ++k) {
591 if(k!=j) m[k*nrow+j] -= *sjk;
620 nrow = ncol = hm1.nrow;
621 if(nrow*ncol != size_)
627 mcIter sjk = hm1.m.begin();
629 for(
int j=0; j!=nrow; ++j) {
630 for(
int k=0; k<=j; ++k) {
635 if(k!=j) m[k*nrow+j] = *sjk;
659 size_ = nrow * (nrow+1) / 2;
666 for(
int r=1; r<=nrow; r++) {
668 if(r<nrow) mrr += (r+1);
680 if(os.flags() & std::ios::fixed)
681 width = os.precision()+3;
683 width = os.precision()+7;
684 for(
int irow = 1; irow<= q.
num_row(); irow++)
686 for(
int icol = 1; icol <= q.
num_col(); icol++)
689 os << q(irow,icol) <<
" ";
697apply(
double (*
f)(
double,
int,
int))
const
698#ifdef HEP_GNU_OPTIMIZED_RETURN
699return mret(num_row());
707 for(
int ir=1;ir<=num_row();ir++) {
708 for(
int ic=1;ic<=ir;ic++) {
709 *(b++) = (*
f)(*(a++), ir, ic);
720 size_ = nrow * (nrow+1) / 2;
725 for(
int r=1;r<=nrow;r++) {
727 for(
int c=1;c<=r;c++) {
730 if(r<nrow) a += nrow;
735#ifdef HEP_GNU_OPTIMIZED_RETURN
748 for(
int r=1;r<=mret.num_row();r++) {
750 for(
int c=1;c<=r;c++) {
754 for(
int i=1;i<=hm1.
num_col();i++) {
755 tmp+=(*(tempri++))*(*(hm1ci++));
766#ifdef HEP_GNU_OPTIMIZED_RETURN
777 for(
int r=1;r<=mret.num_row();r++) {
786 tmp+=(*(tempri++))*(*(hm1ci++));
788 for(i=c;i<=hm1.
num_col();i++) {
789 tmp+=(*(tempri++))*(*(hm1ci));
790 if(i<hm1.
num_col()) hm1ci += i;
809 for(;a<e;) mret += (*(a++)) * (*(b++));
814#ifdef HEP_GNU_OPTIMIZED_RETURN
822 int n = hm1.num_col();
825 for(
int r=1;r<=mret.num_row();r++) {
827 for(
int c=1;c<=r;c++) {
829 for(
int i=1;i<=hm1.num_row();i++) {
832 tmp+=(*(tempir))*(*(hm1ic));
851 double c11,c12,c13,c22,c23,c33;
852 c11 = (*(m.begin()+2)) * (*(m.begin()+5)) - (*(m.begin()+4)) * (*(m.begin()+4));
853 c12 = (*(m.begin()+4)) * (*(m.begin()+3)) - (*(m.begin()+1)) * (*(m.begin()+5));
854 c13 = (*(m.begin()+1)) * (*(m.begin()+4)) - (*(m.begin()+2)) * (*(m.begin()+3));
855 c22 = (*(m.begin()+5)) * (*m.begin()) - (*(m.begin()+3)) * (*(m.begin()+3));
856 c23 = (*(m.begin()+3)) * (*(m.begin()+1)) - (*(m.begin()+4)) * (*m.begin());
857 c33 = (*m.begin()) * (*(m.begin()+2)) - (*(m.begin()+1)) * (*(m.begin()+1));
858 t1 = fabs(*m.begin());
859 t2 = fabs(*(m.begin()+1));
860 t3 = fabs(*(m.begin()+3));
863 temp = *(m.begin()+3);
864 det = c23*c12-c22*c13;
867 det = c22*c33-c23*c23;
869 }
else if (t3 >= t2) {
870 temp = *(m.begin()+3);
871 det = c23*c12-c22*c13;
873 temp = *(m.begin()+1);
874 det = c13*c23-c12*c33;
881 double ds = temp/det;
894 double det, temp, ds;
895 det = (*m.begin())*(*(m.begin()+2)) - (*(m.begin()+1))*(*(m.begin()+1));
901 *(m.begin()+1) *= -ds;
902 temp = ds*(*(m.begin()+2));
903 *(m.begin()+2) = ds*(*m.begin());
909 if ((*m.begin())==0) {
913 *m.begin() = 1.0/(*m.begin());
941 static const int max_array = 20;
943 static std::vector<int> ir_vec (max_array+1);
944 if (ir_vec.size() <=
static_cast<unsigned int>(nrow)) ir_vec.resize(nrow+1);
945 int * ir = &ir_vec[0];
949 int i = mt.dfact_matrix(det, ir);
956 for (
int i=0; i<nrow; i++)
957 t += *(m.begin() + (i+3)*i/2);
979 static const int max_array = 25;
981 static std::vector<double> xvec (max_array);
982 static std::vector<int> pivv (max_array);
983 typedef std::vector<int>::iterator pivIter;
985 static std::vector<double,Alloc<double,25> > xvec (max_array);
986 static std::vector<int, Alloc<int, 25> > pivv (max_array);
987 typedef std::vector<int,Alloc<int,25> >::iterator pivIter;
989 if (xvec.size() <
static_cast<unsigned int>(nrow)) xvec.resize(nrow);
990 if (pivv.size() <
static_cast<unsigned int>(nrow)) pivv.resize(nrow);
995 mIter x = xvec.begin();
997 pivIter piv = pivv.begin();
1000 double temp1, temp2;
1002 double lambda, sigma;
1003 const double alpha = .6404;
1004 const double epsilon = 32*DBL_EPSILON;
1010 for (i = 0; i < nrow; ++i) piv[i] = i+1;
1018 for (j=1; j < nrow; j+=is)
1020 mjj = m.begin() + j*(j-1)/2 + j-1;
1024 for (i=j+1; i <= nrow ; ++i) {
1026 ip = m.begin() + (i-1)*i/2 + j-1;
1027 if (fabs(*ip) > lambda) {
1040 if (fabs(*mjj) >= lambda*alpha) {
1045 ip = m.begin() + pivrow*(pivrow-1)/2+j-1;
1046 for (k=j; k < pivrow; k++) {
1047 if (fabs(*ip) > sigma) sigma = fabs(*ip);
1050 if (sigma * fabs(*mjj) >= alpha * lambda * lambda) {
1053 }
else if (fabs(*(m.begin()+pivrow*(pivrow-1)/2+pivrow-1))
1066 temp2 = *mjj = 1./ *mjj;
1069 for (i=j+1; i <= nrow; i++) {
1070 temp1 = *(m.begin() + i*(i-1)/2 + j-1) * temp2;
1071 ip = m.begin()+i*(i-1)/2+j;
1072 for (k=j+1; k<=i; k++) {
1073 *ip -= temp1 * *(m.begin() + k*(k-1)/2 + j-1);
1074 if (fabs(*ip) <= epsilon)
1081 for (i=j+1; i <= nrow; ++i) {
1083 ip = m.begin() + (i-1)*i/2 + j-1;
1091 ip = m.begin() + pivrow*(pivrow-1)/2 + j;
1092 for (i=j+1; i < pivrow; i++, ip++) {
1093 temp1 = *(m.begin() + i*(i-1)/2 + j-1);
1094 *(m.begin() + i*(i-1)/2 + j-1)= *ip;
1098 *mjj = *(m.begin()+pivrow*(pivrow-1)/2+pivrow-1);
1099 *(m.begin()+pivrow*(pivrow-1)/2+pivrow-1) = temp1;
1100 ip = m.begin() + (pivrow+1)*pivrow/2 + j-1;
1102 for (i = pivrow+1; i <= nrow; ip += i, iq += i++) {
1112 temp2 = *mjj = 1./ *mjj;
1115 for (i = j+1; i <= nrow; i++) {
1116 temp1 = *(m.begin() + i*(i-1)/2 + j-1) * temp2;
1117 ip = m.begin()+i*(i-1)/2+j;
1118 for (k=j+1; k<=i; k++) {
1119 *ip -= temp1 * *(m.begin() + k*(k-1)/2 + j-1);
1120 if (fabs(*ip) <= epsilon)
1127 for (i=j+1; i <= nrow; ++i) {
1129 ip = m.begin() + (i-1)*i/2 + j-1;
1136 if (j+1 != pivrow) {
1139 ip = m.begin() + pivrow*(pivrow-1)/2 + j+1;
1140 for (i=j+2; i < pivrow; i++, ip++) {
1141 temp1 = *(m.begin() + i*(i-1)/2 + j);
1142 *(m.begin() + i*(i-1)/2 + j) = *ip;
1145 temp1 = *(mjj + j + 1);
1147 *(m.begin() + pivrow*(pivrow-1)/2 + pivrow-1);
1148 *(m.begin() + pivrow*(pivrow-1)/2 + pivrow-1) = temp1;
1150 *(mjj + j) = *(m.begin() + pivrow*(pivrow-1)/2 + j-1);
1151 *(m.begin() + pivrow*(pivrow-1)/2 + j-1) = temp1;
1152 ip = m.begin() + (pivrow+1)*pivrow/2 + j;
1153 iq = ip + pivrow-(j+1);
1154 for (i = pivrow+1; i <= nrow; ip += i, iq += i++) {
1161 temp2 = *mjj * *(mjj + j + 1) - *(mjj + j) * *(mjj + j);
1164 <<
"SymMatrix::bunch_invert: error in pivot choice"
1171 *mjj = *(mjj + j + 1) * temp2;
1172 *(mjj + j + 1) = temp1 * temp2;
1173 *(mjj + j) = - *(mjj + j) * temp2;
1177 for (i=j+2; i <= nrow ; i++) {
1178 ip = m.begin() + i*(i-1)/2 + j-1;
1179 temp1 = *ip * *mjj + *(ip + 1) * *(mjj + j);
1180 if (fabs(temp1 ) <= epsilon) temp1 = 0;
1181 temp2 = *ip * *(mjj + j) + *(ip + 1) * *(mjj + j + 1);
1182 if (fabs(temp2 ) <= epsilon) temp2 = 0;
1183 for (k = j+2; k <= i ; k++) {
1184 ip = m.begin() + i*(i-1)/2 + k-1;
1185 iq = m.begin() + k*(k-1)/2 + j-1;
1186 *ip -= temp1 * *iq + temp2 * *(iq+1);
1187 if (fabs(*ip) <= epsilon)
1192 for (i=j+2; i <= nrow ; i++) {
1193 ip = m.begin() + i*(i-1)/2 + j-1;
1194 temp1 = *ip * *mjj + *(ip+1) * *(mjj + j);
1195 if (fabs(temp1) <= epsilon) temp1 = 0;
1196 *(ip+1) = *ip * *(mjj + j)
1197 + *(ip+1) * *(mjj + j + 1);
1198 if (fabs(*(ip+1)) <= epsilon) *(ip+1) = 0;
1207 mjj = m.begin() + j*(j-1)/2 + j-1;
1211 }
else { *mjj = 1. / *mjj; }
1216 for (j = nrow ; j >= 1 ; j -= is)
1218 mjj = m.begin() + j*(j-1)/2 + j-1;
1224 ip = m.begin() + (j+1)*j/2 - 1;
1225 for (i=0; i < nrow-j; ++i) {
1229 for (i=j+1; i<=nrow ; i++) {
1231 ip = m.begin() + i*(i-1)/2 + j;
1232 for (k=0; k <= i-j-1; k++) temp2 += *ip++ * x[k];
1236 for ( ; k < nrow-j; ++k) {
1238 temp2 += *ip * x[k];
1240 *(m.begin()+ i*(i-1)/2 + j-1) = -temp2;
1246 ip = m.begin() + (j+1)*j/2 - 1;
1247 for (k=0; k < nrow-j; ++k) {
1249 temp2 += x[k] * *ip;
1255 std::cerr <<
"error in piv" << piv[j-1] << std::endl;
1260 ip = m.begin() + (j+1)*j/2 - 1;
1261 for (i=0; i < nrow-j; ++i) {
1265 for (i=j+1; i<=nrow ; i++) {
1267 ip = m.begin() + i*(i-1)/2 + j;
1268 for (k=0; k <= i-j-1; k++)
1269 temp2 += *ip++ * x[k];
1270 for (ip += i-1; k < nrow-j; ip += 1+j+k++)
1271 temp2 += *ip * x[k];
1272 *(m.begin()+ i*(i-1)/2 + j-1) = -temp2;
1277 ip = m.begin() + (j+1)*j/2 - 1;
1278 for (k=0; k < nrow-j; ++k) {
1280 temp2 += x[k] * *ip;
1286 ip = m.begin() + (j+1)*j/2 - 2;
1287 for (i=j+1; i <= nrow; ++i) {
1289 temp2 += *ip * *(ip+1);
1294 ip = m.begin() + (j+1)*j/2 - 2;
1295 for (i=0; i < nrow-j; ++i) {
1299 for (i=j+1; i <= nrow ; i++) {
1301 ip = m.begin() + i*(i-1)/2 + j;
1302 for (k=0; k <= i-j-1; k++)
1303 temp2 += *ip++ * x[k];
1304 for (ip += i-1; k < nrow-j; ip += 1+j+k++)
1305 temp2 += *ip * x[k];
1306 *(m.begin()+ i*(i-1)/2 + j-2)= -temp2;
1312 ip = m.begin() + (j+1)*j/2 - 2;
1313 for (k=0; k < nrow-j; ++k) {
1315 temp2 += x[k] * *ip;
1324 pivrow = (piv[j-1]==0)? -piv[j-2] : piv[j-1];
1325 ip = m.begin() + pivrow*(pivrow-1)/2 + j;
1326 for (i=j+1;i < pivrow; i++, ip++) {
1327 temp1 = *(m.begin() + i*(i-1)/2 + j-1);
1328 *(m.begin() + i*(i-1)/2 + j-1) = *ip;
1332 *mjj = *(m.begin() + pivrow*(pivrow-1)/2 + pivrow-1);
1333 *(m.begin() + pivrow*(pivrow-1)/2 + pivrow-1) = temp1;
1336 *(mjj-1) = *( m.begin() + pivrow*(pivrow-1)/2 + j-2);
1337 *( m.begin() + pivrow*(pivrow-1)/2 + j-2) = temp1;
1341 if( pivrow < nrow ) {
1342 ip = m.begin() + (pivrow+1)*pivrow/2 + j-1;
1344 iq = ip + (pivrow-j);
1345 for (i = pivrow+1; i <= nrow; i++) {
#define CHK_DIM_2(r1, r2, c1, c2, fun)
#define CHK_DIM_1(c1, r2, fun)
std::vector< double, Alloc< double, 25 > >::const_iterator mcIter
std::vector< double, Alloc< double, 25 > >::iterator mIter
static void error(const char *s)
HepMatrix & operator=(const HepMatrix &)
virtual int num_col() const
virtual int num_row() const
HepMatrix & operator+=(const HepMatrix &)
HepMatrix & operator-=(const HepMatrix &)
virtual int num_size() const
HepSymMatrix & operator*=(double t)
double determinant() const
HepSymMatrix & operator+=(const HepSymMatrix &hm2)
void assign(const HepMatrix &hm2)
HepSymMatrix apply(double(*f)(double, int, int)) const
HepSymMatrix similarityT(const HepMatrix &hm1) const
HepSymMatrix & operator=(const HepSymMatrix &hm2)
HepSymMatrix sub(int min_row, int max_row) const
HepSymMatrix operator-() const
HepSymMatrix & operator-=(const HepSymMatrix &hm2)
HepSymMatrix similarity(const HepMatrix &hm1) const
void invertBunchKaufman(int &ifail)
HepSymMatrix & operator/=(double t)
virtual int num_row() const
HepSymMatrix vT_times_v(const HepVector &v)
std::ostream & operator<<(std::ostream &s, const HepDiagMatrix &q)
HepMatrix operator+(const HepMatrix &hm1, const HepDiagMatrix &d2)
HepMatrix operator-(const HepMatrix &hm1, const HepDiagMatrix &d2)
HepMatrix operator*(const HepMatrix &hm1, const HepDiagMatrix &hm2)
HepDiagMatrix dsum(const HepDiagMatrix &s1, const HepDiagMatrix &s2)