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 // SYMBOL "blazing_1d_boor_eval"
21 template<typename T1>
22 void casadi_blazing_1d_boor_eval(T1* f, T1* J, T1* H, const T1* all_knots, 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)
23  casadi_int n_dims = 1;
24  casadi_int m = 1;
25  casadi_int n_iter, i, pivot;
26  casadi_int *boor_offset, *starts, *index, *coeff_offset;
27  T1 *cumprod;
28  boor_offset = iw; iw+=n_dims+1;
29  starts = iw; iw+=n_dims;
30  index = iw; iw+=n_dims;
31  coeff_offset = iw;
32  cumprod = w; w+= n_dims+1;
33  boor_offset[0] = 0;
34  cumprod[n_dims] = 1;
35  coeff_offset[n_dims] = 0;
36 
37  casadi_int stride1 = offset[1]-offset[0]-4;
38 
39  simde__m256d zero = simde_mm256_set1_pd(0.0);
40 
41  simde__m256d boor_start_0000 = zero;
42  simde__m256d boor_start_1111 = simde_mm256_set1_pd(1.0);
43  simde__m256d boor_start_0001 = simde_mm256_set_pd(1.0, 0.0, 0.0, 0.0);
44  simde__m256d boor_start_0010 = simde_mm256_set_pd(0.0, 1.0, 0.0, 0.0);
45 
46  simde__m256d boor0_d3;
47  simde__m256d boor0_d2;
48  simde__m256d boor0_d1;
49  simde__m256d boor0_d0;
50 
51  const T1* knots;
52  T1 x;
53  casadi_int degree, n_knots, n_b, L, start;
54  degree = 3;
55  knots = all_knots + offset[0];
56  n_knots = offset[0+1]-offset[0];
57  n_b = n_knots-degree-1;
58  x = all_x[0];
59  L = casadi_low(x, knots+degree, n_knots-2*degree, lookup_mode[0]);
60  start = L;
61  if (start>n_b-degree-1) start = n_b-degree-1;
62  starts[0] = start;
63  boor0_d3 = boor_start_0000;
64  if (x>=knots[0] && x<=knots[n_knots-1]) {
65  if (x==knots[1]) {
66  boor0_d3 = boor_start_1111;
67  } else if (x==knots[n_knots-1]) {
68  boor0_d3 = boor_start_0001;
69  } else if (knots[L+degree]==x) {
70  boor0_d3 = boor_start_0010;
71  } else {
72  boor0_d3 = boor_start_0001;
73  }
74  }
75  casadi_blazing_de_boor(x, knots+start, &boor0_d0, &boor0_d1, &boor0_d2, &boor0_d3);
76 
77  double boor0_d0v[4];
78  simde_mm256_storeu_pd(boor0_d0v, boor0_d0);
79 
80  const T1* C = c+starts[0];
81  if (f) {
82  f[0] = 0;
83  for (casadi_int i=0;i<4;++i) {
84  f[0] += boor0_d0v[i]*C[i];
85  }
86  }
87 
88  // First derivative
89  if (dc && J) {
90  C = dc+starts[0];
91 
92  double boor0_d1v[4];
93  simde_mm256_storeu_pd(boor0_d1v, boor0_d1);
94 
95  J[0] = 0;
96  for (casadi_int i=0;i<3;++i) {
97  J[0] += boor0_d1v[i+1]*C[i];
98  }
99  }
100 
101  if (ddc && H) {
102  C = ddc+starts[0];
103 
104  double boor0_d2v[4];
105  simde_mm256_storeu_pd(boor0_d2v, boor0_d2);
106 
107  H[0] = 0;
108  for (casadi_int i=0;i<2;++i) {
109  H[0] += boor0_d2v[i+2]*C[i];
110  }
111  }
112 }