casadi_blazing_1d_boor_eval.hpp
1 //
2 // MIT No Attribution
3 //
4 // Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl, KU Leuven.
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
7 // software and associated documentation files (the "Software"), to deal in the Software
8 // without restriction, including without limitation the rights to use, copy, modify,
9 // merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
10 // permit persons to whom the Software is furnished to do so.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13 // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
14 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
15 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
16 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
17 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 //
19 
20 // C-REPLACE "casadi_blazing_boor_init<T1>" "casadi_blazing_boor_init"
21 // C-REPLACE "casadi_blazing_dbasis<T1>" "casadi_blazing_dbasis"
22 // C-REPLACE "casadi_blazing_d2basis<T1>" "casadi_blazing_d2basis"
23 
24 // SYMBOL "blazing_1d_boor_eval"
25 template<typename T1>
26 void casadi_blazing_1d_boor_eval(T1* f, T1* J, T1* H, const T1* all_knots, const T1* all_knots_cache, const casadi_int* offset, const T1* c, const T1* dc, const T1* ddc, const T1* all_x, const casadi_int* lookup_mode, casadi_int* iw, T1* w) { // NOLINT(whitespace/line_length)
27  casadi_int *starts;
28  iw+=1+1;
29  starts = iw;
30 
31  simde__m256d boor0_d2, boor0_d1, boor0_d0;
32  const T1* inv2_0 = 0; const T1* inv3_0 = 0;
33  // For 1D the cache slice is just the global cache.
34  starts[0] = casadi_blazing_boor_init<T1>(all_x[0], all_knots, all_knots_cache,
35  offset[0], offset[1], lookup_mode[0], &boor0_d0, &boor0_d1, &boor0_d2, &inv2_0, &inv3_0);
36 
37  const T1* C = c+starts[0];
38  if (f) {
39  double boor0_d0v[4];
40  simde_mm256_storeu_pd(boor0_d0v, boor0_d0);
41 
42  f[0] = 0;
43  for (casadi_int i=0;i<4;++i) {
44  f[0] += boor0_d0v[i]*C[i];
45  }
46  }
47 
48  // First derivative
49  if (J) {
50  if (dc) {
51  // Precomputed derivative coefficients
52  const T1* Cdc = dc+starts[0];
53 
54  double boor0_d1v[4];
55  simde_mm256_storeu_pd(boor0_d1v, boor0_d1);
56 
57  J[0] = 0;
58  for (casadi_int i=0;i<3;++i) {
59  J[0] += boor0_d1v[i+1]*Cdc[i];
60  }
61  } else {
62  // NPC: summation by parts
63  const T1* t0 = all_knots + offset[0] + starts[0];
64  simde__m256d boor0_J;
65  casadi_blazing_dbasis<T1>(&boor0_J, &boor0_d1, t0, inv3_0);
66 
67  double boor0_Jv[4];
68  simde_mm256_storeu_pd(boor0_Jv, boor0_J);
69 
70  J[0] = 0;
71  for (casadi_int i=0;i<4;++i) {
72  J[0] += boor0_Jv[i]*C[i];
73  }
74  }
75  }
76 
77  // Second derivative
78  if (H) {
79  if (ddc) {
80  // Precomputed derivative coefficients
81  const T1* Cddc = ddc+starts[0];
82 
83  double boor0_d2v[4];
84  simde_mm256_storeu_pd(boor0_d2v, boor0_d2);
85 
86  H[0] = 0;
87  for (casadi_int i=0;i<2;++i) {
88  H[0] += boor0_d2v[i+2]*Cddc[i];
89  }
90  } else {
91  // NPC: summation by parts (applied twice)
92  const T1* t0 = all_knots + offset[0] + starts[0];
93  simde__m256d boor0_H;
94  casadi_blazing_d2basis<T1>(&boor0_H, &boor0_d2, t0, inv2_0, inv3_0);
95 
96  double boor0_Hv[4];
97  simde_mm256_storeu_pd(boor0_Hv, boor0_H);
98 
99  H[0] = 0;
100  for (casadi_int i=0;i<4;++i) {
101  H[0] += boor0_Hv[i]*C[i];
102  }
103  }
104  }
105 }