gps_pvt 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/CHANGELOG.md +5 -0
  4. data/CODE_OF_CONDUCT.md +84 -0
  5. data/Gemfile +10 -0
  6. data/README.md +86 -0
  7. data/Rakefile +86 -0
  8. data/bin/console +15 -0
  9. data/bin/setup +8 -0
  10. data/ext/gps_pvt/Coordinate/Coordinate_wrap.cxx +6613 -0
  11. data/ext/gps_pvt/GPS/GPS_wrap.cxx +16019 -0
  12. data/ext/gps_pvt/SylphideMath/SylphideMath_wrap.cxx +21050 -0
  13. data/ext/gps_pvt/extconf.rb +70 -0
  14. data/ext/ninja-scan-light/tool/navigation/EGM.h +2971 -0
  15. data/ext/ninja-scan-light/tool/navigation/GPS.h +2432 -0
  16. data/ext/ninja-scan-light/tool/navigation/GPS_Solver.h +479 -0
  17. data/ext/ninja-scan-light/tool/navigation/GPS_Solver_Base.h +1081 -0
  18. data/ext/ninja-scan-light/tool/navigation/GPS_Solver_MultiFrequency.h +199 -0
  19. data/ext/ninja-scan-light/tool/navigation/GPS_Solver_RAIM.h +210 -0
  20. data/ext/ninja-scan-light/tool/navigation/MagneticField.h +928 -0
  21. data/ext/ninja-scan-light/tool/navigation/NTCM.h +211 -0
  22. data/ext/ninja-scan-light/tool/navigation/RINEX.h +1781 -0
  23. data/ext/ninja-scan-light/tool/navigation/WGS84.h +186 -0
  24. data/ext/ninja-scan-light/tool/navigation/coordinate.h +406 -0
  25. data/ext/ninja-scan-light/tool/param/bit_array.h +145 -0
  26. data/ext/ninja-scan-light/tool/param/complex.h +558 -0
  27. data/ext/ninja-scan-light/tool/param/matrix.h +4049 -0
  28. data/ext/ninja-scan-light/tool/param/matrix_fixed.h +665 -0
  29. data/ext/ninja-scan-light/tool/param/matrix_special.h +562 -0
  30. data/ext/ninja-scan-light/tool/param/quaternion.h +765 -0
  31. data/ext/ninja-scan-light/tool/param/vector3.h +651 -0
  32. data/ext/ninja-scan-light/tool/swig/Coordinate.i +177 -0
  33. data/ext/ninja-scan-light/tool/swig/GPS.i +1102 -0
  34. data/ext/ninja-scan-light/tool/swig/SylphideMath.i +1234 -0
  35. data/ext/ninja-scan-light/tool/swig/extconf.rb +5 -0
  36. data/ext/ninja-scan-light/tool/swig/makefile +53 -0
  37. data/ext/ninja-scan-light/tool/swig/spec/GPS_spec.rb +417 -0
  38. data/ext/ninja-scan-light/tool/swig/spec/SylphideMath_spec.rb +489 -0
  39. data/gps_pvt.gemspec +57 -0
  40. data/lib/gps_pvt/receiver.rb +375 -0
  41. data/lib/gps_pvt/ubx.rb +148 -0
  42. data/lib/gps_pvt/version.rb +5 -0
  43. data/lib/gps_pvt.rb +9 -0
  44. data/sig/gps_pvt.rbs +4 -0
  45. metadata +117 -0
