Ejemplo n.º 1
0
    inline Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>
    wishart_rng(const double nu,
                const Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>& S,
                RNG& rng) {

      static const char* function = "stan::prob::wishart_rng(%1%)";

      using stan::math::check_size_match;
      using stan::math::check_positive;

      check_positive(function,nu,"degrees of freedom",(double*)0);
      check_size_match(function, 
                       S.rows(), "Rows of scale parameter",
                       S.cols(), "columns of scale parameter",
                       (double*)0);

      Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> B(S.rows(), S.cols());
      B.setZero();

      for(int i = 0; i < S.cols(); i++) {
        B(i,i) = std::sqrt(chi_square_rng(nu - i, rng));
        for(int j = 0; j < i; j++)
          B(j,i) = normal_rng(0,1,rng);
      }

      return stan::math::multiply_lower_tri_self_transpose(S.llt().matrixL() * B);
    }
Ejemplo n.º 2
0
    inline Eigen::Matrix<typename return_type<T1, T2>::type, 
                         Eigen::Dynamic, Eigen::Dynamic>
    append_col(const Eigen::Matrix<T1, R1, C1>& A,
               const Eigen::Matrix<T2, R2, C2>& B) {

      using Eigen::Dynamic;
      using Eigen::Matrix; 
      using stan::math::check_size_match;

      int Arows = A.rows();
      int Brows = B.rows();
      int Acols = A.cols();
      int Bcols = B.cols();
      check_size_match("append_col",
                       "rows of A", Arows, 
                       "rows of B", Brows);
      
      Matrix<typename return_type<T1, T2>::type, Dynamic, Dynamic>
        result(Arows, Acols+Bcols);
      for (int j = 0; j < Acols; j++)
        for (int i = 0; i < Arows; i++)
          result(i, j) = A(i, j);
          
      for (int j = Acols, k = 0; k < Bcols; j++, k++)
        for (int i = 0; i < Arows; i++)
          result(i, j) = B(i, k);
      return result;
    }
Ejemplo n.º 3
0
    inline 
    Eigen::Matrix<fvar<T>,R1,C2>
    mdivide_right(const Eigen::Matrix<fvar<T>,R1,C1> &A,
                  const Eigen::Matrix<double,R2,C2> &b) {
      
      using stan::math::multiply;      
      using stan::math::mdivide_right;
      stan::math::check_square("mdivide_right(%1%)",b,"b",(double*)0);
      stan::math::check_multiplicable("mdivide_right(%1%)",A,"A",
                                      b,"b",(double*)0);

      Eigen::Matrix<T,R2,C2> deriv_b_mult_inv_b(b.rows(),b.cols());
      Eigen::Matrix<T,R1,C1> val_A(A.rows(),A.cols()); 
      Eigen::Matrix<T,R1,C1> deriv_A(A.rows(),A.cols());

      for (int j = 0; j < A.cols(); j++) {
        for(int i = 0; i < A.rows(); i++) {
          val_A(i,j) = A(i,j).val_;
          deriv_A(i,j) = A(i,j).d_;
        }
      }

      return stan::agrad::to_fvar(mdivide_right(val_A, b), 
                                  mdivide_right(deriv_A, b));
    }
Ejemplo n.º 4
0
 inline bool check_corr_matrix(const char* function,
               const Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic>& y,
               const char* name,
               T_result* result,
               const Policy&) {
   if (!check_size_match(function, 
       y.rows(), "Rows of correlation matrix",
       y.cols(), "columns of correlation matrix",
       result, Policy())) 
     return false;
   if (!check_positive(function, y.rows(), "rows", result, Policy()))
     return false;
   if (!check_symmetric(function, y, "y", result, Policy()))
     return false;
   for (typename Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic>::size_type
          k = 0; k < y.rows(); ++k) {
     if (fabs(y(k,k) - 1.0) > CONSTRAINT_TOLERANCE) {
       std::ostringstream message;
       message << name << " is not a valid correlation matrix. " 
               << name << "(" << k << "," << k 
               << ") is %1%, but should be near 1.0";
       T_result tmp 
         = policies::raise_domain_error<T_y>(function,
                                             message.str().c_str(),
                                             y(k,k), Policy());
       if (result != 0)
         *result = tmp;
       return false;
     }
   }
   if (!check_pos_definite(function, y, "y", result, Policy()))
     return false;
   return true;
 }
