CMS 3D CMS Logo

LinearEquation3.h
Go to the documentation of this file.
1 #ifndef LinearEquation3_H
2 #define LinearEquation3_H
3 
5 
6 #include <algorithm>
7 
8 #ifdef DEBUG_SOLUTION
9 #include <iostream>
10 #endif
11 
12 template <class T>
14 public:
15 
16  template <class U>
17  class Array3 {
18  public:
19  Array3() {}
20  Array3( U a0, U a1, U a2) { a_[0] = a0; a_[1] = a1; a_[2] = a2;}
22  a_[0] = v.x(); a_[1] = v.y(); a_[2] = v.z();
23  }
24 
26  a_[0] = other[0]; a_[1] = other[1]; a_[2] = other[2];
27  return *this;
28  }
29 
31  a_[0] = v.x(); a_[1] = v.y(); a_[2] = v.z();
32  return *this;
33  }
34 
35  U& operator[]( int i) { return a_[i];}
36  const U& operator[]( int i) const { return a_[i];}
37  void operator-=( const Array3& other) {
38  a_[0] -= other[0];
39  a_[1] -= other[1];
40  a_[2] -= other[2];
41  }
42 
43  Array3 operator*( U t) const {
44  return Array3( a_[0]*t, a_[1]*t, a_[2]*t);
45  }
46 
47  void subtractScaled( const Array3& a, U c) {
48  a_[0] -= a[0]*c; a_[1] -= a[1]*c; a_[2] -= a[2]*c;
49  }
50 
51  private:
52  U a_[3];
53  };
54 
56  const Basic3DVector<T>& row1,
57  const Basic3DVector<T>& row2,
58  const Basic3DVector<T>& rhsvec) const {
59 
60  // copy the input to internal "matrix"
61  Array3<T> row[3];
62  row[0] = row0;
63  row[1] = row1;
64  row[2] = row2;
65  Array3<T> rhs(rhsvec);
66 
67  // no implicit pivoting - rows expected to be normalized already
68 
69  // find pivot 0, i.e. row with largest first element
70  int i0 = std::abs(row[0][0]) > std::abs(row[1][0]) ? 0 : 1;
71  if (std::abs(row[i0][0]) < std::abs(row[2][0])) i0 = 2;
72 
73  int i1 = (i0+1)%3;
74  int i2 = (i0+2)%3;
75 
76  // zero the first column of rows i1 and i2
77  T c1 = row[i1][0] / row[i0][0];
78  // row[i1] -= c1*row[i0];
79  row[i1].subtractScaled( row[i0], c1);
80  rhs[i1] -= c1*rhs[i0];
81  T c2 = row[i2][0] / row[i0][0];
82  // row[i2] -= c2*row[i0];
83  row[i2].subtractScaled( row[i0], c2);
84  rhs[i2] -= c2*rhs[i0];
85 
86  // find pivot 1, i.e. which row (i1 or i2) has the largest second element
87  if (std::abs(row[i1][1]) < std::abs(row[i2][1])) std::swap( i1, i2);
88 
89  // zero the second column of row i2
90  T c3 = row[i2][1] / row[i1][1];
91  row[i2][1] -= c3 * row[i1][1];
92  row[i2][2] -= c3 * row[i1][2];
93  rhs[i2] -= c3*rhs[i1];
94 
95  // compute the solution
96  T x2 = rhs[i2] / row[i2][2];
97  T x1 = (rhs[i1] - x2*row[i1][2]) / row[i1][1];
98  T x0 = (rhs[i0] - x1*row[i0][1] - x2*row[i0][2]) / row[i0][0];
99 
100  return Basic3DVector<T>(x0, x1, x2);
101  }
102 
103 #ifdef DEBUG_SOLUTION
104 private:
105  typedef Array3<T> AT;
106  void dump(const AT row[]) const {
107  std::cout << " (" << row[0][0] << ',' << row[0][1] << ',' << row[0][2] << ") " << std::endl;
108  std::cout << " (" << row[1][0] << ',' << row[1][1] << ',' << row[1][2] << ") " << std::endl;
109  std::cout << " (" << row[2][0] << ',' << row[2][1] << ',' << row[2][2] << ") " << std::endl;
110  std::cout << std::endl;
111  }
112 #endif
113 
114 };
115 
116 #endif
void subtractScaled(const Array3 &a, U c)
T y() const
Cartesian y coordinate.
T x() const
Cartesian x coordinate.
Basic3DVector< T > solution(const Basic3DVector< T > &row0, const Basic3DVector< T > &row1, const Basic3DVector< T > &row2, const Basic3DVector< T > &rhsvec) const
const U & operator[](int i) const
void operator-=(const Array3 &other)
Array3 & operator=(const Array3 &other)
Array3 & operator=(const Basic3DVector< U > &v)
T z() const
Cartesian z coordinate.
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
Array3 operator*(U t) const
Array3(U a0, U a1, U a2)
Array3(const Basic3DVector< U > &v)
double a
Definition: hdecay.h:121
long double T