@@ -0,0 +1,562 @@
1
+ /*
2
+ * Copyright (c) 2020, M.Naruoka (fenrir)
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without modification,
6
+ * are permitted provided that the following conditions are met:
7
+ *
8
+ * - Redistributions of source code must retain the above copyright notice,
9
+ * this list of conditions and the following disclaimer.
10
+ * - Redistributions in binary form must reproduce the above copyright notice,
11
+ * this list of conditions and the following disclaimer in the documentation
12
+ * and/or other materials provided with the distribution.
13
+ * - Neither the name of the naruoka.org nor the names of its contributors
14
+ * may be used to endorse or promote products derived from this software
15
+ * without specific prior written permission.
16
+ *
17
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
21
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
22
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ *
30
+ */
31
+
32
+ #ifndef __MATRIX_SPECIAL_H__
33
+ #define __MATRIX_SPECIAL_H__
34
+
35
+ /** @file
36
+ * @brief extension of Portable matrix library to add special type matrices such as symmetric matrix
37
+ *
38
+ */
39
+
40
+ #include "param/matrix.h"
41
+
42
+ #if (__cplusplus < 201103L) && !defined(noexcept)
43
+ #define noexcept throw()
44
+ #endif
45
+ #if defined(DEBUG) && !defined(throws_when_debug)
46
+ #define throws_when_debug
47
+ #else
48
+ #define throws_when_debug noexcept
49
+ #endif
50
+
51
+ #if defined(_MSC_VER)
52
+ #define DELETE_IF_MSC(x)
53
+ #else
54
+ #define DELETE_IF_MSC(x) x
55
+ #endif
56
+
57
+ template <class BaseView>
58
+ struct MatrixViewSpecial_Symmetric;
59
+
60
+ template <class BaseView>
61
+ struct MatrixViewSpecial_Diagonal;
62
+
63
+ template <class View>
64
+ struct MatrixViewSpecialBuilder : public MatrixViewBuilder<View> {
65
+ typedef View view_t;
66
+ template <template <class> class RemoveView>
67
+ struct remove_t {
68
+ typedef MatrixViewSpecialBuilder<
69
+ typename MatrixViewBuilder<View>::template remove_t<RemoveView>::res_t> builder_t;
70
+ };
71
+ typedef typename remove_t<MatrixViewSpecial_Symmetric>::builder_t
72
+ ::template remove_t<MatrixViewSpecial_Diagonal>::builder_t
73
+ ::view_t none_special_t;
74
+ };
75
+
76
+ template <class MatrixT, template <class> class ViewType_Special>
77
+ struct MatrixBuilderSpecial;
78
+
79
+ template <
80
+ class T, class Array2D_Type, class ViewType,
81
+ template <class> class ViewType_Special>
82
+ struct MatrixBuilderSpecial<Matrix_Frozen<T, Array2D_Type, ViewType>, ViewType_Special> {
83
+ typedef typename MatrixViewSpecialBuilder<ViewType_Special<
84
+ typename MatrixViewSpecialBuilder<ViewType>::none_special_t> >::view_t view_special_t;
85
+ typedef Matrix_Frozen<T, Array2D_Type, view_special_t> special_t;
86
+ };
87
+ template <class T, template <class> class ViewType_Special>
88
+ struct MatrixBuilderSpecial<Matrix_Frozen<T, Array2D_ScaledUnit<T>, MatrixViewBase<> >, ViewType_Special> {
89
+ typedef Matrix_Frozen<T, Array2D_ScaledUnit<T>, MatrixViewBase<> > special_t;
90
+ };
91
+ template <
92
+ class T, class Array2D_Type, class ViewType,
93
+ template <class> class ViewType_Special>
94
+ struct MatrixBuilderSpecial<Matrix<T, Array2D_Type, ViewType>, ViewType_Special>
95
+ : public MatrixBuilderSpecial<Matrix_Frozen<T, Array2D_Type, ViewType>, ViewType_Special> {};
96
+
97
+ template <
98
+ class T, class Array2D_Type, class ViewType,
99
+ template <class> class ViewType_Special>
100
+ struct Matrix_Frozen_Special
101
+ : public Matrix_Frozen<T, Array2D_Type, typename ViewType_Special<ViewType>::base_t> {
102
+ typedef Matrix_Frozen_Special<T, Array2D_Type, ViewType, ViewType_Special> self_t;
103
+ typedef Matrix_Frozen<T, Array2D_Type, typename ViewType_Special<ViewType>::base_t> super_t;
104
+ typedef typename MatrixBuilderSpecial<
105
+ Matrix_Frozen<T, Array2D_Type, ViewType>, ViewType_Special>::special_t special_t;
106
+ typedef MatrixBuilder<super_t> builder_t;
107
+ template <class ViewType2>
108
+ Matrix_Frozen_Special(const Matrix_Frozen<T, Array2D_Type, ViewType2> &mat) noexcept
109
+ : super_t(mat){
110
+ /* Reason to use template ViewType2 is to treat with duplication of special view.
111
+ * For example, if as_symmetric(as_symmetric(mat)), then this construct receives
112
+ * ViewType2 == Symmetric<AnotherBaseView> different from ViewType = AnotherBaseView.
113
+ */
114
+ }
115
+ Matrix_Frozen_Special(const Array2D_Type &storage) noexcept
116
+ : super_t(storage) {}
117
+ operator typename builder_t::assignable_t() const {
118
+ typedef typename builder_t::assignable_t res_t;
119
+ res_t res(res_t::blank(super_t::rows(), super_t::columns()));
120
+ builder_t::copy_value(res, *this);
121
+ return res;
122
+ }
123
+ static special_t as_special(const Matrix_Frozen<T, Array2D_Type, ViewType> &mat){
124
+ return special_t(mat);
125
+ }
126
+
127
+ template<typename U> struct arg_type;
128
+ template<typename U, typename V> struct arg_type<U(V)>{typedef V type;};
129
+ #define get_type(t) typename arg_type<void(t)>::type
130
+ #define upgrade_function(fname, in_type, out_type) \
131
+ typename MatrixBuilderSpecial<get_type(out_type), ViewType_Special>::special_t \
132
+ fname(const get_type(in_type) &in) const { \
133
+ return typename MatrixBuilderSpecial< \
134
+ get_type(out_type), ViewType_Special>::special_t(super_t::fname(in)); \
135
+ }
136
+ #define upgrade_friend_operator(op, in_type, out_type) \
137
+ friend typename MatrixBuilderSpecial<get_type(out_type), ViewType_Special>::special_t \
138
+ operator op(const get_type(in_type) &in, const self_t &matrix) { \
139
+ return in op (const super_t &)matrix; \
140
+ }
141
+
142
+ upgrade_function(operator*, T, typename super_t::mul_mat_scalar_t::mat_t);
143
+
144
+ upgrade_friend_operator(*, T, typename super_t::mul_mat_scalar_t::mat_t);
145
+
146
+ upgrade_function(operator/, T, typename super_t::mul_mat_scalar_t::mat_t);
147
+
148
+ typename MatrixBuilderSpecial<
149
+ typename super_t::mul_mat_scalar_t::mat_t, ViewType_Special>::special_t
150
+ operator-() const noexcept {
151
+ return super_t::operator-();
152
+ }
153
+
154
+ upgrade_function(operator+, T,
155
+ typename super_t::template Add_Matrix_to_Matrix<typename super_t::scalar_matrix_t>::mat_t);
156
+
157
+ upgrade_function(operator-, T,
158
+ typename super_t::template Add_Matrix_to_Matrix<typename super_t::scalar_matrix_t>::mat_t);
159
+
160
+ upgrade_friend_operator(+, T,
161
+ typename super_t::template Add_Matrix_to_Matrix<typename super_t::scalar_matrix_t>::mat_t);
162
+
163
+ upgrade_friend_operator(-, T,
164
+ (typename super_t::scalar_matrix_t::template Add_Matrix_to_Matrix<super_t, false>::mat_t));
165
+
166
+ // Adding / Subtracting a matrix having same or different special feature {
167
+ template <class MatrixT, template <class> class ViewType_Special_self, bool rhs_positive = true>
168
+ struct add_mat_mat_t {
169
+ typedef typename super_t::template Add_Matrix_to_Matrix<MatrixT, rhs_positive>::mat_t res_t;
170
+ };
171
+ template <class T2, bool rhs_positive>
172
+ struct add_mat_mat_t<Matrix_Frozen<T2, Array2D_ScaledUnit<T2> >, ViewType_Special, rhs_positive> {
173
+ // Preserve feature even if scalar is added / subtracted
174
+ typedef typename MatrixBuilderSpecial<
175
+ typename super_t::template Add_Matrix_to_Matrix<
176
+ Matrix_Frozen<T2, Array2D_ScaledUnit<T2> >, rhs_positive>::mat_t,
177
+ ViewType_Special>::special_t res_t;
178
+ };
179
+ template <class T2, class Array2D_Type2, class ViewType2, bool rhs_positive>
180
+ struct add_mat_mat_t<
181
+ Matrix_Frozen<T2, Array2D_Type2, ViewType_Special<ViewType2> >, ViewType_Special, rhs_positive> {
182
+ // (same feature) + (same feature) => (same feature), ex) (symmetric) + (symmetric) => (symmetric)
183
+ typedef typename MatrixBuilderSpecial<
184
+ typename super_t::template Add_Matrix_to_Matrix<
185
+ Matrix_Frozen<T2, Array2D_Type2, ViewType_Special<ViewType2> >, rhs_positive>::mat_t,
186
+ ViewType_Special>::special_t res_t;
187
+ };
188
+ #define make_entry(self, another, result) \
189
+ template <class T2, class Array2D_Type2, class ViewType2, bool rhs_positive> \
190
+ struct add_mat_mat_t< \
191
+ Matrix_Frozen<T2, Array2D_Type2, MatrixViewSpecial_ ## another <ViewType2> >, \
192
+ MatrixViewSpecial_ ## self, rhs_positive> { \
193
+ typedef typename MatrixBuilderSpecial< \
194
+ typename super_t::template Add_Matrix_to_Matrix< \
195
+ Matrix_Frozen<T2, Array2D_Type2, MatrixViewSpecial_ ## another <ViewType2> >, rhs_positive>::mat_t, \
196
+ MatrixViewSpecial_ ## result>::special_t res_t; \
197
+ };
198
+ make_entry(Diagonal, Symmetric, Symmetric); // (diagonal) + (symmetric) => (symmetric)
199
+ make_entry(Symmetric, Diagonal, Symmetric); // (symmetric) + (diagonal) => (symmetric)
200
+ #undef make_entry
201
+
202
+ template <class T2, class Array2D_Type2, class ViewType2>
203
+ typename add_mat_mat_t<Matrix_Frozen<T2, Array2D_Type2, ViewType2>, ViewType_Special>::res_t operator+(
204
+ const Matrix_Frozen<T2, Array2D_Type2, ViewType2> &matrix) const {
205
+ return super_t::operator+(matrix);
206
+ }
207
+ template <class T2, class Array2D_Type2, class ViewType2>
208
+ typename add_mat_mat_t<Matrix_Frozen<T2, Array2D_Type2, ViewType2>, ViewType_Special, false>::res_t operator-(
209
+ const Matrix_Frozen<T2, Array2D_Type2, ViewType2> &matrix) const {
210
+ return super_t::operator-(matrix);
211
+ }
212
+ // }
213
+
214
+ // Multiplying a matrix having same or different special feature {
215
+ template <class MatrixT, template <class> class ViewType_Special_self>
216
+ struct mul_mat_mat_t {
217
+ typedef typename super_t::template Multiply_Matrix_by_Matrix<MatrixT>::mat_t res_t;
218
+ typedef typename res_t::view_t res_view_t;
219
+ };
220
+ template <class T2>
221
+ struct mul_mat_mat_t<Matrix_Frozen<T2, Array2D_ScaledUnit<T2> >, ViewType_Special> {
222
+ // Preserve feature even if scalar is multiplied
223
+ typedef MatrixBuilderSpecial<
224
+ typename super_t::template Multiply_Matrix_by_Scalar<T2>::mat_t,
225
+ ViewType_Special> builder_t;
226
+ typedef typename builder_t::special_t res_t;
227
+ typedef typename builder_t::view_special_t res_view_t;
228
+ };
229
+ template <class T2, class Array2D_Type2, class ViewType2>
230
+ struct mul_mat_mat_t<Matrix_Frozen<T2, Array2D_Type2, ViewType_Special<ViewType2> >, ViewType_Special> {
231
+ // (same feature) * (same feature) => (same feature), ex) (symmetric) * (symmetric) => (symmetric)
232
+ typedef MatrixBuilderSpecial<
233
+ typename super_t::template Multiply_Matrix_by_Matrix<
234
+ Matrix_Frozen<T2, Array2D_Type2, ViewType_Special<ViewType2> > >::mat_t,
235
+ ViewType_Special> builder_t;
236
+ typedef typename builder_t::special_t res_t;
237
+ typedef typename builder_t::view_special_t res_view_t;
238
+ };
239
+ #define make_entry(self, another, result) \
240
+ template <class T2, class Array2D_Type2, class ViewType2> \
241
+ struct mul_mat_mat_t<Matrix_Frozen<T2, Array2D_Type2, MatrixViewSpecial_ ## another <ViewType2> >, \
242
+ MatrixViewSpecial_ ## self > { \
243
+ typedef MatrixBuilderSpecial< \
244
+ typename super_t::template Multiply_Matrix_by_Matrix< \
245
+ Matrix_Frozen<T2, Array2D_Type2, MatrixViewSpecial_## another<ViewType2> > >::mat_t, \
246
+ MatrixViewSpecial_ ## result> builder_t; \
247
+ typedef typename builder_t::special_t res_t; \
248
+ typedef typename builder_t::view_special_t res_view_t; \
249
+ };
250
+ make_entry(Diagonal, Symmetric, Symmetric); // (diagonal) * (symmetric) => (symmetric)
251
+ make_entry(Symmetric, Diagonal, Symmetric); // (symmetric) * (diagonal) => (symmetric)
252
+ #undef make_entry
253
+
254
+ template <class T2, class Array2D_Type2, class ViewType2>
255
+ typename mul_mat_mat_t<Matrix_Frozen<T2, Array2D_Type2, ViewType2>, ViewType_Special>::res_t operator*(
256
+ const Matrix_Frozen<T2, Array2D_Type2, ViewType2> &matrix) const {
257
+ return super_t::operator*(matrix);
258
+ }
259
+ // }]
260
+
261
+ // inverse {
262
+ template <class MatrixT = self_t, class U = void>
263
+ struct Inverse_Matrix {
264
+ typedef typename MatrixT::template Inverse_Matrix<>::mat_t mat_t;
265
+ };
266
+ template <class U>
267
+ struct Inverse_Matrix<self_t, U> {
268
+ typedef typename MatrixBuilderSpecial<
269
+ typename super_t::template Inverse_Matrix<super_t>::mat_t,
270
+ ViewType_Special>::special_t mat_t;
271
+ };
272
+
273
+ typename Inverse_Matrix<>::mat_t inverse() const {
274
+ return typename Inverse_Matrix<>::mat_t(static_cast<const special_t *>(this)->inverse_optimized());
275
+ }
276
+ typename super_t::template Inverse_Matrix<>::mat_t inverse_optimized() const {
277
+ return super_t::inverse();
278
+ }
279
+
280
+ template <class T2, class Array2D_Type2, class ViewType2>
281
+ typename MatrixBuilder<
282
+ typename super_t::template Multiply_Matrix_by_Matrix<
283
+ typename Inverse_Matrix<Matrix_Frozen<T2, Array2D_Type2, ViewType2> >::mat_t>::mat_t>
284
+ ::template view_replace_t<typename mul_mat_mat_t<
285
+ Matrix_Frozen<T2, Array2D_Type2, ViewType2>,
286
+ ViewType_Special>::res_view_t>::replaced_t
287
+ operator/(const Matrix_Frozen<T2, Array2D_Type2, ViewType2> &matrix) const {
288
+ typedef Matrix_Frozen<T2, Array2D_Type2, ViewType2> input_t;
289
+ typedef typename Inverse_Matrix<input_t>::mat_t inv_t;
290
+ return super_t::template Multiply_Matrix_by_Matrix<inv_t>::generate(*this, matrix.inverse());
291
+ }
292
+ friend typename MatrixBuilderSpecial<
293
+ typename super_t::template Multiply_Matrix_by_Scalar<
294
+ T, typename Inverse_Matrix<>::mat_t>::mat_t,
295
+ ViewType_Special>::special_t operator/(const T &scalar, const self_t &matrix) {
296
+ typedef typename Inverse_Matrix<>::mat_t inv_t;
297
+ return super_t::template Multiply_Matrix_by_Scalar<T, inv_t>::generate(
298
+ matrix.inverse(), scalar);
299
+ }
300
+ // }
301
+
302
+ #undef upgrade_function
303
+ #undef upgrade_friend_operator
304
+ #undef get_type
305
+ };
306
+
307
+ #define upgrade_square_matrix(fname, special_upgraded) \
308
+ template <class T, class Array2D_Type, class ViewType> \
309
+ typename MatrixBuilderSpecial< \
310
+ Matrix_Frozen<T, Array2D_Type, ViewType>, special_upgraded>::special_t fname( \
311
+ const Matrix_Frozen<T, Array2D_Type, ViewType> &mat, \
312
+ const bool &do_check = false){ \
313
+ if(do_check && (!mat.isSquare())){ \
314
+ throw std::runtime_error("Could not be upgraded to " #special_upgraded); \
315
+ } \
316
+ return typename MatrixBuilderSpecial< \
317
+ Matrix_Frozen<T, Array2D_Type, ViewType>, special_upgraded>::special_t(mat); \
318
+ }
319
+
320
+
321
+ // Symmetric {
322
+ template <class BaseView>
323
+ struct MatrixViewSpecial_SymmetricBase : public BaseView {
324
+ struct {} prop;
325
+ template <class T, class Array2D_Type>
326
+ inline T operator()(
327
+ Array2D_Type &storage, const unsigned int &i, const unsigned int &j) const {
328
+ return (i > j) // use upper triangle forcedly
329
+ ? BaseView::DELETE_IF_MSC(template) operator()<T>(storage, j, i)
330
+ : BaseView::DELETE_IF_MSC(template) operator()<T>(storage, i, j);
331
+ }
332
+ static const char *name;
333
+ template<class CharT, class Traits>
334
+ friend std::basic_ostream<CharT, Traits> &operator<<(
335
+ std::basic_ostream<CharT, Traits> &out, const MatrixViewSpecial_SymmetricBase<BaseView> &view){
336
+ return out << name << " " << (const BaseView &)view;
337
+ }
338
+ };
339
+ template <class BaseView>
340
+ const char *MatrixViewSpecial_SymmetricBase<BaseView>::name = "[Symmetric]";
341
+ template <class BaseView>
342
+ struct MatrixViewSpecial_Symmetric : public MatrixViewSpecial_SymmetricBase<BaseView> {
343
+ typedef MatrixViewSpecial_SymmetricBase<BaseView> base_t;
344
+ static const char *name;
345
+ };
346
+ template <class BaseView>
347
+ const char *MatrixViewSpecial_Symmetric<BaseView>::name = MatrixViewSpecial_SymmetricBase<BaseView>::name;
348
+
349
+ upgrade_square_matrix(as_symmetric, MatrixViewSpecial_Symmetric);
350
+ template <class T, class Array2D_Type, class ViewType>
351
+ struct Matrix_Frozen<T, Array2D_Type, MatrixViewSpecial_Symmetric<ViewType> >
352
+ : public Matrix_Frozen_Special<T, Array2D_Type, ViewType, MatrixViewSpecial_Symmetric> {
353
+ typedef Matrix_Frozen_Special<T, Array2D_Type, ViewType, MatrixViewSpecial_Symmetric> super_t;
354
+ template <class ViewType2>
355
+ Matrix_Frozen(const Matrix_Frozen<T, Array2D_Type, ViewType2> &mat) noexcept
356
+ : super_t(mat){
357
+ }
358
+ Matrix_Frozen(const Array2D_Type &storage) noexcept : super_t(storage){}
359
+ bool isSquare() const noexcept {return true;}
360
+ bool isDiagonal() const noexcept {return false;}
361
+ bool isSymmetric() const noexcept {return true;}
362
+ typename super_t::special_t transpose() const noexcept {
363
+ return typename super_t::special_t(*this);
364
+ }
365
+ };
366
+ template <class T, class Array2D_Type, class ViewType>
367
+ struct MatrixBuilder_ValueCopier<
368
+ Matrix_Frozen<
369
+ T, Array2D_Type, MatrixViewSpecial_SymmetricBase<ViewType> > > {
370
+
371
+ template <class T2, class Array2D_Type2, class ViewType2>
372
+ static Matrix<T2, Array2D_Type2, ViewType2> &copy_value(
373
+ Matrix<T2, Array2D_Type2, ViewType2> &dest,
374
+ const Matrix_Frozen<
375
+ T, Array2D_Type, MatrixViewSpecial_SymmetricBase<ViewType> > &src) {
376
+ // use only upper triangle; lower one is cloned with upper one.
377
+ const unsigned int i_end(src.rows()), j_end(src.columns());
378
+ for(unsigned int i(0); i < i_end; ++i){
379
+ dest(i, i) = (T2)(src(i, i));
380
+ for(unsigned int j(i+1); j < j_end; ++j){
381
+ dest(i, j) = dest(j, i) = (T2)(src(i, j));
382
+ }
383
+ }
384
+ return dest;
385
+ }
386
+ };
387
+ // }
388
+
389
+ // Diagonal {
390
+ template <class BaseView>
391
+ struct MatrixViewSpecial_DiagonalBase : public BaseView {
392
+ struct {} prop;
393
+ template <class T, class Array2D_Type>
394
+ inline T operator()(
395
+ Array2D_Type &storage, const unsigned int &i, const unsigned int &j) const {
396
+ return (i != j) // use upper triangle forcedly
397
+ ? 0
398
+ : BaseView::DELETE_IF_MSC(template) operator()<T>(storage, i, i);
399
+ }
400
+ static const char *name;
401
+ template<class CharT, class Traits>
402
+ friend std::basic_ostream<CharT, Traits> &operator<<(
403
+ std::basic_ostream<CharT, Traits> &out, const MatrixViewSpecial_DiagonalBase<BaseView> &view){
404
+ return out << name << " " << (const BaseView &)view;
405
+ }
406
+ };
407
+ template <class BaseView>
408
+ const char *MatrixViewSpecial_DiagonalBase<BaseView>::name = "[Diagonal]";
409
+ template <class BaseView>
410
+ struct MatrixViewSpecial_Diagonal : public MatrixViewSpecial_DiagonalBase<BaseView> {
411
+ typedef MatrixViewSpecial_DiagonalBase<BaseView> base_t;
412
+ static const char *name;
413
+ };
414
+ template <class BaseView>
415
+ const char *MatrixViewSpecial_Diagonal<BaseView>::name = MatrixViewSpecial_DiagonalBase<BaseView>::name;
416
+
417
+ upgrade_square_matrix(as_diagonal, MatrixViewSpecial_Diagonal);
418
+ template <class T, class Array2D_Type, class ViewType>
419
+ struct Matrix_Frozen<T, Array2D_Type, MatrixViewSpecial_Diagonal<ViewType> >
420
+ : public Matrix_Frozen_Special<T, Array2D_Type, ViewType, MatrixViewSpecial_Diagonal> {
421
+ typedef Matrix_Frozen_Special<T, Array2D_Type, ViewType, MatrixViewSpecial_Diagonal> super_t;
422
+ template <class ViewType2>
423
+ Matrix_Frozen(const Matrix_Frozen<T, Array2D_Type, ViewType2> &mat) noexcept
424
+ : super_t(mat){
425
+ }
426
+ Matrix_Frozen(const Array2D_Type &storage) noexcept : super_t(storage){}
427
+ bool isSquare() const noexcept {return true;}
428
+ bool isDiagonal() const noexcept {return true;}
429
+ bool isSymmetric() const noexcept {return true;}
430
+ typename super_t::special_t transpose() const noexcept {
431
+ return typename super_t::special_t(*this);
432
+ }
433
+ typename super_t::super_t::template Inverse_Matrix<>::mat_t inverse_optimized() const noexcept {
434
+ // TODO optimize by returning unary operation
435
+ typename super_t::super_t::template Inverse_Matrix<>::mat_t res(this->rows(), this->rows());
436
+ for(unsigned int i(0), i_end(this->rows()); i < i_end; ++i){
437
+ res(i, i) = T(1) / (*this)(i, i);
438
+ }
439
+ return res;
440
+ }
441
+ };
442
+ template <class T, class Array2D_Type, class ViewType>
443
+ struct MatrixBuilder_ValueCopier<
444
+ Matrix_Frozen<
445
+ T, Array2D_Type, MatrixViewSpecial_DiagonalBase<ViewType> > > {
446
+
447
+ template <class T2, class Array2D_Type2, class ViewType2>
448
+ static Matrix<T2, Array2D_Type2, ViewType2> &copy_value(
449
+ Matrix<T2, Array2D_Type2, ViewType2> &dest,
450
+ const Matrix_Frozen<
451
+ T, Array2D_Type, MatrixViewSpecial_DiagonalBase<ViewType> > &src) {
452
+ const unsigned int i_end(src.rows()), j_end(src.columns());
453
+ for(unsigned int i(0); i < i_end; ++i){
454
+ dest(i, i) = (T2)(src(i, i));
455
+ for(unsigned int j(i+1); j < j_end; ++j){
456
+ dest(i, j) = dest(j, i) = (T2)0;
457
+ }
458
+ }
459
+ return dest;
460
+ }
461
+ };
462
+ // }
463
+
464
+ // Optimization for multiplication of special matrix {
465
+ #define upgrade_mul_mat_mat(view_lhs, view_rhs) \
466
+ template < \
467
+ class T, class Array2D_Type, class ViewType, \
468
+ class T2, class Array2D_Type2, class ViewType2> \
469
+ struct Array2D_Operator_Multiply_by_Matrix< \
470
+ Matrix_Frozen<T, Array2D_Type, view_lhs >, \
471
+ Matrix_Frozen<T2, Array2D_Type2, view_rhs > > \
472
+ : public Array2D_Operator_Binary< \
473
+ Matrix_Frozen<T, Array2D_Type, view_lhs >, \
474
+ Matrix_Frozen<T2, Array2D_Type2, view_rhs > >{ \
475
+ typedef Matrix_Frozen<T, Array2D_Type, view_lhs > lhs_t; \
476
+ typedef Matrix_Frozen<T2, Array2D_Type2, view_rhs > rhs_t; \
477
+ typedef Array2D_Operator_Multiply_by_Matrix<lhs_t, rhs_t> self_t; \
478
+ typedef Array2D_Operator_Binary<lhs_t, rhs_t> super_t; \
479
+ static const int tag = lhs_t::OPERATOR_2_Multiply_Matrix_by_Matrix; \
480
+ Array2D_Operator_Multiply_by_Matrix(const lhs_t &_lhs, const rhs_t &_rhs) noexcept \
481
+ : super_t(_lhs, _rhs) {} \
482
+ T operator()(const unsigned int &row, const unsigned int &column) const noexcept; \
483
+ typedef Matrix_Frozen<T, Array2D_Operator<T, self_t> > mat_t; \
484
+ static mat_t generate(const lhs_t &mat1, const rhs_t &mat2) { \
485
+ return mat_t( \
486
+ typename mat_t::storage_t( \
487
+ mat1.rows(), mat2.columns(), self_t(mat1, mat2))); \
488
+ } \
489
+ };
490
+ #define upgrade_mul_mat_mat_function(view_lhs, view_rhs, fname, out_type) \
491
+ template < \
492
+ class T, class Array2D_Type, class ViewType, \
493
+ class T2, class Array2D_Type2, class ViewType2> \
494
+ out_type Array2D_Operator_Multiply_by_Matrix< \
495
+ Matrix_Frozen<T, Array2D_Type, view_lhs >, \
496
+ Matrix_Frozen<T2, Array2D_Type2, view_rhs > >::fname
497
+
498
+ upgrade_mul_mat_mat(ViewType, MatrixViewSpecial_Diagonal<ViewType2>);
499
+ upgrade_mul_mat_mat_function(ViewType, MatrixViewSpecial_Diagonal<ViewType2>, operator(), T)
500
+ (const unsigned int &row, const unsigned int &column) const noexcept{
501
+ return super_t::lhs(row, column) * super_t::rhs(column, column);
502
+ }
503
+ upgrade_mul_mat_mat(MatrixViewSpecial_DiagonalBase<ViewType>, ViewType2);
504
+ upgrade_mul_mat_mat_function(MatrixViewSpecial_DiagonalBase<ViewType>, ViewType2, operator(), T)
505
+ (const unsigned int &row, const unsigned int &column) const noexcept{
506
+ return super_t::lhs(row, row) * super_t::rhs(row, column);
507
+ }
508
+ upgrade_mul_mat_mat(MatrixViewSpecial_DiagonalBase<ViewType>, MatrixViewSpecial_Diagonal<ViewType2>);
509
+ upgrade_mul_mat_mat_function(
510
+ MatrixViewSpecial_DiagonalBase<ViewType>, MatrixViewSpecial_Diagonal<ViewType2>, operator(), T)
511
+ (const unsigned int &row, const unsigned int &column) const noexcept{
512
+ return (row == column) ? (super_t::lhs(row, row) * super_t::rhs(column, column)) : T(0);
513
+ }
514
+
515
+ // For ambiguity resolution (diagonal_M * scalar_M)
516
+ template <
517
+ class T, class Array2D_Type, class ViewType,
518
+ class T2>
519
+ struct Array2D_Operator_Multiply_by_Matrix<
520
+ Matrix_Frozen<T, Array2D_Type, MatrixViewSpecial_DiagonalBase<ViewType> >,
521
+ Matrix_Frozen<T2, Array2D_ScaledUnit<T2> > >
522
+ : public Matrix_multiplied_by_Scalar<
523
+ Matrix_Frozen<T, Array2D_Type, MatrixViewSpecial_DiagonalBase<ViewType> >, T2> {
524
+ typedef Matrix_multiplied_by_Scalar<
525
+ Matrix_Frozen<T, Array2D_Type, MatrixViewSpecial_DiagonalBase<ViewType> >, T2> super_t;
526
+ static typename super_t::mat_t generate(
527
+ const typename super_t::lhs_t &mat1, const Matrix_Frozen<T2, Array2D_ScaledUnit<T2> > &mat2) {
528
+ return super_t::generate(mat1, mat2(0, 0));
529
+ }
530
+ };
531
+
532
+
533
+ #undef upgrade_mul_mat_mat
534
+ #undef upgrade_mul_mat_mat_function
535
+ // }
536
+
537
+
538
+ /* The following specializations are required to treat with internal reuse of expression type
539
+ * for optimization. Their typical example is (mat * scalar) * scalar => (mat * (scalar * scalar)),
540
+ * whose result type before as_special is special_Base<View>. as_special() may result in
541
+ * special<special_Base<View> > without these specializations.
542
+ */
543
+ #define resolve_redundant_special(special) \
544
+ template <class BaseView> \
545
+ struct MatrixViewSpecialBuilder< \
546
+ MatrixViewSpecial_ ## special<MatrixViewSpecial_ ## special ## Base<BaseView> > > { \
547
+ typedef MatrixViewSpecial_ ## special<BaseView> view_t; \
548
+ };
549
+ resolve_redundant_special(Symmetric);
550
+ resolve_redundant_special(Diagonal);
551
+ #undef resolve_redundant_special
552
+
553
+ #undef upgrade_square_matrix
554
+
555
+ #undef DELETE_IF_MSC
556
+
557
+ #undef throws_when_debug
558
+ #if (__cplusplus < 201103L) && defined(noexcept)
559
+ #undef noexcept
560
+ #endif
561
+
562
+ #endif /* __MATRIX_SPECIAL_H__ */