Ejemplo n.º 5
0
    inline 
    fvar<T>
    determinant(const Eigen::Matrix<fvar<T>, R, C>& m) {
      using stan::math::multiply;
      using stan::math::inverse;

      stan::math::check_square("determinant", "m", m);
      Eigen::Matrix<T,R,C> m_deriv(m.rows(), m.cols());
      Eigen::Matrix<T,R,C> m_val(m.rows(), m.cols());

      for(size_type i = 0; i < m.rows(); i++) {
        for(size_type j = 0; j < m.cols(); j++) {
          m_deriv(i,j) = m(i,j).d_;
          m_val(i,j) = m(i,j).val_;
        }
      }

      Eigen::Matrix<T,R,C> m_inv = inverse<T>(m_val);
      m_deriv = multiply(m_inv, m_deriv);

      fvar<T> result;
      result.val_ = m_val.determinant();
      result.d_ = result.val_ * m_deriv.trace();

      // FIXME:  I think this will overcopy compared to retur fvar<T>(...);
      return result;
    }
Ejemplo n.º 6
0
    inline int
    categorical_rng(const Eigen::Matrix<double, Eigen::Dynamic, 1>& theta,
                    RNG& rng) {
      using boost::variate_generator;
      using boost::uniform_01;

      static const char* function("categorical_rng");

      check_simplex(function, "Probabilities parameter", theta);

      variate_generator<RNG&, uniform_01<> >
        uniform01_rng(rng, uniform_01<>());

      Eigen::VectorXd index(theta.rows());
      index.setZero();

      for (int i = 0; i < theta.rows(); i++) {
        for (int j = i; j < theta.rows(); j++)
          index(j) += theta(i, 0);
      }

      double c = uniform01_rng();
      int b = 0;
      while (c > index(b, 0))
        b++;
      return b + 1;
    }
Ejemplo n.º 7
0
    typename boost::math::tools::promote_args<T_prob,T_prior_sample_size>::type
    dirichlet_log(const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta,
		  const Eigen::Matrix<T_prior_sample_size,Eigen::Dynamic,1>& alpha) {
      static const char* function = "stan::prob::dirichlet_log(%1%)";
      using boost::math::lgamma;
      using boost::math::tools::promote_args;
      using stan::math::check_consistent_sizes;
      using stan::math::check_positive;
      using stan::math::check_simplex;
      using stan::math::multiply_log;
      
      typename promote_args<T_prob,T_prior_sample_size>::type lp(0.0);      
      check_consistent_sizes(function, theta, alpha,
                             "probabilities", "prior sample sizes",
                             &lp);
      check_positive(function, alpha, "prior sample sizes", &lp);
      check_simplex(function, theta, "probabilities", &lp);

      if (include_summand<propto,T_prior_sample_size>::value) {
        lp += lgamma(alpha.sum());
        for (int k = 0; k < alpha.rows(); ++k)
          lp -= lgamma(alpha[k]);
      }
      if (include_summand<propto,T_prob,T_prior_sample_size>::value)
        for (int k = 0; k < theta.rows(); ++k) 
          lp += multiply_log(alpha[k]-1, theta[k]);
      return lp;
    }
Ejemplo n.º 8
0
 inline typename
 boost::disable_if_c<boost::is_same<I1, index_uni>::value
                     || boost::is_same<I2, index_uni>::value, void>::type
 assign(Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& x,
        const cons_index_list<I1,
                              cons_index_list<I2, nil_index_list> >& idxs,
        const Eigen::Matrix<U, Eigen::Dynamic, Eigen::Dynamic>& y,
        const char* name = "ANON", int depth = 0) {
   int x_idxs_rows = rvalue_index_size(idxs.head_, x.rows());
   int x_idxs_cols = rvalue_index_size(idxs.tail_.head_, x.cols());
   math::check_size_match("matrix[multi,multi] assign sizes",
                          "lhs", x_idxs_rows,
                          name, y.rows());
   math::check_size_match("matrix[multi,multi] assign sizes",
                          "lhs", x_idxs_cols,
                          name, y.cols());
   for (int j = 0; j < y.cols(); ++j) {
     int n = rvalue_at(j, idxs.tail_.head_);
     math::check_range("matrix[multi,multi] assign range", name,
                       x.cols(), n);
     for (int i = 0; i < y.rows(); ++i) {
       int m = rvalue_at(i, idxs.head_);
       math::check_range("matrix[multi,multi] assign range", name,
                         x.rows(), m);
       x(m - 1, n - 1) = y(i, j);
     }
   }
 }
