1 #ifndef __STAN__MATH__MATRIX_HPP__
2 #define __STAN__MATH__MATRIX_HPP__
8 #include <boost/math/tools/promotion.hpp>
10 #define EIGEN_DENSEBASE_PLUGIN "stan/math/EigenDenseBaseAddons.hpp"
11 #include <Eigen/Dense>
34 typedef Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic>
matrix;
39 typedef Eigen::Matrix<T,Eigen::Dynamic,1>
vector;
64 typedef Eigen::Array<T,Eigen::Dynamic,Eigen::Dynamic>
array_matrix;
85 void resize(Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic>& x,
86 const std::vector<size_t>& dims,
88 x.resize(dims[pos],dims[pos+1]);
92 void resize(Eigen::Matrix<T,Eigen::Dynamic,1>& x,
93 const std::vector<size_t>& dims,
99 void resize(Eigen::Matrix<T,1,Eigen::Dynamic>& x,
100 const std::vector<size_t>& dims,
107 const std::vector<size_t>& dims,
112 template <
typename T>
113 void resize(std::vector<T>& x,
114 const std::vector<size_t>& dims,
118 if (pos >= dims.size())
return;
119 for (
size_t i = 0; i < x.size(); ++i)
134 template <
typename T>
135 inline void resize(T& x, std::vector<size_t> dims) {
144 void raise_range_error(
size_t max,
149 s <<
"INDEX OPERATOR [] OUT OF BOUNDS"
152 <<
"; upper bound=" << max
153 <<
"; index position=" << idx
156 throw std::out_of_range(s.str());
160 void check_range(
size_t max,
165 if (i < 1 || i > max)
166 raise_range_error(max,i,msg,idx);
186 template <
typename T>
190 const char* error_msg,
192 check_range(x.size(),i,error_msg,idx);
211 template <
typename T>
216 const char* error_msg,
218 check_range(x.size(),i1,error_msg,idx);
219 return get_base1(x[i1 - 1],i2,error_msg,idx+1);
238 template <
typename T>
240 T&
get_base1(std::vector<std::vector<std::vector<T> > >& x,
244 const char* error_msg,
246 check_range(x.size(),i1,error_msg,idx);
247 return get_base1(x[i1 - 1],i2,i3,error_msg,idx+1);
267 template <
typename T>
269 T&
get_base1(std::vector<std::vector<std::vector<std::vector<T> > > >& x,
274 const char* error_msg,
276 check_range(x.size(),i1,error_msg,idx);
277 return get_base1(x[i1 - 1],i2,i3,i4,error_msg,idx+1);
298 template <
typename T>
300 T&
get_base1(std::vector<std::vector<std::vector<std::vector<std::vector<T> > > > >& x,
306 const char* error_msg,
308 check_range(x.size(),i1,error_msg,idx);
309 return get_base1(x[i1 - 1],i2,i3,i4,i5,error_msg,idx+1);
331 template <
typename T>
333 T&
get_base1(std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<T> > > > > >& x,
340 const char* error_msg,
342 check_range(x.size(),i1,error_msg,idx);
343 return get_base1(x[i1 - 1],i2,i3,i4,i5,i6,error_msg,idx+1);
367 template <
typename T>
369 T&
get_base1(std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<T> > > > > > >& x,
377 const char* error_msg,
379 check_range(x.size(),i1,error_msg,idx);
380 return get_base1(x[i1 - 1],i2,i3,i4,i5,i6,i7,error_msg,idx+1);
405 template <
typename T>
407 T&
get_base1(std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<T> > > > > > > >& x,
416 const char* error_msg,
418 check_range(x.size(),i1,error_msg,idx);
419 return get_base1(x[i1 - 1],i2,i3,i4,i5,i6,i7,i8,error_msg,idx+1);
443 template <
typename T>
445 Eigen::Matrix<T,1,Eigen::Dynamic>
446 get_base1(Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic>& x,
448 const char* error_msg,
450 check_range(x.rows(),m,error_msg,idx);
470 template <
typename T>
472 T&
get_base1(Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic>& x,
475 const char* error_msg,
477 check_range(x.rows(),m,error_msg,idx);
478 check_range(x.cols(),n,error_msg,idx + 1);
479 return x(m - 1, n - 1);
496 template <
typename T>
500 const char* error_msg,
502 check_range(x.size(),m,error_msg,idx);
521 template <
typename T>
525 const char* error_msg,
527 check_range(x.size(),n,error_msg,idx);
589 template <
typename T,
int R,
int C>
593 if (j > 0 && j <= static_cast<size_t>(m.cols()))
return;
594 std::stringstream ss;
595 ss <<
"require 0 < column index <= number of columns in" << msg;
596 ss <<
" found cols()=" << m.cols()
597 <<
"; index j=" << j;
598 throw std::domain_error(ss.str());
601 template <
typename T,
int R,
int C>
605 if (i > 0 && i <= static_cast<size_t>(m.rows()))
return;
606 std::stringstream ss;
607 ss <<
"require 0 < row index <= number of rows in" << msg;
608 ss <<
" found rows()=" << m.rows()
609 <<
"; index i=" << i;
610 throw std::domain_error(ss.str());
613 template <
typename T,
int R,
int C>
616 if (x.rows() == x.cols())
return;
617 std::stringstream ss;
618 ss <<
"error in call to " << msg
619 <<
"; require square matrix, but found"
620 <<
" rows=" << x.rows()
621 <<
"; cols=" << x.cols();
622 throw std::domain_error(ss.str());
625 template <
typename T1,
int R1,
int C1,
typename T2,
int R2,
int C2>
627 const Eigen::Matrix<T2,R2,C2>& x2,
629 if (x1.rows() == x2.rows()
630 && x1.cols() == x2.cols())
return;
631 std::stringstream ss;
632 ss <<
"error in call to " << msg
633 <<
"; require matching dimensions, but found"
634 <<
" arg1 rows=" << x1.rows() <<
" arg1 cols=" << x1.cols()
635 <<
" arg2 rows=" << x2.rows() <<
" arg2 cols=" << x2.cols();
636 throw std::domain_error(ss.str());
639 template <
typename T1,
typename T2>
641 const std::vector<T2>& x2,
643 if (x1.size() == x2.size())
return;
644 std::stringstream ss;
645 ss <<
"require matching sizes in " << msg
646 <<
" found first argument size=" << x1.size()
647 <<
"; second argument size=" << x2.size();
648 throw std::domain_error(ss.str());
651 template <
typename T1,
int R1,
int C1,
typename T2,
int R2,
int C2>
653 const Eigen::Matrix<T2,R2,C2>& x2,
655 if (x1.size() == x2.size())
return;
656 std::stringstream ss;
657 ss <<
"error in call to " << msg
658 <<
"; require matching sizes, but found"
659 <<
" arg1 rows=" << x1.rows() <<
" arg1 cols=" << x1.cols()
660 <<
" arg1 size=" << (x1.rows() * x1.cols())
661 <<
" arg2 rows=" << x2.rows() <<
" arg2 cols=" << x2.cols()
662 <<
" arg2 size=" << (x2.rows() * x2.cols());
663 throw std::domain_error(ss.str());
666 template <
typename T1,
int R1,
int C1,
typename T2,
int R2,
int C2>
668 const Eigen::Matrix<T2,R2,C2>& x2,
670 if (x1.cols() == x2.rows())
return;
671 std::stringstream ss;
672 ss <<
"error in call to " << msg
673 <<
"; require cols of arg1 to match rows of arg2, but found "
674 <<
" arg1 rows=" << x1.rows() <<
" arg1 cols=" << x1.cols()
675 <<
" arg2 rows=" << x2.rows() <<
" arg2 cols=" << x2.cols();
676 throw std::domain_error(ss.str());
679 template <
typename T>
681 if (x.size() > 0)
return;
682 std::stringstream ss;
683 ss <<
"require non-zero size for " << msg
684 <<
"found size=" << x.size();
685 throw std::domain_error(ss.str());
688 template <
typename T,
int R,
int C>
691 if (x.rows() == 1 || x.cols() == 1)
return;
692 std::stringstream ss;
693 ss <<
"error in " << msg
694 <<
"; require vector, found "
695 <<
" rows=" << x.rows() <<
"cols=" << x.cols();
696 throw std::domain_error(ss.str());
722 template <
int R,
int C>
723 inline double dot_self(
const Eigen::Matrix<double, R, C>& v) {
726 for (
int i = 0; i < v.size(); ++i)
737 inline Eigen::Matrix<T,Eigen::Dynamic,1>
739 return x.colwise().squaredNorm();
751 template<
int R1,
int C1,
int R2,
int C2>
752 inline double dot_product(
const Eigen::Matrix<double, R1, C1>& v1,
753 const Eigen::Matrix<double, R2, C2>& v2) {
758 for (
int i = 0; i < v1.size(); ++i)
759 sum += v1[i] * v2[i];
771 for (
size_t i = 0; i <
length; i++)
772 result += v1[i] * v2[i];
782 const std::vector<double>& v2) {
794 inline int min(
const std::vector<int>& x) {
796 throw std::domain_error(
"error: cannot take min of empty int vector");
798 for (
size_t i = 1; i < x.size(); ++i)
811 template <
typename T>
812 inline T
min(
const std::vector<T>& x) {
814 return std::numeric_limits<T>::infinity();
816 for (
size_t i = 1; i < x.size(); ++i)
828 template <
typename T,
int R,
int C>
829 inline T
min(
const Eigen::Matrix<T,R,C>& m) {
831 return std::numeric_limits<double>::infinity();
845 inline int max(
const std::vector<int>& x) {
847 throw std::domain_error(
"error: cannot take max of empty int vector");
849 for (
size_t i = 1; i < x.size(); ++i)
862 template <
typename T>
863 inline T
max(
const std::vector<T>& x) {
865 return -std::numeric_limits<T>::infinity();
867 for (
size_t i = 1; i < x.size(); ++i)
879 template <
typename T,
int R,
int C>
880 inline T
max(
const Eigen::Matrix<T,R,C>& m) {
882 return -std::numeric_limits<double>::infinity();
894 template <
typename T>
896 typename boost::math::tools::promote_args<T>::type
897 mean(
const std::vector<T>& v) {
900 for (
size_t i = 1; i < v.size(); ++i)
902 return sum / v.size();
911 template <
typename T,
int R,
int C>
913 typename boost::math::tools::promote_args<T>::type
914 mean(
const Eigen::Matrix<T,R,C>& m) {
927 template <
typename T>
929 typename boost::math::tools::promote_args<T>::type
936 for (
size_t i = 0; i < v.size(); ++i) {
937 T diff = v[i] - v_mean;
938 sum_sq_diff += diff * diff;
940 return sum_sq_diff / (v.size() - 1);
949 template <
typename T,
int R,
int C>
951 typename boost::math::tools::promote_args<T>::type
956 typename boost::math::tools::promote_args<T>::type
958 typename boost::math::tools::promote_args<T>::type
960 for (
int i = 0; i < m.size(); ++i) {
961 typename boost::math::tools::promote_args<T>::type
963 sum_sq_diff += diff * diff;
965 return sum_sq_diff / (m.size() - 1);
974 template <
typename T>
976 typename boost::math::tools::promote_args<T>::type
977 sd(
const std::vector<T>& v) {
979 if (v.size() == 1)
return 0.0;
989 template <
typename T,
int R,
int C>
991 typename boost::math::tools::promote_args<T>::type
992 sd(
const Eigen::Matrix<T,R,C>& m) {
995 if (m.size() == 1)
return 0.0;
1007 template <
typename T>
1008 inline T
sum(
const std::vector<T>& xs) {
1009 if (xs.size() == 0)
return 0;
1011 for (
size_t i = 1; i < xs.size(); ++i)
1022 template <
typename T,
int R,
int C>
1023 inline double sum(
const Eigen::Matrix<T,R,C>& v) {
1033 template <
typename T>
1034 inline T
prod(
const std::vector<T>& v) {
1035 if (v.size() == 0)
return 1;
1037 for (
size_t i = 1; i < v.size(); ++i)
1048 template <
typename T,
int R,
int C>
1049 inline T
prod(
const Eigen::Matrix<T,R,C>& v) {
1050 if (v.size() == 0)
return 1.0;
1063 template <
typename T>
1064 inline T
trace(
const Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic>& m) {
1074 template<
typename T,
int Rows,
int Cols>
1075 inline Eigen::Matrix<T,Rows,Cols>
log(
const Eigen::Matrix<T,Rows,Cols>& m) {
1076 return m.array().log().matrix();
1085 template<
typename T,
int Rows,
int Cols>
1086 inline Eigen::Matrix<T,Rows,Cols>
exp(
const Eigen::Matrix<T,Rows,Cols>& m) {
1087 return m.array().exp().matrix();
1129 template<
int Rows,
int Cols>
1130 inline Eigen::Matrix<double,Rows,Cols>
add(
const Eigen::Matrix<double,Rows,Cols>& m,
const double& c) {
1131 return (m.array() + c).matrix();
1139 template<
int Rows,
int Cols>
1140 inline Eigen::Matrix<double,Rows,Cols>
add(
const double& c,
const Eigen::Matrix<double,Rows,Cols>& m) {
1141 return (c + m.array()).matrix();
1178 template<
int Rows,
int Cols>
1179 inline Eigen::Matrix<double,Rows,Cols>
subtract(
const Eigen::Matrix<double,Rows,Cols>& m,
1181 return (m.array() - c).matrix();
1189 template<
int Rows,
int Cols>
1190 inline Eigen::Matrix<double,Rows,Cols>
subtract(
double c,
const Eigen::Matrix<double,Rows,Cols>& m) {
1191 return (c - m.array()).matrix();
1320 template<
int R1,
int C1,
int R2,
int C2>
1321 inline Eigen::Matrix<double,R1,C2>
multiply(
const Eigen::Matrix<double,R1,C1>& m1,
1322 const Eigen::Matrix<double,R2,C2>& m2) {
1324 if (m1.cols() != m2.rows())
1325 throw std::domain_error(
"m1.cols() != m2.rows()");
1337 template<
int C1,
int R2>
1338 inline double multiply(
const Eigen::Matrix<double,1,C1>& rv,
1339 const Eigen::Matrix<double,R2,1>& v) {
1341 if (rv.size() != v.size())
1342 throw std::domain_error(
"rv.size() != v.size()");
1380 if (L.rows() == 1) {
1382 result(0,0) = L(0,0) * L(0,0);
1387 matrix_d L_tri = L.transpose().triangularView<Eigen::Upper>();
1388 return L.triangularView<Eigen::Lower>() * L_tri;
1402 return M * M.transpose();
1404 matrix_d result(M.rows(),M.rows());
1405 return result.setZero().selfadjointView<Eigen::Upper>().rankUpdate(M);
1497 template<
int R1,
int C1,
int R2,
int C2>
1499 const Eigen::Matrix<double,R2,C2> &b) {
1500 if (A.cols() != A.rows())
1501 throw std::domain_error(
"A is not square");
1502 if (A.cols() != b.rows())
1503 throw std::domain_error(
"A.cols() != b.rows()");
1504 return A.template triangularView<Eigen::Lower>().solve(b);
1508 if (A.cols() != A.rows())
1509 throw std::domain_error(
"A is not square");
1513 A.triangularView<Eigen::Lower>().solveInPlace(b);
1526 template<
int TriView,
int R1,
int C1,
int R2,
int C2>
1528 const Eigen::Matrix<double,R2,C2> &b) {
1529 if (A.cols() != A.rows())
1530 throw std::domain_error(
"A is not square");
1531 if (A.cols() != b.rows())
1532 throw std::domain_error(
"A.cols() != b.rows()");
1533 return A.template triangularView<TriView>().solve(b);
1542 template<
int TriView>
1543 inline Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>
mdivide_left_tri(
const Eigen::MatrixXd &A) {
1544 if (A.cols() != A.rows())
1545 throw std::domain_error(
"A is not square");
1549 A.triangularView<TriView>().solveInPlace(b);
1561 template<
int TriView,
int R1,
int C1,
int R2,
int C2>
1563 const Eigen::Matrix<double,R2,C2> &A) {
1564 if (A.cols() != A.rows())
1565 throw std::domain_error(
"A is not square");
1566 if (A.rows() != b.cols())
1567 throw std::domain_error(
"A.rows() != b.cols()");
1568 return A.template triangularView<TriView>().
transpose().solve(b.transpose()).
transpose();
1579 template<
int R1,
int C1,
int R2,
int C2>
1581 const Eigen::Matrix<double,R2,C2> &A) {
1582 return mdivide_right_tri<Eigen::Lower>(b,A);
1594 template<
int R1,
int C1,
int R2,
int C2>
1595 inline Eigen::Matrix<double,R1,C2>
mdivide_left(
const Eigen::Matrix<double,R1,C1> &A,
1596 const Eigen::Matrix<double,R2,C2> &b) {
1597 if (A.cols() != A.rows())
1598 throw std::domain_error(
"A is not square");
1599 if (A.cols() != b.rows())
1600 throw std::domain_error(
"A.cols() != b.rows()");
1601 return A.lu().solve(b);
1611 template<
int R1,
int C1,
int R2,
int C2>
1612 inline Eigen::Matrix<double,R1,C2>
mdivide_right(
const Eigen::Matrix<double,R1,C1> &b,
1613 const Eigen::Matrix<double,R2,C2> &A) {
1614 if (A.cols() != A.rows())
1615 throw std::domain_error(
"A is not square");
1616 if (A.rows() != b.cols())
1617 throw std::domain_error(
"A.rows() != b.cols()");
1618 return A.transpose().lu().solve(b.transpose()).
transpose();
1741 template <
typename T>
1746 template <
typename T>
1749 for (
int i = 0; i < x.size(); ++i) {
1750 if (i > 0) *o <<
',';
1756 template <
typename T>
1757 void stan_print(std::ostream* o,
const Eigen::Matrix<T,Eigen::Dynamic,1>& x) {
1759 for (
int i = 0; i < x.size(); ++i) {
1760 if (i > 0) *o <<
',';
1766 template <
typename T>
1767 void stan_print(std::ostream* o,
const Eigen::Matrix<T,1,Eigen::Dynamic>& x) {
1769 for (
int i = 0; i < x.size(); ++i) {
1770 if (i > 0) *o <<
',';
1776 template <
typename T>
1777 void stan_print(std::ostream* o,
const Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic>& x) {
1779 for (
int i = 0; i < x.rows(); ++i) {
1780 if (i > 0) *o <<
',';