gps_pvt 0.9.2 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -31,9 +31,17 @@
31
31
  %include std_string.i
32
32
  //%include std_vector.i
33
33
  %include exception.i
34
+ %include std_except.i
34
35
 
36
+ %ignore native_exception;
35
37
  #if !defined(SWIGIMPORTED)
36
- %header {
38
+ %exceptionclass native_exception;
39
+ %typemap(throws,noblock=1) native_exception {
40
+ $1.regenerate();
41
+ SWIG_fail;
42
+ }
43
+ %ignore native_exception;
44
+ %inline {
37
45
  struct native_exception : public std::exception {
38
46
  #if defined(SWIGRUBY)
39
47
  int state;
@@ -44,16 +52,6 @@ struct native_exception : public std::exception {
44
52
  #endif
45
53
  };
46
54
  }
47
- %exception {
48
- try {
49
- $action
50
- } catch (const native_exception &e) {
51
- e.regenerate();
52
- SWIG_fail;
53
- } catch (const std::exception& e) {
54
- SWIG_exception_fail(SWIG_RuntimeError, e.what());
55
- }
56
- }
57
55
  #endif
58
56
 
59
57
  %define MAKE_ACCESSOR(name, type)
@@ -125,16 +123,16 @@ class Complex;
125
123
  typedef Complex<T> value_type;
126
124
  static int asval(VALUE obj, value_type *v) {
127
125
  if(RB_TYPE_P(obj, T_COMPLEX)){
128
- #if RUBY_API_VERSION_CODE < 20600
126
+ %#if RUBY_API_VERSION_CODE < 20600
129
127
  static const ID id_r(rb_intern("real")), id_i(rb_intern("imag"));
130
128
  int res = swig::asval(rb_funcall(obj, id_r, 0), &(v->real()));
131
129
  if(!SWIG_IsOK(res)){return res;}
132
130
  return swig::asval(rb_funcall(obj, id_i, 0), &(v->imaginary()));
133
- #else
131
+ %#else
134
132
  int res = swig::asval(rb_complex_real(obj), &(v->real()));
135
133
  if(!SWIG_IsOK(res)){return res;}
136
134
  return swig::asval(rb_complex_imag(obj), &(v->imaginary()));
137
- #endif
135
+ %#endif
138
136
  }else{
139
137
  v->imaginary() = T(0);
140
138
  return swig::asval(obj, &(v->real()));
@@ -150,14 +148,14 @@ class Complex;
150
148
  template <class T> struct traits_check< Complex<T>, value_category> {
151
149
  static bool check(VALUE obj) {
152
150
  if(RB_TYPE_P(obj, T_COMPLEX)){
153
- #if RUBY_API_VERSION_CODE < 20600
151
+ %#if RUBY_API_VERSION_CODE < 20600
154
152
  static const ID id_r(rb_intern("real")), id_i(rb_intern("imag"));
155
153
  return swig::check<T>(rb_funcall(obj, id_r, 0))
156
154
  && swig::check<T>(rb_funcall(obj, id_i, 0));
157
- #else
155
+ %#else
158
156
  return swig::check<T>(rb_complex_real(obj))
159
157
  && swig::check<T>(rb_complex_imag(obj));
160
- #endif
158
+ %#endif
161
159
  }else{
162
160
  return swig::check<T>(obj);
163
161
  }
@@ -347,12 +345,6 @@ struct MatrixViewFilter : public BaseView {
347
345
  res.view().partial(new_rows, new_columns, row_offset, column_offset);
348
346
  return res;
349
347
  }
350
- template <class T, class Array2D_Type, class ViewType>
351
- static Matrix_Frozen<T, Array2D_Type, self_t> partial(
352
- const Matrix_Frozen<T, Array2D_Type, ViewType> &orig,
353
- const unsigned int &new_rows, const unsigned int &new_columns) {
354
- return partial(orig, new_rows, new_columns, 0, 0);
355
- }
356
348
 
357
349
  template<class CharT, class Traits>
358
350
  friend std::basic_ostream<CharT, Traits> &operator<<(
@@ -414,17 +406,27 @@ class Matrix_Frozen {
414
406
  template <class T2, class Array2D_Type2, class ViewType2>
415
407
  bool operator==(const Matrix_Frozen<T2, Array2D_Type2, ViewType2> &matrix) const noexcept;
416
408
  // bool operator!= // automatically defined
417
-
409
+
418
410
  bool isSquare() const noexcept;
419
411
  bool isDiagonal() const noexcept;
412
+ bool isLowerTriangular() const noexcept;
413
+ bool isUpperTriangular() const noexcept;
420
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;
421
420
 
422
- T trace(const bool &do_check = true) const;
421
+ T trace() const;
423
422
  T sum() const noexcept;
424
423
 
425
424
  // bool isLU() const noexcept
426
425
 
427
- T determinant(const bool &do_check = true) const;
426
+ T determinant() const;
427
+ unsigned int rank() const;
428
+ T cofactor(
429
+ const unsigned int &row, const unsigned int &column) const;
428
430
  };
429
431
 
430
432
  template <class T, class Array2D_Type, class ViewType = MatrixViewBase<> >
@@ -472,6 +474,11 @@ typedef MatrixViewTranspose<MatrixViewSizeVariable<MatrixViewOffset<MatrixViewBa
472
474
 
473
475
  %{
474
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
+ };
475
482
  enum each_which_t {
476
483
  EACH_ALL,
477
484
  EACH_DIAGONAL,
@@ -480,6 +487,7 @@ struct MatrixUtil {
480
487
  EACH_UPPER,
481
488
  EACH_STRICT_LOWER,
482
489
  EACH_STRICT_UPPER,
490
+ EACH_UNKNOWN,
483
491
  };
484
492
  template <class T,
485
493
  class Array2D_Type, class ViewType,
@@ -490,7 +498,7 @@ struct MatrixUtil {
490
498
  const T &src_elm, T *dst_elm,
491
499
  const unsigned int &i, const unsigned int &j),
492
500
  const each_which_t &each_which = EACH_ALL,
493
- Matrix<T, Array2D_Type2, ViewType2> *dst = NULL){
501
+ Matrix<T, Array2D_Type2, ViewType2> *dst = NULL) {
494
502
  unsigned int i_max(src.rows()), j_max(src.columns());
495
503
  switch(each_which){
496
504
  case EACH_DIAGONAL:
@@ -546,10 +554,8 @@ struct MatrixUtil {
546
554
  }
547
555
  }
548
556
  #if defined(SWIGRUBY)
549
- static const each_which_t &sym2each_which(const VALUE &value){
550
- if(!RB_TYPE_P(value, T_SYMBOL)){
551
- std::runtime_error("Symbol is required");
552
- }
557
+ static each_which_t sym2each_which(const VALUE &value){
558
+ if(!RB_TYPE_P(value, T_SYMBOL)){return EACH_UNKNOWN;}
553
559
  static const struct {
554
560
  VALUE sym;
555
561
  each_which_t which;
@@ -566,9 +572,7 @@ struct MatrixUtil {
566
572
  while(value != cmp[i].sym){
567
573
  if(++i >= (sizeof(cmp) / sizeof(cmp[0]))){break;}
568
574
  }
569
- if(i >= (sizeof(cmp) / sizeof(cmp[0]))){
570
- std::runtime_error("Unknown enumerate direction");
571
- }
575
+ if(i >= (sizeof(cmp) / sizeof(cmp[0]))){return EACH_UNKNOWN;}
572
576
  return cmp[i].which;
573
577
  }
574
578
  #endif
@@ -602,16 +606,16 @@ struct MatrixUtil {
602
606
  if(value && RB_TYPE_P(*value, T_ARRAY)){
603
607
  if(RB_TYPE_P(RARRAY_AREF(*value, 0), T_ARRAY)){ // [[r0c0, r0c1, ...], ...]
604
608
  if((unsigned int)RARRAY_LEN(*value) < r){
605
- throw std::runtime_error("Length is too short");
609
+ throw std::invalid_argument("Length is too short");
606
610
  }
607
611
  VALUE value_r;
608
612
  for(; i_elm < len; i_elm++){
609
613
  if(j == 0){
610
614
  value_r = RARRAY_AREF(*value, i);
611
615
  if(!RB_TYPE_P(value_r, T_ARRAY)){
612
- throw std::runtime_error("double array [[...], ...] is required");
616
+ throw std::invalid_argument("double array [[...], ...] is required");
613
617
  }else if((unsigned int)RARRAY_LEN(value_r) < c){
614
- throw std::runtime_error("Length is too short");
618
+ throw std::invalid_argument("Length is too short");
615
619
  }
616
620
  }
617
621
  v_elm = RARRAY_AREF(value_r, j);
@@ -620,7 +624,7 @@ struct MatrixUtil {
620
624
  }
621
625
  }else{ // [r0c0, r0c1, ...]
622
626
  if((unsigned int)RARRAY_LEN(*value) < len){
623
- throw std::runtime_error("Length is too short");
627
+ throw std::invalid_argument("Length is too short");
624
628
  }
625
629
  for(; i_elm < len; i_elm++){
626
630
  v_elm = RARRAY_AREF(*value, i_elm);
@@ -647,7 +651,7 @@ struct MatrixUtil {
647
651
  if(replaced && (i_elm < len)){
648
652
  std::stringstream s;
649
653
  s << "Unexpected input [" << i << "," << j << "]: ";
650
- throw std::runtime_error(s.str().append(inspect_str(v_elm)));
654
+ throw std::invalid_argument(s.str().append(inspect_str(v_elm)));
651
655
  }
652
656
  #endif
653
657
  return replaced;
@@ -668,6 +672,14 @@ struct MatrixUtil {
668
672
  %}
669
673
 
670
674
  %extend Matrix_Frozen {
675
+ %catches(std::logic_error) trace;
676
+ %catches(std::out_of_range) partial;
677
+ %catches(std::out_of_range) rowVector;
678
+ %catches(std::out_of_range) columnVector;
679
+ %catches(std::logic_error, std::runtime_error) determinant;
680
+ %catches(std::logic_error) rank;
681
+ %catches(std::logic_error, std::runtime_error) cofactor;
682
+
671
683
  T __getitem__(const unsigned int &row, const unsigned int &column) const {
672
684
  return ($self)->operator()(row, column);
673
685
  }
@@ -705,6 +717,7 @@ struct MatrixUtil {
705
717
  return (Matrix<T, Array2D_Dense<T> >)(($self)->operator-());
706
718
  }
707
719
 
720
+ %catches(std::invalid_argument) operator+;
708
721
  template <class T2, class Array2D_Type2, class ViewType2>
709
722
  Matrix<T, Array2D_Dense<T> > operator+(
710
723
  const Matrix_Frozen<T2, Array2D_Type2, ViewType2> &matrix) const {
@@ -715,6 +728,7 @@ struct MatrixUtil {
715
728
  return (Matrix<T, Array2D_Dense<T> >)(($self)->operator+(scalar));
716
729
  }
717
730
 
731
+ %catches(std::invalid_argument) operator-;
718
732
  template <class T2, class Array2D_Type2, class ViewType2>
719
733
  Matrix<T, Array2D_Dense<T> > operator-(
720
734
  const Matrix_Frozen<T2, Array2D_Type2, ViewType2> &matrix) const {
@@ -725,12 +739,36 @@ struct MatrixUtil {
725
739
  return (Matrix<T, Array2D_Dense<T> >)(($self)->operator-(scalar));
726
740
  }
727
741
 
742
+ #ifdef SWIGRUBY
743
+ %alias entrywise_product "hadamard_product";
744
+ #endif
745
+ %catches(std::invalid_argument) entrywise_product;
728
746
  template <class T2, class Array2D_Type2, class ViewType2>
729
- Matrix<T, Array2D_Dense<T> > operator*(
747
+ Matrix<T, Array2D_Dense<T> > entrywise_product(
730
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
+
753
+ template <class T2, class Array2D_Type2, class ViewType2>
754
+ Matrix<T, Array2D_Dense<T> > operator*(
755
+ const Matrix_Frozen<T2, Array2D_Type2, ViewType2> &matrix)
756
+ const throw(std::invalid_argument) {
731
757
  return (Matrix<T, Array2D_Dense<T> >)(($self)->operator*(matrix));
732
758
  }
733
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
+ }
734
772
 
735
773
  %typemap(in,numinputs=0)
736
774
  Matrix<T, Array2D_Dense<T> > &output_L (Matrix<T, Array2D_Dense<T> > temp),
@@ -750,6 +788,7 @@ struct MatrixUtil {
750
788
  Matrix<T, Array2D_Dense<T> > &output_R {
751
789
  %append_output(SWIG_NewPointerObj((new $*1_ltype(*$1)), $1_descriptor, SWIG_POINTER_OWN));
752
790
  }
791
+ %catches(std::logic_error, std::runtime_error) lup;
753
792
  void lup(
754
793
  Matrix<T, Array2D_Dense<T> > &output_L,
755
794
  Matrix<T, Array2D_Dense<T> > &output_U,
@@ -775,6 +814,7 @@ struct MatrixUtil {
775
814
  output_U = LU.partial($self->rows(), $self->columns(), 0, $self->rows()).copy();
776
815
  output_P = buf.P();
777
816
  }
817
+ %catches(std::logic_error) ud;
778
818
  void ud(
779
819
  Matrix<T, Array2D_Dense<T> > &output_U,
780
820
  Matrix<T, Array2D_Dense<T> > &output_D) const {
@@ -790,12 +830,14 @@ struct MatrixUtil {
790
830
  output_R = QR.partial($self->rows(), $self->columns(), 0, $self->rows()).copy();
791
831
  }
792
832
 
833
+ %catches(std::logic_error, std::runtime_error) inverse;
793
834
  Matrix<T, Array2D_Dense<T> > inverse() const {
794
835
  return (Matrix<T, Array2D_Dense<T> >)(($self)->inverse());
795
836
  }
796
837
  template <class T2, class Array2D_Type2, class ViewType2>
797
838
  Matrix<T, Array2D_Dense<T> > operator/(
798
- const Matrix_Frozen<T2, Array2D_Type2, ViewType2> &matrix) const {
839
+ const Matrix_Frozen<T2, Array2D_Type2, ViewType2> &matrix)
840
+ const throw(std::logic_error, std::runtime_error) {
799
841
  return (Matrix<T, Array2D_Dense<T> >)(($self)->operator/(matrix));
800
842
  }
801
843
  INSTANTIATE_MATRIX_FUNC(operator/, __div__);
@@ -805,16 +847,33 @@ struct MatrixUtil {
805
847
  s << $self->inspect();
806
848
  return s.str();
807
849
  }
850
+
851
+ /* The followings are better to be implemented in Ruby
852
+ * combine, hstack, vstack (due to their arguments are variable)
853
+ */
808
854
 
809
855
  #ifdef SWIGRUBY
810
856
  %rename("square?") isSquare;
811
857
  %rename("diagonal?") isDiagonal;
858
+ %rename("lower_triangular?") isLowerTriangular;
859
+ %rename("upper_triangular?") isUpperTriangular;
812
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;
813
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";
814
872
  %alias trace "tr";
815
873
  %alias determinant "det";
816
874
  %alias inverse "inv";
817
875
  %alias transpose "t";
876
+ %alias conjugate "conj";
818
877
  %alias lup "lup_decomposition";
819
878
  %alias ud "ud_decomposition";
820
879
  %alias qr "qr_decomposition";
@@ -822,7 +881,7 @@ struct MatrixUtil {
822
881
  %fragment(SWIG_From_frag(Matrix_Frozen_Helper<T>), "header",
823
882
  fragment=SWIG_Traits_frag(T)){
824
883
  template <bool with_index = false, bool assign = false>
825
- static inline void matrix_yield_internal(
884
+ static inline VALUE matrix_yield_internal(
826
885
  const T &src, T *dst, const unsigned int &i, const unsigned int &j){
827
886
  SWIG_Object v;
828
887
  if(with_index){
@@ -835,8 +894,9 @@ struct MatrixUtil {
835
894
  if(assign && !SWIG_IsOK(swig::asval(v, dst))){
836
895
  std::stringstream s;
837
896
  s << "Unknown input (T expected) [" << i << "," << j << "]: ";
838
- throw std::runtime_error(s.str().append(inspect_str(v)));
897
+ throw std::invalid_argument(s.str().append(inspect_str(v)));
839
898
  }
899
+ return v;
840
900
  }
841
901
  static void matrix_yield(
842
902
  const T &src, T *dst, const unsigned int &i, const unsigned int &j){
@@ -854,11 +914,17 @@ struct MatrixUtil {
854
914
  const T &src, T *dst, const unsigned int &i, const unsigned int &j){
855
915
  matrix_yield_internal<true, true>(src, dst, i, j);
856
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
+ }
857
923
  static void (*matrix_each(const T *))
858
924
  (const T &, T *, const unsigned int &, const unsigned int &) {
859
925
  ID id_thisf(rb_frame_this_func()), id_callee(rb_frame_callee());
860
926
  static const ID
861
- id_map(rb_intern("map")), id_mapb(rb_intern("map!")),
927
+ id_map(rb_intern("map")), id_mapb(rb_intern("map!")),
862
928
  id_eachwi(rb_intern("each_with_index"));
863
929
  if((id_thisf == id_map) || (id_thisf == id_mapb)){
864
930
  static const ID with_index[] = {
@@ -884,37 +950,63 @@ struct MatrixUtil {
884
950
  }
885
951
  $1 = matrix_each((const T *)0);
886
952
  }
887
- %typemap(typecheck) const typename MatrixUtil::each_which_t &each_which {
888
- $1 = RB_TYPE_P($input, T_SYMBOL);
953
+ %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER) const typename MatrixUtil::each_which_t each_which {
954
+ $1 = (MatrixUtil::sym2each_which($input) != MatrixUtil::EACH_UNKNOWN);
889
955
  }
890
- %typemap(in) const typename MatrixUtil::each_which_t &each_which {
891
- try{
892
- $1 = &const_cast<typename MatrixUtil::each_which_t &>(MatrixUtil::sym2each_which($input));
893
- }catch(std::runtime_error &e){
894
- SWIG_exception(SWIG_TypeError, e.what());
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());
895
961
  }
896
962
  }
963
+ %catches(native_exception) each;
897
964
  const Matrix_Frozen<T, Array2D_Type, ViewType> &each(
898
965
  void (*each_func)(
899
966
  const T &src, T *dst,
900
967
  const unsigned int &i, const unsigned int &j),
901
- const typename MatrixUtil::each_which_t &each_which = MatrixUtil::EACH_ALL) const {
968
+ const typename MatrixUtil::each_which_t each_which = MatrixUtil::EACH_ALL) const {
902
969
  MatrixUtil::each(*$self, each_func, each_which);
903
970
  return *$self;
904
971
  }
905
972
  %alias each "each_with_index";
906
973
 
974
+ %catches(native_exception, std::invalid_argument) map;
907
975
  Matrix<T, Array2D_Dense<T> > map(
908
976
  void (*each_func)(
909
977
  const T &src, T *dst,
910
978
  const unsigned int &i, const unsigned int &j),
911
- const typename MatrixUtil::each_which_t &each_which = MatrixUtil::EACH_ALL) const {
979
+ const typename MatrixUtil::each_which_t each_which = MatrixUtil::EACH_ALL) const {
912
980
  Matrix<T, Array2D_Dense<T> > res($self->operator Matrix<T, Array2D_Dense<T> >());
913
981
  MatrixUtil::each(*$self, each_func, each_which, &res);
914
982
  return res;
915
983
  }
916
984
  %alias map "collect,map_with_index,collect_with_index";
917
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
+
918
1010
  SWIG_Object to_a() const {
919
1011
  unsigned int i_max($self->rows()), j_max($self->columns());
920
1012
  SWIG_Object res = rb_ary_new2(i_max);
@@ -950,7 +1042,8 @@ MAKE_TO_S(Matrix_Frozen)
950
1042
  %fragment(SWIG_Traits_frag(T));
951
1043
 
952
1044
  Matrix(const unsigned int &rows, const unsigned int &columns,
953
- const void *replacer = NULL){
1045
+ const void *replacer = NULL)
1046
+ throw(native_exception, std::invalid_argument) {
954
1047
  Matrix<T, Array2D_Type, ViewType> res(rows, columns);
955
1048
  MatrixUtil::replace(res, replacer);
956
1049
  return new Matrix<T, Array2D_Type, ViewType>(res);
@@ -964,7 +1057,7 @@ MAKE_TO_S(Matrix_Frozen)
964
1057
  #if defined(SWIGRUBY)
965
1058
  %fragment(SWIG_AsVal_frag(unsigned int));
966
1059
  %fragment("check_value"{unsigned int});
967
- Matrix(const void *replacer){
1060
+ Matrix(const void *replacer) throw(native_exception, std::invalid_argument) {
968
1061
  const SWIG_Object *value(static_cast<const SWIG_Object *>(replacer));
969
1062
  static const ID id_r(rb_intern("row_size")), id_c(rb_intern("column_size"));
970
1063
  if(value && RB_TYPE_P(*value, T_ARRAY) && RB_TYPE_P(RARRAY_AREF(*value, 0), T_ARRAY)){
@@ -978,8 +1071,8 @@ MAKE_TO_S(Matrix_Frozen)
978
1071
  VALUE v_r(rb_funcall(*value, id_r, 0, 0)), v_c(rb_funcall(*value, id_c, 0, 0));
979
1072
  if(!SWIG_IsOK(SWIG_AsVal(unsigned int)(v_r, &r)) || is_lt_zero_after_asval(r)
980
1073
  || !SWIG_IsOK(SWIG_AsVal(unsigned int)(v_c, &c)) || is_lt_zero_after_asval(c)){
981
- throw std::runtime_error(
982
- std::string("Unexpected length [")
1074
+ throw std::invalid_argument(
1075
+ std::string("Invalid length [")
983
1076
  .append(inspect_str(v_r)).append(", ")
984
1077
  .append(inspect_str(v_c)).append("]"));
985
1078
  }
@@ -987,7 +1080,7 @@ MAKE_TO_S(Matrix_Frozen)
987
1080
  MatrixUtil::replace(res, replacer);
988
1081
  return new Matrix<T, Array2D_Type, ViewType>(res);
989
1082
  }else{
990
- throw std::runtime_error("double array [[...], ...] or Matrix is required");
1083
+ throw std::invalid_argument("double array [[...], ...] or Matrix is required");
991
1084
  }
992
1085
  }
993
1086
  #endif
@@ -1026,11 +1119,13 @@ MAKE_TO_S(Matrix_Frozen)
1026
1119
  %rename("scalar") getScalar;
1027
1120
  %rename("I") getI;
1028
1121
 
1122
+ %catches(std::out_of_range) swap_rows;
1029
1123
  void swap_rows(
1030
1124
  self_t *self_p,
1031
1125
  const unsigned int &r1, const unsigned int &r2){
1032
1126
  $self->swapRows(r1, r2);
1033
1127
  }
1128
+ %catches(std::out_of_range) swap_columns;
1034
1129
  void swap_columns(
1035
1130
  self_t *self_p,
1036
1131
  const unsigned int &c1, const unsigned int &c2){
@@ -1040,18 +1135,20 @@ MAKE_TO_S(Matrix_Frozen)
1040
1135
  template <class T2, class Array2D_Type2, class ViewType2>
1041
1136
  void replace(
1042
1137
  self_t *self_p,
1043
- const Matrix_Frozen<T2, Array2D_Type2, ViewType2> &matrix){
1138
+ const Matrix_Frozen<T2, Array2D_Type2, ViewType2> &matrix)
1139
+ throw(std::invalid_argument) {
1044
1140
  $self->replace(matrix);
1045
1141
  }
1046
1142
  INSTANTIATE_MATRIX_FUNC(replace, replace);
1047
1143
 
1048
- void replace(self_t *self_p, const void *replacer = NULL){
1144
+ void replace(self_t *self_p, const void *replacer = NULL)
1145
+ throw(native_exception, std::invalid_argument, std::runtime_error){
1049
1146
  if(!MatrixUtil::replace(*$self, replacer)){
1050
1147
  throw std::runtime_error("Unsupported replacement");
1051
1148
  }
1052
1149
  }
1053
1150
 
1054
- void replace(self_t *self_p, const T *serialized){
1151
+ void replace(self_t *self_p, const T *serialized) throw(std::runtime_error) {
1055
1152
  if(!MatrixUtil::replace(*$self, serialized)){
1056
1153
  throw std::runtime_error("Unsupported replacement");
1057
1154
  }
@@ -1062,12 +1159,13 @@ MAKE_TO_S(Matrix_Frozen)
1062
1159
  %bang swap_columns;
1063
1160
  %rename("replace!") replace;
1064
1161
 
1162
+ %catches(native_exception, std::invalid_argument) map_bang;
1065
1163
  void map_bang(
1066
1164
  self_t *self_p,
1067
1165
  void (*each_func)(
1068
1166
  const T &src, T *dst,
1069
1167
  const unsigned int &i, const unsigned int &j),
1070
- const typename MatrixUtil::each_which_t &each_which = MatrixUtil::EACH_ALL){
1168
+ const typename MatrixUtil::each_which_t each_which = MatrixUtil::EACH_ALL){
1071
1169
  MatrixUtil::each(*$self, each_func, each_which, $self);
1072
1170
  }
1073
1171
  %rename("map!") map_bang;
@@ -1096,6 +1194,14 @@ MAKE_TO_S(Matrix_Frozen)
1096
1194
  return MatView_f::partial(*$self, new_rows, new_columns, row_offset, column_offset);
1097
1195
  #else
1098
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);
1099
1205
  #endif
1100
1206
  }
1101
1207
  Matrix_Frozen<type, storage, view_to> row_vector(const unsigned int &row) const {
@@ -1113,6 +1219,9 @@ MAKE_TO_S(Matrix_Frozen)
1113
1219
  #endif
1114
1220
  }
1115
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
+ */
1116
1225
  %enddef
1117
1226
 
1118
1227
  %define INSTANTIATE_MATRIX_EIGEN2(type, ctype, storage, view)
@@ -1129,10 +1238,11 @@ MAKE_TO_S(Matrix_Frozen)
1129
1238
  Matrix<ctype, Array2D_Dense<ctype > > &output_V {
1130
1239
  %append_output(SWIG_NewPointerObj((new $*1_ltype(*$1)), $1_descriptor, SWIG_POINTER_OWN));
1131
1240
  }
1241
+ %catches(std::logic_error, std::runtime_error) eigen;
1132
1242
  void eigen(
1133
1243
  Matrix<ctype, Array2D_Dense<ctype > > &output_V,
1134
1244
  Matrix<ctype, Array2D_Dense<ctype > > &output_D) const {
1135
- typedef typename Matrix_Frozen<type, storage, view >::complex_t::m_t cmat_t;
1245
+ typedef Matrix<ctype, Array2D_Dense<ctype > > cmat_t;
1136
1246
  cmat_t VD($self->eigen());
1137
1247
  output_V = VD.partial($self->rows(), $self->rows()).copy();
1138
1248
  cmat_t D($self->rows(), $self->rows());
@@ -1258,7 +1368,7 @@ INSTANTIATE_MATRIX_PARTIAL(type, Array2D_Dense<type >, MatView_pt, MatView_pt);
1258
1368
  }
1259
1369
  Matrix<type, Array2D_Dense<type > > &resize(
1260
1370
  const unsigned int *r_p, const unsigned int *c_p){
1261
- unsigned int r(r_p ? *r_p : $self->rows()), c(c_p ? *c_p : self->columns());
1371
+ unsigned int r(r_p ? *r_p : $self->rows()), c(c_p ? *c_p : $self->columns());
1262
1372
  Matrix<type, Array2D_Dense<type > > mat_new(r, c);
1263
1373
  unsigned int r_min(r), c_min(c);
1264
1374
  if(r_min > $self->rows()){r_min = $self->rows();}
@@ -1288,6 +1398,19 @@ INSTANTIATE_MATRIX_EIGEN(double, Complex<double>);
1288
1398
  INSTANTIATE_MATRIX(Complex<double>, ComplexD);
1289
1399
  INSTANTIATE_MATRIX_EIGEN(Complex<double>, Complex<double>);
1290
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
+
1291
1414
  #undef INSTANTIATE_MATRIX_FUNC
1292
1415
  #undef INSTANTIATE_MATRIX_TRANSPOSE
1293
1416
  #undef INSTANTIATE_MATRIX_PARTIAL
@@ -918,7 +918,7 @@ __RINEX_CLK_TEXT__
918
918
  expect(solver.options[:skip_exclusion]).to eq(true)
919
919
  expect(solver.correction[:gps_ionospheric]).to include(:klobuchar)
920
920
  expect(solver.correction[:gps_tropospheric]).to include(:hopfield)
921
- expect{solver.correction = nil}.to raise_error(RuntimeError)
921
+ expect{solver.correction = nil}.to raise_error(ArgumentError)
922
922
  expect{solver.correction = {
923
923
  :gps_ionospheric => [proc{|t, usr_pos, sat_pos|
924
924
  expect(t).to be_a_kind_of(GPS::Time)