Ejemplo n.º 9
0
    inline bool check_corr_matrix(const std::string& function,
                                  const std::string& name,
                                  const Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic>& y) {
      using Eigen::Dynamic;
      using Eigen::Matrix;
      using stan::math::index_type;

      typedef typename index_type<Matrix<T_y,Dynamic,Dynamic> >::type size_t;

      check_size_match(function, 
                       "Rows of correlation matrix", y.rows(), 
                       "columns of correlation matrix", y.cols());
      
      check_positive(function, "rows", y.rows());

      check_symmetric(function, "y", y);
      
      for (size_t k = 0; k < y.rows(); ++k) {
        if (!(fabs(y(k,k) - 1.0) <= CONSTRAINT_TOLERANCE)) {
          std::ostringstream msg;
          msg << "is not a valid correlation matrix. " 
              << name << "(" << stan::error_index::value + k 
              << "," << stan::error_index::value + k 
              << ") is "; ;
          dom_err(function, name, y(k,k),
                  msg.str(),
                  ", but should be near 1.0");
          return false;
        }
      }
      stan::error_handling::check_pos_definite(function, "y", y);
      return true;
    }
Ejemplo n.º 10
0
void expect_matrix_eq(const Eigen::Matrix<T1,Eigen::Dynamic,Eigen::Dynamic>& a,
                      const Eigen::Matrix<T2,Eigen::Dynamic,Eigen::Dynamic>& b) {
  EXPECT_EQ(a.rows(), b.rows());
  EXPECT_EQ(a.cols(), b.cols());
  for (int i = 0; i < a.rows(); ++i)
    for (int j = 0; j < a.cols(); ++j)
      EXPECT_FLOAT_EQ(value_of(a(i,j)), value_of(b(i,j)));
}
Ejemplo n.º 11
0
void vector_test(const Eigen::Matrix<Real, NbRows, NbCols>& A, const Eigen::Matrix<Real, NbRows, NbCols>& B, Accumulator& Result)
{
    for(int i = 0, k = 0; i != A.rows() && k != B.rows(); ++i, ++k)
        for(int j = 0, l = 0; j != A.cols() && l != B.cols(); ++j, ++l)
            test(A(i, j), B(k, l), Result);

    Result.exact(A.rows() == B.rows() && A.cols() == B.cols());
};
Ejemplo n.º 12
0
 inline Eigen::Matrix<fvar<T>,R,1> 
 rows_dot_self(const Eigen::Matrix<fvar<T>,R,C>& x) {
   Eigen::Matrix<fvar<T>,R,1> ret(x.rows(),1);
   for (size_type i = 0; i < x.rows(); i++) {
     Eigen::Matrix<fvar<T>,1,C> crow = x.row(i);
     ret(i,0) = dot_self(crow);
   }
   return ret;
 }
Ejemplo n.º 13
0
 inline Eigen::Matrix<fvar<T>,R,C>
 divide(const Eigen::Matrix<fvar<T>, R,C>& v, const fvar<T>& c) {
   Eigen::Matrix<fvar<T>,R,C> res(v.rows(),v.cols());
   for(int i = 0; i < v.rows(); i++) {
     for(int j = 0; j < v.cols(); j++)
       res(i,j) = v(i,j) / c;
   }
   return res;
 }
