gps_pvt 0.9.3 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|