]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/units/example/complex.cpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / libs / units / example / complex.cpp
CommitLineData
7c673cae
FG
1// Boost.Units - A C++ library for zero-overhead dimensional analysis and
2// unit/quantity manipulation and conversion
3//
4// Copyright (C) 2003-2008 Matthias Christian Schabel
5// Copyright (C) 2008 Steven Watanabe
6//
7// Distributed under the Boost Software License, Version 1.0. (See
8// accompanying file LICENSE_1_0.txt or copy at
9// http://www.boost.org/LICENSE_1_0.txt)
10
11/**
12\file
13
14\brief complex.cpp
15
16\details
17Demonstrate a complex number class that functions correctly with quantities.
18
19Output:
20@verbatim
21
22//[complex_output_1
23+L = 2 + 1 i m
24-L = -2 + -1 i m
25L+L = 4 + 2 i m
26L-L = 0 + 0 i m
27L*L = 3 + 4 i m^2
28L/L = 1 + 0 i dimensionless
29L^3 = 2 + 11 i m^3
30L^(3/2) = 2.56713 + 2.14247 i m^(3/2)
313vL = 1.29207 + 0.201294 i m^(1/3)
32(3/2)vL = 1.62894 + 0.520175 i m^(2/3)
33//]
34
35//[complex_output_2
36+L = 2 m + 1 m i
37-L = -2 m + -1 m i
38L+L = 4 m + 2 m i
39L-L = 0 m + 0 m i
40L*L = 3 m^2 + 4 m^2 i
41L/L = 1 dimensionless + 0 dimensionless i
42L^3 = 2 m^3 + 11 m^3 i
43L^(3/2) = 2.56713 m^(3/2) + 2.14247 m^(3/2) i
443vL = 1.29207 m^(1/3) + 0.201294 m^(1/3) i
45(3/2)vL = 1.62894 m^(2/3) + 0.520175 m^(2/3) i
46//]
47
48@endverbatim
49**/
50
51#include <cmath>
52#include <complex>
53#include <iostream>
54
55#include <boost/mpl/list.hpp>
56
57#include <boost/units/io.hpp>
58#include <boost/units/pow.hpp>
59#include <boost/units/quantity.hpp>
60
61#include "test_system.hpp"
62
63//[complex_class_snippet_1
64namespace boost {
65
66namespace units {
67
68/// replacement complex class
69template<class T>
70class complex
71{
72 public:
73 typedef complex<T> this_type;
74
11fdf7f2
TL
75 constexpr complex(const T& r = 0,const T& i = 0) : r_(r),i_(i) { }
76 constexpr complex(const this_type& source) : r_(source.r_),i_(source.i_) { }
7c673cae 77
11fdf7f2 78 constexpr this_type& operator=(const this_type& source)
7c673cae
FG
79 {
80 if (this == &source) return *this;
81
82 r_ = source.r_;
83 i_ = source.i_;
84
85 return *this;
86 }
87
11fdf7f2
TL
88 constexpr T& real() { return r_; }
89 constexpr T& imag() { return i_; }
7c673cae 90
11fdf7f2
TL
91 constexpr const T& real() const { return r_; }
92 constexpr const T& imag() const { return i_; }
7c673cae 93
11fdf7f2 94 constexpr this_type& operator+=(const T& val)
7c673cae
FG
95 {
96 r_ += val;
97 return *this;
98 }
99
11fdf7f2 100 constexpr this_type& operator-=(const T& val)
7c673cae
FG
101 {
102 r_ -= val;
103 return *this;
104 }
105
11fdf7f2 106 constexpr this_type& operator*=(const T& val)
7c673cae
FG
107 {
108 r_ *= val;
109 i_ *= val;
110 return *this;
111 }
112
11fdf7f2 113 constexpr this_type& operator/=(const T& val)
7c673cae
FG
114 {
115 r_ /= val;
116 i_ /= val;
117 return *this;
118 }
119
11fdf7f2 120 constexpr this_type& operator+=(const this_type& source)
7c673cae
FG
121 {
122 r_ += source.r_;
123 i_ += source.i_;
124 return *this;
125 }
126
11fdf7f2 127 constexpr this_type& operator-=(const this_type& source)
7c673cae
FG
128 {
129 r_ -= source.r_;
130 i_ -= source.i_;
131 return *this;
132 }
133
11fdf7f2 134 constexpr this_type& operator*=(const this_type& source)
7c673cae
FG
135 {
136 *this = *this * source;
137 return *this;
138 }
139
11fdf7f2 140 constexpr this_type& operator/=(const this_type& source)
7c673cae
FG
141 {
142 *this = *this / source;
143 return *this;
144 }
145
146 private:
147 T r_,i_;
148};
149
150}
151
152}
153
154#if BOOST_UNITS_HAS_BOOST_TYPEOF
155
156#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
157
158BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::complex, 1)
159
160#endif
161
162namespace boost {
163
164namespace units {
165
166template<class X>
11fdf7f2 167constexpr
7c673cae
FG
168complex<typename unary_plus_typeof_helper<X>::type>
169operator+(const complex<X>& x)
170{
171 typedef typename unary_plus_typeof_helper<X>::type type;
172
173 return complex<type>(x.real(),x.imag());
174}
175
176template<class X>
11fdf7f2 177constexpr
7c673cae
FG
178complex<typename unary_minus_typeof_helper<X>::type>
179operator-(const complex<X>& x)
180{
181 typedef typename unary_minus_typeof_helper<X>::type type;
182
183 return complex<type>(-x.real(),-x.imag());
184}
185
186template<class X,class Y>
11fdf7f2 187constexpr
7c673cae
FG
188complex<typename add_typeof_helper<X,Y>::type>
189operator+(const complex<X>& x,const complex<Y>& y)
190{
191 typedef typename boost::units::add_typeof_helper<X,Y>::type type;
192
193 return complex<type>(x.real()+y.real(),x.imag()+y.imag());
194}
195
196template<class X,class Y>
11fdf7f2 197constexpr
7c673cae
FG
198complex<typename boost::units::subtract_typeof_helper<X,Y>::type>
199operator-(const complex<X>& x,const complex<Y>& y)
200{
201 typedef typename boost::units::subtract_typeof_helper<X,Y>::type type;
202
203 return complex<type>(x.real()-y.real(),x.imag()-y.imag());
204}
205
206template<class X,class Y>
11fdf7f2 207constexpr
7c673cae
FG
208complex<typename boost::units::multiply_typeof_helper<X,Y>::type>
209operator*(const complex<X>& x,const complex<Y>& y)
210{
211 typedef typename boost::units::multiply_typeof_helper<X,Y>::type type;
212
213 return complex<type>(x.real()*y.real() - x.imag()*y.imag(),
214 x.real()*y.imag() + x.imag()*y.real());
215
216// fully correct implementation has more complex return type
217//
218// typedef typename boost::units::multiply_typeof_helper<X,Y>::type xy_type;
219//
220// typedef typename boost::units::add_typeof_helper<
221// xy_type,xy_type>::type xy_plus_xy_type;
222// typedef typename
223// boost::units::subtract_typeof_helper<xy_type,xy_type>::type
224// xy_minus_xy_type;
225//
226// BOOST_STATIC_ASSERT((boost::is_same<xy_plus_xy_type,
227// xy_minus_xy_type>::value == true));
228//
229// return complex<xy_plus_xy_type>(x.real()*y.real()-x.imag()*y.imag(),
230// x.real()*y.imag()+x.imag()*y.real());
231}
232
233template<class X,class Y>
11fdf7f2 234constexpr
7c673cae
FG
235complex<typename boost::units::divide_typeof_helper<X,Y>::type>
236operator/(const complex<X>& x,const complex<Y>& y)
237{
238 // naive implementation of complex division
239 typedef typename boost::units::divide_typeof_helper<X,Y>::type type;
240
241 return complex<type>((x.real()*y.real()+x.imag()*y.imag())/
242 (y.real()*y.real()+y.imag()*y.imag()),
243 (x.imag()*y.real()-x.real()*y.imag())/
244 (y.real()*y.real()+y.imag()*y.imag()));
245
246// fully correct implementation has more complex return type
247//
248// typedef typename boost::units::multiply_typeof_helper<X,Y>::type xy_type;
249// typedef typename boost::units::multiply_typeof_helper<Y,Y>::type yy_type;
250//
251// typedef typename boost::units::add_typeof_helper<xy_type, xy_type>::type
252// xy_plus_xy_type;
253// typedef typename boost::units::subtract_typeof_helper<
254// xy_type,xy_type>::type xy_minus_xy_type;
255//
256// typedef typename boost::units::divide_typeof_helper<
257// xy_plus_xy_type,yy_type>::type xy_plus_xy_over_yy_type;
258// typedef typename boost::units::divide_typeof_helper<
259// xy_minus_xy_type,yy_type>::type xy_minus_xy_over_yy_type;
260//
261// BOOST_STATIC_ASSERT((boost::is_same<xy_plus_xy_over_yy_type,
262// xy_minus_xy_over_yy_type>::value == true));
263//
264// return complex<xy_plus_xy_over_yy_type>(
265// (x.real()*y.real()+x.imag()*y.imag())/
266// (y.real()*y.real()+y.imag()*y.imag()),
267// (x.imag()*y.real()-x.real()*y.imag())/
268// (y.real()*y.real()+y.imag()*y.imag()));
269}
270
271template<class Y>
272complex<Y>
273pow(const complex<Y>& x,const Y& y)
274{
275 std::complex<Y> tmp(x.real(),x.imag());
276
277 tmp = std::pow(tmp,y);
278
279 return complex<Y>(tmp.real(),tmp.imag());
280}
281
282template<class Y>
283std::ostream& operator<<(std::ostream& os,const complex<Y>& val)
284{
285 os << val.real() << " + " << val.imag() << " i";
286
287 return os;
288}
289
290/// specialize power typeof helper for complex<Y>
291template<class Y,long N,long D>
292struct power_typeof_helper<complex<Y>,static_rational<N,D> >
293{
294 typedef complex<
295 typename power_typeof_helper<Y,static_rational<N,D> >::type
296 > type;
297
298 static type value(const complex<Y>& x)
299 {
300 const static_rational<N,D> rat;
301
302 const Y m = Y(rat.numerator())/Y(rat.denominator());
303
304 return boost::units::pow(x,m);
305 }
306};
307
308/// specialize root typeof helper for complex<Y>
309template<class Y,long N,long D>
310struct root_typeof_helper<complex<Y>,static_rational<N,D> >
311{
312 typedef complex<
313 typename root_typeof_helper<Y,static_rational<N,D> >::type
314 > type;
315
316 static type value(const complex<Y>& x)
317 {
318 const static_rational<N,D> rat;
319
320 const Y m = Y(rat.denominator())/Y(rat.numerator());
321
322 return boost::units::pow(x,m);
323 }
324};
325
326/// specialize power typeof helper for complex<quantity<Unit,Y> >
327template<class Y,class Unit,long N,long D>
328struct power_typeof_helper<complex<quantity<Unit,Y> >,static_rational<N,D> >
329{
330 typedef typename
331 power_typeof_helper<Y,static_rational<N,D> >::type value_type;
332 typedef typename
333 power_typeof_helper<Unit,static_rational<N,D> >::type unit_type;
334 typedef quantity<unit_type,value_type> quantity_type;
335 typedef complex<quantity_type> type;
336
337 static type value(const complex<quantity<Unit,Y> >& x)
338 {
339 const complex<value_type> tmp =
340 pow<static_rational<N,D> >(complex<Y>(x.real().value(),
341 x.imag().value()));
342
343 return type(quantity_type::from_value(tmp.real()),
344 quantity_type::from_value(tmp.imag()));
345 }
346};
347
348/// specialize root typeof helper for complex<quantity<Unit,Y> >
349template<class Y,class Unit,long N,long D>
350struct root_typeof_helper<complex<quantity<Unit,Y> >,static_rational<N,D> >
351{
352 typedef typename
353 root_typeof_helper<Y,static_rational<N,D> >::type value_type;
354 typedef typename
355 root_typeof_helper<Unit,static_rational<N,D> >::type unit_type;
356 typedef quantity<unit_type,value_type> quantity_type;
357 typedef complex<quantity_type> type;
358
359 static type value(const complex<quantity<Unit,Y> >& x)
360 {
361 const complex<value_type> tmp =
362 root<static_rational<N,D> >(complex<Y>(x.real().value(),
363 x.imag().value()));
364
365 return type(quantity_type::from_value(tmp.real()),
366 quantity_type::from_value(tmp.imag()));
367 }
368};
369
370} // namespace units
371
372} // namespace boost
373//]
374
375int main(void)
376{
7c673cae
FG
377 using namespace boost::units;
378 using namespace boost::units::test;
379
380 {
381 //[complex_snippet_1
382 typedef quantity<length,complex<double> > length_dimension;
383
11fdf7f2 384 const length_dimension L(complex<double>(2.0,1.0)*meters);
7c673cae
FG
385 //]
386
387 std::cout << "+L = " << +L << std::endl
388 << "-L = " << -L << std::endl
389 << "L+L = " << L+L << std::endl
390 << "L-L = " << L-L << std::endl
391 << "L*L = " << L*L << std::endl
392 << "L/L = " << L/L << std::endl
393 << "L^3 = " << pow<3>(L) << std::endl
394 << "L^(3/2) = " << pow< static_rational<3,2> >(L) << std::endl
395 << "3vL = " << root<3>(L) << std::endl
396 << "(3/2)vL = " << root< static_rational<3,2> >(L) << std::endl
397 << std::endl;
398 }
399
400 {
401 //[complex_snippet_2
402 typedef complex<quantity<length> > length_dimension;
403
11fdf7f2 404 const length_dimension L(2.0*meters,1.0*meters);
7c673cae
FG
405 //]
406
407 std::cout << "+L = " << +L << std::endl
408 << "-L = " << -L << std::endl
409 << "L+L = " << L+L << std::endl
410 << "L-L = " << L-L << std::endl
411 << "L*L = " << L*L << std::endl
412 << "L/L = " << L/L << std::endl
413 << "L^3 = " << pow<3>(L) << std::endl
414 << "L^(3/2) = " << pow< static_rational<3,2> >(L) << std::endl
415 << "3vL = " << root<3>(L) << std::endl
416 << "(3/2)vL = " << root< static_rational<3,2> >(L) << std::endl
417 << std::endl;
418 }
419
420 return 0;
421}