Ejemplo n.º 14
0
 inline Eigen::Matrix<fvar<typename stan::return_type<T1,T2>::type>,R,C>
 divide(const Eigen::Matrix<T1, R,C>& v, const fvar<T2>& c) {
   Eigen::Matrix<fvar<typename stan::return_type<T1,T2>::type>,R,C> res(v.rows(),v.cols());
   for(int i = 0; i < v.rows(); i++) {
     for(int j = 0; j < v.cols(); j++)
       res(i,j) = to_fvar(v(i,j)) / c;
   }
   return res;
 }
Ejemplo n.º 15
0
 inline 
 Eigen::Matrix<fvar<T>,R1,C1> 
 multiply(const Eigen::Matrix<fvar<T>, R1, C1>& m, const fvar<T>& c) {
   Eigen::Matrix<fvar<T>,R1,C1> res(m.rows(),m.cols());
   for(int i = 0; i < m.rows(); i++) {
     for(int j = 0; j < m.cols(); j++)
       res(i,j) = c * m(i,j);
   }
   return res;
 }
Ejemplo n.º 16
0
 inline Eigen::Matrix<double, R1, 1>
 rows_dot_product(const Eigen::Matrix<double, R1, C1>& v1, 
                     const Eigen::Matrix<double, R2, C2>& v2) {
   validate_matching_sizes(v1,v2,"rows_dot_product");
   Eigen::Matrix<double, R1, 1> ret(v1.rows(),1);
   for (size_type j = 0; j < v1.rows(); ++j) {
     ret(j) = v1.row(j).dot(v2.row(j));
   }
   return ret;
 }    
Ejemplo n.º 17
0
 inline 
 Eigen::Matrix<fvar<typename stan::return_type<T1,T2>::type>, R2, C2> 
 multiply(const Eigen::Matrix<fvar<T1>, R2, C2>& m, const T2& c) {
   Eigen::Matrix<fvar<typename stan::return_type<T1,T2>::type>,R2,C2> res(m.rows(),m.cols());
   for(int i = 0; i < m.rows(); i++) {
     for(int j = 0; j < m.cols(); j++)
       res(i,j) = to_fvar(c) * m(i,j);
   }
   return res;
 }
Ejemplo n.º 18
0
 void validate_row_index(const Eigen::Matrix<T,R,C>& m,
                         size_t i,
                         const char* msg) {
   if (i > 0 && i <=  static_cast<size_t>(m.rows())) return;
   std::stringstream ss;
   ss << "require 0 < row index <= number of rows in" << msg;
   ss << " found rows()=" << m.rows()
      << "; index i=" << i;
   throw std::domain_error(ss.str());
 }
Ejemplo n.º 19
0
 inline 
 Eigen::Matrix<fvar<typename stan::return_type<T1,T2>::type>,R1,C1> 
 multiply(const Eigen::Matrix<T1, R1, C1>& m, const fvar<T2>& c) {
   Eigen::Matrix<fvar<typename stan::return_type<T1,T2>::type>,R1,C1> res(m.rows(),m.cols());
   for(int i = 0; i < m.rows(); i++) {
     for(int j = 0; j < m.cols(); j++)
       res(i,j) = c * to_fvar(m(i,j));
   }
   return res;
 }
Ejemplo n.º 20
0
 inline bool check_cov_matrix(const std::string& function,
                              const std::string& name,
                              const Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic>& y) {
   check_size_match(function, 
                    "Rows of covariance matrix", y.rows(),
                    "columns of covariance matrix", y.cols());
   check_positive(function, "rows", y.rows());
   check_symmetric(function, name, y);
   check_pos_definite(function, name, y);
   return true;
 }
Ejemplo n.º 21
0
 inline
 Eigen::Matrix<T,Eigen::Dynamic,1>
 segment(const Eigen::Matrix<T,Eigen::Dynamic,1>& v,
         size_t i, size_t n) {
   stan::math::check_greater("segment(%1%)",i,0.0,"n",(double*)0);
   stan::math::check_less_or_equal("segment(%1%)",i,static_cast<size_t>(v.rows()),"n",(double*)0);
   if (n != 0) {
     stan::math::check_greater("segment(%1%)",i+n-1,0.0,"n",(double*)0);
     stan::math::check_less_or_equal("segment(%1%)",i+n-1,static_cast<size_t>(v.rows()),"n",(double*)0);
   } 
   return v.segment(i-1,n);
 }
