OPAL (Object Oriented Parallel Accelerator Library) 2022.1
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
30#include <iomanip>
31#include <iostream>
32#include <cstring>
33#include <functional>
34
35// Implementation of template class LinearFun<T,N>.
36// ------------------------------------------------------------------------
37
38template <class T, int N>
40 for(int i = 0; i <= N; ++i) data[i] = 0.0;
41}
42
43
44template <class T, int N>
46 data[0] = rhs;
47 for(int i = 1; i <= N; ++i) data[i] = 0.0;
48}
49
50
51template <class T, int N>
53 data[0] = T(rhs);
54 for(int i = 1; i <= N; ++i) data[i] = 0.0;
55}
56
57
58template <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
66template <class T, int N>
67const T LinearFun<T, N>::getCoefficient(int index) const {
68 return (index > N) ? T(0) : data[index];
69}
70
71
72template <class T, int N>
73void LinearFun<T, N>::setCoefficient(int index, const T &value) {
74 if(index <= N) data[index] = value;
75}
76
77
78template <class T, int N> inline
79const T LinearFun<T, N>::operator[](int index) const {
80 return data[index];
81}
82
83
84template <class T, int N> inline
86 return data[index];
87}
88
89
90template <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
99template <class T, int N> inline
101 return *this;
102}
103
104
105template <class T, int N>
108 for(int i = 0; i <= N; ++i) z.data[i] = - data[i];
109 return z;
110}
111
112
113template <class T, int N>
115 for(int i = 0; i <= N; ++i) data[i] += rhs.data[i];
116 return *this;
117}
118
119
120template <class T, int N>
122 for(int i = 0; i <= N; ++i) data[i] -= rhs.data[i];
123 return *this;
124}
125
126
127template <class T, int N>
129 return *this = multiply(rhs);
130}
131
132
133template <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
147template <class T, int N> inline
149 data[0] += rhs;
150 return *this;
151}
152
153
154template <class T, int N> inline
156 data[0] -= rhs;
157 return *this;
158}
159
160
161template <class T, int N>
163 for(int i = 0; i <= N; ++i) data[i] *= rhs;
164 return *this;
165}
166
167
168template <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
176template <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
186template <class T, int N>
187bool 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
198template <class T, int N> inline
200 return !(*this == rhs);
201}
202
203
204template <class T, int N> inline
205bool LinearFun<T, N>::operator!=(const T &rhs) const {
206 return !(*this == rhs);
207}
208
209
210template <class T, int N>
212 T aZero = data[0];
213 if(aZero == T(0)) throw DivideError("LinearFun::inverse()");
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
225template <class T, int N> LinearFun<T, N>
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
238template <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
246template <class T, int N>
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
261template <class T, int N>
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
276template <class T, int N>
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
289template <class T, int N>
290std::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
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
342template <class T, int N>
343std::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
375template <class T, int N> inline
377 LinearFun<T, N> z(lhs);
378 return z += rhs;
379}
380
381
382template <class T, int N> inline
384 LinearFun<T, N> z(lhs);
385 return z -= rhs;
386}
387
388
389template <class T, int N> inline
391 LinearFun<T, N> z(lhs);
392 return z += rhs;
393}
394
395
396template <class T, int N> inline
398 LinearFun<T, N> z(lhs);
399 return z -= rhs;
400}
401
402
403template <class T, int N> inline
405 LinearFun<T, N> z(rhs);
406 return z += lhs;
407}
408
409
410template <class T, int N> inline
412 LinearFun<T, N> z(- rhs);
413 return z += lhs;
414}
415
416
417template <class T, int N> inline
419 return lhs.multiply(rhs);
420}
421
422
423template <class T, int N> inline
425 return lhs.multiply(rhs.inverse());
426}
427
428
429template <class T, int N> inline
431 LinearFun<T, N> z(lhs);
432 return z *= rhs;
433}
434
435
436template <class T, int N> inline
438 LinearFun<T, N> z(lhs);
439 return z /= rhs;
440}
441
442
443template <class T, int N> inline
445 LinearFun<T, N> z(rhs);
446 return z *= lhs;
447}
448
449
450template <class T, int N> inline
452 return rhs.inverse() * lhs;
453}
454
455
456template <class T, int N> inline
457bool operator==(const T &lhs, const LinearFun<T, N> &rhs) {
458 return rhs == lhs;
459}
460
461
462template <class T, int N> inline
463bool operator!=(const T &lhs, const LinearFun<T, N> &rhs) {
464 return rhs != lhs;
465}
466
467
468template <class T, int N> inline
469std::istream &operator>>(std::istream &is, LinearFun<T, N> &tps) {
470 return tps.get(is);
471}
472
473
474template <class T, int N> inline
475std::ostream &operator<<(std::ostream &os, const LinearFun<T, N> &tps) {
476 return tps.put(os);
477}
478
479#endif // CLASSIC_LinearFun_CC
LinearFun< T, N > operator-(const LinearFun< T, N > &lhs, const LinearFun< T, N > &rhs)
Subtract.
Definition: LinearFun.hpp:383
LinearFun< T, N > operator/(const LinearFun< T, N > &lhs, const LinearFun< T, N > &rhs)
Divide.
Definition: LinearFun.hpp:424
LinearFun< T, N > operator+(const LinearFun< T, N > &lhs, const LinearFun< T, N > &rhs)
Add.
Definition: LinearFun.hpp:376
std::ostream & operator<<(std::ostream &os, const LinearFun< T, N > &tps)
Insert LinearFun to stream [b]os[/b].
Definition: LinearFun.hpp:475
bool operator==(const T &lhs, const LinearFun< T, N > &rhs)
Equality.
Definition: LinearFun.hpp:457
LinearFun< T, N > operator*(const LinearFun< T, N > &lhs, const LinearFun< T, N > &rhs)
Multiply.
Definition: LinearFun.hpp:418
std::istream & operator>>(std::istream &is, LinearFun< T, N > &tps)
Extract LinearFun from stream [b]is[/b].
Definition: LinearFun.hpp:469
bool operator!=(const T &lhs, const LinearFun< T, N > &rhs)
Inequality.
Definition: LinearFun.hpp:463
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
A templated representation for vectors.
Definition: FVector.h:38
Linear map with values of type [b]T[/b] in [b]N[/b] variables.
Definition: LinearMap.h:38
Linear function in N variables of type T.
Definition: LinearFun.h:39
LinearFun & operator=(const T &y)
Convert and assign.
Definition: LinearFun.hpp:59
const T operator[](int index) const
Get coefficient.
Definition: LinearFun.hpp:79
LinearFun & operator-=(const LinearFun &y)
Subtract and assign.
Definition: LinearFun.hpp:121
const T getCoefficient(int index) const
Get coefficient.
Definition: LinearFun.hpp:67
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
LinearFun< T, N > substitute(const LinearMap< T, N > &m) const
Substitute.
Definition: LinearFun.hpp:262
LinearFun multiply(const LinearFun &y) const
Multiplication truncated to order one.
Definition: LinearFun.hpp:226
T evaluate(const FVector< T, N > &) const
Evaluate LinearFun at point.
Definition: LinearFun.hpp:239
T data[N+1]
Representation.
Definition: LinearFun.h:164
LinearFun & operator+=(const LinearFun &y)
Add and assign.
Definition: LinearFun.hpp:114
LinearFun taylor(const T series[2]) const
Taylor series.
Definition: LinearFun.hpp:277
bool operator!=(const LinearFun &y) const
Inequality operator.
Definition: LinearFun.hpp:199
LinearFun operator-() const
Unary minus.
Definition: LinearFun.hpp:106
LinearFun operator+() const
Unary plus.
Definition: LinearFun.hpp:100
LinearFun & operator/=(const LinearFun &y)
Approximate division and assignation.
Definition: LinearFun.hpp:134
bool operator==(const LinearFun &y) const
Equality operator.
Definition: LinearFun.hpp:177
LinearFun & operator*=(const LinearFun &y)
Multiply and assign.
Definition: LinearFun.hpp:128
static LinearFun makeVariable(int var)
Make variable.
Definition: LinearFun.hpp:91
LinearFun()
Default constructor.
Definition: LinearFun.hpp:39
LinearFun inverse() const
Approximate reciprocal value 1/(*this).
Definition: LinearFun.hpp:211
std::ostream & put(std::ostream &os) const
Write LinearFun on the stream [b]os[/b].
Definition: LinearFun.hpp:343
Zero divide error.
Definition: DivideError.h:32
Format error exception.
Definition: FormatError.h:32
FmtFlags_t setf(FmtFlags_t setbits, FmtFlags_t field)
Definition: Inform.h:101
int precision() const
Definition: Inform.h:112