File indexing completed on 2025-01-18 09:42:56
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #ifndef BOOST_NUMERIC_ODEINT_STEPPER_CONTROLLED_RUNGE_KUTTA_HPP_INCLUDED
0019 #define BOOST_NUMERIC_ODEINT_STEPPER_CONTROLLED_RUNGE_KUTTA_HPP_INCLUDED
0020
0021
0022
0023 #include <cmath>
0024
0025 #include <boost/config.hpp>
0026 #include <boost/utility/enable_if.hpp>
0027 #include <boost/type_traits/is_same.hpp>
0028
0029 #include <boost/numeric/odeint/util/bind.hpp>
0030 #include <boost/numeric/odeint/util/unwrap_reference.hpp>
0031 #include <boost/numeric/odeint/util/copy.hpp>
0032
0033 #include <boost/numeric/odeint/util/state_wrapper.hpp>
0034 #include <boost/numeric/odeint/util/is_resizeable.hpp>
0035 #include <boost/numeric/odeint/util/resizer.hpp>
0036 #include <boost/numeric/odeint/util/detail/less_with_sign.hpp>
0037
0038 #include <boost/numeric/odeint/algebra/range_algebra.hpp>
0039 #include <boost/numeric/odeint/algebra/default_operations.hpp>
0040 #include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
0041
0042 #include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
0043 #include <boost/numeric/odeint/stepper/stepper_categories.hpp>
0044
0045 namespace boost {
0046 namespace numeric {
0047 namespace odeint {
0048
0049
0050 template
0051 <
0052 class Value ,
0053 class Algebra ,
0054 class Operations
0055 >
0056 class default_error_checker
0057 {
0058 public:
0059
0060 typedef Value value_type;
0061 typedef Algebra algebra_type;
0062 typedef Operations operations_type;
0063
0064 default_error_checker(
0065 value_type eps_abs = static_cast< value_type >( 1.0e-6 ) ,
0066 value_type eps_rel = static_cast< value_type >( 1.0e-6 ) ,
0067 value_type a_x = static_cast< value_type >( 1 ) ,
0068 value_type a_dxdt = static_cast< value_type >( 1 ))
0069 : m_eps_abs( eps_abs ) , m_eps_rel( eps_rel ) , m_a_x( a_x ) , m_a_dxdt( a_dxdt )
0070 { }
0071
0072
0073 template< class State , class Deriv , class Err, class Time >
0074 value_type error( const State &x_old , const Deriv &dxdt_old , Err &x_err , Time dt ) const
0075 {
0076 return error( algebra_type() , x_old , dxdt_old , x_err , dt );
0077 }
0078
0079 template< class State , class Deriv , class Err, class Time >
0080 value_type error( algebra_type &algebra , const State &x_old , const Deriv &dxdt_old , Err &x_err , Time dt ) const
0081 {
0082 using std::abs;
0083
0084 algebra.for_each3( x_err , x_old , dxdt_old ,
0085 typename operations_type::template rel_error< value_type >( m_eps_abs , m_eps_rel , m_a_x , m_a_dxdt * abs(get_unit_value( dt )) ) );
0086
0087
0088
0089 return algebra.norm_inf( x_err );
0090 }
0091
0092 private:
0093
0094 value_type m_eps_abs;
0095 value_type m_eps_rel;
0096 value_type m_a_x;
0097 value_type m_a_dxdt;
0098
0099 };
0100
0101
0102 template< typename Value, typename Time >
0103 class default_step_adjuster
0104 {
0105 public:
0106 typedef Time time_type;
0107 typedef Value value_type;
0108
0109 default_step_adjuster(const time_type max_dt=static_cast<time_type>(0))
0110 : m_max_dt(max_dt)
0111 {}
0112
0113
0114 time_type decrease_step(time_type dt, const value_type error, const int error_order) const
0115 {
0116
0117 BOOST_USING_STD_MIN();
0118 BOOST_USING_STD_MAX();
0119 using std::pow;
0120
0121 dt *= max
0122 BOOST_PREVENT_MACRO_SUBSTITUTION(
0123 static_cast<value_type>( static_cast<value_type>(9) / static_cast<value_type>(10) *
0124 pow(error, static_cast<value_type>(-1) / (error_order - 1))),
0125 static_cast<value_type>( static_cast<value_type>(1) / static_cast<value_type> (5)));
0126 if(m_max_dt != static_cast<time_type >(0))
0127
0128 dt = detail::min_abs(dt, m_max_dt);
0129 return dt;
0130 }
0131
0132 time_type increase_step(time_type dt, value_type error, const int stepper_order) const
0133 {
0134
0135 BOOST_USING_STD_MIN();
0136 BOOST_USING_STD_MAX();
0137 using std::pow;
0138
0139
0140 if(error < 0.5)
0141 {
0142
0143 error = max BOOST_PREVENT_MACRO_SUBSTITUTION (
0144 static_cast<value_type>( pow( static_cast<value_type>(5.0) , -static_cast<value_type>(stepper_order) ) ) ,
0145 error);
0146
0147
0148 dt *= static_cast<value_type>(9)/static_cast<value_type>(10) *
0149 pow(error, static_cast<value_type>(-1) / stepper_order);
0150 if(m_max_dt != static_cast<time_type >(0))
0151
0152 dt = detail::min_abs(dt, m_max_dt);
0153 }
0154 return dt;
0155 }
0156
0157 bool check_step_size_limit(const time_type dt)
0158 {
0159 if(m_max_dt != static_cast<time_type >(0))
0160 return detail::less_eq_with_sign(dt, m_max_dt, dt);
0161 return true;
0162 }
0163
0164 time_type get_max_dt() { return m_max_dt; }
0165
0166 protected:
0167 time_type m_max_dt;
0168 };
0169
0170
0171
0172
0173
0174
0175 template<
0176 class ErrorStepper ,
0177 class ErrorChecker = default_error_checker< typename ErrorStepper::value_type ,
0178 typename ErrorStepper::algebra_type ,
0179 typename ErrorStepper::operations_type > ,
0180 class StepAdjuster = default_step_adjuster< typename ErrorStepper::value_type ,
0181 typename ErrorStepper::time_type > ,
0182 class Resizer = typename ErrorStepper::resizer_type ,
0183 class ErrorStepperCategory = typename ErrorStepper::stepper_category
0184 >
0185 class controlled_runge_kutta ;
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209 template<
0210 class ErrorStepper,
0211 class ErrorChecker,
0212 class StepAdjuster,
0213 class Resizer
0214 >
0215 class controlled_runge_kutta< ErrorStepper , ErrorChecker , StepAdjuster, Resizer ,
0216 explicit_error_stepper_tag >
0217 {
0218
0219 public:
0220
0221 typedef ErrorStepper stepper_type;
0222 typedef typename stepper_type::state_type state_type;
0223 typedef typename stepper_type::value_type value_type;
0224 typedef typename stepper_type::deriv_type deriv_type;
0225 typedef typename stepper_type::time_type time_type;
0226 typedef typename stepper_type::algebra_type algebra_type;
0227 typedef typename stepper_type::operations_type operations_type;
0228 typedef Resizer resizer_type;
0229 typedef ErrorChecker error_checker_type;
0230 typedef StepAdjuster step_adjuster_type;
0231 typedef explicit_controlled_stepper_tag stepper_category;
0232
0233 #ifndef DOXYGEN_SKIP
0234 typedef typename stepper_type::wrapped_state_type wrapped_state_type;
0235 typedef typename stepper_type::wrapped_deriv_type wrapped_deriv_type;
0236
0237 typedef controlled_runge_kutta< ErrorStepper , ErrorChecker , StepAdjuster ,
0238 Resizer , explicit_error_stepper_tag > controlled_stepper_type;
0239 #endif
0240
0241
0242
0243
0244
0245
0246
0247 controlled_runge_kutta(
0248 const error_checker_type &error_checker = error_checker_type( ) ,
0249 const step_adjuster_type &step_adjuster = step_adjuster_type() ,
0250 const stepper_type &stepper = stepper_type( )
0251 )
0252 : m_stepper(stepper), m_error_checker(error_checker) , m_step_adjuster(step_adjuster)
0253 { }
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280 template< class System , class StateInOut >
0281 controlled_step_result try_step( System system , StateInOut &x , time_type &t , time_type &dt )
0282 {
0283 return try_step_v1( system , x , t, dt );
0284 }
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305 template< class System , class StateInOut >
0306 controlled_step_result try_step( System system , const StateInOut &x , time_type &t , time_type &dt )
0307 {
0308 return try_step_v1( system , x , t, dt );
0309 }
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337 template< class System , class StateInOut , class DerivIn >
0338 controlled_step_result try_step( System system , StateInOut &x , const DerivIn &dxdt , time_type &t , time_type &dt )
0339 {
0340 m_xnew_resizer.adjust_size( x , detail::bind( &controlled_runge_kutta::template resize_m_xnew_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) );
0341 controlled_step_result res = try_step( system , x , dxdt , t , m_xnew.m_v , dt );
0342 if( res == success )
0343 {
0344 boost::numeric::odeint::copy( m_xnew.m_v , x );
0345 }
0346 return res;
0347 }
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376 template< class System , class StateIn , class StateOut >
0377 typename boost::disable_if< boost::is_same< StateIn , time_type > , controlled_step_result >::type
0378 try_step( System system , const StateIn &in , time_type &t , StateOut &out , time_type &dt )
0379 {
0380 typename odeint::unwrap_reference< System >::type &sys = system;
0381 m_dxdt_resizer.adjust_size( in , detail::bind( &controlled_runge_kutta::template resize_m_dxdt_impl< StateIn > , detail::ref( *this ) , detail::_1 ) );
0382 sys( in , m_dxdt.m_v , t );
0383 return try_step( system , in , m_dxdt.m_v , t , out , dt );
0384 }
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411 template< class System , class StateIn , class DerivIn , class StateOut >
0412 controlled_step_result try_step( System system , const StateIn &in , const DerivIn &dxdt , time_type &t , StateOut &out , time_type &dt )
0413 {
0414 unwrapped_step_adjuster &step_adjuster = m_step_adjuster;
0415 if( !step_adjuster.check_step_size_limit(dt) )
0416 {
0417
0418 dt = step_adjuster.get_max_dt();
0419 return fail;
0420 }
0421
0422 m_xerr_resizer.adjust_size( in , detail::bind( &controlled_runge_kutta::template resize_m_xerr_impl< StateIn > , detail::ref( *this ) , detail::_1 ) );
0423
0424
0425 m_stepper.do_step( system , in , dxdt , t , out , dt , m_xerr.m_v );
0426
0427 value_type max_rel_err = m_error_checker.error( m_stepper.algebra() , in , dxdt , m_xerr.m_v , dt );
0428
0429 if( max_rel_err > 1.0 )
0430 {
0431
0432 dt = step_adjuster.decrease_step(dt, max_rel_err, m_stepper.error_order());
0433 return fail;
0434 } else
0435 {
0436
0437 t += dt;
0438 dt = step_adjuster.increase_step(dt, max_rel_err, m_stepper.stepper_order());
0439 return success;
0440 }
0441 }
0442
0443
0444
0445
0446
0447 template< class StateType >
0448 void adjust_size( const StateType &x )
0449 {
0450 resize_m_xerr_impl( x );
0451 resize_m_dxdt_impl( x );
0452 resize_m_xnew_impl( x );
0453 m_stepper.adjust_size( x );
0454 }
0455
0456
0457
0458
0459
0460 stepper_type& stepper( void )
0461 {
0462 return m_stepper;
0463 }
0464
0465
0466
0467
0468
0469 const stepper_type& stepper( void ) const
0470 {
0471 return m_stepper;
0472 }
0473
0474 private:
0475
0476
0477 template< class System , class StateInOut >
0478 controlled_step_result try_step_v1( System system , StateInOut &x , time_type &t , time_type &dt )
0479 {
0480 typename odeint::unwrap_reference< System >::type &sys = system;
0481 m_dxdt_resizer.adjust_size( x , detail::bind( &controlled_runge_kutta::template resize_m_dxdt_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) );
0482 sys( x , m_dxdt.m_v ,t );
0483 return try_step( system , x , m_dxdt.m_v , t , dt );
0484 }
0485
0486 template< class StateIn >
0487 bool resize_m_xerr_impl( const StateIn &x )
0488 {
0489 return adjust_size_by_resizeability( m_xerr , x , typename is_resizeable<state_type>::type() );
0490 }
0491
0492 template< class StateIn >
0493 bool resize_m_dxdt_impl( const StateIn &x )
0494 {
0495 return adjust_size_by_resizeability( m_dxdt , x , typename is_resizeable<deriv_type>::type() );
0496 }
0497
0498 template< class StateIn >
0499 bool resize_m_xnew_impl( const StateIn &x )
0500 {
0501 return adjust_size_by_resizeability( m_xnew , x , typename is_resizeable<state_type>::type() );
0502 }
0503
0504
0505
0506 stepper_type m_stepper;
0507 error_checker_type m_error_checker;
0508 step_adjuster_type m_step_adjuster;
0509 typedef typename unwrap_reference< step_adjuster_type >::type unwrapped_step_adjuster;
0510
0511 resizer_type m_dxdt_resizer;
0512 resizer_type m_xerr_resizer;
0513 resizer_type m_xnew_resizer;
0514
0515 wrapped_deriv_type m_dxdt;
0516 wrapped_state_type m_xerr;
0517 wrapped_state_type m_xnew;
0518 };
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549 template<
0550 class ErrorStepper ,
0551 class ErrorChecker ,
0552 class StepAdjuster ,
0553 class Resizer
0554 >
0555 class controlled_runge_kutta< ErrorStepper , ErrorChecker , StepAdjuster , Resizer , explicit_error_stepper_fsal_tag >
0556 {
0557
0558 public:
0559
0560 typedef ErrorStepper stepper_type;
0561 typedef typename stepper_type::state_type state_type;
0562 typedef typename stepper_type::value_type value_type;
0563 typedef typename stepper_type::deriv_type deriv_type;
0564 typedef typename stepper_type::time_type time_type;
0565 typedef typename stepper_type::algebra_type algebra_type;
0566 typedef typename stepper_type::operations_type operations_type;
0567 typedef Resizer resizer_type;
0568 typedef ErrorChecker error_checker_type;
0569 typedef StepAdjuster step_adjuster_type;
0570 typedef explicit_controlled_stepper_fsal_tag stepper_category;
0571
0572 #ifndef DOXYGEN_SKIP
0573 typedef typename stepper_type::wrapped_state_type wrapped_state_type;
0574 typedef typename stepper_type::wrapped_deriv_type wrapped_deriv_type;
0575
0576 typedef controlled_runge_kutta< ErrorStepper , ErrorChecker , StepAdjuster , Resizer , explicit_error_stepper_tag > controlled_stepper_type;
0577 #endif
0578
0579
0580
0581
0582
0583
0584 controlled_runge_kutta(
0585 const error_checker_type &error_checker = error_checker_type() ,
0586 const step_adjuster_type &step_adjuster = step_adjuster_type() ,
0587 const stepper_type &stepper = stepper_type()
0588 )
0589 : m_stepper( stepper ) , m_error_checker( error_checker ) , m_step_adjuster(step_adjuster) ,
0590 m_first_call( true )
0591 { }
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616 template< class System , class StateInOut >
0617 controlled_step_result try_step( System system , StateInOut &x , time_type &t , time_type &dt )
0618 {
0619 return try_step_v1( system , x , t , dt );
0620 }
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642 template< class System , class StateInOut >
0643 controlled_step_result try_step( System system , const StateInOut &x , time_type &t , time_type &dt )
0644 {
0645 return try_step_v1( system , x , t , dt );
0646 }
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677 template< class System , class StateIn , class StateOut >
0678 typename boost::disable_if< boost::is_same< StateIn , time_type > , controlled_step_result >::type
0679 try_step( System system , const StateIn &in , time_type &t , StateOut &out , time_type &dt )
0680 {
0681 if( m_dxdt_resizer.adjust_size( in , detail::bind( &controlled_runge_kutta::template resize_m_dxdt_impl< StateIn > , detail::ref( *this ) , detail::_1 ) ) || m_first_call )
0682 {
0683 initialize( system , in , t );
0684 }
0685 return try_step( system , in , m_dxdt.m_v , t , out , dt );
0686 }
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713 template< class System , class StateInOut , class DerivInOut >
0714 controlled_step_result try_step( System system , StateInOut &x , DerivInOut &dxdt , time_type &t , time_type &dt )
0715 {
0716 m_xnew_resizer.adjust_size( x , detail::bind( &controlled_runge_kutta::template resize_m_xnew_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) );
0717 m_dxdt_new_resizer.adjust_size( x , detail::bind( &controlled_runge_kutta::template resize_m_dxdt_new_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) );
0718 controlled_step_result res = try_step( system , x , dxdt , t , m_xnew.m_v , m_dxdtnew.m_v , dt );
0719 if( res == success )
0720 {
0721 boost::numeric::odeint::copy( m_xnew.m_v , x );
0722 boost::numeric::odeint::copy( m_dxdtnew.m_v , dxdt );
0723 }
0724 return res;
0725 }
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752 template< class System , class StateIn , class DerivIn , class StateOut , class DerivOut >
0753 controlled_step_result try_step( System system , const StateIn &in , const DerivIn &dxdt_in , time_type &t ,
0754 StateOut &out , DerivOut &dxdt_out , time_type &dt )
0755 {
0756 unwrapped_step_adjuster &step_adjuster = m_step_adjuster;
0757 if( !step_adjuster.check_step_size_limit(dt) )
0758 {
0759
0760 dt = step_adjuster.get_max_dt();
0761 return fail;
0762 }
0763
0764 m_xerr_resizer.adjust_size( in , detail::bind( &controlled_runge_kutta::template resize_m_xerr_impl< StateIn > , detail::ref( *this ) , detail::_1 ) );
0765
0766
0767
0768 m_stepper.do_step( system , in , dxdt_in , t , out , dxdt_out , dt , m_xerr.m_v );
0769
0770
0771 value_type max_rel_err = m_error_checker.error( m_stepper.algebra() , in , dxdt_in , m_xerr.m_v , dt );
0772
0773 if( max_rel_err > 1.0 )
0774 {
0775
0776 dt = step_adjuster.decrease_step(dt, max_rel_err, m_stepper.error_order());
0777 return fail;
0778 }
0779
0780 t += dt;
0781 dt = step_adjuster.increase_step(dt, max_rel_err, m_stepper.stepper_order());
0782 return success;
0783 }
0784
0785
0786
0787
0788
0789 void reset( void )
0790 {
0791 m_first_call = true;
0792 }
0793
0794
0795
0796
0797
0798
0799 template< class DerivIn >
0800 void initialize( const DerivIn &deriv )
0801 {
0802 boost::numeric::odeint::copy( deriv , m_dxdt.m_v );
0803 m_first_call = false;
0804 }
0805
0806
0807
0808
0809
0810
0811
0812
0813
0814 template< class System , class StateIn >
0815 void initialize( System system , const StateIn &x , time_type t )
0816 {
0817 typename odeint::unwrap_reference< System >::type &sys = system;
0818 sys( x , m_dxdt.m_v , t );
0819 m_first_call = false;
0820 }
0821
0822
0823
0824
0825
0826
0827 bool is_initialized( void ) const
0828 {
0829 return ! m_first_call;
0830 }
0831
0832
0833
0834
0835
0836
0837 template< class StateType >
0838 void adjust_size( const StateType &x )
0839 {
0840 resize_m_xerr_impl( x );
0841 resize_m_dxdt_impl( x );
0842 resize_m_dxdt_new_impl( x );
0843 resize_m_xnew_impl( x );
0844 }
0845
0846
0847
0848
0849
0850
0851 stepper_type& stepper( void )
0852 {
0853 return m_stepper;
0854 }
0855
0856
0857
0858
0859
0860 const stepper_type& stepper( void ) const
0861 {
0862 return m_stepper;
0863 }
0864
0865
0866
0867 private:
0868
0869
0870 template< class StateIn >
0871 bool resize_m_xerr_impl( const StateIn &x )
0872 {
0873 return adjust_size_by_resizeability( m_xerr , x , typename is_resizeable<state_type>::type() );
0874 }
0875
0876 template< class StateIn >
0877 bool resize_m_dxdt_impl( const StateIn &x )
0878 {
0879 return adjust_size_by_resizeability( m_dxdt , x , typename is_resizeable<deriv_type>::type() );
0880 }
0881
0882 template< class StateIn >
0883 bool resize_m_dxdt_new_impl( const StateIn &x )
0884 {
0885 return adjust_size_by_resizeability( m_dxdtnew , x , typename is_resizeable<deriv_type>::type() );
0886 }
0887
0888 template< class StateIn >
0889 bool resize_m_xnew_impl( const StateIn &x )
0890 {
0891 return adjust_size_by_resizeability( m_xnew , x , typename is_resizeable<state_type>::type() );
0892 }
0893
0894
0895 template< class System , class StateInOut >
0896 controlled_step_result try_step_v1( System system , StateInOut &x , time_type &t , time_type &dt )
0897 {
0898 if( m_dxdt_resizer.adjust_size( x , detail::bind( &controlled_runge_kutta::template resize_m_dxdt_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) ) || m_first_call )
0899 {
0900 initialize( system , x , t );
0901 }
0902 return try_step( system , x , m_dxdt.m_v , t , dt );
0903 }
0904
0905
0906 stepper_type m_stepper;
0907 error_checker_type m_error_checker;
0908 step_adjuster_type m_step_adjuster;
0909 typedef typename unwrap_reference< step_adjuster_type >::type unwrapped_step_adjuster;
0910
0911 resizer_type m_dxdt_resizer;
0912 resizer_type m_xerr_resizer;
0913 resizer_type m_xnew_resizer;
0914 resizer_type m_dxdt_new_resizer;
0915
0916 wrapped_deriv_type m_dxdt;
0917 wrapped_state_type m_xerr;
0918 wrapped_state_type m_xnew;
0919 wrapped_deriv_type m_dxdtnew;
0920 bool m_first_call;
0921 };
0922
0923
0924
0925
0926
0927
0928
0929
0930
0931
0932
0933
0934
0935
0936
0937
0938
0939
0940
0941
0942
0943
0944
0945
0946
0947
0948
0949
0950
0951
0952
0953
0954
0955
0956
0957
0958
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968
0969
0970
0971
0972
0973
0974
0975
0976
0977
0978
0979
0980
0981
0982
0983
0984
0985
0986
0987
0988
0989
0990
0991
0992
0993
0994
0995
0996
0997
0998
0999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013 }
1014 }
1015 }
1016
1017
1018 #endif