OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
LinearFun.hpp
Go to the documentation of this file.
1 #ifndef CLASSIC_LinearFun_CC
2 #define CLASSIC_LinearFun_CC
3 
4 // ------------------------------------------------------------------------
5 // $RCSfile: LinearFun.cpp,v $
6 // ------------------------------------------------------------------------
7 // $Revision: 1.2 $
8 // ------------------------------------------------------------------------
9 // Copyright: see Copyright.readme
10 // ------------------------------------------------------------------------
11 //
12 // Template class: LinearFun<T,N>
13 // Representation of a linear function with values of type T,
14 // and fixed number of variables N.
15 //
16 // ------------------------------------------------------------------------
17 // Class category: FixedAlgebra
18 // ------------------------------------------------------------------------
19 //
20 // $Date: 2000/03/28 13:20:54 $
21 // $Author: mad $
22 //
23 // ------------------------------------------------------------------------
24 
25 #include "FixedAlgebra/LinearFun.h"
26 #include "FixedAlgebra/FMatrix.h"
27 #include "FixedAlgebra/FVector.h"
28 #include "Utilities/DivideError.h"
29 #include "Utilities/FormatError.h"
30 #include <iomanip>
31 #include <iostream>
32 #include <cstring>
33 #include <functional>
34 
35 // Implementation of template class LinearFun<T,N>.
36 // ------------------------------------------------------------------------
37 
38 template <class T, int N>
40  for(int i = 0; i <= N; ++i) data[i] = 0.0;
41 }
42 
43 
44 template <class T, int N>
46  data[0] = rhs;
47  for(int i = 1; i <= N; ++i) data[i] = 0.0;
48 }
49 
50 
51 template <class T, int N>
53  data[0] = T(rhs);
54  for(int i = 1; i <= N; ++i) data[i] = 0.0;
55 }
56 
57 
58 template <class T, int N>
60  data[0] = rhs;
61  for(int i = 1; i <= N; ++i) data[i] = 0.0;
62  return *this;
63 }
64 
65 
66 template <class T, int N>
67 const T LinearFun<T, N>::getCoefficient(int index) const {
68  return (index > N) ? T(0) : data[index];
69 }
70 
71 
72 template <class T, int N>
73 void LinearFun<T, N>::setCoefficient(int index, const T &value) {
74  if(index <= N) data[index] = value;
75 }
76 
77 
78 template <class T, int N> inline
79 const T LinearFun<T, N>::operator[](int index) const {
80  return data[index];
81 }
82 
83 
84 template <class T, int N> inline
86  return data[index];
87 }
88 
89 
90 template <class T, int N>
93  for(int i = 0; i <= N; ++i) z.data[i] = 0.0;
94  z.data[var+1] = T(1);
95  return z;
96 }
97 
98 
99 template <class T, int N> inline
101  return *this;
102 }
103 
104 
105 template <class T, int N>
107  LinearFun<T, N> z;
108  for(int i = 0; i <= N; ++i) z.data[i] = - data[i];
109  return z;
110 }
111 
112 
113 template <class T, int N>
115  for(int i = 0; i <= N; ++i) data[i] += rhs.data[i];
116  return *this;
117 }
118 
119 
120 template <class T, int N>
122  for(int i = 0; i <= N; ++i) data[i] -= rhs.data[i];
123  return *this;
124 }
125 
126 
127 template <class T, int N>
129  return *this = multiply(rhs);
130 }
131 
132 
133 template <class T, int N>
135  if(rhs.data[0] == T(0)) throw DivideError("LinearFun::operator/=()");
136  T div = T(1) / rhs.data[0];
137  data[0] *= div;
138 
139  for(int i = 1; i <= N; ++i) {
140  data[i] = (data[i] - data[0] * rhs.data[i]) * div;
141  }
142 
143  return *this;
144 }
145 
146 
147 template <class T, int N> inline
149  data[0] += rhs;
150  return *this;
151 }
152 
153 
154 template <class T, int N> inline
156  data[0] -= rhs;
157  return *this;
158 }
159 
160 
161 template <class T, int N>
163  for(int i = 0; i <= N; ++i) data[i] *= rhs;
164  return *this;
165 }
166 
167 
168 template <class T, int N>
170  if(rhs == T(0)) throw DivideError("LinearFun::operator/=()");
171  for(int i = 0; i <= N; ++i) data[i] /= rhs;
172  return *this;
173 }
174 
175 
176 template <class T, int N>
178  for(int i = 0; i <= N; ++i) {
179  if(data[i] != rhs.data[i]) return false;
180  }
181 
182  return true;
183 }
184 
185 
186 template <class T, int N>
187 bool LinearFun<T, N>::operator==(const T &rhs) const {
188  if(data[0] != rhs) return false;
189 
190  for(int i = 1; i <= N; ++i) {
191  if(data[i] != T(0)) return false;
192  }
193 
194  return true;
195 }
196 
197 
198 template <class T, int N> inline
200  return !(*this == rhs);
201 }
202 
203 
204 template <class T, int N> inline
205 bool LinearFun<T, N>::operator!=(const T &rhs) const {
206  return !(*this == rhs);
207 }
208 
209 
210 template <class T, int N>
212  T aZero = data[0];
213  if(aZero == T(0)) throw DivideError("LinearFun::inverse()");
214  LinearFun<T, N> z;
215  z.data[0] = T(1) / aZero;
216 
217  for(int i = 1; i <= N; ++i) {
218  z.data[i] = - data[i] * data[i] * z.data[0];
219  }
220 
221  return z;
222 }
223 
224 
225 template <class T, int N> LinearFun<T, N>
227  LinearFun<T, N> z;
228  z.data[0] = data[0] * rhs.data[0];
229 
230  for(int i = 1; i <= N; ++i) {
231  z.data[i] = data[0] * rhs.data[i] + data[i] * rhs.data[0];
232  }
233 
234  return z;
235 }
236 
237 
238 template <class T, int N>
240  T z = data[0];
241  for(int i = 0; i < N; ++i) z += data[i+1] * rhs[i];
242  return z;
243 }
244 
245 
246 template <class T, int N>
248  LinearFun<T, N> z;
249  z.data[0] = data[0];
250 
251  for(int i = 0; i < N; ++i) {
252  for(int j = 0; j < N; ++i) {
253  z.data[i+1] += data[j+1] * M[j][i];
254  }
255  }
256 
257  return z;
258 }
259 
260 
261 template <class T, int N>
263  LinearFun<T, N> z;
264  z.data[0] = data[0];
265 
266  for(int i = 0; i <= N; ++i) {
267  for(int j = 0; j < N; ++i) {
268  z.data[i] += data[j] * m[j][i];
269  }
270  }
271 
272  return z;
273 }
274 
275 
276 template <class T, int N>
277 LinearFun<T, N> LinearFun<T, N>::taylor(const T series[2]) const {
278  LinearFun<T, N> z;
279  z.data[0] = series[0];
280 
281  for(int i = 1; i <= N; ++i) {
282  z.data[i] = series[1] * data[i];
283  }
284 
285  return z;
286 }
287 
288 
289 template <class T, int N>
290 std::istream &LinearFun<T, N>::get(std::istream &is) {
291  is.flags(std::ios::skipws);
292  char head[4];
293  is.get(head, 4);
294 
295  if(strcmp(head, "LinearFun") != 0) {
296  throw FormatError("LinearFun::get()", "Flag word \"Tps\" missing.");
297  }
298 
299  int maxOrder, truncOrder, nVar;
300  is >> maxOrder >> truncOrder >> nVar;
301 
302  if(nVar != N) {
303  throw FormatError("LinearFun::get()", "Invalid number of variables.");
304  }
305 
306  LinearFun<T, N> z;
307  T coeff;
308  bool done = false;
309  bool fail = false;
310 
311  while(true) {
312  is >> coeff;
313  fail = is.fail();
314 
315  int order = 0;
316  int index = 0;
317  for(int var = 0; var < N; var++) {
318  int p;
319  is >> p;
320  fail |= is.fail();
321  if(p < 0) {
322  done = true;
323  } else if(p > 0) {
324  index = var;
325  }
326 
327  order += p;
328  }
329 
330  if(done) break;
331  if(fail) throw FormatError("LinearFun::get()", "File read error");
332 
333  if(order <= 1 && coeff != T(0)) {
334  z.data[index] = coeff;
335  }
336  }
337 
338  *this = z;
339 }
340 
341 
342 template <class T, int N>
343 std::ostream &LinearFun<T, N>::put(std::ostream &os) const {
344  os << "LinearFun " << 1 << ' ' << 1 << ' ' << N << std::endl;
345  os.precision(14);
346  os.setf(std::ios::scientific, std::ios::floatfield);
347 
348  for(int i = 0; i <= N; i++) {
349  if(data[i] != T(0)) {
350  os << std::setw(24) << data[i];
351 
352  for(int v = 1; v <= N; ++v) {
353  os << std::setw(3) << (v == i ? 1 : 0);
354  }
355 
356  os << std::endl;
357  }
358  }
359 
360  os << std::setw(24) << T(0);
361 
362  for(int v = 0; v < N; v++) {
363  os << std::setw(3) << (-1);
364  }
365 
366  os << std::endl;
367  os.setf(std::ios::fixed, std::ios::floatfield);
368  return os;
369 }
370 
371 
372 // Global functions acting on LinearFun<T> objects.
373 // ------------------------------------------------------------------------
374 
375 template <class T, int N> inline
377  LinearFun<T, N> z(lhs);
378  return z += rhs;
379 }
380 
381 
382 template <class T, int N> inline
384  LinearFun<T, N> z(lhs);
385  return z -= rhs;
386 }
387 
388 
389 template <class T, int N> inline
390 LinearFun<T, N> operator+(const LinearFun<T, N> &lhs, const T &rhs) {
391  LinearFun<T, N> z(lhs);
392  return z += rhs;
393 }
394 
395 
396 template <class T, int N> inline
397 LinearFun<T, N> operator-(const LinearFun<T, N> &lhs, const T &rhs) {
398  LinearFun<T, N> z(lhs);
399  return z -= rhs;
400 }
401 
402 
403 template <class T, int N> inline
404 LinearFun<T, N> operator+(const T &lhs, const LinearFun<T, N> &rhs) {
405  LinearFun<T, N> z(rhs);
406  return z += lhs;
407 }
408 
409 
410 template <class T, int N> inline
411 LinearFun<T, N> operator-(const T &lhs, const LinearFun<T, N> &rhs) {
412  LinearFun<T, N> z(- rhs);
413  return z += lhs;
414 }
415 
416 
417 template <class T, int N> inline
419  return lhs.multiply(rhs);
420 }
421 
422 
423 template <class T, int N> inline
425  return lhs.multiply(rhs.inverse());
426 }
427 
428 
429 template <class T, int N> inline
430 LinearFun<T, N> operator*(const LinearFun<T, N> &lhs, const T &rhs) {
431  LinearFun<T, N> z(lhs);
432  return z *= rhs;
433 }
434 
435 
436 template <class T, int N> inline
437 LinearFun<T, N> operator/(const LinearFun<T, N> &lhs, const T &rhs) {
438  LinearFun<T, N> z(lhs);
439  return z /= rhs;
440 }
441 
442 
443 template <class T, int N> inline
444 LinearFun<T, N> operator*(const T &lhs, const LinearFun<T, N> &rhs) {
445  LinearFun<T, N> z(rhs);
446  return z *= lhs;
447 }
448 
449 
450 template <class T, int N> inline
451 LinearFun<T, N> operator/(const T &lhs, const LinearFun<T, N> &rhs) {
452  return rhs.inverse() * lhs;
453 }
454 
455 
456 template <class T, int N> inline
457 bool operator==(const T &lhs, const LinearFun<T, N> &rhs) {
458  return rhs == lhs;
459 }
460 
461 
462 template <class T, int N> inline
463 bool operator!=(const T &lhs, const LinearFun<T, N> &rhs) {
464  return rhs != lhs;
465 }
466 
467 
468 template <class T, int N> inline
469 std::istream &operator>>(std::istream &is, LinearFun<T, N> &tps) {
470  return tps.get(is);
471 }
472 
473 
474 template <class T, int N> inline
475 std::ostream &operator<<(std::ostream &os, const LinearFun<T, N> &tps) {
476  return tps.put(os);
477 }
478 
479 #endif // CLASSIC_LinearFun_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
Definition: rbendmap.h:8
LinearFun operator+() const
Unary plus.
Definition: LinearFun.hpp:100
std::ostream & put(std::ostream &os) const
Write LinearFun on the stream [b]os[/b].
Definition: LinearFun.hpp:343
LinearFun taylor(const T series[2]) const
Taylor series.
Definition: LinearFun.hpp:277
LinearFun multiply(const LinearFun &y) const
Multiplication truncated to order one.
Definition: LinearFun.hpp:226
A templated representation for vectors.
Definition: PartBunchBase.h:26
LinearFun inverse() const
Approximate reciprocal value 1/(*this).
Definition: LinearFun.hpp:211
Matrix< T > operator*(const Matrix< T > &, const Matrix< T > &)
Matrix multiply.
Definition: Matrix.h:297
LinearFun & operator/=(const LinearFun &y)
Approximate division and assignation.
Definition: LinearFun.hpp:134
LinearFun & operator+=(const LinearFun &y)
Add and assign.
Definition: LinearFun.hpp:114
FmtFlags_t setf(FmtFlags_t setbits, FmtFlags_t field)
Definition: Inform.h:104
const T operator[](int index) const
Get coefficient.
Definition: LinearFun.hpp:79
static LinearFun makeVariable(int var)
Make variable.
Definition: LinearFun.hpp:91
LinearFun< T, N > substitute(const LinearMap< T, N > &m) const
Substitute.
Definition: LinearFun.hpp:262
std::istream & get(std::istream &is)
Read LinearFun on the stream [b]is[/b].
Definition: LinearFun.hpp:290
void setCoefficient(int index, const T &value)
Set coefficient.
Definition: LinearFun.hpp:73
Linear map with values of type [b]T[/b] in [b]N[/b] variables.
Zero divide error.
Definition: DivideError.h:32
LinearFun & operator*=(const LinearFun &y)
Multiply and assign.
Definition: LinearFun.hpp:128
LinearFun & operator=(const T &y)
Convert and assign.
Definition: LinearFun.hpp:59
int precision() const
Definition: Inform.h:115
bool operator!=(const Offset &off1, const Offset &off2)
Definition: Offset.cpp:225
bool operator!=(const LinearFun &y) const
Inequality operator.
Definition: LinearFun.hpp:199
LinearFun()
Default constructor.
Definition: LinearFun.hpp:39
T data[N+1]
Representation.
Definition: LinearFun.h:164
T evaluate(const FVector< T, N > &) const
Evaluate LinearFun at point.
Definition: LinearFun.hpp:239
Format error exception.
Definition: FormatError.h:32
bool operator==(const LinearFun &y) const
Equality operator.
Definition: LinearFun.hpp:177
LinearFun & operator-=(const LinearFun &y)
Subtract and assign.
Definition: LinearFun.hpp:121
Linear function in N variables of type T.
Definition: LinearFun.h:39
Matrix< T > operator-(const Matrix< T > &, const Matrix< T > &)
Matrix subtraction.
Definition: Matrix.h:282
const T getCoefficient(int index) const
Get coefficient.
Definition: LinearFun.hpp:67
LinearFun operator-() const
Unary minus.
Definition: LinearFun.hpp:106
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)