Skip to content

Commit b4514df

Browse files
committed
Add span API for concatenate. Empty span support.
1 parent 005e103 commit b4514df

File tree

8 files changed

+66
-38
lines changed

8 files changed

+66
-38
lines changed

include/dsplib/slice.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,18 @@ template<typename T>
2020
class const_slice_t;
2121

2222
//----------------------------------------------------------------------------------------
23+
//TODO: support empty slices
2324
class base_slice_t
2425
{
2526
public:
27+
base_slice_t() = default;
28+
2629
explicit base_slice_t(int n, int i1, int i2, int m) {
27-
DSPLIB_ASSERT(n != 0, "Slicing from an empty array");
30+
//is empty
31+
if (n == 0) {
32+
return;
33+
}
34+
2835
DSPLIB_ASSERT(m != 0, "Slice stride cannot be zero");
2936

3037
_m = m;
@@ -56,6 +63,10 @@ class base_slice_t
5663
}
5764
}
5865

66+
bool empty() const noexcept {
67+
return (_nc == 0);
68+
}
69+
5970
protected:
6071
int _i1{0};
6172
int _i2{0};
@@ -73,6 +84,8 @@ class const_slice_t : public base_slice_t
7384
friend class slice_t<T>;
7485
using const_iterator = SliceIterator<const T>;
7586

87+
const_slice_t() = default;
88+
7689
const_slice_t(const T* data, int size, int i1, int i2, int m)
7790
: base_slice_t(size, i1, i2, m)
7891
, _data{data} {
@@ -123,6 +136,8 @@ class slice_t : public base_slice_t
123136
using iterator = SliceIterator<T>;
124137
using const_iterator = SliceIterator<const T>;
125138

139+
slice_t() = default;
140+
126141
slice_t(T* data, int size, int i1, int i2, int m)
127142
: base_slice_t(size, i1, i2, m)
128143
, _data{data} {

include/dsplib/span.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class mut_span_t : public slice_t<T>
2828
public:
2929
friend class span_t<T>;
3030

31+
mut_span_t() = default;
32+
3133
explicit mut_span_t(T* data, int size)
3234
: slice_t<T>(data, size, 0, size, 1)
3335
, _ptr{data}
@@ -129,6 +131,8 @@ class span_t : public const_slice_t<T>
129131
public:
130132
friend class mut_span_t<T>;
131133

134+
span_t() = default;
135+
132136
explicit span_t(const T* data, int size)
133137
: const_slice_t<T>(data, size, 0, size, 1)
134138
, _ptr{data}

include/dsplib/utils.h

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -57,28 +57,9 @@ template<typename T1, typename T2, typename T3, class R = typename enable_if_som
5757
}
5858

5959
//join a sequence of arrays
60-
//TODO: add impl for slice/span
61-
template<class T>
62-
T concatenate(const T& a1, const T& a2, const T& a3 = T(), const T& a4 = T(), const T& a5 = T()) {
63-
std::array<const T*, 5> arrays{&a1, &a2, &a3, &a4, &a5};
64-
65-
size_t nr = 0;
66-
for (auto array : arrays) {
67-
nr += array->size();
68-
}
69-
70-
T r(nr);
71-
auto* pr = r.data();
72-
for (auto array : arrays) {
73-
const auto* pa = array->data();
74-
for (int i = 0; i < array->size(); ++i) {
75-
*pr = pa[i];
76-
pr++;
77-
}
78-
}
79-
80-
return r;
81-
}
60+
//TODO: add slice args?
61+
arr_real concatenate(span_real x1, span_real x2, span_real x3 = {}, span_real x4 = {}, span_real x5 = {});
62+
arr_cmplx concatenate(span_cmplx x1, span_cmplx x2, span_cmplx x3 = {}, span_cmplx x4 = {}, span_cmplx x5 = {});
8263

8364
//create array of all zeros
8465
inline arr_real zeros(int n) {

lib/fft/czt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class CztPlanImpl
3636
}
3737

3838
const arr_cmplx dp = chirp.slice(0, m + n - 1);
39-
_ich = _fft2->solve((1.0 / dp) | zeros(n2 - m - n + 1));
39+
_ich = _fft2->solve(zeropad((1.0 / dp), n2));
4040
_rp = chirp.slice(_n - 1, _m + _n - 1);
4141
}
4242

