gps_pvt 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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__ */