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