lib/hilbert.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ arr_cmplx HilbertFilter::design_fir(int flen, real_t fs, real_t f1) {
3030

3131
const auto lm = power(arange(k1 - 1) / (k1 - 1), 8);
3232
const auto rm = flip(lm);
33-
const arr_cmplx H = complex(lm | ones(k2 - k1 + 1) | rm | zeros(N / 2 - 1));
33+
const arr_cmplx H = complex(concatenate(lm, ones(k2 - k1 + 1), rm, zeros(N / 2 - 1)));
3434
const arr_cmplx h = ifft(H); // desired impulse response
3535

3636
const auto w = window::kaiser(M, 8);
37-
const auto wzp = *w.slice(M / 2, M) | zeros(N - M) | *w.slice(0, M / 2);
37+
const auto wzp = concatenate(w.slice(M / 2, M), zeros(N - M), w.slice(0, M / 2));
3838
const auto hw = wzp * h; // single-sideband FIR filter, zero-centered
39-
const auto hh = *hw.slice(N - (M / 2), N) | *hw.slice(0, (M + 1) / 2); // casual FIR
39+
const auto hh = concatenate(hw.slice(N - (M / 2), N), hw.slice(0, (M + 1) / 2)); // casual FIR
4040
return hh;
4141
}
4242

lib/medfilt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ arr_real medfilt(arr_real& x, int n) {
6969
auto flt = MedianFilter(n);
7070
const int n1 = (n / 2);
7171
const int n2 = (n % 2 == 1) ? (n / 2) : (n / 2 - 1);
72-
arr_real xp = zeros(n1) | x | zeros(n2);
72+
arr_real xp = concatenate(zeros(n1), x, zeros(n2));
7373
auto y = flt.process(xp);
7474
return y.slice(n - 1, indexing::end);
7575
}

lib/utils.cpp

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -200,32 +200,60 @@ static int _finddelay(const base_array<T>& x1, const base_array<T>& x2) {
200200
return -delay;
201201
}
202202

203-
int finddelay(const dsplib::arr_real& x1, const dsplib::arr_real& x2) {
203+
int finddelay(const arr_real& x1, const arr_real& x2) {
204204
return _finddelay(x1, x2);
205205
}
206206

207-
int finddelay(const dsplib::arr_cmplx& x1, const dsplib::arr_cmplx& x2) {
207+
int finddelay(const arr_cmplx& x1, const arr_cmplx& x2) {
208208
return _finddelay(x1, x2);
209209
}
210210

211-
arr_real zeropad(span_t<real_t> x, int n) {
211+
template<typename T>
212+
static base_array<T> _zeropad(span_t<T> x, int n) {
212213
DSPLIB_ASSERT(x.size() <= n, "padding size error");
213214
if (x.size() == n) {
214215
return x;
215216
}
216-
arr_real r(n);
217+
base_array<T> r(n);
217218
r.slice(0, x.size()) = x;
218219
return r;
219220
}
220221

222+
arr_real zeropad(span_t<real_t> x, int n) {
223+
return _zeropad<real_t>(x, n);
224+
}
225+
221226
arr_cmplx zeropad(span_t<cmplx_t> x, int n) {
222-
DSPLIB_ASSERT(x.size() <= n, "padding size error");
223-
if (x.size() == n) {
224-
return x;
227+
return _zeropad<cmplx_t>(x, n);
228+
}
229+
230+
template<class T>
231+
static base_array<T> _concatenate(span_t<T> a1, span_t<T> a2, span_t<T> a3, span_t<T> a4, span_t<T> a5) {
232+
std::array<span_t<T>, 5> span_list{a1, a2, a3, a4, a5};
233+
234+
size_t nr = 0;
235+
for (const auto& x : span_list) {
236+
nr += x.size();
237+
}
238+
239+
base_array<T> r(nr);
240+
auto* pr = r.data();
241+
for (const auto& x : span_list) {
242+
if (x.empty()) {
243+
continue;
244+
}
245+
std::memcpy(pr, x.data(), x.size() * sizeof(T));
246+
pr += x.size();
225247
}
226-
arr_cmplx r(n);
227-
r.slice(0, x.size()) = x;
228248
return r;
229249
}
230250

251+
arr_real concatenate(span_real x1, span_real x2, span_real x3, span_real x4, span_real x5) {
252+
return _concatenate<real_t>(x1, x2, x3, x4, x5);
253+
}
254+
255+
arr_cmplx concatenate(span_cmplx x1, span_cmplx x2, span_cmplx x3, span_cmplx x4, span_cmplx x5) {
256+
return _concatenate<cmplx_t>(x1, x2, x3, x4, x5);
257+
}
258+
231259
} // namespace dsplib

lib/window.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ arr_real kaiser(int nw, real_t beta) {
109109
w[i] = std::abs(_besseli0(beta * std::sqrt(1 - (xi / xind))) / bes);
110110
}
111111
const arr_real wl = flip(*w.slice(odd, n));
112-
return (wl | w);
112+
return concatenate(wl, w);
113113
}
114114

115115
} // namespace window

0 commit comments

Comments
 (0)