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.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +10 -0
- data/README.md +86 -0
- data/Rakefile +86 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/ext/gps_pvt/Coordinate/Coordinate_wrap.cxx +6613 -0
- data/ext/gps_pvt/GPS/GPS_wrap.cxx +16019 -0
- data/ext/gps_pvt/SylphideMath/SylphideMath_wrap.cxx +21050 -0
- data/ext/gps_pvt/extconf.rb +70 -0
- data/ext/ninja-scan-light/tool/navigation/EGM.h +2971 -0
- data/ext/ninja-scan-light/tool/navigation/GPS.h +2432 -0
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver.h +479 -0
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_Base.h +1081 -0
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_MultiFrequency.h +199 -0
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_RAIM.h +210 -0
- data/ext/ninja-scan-light/tool/navigation/MagneticField.h +928 -0
- data/ext/ninja-scan-light/tool/navigation/NTCM.h +211 -0
- data/ext/ninja-scan-light/tool/navigation/RINEX.h +1781 -0
- data/ext/ninja-scan-light/tool/navigation/WGS84.h +186 -0
- data/ext/ninja-scan-light/tool/navigation/coordinate.h +406 -0
- data/ext/ninja-scan-light/tool/param/bit_array.h +145 -0
- data/ext/ninja-scan-light/tool/param/complex.h +558 -0
- data/ext/ninja-scan-light/tool/param/matrix.h +4049 -0
- data/ext/ninja-scan-light/tool/param/matrix_fixed.h +665 -0
- data/ext/ninja-scan-light/tool/param/matrix_special.h +562 -0
- data/ext/ninja-scan-light/tool/param/quaternion.h +765 -0
- data/ext/ninja-scan-light/tool/param/vector3.h +651 -0
- data/ext/ninja-scan-light/tool/swig/Coordinate.i +177 -0
- data/ext/ninja-scan-light/tool/swig/GPS.i +1102 -0
- data/ext/ninja-scan-light/tool/swig/SylphideMath.i +1234 -0
- data/ext/ninja-scan-light/tool/swig/extconf.rb +5 -0
- data/ext/ninja-scan-light/tool/swig/makefile +53 -0
- data/ext/ninja-scan-light/tool/swig/spec/GPS_spec.rb +417 -0
- data/ext/ninja-scan-light/tool/swig/spec/SylphideMath_spec.rb +489 -0
- data/gps_pvt.gemspec +57 -0
- data/lib/gps_pvt/receiver.rb +375 -0
- data/lib/gps_pvt/ubx.rb +148 -0
- data/lib/gps_pvt/version.rb +5 -0
- data/lib/gps_pvt.rb +9 -0
- data/sig/gps_pvt.rbs +4 -0
- 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> ©_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> ©_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__ */
|