@@ -13,49 +13,45 @@ namespace math {
1313 *
1414 * Symmetry of the resulting matrix is guaranteed.
1515 *
16- * @tparam TA type of elements in the symmetric matrix
17- * @tparam RA number of rows in the symmetric matrix, can be Eigen::Dynamic
18- * @tparam CA number of columns in the symmetric matrix, can be Eigen::Dynamic
19- * @tparam TB type of elements in the second matrix
20- * @tparam RB number of rows in the second matrix, can be Eigen::Dynamic
21- * @tparam CB number of columns in the second matrix, can be Eigen::Dynamic
16+ * @tparam EigMat1 type of the first (symmetric) matrix
17+ * @tparam EigMat2 type of the second matrix
2218 *
2319 * @param A symmetric matrix
2420 * @param B second matrix
2521 * @return The quadratic form, which is a symmetric matrix of size CB.
2622 * @throws std::invalid_argument if A is not symmetric, or if A cannot be
2723 * multiplied by B
2824 */
29- template <typename TA, int RA, int CA, typename TB, int RB, int CB,
30- require_any_fvar_t <TA, TB>...>
31- inline Eigen::Matrix<return_type_t <TA, TB>, CB, CB> quad_form_sym (
32- const Eigen::Matrix<TA, RA, CA>& A, const Eigen::Matrix<TB, RB, CB>& B) {
33- using T = return_type_t <TA, TB>;
25+ template <typename EigMat1, typename EigMat2,
26+ require_all_eigen_t <EigMat1, EigMat2>* = nullptr ,
27+ require_not_eigen_col_vector_t <EigMat2>* = nullptr ,
28+ require_any_vt_fvar<EigMat1, EigMat2>* = nullptr >
29+ inline promote_scalar_t <return_type_t <EigMat1, EigMat2>, EigMat2> quad_form_sym (
30+ const EigMat1& A, const EigMat2& B) {
31+ using T_ret = return_type_t <EigMat1, EigMat2>;
3432 check_multiplicable (" quad_form_sym" , " A" , A, " B" , B);
3533 check_symmetric (" quad_form_sym" , " A" , A);
36- Eigen::Matrix<T, CB, CB > ret (multiply (transpose (B ), multiply (A, B)));
37- return T (0.5 ) * (ret + transpose (ret ));
34+ promote_scalar_t <T_ret, EigMat2 > ret (multiply (B. transpose (), multiply (A, B)));
35+ return T_ret (0.5 ) * (ret + ret. transpose ());
3836}
3937
4038/* *
4139 * Return the quadratic form \f$ B^T A B \f$ of a symmetric matrix.
4240 *
43- * @tparam TA type of elements in the symmetric matrix
44- * @tparam RA number of rows in the symmetric matrix, can be Eigen::Dynamic
45- * @tparam CA number of columns in the symmetric matrix, can be Eigen::Dynamic
46- * @tparam TB type of elements in the vector
47- * @tparam RB number of rows in the vector, can be Eigen::Dynamic
41+ * @tparam EigMat type of the (symmetric) matrix
42+ * @tparam ColVec type of the vector
4843 *
4944 * @param A symmetric matrix
5045 * @param B vector
5146 * @return The quadratic form (a scalar).
5247 * @throws std::invalid_argument if A is not symmetric, or if A cannot be
5348 * multiplied by B
5449 */
55- template <typename TA, int RA, int CA, typename TB, int RB,
56- require_any_fvar_t <TA, TB>...>
57- inline return_type_t <TA, TB> quad_form_sym (const Eigen::Matrix<TA, RA, CA>& A,
58- const Eigen::Matrix<TB, RB, 1 >& B) {
50+ template <typename EigMat, typename ColVec, require_eigen_t <EigMat>* = nullptr ,
51+ require_eigen_col_vector_t <ColVec>* = nullptr ,
52+ require_any_vt_fvar<EigMat, ColVec>* = nullptr >
53+ inline return_type_t <EigMat, ColVec> quad_form_sym (const EigMat& A,
54+ const ColVec& B) {
5955 check_multiplicable (" quad_form_sym" , " A" , A, " B" , B);
6056 check_symmetric (" quad_form_sym" , " A" , A);
6157 return dot_product (B, multiply (A, B));
0 commit comments