OTB  9.0.0
Orfeo Toolbox
otbLagrangianOrbitInterpolator.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2024 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbLagrangianOrbitInterpolator_h
22 #define otbLagrangianOrbitInterpolator_h
23 
24 #include <vector>
25 #include <cassert>
26 #include <limits>
27 #include <array>
28 #include "otbMdSpan.h"
29 
30 #include "otbSARMetadata.h"
31 #include "otbMacro.h"
32 
33 namespace otb
34 {
35 
46 {
48 
49 public:
52 
54  std::vector<Orbit> const& orbits,
55  unsigned int polynomial_degree = 8)
56  : m_polynomial_degree(polynomial_degree - 2)
57  , m_orbits(orbits)
58  {
59  // Legacy implementation used to misinterpret "degree".
60  // For a polynom of degree 8, 8 values shall be used:
61  // \Sum_{i=0}^{n} \Mult_{j=0, j!=i=^{n} \frac{X - x_i}{x_j - x-i}
62  // => 9 values for i ([0..n]), 8 values for j ([0..i[ U ]i..n])
63  //
64  // Let's assume a center at idx=7, and degree 8
65  // legacyBegin = idx-deg/2+1 = 4
66  // legacyEnd = legacyBegin + deg - 1 = 4+8-1 = 11
67  // and we loop in [legacyBegin..legacyEnd[ => 7 values
68  // IOW, real degree is 6 (7-1)!
69  assert(m_polynomial_degree < 30); // Lagrangian interpolator fails
70  // miserably at 20 elements... Let's
71  // expected less than 30 as reasonable
72 
73  m_buffer.resize(2*m_polynomial_degree * orbits.size());
75  m_buffer.data(), narrow{},
76  orbits.size(),
78 
79  auto nLast = m_orbits.size();
80  for (std::size_t nBegin = 0; nBegin < nLast ; ++nBegin)
81  {
82  auto const nEnd = std::min(nLast, nBegin + m_polynomial_degree+1);
83  // ∀ i ∈ [nBegin..nEnd[
84  // --> inv_den(nBegin, i) = TT_{j!=i} t[i] - t[j]
85  auto const offset_max = std::min(nLast-nBegin, std::size_t(1 + m_polynomial_degree));
86  for (std::size_t offset_i=0; offset_i < offset_max ; ++offset_i)
87  {
88  std::ptrdiff_t i = offset_i + nBegin;
89  assert(i < std::ptrdiff_t(nLast));
90  auto const t_i = m_orbits[i].time;
91 
92  double w = 1.;
93  unsigned int j = nBegin;
94  for( ; j < i ; ++j)
95  {
96  assert(i != j);
97  auto const den = t_i - m_orbits[j].time;
98  assert(den.NumberOfTicks() != 0);
99  w *= den.NumberOfTicks();;
100  }
101  for( ++j ; j < nEnd; ++j)
102  {
103  assert(i != j);
104  auto const den = t_i - m_orbits[j].time;
105  assert(den.NumberOfTicks() != 0);
106  w *= den.NumberOfTicks();;
107  }
108  assert(nBegin < m_orbits.size());
109  assert(offset_i < 1 + m_polynomial_degree);
110  assert(w != 0);
111  m_inv_den(unsigned(nBegin), unsigned(offset_i)) = 1.0 / w;
112  }
113  }
114  }
115 
116  std::pair<Orbit::PointType, Orbit::PointType> interpolatePosVel(
117  TimePoint time, std::size_t nBegin, std::size_t nEnd) const
118  {
119  // Compute lagrangian interpolation using records from nBegin to nEnd
120  assert(nEnd - nBegin < m_polynomial_degree+2);
121  assert(nBegin < nEnd);
122 
123  // Time differences between time and sample[i].time
124  std::array<double, 30> td1s;
125  for(unsigned int i = nBegin; i < nEnd; ++i)
126  {
127  td1s[i-nBegin] = (time - m_orbits[i].time).NumberOfTicks();
128  }
129 
130  PointType pos(0.); // Fill all with 0.
131  PointType vel(0.); // Fill all with 0.
132 
133  for(unsigned int i = nBegin; i < nEnd; ++i)
134  {
135  double w = 1.;
136  std::size_t j = nBegin;
137  for( ; j != i ; ++j)
138  {
139  w *= td1s[j-nBegin];
140  }
141  ++j;
142  for( ; j < nEnd; ++j)
143  {
144  w *= td1s[j-nBegin];
145  }
146  auto const den = m_inv_den(std::ptrdiff_t(nBegin), std::ptrdiff_t(i-nBegin));
147  w *= den;
148 
149  pos[0]+=w*m_orbits[i].position[0];
150  pos[1]+=w*m_orbits[i].position[1];
151  pos[2]+=w*m_orbits[i].position[2];
152  vel[0]+=w*m_orbits[i].velocity[0];
153  vel[1]+=w*m_orbits[i].velocity[1];
154  vel[2]+=w*m_orbits[i].velocity[2];
155  }
156 
157  return {pos, vel};
158  }
159 
160 private:
163 
164  unsigned int m_polynomial_degree;
165 
166  std::vector<Orbit> const& m_orbits;
167  std::vector<double> m_buffer;
169 };
170 
171 } // otb namespace
172 
173 #endif // otbLagrangianOrbitInterpolator_h
otb::basic_mdspan
Definition: otbMdSpan.h:41
otb::LagrangianOrbitInterpolator::LagrangianOrbitInterpolator
LagrangianOrbitInterpolator(std::vector< Orbit > const &orbits, unsigned int polynomial_degree=8)
Definition: otbLagrangianOrbitInterpolator.h:53
otb::LagrangianOrbitInterpolator::PointType
Orbit::PointType PointType
Definition: otbLagrangianOrbitInterpolator.h:50
otb::LagrangianOrbitInterpolator::m_inv_den
inv_den_view_t m_inv_den
Definition: otbLagrangianOrbitInterpolator.h:168
otb::narrow
Definition: otbMdSpan.h:30
otb::LagrangianOrbitInterpolator::m_orbits
std::vector< Orbit > const & m_orbits
Definition: otbLagrangianOrbitInterpolator.h:166
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otbMacro.h
otb::LagrangianOrbitInterpolator::m_buffer
std::vector< double > m_buffer
Definition: otbLagrangianOrbitInterpolator.h:167
otbSARMetadata.h
otb::Orbit::PointType
itk::Point< double, 3 > PointType
Definition: otbSARMetadata.h:96
otb::LagrangianOrbitInterpolator::operator=
LagrangianOrbitInterpolator & operator=(LagrangianOrbitInterpolator const &)=delete
otb::LagrangianOrbitInterpolator
Definition: otbLagrangianOrbitInterpolator.h:45
otb::LagrangianOrbitInterpolator::interpolatePosVel
std::pair< Orbit::PointType, Orbit::PointType > interpolatePosVel(TimePoint time, std::vcl_size_t nBegin, std::vcl_size_t nEnd) const
Definition: otbLagrangianOrbitInterpolator.h:116
otbMdSpan.h
otb::LagrangianOrbitInterpolator::m_polynomial_degree
unsigned int m_polynomial_degree
Definition: otbLagrangianOrbitInterpolator.h:164
otb::MetaData::TimePoint
Represents a point in Time.
Definition: otbDateTime.h:94
otb::LagrangianOrbitInterpolator::inv_den_view_t
mdspan< double, dynamic_extent, dynamic_extent > inv_den_view_t
Definition: otbLagrangianOrbitInterpolator.h:47