LILAC
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
euler_sde_tmpl.hpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2014, Sam Schetterer, Nathan Kutz, University of Washington
3 Authors: Sam Schetterer
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 
8 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 
10 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
11 
12 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
13 
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15 
16 */
17 #pragma once
18 #ifndef EULER_SDE_TMPL_HPP
19 #define EULER_SDE_TMPL_HPP
20 #include "utils/defs.hpp"
21 #include "utils/noise.hpp"
22 #include "rhs/rhs_sde.h"
23 #include "euler_sde.h"
24 #include <limits>
25 #include <stdlib.h>
26 #include "types/float_traits.hpp"
28 template<class T>
29 class euler_sde_tmpl: public euler_sde{
30  typedef typename float_traits<T>::type real_type;
32  T* restr f0, * restr w0, *restr bfnc;
34  int calc_dw;
36  public:
37  const std::type_info& vtype() const;
38  void postprocess(input& dat);
39  std::string type() const;
40  int integrate(ptr_passer u, double t0, double tf);
41 
42 };
43 template<class T>
44 int euler_sde_tmpl<T>::integrate(ptr_passer u0, double ts, double tf){
45  T* restr vals = u0;
46  size_t steps = std::ceil((tf-ts)/stepsize);
47  double dt = (tf-ts)/steps;
48  double tc = ts;
49  //separate real_type for use as a multiplying noise factor
50  real_type dt_mul = dt;
51  ALIGNED(vals);
52  ALIGNED(f0);
53  ALIGNED(w0);
54  ALIGNED(bfnc);
55  for(size_t i = 0; i < steps; i++){
56  if(std::abs(dw_weight) > std::numeric_limits<real_type>::epsilon())
57  {
58  gaussian_noise(w0, dimension, 0, dt*dw_weight);
59  if(func){
60  func->mod_w(w0, tc);
61  }
62  //only calculate coefficients for dw if needed
63  if(calc_dw){
64  func->dxdt(vals, f0, tc);
65  func->dwdt(vals, bfnc, tc);
66  for(size_t j = 0; j < dimension; j++){
67  vals[j] = vals[j] + dt_mul*f0[j] + bfnc[j]*w0[j];
68  }
69  }
70  else{
71  rh_val->dxdt(vals, f0, tc);
72  for(size_t j = 0; j < dimension; j++){
73  vals[j] = vals[j] + dt_mul*f0[j] + w0[j];
74  }
75  }
76  }
77  else{
78  rh_val->dxdt(vals, f0, tc);
79  for(size_t j = 0; j < dimension; j++){
80  vals[j] = vals[j] + dt_mul*f0[j];
81  }
82  }
83 
84  tc += dt;
85  }
86  return 0;
87 }
88 template<class T>
89 const std::type_info& euler_sde_tmpl<T>::vtype() const{
90  return typeid(T);
91 }
92 template<class T>
94  return std::string("euler_sde_tmpl<") + this->vname() + ">";
95 }
96 template<class T>
99  //since the rh_val is already obtained by the map,
100  //may as well just check instead of going through retrieve
101  dat.retrieve(calc_dw, "calc_dw", this);
102  func = dynamic_cast<rhs_sde*>(rh_val);
103  if(calc_dw){
104  if(func == 0){
105  err(std::string("The rhs, ") + rh_val->name() + ", is not part of the rhs_sde inheritance heirarchy." +
106  " Consider setting calc_dw to 0 to allow for a constant multiple of the noise factor",
107  this->type() + "::postprocess", "integrator/euler_sde_tmpl.hpp", FATAL_ERROR);
108  }
109  }
110  if(!rh_val->compare<T>()){
111  err("Bad rhs type passed to euler_sde integrator", "euler_sde_tmpl::postprocess",
112  "integrator/euler_sde_tmpl.h", FATAL_ERROR);
113  }
114  //This is a temporay value so that the retrieve is always double
115  double _dw_weight;
116  dat.retrieve(_dw_weight, "dw_weight", this);
117  dw_weight=_dw_weight;
118  double _stepsize;
119  dat.retrieve(_stepsize, "stepsize", this);
120  stepsize=_stepsize;
121  if(stepsize <= 0){
122  err("stepsize is invalid, must be >= 0", "euler_sde_tmpl::postprocess",
123  "integrator/euler_sde_tmpl.hpp", dat["stepsize"], FATAL_ERROR);
124  }
125  memp.create(dimension, &f0, &w0, &bfnc);
126 }
127 #endif