@@ -21,32 +21,39 @@ namespace proxsuite {
2121namespace proxqp {
2222namespace dense {
2323
24- template <typename T>
24+ template <typename T,
25+ typename MatIn,
26+ typename VecIn1,
27+ typename VecIn2,
28+ typename VecIn3>
2529T
26- power_iteration (MatRef<T> H,
27- VecRefMut<T> dw,
28- VecRefMut<T> rhs,
29- VecRefMut<T> err_v,
30+ power_iteration (const Eigen::MatrixBase<MatIn>& H,
31+ const Eigen::MatrixBase<VecIn1>& dw,
32+ const Eigen::MatrixBase<VecIn2>& rhs,
33+ const Eigen::MatrixBase<VecIn3>& err_v,
3034 T power_iteration_accuracy,
3135 isize nb_power_iteration)
3236{
37+ auto & dw_cc = dw.const_cast_derived ();
38+ auto & rhs_cc = rhs.const_cast_derived ();
39+ auto & err_v_cc = err_v.const_cast_derived ();
3340 // computes maximal eigen value of the bottom right matrix of the LDLT
3441 isize dim = H.rows ();
35- rhs .setZero ();
42+ rhs_cc .setZero ();
3643 // stores eigenvector
37- rhs .array () += 1 . / std::sqrt (dim);
44+ rhs_cc .array () += 1 . / std::sqrt (dim);
3845 // stores Hx
39- dw .noalias () = H.template selfadjointView <Eigen::Lower>() * rhs ; // Hx
46+ dw_cc .noalias () = H.template selfadjointView <Eigen::Lower>() * rhs_cc ; // Hx
4047 T eig = 0 ;
4148 for (isize i = 0 ; i < nb_power_iteration; i++) {
4249
43- rhs = dw / dw .norm ();
44- dw .noalias () = (H.template selfadjointView <Eigen::Lower>() * rhs );
50+ rhs_cc = dw_cc / dw_cc .norm ();
51+ dw_cc .noalias () = (H.template selfadjointView <Eigen::Lower>() * rhs_cc );
4552 // calculate associated eigenvalue
46- eig = rhs.dot (dw );
53+ eig = rhs.dot (dw_cc );
4754 // calculate associated error
48- err_v = dw - eig * rhs ;
49- T err = proxsuite::proxqp::dense::infty_norm (err_v );
55+ err_v_cc = dw_cc - eig * rhs_cc ;
56+ T err = proxsuite::proxqp::dense::infty_norm (err_v_cc );
5057 // std::cout << "power iteration max: i " << i << " err " << err <<
5158 // std::endl;
5259 if (err <= power_iteration_accuracy) {
@@ -55,37 +62,46 @@ power_iteration(MatRef<T> H,
5562 }
5663 return eig;
5764}
58- template <typename T>
65+ template <typename T,
66+ typename MatIn,
67+ typename VecIn1,
68+ typename VecIn2,
69+ typename VecIn3>
5970T
60- min_eigen_value_via_modified_power_iteration (MatRef<T> H,
61- VecRefMut<T> dw,
62- VecRefMut<T> rhs,
63- VecRefMut<T> err_v,
64- T max_eigen_value,
65- T power_iteration_accuracy,
66- isize nb_power_iteration)
71+ min_eigen_value_via_modified_power_iteration (
72+ const Eigen::MatrixBase<MatIn>& H,
73+ const Eigen::MatrixBase<VecIn1>& dw,
74+ const Eigen::MatrixBase<VecIn2>& rhs,
75+ const Eigen::MatrixBase<VecIn3>& err_v,
76+ T max_eigen_value,
77+ T power_iteration_accuracy,
78+ isize nb_power_iteration)
6779{
6880 // performs power iteration on the matrix: max_eigen_value I - H
6981 // estimates then the minimal eigenvalue with: minimal_eigenvalue =
7082 // max_eigen_value - eig
83+ auto & dw_cc = dw.const_cast_derived ();
84+ auto & rhs_cc = rhs.const_cast_derived ();
85+ auto & err_v_cc = err_v.const_cast_derived ();
7186 isize dim = H.rows ();
72- rhs .setZero ();
87+ rhs_cc .setZero ();
7388 // stores eigenvector
74- rhs .array () += 1 . / std::sqrt (dim);
89+ rhs_cc .array () += 1 . / std::sqrt (dim);
7590 // stores Hx
76- dw.noalias () = -(H.template selfadjointView <Eigen::Lower>() * rhs); // Hx
77- dw += max_eigen_value * rhs;
91+ dw_cc.noalias () =
92+ -(H.template selfadjointView <Eigen::Lower>() * rhs_cc); // Hx
93+ dw_cc += max_eigen_value * rhs_cc;
7894 T eig = 0 ;
7995 for (isize i = 0 ; i < nb_power_iteration; i++) {
8096
81- rhs = dw / dw .norm ();
82- dw .noalias () = -(H.template selfadjointView <Eigen::Lower>() * rhs );
83- dw += max_eigen_value * rhs ;
97+ rhs_cc = dw_cc / dw_cc .norm ();
98+ dw_cc .noalias () = -(H.template selfadjointView <Eigen::Lower>() * rhs_cc );
99+ dw_cc += max_eigen_value * rhs_cc ;
84100 // calculate associated eigenvalue
85- eig = rhs .dot (dw );
101+ eig = rhs_cc .dot (dw_cc );
86102 // calculate associated error
87- err_v = dw - eig * rhs ;
88- T err = proxsuite::proxqp::dense::infty_norm (err_v );
103+ err_v_cc = dw_cc - eig * rhs_cc ;
104+ T err = proxsuite::proxqp::dense::infty_norm (err_v_cc );
89105 // std::cout << "power iteration min: i " << i << " err " << err <<
90106 // std::endl;
91107 if (err <= power_iteration_accuracy) {
@@ -104,10 +120,10 @@ min_eigen_value_via_modified_power_iteration(MatRef<T> H,
104120 * @param nb_power_iteration maximal number of power iteration executed
105121 *
106122 */
107- template <typename T>
123+ template <typename T, typename MatIn >
108124T
109125estimate_minimal_eigen_value_of_symmetric_matrix (
110- MatRef<T> H,
126+ const Eigen::MatrixBase<MatIn>& H,
111127 EigenValueEstimateMethodOption estimate_method_option,
112128 T power_iteration_accuracy,
113129 isize nb_power_iteration)
@@ -129,16 +145,16 @@ estimate_minimal_eigen_value_of_symmetric_matrix(
129145 Vec<T> dw (dim);
130146 Vec<T> rhs (dim);
131147 Vec<T> err (dim);
132- T dominant_eigen_value = power_iteration<T> (
148+ T dominant_eigen_value = power_iteration (
133149 H, dw, rhs, err, power_iteration_accuracy, nb_power_iteration);
134- T min_eigenvalue = min_eigen_value_via_modified_power_iteration<T>(
135- H,
136- dw,
137- rhs,
138- err,
139- dominant_eigen_value,
140- power_iteration_accuracy,
141- nb_power_iteration);
150+ T min_eigenvalue =
151+ min_eigen_value_via_modified_power_iteration ( H,
152+ dw,
153+ rhs,
154+ err,
155+ dominant_eigen_value,
156+ power_iteration_accuracy,
157+ nb_power_iteration);
142158 res = std::min (min_eigenvalue, dominant_eigen_value);
143159 } break ;
144160 case EigenValueEstimateMethodOption::ExactMethod: {
0 commit comments