Ejemplo n.º 22
0
 Eigen::Matrix<fvar<T>,Eigen::Dynamic,Eigen::Dynamic>
 qr_Q(const Eigen::Matrix<fvar<T>,Eigen::Dynamic,Eigen::Dynamic>& m) {
   typedef Eigen::Matrix<fvar<T>,Eigen::Dynamic,Eigen::Dynamic> matrix_fwd_t;
   stan::math::check_nonzero_size("qr_Q", "m", m);
   stan::math::check_greater_or_equal("qr_Q", "m.rows()", m.rows(), m.cols());
   Eigen::HouseholderQR< matrix_fwd_t > qr(m.rows(), m.cols());
   qr.compute(m);
   matrix_fwd_t Q = qr.householderQ();
   for (int i=0; i<m.cols(); i++)
     if (qr.matrixQR()(i,i) < 0.0)
       Q.col(i) *= -1.0;
   return Q;
 }
Ejemplo n.º 23
0
 inline bool check_cov_matrix(const char* function,
                              const Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic>& y,
                              const char* name,
                              T_result* result) {
   check_size_match(function, 
                    y.rows(), "Rows of covariance matrix",
                    y.cols(), "columns of covariance matrix",
                    result);
   check_positive(function, y.rows(), "rows", result);
   check_symmetric(function, y, name, result);
   check_pos_definite(function, y, name, result);
   return true;
 }
Ejemplo n.º 24
0
 std::string Gaussian<ScalarType>::toJSONString(bool styledWriter) const
 {
     DEBUG_OUT("saving gaussian as JSON", 40);
     //uses Jsoncpp as library. Jsoncpp is licensed as MIT, so we may use it without restriction.
     Json::Value root;
     Json::Writer* writer=NULL;
     
     if (styledWriter)
         writer = new Json::StyledWriter();
     else
         writer = new Json::FastWriter();
     
     //output the weight
     root["weight"]      = getWeight();
     
     //output the mean as array of doubles
     Json::Value mean(Json::arrayValue);
     Eigen::Matrix<ScalarType, Eigen::Dynamic, 1> gMean = getMean();
     for (int i=0; i<gMean.size(); i++)
         mean.append(Json::Value(gMean[i]));
     root["mean"]        = mean;
     
     //output the variance as array of double. only save the lower
     //triangular, as the other values are mirrored.
     Json::Value variance(Json::arrayValue);
     Eigen::Matrix<ScalarType, Eigen::Dynamic, Eigen::Dynamic> gVariance = getCovarianceMatrix();
     if (isDiagonal(gVariance))
     {
         DEBUG_OUT("save as diagonal covariance matrix", 45);
         for (int i=0; i<gVariance.rows(); i++)
         {
             variance.append(Json::Value(gVariance(i, i)));
         }
     }
     else
     {
         DEBUG_OUT("save as full covariance matrix", 45);
         for (int i=0; i<gVariance.rows(); i++)
         {
             for (int j=i; j<gVariance.cols(); j++)
             {
                 variance.append(Json::Value(gVariance(i, j)));
             }
         }
     }
     root["covariance"]    = variance;
     
     std::string str = writer->write(root);
     delete writer;
     return str;
 }
Ejemplo n.º 25
0
    inline var log_determinant_spd(const Eigen::Matrix<var,R,C>& m) {
      using stan::math::domain_error;
      using Eigen::Matrix;

      math::check_square("log_determinant_spd", "m", m);

      Matrix<double,R,C> m_d(m.rows(),m.cols());
      for (int i = 0; i < m.size(); ++i)
        m_d(i) = m(i).val();

      Eigen::LDLT<Matrix<double,R,C> > ldlt(m_d);
      if (ldlt.info() != Eigen::Success) {
        double y = 0;
        domain_error("log_determinant_spd",
                "matrix argument", y,
                "failed LDLT factorization");
      }

       // compute the inverse of A (needed for the derivative)
      m_d.setIdentity(m.rows(), m.cols());
      ldlt.solveInPlace(m_d);
          
      if (ldlt.isNegative() || (ldlt.vectorD().array() <= 1e-16).any()) {
        double y = 0;
        domain_error("log_determinant_spd",
                "matrix argument", y,
                "matrix is negative definite");
      }

      double val = ldlt.vectorD().array().log().sum();

      if (!boost::math::isfinite(val)) {
        double y = 0;
        domain_error("log_determinant_spd",
                "matrix argument", y,
                "log determininant is infinite");
      }

      vari** operands = ChainableStack::memalloc_
        .alloc_array<vari*>(m.size());
      for (int i = 0; i < m.size(); ++i)
        operands[i] = m(i).vi_;

      double* gradients = ChainableStack::memalloc_
        .alloc_array<double>(m.size());
      for (int i = 0; i < m.size(); ++i)
        gradients[i] = m_d(i);

      return var(new precomputed_gradients_vari(val,m.size(),operands,gradients));
    }
