OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
TransportFun.hpp
Go to the documentation of this file.
1 #ifndef CLASSIC_TransportFun_CC
2 #define CLASSIC_TransportFun_CC
3 
4 // ------------------------------------------------------------------------
5 // $RCSfile: TransportFun.cpp,v $
6 // ------------------------------------------------------------------------
7 // $Revision: 1.2.2.1 $
8 // ------------------------------------------------------------------------
9 // Copyright: see Copyright.readme
10 // ------------------------------------------------------------------------
11 //
12 // Template class: TransportFun<T,N>
13 // Representation of a second-order function with values of type T,
14 // and fixed number of variables N.
15 //
16 // ------------------------------------------------------------------------
17 // Class category: FixedAlgebra
18 // ------------------------------------------------------------------------
19 //
20 // $Date: 2004/11/18 22:18:06 $
21 // $Author: jsberg $
22 //
23 // ------------------------------------------------------------------------
24 
26 #include "FixedAlgebra/FMatrix.h"
27 #include "FixedAlgebra/FVector.h"
29 #include "Utilities/DivideError.h"
30 #include "Utilities/FormatError.h"
31 #include <iomanip>
32 #include <iostream>
33 #include <cstring>
34 
35 
36 // Implementation of template class TransportFun<T,N>.
37 // ------------------------------------------------------------------------
38 
39 template <class T, int N>
41  for(int i = 0; i < SIZE; ++i) data[i] = 0.0;
42 }
43 
44 
45 template <class T, int N>
47  data[0] = rhs;
48  for(int i = 1; i < SIZE; ++i) data[i] = 0.0;
49 }
50 
51 
52 template <class T, int N>
54  data[0] = T(rhs);
55  for(int i = 1; i < SIZE; ++i) data[i] = 0.0;
56 }
57 
58 
59 template <class T, int N>
61  data[0] = rhs;
62  for(int i = 1; i < SIZE; ++i) data[i] = 0.0;
63  return *this;
64 }
65 
66 
67 template <class T, int N>
68 const T TransportFun<T, N>::getCoefficient(int index) const {
69  return (index > N) ? T(0) : data[index];
70 }
71 
72 
73 template <class T, int N>
74 const T TransportFun<T, N>::getCoefficient(int index1, int index2) const {
75  if(index1 <= index2 && index2 < N) {
76  int index = N * (2 * N + 1 - index1) * index1 + (N + 1) + index2;
77  return data[index];
78  } else {
79  return T(0);
80  }
81 }
82 
83 
84 template <class T, int N>
85 void TransportFun<T, N>::setCoefficient(int index, const T &value) {
86  if(index <= N) data[index] = value;
87 }
88 
89 
90 template <class T, int N>
91 void TransportFun<T, N>::setCoefficient(int index1, int index2, const T &value) {
92  if(index1 <= index2 && index2 < N) {
93  int index = N * (2 * N + 1 - index1) * index1 + (N + 1) + index2;
94  data[index] = value;
95  }
96 }
97 
98 
99 template <class T, int N> inline
100 const T TransportFun<T, N>::operator[](int index) const {
101  return data[index];
102 }
103 
104 
105 template <class T, int N> inline
107  return data[index];
108 }
109 
110 
111 template <class T, int N> inline
112 const T TransportFun<T, N>::operator()(int index1, int index2) const {
113  int index = N * (2 * N + 1 - index1) * index1 + (N + 1) + index2;
114  return data[index];
115 }
116 
117 
118 template <class T, int N> inline
119 T &TransportFun<T, N>::operator()(int index1, int index2) {
120  int index = N * (2 * N + 1 - index1) * index1 + (N + 1) + index2;
121  return data[index];
122 }
123 
124 
125 template <class T, int N>
128  for(int i = 0; i < SIZE; ++i) z.data[i] = 0.0;
129  z.data[var+1] = T(1);
130  return z;
131 }
132 
133 
134 template <class T, int N> inline
136  return *this;
137 }
138 
139 
140 template <class T, int N>
143  for(int i = 0; i < SIZE; ++i) z.data[i] = - data[i];
144  return z;
145 }
146 
147 
148 template <class T, int N>
150  for(int i = 0; i < SIZE; ++i) data[i] += rhs.data[i];
151  return *this;
152 }
153 
154 
155 template <class T, int N>
157  for(int i = 0; i < SIZE; ++i) data[i] -= rhs.data[i];
158  return *this;
159 }
160 
161 
162 template <class T, int N>
164  return *this = multiply(rhs);
165 }
166 
167 
168 template <class T, int N>
170  if(rhs.data[0] == T(0)) throw DivideError("TransportFun::operator/=()");
171  return *this = multiply(rhs.inverse());
172 }
173 
174 
175 template <class T, int N> inline
177  data[0] += rhs;
178  return *this;
179 }
180 
181 
182 template <class T, int N> inline
184  data[0] -= rhs;
185  return *this;
186 }
187 
188 
189 template <class T, int N>
191  for(int i = 0; i < SIZE; ++i) data[i] *= rhs;
192  return *this;
193 }
194 
195 
196 template <class T, int N>
198  if(rhs == T(0)) throw DivideError("TransportFun::operator/=()");
199  for(int i = 0; i < SIZE; ++i) data[i] /= rhs;
200  return *this;
201 }
202 
203 
204 template <class T, int N>
206  for(int i = 0; i < SIZE; ++i) {
207  if(data[i] != rhs.data[i]) return false;
208  }
209 
210  return true;
211 }
212 
213 
214 template <class T, int N>
215 bool TransportFun<T, N>::operator==(const T &rhs) const {
216  if(data[0] != rhs) return false;
217 
218  for(int i = 1; i < SIZE; ++i) {
219  if(data[i] != T(0)) return false;
220  }
221 
222  return true;
223 }
224 
225 
226 template <class T, int N> inline
228  return !(*this == rhs);
229 }
230 
231 
232 template <class T, int N> inline
233 bool TransportFun<T, N>::operator!=(const T &rhs) const {
234  return !(*this == rhs);
235 }
236 
237 
238 template <class T, int N>
240  T aZero = data[0];
241  if(aZero == T(0)) throw DivideError("TransportFun::inverse()");
242 
243  T series[3];
244  series[0] = T(1) / aZero;
245  series[1] = - series[0] / aZero;
246  series[2] = - series[1] / aZero;
247  return taylor(series);
248 }
249 
250 
251 template <class T, int N> TransportFun<T, N>
254 
255  // Product of constant terms.
256  z.data[0] = data[0] * rhs.data[0];
257 
258  // Products of constant term with non-constant terms of other factor.
259  for(int i = 1; i < SIZE; ++i) {
260  z.data[i] = data[0] * rhs.data[i] + data[i] * rhs.data[0];
261  }
262 
263  // Second-order terms generated as products of linear terms.
264  int k = N;
265  for(int i = 0; i < N; ++i) {
266  // Quadratic terms.
267  ++k;
268  z.data[k] += data[i+1] * rhs.data[i+1];
269 
270  // Bilinear terms.
271  for(int j = i + 1; j < N; ++j) {
272  ++k;
273  z.data[k] += data[i+1] * rhs.data[j+1] + data[j+1] * rhs.data[i+1];
274  }
275  }
276 
277  return z;
278 }
279 
280 
281 template <class T, int N>
283  // Constant term.
284  T z = data[0];
285 
286  // Linear terms.
287  int k = 0;
288  for(int i = 0; i < N; ++i) {
289  z += data[++k] * rhs[i];
290  }
291 
292  // Second-order terms.
293  for(int i = 0; i < N; ++i) {
294  for(int j = i; j < N; ++j) {
295  z += data[++k] * rhs[i] * rhs[j];
296  }
297  }
298 
299  return z;
300 }
301 
302 
303 template <class T, int N>
305  return substitute(TransportMap<T, N>(M));
306 }
307 
308 
309 template <class T, int N>
312  z.data[0] = data[0];
313 
314  // Linear terms.
315  int k = 0;
316  for(int i = 0; i < N; ++i) {
317  z += data[++k] * m[i];
318  }
319 
320  // Second-order terms.
321  for(int i = 0; i < N; ++i) {
322  for(int j = i; j < N; ++i) {
323  z += data[++k] * m[i] * m[j];
324  }
325  }
326 
327  return z;
328 }
329 
330 
331 template <class T, int N>
333  TransportFun<T, N> x(*this);
334  x[0] = 0.0;
335  return (series[2] * x + series[1]) * x + series[0];
336 }
337 
338 
339 template <class T, int N>
340 std::istream &TransportFun<T, N>::get(std::istream &is) {
341  is.flags(std::ios::skipws);
342  char head[4];
343  is.get(head, 4);
344 
345  if(strcmp(head, "Tps") != 0) {
346  throw FormatError("TransportFun::get()", "Flag word \"Tps\" missing.");
347  }
348 
349  int maxOrder, truncOrder, nVar;
350  is >> maxOrder >> truncOrder >> nVar;
351 
352  if(nVar != N) {
353  throw FormatError("TransportFun::get()", "Invalid number of variables.");
354  }
355 
356  T coeff;
357  int mono[N];
358  bool done = false;
359  bool fail = false;
360 
361  while(true) {
362  is >> coeff;
363  fail = is.fail();
364 
365  int order = 0;
366  for(int var = 0; var < nVar; ++var) {
367  is >> mono[var];
368  fail |= is.fail();
369  if(mono[var] < 0) done = true;
370  order += mono[var];
371  }
372 
373  if(done) break;
374  if(fail) throw FormatError("TransportFun::get()", "File read error");
375 
376  // Store coefficient in proper place.
377  if(order <= 2 && coeff != T(0)) {
378  int order = 0;
379  int index = 0;
380  for(int var = N; var-- > 0;) {
381  order += mono[var];
382  if(order == 1) {
383  ++index;
384  } else if(order == 2) {
385  index += N + order - var;
386  }
387  }
388  data[index] = coeff;
389  }
390  }
391 }
392 
393 
394 template <class T, int N>
395 std::ostream &TransportFun<T, N>::put(std::ostream &os) const {
396  os << "Tps " << this->itsRep->max << ' ' << this->itsRep->trc << ' ' << N
397  << std::endl;
398  std::streamsize old_prec = os.precision(14);
399  os.setf(std::ios::scientific, std::ios::floatfield);
400 
401  // Constant term.
402  T *coeff = data;
403  if(*coeff != T(0)) {
404  os << std::setw(24) << *coeff[0];
405  for(int var = 0; var < N; ++var) {
406  os << std::setw(3) << 0;
407  }
408  }
409 
410  // Linear terms.
411  for(int i = 0; i < N; i++) {
412  ++coeff;
413  if(*coeff != T(0)) {
414  os << std::setw(24) << *coeff;
415  for(int var = 0; var < N; ++var) {
416  os << std::setw(3) << ((var == i) ? 1 : 0);
417  }
418  os << std::endl;
419  }
420  }
421 
422  // Second-order terms.
423  for(int i = 0; i < N; ++i) {
424  ++coeff;
425  if(*coeff != T(0)) {
426  os << std::setw(24) << *coeff;
427  for(int var = 0; var < N; ++var) {
428  os << std::setw(3) << ((var == i) ? 2 : 0);
429  }
430  }
431  for(int j = i + 1; j < N; ++j) {
432  ++coeff;
433  if(*coeff != T(0)) {
434  os << std::setw(24) << *coeff;
435  for(int var = 0; var < N; ++var) {
436  os << std::setw(3) << ((var == i || var == j) ? 1 : 0);
437  }
438  os << std::endl;
439  }
440  }
441  }
442 
443  // End marker.
444  os << std::setw(24) << T(0);
445  for(int var = 0; var < N; ++var) {
446  os << std::setw(3) << (-1);
447  }
448  os << std::endl;
449 
450  os.precision(old_prec);
451  os.setf(std::ios::fixed, std::ios::floatfield);
452  return os;
453 }
454 
455 
456 // Global functions acting on TransportFun<T> objects.
457 // ------------------------------------------------------------------------
458 
459 template <class T, int N> inline
461  TransportFun<T, N> z(lhs);
462  return z += rhs;
463 }
464 
465 
466 template <class T, int N> inline
468  TransportFun<T, N> z(lhs);
469  return z -= rhs;
470 }
471 
472 
473 template <class T, int N> inline
475  TransportFun<T, N> z(lhs);
476  return z += rhs;
477 }
478 
479 
480 template <class T, int N> inline
482  TransportFun<T, N> z(lhs);
483  return z -= rhs;
484 }
485 
486 
487 template <class T, int N> inline
489  TransportFun<T, N> z(rhs);
490  return z += lhs;
491 }
492 
493 
494 template <class T, int N> inline
496  TransportFun<T, N> z(- rhs);
497  return z += lhs;
498 }
499 
500 
501 template <class T, int N> inline
503  return lhs.multiply(rhs);
504 }
505 
506 
507 template <class T, int N> inline
509  return lhs.multiply(rhs.inverse());
510 }
511 
512 
513 template <class T, int N> inline
515  TransportFun<T, N> z(lhs);
516  return z *= rhs;
517 }
518 
519 
520 template <class T, int N> inline
522  TransportFun<T, N> z(lhs);
523  return z /= rhs;
524 }
525 
526 
527 template <class T, int N> inline
529  TransportFun<T, N> z(rhs);
530  return z *= lhs;
531 }
532 
533 
534 template <class T, int N> inline
536  return rhs.inverse() * lhs;
537 }
538 
539 
540 template <class T, int N> inline
541 bool operator==(const T &lhs, const TransportFun<T, N> &rhs) {
542  return rhs == lhs;
543 }
544 
545 
546 template <class T, int N> inline
547 bool operator!=(const T &lhs, const TransportFun<T, N> &rhs) {
548  return rhs != lhs;
549 }
550 
551 
552 template <class T, int N>
553 std::istream &operator>>(std::istream &is, TransportFun<T, N> &fun) {
554  return fun.get(is);
555 }
556 
557 
558 template <class T, int N>
559 std::ostream &operator<<(std::ostream &os, const TransportFun<T, N> &fun) {
560  return fun.put(os);
561 }
562 
563 #endif // CLASSIC_TransportFun_CC
Matrix< T > operator+(const Matrix< T > &, const Matrix< T > &)
Matrix addition.
Definition: Matrix.h:275
Matrix< T > operator/(const Matrix< T > &, const T &)
Matrix divided by scalar.
Definition: Matrix.h:329
std::ostream & put(std::ostream &os) const
Write TransportFun on the stream [b]os[/b].
TransportFun()
Default constructor.
Definition: rbendmap.h:8
Transport map with values of type [b]T[/b] in [b]N[/b] variables.
Definition: Mapper.h:33
A templated representation for vectors.
Definition: PartBunchBase.h:26
static TransportFun makeVariable(int var)
Make variable.
Matrix< T > operator*(const Matrix< T > &, const Matrix< T > &)
Matrix multiply.
Definition: Matrix.h:297
const T getCoefficient(int index) const
Get coefficient.
const T operator()(int i1, int i2) const
Get coefficient.
TransportFun & operator+=(const TransportFun &y)
Add and assign.
TransportFun & operator-=(const TransportFun &y)
Subtract and assign.
T data[SIZE]
Representation.
Definition: TransportFun.h:192
std::istream & get(std::istream &is)
Read TransportFun on the stream [b]is[/b].
TransportFun taylor(const T series[2]) const
Taylor series.
Transport function in N variables of type T.
Definition: TransportFun.h:40
const T operator[](int) const
Get coefficient.
Zero divide error.
Definition: DivideError.h:32
void setCoefficient(int index, const T &value)
Set coefficient.
TransportFun & operator=(const T &y)
Convert and assign.
TransportFun & operator*=(const TransportFun &y)
Multiply and assign.
TransportFun & operator/=(const TransportFun &y)
Approximate division and assignation.
int precision() const
Definition: Inform.h:115
TransportFun multiply(const TransportFun &y) const
Multiplication truncated to order one.
bool operator!=(const Offset &off1, const Offset &off2)
Definition: Offset.cpp:225
TransportFun operator+() const
Unary plus.
bool operator==(const TransportFun &y) const
Equality operator.
TransportFun operator-() const
Unary minus.
T evaluate(const FVector< T, N > &) const
Evaluate TransportFun at point.
Format error exception.
Definition: FormatError.h:32
TransportFun< T, N > substitute(const TransportMap< T, N > &m) const
Substitute.
Matrix< T > operator-(const Matrix< T > &, const Matrix< T > &)
Matrix subtraction.
Definition: Matrix.h:282
bool operator!=(const TransportFun &y) const
Inequality operator.
std::istream & operator>>(std::istream &, LieMap< T > &x)
Extract LieMap&lt;T&gt; from stream.
Definition: LieMap.h:231
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
bool operator==(const TwoPolynomial &left, const TwoPolynomial &right)
TransportFun inverse() const
Approximate reciprocal value 1/(*this).