11/* ******************************************************************
22 * File: lagg.hpp
33 *
4- * Lag utilities for matrices.
4+ * Lagged aggregation utilities for matrices.
55 *
6- * Provides lagged aggregation operators for:
6+ * This module provides lag operators for three common structures
77 *
8- * - Arbitrary lattice graphs
9- * - Regular grids
10- * - Time series
8+ * 1. Arbitrary lattice graphs
9+ * 2. Regular spatial grids
10+ * 3. Time series
1111 *
12- * Each column of the input matrix is treated as a variable.
12+ * The input matrix follows the internal representation used in
13+ * the infoxtr library
14+ *
15+ * Matrix = std::vector<std::vector<double>>
16+ *
17+ * Each inner vector represents one observation unit and each
18+ * column corresponds to a variable.
19+ *
20+ * Output Orientation
21+ *
22+ * A boolean parameter `byrow` controls the orientation of the
23+ * returned matrix.
24+ *
25+ * byrow = true
26+ * Output keeps the current layout
27+ * Each observation corresponds to one row vector
28+ *
29+ * byrow = false
30+ * Output is stored in column major orientation
31+ * Each inner vector corresponds to one variable
32+ *
33+ * This option allows direct compatibility with external matrix
34+ * layouts used by R or column oriented algorithms.
35+ *
36+ * Supported operations
37+ *
38+ * lagg(mat, nb, lag, byrow)
39+ * Lag aggregation on arbitrary neighbor graphs
40+ *
41+ * lagg(mat, nrows, lag, byrow)
42+ * Lag aggregation on regular grids
43+ *
44+ * lagg(mat, lag, byrow)
45+ * Temporal lag for time series
1346 *
1447 * Author: Wenbo Lyu (Github: @SpatLyu)
1548 * License: GPL-3
@@ -52,16 +85,29 @@ namespace lagg
5285 inline Matrix lagg (
5386 const Matrix& mat,
5487 const NeighborMat& nb,
55- size_t lag
88+ size_t lag = 1 ,
89+ bool byrow = true
5690 )
5791 {
5892 const size_t n = nb.size ();
5993 const size_t p = mat.front ().size ();
6094
61- Matrix out (n, Vector (p, NaN));
95+ Matrix out;
96+ if (byrow)
97+ out.assign (n, Vector (p, NaN));
98+ else
99+ out.assign (p, Vector (n, NaN));
100+
101+ if (lag == 0 )
102+ {
103+ if (byrow)
104+ return mat;
62105
63- if (lag == 0 ) {
64- return mat;
106+ for (size_t i = 0 ; i < n; ++i)
107+ for (size_t j = 0 ; j < p; ++j)
108+ out[j][i] = mat[i][j];
109+
110+ return out;
65111 }
66112
67113 for (size_t i = 0 ; i < n; ++i)
@@ -105,9 +151,14 @@ namespace lagg
105151 ++cnt;
106152 }
107153 }
108-
154+
109155 if (cnt > 0 )
110- out[i][j] = sum / cnt;
156+ {
157+ if (byrow)
158+ out[i][j] = sum / cnt;
159+ else
160+ out[j][i] = sum / cnt;
161+ }
111162 }
112163 }
113164
@@ -128,7 +179,8 @@ namespace lagg
128179 inline Matrix lagg (
129180 const Matrix& mat,
130181 size_t nrows,
131- size_t lag
182+ size_t lag = 1 ,
183+ bool byrow = true
132184 )
133185 {
134186 const size_t N = mat.size ();
@@ -139,10 +191,23 @@ namespace lagg
139191
140192 const size_t ncols = N / nrows;
141193
142- Matrix out (N, Vector (p, NaN));
194+ Matrix out;
195+ if (byrow)
196+ out.assign (N, Vector (p, NaN));
197+ else
198+ out.assign (p, Vector (N, NaN));
143199
144200 if (lag == 0 )
145- return mat;
201+ {
202+ if (byrow)
203+ return mat;
204+
205+ for (size_t i = 0 ; i < N; ++i)
206+ for (size_t j = 0 ; j < p; ++j)
207+ out[j][i] = mat[i][j];
208+
209+ return out;
210+ }
146211
147212 std::vector<std::pair<int ,int >> offsets;
148213
@@ -186,9 +251,14 @@ namespace lagg
186251 }
187252 }
188253 }
189-
254+
190255 if (cnt > 0 )
191- out[id][j] = sum / cnt;
256+ {
257+ if (byrow)
258+ out[id][j] = sum / cnt;
259+ else
260+ out[j][id] = sum / cnt;
261+ }
192262 }
193263 }
194264 }
@@ -202,24 +272,44 @@ namespace lagg
202272
203273 inline Matrix lagg (
204274 const Matrix& mat,
205- size_t lag
275+ size_t lag = 1 ,
276+ bool byrow = true
206277 )
207278 {
208279 const size_t n = mat.size ();
209280 const size_t p = mat.front ().size ();
210-
211- Matrix out (n, Vector (p, NaN));
281+
282+ Matrix out;
283+ if (byrow)
284+ out.assign (n, Vector (p, NaN));
285+ else
286+ out.assign (p, Vector (n, NaN));
212287
213288 if (lag == 0 )
214- return mat;
289+ {
290+ if (byrow)
291+ return mat;
292+
293+ for (size_t i = 0 ; i < n; ++i)
294+ for (size_t j = 0 ; j < p; ++j)
295+ out[j][i] = mat[i][j];
296+
297+ return out;
298+ }
215299
216300 for (size_t t = lag; t < n; ++t)
217301 {
218302 for (size_t j = 0 ; j < p; ++j)
219303 {
220304 double v = mat[t - lag][j];
305+
221306 if (!std::isnan (v))
222- out[t][j] = v;
307+ {
308+ if (byrow)
309+ out[t][j] = v;
310+ else
311+ out[j][t] = v;
312+ }
223313 }
224314 }
225315
0 commit comments