gps_pvt 0.9.3 → 0.10.0
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 +4 -4
- data/CHANGELOG.md +159 -3
- data/README.md +4 -3
- data/Rakefile +24 -0
- data/exe/gps2ubx +12 -5
- data/exe/gps_pvt +7 -2
- data/ext/gps_pvt/Coordinate/Coordinate_wrap.cxx +53 -19
- data/ext/gps_pvt/GPS/GPS_wrap.cxx +39 -7
- data/ext/gps_pvt/SylphideMath/SylphideMath_wrap.cxx +5210 -2058
- data/ext/gps_pvt/extconf.rb +6 -5
- data/ext/ninja-scan-light/tool/navigation/GLONASS_Solver.h +1 -1
- data/ext/ninja-scan-light/tool/navigation/GPS.h +6 -2
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver.h +1 -1
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_Base.h +3 -1
- data/ext/ninja-scan-light/tool/navigation/GPS_Solver_MultiFrequency.h +3 -0
- data/ext/ninja-scan-light/tool/navigation/RINEX.h +9 -9
- data/ext/ninja-scan-light/tool/navigation/SBAS_Solver.h +1 -1
- data/ext/ninja-scan-light/tool/navigation/coordinate.h +13 -6
- data/ext/ninja-scan-light/tool/param/matrix.h +1020 -247
- data/ext/ninja-scan-light/tool/param/matrix_fixed.h +26 -0
- data/ext/ninja-scan-light/tool/swig/GPS.i +6 -4
- data/ext/ninja-scan-light/tool/swig/SylphideMath.i +139 -36
- data/ext/ninja-scan-light/tool/swig/spec/SylphideMath_spec.rb +115 -5
- data/gps_pvt.gemspec +3 -1
- data/lib/gps_pvt/asn1/asn1.rb +888 -0
- data/lib/gps_pvt/asn1/asn1.y +903 -0
- data/lib/gps_pvt/asn1/per.rb +182 -0
- data/lib/gps_pvt/ntrip.rb +1 -1
- data/lib/gps_pvt/receiver/agps.rb +31 -0
- data/lib/gps_pvt/receiver/extension.rb +94 -0
- data/lib/gps_pvt/receiver/rtcm3.rb +6 -4
- data/lib/gps_pvt/receiver.rb +41 -24
- data/lib/gps_pvt/rtcm3.rb +24 -34
- data/lib/gps_pvt/supl.rb +567 -0
- data/lib/gps_pvt/ubx.rb +15 -0
- data/lib/gps_pvt/upl/LPP-V17_5_0-Release17.asn +6441 -0
- data/lib/gps_pvt/upl/RRLP-V17_0_0-Release17.asn +2780 -0
- data/lib/gps_pvt/upl/ULP-V2_0_6-20200720-D.asn +2185 -0
- data/lib/gps_pvt/upl/upl.json.gz +0 -0
- data/lib/gps_pvt/upl/upl.rb +99 -0
- data/lib/gps_pvt/util.rb +1 -0
- data/lib/gps_pvt/version.rb +1 -1
- metadata +41 -3
@@ -380,6 +380,32 @@ struct MatrixBuilder_Dependency<
|
|
380
380
|
(MatrixViewProperty<ViewType_R>::transposed ? nR_R : nC_R)>,
|
381
381
|
ViewType> > {};
|
382
382
|
|
383
|
+
template <
|
384
|
+
class T, class T_op,
|
385
|
+
class T2, class T3, class T4, class T5,
|
386
|
+
class ViewType,
|
387
|
+
int nR_L, int nC_L, class ViewType_L,
|
388
|
+
int nR_R, int nC_R, class ViewType_R,
|
389
|
+
bool horizontal_R>
|
390
|
+
struct MatrixBuilder_Dependency<
|
391
|
+
Matrix_Frozen<
|
392
|
+
T,
|
393
|
+
Array2D_Operator<T_op, Array2D_Operator_Stack<
|
394
|
+
Matrix_Frozen<T2, Array2D_Fixed<T3, nR_L, nC_L>, ViewType_L>,
|
395
|
+
Matrix_Frozen<T4, Array2D_Fixed<T5, nR_R, nC_R>, ViewType_R>,
|
396
|
+
horizontal_R> >,
|
397
|
+
ViewType> >
|
398
|
+
: public MatrixBuilder_Dependency<
|
399
|
+
Matrix_Frozen<
|
400
|
+
T,
|
401
|
+
Array2D_Fixed<
|
402
|
+
T,
|
403
|
+
(MatrixViewProperty<ViewType_L>::transposed ? nC_L : nR_L)
|
404
|
+
+ (horizontal_R ? 0 : (MatrixViewProperty<ViewType_R>::transposed ? nC_R : nR_R)),
|
405
|
+
(MatrixViewProperty<ViewType_L>::transposed ? nR_L : nC_L)
|
406
|
+
+ (horizontal_R ? (MatrixViewProperty<ViewType_R>::transposed ? nR_R : nC_R) : 0)>,
|
407
|
+
ViewType> > {};
|
408
|
+
|
383
409
|
// For optimization of local temporary matrix
|
384
410
|
template <
|
385
411
|
template <class, class, class> class MatrixT,
|
@@ -1094,18 +1094,18 @@ struct GPS_User_PVT
|
|
1094
1094
|
.append(inspect_str(v_key_value)).append("}").c_str());
|
1095
1095
|
}
|
1096
1096
|
rb_hash_foreach(v_key_value,
|
1097
|
-
|
1097
|
+
%#if RUBY_API_VERSION_CODE < 20700
|
1098
1098
|
// @see https://docs.ruby-lang.org/ja/latest/doc/news=2f2_7_0.html
|
1099
1099
|
(int (*)(ANYARGS))
|
1100
|
-
|
1100
|
+
%#endif
|
1101
1101
|
arg_t::iter2, v_arg);
|
1102
1102
|
return ST_CONTINUE;
|
1103
1103
|
}
|
1104
1104
|
} arg = {val};
|
1105
1105
|
rb_hash_foreach(obj,
|
1106
|
-
|
1106
|
+
%#if RUBY_API_VERSION_CODE < 20700
|
1107
1107
|
(int (*)(ANYARGS))
|
1108
|
-
|
1108
|
+
%#endif
|
1109
1109
|
arg_t::iter1, reinterpret_cast<VALUE>(&arg));
|
1110
1110
|
return SWIG_OK;
|
1111
1111
|
}
|
@@ -1169,6 +1169,7 @@ struct GPS_Measurement {
|
|
1169
1169
|
L1_RANGE_RATE_SIGMA,
|
1170
1170
|
L1_SIGNAL_STRENGTH_dBHz,
|
1171
1171
|
L1_LOCK_SEC,
|
1172
|
+
L1_CARRIER_PHASE_AMBIGUITY_SCALE,
|
1172
1173
|
L1_FREQUENCY,
|
1173
1174
|
#define make_entry(key) L2CM_ ## key, L2CL_ ## key
|
1174
1175
|
#define make_entry2(key) make_entry(key), make_entry(key ## _SIGMA)
|
@@ -1178,6 +1179,7 @@ struct GPS_Measurement {
|
|
1178
1179
|
make_entry2(RANGE_RATE),
|
1179
1180
|
make_entry(SIGNAL_STRENGTH_dBHz),
|
1180
1181
|
make_entry(LOCK_SEC),
|
1182
|
+
make_entry(CARRIER_PHASE_AMBIGUITY_SCALE),
|
1181
1183
|
#undef make_entry2
|
1182
1184
|
#undef make_entry
|
1183
1185
|
ITEMS_PREDEFINED,
|
@@ -123,16 +123,16 @@ class Complex;
|
|
123
123
|
typedef Complex<T> value_type;
|
124
124
|
static int asval(VALUE obj, value_type *v) {
|
125
125
|
if(RB_TYPE_P(obj, T_COMPLEX)){
|
126
|
-
|
126
|
+
%#if RUBY_API_VERSION_CODE < 20600
|
127
127
|
static const ID id_r(rb_intern("real")), id_i(rb_intern("imag"));
|
128
128
|
int res = swig::asval(rb_funcall(obj, id_r, 0), &(v->real()));
|
129
129
|
if(!SWIG_IsOK(res)){return res;}
|
130
130
|
return swig::asval(rb_funcall(obj, id_i, 0), &(v->imaginary()));
|
131
|
-
|
131
|
+
%#else
|
132
132
|
int res = swig::asval(rb_complex_real(obj), &(v->real()));
|
133
133
|
if(!SWIG_IsOK(res)){return res;}
|
134
134
|
return swig::asval(rb_complex_imag(obj), &(v->imaginary()));
|
135
|
-
|
135
|
+
%#endif
|
136
136
|
}else{
|
137
137
|
v->imaginary() = T(0);
|
138
138
|
return swig::asval(obj, &(v->real()));
|
@@ -148,14 +148,14 @@ class Complex;
|
|
148
148
|
template <class T> struct traits_check< Complex<T>, value_category> {
|
149
149
|
static bool check(VALUE obj) {
|
150
150
|
if(RB_TYPE_P(obj, T_COMPLEX)){
|
151
|
-
|
151
|
+
%#if RUBY_API_VERSION_CODE < 20600
|
152
152
|
static const ID id_r(rb_intern("real")), id_i(rb_intern("imag"));
|
153
153
|
return swig::check<T>(rb_funcall(obj, id_r, 0))
|
154
154
|
&& swig::check<T>(rb_funcall(obj, id_i, 0));
|
155
|
-
|
155
|
+
%#else
|
156
156
|
return swig::check<T>(rb_complex_real(obj))
|
157
157
|
&& swig::check<T>(rb_complex_imag(obj));
|
158
|
-
|
158
|
+
%#endif
|
159
159
|
}else{
|
160
160
|
return swig::check<T>(obj);
|
161
161
|
}
|
@@ -345,12 +345,6 @@ struct MatrixViewFilter : public BaseView {
|
|
345
345
|
res.view().partial(new_rows, new_columns, row_offset, column_offset);
|
346
346
|
return res;
|
347
347
|
}
|
348
|
-
template <class T, class Array2D_Type, class ViewType>
|
349
|
-
static Matrix_Frozen<T, Array2D_Type, self_t> partial(
|
350
|
-
const Matrix_Frozen<T, Array2D_Type, ViewType> &orig,
|
351
|
-
const unsigned int &new_rows, const unsigned int &new_columns) {
|
352
|
-
return partial(orig, new_rows, new_columns, 0, 0);
|
353
|
-
}
|
354
348
|
|
355
349
|
template<class CharT, class Traits>
|
356
350
|
friend std::basic_ostream<CharT, Traits> &operator<<(
|
@@ -412,17 +406,27 @@ class Matrix_Frozen {
|
|
412
406
|
template <class T2, class Array2D_Type2, class ViewType2>
|
413
407
|
bool operator==(const Matrix_Frozen<T2, Array2D_Type2, ViewType2> &matrix) const noexcept;
|
414
408
|
// bool operator!= // automatically defined
|
415
|
-
|
409
|
+
|
416
410
|
bool isSquare() const noexcept;
|
417
411
|
bool isDiagonal() const noexcept;
|
412
|
+
bool isLowerTriangular() const noexcept;
|
413
|
+
bool isUpperTriangular() const noexcept;
|
418
414
|
bool isSymmetric() const noexcept;
|
415
|
+
bool isHermitian() const noexcept;
|
416
|
+
bool isSkewSymmetric() const noexcept;
|
417
|
+
bool isNormal() const noexcept;
|
418
|
+
bool isOrthogonal() const noexcept;
|
419
|
+
bool isUnitary() const noexcept;
|
419
420
|
|
420
|
-
T trace(
|
421
|
+
T trace() const;
|
421
422
|
T sum() const noexcept;
|
422
423
|
|
423
424
|
// bool isLU() const noexcept
|
424
425
|
|
425
|
-
T determinant(
|
426
|
+
T determinant() const;
|
427
|
+
unsigned int rank() const;
|
428
|
+
T cofactor(
|
429
|
+
const unsigned int &row, const unsigned int &column) const;
|
426
430
|
};
|
427
431
|
|
428
432
|
template <class T, class Array2D_Type, class ViewType = MatrixViewBase<> >
|
@@ -470,6 +474,11 @@ typedef MatrixViewTranspose<MatrixViewSizeVariable<MatrixViewOffset<MatrixViewBa
|
|
470
474
|
|
471
475
|
%{
|
472
476
|
struct MatrixUtil {
|
477
|
+
struct each_break_t {
|
478
|
+
unsigned int r, c;
|
479
|
+
each_break_t(const unsigned int &row, const unsigned int &column)
|
480
|
+
: r(row), c(column) {}
|
481
|
+
};
|
473
482
|
enum each_which_t {
|
474
483
|
EACH_ALL,
|
475
484
|
EACH_DIAGONAL,
|
@@ -478,6 +487,7 @@ struct MatrixUtil {
|
|
478
487
|
EACH_UPPER,
|
479
488
|
EACH_STRICT_LOWER,
|
480
489
|
EACH_STRICT_UPPER,
|
490
|
+
EACH_UNKNOWN,
|
481
491
|
};
|
482
492
|
template <class T,
|
483
493
|
class Array2D_Type, class ViewType,
|
@@ -488,7 +498,7 @@ struct MatrixUtil {
|
|
488
498
|
const T &src_elm, T *dst_elm,
|
489
499
|
const unsigned int &i, const unsigned int &j),
|
490
500
|
const each_which_t &each_which = EACH_ALL,
|
491
|
-
Matrix<T, Array2D_Type2, ViewType2> *dst = NULL){
|
501
|
+
Matrix<T, Array2D_Type2, ViewType2> *dst = NULL) {
|
492
502
|
unsigned int i_max(src.rows()), j_max(src.columns());
|
493
503
|
switch(each_which){
|
494
504
|
case EACH_DIAGONAL:
|
@@ -544,10 +554,8 @@ struct MatrixUtil {
|
|
544
554
|
}
|
545
555
|
}
|
546
556
|
#if defined(SWIGRUBY)
|
547
|
-
static
|
548
|
-
if(!RB_TYPE_P(value, T_SYMBOL)){
|
549
|
-
std::invalid_argument("Symbol is required");
|
550
|
-
}
|
557
|
+
static each_which_t sym2each_which(const VALUE &value){
|
558
|
+
if(!RB_TYPE_P(value, T_SYMBOL)){return EACH_UNKNOWN;}
|
551
559
|
static const struct {
|
552
560
|
VALUE sym;
|
553
561
|
each_which_t which;
|
@@ -564,9 +572,7 @@ struct MatrixUtil {
|
|
564
572
|
while(value != cmp[i].sym){
|
565
573
|
if(++i >= (sizeof(cmp) / sizeof(cmp[0]))){break;}
|
566
574
|
}
|
567
|
-
if(i >= (sizeof(cmp) / sizeof(cmp[0]))){
|
568
|
-
std::invalid_argument("Unknown enumerate direction");
|
569
|
-
}
|
575
|
+
if(i >= (sizeof(cmp) / sizeof(cmp[0]))){return EACH_UNKNOWN;}
|
570
576
|
return cmp[i].which;
|
571
577
|
}
|
572
578
|
#endif
|
@@ -671,6 +677,8 @@ struct MatrixUtil {
|
|
671
677
|
%catches(std::out_of_range) rowVector;
|
672
678
|
%catches(std::out_of_range) columnVector;
|
673
679
|
%catches(std::logic_error, std::runtime_error) determinant;
|
680
|
+
%catches(std::logic_error) rank;
|
681
|
+
%catches(std::logic_error, std::runtime_error) cofactor;
|
674
682
|
|
675
683
|
T __getitem__(const unsigned int &row, const unsigned int &column) const {
|
676
684
|
return ($self)->operator()(row, column);
|
@@ -731,6 +739,17 @@ struct MatrixUtil {
|
|
731
739
|
return (Matrix<T, Array2D_Dense<T> >)(($self)->operator-(scalar));
|
732
740
|
}
|
733
741
|
|
742
|
+
#ifdef SWIGRUBY
|
743
|
+
%alias entrywise_product "hadamard_product";
|
744
|
+
#endif
|
745
|
+
%catches(std::invalid_argument) entrywise_product;
|
746
|
+
template <class T2, class Array2D_Type2, class ViewType2>
|
747
|
+
Matrix<T, Array2D_Dense<T> > entrywise_product(
|
748
|
+
const Matrix_Frozen<T2, Array2D_Type2, ViewType2> &matrix) const {
|
749
|
+
return (Matrix<T, Array2D_Dense<T> >)(($self)->entrywise_product(matrix));
|
750
|
+
}
|
751
|
+
INSTANTIATE_MATRIX_FUNC(entrywise_product, entrywise_product);
|
752
|
+
|
734
753
|
template <class T2, class Array2D_Type2, class ViewType2>
|
735
754
|
Matrix<T, Array2D_Dense<T> > operator*(
|
736
755
|
const Matrix_Frozen<T2, Array2D_Type2, ViewType2> &matrix)
|
@@ -738,6 +757,18 @@ struct MatrixUtil {
|
|
738
757
|
return (Matrix<T, Array2D_Dense<T> >)(($self)->operator*(matrix));
|
739
758
|
}
|
740
759
|
INSTANTIATE_MATRIX_FUNC(operator*, __mul__);
|
760
|
+
|
761
|
+
// TODO __pow__ for **
|
762
|
+
// TODO __pos__ for +@
|
763
|
+
|
764
|
+
Matrix<T, Array2D_Dense<T> > first_minor(
|
765
|
+
const unsigned int &row,
|
766
|
+
const unsigned int &column) const noexcept {
|
767
|
+
return (Matrix<T, Array2D_Dense<T> >)(($self)->matrix_for_minor(row, column));
|
768
|
+
}
|
769
|
+
Matrix<T, Array2D_Dense<T> > adjugate() const {
|
770
|
+
return (Matrix<T, Array2D_Dense<T> >)(($self)->adjugate());
|
771
|
+
}
|
741
772
|
|
742
773
|
%typemap(in,numinputs=0)
|
743
774
|
Matrix<T, Array2D_Dense<T> > &output_L (Matrix<T, Array2D_Dense<T> > temp),
|
@@ -816,16 +847,33 @@ struct MatrixUtil {
|
|
816
847
|
s << $self->inspect();
|
817
848
|
return s.str();
|
818
849
|
}
|
850
|
+
|
851
|
+
/* The followings are better to be implemented in Ruby
|
852
|
+
* combine, hstack, vstack (due to their arguments are variable)
|
853
|
+
*/
|
819
854
|
|
820
855
|
#ifdef SWIGRUBY
|
821
856
|
%rename("square?") isSquare;
|
822
857
|
%rename("diagonal?") isDiagonal;
|
858
|
+
%rename("lower_triangular?") isLowerTriangular;
|
859
|
+
%rename("upper_triangular?") isUpperTriangular;
|
823
860
|
%rename("symmetric?") isSymmetric;
|
861
|
+
%rename("hermitian?") isHermitian;
|
862
|
+
%rename("skew_symmetric?") isSkewSymmetric;
|
863
|
+
%alias isSkewSymmetric "antisymmetric?"
|
864
|
+
%rename("normal?") isNormal;
|
865
|
+
%rename("orthogonal?") isOrthogonal;
|
866
|
+
%rename("unitary?") isUnitary;
|
824
867
|
%rename("different_size?") isDifferentSize;
|
868
|
+
%alias __getitem__ "element,component";
|
869
|
+
// %alias __eq__ "eql?"; // Intentionally commented out because eql? is more strict than ==
|
870
|
+
%alias rows "row_size,row_count";
|
871
|
+
%alias columns "column_size,column_count";
|
825
872
|
%alias trace "tr";
|
826
873
|
%alias determinant "det";
|
827
874
|
%alias inverse "inv";
|
828
875
|
%alias transpose "t";
|
876
|
+
%alias conjugate "conj";
|
829
877
|
%alias lup "lup_decomposition";
|
830
878
|
%alias ud "ud_decomposition";
|
831
879
|
%alias qr "qr_decomposition";
|
@@ -833,7 +881,7 @@ struct MatrixUtil {
|
|
833
881
|
%fragment(SWIG_From_frag(Matrix_Frozen_Helper<T>), "header",
|
834
882
|
fragment=SWIG_Traits_frag(T)){
|
835
883
|
template <bool with_index = false, bool assign = false>
|
836
|
-
static inline
|
884
|
+
static inline VALUE matrix_yield_internal(
|
837
885
|
const T &src, T *dst, const unsigned int &i, const unsigned int &j){
|
838
886
|
SWIG_Object v;
|
839
887
|
if(with_index){
|
@@ -848,6 +896,7 @@ struct MatrixUtil {
|
|
848
896
|
s << "Unknown input (T expected) [" << i << "," << j << "]: ";
|
849
897
|
throw std::invalid_argument(s.str().append(inspect_str(v)));
|
850
898
|
}
|
899
|
+
return v;
|
851
900
|
}
|
852
901
|
static void matrix_yield(
|
853
902
|
const T &src, T *dst, const unsigned int &i, const unsigned int &j){
|
@@ -865,11 +914,17 @@ struct MatrixUtil {
|
|
865
914
|
const T &src, T *dst, const unsigned int &i, const unsigned int &j){
|
866
915
|
matrix_yield_internal<true, true>(src, dst, i, j);
|
867
916
|
}
|
917
|
+
|
918
|
+
static void matrix_yield_check(
|
919
|
+
const T &src, T *dst, const unsigned int &i, const unsigned int &j){
|
920
|
+
VALUE res(matrix_yield_internal<false, false>(src, dst, i, j));
|
921
|
+
if(RTEST(res)){throw typename MatrixUtil::each_break_t(i, j);}
|
922
|
+
}
|
868
923
|
static void (*matrix_each(const T *))
|
869
924
|
(const T &, T *, const unsigned int &, const unsigned int &) {
|
870
925
|
ID id_thisf(rb_frame_this_func()), id_callee(rb_frame_callee());
|
871
926
|
static const ID
|
872
|
-
id_map(rb_intern("map")), id_mapb(rb_intern("map!")),
|
927
|
+
id_map(rb_intern("map")), id_mapb(rb_intern("map!")),
|
873
928
|
id_eachwi(rb_intern("each_with_index"));
|
874
929
|
if((id_thisf == id_map) || (id_thisf == id_mapb)){
|
875
930
|
static const ID with_index[] = {
|
@@ -895,14 +950,14 @@ struct MatrixUtil {
|
|
895
950
|
}
|
896
951
|
$1 = matrix_each((const T *)0);
|
897
952
|
}
|
898
|
-
%typemap(typecheck) const typename MatrixUtil::each_which_t
|
899
|
-
$1 =
|
953
|
+
%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER) const typename MatrixUtil::each_which_t each_which {
|
954
|
+
$1 = (MatrixUtil::sym2each_which($input) != MatrixUtil::EACH_UNKNOWN);
|
900
955
|
}
|
901
|
-
%typemap(in) const typename MatrixUtil::each_which_t
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
956
|
+
%typemap(in) const typename MatrixUtil::each_which_t each_which {
|
957
|
+
$1 = MatrixUtil::sym2each_which($input);
|
958
|
+
if($1 == MatrixUtil::EACH_UNKNOWN){
|
959
|
+
SWIG_exception(SWIG_ValueError,
|
960
|
+
std::string("Unknown enumerate direction: ").append(inspect_str($1)).c_str());
|
906
961
|
}
|
907
962
|
}
|
908
963
|
%catches(native_exception) each;
|
@@ -910,7 +965,7 @@ struct MatrixUtil {
|
|
910
965
|
void (*each_func)(
|
911
966
|
const T &src, T *dst,
|
912
967
|
const unsigned int &i, const unsigned int &j),
|
913
|
-
const typename MatrixUtil::each_which_t
|
968
|
+
const typename MatrixUtil::each_which_t each_which = MatrixUtil::EACH_ALL) const {
|
914
969
|
MatrixUtil::each(*$self, each_func, each_which);
|
915
970
|
return *$self;
|
916
971
|
}
|
@@ -921,13 +976,37 @@ struct MatrixUtil {
|
|
921
976
|
void (*each_func)(
|
922
977
|
const T &src, T *dst,
|
923
978
|
const unsigned int &i, const unsigned int &j),
|
924
|
-
const typename MatrixUtil::each_which_t
|
979
|
+
const typename MatrixUtil::each_which_t each_which = MatrixUtil::EACH_ALL) const {
|
925
980
|
Matrix<T, Array2D_Dense<T> > res($self->operator Matrix<T, Array2D_Dense<T> >());
|
926
981
|
MatrixUtil::each(*$self, each_func, each_which, &res);
|
927
982
|
return res;
|
928
983
|
}
|
929
984
|
%alias map "collect,map_with_index,collect_with_index";
|
930
985
|
|
986
|
+
%catches(native_exception) index;
|
987
|
+
VALUE index(
|
988
|
+
const typename MatrixUtil::each_which_t each_which = MatrixUtil::EACH_ALL) const {
|
989
|
+
try{
|
990
|
+
MatrixUtil::each(*$self, matrix_yield_check, each_which);
|
991
|
+
return Qnil;
|
992
|
+
}catch(const typename MatrixUtil::each_break_t &each_break){
|
993
|
+
return rb_ary_new_from_args(2, UINT2NUM(each_break.r), UINT2NUM(each_break.c));
|
994
|
+
}
|
995
|
+
}
|
996
|
+
%typemap(check,noblock=1) VALUE idx_selector {
|
997
|
+
if(MatrixUtil::sym2each_which($1) == MatrixUtil::EACH_UNKNOWN){
|
998
|
+
SWIG_exception(SWIG_ValueError,
|
999
|
+
std::string("Unknown enumerate direction: ").append(inspect_str($1)).c_str());
|
1000
|
+
}
|
1001
|
+
}
|
1002
|
+
VALUE index(VALUE value, VALUE idx_selector = Qnil) const {
|
1003
|
+
return rb_block_call(
|
1004
|
+
rb_current_receiver(), rb_frame_callee(),
|
1005
|
+
(RTEST(idx_selector) ? 1 : 0), &idx_selector,
|
1006
|
+
(rb_block_call_func_t)rb_equal, value);
|
1007
|
+
}
|
1008
|
+
%alias index "find_index";
|
1009
|
+
|
931
1010
|
SWIG_Object to_a() const {
|
932
1011
|
unsigned int i_max($self->rows()), j_max($self->columns());
|
933
1012
|
SWIG_Object res = rb_ary_new2(i_max);
|
@@ -1086,7 +1165,7 @@ MAKE_TO_S(Matrix_Frozen)
|
|
1086
1165
|
void (*each_func)(
|
1087
1166
|
const T &src, T *dst,
|
1088
1167
|
const unsigned int &i, const unsigned int &j),
|
1089
|
-
const typename MatrixUtil::each_which_t
|
1168
|
+
const typename MatrixUtil::each_which_t each_which = MatrixUtil::EACH_ALL){
|
1090
1169
|
MatrixUtil::each(*$self, each_func, each_which, $self);
|
1091
1170
|
}
|
1092
1171
|
%rename("map!") map_bang;
|
@@ -1115,6 +1194,14 @@ MAKE_TO_S(Matrix_Frozen)
|
|
1115
1194
|
return MatView_f::partial(*$self, new_rows, new_columns, row_offset, column_offset);
|
1116
1195
|
#else
|
1117
1196
|
return $self->partial(new_rows, new_columns, row_offset, column_offset);
|
1197
|
+
#endif
|
1198
|
+
}
|
1199
|
+
Matrix_Frozen<type, storage, view_to> partial(
|
1200
|
+
const unsigned int &new_rows, const unsigned int &new_columns) const {
|
1201
|
+
#if defined(USE_MATRIX_VIEW_FILTER)
|
1202
|
+
return MatView_f::partial(*$self, new_rows, new_columns, 0, 0);
|
1203
|
+
#else
|
1204
|
+
return $self->partial(new_rows, new_columns, 0, 0);
|
1118
1205
|
#endif
|
1119
1206
|
}
|
1120
1207
|
Matrix_Frozen<type, storage, view_to> row_vector(const unsigned int &row) const {
|
@@ -1132,6 +1219,9 @@ MAKE_TO_S(Matrix_Frozen)
|
|
1132
1219
|
#endif
|
1133
1220
|
}
|
1134
1221
|
};
|
1222
|
+
/* Ruby #row, #column, #row_vectors, #column_vectors are not intentionally implemented
|
1223
|
+
* because a vector is treated as a (1*n) or (n*1) matrix in C++.
|
1224
|
+
*/
|
1135
1225
|
%enddef
|
1136
1226
|
|
1137
1227
|
%define INSTANTIATE_MATRIX_EIGEN2(type, ctype, storage, view)
|
@@ -1152,7 +1242,7 @@ MAKE_TO_S(Matrix_Frozen)
|
|
1152
1242
|
void eigen(
|
1153
1243
|
Matrix<ctype, Array2D_Dense<ctype > > &output_V,
|
1154
1244
|
Matrix<ctype, Array2D_Dense<ctype > > &output_D) const {
|
1155
|
-
typedef
|
1245
|
+
typedef Matrix<ctype, Array2D_Dense<ctype > > cmat_t;
|
1156
1246
|
cmat_t VD($self->eigen());
|
1157
1247
|
output_V = VD.partial($self->rows(), $self->rows()).copy();
|
1158
1248
|
cmat_t D($self->rows(), $self->rows());
|
@@ -1308,6 +1398,19 @@ INSTANTIATE_MATRIX_EIGEN(double, Complex<double>);
|
|
1308
1398
|
INSTANTIATE_MATRIX(Complex<double>, ComplexD);
|
1309
1399
|
INSTANTIATE_MATRIX_EIGEN(Complex<double>, Complex<double>);
|
1310
1400
|
|
1401
|
+
%rename("tolerance=") set_tolerance;
|
1402
|
+
%rename("tolerance") get_tolerance;
|
1403
|
+
%inline %{
|
1404
|
+
double set_tolerance(const double &width){
|
1405
|
+
MatrixValue<double>::zero = width;
|
1406
|
+
MatrixValue<Complex<double> >::zero = width;
|
1407
|
+
return width;
|
1408
|
+
}
|
1409
|
+
double get_tolerance(){
|
1410
|
+
return set_tolerance(MatrixValue<double>::zero.width);
|
1411
|
+
}
|
1412
|
+
%}
|
1413
|
+
|
1311
1414
|
#undef INSTANTIATE_MATRIX_FUNC
|
1312
1415
|
#undef INSTANTIATE_MATRIX_TRANSPOSE
|
1313
1416
|
#undef INSTANTIATE_MATRIX_PARTIAL
|
@@ -6,6 +6,8 @@ require 'SylphideMath.so'
|
|
6
6
|
require 'matrix'
|
7
7
|
|
8
8
|
shared_examples 'Matrix' do
|
9
|
+
let!(:tolerance){SylphideMath::tolerance}
|
10
|
+
after{SylphideMath::tolerance = tolerance}
|
9
11
|
let(:params){{
|
10
12
|
:rc => [8, 8],
|
11
13
|
:acceptable_delta => 1E-10,
|
@@ -92,17 +94,25 @@ shared_examples 'Matrix' do
|
|
92
94
|
end
|
93
95
|
|
94
96
|
describe 'property' do
|
95
|
-
let(:
|
96
|
-
:square => proc{
|
97
|
+
let(:mat_gen){{
|
98
|
+
:square => proc{|r| # example: [[1, 3, 6], [2, 5, 8], [4, 7, 9]]
|
97
99
|
k = 0
|
98
|
-
mat_type::new(
|
99
|
-
|
100
|
+
res = mat_type::new(r, r)
|
101
|
+
(r * 2 - 1).times{|ij|
|
102
|
+
(([ij - r + 1, 0].max)..([ij, r - 1].min)).each{|i| res[ij - i, i] = (k += 1)}
|
103
|
+
}
|
104
|
+
res
|
105
|
+
}
|
106
|
+
}}
|
107
|
+
let(:mat){{
|
108
|
+
:square => mat_gen[:square].call(params[:rc][0]),
|
100
109
|
:not_square => proc{
|
101
110
|
k = 0
|
102
111
|
mat_type::new(params[:rc][0], params[:rc][0] * 2){|i, j| k += 1}
|
103
112
|
}.call,
|
104
113
|
:diagonal => mat_type::new(params[:rc][0], params[:rc][0]){|i, j| i == j ? 1 : 0},
|
105
114
|
:symmetric => mat_type::new(params[:rc][0], params[:rc][0]){|i, j| i + j},
|
115
|
+
:unit => mat_type::I(params[:rc][0]),
|
106
116
|
}}
|
107
117
|
describe 'is checked with' do
|
108
118
|
it 'square?' do
|
@@ -117,12 +127,52 @@ shared_examples 'Matrix' do
|
|
117
127
|
expect(mat[:diagonal].diagonal?) .to eq(true)
|
118
128
|
expect(mat[:symmetric].diagonal?) .to eq(false)
|
119
129
|
end
|
130
|
+
it 'lower_triangular?' do
|
131
|
+
expect(mat[:square].lower_triangular?) .to eq(false)
|
132
|
+
expect(mat[:not_square].lower_triangular?) .to eq(false)
|
133
|
+
expect(mat[:diagonal].lower_triangular?) .to eq(true)
|
134
|
+
expect(mat[:symmetric].lower_triangular?) .to eq(false)
|
135
|
+
end
|
136
|
+
it 'upper_triangular?' do
|
137
|
+
expect(mat[:square].upper_triangular?) .to eq(false)
|
138
|
+
expect(mat[:not_square].upper_triangular?) .to eq(false)
|
139
|
+
expect(mat[:diagonal].upper_triangular?) .to eq(true)
|
140
|
+
expect(mat[:symmetric].upper_triangular?) .to eq(false)
|
141
|
+
end
|
120
142
|
it 'symmetric?' do
|
121
143
|
expect(mat[:square].symmetric?) .to eq(false)
|
122
144
|
expect(mat[:not_square].symmetric?) .to eq(false)
|
123
145
|
expect(mat[:diagonal].symmetric?) .to eq(true)
|
124
146
|
expect(mat[:symmetric].symmetric?) .to eq(true)
|
125
147
|
end
|
148
|
+
it 'hermitian?' do
|
149
|
+
expect(mat[:square].hermitian?) .to eq(false)
|
150
|
+
expect(mat[:not_square].hermitian?) .to eq(false)
|
151
|
+
expect(mat[:diagonal].hermitian?) .to eq(true)
|
152
|
+
expect(mat[:symmetric].hermitian?) .to eq(true)
|
153
|
+
end
|
154
|
+
it 'skew_symmetric?' do
|
155
|
+
expect(mat[:square].skew_symmetric?) .to eq(false)
|
156
|
+
expect(mat[:not_square].skew_symmetric?) .to eq(false)
|
157
|
+
expect(mat[:diagonal].skew_symmetric?) .to eq(true)
|
158
|
+
expect(mat[:symmetric].skew_symmetric?) .to eq(false)
|
159
|
+
end
|
160
|
+
it 'normal?' do
|
161
|
+
expect(mat[:square].normal?) .to eq(false)
|
162
|
+
expect(mat[:not_square].normal?) .to eq(false)
|
163
|
+
expect(mat[:diagonal].normal?) .to eq(true)
|
164
|
+
expect(mat[:symmetric].normal?) .to eq(true)
|
165
|
+
end
|
166
|
+
it 'orthogonal?' do
|
167
|
+
expect(mat[:square].orthogonal?) .to eq(false)
|
168
|
+
expect(mat[:not_square].orthogonal?).to eq(false)
|
169
|
+
expect(mat[:unit].orthogonal?) .to eq(true)
|
170
|
+
end
|
171
|
+
it 'unitary?' do
|
172
|
+
expect(mat[:square].unitary?) .to eq(false)
|
173
|
+
expect(mat[:not_square].unitary?) .to eq(false)
|
174
|
+
expect(mat[:unit].unitary?) .to eq(true)
|
175
|
+
end
|
126
176
|
it 'different_size?' do
|
127
177
|
mat.keys.combination(2).each{|mat1, mat2|
|
128
178
|
expect(mat[mat1].different_size?(mat[mat2])).to eq([mat1, mat2].include?(:not_square))
|
@@ -142,10 +192,40 @@ shared_examples 'Matrix' do
|
|
142
192
|
end
|
143
193
|
it 'determinant, det' do
|
144
194
|
[:determinant, :det].each{|f|
|
145
|
-
|
195
|
+
expect(mat[:square].send(f)).to eq(Matrix[*mat[:square].to_a].det)
|
146
196
|
expect{mat[:not_square].send(f)}.to raise_error(RuntimeError)
|
147
197
|
}
|
148
198
|
end
|
199
|
+
it 'rank' do
|
200
|
+
(5..8).each{|n|
|
201
|
+
orig = mat_gen[:square].call(n)
|
202
|
+
expect(orig.rank).to eq(Matrix[*orig.to_a].rank)
|
203
|
+
}
|
204
|
+
expect(mat[:symmetric].rank).to eq(Matrix[*mat[:symmetric].to_a].rank)
|
205
|
+
expect{mat[:not_square].rank}.to raise_error(RuntimeError)
|
206
|
+
end
|
207
|
+
it 'cofactor' do
|
208
|
+
SylphideMath::tolerance = 1E-10
|
209
|
+
(5..8).each{|n|
|
210
|
+
orig = mat_gen[:square].call(n)
|
211
|
+
cmp = Matrix[*orig.to_a]
|
212
|
+
orig.rows.times{|i|
|
213
|
+
orig.columns.times{|j|
|
214
|
+
a, b = [orig, cmp].collect{|item| item.cofactor(i, j)} #rescue next
|
215
|
+
expect((a - b).abs).to be < params[:acceptable_delta]
|
216
|
+
}
|
217
|
+
}
|
218
|
+
}
|
219
|
+
end
|
220
|
+
it 'adjugate' do
|
221
|
+
SylphideMath::tolerance = 1E-10
|
222
|
+
(5..8).each{|n|
|
223
|
+
orig = mat_gen[:square].call(n)
|
224
|
+
(Matrix[*orig.adjugate.to_a] - Matrix[*orig.to_a].adjugate).each{|v|
|
225
|
+
expect(v.abs).to be < params[:acceptable_delta]
|
226
|
+
}
|
227
|
+
}
|
228
|
+
end
|
149
229
|
end
|
150
230
|
end
|
151
231
|
|
@@ -257,6 +337,8 @@ shared_examples 'Matrix' do
|
|
257
337
|
expect(mat.adjoint.to_a).to eq(Matrix[*compare_with].conj.t.to_a)
|
258
338
|
end
|
259
339
|
it 'supports submatrix with partial' do
|
340
|
+
expect(mat.partial(params[:rc][0] - 1, params[:rc][1] - 1).to_a) \
|
341
|
+
.to eq(Matrix[*compare_with[0..-2].collect{|values| values[0..-2]}].to_a)
|
260
342
|
expect(mat.partial(params[:rc][0] - 1, params[:rc][1] - 1, 1, 1).to_a) \
|
261
343
|
.to eq(Matrix[*compare_with[1..-1].collect{|values| values[1..-1]}].to_a)
|
262
344
|
end
|
@@ -280,6 +362,14 @@ shared_examples 'Matrix' do
|
|
280
362
|
}
|
281
363
|
}
|
282
364
|
end
|
365
|
+
it 'generates minor matrix with first_minor' do
|
366
|
+
params[:rc][0].times{|i|
|
367
|
+
params[:rc][1].times{|j|
|
368
|
+
expect(mat.first_minor(i, j).to_a) \
|
369
|
+
.to eq(Matrix[*compare_with].first_minor(i, j).to_a)
|
370
|
+
}
|
371
|
+
}
|
372
|
+
end
|
283
373
|
end
|
284
374
|
|
285
375
|
describe 'iterator' do
|
@@ -310,6 +400,19 @@ shared_examples 'Matrix' do
|
|
310
400
|
}
|
311
401
|
}
|
312
402
|
end
|
403
|
+
it 'supports index, find_index' do
|
404
|
+
cnd = proc{|v| v.abs >= 0.5}
|
405
|
+
[:index, :find_index].each{|func|
|
406
|
+
opt.each{|k, indices|
|
407
|
+
expect(mat.send(*[func, k].compact, &cnd)).to eq(
|
408
|
+
indices.select{|i, j| cnd.call(compare_with[i][j])}.first)
|
409
|
+
indices.each{|i, j|
|
410
|
+
expect(mat.send(*[func, compare_with[i][j], k].compact)).to eq([i, j])
|
411
|
+
}
|
412
|
+
expect(mat.send(*[func, 1, k].compact)).to be(nil)
|
413
|
+
}
|
414
|
+
}
|
415
|
+
end
|
313
416
|
it 'supports map, collect, map_with_index, collect_with_index' do
|
314
417
|
[:map, :collect, :map_with_index, :collect_with_index].each{|func|
|
315
418
|
opt.each{|k, indices|
|
@@ -398,6 +501,13 @@ shared_examples 'Matrix' do
|
|
398
501
|
expect{mat[2] * mat[3]}.to raise_error(ArgumentError)
|
399
502
|
expect((mat[2] * mat[3].t).to_a).to eq((Matrix[*compare_with[2]] * Matrix[*compare_with[3]].t).to_a)
|
400
503
|
end
|
504
|
+
it 'have entrywise_product(mat), a.k.a. .*(mat)' do
|
505
|
+
[:entrywise_product, :hadamard_product].each{|func|
|
506
|
+
[[0, 1], [2, 3]].each{|i, j|
|
507
|
+
expect((mat[i].send(func, mat[j])).to_a).to eq((Matrix[*compare_with[i]].send(func, Matrix[*compare_with[j]])).to_a)
|
508
|
+
}
|
509
|
+
} if Gem::Version::create(RUBY_VERSION) >= Gem::Version::create("2.5.0")
|
510
|
+
end
|
401
511
|
it 'have /(scalar)' do
|
402
512
|
expect((mat[0] / 2).to_a).to eq((Matrix[*compare_with[0]] / 2).to_a)
|
403
513
|
expect((mat[2] / 2).to_a).to eq((Matrix[*compare_with[2]] / 2).to_a)
|
data/gps_pvt.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
17
17
|
|
18
18
|
spec.metadata["homepage_uri"] = spec.homepage
|
19
19
|
spec.metadata["source_code_uri"] = spec.homepage
|
20
|
-
#spec.metadata["changelog_uri"] = "
|
20
|
+
#spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/-/CHANGELOG.md"
|
21
21
|
|
22
22
|
spec.extensions = ["ext/gps_pvt/extconf.rb"]
|
23
23
|
|
@@ -63,6 +63,8 @@ Gem::Specification.new do |spec|
|
|
63
63
|
spec.add_development_dependency "rake-compiler"
|
64
64
|
spec.add_development_dependency "rspec", "~> 3.0"
|
65
65
|
spec.add_development_dependency "matrix" if GPS_PVT::version_compare(RUBY_VERSION, "3.1") >= 0
|
66
|
+
spec.add_development_dependency "racc"
|
67
|
+
spec.add_development_dependency "github_changelog_generator" unless ((Gem::Platform.local.os =~ /mingw/) && (GPS_PVT::version_compare(RUBY_VERSION, "3.1") >= 0))
|
66
68
|
|
67
69
|
# For more information and examples about making a new gem, checkout our
|
68
70
|
# guide at: https://bundler.io/guides/creating_gem.html
|