cheshirekow  v0.1.0
differentiate.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Josh Bialkowski (jbialk@mit.edu)
3  *
4  * This file is part of mpblocks.
5  *
6  * mpblocks is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * mpblocks is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with mpblocks. If not, see <http://www.gnu.org/licenses/>.
18  */
27 #ifndef MPBLOCKS_CUDA_POLYNOMIAL_DIFFERENTIATE_H_
28 #define MPBLOCKS_CUDA_POLYNOMIAL_DIFFERENTIATE_H_
29 
30 
31 namespace mpblocks {
32 namespace cuda {
33 namespace polynomial {
34 
35 
36 template < class Spec, int n >
37 struct DerivativeSpec{};
38 
39 template< int Head, class Tail, int n>
40 struct DerivativeSpec< IntList<Head,Tail>, n >
41 {
42  typedef typename
43  intlist::if_else< (Head < n),
45  IntList<Head-n, typename DerivativeSpec<Tail,n>::result>
46  >::result
48 };
49 
50 template< int Head, int n>
51 struct DerivativeSpec< IntList<Head,intlist::Terminal>, n >
52 {
53  typedef typename
54  intlist::if_else< (Head < n),
57  >::result
59 };
60 
61 
62 namespace derivative_detail
63 {
64  template< int n, class Exp1, class Exp2, class Spec>
65  struct InitHelper{};
66 
67  template< int n, class Exp1, class Exp2, int Head, class Tail >
68  struct InitHelper< n, Exp1, Exp2, IntList<Head,Tail> >
69  {
71  static void copy( const Exp1& in, Exp2& out )
72  {
73  set<Head>(out) = get<Head+n>(in);
75  }
76  };
77 
78  template< int n, class Exp1, class Exp2, int Head >
79  struct InitHelper< n, Exp1, Exp2, IntList<Head,intlist::Terminal> >
80  {
82  static void copy( const Exp1& in, Exp2& out )
83  {
84  set<Head>(out) = get<Head+n>(in);
85  }
86  };
87 
88  template< bool B, class Exp, int j, int i >
89  struct SetHelper
90  {
92  static void do_it( Exp& out ){}
93  };
94 
95  template< class Exp, int j, int i >
96  struct SetHelper<true,Exp,j,i>
97  {
99  static void do_it( Exp& out )
100  {
101  set<j>(out) *= i;
102  }
103  };
104 
105 
106  template< class Exp, class Spec, int j, int i, int size2>
107  struct Looper2
108  {
110  static void go( Exp& out )
111  {
112  SetHelper< intlist::contains<Spec,j>::value, Exp,j,i >::do_it(out);
114  }
115  };
116 
118  template< class Exp, class Spec, int i, int size2>
119  struct Looper2<Exp, Spec, i, i, size2 >
120  {
122  static void go( Exp& out ){}
123  };
124 
126  template< class Exp, class Spec, int i, int size2>
127  struct Looper2<Exp, Spec, size2, i, size2 >
128  {
130  static void go( Exp& out ){}
131  };
132 
134  template< class Exp, class Spec, int size2>
135  struct Looper2<Exp, Spec, size2, size2, size2 >
136  {
138  static void go( Exp& out ){}
139  };
140 
141  template< int n, int size1, class Exp2, class Spec2, int i>
142  struct Looper1
143  {
145  static void go( Exp2& out )
146  {
147  Looper2< Exp2,Spec2,i-n,i, intlist::max<Spec2>::value+1 >::go(out);
149  }
150  };
151 
152  template< int n, int size1, class Exp2, class Spec2>
153  struct Looper1<n,size1,Exp2,Spec2,size1>
154  {
156  static void go( Exp2& out ){}
157  };
158 
159 }
160 
161 
163 template <int n, typename Scalar, class Exp1, class InSpec, class Exp2>
166  LValue<Scalar,Exp2>& out )
167 {
168  typedef typename DerivativeSpec<InSpec,n>::result OutSpec;
169 
170  enum{ max_in = intlist::max<InSpec>::value };
171  enum{ max_out = intlist::max<OutSpec>::value };
172 
173  // initialize the output
175  static_cast<const Exp1&>(in),
176  static_cast<Exp2&>(out) );
177 // for(int i=0; i < out.size(); i++)
178 // out[i] = in[i+n];
179 
180 
181  // fill the output with the initial coefficients
183  static_cast<Exp2&>(out) );
184 // for(int i=2; i < in.size(); i++)
185 // {
186 // // the factor i contributes to all coefficients of the output
187 // // with index >= (i-n) < (i)
188 // for(int j = i-n; j < i && j < out.size(); j++)
189 // out[j] *= i;
190 // }
191 }
192 
194 template <int n, typename Scalar, class Exp, class Spec>
197 {
199  static_cast< const Exp& >(exp) );
200 };
201 
202 
203 
204 } // namespace polynomial
205 } // namespace cuda
206 } // namespace mpblocks
207 
208 
209 
210 
211 
212 
213 
214 
215 
216 
217 
218 
219 
220 
221 
222 #endif // DIFFERENTIATE_H_
__host__ static __device__ void go(Exp2 &out)
__host__ __device__ void differentiate(const RValue< Scalar, Exp1, InSpec > &in, LValue< Scalar, Exp2 > &out)
evaluate a polynomial
__host__ static __device__ void go(Exp &out)
expression template for rvalues
Definition: RValue.h:40
expression template for lvalues
Definition: LValue.h:85
__host__ __device__ DerivativeSurrogate< n, Scalar, Exp, Spec > d_ds(const RValue< Scalar, Exp, Spec > &exp)
return a surrogate which notifies LValue to call differentiate
intermediate object which allows LValue assignment operator to call differntiate expression template ...
Definition: LValue.h:73
__host__ static __device__ void do_it(Exp &out)
Definition: differentiate.h:92
#define __device__
Definition: fakecuda.h:34
retrieve the max element of the list (linear without short circut so it works with non-sorted arrays ...
Definition: IntList.h:415
#define __host__
Definition: fakecuda.h:37
Char8_t * copy(const Char8_t *s)
compile time integer list (because cuda doesn't understand variadic templates )
Definition: IntList.h:50