• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef LE_FX_ENGINE_DSP_CORE_INTERPOLATOR_BASE_INL_H_
18 #define LE_FX_ENGINE_DSP_CORE_INTERPOLATOR_BASE_INL_H_
19 #ifndef LOG_TAG
20 #define LOG_TAG NULL
21 #endif
22 //#define LOG_NDEBUG 0
23 
24 #include <log/log.h>
25 
26 #include "dsp/core/basic.h"
27 
28 namespace le_fx {
29 
30 namespace sigmod {
31 
32 template <typename T, class Algorithm>
InterpolatorBase()33 InterpolatorBase<T, Algorithm>::InterpolatorBase() {
34   status_ = false;
35   cached_index_ = 0;
36   x_data_ = NULL;
37   y_data_ = NULL;
38   data_length_ = 0;
39   own_x_data_ = false;
40   x_start_offset_ = 0.0;
41   last_element_index_ = -1;
42   x_inverse_sampling_interval_ = 0.0;
43   state_ = NULL;
44 }
45 
46 template <typename T, class Algorithm>
~InterpolatorBase()47 InterpolatorBase<T, Algorithm>::~InterpolatorBase() {
48   delete [] state_;
49   if (own_x_data_) {
50     delete [] x_data_;
51   }
52 }
53 
54 template <typename T, class Algorithm>
Initialize(const vector<T> & x_data,const vector<T> & y_data)55 bool InterpolatorBase<T, Algorithm>::Initialize(const vector<T> &x_data,
56                                                 const vector<T> &y_data) {
57 #ifndef NDEBUG
58   if (x_data.size() != y_data.size()) {
59     LoggerError("InterpolatorBase::Initialize: xData size (%d) != yData size"
60                   " (%d)", x_data.size(), y_data.size());
61   }
62 #endif
63   return Initialize(&x_data[0], &y_data[0], x_data.size());
64 }
65 
66 template <typename T, class Algorithm>
Initialize(double x_start_offset,double x_sampling_interval,const vector<T> & y_data)67 bool InterpolatorBase<T, Algorithm>::Initialize(double x_start_offset,
68                                                 double x_sampling_interval,
69                                                 const vector<T> &y_data) {
70   return Initialize(x_start_offset,
71                     x_sampling_interval,
72                     &y_data[0],
73                     y_data.size());
74 }
75 
76 template <typename T, class Algorithm>
Initialize(double x_start_offset,double x_sampling_interval,const T * y_data,int data_length)77 bool InterpolatorBase<T, Algorithm>::Initialize(double x_start_offset,
78                                                 double x_sampling_interval,
79                                                 const T *y_data,
80                                                 int data_length) {
81   // Constructs and populate x-axis data: `x_data_`
82   T *x_data_tmp = new T[data_length];
83   float time_offset = x_start_offset;
84   for (int n = 0; n < data_length; n++) {
85     x_data_tmp[n] = time_offset;
86     time_offset += x_sampling_interval;
87   }
88   Initialize(x_data_tmp, y_data, data_length);
89   // Sets-up the regularly sampled interpolation mode
90   x_start_offset_ = x_start_offset;
91   x_inverse_sampling_interval_ = 1.0 / x_sampling_interval;
92   own_x_data_ = true;
93   return status_;
94 }
95 
96 
97 template <typename T, class Algorithm>
Initialize(const T * x_data,const T * y_data,int data_length)98 bool InterpolatorBase<T, Algorithm>::Initialize(
99     const T *x_data, const T *y_data, int data_length) {
100   // Default settings
101   cached_index_ = 0;
102   data_length_ = 0;
103   x_start_offset_ = 0;
104   x_inverse_sampling_interval_ = 0;
105   state_ = NULL;
106   // Input data is externally owned
107   own_x_data_ = false;
108   x_data_ = x_data;
109   y_data_ = y_data;
110   data_length_ = data_length;
111   last_element_index_ = data_length - 1;
112   // Check input data sanity
113   for (int n = 0; n < last_element_index_; ++n) {
114     if (x_data_[n + 1] <= x_data_[n]) {
115       ALOGE("InterpolatorBase::Initialize: xData are not ordered or "
116               "contain equal values (X[%d] <= X[%d]) (%.5e <= %.5e)",
117             n + 1, n, x_data_[n + 1], x_data_[n]);
118       status_ = false;
119       return false;
120     }
121   }
122   // Pre-compute internal state by calling the corresponding function of the
123   // derived class.
124   status_ = static_cast<Algorithm*>(this)->SetInternalState();
125   return status_;
126 }
127 
128 template <typename T, class Algorithm>
Interpolate(T x)129 T InterpolatorBase<T, Algorithm>::Interpolate(T x) {
130 #ifndef NDEBUG
131   if (cached_index_ < 0 || cached_index_ > data_length_ - 2) {
132     LoggerError("InterpolatorBase:Interpolate: CachedIndex_ out of bounds "
133                   "[0, %d, %d]", cached_index_, data_length_ - 2);
134   }
135 #endif
136   // Search for the containing interval
137   if (x <= x_data_[cached_index_]) {
138     if (cached_index_ <= 0) {
139       cached_index_ = 0;
140       return y_data_[0];
141     }
142     if (x >= x_data_[cached_index_ - 1]) {
143       cached_index_--;  // Fast descending
144     } else {
145       if (x <= x_data_[0]) {
146         cached_index_ = 0;
147         return y_data_[0];
148       }
149       cached_index_ = SearchIndex(x_data_, x, 0, cached_index_);
150     }
151   } else {
152     if (cached_index_ >= last_element_index_) {
153       cached_index_ = last_element_index_;
154       return y_data_[last_element_index_];
155     }
156     if (x > x_data_[cached_index_ + 1]) {
157       if (cached_index_ + 2 > last_element_index_) {
158         cached_index_ = last_element_index_ - 1;
159         return y_data_[last_element_index_];
160       }
161       if (x <= x_data_[cached_index_ + 2]) {
162         cached_index_++;  // Fast ascending
163       } else {
164         if (x >= x_data_[last_element_index_]) {
165           cached_index_ = last_element_index_ - 1;
166           return y_data_[last_element_index_];
167         }
168         cached_index_ = SearchIndex(
169             x_data_, x, cached_index_, last_element_index_);
170       }
171     }
172   }
173   // Compute interpolated value by calling the corresponding function of the
174   // derived class.
175   return static_cast<Algorithm*>(this)->MethodSpecificInterpolation(x);
176 }
177 
178 }  // namespace sigmod
179 
180 }  // namespace le_fx
181 
182 #endif  // LE_FX_ENGINE_DSP_CORE_INTERPOLATOR_BASE_INL_H_
183