@@ -27,13 +27,13 @@ namespace math {
2727template <typename M, require_eigen_dense_dynamic_t <M>* = nullptr >
2828inline Eigen::Matrix<complex_return_t <scalar_type_t <M>>, -1 , -1 >
2929complex_schur_decompose_u (const M& m) {
30- if (m.size () == 0 )
30+ if (unlikely ( m.size () == 0 )) {
3131 return m;
32+ }
3233 check_square (" complex_schur_decompose_u" , " m" , m);
3334 using MatType = Eigen::Matrix<scalar_type_t <M>, -1 , -1 >;
3435 // copy because ComplexSchur requires Eigen::Matrix type
35- MatType mv = m;
36- Eigen::ComplexSchur<MatType> cs (mv);
36+ Eigen::ComplexSchur<MatType> cs{MatType (m)};
3737 return cs.matrixU ();
3838}
3939
@@ -51,16 +51,46 @@ complex_schur_decompose_u(const M& m) {
5151template <typename M, require_eigen_dense_dynamic_t <M>* = nullptr >
5252inline Eigen::Matrix<complex_return_t <scalar_type_t <M>>, -1 , -1 >
5353complex_schur_decompose_t (const M& m) {
54- if (m.size () == 0 )
54+ if (unlikely ( m.size () == 0 )) {
5555 return m;
56+ }
5657 check_square (" complex_schur_decompose_t" , " m" , m);
5758 using MatType = Eigen::Matrix<scalar_type_t <M>, -1 , -1 >;
5859 // copy because ComplexSchur requires Eigen::Matrix type
59- MatType mv = m;
60- Eigen::ComplexSchur<MatType> cs (mv, false );
60+ Eigen::ComplexSchur<MatType> cs{MatType (m), false };
6161 return cs.matrixT ();
6262}
6363
64+ /* *
65+ * Return the complex Schur decomposition of the
66+ * specified square matrix.
67+ *
68+ * The complex Schur decomposition of a square matrix `A` produces a
69+ * complex unitary matrix `U` and a complex upper-triangular Schur
70+ * form matrix `T` such that `A = U * T * inv(U)`. Further, the
71+ * unitary matrix's inverse is equal to its conjugate transpose,
72+ * `inv(U) = U*`, where `U*(i, j) = conj(U(j, i))`
73+ *
74+ * @tparam M type of matrix
75+ * @param m real matrix to decompose
76+ * @return a tuple (U,T) where U is the complex unitary matrix of the complex
77+ * Schur decomposition of `m` and T is the Schur form matrix of
78+ * the complex Schur decomposition of `m`
79+ */
80+ template <typename M, require_eigen_dense_dynamic_t <M>* = nullptr >
81+ inline std::tuple<Eigen::Matrix<complex_return_t <scalar_type_t <M>>, -1 , -1 >,
82+ Eigen::Matrix<complex_return_t <scalar_type_t <M>>, -1 , -1 >>
83+ complex_schur_decompose (const M& m) {
84+ if (unlikely (m.size () == 0 )) {
85+ return std::make_tuple (m, m);
86+ }
87+ check_square (" complex_schur_decompose" , " m" , m);
88+ using MatType = Eigen::Matrix<scalar_type_t <M>, -1 , -1 >;
89+ // copy because ComplexSchur requires Eigen::Matrix type
90+ Eigen::ComplexSchur<MatType> cs{MatType (m)};
91+ return std::make_tuple (std::move (cs.matrixU ()), std::move (cs.matrixT ()));
92+ }
93+
6494} // namespace math
6595} // namespace stan
6696#endif
0 commit comments