Ejemplo n.º 26
0
    inline void check_pos_definite(const char* function, const char* name,
                                   const Eigen::Matrix<T_y, -1, -1>& y) {
      check_symmetric(function, name, y);
      check_positive_size(function, name, "rows", y.rows());
      if (y.rows() == 1 && !(y(0, 0) > CONSTRAINT_TOLERANCE))
        domain_error(function, name, "is not positive definite.", "");

      Eigen::LDLT<Eigen::MatrixXd> cholesky = value_of_rec(y).ldlt();
      if (cholesky.info() != Eigen::Success
          || !cholesky.isPositive()
          || (cholesky.vectorD().array() <= 0.0).any())
        domain_error(function, name, "is not positive definite.", "");
      check_not_nan(function, name, y);
    }
Ejemplo n.º 27
0
    inline Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
    append_col(const Eigen::Matrix<T, R1, C1>& A,
               const Eigen::Matrix<T, R2, C2>& B) {
      using Eigen::Matrix;
      using Eigen::Dynamic;

      check_size_match("append_col",
                       "rows of A", A.rows(),
                       "rows of B", B.rows());

      Matrix<T, Dynamic, Dynamic> result(A.rows(), A.cols()+B.cols());
      result << A, B;
      return result;
    }
Ejemplo n.º 28
0
 inline 
 Eigen::Matrix<fvar<typename stan::return_type<T1,T2>::type>,R1,C2> 
 multiply(const Eigen::Matrix<fvar<T1>,R1,C1>& m1,
          const Eigen::Matrix<T2,R2,C2>& m2) {
   stan::math::validate_multiplicable(m1,m2,"multiply");
   Eigen::Matrix<fvar<typename stan::return_type<T1,T2>::type>,R1,C2> result(m1.rows(),m2.cols());
   for (size_type i = 0; i < m1.rows(); i++) {
     Eigen::Matrix<fvar<T1>,1,C1> crow = m1.row(i);
     for (size_type j = 0; j < m2.cols(); j++) {
       Eigen::Matrix<T2,R2,1> ccol = m2.col(j);
       result(i,j) = stan::agrad::dot_product(crow,ccol);
       }
     }
   return result;
 }
Ejemplo n.º 29
0
 void write_stan(const Eigen::Matrix<double,
                                     Eigen::Dynamic,Eigen::Dynamic>& x) {
   typedef Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>::Index Index;
   out_ << "structure(c(";
   std::vector<double> vals;
   for (Index m = 0; m < x.cols(); ++m) {
     for (Index n = 0; n < x.rows(); ++n) {
       if (m > 0 || n > 0) out_ << ", ";
       write_val(x(m,n));
     }
   }
   out_ << "), .Dim = c(";
   out_ << x.rows() << ", " << x.cols();
   out_ << "))";
 }
void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src, Mat& dst )
{
    if( !(src.Flags & Eigen::RowMajorBit) )
    {
        Mat _src(src.cols(), src.rows(), DataType<_Tp>::type,
              (void*)src.data(), src.stride()*sizeof(_Tp));
        transpose(_src, dst);
    }
    else
    {
        Mat _src(src.rows(), src.cols(), DataType<_Tp>::type,
                 (void*)src.data(), src.stride()*sizeof(_Tp));
        _src.copyTo(dst);
    }
}