CMS 3D CMS Logo

rz_poly.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include "rz_poly.h"
3 
4 using namespace std;
5 using namespace magfieldparam;
6 
7 //_______________________________________________________________________________
8 rz_poly::rz_poly(int N) {
9  int nz, nr = 0, nv, nt;
10  poly_term v3;
11 
12  if (N < 2)
13  N = 2;
14  data.reserve(N);
15 
16  v3.coeff = 1.;
17  v3.np[0] = 0;
18  v3.np[1] = 1;
19 
20  data.push_back(poly_vect(1, v3));
21 
22  for (int m = 2; m <= N; ++m) {
23  nz = m;
24  nr = 0;
25  nv = 0;
26  v3.coeff = 1. / m;
27  v3.np[0] = nr;
28  v3.np[1] = nz;
29 
30  nt = (m + 2) / 2;
31  poly_vect v3x(nt, v3);
32 
33  while (nz >= 2) {
34  nz -= 2;
35  nr += 2;
36  nv += 1;
37  v3x[nv].coeff = -v3x[nv - 1].coeff * (nz + 1) * (nz + 2) / (nr * nr);
38  v3x[nv].np[0] = nr;
39  v3x[nv].np[1] = nz;
40  }
41  data.push_back(v3x);
42  }
43  max_nr = nr + 1;
44  max_nz = N + 1;
45  r_pow = new double[max_nr];
46  z_pow = new double[max_nz];
47  fill(r_pow, r_pow + max_nr, 1.);
48  fill(z_pow, z_pow + max_nz, 1.);
49 
50  n_active = data.size();
51  is_off = new bool[n_active];
52  fill(is_off, is_off + n_active, false);
53 }
54 
55 //_______________________________________________________________________________
56 rz_poly::rz_poly(const rz_poly &S) {
57  data = S.data;
58  max_nr = S.max_nr;
59  max_nz = S.max_nz;
60  n_active = S.n_active;
61 
62  if (max_nr) {
63  r_pow = new double[max_nr];
64  copy(S.r_pow, S.r_pow + max_nr, r_pow);
65  } else
66  r_pow = nullptr;
67 
68  if (max_nz) {
69  z_pow = new double[max_nz];
70  copy(S.z_pow, S.z_pow + max_nz, z_pow);
71  } else
72  z_pow = nullptr;
73 
74  if (S.is_off) {
75  is_off = new bool[data.size()];
76  copy(S.is_off, S.is_off + data.size(), is_off);
77  } else
78  is_off = nullptr;
79 }
80 
81 //_______________________________________________________________________________
82 rz_poly::~rz_poly() {
83  if (is_off)
84  delete[] is_off;
85  if (r_pow)
86  delete[] r_pow;
87  if (z_pow)
88  delete[] z_pow;
89 }
90 
91 //_______________________________________________________________________________
92 void rz_poly::SetOFF(int npoly) {
93  if ((npoly < 0) || (npoly >= (int)data.size()))
94  return;
95  if (is_off[npoly])
96  return;
97  is_off[npoly] = true;
98  --n_active;
99 }
100 
101 //_______________________________________________________________________________
102 void rz_poly::SetON(int npoly) {
103  if ((npoly < 0) || (npoly >= (int)data.size()))
104  return;
105  if (is_off[npoly]) {
106  is_off[npoly] = false;
107  ++n_active;
108  }
109 }
110 
111 //_______________________________________________________________________________
112 void rz_poly::Print() {
113  if (data.empty()) {
114  cout << "The \"rz_poly\" object is NOT initialized!" << endl;
115  return;
116  }
117 
118  for (unsigned int ip = 0; ip < data.size(); ++ip) {
119  cout << "Polynomial " << ip << " (size=" << data[ip].size() << ", status=";
120  if (is_off[ip])
121  cout << "OFF):" << endl;
122  else
123  cout << "ON):" << endl;
124  for (unsigned int it = 0; it < data[ip].size(); ++it) {
125  cout << "\tnr=" << data[ip][it].np[0] << "\tnz=" << data[ip][it].np[1] << "\tcoeff=" << data[ip][it].coeff
126  << endl;
127  }
128  }
129 }
130 
131 //_______________________________________________________________________________
132 rz_poly rz_poly::Diff(int nvar, bool keep_empty) {
133  //Return the derivative of original polynomial by variable nvar.
134  //If keep_empty=true, resulting polynomial may contain zero basis terms,
135  //otherwise the resulting polynomial will be compressed, so that corresponding
136  //basis terms will be shifted relatively to the original polynomial.
137  //
138  poly_term v3;
139  rz_poly p_out;
140  p_out.data.reserve(data.size());
141 
142  bool *tmp_mask = new bool[data.size()];
143  unsigned int ind_tmp = 0;
144  int tmp_act = 0;
145 
146  for (unsigned int ip = 0; ip < data.size(); ++ip) {
147  poly_vect v3x;
148  v3x.reserve(data[ip].size());
149  for (unsigned int it = 0; it < data[ip].size(); ++it) {
150  v3 = data[ip][it];
151  v3.coeff = data[ip][it].coeff * data[ip][it].np[nvar];
152  if (v3.coeff != 0) {
153  v3.np[nvar] = data[ip][it].np[nvar] - 1;
154  v3x.push_back(v3);
155  }
156  }
157  if (!v3x.empty() || keep_empty) {
158  v3x.resize(v3x.size());
159  p_out.data.push_back(v3x);
160  tmp_mask[ind_tmp] = is_off[ip];
161  ++ind_tmp;
162  if (!is_off[ip])
163  ++tmp_act;
164  }
165  }
166 
167  p_out.data.resize(p_out.data.size());
168  p_out.max_nr = max_nr;
169  p_out.max_nz = max_nz;
170 
171  if (nvar == 0)
172  --p_out.max_nr;
173  else
174  --p_out.max_nz;
175 
176  p_out.r_pow = new double[p_out.max_nr];
177  copy(r_pow, r_pow + p_out.max_nr, p_out.r_pow);
178  p_out.z_pow = new double[p_out.max_nz];
179  copy(z_pow, z_pow + p_out.max_nz, p_out.z_pow);
180 
181  p_out.n_active = tmp_act;
182  p_out.is_off = new bool[p_out.data.size()];
183  copy(tmp_mask, tmp_mask + p_out.data.size(), p_out.is_off);
184 
185  delete[] tmp_mask;
186 
187  return p_out;
188 }
189 
190 //_______________________________________________________________________________
192  //Return the integral of original polynomial by variable nvar
193  //
194  rz_poly p_out;
195  p_out.data = data;
196  for (unsigned int ip = 0; ip < data.size(); ++ip) {
197  for (unsigned int it = 0; it < data[ip].size(); ++it) {
198  p_out.data[ip][it].coeff /= ++p_out.data[ip][it].np[nvar];
199  }
200  }
201 
202  p_out.max_nr = max_nr;
203  p_out.max_nz = max_nz;
204 
205  if (nvar == 0)
206  ++p_out.max_nr;
207  else
208  ++p_out.max_nz;
209 
210  p_out.r_pow = new double[p_out.max_nr];
211  copy(r_pow, r_pow + max_nr, p_out.r_pow);
212  p_out.z_pow = new double[p_out.max_nz];
213  copy(z_pow, z_pow + max_nz, p_out.z_pow);
214 
215  if (nvar == 0)
216  p_out.r_pow[max_nr] = p_out.r_pow[max_nr - 1] * r_pow[1];
217  else
218  p_out.z_pow[max_nz] = p_out.z_pow[max_nz - 1] * z_pow[1];
219 
220  p_out.n_active = n_active;
221  p_out.is_off = new bool[data.size()];
222  copy(is_off, is_off + data.size(), p_out.is_off);
223 
224  return p_out;
225 }
226 
227 //_______________________________________________________________________________
229  //Multiply the polynomial by a constant. Skips terms that are switched off
230 
231  for (unsigned int ip = 0; ip < data.size(); ++ip) {
232  if (is_off[ip])
233  continue;
234  for (unsigned int it = 0; it < data[ip].size(); ++it) {
235  data[ip][it].coeff *= C;
236  }
237  }
238  return *this;
239 }
240 
241 //_______________________________________________________________________________
243  //Multiply the polynomial by an array. Skips terms that are switched off
244 
245  for (unsigned int ip = 0; ip < data.size(); ++ip) {
246  if (is_off[ip])
247  continue;
248  for (unsigned int it = 0; it < data[ip].size(); ++it) {
249  data[ip][it].coeff *= *C;
250  }
251  ++C;
252  }
253  return *this;
254 }
255 
256 //_______________________________________________________________________________
257 double rz_poly::GetSVal(double r, double z, const double *C) const {
258  //Return value of a polynomial, ignoring terms, that are switched off
259 
260  if (r_pow == nullptr)
261  return 0.;
262 
263  double term, rez = 0.;
264  int ip, it;
265 
266  if (r != r_pow[1])
267  for (ip = 1; ip < max_nr; ++ip)
268  r_pow[ip] = r * r_pow[ip - 1];
269  if (z != z_pow[1])
270  for (ip = 1; ip < max_nz; ++ip)
271  z_pow[ip] = z * z_pow[ip - 1];
272 
273  for (ip = 0; ip < (int)data.size(); ++ip) {
274  if (is_off[ip])
275  continue;
276  term = 0.;
277  for (it = 0; it < (int)data[ip].size(); ++it) {
278  term += data[ip][it].coeff * r_pow[data[ip][it].np[0]] * z_pow[data[ip][it].np[1]];
279  }
280  rez += *C * term;
281  ++C;
282  }
283 
284  return rez;
285 }
286 
287 //_______________________________________________________________________________
288 double *rz_poly::GetVVal(double r, double z, double *rez_out) {
289  //return an array of doubleype with values of the basis functions in the point
290  //(r,z). In a case if rez_out != 0, the rez_out array must be long enough to fit
291  //in n_active elements. In a case if rez_out == 0, a new array of n_active length
292  //is created; it is in user's responsibility to free the memory after all;
293  //
294  if (r_pow == nullptr)
295  return nullptr;
296 
297  double term;
298  int ip, it;
299 
300  double *rez;
301  if (rez_out)
302  rez = rez_out;
303  else
304  rez = new double[n_active];
305 
306  double *pnt = rez;
307 
308  if (r != r_pow[1])
309  for (ip = 1; ip < max_nr; ++ip)
310  r_pow[ip] = r * r_pow[ip - 1];
311  if (z != z_pow[1])
312  for (ip = 1; ip < max_nz; ++ip)
313  z_pow[ip] = z * z_pow[ip - 1];
314 
315  for (ip = 0; ip < (int)data.size(); ++ip) {
316  if (is_off[ip])
317  continue;
318  term = 0.;
319  for (it = 0; it < (int)data[ip].size(); ++it) {
320  term += data[ip][it].coeff * r_pow[data[ip][it].np[0]] * z_pow[data[ip][it].np[1]];
321  }
322  *pnt = term;
323  ++pnt;
324  }
325 
326  return rez;
327 }
328 
329 //_______________________________________________________________________________
330 double *rz_poly::Expand(double *C) {
331  //Take C[n_active] - reduced vector of coefficients and return pointer to
332  //expanded vector of coefficients of the data.size() length. It is in user's
333  //responsibility to free the memory after all;
334  //
335  double *rez = new double[data.size()];
336  for (int ip = 0; ip < (int)data.size(); ++ip) {
337  if (is_off[ip])
338  rez[ip] = 0.;
339  else {
340  rez[ip] = *C;
341  ++C;
342  }
343  }
344  return rez;
345 }
Basic3DVector & operator*=(T t)
Scaling by a scalar value (multiplication)
std::vector< poly_term > poly_vect
Definition: rz_poly.h:21
int nt
Definition: AMPTWrapper.h:42
#define N
Definition: blowfish.cc:9
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80