@@ -580,17 +580,23 @@ class HPolytope {
580
580
NT inner_prev = params.inner_vi_ak ;
581
581
NT* Av_data = Av.data ();
582
582
583
+ // Updating Av due to the change in direction caused by the previous reflection
583
584
// Av += (-2.0 * inner_prev) * AA.col(params.facet_prev)
584
585
585
586
for (Eigen::SparseMatrix<double >::InnerIterator it (AA, params.facet_prev ); it; ++it) {
586
587
588
+ // val(row) - params.moved_dist = The distance until we would hit the facet given by row
589
+ // all those values are stored inside distances_set for quick retrieval of the minimum
587
590
591
+ // Before updating Av(row)
588
592
// val(row) = (b(row) - Ar(row)) / Av(row) + params.moved_dist
589
593
// (val(row) - params.moved_dist) = (b(row) - Ar(row)) / Av(row)
590
594
// (val(row) - params.moved_dist) * Av(row) = b(row) - Ar(row)
595
+ // b(row) - Ar(row) = (val(row) - params.moved_dist) * Av(row)
591
596
592
597
*(Av_data + it.row ()) += (-2.0 * inner_prev) * it.value ();
593
598
599
+ // After updating Av(row)
594
600
// b(row) - Ar(row) = (old_val(row) - params.moved_dist) * old_Av(row)
595
601
// new_val(row) = (b(row) - Ar(row) ) / new_Av(row) + params.moved_dist
596
602
// new_val(row) = ((old_val(row) - params.moved_dist) * old_Av(row)) / new_Av(row) + params.moved_dist
@@ -608,8 +614,12 @@ class HPolytope {
608
614
distances_set.change_val (it.row (), val, params.moved_dist );
609
615
}
610
616
617
+ // Finding the distance to the closest facet and its row
611
618
std::pair<NT, int > ans = distances_set.get_min ();
619
+
620
+ // Subtract params.moved_dist to obtain the actual distance to the facet
612
621
ans.first -= params.moved_dist ;
622
+
613
623
params.inner_vi_ak = *(Av_data + ans.second );
614
624
params.facet_prev = ans.second ;
615
625
@@ -1002,34 +1012,59 @@ class HPolytope {
1002
1012
return total;
1003
1013
}
1004
1014
1015
+ // Updates the velocity vector v and the position vector p after a reflection
1005
1016
template <typename update_parameters>
1006
1017
void compute_reflection (Point &v, Point const &, update_parameters const & params) const {
1007
1018
Point a ((-2.0 * params.inner_vi_ak ) * A.row (params.facet_prev ));
1008
1019
v += a;
1009
1020
}
1010
1021
1011
- // updates the velocity vector v and the position vector p after a reflection
1012
- // the real value of p is given by p + moved_dist * v
1022
+ // Only to be called when MT is in RowMajor format
1023
+ // The real value of p is given by p + params. moved_dist * v
1013
1024
template <typename update_parameters>
1014
- auto compute_reflection (Point &v, Point &p, update_parameters const & params) const
1015
- -> std::enable_if_t<std::is_same_v<MT, Eigen::SparseMatrix<NT, Eigen::RowMajor>> && !std::is_same_v<update_parameters, int>, void> { // MT must be in RowMajor format
1016
- NT* v_data = v.pointerToData ();
1017
- NT* p_data = p.pointerToData ();
1018
- for (Eigen::SparseMatrix<double , Eigen::RowMajor>::InnerIterator it (A, params.facet_prev ); it; ++it) {
1019
- *(v_data + it.col ()) += (-2.0 * params.inner_vi_ak ) * it.value ();
1020
- *(p_data + it.col ()) -= (-2.0 * params.inner_vi_ak * params.moved_dist ) * it.value ();
1021
- }
1025
+ auto compute_reflection_abw_sparse (Point &v, Point &p, update_parameters const & params) const
1026
+ {
1027
+ NT* v_data = v.pointerToData ();
1028
+ NT* p_data = p.pointerToData ();
1029
+ for (Eigen::SparseMatrix<double , Eigen::RowMajor>::InnerIterator it (A, params.facet_prev ); it; ++it) {
1030
+ *(v_data + it.col ()) += (-2.0 * params.inner_vi_ak ) * it.value ();
1031
+ *(p_data + it.col ()) -= (-2.0 * params.inner_vi_ak * params.moved_dist ) * it.value ();
1032
+ }
1022
1033
}
1023
1034
1024
- template <typename update_parameters>
1025
- NT compute_reflection (Point &v, const Point &, DenseMT const &AE, VT const &AEA, NT const &vEv, update_parameters const ¶ms) const {
1035
+ // function to compute reflection for GaBW random walk
1036
+ // compatible when the polytope is both dense or sparse
1037
+ template <typename DenseSparseMT, typename update_parameters>
1038
+ NT compute_reflection (Point &v, Point &p, NT &vEv, DenseSparseMT const &AE, VT const &AEA, update_parameters const ¶ms) const {
1039
+
1040
+ NT new_vEv;
1041
+ if constexpr (!std::is_same_v<MT, Eigen::SparseMatrix<NT, Eigen::RowMajor>>) {
1042
+ Point a ((-2.0 * params.inner_vi_ak ) * A.row (params.facet_prev ));
1043
+ VT x = v.getCoefficients ();
1044
+ new_vEv = vEv - (4.0 * params.inner_vi_ak ) * (AE.row (params.facet_prev ).dot (x) - params.inner_vi_ak * AEA (params.facet_prev ));
1045
+ v += a;
1046
+ } else {
1047
+
1048
+ if constexpr (!std::is_same_v<DenseSparseMT, Eigen::SparseMatrix<NT, Eigen::RowMajor>>) {
1049
+ VT x = v.getCoefficients ();
1050
+ new_vEv = vEv - (4.0 * params.inner_vi_ak ) * (AE.row (params.facet_prev ).dot (x) - params.inner_vi_ak * AEA (params.facet_prev ));
1051
+ } else {
1052
+ new_vEv = vEv + 4.0 * params.inner_vi_ak * params.inner_vi_ak * AEA (params.facet_prev );
1053
+ NT* v_data = v.pointerToData ();
1054
+ for (Eigen::SparseMatrix<double , Eigen::RowMajor>::InnerIterator it (AE, params.facet_prev ); it; ++it) {
1055
+ new_vEv -= 4.0 * params.inner_vi_ak * it.value () * *(v_data + it.col ());
1056
+ }
1057
+ }
1026
1058
1027
- Point a ((-2.0 * params.inner_vi_ak ) * A.row (params.facet_prev ));
1028
- VT x = v.getCoefficients ();
1029
- NT new_vEv = vEv - (4.0 * params.inner_vi_ak ) * (AE.row (params.facet_prev ).dot (x) - params.inner_vi_ak * AEA (params.facet_prev ));
1030
- v += a;
1059
+ NT* v_data = v.pointerToData ();
1060
+ NT* p_data = p.pointerToData ();
1061
+ for (Eigen::SparseMatrix<double , Eigen::RowMajor>::InnerIterator it (A, params.facet_prev ); it; ++it) {
1062
+ *(v_data + it.col ()) += (-2.0 * params.inner_vi_ak ) * it.value ();
1063
+ *(p_data + it.col ()) -= (-2.0 * params.inner_vi_ak * params.moved_dist ) * it.value ();
1064
+ }
1065
+ }
1031
1066
NT coeff = std::sqrt (vEv / new_vEv);
1032
- v = v * coeff ;
1067
+ vEv = new_vEv ;
1033
1068
return coeff;
1034
1069
}
1035
1070
0 commit comments