CLHEP 2.4.6.4
C++ Class Library for High Energy Physics
Loading...
Searching...
No Matches
Vector.cc
Go to the documentation of this file.
1// -*- C++ -*-
2// ---------------------------------------------------------------------------
3//
4
5#include <iostream>
6#include <string.h>
7
8#include "CLHEP/Matrix/defs.h"
9#include "CLHEP/Random/Random.h"
10#include "CLHEP/Vector/ThreeVector.h"
11#include "CLHEP/Matrix/Vector.h"
12#include "CLHEP/Matrix/Matrix.h"
13#include "CLHEP/Utility/thread_local.h"
14
15#ifdef HEP_DEBUG_INLINE
16#include "CLHEP/Matrix/Vector.icc"
17#endif
18
19namespace CLHEP {
20
21// Simple operation for all elements
22
23#define SIMPLE_UOP(OPER) \
24 HepGenMatrix::mIter a=m.begin(); \
25 HepGenMatrix::mIter e=m.begin()+num_size(); \
26 for(;a<e; a++) (*a) OPER t;
27
28#define SIMPLE_BOP(OPER) \
29 mIter a=m.begin(); \
30 mcIter b=hm2.m.begin(); \
31 mcIter e=m.begin()+num_size(); \
32 for(;a<e; a++, b++) (*a) OPER (*b);
33
34#define SIMPLE_TOP(OPER) \
35 HepGenMatrix::mcIter a=hm1.m.begin(); \
36 HepGenMatrix::mcIter b=hm2.m.begin(); \
37 HepGenMatrix::mIter t=mret.m.begin(); \
38 HepGenMatrix::mcIter e=hm1.m.begin()+hm1.num_size(); \
39 for( ;a<e; a++, b++, t++) (*t) = (*a) OPER (*b);
40
41#define CHK_DIM_2(r1,r2,c1,c2,fun) \
42 if (r1!=r2 || c1!=c2) { \
43 HepGenMatrix::error("Range error in Vector function " #fun "(1)."); \
44 }
45
46#define CHK_DIM_1(c1,r2,fun) \
47 if (c1!=r2) { \
48 HepGenMatrix::error("Range error in Vector function " #fun "(2)."); \
49 }
50
51// Constructors. (Default constructors are inlined and in .icc file)
52
54 : m(p), nrow(p)
55{
56}
57
59 : m(p), nrow(p)
60{
61 switch (init)
62 {
63 case 0:
64 m.assign(p,0);
65 break;
66
67 case 1:
68 {
69 mIter e = m.begin() + nrow;
70 for (mIter i=m.begin(); i<e; i++) *i = 1.0;
71 break;
72 }
73
74 default:
75 error("Vector: initialization must be either 0 or 1.");
76 }
77}
78
80 : m(p), nrow(p)
81{
82 HepGenMatrix::mIter a = m.begin();
83 HepGenMatrix::mIter b = m.begin() + nrow;
84 for(;a<b;a++) *a = r();
85}
86
87
88//
89// Destructor
90//
92}
93
95 : HepGenMatrix(hm1), m(hm1.nrow), nrow(hm1.nrow)
96{
97 m = hm1.m;
98}
99
100//
101// Copy constructor from the class of other precision
102//
103
104
106 : m(hm1.nrow), nrow(hm1.nrow)
107{
108 if (hm1.num_col() != 1)
109 error("Vector::Vector(Matrix) : Matrix is not Nx1");
110
111 m = hm1.m;
112}
113
114// trivial methods
115
116int HepVector::num_row() const {return nrow;}
117int HepVector::num_size() const {return nrow;}
118int HepVector::num_col() const { return 1; }
119
120// operator()
121
122#ifdef MATRIX_BOUND_CHECK
123double & HepVector::operator()(int row, int col)
124{
125 if( col!=1 || row<1 || row>nrow)
126 error("Range error in HepVector::operator(i,j)");
127#else
128double & HepVector::operator()(int row, int)
129{
130#endif
131
132 return *(m.begin()+(row-1));
133}
134
135#ifdef MATRIX_BOUND_CHECK
136const double & HepVector::operator()(int row, int col) const
137{
138 if( col!=1 || row<1 || row>nrow)
139 error("Range error in HepVector::operator(i,j)");
140#else
141const double & HepVector::operator()(int row, int) const
142{
143#endif
144
145 return *(m.begin()+(row-1));
146}
147
148// Sub matrix
149
150HepVector HepVector::sub(int min_row, int max_row) const
151#ifdef HEP_GNU_OPTIMIZED_RETURN
152return vret(max_row-min_row+1);
153{
154#else
155{
156 HepVector vret(max_row-min_row+1);
157#endif
158 if(max_row > num_row())
159 error("HepVector::sub: Index out of range");
160 HepGenMatrix::mIter a = vret.m.begin();
161 HepGenMatrix::mcIter b = m.begin() + min_row - 1;
162 HepGenMatrix::mIter e = vret.m.begin() + vret.num_row();
163 for(;a<e;) *(a++) = *(b++);
164 return vret;
165}
166
167HepVector HepVector::sub(int min_row, int max_row)
168{
169 HepVector vret(max_row-min_row+1);
170 if(max_row > num_row())
171 error("HepVector::sub: Index out of range");
172 HepGenMatrix::mIter a = vret.m.begin();
173 HepGenMatrix::mIter b = m.begin() + min_row - 1;
174 HepGenMatrix::mIter e = vret.m.begin() + vret.num_row();
175 for(;a<e;) *(a++) = *(b++);
176 return vret;
177}
178
179void HepVector::sub(int row,const HepVector &v1)
180{
181 if(row <1 || row+v1.num_row()-1 > num_row())
182 error("HepVector::sub: Index out of range");
183 HepGenMatrix::mcIter a = v1.m.begin();
184 HepGenMatrix::mIter b = m.begin() + row - 1;
185 HepGenMatrix::mcIter e = v1.m.begin() + v1.num_row();
186 for(;a<e;) *(b++) = *(a++);
187}
188
189//
190// Direct sum of two matricies
191//
192
194 const HepVector &hm2)
195#ifdef HEP_GNU_OPTIMIZED_RETURN
196 return mret(hm1.num_row() + hm2.num_row(), 0);
197{
198#else
199{
200 HepVector mret(hm1.num_row() + hm2.num_row(),
201 0);
202#endif
203 mret.sub(1,hm1);
204 mret.sub(hm1.num_row()+1,hm2);
205 return mret;
206}
207
208/* -----------------------------------------------------------------------
209 This section contains support routines for matrix.h. This section contains
210 The two argument functions +,-. They call the copy constructor and +=,-=.
211 ----------------------------------------------------------------------- */
213#ifdef HEP_GNU_OPTIMIZED_RETURN
214 return hm2(nrow);
215{
216#else
217{
218 HepVector hm2(nrow);
219#endif
220 HepGenMatrix::mcIter a=m.begin();
221 HepGenMatrix::mIter b=hm2.m.begin();
222 HepGenMatrix::mcIter e=m.begin()+num_size();
223 for(;a<e; a++, b++) (*b) = -(*a);
224 return hm2;
225}
226
227
228
230#ifdef HEP_GNU_OPTIMIZED_RETURN
231 return mret(hm2);
232{
233#else
234{
235 HepVector mret(hm2);
236#endif
237 CHK_DIM_2(hm1.num_row(),hm2.num_row(),hm1.num_col(),1,+);
238 mret += hm1;
239 return mret;
240}
241
243#ifdef HEP_GNU_OPTIMIZED_RETURN
244 return mret(hm1);
245{
246#else
247{
248 HepVector mret(hm1);
249#endif
250 CHK_DIM_2(hm1.num_row(),hm2.num_row(),1,hm2.num_col(),+);
251 mret += hm2;
252 return mret;
253}
254
256#ifdef HEP_GNU_OPTIMIZED_RETURN
257 return mret(hm1.num_row());
258{
259#else
260{
261 HepVector mret(hm1.num_row());
262#endif
263 CHK_DIM_1(hm1.num_row(),hm2.num_row(),+);
264 SIMPLE_TOP(+)
265 return mret;
266}
267
268//
269// operator -
270//
271
272HepVector operator-(const HepMatrix &hm1,const HepVector &hm2)
273#ifdef HEP_GNU_OPTIMIZED_RETURN
274 return mret;
275{
276#else
277{
278 HepVector mret;
279#endif
280 CHK_DIM_2(hm1.num_row(),hm2.num_row(),hm1.num_col(),1,-);
281 mret = hm1;
282 mret -= hm2;
283 return mret;
284}
285
287#ifdef HEP_GNU_OPTIMIZED_RETURN
288 return mret(hm1);
289{
290#else
291{
292 HepVector mret(hm1);
293#endif
294 CHK_DIM_2(hm1.num_row(),hm2.num_row(),1,hm2.num_col(),-);
295 mret -= hm2;
296 return mret;
297}
298
300#ifdef HEP_GNU_OPTIMIZED_RETURN
301 return mret(hm1.num_row());
302{
303#else
304{
305 HepVector mret(hm1.num_row());
306#endif
307 CHK_DIM_1(hm1.num_row(),hm2.num_row(),-);
308 SIMPLE_TOP(-)
309 return mret;
310}
311
312/* -----------------------------------------------------------------------
313 This section contains support routines for matrix.h. This file contains
314 The two argument functions *,/. They call copy constructor and then /=,*=.
315 ----------------------------------------------------------------------- */
316
317HepVector operator/(
318const HepVector &hm1,double t)
319#ifdef HEP_GNU_OPTIMIZED_RETURN
320 return mret(hm1);
321{
322#else
323{
324 HepVector mret(hm1);
325#endif
326 mret /= t;
327 return mret;
328}
329
330HepVector operator*(const HepVector &hm1,double t)
331#ifdef HEP_GNU_OPTIMIZED_RETURN
332 return mret(hm1);
333{
334#else
335{
336 HepVector mret(hm1);
337#endif
338 mret *= t;
339 return mret;
340}
341
342HepVector operator*(double t,const HepVector &hm1)
343#ifdef HEP_GNU_OPTIMIZED_RETURN
344 return mret(hm1);
345{
346#else
347{
348 HepVector mret(hm1);
349#endif
350 mret *= t;
351 return mret;
352}
353
355#ifdef HEP_GNU_OPTIMIZED_RETURN
356 return mret(hm1.num_row());
357{
358#else
359{
360 HepVector mret(hm1.num_row());
361#endif
362 CHK_DIM_1(hm1.num_col(),hm2.num_row(),*);
363 HepGenMatrix::mcIter hm1p,hm2p,vp;
365 double temp;
366 m3p=mret.m.begin();
367 for(hm1p=hm1.m.begin();hm1p<hm1.m.begin()+hm1.num_row()*hm1.num_col();hm1p=hm2p)
368 {
369 temp=0;
370 vp=hm2.m.begin();
371 hm2p=hm1p;
372 while(hm2p<hm1p+hm1.num_col())
373 temp+=(*(hm2p++))*(*(vp++));
374 *(m3p++)=temp;
375 }
376 return mret;
377}
378
380#ifdef HEP_GNU_OPTIMIZED_RETURN
381 return mret(hm1.num_row(),hm2.num_col());
382{
383#else
384{
385 HepMatrix mret(hm1.num_row(),hm2.num_col());
386#endif
387 CHK_DIM_1(1,hm2.num_row(),*);
390 HepMatrix::mIter mrp=mret.m.begin();
391 for(hm1p=hm1.m.begin();hm1p<hm1.m.begin()+hm1.num_row();hm1p++)
392 for(hm2p=hm2.m.begin();hm2p<hm2.m.begin()+hm2.num_col();hm2p++)
393 *(mrp++)=*hm1p*(*hm2p);
394 return mret;
395}
396
397/* -----------------------------------------------------------------------
398 This section contains the assignment and inplace operators =,+=,-=,*=,/=.
399 ----------------------------------------------------------------------- */
400
402{
403 CHK_DIM_2(num_row(),hm2.num_row(),num_col(),1,+=);
404 SIMPLE_BOP(+=)
405 return (*this);
406}
407
409{
410 CHK_DIM_2(num_row(),hm2.num_row(),1,hm2.num_col(),+=);
411 SIMPLE_BOP(+=)
412 return (*this);
413}
414
416{
417 CHK_DIM_1(num_row(),hm2.num_row(),+=);
418 SIMPLE_BOP(+=)
419 return (*this);
420}
421
423{
424 CHK_DIM_2(num_row(),hm2.num_row(),num_col(),1,-=);
425 SIMPLE_BOP(-=)
426 return (*this);
427}
428
430{
431 CHK_DIM_2(num_row(),hm2.num_row(),1,hm2.num_col(),-=);
432 SIMPLE_BOP(-=)
433 return (*this);
434}
435
437{
438 CHK_DIM_1(num_row(),hm2.num_row(),-=);
439 SIMPLE_BOP(-=)
440 return (*this);
441}
442
444{
445 SIMPLE_UOP(/=)
446 return (*this);
447}
448
450{
451 SIMPLE_UOP(*=)
452 return (*this);
453}
454
456{
457 if(hm1.nrow != size_)
458 {
459 size_ = hm1.nrow;
460 m.resize(size_);
461 }
462 nrow = hm1.nrow;
463 ncol = 1;
464 m = hm1.m;
465 return (*this);
466}
467
469{
470 if(hm1.nrow != nrow)
471 {
472 nrow = hm1.nrow;
473 m.resize(nrow);
474 }
475 m = hm1.m;
476 return (*this);
477}
478
480{
481 if (hm1.num_col() != 1)
482 error("Vector::operator=(Matrix) : Matrix is not Nx1");
483
484 if(hm1.nrow != nrow)
485 {
486 nrow = hm1.nrow;
487 m.resize(nrow);
488 }
489 m = hm1.m;
490 return (*this);
491}
492
494{
495 if(nrow != 3)
496 {
497 nrow = 3;
498 m.resize(nrow);
499 }
500 m[0] = v.x();
501 m[1] = v.y();
502 m[2] = v.z();
503 return (*this);
504}
505
506//
507// Copy constructor from the class of other precision
508//
509
510
511// Print the Matrix.
512
513std::ostream& operator<<(std::ostream &os, const HepVector &q)
514{
515 os << std::endl;
516/* Fixed format needs 3 extra characters for field, while scientific needs 7 */
517 long width;
518 if(os.flags() & std::ios::fixed)
519 width = os.precision()+3;
520 else
521 width = os.precision()+7;
522 for(int irow = 1; irow<= q.num_row(); irow++)
523 {
524 os.width(width);
525 os << q(irow) << std::endl;
526 }
527 return os;
528}
529
531#ifdef HEP_GNU_OPTIMIZED_RETURN
532return mret(1,num_row());
533{
534#else
535{
536 HepMatrix mret(1,num_row());
537#endif
538 mret.m = m;
539 return mret;
540}
541
542double dot(const HepVector &v1,const HepVector &v2)
543{
544 if(v1.num_row()!=v2.num_row())
545 HepGenMatrix::error("v1 and v2 need to be the same size in dot(HepVector, HepVector)");
546 double d= 0;
547 HepGenMatrix::mcIter a = v1.m.begin();
548 HepGenMatrix::mcIter b = v2.m.begin();
549 HepGenMatrix::mcIter e = a + v1.num_size();
550 for(;a<e;) d += (*(a++)) * (*(b++));
551 return d;
552}
553
555apply(double (*f)(double, int)) const
556#ifdef HEP_GNU_OPTIMIZED_RETURN
557return mret(num_row());
558{
559#else
560{
561 HepVector mret(num_row());
562#endif
563 HepGenMatrix::mcIter a = m.begin();
564 HepGenMatrix::mIter b = mret.m.begin();
565 for(int ir=1;ir<=num_row();ir++) {
566 *(b++) = (*f)(*(a++), ir);
567 }
568 return mret;
569}
570
571void HepVector::invert(int &) {
572 error("HepVector::invert: You cannot invert a Vector");
573}
574
576#ifdef HEP_GNU_OPTIMIZED_RETURN
577 return vret(v);
578{
579#else
580{
581 HepVector vret(v);
582#endif
583 static CLHEP_THREAD_LOCAL int max_array = 20;
584 static CLHEP_THREAD_LOCAL int *ir = new int [max_array+1];
585
586 if(a.ncol != a.nrow)
587 HepGenMatrix::error("Matrix::solve Matrix is not NxN");
588 if(a.ncol != v.nrow)
589 HepGenMatrix::error("Matrix::solve Vector has wrong number of rows");
590
591 int n = a.ncol;
592 if (n > max_array) {
593 delete [] ir;
594 max_array = n;
595 ir = new int [max_array+1];
596 }
597 double det;
598 HepMatrix mt(a);
599 int i = mt.dfact_matrix(det, ir);
600 if (i!=0) {
601 for (i=1;i<=n;i++) vret(i) = 0;
602 return vret;
603 }
604 double s21, s22;
605 int nxch = ir[n];
606 if (nxch!=0) {
607 for (int hmm=1;hmm<=nxch;hmm++) {
608 int ij = ir[hmm];
609 i = ij >> 12;
610 int j = ij%4096;
611 double te = vret(i);
612 vret(i) = vret(j);
613 vret(j) = te;
614 }
615 }
616 vret(1) = mt(1,1) * vret(1);
617 if (n!=1) {
618 for (i=2;i<=n;i++) {
619 s21 = -vret(i);
620 for (int j=1;j<i;j++) {
621 s21 += mt(i,j) * vret(j);
622 }
623 vret(i) = -mt(i,i)*s21;
624 }
625 for (i=1;i<n;i++) {
626 int nmi = n-i;
627 s22 = -vret(nmi);
628 for (int j=1;j<=i;j++) {
629 s22 += mt(nmi,n-j+1) * vret(n-j+1);
630 }
631 vret(nmi) = -s22;
632 }
633 }
634 return vret;
635}
636
637} // namespace CLHEP
#define CHK_DIM_2(r1, r2, c1, c2, fun)
Definition: DiagMatrix.cc:44
#define SIMPLE_BOP(OPER)
Definition: DiagMatrix.cc:31
#define SIMPLE_UOP(OPER)
Definition: DiagMatrix.cc:26
#define SIMPLE_TOP(OPER)
Definition: DiagMatrix.cc:37
#define CHK_DIM_1(c1, r2, fun)
Definition: DiagMatrix.cc:49
double z() const
double x() const
double y() const
std::vector< double, Alloc< double, 25 > >::const_iterator mcIter
Definition: GenMatrix.h:74
std::vector< double, Alloc< double, 25 > >::iterator mIter
Definition: GenMatrix.h:73
static void error(const char *s)
Definition: GenMatrix.cc:70
HepMatrix & operator=(const HepMatrix &)
Definition: Matrix.cc:415
virtual int num_col() const
Definition: Matrix.cc:120
virtual int num_row() const
Definition: Matrix.cc:118
HepMatrix & operator+=(const HepMatrix &)
Definition: Matrix.cc:389
HepMatrix & operator-=(const HepMatrix &)
Definition: Matrix.cc:396
HepVector & operator/=(double t)
Definition: Vector.cc:443
HepVector sub(int min_row, int max_row) const
Definition: Vector.cc:150
HepMatrix T() const
Definition: Vector.cc:530
HepVector & operator-=(const HepMatrix &v2)
Definition: Vector.cc:429
virtual ~HepVector()
Definition: Vector.cc:91
virtual int num_size() const
Definition: Vector.cc:117
virtual int num_col() const
Definition: Vector.cc:118
HepVector apply(double(*f)(double, int)) const
Definition: Vector.cc:555
HepVector operator-() const
Definition: Vector.cc:212
virtual int num_row() const
Definition: Vector.cc:116
friend double dot(const HepVector &v1, const HepVector &v2)
Definition: Vector.cc:542
friend HepVector solve(const HepMatrix &a, const HepVector &v)
Definition: Vector.cc:575
const double & operator()(int row) const
HepVector & operator=(const HepVector &hm2)
Definition: Vector.cc:468
friend HepVector operator*(const HepSymMatrix &hm1, const HepVector &hm2)
Definition: SymMatrix.cc:507
friend HepVector operator+(const HepVector &v1, const HepVector &v2)
Definition: Vector.cc:255
HepVector & operator*=(double t)
Definition: Vector.cc:449
HepVector & operator+=(const HepMatrix &v2)
Definition: Vector.cc:408
void f(void g())
Definition: excDblThrow.cc:38
std::ostream & operator<<(std::ostream &s, const HepDiagMatrix &q)
Definition: DiagMatrix.cc:560
HepDiagMatrix dsum(const HepDiagMatrix &s1, const HepDiagMatrix &s2)
Definition: DiagMatrix.cc:161
void init()
Definition: testRandom.cc:29