CMS 3D CMS Logo

poly2d_base.cc
Go to the documentation of this file.
1 #include "poly2d_base.h"
2 
3 using namespace magfieldparam;
4 
6 // //
7 // The "poly2d_term" represent a term of a polynomial of 2 variables. //
8 // //
10 
11 //_______________________________________________________________________________
12 void poly2d_term::Print(std::ostream &out, bool first_term)
13 {
14  if (first_term) out << coeff;
15  else if (coeff > 0.) out << " + " << coeff;
16  else out << " - " << -coeff;
17  if (np[0] != 0) {
18  out << "*r";
19  if (np[0] != 1) out << "^" << np[0];
20  }
21  if (np[1] != 0) {
22  out << "*z";
23  if (np[1] != 1) out << "^" << np[1];
24  }
25 }
26 
28 // //
29 // Base class that represent a polynomial of 2 variables. It isn't supposed //
30 // to be used directly and provides no way of setting coefficients directly. //
31 // Such methods must be defined in derived classes. //
32 // //
34 
35 //_______________________________________________________________________________
36 double poly2d_base::rval = 0.; //Last values of r and z used
37 double poly2d_base::zval = 0.;
38 
39 double **poly2d_base::rz_pow = nullptr; //table with calculated r^n*z^m values
40 unsigned poly2d_base::NTab = 0; //rz_pow table size
41 unsigned poly2d_base::NPwr = 0; //max power in use by CLASS
42 
43 bool poly2d_base::rz_set = false;
44 
45 const double poly2d_base::MIN_COEFF = DBL_EPSILON; //Thresh. for coeff == 0
46 std::set<poly2d_base*> poly2d_base::poly2d_base_set;
47 
48 //_______________________________________________________________________________
50 {
51  poly2d_base_set.erase(poly2d_base_set.find(this));
52  if(!poly2d_base_set.empty()) { //some objects left
53  if (max_pwr >= NPwr) NPwr = GetMaxPow();
54  } else {
55  if (rz_pow) {
56  delete [] rz_pow[0]; //deleting the last instance -> memory cleanup
57  delete [] rz_pow;
58  }
59  rz_pow = nullptr;
60  rval = zval = 0.;
61  NPwr = 0;
62  NTab = 0;
63  rz_set = false;
64 // poly2d_base_set.resize(0);
65  }
66 }
67 
68 //_______________________________________________________________________________
69 void poly2d_base::SetTabSize(const unsigned N)
70 {
71  if (N <= NTab) return;
72  if (rz_pow) {
73  delete [] rz_pow[0];
74  delete [] rz_pow;
75  }
76  rz_pow = new double* [N];
77  unsigned jr, dN = N*(N+1)/2;
78  rz_pow[0] = new double [dN];
79  memset(rz_pow[0], 0, dN*sizeof(double));
80  rz_pow[0][0] = 1.;
81  for (jr = 1, dN = N; jr < N; ++jr, --dN) {
82  rz_pow[jr] = rz_pow[jr-1] + dN;
83  }
84  rval = zval = 0.;
85  NTab = N;
86 }
87 
88 //_______________________________________________________________________________
89 void poly2d_base::FillTable(const double r, const double z)
90 {
91  if (!rz_pow) return;
92  unsigned jr, jz;
93  for (jz = 1; jz <= NPwr; ++jz) rz_pow[0][jz] = z*rz_pow[0][jz-1];
94  for (jr = 1; jr <= NPwr; ++jr) {
95  for (jz = 0; jz <= (NPwr - jr); ++jz) {
96  rz_pow[jr][jz] = r*rz_pow[jr-1][jz];
97  }
98  }
99 }
100 
101 //_______________________________________________________________________________
103 {
104  int curp, maxp = 0;
105  std::set<poly2d_base*>::iterator it;
106 
107  for (it = poly2d_base_set.begin(); it != poly2d_base_set.end(); ++it) {
108  curp = (*it)->max_pwr;
109  if (curp > maxp) maxp = curp;
110  }
111  return maxp;
112 }
113 
114 //_______________________________________________________________________________
116 {
117  NPwr = GetMaxPow();
118  if (NPwr >= NTab) SetTabSize(NPwr+1);
119 }
120 
121 //_______________________________________________________________________________
122 void poly2d_base::PrintTab(std::ostream &out, const std::streamsize prec)
123 {
124  out << "poly2d_base table size NTab = " << NTab
125  << "\tmax. power NPwr = " << NPwr << std::endl;
126  if (rz_pow) {
127  if (NPwr < NTab) {
128  std::streamsize old_prec = out.precision(), wdt = prec+7;
129  out.precision(prec);
130  out << "Table content:" << std::endl;
131  unsigned jr, jz;
132  for (jr = 0; jr <= NPwr; ++jr) {
133  for (jz = 0; jz <= (NPwr-jr); ++jz) {
134  out << std::setw(wdt) << std::left << rz_pow[jr][jz];
135  }
136  out << "|" << std::endl;
137  }
138  out.precision(old_prec);
139  } else {
140  out << "\tTable size is not adjusted." << std::endl;
141  }
142  } else {
143  out << "\tTable is not allocated." << std::endl;
144  }
145 }
146 
147 //_______________________________________________________________________________
148 void poly2d_base::SetPoint(const double r, const double z)
149 {
150  if (!Count()) return;
151  if (NPwr >= NTab) { SetTabSize(NPwr+1); FillTable(r, z);}
152  else if ((r != rval) || (z != zval)) FillTable(r, z);
153  rz_set = true;
154 }
155 
156 //_______________________________________________________________________________
158 {
159  double S = 0.;
160  for (unsigned j = 0; j < data.size(); ++j)
161  S += data[j].coeff*rz_pow[data[j].np[0]][data[j].np[1]];
162  return S;
163 }
164 
165 //_______________________________________________________________________________
167 {
168  if (!(data.size())) return;
169 
170  unsigned j1, j2, rpow, zpow, noff = 0, jend = data.size();
171  double C;
172  std::vector<bool> mask(jend, false);
173  max_pwr = 0;
174 
175  for (j1 = 0; j1 < jend; ++j1) {
176  if (mask[j1]) continue;
177  C = data[j1].coeff;
178  rpow = data[j1].np[0];
179  zpow = data[j1].np[1];
180  for (j2 = j1+1; j2 < jend; ++j2) {
181  if (mask[j2]) continue;
182  if ((rpow == data[j2].np[0]) && (zpow == data[j2].np[1])) {
183  C += data[j2].coeff;
184  mask[j2] = true;
185  ++noff;
186  }
187  }
188  if (fabs(C) > MIN_COEFF) {
189  data[j1].coeff = C;
190  if ((rpow = rpow+zpow) > max_pwr) max_pwr = rpow;
191  } else {
192  mask[j1] = true;
193  ++noff;
194  }
195  }
196  std::vector<poly2d_term> newdata; newdata.reserve(jend - noff);
197  for (j1 = 0; j1 < jend; ++j1) {
198  if (!(mask[j1])) newdata.push_back(data[j1]);
199  }
200  data.swap(newdata);
201 }
202 
203 //_______________________________________________________________________________
204 void poly2d_base::Print(std::ostream &out, const std::streamsize prec)
205 {
206  if (data.empty()) {
207  out << "\"poly2d_base\" object contains no terms." << std::endl;
208  return;
209  }
210  out << data.size() << " terms; max. degree = " << max_pwr << ":" << std::endl;
211  std::streamsize old_prec = out.precision();
212  out.precision(prec);
213  data[0].Print(out);
214  for (unsigned it = 1; it < data.size(); ++it) {
215  data[it].Print(out, false);
216  }
217  out << std::endl;
218  out.precision(old_prec);
219 }
220 
221 //_______________________________________________________________________________
222 void poly2d_base::Diff(int nvar)
223 {
224 //differentiate the polynomial by variable nvar.
225 //
226  poly2d_term v3;
227  std::vector<poly2d_term> newdata;
228  newdata.reserve(data.size());
229  unsigned cur_pwr = 0, maxp = 0, oldp = max_pwr;
230  for (unsigned it = 0; it < data.size(); ++it) {
231  v3 = data[it];
232  v3.coeff *= v3.np[nvar];
233  if (v3.coeff != 0.) {
234  --v3.np[nvar];
235  newdata.push_back(v3);
236  if ((cur_pwr = v3.np[0] + v3.np[1]) > maxp) maxp = cur_pwr;
237  }
238  }
239  newdata.resize(newdata.size());
240  max_pwr = maxp;
241  data.swap(newdata);
242  if (oldp >= NPwr) NPwr = GetMaxPow();
243 }
244 
245 //_______________________________________________________________________________
246 void poly2d_base::Int(int nvar)
247 {
248 //Integrate the polynomial by variable# nvar. Doesn't remove terms
249 //with zero coefficients; if you suspect they can appear, use Compress()
250 //after the integration.
251 //
252  for (unsigned it = 0; it < data.size(); ++it) {
253  data[it].coeff /= ++data[it].np[nvar];
254  }
255  ++max_pwr;
256  if (max_pwr > NPwr) NPwr = GetMaxPow();
257 }
258 
259 //_______________________________________________________________________________
260 void poly2d_base::IncPow(int nvar)
261 {
262 //Multiply the polynomial by variable# nvar
263 //
264  for (unsigned it = 0; it < data.size(); ++it) {
265  ++data[it].np[nvar];
266  }
267  ++max_pwr;
268  if (max_pwr > NPwr) NPwr = GetMaxPow();
269 }
270 
271 //_______________________________________________________________________________
272 void poly2d_base::DecPow(int nvar)
273 {
274 //Divide the polynomial by variable# nvar. Remove terms with zero coefficients
275 //and also terms where the initial power of nvar is equal zero
276 //
277  poly2d_term v3;
278  std::vector<poly2d_term> newdata;
279  newdata.reserve(data.size());
280  unsigned cur_pwr = 0, maxp = 0, oldp = max_pwr;
281  for (unsigned it = 0; it < data.size(); ++it) {
282  v3 = data[it];
283  if ((v3.coeff != 0.) && (v3.np[nvar] > 0)) {
284  --v3.np[nvar];
285  newdata.push_back(v3);
286  if ((cur_pwr = v3.np[0] + v3.np[1]) > maxp) maxp = cur_pwr;
287  }
288  }
289  newdata.resize(newdata.size());
290  max_pwr = maxp;
291  data.swap(newdata);
292  if (oldp >= NPwr) NPwr = GetMaxPow();
293 }
294 
295 //_______________________________________________________________________________
296 void poly2d_base::Scale(const double C)
297 {
298 //Multiply the polynomial by a constant.
299 //
300  if (C != 0.) {
301  for (unsigned it = 0; it < data.size(); ++it) {
302  data[it].coeff *= C;
303  }
304  } else data.resize(0);
305 }
306 
static unsigned NTab
Definition: poly2d_base.h:53
void Print(std::ostream &out=std::cout, const std::streamsize prec=5)
Definition: poly2d_base.cc:204
static void SetTabSize(const unsigned N)
Definition: poly2d_base.cc:69
static double ** rz_pow
Definition: poly2d_base.h:52
static std::set< poly2d_base * > poly2d_base_set
Definition: poly2d_base.h:59
void Scale(const double C)
Definition: poly2d_base.cc:296
static void SetPoint(const double r, const double z)
Definition: poly2d_base.cc:148
void Print(std::ostream &out=std::cout, bool first_term=true)
Definition: poly2d_base.cc:12
static void FillTable(const double r, const double z)
Definition: poly2d_base.cc:89
unsigned long long int rval
Definition: vlib.h:22
#define N
Definition: blowfish.cc:9
static void PrintTab(std::ostream &out=std::cout, const std::streamsize prec=5)
Definition: poly2d_base.cc:122
double S(const TLorentzVector &, const TLorentzVector &)
Definition: Particle.cc:99
static unsigned NPwr
Definition: poly2d_base.h:54
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
static const double MIN_COEFF
Definition: poly2d_base.h:57